summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.dockerignore2
-rw-r--r--.eslintrc.yml4
-rw-r--r--.gitignore1
-rw-r--r--.gitlab-ci.yml1
-rw-r--r--.gitlab/CODEOWNERS310
-rw-r--r--.gitlab/ci/docs.gitlab-ci.yml9
-rw-r--r--.gitlab/ci/frontend.gitlab-ci.yml5
-rw-r--r--.gitlab/ci/qa.gitlab-ci.yml9
-rw-r--r--.gitlab/ci/rails.gitlab-ci.yml14
-rw-r--r--.gitlab/ci/review-apps/dast.gitlab-ci.yml3
-rw-r--r--.gitlab/ci/review-apps/qa.gitlab-ci.yml75
-rw-r--r--.gitlab/ci/rules.gitlab-ci.yml75
-rw-r--r--.gitlab/ci/setup.gitlab-ci.yml11
-rw-r--r--.gitlab/ci/workhorse.gitlab-ci.yml2
-rw-r--r--.gitlab/ci/yaml.gitlab-ci.yml2
-rw-r--r--.gitlab/issue_templates/Experiment Rollout.md14
-rw-r--r--.gitlab/issue_templates/Feature Proposal - basic.md2
-rw-r--r--.gitlab/issue_templates/Feature Proposal - lean.md5
-rw-r--r--.gitlab/issue_templates/Feature proposal - detailed.md2
-rw-r--r--.gitlab/issue_templates/Geo Replicate a new Git repository type.md8
-rw-r--r--.gitlab/issue_templates/Geo Replicate a new blob type.md8
-rw-r--r--.gitlab/issue_templates/Performance Indicator Metric.md23
-rw-r--r--.gitlab/issue_templates/Security developer workflow.md1
-rw-r--r--.gitlab/merge_request_templates/Deprecations.md12
-rw-r--r--.gitlab/merge_request_templates/Removals.md103
-rw-r--r--.markdownlint.yml5
-rw-r--r--.rubocop_todo.yml1
-rw-r--r--.rubocop_todo/database/multiple_databases.yml12
-rw-r--r--.rubocop_todo/gitlab/delegate_predicate_methods.yml3
-rw-r--r--.rubocop_todo/gitlab/namespaced_class.yml1
-rw-r--r--.rubocop_todo/graphql/argument_name.yml4
-rw-r--r--.rubocop_todo/graphql/field_definitions.yml3
-rw-r--r--.rubocop_todo/graphql/field_method.yml4
-rw-r--r--.rubocop_todo/graphql/ordered_arguments.yml3
-rw-r--r--.rubocop_todo/rails/include_url_helper.yml1
-rw-r--r--.rubocop_todo/rails/save_bang.yml53
-rw-r--r--.rubocop_todo/rails/time_zone.yml2
-rw-r--r--.rubocop_todo/rspec/timecop_freeze.yml3
-rw-r--r--.rubocop_todo/style/open_struct_use.yml5
-rw-r--r--CHANGELOG.md8
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--GITLAB_PAGES_VERSION2
-rw-r--r--GITLAB_SHELL_VERSION2
-rw-r--r--Gemfile39
-rw-r--r--Gemfile.lock214
-rw-r--r--README.md2
-rw-r--r--app/assets/images/file_icons.svg2
-rw-r--r--app/assets/javascripts/admin/users/components/user_actions.vue3
-rw-r--r--app/assets/javascripts/analytics/shared/components/projects_dropdown_filter.vue13
-rw-r--r--app/assets/javascripts/api/packages_api.js8
-rw-r--r--app/assets/javascripts/behaviors/copy_code.js3
-rw-r--r--app/assets/javascripts/behaviors/copy_to_clipboard.js46
-rw-r--r--app/assets/javascripts/behaviors/markdown/render_gfm.js7
-rw-r--r--app/assets/javascripts/behaviors/markdown/render_sandboxed_mermaid.js234
-rw-r--r--app/assets/javascripts/behaviors/preview_markdown.js7
-rw-r--r--app/assets/javascripts/blob/blob_line_permalink_updater.js2
-rw-r--r--app/assets/javascripts/blob/components/blob_header.vue2
-rw-r--r--app/assets/javascripts/blob/components/blob_header_filepath.vue11
-rw-r--r--app/assets/javascripts/blob/components/blob_header_viewer_switcher.vue4
-rw-r--r--app/assets/javascripts/blob/line_highlighter.js (renamed from app/assets/javascripts/line_highlighter.js)0
-rw-r--r--app/assets/javascripts/boards/components/board_card.vue2
-rw-r--r--app/assets/javascripts/boards/components/board_content_sidebar.vue29
-rw-r--r--app/assets/javascripts/boards/components/board_filtered_search.vue17
-rw-r--r--app/assets/javascripts/boards/components/board_list_header.vue2
-rw-r--r--app/assets/javascripts/boards/components/sidebar/board_sidebar_title.vue2
-rw-r--r--app/assets/javascripts/boards/constants.js4
-rw-r--r--app/assets/javascripts/boards/graphql/group_board_milestones.query.graphql4
-rw-r--r--app/assets/javascripts/boards/graphql/issue.fragment.graphql35
-rw-r--r--app/assets/javascripts/boards/graphql/issue_create.mutation.graphql2
-rw-r--r--app/assets/javascripts/boards/graphql/issue_move_list.mutation.graphql2
-rw-r--r--app/assets/javascripts/boards/graphql/lists_issues.query.graphql4
-rw-r--r--app/assets/javascripts/boards/graphql/project_board_milestones.query.graphql4
-rw-r--r--app/assets/javascripts/boards/stores/actions.js2
-rw-r--r--app/assets/javascripts/branches/branches_delete_modal.js53
-rw-r--r--app/assets/javascripts/clusters/agents/components/show.vue13
-rw-r--r--app/assets/javascripts/clusters/agents/graphql/provider.js26
-rw-r--r--app/assets/javascripts/clusters/agents/index.js24
-rw-r--r--app/assets/javascripts/clusters_list/components/agent_options.vue200
-rw-r--r--app/assets/javascripts/clusters_list/components/agent_table.vue65
-rw-r--r--app/assets/javascripts/clusters_list/components/agents.vue6
-rw-r--r--app/assets/javascripts/clusters_list/constants.js4
-rw-r--r--app/assets/javascripts/clusters_list/graphql/cache_update.js22
-rw-r--r--app/assets/javascripts/clusters_list/graphql/mutations/delete_agent.mutation.graphql5
-rw-r--r--app/assets/javascripts/clusters_list/index.js2
-rw-r--r--app/assets/javascripts/confirm_danger_modal.js64
-rw-r--r--app/assets/javascripts/content_editor/components/wrappers/frontmatter.vue2
-rw-r--r--app/assets/javascripts/content_editor/constants.js7
-rw-r--r--app/assets/javascripts/content_editor/extensions/code.js13
-rw-r--r--app/assets/javascripts/content_editor/extensions/code_block_highlight.js9
-rw-r--r--app/assets/javascripts/content_editor/extensions/frontmatter.js11
-rw-r--r--app/assets/javascripts/content_editor/extensions/image.js11
-rw-r--r--app/assets/javascripts/content_editor/services/markdown_serializer.js2
-rw-r--r--app/assets/javascripts/content_editor/services/serialization_helpers.js9
-rw-r--r--app/assets/javascripts/content_editor/services/track_input_rules_and_shortcuts.js48
-rw-r--r--app/assets/javascripts/create_merge_request_dropdown.js566
-rw-r--r--app/assets/javascripts/crm/components/form.vue232
-rw-r--r--app/assets/javascripts/cycle_analytics/components/base.vue2
-rw-r--r--app/assets/javascripts/cycle_analytics/components/path_navigation.vue2
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_table.vue33
-rw-r--r--app/assets/javascripts/cycle_analytics/components/value_stream_filters.vue4
-rw-r--r--app/assets/javascripts/design_management/components/design_notes/design_discussion.vue85
-rw-r--r--app/assets/javascripts/design_management/components/design_notes/design_note_signed_out.vue50
-rw-r--r--app/assets/javascripts/design_management/components/design_presentation.vue4
-rw-r--r--app/assets/javascripts/design_management/components/design_sidebar.vue24
-rw-r--r--app/assets/javascripts/design_management/index.js4
-rw-r--r--app/assets/javascripts/diffs/components/compare_versions.vue2
-rw-r--r--app/assets/javascripts/diffs/components/image_diff_overlay.vue16
-rw-r--r--app/assets/javascripts/dropzone_input.js1
-rw-r--r--app/assets/javascripts/editor/source_editor.js2
-rw-r--r--app/assets/javascripts/emoji/components/picker.vue16
-rw-r--r--app/assets/javascripts/environments/components/confirm_rollback_modal.vue3
-rw-r--r--app/assets/javascripts/environments/components/deployment.vue25
-rw-r--r--app/assets/javascripts/environments/components/deployment_status_badge.vue60
-rw-r--r--app/assets/javascripts/environments/components/environment_actions.vue25
-rw-r--r--app/assets/javascripts/environments/components/environment_item.vue11
-rw-r--r--app/assets/javascripts/environments/components/environment_stop.vue27
-rw-r--r--app/assets/javascripts/environments/components/new_environment_folder.vue26
-rw-r--r--app/assets/javascripts/environments/components/new_environment_item.vue265
-rw-r--r--app/assets/javascripts/environments/components/new_environments_app.vue39
-rw-r--r--app/assets/javascripts/environments/components/stop_environment_modal.vue15
-rw-r--r--app/assets/javascripts/environments/graphql/mutations/action.mutation.graphql5
-rw-r--r--app/assets/javascripts/environments/graphql/mutations/set_environment_to_stop.mutation.graphql3
-rw-r--r--app/assets/javascripts/environments/graphql/queries/environment_to_stop.query.graphql3
-rw-r--r--app/assets/javascripts/environments/graphql/queries/is_environment_stopping.query.graphql3
-rw-r--r--app/assets/javascripts/environments/graphql/queries/is_last_deployment.query.graphql3
-rw-r--r--app/assets/javascripts/environments/graphql/resolvers.js18
-rw-r--r--app/assets/javascripts/environments/graphql/typedefs.graphql6
-rw-r--r--app/assets/javascripts/experimental_flags.js15
-rw-r--r--app/assets/javascripts/flash.js139
-rw-r--r--app/assets/javascripts/gitlab_version_check.js20
-rw-r--r--app/assets/javascripts/google_cloud/components/deployments_service_table.vue61
-rw-r--r--app/assets/javascripts/google_cloud/components/home.vue17
-rw-r--r--app/assets/javascripts/google_tag_manager/index.js122
-rw-r--r--app/assets/javascripts/graphql_shared/fragment_types/vulnerability_location_types.js17
-rw-r--r--app/assets/javascripts/graphql_shared/fragments/issue.fragment.graphql37
-rw-r--r--app/assets/javascripts/group.js7
-rw-r--r--app/assets/javascripts/groups/components/item_stats.vue2
-rw-r--r--app/assets/javascripts/groups/groups_list.js18
-rw-r--r--app/assets/javascripts/groups/landing.js (renamed from app/assets/javascripts/landing.js)0
-rw-r--r--app/assets/javascripts/groups/store/groups_store.js3
-rw-r--r--app/assets/javascripts/groups/transfer_edit.js (renamed from app/assets/javascripts/transfer_edit.js)0
-rw-r--r--app/assets/javascripts/groups_list.js18
-rw-r--r--app/assets/javascripts/header_search/components/app.vue7
-rw-r--r--app/assets/javascripts/helpers/event_hub_factory.js7
-rw-r--r--app/assets/javascripts/ide/components/jobs/stage.vue5
-rw-r--r--app/assets/javascripts/ide/stores/modules/pipelines/actions.js8
-rw-r--r--app/assets/javascripts/init_confirm_danger.js18
-rw-r--r--app/assets/javascripts/integrations/constants.js5
-rw-r--r--app/assets/javascripts/integrations/edit/components/dynamic_field.vue5
-rw-r--r--app/assets/javascripts/integrations/edit/components/integration_form.vue143
-rw-r--r--app/assets/javascripts/integrations/edit/components/reset_confirmation_modal.vue2
-rw-r--r--app/assets/javascripts/integrations/edit/index.js7
-rw-r--r--app/assets/javascripts/integrations/edit/store/actions.js23
-rw-r--r--app/assets/javascripts/integrations/edit/store/mutations.js9
-rw-r--r--app/assets/javascripts/integrations/edit/store/state.js2
-rw-r--r--app/assets/javascripts/integrations/overrides/components/integration_overrides.vue7
-rw-r--r--app/assets/javascripts/integrations/overrides/components/integration_tabs.vue52
-rw-r--r--app/assets/javascripts/integrations/overrides/index.js5
-rw-r--r--app/assets/javascripts/issuable/bulk_update_sidebar/index.js28
-rw-r--r--app/assets/javascripts/issuable/bulk_update_sidebar/init_issue_status_select.js17
-rw-r--r--app/assets/javascripts/issuable/bulk_update_sidebar/issuable_bulk_update_sidebar.js10
-rw-r--r--app/assets/javascripts/issuable/bulk_update_sidebar/issuable_init_bulk_update_sidebar.js19
-rw-r--r--app/assets/javascripts/issuable/components/csv_import_modal.vue6
-rw-r--r--app/assets/javascripts/issuable/index.js37
-rw-r--r--app/assets/javascripts/issues/constants.js6
-rw-r--r--app/assets/javascripts/issues/create_merge_request_dropdown.js566
-rw-r--r--app/assets/javascripts/issues/form.js24
-rw-r--r--app/assets/javascripts/issues/index.js88
-rw-r--r--app/assets/javascripts/issues/init_filtered_search_service_desk.js11
-rw-r--r--app/assets/javascripts/issues/issue.js2
-rw-r--r--app/assets/javascripts/issues/list/components/issue_card_time_info.vue (renamed from app/assets/javascripts/issues_list/components/issue_card_time_info.vue)0
-rw-r--r--app/assets/javascripts/issues/list/components/issues_list_app.vue821
-rw-r--r--app/assets/javascripts/issues/list/components/jira_issues_import_status_app.vue (renamed from app/assets/javascripts/issues_list/components/jira_issues_import_status_app.vue)0
-rw-r--r--app/assets/javascripts/issues/list/components/new_issue_dropdown.vue127
-rw-r--r--app/assets/javascripts/issues/list/constants.js316
-rw-r--r--app/assets/javascripts/issues/list/eventhub.js (renamed from app/assets/javascripts/issues_list/eventhub.js)0
-rw-r--r--app/assets/javascripts/issues/list/index.js165
-rw-r--r--app/assets/javascripts/issues/list/queries/get_issues.query.graphql (renamed from app/assets/javascripts/issues_list/queries/get_issues.query.graphql)0
-rw-r--r--app/assets/javascripts/issues/list/queries/get_issues_counts.query.graphql (renamed from app/assets/javascripts/issues_list/queries/get_issues_counts.query.graphql)0
-rw-r--r--app/assets/javascripts/issues/list/queries/get_issues_list_details.query.graphql (renamed from app/assets/javascripts/issues_list/queries/get_issues_list_details.query.graphql)0
-rw-r--r--app/assets/javascripts/issues/list/queries/issue.fragment.graphql (renamed from app/assets/javascripts/issues_list/queries/issue.fragment.graphql)0
-rw-r--r--app/assets/javascripts/issues/list/queries/label.fragment.graphql (renamed from app/assets/javascripts/issues_list/queries/label.fragment.graphql)0
-rw-r--r--app/assets/javascripts/issues/list/queries/milestone.fragment.graphql (renamed from app/assets/javascripts/issues_list/queries/milestone.fragment.graphql)0
-rw-r--r--app/assets/javascripts/issues/list/queries/reorder_issues.mutation.graphql (renamed from app/assets/javascripts/issues_list/queries/reorder_issues.mutation.graphql)0
-rw-r--r--app/assets/javascripts/issues/list/queries/search_labels.query.graphql (renamed from app/assets/javascripts/issues_list/queries/search_labels.query.graphql)0
-rw-r--r--app/assets/javascripts/issues/list/queries/search_milestones.query.graphql (renamed from app/assets/javascripts/issues_list/queries/search_milestones.query.graphql)0
-rw-r--r--app/assets/javascripts/issues/list/queries/search_projects.query.graphql (renamed from app/assets/javascripts/issues_list/queries/search_projects.query.graphql)0
-rw-r--r--app/assets/javascripts/issues/list/queries/search_users.query.graphql (renamed from app/assets/javascripts/issues_list/queries/search_users.query.graphql)0
-rw-r--r--app/assets/javascripts/issues/list/queries/user.fragment.graphql (renamed from app/assets/javascripts/issues_list/queries/user.fragment.graphql)0
-rw-r--r--app/assets/javascripts/issues/list/utils.js261
-rw-r--r--app/assets/javascripts/issues/manual_ordering.js6
-rw-r--r--app/assets/javascripts/issues/new/index.js4
-rw-r--r--app/assets/javascripts/issues/related_merge_requests/index.js32
-rw-r--r--app/assets/javascripts/issues/sentry_error_stack_trace/index.js22
-rw-r--r--app/assets/javascripts/issues/show.js59
-rw-r--r--app/assets/javascripts/issues/show/components/app.vue8
-rw-r--r--app/assets/javascripts/issues/show/components/fields/type.vue10
-rw-r--r--app/assets/javascripts/issues/show/components/header_actions.vue13
-rw-r--r--app/assets/javascripts/issues/show/components/sentry_error_stack_trace.vue (renamed from app/assets/javascripts/issues/sentry_error_stack_trace/components/sentry_error_stack_trace.vue)0
-rw-r--r--app/assets/javascripts/issues/show/constants.js26
-rw-r--r--app/assets/javascripts/issues/show/incident.js101
-rw-r--r--app/assets/javascripts/issues/show/index.js161
-rw-r--r--app/assets/javascripts/issues/show/issue.js86
-rw-r--r--app/assets/javascripts/issues_list/components/issuable.vue441
-rw-r--r--app/assets/javascripts/issues_list/components/issuables_list_app.vue426
-rw-r--r--app/assets/javascripts/issues_list/components/issues_list_app.vue822
-rw-r--r--app/assets/javascripts/issues_list/components/new_issue_dropdown.vue127
-rw-r--r--app/assets/javascripts/issues_list/constants.js372
-rw-r--r--app/assets/javascripts/issues_list/index.js195
-rw-r--r--app/assets/javascripts/issues_list/service_desk_helper.js111
-rw-r--r--app/assets/javascripts/issues_list/utils.js261
-rw-r--r--app/assets/javascripts/jira_import/utils/constants.js2
-rw-r--r--app/assets/javascripts/jira_import/utils/jira_import_utils.js2
-rw-r--r--app/assets/javascripts/jobs/bridge/app.vue106
-rw-r--r--app/assets/javascripts/jobs/bridge/components/sidebar.vue65
-rw-r--r--app/assets/javascripts/jobs/bridge/graphql/queries/pipeline.query.graphql70
-rw-r--r--app/assets/javascripts/jobs/components/job_log_controllers.vue1
-rw-r--r--app/assets/javascripts/jobs/components/sidebar_job_details_container.vue9
-rw-r--r--app/assets/javascripts/jobs/index.js13
-rw-r--r--app/assets/javascripts/labels/components/delete_label_modal.vue13
-rw-r--r--app/assets/javascripts/labels/create_label_dropdown.js4
-rw-r--r--app/assets/javascripts/labels/index.js2
-rw-r--r--app/assets/javascripts/lib/mermaid.js61
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js10
-rw-r--r--app/assets/javascripts/lib/utils/constants.js1
-rw-r--r--app/assets/javascripts/lib/utils/resize_observer.js58
-rw-r--r--app/assets/javascripts/main.js15
-rw-r--r--app/assets/javascripts/members/components/table/members_table.vue43
-rw-r--r--app/assets/javascripts/members/constants.js30
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/details_header.vue7
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/empty_state.vue44
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue67
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row.vue7
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/components/registry_breadcrumb.vue51
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/common.js2
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/details.js7
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/list.js3
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags.query.graphql4
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/index.js39
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/details.vue19
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue347
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/composer_installation.vue10
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/conan_installation.vue8
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/maven_installation.vue19
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/npm_installation.vue10
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/nuget_installation.vue7
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue6
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/pypi_installation.vue9
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/list/package_list_row.vue20
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/constants.js7
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql10
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/index.js58
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/pages/details.js27
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue350
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/router.js20
-rw-r--r--app/assets/javascripts/packages_and_registries/shared/components/persisted_search.vue80
-rw-r--r--app/assets/javascripts/packages_and_registries/shared/components/registry_breadcrumb.vue56
-rw-r--r--app/assets/javascripts/packages_and_registries/shared/utils.js35
-rw-r--r--app/assets/javascripts/pages/admin/integrations/edit/index.js2
-rw-r--r--app/assets/javascripts/pages/admin/labels/edit/index.js2
-rw-r--r--app/assets/javascripts/pages/admin/runners/edit/index.js3
-rw-r--r--app/assets/javascripts/pages/admin/runners/show/index.js3
-rw-r--r--app/assets/javascripts/pages/dashboard/todos/index/todos.js8
-rw-r--r--app/assets/javascripts/pages/explore/groups/index.js6
-rw-r--r--app/assets/javascripts/pages/groups/edit/index.js4
-rw-r--r--app/assets/javascripts/pages/groups/issues/index.js10
-rw-r--r--app/assets/javascripts/pages/groups/labels/edit/index.js2
-rw-r--r--app/assets/javascripts/pages/groups/merge_requests/index.js4
-rw-r--r--app/assets/javascripts/pages/groups/new/index.js7
-rw-r--r--app/assets/javascripts/pages/groups/packages/index.js8
-rw-r--r--app/assets/javascripts/pages/groups/packages/index/index.js3
-rw-r--r--app/assets/javascripts/pages/groups/settings/access_tokens/index.js3
-rw-r--r--app/assets/javascripts/pages/groups/settings/integrations/edit/index.js2
-rw-r--r--app/assets/javascripts/pages/help/index/index.js5
-rw-r--r--app/assets/javascripts/pages/profiles/keys/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/blob/show/index.js6
-rw-r--r--app/assets/javascripts/pages/projects/branches/index/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/edit/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/find_file/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/imports/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/incidents/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/init_blob.js2
-rw-r--r--app/assets/javascripts/pages/projects/issues/edit/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/issues/index/index.js11
-rw-r--r--app/assets/javascripts/pages/projects/issues/new/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/issues/service_desk/index.js7
-rw-r--r--app/assets/javascripts/pages/projects/issues/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/labels/edit/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/index/index.js5
-rw-r--r--app/assets/javascripts/pages/projects/new/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/packages/packages/index.js8
-rw-r--r--app/assets/javascripts/pages/projects/packages/packages/index/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/packages/packages/show/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js4
-rw-r--r--app/assets/javascripts/pages/projects/services/edit/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue40
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/index.js31
-rw-r--r--app/assets/javascripts/pages/projects/show/index.js4
-rw-r--r--app/assets/javascripts/pages/registrations/new/index.js4
-rw-r--r--app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue4
-rw-r--r--app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue1
-rw-r--r--app/assets/javascripts/pipeline_editor/components/editor/text_editor.vue10
-rw-r--r--app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue4
-rw-r--r--app/assets/javascripts/pipeline_editor/components/header/validation_segment.vue22
-rw-r--r--app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue8
-rw-r--r--app/assets/javascripts/pipeline_editor/components/ui/editor_tab.vue17
-rw-r--r--app/assets/javascripts/pipeline_editor/constants.js2
-rw-r--r--app/assets/javascripts/pipeline_editor/index.js2
-rw-r--r--app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue43
-rw-r--r--app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/header_component.vue4
-rw-r--r--app/assets/javascripts/pipelines/components/jobs/jobs_app.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/parsing_utils.js22
-rw-r--r--app/assets/javascripts/pipelines/components/pipeline_graph/pipeline_graph.vue7
-rw-r--r--app/assets/javascripts/pipelines/components/unwrapping_utils.js9
-rw-r--r--app/assets/javascripts/pipelines/constants.js2
-rw-r--r--app/assets/javascripts/pipelines/graphql/fragmentTypes.json1
-rw-r--r--app/assets/javascripts/pipelines/pipeline_shared_client.js9
-rw-r--r--app/assets/javascripts/pipelines/utils.js6
-rw-r--r--app/assets/javascripts/profile/add_ssh_key_validation.js17
-rw-r--r--app/assets/javascripts/project_import.js7
-rw-r--r--app/assets/javascripts/project_select_combo_button.js19
-rw-r--r--app/assets/javascripts/project_visibility.js58
-rw-r--r--app/assets/javascripts/projects/project_find_file.js (renamed from app/assets/javascripts/project_find_file.js)0
-rw-r--r--app/assets/javascripts/projects/project_import.js7
-rw-r--r--app/assets/javascripts/projects/project_visibility.js71
-rw-r--r--app/assets/javascripts/projects/star.js38
-rw-r--r--app/assets/javascripts/related_issues/components/related_issues_list.vue2
-rw-r--r--app/assets/javascripts/repository/components/blob_button_group.vue25
-rw-r--r--app/assets/javascripts/repository/components/blob_content_viewer.vue10
-rw-r--r--app/assets/javascripts/repository/components/blob_controls.vue119
-rw-r--r--app/assets/javascripts/repository/components/blob_edit.vue1
-rw-r--r--app/assets/javascripts/repository/components/delete_blob_modal.vue4
-rw-r--r--app/assets/javascripts/repository/components/fork_suggestion.vue1
-rw-r--r--app/assets/javascripts/repository/components/preview/index.vue9
-rw-r--r--app/assets/javascripts/repository/components/upload_blob_modal.vue4
-rw-r--r--app/assets/javascripts/repository/index.js21
-rw-r--r--app/assets/javascripts/repository/queries/blob_controls.query.graphql18
-rw-r--r--app/assets/javascripts/repository/queries/blob_info.query.graphql16
-rw-r--r--app/assets/javascripts/repository/queries/path_locks.fragment.graphql3
-rw-r--r--app/assets/javascripts/runner/admin_runner_edit/admin_runner_edit_app.vue58
-rw-r--r--app/assets/javascripts/runner/admin_runner_edit/index.js32
-rw-r--r--app/assets/javascripts/runner/admin_runners/admin_runners_app.vue131
-rw-r--r--app/assets/javascripts/runner/admin_runners/index.js30
-rw-r--r--app/assets/javascripts/runner/components/cells/runner_actions_cell.vue17
-rw-r--r--app/assets/javascripts/runner/components/cells/runner_status_cell.vue12
-rw-r--r--app/assets/javascripts/runner/components/registration/registration_token_reset_dropdown_item.vue34
-rw-r--r--app/assets/javascripts/runner/components/runner_header.vue52
-rw-r--r--app/assets/javascripts/runner/components/runner_status_badge.vue8
-rw-r--r--app/assets/javascripts/runner/components/runner_type_alert.vue54
-rw-r--r--app/assets/javascripts/runner/components/runner_update_form.vue10
-rw-r--r--app/assets/javascripts/runner/components/search_tokens/status_token_config.js4
-rw-r--r--app/assets/javascripts/runner/components/search_tokens/tag_token.vue4
-rw-r--r--app/assets/javascripts/runner/components/stat/runner_online_stat.vue17
-rw-r--r--app/assets/javascripts/runner/components/stat/runner_stats.vue49
-rw-r--r--app/assets/javascripts/runner/components/stat/runner_status_stat.vue65
-rw-r--r--app/assets/javascripts/runner/constants.js5
-rw-r--r--app/assets/javascripts/runner/graphql/get_group_runners.query.graphql2
-rw-r--r--app/assets/javascripts/runner/graphql/get_group_runners_count.query.graphql20
-rw-r--r--app/assets/javascripts/runner/graphql/get_runners.query.graphql1
-rw-r--r--app/assets/javascripts/runner/graphql/get_runners_count.query.graphql10
-rw-r--r--app/assets/javascripts/runner/graphql/runner_details_shared.fragment.graphql2
-rw-r--r--app/assets/javascripts/runner/graphql/runner_node.fragment.graphql4
-rw-r--r--app/assets/javascripts/runner/group_runners/group_runners_app.vue56
-rw-r--r--app/assets/javascripts/runner/runner_details/index.js32
-rw-r--r--app/assets/javascripts/runner/runner_details/runner_details_app.vue71
-rw-r--r--app/assets/javascripts/runner/runner_search_utils.js28
-rw-r--r--app/assets/javascripts/runner/runner_update_form_utils.js (renamed from app/assets/javascripts/runner/runner_details/runner_update_form_utils.js)0
-rw-r--r--app/assets/javascripts/security_configuration/components/app.vue32
-rw-r--r--app/assets/javascripts/security_configuration/components/auto_dev_ops_alert.vue1
-rw-r--r--app/assets/javascripts/security_configuration/components/constants.js2
-rw-r--r--app/assets/javascripts/security_configuration/components/training_provider_list.vue130
-rw-r--r--app/assets/javascripts/security_configuration/graphql/configure_security_training_providers.mutation.graphql9
-rw-r--r--app/assets/javascripts/security_configuration/index.js30
-rw-r--r--app/assets/javascripts/security_configuration/resolver.js56
-rw-r--r--app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue2
-rw-r--r--app/assets/javascripts/sidebar/components/crm_contacts/crm_contacts.vue15
-rw-r--r--app/assets/javascripts/sidebar/mount_sidebar.js7
-rw-r--r--app/assets/javascripts/sidebar/sidebar_mediator.js52
-rw-r--r--app/assets/javascripts/sidebar/stores/sidebar_store.js4
-rw-r--r--app/assets/javascripts/star.js38
-rw-r--r--app/assets/javascripts/tracking/index.js5
-rw-r--r--app/assets/javascripts/tree.js64
-rw-r--r--app/assets/javascripts/version_check_image.js6
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/actions.vue1
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue50
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js1
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/merge_checks_failed.vue45
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.vue11
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.vue6
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue10
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue15
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue62
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/pipeline_failed.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/sha_mismatch.vue8
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue22
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue5
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/constants.js3
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js173
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue20
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js5
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js12
-rw-r--r--app/assets/javascripts/vue_shared/components/actions_button.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/clipboard_button.vue60
-rw-r--r--app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger.vue7
-rw-r--r--app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.stories.js17
-rw-r--r--app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.vue25
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/author_token.vue4
-rw-r--r--app/assets/javascripts/vue_shared/components/gitlab_version_check.vue67
-rw-r--r--app/assets/javascripts/vue_shared/components/line_numbers.vue30
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/apply_suggestion.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/field.vue75
-rw-r--r--app/assets/javascripts/vue_shared/components/modal_copy_button.vue4
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue5
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue19
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue12
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_header.vue1
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/label_item.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue1
-rw-r--r--app/assets/javascripts/vue_shared/components/source_editor.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/source_viewer.vue45
-rw-r--r--app/assets/javascripts/vue_shared/components/web_ide_link.vue96
-rw-r--r--app/assets/javascripts/vue_shared/issuable/list/components/issuable_bulk_edit_sidebar.vue1
-rw-r--r--app/assets/javascripts/vue_shared/issuable/list/components/issuable_item.vue8
-rw-r--r--app/assets/javascripts/vue_shared/issuable/list/components/issuable_tabs.vue6
-rw-r--r--app/assets/javascripts/vue_shared/issuable/list/constants.js2
-rw-r--r--app/assets/javascripts/vue_shared/issuable/show/constants.js5
-rw-r--r--app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue18
-rw-r--r--app/assets/javascripts/work_items/components/item_title.vue4
-rw-r--r--app/assets/javascripts/work_items/constants.js2
-rw-r--r--app/assets/javascripts/work_items/pages/work_item_root.vue16
-rw-r--r--app/assets/stylesheets/_page_specific_files.scss1
-rw-r--r--app/assets/stylesheets/components/whats_new.scss6
-rw-r--r--app/assets/stylesheets/framework/contextual_sidebar.scss8
-rw-r--r--app/assets/stylesheets/framework/diffs.scss28
-rw-r--r--app/assets/stylesheets/framework/emojis.scss4
-rw-r--r--app/assets/stylesheets/framework/flash.scss4
-rw-r--r--app/assets/stylesheets/framework/header.scss4
-rw-r--r--app/assets/stylesheets/framework/layout.scss8
-rw-r--r--app/assets/stylesheets/framework/mixins.scss26
-rw-r--r--app/assets/stylesheets/framework/secondary_navigation_elements.scss10
-rw-r--r--app/assets/stylesheets/framework/sidebar.scss2
-rw-r--r--app/assets/stylesheets/framework/system_messages.scss10
-rw-r--r--app/assets/stylesheets/framework/typography.scss15
-rw-r--r--app/assets/stylesheets/framework/variables.scss31
-rw-r--r--app/assets/stylesheets/framework/variables_overrides.scss2
-rw-r--r--app/assets/stylesheets/framework/wells.scss27
-rw-r--r--app/assets/stylesheets/highlight/white_base.scss49
-rw-r--r--app/assets/stylesheets/notify.scss12
-rw-r--r--app/assets/stylesheets/page_bundles/boards.scss4
-rw-r--r--app/assets/stylesheets/page_bundles/build.scss6
-rw-r--r--app/assets/stylesheets/page_bundles/cycle_analytics.scss6
-rw-r--r--app/assets/stylesheets/page_bundles/import.scss2
-rw-r--r--app/assets/stylesheets/page_bundles/issues_list.scss4
-rw-r--r--app/assets/stylesheets/page_bundles/members.scss4
-rw-r--r--app/assets/stylesheets/page_bundles/merge_requests.scss2
-rw-r--r--app/assets/stylesheets/pages/issuable.scss2
-rw-r--r--app/assets/stylesheets/pages/issues.scss2
-rw-r--r--app/assets/stylesheets/pages/labels.scss12
-rw-r--r--app/assets/stylesheets/pages/login.scss4
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss18
-rw-r--r--app/assets/stylesheets/pages/notes.scss2
-rw-r--r--app/assets/stylesheets/pages/profile.scss25
-rw-r--r--app/assets/stylesheets/pages/settings.scss12
-rw-r--r--app/assets/stylesheets/pages/sherlock.scss31
-rw-r--r--app/assets/stylesheets/pages/users.scss4
-rw-r--r--app/assets/stylesheets/performance_bar.scss2
-rw-r--r--app/assets/stylesheets/startup/startup-dark.scss64
-rw-r--r--app/assets/stylesheets/startup/startup-general.scss59
-rw-r--r--app/assets/stylesheets/startup/startup-signin.scss11
-rw-r--r--app/assets/stylesheets/themes/theme_helper.scss24
-rw-r--r--app/assets/stylesheets/utilities.scss22
-rw-r--r--app/controllers/admin/runner_projects_controller.rb6
-rw-r--r--app/controllers/admin/runners_controller.rb10
-rw-r--r--app/controllers/admin/users_controller.rb2
-rw-r--r--app/controllers/autocomplete_controller.rb7
-rw-r--r--app/controllers/concerns/access_tokens_actions.rb83
-rw-r--r--app/controllers/concerns/check_rate_limit.rb5
-rw-r--r--app/controllers/concerns/integrations/actions.rb3
-rw-r--r--app/controllers/concerns/integrations/params.rb1
-rw-r--r--app/controllers/concerns/sessionless_authentication.rb2
-rw-r--r--app/controllers/graphql_controller.rb7
-rw-r--r--app/controllers/groups/application_controller.rb12
-rw-r--r--app/controllers/groups/boards_controller.rb1
-rw-r--r--app/controllers/groups/dependency_proxy_for_containers_controller.rb30
-rw-r--r--app/controllers/groups/packages_controller.rb5
-rw-r--r--app/controllers/groups/runners_controller.rb7
-rw-r--r--app/controllers/groups/settings/access_tokens_controller.rb18
-rw-r--r--app/controllers/groups_controller.rb4
-rw-r--r--app/controllers/import/gitlab_controller.rb2
-rw-r--r--app/controllers/oauth/token_info_controller.rb2
-rw-r--r--app/controllers/profiles/emails_controller.rb2
-rw-r--r--app/controllers/profiles_controller.rb3
-rw-r--r--app/controllers/projects/analytics/cycle_analytics/stages_controller.rb2
-rw-r--r--app/controllers/projects/analytics/cycle_analytics/summary_controller.rb2
-rw-r--r--app/controllers/projects/boards_controller.rb3
-rw-r--r--app/controllers/projects/google_cloud/base_controller.rb35
-rw-r--r--app/controllers/projects/google_cloud/deployments_controller.rb13
-rw-r--r--app/controllers/projects/google_cloud/service_accounts_controller.rb64
-rw-r--r--app/controllers/projects/issues_controller.rb13
-rw-r--r--app/controllers/projects/jobs_controller.rb1
-rw-r--r--app/controllers/projects/mattermosts_controller.rb2
-rw-r--r--app/controllers/projects/merge_requests/creations_controller.rb4
-rw-r--r--app/controllers/projects/merge_requests/diffs_controller.rb5
-rw-r--r--app/controllers/projects/merge_requests_controller.rb9
-rw-r--r--app/controllers/projects/packages/infrastructure_registry_controller.rb6
-rw-r--r--app/controllers/projects/packages/packages_controller.rb3
-rw-r--r--app/controllers/projects/prometheus/metrics_controller.rb6
-rw-r--r--app/controllers/projects/security/configuration_controller.rb31
-rw-r--r--app/controllers/projects/service_hook_logs_controller.rb4
-rw-r--r--app/controllers/projects/services_controller.rb7
-rw-r--r--app/controllers/projects/settings/access_tokens_controller.rb70
-rw-r--r--app/controllers/projects/settings/ci_cd_controller.rb8
-rw-r--r--app/controllers/projects/settings/repository_controller.rb3
-rw-r--r--app/controllers/projects/tree_controller.rb4
-rw-r--r--app/controllers/projects_controller.rb2
-rw-r--r--app/controllers/registrations_controller.rb7
-rw-r--r--app/controllers/repositories/lfs_api_controller.rb2
-rw-r--r--app/controllers/sandbox_controller.rb11
-rw-r--r--app/controllers/search_controller.rb8
-rw-r--r--app/controllers/sherlock/application_controller.rb14
-rw-r--r--app/controllers/sherlock/file_samples_controller.rb9
-rw-r--r--app/controllers/sherlock/queries_controller.rb9
-rw-r--r--app/controllers/sherlock/transactions_controller.rb21
-rw-r--r--app/controllers/users_controller.rb3
-rw-r--r--app/events/ci/pipeline_created_event.rb14
-rw-r--r--app/experiments/change_continuous_onboarding_link_urls_experiment.rb9
-rw-r--r--app/experiments/new_project_sast_enabled_experiment.rb3
-rw-r--r--app/experiments/require_verification_for_namespace_creation_experiment.rb27
-rw-r--r--app/experiments/templates/new_project_readme_content/readme_advanced.md.tt2
-rw-r--r--app/finders/ci/runners_finder.rb12
-rw-r--r--app/finders/environments/environments_by_deployments_finder.rb3
-rw-r--r--app/finders/fork_targets_finder.rb4
-rw-r--r--app/finders/group_descendants_finder.rb16
-rw-r--r--app/finders/group_members_finder.rb33
-rw-r--r--app/finders/groups/user_groups_finder.rb3
-rw-r--r--app/finders/groups_finder.rb4
-rw-r--r--app/finders/issues_finder.rb6
-rw-r--r--app/finders/merge_requests_finder.rb9
-rw-r--r--app/finders/packages/package_file_finder.rb6
-rw-r--r--app/finders/projects/members/effective_access_level_finder.rb8
-rw-r--r--app/finders/user_group_notification_settings_finder.rb10
-rw-r--r--app/finders/user_recent_events_finder.rb24
-rw-r--r--app/graphql/mutations/clusters/agent_tokens/revoke.rb35
-rw-r--r--app/graphql/mutations/issues/set_crm_contacts.rb9
-rw-r--r--app/graphql/mutations/issues/set_escalation_status.rb46
-rw-r--r--app/graphql/mutations/work_items/create.rb57
-rw-r--r--app/graphql/queries/pipelines/get_pipeline_details.query.graphql21
-rw-r--r--app/graphql/resolvers/base_issues_resolver.rb3
-rw-r--r--app/graphql/resolvers/ci/config_resolver.rb2
-rw-r--r--app/graphql/resolvers/clusters/agent_tokens_resolver.rb9
-rw-r--r--app/graphql/resolvers/concerns/resolves_pipelines.rb4
-rw-r--r--app/graphql/resolvers/design_management/version/designs_at_version_resolver.rb6
-rw-r--r--app/graphql/resolvers/design_management/version_in_collection_resolver.rb6
-rw-r--r--app/graphql/resolvers/group_milestones_resolver.rb6
-rw-r--r--app/graphql/resolvers/merge_requests_resolver.rb4
-rw-r--r--app/graphql/resolvers/users/groups_resolver.rb4
-rw-r--r--app/graphql/resolvers/work_items/types_resolver.rb15
-rw-r--r--app/graphql/types/ci/config/config_type.rb2
-rw-r--r--app/graphql/types/ci/job_type.rb6
-rw-r--r--app/graphql/types/ci/pipeline_message_type.rb16
-rw-r--r--app/graphql/types/ci/pipeline_type.rb23
-rw-r--r--app/graphql/types/ci/runner_type.rb15
-rw-r--r--app/graphql/types/clusters/agent_token_status_enum.rb14
-rw-r--r--app/graphql/types/clusters/agent_token_type.rb5
-rw-r--r--app/graphql/types/commit_type.rb2
-rw-r--r--app/graphql/types/deprecated_mutations.rb3
-rw-r--r--app/graphql/types/group_type.rb5
-rw-r--r--app/graphql/types/incident_management/escalation_status_enum.rb14
-rw-r--r--app/graphql/types/issue_type.rb9
-rw-r--r--app/graphql/types/issue_type_enum.rb2
-rw-r--r--app/graphql/types/merge_request_type.rb22
-rw-r--r--app/graphql/types/mutation_type.rb4
-rw-r--r--app/graphql/types/packages/package_details_type.rb51
-rw-r--r--app/graphql/types/project_type.rb48
-rw-r--r--app/graphql/types/projects/topic_type.rb3
-rw-r--r--app/graphql/types/release_type.rb11
-rw-r--r--app/graphql/types/repository/blob_type.rb19
-rw-r--r--app/graphql/types/sha_format_enum.rb19
-rw-r--r--app/graphql/types/user_interface.rb3
-rw-r--r--app/graphql/types/work_item_type.rb23
-rw-r--r--app/graphql/types/work_items/type_type.rb18
-rw-r--r--app/helpers/admin/background_migrations_helper.rb14
-rw-r--r--app/helpers/application_helper.rb13
-rw-r--r--app/helpers/application_settings_helper.rb44
-rw-r--r--app/helpers/auth_helper.rb19
-rw-r--r--app/helpers/button_helper.rb2
-rw-r--r--app/helpers/ci/jobs_helper.rb8
-rw-r--r--app/helpers/ci/pipeline_editor_helper.rb1
-rw-r--r--app/helpers/ci/runners_helper.rb11
-rw-r--r--app/helpers/commits_helper.rb18
-rw-r--r--app/helpers/custom_metrics_helper.rb2
-rw-r--r--app/helpers/environment_helper.rb2
-rw-r--r--app/helpers/environments_helper.rb2
-rw-r--r--app/helpers/groups/crm_settings_helper.rb9
-rw-r--r--app/helpers/groups_helper.rb10
-rw-r--r--app/helpers/hooks_helper.rb2
-rw-r--r--app/helpers/integrations_helper.rb17
-rw-r--r--app/helpers/issues_helper.rb19
-rw-r--r--app/helpers/learn_gitlab_helper.rb8
-rw-r--r--app/helpers/namespaces_helper.rb7
-rw-r--r--app/helpers/nav/top_nav_helper.rb15
-rw-r--r--app/helpers/nav_helper.rb4
-rw-r--r--app/helpers/notes_helper.rb2
-rw-r--r--app/helpers/packages_helper.rb28
-rw-r--r--app/helpers/page_layout_helper.rb2
-rw-r--r--app/helpers/preferences_helper.rb10
-rw-r--r--app/helpers/projects/cluster_agents_helper.rb5
-rw-r--r--app/helpers/projects/issues/service_desk_helper.rb35
-rw-r--r--app/helpers/projects_helper.rb25
-rw-r--r--app/helpers/search_helper.rb4
-rw-r--r--app/helpers/snippets_helper.rb7
-rw-r--r--app/helpers/sorting_titles_values_helper.rb4
-rw-r--r--app/helpers/ssh_keys_helper.rb10
-rw-r--r--app/helpers/tracking_helper.rb4
-rw-r--r--app/helpers/tree_helper.rb5
-rw-r--r--app/helpers/version_check_helper.rb9
-rw-r--r--app/helpers/webpack_helper.rb4
-rw-r--r--app/mailers/previews/notify_preview.rb2
-rw-r--r--app/models/active_session.rb15
-rw-r--r--app/models/alert_management/alert.rb13
-rw-r--r--app/models/application_setting.rb26
-rw-r--r--app/models/application_setting_implementation.rb11
-rw-r--r--app/models/audit_event.rb1
-rw-r--r--app/models/bulk_imports/file_transfer/project_config.rb6
-rw-r--r--app/models/ci/build.rb64
-rw-r--r--app/models/ci/job_artifact.rb16
-rw-r--r--app/models/ci/namespace_mirror.rb6
-rw-r--r--app/models/ci/pipeline.rb22
-rw-r--r--app/models/ci/project_mirror.rb3
-rw-r--r--app/models/ci/runner.rb66
-rw-r--r--app/models/ci/secure_file.rb33
-rw-r--r--app/models/clusters/agent.rb12
-rw-r--r--app/models/clusters/agent_token.rb42
-rw-r--r--app/models/clusters/agents/activity_event.rb2
-rw-r--r--app/models/clusters/applications/runner.rb4
-rw-r--r--app/models/commit_status.rb17
-rw-r--r--app/models/concerns/ci/contextable.rb36
-rw-r--r--app/models/concerns/ci/metadatable.rb10
-rw-r--r--app/models/concerns/forced_email_confirmation.rb26
-rw-r--r--app/models/concerns/has_wiki.rb2
-rw-r--r--app/models/concerns/import_state/sidekiq_job_tracker.rb2
-rw-r--r--app/models/concerns/incident_management/escalatable.rb11
-rw-r--r--app/models/concerns/packages/debian/distribution.rb9
-rw-r--r--app/models/concerns/packages/destructible.rb15
-rw-r--r--app/models/concerns/packages/installable.rb16
-rw-r--r--app/models/concerns/participable.rb2
-rw-r--r--app/models/concerns/routable.rb5
-rw-r--r--app/models/concerns/runner_token_expiration_interval.rb22
-rw-r--r--app/models/concerns/ttl_expirable.rb8
-rw-r--r--app/models/container_repository.rb6
-rw-r--r--app/models/customer_relations/contact.rb15
-rw-r--r--app/models/customer_relations/issue_contact.rb8
-rw-r--r--app/models/dependency_proxy/blob.rb1
-rw-r--r--app/models/dependency_proxy/manifest.rb1
-rw-r--r--app/models/deployment.rb10
-rw-r--r--app/models/email.rb9
-rw-r--r--app/models/experiment.rb24
-rw-r--r--app/models/external_pull_request.rb5
-rw-r--r--app/models/group.rb46
-rw-r--r--app/models/group/crm_settings.rb10
-rw-r--r--app/models/group_group_link.rb2
-rw-r--r--app/models/hooks/project_hook.rb5
-rw-r--r--app/models/hooks/service_hook.rb4
-rw-r--r--app/models/hooks/web_hook.rb5
-rw-r--r--app/models/instance_configuration.rb3
-rw-r--r--app/models/integration.rb1
-rw-r--r--app/models/integrations/base_chat_notification.rb8
-rw-r--r--app/models/integrations/datadog.rb47
-rw-r--r--app/models/integrations/jira.rb6
-rw-r--r--app/models/internal_id.rb2
-rw-r--r--app/models/issue.rb14
-rw-r--r--app/models/key.rb2
-rw-r--r--app/models/label.rb2
-rw-r--r--app/models/loose_foreign_keys/deleted_record.rb2
-rw-r--r--app/models/loose_foreign_keys/modification_tracker.rb2
-rw-r--r--app/models/member.rb13
-rw-r--r--app/models/members/group_member.rb2
-rw-r--r--app/models/members/project_namespace_member.rb7
-rw-r--r--app/models/merge_request.rb22
-rw-r--r--app/models/namespace.rb6
-rw-r--r--app/models/namespace_setting.rb23
-rw-r--r--app/models/namespaces/traversal/linear.rb13
-rw-r--r--app/models/namespaces/traversal/linear_scopes.rb37
-rw-r--r--app/models/namespaces/traversal/recursive_scopes.rb4
-rw-r--r--app/models/onboarding_progress.rb26
-rw-r--r--app/models/packages/debian/group_distribution.rb4
-rw-r--r--app/models/packages/debian/project_distribution.rb1
-rw-r--r--app/models/packages/package.rb10
-rw-r--r--app/models/packages/package_file.rb26
-rw-r--r--app/models/pages_domain.rb29
-rw-r--r--app/models/preloaders/environments/deployment_preloader.rb43
-rw-r--r--app/models/project.rb40
-rw-r--r--app/models/project_ci_cd_setting.rb6
-rw-r--r--app/models/project_setting.rb10
-rw-r--r--app/models/protectable_dropdown.rb12
-rw-r--r--app/models/ref_matcher.rb4
-rw-r--r--app/models/repository.rb2
-rw-r--r--app/models/route.rb1
-rw-r--r--app/models/user.rb149
-rw-r--r--app/models/users/callout.rb3
-rw-r--r--app/models/work_item.rb6
-rw-r--r--app/models/work_item/type.rb55
-rw-r--r--app/models/work_items/type.rb64
-rw-r--r--app/policies/global_policy.rb2
-rw-r--r--app/policies/group_member_policy.rb5
-rw-r--r--app/policies/group_policy.rb24
-rw-r--r--app/policies/project_policy.rb6
-rw-r--r--app/policies/work_items/type_policy.rb9
-rw-r--r--app/presenters/blob_presenter.rb20
-rw-r--r--app/presenters/ci/runner_presenter.rb4
-rw-r--r--app/presenters/label_presenter.rb6
-rw-r--r--app/presenters/packages/conan/package_presenter.rb8
-rw-r--r--app/presenters/packages/detail/package_presenter.rb12
-rw-r--r--app/presenters/packages/npm/package_presenter.rb6
-rw-r--r--app/presenters/packages/nuget/presenter_helpers.rb9
-rw-r--r--app/presenters/packages/pypi/package_presenter.rb8
-rw-r--r--app/presenters/project_presenter.rb2
-rw-r--r--app/presenters/service_hook_presenter.rb4
-rw-r--r--app/serializers/analytics_build_entity.rb7
-rw-r--r--app/serializers/analytics_issue_entity.rb7
-rw-r--r--app/serializers/environment_serializer.rb12
-rw-r--r--app/serializers/group_child_entity.rb2
-rw-r--r--app/serializers/merge_request_poll_cached_widget_entity.rb5
-rw-r--r--app/serializers/merge_request_poll_widget_entity.rb4
-rw-r--r--app/serializers/merge_request_sidebar_basic_entity.rb4
-rw-r--r--app/services/alert_management/alerts/update_service.rb31
-rw-r--r--app/services/audit_event_service.rb2
-rw-r--r--app/services/auth/container_registry_authentication_service.rb13
-rw-r--r--app/services/auto_merge/base_service.rb6
-rw-r--r--app/services/bulk_imports/archive_extraction_service.rb4
-rw-r--r--app/services/bulk_imports/file_decompression_service.rb27
-rw-r--r--app/services/bulk_imports/file_download_service.rb28
-rw-r--r--app/services/bulk_imports/file_export_service.rb4
-rw-r--r--app/services/bulk_imports/lfs_objects_export_service.rb64
-rw-r--r--app/services/ci/archive_trace_service.rb4
-rw-r--r--app/services/ci/create_pipeline_service.rb11
-rw-r--r--app/services/ci/destroy_pipeline_service.rb12
-rw-r--r--app/services/ci/job_artifacts/delete_project_artifacts_service.rb11
-rw-r--r--app/services/ci/job_artifacts/destroy_all_expired_service.rb31
-rw-r--r--app/services/ci/job_artifacts/expire_project_build_artifacts_service.rb35
-rw-r--r--app/services/ci/pipeline_processing/atomic_processing_service.rb4
-rw-r--r--app/services/ci/pipelines/add_job_service.rb6
-rw-r--r--app/services/ci/play_build_service.rb5
-rw-r--r--app/services/ci/process_build_service.rb19
-rw-r--r--app/services/ci/process_sync_events_service.rb8
-rw-r--r--app/services/ci/register_runner_service.rb36
-rw-r--r--app/services/ci/retry_build_service.rb35
-rw-r--r--app/services/ci/stuck_builds/drop_helpers.rb12
-rw-r--r--app/services/ci/update_build_queue_service.rb14
-rw-r--r--app/services/clusters/agent_tokens/create_service.rb5
-rw-r--r--app/services/clusters/agent_tokens/track_usage_service.rb54
-rw-r--r--app/services/clusters/agents/create_activity_event_service.rb28
-rw-r--r--app/services/clusters/agents/delete_expired_events_service.rb25
-rw-r--r--app/services/concerns/issues/issue_type_helpers.rb2
-rw-r--r--app/services/dependency_proxy/download_blob_service.rb38
-rw-r--r--app/services/dependency_proxy/find_or_create_blob_service.rb48
-rw-r--r--app/services/deployments/archive_in_project_service.rb4
-rw-r--r--app/services/deployments/create_for_build_service.rb25
-rw-r--r--app/services/deployments/update_environment_service.rb2
-rw-r--r--app/services/design_management/copy_design_collection/copy_service.rb2
-rw-r--r--app/services/emails/confirm_service.rb2
-rw-r--r--app/services/error_tracking/collect_error_service.rb21
-rw-r--r--app/services/events/destroy_service.rb15
-rw-r--r--app/services/google_cloud/create_service_accounts_service.rb60
-rw-r--r--app/services/google_cloud/service_accounts_service.rb19
-rw-r--r--app/services/groups/update_service.rb10
-rw-r--r--app/services/import/gitlab_projects/create_project_from_remote_file_service.rb21
-rw-r--r--app/services/import/validate_remote_git_endpoint_service.rb2
-rw-r--r--app/services/incident_management/issuable_escalation_statuses/after_update_service.rb42
-rw-r--r--app/services/incident_management/issuable_escalation_statuses/prepare_update_service.rb99
-rw-r--r--app/services/issuable_base_service.rb14
-rw-r--r--app/services/issues/base_service.rb36
-rw-r--r--app/services/issues/build_service.rb24
-rw-r--r--app/services/issues/create_service.rb5
-rw-r--r--app/services/issues/set_crm_contacts_service.rb2
-rw-r--r--app/services/issues/update_service.rb21
-rw-r--r--app/services/labels/transfer_service.rb31
-rw-r--r--app/services/loose_foreign_keys/process_deleted_records_service.rb1
-rw-r--r--app/services/merge_requests/add_todo_when_build_fails_service.rb4
-rw-r--r--app/services/merge_requests/base_service.rb4
-rw-r--r--app/services/merge_requests/handle_assignees_change_service.rb4
-rw-r--r--app/services/merge_requests/merge_base_service.rb2
-rw-r--r--app/services/merge_requests/remove_approval_service.rb1
-rw-r--r--app/services/merge_requests/squash_service.rb2
-rw-r--r--app/services/packages/maven/metadata/sync_service.rb13
-rw-r--r--app/services/packages/terraform_module/create_package_service.rb2
-rw-r--r--app/services/projects/destroy_service.rb8
-rw-r--r--app/services/projects/fork_service.rb6
-rw-r--r--app/services/projects/overwrite_project_service.rb4
-rw-r--r--app/services/projects/prometheus/alerts/notify_service.rb31
-rw-r--r--app/services/projects/update_pages_configuration_service.rb109
-rw-r--r--app/services/projects/update_remote_mirror_service.rb41
-rw-r--r--app/services/projects/update_service.rb19
-rw-r--r--app/services/resource_access_tokens/create_service.rb5
-rw-r--r--app/services/resource_access_tokens/revoke_service.rb10
-rw-r--r--app/services/search_service.rb4
-rw-r--r--app/services/users/upsert_credit_card_validation_service.rb5
-rw-r--r--app/services/web_hook_service.rb41
-rw-r--r--app/services/work_items/build_service.rb11
-rw-r--r--app/services/work_items/create_service.rb19
-rw-r--r--app/uploaders/ci/secure_file_uploader.rb46
-rw-r--r--app/validators/json_schemas/error_tracking_event_payload.json107
-rw-r--r--app/views/admin/application_settings/_account_and_limit.html.haml5
-rw-r--r--app/views/admin/application_settings/_ci_cd.html.haml6
-rw-r--r--app/views/admin/application_settings/_email.html.haml2
-rw-r--r--app/views/admin/application_settings/_external_authorization_service_form.html.haml23
-rw-r--r--app/views/admin/application_settings/_floc.html.haml2
-rw-r--r--app/views/admin/application_settings/_localization.html.haml4
-rw-r--r--app/views/admin/application_settings/_outbound.html.haml15
-rw-r--r--app/views/admin/application_settings/_prometheus.html.haml2
-rw-r--r--app/views/admin/application_settings/_registry.html.haml4
-rw-r--r--app/views/admin/application_settings/_runner_registrars_form.html.haml2
-rw-r--r--app/views/admin/application_settings/_sourcegraph.html.haml2
-rw-r--r--app/views/admin/application_settings/_spam.html.haml4
-rw-r--r--app/views/admin/application_settings/_third_party_offers.html.haml6
-rw-r--r--app/views/admin/application_settings/appearances/_form.html.haml12
-rw-r--r--app/views/admin/application_settings/appearances/_system_header_footer_form.html.haml2
-rw-r--r--app/views/admin/application_settings/general.html.haml1
-rw-r--r--app/views/admin/application_settings/network.html.haml6
-rw-r--r--app/views/admin/background_migrations/_migration.html.haml2
-rw-r--r--app/views/admin/background_migrations/index.html.haml9
-rw-r--r--app/views/admin/cohorts/_cohorts_table.html.haml2
-rw-r--r--app/views/admin/dashboard/index.html.haml4
-rw-r--r--app/views/admin/deploy_keys/index.html.haml43
-rw-r--r--app/views/admin/groups/_group.html.haml3
-rw-r--r--app/views/admin/labels/_form.html.haml31
-rw-r--r--app/views/admin/labels/edit.html.haml2
-rw-r--r--app/views/admin/labels/new.html.haml2
-rw-r--r--app/views/admin/runners/edit.html.haml99
-rw-r--r--app/views/admin/runners/show.html.haml93
-rw-r--r--app/views/admin/users/_head.html.haml15
-rw-r--r--app/views/admin/users/_users.html.haml10
-rw-r--r--app/views/admin/users/projects.html.haml2
-rw-r--r--app/views/ci/runner/_how_to_setup_runner.html.haml2
-rw-r--r--app/views/clusters/clusters/_advanced_settings.html.haml2
-rw-r--r--app/views/clusters/clusters/_integrations.html.haml2
-rw-r--r--app/views/clusters/clusters/_namespace.html.haml2
-rw-r--r--app/views/clusters/clusters/_provider_details_form.html.haml4
-rw-r--r--app/views/clusters/clusters/gcp/_form.html.haml6
-rw-r--r--app/views/clusters/clusters/show.html.haml2
-rw-r--r--app/views/clusters/clusters/user/_form.html.haml8
-rw-r--r--app/views/dashboard/issues.html.haml2
-rw-r--r--app/views/dashboard/merge_requests.html.haml2
-rw-r--r--app/views/dashboard/todos/index.html.haml61
-rw-r--r--app/views/devise/confirmations/almost_there.haml2
-rw-r--r--app/views/devise/shared/_signup_box.html.haml2
-rw-r--r--app/views/devise/shared/_signup_omniauth_provider_list.haml2
-rw-r--r--app/views/doorkeeper/authorizations/new.html.haml56
-rw-r--r--app/views/graphiql/rails/editors/show.html.erb99
-rw-r--r--app/views/groups/_home_panel.html.haml13
-rw-r--r--app/views/groups/_new_group_fields.html.haml5
-rw-r--r--app/views/groups/edit.html.haml5
-rw-r--r--app/views/groups/issues.html.haml14
-rw-r--r--app/views/groups/merge_requests.html.haml2
-rw-r--r--app/views/groups/new.html.haml2
-rw-r--r--app/views/groups/packages/index.html.haml5
-rw-r--r--app/views/groups/runners/_group_runners.html.haml2
-rw-r--r--app/views/groups/runners/_runner.html.haml17
-rw-r--r--app/views/groups/settings/_ip_restriction_registration_features_cta.html.haml8
-rw-r--r--app/views/groups/settings/_permissions.html.haml12
-rw-r--r--app/views/groups/settings/_project_access_token_creation.html.haml9
-rw-r--r--app/views/groups/settings/_resource_access_token_creation.html.haml11
-rw-r--r--app/views/groups/settings/access_tokens/index.html.haml50
-rw-r--r--app/views/groups/settings/ci_cd/_auto_devops_form.html.haml3
-rw-r--r--app/views/help/index.html.haml15
-rw-r--r--app/views/layouts/_init_auto_complete.html.haml2
-rw-r--r--app/views/layouts/header/_default.html.haml46
-rw-r--r--app/views/layouts/header/_gitlab_version.html.haml11
-rw-r--r--app/views/layouts/header/_help_dropdown.html.haml1
-rw-r--r--app/views/layouts/header/_marketing_links.html.haml34
-rw-r--r--app/views/layouts/header/_sign_in_register_button.html.haml6
-rw-r--r--app/views/notify/_note_email.html.haml6
-rw-r--r--app/views/notify/repository_push_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/chat_names/index.html.haml3
-rw-r--r--app/views/profiles/emails/index.html.haml14
-rw-r--r--app/views/profiles/gpg_keys/index.html.haml2
-rw-r--r--app/views/profiles/keys/_form.html.haml4
-rw-r--r--app/views/profiles/keys/index.html.haml7
-rw-r--r--app/views/profiles/personal_access_tokens/index.html.haml61
-rw-r--r--app/views/profiles/preferences/show.html.haml13
-rw-r--r--app/views/profiles/show.html.haml12
-rw-r--r--app/views/projects/_home_panel.html.haml13
-rw-r--r--app/views/projects/_import_project_pane.html.haml23
-rw-r--r--app/views/projects/_merge_request_merge_checks_settings.html.haml2
-rw-r--r--app/views/projects/_merge_request_merge_commit_template.html.haml11
-rw-r--r--app/views/projects/_merge_request_merge_method_settings.html.haml3
-rw-r--r--app/views/projects/_merge_request_merge_suggestions_settings.html.haml11
-rw-r--r--app/views/projects/_merge_request_squash_commit_template.html.haml11
-rw-r--r--app/views/projects/_merge_request_squash_options_settings.html.haml4
-rw-r--r--app/views/projects/_new_project_fields.html.haml27
-rw-r--r--app/views/projects/branches/_branch.html.haml45
-rw-r--r--app/views/projects/branches/_delete_protected_modal.html.haml42
-rw-r--r--app/views/projects/branches/index.html.haml4
-rw-r--r--app/views/projects/buttons/_fork.html.haml2
-rw-r--r--app/views/projects/ci/pipeline_editor/show.html.haml1
-rw-r--r--app/views/projects/commit/_limit_exceeded_message.html.haml13
-rw-r--r--app/views/projects/commit/branches.html.haml5
-rw-r--r--app/views/projects/default_branch/_show.html.haml2
-rw-r--r--app/views/projects/deployments/_deployment.html.haml3
-rw-r--r--app/views/projects/diffs/_email_line.html.haml21
-rw-r--r--app/views/projects/diffs/_file_header.html.haml2
-rw-r--r--app/views/projects/diffs/_line.html.haml2
-rw-r--r--app/views/projects/diffs/_text_file.html.haml36
-rw-r--r--app/views/projects/edit.html.haml10
-rw-r--r--app/views/projects/forks/index.html.haml2
-rw-r--r--app/views/projects/import/jira/show.html.haml2
-rw-r--r--app/views/projects/issues/_by_email_description.html.haml4
-rw-r--r--app/views/projects/issues/_design_management.html.haml6
-rw-r--r--app/views/projects/issues/_issue.html.haml1
-rw-r--r--app/views/projects/issues/_issues.html.haml29
-rw-r--r--app/views/projects/issues/_service_desk_empty_state.html.haml12
-rw-r--r--app/views/projects/issues/service_desk.html.haml13
-rw-r--r--app/views/projects/jobs/show.html.haml2
-rw-r--r--app/views/projects/mattermosts/_no_teams.html.haml2
-rw-r--r--app/views/projects/mattermosts/_team_selection.html.haml2
-rw-r--r--app/views/projects/merge_requests/_widget.html.haml43
-rw-r--r--app/views/projects/merge_requests/invalid.html.haml11
-rw-r--r--app/views/projects/merge_requests/show.html.haml2
-rw-r--r--app/views/projects/mirrors/_authentication_method.html.haml2
-rw-r--r--app/views/projects/mirrors/_mirror_repos.html.haml2
-rw-r--r--app/views/projects/mirrors/_mirror_repos_form.html.haml2
-rw-r--r--app/views/projects/packages/packages/index.html.haml5
-rw-r--r--app/views/projects/packages/packages/show.html.haml9
-rw-r--r--app/views/projects/pages/_list.html.haml6
-rw-r--r--app/views/projects/pipelines/_info.html.haml34
-rw-r--r--app/views/projects/pipelines/show.html.haml1
-rw-r--r--app/views/projects/prometheus/metrics/edit.html.haml2
-rw-r--r--app/views/projects/prometheus/metrics/new.html.haml2
-rw-r--r--app/views/projects/protected_branches/shared/_branches_list.html.haml2
-rw-r--r--app/views/projects/protected_branches/shared/_protected_branch.html.haml6
-rw-r--r--app/views/projects/protected_tags/shared/_protected_tag.html.haml2
-rw-r--r--app/views/projects/protected_tags/shared/_tags_list.html.haml2
-rw-r--r--app/views/projects/registry/repositories/index.html.haml2
-rw-r--r--app/views/projects/runners/_group_runners.html.haml4
-rw-r--r--app/views/projects/runners/_specific_runners.html.haml2
-rw-r--r--app/views/projects/services/_form.html.haml9
-rw-r--r--app/views/projects/settings/access_tokens/index.html.haml16
-rw-r--r--app/views/projects/settings/ci_cd/_autodevops_form.html.haml8
-rw-r--r--app/views/projects/settings/ci_cd/_form.html.haml18
-rw-r--r--app/views/projects/settings/packages_and_registries/show.html.haml4
-rw-r--r--app/views/projects/starrers/index.html.haml2
-rw-r--r--app/views/projects/tree/_tree_header.html.haml3
-rw-r--r--app/views/projects/triggers/_index.html.haml4
-rw-r--r--app/views/registrations/welcome/show.html.haml6
-rw-r--r--app/views/sandbox/mermaid.html.erb9
-rw-r--r--app/views/shared/_confirm_modal.html.haml21
-rw-r--r--app/views/shared/_integration_settings.html.haml14
-rw-r--r--app/views/shared/_label.html.haml32
-rw-r--r--app/views/shared/_new_project_item_select.html.haml2
-rw-r--r--app/views/shared/_old_visibility_level.html.haml2
-rw-r--r--app/views/shared/_registration_features_discovery_message.html.haml8
-rw-r--r--app/views/shared/_service_settings.html.haml14
-rw-r--r--app/views/shared/_web_ide_button.html.haml2
-rw-r--r--app/views/shared/access_tokens/_form.html.haml8
-rw-r--r--app/views/shared/access_tokens/_table.html.haml12
-rw-r--r--app/views/shared/empty_states/_deploy_keys.html.haml9
-rw-r--r--app/views/shared/empty_states/_issues.html.haml2
-rw-r--r--app/views/shared/empty_states/_merge_requests.html.haml2
-rw-r--r--app/views/shared/empty_states/_wikis.html.haml2
-rw-r--r--app/views/shared/gitpod/_enable_gitpod_modal.html.haml12
-rw-r--r--app/views/shared/hook_logs/_content.html.haml3
-rw-r--r--app/views/shared/hook_logs/_recent_deliveries_table.html.haml3
-rw-r--r--app/views/shared/hook_logs/_status_label.html.haml7
-rw-r--r--app/views/shared/integrations/_form.html.haml4
-rw-r--r--app/views/shared/integrations/edit.html.haml5
-rw-r--r--app/views/shared/integrations/overrides.html.haml3
-rw-r--r--app/views/shared/issuable/_form.html.haml4
-rw-r--r--app/views/shared/issuable/_label_page_create.html.haml5
-rw-r--r--app/views/shared/issuable/_search_bar.html.haml7
-rw-r--r--app/views/shared/issuable/form/_merge_params.html.haml2
-rw-r--r--app/views/shared/labels/_form.html.haml27
-rw-r--r--app/views/shared/members/_badge.html.haml4
-rw-r--r--app/views/shared/members/_blocked_badge.html.haml2
-rw-r--r--app/views/shared/members/_its_you_badge.html.haml2
-rw-r--r--app/views/shared/members/_two_factor_auth_badge.html.haml2
-rw-r--r--app/views/shared/nav/_sidebar_menu.html.haml2
-rw-r--r--app/views/shared/notes/_hints.html.haml4
-rw-r--r--app/views/shared/runners/_shared_runners_description.html.haml2
-rw-r--r--app/views/shared/web_hooks/_form.html.haml32
-rw-r--r--app/views/shared/web_hooks/_hook.html.haml15
-rw-r--r--app/views/shared/web_hooks/_index.html.haml2
-rw-r--r--app/views/sherlock/file_samples/show.html.haml55
-rw-r--r--app/views/sherlock/queries/_backtrace.html.haml31
-rw-r--r--app/views/sherlock/queries/_general.html.haml54
-rw-r--r--app/views/sherlock/queries/show.html.haml26
-rw-r--r--app/views/sherlock/transactions/_file_samples.html.haml24
-rw-r--r--app/views/sherlock/transactions/_general.html.haml38
-rw-r--r--app/views/sherlock/transactions/_queries.html.haml24
-rw-r--r--app/views/sherlock/transactions/index.html.haml41
-rw-r--r--app/views/sherlock/transactions/show.html.haml36
-rw-r--r--app/views/users/show.html.haml6
-rw-r--r--app/workers/all_queues.yml49
-rw-r--r--app/workers/ci/build_finished_worker.rb2
-rw-r--r--app/workers/ci/external_pull_requests/create_pipeline_worker.rb2
-rw-r--r--app/workers/ci/job_artifacts/expire_project_build_artifacts_worker.rb20
-rw-r--r--app/workers/clusters/agents/delete_expired_events_worker.rb21
-rw-r--r--app/workers/concerns/application_worker.rb16
-rw-r--r--app/workers/concerns/cluster_agent_queue.rb10
-rw-r--r--app/workers/concerns/dependency_proxy/cleanup_worker.rb63
-rw-r--r--app/workers/concerns/dependency_proxy/expireable.rb2
-rw-r--r--app/workers/concerns/packages/cleanup_artifact_worker.rb60
-rw-r--r--app/workers/dependency_proxy/cleanup_blob_worker.rb7
-rw-r--r--app/workers/dependency_proxy/cleanup_dependency_proxy_worker.rb4
-rw-r--r--app/workers/dependency_proxy/cleanup_manifest_worker.rb7
-rw-r--r--app/workers/dependency_proxy/image_ttl_group_policy_worker.rb4
-rw-r--r--app/workers/email_receiver_worker.rb33
-rw-r--r--app/workers/expire_build_artifacts_worker.rb4
-rw-r--r--app/workers/loose_foreign_keys/cleanup_worker.rb28
-rw-r--r--app/workers/merge_requests/update_head_pipeline_worker.rb23
-rw-r--r--app/workers/metrics/dashboard/sync_dashboards_worker.rb2
-rw-r--r--app/workers/packages/cleanup_package_file_worker.rb44
-rw-r--r--app/workers/packages/cleanup_package_registry_worker.rb41
-rw-r--r--app/workers/pages_update_configuration_worker.rb16
-rw-r--r--app/workers/pages_worker.rb9
-rw-r--r--app/workers/update_external_pull_requests_worker.rb2
-rw-r--r--app/workers/update_head_pipeline_for_merge_request_worker.rb2
-rw-r--r--app/workers/web_hook_worker.rb12
-rw-r--r--config/application.rb3
-rw-r--r--config/environments/production.rb4
-rw-r--r--config/feature_categories.yml4
-rw-r--r--config/feature_flags/development/admin_deploy_keys_vue.yml8
-rw-r--r--config/feature_flags/development/bulk_expire_project_artifacts.yml8
-rw-r--r--config/feature_flags/development/cached_mr_widget.yml8
-rw-r--r--config/feature_flags/development/chat_notification_deployment_protected_branch_filter.yml8
-rw-r--r--config/feature_flags/development/ci_archived_build_trace_checksum.yml8
-rw-r--r--config/feature_flags/development/ci_artifact_fast_removal_large_loop_limit.yml8
-rw-r--r--config/feature_flags/development/ci_decompose_for_namespace_monthly_usage_query.yml8
-rw-r--r--config/feature_flags/development/ci_destroy_all_expired_service.yml8
-rw-r--r--config/feature_flags/development/ci_find_runners_by_ci_mirrors.yml8
-rw-r--r--config/feature_flags/development/ci_owned_runners_cross_joins_fix.yml8
-rw-r--r--config/feature_flags/development/ci_retry_downstream_pipeline.yml2
-rw-r--r--config/feature_flags/development/ci_skip_legacy_extra_minutes_recalculation.yml8
-rw-r--r--config/feature_flags/development/ci_skip_require_credit_card_for_addon_ci_minutes.yml8
-rw-r--r--config/feature_flags/development/ci_store_trace_outside_transaction.yml8
-rw-r--r--config/feature_flags/development/ci_use_variables_builder_definitions.yml8
-rw-r--r--config/feature_flags/development/container_registry_cdn_redirect.yml8
-rw-r--r--config/feature_flags/development/create_deployment_in_separate_transaction.yml2
-rw-r--r--config/feature_flags/development/create_project_namespace_on_project_create.yml2
-rw-r--r--config/feature_flags/development/custom_preloader_for_deployments.yml8
-rw-r--r--config/feature_flags/development/dast_api_scanner.yml8
-rw-r--r--config/feature_flags/development/dast_view_scans.yml8
-rw-r--r--config/feature_flags/development/datadog_integration_logs_collection.yml8
-rw-r--r--config/feature_flags/development/delete_branch_confirmation_modals.yml8
-rw-r--r--config/feature_flags/development/dependency_proxy_workhorse.yml8
-rw-r--r--config/feature_flags/development/deployments_archive.yml8
-rw-r--r--config/feature_flags/development/expire_job_and_pipeline_cache_synchronously.yml8
-rw-r--r--config/feature_flags/development/find_tag_via_gitaly.yml8
-rw-r--r--config/feature_flags/development/fix_comment_scroll.yml8
-rw-r--r--config/feature_flags/development/github_importer_use_diff_note_with_suggestions.yml2
-rw-r--r--config/feature_flags/development/graphql_ci_runner_executor.yml8
-rw-r--r--config/feature_flags/development/hide_access_tokens.yml8
-rw-r--r--config/feature_flags/development/import_redis_increment_by.yml2
-rw-r--r--config/feature_flags/development/improved_container_scan_matching.yml8
-rw-r--r--config/feature_flags/development/inline_haml_diff_line_rendering.yml8
-rw-r--r--config/feature_flags/development/jira_use_first_ref_by_oid.yml8
-rw-r--r--config/feature_flags/development/lfs_auto_link_fork_source.yml2
-rw-r--r--config/feature_flags/development/lfs_link_existing_object.yml1
-rw-r--r--config/feature_flags/development/linear_group_descendants_finder.yml8
-rw-r--r--config/feature_flags/development/linear_mirrors_worker_roots.yml8
-rw-r--r--config/feature_flags/development/linear_user_group_notification_settings_finder_ancestors_scopes.yml8
-rw-r--r--config/feature_flags/development/log_implicit_sidekiq_status_calls.yml8
-rw-r--r--config/feature_flags/development/log_import_export_relation_creation.yml8
-rw-r--r--config/feature_flags/development/loose_index_scan_for_distinct_values.yml8
-rw-r--r--config/feature_flags/development/migrate_vulnerability_finding_uuids.yml8
-rw-r--r--config/feature_flags/development/multiple_gpg_signatures.yml8
-rw-r--r--config/feature_flags/development/operational_vulnerabilities.yml8
-rw-r--r--config/feature_flags/development/optimize_merge_request_parser.yml8
-rw-r--r--config/feature_flags/development/optimized_issue_neighbor_queries.yml8
-rw-r--r--config/feature_flags/development/packages_installable_package_files.yml8
-rw-r--r--config/feature_flags/development/paginatable_namespace_drop_down_for_project_creation.yml8
-rw-r--r--config/feature_flags/development/permitted_attributes_for_import_export.yml8
-rw-r--r--config/feature_flags/development/rate_limit_gitlab_shell.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/rebase_without_ci_ui.yml8
-rw-r--r--config/feature_flags/development/remote_mirror_fail_on_lfs.yml8
-rw-r--r--config/feature_flags/development/runner_read_only_admin_view.yml8
-rw-r--r--config/feature_flags/development/sandboxed_mermaid.yml8
-rw-r--r--config/feature_flags/development/scim_token_vue.yml8
-rw-r--r--config/feature_flags/development/show_relevant_approval_rule_approvers.yml8
-rw-r--r--config/feature_flags/development/sidekiq_push_bulk_in_batches.yml8
-rw-r--r--config/feature_flags/development/sourcegraph.yml2
-rw-r--r--config/feature_flags/development/swimlanes_buffered_rendering.yml8
-rw-r--r--config/feature_flags/development/track_geo_proxy_events.yml8
-rw-r--r--config/feature_flags/development/trigger_job_retry_action.yml8
-rw-r--r--config/feature_flags/development/unify_security_configuration.yml8
-rw-r--r--config/feature_flags/development/use_cmark_renderer.yml8
-rw-r--r--config/feature_flags/development/use_optimized_group_labels_query.yml8
-rw-r--r--config/feature_flags/development/use_primary_and_secondary_stores_for_sessions.yml8
-rw-r--r--config/feature_flags/development/use_primary_store_as_default_for_sessions.yml8
-rw-r--r--config/feature_flags/development/use_traversal_ids.yml2
-rw-r--r--config/feature_flags/development/use_traversal_ids_for_ancestor_scopes.yml2
-rw-r--r--config/feature_flags/development/use_traversal_ids_for_ancestors.yml2
-rw-r--r--config/feature_flags/development/use_traversal_ids_for_ancestors_upto.yml2
-rw-r--r--config/feature_flags/development/use_traversal_ids_for_root_ancestor.yml2
-rw-r--r--config/feature_flags/development/use_traversal_ids_for_self_and_hierarchy.yml8
-rw-r--r--config/feature_flags/development/use_traversal_ids_groups_finder.yml2
-rw-r--r--config/feature_flags/development/use_typhoeus_elasticsearch_adapter.yml8
-rw-r--r--config/feature_flags/development/verify_participants_access.yml8
-rw-r--r--config/feature_flags/development/vue_epics_list.yml8
-rw-r--r--config/feature_flags/development/vue_integration_form.yml8
-rw-r--r--config/feature_flags/development/vue_issuables_list.yml8
-rw-r--r--config/feature_flags/development/vulnerability_finding_replace_metadata.yml3
-rw-r--r--config/feature_flags/development/vulnerability_location_image_filter.yml8
-rw-r--r--config/feature_flags/development/wiki_switch_between_content_editor_raw_markdown.yml2
-rw-r--r--config/feature_flags/experiment/logged_out_marketing_header.yml8
-rw-r--r--config/feature_flags/experiment/pql_three_cta_test.yml8
-rw-r--r--config/feature_flags/experiment/require_verification_for_group_creation.yml8
-rw-r--r--config/feature_flags/experiment/require_verification_for_namespace_creation.yml8
-rw-r--r--config/feature_flags/ops/ci_unsafe_regexp_logger.yml8
-rw-r--r--config/feature_flags/ops/gitlab_gtm_datalayer.yml8
-rw-r--r--config/feature_flags/ops/prometheus_notify_max_alerts.yml8
-rw-r--r--config/gitlab.yml.example18
-rw-r--r--config/helpers/patched_crypto.js22
-rw-r--r--config/helpers/vendor_dll_hash.js4
-rw-r--r--config/initializers/0_inject_enterprise_edition_module.rb2
-rw-r--r--config/initializers/1_settings.rb14
-rw-r--r--config/initializers/7_prometheus_metrics.rb12
-rw-r--r--config/initializers/active_record_lifecycle.rb2
-rw-r--r--config/initializers/active_record_transaction_observer.rb11
-rw-r--r--config/initializers/database_config.rb2
-rw-r--r--config/initializers/session_store.rb10
-rw-r--r--config/initializers/sherlock.rb7
-rw-r--r--config/initializers/webhook_recursion_detection.rb5
-rw-r--r--config/initializers/wikicloth_disable_lua_patch.rb31
-rw-r--r--config/initializers/wikicloth_redos_patch.rb (renamed from config/initializers/wikicloth_patch.rb)0
-rw-r--r--config/locales/sherlock.en.yml38
-rw-r--r--config/mail_room.yml2
-rw-r--r--config/metrics/counts_28d/20210216175109_suggestions.yml3
-rw-r--r--config/metrics/counts_28d/20210216175550_ci_pipeline_config_repository.yml2
-rw-r--r--config/metrics/counts_28d/20210216183640_gitlab.yml4
-rw-r--r--config/metrics/counts_28d/20210216183712_total.yml2
-rw-r--r--config/metrics/counts_28d/20210216183714_gitlab_project.yml2
-rw-r--r--config/metrics/counts_28d/20210216183716_gitlab.yml2
-rw-r--r--config/metrics/counts_28d/20210216183718_github.yml2
-rw-r--r--config/metrics/counts_28d/20210216183720_bitbucket.yml2
-rw-r--r--config/metrics/counts_28d/20210216183722_bitbucket_server.yml2
-rw-r--r--config/metrics/counts_28d/20210216183724_gitea.yml2
-rw-r--r--config/metrics/counts_28d/20210216183726_git.yml2
-rw-r--r--config/metrics/counts_28d/20210216183728_manifest.yml2
-rw-r--r--config/metrics/counts_28d/20210216183730_jira.yml2
-rw-r--r--config/metrics/counts_28d/20210216183731_fogbugz.yml2
-rw-r--r--config/metrics/counts_28d/20210216183733_phabricator.yml2
-rw-r--r--config/metrics/counts_28d/20210216183735_csv.yml2
-rw-r--r--config/metrics/counts_28d/20210216183737_groups_imported.yml2
-rw-r--r--config/metrics/counts_28d/20210216184814_i_package_container_deploy_token_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210216184818_i_package_debian_deploy_token_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210216184826_i_package_golang_deploy_token_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210216184846_i_package_tag_deploy_token_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210216184902_i_package_container_user_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210216184906_i_package_debian_user_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210216184913_i_package_golang_user_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210216184933_i_package_tag_user_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20211216083832_users_clicking_license_testing_visiting_external_website_monthly.yml25
-rw-r--r--config/metrics/counts_7d/20210216184805_i_package_composer_deploy_token_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210216184812_i_package_container_deploy_token_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210216184816_i_package_debian_deploy_token_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210216184824_i_package_golang_deploy_token_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210216184844_i_package_tag_deploy_token_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210216184900_i_package_container_user_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210216184904_i_package_debian_user_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210216184911_i_package_golang_user_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210216184931_i_package_tag_user_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20211216084934_users_clicking_license_testing_visiting_external_website_weekly.yml25
-rw-r--r--config/metrics/counts_all/20210216175053_suggestions.yml3
-rw-r--r--config/metrics/counts_all/20210216175518_ci_pipeline_config_repository.yml2
-rw-r--r--config/metrics/counts_all/20210216175533_ci_pipeline_config_repository.yml2
-rw-r--r--config/metrics/counts_all/20210216180634_gitlab.yml2
-rw-r--r--config/metrics/counts_all/20210216180705_total.yml2
-rw-r--r--config/metrics/counts_all/20210216180707_gitlab_project.yml2
-rw-r--r--config/metrics/counts_all/20210216180709_gitlab.yml2
-rw-r--r--config/metrics/counts_all/20210216180711_github.yml2
-rw-r--r--config/metrics/counts_all/20210216180713_bitbucket.yml2
-rw-r--r--config/metrics/counts_all/20210216180715_bitbucket_server.yml2
-rw-r--r--config/metrics/counts_all/20210216180716_gitea.yml2
-rw-r--r--config/metrics/counts_all/20210216180718_git.yml2
-rw-r--r--config/metrics/counts_all/20210216180720_manifest.yml2
-rw-r--r--config/metrics/counts_all/20210216180722_jira.yml2
-rw-r--r--config/metrics/counts_all/20210216180724_fogbugz.yml2
-rw-r--r--config/metrics/counts_all/20210216180726_phabricator.yml2
-rw-r--r--config/metrics/counts_all/20210216180727_csv.yml2
-rw-r--r--config/metrics/counts_all/20210216180729_groups_imported.yml2
-rw-r--r--config/metrics/counts_all/20210216183017_package_events_i_package_tag_delete_package.yml2
-rw-r--r--config/metrics/counts_all/20210216183019_package_events_i_package_tag_pull_package.yml2
-rw-r--r--config/metrics/counts_all/20210216183021_package_events_i_package_tag_push_package.yml2
-rw-r--r--config/metrics/schema.json2
-rw-r--r--config/metrics/settings/20211201012652_flavor.yml24
-rw-r--r--config/object_store_settings.rb2
-rw-r--r--config/routes.rb7
-rw-r--r--config/routes/admin.rb2
-rw-r--r--config/routes/group.rb8
-rw-r--r--config/routes/project.rb5
-rw-r--r--config/routes/sherlock.rb14
-rw-r--r--config/sidekiq_queues.yml10
-rw-r--r--config/webpack.config.js5
-rw-r--r--danger/datateam/Dangerfile18
-rw-r--r--danger/plugins/datateam.rb9
-rw-r--r--data/deprecations/ runner-s3-authenticationtype-nonexplicit-config-deprecation.yml13
-rw-r--r--data/deprecations/14-0-nfs-fot-git-repository-storage.yml3
-rw-r--r--data/deprecations/14-2-deprecation-release-cli.yml14
-rw-r--r--data/deprecations/14-2-deprecation-task-runner.yml1
-rw-r--r--data/deprecations/14-3-database-deprecate-legacy-database-conf.yml11
-rw-r--r--data/deprecations/14-3-deprecation-release-cli.yml13
-rw-r--r--data/deprecations/14-3-deprecation_omniauth-kerberos_gem.yml17
-rw-r--r--data/deprecations/14-3-package-container-registry-api-group-update.yml13
-rw-r--r--data/deprecations/14-3-repository-push-audit-events.yml3
-rw-r--r--data/deprecations/14-3-serverless.yml14
-rw-r--r--data/deprecations/14-5-certificate-based-integration-with-kubernetes.yml1
-rw-r--r--data/deprecations/14-5-deprecate-convert-instance-runner-to-project.yml2
-rw-r--r--data/deprecations/14-5-deprecate-defaultMergeCommitMessageWithDescription-graphql.yml15
-rw-r--r--data/deprecations/14-5-deprecate-opensuse-15-2.yml1
-rw-r--r--data/deprecations/14-5-deprecate-sles-12sp2.yml8
-rw-r--r--data/deprecations/14-5-deprecation-versions-packagetype.yml13
-rw-r--r--data/deprecations/14-5-deprecation-vsa-announce-deprecation-of-vsa-filtering-calculation.yml3
-rw-r--r--data/deprecations/14-5-disable_strict_host_key_checking.yml14
-rw-r--r--data/deprecations/14-5-geo-deprecate-promote-db.yml15
-rw-r--r--data/deprecations/14-5-geo-deprecate-promote-to-primary-node.yml15
-rw-r--r--data/deprecations/14-5-package-container-registry-api-group-update.yml14
-rw-r--r--data/deprecations/14-5-remove-dependency-proxy-permissions-flag.yml13
-rw-r--r--data/deprecations/14-5-remove-package-pipelines-api.yml13
-rw-r--r--data/deprecations/14-5-remove-pipelines-from-version-field.yml16
-rw-r--r--data/deprecations/14-5-runner-api-status-does-contain-paused.yml3
-rw-r--r--data/deprecations/14-5-runner-s3-authenticationtype-nonexplicit-config-deprecation.yml14
-rw-r--r--data/deprecations/14-6-Enforce-validation-of-security-schemas.yml26
-rw-r--r--data/deprecations/14-6-container-scanning-schemas-below-14.yml23
-rw-r--r--data/deprecations/14-6-coverage-fuzzing-schemas-below-14.yml26
-rw-r--r--data/deprecations/14-6-dast-schemas-below-14.yml26
-rw-r--r--data/deprecations/14-6-dependency-scanning-schemas-below-14.yml26
-rw-r--r--data/deprecations/14-6-deprecate-types.yml3
-rw-r--r--data/deprecations/14-6-deprecation-license-compliance-api-terms.yml7
-rw-r--r--data/deprecations/14-6-deprecation-secure-dependency-scanning-bundler-audit.yml5
-rw-r--r--data/deprecations/14-6-job_char_limit.yml15
-rw-r--r--data/deprecations/14-6-pipeline-fields-package-deprecation.yml1
-rw-r--r--data/deprecations/14-6-remove-api-fuzzing-ci-configuration-create-mutation.yml3
-rw-r--r--data/deprecations/14-6-runner-api-status-renames-not_connected.yml1
-rw-r--r--data/deprecations/14-6-runner_api_new_stale_status_breaking_change.yml14
-rw-r--r--data/deprecations/14-6-sast-schemas-below-14.yml26
-rw-r--r--data/deprecations/14-6-secret-detection-schemas-below-14.yml26
-rw-r--r--data/deprecations/14-7-deprecate-artifacts-keyword.yml16
-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.yml27
-rw-r--r--data/deprecations/14-7-deprecate-static-site-editor.yml14
-rw-r--r--data/deprecations/14-7-pseudonymizer.yml12
-rw-r--r--data/deprecations/14-7-sidekiq-metrics-health-check-donfig.yml30
-rw-r--r--data/deprecations/14-8-remove-support-for-fixup-in-commit-message-triggering-draft-status.yml15
-rw-r--r--data/deprecations/15-0-deprecate-monitor-logging.yml16
-rw-r--r--data/deprecations/15-0-deprecate-monitor-metrics.yml17
-rw-r--r--data/deprecations/15-0-deprecate-monitor-tracing.yml16
-rw-r--r--data/deprecations/15-0-deprecate-sles-12sp2.yml7
-rw-r--r--data/deprecations/15-0-deprecation-versions-packagetype.yml13
-rw-r--r--data/deprecations/15-0-remove-dependency-proxy-permissions-flag.yml12
-rw-r--r--data/deprecations/15-0-remove-package-pipelines-api.yml12
-rw-r--r--data/deprecations/15-0-remove-pipelines-from-version-field.yml15
-rw-r--r--data/deprecations/deprecate-defaultMergeCommitMessageWithDescription-graphql.yml14
-rw-r--r--data/deprecations/deprecation_omniauth-kerberos_gem.yml16
-rw-r--r--data/deprecations/disable_strict_host_key_checking.yml13
-rw-r--r--data/deprecations/job_char_limit.yml26
-rw-r--r--data/deprecations/runner_api_new_stale_status_breaking_change.yml13
-rw-r--r--data/deprecations/serverless.yml14
-rw-r--r--data/deprecations/templates/_deprecation_template.md.erb16
-rw-r--r--data/deprecations/templates/example.yml3
-rw-r--r--data/removals/14_0/14_0-ds-deprecations.yml10
-rw-r--r--data/removals/14_0/14_0-lc-deprecations.yml6
-rw-r--r--data/removals/14_0/change_default_branch_name_to_main.yml10
-rw-r--r--data/removals/14_0/create-code-review-draft-wip.yml6
-rw-r--r--data/removals/14_0/create-code-review-w-parameter-removal.yml6
-rw-r--r--data/removals/14_0/deprecate_ci_project_config_path_variable.yml6
-rw-r--r--data/removals/14_0/deprecation_bump_terraform_template_version.yml18
-rw-r--r--data/removals/14_0/deprecation_manage_access_14_0.yml17
-rw-r--r--data/removals/14_0/deprecation_update_cicd_templates_to_stop_using_hardcode_master.yml6
-rw-r--r--data/removals/14_0/deuley_servicetemplates_removal.yml8
-rw-r--r--data/removals/14_0/release_announce_deprecation_of_release_notes_api.yml7
-rw-r--r--data/removals/14_0/release_deprecation_auto-deploy-image.yml9
-rw-r--r--data/removals/14_0/release_domainsource_configuration_for_gitlab_pages_deprecation.yml7
-rw-r--r--data/removals/14_0/release_legacy_feature_flags_deprecation.yml7
-rw-r--r--data/removals/14_0/release_remove_redundant_keyvalue_pair_from_the_payload_of_dora.yml7
-rw-r--r--data/removals/14_0/removal-geo-fdw-settings.yml11
-rw-r--r--data/removals/14_0/removal-graphql-fields.yml13
-rw-r--r--data/removals/14_0/removal-legacy-storage.yml6
-rw-r--r--data/removals/14_0/removal-protect-features.yml13
-rw-r--r--data/removals/14_0/removal-sidekiq_experimental_queue_selector.yml10
-rw-r--r--data/removals/14_0/removal-unicorn.yml6
-rw-r--r--data/removals/14_0/removal_ci_project_config_path.yml11
-rw-r--r--data/removals/14_0/removal_enablement_helm2.yml8
-rw-r--r--data/removals/14_0/removal_enablement_opensuse_15_1.yml6
-rw-r--r--data/removals/14_0/removal_enablement_pg11.yml10
-rw-r--r--data/removals/14_0/removal_enablement_ubuntu_16.yml11
-rw-r--r--data/removals/14_0/removal_repost_static_analysis_notices.yml39
-rw-r--r--data/removals/14_0/removal_runner_25555.yml7
-rw-r--r--data/removals/14_0/removal_runner_26036.yml6
-rw-r--r--data/removals/14_0/removal_runner_26419.yml6
-rw-r--r--data/removals/14_0/removal_runner_4845.yml6
-rw-r--r--data/removals/14_0/removal_runner_6413.yml6
-rw-r--r--data/removals/14_0/removals-14-testing-team.yml26
-rw-r--r--data/removals/14_0/removals_runner_26651.yml6
-rw-r--r--data/removals/14_0/removals_runner_26679.yml6
-rw-r--r--data/removals/14_0/removals_runner_26900.yml6
-rw-r--r--data/removals/14_0/removals_runner_27175.yml6
-rw-r--r--data/removals/14_0/removals_runner_27218.yml6
-rw-r--r--data/removals/14_0/removals_runner_27551.yml6
-rw-r--r--data/removals/14_0/removals_runner_27899.yml6
-rw-r--r--data/removals/14_0/remove-sql-elector.yml9
-rw-r--r--data/removals/14_0/remove_dast_env_variables.yml15
-rw-r--r--data/removals/14_0/remove_dast_legacy_domain_validation.yml8
-rw-r--r--data/removals/14_0/remove_dast_legacy_report_fields.yml8
-rw-r--r--data/removals/14_0/remove_dast_spider_host_reset.yml6
-rw-r--r--data/removals/14_0/remove_dast_template_stages.yml6
-rw-r--r--data/removals/14_0/remove_optimize_api.yml6
-rw-r--r--data/removals/14_0/remove_terraform_template.yml9
-rw-r--r--data/removals/14_0/verify-ci-removal-parametertrace.yml8
-rw-r--r--data/removals/14_0/verify-ci-removalpipelineservice.yml6
-rw-r--r--data/removals/14_1/removal-memory-prometheus-options-source.yml8
-rw-r--r--data/removals/14_1/removal-outdated-browser-support.yml20
-rw-r--r--data/removals/14_2/removal-verify-build-log.yml7
-rw-r--r--data/removals/14_3/removal-limit-tags-to-50.yml6
-rw-r--r--data/removals/14_3/removal-verify-pe-pipelinefindername.yml6
-rw-r--r--data/removals/14_3/removal_legacy_storage_setting.yml8
-rw-r--r--data/removals/templates/_removal_template.md.erb46
-rw-r--r--data/removals/templates/example.yml32
-rw-r--r--data/whats_new/202010230001_13_05.yml2
-rw-r--r--data/whats_new/2021102000001_14_04.yml2
-rw-r--r--data/whats_new/2021111800001_14_05.yml2
-rw-r--r--db/fixtures/development/18_abuse_reports.rb2
-rw-r--r--db/fixtures/development/31_terraform_state.rb26
-rw-r--r--db/init_structure.sql1078
-rw-r--r--db/migrate/20201211145950_add_bloat_estimate_to_reindex_action.rb9
-rw-r--r--db/migrate/20201214000000_change_mr_allow_maintainer_to_push_default.rb19
-rw-r--r--db/migrate/20201214032220_add_has_external_wiki_trigger.rb52
-rw-r--r--db/migrate/20201214084105_add_expiration_policy_completed_at_to_container_repositories.rb12
-rw-r--r--db/migrate/20201214111858_add_container_registry_cleanup_tags_service_max_list_size_to_application_settings.rb11
-rw-r--r--db/migrate/20201214112752_add_app_settings_container_reg_cleanup_tags_service_max_list_size_constraint.rb19
-rw-r--r--db/migrate/20201214113729_add_custom_mapping_columns_to_http_integrations.rb10
-rw-r--r--db/migrate/20201214184020_add_epic_board_list.rb33
-rw-r--r--db/migrate/20201215084652_delete_mock_deployment_service_records.rb15
-rw-r--r--db/migrate/20201215132151_change_unique_index_on_security_findings.rb36
-rw-r--r--db/migrate/20201215205404_create_namespace_package_settings.rb25
-rw-r--r--db/migrate/20201216151616_add_squash_commit_sha_index.rb22
-rw-r--r--db/migrate/20201216154457_add_devops_adoption_snapshot_range_end.rb11
-rw-r--r--db/migrate/20201217070530_add_group_merge_request_approval_settings.rb24
-rw-r--r--db/migrate/20201217111448_change_pages_deployment_size_to_bigint.rb17
-rw-r--r--db/migrate/20201217132603_create_elastic_reindexing_subtasks.rb56
-rw-r--r--db/migrate/20201218194311_create_admin_notes.rb21
-rw-r--r--db/migrate/20201221124036_add_devops_snapshot_index.rb19
-rw-r--r--db/migrate/20201221213415_change_clusters_helm_major_version_default_to_3.rb9
-rw-r--r--db/migrate/20201221225303_add_service_desk_reply_to_is_not_null_index_on_issues.rb11
-rw-r--r--db/migrate/20201222151823_update_trusted_apps_to_confidential.rb23
-rw-r--r--db/migrate/20201223114050_add_restrict_user_defined_variables_to_project_settings.rb19
-rw-r--r--db/migrate/20201224144948_migrate_coverage_report_worker.rb15
-rw-r--r--db/migrate/20201228110136_create_iterations_cadence.rb29
-rw-r--r--db/migrate/20201228110238_add_iterations_cadence_to_sprints.rb22
-rw-r--r--db/migrate/20201228184500_add_dismissal_reason_into_vulnerability_feedback_table.rb13
-rw-r--r--db/migrate/20201229105948_add_invisible_captcha_enabled_to_settings.rb9
-rw-r--r--db/migrate/20201230161206_add_rate_limiting_response_text_to_application_settings.rb12
-rw-r--r--db/migrate/20201230180202_create_onboarding_progress.rb36
-rw-r--r--db/migrate/20210101110640_set_limit_for_rate_limiting_response_text.rb16
-rw-r--r--db/migrate/20210102164121_drop_temporary_index_on_ci_builds.rb19
-rw-r--r--db/migrate/20210104163218_add_epic_board_position_index.rb18
-rw-r--r--db/migrate/20210105052034_rename_asset_proxy_whitelist_on_application_settings.rb21
-rw-r--r--db/migrate/20210105153342_add_entity_columns_to_vulnerability_occurrences.rb16
-rw-r--r--db/migrate/20210105154321_add_text_limit_to_vulnerability_occurrences_entity_columns.rb23
-rw-r--r--db/migrate/20210106061254_add_unique_index_for_golang_packages.rb20
-rw-r--r--db/migrate/20210106153021_drop_tmp_index_on_emails.rb20
-rw-r--r--db/migrate/20210106155209_add_merge_request_diff_commit_trailers.rb22
-rw-r--r--db/migrate/20210106191305_rename_indexes_on_git_lab_com.rb57
-rw-r--r--db/migrate/20210106225424_add_keep_latest_artifacts_to_application_settings.rb11
-rw-r--r--db/migrate/20210107105306_add_diff_type_to_merge_request_diffs.rb31
-rw-r--r--db/migrate/20210107154615_add_merge_request_context_commit_trailers.rb12
-rw-r--r--db/migrate/20210108161039_update_max_import_size_default.rb9
-rw-r--r--db/migrate/20210111051045_create_dast_profiles.rb35
-rw-r--r--db/migrate/20210111053308_add_project_fk_for_dast_profile.rb19
-rw-r--r--db/migrate/20210111075104_add_temporary_index_on_security_findings_scan_id.rb18
-rw-r--r--db/migrate/20210112084512_drop_tmp_index_on_emails_again.rb18
-rw-r--r--db/migrate/20210112202949_create_composer_cache_file.rb34
-rw-r--r--db/migrate/20210113224909_add_pipeline_configuration_full_path_to_compliance_pipeline.rb16
-rw-r--r--db/migrate/20210113231532_add_converted_at_to_experiment_subjects.rb9
-rw-r--r--db/migrate/20210113231546_add_context_to_experiment_subjects.rb9
-rw-r--r--db/migrate/20210114033715_remove_group_id_title_index.rb20
-rw-r--r--db/migrate/20210114142443_add_indexes_to_onboarding_progresses.rb27
-rw-r--r--db/migrate/20210115090452_create_group_repository_storage_move.rb34
-rw-r--r--db/migrate/20210117210226_add_has_external_issue_tracker_trigger.rb61
-rw-r--r--db/migrate/20210118111307_add_enforce_ssh_key_expiration_to_application_settings.rb9
-rw-r--r--db/migrate/20210119153801_add_proxy_settings_to_jira_tracker_data.rb16
-rw-r--r--db/migrate/20210119162812_add_text_limit_to_compliance_pipeline_configuration_full_path.rb17
-rw-r--r--db/migrate/20210120180956_extend_index_on_ci_builds_metadata.rb40
-rw-r--r--db/migrate/20210120221743_delete_oauth_applications_tmp_index.rb18
-rw-r--r--db/migrate/20210121093618_remove_repository_read_only_to_groups.rb23
-rw-r--r--db/migrate/20210121100038_add_devops_adoption_group_segment.rb18
-rw-r--r--db/migrate/20210121121102_optional_devops_adoption_segment_name.rb24
-rw-r--r--db/migrate/20210122073805_add_repository_read_only_to_namespace_settings.rb19
-rw-r--r--db/migrate/20210122153259_add_state_to_merge_request_reviewers.rb11
-rw-r--r--db/migrate/20210122155158_add_pipeline_step_to_bulk_imports_failures.rb25
-rw-r--r--db/migrate/20210125105410_add_devops_adoption_segment_namespace_fk.rb17
-rw-r--r--db/migrate/20210126030249_add_security_dashboard_access_level_into_project_features.rb20
-rw-r--r--db/migrate/20210126091713_add_unique_index_services_project_id_and_type.rb19
-rw-r--r--db/migrate/20210126092102_remove_index_services_project_id_and_type.rb20
-rw-r--r--db/migrate/20210126233608_add_rubygems_max_file_size_to_plan_limits.rb9
-rw-r--r--db/migrate/20210127052226_add_subgroup_events_to_web_hooks.rb9
-rw-r--r--db/migrate/20210127143025_add_oldest_merge_requests_index.rb13
-rw-r--r--db/migrate/20210127152613_add_iterations_cadence_date_range_constraint.rb30
-rw-r--r--db/migrate/20210127202613_remove_iteration_group_date_range_constraint.rb30
-rw-r--r--db/migrate/20210128044930_add_git_two_factor_session_expiry_to_application_settings.rb9
-rw-r--r--db/migrate/20210128101707_add_prevent_merge_without_jira_issue_to_project_settings.rb18
-rw-r--r--db/migrate/20210128114526_add_auto_delete_at_to_environments.rb19
-rw-r--r--db/migrate/20210128140157_add_content_type_to_dependency_proxy_manifests.rb12
-rw-r--r--db/migrate/20210128140232_add_text_limit_to_dependency_proxy_manifests_content_type.rb16
-rw-r--r--db/migrate/20210128152830_create_ci_namespace_monthly_usage.rb30
-rw-r--r--db/migrate/20210128172149_create_background_migration_tracking_tables.rb59
-rw-r--r--db/migrate/20210129225244_add_index_to_oncall_shfts_on_starts_at_and_ends_at.rb24
-rw-r--r--db/migrate/20210201034649_add_active_periods_to_on_call_rotations.rb10
-rw-r--r--db/migrate/20210201140434_add_oldest_merge_requests_index_again.rb59
-rw-r--r--db/migrate/20210203002331_drop_backup_label_index.rb19
-rw-r--r--db/migrate/20210203092540_remove_has_external_wiki_constraint.rb20
-rw-r--r--db/migrate/20210203092549_restore_has_external_wiki_default_value.rb31
-rw-r--r--db/migrate/20210203221631_create_packages_rubygems_metadata.rb69
-rw-r--r--db/migrate/20210203222620_add_expired_index_to_composer_cache_files.rb19
-rw-r--r--db/migrate/20210203223551_add_orphan_index_to_composer_cache_files.rb19
-rw-r--r--db/migrate/20210204152257_add_status_to_packages_packages.rb9
-rw-r--r--db/migrate/20210204212850_add_group_id_to_ci_daily_build_group_report_results.rb9
-rw-r--r--db/migrate/20210205084357_create_ci_project_monthly_usage.rb29
-rw-r--r--db/migrate/20210205134213_add_creator_id_to_custom_emoji.rb23
-rw-r--r--db/migrate/20210205143926_remove_namespace_id_foreign_key_on_namespace_onboarding_actions.rb19
-rw-r--r--db/migrate/20210205213915_remove_foreign_keys_from_alerts_service_data.rb19
-rw-r--r--db/migrate/20210208103243_add_issue_created_at_to_onboarding_progress.rb9
-rw-r--r--db/migrate/20210208125050_add_status_expires_at_to_user_statuses.rb19
-rw-r--r--db/migrate/20210208125248_add_index_on_user_statuses_status_expires_at.rb18
-rw-r--r--db/migrate/20210208144134_add_index_group_id_to_ci_daily_build_group_report_results.rb20
-rw-r--r--db/migrate/20210208161207_add_notes_create_limit_to_application_settings.rb9
-rw-r--r--db/migrate/20210208200914_add_ends_at_to_oncall_rotations.rb9
-rw-r--r--db/migrate/20210209110019_create_external_approval_rules.rb44
-rw-r--r--db/migrate/20210209160510_create_security_orchestration_policy_configurations.rb25
-rw-r--r--db/migrate/20210209171525_add_status_index_to_packages_packages.rb19
-rw-r--r--db/migrate/20210209232508_add_markdown_surround_selection_to_user_preferences.rb21
-rw-r--r--db/migrate/20210210210232_add_notes_create_limit_allowlist_to_application_settings.rb9
-rw-r--r--db/migrate/20210211195543_add_created_by_user_for_cluster_agent_token.rb28
-rw-r--r--db/migrate/20210212153934_make_the_geo_oauth_application_trusted_by_default.rb20
-rw-r--r--db/migrate/20210212163231_add_merge_when_pipeline_succeeds_to_notification_settings.rb12
-rw-r--r--db/migrate/20210214201118_add_delayed_project_removal_to_namespace_settings.rb9
-rw-r--r--db/migrate/20210214205155_add_index_to_namespaces_delayed_project_removal.rb18
-rw-r--r--db/migrate/20210215172449_remove_artifact_expiry_temp_index.rb18
-rw-r--r--db/migrate/20210216122140_add_in_product_marketing_emails_enabled_setting.rb9
-rw-r--r--db/migrate/20210216135504_add_created_by_to_cluster_agent.rb27
-rw-r--r--db/migrate/20210216193620_add_description_to_cluster_token.rb21
-rw-r--r--db/migrate/20210216223335_remove_index_on_issues_where_service_desk_reply_to_is_not_null.rb21
-rw-r--r--db/migrate/20210217101901_create_epic_list_user_preferences.rb20
-rw-r--r--db/migrate/20210218040814_add_environment_scope_to_group_variables.rb45
-rw-r--r--db/migrate/20210218142626_change_finding_fingerprint_enum.rb15
-rw-r--r--db/migrate/20210218144056_add_sprints_start_date_not_null_check_constraint.rb17
-rw-r--r--db/migrate/20210218144656_add_sprints_due_date_not_null_check_constraint.rb17
-rw-r--r--db/migrate/20210219100137_add_creator_foreign_key_to_custom_emoji.rb23
-rw-r--r--db/migrate/20210219111040_add_epic_issue_composite_index.rb18
-rw-r--r--db/migrate/20210219211845_add_version_usage_data_id_to_raw_usage_data.rb9
-rw-r--r--db/migrate/20210222030537_add_is_removed_to_oncall_participant.rb19
-rw-r--r--db/migrate/20210222042745_add_is_removed_index_to_oncall_participant.rb21
-rw-r--r--db/migrate/20210222070356_add_storage_size_to_namespace_statistics.rb19
-rw-r--r--db/migrate/20210222070413_add_wiki_size_to_namespace_statistics.rb19
-rw-r--r--db/migrate/20210222085529_add_epic_board_user_preference_user_fk.rb19
-rw-r--r--db/migrate/20210222085551_add_epic_board_user_preference_epic_list_fk.rb19
-rw-r--r--db/migrate/20210222105120_add_container_registry_access_level.rb25
-rw-r--r--db/migrate/20210223053451_add_branch_name_to_dast_profile.rb23
-rw-r--r--db/migrate/20210223132934_add_foreign_key_to_external_approval_rules.rb18
-rw-r--r--db/migrate/20210223133116_add_foreign_key_to_external_approval_rules_protected_branches.rb18
-rw-r--r--db/migrate/20210223230600_update_rubygems_metadata_metadata.rb19
-rw-r--r--db/migrate/20210224132547_add_null_constraint_to_terraform_state_name.rb11
-rw-r--r--db/migrate/20210224133337_add_name_field_to_cluster_agent_token.rb12
-rw-r--r--db/migrate/20210224161552_add_jira_issue_transition_automatic_to_jira_tracker_data.rb9
-rw-r--r--db/migrate/20210225090801_create_dora_daily_metrics.rb31
-rw-r--r--db/migrate/20210225135533_limit_cluster_token_size.rb17
-rw-r--r--db/migrate/20210225153522_add_allow_force_push_to_protected_branches.rb19
-rw-r--r--db/migrate/20210301150451_add_tier_to_environments.rb19
-rw-r--r--db/migrate/20210301193412_add_optional_to_ci_build_needs.rb19
-rw-r--r--db/migrate/20210301200601_rename_asset_proxy_allowlist_on_application_settings.rb29
-rw-r--r--db/migrate/20210301200959_init_schema.rb (renamed from db/migrate/20181228175414_init_schema.rb)0
-rw-r--r--db/migrate/20210811193033_add_unique_index_to_vulnerability_finding_links.rb18
-rw-r--r--db/migrate/20211026124336_add_archive_trace_events_to_integrations.rb7
-rw-r--r--db/migrate/20211209230042_add_status_to_cluster_agent_tokens.rb7
-rw-r--r--db/migrate/20211210025754_alter_constraint_of_phone.rb17
-rw-r--r--db/migrate/20211210031721_change_user_details_phone_text_limit.rb15
-rw-r--r--db/migrate/20211213142344_add_settings_user_email_lookup_limit.rb13
-rw-r--r--db/migrate/20211213154259_add_status_to_packages_package_files.rb7
-rw-r--r--db/migrate/20211213154704_add_status_index_to_packages_package_files.rb15
-rw-r--r--db/migrate/20211215182006_update_application_settings_protected_paths.rb58
-rw-r--r--db/migrate/20211216133107_add_cluster_agent_id_to_vulnerability_reads.rb10
-rw-r--r--db/migrate/20211216134134_add_text_limit_to_vulnerability_reads_cluster_agent_id.rb13
-rw-r--r--db/migrate/20211216135651_add_index_to_cluster_agent_id.rb16
-rw-r--r--db/migrate/20211216220939_add_group_crm_settings.rb13
-rw-r--r--db/migrate/20211217050753_remove_artifacts_archive_id_foreign_key_from_project_pages_metadata.rb19
-rw-r--r--db/migrate/20211220174504_add_secure_scanning_actions_to_onboarding_progresses.rb15
-rw-r--r--db/migrate/20211223125921_add_temp_index_to_members_state.rb16
-rw-r--r--db/migrate/20211224112937_add_packages_cleanup_package_file_worker_capacity_to_application_settings.rb13
-rw-r--r--db/migrate/20211224114539_add_packages_cleanup_package_file_worker_capacity_check_constraint_to_app_settings.rb15
-rw-r--r--db/migrate/20220104174445_add_ci_runners_index_on_active_state.rb15
-rw-r--r--db/migrate/20220105121325_add_route_namespace_reference.rb13
-rw-r--r--db/migrate/20220106141756_remove_lock_version_indexes.rb23
-rw-r--r--db/migrate/20220106230629_add_registry_migration_application_settings.rb15
-rw-r--r--db/migrate/20220106230712_add_migration_columns_to_container_repositories.rb19
-rw-r--r--db/migrate/20220107091629_add_route_namespace_index.rb19
-rw-r--r--db/migrate/20220107165036_remove_note_id_index.rb16
-rw-r--r--db/migrate/20220109133006_remove_ci_pipelines_lock_version_index.rb17
-rw-r--r--db/migrate/20220110170953_create_ci_secure_files.rb19
-rw-r--r--db/migrate/20220111095006_add_maintainer_note_to_ci_runners.rb12
-rw-r--r--db/migrate/20220111095007_add_text_limit_to_ci_runners_maintainer_note.rb13
-rw-r--r--db/migrate/20220111200254_remove_index_from_merge_requests.rb15
-rw-r--r--db/migrate/20220112115413_add_requires_verification_to_user_details.rb9
-rw-r--r--db/migrate/20220112205111_create_security_training_providers.rb14
-rw-r--r--db/migrate/20220112232037_add_member_namespace_reference.rb13
-rw-r--r--db/migrate/20220112232605_add_member_namespace_index.rb19
-rw-r--r--db/migrate/20220113125401_create_security_trainings.rb18
-rw-r--r--db/migrate/20220114131950_add_status_only_index_to_packages_package_files.rb15
-rw-r--r--db/migrate/20220117225936_add_text_limits_to_container_repositories_migration_columns.rb15
-rw-r--r--db/migrate/20220118141950_add_text_limit_to_container_registry_import_target_plan.rb13
-rw-r--r--db/migrate/20220118155846_add_runner_token_expiration_interval_settings_to_application_settings.rb9
-rw-r--r--db/migrate/20220118155847_add_runner_token_expiration_interval_settings_to_namespace_settings.rb11
-rw-r--r--db/migrate/20220118155848_add_runner_token_expiration_interval_settings_to_project_settings.rb9
-rw-r--r--db/post_migrate/20201211090634_schedule_populate_finding_uuid_for_vulnerability_feedback.rb25
-rw-r--r--db/post_migrate/20201216185336_add_devops_adoption_snapshot_not_null.rb31
-rw-r--r--db/post_migrate/20201217112249_change_pages_deployment_size_to_bigint_cleanup.rb17
-rw-r--r--db/post_migrate/20201223012231_reindex_ci_pipelines_on_schedule_id_and_id.rb21
-rw-r--r--db/post_migrate/20201231133921_schedule_set_default_iteration_cadences.rb26
-rw-r--r--db/post_migrate/20210105030125_cleanup_projects_with_bad_has_external_wiki_data.rb88
-rw-r--r--db/post_migrate/20210105052229_clean_up_asset_proxy_whitelist_rename_on_application_settings.rb19
-rw-r--r--db/post_migrate/20210105103649_delete_column_group_id_on_compliance_framework.rb9
-rw-r--r--db/post_migrate/20210107194543_remove_alerts_service_records.rb19
-rw-r--r--db/post_migrate/20210111075105_schedule_uuid_population_for_security_findings.rb20
-rw-r--r--db/post_migrate/20210111075206_schedule_uuid_population_for_security_findings2.rb34
-rw-r--r--db/post_migrate/20210112143418_remove_duplicate_services2.rb29
-rw-r--r--db/post_migrate/20210115215854_cancel_artifact_expiry_backfill.rb22
-rw-r--r--db/post_migrate/20210115220610_schedule_artifact_expiry_backfill.rb48
-rw-r--r--db/post_migrate/20210119122354_alter_vsa_issue_first_mentioned_in_commit_value.rb34
-rw-r--r--db/post_migrate/20210203143131_migrate_existing_devops_segments_to_groups.rb15
-rw-r--r--db/post_migrate/20210205104425_add_new_post_eoa_plans.rb14
-rw-r--r--db/post_migrate/20210205144537_remove_namespace_onboarding_actions_table.rb23
-rw-r--r--db/post_migrate/20210205174154_remove_bad_dependency_proxy_manifests.rb15
-rw-r--r--db/post_migrate/20210205213933_drop_alerts_service_data.rb26
-rw-r--r--db/post_migrate/20210205214003_remove_alerts_service_records_again.rb19
-rw-r--r--db/post_migrate/20210210093901_backfill_updated_at_after_repository_storage_move.rb34
-rw-r--r--db/post_migrate/20210210221006_cleanup_projects_with_bad_has_external_issue_tracker_data.rb84
-rw-r--r--db/post_migrate/20210215095328_migrate_delayed_project_removal_from_namespaces_to_namespace_settings.rb28
-rw-r--r--db/post_migrate/20210215144909_migrate_usage_trends_sidekiq_queue.rb19
-rw-r--r--db/post_migrate/20210217100728_move_create_release_evidence_queue_out_of_cronjob_namespace.rb16
-rw-r--r--db/post_migrate/20210218105431_remove_deprecated_ci_builds_columns.rb36
-rw-r--r--db/post_migrate/20210218110552_remove_deprecated_ci_runner_column.rb22
-rw-r--r--db/post_migrate/20210219102900_reschedule_set_default_iteration_cadences.rb30
-rw-r--r--db/post_migrate/20210222185538_remove_backup_labels_foreign_keys.rb21
-rw-r--r--db/post_migrate/20210222192144_remove_backup_labels_table.rb36
-rw-r--r--db/post_migrate/20210224150506_reschedule_artifact_expiry_backfill.rb44
-rw-r--r--db/post_migrate/20210226120851_move_container_registry_enabled_to_project_features.rb28
-rw-r--r--db/post_migrate/20210226141517_dedup_issue_metrics.rb71
-rw-r--r--db/post_migrate/20210301200959_clean_up_asset_proxy_allowlist_rename_on_application_settings.rb21
-rw-r--r--db/post_migrate/20210426225417_schedule_recalculate_uuid_on_vulnerabilities_occurrences2.rb29
-rw-r--r--db/post_migrate/20210813195518_schedule_recalculate_uuid_on_vulnerabilities_occurrences3.rb22
-rw-r--r--db/post_migrate/20210918202855_reschedule_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid.rb10
-rw-r--r--db/post_migrate/20211123161906_cleanup_after_drop_invalid_security_findings.rb26
-rw-r--r--db/post_migrate/20211206161271_add_indexes_for_primary_email_cleanup_migration.rb28
-rw-r--r--db/post_migrate/20211206162601_cleanup_after_add_primary_email_to_emails_if_user_confirmed.rb59
-rw-r--r--db/post_migrate/20211207081708_add_index_ci_job_artifacts_project_id_file_type.rb15
-rw-r--r--db/post_migrate/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid.rb16
-rw-r--r--db/post_migrate/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4.rb28
-rw-r--r--db/post_migrate/20211207173510_remove_extra_finding_evidence_tables_foreign_keys.rb57
-rw-r--r--db/post_migrate/20211207173511_remove_extra_finding_evidence_tables.rb71
-rw-r--r--db/post_migrate/20211208122200_schedule_backfill_ci_namespace_mirrors.rb23
-rw-r--r--db/post_migrate/20211208122201_schedule_backfill_ci_project_mirrors.rb23
-rw-r--r--db/post_migrate/20211209203820_add_tmp_index_on_report_type.rb16
-rw-r--r--db/post_migrate/20211209203821_convert_stringified_raw_metadata_hash_to_json.rb25
-rw-r--r--db/post_migrate/20211210140000_add_temporary_static_object_token_index.rb15
-rw-r--r--db/post_migrate/20211210140629_encrypt_static_object_token.rb22
-rw-r--r--db/post_migrate/20211214012507_backfill_incident_issue_escalation_statuses.rb26
-rw-r--r--db/post_migrate/20211217120000_modify_kubernetes_resource_location_index_to_vulnerability_occurrences.rb41
-rw-r--r--db/post_migrate/20211217145923_add_index_to_events_on_author_id_and_action_and_id.rb14
-rw-r--r--db/post_migrate/20211217174331_mark_recalculate_finding_signatures_as_completed.rb20
-rw-r--r--db/post_migrate/20211220064757_drop_temporary_indexes_for_primary_email_migration.rb28
-rw-r--r--db/post_migrate/20211220120402_add_index_on_ci_pipelines_user_id_id_failure_reason.rb15
-rw-r--r--db/post_migrate/20211220123956_update_invalid_member_states.rb21
-rw-r--r--db/post_migrate/20211229023654_add_async_index_ci_job_artifacts_project_id_file_type.rb15
-rw-r--r--db/post_migrate/20211230112517_remove_index_events_on_author_id_and_action_and_id.rb17
-rw-r--r--db/post_migrate/20211230113031_add_index_to_events_on_author_id_and_id.rb15
-rw-r--r--db/post_migrate/20220104060049_remove_foreign_key_ci_group_variables_group_id.rb17
-rw-r--r--db/post_migrate/20220105020514_remove_ci_minutes_additional_packs_namespace_id_foreign_key_constraint.rb17
-rw-r--r--db/post_migrate/20220106231518_remove_foreign_key_ci_daily_build_group_report_results_group_id.rb17
-rw-r--r--db/post_migrate/20220106233459_remove_foreign_key_ci_pending_builds_namespace_id.rb17
-rw-r--r--db/post_migrate/20220106235626_remove_foreign_key_ci_runner_namespaces_namespace_id.rb17
-rw-r--r--db/post_migrate/20220109134455_add_idx_vulnerability_occurrences_dedup_again.rb17
-rw-r--r--db/post_migrate/20220110171049_schedule_populate_test_reports_issue_id.rb23
-rw-r--r--db/post_migrate/20220110224913_remove_dast_scanner_profiles_builds_ci_build_id_fk.rb18
-rw-r--r--db/post_migrate/20220110231420_remove_requirements_management_test_reports_build_id_fk.rb18
-rw-r--r--db/post_migrate/20220110233155_remove_dast_site_profiles_builds_ci_build_id_fk.rb18
-rw-r--r--db/post_migrate/20220111002756_remove_security_scans_build_id_fk.rb18
-rw-r--r--db/post_migrate/20220111023852_index_cluster_agent_tokens_on_status.rb15
-rw-r--r--db/post_migrate/20220111102314_truncate_ci_mirror_tables.rb14
-rw-r--r--db/post_migrate/20220111221516_remove_projects_ci_pending_builds_fk.rb15
-rw-r--r--db/post_migrate/20220112015940_remove_projects_ci_running_builds_fk.rb17
-rw-r--r--db/post_migrate/20220112090556_remove_cascade_delete_from_project_namespace_foreign_key.rb23
-rw-r--r--db/post_migrate/20220112230642_remove_projects_ci_unit_tests_project_id_fk.rb15
-rw-r--r--db/post_migrate/20220112232723_remove_projects_ci_daily_build_group_report_results_project_id_fk.rb16
-rw-r--r--db/post_migrate/20220113013319_remove_projects_ci_freeze_periods_project_id_fk.rb15
-rw-r--r--db/post_migrate/20220113014438_remove_projects_ci_resource_groups_project_id_fk.rb15
-rw-r--r--db/post_migrate/20220113015830_remove_projects_ci_build_report_results_project_id_fk.rb15
-rw-r--r--db/post_migrate/20220113035519_remove_users_ci_job_token_project_scope_links_added_by_id_fk.rb15
-rw-r--r--db/post_migrate/20220113040447_remove_users_ci_pipeline_schedules_owner_id_fk.rb15
-rw-r--r--db/post_migrate/20220114105525_add_index_on_projects_path.rb17
-rw-r--r--db/post_migrate/20220116175851_add_author_index_to_design_management_versions.rb16
-rw-r--r--db/post_migrate/20220119141736_remove_projects_ci_pipeline_artifacts_project_id_fk.rb17
-rw-r--r--db/schema_migrations/201812281754141
-rw-r--r--db/schema_migrations/202012110906341
-rw-r--r--db/schema_migrations/202012111459501
-rw-r--r--db/schema_migrations/202012140000001
-rw-r--r--db/schema_migrations/202012140322201
-rw-r--r--db/schema_migrations/202012140841051
-rw-r--r--db/schema_migrations/202012141118581
-rw-r--r--db/schema_migrations/202012141127521
-rw-r--r--db/schema_migrations/202012141137291
-rw-r--r--db/schema_migrations/202012141840201
-rw-r--r--db/schema_migrations/202012150846521
-rw-r--r--db/schema_migrations/202012151321511
-rw-r--r--db/schema_migrations/202012152054041
-rw-r--r--db/schema_migrations/202012161516161
-rw-r--r--db/schema_migrations/202012161544571
-rw-r--r--db/schema_migrations/202012161853361
-rw-r--r--db/schema_migrations/202012170705301
-rw-r--r--db/schema_migrations/202012171114481
-rw-r--r--db/schema_migrations/202012171122491
-rw-r--r--db/schema_migrations/202012171326031
-rw-r--r--db/schema_migrations/202012181943111
-rw-r--r--db/schema_migrations/202012211240361
-rw-r--r--db/schema_migrations/202012212134151
-rw-r--r--db/schema_migrations/202012212253031
-rw-r--r--db/schema_migrations/202012221518231
-rw-r--r--db/schema_migrations/202012230122311
-rw-r--r--db/schema_migrations/202012231140501
-rw-r--r--db/schema_migrations/202012241449481
-rw-r--r--db/schema_migrations/202012281101361
-rw-r--r--db/schema_migrations/202012281102381
-rw-r--r--db/schema_migrations/202012281845001
-rw-r--r--db/schema_migrations/202012291059481
-rw-r--r--db/schema_migrations/202012301612061
-rw-r--r--db/schema_migrations/202012301802021
-rw-r--r--db/schema_migrations/202012311339211
-rw-r--r--db/schema_migrations/202101011106401
-rw-r--r--db/schema_migrations/202101021641211
-rw-r--r--db/schema_migrations/202101041632181
-rw-r--r--db/schema_migrations/202101050301251
-rw-r--r--db/schema_migrations/202101050520341
-rw-r--r--db/schema_migrations/202101050522291
-rw-r--r--db/schema_migrations/202101051036491
-rw-r--r--db/schema_migrations/202101051533421
-rw-r--r--db/schema_migrations/202101051543211
-rw-r--r--db/schema_migrations/202101060612541
-rw-r--r--db/schema_migrations/202101061530211
-rw-r--r--db/schema_migrations/202101061552091
-rw-r--r--db/schema_migrations/202101061913051
-rw-r--r--db/schema_migrations/202101062254241
-rw-r--r--db/schema_migrations/202101071053061
-rw-r--r--db/schema_migrations/202101071546151
-rw-r--r--db/schema_migrations/202101071945431
-rw-r--r--db/schema_migrations/202101081610391
-rw-r--r--db/schema_migrations/202101110510451
-rw-r--r--db/schema_migrations/202101110533081
-rw-r--r--db/schema_migrations/202101110751041
-rw-r--r--db/schema_migrations/202101110751051
-rw-r--r--db/schema_migrations/202101110752061
-rw-r--r--db/schema_migrations/202101120845121
-rw-r--r--db/schema_migrations/202101121434181
-rw-r--r--db/schema_migrations/202101122029491
-rw-r--r--db/schema_migrations/202101132249091
-rw-r--r--db/schema_migrations/202101132315321
-rw-r--r--db/schema_migrations/202101132315461
-rw-r--r--db/schema_migrations/202101140337151
-rw-r--r--db/schema_migrations/202101141424431
-rw-r--r--db/schema_migrations/202101150904521
-rw-r--r--db/schema_migrations/202101152158541
-rw-r--r--db/schema_migrations/202101152206101
-rw-r--r--db/schema_migrations/202101172102261
-rw-r--r--db/schema_migrations/202101181113071
-rw-r--r--db/schema_migrations/202101191223541
-rw-r--r--db/schema_migrations/202101191538011
-rw-r--r--db/schema_migrations/202101191628121
-rw-r--r--db/schema_migrations/202101201809561
-rw-r--r--db/schema_migrations/202101202217431
-rw-r--r--db/schema_migrations/202101210936181
-rw-r--r--db/schema_migrations/202101211000381
-rw-r--r--db/schema_migrations/202101211211021
-rw-r--r--db/schema_migrations/202101220738051
-rw-r--r--db/schema_migrations/202101221532591
-rw-r--r--db/schema_migrations/202101221551581
-rw-r--r--db/schema_migrations/202101251054101
-rw-r--r--db/schema_migrations/202101260302491
-rw-r--r--db/schema_migrations/202101260917131
-rw-r--r--db/schema_migrations/202101260921021
-rw-r--r--db/schema_migrations/202101262336081
-rw-r--r--db/schema_migrations/202101270522261
-rw-r--r--db/schema_migrations/202101271430251
-rw-r--r--db/schema_migrations/202101271526131
-rw-r--r--db/schema_migrations/202101272026131
-rw-r--r--db/schema_migrations/202101280449301
-rw-r--r--db/schema_migrations/202101281017071
-rw-r--r--db/schema_migrations/202101281145261
-rw-r--r--db/schema_migrations/202101281401571
-rw-r--r--db/schema_migrations/202101281402321
-rw-r--r--db/schema_migrations/202101281528301
-rw-r--r--db/schema_migrations/202101281721491
-rw-r--r--db/schema_migrations/202101292252441
-rw-r--r--db/schema_migrations/202102010346491
-rw-r--r--db/schema_migrations/202102011404341
-rw-r--r--db/schema_migrations/202102030023311
-rw-r--r--db/schema_migrations/202102030925401
-rw-r--r--db/schema_migrations/202102030925491
-rw-r--r--db/schema_migrations/202102031431311
-rw-r--r--db/schema_migrations/202102032216311
-rw-r--r--db/schema_migrations/202102032226201
-rw-r--r--db/schema_migrations/202102032235511
-rw-r--r--db/schema_migrations/202102041522571
-rw-r--r--db/schema_migrations/202102042128501
-rw-r--r--db/schema_migrations/202102050843571
-rw-r--r--db/schema_migrations/202102051044251
-rw-r--r--db/schema_migrations/202102051342131
-rw-r--r--db/schema_migrations/202102051439261
-rw-r--r--db/schema_migrations/202102051445371
-rw-r--r--db/schema_migrations/202102051741541
-rw-r--r--db/schema_migrations/202102052139151
-rw-r--r--db/schema_migrations/202102052139331
-rw-r--r--db/schema_migrations/202102052140031
-rw-r--r--db/schema_migrations/202102081032431
-rw-r--r--db/schema_migrations/202102081250501
-rw-r--r--db/schema_migrations/202102081252481
-rw-r--r--db/schema_migrations/202102081441341
-rw-r--r--db/schema_migrations/202102081612071
-rw-r--r--db/schema_migrations/202102082009141
-rw-r--r--db/schema_migrations/202102091100191
-rw-r--r--db/schema_migrations/202102091605101
-rw-r--r--db/schema_migrations/202102091715251
-rw-r--r--db/schema_migrations/202102092325081
-rw-r--r--db/schema_migrations/202102100939011
-rw-r--r--db/schema_migrations/202102102102321
-rw-r--r--db/schema_migrations/202102102210061
-rw-r--r--db/schema_migrations/202102111955431
-rw-r--r--db/schema_migrations/202102121539341
-rw-r--r--db/schema_migrations/202102121632311
-rw-r--r--db/schema_migrations/202102142011181
-rw-r--r--db/schema_migrations/202102142051551
-rw-r--r--db/schema_migrations/202102150953281
-rw-r--r--db/schema_migrations/202102151449091
-rw-r--r--db/schema_migrations/202102151724491
-rw-r--r--db/schema_migrations/202102161221401
-rw-r--r--db/schema_migrations/202102161355041
-rw-r--r--db/schema_migrations/202102161936201
-rw-r--r--db/schema_migrations/202102162233351
-rw-r--r--db/schema_migrations/202102171007281
-rw-r--r--db/schema_migrations/202102171019011
-rw-r--r--db/schema_migrations/202102180408141
-rw-r--r--db/schema_migrations/202102181054311
-rw-r--r--db/schema_migrations/202102181105521
-rw-r--r--db/schema_migrations/202102181426261
-rw-r--r--db/schema_migrations/202102181440561
-rw-r--r--db/schema_migrations/202102181446561
-rw-r--r--db/schema_migrations/202102191001371
-rw-r--r--db/schema_migrations/202102191029001
-rw-r--r--db/schema_migrations/202102191110401
-rw-r--r--db/schema_migrations/202102192118451
-rw-r--r--db/schema_migrations/202102220305371
-rw-r--r--db/schema_migrations/202102220427451
-rw-r--r--db/schema_migrations/202102220703561
-rw-r--r--db/schema_migrations/202102220704131
-rw-r--r--db/schema_migrations/202102220855291
-rw-r--r--db/schema_migrations/202102220855511
-rw-r--r--db/schema_migrations/202102221051201
-rw-r--r--db/schema_migrations/202102221855381
-rw-r--r--db/schema_migrations/202102221921441
-rw-r--r--db/schema_migrations/202102230534511
-rw-r--r--db/schema_migrations/202102231329341
-rw-r--r--db/schema_migrations/202102231331161
-rw-r--r--db/schema_migrations/202102232306001
-rw-r--r--db/schema_migrations/202102241325471
-rw-r--r--db/schema_migrations/202102241333371
-rw-r--r--db/schema_migrations/202102241505061
-rw-r--r--db/schema_migrations/202102241615521
-rw-r--r--db/schema_migrations/202102250908011
-rw-r--r--db/schema_migrations/202102251355331
-rw-r--r--db/schema_migrations/202102251535221
-rw-r--r--db/schema_migrations/202102261208511
-rw-r--r--db/schema_migrations/202102261415171
-rw-r--r--db/schema_migrations/202103011504511
-rw-r--r--db/schema_migrations/202103011934121
-rw-r--r--db/schema_migrations/202103012006011
-rw-r--r--db/schema_migrations/202108111930331
-rw-r--r--db/schema_migrations/202110261243361
-rw-r--r--db/schema_migrations/202111231619061
-rw-r--r--db/schema_migrations/202112061612711
-rw-r--r--db/schema_migrations/202112061626011
-rw-r--r--db/schema_migrations/202112070817081
-rw-r--r--db/schema_migrations/202112071253311
-rw-r--r--db/schema_migrations/202112071353311
-rw-r--r--db/schema_migrations/202112071735101
-rw-r--r--db/schema_migrations/202112071735111
-rw-r--r--db/schema_migrations/202112081222001
-rw-r--r--db/schema_migrations/202112081222011
-rw-r--r--db/schema_migrations/202112092038201
-rw-r--r--db/schema_migrations/202112092038211
-rw-r--r--db/schema_migrations/202112092300421
-rw-r--r--db/schema_migrations/202112100257541
-rw-r--r--db/schema_migrations/202112100317211
-rw-r--r--db/schema_migrations/202112101400001
-rw-r--r--db/schema_migrations/202112101406291
-rw-r--r--db/schema_migrations/202112131423441
-rw-r--r--db/schema_migrations/202112131542591
-rw-r--r--db/schema_migrations/202112131547041
-rw-r--r--db/schema_migrations/202112140125071
-rw-r--r--db/schema_migrations/202112151820061
-rw-r--r--db/schema_migrations/202112161331071
-rw-r--r--db/schema_migrations/202112161341341
-rw-r--r--db/schema_migrations/202112161356511
-rw-r--r--db/schema_migrations/202112162209391
-rw-r--r--db/schema_migrations/202112170507531
-rw-r--r--db/schema_migrations/202112171200001
-rw-r--r--db/schema_migrations/202112171459231
-rw-r--r--db/schema_migrations/202112171743311
-rw-r--r--db/schema_migrations/202112200647571
-rw-r--r--db/schema_migrations/202112201204021
-rw-r--r--db/schema_migrations/202112201239561
-rw-r--r--db/schema_migrations/202112201745041
-rw-r--r--db/schema_migrations/202112231259211
-rw-r--r--db/schema_migrations/202112241129371
-rw-r--r--db/schema_migrations/202112241145391
-rw-r--r--db/schema_migrations/202112290236541
-rw-r--r--db/schema_migrations/202112301125171
-rw-r--r--db/schema_migrations/202112301130311
-rw-r--r--db/schema_migrations/202201040600491
-rw-r--r--db/schema_migrations/202201041744451
-rw-r--r--db/schema_migrations/202201050205141
-rw-r--r--db/schema_migrations/202201051213251
-rw-r--r--db/schema_migrations/202201061417561
-rw-r--r--db/schema_migrations/202201062306291
-rw-r--r--db/schema_migrations/202201062307121
-rw-r--r--db/schema_migrations/202201062315181
-rw-r--r--db/schema_migrations/202201062334591
-rw-r--r--db/schema_migrations/202201062356261
-rw-r--r--db/schema_migrations/202201070916291
-rw-r--r--db/schema_migrations/202201071650361
-rw-r--r--db/schema_migrations/202201091330061
-rw-r--r--db/schema_migrations/202201091344551
-rw-r--r--db/schema_migrations/202201101709531
-rw-r--r--db/schema_migrations/202201101710491
-rw-r--r--db/schema_migrations/202201102249131
-rw-r--r--db/schema_migrations/202201102314201
-rw-r--r--db/schema_migrations/202201102331551
-rw-r--r--db/schema_migrations/202201110027561
-rw-r--r--db/schema_migrations/202201110238521
-rw-r--r--db/schema_migrations/202201110950061
-rw-r--r--db/schema_migrations/202201110950071
-rw-r--r--db/schema_migrations/202201111023141
-rw-r--r--db/schema_migrations/202201112002541
-rw-r--r--db/schema_migrations/202201112215161
-rw-r--r--db/schema_migrations/202201120159401
-rw-r--r--db/schema_migrations/202201120905561
-rw-r--r--db/schema_migrations/202201121154131
-rw-r--r--db/schema_migrations/202201122051111
-rw-r--r--db/schema_migrations/202201122306421
-rw-r--r--db/schema_migrations/202201122320371
-rw-r--r--db/schema_migrations/202201122326051
-rw-r--r--db/schema_migrations/202201122327231
-rw-r--r--db/schema_migrations/202201130133191
-rw-r--r--db/schema_migrations/202201130144381
-rw-r--r--db/schema_migrations/202201130158301
-rw-r--r--db/schema_migrations/202201130355191
-rw-r--r--db/schema_migrations/202201130404471
-rw-r--r--db/schema_migrations/202201131254011
-rw-r--r--db/schema_migrations/202201141055251
-rw-r--r--db/schema_migrations/202201141319501
-rw-r--r--db/schema_migrations/202201161758511
-rw-r--r--db/schema_migrations/202201172259361
-rw-r--r--db/schema_migrations/202201181419501
-rw-r--r--db/schema_migrations/202201181558461
-rw-r--r--db/schema_migrations/202201181558471
-rw-r--r--db/schema_migrations/202201181558481
-rw-r--r--db/schema_migrations/202201191417361
-rw-r--r--db/structure.sql492
-rw-r--r--doc/.vale/gitlab/ReadingLevel.yml12
-rw-r--r--doc/.vale/gitlab/SubstitutionWarning.yml1
-rw-r--r--doc/.vale/gitlab/Uppercase.yml2
-rw-r--r--doc/.vale/gitlab/spelling-exceptions.txt4
-rw-r--r--doc/.vale/vale.tmpl2
-rw-r--r--doc/administration/audit_event_streaming.md6
-rw-r--r--doc/administration/auth/atlassian.md2
-rw-r--r--doc/administration/auth/authentiq.md2
-rw-r--r--doc/administration/auth/cognito.md2
-rw-r--r--doc/administration/auth/crowd.md2
-rw-r--r--doc/administration/auth/index.md2
-rw-r--r--doc/administration/auth/jwt.md2
-rw-r--r--doc/administration/auth/ldap/google_secure_ldap.md2
-rw-r--r--doc/administration/auth/ldap/index.md17
-rw-r--r--doc/administration/auth/ldap/ldap-troubleshooting.md2
-rw-r--r--doc/administration/auth/ldap/ldap_synchronization.md2
-rw-r--r--doc/administration/auth/oidc.md2
-rw-r--r--doc/administration/auth/smartcard.md2
-rw-r--r--doc/administration/clusters/kas.md2
-rw-r--r--doc/administration/compliance.md129
-rw-r--r--doc/administration/configure.md2
-rw-r--r--doc/administration/docs_self_host.md131
-rw-r--r--doc/administration/geo/disaster_recovery/background_verification.md3
-rw-r--r--doc/administration/geo/disaster_recovery/index.md25
-rw-r--r--doc/administration/geo/index.md6
-rw-r--r--doc/administration/geo/replication/configuration.md15
-rw-r--r--doc/administration/geo/replication/datatypes.md8
-rw-r--r--doc/administration/geo/replication/faq.md3
-rw-r--r--doc/administration/geo/replication/geo_validation_tests.md3
-rw-r--r--doc/administration/geo/replication/troubleshooting.md357
-rw-r--r--doc/administration/geo/replication/usage.md4
-rw-r--r--doc/administration/geo/replication/version_specific_updates.md8
-rw-r--r--doc/administration/geo/setup/external_database.md3
-rw-r--r--doc/administration/get_started.md2
-rw-r--r--doc/administration/git_protocol.md13
-rw-r--r--doc/administration/gitaly/configure_gitaly.md69
-rw-r--r--doc/administration/gitaly/index.md22
-rw-r--r--doc/administration/gitaly/praefect.md42
-rw-r--r--doc/administration/img/instance_review_button.pngbin24525 -> 0 bytes
-rw-r--r--doc/administration/img/instance_review_v14_7.pngbin0 -> 6594 bytes
-rw-r--r--doc/administration/incoming_email.md38
-rw-r--r--doc/administration/index.md4
-rw-r--r--doc/administration/instance_limits.md17
-rw-r--r--doc/administration/instance_review.md30
-rw-r--r--doc/administration/job_artifacts.md3
-rw-r--r--doc/administration/job_logs.md4
-rw-r--r--doc/administration/logs.md88
-rw-r--r--doc/administration/maintenance_mode/index.md3
-rw-r--r--doc/administration/merge_request_diffs.md12
-rw-r--r--doc/administration/monitoring/github_imports.md2
-rw-r--r--doc/administration/monitoring/ip_whitelist.md2
-rw-r--r--doc/administration/monitoring/prometheus/gitlab_metrics.md10
-rw-r--r--doc/administration/monitoring/prometheus/index.md8
-rw-r--r--doc/administration/monitoring/prometheus/pgbouncer_exporter.md2
-rw-r--r--doc/administration/monitoring/prometheus/registry_exporter.md2
-rw-r--r--doc/administration/nfs.md2
-rw-r--r--doc/administration/object_storage.md30
-rw-r--r--doc/administration/operations/cleaning_up_redis_sessions.md9
-rw-r--r--doc/administration/operations/fast_ssh_key_lookup.md14
-rw-r--r--doc/administration/operations/moving_repositories.md50
-rw-r--r--doc/administration/operations/rails_console.md2
-rw-r--r--doc/administration/package_information/defaults.md77
-rw-r--r--doc/administration/package_information/deprecation_policy.md2
-rw-r--r--doc/administration/package_information/index.md2
-rw-r--r--doc/administration/package_information/postgresql_versions.md2
-rw-r--r--doc/administration/package_information/supported_os.md1
-rw-r--r--doc/administration/packages/container_registry.md11
-rw-r--r--doc/administration/packages/dependency_proxy.md82
-rw-r--r--doc/administration/pages/index.md93
-rw-r--r--doc/administration/pages/source.md43
-rw-r--r--doc/administration/pseudonymizer.md7
-rw-r--r--doc/administration/raketasks/check.md85
-rw-r--r--doc/administration/raketasks/doctor.md89
-rw-r--r--doc/administration/raketasks/geo.md1
-rw-r--r--doc/administration/raketasks/ldap.md2
-rw-r--r--doc/administration/raketasks/maintenance.md5
-rw-r--r--doc/administration/redis/replication_and_failover.md6
-rw-r--r--doc/administration/reference_architectures/10k_users.md21
-rw-r--r--doc/administration/reference_architectures/25k_users.md21
-rw-r--r--doc/administration/reference_architectures/2k_users.md21
-rw-r--r--doc/administration/reference_architectures/3k_users.md21
-rw-r--r--doc/administration/reference_architectures/50k_users.md21
-rw-r--r--doc/administration/reference_architectures/5k_users.md21
-rw-r--r--doc/administration/reference_architectures/index.md29
-rw-r--r--doc/administration/sidekiq.md40
-rw-r--r--doc/administration/sidekiq_health_check.md60
-rw-r--r--doc/administration/terraform_state.md5
-rw-r--r--doc/administration/troubleshooting/defcon.md2
-rw-r--r--doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md33
-rw-r--r--doc/administration/troubleshooting/group_saml_scim.md2
-rw-r--r--doc/administration/troubleshooting/img/okta_setting_username.pngbin69815 -> 17785 bytes
-rw-r--r--doc/administration/troubleshooting/kubernetes_cheat_sheet.md32
-rw-r--r--doc/administration/troubleshooting/postgresql.md40
-rw-r--r--doc/administration/troubleshooting/sidekiq.md2
-rw-r--r--doc/administration/troubleshooting/ssl.md2
-rw-r--r--doc/administration/user_settings.md2
-rw-r--r--doc/api/access_requests.md2
-rw-r--r--doc/api/api_resources.md6
-rw-r--r--doc/api/appearance.md2
-rw-r--r--doc/api/applications.md2
-rw-r--r--doc/api/avatar.md2
-rw-r--r--doc/api/commits.md7
-rw-r--r--doc/api/container_registry.md5
-rw-r--r--doc/api/dependencies.md2
-rw-r--r--doc/api/deployments.md35
-rw-r--r--doc/api/epics.md24
-rw-r--r--doc/api/geo_nodes.md12
-rw-r--r--doc/api/graphql/getting_started.md5
-rw-r--r--doc/api/graphql/index.md3
-rw-r--r--doc/api/graphql/reference/index.md512
-rw-r--r--doc/api/group_access_tokens.md112
-rw-r--r--doc/api/group_badges.md2
-rw-r--r--doc/api/group_iterations.md1
-rw-r--r--doc/api/group_protected_environments.md26
-rw-r--r--doc/api/groups.md12
-rw-r--r--doc/api/index.md13
-rw-r--r--doc/api/integrations.md16
-rw-r--r--doc/api/issues.md70
-rw-r--r--doc/api/issues_statistics.md1
-rw-r--r--doc/api/job_artifacts.md32
-rw-r--r--doc/api/markdown.md5
-rw-r--r--doc/api/members.md17
-rw-r--r--doc/api/merge_requests.md159
-rw-r--r--doc/api/namespaces.md2
-rw-r--r--doc/api/oauth2.md16
-rw-r--r--doc/api/packages.md10
-rw-r--r--doc/api/packages/maven.md8
-rw-r--r--doc/api/packages/npm.md6
-rw-r--r--doc/api/packages/pypi.md2
-rw-r--r--doc/api/pipelines.md2
-rw-r--r--doc/api/plan_limits.md2
-rw-r--r--doc/api/project_access_tokens.md112
-rw-r--r--doc/api/project_badges.md5
-rw-r--r--doc/api/project_import_export.md7
-rw-r--r--doc/api/project_snippets.md5
-rw-r--r--doc/api/project_templates.md7
-rw-r--r--doc/api/projects.md12
-rw-r--r--doc/api/protected_branches.md18
-rw-r--r--doc/api/protected_environments.md18
-rw-r--r--doc/api/protected_tags.md5
-rw-r--r--doc/api/releases/index.md6
-rw-r--r--doc/api/releases/links.md4
-rw-r--r--doc/api/repository_submodules.md5
-rw-r--r--doc/api/resource_access_tokens.md113
-rw-r--r--doc/api/runners.md23
-rw-r--r--doc/api/scim.md2
-rw-r--r--doc/api/search.md6
-rw-r--r--doc/api/settings.md4
-rw-r--r--doc/api/snippets.md7
-rw-r--r--doc/api/statistics.md2
-rw-r--r--doc/api/tags.md8
-rw-r--r--doc/api/users.md10
-rw-r--r--doc/api/vulnerabilities.md184
-rw-r--r--doc/api/vulnerability_findings.md133
-rw-r--r--doc/api/wikis.md5
-rw-r--r--doc/architecture/blueprints/ci_data_decay/index.md255
-rw-r--r--doc/architecture/blueprints/ci_data_decay/pipeline_data_time_decay.pngbin0 -> 13687 bytes
-rw-r--r--doc/architecture/blueprints/container_registry_metadata_database/index.md2
-rw-r--r--doc/architecture/blueprints/database_testing/index.md3
-rw-r--r--doc/architecture/blueprints/runner_scaling/gitlab-autoscaling-overview.pngbin0 -> 94088 bytes
-rw-r--r--doc/architecture/blueprints/runner_scaling/index.md239
-rw-r--r--doc/ci/caching/index.md33
-rw-r--r--doc/ci/ci_cd_for_external_repos/bitbucket_integration.md3
-rw-r--r--doc/ci/ci_cd_for_external_repos/img/ci_cd_for_external_repo.pngbin66760 -> 0 bytes
-rw-r--r--doc/ci/ci_cd_for_external_repos/index.md4
-rw-r--r--doc/ci/cloud_services/aws/index.md92
-rw-r--r--doc/ci/cloud_services/index.md133
-rw-r--r--doc/ci/docker/using_docker_build.md340
-rw-r--r--doc/ci/docker/using_docker_images.md12
-rw-r--r--doc/ci/docker/using_kaniko.md2
-rw-r--r--doc/ci/environments/deployment_approvals.md114
-rw-r--r--doc/ci/environments/deployment_safety.md4
-rw-r--r--doc/ci/environments/index.md8
-rw-r--r--doc/ci/environments/protected_environments.md4
-rw-r--r--doc/ci/examples/authenticating-with-hashicorp-vault/index.md22
-rw-r--r--doc/ci/examples/end_to_end_testing_webdriverio/index.md2
-rw-r--r--doc/ci/examples/laravel_with_gitlab_and_envoy/index.md2
-rw-r--r--doc/ci/git_submodules.md11
-rw-r--r--doc/ci/index.md1
-rw-r--r--doc/ci/interactive_web_terminal/index.md16
-rw-r--r--doc/ci/jobs/ci_job_token.md5
-rw-r--r--doc/ci/jobs/job_control.md43
-rw-r--r--doc/ci/pipeline_editor/index.md53
-rw-r--r--doc/ci/pipelines/cicd_minutes.md221
-rw-r--r--doc/ci/pipelines/img/group_cicd_minutes_quota.png (renamed from doc/user/admin_area/settings/img/group_pipelines_quota.png)bin21010 -> 21010 bytes
-rw-r--r--doc/ci/pipelines/img/pipeline_fork_v13_7.png (renamed from doc/ci/pipelines/img/pipeline-fork_v13_7.png)bin15697 -> 15697 bytes
-rw-r--r--doc/ci/pipelines/index.md109
-rw-r--r--doc/ci/pipelines/job_artifacts.md24
-rw-r--r--doc/ci/pipelines/merge_request_pipelines.md281
-rw-r--r--doc/ci/pipelines/merge_trains.md8
-rw-r--r--doc/ci/pipelines/pipelines_for_merged_results.md8
-rw-r--r--doc/ci/pipelines/settings.md19
-rw-r--r--doc/ci/review_apps/index.md2
-rw-r--r--doc/ci/runners/configure_runners.md3
-rw-r--r--doc/ci/runners/index.md6
-rw-r--r--doc/ci/runners/runners_scope.md6
-rw-r--r--doc/ci/runners/saas/windows_saas_runner.md2
-rw-r--r--doc/ci/test_cases/index.md4
-rw-r--r--doc/ci/triggers/index.md14
-rw-r--r--doc/ci/variables/index.md69
-rw-r--r--doc/ci/variables/predefined_variables.md2
-rw-r--r--doc/ci/variables/where_variables_can_be_used.md33
-rw-r--r--doc/ci/yaml/artifacts_reports.md10
-rw-r--r--doc/ci/yaml/index.md36
-rw-r--r--doc/ci/yaml/script.md6
-rw-r--r--doc/development/application_limits.md3
-rw-r--r--doc/development/architecture.md4
-rw-r--r--doc/development/avoiding_downtime_in_migrations.md97
-rw-r--r--doc/development/background_migrations.md99
-rw-r--r--doc/development/cascading_settings.md2
-rw-r--r--doc/development/cicd/index.md13
-rw-r--r--doc/development/code_review.md13
-rw-r--r--doc/development/database/efficient_in_operator_queries.md81
-rw-r--r--doc/development/database/loose_foreign_keys.md33
-rw-r--r--doc/development/database_review.md12
-rw-r--r--doc/development/documentation/feature_flags.md3
-rw-r--r--doc/development/documentation/redirects.md1
-rw-r--r--doc/development/documentation/restful_api_styleguide.md2
-rw-r--r--doc/development/documentation/styleguide/index.md102
-rw-r--r--doc/development/documentation/styleguide/word_list.md32
-rw-r--r--doc/development/documentation/testing.md11
-rw-r--r--doc/development/ee_features.md28
-rw-r--r--doc/development/emails.md38
-rw-r--r--doc/development/event_store.md292
-rw-r--r--doc/development/experiment_guide/experimentation.md403
-rw-r--r--doc/development/experiment_guide/gitlab_experiment.md2
-rw-r--r--doc/development/experiment_guide/index.md5
-rw-r--r--doc/development/fe_guide/style/javascript.md18
-rw-r--r--doc/development/fe_guide/vue3_migration.md26
-rw-r--r--doc/development/feature_flags/controls.md15
-rw-r--r--doc/development/feature_flags/index.md1
-rw-r--r--doc/development/features_inside_dot_gitlab.md2
-rw-r--r--doc/development/geo.md128
-rw-r--r--doc/development/geo/framework.md8
-rw-r--r--doc/development/gitaly.md11
-rw-r--r--doc/development/import_project.md2
-rw-r--r--doc/development/index.md4
-rw-r--r--doc/development/integrations/jenkins.md4
-rw-r--r--doc/development/integrations/jira_connect.md3
-rw-r--r--doc/development/integrations/secure.md78
-rw-r--r--doc/development/internal_api/index.md32
-rw-r--r--doc/development/licensing.md2
-rw-r--r--doc/development/merge_request_performance_guidelines.md4
-rw-r--r--doc/development/migration_style_guide.md29
-rw-r--r--doc/development/permissions.md4
-rw-r--r--doc/development/pipelines.md373
-rw-r--r--doc/development/policies.md2
-rw-r--r--doc/development/profiling.md14
-rw-r--r--doc/development/redis/new_redis_instance.md125
-rw-r--r--doc/development/secure_coding_guidelines.md351
-rw-r--r--doc/development/service_ping/index.md7
-rw-r--r--doc/development/service_ping/metrics_instrumentation.md6
-rw-r--r--doc/development/service_ping/performance_indicator_metrics.md17
-rw-r--r--doc/development/sidekiq_style_guide.md19
-rw-r--r--doc/development/snowplow/dictionary.md4
-rw-r--r--doc/development/snowplow/implementation.md1
-rw-r--r--doc/development/snowplow/schemas.md4
-rw-r--r--doc/development/testing_guide/best_practices.md5
-rw-r--r--doc/development/testing_guide/ci.md9
-rw-r--r--doc/development/testing_guide/end_to_end/feature_flags.md26
-rw-r--r--doc/development/testing_guide/end_to_end/index.md29
-rw-r--r--doc/development/testing_guide/end_to_end/rspec_metadata_tests.md4
-rw-r--r--doc/development/testing_guide/review_apps.md15
-rw-r--r--doc/development/wikis.md3
-rw-r--r--doc/gitlab-basics/command-line-commands.md5
-rw-r--r--doc/install/aws/gitlab_hybrid_on_aws.md6
-rw-r--r--doc/install/aws/index.md3
-rw-r--r--doc/install/aws/manual_install_aws.md3
-rw-r--r--doc/install/docker.md82
-rw-r--r--doc/install/next_steps.md6
-rw-r--r--doc/install/requirements.md15
-rw-r--r--doc/integration/bitbucket.md4
-rw-r--r--doc/integration/datadog.md4
-rw-r--r--doc/integration/elasticsearch.md2
-rw-r--r--doc/integration/jenkins.md209
-rw-r--r--doc/integration/kerberos.md21
-rw-r--r--doc/integration/mattermost/index.md3
-rw-r--r--doc/integration/oauth_provider.md2
-rw-r--r--doc/integration/omniauth.md12
-rw-r--r--doc/integration/openid_connect_provider.md29
-rw-r--r--doc/integration/saml.md8
-rw-r--r--doc/integration/sourcegraph.md45
-rw-r--r--doc/operations/error_tracking.md2
-rw-r--r--doc/operations/feature_flags.md3
-rw-r--r--doc/operations/incident_management/incidents.md2
-rw-r--r--doc/operations/index.md30
-rw-r--r--doc/operations/metrics/alerts.md5
-rw-r--r--doc/operations/metrics/dashboards/default.md8
-rw-r--r--doc/operations/metrics/dashboards/develop.md8
-rw-r--r--doc/operations/metrics/dashboards/index.md9
-rw-r--r--doc/operations/metrics/dashboards/panel_types.md8
-rw-r--r--doc/operations/metrics/dashboards/settings.md8
-rw-r--r--doc/operations/metrics/dashboards/templating_variables.md9
-rw-r--r--doc/operations/metrics/dashboards/variables.md8
-rw-r--r--doc/operations/metrics/dashboards/yaml.md8
-rw-r--r--doc/operations/tracing.md8
-rw-r--r--doc/policy/alpha-beta-support.md4
-rw-r--r--doc/push_rules/push_rules.md148
-rw-r--r--doc/raketasks/backup_restore.md245
-rw-r--r--doc/raketasks/index.md3
-rw-r--r--doc/security/asset_proxy.md2
-rw-r--r--doc/security/crime_vulnerability.md2
-rw-r--r--doc/security/img/unlock_user_v14_7.pngbin0 -> 31666 bytes
-rw-r--r--doc/security/index.md2
-rw-r--r--doc/security/information_exclusivity.md2
-rw-r--r--doc/security/password_length_limits.md2
-rw-r--r--doc/security/password_storage.md2
-rw-r--r--doc/security/passwords_for_integrated_authentication_methods.md2
-rw-r--r--doc/security/project_import_decompressed_archive_size_limits.md2
-rw-r--r--doc/security/rack_attack.md9
-rw-r--r--doc/security/rate_limits.md29
-rw-r--r--doc/security/reset_user_password.md8
-rw-r--r--doc/security/ssh_keys_restrictions.md2
-rw-r--r--doc/security/token_overview.md24
-rw-r--r--doc/security/two_factor_authentication.md6
-rw-r--r--doc/security/unlock_user.md20
-rw-r--r--doc/security/user_email_confirmation.md2
-rw-r--r--doc/security/user_file_uploads.md2
-rw-r--r--doc/security/webhooks.md5
-rw-r--r--doc/ssh/index.md20
-rw-r--r--doc/subscriptions/bronze_starter.md4
-rw-r--r--doc/subscriptions/gitlab_com/index.md173
-rw-r--r--doc/subscriptions/img/quarterly_reconciliation.pngbin0 -> 7503 bytes
-rw-r--r--doc/subscriptions/index.md11
-rw-r--r--doc/subscriptions/quarterly_reconciliation.md40
-rw-r--r--doc/subscriptions/self_managed/index.md22
-rw-r--r--doc/system_hooks/system_hooks.md2
-rw-r--r--doc/topics/authentication/index.md9
-rw-r--r--doc/topics/autodevops/customize.md66
-rw-r--r--doc/topics/autodevops/stages.md24
-rw-r--r--doc/topics/build_your_application.md4
-rw-r--r--doc/topics/git/how_to_install_git/index.md111
-rw-r--r--doc/topics/git/lfs/index.md12
-rw-r--r--doc/topics/git/troubleshooting_git.md9
-rw-r--r--doc/topics/gitlab_flow.md10
-rw-r--r--doc/topics/release_your_application.md62
-rw-r--r--doc/topics/set_up_organization.md4
-rw-r--r--doc/topics/use_gitlab.md4
-rw-r--r--doc/tutorials/index.md123
-rw-r--r--doc/update/deprecations.md682
-rw-r--r--doc/update/index.md47
-rw-r--r--doc/update/plan_your_upgrade.md12
-rw-r--r--doc/update/removals.md390
-rw-r--r--doc/user/admin_area/analytics/dev_ops_report.md2
-rw-r--r--doc/user/admin_area/appearance.md5
-rw-r--r--doc/user/admin_area/credentials_inventory.md2
-rw-r--r--doc/user/admin_area/geo_nodes.md21
-rw-r--r--doc/user/admin_area/img/admin_labels.pngbin23063 -> 0 bytes
-rw-r--r--doc/user/admin_area/img/admin_labels_v14_7.pngbin0 -> 10804 bytes
-rw-r--r--doc/user/admin_area/img/license_upload_v13_12.pngbin39998 -> 0 bytes
-rw-r--r--doc/user/admin_area/index.md6
-rw-r--r--doc/user/admin_area/labels.md9
-rw-r--r--doc/user/admin_area/license.md224
-rw-r--r--doc/user/admin_area/moderate_users.md14
-rw-r--r--doc/user/admin_area/monitoring/background_migrations.md2
-rw-r--r--doc/user/admin_area/monitoring/health_check.md29
-rw-r--r--doc/user/admin_area/monitoring/img/health_check_token.pngbin4863 -> 0 bytes
-rw-r--r--doc/user/admin_area/review_abuse_reports.md2
-rw-r--r--doc/user/admin_area/settings/account_and_limit_settings.md27
-rw-r--r--doc/user/admin_area/settings/continuous_integration.md79
-rw-r--r--doc/user/admin_area/settings/external_authorization.md40
-rw-r--r--doc/user/admin_area/settings/img/admin_project_quota_view.pngbin2670 -> 0 bytes
-rw-r--r--doc/user/admin_area/settings/img/external_authorization_service_settings.pngbin74753 -> 0 bytes
-rw-r--r--doc/user/admin_area/settings/img/file_template_admin_area_v14_0.pngbin11252 -> 0 bytes
-rw-r--r--doc/user/admin_area/settings/index.md5
-rw-r--r--doc/user/admin_area/settings/instance_template_repository.md10
-rw-r--r--doc/user/admin_area/settings/sign_in_restrictions.md8
-rw-r--r--doc/user/admin_area/settings/third_party_offers.md15
-rw-r--r--doc/user/admin_area/settings/visibility_and_access_controls.md3
-rw-r--r--doc/user/analytics/ci_cd_analytics.md11
-rw-r--r--doc/user/analytics/code_review_analytics.md18
-rw-r--r--doc/user/analytics/img/repository_analytics_v13_0.pngbin35278 -> 0 bytes
-rw-r--r--doc/user/analytics/index.md4
-rw-r--r--doc/user/analytics/issue_analytics.md4
-rw-r--r--doc/user/analytics/repository_analytics.md40
-rw-r--r--doc/user/analytics/value_stream_analytics.md51
-rw-r--r--doc/user/application_security/api_fuzzing/index.md40
-rw-r--r--doc/user/application_security/cluster_image_scanning/index.md10
-rw-r--r--doc/user/application_security/container_scanning/index.md6
-rw-r--r--doc/user/application_security/coverage_fuzzing/index.md205
-rw-r--r--doc/user/application_security/dast/index.md40
-rw-r--r--doc/user/application_security/dast_api/index.md40
-rw-r--r--doc/user/application_security/dependency_scanning/index.md9
-rw-r--r--doc/user/application_security/iac_scanning/index.md4
-rw-r--r--doc/user/application_security/index.md68
-rw-r--r--doc/user/application_security/policies/img/scan_execution_policy_yaml_mode_v14_3.pngbin23658 -> 0 bytes
-rw-r--r--doc/user/application_security/policies/img/scan_execution_policy_yaml_mode_v14_7.pngbin0 -> 25442 bytes
-rw-r--r--doc/user/application_security/policies/index.md26
-rw-r--r--doc/user/application_security/sast/analyzers.md3
-rw-r--r--doc/user/application_security/sast/index.md57
-rw-r--r--doc/user/application_security/secret_detection/index.md50
-rw-r--r--doc/user/application_security/security_dashboard/img/group_security_dashboard_v13_3.pngbin29038 -> 0 bytes
-rw-r--r--doc/user/application_security/security_dashboard/img/pipeline_security_dashboard_v14_4.pngbin44152 -> 0 bytes
-rw-r--r--doc/user/application_security/security_dashboard/img/project_security_dashboard_chart_v13_11.pngbin15914 -> 0 bytes
-rw-r--r--doc/user/application_security/security_dashboard/img/security_center_settings_v13_4.pngbin23188 -> 0 bytes
-rw-r--r--doc/user/application_security/security_dashboard/index.md245
-rw-r--r--doc/user/application_security/vulnerabilities/index.md4
-rw-r--r--doc/user/application_security/vulnerability_report/index.md2
-rw-r--r--doc/user/clusters/agent/ci_cd_tunnel.md7
-rw-r--r--doc/user/clusters/agent/index.md27
-rw-r--r--doc/user/clusters/agent/install/index.md258
-rw-r--r--doc/user/clusters/agent/repository.md3
-rw-r--r--doc/user/clusters/applications.md6
-rw-r--r--doc/user/compliance/index.md15
-rw-r--r--doc/user/compliance/license_compliance/index.md13
-rw-r--r--doc/user/crm/index.md31
-rw-r--r--doc/user/gitlab_com/index.md37
-rw-r--r--doc/user/group/epics/epic_boards.md4
-rw-r--r--doc/user/group/epics/img/epics_search_v13_11.pngbin23566 -> 0 bytes
-rw-r--r--doc/user/group/epics/img/epics_search_v14_7.pngbin0 -> 40250 bytes
-rw-r--r--doc/user/group/epics/img/epics_sort.pngbin71177 -> 0 bytes
-rw-r--r--doc/user/group/epics/img/epics_sort_14_7.pngbin0 -> 88364 bytes
-rw-r--r--doc/user/group/epics/index.md4
-rw-r--r--doc/user/group/epics/manage_epics.md10
-rw-r--r--doc/user/group/img/group_code_coverage_analytics_v13_9.pngbin29915 -> 0 bytes
-rw-r--r--doc/user/group/index.md112
-rw-r--r--doc/user/group/issues_analytics/index.md9
-rw-r--r--doc/user/group/repositories_analytics/index.md8
-rw-r--r--doc/user/group/saml_sso/group_managed_accounts.md4
-rw-r--r--doc/user/group/saml_sso/index.md30
-rw-r--r--doc/user/group/saml_sso/scim_setup.md5
-rw-r--r--doc/user/group/settings/group_access_tokens.md147
-rw-r--r--doc/user/group/subgroups/index.md4
-rw-r--r--doc/user/group/value_stream_analytics/img/vsa_stage_table_v13_12.pngbin81442 -> 0 bytes
-rw-r--r--doc/user/group/value_stream_analytics/img/vsa_stage_table_v14_7.pngbin0 -> 242008 bytes
-rw-r--r--doc/user/group/value_stream_analytics/index.md52
-rw-r--r--doc/user/infrastructure/clusters/manage/management_project_applications/cilium.md2
-rw-r--r--doc/user/infrastructure/clusters/migrate_to_gitlab_agent.md88
-rw-r--r--doc/user/infrastructure/iac/index.md26
-rw-r--r--doc/user/markdown.md56
-rw-r--r--doc/user/operations_dashboard/index.md3
-rw-r--r--doc/user/packages/container_registry/index.md333
-rw-r--r--doc/user/packages/container_registry/reduce_container_registry_storage.md272
-rw-r--r--doc/user/packages/debian_repository/index.md2
-rw-r--r--doc/user/packages/dependency_proxy/index.md18
-rw-r--r--doc/user/packages/generic_packages/index.md7
-rw-r--r--doc/user/packages/helm_repository/index.md2
-rw-r--r--doc/user/packages/maven_repository/index.md9
-rw-r--r--doc/user/packages/npm_registry/index.md5
-rw-r--r--doc/user/packages/package_registry/index.md19
-rw-r--r--doc/user/packages/terraform_module_registry/index.md2
-rw-r--r--doc/user/permissions.md328
-rw-r--r--doc/user/profile/account/create_accounts.md2
-rw-r--r--doc/user/profile/account/delete_account.md2
-rw-r--r--doc/user/profile/account/two_factor_authentication.md447
-rw-r--r--doc/user/profile/index.md2
-rw-r--r--doc/user/profile/personal_access_tokens.md6
-rw-r--r--doc/user/profile/unknown_sign_in_notification.md2
-rw-r--r--doc/user/project/badges.md7
-rw-r--r--doc/user/project/clusters/serverless/aws.md2
-rw-r--r--doc/user/project/code_owners.md34
-rw-r--r--doc/user/project/deploy_keys/index.md2
-rw-r--r--doc/user/project/deploy_tokens/index.md10
-rw-r--r--doc/user/project/description_templates.md161
-rw-r--r--doc/user/project/file_lock.md3
-rw-r--r--doc/user/project/img/description_templates.pngbin7903 -> 0 bytes
-rw-r--r--doc/user/project/img/description_templates_v14_7.pngbin0 -> 13186 bytes
-rw-r--r--doc/user/project/import/bitbucket_server.md1
-rw-r--r--doc/user/project/import/github.md9
-rw-r--r--doc/user/project/import/index.md11
-rw-r--r--doc/user/project/index.md9
-rw-r--r--doc/user/project/insights/index.md4
-rw-r--r--doc/user/project/integrations/discord_notifications.md12
-rw-r--r--doc/user/project/integrations/github.md5
-rw-r--r--doc/user/project/integrations/gitlab_slack_application.md3
-rw-r--r--doc/user/project/integrations/hangouts_chat.md2
-rw-r--r--doc/user/project/integrations/overview.md2
-rw-r--r--doc/user/project/integrations/pipeline_status_emails.md23
-rw-r--r--doc/user/project/integrations/prometheus.md12
-rw-r--r--doc/user/project/integrations/prometheus_library/cloudwatch.md8
-rw-r--r--doc/user/project/integrations/prometheus_library/haproxy.md8
-rw-r--r--doc/user/project/integrations/prometheus_library/index.md8
-rw-r--r--doc/user/project/integrations/prometheus_library/kubernetes.md10
-rw-r--r--doc/user/project/integrations/prometheus_library/nginx.md8
-rw-r--r--doc/user/project/integrations/prometheus_library/nginx_ingress.md8
-rw-r--r--doc/user/project/integrations/prometheus_library/nginx_ingress_vts.md8
-rw-r--r--doc/user/project/integrations/slack.md28
-rw-r--r--doc/user/project/integrations/webhooks.md15
-rw-r--r--doc/user/project/issues/img/issue_board.pngbin85331 -> 0 bytes
-rw-r--r--doc/user/project/issues/managing_issues.md5
-rw-r--r--doc/user/project/labels.md7
-rw-r--r--doc/user/project/members/index.md4
-rw-r--r--doc/user/project/members/share_project_with_groups.md2
-rw-r--r--doc/user/project/merge_requests/accessibility_testing.md80
-rw-r--r--doc/user/project/merge_requests/allow_collaboration.md113
-rw-r--r--doc/user/project/merge_requests/approvals/rules.md6
-rw-r--r--doc/user/project/merge_requests/approvals/settings.md9
-rw-r--r--doc/user/project/merge_requests/browser_performance_testing.md2
-rw-r--r--doc/user/project/merge_requests/code_quality.md14
-rw-r--r--doc/user/project/merge_requests/commit_templates.md9
-rw-r--r--doc/user/project/merge_requests/creating_merge_requests.md9
-rw-r--r--doc/user/project/merge_requests/fail_fast_testing.md2
-rw-r--r--doc/user/project/merge_requests/fast_forward_merge.md12
-rw-r--r--doc/user/project/merge_requests/getting_started.md6
-rw-r--r--doc/user/project/merge_requests/img/commit-button_v13_12.pngbin8834 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/ff_merge_rebase.pngbin26945 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/ff_merge_rebase_v14_7.pngbin0 -> 13865 bytes
-rw-r--r--doc/user/project/merge_requests/img/squash_edit_form.pngbin4231 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/squash_mr_commits.pngbin31491 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/squash_mr_message.pngbin37675 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/squash_mr_widget.pngbin3573 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/squash_squashed_commit.pngbin16725 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/load_performance_testing.md2
-rw-r--r--doc/user/project/merge_requests/revert_changes.md6
-rw-r--r--doc/user/project/merge_requests/reviews/img/suggestions_custom_commit_messages_v13_1.jpgbin35055 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/reviews/img/suggestions_custom_commit_messages_v14_7.pngbin0 -> 14774 bytes
-rw-r--r--doc/user/project/merge_requests/reviews/suggestions.md2
-rw-r--r--doc/user/project/merge_requests/squash_and_merge.md152
-rw-r--r--doc/user/project/merge_requests/versions.md2
-rw-r--r--doc/user/project/pages/getting_started/pages_new_project_template.md3
-rw-r--r--doc/user/project/pages/img/icons/lock.pngbin3404 -> 0 bytes
-rw-r--r--doc/user/project/pages/introduction.md2
-rw-r--r--doc/user/project/pages/pages_access_control.md4
-rw-r--r--doc/user/project/protected_branches.md5
-rw-r--r--doc/user/project/protected_tags.md5
-rw-r--r--doc/user/project/push_options.md5
-rw-r--r--doc/user/project/quick_actions.md142
-rw-r--r--doc/user/project/releases/img/feature_count_v14_6.pngbin24569 -> 6846 bytes
-rw-r--r--doc/user/project/releases/index.md10
-rw-r--r--doc/user/project/repository/gpg_signed_commits/index.md6
-rw-r--r--doc/user/project/repository/index.md6
-rw-r--r--doc/user/project/repository/jupyter_notebooks/index.md4
-rw-r--r--doc/user/project/repository/mirror/index.md2
-rw-r--r--doc/user/project/repository/mirror/push.md2
-rw-r--r--doc/user/project/repository/reducing_the_repo_size_using_git.md3
-rw-r--r--doc/user/project/repository/web_editor.md3
-rw-r--r--doc/user/project/requirements/index.md4
-rw-r--r--doc/user/project/service_desk.md15
-rw-r--r--doc/user/project/settings/img/import_export_download_export.pngbin23285 -> 0 bytes
-rw-r--r--doc/user/project/settings/img/import_export_export_button.pngbin31790 -> 0 bytes
-rw-r--r--doc/user/project/settings/img/import_export_mail_link.pngbin6307 -> 0 bytes
-rw-r--r--doc/user/project/settings/img/import_export_new_project.pngbin8011 -> 0 bytes
-rw-r--r--doc/user/project/settings/img/import_export_select_file.pngbin11254 -> 0 bytes
-rw-r--r--doc/user/project/settings/import_export.md296
-rw-r--r--doc/user/project/settings/index.md23
-rw-r--r--doc/user/project/settings/project_access_tokens.md93
-rw-r--r--doc/user/project/time_tracking.md9
-rw-r--r--doc/user/project/web_ide/index.md48
-rw-r--r--doc/user/project/wiki/index.md15
-rw-r--r--doc/user/project/working_with_projects.md4
-rw-r--r--doc/user/search/advanced_search.md4
-rw-r--r--doc/user/search/img/code_search.pngbin0 -> 113383 bytes
-rw-r--r--doc/user/search/img/project_code_search.pngbin24924 -> 0 bytes
-rw-r--r--doc/user/search/index.md12
-rw-r--r--lib/api/api.rb1
-rw-r--r--lib/api/ci/helpers/runner.rb8
-rw-r--r--lib/api/ci/job_artifacts.rb11
-rw-r--r--lib/api/ci/runner.rb20
-rw-r--r--lib/api/ci/runners.rb7
-rw-r--r--lib/api/ci/triggers.rb2
-rw-r--r--lib/api/debian_project_packages.rb1
-rw-r--r--lib/api/deployments.rb2
-rw-r--r--lib/api/entities/group_detail.rb2
-rw-r--r--lib/api/entities/issue_basic.rb2
-rw-r--r--lib/api/entities/merge_request_basic.rb4
-rw-r--r--lib/api/entities/project.rb3
-rw-r--r--lib/api/entities/project_with_access.rb2
-rw-r--r--lib/api/entities/resource_access_token.rb2
-rw-r--r--lib/api/helpers/integrations_helpers.rb16
-rw-r--r--lib/api/helpers/members_helpers.rb2
-rw-r--r--lib/api/helpers/projects_helpers.rb2
-rw-r--r--lib/api/helpers/rate_limiter.rb5
-rw-r--r--lib/api/integrations.rb9
-rw-r--r--lib/api/internal/base.rb4
-rw-r--r--lib/api/internal/kubernetes.rb2
-rw-r--r--lib/api/internal/mail_room.rb51
-rw-r--r--lib/api/issues.rb4
-rw-r--r--lib/api/package_files.rb19
-rw-r--r--lib/api/project_container_repositories.rb1
-rw-r--r--lib/api/projects.rb1
-rw-r--r--lib/api/resource_access_tokens.rb10
-rw-r--r--lib/api/rubygem_packages.rb9
-rw-r--r--lib/api/search.rb14
-rw-r--r--lib/api/terraform/modules/v1/packages.rb6
-rw-r--r--lib/api/users.rb8
-rw-r--r--lib/api/v3/github.rb8
-rw-r--r--lib/backup.rb13
-rw-r--r--lib/backup/database.rb2
-rw-r--r--lib/backup/files.rb8
-rw-r--r--lib/backup/gitaly_backup.rb47
-rw-r--r--lib/backup/gitaly_rpc_backup.rb2
-rw-r--r--lib/backup/manager.rb2
-rw-r--r--lib/backup/packages.rb13
-rw-r--r--lib/backup/repositories.rb4
-rw-r--r--lib/backup/terraform_state.rb13
-rw-r--r--lib/banzai/filter/base_sanitization_filter.rb2
-rw-r--r--lib/banzai/filter/footnote_filter.rb62
-rw-r--r--lib/banzai/filter/markdown_engines/common_mark.rb36
-rw-r--r--lib/banzai/filter/markdown_post_escape_filter.rb18
-rw-r--r--lib/banzai/filter/plantuml_filter.rb7
-rw-r--r--lib/banzai/filter/references/abstract_reference_filter.rb2
-rw-r--r--lib/banzai/filter/sanitization_filter.rb19
-rw-r--r--lib/banzai/filter/syntax_highlight_filter.rb14
-rw-r--r--lib/banzai/reference_parser/merge_request_parser.rb2
-rw-r--r--lib/banzai/renderer/common_mark/html.rb21
-rw-r--r--lib/bulk_imports/common/extractors/ndjson_extractor.rb34
-rw-r--r--lib/bulk_imports/common/pipelines/uploads_pipeline.rb14
-rw-r--r--lib/bulk_imports/ndjson_pipeline.rb2
-rw-r--r--lib/bulk_imports/projects/pipelines/project_attributes_pipeline.rb31
-rw-r--r--lib/feature.rb9
-rw-r--r--lib/gitlab.rb50
-rw-r--r--lib/gitlab/anonymous_session.rb8
-rw-r--r--lib/gitlab/application_rate_limiter.rb10
-rw-r--r--lib/gitlab/asciidoc/syntax_highlighter/html_pipeline_adapter.rb6
-rw-r--r--lib/gitlab/auth.rb12
-rw-r--r--lib/gitlab/auth/auth_finders.rb2
-rw-r--r--lib/gitlab/auth/ldap/config.rb3
-rw-r--r--lib/gitlab/auth/o_auth/user.rb4
-rw-r--r--lib/gitlab/background_migration/backfill_ci_namespace_mirrors.rb77
-rw-r--r--lib/gitlab/background_migration/backfill_ci_project_mirrors.rb52
-rw-r--r--lib/gitlab/background_migration/backfill_incident_issue_escalation_statuses.rb32
-rw-r--r--lib/gitlab/background_migration/base_job.rb23
-rw-r--r--lib/gitlab/background_migration/cleanup_concurrent_rename.rb14
-rw-r--r--lib/gitlab/background_migration/cleanup_concurrent_schema_change.rb56
-rw-r--r--lib/gitlab/background_migration/cleanup_concurrent_type_change.rb14
-rw-r--r--lib/gitlab/background_migration/copy_column.rb41
-rw-r--r--lib/gitlab/background_migration/encrypt_static_object_token.rb70
-rw-r--r--lib/gitlab/background_migration/fix_vulnerability_occurrences_with_hashes_as_raw_metadata.rb124
-rw-r--r--lib/gitlab/background_migration/job_coordinator.rb14
-rw-r--r--lib/gitlab/background_migration/migrate_legacy_artifacts.rb130
-rw-r--r--lib/gitlab/background_migration/populate_test_reports_issue_id.rb14
-rw-r--r--lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid.rb148
-rw-r--r--lib/gitlab/background_migration/remove_duplicate_services.rb58
-rw-r--r--lib/gitlab/checks/changes_access.rb35
-rw-r--r--lib/gitlab/ci/build/policy/refs.rb5
-rw-r--r--lib/gitlab/ci/build/status/reason.rb37
-rw-r--r--lib/gitlab/ci/config.rb2
-rw-r--r--lib/gitlab/ci/config/entry/root.rb8
-rw-r--r--lib/gitlab/ci/jwt_v2.rb17
-rw-r--r--lib/gitlab/ci/pipeline/chain/create.rb48
-rw-r--r--lib/gitlab/ci/pipeline/chain/create_deployments.rb15
-rw-r--r--lib/gitlab/ci/pipeline/chain/seed.rb9
-rw-r--r--lib/gitlab/ci/pipeline/logger.rb36
-rw-r--r--lib/gitlab/ci/pipeline/seed/build.rb16
-rw-r--r--lib/gitlab/ci/pipeline/seed/context.rb11
-rw-r--r--lib/gitlab/ci/queue/metrics.rb37
-rw-r--r--lib/gitlab/ci/status/build/factory.rb3
-rw-r--r--lib/gitlab/ci/status/build/waiting_for_approval.rb24
-rw-r--r--lib/gitlab/ci/tags/bulk_insert.rb20
-rw-r--r--lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Secret-Detection.gitlab-ci.yml16
-rw-r--r--lib/gitlab/ci/templates/Ruby.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml1
-rw-r--r--lib/gitlab/ci/templates/Security/DAST-On-Demand-API-Scan.gitlab-ci.yml27
-rw-r--r--lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/trace/remote_checksum.rb1
-rw-r--r--lib/gitlab/ci/trace/stream.rb5
-rw-r--r--lib/gitlab/ci/variables/builder.rb64
-rw-r--r--lib/gitlab/ci/yaml_processor.rb8
-rw-r--r--lib/gitlab/color_schemes.rb28
-rw-r--r--lib/gitlab/config/entry/configurable.rb3
-rw-r--r--lib/gitlab/config/entry/factory.rb5
-rw-r--r--lib/gitlab/config/entry/node.rb20
-rw-r--r--lib/gitlab/content_security_policy/config_loader.rb2
-rw-r--r--lib/gitlab/data_builder/archive_trace.rb19
-rw-r--r--lib/gitlab/data_builder/deployment.rb3
-rw-r--r--lib/gitlab/database/background_migration/batched_job.rb18
-rw-r--r--lib/gitlab/database/background_migration/batched_migration.rb2
-rw-r--r--lib/gitlab/database/background_migration_job.rb2
-rw-r--r--lib/gitlab/database/batch_counter.rb29
-rw-r--r--lib/gitlab/database/gitlab_loose_foreign_keys.yml93
-rw-r--r--lib/gitlab/database/gitlab_schemas.yml12
-rw-r--r--lib/gitlab/database/grant.rb2
-rw-r--r--lib/gitlab/database/load_balancing/setup.rb4
-rw-r--r--lib/gitlab/database/loose_index_scan_distinct_count.rb102
-rw-r--r--lib/gitlab/database/migration_helpers.rb180
-rw-r--r--lib/gitlab/database/migrations/background_migration_helpers.rb70
-rw-r--r--lib/gitlab/database/partitioning/partition_manager.rb4
-rw-r--r--lib/gitlab/database/partitioning/sliding_list_strategy.rb28
-rw-r--r--lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table.rb20
-rw-r--r--lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb3
-rw-r--r--lib/gitlab/database/reflection.rb29
-rw-r--r--lib/gitlab/database/reindexing.rb15
-rw-r--r--lib/gitlab/database/reindexing/coordinator.rb19
-rw-r--r--lib/gitlab/database_importers/work_items/base_type_importer.rb4
-rw-r--r--lib/gitlab/email.rb1
-rw-r--r--lib/gitlab/email/failure_handler.rb46
-rw-r--r--lib/gitlab/error_tracking/processor/sidekiq_processor.rb2
-rw-r--r--lib/gitlab/event_store.rb42
-rw-r--r--lib/gitlab/event_store/event.rb54
-rw-r--r--lib/gitlab/event_store/store.rb54
-rw-r--r--lib/gitlab/event_store/subscriber.rb36
-rw-r--r--lib/gitlab/event_store/subscription.rb37
-rw-r--r--lib/gitlab/exceptions_app.rb43
-rw-r--r--lib/gitlab/experimentation.rb8
-rw-r--r--lib/gitlab/gon_helper.rb1
-rw-r--r--lib/gitlab/gpg/commit.rb2
-rw-r--r--lib/gitlab/http.rb3
-rw-r--r--lib/gitlab/i18n.rb22
-rw-r--r--lib/gitlab/import/set_async_jid.rb2
-rw-r--r--lib/gitlab/import_export/base/relation_factory.rb2
-rw-r--r--lib/gitlab/import_export/group/relation_tree_restorer.rb10
-rw-r--r--lib/gitlab/import_export/project/import_export.yml2
-rw-r--r--lib/gitlab/jwt_authenticatable.rb36
-rw-r--r--lib/gitlab/kas.rb2
-rw-r--r--lib/gitlab/lfs/client.rb81
-rw-r--r--lib/gitlab/logger.rb6
-rw-r--r--lib/gitlab/mail_room.rb16
-rw-r--r--lib/gitlab/mail_room/authenticator.rb50
-rw-r--r--lib/gitlab/merge_requests/commit_message_generator.rb72
-rw-r--r--lib/gitlab/metrics/exporter/base_exporter.rb45
-rw-r--r--lib/gitlab/metrics/exporter/gc_request_middleware.rb19
-rw-r--r--lib/gitlab/metrics/exporter/health_checks_middleware.rb35
-rw-r--r--lib/gitlab/metrics/exporter/metrics_middleware.rb41
-rw-r--r--lib/gitlab/metrics/exporter/sidekiq_exporter.rb11
-rw-r--r--lib/gitlab/metrics/exporter/web_exporter.rb8
-rw-r--r--lib/gitlab/metrics/samplers/action_cable_sampler.rb4
-rw-r--r--lib/gitlab/metrics/samplers/base_sampler.rb14
-rw-r--r--lib/gitlab/metrics/samplers/ruby_sampler.rb4
-rw-r--r--lib/gitlab/middleware/multipart.rb4
-rw-r--r--lib/gitlab/middleware/webhook_recursion_detection.rb19
-rw-r--r--lib/gitlab/pages.rb2
-rw-r--r--lib/gitlab/pagination/keyset/column_order_definition.rb25
-rw-r--r--lib/gitlab/pagination/keyset/in_operator_optimization/column_data.rb19
-rw-r--r--lib/gitlab/pagination/keyset/in_operator_optimization/order_by_column_data.rb37
-rw-r--r--lib/gitlab/pagination/keyset/in_operator_optimization/order_by_columns.rb6
-rw-r--r--lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb4
-rw-r--r--lib/gitlab/pagination/keyset/in_operator_optimization/strategies/order_values_loader_strategy.rb15
-rw-r--r--lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy.rb16
-rw-r--r--lib/gitlab/pagination/keyset/sql_type_missing_error.rb19
-rw-r--r--lib/gitlab/password.rb14
-rw-r--r--lib/gitlab/redis/multi_store.rb229
-rw-r--r--lib/gitlab/redis/sessions.rb36
-rw-r--r--lib/gitlab/redis/sessions_store_helper.rb27
-rw-r--r--lib/gitlab/regex.rb26
-rw-r--r--lib/gitlab/repository_archive_rate_limiter.rb2
-rw-r--r--lib/gitlab/search/params.rb11
-rw-r--r--lib/gitlab/sherlock.rb21
-rw-r--r--lib/gitlab/sherlock/collection.rb51
-rw-r--r--lib/gitlab/sherlock/file_sample.rb33
-rw-r--r--lib/gitlab/sherlock/line_profiler.rb100
-rw-r--r--lib/gitlab/sherlock/line_sample.rb38
-rw-r--r--lib/gitlab/sherlock/location.rb28
-rw-r--r--lib/gitlab/sherlock/middleware.rb43
-rw-r--r--lib/gitlab/sherlock/query.rb112
-rw-r--r--lib/gitlab/sherlock/transaction.rb140
-rw-r--r--lib/gitlab/sidekiq_logging/json_formatter.rb1
-rw-r--r--lib/gitlab/sidekiq_logging/structured_logger.rb2
-rw-r--r--lib/gitlab/sidekiq_middleware/monitor.rb2
-rw-r--r--lib/gitlab/sidekiq_status.rb22
-rw-r--r--lib/gitlab/sidekiq_status/client_middleware.rb4
-rw-r--r--lib/gitlab/sourcegraph.rb7
-rw-r--r--lib/gitlab/ssh_public_key.rb26
-rw-r--r--lib/gitlab/themes.rb40
-rw-r--r--lib/gitlab/tracking/standard_context.rb5
-rw-r--r--lib/gitlab/untrusted_regexp/ruby_syntax.rb16
-rw-r--r--lib/gitlab/usage_data.rb33
-rw-r--r--lib/gitlab/usage_data_counters/counter_events/package_events.yml7
-rw-r--r--lib/gitlab/usage_data_counters/hll_redis_counter.rb2
-rw-r--r--lib/gitlab/usage_data_counters/known_events/ci_templates.yml8
-rw-r--r--lib/gitlab/usage_data_counters/known_events/common.yml10
-rw-r--r--lib/gitlab/usage_data_counters/known_events/package_events.yml32
-rw-r--r--lib/gitlab/usage_data_counters/known_events/quickactions.yml8
-rw-r--r--lib/gitlab/utils/sanitize_node_link.rb6
-rw-r--r--lib/gitlab/utils/usage_data.rb12
-rw-r--r--lib/gitlab/web_hooks.rb7
-rw-r--r--lib/gitlab/web_hooks/recursion_detection.rb94
-rw-r--r--lib/gitlab/web_hooks/recursion_detection/uuid.rb46
-rw-r--r--lib/gitlab/workhorse.rb6
-rw-r--r--lib/gitlab_edition.rb50
-rw-r--r--lib/sidebars/groups/menus/ci_cd_menu.rb4
-rw-r--r--lib/sidebars/groups/menus/settings_menu.rb14
-rw-r--r--lib/sidebars/projects/menus/infrastructure_menu.rb2
-rw-r--r--lib/sidebars/projects/menus/issues_menu.rb6
-rw-r--r--lib/tasks/gitlab/backup.rake109
-rw-r--r--lib/tasks/gitlab/cleanup.rake4
-rw-r--r--lib/tasks/gitlab/db.rake2
-rw-r--r--lib/tasks/gitlab/docs/compile_deprecations.rake39
-rw-r--r--lib/tasks/gitlab/docs/redirect.rake2
-rw-r--r--lib/tasks/gitlab/gitaly.rake38
-rw-r--r--lib/tasks/gitlab/seed/group_seed.rake2
-rw-r--r--lib/version_check.rb8
-rw-r--r--locale/am_ET/gitlab.po1124
-rw-r--r--locale/ar_SA/gitlab.po1136
-rw-r--r--locale/as_IN/gitlab.po1124
-rw-r--r--locale/az_AZ/gitlab.po1124
-rw-r--r--locale/ba_RU/gitlab.po1121
-rw-r--r--locale/bg/gitlab.po1126
-rw-r--r--locale/bn_BD/gitlab.po1124
-rw-r--r--locale/bn_IN/gitlab.po1124
-rw-r--r--locale/br_FR/gitlab.po1133
-rw-r--r--locale/bs_BA/gitlab.po1127
-rw-r--r--locale/ca_ES/gitlab.po1124
-rw-r--r--locale/cs_CZ/gitlab.po1130
-rw-r--r--locale/cy_GB/gitlab.po1136
-rw-r--r--locale/da_DK/gitlab.po1138
-rw-r--r--locale/de/gitlab.po1196
-rw-r--r--locale/el_GR/gitlab.po1124
-rw-r--r--locale/eo/gitlab.po1126
-rw-r--r--locale/es/gitlab.po1546
-rw-r--r--locale/et_EE/gitlab.po1124
-rw-r--r--locale/fa_IR/gitlab.po1124
-rw-r--r--locale/fi_FI/gitlab.po1124
-rw-r--r--locale/fil_PH/gitlab.po1124
-rw-r--r--locale/fr/gitlab.po1128
-rw-r--r--locale/gitlab.pot1326
-rw-r--r--locale/gl_ES/gitlab.po1124
-rw-r--r--locale/he_IL/gitlab.po1130
-rw-r--r--locale/hi_IN/gitlab.po1124
-rw-r--r--locale/hr_HR/gitlab.po1127
-rw-r--r--locale/hu_HU/gitlab.po1124
-rw-r--r--locale/hy_AM/gitlab.po1124
-rw-r--r--locale/id_ID/gitlab.po1121
-rw-r--r--locale/ig_NG/gitlab.po1121
-rw-r--r--locale/is_IS/gitlab.po1124
-rw-r--r--locale/it/gitlab.po1126
-rw-r--r--locale/ja/gitlab.po1699
-rw-r--r--locale/ka_GE/gitlab.po1124
-rw-r--r--locale/kab/gitlab.po1124
-rw-r--r--locale/ko/gitlab.po1833
-rw-r--r--locale/ku_TR/gitlab.po1124
-rw-r--r--locale/ky_KG/gitlab.po1124
-rw-r--r--locale/lt_LT/gitlab.po1130
-rw-r--r--locale/mk_MK/gitlab.po1124
-rw-r--r--locale/mn_MN/gitlab.po1124
-rw-r--r--locale/nb_NO/gitlab.po1134
-rw-r--r--locale/nl_NL/gitlab.po1124
-rw-r--r--locale/pa_IN/gitlab.po1124
-rw-r--r--locale/pl_PL/gitlab.po1132
-rw-r--r--locale/pt_BR/gitlab.po1640
-rw-r--r--locale/pt_PT/gitlab.po1124
-rw-r--r--locale/ro_RO/gitlab.po1139
-rw-r--r--locale/ru/gitlab.po1592
-rw-r--r--locale/si_LK/gitlab.po1124
-rw-r--r--locale/sk_SK/gitlab.po1130
-rw-r--r--locale/sl_SI/gitlab.po1130
-rw-r--r--locale/sq_AL/gitlab.po1124
-rw-r--r--locale/sr_CS/gitlab.po1127
-rw-r--r--locale/sr_SP/gitlab.po1127
-rw-r--r--locale/sv_SE/gitlab.po1124
-rw-r--r--locale/sw_KE/gitlab.po1124
-rw-r--r--locale/ta_IN/gitlab.po1124
-rw-r--r--locale/tr_TR/gitlab.po1124
-rw-r--r--locale/uk/gitlab.po1496
-rw-r--r--locale/ur_PK/gitlab.po1124
-rw-r--r--locale/uz_UZ/gitlab.po1124
-rw-r--r--locale/vi_VN/gitlab.po1121
-rw-r--r--locale/zh_CN/gitlab.po2035
-rw-r--r--locale/zh_HK/gitlab.po1123
-rw-r--r--locale/zh_TW/gitlab.po1121
-rw-r--r--metrics_server/dependencies.rb7
-rw-r--r--metrics_server/metrics_server.rb10
-rw-r--r--metrics_server/override_gitlab_current_settings.rb21
-rw-r--r--metrics_server/settings_overrides.rb5
-rw-r--r--package.json66
-rw-r--r--public/500.html1
-rw-r--r--qa/.confiner/quarantine.yml15
-rw-r--r--qa/Dockerfile2
-rw-r--r--qa/Gemfile4
-rw-r--r--qa/Gemfile.lock32
-rw-r--r--qa/Rakefile14
-rw-r--r--qa/knapsack/.gitignore4
-rw-r--r--qa/knapsack/gcs/.gitignore3
-rw-r--r--qa/knapsack/master_report.json404
-rw-r--r--qa/lib/gitlab/page/main/welcome.rb13
-rw-r--r--qa/lib/gitlab/page/main/welcome.stub.rb33
-rw-r--r--qa/qa.rb2
-rw-r--r--qa/qa/fixtures/metrics_dashboards/templating.yml2
-rw-r--r--qa/qa/flow/login.rb5
-rw-r--r--qa/qa/flow/sign_up.rb5
-rw-r--r--qa/qa/flow/user_onboarding.rb19
-rw-r--r--qa/qa/page/base.rb4
-rw-r--r--qa/qa/page/component/confirm_modal.rb6
-rw-r--r--qa/qa/page/component/invite_members_modal.rb44
-rw-r--r--qa/qa/page/dashboard/welcome.rb4
-rw-r--r--qa/qa/page/file/show.rb20
-rw-r--r--qa/qa/page/main/login.rb5
-rw-r--r--qa/qa/page/project/branches/show.rb1
-rw-r--r--qa/qa/page/project/members.rb5
-rw-r--r--qa/qa/page/project/new.rb1
-rw-r--r--qa/qa/page/project/packages/show.rb2
-rw-r--r--qa/qa/page/project/pipeline_editor/show.rb83
-rw-r--r--qa/qa/page/project/secure/configuration_form.rb46
-rw-r--r--qa/qa/page/project/settings/visibility_features_permissions.rb7
-rw-r--r--qa/qa/page/registration/sign_up.rb4
-rw-r--r--qa/qa/page/registration/welcome.rb23
-rw-r--r--qa/qa/page/trials/new.rb18
-rw-r--r--qa/qa/resource/api_fabricator.rb6
-rw-r--r--qa/qa/resource/base.rb75
-rw-r--r--qa/qa/resource/bulk_import_group.rb19
-rw-r--r--qa/qa/resource/group_badge.rb17
-rw-r--r--qa/qa/resource/group_base.rb12
-rw-r--r--qa/qa/resource/group_milestone.rb17
-rw-r--r--qa/qa/resource/issue.rb22
-rw-r--r--qa/qa/resource/label_base.rb17
-rw-r--r--qa/qa/resource/merge_request.rb71
-rw-r--r--qa/qa/resource/project.rb69
-rw-r--r--qa/qa/resource/repository/commit.rb99
-rw-r--r--qa/qa/resource/reusable_group.rb54
-rw-r--r--qa/qa/resource/reusable_project.rb6
-rw-r--r--qa/qa/resource/user.rb15
-rw-r--r--qa/qa/runtime/env.rb26
-rw-r--r--qa/qa/scenario/bootable.rb7
-rw-r--r--qa/qa/scenario/shared_attributes.rb1
-rw-r--r--qa/qa/scenario/template.rb8
-rw-r--r--qa/qa/service/praefect_manager.rb157
-rw-r--r--qa/qa/specs/features/api/1_manage/bulk_import_group_spec.rb179
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb185
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_issue_spec.rb55
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb71
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb94
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb85
-rw-r--r--qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb6
-rw-r--r--qa/qa/specs/features/api/3_create/gitaly/automatic_failover_and_recovery_spec.rb1
-rw-r--r--qa/qa/specs/features/api/3_create/gitaly/praefect_connectivity_spec.rb41
-rw-r--r--qa/qa/specs/features/api/3_create/gitaly/praefect_repo_sync_spec.rb14
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/group/bulk_import_group_spec.rb78
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/group/gitlab_migration_group_spec.rb77
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb12
-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/create_project_spec.rb3
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb88
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_merge_ref_diff_spec.rb90
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/wiki/content_editor_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_lint_spec.rb95
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/update_ci_file_with_pipeline_editor_spec.rb73
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/container_registry/online_garbage_collection_spec.rb5
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/8_monitor/.gitkeep0
-rw-r--r--qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb142
-rw-r--r--qa/qa/specs/features/browser_ui/8_monitor/cluster_with_prometheus.rb67
-rw-r--r--qa/qa/specs/helpers/quarantine.rb25
-rw-r--r--qa/qa/specs/runner.rb14
-rw-r--r--qa/qa/support/formatters/quarantine_formatter.rb10
-rw-r--r--qa/qa/support/formatters/test_stats_formatter.rb7
-rw-r--r--qa/qa/support/matchers/eventually_matcher.rb60
-rw-r--r--qa/qa/support/matchers/have_matcher.rb3
-rw-r--r--qa/qa/support/page_error_checker.rb62
-rw-r--r--qa/qa/support/wait_for_requests.rb7
-rw-r--r--qa/qa/tools/delete_projects.rb2
-rw-r--r--qa/qa/tools/delete_subgroups.rb2
-rw-r--r--qa/qa/tools/delete_test_resources.rb85
-rw-r--r--qa/qa/tools/delete_test_ssh_keys.rb2
-rw-r--r--qa/qa/tools/generate_perf_testdata.rb2
-rw-r--r--qa/qa/tools/initialize_gitlab_auth.rb2
-rw-r--r--qa/qa/tools/knapsack_report.rb118
-rw-r--r--qa/qa/tools/long_running_spec_reporter.rb97
-rw-r--r--qa/qa/tools/reliable_report.rb114
-rw-r--r--qa/qa/tools/revoke_all_personal_access_tokens.rb2
-rw-r--r--qa/qa/tools/test_resource_data_processor.rb66
-rw-r--r--qa/spec/page/logging_spec.rb1
-rw-r--r--qa/spec/resource/base_spec.rb13
-rw-r--r--qa/spec/runtime/env_spec.rb96
-rw-r--r--qa/spec/scenario/test/integration/github_spec.rb2
-rw-r--r--qa/spec/spec_helper.rb23
-rw-r--r--qa/spec/specs/runner_spec.rb26
-rw-r--r--qa/spec/support/formatters/test_stats_formatter_spec.rb9
-rw-r--r--qa/spec/support/page_error_checker_spec.rb217
-rw-r--r--qa/spec/support/wait_for_requests_spec.rb16
-rw-r--r--qa/spec/tools/long_running_spec_reporter_spec.rb69
-rw-r--r--qa/spec/tools/reliable_report_spec.rb62
-rw-r--r--qa/spec/tools/test_resources_data_processor_spec.rb33
-rw-r--r--qa/tasks/knapsack.rake11
-rw-r--r--qa/tasks/reliable_report.rake2
-rw-r--r--rubocop/code_reuse_helpers.rb16
-rw-r--r--rubocop/cop/database/establish_connection.rb20
-rw-r--r--rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction.rb41
-rw-r--r--rubocop/cop/migration/schedule_async.rb27
-rwxr-xr-xscripts/gitaly-test-build2
-rwxr-xr-xscripts/gitaly-test-spawn14
-rwxr-xr-xscripts/insert-rspec-profiling-data2
-rwxr-xr-xscripts/lint-doc.sh2
-rwxr-xr-xscripts/setup/find-jh-branch.rb102
-rwxr-xr-xscripts/undercoverage2
-rwxr-xr-xscripts/used-feature-flags6
-rw-r--r--scripts/utils.sh2
-rw-r--r--shared/packages/.gitkeep0
-rw-r--r--shared/terraform_state/.gitkeep0
-rw-r--r--sidekiq_cluster/cli.rb12
-rw-r--r--spec/commands/metrics_server/metrics_server_spec.rb6
-rw-r--r--spec/commands/sidekiq_cluster/cli_spec.rb122
-rw-r--r--spec/config/inject_enterprise_edition_module_spec.rb2
-rw-r--r--spec/config/mail_room_spec.rb3
-rw-r--r--spec/controllers/admin/application_settings_controller_spec.rb1
-rw-r--r--spec/controllers/admin/instance_review_controller_spec.rb1
-rw-r--r--spec/controllers/admin/runner_projects_controller_spec.rb59
-rw-r--r--spec/controllers/admin/runners_controller_spec.rb38
-rw-r--r--spec/controllers/admin/users_controller_spec.rb35
-rw-r--r--spec/controllers/autocomplete_controller_spec.rb12
-rw-r--r--spec/controllers/concerns/check_rate_limit_spec.rb85
-rw-r--r--spec/controllers/groups/boards_controller_spec.rb18
-rw-r--r--spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb82
-rw-r--r--spec/controllers/groups/packages_controller_spec.rb27
-rw-r--r--spec/controllers/import/gitlab_controller_spec.rb17
-rw-r--r--spec/controllers/ldap/omniauth_callbacks_controller_spec.rb2
-rw-r--r--spec/controllers/oauth/token_info_controller_spec.rb24
-rw-r--r--spec/controllers/profiles/emails_controller_spec.rb2
-rw-r--r--spec/controllers/profiles_controller_spec.rb28
-rw-r--r--spec/controllers/projects/boards_controller_spec.rb18
-rw-r--r--spec/controllers/projects/mattermosts_controller_spec.rb4
-rw-r--r--spec/controllers/projects/merge_requests/diffs_controller_spec.rb5
-rw-r--r--spec/controllers/projects/notes_controller_spec.rb9
-rw-r--r--spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb24
-rw-r--r--spec/controllers/projects/packages/packages_controller_spec.rb28
-rw-r--r--spec/controllers/projects/prometheus/metrics_controller_spec.rb20
-rw-r--r--spec/controllers/projects/raw_controller_spec.rb136
-rw-r--r--spec/controllers/projects/repositories_controller_spec.rb19
-rw-r--r--spec/controllers/projects/security/configuration_controller_spec.rb25
-rw-r--r--spec/controllers/projects/service_hook_logs_controller_spec.rb4
-rw-r--r--spec/controllers/projects/services_controller_spec.rb4
-rw-r--r--spec/controllers/projects/settings/access_tokens_controller_spec.rb82
-rw-r--r--spec/controllers/projects/settings/ci_cd_controller_spec.rb13
-rw-r--r--spec/controllers/registrations_controller_spec.rb20
-rw-r--r--spec/controllers/search_controller_spec.rb27
-rw-r--r--spec/controllers/snippets/notes_controller_spec.rb28
-rw-r--r--spec/db/schema_spec.rb3
-rw-r--r--spec/experiments/change_continuous_onboarding_link_urls_experiment_spec.rb53
-rw-r--r--spec/experiments/new_project_sast_enabled_experiment_spec.rb7
-rw-r--r--spec/experiments/require_verification_for_namespace_creation_experiment_spec.rb59
-rw-r--r--spec/factories/ci/builds.rb9
-rw-r--r--spec/factories/ci/job_artifacts.rb4
-rw-r--r--spec/factories/ci/pipeline_message.rb9
-rw-r--r--spec/factories/ci/pipelines.rb4
-rw-r--r--spec/factories/ci/secure_files.rb10
-rw-r--r--spec/factories/clusters/agent_tokens.rb4
-rw-r--r--spec/factories/clusters/applications/helm.rb1
-rw-r--r--spec/factories/dependency_proxy.rb8
-rw-r--r--spec/factories/group/crm_settings.rb7
-rw-r--r--spec/factories/groups.rb6
-rw-r--r--spec/factories/incident_management/issuable_escalation_statuses.rb2
-rw-r--r--spec/factories/integrations.rb2
-rw-r--r--spec/factories/labels.rb2
-rw-r--r--spec/factories/namespaces.rb8
-rw-r--r--spec/factories/packages/package_files.rb6
-rw-r--r--spec/factories/projects.rb7
-rw-r--r--spec/factories/usage_data.rb20
-rw-r--r--spec/factories/users.rb2
-rw-r--r--spec/factories/wikis.rb2
-rw-r--r--spec/factories/work_item/work_item_types.rb41
-rw-r--r--spec/factories/work_items/work_item_types.rb41
-rw-r--r--spec/features/admin/admin_deploy_keys_spec.rb125
-rw-r--r--spec/features/admin/admin_labels_spec.rb24
-rw-r--r--spec/features/admin/admin_runners_spec.rb146
-rw-r--r--spec/features/admin/admin_settings_spec.rb3
-rw-r--r--spec/features/admin/admin_users_spec.rb29
-rw-r--r--spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb15
-rw-r--r--spec/features/admin/users/user_spec.rb20
-rw-r--r--spec/features/admin/users/users_spec.rb4
-rw-r--r--spec/features/boards/board_filters_spec.rb4
-rw-r--r--spec/features/boards/boards_spec.rb2
-rw-r--r--spec/features/boards/sidebar_spec.rb6
-rw-r--r--spec/features/commits_spec.rb54
-rw-r--r--spec/features/dashboard/issues_spec.rb2
-rw-r--r--spec/features/dashboard/milestones_spec.rb2
-rw-r--r--spec/features/dashboard/todos/todos_spec.rb20
-rw-r--r--spec/features/dashboard/user_filters_projects_spec.rb6
-rw-r--r--spec/features/graphiql_spec.rb4
-rw-r--r--spec/features/groups/dependency_proxy_for_containers_spec.rb17
-rw-r--r--spec/features/groups/issues_spec.rb4
-rw-r--r--spec/features/groups/labels/edit_spec.rb14
-rw-r--r--spec/features/groups/labels/sort_labels_spec.rb2
-rw-r--r--spec/features/groups/merge_requests_spec.rb2
-rw-r--r--spec/features/groups/navbar_spec.rb7
-rw-r--r--spec/features/groups/packages_spec.rb3
-rw-r--r--spec/features/groups/settings/access_tokens_spec.rb53
-rw-r--r--spec/features/groups_spec.rb22
-rw-r--r--spec/features/help_dropdown_spec.rb67
-rw-r--r--spec/features/help_pages_spec.rb17
-rw-r--r--spec/features/issuables/sorting_list_spec.rb16
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb70
-rw-r--r--spec/features/issues/service_desk_spec.rb2
-rw-r--r--spec/features/issues/user_bulk_edits_issues_spec.rb20
-rw-r--r--spec/features/issues/user_comments_on_issue_spec.rb3
-rw-r--r--spec/features/issues/user_creates_branch_and_merge_request_spec.rb2
-rw-r--r--spec/features/issues/user_scrolls_to_deeplinked_note_spec.rb33
-rw-r--r--spec/features/issues/user_sees_breadcrumb_links_spec.rb2
-rw-r--r--spec/features/markdown/copy_as_gfm_spec.rb4
-rw-r--r--spec/features/markdown/mermaid_spec.rb4
-rw-r--r--spec/features/markdown/sandboxed_mermaid_spec.rb32
-rw-r--r--spec/features/merge_request/user_sees_merge_widget_spec.rb2
-rw-r--r--spec/features/password_reset_spec.rb4
-rw-r--r--spec/features/profile_spec.rb65
-rw-r--r--spec/features/profiles/chat_names_spec.rb2
-rw-r--r--spec/features/profiles/emails_spec.rb2
-rw-r--r--spec/features/profiles/keys_spec.rb4
-rw-r--r--spec/features/profiles/password_spec.rb8
-rw-r--r--spec/features/profiles/personal_access_tokens_spec.rb11
-rw-r--r--spec/features/projects/blobs/blob_line_permalink_updater_spec.rb22
-rw-r--r--spec/features/projects/blobs/blob_show_spec.rb4
-rw-r--r--spec/features/projects/branches/user_deletes_branch_spec.rb24
-rw-r--r--spec/features/projects/branches_spec.rb24
-rw-r--r--spec/features/projects/clusters/gcp_spec.rb2
-rw-r--r--spec/features/projects/environments/environment_spec.rb18
-rw-r--r--spec/features/projects/features_visibility_spec.rb4
-rw-r--r--spec/features/projects/files/user_browses_files_spec.rb2
-rw-r--r--spec/features/projects/files/user_browses_lfs_files_spec.rb6
-rw-r--r--spec/features/projects/files/user_deletes_files_spec.rb1
-rw-r--r--spec/features/projects/files/user_edits_files_spec.rb8
-rw-r--r--spec/features/projects/files/user_replaces_files_spec.rb1
-rw-r--r--spec/features/projects/import_export/import_file_spec.rb3
-rw-r--r--spec/features/projects/integrations/user_activates_jira_spec.rb8
-rw-r--r--spec/features/projects/labels/sort_labels_spec.rb2
-rw-r--r--spec/features/projects/labels/user_edits_labels_spec.rb14
-rw-r--r--spec/features/projects/new_project_spec.rb38
-rw-r--r--spec/features/projects/packages_spec.rb3
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb97
-rw-r--r--spec/features/projects/services/user_activates_issue_tracker_spec.rb6
-rw-r--r--spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_slack_notifications_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_slack_slash_command_spec.rb4
-rw-r--r--spec/features/projects/settings/access_tokens_spec.rb162
-rw-r--r--spec/features/projects/settings/project_settings_spec.rb4
-rw-r--r--spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb6
-rw-r--r--spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb2
-rw-r--r--spec/features/projects/user_changes_project_visibility_spec.rb90
-rw-r--r--spec/features/projects/user_creates_project_spec.rb17
-rw-r--r--spec/features/projects/user_sorts_projects_spec.rb4
-rw-r--r--spec/features/projects/view_on_env_spec.rb21
-rw-r--r--spec/features/protected_branches_spec.rb41
-rw-r--r--spec/features/runners_spec.rb25
-rw-r--r--spec/features/user_sees_marketing_header_spec.rb69
-rw-r--r--spec/features/user_sorts_things_spec.rb6
-rw-r--r--spec/features/users/anonymous_sessions_spec.rb2
-rw-r--r--spec/features/users/login_spec.rb24
-rw-r--r--spec/finders/ci/runners_finder_spec.rb12
-rw-r--r--spec/finders/environments/environments_by_deployments_finder_spec.rb12
-rw-r--r--spec/finders/fork_targets_finder_spec.rb8
-rw-r--r--spec/finders/group_descendants_finder_spec.rb334
-rw-r--r--spec/finders/group_members_finder_spec.rb116
-rw-r--r--spec/finders/groups/user_groups_finder_spec.rb17
-rw-r--r--spec/finders/merge_requests_finder_spec.rb101
-rw-r--r--spec/finders/packages/conan/package_file_finder_spec.rb30
-rw-r--r--spec/finders/packages/go/package_finder_spec.rb2
-rw-r--r--spec/finders/packages/maven/package_finder_spec.rb2
-rw-r--r--spec/finders/packages/npm/package_finder_spec.rb2
-rw-r--r--spec/finders/packages/nuget/package_finder_spec.rb2
-rw-r--r--spec/finders/packages/package_file_finder_spec.rb28
-rw-r--r--spec/finders/user_group_notification_settings_finder_spec.rb238
-rw-r--r--spec/finders/user_recent_events_finder_spec.rb36
-rw-r--r--spec/fixtures/api/schemas/graphql/packages/package_details.json24
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/merge_request.json12
-rw-r--r--spec/fixtures/ci_secure_files/upload-keystore.jksbin0 -> 2760 bytes
-rw-r--r--spec/fixtures/error_tracking/go_two_exception_event.json1
-rw-r--r--spec/fixtures/security_reports/master/gl-sast-report.json10
-rw-r--r--spec/frontend/__helpers__/matchers.js68
-rw-r--r--spec/frontend/__helpers__/matchers/index.js3
-rw-r--r--spec/frontend/__helpers__/matchers/to_have_sprite_icon.js36
-rw-r--r--spec/frontend/__helpers__/matchers/to_have_tracking_attributes.js35
-rw-r--r--spec/frontend/__helpers__/matchers/to_have_tracking_attributes_spec.js65
-rw-r--r--spec/frontend/__helpers__/matchers/to_match_interpolated_text.js30
-rw-r--r--spec/frontend/__helpers__/matchers/to_match_interpolated_text_spec.js46
-rw-r--r--spec/frontend/__helpers__/matchers_spec.js48
-rw-r--r--spec/frontend/__helpers__/shared_test_setup.js2
-rw-r--r--spec/frontend/__helpers__/wait_using_real_timer.js7
-rw-r--r--spec/frontend/alerts_settings/components/alerts_settings_form_spec.js10
-rw-r--r--spec/frontend/analytics/shared/components/projects_dropdown_filter_spec.js4
-rw-r--r--spec/frontend/api/packages_api_spec.js11
-rw-r--r--spec/frontend/behaviors/copy_to_clipboard_spec.js187
-rw-r--r--spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap14
-rw-r--r--spec/frontend/blob/components/__snapshots__/blob_header_spec.js.snap2
-rw-r--r--spec/frontend/blob/components/blob_edit_header_spec.js2
-rw-r--r--spec/frontend/blob/components/blob_header_filepath_spec.js8
-rw-r--r--spec/frontend/blob/line_highlighter_spec.js275
-rw-r--r--spec/frontend/blob/viewer/index_spec.js1
-rw-r--r--spec/frontend/boards/components/board_card_spec.js4
-rw-r--r--spec/frontend/boards/components/board_content_sidebar_spec.js20
-rw-r--r--spec/frontend/boards/components/board_filtered_search_spec.js22
-rw-r--r--spec/frontend/boards/components/board_list_header_spec.js8
-rw-r--r--spec/frontend/boards/components/boards_selector_spec.js12
-rw-r--r--spec/frontend/boards/stores/actions_spec.js32
-rw-r--r--spec/frontend/branches/branches_delete_modal_spec.js40
-rw-r--r--spec/frontend/ci_lint/components/ci_lint_spec.js2
-rw-r--r--spec/frontend/clusters/agents/components/show_spec.js8
-rw-r--r--spec/frontend/clusters/forms/components/integration_form_spec.js4
-rw-r--r--spec/frontend/clusters_list/components/agent_options_spec.js211
-rw-r--r--spec/frontend/clusters_list/components/agent_table_spec.js26
-rw-r--r--spec/frontend/clusters_list/components/clusters_spec.js2
-rw-r--r--spec/frontend/clusters_list/mocks/apollo.js12
-rw-r--r--spec/frontend/commit/pipelines/pipelines_table_spec.js2
-rw-r--r--spec/frontend/content_editor/components/wrappers/frontmatter_spec.js5
-rw-r--r--spec/frontend/content_editor/extensions/code_block_highlight_spec.js6
-rw-r--r--spec/frontend/content_editor/extensions/code_spec.js8
-rw-r--r--spec/frontend/content_editor/extensions/frontmatter_spec.js25
-rw-r--r--spec/frontend/content_editor/extensions/image_spec.js41
-rw-r--r--spec/frontend/content_editor/extensions/link_spec.js2
-rw-r--r--spec/frontend/content_editor/services/markdown_serializer_spec.js15
-rw-r--r--spec/frontend/create_cluster/components/cluster_form_dropdown_spec.js2
-rw-r--r--spec/frontend/create_cluster/eks_cluster/components/service_credentials_form_spec.js6
-rw-r--r--spec/frontend/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js2
-rw-r--r--spec/frontend/create_cluster/gke_cluster/components/gke_project_id_dropdown_spec.js6
-rw-r--r--spec/frontend/create_cluster/gke_cluster/components/gke_zone_dropdown_spec.js2
-rw-r--r--spec/frontend/create_merge_request_dropdown_spec.js122
-rw-r--r--spec/frontend/crm/contact_form_spec.js4
-rw-r--r--spec/frontend/crm/form_spec.js278
-rw-r--r--spec/frontend/crm/mock_data.js8
-rw-r--r--spec/frontend/crm/new_organization_form_spec.js2
-rw-r--r--spec/frontend/cycle_analytics/stage_table_spec.js57
-rw-r--r--spec/frontend/cycle_analytics/value_stream_metrics_spec.js2
-rw-r--r--spec/frontend/deploy_freeze/components/timezone_dropdown_spec.js2
-rw-r--r--spec/frontend/design_management/components/design_notes/__snapshots__/design_note_signed_out_spec.js.snap41
-rw-r--r--spec/frontend/design_management/components/design_notes/design_discussion_spec.js50
-rw-r--r--spec/frontend/design_management/components/design_notes/design_note_signed_out_spec.js36
-rw-r--r--spec/frontend/design_management/components/design_overlay_spec.js10
-rw-r--r--spec/frontend/design_management/components/design_presentation_spec.js27
-rw-r--r--spec/frontend/design_management/components/design_sidebar_spec.js51
-rw-r--r--spec/frontend/design_management/components/image_spec.js2
-rw-r--r--spec/frontend/design_management/components/toolbar/design_navigation_spec.js4
-rw-r--r--spec/frontend/design_management/components/toolbar/index_spec.js2
-rw-r--r--spec/frontend/design_management/components/upload/design_version_dropdown_spec.js2
-rw-r--r--spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap27
-rw-r--r--spec/frontend/design_management/pages/design/index_spec.js2
-rw-r--r--spec/frontend/design_management/pages/index_spec.js14
-rw-r--r--spec/frontend/diffs/components/image_diff_overlay_spec.js19
-rw-r--r--spec/frontend/editor/source_editor_spec.js15
-rw-r--r--spec/frontend/emoji/components/category_spec.js2
-rw-r--r--spec/frontend/emoji/components/emoji_list_spec.js2
-rw-r--r--spec/frontend/environments/confirm_rollback_modal_spec.js8
-rw-r--r--spec/frontend/environments/deployment_spec.js29
-rw-r--r--spec/frontend/environments/deployment_status_badge_spec.js42
-rw-r--r--spec/frontend/environments/environment_actions_spec.js35
-rw-r--r--spec/frontend/environments/environment_stop_spec.js72
-rw-r--r--spec/frontend/environments/graphql/mock_data.js136
-rw-r--r--spec/frontend/environments/graphql/resolvers_spec.js34
-rw-r--r--spec/frontend/environments/new_environment_folder_spec.js34
-rw-r--r--spec/frontend/environments/new_environment_item_spec.js341
-rw-r--r--spec/frontend/environments/new_environments_app_spec.js37
-rw-r--r--spec/frontend/error_tracking/components/error_details_spec.js28
-rw-r--r--spec/frontend/error_tracking/components/error_tracking_list_spec.js2
-rw-r--r--spec/frontend/fixtures/blob.rb1
-rw-r--r--spec/frontend/fixtures/runner.rb117
-rw-r--r--spec/frontend/fixtures/static/project_select_combo_button.html2
-rw-r--r--spec/frontend/flash_spec.js255
-rw-r--r--spec/frontend/google_cloud/components/app_spec.js2
-rw-r--r--spec/frontend/google_cloud/components/deployments_service_table_spec.js40
-rw-r--r--spec/frontend/google_cloud/components/home_spec.js4
-rw-r--r--spec/frontend/google_tag_manager/index_spec.js259
-rw-r--r--spec/frontend/groups/components/group_item_spec.js1
-rw-r--r--spec/frontend/groups/components/item_stats_spec.js1
-rw-r--r--spec/frontend/groups/landing_spec.js184
-rw-r--r--spec/frontend/groups/transfer_edit_spec.js31
-rw-r--r--spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap9
-rw-r--r--spec/frontend/ide/components/preview/clientside_spec.js20
-rw-r--r--spec/frontend/ide/components/repo_editor_spec.js11
-rw-r--r--spec/frontend/ide/components/terminal/terminal_spec.js2
-rw-r--r--spec/frontend/ide/stores/modules/pipelines/actions_spec.js18
-rw-r--r--spec/frontend/integrations/edit/components/dynamic_field_spec.js13
-rw-r--r--spec/frontend/integrations/edit/components/integration_form_spec.js413
-rw-r--r--spec/frontend/integrations/edit/store/actions_spec.js37
-rw-r--r--spec/frontend/integrations/edit/store/mutations_spec.js24
-rw-r--r--spec/frontend/integrations/edit/store/state_spec.js2
-rw-r--r--spec/frontend/integrations/overrides/components/integration_overrides_spec.js16
-rw-r--r--spec/frontend/integrations/overrides/components/integration_tabs_spec.js64
-rw-r--r--spec/frontend/invite_members/components/invite_members_modal_spec.js12
-rw-r--r--spec/frontend/invite_members/mock_data/api_responses.js2
-rw-r--r--spec/frontend/issuable/components/related_issuable_item_spec.js2
-rw-r--r--spec/frontend/issues/create_merge_request_dropdown_spec.js122
-rw-r--r--spec/frontend/issues/list/components/issue_card_time_info_spec.js122
-rw-r--r--spec/frontend/issues/list/components/issues_list_app_spec.js829
-rw-r--r--spec/frontend/issues/list/components/jira_issues_import_status_app_spec.js117
-rw-r--r--spec/frontend/issues/list/components/new_issue_dropdown_spec.js131
-rw-r--r--spec/frontend/issues/list/mock_data.js (renamed from spec/frontend/issues_list/mock_data.js)0
-rw-r--r--spec/frontend/issues/list/utils_spec.js127
-rw-r--r--spec/frontend/issues/new/components/title_suggestions_spec.js14
-rw-r--r--spec/frontend/issues/sentry_error_stack_trace/components/sentry_error_stack_trace_spec.js82
-rw-r--r--spec/frontend/issues/show/components/fields/type_spec.js18
-rw-r--r--spec/frontend/issues/show/components/header_actions_spec.js19
-rw-r--r--spec/frontend/issues/show/components/sentry_error_stack_trace_spec.js81
-rw-r--r--spec/frontend/issues/show/issue_spec.js6
-rw-r--r--spec/frontend/issues_list/components/__snapshots__/issuables_list_app_spec.js.snap14
-rw-r--r--spec/frontend/issues_list/components/issuable_spec.js508
-rw-r--r--spec/frontend/issues_list/components/issuables_list_app_spec.js653
-rw-r--r--spec/frontend/issues_list/components/issue_card_time_info_spec.js122
-rw-r--r--spec/frontend/issues_list/components/issues_list_app_spec.js829
-rw-r--r--spec/frontend/issues_list/components/jira_issues_import_status_app_spec.js117
-rw-r--r--spec/frontend/issues_list/components/new_issue_dropdown_spec.js131
-rw-r--r--spec/frontend/issues_list/issuable_list_test_data.js77
-rw-r--r--spec/frontend/issues_list/service_desk_helper_spec.js28
-rw-r--r--spec/frontend/issues_list/utils_spec.js127
-rw-r--r--spec/frontend/jira_import/utils/jira_import_utils_spec.js2
-rw-r--r--spec/frontend/jobs/bridge/app_spec.js123
-rw-r--r--spec/frontend/jobs/bridge/components/empty_state_spec.js7
-rw-r--r--spec/frontend/jobs/bridge/components/sidebar_spec.js97
-rw-r--r--spec/frontend/jobs/bridge/mock_data.js101
-rw-r--r--spec/frontend/jobs/components/table/job_table_app_spec.js2
-rw-r--r--spec/frontend/labels/delete_label_modal_spec.js33
-rw-r--r--spec/frontend/landing_spec.js184
-rw-r--r--spec/frontend/lib/utils/resize_observer_spec.js68
-rw-r--r--spec/frontend/line_highlighter_spec.js275
-rw-r--r--spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap2
-rw-r--r--spec/frontend/monitoring/components/charts/time_series_spec.js2
-rw-r--r--spec/frontend/monitoring/components/dashboard_spec.js2
-rw-r--r--spec/frontend/monitoring/components/dashboards_dropdown_spec.js2
-rw-r--r--spec/frontend/mr_popover/mr_popover_spec.js4
-rw-r--r--spec/frontend/notes/components/comment_form_spec.js4
-rw-r--r--spec/frontend/notes/components/note_form_spec.js2
-rw-r--r--spec/frontend/notifications/components/custom_notifications_modal_spec.js6
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/__snapshots__/registry_breadcrumb_spec.js.snap84
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js76
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/empty_state_spec.js54
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js21
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js100
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/registry_breadcrumb_spec.js78
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js19
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/__snapshots__/file_sha_spec.js.snap5
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/file_sha_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/__snapshots__/packages_list_app_spec.js.snap8
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js8
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/conan_installation_spec.js.snap14
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/file_sha_spec.js.snap5
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/maven_installation_spec.js.snap42
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/npm_installation_spec.js.snap14
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/nuget_installation_spec.js.snap14
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap24
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/app_spec.js408
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/composer_installation_spec.js8
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/conan_installation_spec.js23
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/file_sha_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/maven_installation_spec.js30
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/npm_installation_spec.js28
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/nuget_installation_spec.js18
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/package_files_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/pypi_installation_spec.js22
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/__snapshots__/package_list_row_spec.js.snap10
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js23
-rw-r--r--spec/frontend/packages_and_registries/package_registry/mock_data.js11
-rw-r--r--spec/frontend/packages_and_registries/package_registry/pages/__snapshots__/list_spec.js.snap8
-rw-r--r--spec/frontend/packages_and_registries/package_registry/pages/details_spec.js426
-rw-r--r--spec/frontend/packages_and_registries/shared/components/__snapshots__/publish_method_spec.js.snap (renamed from spec/frontend/packages_and_registries/shared/__snapshots__/publish_method_spec.js.snap)0
-rw-r--r--spec/frontend/packages_and_registries/shared/components/__snapshots__/registry_breadcrumb_spec.js.snap96
-rw-r--r--spec/frontend/packages_and_registries/shared/components/package_icon_and_name_spec.js (renamed from spec/frontend/packages_and_registries/shared/package_icon_and_name_spec.js)0
-rw-r--r--spec/frontend/packages_and_registries/shared/components/package_path_spec.js (renamed from spec/frontend/packages_and_registries/shared/package_path_spec.js)0
-rw-r--r--spec/frontend/packages_and_registries/shared/components/package_tags_spec.js (renamed from spec/frontend/packages_and_registries/shared/package_tags_spec.js)0
-rw-r--r--spec/frontend/packages_and_registries/shared/components/packages_list_loader_spec.js (renamed from spec/frontend/packages_and_registries/shared/packages_list_loader_spec.js)0
-rw-r--r--spec/frontend/packages_and_registries/shared/components/persisted_search_spec.js145
-rw-r--r--spec/frontend/packages_and_registries/shared/components/publish_method_spec.js (renamed from spec/frontend/packages_and_registries/shared/publish_method_spec.js)0
-rw-r--r--spec/frontend/packages_and_registries/shared/components/registry_breadcrumb_spec.js78
-rw-r--r--spec/frontend/pages/dashboard/todos/index/todos_spec.js4
-rw-r--r--spec/frontend/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js6
-rw-r--r--spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js42
-rw-r--r--spec/frontend/pages/shared/nav/sidebar_tracking_spec.js36
-rw-r--r--spec/frontend/pages/shared/wikis/components/wiki_form_spec.js211
-rw-r--r--spec/frontend/pipeline_editor/components/editor/text_editor_spec.js40
-rw-r--r--spec/frontend/pipeline_editor/components/header/validation_segment_spec.js64
-rw-r--r--spec/frontend/pipeline_editor/components/ui/editor_tab_spec.js89
-rw-r--r--spec/frontend/pipeline_editor/mock_data.js1
-rw-r--r--spec/frontend/pipeline_editor/pipeline_editor_app_spec.js131
-rw-r--r--spec/frontend/pipelines/__snapshots__/utils_spec.js.snap29
-rw-r--r--spec/frontend/pipelines/graph/mock_data.js125
-rw-r--r--spec/frontend/profile/account/components/update_username_spec.js2
-rw-r--r--spec/frontend/profile/add_ssh_key_validation_spec.js36
-rw-r--r--spec/frontend/project_find_file_spec.js91
-rw-r--r--spec/frontend/project_select_combo_button_spec.js4
-rw-r--r--spec/frontend/projects/commits/components/author_select_spec.js10
-rw-r--r--spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js2
-rw-r--r--spec/frontend/projects/project_find_file_spec.js91
-rw-r--r--spec/frontend/repository/components/blob_button_group_spec.js47
-rw-r--r--spec/frontend/repository/components/blob_content_viewer_spec.js28
-rw-r--r--spec/frontend/repository/components/blob_controls_spec.js88
-rw-r--r--spec/frontend/repository/components/breadcrumbs_spec.js8
-rw-r--r--spec/frontend/repository/components/last_commit_spec.js2
-rw-r--r--spec/frontend/repository/components/preview/index_spec.js6
-rw-r--r--spec/frontend/repository/components/table/index_spec.js2
-rw-r--r--spec/frontend/repository/components/table/row_spec.js2
-rw-r--r--spec/frontend/repository/components/tree_content_spec.js8
-rw-r--r--spec/frontend/repository/components/upload_blob_modal_spec.js4
-rw-r--r--spec/frontend/repository/mock_data.js23
-rw-r--r--spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js88
-rw-r--r--spec/frontend/runner/admin_runners/admin_runners_app_spec.js116
-rw-r--r--spec/frontend/runner/components/cells/runner_actions_cell_spec.js66
-rw-r--r--spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js40
-rw-r--r--spec/frontend/runner/components/runner_header_spec.js93
-rw-r--r--spec/frontend/runner/components/runner_list_spec.js4
-rw-r--r--spec/frontend/runner/components/runner_status_badge_spec.js20
-rw-r--r--spec/frontend/runner/components/runner_type_alert_spec.js61
-rw-r--r--spec/frontend/runner/components/runner_update_form_spec.js12
-rw-r--r--spec/frontend/runner/components/search_tokens/tag_token_spec.js6
-rw-r--r--spec/frontend/runner/components/stat/runner_online_stat_spec.js34
-rw-r--r--spec/frontend/runner/components/stat/runner_stats_spec.js46
-rw-r--r--spec/frontend/runner/components/stat/runner_status_stat_spec.js67
-rw-r--r--spec/frontend/runner/group_runners/group_runners_app_spec.js50
-rw-r--r--spec/frontend/runner/mock_data.js4
-rw-r--r--spec/frontend/runner/runner_detail/runner_details_app_spec.js87
-rw-r--r--spec/frontend/runner/runner_detail/runner_update_form_utils_spec.js96
-rw-r--r--spec/frontend/runner/runner_search_utils_spec.js18
-rw-r--r--spec/frontend/runner/runner_update_form_utils_spec.js93
-rw-r--r--spec/frontend/search/topbar/components/searchable_dropdown_spec.js4
-rw-r--r--spec/frontend/security_configuration/components/app_spec.js38
-rw-r--r--spec/frontend/security_configuration/components/training_provider_list_spec.js181
-rw-r--r--spec/frontend/security_configuration/mock_data.js25
-rw-r--r--spec/frontend/serverless/components/__snapshots__/empty_state_spec.js.snap8
-rw-r--r--spec/frontend/set_status_modal/set_status_modal_wrapper_spec.js11
-rw-r--r--spec/frontend/sidebar/components/reviewers/uncollapsed_reviewer_list_spec.js8
-rw-r--r--spec/frontend/sidebar/participants_spec.js8
-rw-r--r--spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap2
-rw-r--r--spec/frontend/snippets/components/snippet_blob_view_spec.js2
-rw-r--r--spec/frontend/snippets/components/snippet_header_spec.js2
-rw-r--r--spec/frontend/static_site_editor/components/edit_area_spec.js4
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/modals/add_image/add_image_modal_spec.js4
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_identifier_paragraph_spec.js2
-rw-r--r--spec/frontend/terraform/components/states_table_actions_spec.js2
-rw-r--r--spec/frontend/tracking/tracking_initialization_spec.js5
-rw-r--r--spec/frontend/transfer_edit_spec.js31
-rw-r--r--spec/frontend/version_check_image_spec.js42
-rw-r--r--spec/frontend/vue_mr_widget/components/approvals/approvals_spec.js2
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_header_spec.js4
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_rebase_spec.js209
-rw-r--r--spec/frontend/vue_mr_widget/components/states/merge_checks_failed_spec.js29
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js4
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_commits_header_spec.js4
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js2
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js2
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js8
-rw-r--r--spec/frontend/vue_mr_widget/components/terraform/mock_data.js6
-rw-r--r--spec/frontend/vue_mr_widget/components/terraform/mr_widget_terraform_container_spec.js2
-rw-r--r--spec/frontend/vue_mr_widget/extentions/terraform/index_spec.js178
-rw-r--r--spec/frontend/vue_mr_widget/mock_data.js2
-rw-r--r--spec/frontend/vue_mr_widget/mr_widget_options_spec.js69
-rw-r--r--spec/frontend/vue_mr_widget/stores/mr_widget_store_spec.js2
-rw-r--r--spec/frontend/vue_mr_widget/test_extensions.js10
-rw-r--r--spec/frontend/vue_shared/alert_details/alert_details_spec.js2
-rw-r--r--spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_assignees_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/chronic_duration_input_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/clipboard_button_spec.js72
-rw-r--r--spec/frontend/vue_shared/components/confirm_danger/confirm_danger_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js22
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js14
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/branch_token_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/gitlab_version_check_spec.js77
-rw-r--r--spec/frontend/vue_shared/components/line_numbers_spec.js36
-rw-r--r--spec/frontend/vue_shared/components/markdown/field_spec.js36
-rw-r--r--spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/registry/__snapshots__/code_instruction_spec.js.snap11
-rw-r--r--spec/frontend/vue_shared/components/registry/code_instruction_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/sidebar/issuable_move_dropdown_spec.js24
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js8
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js24
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js26
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js13
-rw-r--r--spec/frontend/vue_shared/components/source_viewer_spec.js47
-rw-r--r--spec/frontend/vue_shared/components/web_ide_link_spec.js155
-rw-r--r--spec/frontend/vue_shared/directives/track_event_spec.js2
-rw-r--r--spec/frontend/vue_shared/issuable/list/components/issuable_list_root_spec.js6
-rw-r--r--spec/frontend/vue_shared/issuable/list/components/issuable_tabs_spec.js5
-rw-r--r--spec/frontend/vue_shared/issuable/list/mock_data.js2
-rw-r--r--spec/frontend/vue_shared/issuable/show/components/issuable_title_spec.js2
-rw-r--r--spec/frontend/work_items/pages/work_item_root_spec.js31
-rw-r--r--spec/graphql/mutations/ci/runner/delete_spec.rb14
-rw-r--r--spec/graphql/mutations/clusters/agent_tokens/revoke_spec.rb55
-rw-r--r--spec/graphql/mutations/customer_relations/contacts/create_spec.rb15
-rw-r--r--spec/graphql/mutations/customer_relations/contacts/update_spec.rb2
-rw-r--r--spec/graphql/mutations/customer_relations/organizations/create_spec.rb2
-rw-r--r--spec/graphql/mutations/customer_relations/organizations/update_spec.rb13
-rw-r--r--spec/graphql/mutations/issues/set_escalation_status_spec.rb66
-rw-r--r--spec/graphql/resolvers/clusters/agent_tokens_resolver_spec.rb9
-rw-r--r--spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb20
-rw-r--r--spec/graphql/resolvers/merge_requests_resolver_spec.rb22
-rw-r--r--spec/graphql/resolvers/users/groups_resolver_spec.rb8
-rw-r--r--spec/graphql/resolvers/work_items/types_resolver_spec.rb22
-rw-r--r--spec/graphql/types/ci/config/config_type_spec.rb1
-rw-r--r--spec/graphql/types/ci/job_type_spec.rb1
-rw-r--r--spec/graphql/types/ci/pipeline_message_type_spec.rb15
-rw-r--r--spec/graphql/types/ci/pipeline_type_spec.rb2
-rw-r--r--spec/graphql/types/ci/runner_type_spec.rb4
-rw-r--r--spec/graphql/types/clusters/agent_token_status_enum_spec.rb8
-rw-r--r--spec/graphql/types/clusters/agent_token_type_spec.rb2
-rw-r--r--spec/graphql/types/commit_type_spec.rb2
-rw-r--r--spec/graphql/types/group_member_relation_enum_spec.rb2
-rw-r--r--spec/graphql/types/group_type_spec.rb2
-rw-r--r--spec/graphql/types/incident_management/escalation_status_enum_spec.rb25
-rw-r--r--spec/graphql/types/issue_type_spec.rb47
-rw-r--r--spec/graphql/types/merge_request_type_spec.rb26
-rw-r--r--spec/graphql/types/mutation_type_spec.rb8
-rw-r--r--spec/graphql/types/packages/package_details_type_spec.rb5
-rw-r--r--spec/graphql/types/project_type_spec.rb3
-rw-r--r--spec/graphql/types/projects/service_type_spec.rb2
-rw-r--r--spec/graphql/types/repository/blob_type_spec.rb6
-rw-r--r--spec/helpers/admin/background_migrations_helper_spec.rb16
-rw-r--r--spec/helpers/application_helper_spec.rb40
-rw-r--r--spec/helpers/application_settings_helper_spec.rb26
-rw-r--r--spec/helpers/auth_helper_spec.rb6
-rw-r--r--spec/helpers/auto_devops_helper_spec.rb2
-rw-r--r--spec/helpers/button_helper_spec.rb1
-rw-r--r--spec/helpers/ci/jobs_helper_spec.rb10
-rw-r--r--spec/helpers/ci/pipeline_editor_helper_spec.rb2
-rw-r--r--spec/helpers/ci/runners_helper_spec.rb9
-rw-r--r--spec/helpers/environment_helper_spec.rb10
-rw-r--r--spec/helpers/environments_helper_spec.rb2
-rw-r--r--spec/helpers/groups/crm_settings_helper_spec.rb25
-rw-r--r--spec/helpers/hooks_helper_spec.rb10
-rw-r--r--spec/helpers/integrations_helper_spec.rb28
-rw-r--r--spec/helpers/issues_helper_spec.rb23
-rw-r--r--spec/helpers/learn_gitlab_helper_spec.rb13
-rw-r--r--spec/helpers/namespaces_helper_spec.rb38
-rw-r--r--spec/helpers/nav/top_nav_helper_spec.rb23
-rw-r--r--spec/helpers/operations_helper_spec.rb2
-rw-r--r--spec/helpers/packages_helper_spec.rb41
-rw-r--r--spec/helpers/projects/cluster_agents_helper_spec.rb5
-rw-r--r--spec/helpers/projects/issues/service_desk_helper_spec.rb54
-rw-r--r--spec/helpers/search_helper_spec.rb3
-rw-r--r--spec/helpers/snippets_helper_spec.rb3
-rw-r--r--spec/helpers/ssh_keys_helper_spec.rb25
-rw-r--r--spec/helpers/tree_helper_spec.rb18
-rw-r--r--spec/helpers/version_check_helper_spec.rb47
-rw-r--r--spec/initializers/doorkeeper_spec.rb2
-rw-r--r--spec/initializers/session_store_spec.rb36
-rw-r--r--spec/lib/api/entities/ci/pipeline_spec.rb21
-rw-r--r--spec/lib/api/entities/merge_request_basic_spec.rb3
-rw-r--r--spec/lib/api/helpers/rate_limiter_spec.rb73
-rw-r--r--spec/lib/backup/artifacts_spec.rb2
-rw-r--r--spec/lib/backup/files_spec.rb4
-rw-r--r--spec/lib/backup/gitaly_backup_spec.rb32
-rw-r--r--spec/lib/backup/gitaly_rpc_backup_spec.rb10
-rw-r--r--spec/lib/backup/lfs_spec.rb27
-rw-r--r--spec/lib/backup/manager_spec.rb6
-rw-r--r--spec/lib/backup/object_backup_spec.rb36
-rw-r--r--spec/lib/backup/repositories_spec.rb12
-rw-r--r--spec/lib/backup/repository_backup_error_spec.rb42
-rw-r--r--spec/lib/backup/uploads_spec.rb3
-rw-r--r--spec/lib/banzai/filter/footnote_filter_spec.rb46
-rw-r--r--spec/lib/banzai/filter/markdown_filter_spec.rb153
-rw-r--r--spec/lib/banzai/filter/plantuml_filter_spec.rb72
-rw-r--r--spec/lib/banzai/filter/references/issue_reference_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/references/merge_request_reference_filter_spec.rb5
-rw-r--r--spec/lib/banzai/filter/sanitization_filter_spec.rb47
-rw-r--r--spec/lib/banzai/filter/syntax_highlight_filter_spec.rb238
-rw-r--r--spec/lib/banzai/pipeline/full_pipeline_spec.rb41
-rw-r--r--spec/lib/banzai/pipeline/plain_markdown_pipeline_spec.rb156
-rw-r--r--spec/lib/banzai/reference_parser/merge_request_parser_spec.rb8
-rw-r--r--spec/lib/bulk_imports/common/extractors/ndjson_extractor_spec.rb6
-rw-r--r--spec/lib/bulk_imports/common/pipelines/uploads_pipeline_spec.rb31
-rw-r--r--spec/lib/bulk_imports/projects/pipelines/project_attributes_pipeline_spec.rb27
-rw-r--r--spec/lib/error_tracking/collector/payload_validator_spec.rb32
-rw-r--r--spec/lib/feature_spec.rb32
-rw-r--r--spec/lib/gitlab/asciidoc_spec.rb1371
-rw-r--r--spec/lib/gitlab/auth/auth_finders_spec.rb30
-rw-r--r--spec/lib/gitlab/auth/ldap/config_spec.rb30
-rw-r--r--spec/lib/gitlab/auth_spec.rb30
-rw-r--r--spec/lib/gitlab/background_migration/backfill_artifact_expiry_date_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/backfill_ci_namespace_mirrors_spec.rb45
-rw-r--r--spec/lib/gitlab/background_migration/backfill_ci_project_mirrors_spec.rb46
-rw-r--r--spec/lib/gitlab/background_migration/backfill_incident_issue_escalation_statuses_spec.rb27
-rw-r--r--spec/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/backfill_project_updated_at_after_repository_storage_move_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/base_job_spec.rb16
-rw-r--r--spec/lib/gitlab/background_migration/cleanup_concurrent_schema_change_spec.rb28
-rw-r--r--spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/encrypt_static_object_token_spec.rb56
-rw-r--r--spec/lib/gitlab/background_migration/fix_vulnerability_occurrences_with_hashes_as_raw_metadata_spec.rb232
-rw-r--r--spec/lib/gitlab/background_migration/job_coordinator_spec.rb45
-rw-r--r--spec/lib/gitlab/background_migration/migrate_legacy_artifacts_spec.rb158
-rw-r--r--spec/lib/gitlab/background_migration/migrate_u2f_webauthn_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/move_container_registry_enabled_to_project_feature_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/populate_issue_email_participants_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb468
-rw-r--r--spec/lib/gitlab/background_migration/remove_duplicate_services_spec.rb121
-rw-r--r--spec/lib/gitlab/background_migration/remove_vulnerability_finding_links_spec.rb4
-rw-r--r--spec/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer_spec.rb2
-rw-r--r--spec/lib/gitlab/checks/changes_access_spec.rb80
-rw-r--r--spec/lib/gitlab/ci/build/status/reason_spec.rb75
-rw-r--r--spec/lib/gitlab/ci/config/entry/root_spec.rb46
-rw-r--r--spec/lib/gitlab/ci/jwt_v2_spec.rb34
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/create_deployments_spec.rb14
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/create_spec.rb13
-rw-r--r--spec/lib/gitlab/ci/pipeline/logger_spec.rb84
-rw-r--r--spec/lib/gitlab/ci/pipeline/seed/build_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/seed/pipeline_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/waiting_for_approval_spec.rb49
-rw-r--r--spec/lib/gitlab/ci/tags/bulk_insert_spec.rb47
-rw-r--r--spec/lib/gitlab/ci/trace/remote_checksum_spec.rb8
-rw-r--r--spec/lib/gitlab/ci/variables/builder_spec.rb196
-rw-r--r--spec/lib/gitlab/ci/yaml_processor_spec.rb36
-rw-r--r--spec/lib/gitlab/color_schemes_spec.rb2
-rw-r--r--spec/lib/gitlab/config/entry/configurable_spec.rb9
-rw-r--r--spec/lib/gitlab/config/entry/factory_spec.rb11
-rw-r--r--spec/lib/gitlab/content_security_policy/config_loader_spec.rb6
-rw-r--r--spec/lib/gitlab/data_builder/archive_trace_spec.rb19
-rw-r--r--spec/lib/gitlab/data_builder/deployment_spec.rb1
-rw-r--r--spec/lib/gitlab/database/background_migration/batched_migration_spec.rb27
-rw-r--r--spec/lib/gitlab/database/background_migration_job_spec.rb2
-rw-r--r--spec/lib/gitlab/database/batch_count_spec.rb76
-rw-r--r--spec/lib/gitlab/database/bulk_update_spec.rb2
-rw-r--r--spec/lib/gitlab/database/loose_index_scan_distinct_count_spec.rb71
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb112
-rw-r--r--spec/lib/gitlab/database/migrations/background_migration_helpers_spec.rb626
-rw-r--r--spec/lib/gitlab/database/migrations/runner_spec.rb2
-rw-r--r--spec/lib/gitlab/database/no_cross_db_foreign_keys_spec.rb81
-rw-r--r--spec/lib/gitlab/database/partitioning/partition_manager_spec.rb3
-rw-r--r--spec/lib/gitlab/database/partitioning/sliding_list_strategy_spec.rb7
-rw-r--r--spec/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table_spec.rb43
-rw-r--r--spec/lib/gitlab/database/reflection_spec.rb60
-rw-r--r--spec/lib/gitlab/database/reindexing/coordinator_spec.rb76
-rw-r--r--spec/lib/gitlab/email/failure_handler_spec.rb69
-rw-r--r--spec/lib/gitlab/error_tracking/processor/sidekiq_processor_spec.rb9
-rw-r--r--spec/lib/gitlab/event_store/event_spec.rb64
-rw-r--r--spec/lib/gitlab/event_store/store_spec.rb262
-rw-r--r--spec/lib/gitlab/exceptions_app_spec.rb68
-rw-r--r--spec/lib/gitlab/gfm/reference_rewriter_spec.rb2
-rw-r--r--spec/lib/gitlab/git_access_spec.rb8
-rw-r--r--spec/lib/gitlab/gpg/commit_spec.rb24
-rw-r--r--spec/lib/gitlab/http_spec.rb34
-rw-r--r--spec/lib/gitlab/import/set_async_jid_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml4
-rw-r--r--spec/lib/gitlab/import_export/avatar_saver_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/base/relation_factory_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/design_repo_restorer_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/group/relation_tree_restorer_spec.rb41
-rw-r--r--spec/lib/gitlab/import_export/project/relation_factory_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/project/relation_tree_restorer_spec.rb41
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml1
-rw-r--r--spec/lib/gitlab/import_export/uploads_saver_spec.rb4
-rw-r--r--spec/lib/gitlab/integrations/sti_type_spec.rb12
-rw-r--r--spec/lib/gitlab/jwt_authenticatable_spec.rb163
-rw-r--r--spec/lib/gitlab/lets_encrypt/client_spec.rb2
-rw-r--r--spec/lib/gitlab/lfs/client_spec.rb87
-rw-r--r--spec/lib/gitlab/logger_spec.rb94
-rw-r--r--spec/lib/gitlab/mail_room/authenticator_spec.rb188
-rw-r--r--spec/lib/gitlab/mail_room/mail_room_spec.rb63
-rw-r--r--spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb322
-rw-r--r--spec/lib/gitlab/metrics/exporter/base_exporter_spec.rb74
-rw-r--r--spec/lib/gitlab/metrics/exporter/gc_request_middleware_spec.rb21
-rw-r--r--spec/lib/gitlab/metrics/exporter/health_checks_middleware_spec.rb52
-rw-r--r--spec/lib/gitlab/metrics/exporter/metrics_middleware_spec.rb39
-rw-r--r--spec/lib/gitlab/metrics/exporter/sidekiq_exporter_spec.rb53
-rw-r--r--spec/lib/gitlab/metrics/exporter/web_exporter_spec.rb6
-rw-r--r--spec/lib/gitlab/metrics/samplers/action_cable_sampler_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb4
-rw-r--r--spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb2
-rw-r--r--spec/lib/gitlab/middleware/go_spec.rb2
-rw-r--r--spec/lib/gitlab/middleware/webhook_recursion_detection_spec.rb42
-rw-r--r--spec/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_column_data_spec.rb35
-rw-r--r--spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb73
-rw-r--r--spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/order_values_loader_strategy_spec.rb37
-rw-r--r--spec/lib/gitlab/redis/multi_store_spec.rb676
-rw-r--r--spec/lib/gitlab/redis/sessions_spec.rb73
-rw-r--r--spec/lib/gitlab/regex_spec.rb2
-rw-r--r--spec/lib/gitlab/search/params_spec.rb8
-rw-r--r--spec/lib/gitlab/shard_health_cache_spec.rb6
-rw-r--r--spec/lib/gitlab/sherlock/collection_spec.rb84
-rw-r--r--spec/lib/gitlab/sherlock/file_sample_spec.rb56
-rw-r--r--spec/lib/gitlab/sherlock/line_profiler_spec.rb75
-rw-r--r--spec/lib/gitlab/sherlock/line_sample_spec.rb35
-rw-r--r--spec/lib/gitlab/sherlock/location_spec.rb42
-rw-r--r--spec/lib/gitlab/sherlock/middleware_spec.rb81
-rw-r--r--spec/lib/gitlab/sherlock/query_spec.rb115
-rw-r--r--spec/lib/gitlab/sherlock/transaction_spec.rb238
-rw-r--r--spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb10
-rw-r--r--spec/lib/gitlab/sidekiq_status_spec.rb40
-rw-r--r--spec/lib/gitlab/sourcegraph_spec.rb6
-rw-r--r--spec/lib/gitlab/ssh_public_key_spec.rb41
-rw-r--r--spec/lib/gitlab/themes_spec.rb2
-rw-r--r--spec/lib/gitlab/tracking/standard_context_spec.rb4
-rw-r--r--spec/lib/gitlab/usage/metrics/instrumentations/database_metric_spec.rb4
-rw-r--r--spec/lib/gitlab/usage/metrics/instrumentations/generic_metric_spec.rb40
-rw-r--r--spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb3
-rw-r--r--spec/lib/gitlab/usage_data_counters/package_event_counter_spec.rb8
-rw-r--r--spec/lib/gitlab/usage_data_queries_spec.rb4
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb77
-rw-r--r--spec/lib/gitlab/utils/usage_data_spec.rb55
-rw-r--r--spec/lib/gitlab/web_hooks/recursion_detection_spec.rb221
-rw-r--r--spec/lib/gitlab_edition_spec.rb160
-rw-r--r--spec/lib/gitlab_spec.rb131
-rw-r--r--spec/lib/sidebars/groups/menus/settings_menu_spec.rb6
-rw-r--r--spec/lib/sidebars/projects/panel_spec.rb3
-rw-r--r--spec/lib/version_check_spec.rb6
-rw-r--r--spec/mailers/emails/profile_spec.rb2
-rw-r--r--spec/mailers/notify_spec.rb10
-rw-r--r--spec/metrics_server/metrics_server_spec.rb42
-rw-r--r--spec/migrations/20210112143418_remove_duplicate_services2_spec.rb52
-rw-r--r--spec/migrations/20210119122354_alter_vsa_issue_first_mentioned_in_commit_value_spec.rb30
-rw-r--r--spec/migrations/20210205174154_remove_bad_dependency_proxy_manifests_spec.rb28
-rw-r--r--spec/migrations/20210210093901_backfill_updated_at_after_repository_storage_move_spec.rb47
-rw-r--r--spec/migrations/20210218040814_add_environment_scope_to_group_variables_spec.rb46
-rw-r--r--spec/migrations/20210226141517_dedup_issue_metrics_spec.rb66
-rw-r--r--spec/migrations/20210918202855_reschedule_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb30
-rw-r--r--spec/migrations/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb44
-rw-r--r--spec/migrations/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4_spec.rb148
-rw-r--r--spec/migrations/20211210140629_encrypt_static_object_token_spec.rb50
-rw-r--r--spec/migrations/20211214012507_backfill_incident_issue_escalation_statuses_spec.rb36
-rw-r--r--spec/migrations/20211217174331_mark_recalculate_finding_signatures_as_completed_spec.rb64
-rw-r--r--spec/migrations/add_has_external_issue_tracker_trigger_spec.rb164
-rw-r--r--spec/migrations/add_has_external_wiki_trigger_spec.rb128
-rw-r--r--spec/migrations/add_new_post_eoa_plans_spec.rb32
-rw-r--r--spec/migrations/cleanup_after_add_primary_email_to_emails_if_user_confirmed_spec.rb48
-rw-r--r--spec/migrations/cleanup_projects_with_bad_has_external_issue_tracker_data_spec.rb94
-rw-r--r--spec/migrations/cleanup_projects_with_bad_has_external_wiki_data_spec.rb89
-rw-r--r--spec/migrations/drop_alerts_service_data_spec.rb21
-rw-r--r--spec/migrations/migrate_delayed_project_removal_from_namespaces_to_namespace_settings_spec.rb30
-rw-r--r--spec/migrations/remove_alerts_service_records_again_spec.rb23
-rw-r--r--spec/migrations/remove_alerts_service_records_spec.rb30
-rw-r--r--spec/migrations/reschedule_artifact_expiry_backfill_spec.rb38
-rw-r--r--spec/migrations/schedule_migrate_pages_to_zip_storage_spec.rb2
-rw-r--r--spec/migrations/schedule_populate_finding_uuid_for_vulnerability_feedback_spec.rb37
-rw-r--r--spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences2_spec.rb127
-rw-r--r--spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences3_spec.rb127
-rw-r--r--spec/migrations/update_application_settings_protected_paths_spec.rb46
-rw-r--r--spec/migrations/update_invalid_member_states_spec.rb30
-rw-r--r--spec/models/alert_management/alert_spec.rb33
-rw-r--r--spec/models/application_record_spec.rb10
-rw-r--r--spec/models/application_setting_spec.rb46
-rw-r--r--spec/models/bulk_imports/file_transfer/project_config_spec.rb6
-rw-r--r--spec/models/ci/build_report_result_spec.rb5
-rw-r--r--spec/models/ci/build_spec.rb228
-rw-r--r--spec/models/ci/build_trace_chunk_spec.rb11
-rw-r--r--spec/models/ci/daily_build_group_report_result_spec.rb12
-rw-r--r--spec/models/ci/freeze_period_spec.rb5
-rw-r--r--spec/models/ci/group_variable_spec.rb6
-rw-r--r--spec/models/ci/job_artifact_spec.rb27
-rw-r--r--spec/models/ci/job_token/project_scope_link_spec.rb5
-rw-r--r--spec/models/ci/namespace_mirror_spec.rb107
-rw-r--r--spec/models/ci/pending_build_spec.rb10
-rw-r--r--spec/models/ci/pipeline_artifact_spec.rb7
-rw-r--r--spec/models/ci/pipeline_schedule_spec.rb5
-rw-r--r--spec/models/ci/pipeline_spec.rb46
-rw-r--r--spec/models/ci/project_mirror_spec.rb34
-rw-r--r--spec/models/ci/resource_group_spec.rb5
-rw-r--r--spec/models/ci/runner_namespace_spec.rb6
-rw-r--r--spec/models/ci/runner_spec.rb112
-rw-r--r--spec/models/ci/running_build_spec.rb5
-rw-r--r--spec/models/ci/secure_file_spec.rb55
-rw-r--r--spec/models/ci/unit_test_spec.rb5
-rw-r--r--spec/models/clusters/agent_spec.rb27
-rw-r--r--spec/models/clusters/agent_token_spec.rb97
-rw-r--r--spec/models/clusters/agents/activity_event_spec.rb23
-rw-r--r--spec/models/clusters/applications/runner_spec.rb13
-rw-r--r--spec/models/commit_status_spec.rb49
-rw-r--r--spec/models/concerns/issuable_spec.rb16
-rw-r--r--spec/models/concerns/participable_spec.rb25
-rw-r--r--spec/models/concerns/routable_spec.rb33
-rw-r--r--spec/models/concerns/triggerable_hooks_spec.rb2
-rw-r--r--spec/models/container_repository_spec.rb8
-rw-r--r--spec/models/customer_relations/contact_spec.rb45
-rw-r--r--spec/models/customer_relations/issue_contact_spec.rb21
-rw-r--r--spec/models/dependency_proxy/blob_spec.rb1
-rw-r--r--spec/models/dependency_proxy/manifest_spec.rb1
-rw-r--r--spec/models/email_spec.rb82
-rw-r--r--spec/models/experiment_spec.rb48
-rw-r--r--spec/models/group/crm_settings_spec.rb15
-rw-r--r--spec/models/group_group_link_spec.rb26
-rw-r--r--spec/models/group_spec.rb384
-rw-r--r--spec/models/hooks/project_hook_spec.rb9
-rw-r--r--spec/models/hooks/service_hook_spec.rb30
-rw-r--r--spec/models/hooks/system_hook_spec.rb2
-rw-r--r--spec/models/instance_configuration_spec.rb4
-rw-r--r--spec/models/integration_spec.rb294
-rw-r--r--spec/models/integrations/asana_spec.rb132
-rw-r--r--spec/models/integrations/datadog_spec.rb33
-rw-r--r--spec/models/integrations/jira_spec.rb12
-rw-r--r--spec/models/internal_id_spec.rb6
-rw-r--r--spec/models/issue_spec.rb48
-rw-r--r--spec/models/key_spec.rb22
-rw-r--r--spec/models/member_spec.rb1
-rw-r--r--spec/models/merge_request_spec.rb83
-rw-r--r--spec/models/namespace_setting_spec.rb53
-rw-r--r--spec/models/namespace_spec.rb28
-rw-r--r--spec/models/namespaces/project_namespace_spec.rb4
-rw-r--r--spec/models/onboarding_progress_spec.rb85
-rw-r--r--spec/models/packages/package_file_spec.rb70
-rw-r--r--spec/models/packages/package_spec.rb19
-rw-r--r--spec/models/pages_domain_spec.rb123
-rw-r--r--spec/models/preloaders/environments/deployment_preloader_spec.rb65
-rw-r--r--spec/models/project_pages_metadatum_spec.rb11
-rw-r--r--spec/models/project_spec.rb412
-rw-r--r--spec/models/protectable_dropdown_spec.rb74
-rw-r--r--spec/models/ref_matcher_spec.rb83
-rw-r--r--spec/models/repository_spec.rb11
-rw-r--r--spec/models/route_spec.rb1
-rw-r--r--spec/models/user_spec.rb329
-rw-r--r--spec/models/users_statistics_spec.rb2
-rw-r--r--spec/models/work_item/type_spec.rb55
-rw-r--r--spec/models/work_items/type_spec.rb87
-rw-r--r--spec/policies/blob_policy_spec.rb7
-rw-r--r--spec/policies/group_member_policy_spec.rb18
-rw-r--r--spec/policies/group_policy_spec.rb186
-rw-r--r--spec/policies/project_policy_spec.rb4
-rw-r--r--spec/presenters/blob_presenter_spec.rb20
-rw-r--r--spec/presenters/label_presenter_spec.rb25
-rw-r--r--spec/presenters/packages/conan/package_presenter_spec.rb34
-rw-r--r--spec/presenters/packages/detail/package_presenter_spec.rb22
-rw-r--r--spec/presenters/packages/npm/package_presenter_spec.rb21
-rw-r--r--spec/presenters/packages/nuget/package_metadata_presenter_spec.rb14
-rw-r--r--spec/presenters/packages/nuget/search_results_presenter_spec.rb4
-rw-r--r--spec/presenters/packages/pypi/package_presenter_spec.rb16
-rw-r--r--spec/presenters/project_presenter_spec.rb2
-rw-r--r--spec/presenters/projects/security/configuration_presenter_spec.rb2
-rw-r--r--spec/presenters/service_hook_presenter_spec.rb4
-rw-r--r--spec/presenters/web_hook_log_presenter_spec.rb4
-rw-r--r--spec/rake_helper.rb2
-rw-r--r--spec/requests/api/ci/job_artifacts_spec.rb65
-rw-r--r--spec/requests/api/ci/runner/runners_post_spec.rb423
-rw-r--r--spec/requests/api/ci/runners_spec.rb12
-rw-r--r--spec/requests/api/ci/triggers_spec.rb2
-rw-r--r--spec/requests/api/commits_spec.rb8
-rw-r--r--spec/requests/api/generic_packages_spec.rb21
-rw-r--r--spec/requests/api/graphql/ci/config_spec.rb18
-rw-r--r--spec/requests/api/graphql/ci/jobs_spec.rb8
-rw-r--r--spec/requests/api/graphql/ci/pipelines_spec.rb108
-rw-r--r--spec/requests/api/graphql/ci/runner_spec.rb6
-rw-r--r--spec/requests/api/graphql/group/group_members_spec.rb11
-rw-r--r--spec/requests/api/graphql/group/work_item_types_spec.rb71
-rw-r--r--spec/requests/api/graphql/mutations/issues/set_crm_contacts_spec.rb103
-rw-r--r--spec/requests/api/graphql/mutations/issues/set_escalation_status_spec.rb82
-rw-r--r--spec/requests/api/graphql/mutations/work_items/create_spec.rb63
-rw-r--r--spec/requests/api/graphql/packages/package_spec.rb238
-rw-r--r--spec/requests/api/graphql/project/issues_spec.rb37
-rw-r--r--spec/requests/api/graphql/project/work_item_types_spec.rb71
-rw-r--r--spec/requests/api/groups_spec.rb48
-rw-r--r--spec/requests/api/integrations_spec.rb6
-rw-r--r--spec/requests/api/internal/base_spec.rb75
-rw-r--r--spec/requests/api/internal/kubernetes_spec.rb6
-rw-r--r--spec/requests/api/internal/mail_room_spec.rb194
-rw-r--r--spec/requests/api/lint_spec.rb19
-rw-r--r--spec/requests/api/maven_packages_spec.rb2
-rw-r--r--spec/requests/api/merge_requests_spec.rb35
-rw-r--r--spec/requests/api/package_files_spec.rb50
-rw-r--r--spec/requests/api/projects_spec.rb49
-rw-r--r--spec/requests/api/resource_access_tokens_spec.rb187
-rw-r--r--spec/requests/api/rubygem_packages_spec.rb28
-rw-r--r--spec/requests/api/search_spec.rb24
-rw-r--r--spec/requests/api/terraform/modules/v1/packages_spec.rb37
-rw-r--r--spec/requests/api/usage_data_non_sql_metrics_spec.rb1
-rw-r--r--spec/requests/api/usage_data_queries_spec.rb1
-rw-r--r--spec/requests/api/users_spec.rb67
-rw-r--r--spec/requests/git_http_spec.rb4
-rw-r--r--spec/requests/groups/crm/contacts_controller_spec.rb16
-rw-r--r--spec/requests/groups/crm/organizations_controller_spec.rb16
-rw-r--r--spec/requests/groups/settings/access_tokens_controller_spec.rb90
-rw-r--r--spec/requests/projects/google_cloud/deployments_controller_spec.rb103
-rw-r--r--spec/requests/projects/merge_requests/context_commit_diffs_spec.rb1
-rw-r--r--spec/requests/projects/merge_requests/diffs_spec.rb16
-rw-r--r--spec/requests/projects/merge_requests_discussions_spec.rb2
-rw-r--r--spec/requests/projects/settings/access_tokens_controller_spec.rb91
-rw-r--r--spec/requests/rack_attack_global_spec.rb14
-rw-r--r--spec/requests/recursive_webhook_detection_spec.rb182
-rw-r--r--spec/requests/sandbox_controller_spec.rb14
-rw-r--r--spec/requests/users_controller_spec.rb13
-rw-r--r--spec/routing/routing_spec.rb6
-rw-r--r--spec/rubocop/code_reuse_helpers_spec.rb73
-rw-r--r--spec/rubocop/cop/database/establish_connection_spec.rb29
-rw-r--r--spec/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction_spec.rb58
-rw-r--r--spec/rubocop/cop/migration/schedule_async_spec.rb32
-rw-r--r--spec/scripts/setup/find_jh_branch_spec.rb97
-rw-r--r--spec/serializers/analytics_build_entity_spec.rb8
-rw-r--r--spec/serializers/analytics_issue_entity_spec.rb8
-rw-r--r--spec/serializers/environment_serializer_spec.rb36
-rw-r--r--spec/serializers/group_child_entity_spec.rb4
-rw-r--r--spec/serializers/pipeline_serializer_spec.rb2
-rw-r--r--spec/services/alert_management/alerts/update_service_spec.rb53
-rw-r--r--spec/services/audit_event_service_spec.rb11
-rw-r--r--spec/services/auth/container_registry_authentication_service_spec.rb53
-rw-r--r--spec/services/branches/delete_merged_service_spec.rb2
-rw-r--r--spec/services/bulk_imports/archive_extraction_service_spec.rb6
-rw-r--r--spec/services/bulk_imports/file_decompression_service_spec.rb18
-rw-r--r--spec/services/bulk_imports/file_download_service_spec.rb32
-rw-r--r--spec/services/bulk_imports/file_export_service_spec.rb16
-rw-r--r--spec/services/bulk_imports/lfs_objects_export_service_spec.rb70
-rw-r--r--spec/services/chat_names/authorize_user_service_spec.rb6
-rw-r--r--spec/services/chat_names/find_user_service_spec.rb2
-rw-r--r--spec/services/ci/after_requeue_job_service_spec.rb2
-rw-r--r--spec/services/ci/archive_trace_service_spec.rb19
-rw-r--r--spec/services/ci/create_downstream_pipeline_service_spec.rb6
-rw-r--r--spec/services/ci/create_pipeline_service/cache_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/custom_config_content_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/custom_yaml_tags_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/dry_run_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/include_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/logger_spec.rb8
-rw-r--r--spec/services/ci/create_pipeline_service/merge_requests_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/needs_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/parallel_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/parameter_content_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/pre_post_stages_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/rules_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/tags_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service_spec.rb126
-rw-r--r--spec/services/ci/destroy_pipeline_service_spec.rb24
-rw-r--r--spec/services/ci/job_artifacts/delete_project_artifacts_service_spec.rb17
-rw-r--r--spec/services/ci/job_artifacts/destroy_all_expired_service_spec.rb47
-rw-r--r--spec/services/ci/job_artifacts/expire_project_build_artifacts_service_spec.rb157
-rw-r--r--spec/services/ci/pipeline_processing/atomic_processing_service_spec.rb4
-rw-r--r--spec/services/ci/pipelines/add_job_service_spec.rb2
-rw-r--r--spec/services/ci/play_build_service_spec.rb14
-rw-r--r--spec/services/ci/process_sync_events_service_spec.rb26
-rw-r--r--spec/services/ci/register_job_service_spec.rb28
-rw-r--r--spec/services/ci/register_runner_service_spec.rb226
-rw-r--r--spec/services/ci/retry_build_service_spec.rb26
-rw-r--r--spec/services/clusters/agent_tokens/track_usage_service_spec.rb84
-rw-r--r--spec/services/clusters/agents/create_activity_event_service_spec.rb44
-rw-r--r--spec/services/clusters/agents/delete_expired_events_service_spec.rb36
-rw-r--r--spec/services/clusters/integrations/create_service_spec.rb2
-rw-r--r--spec/services/customer_relations/contacts/create_service_spec.rb4
-rw-r--r--spec/services/customer_relations/contacts/update_service_spec.rb4
-rw-r--r--spec/services/customer_relations/organizations/create_service_spec.rb2
-rw-r--r--spec/services/customer_relations/organizations/update_service_spec.rb4
-rw-r--r--spec/services/dependency_proxy/download_blob_service_spec.rb59
-rw-r--r--spec/services/dependency_proxy/find_cached_manifest_service_spec.rb4
-rw-r--r--spec/services/dependency_proxy/find_or_create_blob_service_spec.rb71
-rw-r--r--spec/services/deployments/archive_in_project_service_spec.rb11
-rw-r--r--spec/services/deployments/create_for_build_service_spec.rb82
-rw-r--r--spec/services/discussions/update_diff_position_service_spec.rb2
-rw-r--r--spec/services/error_tracking/collect_error_service_spec.rb41
-rw-r--r--spec/services/events/destroy_service_spec.rb16
-rw-r--r--spec/services/feature_flags/hook_service_spec.rb2
-rw-r--r--spec/services/git/process_ref_changes_service_spec.rb10
-rw-r--r--spec/services/google_cloud/create_service_accounts_service_spec.rb45
-rw-r--r--spec/services/google_cloud/service_accounts_service_spec.rb19
-rw-r--r--spec/services/groups/update_service_spec.rb64
-rw-r--r--spec/services/import/gitlab_projects/create_project_from_remote_file_service_spec.rb51
-rw-r--r--spec/services/import/validate_remote_git_endpoint_service_spec.rb11
-rw-r--r--spec/services/incident_management/incidents/create_service_spec.rb6
-rw-r--r--spec/services/incident_management/issuable_escalation_statuses/after_update_service_spec.rb56
-rw-r--r--spec/services/incident_management/issuable_escalation_statuses/prepare_update_service_spec.rb108
-rw-r--r--spec/services/integrations/test/project_service_spec.rb2
-rw-r--r--spec/services/issues/build_service_spec.rb6
-rw-r--r--spec/services/issues/create_service_spec.rb21
-rw-r--r--spec/services/issues/move_service_spec.rb10
-rw-r--r--spec/services/issues/set_crm_contacts_service_spec.rb2
-rw-r--r--spec/services/issues/update_service_spec.rb123
-rw-r--r--spec/services/labels/transfer_service_spec.rb12
-rw-r--r--spec/services/members/destroy_service_spec.rb2
-rw-r--r--spec/services/members/invite_service_spec.rb2
-rw-r--r--spec/services/merge_requests/base_service_spec.rb2
-rw-r--r--spec/services/merge_requests/squash_service_spec.rb2
-rw-r--r--spec/services/merge_requests/update_service_spec.rb2
-rw-r--r--spec/services/notes/create_service_spec.rb2
-rw-r--r--spec/services/notification_service_spec.rb8
-rw-r--r--spec/services/packages/create_event_service_spec.rb18
-rw-r--r--spec/services/packages/maven/metadata/sync_service_spec.rb18
-rw-r--r--spec/services/packages/terraform_module/create_package_service_spec.rb2
-rw-r--r--spec/services/projects/create_service_spec.rb3
-rw-r--r--spec/services/projects/destroy_service_spec.rb7
-rw-r--r--spec/services/projects/fork_service_spec.rb4
-rw-r--r--spec/services/projects/prometheus/alerts/notify_service_spec.rb72
-rw-r--r--spec/services/projects/repository_languages_service_spec.rb2
-rw-r--r--spec/services/projects/update_pages_configuration_service_spec.rb76
-rw-r--r--spec/services/projects/update_remote_mirror_service_spec.rb78
-rw-r--r--spec/services/projects/update_service_spec.rb48
-rw-r--r--spec/services/protected_branches/create_service_spec.rb2
-rw-r--r--spec/services/protected_branches/destroy_service_spec.rb2
-rw-r--r--spec/services/protected_branches/update_service_spec.rb2
-rw-r--r--spec/services/protected_tags/create_service_spec.rb2
-rw-r--r--spec/services/protected_tags/destroy_service_spec.rb2
-rw-r--r--spec/services/protected_tags/update_service_spec.rb2
-rw-r--r--spec/services/quick_actions/interpret_service_spec.rb2
-rw-r--r--spec/services/resource_access_tokens/create_service_spec.rb58
-rw-r--r--spec/services/resource_access_tokens/revoke_service_spec.rb102
-rw-r--r--spec/services/service_ping/submit_service_ping_service_spec.rb2
-rw-r--r--spec/services/test_hooks/system_service_spec.rb2
-rw-r--r--spec/services/users/create_service_spec.rb14
-rw-r--r--spec/services/users/refresh_authorized_projects_service_spec.rb2
-rw-r--r--spec/services/users/upsert_credit_card_validation_service_spec.rb8
-rw-r--r--spec/services/verify_pages_domain_service_spec.rb50
-rw-r--r--spec/services/web_hook_service_spec.rb139
-rw-r--r--spec/services/work_items/build_service_spec.rb20
-rw-r--r--spec/services/work_items/create_service_spec.rb72
-rw-r--r--spec/simplecov_env.rb1
-rw-r--r--spec/spec_helper.rb21
-rw-r--r--spec/support/database/cross-database-modification-allowlist.yml32
-rw-r--r--spec/support/db_cleaner.rb2
-rw-r--r--spec/support/flaky_tests.rb2
-rw-r--r--spec/support/gitlab_stubs/gitlab_ci.yml8
-rw-r--r--spec/support/helpers/cycle_analytics_helpers.rb2
-rw-r--r--spec/support/helpers/gitaly_setup.rb204
-rw-r--r--spec/support/helpers/login_helpers.rb2
-rw-r--r--spec/support/helpers/stub_gitlab_calls.rb7
-rw-r--r--spec/support/helpers/stub_object_storage.rb6
-rw-r--r--spec/support/helpers/test_env.rb132
-rw-r--r--spec/support/helpers/usage_data_helpers.rb4
-rw-r--r--spec/support/import_export/export_file_helper.rb2
-rw-r--r--spec/support/praefect.rb4
-rw-r--r--spec/support/shared_contexts/navbar_structure_context.rb1
-rw-r--r--spec/support/shared_contexts/policies/group_policy_shared_context.rb39
-rw-r--r--spec/support/shared_contexts/policies/project_policy_shared_context.rb2
-rw-r--r--spec/support/shared_examples/controllers/access_tokens_controller_shared_examples.rb124
-rw-r--r--spec/support/shared_examples/controllers/create_notes_rate_limit_shared_examples.rb43
-rw-r--r--spec/support/shared_examples/controllers/rate_limited_endpoint_shared_examples.rb57
-rw-r--r--spec/support/shared_examples/features/access_tokens_shared_examples.rb165
-rw-r--r--spec/support/shared_examples/features/packages_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/features/sidebar/sidebar_labels_shared_examples.rb127
-rw-r--r--spec/support/shared_examples/features/sidebar_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/finders/snippet_visibility_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/graphql/mutation_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/graphql/mutations/issues/permission_check_shared_examples.rb44
-rw-r--r--spec/support/shared_examples/graphql/mutations/merge_requests/permission_check_shared_examples.rb50
-rw-r--r--spec/support/shared_examples/lib/gitlab/database/background_migration_job_shared_examples.rb10
-rw-r--r--spec/support/shared_examples/lib/gitlab/redis/multi_store_feature_flags_shared_examples.rb43
-rw-r--r--spec/support/shared_examples/lib/gitlab/unique_ip_check_shared_examples.rb16
-rw-r--r--spec/support/shared_examples/loose_foreign_keys/have_loose_foreign_key.rb10
-rw-r--r--spec/support/shared_examples/metrics/sampler_shared_examples.rb84
-rw-r--r--spec/support/shared_examples/models/application_setting_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/models/concerns/incident_management/escalatable_shared_examples.rb33
-rw-r--r--spec/support/shared_examples/models/concerns/integrations/slack_mattermost_notifier_shared_examples.rb231
-rw-r--r--spec/support/shared_examples/models/concerns/packages/destructible_shared_examples.rb18
-rw-r--r--spec/support/shared_examples/models/concerns/ttl_expirable_shared_examples.rb13
-rw-r--r--spec/support/shared_examples/models/member_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/models/packages/debian/distribution_shared_examples.rb21
-rw-r--r--spec/support/shared_examples/models/update_project_statistics_shared_examples.rb6
-rw-r--r--spec/support/shared_examples/namespaces/traversal_scope_examples.rb25
-rw-r--r--spec/support/shared_examples/requests/access_tokens_controller_shared_examples.rb138
-rw-r--r--spec/support/shared_examples/requests/api/debian_packages_shared_examples.rb1
-rw-r--r--spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb24
-rw-r--r--spec/support/shared_examples/requests/api/nuget_endpoints_shared_examples.rb1
-rw-r--r--spec/support/shared_examples/services/alert_management_shared_examples.rb6
-rw-r--r--spec/support/shared_examples/services/container_registry_auth_service_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/services/incident_shared_examples.rb16
-rw-r--r--spec/support/shared_examples/services/service_ping/service_ping_payload_with_all_expected_metrics_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/services/service_ping/service_ping_payload_without_restricted_metrics_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/work_item_base_types_importer.rb4
-rw-r--r--spec/support/shared_examples/workers/concerns/dependency_proxy/cleanup_worker_shared_examples.rb14
-rw-r--r--spec/support/system_exit_detected.rb15
-rw-r--r--spec/support_specs/database/multiple_databases_spec.rb12
-rw-r--r--spec/tasks/gitlab/backup_rake_spec.rb108
-rw-r--r--spec/tasks/gitlab/db_rake_spec.rb4
-rw-r--r--spec/tasks/gitlab/password_rake_spec.rb8
-rw-r--r--spec/tasks/gitlab/usage_data_rake_spec.rb1
-rw-r--r--spec/tooling/danger/datateam_spec.rb113
-rw-r--r--spec/tooling/danger/project_helper_spec.rb2
-rw-r--r--spec/tooling/docs/deprecation_handling_spec.rb40
-rw-r--r--spec/uploaders/ci/secure_file_uploader_spec.rb72
-rw-r--r--spec/views/admin/dashboard/index.html.haml_spec.rb13
-rw-r--r--spec/views/groups/edit.html.haml_spec.rb48
-rw-r--r--spec/views/help/index.html.haml_spec.rb1
-rw-r--r--spec/views/layouts/header/_gitlab_version.html.haml_spec.rb16
-rw-r--r--spec/views/profiles/keys/_form.html.haml_spec.rb6
-rw-r--r--spec/views/projects/commits/_commit.html.haml_spec.rb2
-rw-r--r--spec/views/projects/edit.html.haml_spec.rb24
-rw-r--r--spec/views/projects/merge_requests/show.html.haml_spec.rb28
-rw-r--r--spec/views/projects/services/_form.haml_spec.rb30
-rw-r--r--spec/views/shared/access_tokens/_table.html.haml_spec.rb24
-rw-r--r--spec/views/shared/nav/_sidebar.html.haml_spec.rb3
-rw-r--r--spec/views/shared/wikis/_sidebar.html.haml_spec.rb2
-rw-r--r--spec/workers/ci/build_finished_worker_spec.rb15
-rw-r--r--spec/workers/ci/job_artifacts/expire_project_build_artifacts_worker_spec.rb32
-rw-r--r--spec/workers/clusters/agents/delete_expired_events_worker_spec.rb30
-rw-r--r--spec/workers/concerns/application_worker_spec.rb67
-rw-r--r--spec/workers/concerns/cluster_agent_queue_spec.rb19
-rw-r--r--spec/workers/concerns/packages/cleanup_artifact_worker_spec.rb36
-rw-r--r--spec/workers/dependency_proxy/cleanup_dependency_proxy_worker_spec.rb4
-rw-r--r--spec/workers/dependency_proxy/image_ttl_group_policy_worker_spec.rb12
-rw-r--r--spec/workers/deployments/hooks_worker_spec.rb4
-rw-r--r--spec/workers/email_receiver_worker_spec.rb78
-rw-r--r--spec/workers/every_sidekiq_worker_spec.rb3
-rw-r--r--spec/workers/loose_foreign_keys/cleanup_worker_spec.rb28
-rw-r--r--spec/workers/merge_requests/update_head_pipeline_worker_spec.rb138
-rw-r--r--spec/workers/metrics/dashboard/sync_dashboards_worker_spec.rb30
-rw-r--r--spec/workers/packages/cleanup_package_file_worker_spec.rb64
-rw-r--r--spec/workers/packages/cleanup_package_registry_worker_spec.rb57
-rw-r--r--spec/workers/pages_update_configuration_worker_spec.rb53
-rw-r--r--spec/workers/pages_worker_spec.rb16
-rw-r--r--spec/workers/purge_dependency_proxy_cache_worker_spec.rb6
-rw-r--r--spec/workers/web_hook_worker_spec.rb9
-rwxr-xr-xtooling/bin/find_changes2
-rw-r--r--tooling/danger/datateam.rb58
-rw-r--r--tooling/danger/project_helper.rb1
-rw-r--r--tooling/deprecations/docs.rb39
-rw-r--r--tooling/docs/deprecation_handling.rb42
-rw-r--r--workhorse/.gitignore1
-rw-r--r--workhorse/Makefile24
-rw-r--r--workhorse/internal/proxy/proxy.go20
-rw-r--r--workhorse/internal/upstream/upstream.go8
-rw-r--r--workhorse/internal/upstream/upstream_test.go17
-rw-r--r--workhorse/proxy_test.go22
-rw-r--r--yarn.lock714
3951 files changed, 129799 insertions, 58466 deletions
diff --git a/.dockerignore b/.dockerignore
index d20c733313d..b2aef4d31cd 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -5,7 +5,7 @@
# Following are the files we need:
# - ./config/initializers/0_inject_enterprise_edition_module.rb
# - ./ee/app/models/license.rb
-# - ./lib/gitlab.rb
+# - ./lib/gitlab_edition.rb
# - ./lib/gitlab/utils.rb
# - ./qa/
# - ./INSTALLATION_TYPE
diff --git a/.eslintrc.yml b/.eslintrc.yml
index 0f73a9c5105..e80b2e6d9eb 100644
--- a/.eslintrc.yml
+++ b/.eslintrc.yml
@@ -99,6 +99,10 @@ overrides:
rules:
'@gitlab/require-i18n-strings': off
'@gitlab/no-runtime-template-compiler': off
+ 'no-restricted-syntax':
+ - error
+ - selector: CallExpression[callee.object.name=/(wrapper|vm)/][callee.property.name="setData"]
+ message: 'Avoid using "setData" on VTU wrapper'
- files:
- 'config/**/*'
- 'scripts/**/*'
diff --git a/.gitignore b/.gitignore
index 0a7808601ea..03f77ed89e5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,7 @@
eslint-report.html
/.gitlab_shell_secret
.idea
+.nova
/.vscode/*
/.rbenv-version
.rbx/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 405346d68da..314f99c5f41 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -80,6 +80,7 @@ variables:
CACHE_CLASSES: "true"
CHECK_PRECOMPILED_ASSETS: "true"
FF_USE_FASTZIP: "true"
+ SKIP_FLAKY_TESTS_AUTOMATICALLY: "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 5eb96d1addd..71e4571b603 100644
--- a/.gitlab/CODEOWNERS
+++ b/.gitlab/CODEOWNERS
@@ -6,161 +6,6 @@
*.rb @gitlab-org/maintainers/rails-backend
*.rake @gitlab-org/maintainers/rails-backend
-[Documentation Directories]
-.markdownlint.yml @marcel.amirault @eread @aqualls @cnorris
-/doc/.markdownlint @marcel.amirault @eread @aqualls @cnorris
-/doc/ @gl-docsteam
-/doc/.vale/ @marcel.amirault @eread @aqualls @cnorris
-/doc/administration/geo/ @axil
-/doc/administration/gitaly/ @eread
-/doc/administration/lfs/ @aqualls
-/doc/administration/monitoring/ @ngaskill
-/doc/administration/operations/ @axil @eread @marcia
-/doc/administration/packages/ @ngaskill
-/doc/administration/pages/ @rdickenson @kpaizee
-/doc/administration/postgresql/ @marcia
-/doc/administration/raketasks/ @axil @eread
-/doc/administration/redis/ @axil
-/doc/administration/reference_architectures/ @axil
-/doc/administration/snippets/ @aqualls
-/doc/administration/troubleshooting @axil @marcia @eread
-/doc/api/graphql/ @msedlakjakubowski @kpaizee
-/doc/api/graphql/reference/ @kpaizee
-/doc/api/group_activity_analytics.md @fneill
-/doc/api/vulnerabilities.md @fneill
-/doc/ci/ @marcel.amirault @sselhorn
-/doc/ci/environments/ @rdickenson
-/doc/ci/services/ @sselhorn
-/doc/ci/test_cases/ @msedlakjakubowski
-/doc/development/ @marcia
-/doc/development/documentation/ @cnorris @dianalogan
-/doc/development/i18n/ @ngaskill
-/doc/development/value_stream_analytics.md @fneill
-/doc/gitlab-basics/ @aqualls
-/doc/install/ @axil
-/doc/operations/ @ngaskill @rdickenson
-/doc/push_rules/ @aqualls
-/doc/security/ @eread
-/doc/ssh/ @eread
-/doc/subscriptions/ @sselhorn
-/doc/topics/autodevops/ @marcia
-/doc/topics/git/ @aqualls
-/doc/update/ @axil @marcia
-/doc/user/analytics/ @fneill @ngaskill
-/doc/user/application_security/ @rdickenson
-/doc/user/application_security/container_scanning/ @ngaskill
-/doc/user/application_security/cluster_image_scanning/ @ngaskill
-/doc/user/application_security/cve_id_request.md @fneill
-/doc/user/application_security/security_dashboard @fneill
-/doc/user/application_security/vulnerabilities @fneill
-/doc/user/application_security/vulnerability_report @fneill
-/doc/user/clusters/ @marcia
-/doc/user/compliance/ @rdickenson @eread
-/doc/user/group/ @msedlakjakubowski
-/doc/user/group/devops_adoption/ @fneill
-/doc/user/group/epics/ @msedlakjakubowski
-/doc/user/group/insights/ @fneill
-/doc/user/group/iterations/ @msedlakjakubowski
-/doc/user/group/roadmap/ @msedlakjakubowski
-/doc/user/group/value_stream_analytics/ @fneill
-/doc/user/infrastructure/ @marcia
-/doc/user/packages/ @ngaskill
-/doc/user/packages/infrastructure_registry/ @marcia
-/doc/user/packages/terraform_module_registry/ @marcia
-/doc/user/profile/ @msedlakjakubowski @eread
-/doc/user/project/ @aqualls @rdickenson @eread @msedlakjakubowski @ngaskill
-/doc/user/project/clusters/ @marcia
-/doc/user/project/import/ @ngaskill @msedlakjakubowski
-/doc/user/project/issues/ @msedlakjakubowski
-/doc/user/project/merge_requests/ @aqualls @eread
-/doc/user/project/milestones/ @msedlakjakubowski
-/doc/user/project/pages/ @rdickenson
-/doc/user/project/repository/ @aqualls
-/doc/user/project/settings/ @aqualls @eread
-/doc/user/project/static_site_editor/index.md @aqualls
-/doc/user/project/web_ide/index.md @aqualls
-/doc/user/project/wiki/index.md @aqualls
-/doc/user/search/ @marcia @aqualls
-/doc/user/workspace/ @fneill
-
-[Docs Create]
-/doc/administration/file_hooks.md @aqualls
-/doc/administration/git_protocol.md @aqualls
-/doc/administration/invalidate_markdown_cache.md @aqualls
-/doc/administration/issue_closing_pattern.md @aqualls
-/doc/administration/merge_request_diffs.md @aqualls
-/doc/administration/repository_checks.md @aqualls
-/doc/administration/static_objects_external_storage.md @aqualls
-/doc/api/access_requests.md @aqualls
-/doc/api/branches.md @aqualls
-/doc/api/commits.md @aqualls
-/doc/api/discussions.md @aqualls
-/doc/api/group_wikis.md @aqualls
-/doc/api/keys.md @aqualls
-/doc/api/markdown.md @aqualls
-/doc/api/merge_request_approvals.md @aqualls
-/doc/api/merge_request_context_commits.md @aqualls
-/doc/api/merge_requests.md @aqualls
-/doc/api/project_aliases.md @aqualls
-/doc/api/project_badges.md @aqualls
-/doc/api/project_import_export.md @aqualls
-/doc/api/project_level_variables.md @aqualls
-/doc/api/project_snippets.md @aqualls
-/doc/api/project_statistics.md @aqualls
-/doc/api/project_templates.md @aqualls
-/doc/api/project_vulnerabilities.md @aqualls
-/doc/api/protected_branches.md @aqualls
-/doc/api/protected_tags.md @aqualls
-/doc/api/remote_mirrors.md @aqualls
-/doc/api/repositories.md @aqualls
-/doc/api/repository_files.md @aqualls
-/doc/api/repository_submodules.md @aqualls
-/doc/api/search.md @aqualls
-/doc/api/services.md @aqualls
-/doc/api/snippets.md @aqualls
-/doc/api/suggestions.md @aqualls
-/doc/api/tags.md @aqualls
-/doc/api/visual_review_discussions.md @aqualls
-/doc/api/wikis.md @aqualls
-/doc/intro/index.md @aqualls
-/doc/topics/gitlab_flow.md @aqualls
-/doc/user/admin_area/settings/account_and_limit_settings.md @aqualls
-/doc/user/admin_area/settings/instance_template_repository.md @aqualls
-/doc/user/admin_area/settings/project_integration_management.md @aqualls
-/doc/user/admin_area/settings/push_event_activities_limit.md @aqualls
-/doc/user/admin_area/settings/visibility_and_access_controls.md @aqualls
-/doc/user/asciidoc.md @aqualls
-/doc/user/index.md @aqualls
-/doc/user/markdown.md @aqualls
-/doc/user/project/autocomplete_characters.md @aqualls
-/doc/user/project/badges.md @aqualls
-/doc/user/project/code_intelligence.md @aqualls
-/doc/user/project/code_owners.md @aqualls
-/doc/user/project/file_lock.md @aqualls
-/doc/user/project/git_attributes.md @aqualls
-/doc/user/project/highlighting.md @aqualls
-/doc/user/project/index.md @aqualls
-/doc/user/project/protected_branches.md @aqualls
-/doc/user/project/protected_tags.md @aqualls
-/doc/user/project/push_options.md @aqualls
-/doc/user/project/settings/import_export.md @aqualls
-/doc/user/snippets.md @aqualls
-
-[Docs Ecosystem]
-/doc/administration/integration/ @kpaizee
-/doc/integration/ @kpaizee
-/doc/user/project/integrations/ @kpaizee
-/doc/user/project/integrations/prometheus_library/ @ngaskill
-
-[Docs Growth]
-/doc/administration/instance_review.md @kpaizee
-/doc/api/invitations.md @kpaizee
-/doc/api/experiments.md @kpaizee
-/doc/development/experiment_guide/ @kpaizee
-/doc/development/snowplow/ @fneill
-/doc/development/service_ping/ @fneill
-/doc/user/admin_area/license.md @kpaizee
-
[Frontend]
*.scss @annabeldunstone @gitlab-org/maintainers/frontend
*.js @gitlab-org/maintainers/frontend
@@ -357,3 +202,158 @@ ee/lib/ee/gitlab/git_access.rb @proglottis @toon @zj-gitlab
ee/lib/ee/gitlab/git_access_*.rb @proglottis @toon @zj-gitlab
ee/lib/ee/gitlab/checks/** @proglottis @toon @zj-gitlab
lib/gitlab/checks/** @proglottis @toon @zj-gitlab
+
+[Documentation Directories]
+.markdownlint.yml @marcel.amirault @eread @aqualls @cnorris
+/doc/.markdownlint @marcel.amirault @eread @aqualls @cnorris
+/doc/ @gl-docsteam
+/doc/.vale/ @marcel.amirault @eread @aqualls @cnorris
+/doc/administration/geo/ @axil
+/doc/administration/gitaly/ @eread
+/doc/administration/lfs/ @aqualls
+/doc/administration/monitoring/ @ngaskill
+/doc/administration/operations/ @axil @eread @marcia
+/doc/administration/packages/ @ngaskill
+/doc/administration/pages/ @rdickenson @kpaizee
+/doc/administration/postgresql/ @marcia
+/doc/administration/raketasks/ @axil @eread
+/doc/administration/redis/ @axil
+/doc/administration/reference_architectures/ @axil
+/doc/administration/snippets/ @aqualls
+/doc/administration/troubleshooting @axil @marcia @eread
+/doc/api/graphql/ @msedlakjakubowski @kpaizee
+/doc/api/graphql/reference/ @kpaizee
+/doc/api/group_activity_analytics.md @fneill
+/doc/api/vulnerabilities.md @fneill
+/doc/ci/ @marcel.amirault @sselhorn
+/doc/ci/environments/ @rdickenson
+/doc/ci/services/ @sselhorn
+/doc/ci/test_cases/ @msedlakjakubowski
+/doc/development/ @marcia
+/doc/development/documentation/ @cnorris @dianalogan
+/doc/development/i18n/ @ngaskill
+/doc/development/value_stream_analytics.md @fneill
+/doc/gitlab-basics/ @aqualls
+/doc/install/ @axil
+/doc/operations/ @ngaskill @rdickenson
+/doc/push_rules/ @aqualls
+/doc/security/ @eread
+/doc/ssh/ @eread
+/doc/subscriptions/ @sselhorn
+/doc/topics/autodevops/ @marcia
+/doc/topics/git/ @aqualls
+/doc/update/ @axil @marcia
+/doc/user/analytics/ @fneill @ngaskill
+/doc/user/application_security/ @rdickenson
+/doc/user/application_security/container_scanning/ @ngaskill
+/doc/user/application_security/cluster_image_scanning/ @ngaskill
+/doc/user/application_security/cve_id_request.md @fneill
+/doc/user/application_security/security_dashboard @fneill
+/doc/user/application_security/vulnerabilities @fneill
+/doc/user/application_security/vulnerability_report @fneill
+/doc/user/clusters/ @marcia
+/doc/user/compliance/ @rdickenson @eread
+/doc/user/group/ @msedlakjakubowski
+/doc/user/group/devops_adoption/ @fneill
+/doc/user/group/epics/ @msedlakjakubowski
+/doc/user/group/insights/ @fneill
+/doc/user/group/iterations/ @msedlakjakubowski
+/doc/user/group/roadmap/ @msedlakjakubowski
+/doc/user/group/value_stream_analytics/ @fneill
+/doc/user/infrastructure/ @marcia
+/doc/user/packages/ @ngaskill
+/doc/user/packages/infrastructure_registry/ @marcia
+/doc/user/packages/terraform_module_registry/ @marcia
+/doc/user/profile/ @msedlakjakubowski @eread
+/doc/user/project/ @aqualls @rdickenson @eread @msedlakjakubowski @ngaskill
+/doc/user/project/clusters/ @marcia
+/doc/user/project/import/ @ngaskill @msedlakjakubowski
+/doc/user/project/issues/ @msedlakjakubowski
+/doc/user/project/merge_requests/ @aqualls @eread
+/doc/user/project/milestones/ @msedlakjakubowski
+/doc/user/project/pages/ @rdickenson
+/doc/user/project/repository/ @aqualls
+/doc/user/project/settings/ @aqualls @eread
+/doc/user/project/static_site_editor/index.md @aqualls
+/doc/user/project/web_ide/index.md @aqualls
+/doc/user/project/wiki/index.md @aqualls
+/doc/user/search/ @marcia @aqualls
+/doc/user/workspace/ @fneill
+
+[Docs Create]
+/doc/administration/file_hooks.md @aqualls
+/doc/administration/git_protocol.md @aqualls
+/doc/administration/invalidate_markdown_cache.md @aqualls
+/doc/administration/issue_closing_pattern.md @aqualls
+/doc/administration/merge_request_diffs.md @aqualls
+/doc/administration/repository_checks.md @aqualls
+/doc/administration/static_objects_external_storage.md @aqualls
+/doc/api/access_requests.md @aqualls
+/doc/api/branches.md @aqualls
+/doc/api/commits.md @aqualls
+/doc/api/discussions.md @aqualls
+/doc/api/group_wikis.md @aqualls
+/doc/api/keys.md @aqualls
+/doc/api/markdown.md @aqualls
+/doc/api/merge_request_approvals.md @aqualls
+/doc/api/merge_request_context_commits.md @aqualls
+/doc/api/merge_requests.md @aqualls
+/doc/api/project_aliases.md @aqualls
+/doc/api/project_badges.md @aqualls
+/doc/api/project_import_export.md @aqualls
+/doc/api/project_level_variables.md @aqualls
+/doc/api/project_snippets.md @aqualls
+/doc/api/project_statistics.md @aqualls
+/doc/api/project_templates.md @aqualls
+/doc/api/project_vulnerabilities.md @aqualls
+/doc/api/protected_branches.md @aqualls
+/doc/api/protected_tags.md @aqualls
+/doc/api/remote_mirrors.md @aqualls
+/doc/api/repositories.md @aqualls
+/doc/api/repository_files.md @aqualls
+/doc/api/repository_submodules.md @aqualls
+/doc/api/search.md @aqualls
+/doc/api/services.md @aqualls
+/doc/api/snippets.md @aqualls
+/doc/api/suggestions.md @aqualls
+/doc/api/tags.md @aqualls
+/doc/api/visual_review_discussions.md @aqualls
+/doc/api/wikis.md @aqualls
+/doc/intro/index.md @aqualls
+/doc/topics/gitlab_flow.md @aqualls
+/doc/user/admin_area/settings/account_and_limit_settings.md @aqualls
+/doc/user/admin_area/settings/instance_template_repository.md @aqualls
+/doc/user/admin_area/settings/project_integration_management.md @aqualls
+/doc/user/admin_area/settings/push_event_activities_limit.md @aqualls
+/doc/user/admin_area/settings/visibility_and_access_controls.md @aqualls
+/doc/user/asciidoc.md @aqualls
+/doc/user/index.md @aqualls
+/doc/user/markdown.md @aqualls
+/doc/user/project/autocomplete_characters.md @aqualls
+/doc/user/project/badges.md @aqualls
+/doc/user/project/code_intelligence.md @aqualls
+/doc/user/project/code_owners.md @aqualls
+/doc/user/project/file_lock.md @aqualls
+/doc/user/project/git_attributes.md @aqualls
+/doc/user/project/highlighting.md @aqualls
+/doc/user/project/index.md @aqualls
+/doc/user/project/protected_branches.md @aqualls
+/doc/user/project/protected_tags.md @aqualls
+/doc/user/project/push_options.md @aqualls
+/doc/user/project/settings/import_export.md @aqualls
+/doc/user/snippets.md @aqualls
+
+[Docs Ecosystem]
+/doc/administration/integration/ @kpaizee
+/doc/integration/ @kpaizee
+/doc/user/project/integrations/ @kpaizee
+/doc/user/project/integrations/prometheus_library/ @ngaskill
+
+[Docs Growth]
+/doc/administration/instance_review.md @kpaizee
+/doc/api/invitations.md @kpaizee
+/doc/api/experiments.md @kpaizee
+/doc/development/experiment_guide/ @kpaizee
+/doc/development/snowplow/ @fneill
+/doc/development/service_ping/ @fneill
+/doc/user/admin_area/license.md @kpaizee
diff --git a/.gitlab/ci/docs.gitlab-ci.yml b/.gitlab/ci/docs.gitlab-ci.yml
index ae36c0cea70..c439e9a7c80 100644
--- a/.gitlab/ci/docs.gitlab-ci.yml
+++ b/.gitlab/ci/docs.gitlab-ci.yml
@@ -44,7 +44,7 @@ docs-lint markdown:
- .default-retry
- .docs:rules:docs-lint
# When updating the image version here, update it in /scripts/lint-doc.sh too.
- image: registry.gitlab.com/gitlab-org/gitlab-docs/lint-markdown:alpine-3.14-vale-2.12.0-markdownlint-0.29.0
+ image: registry.gitlab.com/gitlab-org/gitlab-docs/lint-markdown:alpine-3.15-vale-2.14.0-markdownlint-0.30.0
stage: lint
needs: []
script:
@@ -53,7 +53,7 @@ docs-lint markdown:
docs-lint links:
extends:
- .docs:rules:docs-lint
- image: registry.gitlab.com/gitlab-org/gitlab-docs/lint-html:alpine-3.14-ruby-2.7.5-08847baa
+ image: registry.gitlab.com/gitlab-org/gitlab-docs/lint-html:alpine-3.15-ruby-2.7.5-cee62c13
stage: lint
needs: []
script:
@@ -77,15 +77,16 @@ ui-docs-links lint:
script:
- bundle exec haml-lint -i DocumentationLinks
-docs-lint deprecations:
+docs-lint deprecations-and-removals:
variables:
SETUP_DB: "false"
extends:
- .default-retry
- .rails-cache
- .default-before_script
- - .docs:rules:deprecations
+ - .docs:rules:deprecations-and-removals
stage: lint
needs: []
script:
- bundle exec rake gitlab:docs:check_deprecations
+ - bundle exec rake gitlab:docs:check_removals
diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml
index ea4ae3b0492..1dd5285e0ae 100644
--- a/.gitlab/ci/frontend.gitlab-ci.yml
+++ b/.gitlab/ci/frontend.gitlab-ci.yml
@@ -306,6 +306,11 @@ qa-frontend-node:latest:
- .qa-frontend-node
- .frontend:rules:qa-frontend-node-latest
image: ${GITLAB_DEPENDENCY_PROXY}node:latest
+ # This is a workaround for https://github.com/webpack/webpack/issues/14532 until
+ # we can upgrade to Webpack 5 and switch to SHA256: https://gitlab.com/gitlab-org/gitlab/-/issues/350120
+ script:
+ - *yarn-install
+ - run_timed_command "retry yarn run webpack-prod-node-latest"
webpack-dev-server:
extends:
diff --git a/.gitlab/ci/qa.gitlab-ci.yml b/.gitlab/ci/qa.gitlab-ci.yml
index 4fec223e66d..b12f76f2823 100644
--- a/.gitlab/ci/qa.gitlab-ci.yml
+++ b/.gitlab/ci/qa.gitlab-ci.yml
@@ -33,6 +33,15 @@ qa:selectors:
script:
- bundle exec bin/qa Test::Sanity::Selectors
+qa:auto_quarantine:
+ extends:
+ - .qa-job-base
+ rules:
+ - if: '$QA_TRIGGER_AUTO_QUARANTINE =~ /true|yes|1/i'
+ script:
+ - bundle exec confiner -r .confiner/quarantine.yml
+ allow_failure: true
+
qa:selectors-as-if-foss:
extends:
- qa:selectors
diff --git a/.gitlab/ci/rails.gitlab-ci.yml b/.gitlab/ci/rails.gitlab-ci.yml
index d676dc2f331..1d2f94b616d 100644
--- a/.gitlab/ci/rails.gitlab-ci.yml
+++ b/.gitlab/ci/rails.gitlab-ci.yml
@@ -346,7 +346,7 @@ rspec fast_spec_helper minimal:
db:rollback:
extends: .db-job-base
script:
- - scripts/db_tasks db:migrate VERSION=20181228175414
+ - scripts/db_tasks db:migrate VERSION=20210301200959
- scripts/db_tasks db:migrate SKIP_SCHEMA_VERSION_CHECK=true
db:rollback decomposed:
@@ -360,6 +360,12 @@ db:migrate:reset:
script:
- bundle exec rake db:migrate:reset
+db:migrate:reset decomposed:
+ extends:
+ - db:migrate:reset
+ - .decomposed-database
+ - .rails:rules:decomposed-databases
+
db:migrate-from-previous-major-version:
extends: .db-job-base
variables:
@@ -457,7 +463,7 @@ db:backup_and_restore:
script:
- . scripts/prepare_build.sh
- bundle exec rake db:drop db:create db:structure:load db:seed_fu
- - mkdir -p tmp/tests/public/uploads tmp/tests/{artifacts,pages,lfs-objects,registry}
+ - mkdir -p tmp/tests/public/uploads tmp/tests/{artifacts,pages,lfs-objects,terraform_state,registry,packages}
- bundle exec rake gitlab:backup:create
- date
- bundle exec rake gitlab:backup:restore
@@ -592,8 +598,10 @@ rspec:undercoverage:
else
echo "Using \$CI_COMMIT_SHA ($CI_COMMIT_SHA) for this non-merge result pipeline.";
fi;
+ - UNDERCOVERAGE_COMPARE="${CI_MERGE_REQUEST_DIFF_BASE_SHA:-$(git merge-base origin/master HEAD)}"
+ - echo "Undercoverage comparing with ${UNDERCOVERAGE_COMPARE}"
- if [ -f scripts/undercoverage ]; then
- run_timed_command "scripts/undercoverage";
+ run_timed_command "scripts/undercoverage ${UNDERCOVERAGE_COMPARE}";
fi;
rspec:feature-flags:
diff --git a/.gitlab/ci/review-apps/dast.gitlab-ci.yml b/.gitlab/ci/review-apps/dast.gitlab-ci.yml
index 512c850b7da..d0ad4d23a82 100644
--- a/.gitlab/ci/review-apps/dast.gitlab-ci.yml
+++ b/.gitlab/ci/review-apps/dast.gitlab-ci.yml
@@ -45,7 +45,6 @@
# 10019, 10021 Missing security headers
# 10023, 10024, 10025, 10037 Information Disclosure
# 10040 Secure Pages Include Mixed Content
-# 10055 CSP
# 10056 X-Debug-Token Information Leak
# Duration: 14 minutes 20 seconds
@@ -54,7 +53,7 @@ dast:secureHeaders-csp-infoLeak:
- .dast_conf
variables:
DAST_USERNAME: "user1"
- DAST_ONLY_INCLUDE_RULES: "10019,10021,10023,10024,10025,10037,10040,10055,10056"
+ DAST_ONLY_INCLUDE_RULES: "10019,10021,10023,10024,10025,10037,10040,10056"
script:
- /analyze
diff --git a/.gitlab/ci/review-apps/qa.gitlab-ci.yml b/.gitlab/ci/review-apps/qa.gitlab-ci.yml
index af4674b802b..4ef6efa2604 100644
--- a/.gitlab/ci/review-apps/qa.gitlab-ci.yml
+++ b/.gitlab/ci/review-apps/qa.gitlab-ci.yml
@@ -26,35 +26,22 @@
- export CI_ENVIRONMENT_URL="$(cat environment_url.txt)"
- echo "${CI_ENVIRONMENT_URL}"
- cd qa
- - if [ -n "$KNAPSACK_REPORT_PATH" ]; then
- bundle exec rake knapsack:download;
- fi
- artifacts:
- paths:
- - qa/tmp
- expire_in: 7 days
- when: always
-
-.parallel-qa-base:
- parallel: 5
- variables:
- KNAPSACK_TEST_FILE_PATTERN: "qa/specs/features/**/*_spec.rb"
script:
- |
bin/test "${QA_SCENARIO}" "${CI_ENVIRONMENT_URL}" \
-- \
--color --format documentation \
--format RspecJunitFormatter --out tmp/rspec.xml
- after_script:
- - if [ -n "$KNAPSACK_GENERATE_REPORT" ]; then
- mv qa/${KNAPSACK_REPORT_PATH} qa/knapsack/gcs/regenerated-${CI_NODE_INDEX}.json;
- fi
artifacts:
paths:
- - qa/tmp # we can't merge list so need to include explicitly once more
- - qa/knapsack/gcs/regenerated-*.json
+ - qa/tmp
reports:
junit: qa/tmp/rspec.xml
+ expire_in: 7 days
+ when: always
+
+.parallel-qa-base:
+ parallel: 5
.allure-report-base:
image:
@@ -79,16 +66,6 @@
--ignore-missing-results \
--color
-.knapsack-upload-base:
- image:
- name: ${QA_IMAGE}
- entrypoint: [""]
- stage: post-qa
- before_script:
- - cd qa
- script:
- - bundle exec rake 'knapsack:upload[knapsack/gcs/regenerated-*.json]'
-
review-qa-smoke:
extends:
- .review-qa-base
@@ -96,8 +73,8 @@ review-qa-smoke:
retry: 1 # This is confusing but this means "2 runs at max".
variables:
QA_RUN_TYPE: review-qa-smoke
- script:
- - bin/test Test::Instance::Smoke "${CI_ENVIRONMENT_URL}"
+ QA_SCENARIO: Test::Instance::Smoke
+
review-qa-reliable:
extends:
@@ -108,7 +85,6 @@ review-qa-reliable:
variables:
QA_RUN_TYPE: review-qa-reliable
QA_SCENARIO: Test::Instance::Reliable
- KNAPSACK_REPORT_PATH: knapsack/gcs/review-qa-reliable.json
review-qa-all:
extends:
@@ -118,7 +94,6 @@ review-qa-all:
variables:
QA_RUN_TYPE: review-qa-all
QA_SCENARIO: Test::Instance::All
- KNAPSACK_REPORT_PATH: knapsack/gcs/review-qa-all.json
review-performance:
extends:
@@ -155,6 +130,15 @@ allure-report-qa-smoke:
ALLURE_REPORT_PATH_PREFIX: gitlab-review-smoke
ALLURE_JOB_NAME: review-qa-smoke
+allure-report-qa-reliable:
+ extends:
+ - .allure-report-base
+ - .review:rules:review-qa-reliable-report
+ needs: ["review-qa-reliable"]
+ variables:
+ ALLURE_REPORT_PATH_PREFIX: gitlab-review-reliable
+ ALLURE_JOB_NAME: review-qa-reliable
+
allure-report-qa-all:
extends:
- .allure-report-base
@@ -164,18 +148,15 @@ allure-report-qa-all:
ALLURE_REPORT_PATH_PREFIX: gitlab-review-all
ALLURE_JOB_NAME: review-qa-all
-knapsack-report-qa-all:
+knapsack-report:
extends:
- - .knapsack-upload-base
- - .review:rules:knapsack-report-qa-all
- needs: ["review-qa-all"]
- variables:
- KNAPSACK_REPORT_PATH: knapsack/gcs/review-qa-all.json
-
-knapsack-report-qa-reliable:
- extends:
- - .knapsack-upload-base
- - .review:rules:knapsack-report-qa-reliable
- needs: ["review-qa-reliable"]
- variables:
- KNAPSACK_REPORT_PATH: knapsack/gcs/review-qa-reliable.json
+ - .review:rules:knapsack-report
+ image:
+ name: ${QA_IMAGE}
+ entrypoint: [""]
+ stage: post-qa
+ allow_failure: true
+ before_script:
+ - cd qa
+ script:
+ - bundle exec rake 'knapsack:upload[tmp/knapsack/*/*.json]'
diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml
index e62de4bc6dc..008b62f6a0f 100644
--- a/.gitlab/ci/rules.gitlab-ci.yml
+++ b/.gitlab/ci/rules.gitlab-ci.yml
@@ -171,12 +171,13 @@
- ".markdownlint.yml"
- "scripts/lint-doc.sh"
-.docs-deprecations-patterns: &docs-deprecations-patterns
+.docs-deprecations-and-removals-patterns: &docs-deprecations-and-removals-patterns
- "doc/update/deprecations.md"
- - "data/deprecations/*.yml"
- - "data/deprecations/templates/_deprecation_template.md.erb"
+ - "doc/update/removals.md"
+ - "data/deprecations/**/*"
+ - "data/removals/**/*"
+ - "tooling/docs/**/*"
- "lib/tasks/gitlab/docs/compile_deprecations.rake"
- - "tooling/deprecations/docs.rb"
.bundler-patterns: &bundler-patterns
- '{Gemfile.lock,*/Gemfile.lock,*/*/Gemfile.lock}'
@@ -228,6 +229,9 @@
- "vendor/assets/**/*"
- "{,ee/,jh/}{app/assets,app/helpers,app/presenters,app/views,locale,public,symbol}/**/*"
+.controllers-patterns: &controllers-patterns
+ - "{,ee/,jh/}{app/controllers}/**/*"
+
.startup-css-patterns: &startup-css-patterns
- "{,ee/,jh/}app/assets/stylesheets/startup/**/*"
@@ -256,7 +260,7 @@
- "lib/gitlab/markdown_cache/active_record/**/*"
- "config/prometheus/common_metrics.yml" # Used by Gitlab::DatabaseImporters::CommonMetrics::Importer
- "{,ee/,jh/}app/models/project_statistics.rb" # Used to calculate sizes in migration specs
- - "GITALY_SERVER_VERSION" # Has interactions with background migrations:https://gitlab.com/gitlab-org/gitlab/-/issues/336538
+ - "GITALY_SERVER_VERSION" # Has interactions with background migrations:https://gitlab.com/gitlab-org/gitlab/-/issues/336538
# CI changes
- ".gitlab-ci.yml"
- ".gitlab/ci/**/*"
@@ -279,7 +283,7 @@
- ".dockerignore"
- "qa/**/*"
-# Code patterns + .ci-patterns + .workhorse-patterns
+# Code patterns + .ci-patterns
.code-patterns: &code-patterns
- "{package.json,yarn.lock}"
- ".browserslistrc"
@@ -541,10 +545,10 @@
changes: *docs-patterns
when: on_success
-.docs:rules:deprecations:
+.docs:rules:deprecations-and-removals:
rules:
- <<: *if-default-refs
- changes: *docs-deprecations-patterns
+ changes: *docs-deprecations-and-removals-patterns
##################
# GraphQL rules #
@@ -1613,11 +1617,13 @@
- <<: *if-dot-com-gitlab-org-merge-request
changes: *frontend-patterns
- <<: *if-dot-com-gitlab-org-merge-request
+ changes: *controllers-patterns
+ - <<: *if-dot-com-gitlab-org-merge-request
+ changes: *qa-patterns
+ - <<: *if-dot-com-gitlab-org-merge-request
changes: *code-patterns
when: manual
allow_failure: true
- - <<: *if-dot-com-gitlab-org-merge-request
- changes: *qa-patterns
- <<: *if-dot-com-gitlab-org-schedule
variables:
KNAPSACK_GENERATE_REPORT: "true"
@@ -1648,56 +1654,51 @@
rules:
- when: on_success
-# The rule needs to be duplicated between `on_success` and `on_failure`
-# because the jobs `needs` the previous job to complete.
-# With `when: always`, and the `review-qa-*` jobs are manual, the `allure-report-qa-*` jobs
-# would start running before the qa jobs have started.
-# See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63844#note_599012559
+# If the needed job isn't allowed to fail, we need to use `when: always` in
+# order to keep the job always running after it.
+#
+# If the needed job is allowed to fail, we need to use both
+# `when: on_success` and `when: on_failure` in order to keep
+# the job always running after it.
+# Not that if the needed job has `when: on_success` we can use `when: always`
+# for the depending job.
+#
+# See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76756
+
+# Since `review-qa-smoke` isn't allowed to fail, we need to use `when: always` for `review-qa-smoke-report`.
.review:rules:review-qa-smoke-report:
rules:
- - when: on_success
- - when: on_failure
+ - when: always
.review:rules:review-qa-reliable:
rules:
- when: on_success
- allow_failure: true
+
+# Since `review-qa-reliable` isn't allowed to fail, we need to use `when: always`for `review-qa-reliable-report`.
+.review:rules:review-qa-reliable-report:
+ rules:
+ - when: always
.review:rules:review-qa-all:
rules:
- - <<: *if-merge-request-labels-run-review-app # we explicitely don't allow the job to fail in that case
+ - <<: *if-merge-request-labels-run-review-app # we explicitly don't allow the job to fail in that case
- <<: *if-dot-com-gitlab-org-merge-request
changes: *code-patterns
when: manual
- allow_failure: true # manual jobs needs to be allowd to fail, otherwise they block the pipeline
+ allow_failure: true # manual jobs needs to be allowed to fail, otherwise they block the pipeline
- when: on_success
allow_failure: true
-# The rule needs to be duplicated between `on_success` and `on_failure`
-# because the jobs `needs` the previous job to complete.
-# With `when: always`, and the `review-qa-*` jobs are manual, the `allure-report-qa-*` jobs
-# would start running before the qa jobs have started.
-# See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63844#note_599012559
+# Since `review-qa-all` is allowed to fail (and potentially manual), we need to use `when: on_success` and `when: on_failure` for `review-qa-all-report`.
.review:rules:review-qa-all-report:
rules:
- when: on_success
- allow_failure: true
- when: on_failure
- allow_failure: true
-# Generate knapsack report on successful runs only
-# Reliable suite will pass most of the time so this should yield best distribution
-.review:rules:knapsack-report-qa-reliable:
- rules:
- - if: '$KNAPSACK_GENERATE_REPORT == "true"'
- when: on_success
- allow_failure: true
-
-.review:rules:knapsack-report-qa-all:
+.review:rules:knapsack-report:
rules:
- if: '$KNAPSACK_GENERATE_REPORT == "true"'
when: always
- allow_failure: true
.review:rules:review-cleanup:
rules:
diff --git a/.gitlab/ci/setup.gitlab-ci.yml b/.gitlab/ci/setup.gitlab-ci.yml
index 1eb3bd2ea41..13108ba289a 100644
--- a/.gitlab/ci/setup.gitlab-ci.yml
+++ b/.gitlab/ci/setup.gitlab-ci.yml
@@ -151,14 +151,17 @@ detect-previous-failed-tests:
add-jh-folder:
extends: .setup:rules:add-jh-folder
- image: ${GITLAB_DEPENDENCY_PROXY}alpine:edge
+ image: ${GITLAB_DEPENDENCY_PROXY}ruby:2.7
stage: prepare
before_script:
- - apk add --no-cache --update curl bash
+ - source ./scripts/utils.sh
+ - install_gitlab_gem
script:
- - curl --location -o "jh-folder.tar.gz" "https://gitlab.com/gitlab-jh/gitlab/-/archive/main-jh/gitlab-main-jh.tar.gz?path=jh"
+ - JH_BRANCH=$(./scripts/setup/find-jh-branch.rb)
+ - 'echo "JH_BRANCH: ${JH_BRANCH}"'
+ - curl --location -o "jh-folder.tar.gz" "https://gitlab.com/gitlab-jh/gitlab/-/archive/${JH_BRANCH}/gitlab-${JH_BRANCH}.tar.gz?path=jh"
- tar -xf "jh-folder.tar.gz"
- - mv gitlab-main-jh-jh/jh/ ./
+ - mv "gitlab-${JH_BRANCH}-jh/jh/" ./
- cp Gemfile.lock jh/
- ls -l jh/
artifacts:
diff --git a/.gitlab/ci/workhorse.gitlab-ci.yml b/.gitlab/ci/workhorse.gitlab-ci.yml
index cd53adc6d4b..aab077e575b 100644
--- a/.gitlab/ci/workhorse.gitlab-ci.yml
+++ b/.gitlab/ci/workhorse.gitlab-ci.yml
@@ -4,7 +4,7 @@ workhorse:verify:
stage: test
needs: []
script:
- - make -C workhorse # test build
+ - make -C workhorse # test build
- make -C workhorse verify
.workhorse:test:
diff --git a/.gitlab/ci/yaml.gitlab-ci.yml b/.gitlab/ci/yaml.gitlab-ci.yml
index 590593b9d75..218dc0a7859 100644
--- a/.gitlab/ci/yaml.gitlab-ci.yml
+++ b/.gitlab/ci/yaml.gitlab-ci.yml
@@ -10,4 +10,4 @@ lint-yaml:
variables:
LINT_PATHS: .gitlab-ci.yml .gitlab/ci lib/gitlab/ci/templates
script:
- - yamllint -f colored $LINT_PATHS
+ - yamllint --strict -f colored $LINT_PATHS
diff --git a/.gitlab/issue_templates/Experiment Rollout.md b/.gitlab/issue_templates/Experiment Rollout.md
index a7d6b46220e..3ddcb5fe89d 100644
--- a/.gitlab/issue_templates/Experiment Rollout.md
+++ b/.gitlab/issue_templates/Experiment Rollout.md
@@ -1,10 +1,10 @@
-<!-- Title suggestion: [Experiment Rollout] experiment-key - description of experiment -->
+<!-- Title suggestion: [Experiment Rollout] feature-flag-name - description of experiment -->
## Summary
This issue tracks the rollout and status of an experiment through to removal.
-1. Experiment key / feature flag name: `<experiment-key>`
+1. Feature flag name: `<feature-flag-name>`
1. Epic or issue link: `<issue or epic link>`
This is an experiment rollout issue
@@ -55,7 +55,7 @@ Note: you can use the [CXL calculator](https://cxl.com/ab-test-calculator/) to d
- Runtime in days, or until we expect to reach statistical significance: `30`
- We will roll this out behind a feature flag and expose this to `<rollout-percentage>`% of actors to start then ramp it up from there.
-`/chatops run feature set <experiment-key> <rollout-percentage> --actors`
+`/chatops run feature set <feature-flag-name> <rollout-percentage> --actors`
### Status
@@ -83,14 +83,14 @@ In this rollout issue, ensure the scoped `experiment::` label is kept accurate.
## Roll Out Steps
- [ ] [Confirm that end-to-end tests pass with the feature flag enabled](https://docs.gitlab.com/ee/development/testing_guide/end_to_end/feature_flags.html#confirming-that-end-to-end-tests-pass-with-a-feature-flag-enabled). If there are failing tests, contact the relevant [stable counterpart in the Quality department](https://about.gitlab.com/handbook/engineering/quality/#individual-contributors) to collaborate in updating the tests or confirming that the failing tests are not caused by the changes behind the enabled feature flag.
-- [ ] Enable on staging (`/chatops run feature set <experiment-key> true --staging`)
+- [ ] Enable on staging (`/chatops run feature set <feature-flag-name> true --staging`)
- [ ] Test on staging
- [ ] Ensure that documentation has been updated
-- [ ] Enable on GitLab.com for individual groups/projects listed above and verify behaviour (`/chatops run feature set --project=gitlab-org/gitlab feature_name true`)
+- [ ] Enable on GitLab.com for individual groups/projects listed above and verify behaviour (`/chatops run feature set --project=gitlab-org/gitlab <feature-flag-name> true`)
- [ ] Coordinate a time to enable the flag with the SRE oncall and release managers
- In `#production` mention `@sre-oncall` and `@release-managers`. Once an SRE on call and Release Manager on call confirm, you can proceed with the rollout
- [ ] Announce on the issue an estimated time this will be enabled on GitLab.com
-- [ ] Enable on GitLab.com by running chatops command in `#production` (`/chatops run feature set feature_name true`)
+- [ ] Enable on GitLab.com by running chatops command in `#production` (`/chatops run feature set <feature-flag-name> true`)
- [ ] Cross post chatops Slack command to `#support_gitlab-com` ([more guidance when this is necessary in the dev docs](https://docs.gitlab.com/ee/development/feature_flags/controls.html#where-to-run-commands)) and in your team channel
- [ ] Announce on the issue that the flag has been enabled
- [ ] Remove experiment code and feature flag and add changelog entry - a separate [cleanup issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new?issuable_template=Experiment%20Successful%20Cleanup) might be required
@@ -102,7 +102,7 @@ In this rollout issue, ensure the scoped `experiment::` label is kept accurate.
- [ ] This feature can be disabled by running the following Chatops command:
```
-/chatops run feature set <experiment-key> false
+/chatops run feature set <feature-flag-name> false
```
## Experiment Successful Cleanup Concerns
diff --git a/.gitlab/issue_templates/Feature Proposal - basic.md b/.gitlab/issue_templates/Feature Proposal - basic.md
index b16b5910b72..b447bcfe0ae 100644
--- a/.gitlab/issue_templates/Feature Proposal - basic.md
+++ b/.gitlab/issue_templates/Feature Proposal - basic.md
@@ -13,6 +13,6 @@ Use the following resources to find the appropriate labels:
- https://about.gitlab.com/handbook/product/categories/features/
-->
-/label ~"group::" ~"section::" ~"Category::"
+/label ~group:: ~section:: ~Category:
/label ~"GitLab Free" ~"GitLab Premium" ~"GitLab Ultimate"
/label ~"type::feature" ~"feature::addition" ~documentation
diff --git a/.gitlab/issue_templates/Feature Proposal - lean.md b/.gitlab/issue_templates/Feature Proposal - lean.md
index c5255315373..c826abe7e10 100644
--- a/.gitlab/issue_templates/Feature Proposal - lean.md
+++ b/.gitlab/issue_templates/Feature Proposal - lean.md
@@ -52,7 +52,6 @@ Use the following resources to find the appropriate labels:
- https://about.gitlab.com/handbook/product/categories/features/
-->
-/label ~"type::feature"
-/label ~"group::" ~"section::" ~"Category::"
+/label ~group:: ~section:: ~Category:
/label ~"GitLab Free" ~"GitLab Premium" ~"GitLab Ultimate"
-/label ~documentation ~direction
+/label ~"type::feature" ~documentation ~direction
diff --git a/.gitlab/issue_templates/Feature proposal - detailed.md b/.gitlab/issue_templates/Feature proposal - detailed.md
index f75ee08bfcb..f7d0567f806 100644
--- a/.gitlab/issue_templates/Feature proposal - detailed.md
+++ b/.gitlab/issue_templates/Feature proposal - detailed.md
@@ -118,6 +118,6 @@ Use the following resources to find the appropriate labels:
- https://gitlab.com/gitlab-org/gitlab/-/labels
- https://about.gitlab.com/handbook/product/categories/features/
-->
-/label ~"group::" ~"section::" ~"Category::"
+/label ~group:: ~section:: ~Category:
/label ~"GitLab Free" ~"GitLab Premium" ~"GitLab Ultimate"
/label ~"type::feature" ~documentation ~direction
diff --git a/.gitlab/issue_templates/Geo Replicate a new Git repository type.md b/.gitlab/issue_templates/Geo Replicate a new Git repository type.md
index 3c482105a22..256bddcbdab 100644
--- a/.gitlab/issue_templates/Geo Replicate a new Git repository type.md
+++ b/.gitlab/issue_templates/Geo Replicate a new Git repository type.md
@@ -175,8 +175,8 @@ That's all of the required database changes.
#### Step 1. Implement replication and verification
- [ ] Add the following lines to the `cool_widget` model to accomplish some important tasks:
- - Include `Gitlab::Geo::ReplicableModel` in the `CoolWidget` class, and specify the Replicator class `with_replicator Geo::CoolWidgetReplicator`.
- - Include the `::Gitlab::Geo::VerificationState` concern.
+ - Include `::Geo::ReplicableModel` in the `CoolWidget` class, and specify the Replicator class `with_replicator Geo::CoolWidgetReplicator`.
+ - Include the `::Geo::VerifiableModel` concern.
- Delegate verification related methods to the `cool_widget_state` model.
- For verification, override some scopes to use the `cool_widget_states` table instead of the model table.
- Implement the `verification_state_object` method to return the object that holds
@@ -192,8 +192,8 @@ That's all of the required database changes.
class CoolWidget < ApplicationRecord
...
- include ::Gitlab::Geo::ReplicableModel
- include ::Gitlab::Geo::VerificationState
+ include ::Geo::ReplicableModel
+ include ::Geo::VerifiableModel
with_replicator Geo::CoolWidgetReplicator
diff --git a/.gitlab/issue_templates/Geo Replicate a new blob type.md b/.gitlab/issue_templates/Geo Replicate a new blob type.md
index d2fc7307c88..44b80158e51 100644
--- a/.gitlab/issue_templates/Geo Replicate a new blob type.md
+++ b/.gitlab/issue_templates/Geo Replicate a new blob type.md
@@ -179,8 +179,8 @@ That's all of the required database changes.
#### Step 1. Implement replication and verification
- [ ] Add the following lines to the `cool_widget` model to accomplish some important tasks:
- - Include `Gitlab::Geo::ReplicableModel` in the `CoolWidget` class, and specify the Replicator class `with_replicator Geo::CoolWidgetReplicator`.
- - Include the `::Gitlab::Geo::VerificationState` concern.
+ - Include `::Geo::ReplicableModel` in the `CoolWidget` class, and specify the Replicator class `with_replicator Geo::CoolWidgetReplicator`.
+ - Include the `::Geo::VerifiableModel` concern.
- Delegate verification related methods to the `cool_widget_state` model.
- For verification, override some scopes to use the `cool_widget_states` table instead of the model table.
- Implement the `verification_state_object` method to return the object that holds
@@ -194,8 +194,8 @@ That's all of the required database changes.
class CoolWidget < ApplicationRecord
...
- include ::Gitlab::Geo::ReplicableModel
- include ::Gitlab::Geo::VerificationState
+ include ::Geo::ReplicableModel
+ include ::Geo::VerifiableModel
with_replicator Geo::CoolWidgetReplicator
diff --git a/.gitlab/issue_templates/Performance Indicator Metric.md b/.gitlab/issue_templates/Performance Indicator Metric.md
new file mode 100644
index 00000000000..f4d8885b119
--- /dev/null
+++ b/.gitlab/issue_templates/Performance Indicator Metric.md
@@ -0,0 +1,23 @@
+<!--
+Performance Indicator Metric issues are used for adding, updating, or removing performance indicator type in Service Ping metrics.
+
+Please title your issue with the following format: "{action}(Add|Update|Remove) Metric name as performance indicator"
+
+Example of title: "Add static_site_editor_views as gmau"
+
+-->
+
+## Summary
+
+<!--
+Summary of the changes
+-->
+
+## Tasks
+
+- [ ] [Link to metric definition]()
+- [ ] Create issue in GitLab Data Team project using [Product Performance Indicator template](https://gitlab.com/gitlab-data/analytics/-/issues/new?issuable_template=Product%20Performance%20Indicator%20Template)
+
+See [Product Intelligence Guide](https://docs.gitlab.com/ee/development/service_ping/performance_indicator_metrics.html) for details
+
+/label ~"product intelligence" ~"Data Warehouse::Impact Check"
diff --git a/.gitlab/issue_templates/Security developer workflow.md b/.gitlab/issue_templates/Security developer workflow.md
index 6bf9e6971d7..e63727fe484 100644
--- a/.gitlab/issue_templates/Security developer workflow.md
+++ b/.gitlab/issue_templates/Security developer workflow.md
@@ -53,6 +53,7 @@ After your merge request has been approved according to our [approval guidelines
| Description | Link |
| -------- | -------- |
| Issue on [GitLab](https://gitlab.com/gitlab-org/gitlab/issues) | #TODO |
+| CVE ID request on [`gitlab-org/cves`](https://gitlab.com/gitlab-org/cves/-/issues?sort=created_date&state=opened) | #TODO for AppSec |
### Details
diff --git a/.gitlab/merge_request_templates/Deprecations.md b/.gitlab/merge_request_templates/Deprecations.md
index 1cadf54ff1d..e0b4f127e4a 100644
--- a/.gitlab/merge_request_templates/Deprecations.md
+++ b/.gitlab/merge_request_templates/Deprecations.md
@@ -2,21 +2,23 @@
/label ~"release post" ~"release post item" ~"Technical Writing" ~"devops::" ~"group::" ~"release post item::deprecation"
/milestone %
-/assign `@PM`
+/assign `@EM/PM` (choose the DRI; remove backticks here, and below)
**Be sure to link this MR to the relevant deprecation issue(s).**
+If the MR does not have a deprecation issue, hit pause and review [this handbook documentation](https://about.gitlab.com/handbook/product/gitlab-the-product/#process-for-deprecating-and-removing-a-feature) and connect with the Product Manager DRI.
+
Deprecation announcements can and should be created and merged into Docs at any time, to optimize user awareness and planning. We encourage confirmed deprecations to be merged as soon as the required reviews are complete, even if weeks ahead of the target milestone's release post. For the announcement to be included in a specific release post and that release's documentation packages, this MR must be reviewed/merged per the due dates below:
**By the 10th**: Assign this MR to these team members as Reviewer and for Approval (optional unless noted as required):
- Product Marketing: `@PMM`
- Product Designer(s): `@ProductDesigners`
-- Group Manager or Director: `@manager`
+- Product Group Manager or Director: `@PM` - Required
- Engineering Manager: `@EM` - Required
- Technical writer: `@TW` - Required
-**By 11:59 AM PDT 15th**: PM assigns this MR to the TW reviewer for final review and merge: `@PM`
+**By 11:59 AM PDT 15th**: EM/PM assigns this MR to the TW reviewer for final review and merge: `@EM/PM`
**By 11:59 PM PDT 17th**: TW Reviewer updates Docs by merging this MR to `master`: `@TW`
@@ -31,9 +33,9 @@ They are frequently updated, and everyone should make sure they are aware of the
- Deprecation Issue:
- Deprecation MR (optional):
-## PM release post item checklist
+## EM/PM release post item checklist
-- [ ] Set yourself as the Assignee.
+- [ ] Set yourself as the Assignee, meaning you are the DRI.
- [ ] If the deprecation is a [breaking change](https://about.gitlab.com/handbook/product/gitlab-the-product/#breaking-change), add label `breaking change`.
- [ ] Follow the process to [create a deprecation YAML file](https://about.gitlab.com/handbook/marketing/blog/release-posts/#creating-a-deprecation-entry).
- [ ] Add reviewers by the 10th.
diff --git a/.gitlab/merge_request_templates/Removals.md b/.gitlab/merge_request_templates/Removals.md
new file mode 100644
index 00000000000..398714826b9
--- /dev/null
+++ b/.gitlab/merge_request_templates/Removals.md
@@ -0,0 +1,103 @@
+<!-- Set the correct label and milestone using autocomplete for guidance. Please @mention only the DRI(s) for each stage or group rather than an entire department. -->
+
+**Be sure to link this MR to the relevant deprecation issue(s).**
+
+If the MR does not have a deprecation issue, hit pause and:
+
+- Review [this handbook documentation](https://about.gitlab.com/handbook/product/gitlab-the-product/#process-for-deprecating-and-removing-a-feature).
+- Connect with the Product Manager DRI.
+
+Removals must be [announced as Deprecations](https://about.gitlab.com/handbook/marketing/blog/release-posts/#deprecations) at least 2 milestones in advance of the planned removal date. Removals can only be removed in a XX.0 major release if it creates a [breaking change](https://about.gitlab.com/handbook/product/gitlab-the-product/#breaking-changes-deprecations-and-removing-features).
+
+**By the 10th**: Assign this MR to these team members as reviewers, and for approval:
+
+- Required:
+ - Product Group Manager or Director: `@PM`
+ - Engineering Manager: `@EM`
+ - Technical writer: `@TW`
+- Optional:
+ - Product Designer(s): `@ProductDesigners`
+ - Product Marketing: `@PMM`
+
+**By 7:59 PM UTC 15th (11:59 AM PT)**: EM/PM assigns this MR to the TW reviewer for final review and merge: `@EM/PM`
+
+**By 7:59 AM UTC 18th (11:59 PM PT 17th)**: TW Reviewer updates Docs by merging this MR to `master`: `@TW`
+
+---
+
+Please review the [guidelines for removals](https://about.gitlab.com/handbook/marketing/blog/release-posts/#removals).
+
+## Links
+
+- Removal Issue:
+- Removal MR (optional):
+
+## EM/PM release post item checklist
+
+- [ ] Set yourself as the Assignee, meaning you are the DRI.
+- [ ] If the removal is a [breaking change](https://about.gitlab.com/handbook/product/gitlab-the-product/#breaking-change), add label `breaking change`.
+- [ ] Follow the process to [create a removal YAML file](https://about.gitlab.com/handbook/marketing/blog/release-posts/#creating-a-removal-entry).
+- [ ] Add reviewers by the 10th.
+- [ ] When ready to be merged and not later than the 15th, add the ~ready label and @ message the TW for final review and merge.
+
+## Reviewers
+
+When the content is ready for review, the Technical Writer and Engineering Manager _must_
+review it. Optional reviewers can include Product Marketing, Product Design, and the Product Leaders
+for this area. Use the
+[Reviewers for Merge Requests](https://docs.gitlab.com/ee/user/project/merge_requests/getting_started#reviewer)
+feature for all reviews. Reviewers will `approve` the MR and remove themselves from the reviewers list when their review is complete.
+
+- [ ] (Recommended) PMM
+- [ ] (Optional) Product Designer
+- [ ] (Optional) Group Manager or Director
+- [ ] Required review and approval: [Technical Writer designated to the corresponding DevOps stage/group](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments).
+
+### Tech writer review
+
+The TW should review according to the criteria listed below. Review a removal MR
+with the same process as regular docs MRs. Add suggestions as needed, @ message
+the PM to inform them the first review is complete, and remove
+yourself as a reviewer if it's not yet ready for merge.
+
+<details>
+<summary>Expand for Details</summary>
+
+- [ ] Title:
+ - Length limit: 7 words (not including articles or prepositions).
+ - Capitalization: ensure the title is [sentence cased](https://design.gitlab.com/content/punctuation#case).
+ - No Markdown `` `code` `` formatting in the title, as it doesn't render correctly in the release post.
+- [ ] Consistency:
+ - Ensure that all resources (docs, removal, etc.) refer to the feature with the same term / feature name.
+- [ ] Content:
+ - Make sure the removal is accurate based on your understanding. Look for typos or grammar mistakes. Work with PM and PMM to ensure a consistent GitLab style and tone for messaging, based on other features and removals.
+ - Review use of whitespace and bullet lists. Will the removal item be easily scannable when published? Consider adding line breaks or breaking content into bullets if you have more than a few sentences.
+ - Make sure there aren't acronyms readers may not understand per <https://about.gitlab.com/handbook/communication/#writing-style-guidelines>.
+- [ ] Links:
+ - All links must be full URLs, as the removal YAML files are used in multiple projects. Do not use relative links. The generated doc is an exception to the relative link rule and currently uses absolute links only.
+ - Make sure all links and anchors are correct. Do not link to the H1 (top) anchor on a docs page.
+- [ ] Code. Make sure any included code is wrapped in code blocks.
+- [ ] Capitalization. Make sure to capitalize feature names. Stay consistent with the Documentation Style Guidance on [Capitalization](https://docs.gitlab.com/ee/development/documentation/styleguide.html#capitalization).
+- [ ] Blank spaces. Remove unnecessary spaces (end of line spaces, double spaces, extra blank lines, and lines with only spaces).
+
+</details>
+
+When the PM indicates it is ready for merge and all issues have been addressed, start the merge process.
+
+#### Technical writer merge process
+
+The [removals doc's `.md` file](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/update/removals.md)
+must be updated before this MR is merged:
+
+1. Check out the MR's branch (in the [`gitlab-org/gitlab`](https://gitlab.com/gitlab-org/gitlab) project).
+1. From the command line (in the branch), run `bin/rake gitlab:docs:compile_removals`.
+ If you want to double check that it worked, you can run `bin/rake gitlab:docs:check_removals`
+ to verify that the doc is up to date.
+1. Commit the updated file and push the changes.
+1. Set the MR to merge when the pipeline succeeds (or merge if the pipeline is already complete).
+
+If you have trouble running the rake task, check the [troubleshooting steps](https://about.gitlab.com/handbook/marketing/blog/release-posts/#deprecation-rake-task-troubleshooting).
+
+/label ~"release post" ~"release post item" ~"Technical Writing" ~devops:: ~group:: ~"release post item::removal"
+/milestone %
+/assign `@EM/PM` (choose the DRI; remove backticks here, and below)
diff --git a/.markdownlint.yml b/.markdownlint.yml
index bb4c859e197..e1e2b246314 100644
--- a/.markdownlint.yml
+++ b/.markdownlint.yml
@@ -26,6 +26,7 @@ proper-names:
names: [
"Akismet",
"Alertmanager",
+ "AlmaLinux",
"API",
"Asana",
"Auth0",
@@ -91,7 +92,7 @@ proper-names:
"markdownlint",
"Mattermost",
"Microsoft",
- "Minikube",
+ "minikube",
"MinIO",
"ModSecurity",
"NGINX Ingress",
@@ -103,6 +104,7 @@ proper-names:
"OpenID",
"OpenShift",
"PgBouncer",
+ "Postfix",
"PostgreSQL",
"Praefect",
"Prometheus",
@@ -117,6 +119,7 @@ proper-names:
"runit",
"Salesforce",
"SAML",
+ "Sendmail",
"Sentry",
"Sidekiq",
"Shibboleth",
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 94d8d40c10f..300706a4d8e 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -325,7 +325,6 @@ Performance/Sum:
- 'lib/container_registry/tag.rb'
- 'lib/gitlab/ci/reports/test_suite_comparer.rb'
- 'lib/gitlab/diff/file.rb'
- - 'lib/gitlab/sherlock/transaction.rb'
- 'lib/gitlab/usage_data.rb'
- 'lib/peek/views/detailed_view.rb'
- 'spec/models/namespace/root_storage_statistics_spec.rb'
diff --git a/.rubocop_todo/database/multiple_databases.yml b/.rubocop_todo/database/multiple_databases.yml
index e555c2f912b..7329d178dc1 100644
--- a/.rubocop_todo/database/multiple_databases.yml
+++ b/.rubocop_todo/database/multiple_databases.yml
@@ -1,14 +1,12 @@
---
Database/MultipleDatabases:
Exclude:
- - ee/lib/ee/gitlab/database.rb
- 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/lib/system_check/geo/geo_database_configured_check.rb
- ee/spec/lib/pseudonymizer/dumper_spec.rb
- ee/spec/services/ee/merge_requests/update_service_spec.rb
- lib/backup/database.rb
@@ -21,16 +19,13 @@ 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/database/schema_cache_with_renamed_table.rb
- lib/gitlab/database/with_lock_retries.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/metrics/samplers/database_sampler.rb
- lib/gitlab/seeder.rb
- - lib/gitlab/sherlock/query.rb
- lib/system_check/orphans/repository_check.rb
- spec/db/schema_spec.rb
- spec/initializers/database_config_spec.rb
@@ -39,15 +34,8 @@ Database/MultipleDatabases:
- spec/lib/gitlab/database_spec.rb
- spec/lib/gitlab/metrics/subscribers/active_record_spec.rb
- spec/lib/gitlab/profiler_spec.rb
- - spec/lib/gitlab/usage_data_metrics_spec.rb
- - spec/lib/gitlab/usage_data_queries_spec.rb
- spec/lib/gitlab/usage/metrics/names_suggestions/relation_parsers/constraints_spec.rb
- spec/lib/gitlab/usage/metrics/names_suggestions/relation_parsers/joins_spec.rb
- - spec/lib/gitlab/usage/metrics/instrumentations/database_metric_spec.rb
- - spec/lib/gitlab/utils/usage_data_spec.rb
- - spec/models/project_feature_usage_spec.rb
- - spec/models/users_statistics_spec.rb
- - spec/services/users/activity_service_spec.rb
- spec/support/caching.rb
- spec/support/gitlab/usage/metrics_instrumentation_shared_examples.rb
- spec/support/helpers/database_connection_helpers.rb
diff --git a/.rubocop_todo/gitlab/delegate_predicate_methods.yml b/.rubocop_todo/gitlab/delegate_predicate_methods.yml
index d31b4a30fc8..7ed3fc3e4fb 100644
--- a/.rubocop_todo/gitlab/delegate_predicate_methods.yml
+++ b/.rubocop_todo/gitlab/delegate_predicate_methods.yml
@@ -2,9 +2,6 @@
Gitlab/DelegatePredicateMethods:
Exclude:
- app/models/clusters/cluster.rb
- - app/models/concerns/ci/metadatable.rb
- app/models/concerns/integrations/base_data_fields.rb
- app/models/project.rb
- ee/app/models/concerns/ee/ci/metadatable.rb
- - ee/app/models/license.rb
- - lib/gitlab/ci/trace/stream.rb
diff --git a/.rubocop_todo/gitlab/namespaced_class.yml b/.rubocop_todo/gitlab/namespaced_class.yml
index 898768c2425..f13325378d3 100644
--- a/.rubocop_todo/gitlab/namespaced_class.yml
+++ b/.rubocop_todo/gitlab/namespaced_class.yml
@@ -369,6 +369,7 @@ Gitlab/NamespacedClass:
- app/models/wiki_page.rb
- app/models/wiki_page/meta.rb
- app/models/wiki_page/slug.rb
+ - app/models/work_item.rb
- app/models/x509_certificate.rb
- app/models/x509_commit_signature.rb
- app/models/x509_issuer.rb
diff --git a/.rubocop_todo/graphql/argument_name.yml b/.rubocop_todo/graphql/argument_name.yml
deleted file mode 100644
index 29d2ae7d4ae..00000000000
--- a/.rubocop_todo/graphql/argument_name.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-GraphQL/ArgumentName:
- Exclude:
- - ee/app/graphql/mutations/audit_events/external_audit_event_destinations/update.rb
diff --git a/.rubocop_todo/graphql/field_definitions.yml b/.rubocop_todo/graphql/field_definitions.yml
index c6ca8674264..35ed870fa41 100644
--- a/.rubocop_todo/graphql/field_definitions.yml
+++ b/.rubocop_todo/graphql/field_definitions.yml
@@ -5,9 +5,6 @@ GraphQL/FieldDefinitions:
- app/graphql/types/group_type.rb
- app/graphql/types/issue_type.rb
- app/graphql/types/label_type.rb
- - app/graphql/types/project_type.rb
- - app/graphql/types/projects/topic_type.rb
- - app/graphql/types/release_type.rb
- 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
diff --git a/.rubocop_todo/graphql/field_method.yml b/.rubocop_todo/graphql/field_method.yml
index 1cc4aa7e264..7c336451c41 100644
--- a/.rubocop_todo/graphql/field_method.yml
+++ b/.rubocop_todo/graphql/field_method.yml
@@ -6,7 +6,3 @@ GraphQL/FieldMethod:
- app/graphql/types/metrics/dashboards/annotation_type.rb
- app/graphql/types/packages/package_details_type.rb
- app/graphql/types/project_type.rb
- - ee/app/graphql/types/dast/profile_type.rb
- - ee/app/graphql/types/dast_site_validation_type.rb
- - ee/app/graphql/types/group_release_stats_type.rb
- - ee/app/graphql/types/incident_management/oncall_rotation_type.rb
diff --git a/.rubocop_todo/graphql/ordered_arguments.yml b/.rubocop_todo/graphql/ordered_arguments.yml
index a2df1315ee9..3a4e805948d 100644
--- a/.rubocop_todo/graphql/ordered_arguments.yml
+++ b/.rubocop_todo/graphql/ordered_arguments.yml
@@ -4,9 +4,6 @@ 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/resolvers/design_management/version/designs_at_version_resolver.rb
- - app/graphql/resolvers/design_management/version_in_collection_resolver.rb
- - app/graphql/resolvers/group_milestones_resolver.rb
- app/graphql/resolvers/merge_requests_resolver.rb
- app/graphql/resolvers/paginated_tree_resolver.rb
- app/graphql/resolvers/tree_resolver.rb
diff --git a/.rubocop_todo/rails/include_url_helper.yml b/.rubocop_todo/rails/include_url_helper.yml
index 2dedba19c78..6a34c58ecf6 100644
--- a/.rubocop_todo/rails/include_url_helper.yml
+++ b/.rubocop_todo/rails/include_url_helper.yml
@@ -7,7 +7,6 @@ Rails/IncludeUrlHelper:
- app/models/integrations/campfire.rb
- app/models/integrations/confluence.rb
- app/models/integrations/custom_issue_tracker.rb
- - app/models/integrations/datadog.rb
- app/models/integrations/discord.rb
- app/models/integrations/ewm.rb
- app/models/integrations/external_wiki.rb
diff --git a/.rubocop_todo/rails/save_bang.yml b/.rubocop_todo/rails/save_bang.yml
index d7c9366d85b..15361fd6743 100644
--- a/.rubocop_todo/rails/save_bang.yml
+++ b/.rubocop_todo/rails/save_bang.yml
@@ -1,24 +1,7 @@
---
Rails/SaveBang:
Exclude:
- - ee/spec/initializers/fog_google_https_private_urls_spec.rb
- ee/spec/lib/analytics/merge_request_metrics_calculator_spec.rb
- - ee/spec/lib/gitlab/auth/ldap/access_spec.rb
- - ee/spec/lib/gitlab/auth/o_auth/user_spec.rb
- - ee/spec/lib/gitlab/auth/saml/user_spec.rb
- - ee/spec/lib/gitlab/elastic/search_results_spec.rb
- - ee/spec/lib/gitlab/email/handler/ee/service_desk_handler_spec.rb
- - ee/spec/lib/gitlab/geo_spec.rb
- - ee/spec/lib/gitlab/git_access_spec.rb
- - ee/spec/lib/gitlab/import_export/group/relation_factory_spec.rb
- - ee/spec/lib/gitlab/mirror_spec.rb
- - ee/spec/models/application_setting_spec.rb
- - ee/spec/models/approval_merge_request_rule_spec.rb
- - ee/spec/models/approval_project_rule_spec.rb
- - ee/spec/models/burndown_spec.rb
- - ee/spec/models/elasticsearch_indexed_namespace_spec.rb
- - ee/spec/models/gitlab_subscription_spec.rb
- - ee/spec/models/issue_spec.rb
- ee/spec/models/protected_environment_spec.rb
- ee/spec/models/repository_spec.rb
- ee/spec/models/scim_identity_spec.rb
@@ -28,31 +11,6 @@ Rails/SaveBang:
- ee/spec/models/visible_approvable_spec.rb
- ee/spec/models/vulnerabilities/feedback_spec.rb
- ee/spec/models/vulnerabilities/issue_link_spec.rb
- - ee/spec/services/ee/merge_requests/update_service_spec.rb
- - ee/spec/services/ee/notes/quick_actions_service_spec.rb
- - ee/spec/services/ee/notification_service_spec.rb
- - ee/spec/services/epic_links/create_service_spec.rb
- - ee/spec/services/epics/close_service_spec.rb
- - ee/spec/services/epics/issue_promote_service_spec.rb
- - ee/spec/services/epics/reopen_service_spec.rb
- - ee/spec/services/epics/tree_reorder_service_spec.rb
- - ee/spec/services/epics/update_dates_service_spec.rb
- - ee/spec/services/epics/update_service_spec.rb
- - ee/spec/services/geo/blob_verification_secondary_service_spec.rb
- - ee/spec/services/geo/files_expire_service_spec.rb
- - ee/spec/services/geo/metrics_update_service_spec.rb
- - ee/spec/services/geo/registry_consistency_service_spec.rb
- - ee/spec/services/geo/repository_verification_secondary_service_spec.rb
- - ee/spec/services/groups/autocomplete_service_spec.rb
- - ee/spec/services/ldap_group_reset_service_spec.rb
- - ee/spec/services/lfs/unlock_file_service_spec.rb
- - ee/spec/services/merge_trains/refresh_merge_request_service_spec.rb
- - ee/spec/services/quick_actions/interpret_service_spec.rb
- - ee/spec/services/slash_commands/global_slack_handler_spec.rb
- - ee/spec/services/start_pull_mirroring_service_spec.rb
- - ee/spec/services/status_page/trigger_publish_service_spec.rb
- - ee/spec/services/todo_service_spec.rb
- - ee/spec/services/vulnerability_feedback/create_service_spec.rb
- spec/lib/backup/manager_spec.rb
- spec/lib/gitlab/alerting/alert_spec.rb
- spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb
@@ -66,11 +24,6 @@ Rails/SaveBang:
- spec/lib/gitlab/database/custom_structure_spec.rb
- spec/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers_spec.rb
- spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb
- - spec/lib/gitlab/gfm/reference_rewriter_spec.rb
- - spec/lib/gitlab/git_access_spec.rb
- - spec/lib/gitlab/import_export/avatar_saver_spec.rb
- - spec/lib/gitlab/import_export/base/relation_factory_spec.rb
- - spec/lib/gitlab/import_export/design_repo_restorer_spec.rb
- spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb
- spec/lib/gitlab/import_export/fork_spec.rb
- spec/lib/gitlab/import_export/group/legacy_tree_saver_spec.rb
@@ -90,9 +43,3 @@ Rails/SaveBang:
- spec/lib/gitlab/import_export/snippets_repo_restorer_spec.rb
- spec/lib/gitlab/import_export/snippets_repo_saver_spec.rb
- spec/lib/gitlab/import_export/uploads_manager_spec.rb
- - spec/lib/gitlab/import_export/uploads_saver_spec.rb
- - spec/lib/gitlab/import_export/wiki_restorer_spec.rb
- - spec/lib/gitlab/lets_encrypt/client_spec.rb
- - spec/lib/gitlab/middleware/go_spec.rb
- - spec/lib/gitlab/shard_health_cache_spec.rb
- - spec/mailers/notify_spec.rb
diff --git a/.rubocop_todo/rails/time_zone.yml b/.rubocop_todo/rails/time_zone.yml
index 0e2b036c312..86d0632ac47 100644
--- a/.rubocop_todo/rails/time_zone.yml
+++ b/.rubocop_todo/rails/time_zone.yml
@@ -76,7 +76,6 @@ Rails/TimeZone:
- lib/gitlab/prometheus/queries/additional_metrics_environment_query.rb
- lib/gitlab/prometheus/queries/matched_metric_query.rb
- lib/gitlab/prometheus_client.rb
- - lib/gitlab/sherlock/transaction.rb
- lib/gitlab/task_helpers.rb
- lib/gitlab/x509/tag.rb
- lib/grafana/time_window.rb
@@ -141,7 +140,6 @@ Rails/TimeZone:
- spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb
- spec/lib/gitlab/prometheus/queries/deployment_query_spec.rb
- spec/lib/gitlab/prometheus/queries/validate_query_spec.rb
- - spec/lib/gitlab/sherlock/transaction_spec.rb
- spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb
- spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing_spec.rb
- spec/lib/gitlab/updated_notes_paginator_spec.rb
diff --git a/.rubocop_todo/rspec/timecop_freeze.yml b/.rubocop_todo/rspec/timecop_freeze.yml
index c20c6214fa8..8deefee1164 100644
--- a/.rubocop_todo/rspec/timecop_freeze.yml
+++ b/.rubocop_todo/rspec/timecop_freeze.yml
@@ -2,9 +2,6 @@
RSpec/TimecopFreeze:
Exclude:
- ee/spec/lib/gitlab/analytics/cycle_analytics/data_collector_spec.rb
- - ee/spec/lib/gitlab/geo/git_push_http_spec.rb
- - ee/spec/lib/gitlab/geo/log_cursor/daemon_spec.rb
- - ee/spec/lib/gitlab/geo/oauth/login_state_spec.rb
- ee/spec/lib/gitlab/insights/reducers/count_per_period_reducer_spec.rb
- ee/spec/models/merge_train_spec.rb
- ee/spec/support/shared_contexts/lib/gitlab/insights/reducers/reducers_shared_contexts.rb
diff --git a/.rubocop_todo/style/open_struct_use.yml b/.rubocop_todo/style/open_struct_use.yml
index aa486f69562..ed4a53f2894 100644
--- a/.rubocop_todo/style/open_struct_use.yml
+++ b/.rubocop_todo/style/open_struct_use.yml
@@ -13,7 +13,6 @@ Style/OpenStructUse:
- lib/gitlab/testing/request_inspector_middleware.rb
- lib/mattermost/session.rb
- spec/controllers/groups/clusters_controller_spec.rb
- - spec/controllers/import/gitlab_controller_spec.rb
- spec/controllers/projects/clusters_controller_spec.rb
- spec/factories/go_module_versions.rb
- spec/factories/wiki_pages.rb
@@ -26,17 +25,13 @@ Style/OpenStructUse:
- spec/graphql/mutations/commits/create_spec.rb
- spec/helpers/application_settings_helper_spec.rb
- spec/helpers/profiles_helper_spec.rb
- - spec/initializers/doorkeeper_spec.rb
- spec/lib/gitlab/auth/o_auth/provider_spec.rb
- - spec/lib/gitlab/database/migrations/runner_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
- spec/lib/gitlab/quick_actions/command_definition_spec.rb
- spec/models/design_management/design_action_spec.rb
- spec/models/design_management/design_at_version_spec.rb
- - spec/models/user_spec.rb
- - spec/presenters/packages/nuget/search_results_presenter_spec.rb
- spec/services/packages/nuget/metadata_extraction_service_spec.rb
- spec/services/projects/import_service_spec.rb
- spec/services/system_note_service_spec.rb
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b97e7faf923..1c3d38f6810 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -400,6 +400,10 @@ No changes.
- [Fix OpenStruct use](gitlab-org/gitlab@f8466f5943a1afeabaf9cf781f7804a8df515a0e) by @mehulsharma ([merge request](gitlab-org/gitlab!74702))
- [Update Sidekiq to 6.3.1](gitlab-org/gitlab@22e8bc0af656717e56428a7227c467fe08021c66) ([merge request](gitlab-org/gitlab!73973))
+## 14.5.3 (2022-01-11)
+
+No changes.
+
## 14.5.2 (2021-12-03)
No changes.
@@ -942,6 +946,10 @@ No changes.
- [Add pipeline artifacts and uploads sizes to project REST API](gitlab-org/gitlab@58d66f28faf42ae98ca11ff1ba0bdd9180e988ad) by @guillaume.chauvel ([merge request](gitlab-org/gitlab!72075))
- [Remove not used parameter from epics finder](gitlab-org/gitlab@49fce172b57b2f376a114726b1dd1900fe36a238) ([merge request](gitlab-org/gitlab!72285)) **GitLab Enterprise Edition**
+## 14.4.5 (2022-01-11)
+
+No changes.
+
## 14.4.4 (2021-12-03)
No changes.
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index f8a030aae56..154c5f58c35 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-14.6.3 \ No newline at end of file
+7cd8ef212eccee3ffd388f1b88ccdeca15971435
diff --git a/GITLAB_PAGES_VERSION b/GITLAB_PAGES_VERSION
index 7f3a46a841e..ba0a719118c 100644
--- a/GITLAB_PAGES_VERSION
+++ b/GITLAB_PAGES_VERSION
@@ -1 +1 @@
-1.49.0
+1.51.0
diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION
index 516e0c5f549..35d41ddb27d 100644
--- a/GITLAB_SHELL_VERSION
+++ b/GITLAB_SHELL_VERSION
@@ -1 +1 @@
-13.22.1
+13.22.2
diff --git a/Gemfile b/Gemfile
index 1d88df82967..334e7df7681 100644
--- a/Gemfile
+++ b/Gemfile
@@ -2,7 +2,7 @@
source 'https://rubygems.org'
-gem 'rails', '~> 6.1.4.1'
+gem 'rails', '~> 6.1.4.4'
gem 'bootsnap', '~> 1.9.1', require: false
@@ -50,7 +50,7 @@ gem 'omniauth-shibboleth', '~> 1.3.0'
gem 'omniauth-twitter', '~> 1.4'
gem 'omniauth_crowd', '~> 2.4.0'
gem 'omniauth-authentiq', '~> 0.3.3'
-gem 'gitlab-omniauth-openid-connect', '~> 0.8.0', require: 'omniauth_openid_connect'
+gem 'gitlab-omniauth-openid-connect', '~> 0.9.0', require: 'omniauth_openid_connect'
gem 'omniauth-salesforce', '~> 1.0.5'
gem 'omniauth-atlassian-oauth2', '~> 0.2.0'
gem 'rack-oauth2', '~> 1.16.0'
@@ -74,7 +74,7 @@ gem 'u2f', '~> 0.2.1'
gem 'validates_hostname', '~> 1.0.11'
gem 'rubyzip', '~> 2.0.0', require: 'zip'
# GitLab Pages letsencrypt support
-gem 'acme-client', '~> 2.0', '>= 2.0.6'
+gem 'acme-client', '~> 2.0', '>= 2.0.9'
# Browser detection
gem 'browser', '~> 4.2'
@@ -98,10 +98,7 @@ gem 'rack-cors', '~> 1.0.6', require: 'rack/cors'
# GraphQL API
gem 'graphql', '~> 1.11.10'
-# NOTE: graphiql-rails v1.5+ doesn't work: https://gitlab.com/gitlab-org/gitlab/issues/31771
-# TODO: remove app/views/graphiql/rails/editors/show.html.erb when https://github.com/rmosolgo/graphiql-rails/pull/71 is released:
-# https://gitlab.com/gitlab-org/gitlab/issues/31747
-gem 'graphiql-rails', '~> 1.4.10'
+gem 'graphiql-rails', '~> 1.8'
gem 'apollo_upload_server', '~> 2.1.0'
gem 'graphql-docs', '~> 1.6.0', group: [:development, :test]
gem 'graphlient', '~> 0.4.0' # Used by BulkImport feature (group::import)
@@ -149,6 +146,7 @@ gem 'aws-sdk-core', '~> 3'
gem 'aws-sdk-cloudformation', '~> 1'
gem 'aws-sdk-s3', '~> 1'
gem 'faraday_middleware-aws-sigv4', '~>0.3.0'
+gem 'typhoeus', '~> 1.4.0' # Used with Elasticsearch to support http keep-alive connections
# Markdown and HTML processing
gem 'html-pipeline', '~> 2.13.2'
@@ -166,10 +164,10 @@ gem 'asciidoctor', '~> 2.0.10'
gem 'asciidoctor-include-ext', '~> 0.3.1', require: false
gem 'asciidoctor-plantuml', '~> 0.0.12'
gem 'asciidoctor-kroki', '~> 0.5.0', require: false
-gem 'rouge', '~> 3.26.1'
+gem 'rouge', '~> 3.27.0'
gem 'truncato', '~> 0.7.11'
gem 'bootstrap_form', '~> 4.2.0'
-gem 'nokogiri', '~> 1.11.4'
+gem 'nokogiri', '~> 1.12'
gem 'escape_utils', '~> 1.1'
# Calendar rendering
@@ -193,12 +191,12 @@ end
# State machine
gem 'state_machines-activerecord', '~> 0.8.0'
-# Issue tags
-gem 'acts-as-taggable-on', '~> 8.1'
+# CI domain tags
+gem 'acts-as-taggable-on', '~> 9.0'
# Background jobs
gem 'sidekiq', '~> 6.3'
-gem 'sidekiq-cron', '~> 1.0'
+gem 'sidekiq-cron', '~> 1.2'
gem 'redis-namespace', '~> 1.8.1'
gem 'gitlab-sidekiq-fetcher', '0.8.0', require: 'sidekiq-reliable-fetch'
@@ -263,7 +261,7 @@ gem 'ruby-fogbugz', '~> 0.2.1'
gem 'kubeclient', '~> 4.9.2'
# Sanitize user input
-gem 'sanitize', '~> 5.2.1'
+gem 'sanitize', '~> 6.0'
gem 'babosa', '~> 1.0.4'
# Sanitizes SVG input
@@ -276,7 +274,7 @@ gem 'licensee', '~> 9.14.1'
gem 'charlock_holmes', '~> 0.7.7'
# Detect mime content type from content
-gem 'ruby-magic', '~> 0.4'
+gem 'ruby-magic', '~> 0.5'
# Faster blank
gem 'fast_blank'
@@ -312,7 +310,7 @@ gem 'pg_query', '~> 2.1'
gem 'premailer-rails', '~> 1.10.3'
# LabKit: Tracing and Correlation
-gem 'gitlab-labkit', '~> 0.21.1'
+gem 'gitlab-labkit', '~> 0.21.3'
# Thrift is a dependency of gitlab-labkit, we want a version higher than 0.14.0
# because of https://gitlab.com/gitlab-org/gitlab/-/issues/321900
gem 'thrift', '>= 0.14.0'
@@ -394,8 +392,6 @@ group :development, :test do
gem 'parallel', '~> 1.19', require: false
- gem 'rblineprof', '~> 0.3.6', platform: :mri, require: false
-
gem 'test_file_finder', '~> 0.1.3'
end
@@ -443,7 +439,8 @@ end
gem 'octokit', '~> 4.15'
-# https://gitlab.com/gitlab-org/gitlab/issues/207207
+# Updating this gem version here is deprecated. See:
+# https://docs.gitlab.com/ee/development/emails.html#mailroom-gem-updates
gem 'gitlab-mail_room', '~> 0.0.9', require: 'mail_room'
gem 'email_reply_trimmer', '~> 0.1'
@@ -483,14 +480,14 @@ end
gem 'spamcheck', '~> 0.1.0'
# Gitaly GRPC protocol definitions
-gem 'gitaly', '~> 14.4.0.pre.rc43'
+gem 'gitaly', '~> 14.6.0.pre.rc1'
# KAS GRPC protocol definitions
gem 'kas-grpc', '~> 0.0.2'
-gem 'grpc', '~> 1.30.2'
+gem 'grpc', '~> 1.42.0'
-gem 'google-protobuf', '~> 3.17.1'
+gem 'google-protobuf', '~> 3.19.0'
gem 'toml-rb', '~> 2.0'
diff --git a/Gemfile.lock b/Gemfile.lock
index 2f30df91862..797a72ce943 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -9,72 +9,72 @@ GEM
remote: https://rubygems.org/
specs:
RedCloth (4.3.2)
- acme-client (2.0.6)
+ acme-client (2.0.9)
faraday (>= 0.17, < 2.0.0)
- actioncable (6.1.4.1)
- actionpack (= 6.1.4.1)
- activesupport (= 6.1.4.1)
+ actioncable (6.1.4.4)
+ actionpack (= 6.1.4.4)
+ activesupport (= 6.1.4.4)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
- actionmailbox (6.1.4.1)
- actionpack (= 6.1.4.1)
- activejob (= 6.1.4.1)
- activerecord (= 6.1.4.1)
- activestorage (= 6.1.4.1)
- activesupport (= 6.1.4.1)
+ actionmailbox (6.1.4.4)
+ actionpack (= 6.1.4.4)
+ activejob (= 6.1.4.4)
+ activerecord (= 6.1.4.4)
+ activestorage (= 6.1.4.4)
+ activesupport (= 6.1.4.4)
mail (>= 2.7.1)
- actionmailer (6.1.4.1)
- actionpack (= 6.1.4.1)
- actionview (= 6.1.4.1)
- activejob (= 6.1.4.1)
- activesupport (= 6.1.4.1)
+ actionmailer (6.1.4.4)
+ actionpack (= 6.1.4.4)
+ actionview (= 6.1.4.4)
+ activejob (= 6.1.4.4)
+ activesupport (= 6.1.4.4)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
- actionpack (6.1.4.1)
- actionview (= 6.1.4.1)
- activesupport (= 6.1.4.1)
+ actionpack (6.1.4.4)
+ actionview (= 6.1.4.4)
+ activesupport (= 6.1.4.4)
rack (~> 2.0, >= 2.0.9)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
- actiontext (6.1.4.1)
- actionpack (= 6.1.4.1)
- activerecord (= 6.1.4.1)
- activestorage (= 6.1.4.1)
- activesupport (= 6.1.4.1)
+ actiontext (6.1.4.4)
+ actionpack (= 6.1.4.4)
+ activerecord (= 6.1.4.4)
+ activestorage (= 6.1.4.4)
+ activesupport (= 6.1.4.4)
nokogiri (>= 1.8.5)
- actionview (6.1.4.1)
- activesupport (= 6.1.4.1)
+ actionview (6.1.4.4)
+ activesupport (= 6.1.4.4)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
- activejob (6.1.4.1)
- activesupport (= 6.1.4.1)
+ activejob (6.1.4.4)
+ activesupport (= 6.1.4.4)
globalid (>= 0.3.6)
- activemodel (6.1.4.1)
- activesupport (= 6.1.4.1)
- activerecord (6.1.4.1)
- activemodel (= 6.1.4.1)
- activesupport (= 6.1.4.1)
+ activemodel (6.1.4.4)
+ activesupport (= 6.1.4.4)
+ activerecord (6.1.4.4)
+ activemodel (= 6.1.4.4)
+ activesupport (= 6.1.4.4)
activerecord-explain-analyze (0.1.0)
activerecord (>= 4)
pg
- activestorage (6.1.4.1)
- actionpack (= 6.1.4.1)
- activejob (= 6.1.4.1)
- activerecord (= 6.1.4.1)
- activesupport (= 6.1.4.1)
+ activestorage (6.1.4.4)
+ actionpack (= 6.1.4.4)
+ activejob (= 6.1.4.4)
+ activerecord (= 6.1.4.4)
+ activesupport (= 6.1.4.4)
marcel (~> 1.0.0)
mini_mime (>= 1.1.0)
- activesupport (6.1.4.1)
+ activesupport (6.1.4.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
- acts-as-taggable-on (8.1.0)
- activerecord (>= 5.0, < 6.2)
+ acts-as-taggable-on (9.0.0)
+ activerecord (>= 6.0, < 7.1)
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
aes_key_wrap (1.1.0)
@@ -124,14 +124,14 @@ GEM
aws-sigv4 (~> 1.1)
aws-sigv4 (1.2.1)
aws-eventstream (~> 1, >= 1.0.2)
- azure-storage-blob (2.0.1)
+ azure-storage-blob (2.0.3)
azure-storage-common (~> 2.0)
- nokogiri (~> 1.11.0.rc2)
- azure-storage-common (2.0.2)
+ nokogiri (~> 1, >= 1.10.8)
+ azure-storage-common (2.0.4)
faraday (~> 1.0)
- faraday_middleware (~> 1.0.0.rc1)
+ faraday_middleware (~> 1.0, >= 1.0.0.rc1)
net-http-persistent (~> 4.0)
- nokogiri (~> 1.11.0.rc2)
+ nokogiri (~> 1, >= 1.10.8)
babosa (1.0.4)
backport (1.2.0)
base32 (0.3.2)
@@ -239,7 +239,6 @@ GEM
danger
gitlab (~> 4.2, >= 4.2.0)
database_cleaner (1.7.0)
- debugger-ruby_core_source (1.3.8)
deckar01-task_list (2.3.1)
html-pipeline
declarative (0.0.20)
@@ -333,8 +332,10 @@ GEM
escape_utils (1.2.1)
et-orbi (1.2.1)
tzinfo
+ ethon (0.15.0)
+ ffi (>= 1.15.0)
eventmachine (1.2.7)
- excon (0.71.1)
+ excon (0.90.0)
execjs (2.8.1)
expression_parser (0.9.0)
extended-markdown-filter (0.6.0)
@@ -450,7 +451,7 @@ GEM
rails (>= 3.2.0)
git (1.7.0)
rchardet (~> 1.8)
- gitaly (14.4.0.pre.rc43)
+ gitaly (14.6.0.pre.rc1)
grpc (~> 1.0)
github-markup (1.7.0)
gitlab (4.16.1)
@@ -472,10 +473,10 @@ GEM
fog-json (~> 1.2.0)
mime-types
ms_rest_azure (~> 0.12.0)
- gitlab-labkit (0.21.1)
+ gitlab-labkit (0.21.3)
actionpack (>= 5.0.0, < 7.0.0)
activesupport (>= 5.0.0, < 7.0.0)
- grpc (~> 1.30.2)
+ grpc (>= 1.37)
jaeger-client (~> 1.1)
opentracing (~> 0.4)
pg_query (~> 2.1)
@@ -491,7 +492,7 @@ GEM
gitlab-mail_room (0.0.9)
gitlab-markup (1.8.0)
gitlab-net-dns (0.9.1)
- gitlab-omniauth-openid-connect (0.8.0)
+ gitlab-omniauth-openid-connect (0.9.1)
addressable (~> 2.7)
omniauth (~> 1.9)
openid_connect (~> 1.2)
@@ -511,7 +512,7 @@ GEM
omniauth (~> 1.3)
pyu-ruby-sasl (>= 0.0.3.3, < 0.1)
rubyntlm (~> 0.5)
- globalid (0.5.2)
+ globalid (1.0.0)
activesupport (>= 5.0)
gon (6.4.0)
actionpack (>= 3.0.20)
@@ -529,8 +530,8 @@ GEM
signet (~> 0.12)
google-cloud-env (1.5.0)
faraday (>= 0.17.3, < 2.0)
- google-protobuf (3.17.3)
- googleapis-common-protos-types (1.1.0)
+ google-protobuf (3.19.1)
+ googleapis-common-protos-types (1.3.0)
google-protobuf (~> 3.14)
googleauth (0.14.0)
faraday (>= 0.17.3, < 2.0)
@@ -559,7 +560,7 @@ GEM
grape_logging (1.8.3)
grape
rack
- graphiql-rails (1.4.10)
+ graphiql-rails (1.8.0)
railties
sprockets-rails
graphlient (0.4.0)
@@ -578,8 +579,8 @@ GEM
graphql (~> 1.6)
html-pipeline (~> 2.8)
sass (~> 3.4)
- grpc (1.30.2)
- google-protobuf (~> 3.12)
+ grpc (1.42.0)
+ google-protobuf (~> 3.18)
googleapis-common-protos-types (~> 1.0)
gssapi (1.2.0)
ffi (>= 1.0.1)
@@ -739,7 +740,7 @@ GEM
lumberjack (1.2.7)
mail (2.7.1)
mini_mime (>= 0.1.1)
- marcel (1.0.1)
+ marcel (1.0.2)
marginalia (1.10.0)
actionpack (>= 2.3)
activerecord (>= 2.3)
@@ -752,7 +753,7 @@ GEM
mini_histogram (0.3.1)
mini_magick (4.10.1)
mini_mime (1.1.1)
- mini_portile2 (2.5.3)
+ mini_portile2 (2.6.1)
minitest (5.11.3)
mixlib-cli (2.1.8)
mixlib-config (3.0.9)
@@ -790,11 +791,9 @@ GEM
netrc (0.11.0)
nio4r (2.5.8)
no_proxy_fix (0.1.2)
- nokogiri (1.11.7)
- mini_portile2 (~> 2.5.0)
+ nokogiri (1.12.5)
+ mini_portile2 (~> 2.6.1)
racc (~> 1.4)
- nokogumbo (2.0.2)
- nokogiri (~> 1.8, >= 1.8.4)
notiffany (0.1.3)
nenv (~> 0.1)
shellany (~> 0.0)
@@ -887,7 +886,7 @@ GEM
nokogiri (>= 1.4.4)
omniauth (~> 1.0)
open4 (1.3.4)
- openid_connect (1.2.0)
+ openid_connect (1.3.0)
activemodel
attr_required (>= 1.0.0)
json-jwt (>= 1.5.0)
@@ -952,7 +951,7 @@ GEM
puma (>= 2.7)
pyu-ruby-sasl (0.0.3.3)
raabro (1.1.6)
- racc (1.5.2)
+ racc (1.6.0)
rack (2.2.3)
rack-accept (0.4.5)
rack (>= 0.4)
@@ -971,20 +970,20 @@ GEM
rack-test (1.1.0)
rack (>= 1.0, < 3)
rack-timeout (0.5.2)
- rails (6.1.4.1)
- actioncable (= 6.1.4.1)
- actionmailbox (= 6.1.4.1)
- actionmailer (= 6.1.4.1)
- actionpack (= 6.1.4.1)
- actiontext (= 6.1.4.1)
- actionview (= 6.1.4.1)
- activejob (= 6.1.4.1)
- activemodel (= 6.1.4.1)
- activerecord (= 6.1.4.1)
- activestorage (= 6.1.4.1)
- activesupport (= 6.1.4.1)
+ rails (6.1.4.4)
+ actioncable (= 6.1.4.4)
+ actionmailbox (= 6.1.4.4)
+ actionmailer (= 6.1.4.4)
+ actionpack (= 6.1.4.4)
+ actiontext (= 6.1.4.4)
+ actionview (= 6.1.4.4)
+ activejob (= 6.1.4.4)
+ activemodel (= 6.1.4.4)
+ activerecord (= 6.1.4.4)
+ activestorage (= 6.1.4.4)
+ activesupport (= 6.1.4.4)
bundler (>= 1.15.0)
- railties (= 6.1.4.1)
+ railties (= 6.1.4.4)
sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
@@ -998,9 +997,9 @@ GEM
rails-i18n (6.0.0)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 7)
- railties (6.1.4.1)
- actionpack (= 6.1.4.1)
- activesupport (= 6.1.4.1)
+ railties (6.1.4.4)
+ actionpack (= 6.1.4.4)
+ activesupport (= 6.1.4.4)
method_source
rake (>= 0.13)
thor (~> 1.0)
@@ -1009,8 +1008,6 @@ GEM
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
- rblineprof (0.3.6)
- debugger-ruby_core_source (~> 1.3)
rbtrace (0.4.14)
ffi (>= 1.0.6)
msgpack (>= 0.4.3)
@@ -1056,7 +1053,7 @@ GEM
rexml (3.2.5)
rinku (2.0.0)
rotp (6.2.0)
- rouge (3.26.1)
+ rouge (3.27.0)
rqrcode (0.7.0)
chunky_png
rqrcode-rails3 (0.1.7)
@@ -1124,8 +1121,8 @@ GEM
rubocop-ast (>= 0.7.1)
ruby-fogbugz (0.2.1)
crack (~> 0.4)
- ruby-magic (0.4.0)
- mini_portile2 (~> 2.5.0)
+ ruby-magic (0.5.3)
+ mini_portile2 (~> 2.6)
ruby-prof (1.3.1)
ruby-progressbar (1.11.0)
ruby-saml (1.13.0)
@@ -1142,10 +1139,9 @@ GEM
safe_yaml (1.0.4)
safety_net_attestation (0.4.0)
jwt (~> 2.0)
- sanitize (5.2.1)
+ sanitize (6.0.0)
crass (~> 1.0.2)
- nokogiri (>= 1.8.0)
- nokogumbo (~> 2.0)
+ nokogiri (>= 1.12.0)
sass (3.5.5)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
@@ -1184,7 +1180,7 @@ GEM
connection_pool (>= 2.2.2)
rack (~> 2.0)
redis (>= 4.2.0)
- sidekiq-cron (1.0.4)
+ sidekiq-cron (1.2.0)
fugit (~> 1.1)
sidekiq (>= 4.2.1)
signet (0.14.0)
@@ -1251,7 +1247,7 @@ GEM
unicode-display_width (>= 1.5, < 3.0)
unicode_utils (~> 1.4)
strings-ansi (0.2.0)
- swd (1.2.0)
+ swd (1.3.0)
activesupport (>= 3)
attr_required (>= 0.0.5)
httpclient (>= 2.4)
@@ -1311,6 +1307,8 @@ GEM
tty-screen (~> 0.8)
wisper (~> 2.0)
tty-screen (0.8.1)
+ typhoeus (1.4.0)
+ ethon (>= 0.9.0)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
u2f (0.2.1)
@@ -1358,7 +1356,7 @@ GEM
safety_net_attestation (~> 0.4.0)
securecompare (~> 1.0)
tpm-key_attestation (~> 0.9.0)
- webfinger (1.1.0)
+ webfinger (1.2.0)
activesupport
httpclient (>= 2.4)
webmock (3.9.1)
@@ -1381,16 +1379,16 @@ GEM
nokogiri (~> 1.8)
yajl-ruby (1.4.1)
yard (0.9.26)
- zeitwerk (2.5.1)
+ zeitwerk (2.5.3)
PLATFORMS
ruby
DEPENDENCIES
RedCloth (~> 4.3.2)
- acme-client (~> 2.0, >= 2.0.6)
+ acme-client (~> 2.0, >= 2.0.9)
activerecord-explain-analyze (~> 0.1)
- acts-as-taggable-on (~> 8.1)
+ acts-as-taggable-on (~> 9.0)
addressable (~> 2.8)
akismet (~> 3.0)
apollo_upload_server (~> 2.1.0)
@@ -1472,36 +1470,36 @@ DEPENDENCIES
gettext (~> 3.3)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3)
- gitaly (~> 14.4.0.pre.rc43)
+ gitaly (~> 14.6.0.pre.rc1)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
gitlab-dangerfiles (~> 2.6.1)
gitlab-experiment (~> 0.6.5)
gitlab-fog-azure-rm (~> 1.2.0)
- gitlab-labkit (~> 0.21.1)
+ gitlab-labkit (~> 0.21.3)
gitlab-license (~> 2.0)
gitlab-license_finder (~> 6.0)
gitlab-mail_room (~> 0.0.9)
gitlab-markup (~> 1.8.0)
gitlab-net-dns (~> 0.9.1)
- gitlab-omniauth-openid-connect (~> 0.8.0)
+ gitlab-omniauth-openid-connect (~> 0.9.0)
gitlab-sidekiq-fetcher (= 0.8.0)
gitlab-styles (~> 6.6.0)
gitlab_chronic_duration (~> 0.10.6.2)
gitlab_omniauth-ldap (~> 2.1.1)
gon (~> 6.4.0)
google-api-client (~> 0.33)
- google-protobuf (~> 3.17.1)
+ google-protobuf (~> 3.19.0)
gpgme (~> 2.0.19)
grape (~> 1.5.2)
grape-entity (~> 0.10.0)
grape-path-helpers (~> 1.7.0)
grape_logging (~> 1.7)
- graphiql-rails (~> 1.4.10)
+ graphiql-rails (~> 1.8)
graphlient (~> 0.4.0)
graphql (~> 1.11.10)
graphql-docs (~> 1.6.0)
- grpc (~> 1.30.2)
+ grpc (~> 1.42.0)
gssapi
guard-rspec
haml_lint (~> 0.36.0)
@@ -1545,7 +1543,7 @@ DEPENDENCIES
net-ldap (~> 0.16.3)
net-ntp
net-ssh (~> 6.0)
- nokogiri (~> 1.11.4)
+ nokogiri (~> 1.12)
oauth2 (~> 1.4)
octokit (~> 4.15)
ohai (~> 16.10)
@@ -1589,11 +1587,10 @@ DEPENDENCIES
rack-oauth2 (~> 1.16.0)
rack-proxy (~> 0.6.0)
rack-timeout (~> 0.5.1)
- rails (~> 6.1.4.1)
+ rails (~> 6.1.4.4)
rails-controller-testing
rails-i18n (~> 6.0)
rainbow (~> 3.0)
- rblineprof (~> 0.3.6)
rbtrace (~> 0.4)
rdoc (~> 6.3.2)
re2 (~> 1.2.0)
@@ -1605,7 +1602,7 @@ DEPENDENCIES
responders (~> 3.0)
retriable (~> 3.1.2)
rexml (~> 3.2.5)
- rouge (~> 3.26.1)
+ rouge (~> 3.27.0)
rqrcode-rails3 (~> 0.1.7)
rspec-parameterized
rspec-rails (~> 5.0.1)
@@ -1613,14 +1610,14 @@ DEPENDENCIES
rspec_junit_formatter
rspec_profiling (~> 0.0.6)
ruby-fogbugz (~> 0.2.1)
- ruby-magic (~> 0.4)
+ ruby-magic (~> 0.5)
ruby-prof (~> 1.3.0)
ruby-progressbar (~> 1.10)
ruby-saml (~> 1.13.0)
ruby_parser (~> 3.15)
rubyzip (~> 2.0.0)
rugged (~> 1.2)
- sanitize (~> 5.2.1)
+ sanitize (~> 6.0)
sassc-rails (~> 2.1.0)
sd_notify (~> 0.1.0)
seed-fu (~> 2.3.7)
@@ -1629,7 +1626,7 @@ DEPENDENCIES
settingslogic (~> 2.0.9)
shoulda-matchers (~> 4.0.1)
sidekiq (~> 6.3)
- sidekiq-cron (~> 1.0)
+ sidekiq-cron (~> 1.2)
simple_po_parser (~> 1.1.2)
simplecov (~> 0.18.5)
simplecov-cobertura (~> 1.3.1)
@@ -1655,6 +1652,7 @@ DEPENDENCIES
timecop (~> 0.9.1)
toml-rb (~> 2.0)
truncato (~> 0.7.11)
+ typhoeus (~> 1.4.0)
u2f (~> 0.2.1)
undercover (~> 0.4.4)
unf (~> 0.1.4)
diff --git a/README.md b/README.md
index 64f19939ec2..cff7a413e0b 100644
--- a/README.md
+++ b/README.md
@@ -121,4 +121,4 @@ Please see [Getting help for GitLab](https://about.gitlab.com/getting-help/) on
## Is it awesome?
-[These people](https://twitter.com/gitlab/likes) seem to like it.
+[These people](https://twitter.com/gitlab/followers) seem to like it.
diff --git a/app/assets/images/file_icons.svg b/app/assets/images/file_icons.svg
index ec38020f978..def87dd9163 100644
--- a/app/assets/images/file_icons.svg
+++ b/app/assets/images/file_icons.svg
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 24 24" id="actionscript" xmlns="http://www.w3.org/2000/svg"><text style="line-height:113.99999857%" x="5.605" y="15.892" transform="scale(.91325 1.095)" font-weight="400" font-size="42.822" font-family="sans-serif" letter-spacing="0" word-spacing="0" fill="#f44336"/><path style="line-height:125%" d="M4.744 2.031c-1.157 0-1.994.31-2.51.93-.515.612-.771 1.678-.771 3.197v2.467c0 1.408-.402 2.111-1.201 2.111v2.035c.8 0 1.2.679 1.2 2.036v2.654c0 1.512.26 2.562.78 3.152.52.59 1.355.885 2.502.885V19.43c-.447 0-.77-.151-.97-.453-.195-.303-.292-.815-.292-1.538v-2.267c0-1.807-.404-2.937-1.214-3.395v-.045c.81-.464 1.214-1.581 1.214-3.351V6.025c0-1.283.42-1.925 1.262-1.925V2.03zm14.66 0V4.1c.842 0 1.262.642 1.262 1.925v2.268c0 1.843.402 2.996 1.207 3.46v.046c-.805.442-1.207 1.544-1.207 3.306v2.356c0 .715-.099 1.22-.299 1.516-.2.302-.52.453-.963.453v2.068c1.152 0 1.984-.295 2.494-.885.516-.59.772-1.663.772-3.218V14.84c0-1.379.404-2.069 1.209-2.069v-2.035c-.805 0-1.21-.696-1.21-2.09V6.113c0-1.49-.255-2.54-.77-3.152-.516-.62-1.348-.93-2.495-.93zm-3.054 4.46c-.455 0-.886.057-1.293.173a3.056 3.056 0 0 0-1.078.527c-.308.241-.551.549-.731.924-.18.37-.27.817-.27 1.336 0 .663.165 1.227.493 1.695.33.468.831.864 1.502 1.188.263.125.509.249.736.37.227.12.422.244.586.374.168.13.299.271.394.424a.963.963 0 0 1 .145.521c0 .144-.03.28-.09.405a.9.9 0 0 1-.275.318c-.12.088-.272.158-.455.21a2.34 2.34 0 0 1-.635.075c-.415 0-.825-.083-1.233-.25a3.644 3.644 0 0 1-1.13-.763v2.222a3.68 3.68 0 0 0 1.101.418c.427.093.875.139 1.346.139.459 0 .894-.05 1.305-.152a3.002 3.002 0 0 0 1.09-.5c.31-.237.556-.543.736-.918.183-.38.275-.849.275-1.405 0-.403-.052-.755-.156-1.056a2.542 2.542 0 0 0-.45-.813 3.295 3.295 0 0 0-.704-.633 6.754 6.754 0 0 0-.922-.535 12.4 12.4 0 0 1-.676-.348c-.2-.115-.37-.231-.51-.347a1.502 1.502 0 0 1-.322-.375.91.91 0 0 1-.115-.453c0-.153.033-.288.101-.408a.948.948 0 0 1 .29-.32c.123-.089.275-.156.454-.202a2.18 2.18 0 0 1 .598-.078c.16 0 .326.015.502.043.18.028.36.07.539.13.18.056.354.13.522.218.171.088.329.188.472.304V6.871a4.039 4.039 0 0 0-.957-.285 6.448 6.448 0 0 0-1.185-.096zm-8.774.165l-3.123 9.967h2.094l.605-2.217h3.053l.61 2.217h2.107L9.869 6.656H7.576zm1.072 1.78h.047c.028.347.077.646.145.896l.922 3.35H7.564l.934-3.377c.08-.288.13-.578.15-.87z" font-weight="400" font-size="51.019" font-family="sans-serif" letter-spacing="0" word-spacing="0" fill="#f44336"/></symbol><symbol viewBox="0 0 24 24" id="android" xmlns="http://www.w3.org/2000/svg"><path d="M15 5h-1V4h1m-5 1H9V4h1m5.53-1.84L16.84.85c.19-.19.19-.51 0-.71a.513.513 0 0 0-.71 0l-1.48 1.48C13.85 1.23 12.95 1 12 1c-.96 0-1.86.23-2.66.63L7.85.14a.501.501 0 0 0-.7 0c-.2.2-.2.52 0 .71l1.31 1.31C6.97 3.26 6 5 6 7h12c0-2-1-3.75-2.47-4.84M20.5 8A1.5 1.5 0 0 0 19 9.5v7a1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5-1.5v-7A1.5 1.5 0 0 0 20.5 8m-17 0A1.5 1.5 0 0 0 2 9.5v7A1.5 1.5 0 0 0 3.5 18 1.5 1.5 0 0 0 5 16.5v-7A1.5 1.5 0 0 0 3.5 8M6 18a1 1 0 0 0 1 1h1v3.5A1.5 1.5 0 0 0 9.5 24a1.5 1.5 0 0 0 1.5-1.5V19h2v3.5a1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5-1.5V19h1a1 1 0 0 0 1-1V8H6v10z" fill="#c0ca33"/></symbol><symbol viewBox="0 0 24 24" id="angular" xmlns="http://www.w3.org/2000/svg"><path d="M12.102 2.625l8.84 3.15-1.34 11.7-7.5 4.15-7.5-4.15-1.34-11.7 8.84-3.15m0 2.1l-5.53 12.4h2.06l1.11-2.78h4.7l1.11 2.78h2.05l-5.5-12.4m1.62 7.9h-3.23l1.61-3.87z" fill="#e53935"/></symbol><symbol viewBox="0 0 24 24" id="angular-component" xmlns="http://www.w3.org/2000/svg"><path d="M12.102 2.625l8.84 3.15-1.34 11.7-7.5 4.15-7.5-4.15-1.34-11.7 8.84-3.15m0 2.1l-5.53 12.4h2.06l1.11-2.78h4.7l1.11 2.78h2.05l-5.5-12.4m1.62 7.9h-3.23l1.61-3.87z" fill="#0288d1"/></symbol><symbol viewBox="0 0 24 24" id="angular-directive" xmlns="http://www.w3.org/2000/svg"><path d="M12.102 2.625l8.84 3.15-1.34 11.7-7.5 4.15-7.5-4.15-1.34-11.7 8.84-3.15m0 2.1l-5.53 12.4h2.06l1.11-2.78h4.7l1.11 2.78h2.05l-5.5-12.4m1.62 7.9h-3.23l1.61-3.87z" fill="#ab47bc"/></symbol><symbol viewBox="0 0 24 24" id="angular-guard" xmlns="http://www.w3.org/2000/svg"><path d="M12.102 2.625l8.84 3.15-1.34 11.7-7.5 4.15-7.5-4.15-1.34-11.7 8.84-3.15m0 2.1l-5.53 12.4h2.06l1.11-2.78h4.7l1.11 2.78h2.05l-5.5-12.4m1.62 7.9h-3.23l1.61-3.87z" fill="#43a047"/></symbol><symbol viewBox="0 0 24 24" id="angular-pipe" xmlns="http://www.w3.org/2000/svg"><path d="M12.102 2.625l8.84 3.15-1.34 11.7-7.5 4.15-7.5-4.15-1.34-11.7 8.84-3.15m0 2.1l-5.53 12.4h2.06l1.11-2.78h4.7l1.11 2.78h2.05l-5.5-12.4m1.62 7.9h-3.23l1.61-3.87z" fill="#00897b"/></symbol><symbol viewBox="0 0 24 24" id="angular-resolver" xmlns="http://www.w3.org/2000/svg"><path d="M12.102 2.625l8.84 3.15-1.34 11.7-7.5 4.15-7.5-4.15-1.34-11.7 8.84-3.15m0 2.1l-5.53 12.4h2.06l1.11-2.78h4.7l1.11 2.78h2.05l-5.5-12.4m1.62 7.9h-3.23l1.61-3.87z" fill="#43a047"/></symbol><symbol viewBox="0 0 24 24" id="angular-routing" xmlns="http://www.w3.org/2000/svg"><path d="M11 10H5L3 8l2-2h6V3l1-1 1 1v1h6l2 2-2 2h-6v2h6l2 2-2 2h-6v6a2 2 0 0 1 2 2H9a2 2 0 0 1 2-2V10z" fill="#43a047"/></symbol><symbol viewBox="0 0 24 24" id="angular-service" xmlns="http://www.w3.org/2000/svg"><path d="M12.102 2.625l8.84 3.15-1.34 11.7-7.5 4.15-7.5-4.15-1.34-11.7 8.84-3.15m0 2.1l-5.53 12.4h2.06l1.11-2.78h4.7l1.11 2.78h2.05l-5.5-12.4m1.62 7.9h-3.23l1.61-3.87z" fill="#ffca28"/></symbol><symbol viewBox="0 0 100 100" id="apiblueprint" xmlns="http://www.w3.org/2000/svg"><title>api-blueprint</title><path d="M50.133 7.521A16.998 16.998 0 0 0 33.135 24.52a16.998 16.998 0 0 0 4.945 11.974L24.861 57.398a16.998 16.998 0 0 0-3.175-.308A16.998 16.998 0 0 0 4.688 74.088a16.998 16.998 0 0 0 16.998 16.998 16.998 16.998 0 0 0 16.998-16.998 16.998 16.998 0 0 0-7.063-13.773l12.576-19.89a16.998 16.998 0 0 0 5.936 1.093 16.998 16.998 0 0 0 6.154-1.155l12.537 19.83a16.998 16.998 0 0 0-7.244 13.895 16.998 16.998 0 0 0 16.998 17 16.998 16.998 0 0 0 16.998-17A16.998 16.998 0 0 0 78.578 57.09a16.998 16.998 0 0 0-2.95.262L62.337 36.327A16.998 16.998 0 0 0 67.13 24.52 16.998 16.998 0 0 0 50.132 7.522z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="applescript" xmlns="http://www.w3.org/2000/svg"><path d="M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z" fill="#78909c"/></symbol><symbol viewBox="0 0 24 24" id="appveyor" xmlns="http://www.w3.org/2000/svg"><path d="M12 2c-.084 0-.165.008-.248.01a10 10 0 0 0-.266.01 9.952 9.952 0 0 0-.754.066 10 10 0 0 0-.148.018 9.855 9.855 0 0 0-.93.177 10 10 0 0 0-.07.02c-.196.049-.392.1-.584.16v.012a10 10 0 0 0-2 .875V3.34c-.02.012-.038.027-.059.039a10 10 0 0 0-.953.635c-.09.067-.172.142-.26.213a10 10 0 0 0-.628.546c-.109.104-.211.211-.315.319a10 10 0 0 0-.476.539c-.1.12-.201.237-.295.361a10 10 0 0 0-.52.766c-.088.143-.17.288-.252.435a10 10 0 0 0-.363.723c-.072.161-.136.327-.2.492a10 10 0 0 0-.269.778c-.02.067-.044.131-.062.199a10 10 0 0 0-.008.027c-.098.364-.166.728-.22 1.09-.012.077-.024.153-.034.23a9.85 9.85 0 0 0-.08 1.182c0 .03-.006.057-.006.086a10 10 0 0 0 .008.148c.001.094-.002.188.002.282l.011.004a10 10 0 0 0 .333 2.158l-.012-.004c.012.047.033.091.047.139a10 10 0 0 0 .322.955c.02.052.037.106.059.158a10 10 0 0 0 .503 1.035c.065.116.14.226.21.34a10 10 0 0 0 .423.64c.092.128.187.252.285.375a10 10 0 0 0 .448.52c.112.123.222.248.341.365a10 10 0 0 0 .803.719 10 10 0 0 0 .01.006c.099.078.207.146.309.22a10 10 0 0 0 .648.442c.138.085.28.163.424.242a10 10 0 0 0 .715.358c.114.051.226.106.343.154a10 10 0 0 0 1.133.389c.016.004.031.01.047.015a10 10 0 0 0 .461.098 10 10 0 0 0 .482.103 10 10 0 0 0 .418.051 10 10 0 0 0 .575.065 10 10 0 0 0 .144.005A10 10 0 0 0 12 22a10 10 0 0 0 .197-.01 10 10 0 0 0 .496-.025 10 10 0 0 0 .49-.043 10 10 0 0 0 .489-.074 10 10 0 0 0 .51-.098 10 10 0 0 0 .47-.12 10 10 0 0 0 .477-.14 10 10 0 0 0 .47-.172 10 10 0 0 0 .481-.197 10 10 0 0 0 .414-.201 10 10 0 0 0 .475-.252 10 10 0 0 0 .39-.238 10 10 0 0 0 .452-.301 10 10 0 0 0 .38-.291 10 10 0 0 0 .385-.315 10 10 0 0 0 .375-.347 10 10 0 0 0 .36-.363 10 10 0 0 0 .293-.334 10 10 0 0 0 .353-.434 10 10 0 0 0 .28-.393 10 10 0 0 0 .263-.4 10 10 0 0 0 .264-.461 10 10 0 0 0 .228-.436 10 10 0 0 0 .195-.437 10 10 0 0 0 .196-.48 10 10 0 0 0 .228-.69 10 10 0 0 0 .028-.094 10 10 0 0 0 .021-.066 10 10 0 0 0 .098-.461 10 10 0 0 0 .103-.482 10 10 0 0 0 .051-.418 10 10 0 0 0 .065-.575 10 10 0 0 0 .005-.144A10 10 0 0 0 22 12a10 10 0 0 0-.01-.197 10 10 0 0 0-.025-.496 10 10 0 0 0-.043-.49 10 10 0 0 0-.074-.489 10 10 0 0 0-.098-.51 10 10 0 0 0-.12-.47 10 10 0 0 0-.14-.477 10 10 0 0 0-.172-.47 10 10 0 0 0-.197-.481 10 10 0 0 0-.201-.414 10 10 0 0 0-.252-.475 10 10 0 0 0-.238-.39 10 10 0 0 0-.301-.452 10 10 0 0 0-.291-.38 10 10 0 0 0-.315-.385 10 10 0 0 0-.347-.375 10 10 0 0 0-.363-.36 10 10 0 0 0-.334-.293 10 10 0 0 0-.434-.353 10 10 0 0 0-.393-.28 10 10 0 0 0-.4-.263 10 10 0 0 0-.461-.264 10 10 0 0 0-.436-.228 10 10 0 0 0-.437-.196 10 10 0 0 0-.48-.195 10 10 0 0 0-.69-.228 10 10 0 0 0-.094-.028 10 10 0 0 0-.066-.021 10 10 0 0 0-.461-.098 10 10 0 0 0-.482-.103 10 10 0 0 0-.418-.051 10 10 0 0 0-.575-.065 10 10 0 0 0-.144-.005A10 10 0 0 0 12 2zm-.016 5.002a5 5 0 0 1 .262.01 5 5 0 0 1 .227.011 5 5 0 0 1 .341.05 5 5 0 0 1 .135.019 5 5 0 0 1 .014.004 5 5 0 0 1 .115.025 5 5 0 0 1 .303.076 5 5 0 0 1 .265.086 5 5 0 0 1 .2.074 5 5 0 0 1 .242.106 5 5 0 0 1 .228.11 5 5 0 0 1 .196.109 5 5 0 0 1 .244.15 5 5 0 0 1 .17.12 5 5 0 0 1 .224.171 5 5 0 0 1 .186.16 5 5 0 0 1 .176.164 5 5 0 0 1 .172.18 5 5 0 0 1 .177.203 5 5 0 0 1 .133.172 5 5 0 0 1 .16.223 5 5 0 0 1 .133.214 5 5 0 0 1 .12.21 5 5 0 0 1 .107.216 5 5 0 0 1 .109.24 5 5 0 0 1 .084.223 5 5 0 0 1 .08.242 5 5 0 0 1 .07.264 5 5 0 0 1 .047.207 5 5 0 0 1 .045.277 5 5 0 0 1 .028.227 5 5 0 0 1 .02.351 5 5 0 0 1 .003.079 5 5 0 0 1-.012.271 5 5 0 0 1-.011.227 5 5 0 0 1-.05.341 5 5 0 0 1-.019.135 5 5 0 0 1-.004.014 5 5 0 0 1-.025.115 5 5 0 0 1-.076.303 5 5 0 0 1-.086.265 5 5 0 0 1-.074.2 5 5 0 0 1-.106.242 5 5 0 0 1-.11.228 5 5 0 0 1-.109.196 5 5 0 0 1-.15.244 5 5 0 0 1-.12.17 5 5 0 0 1-.171.224 5 5 0 0 1-.16.186 5 5 0 0 1-.164.176 5 5 0 0 1-.18.172 5 5 0 0 1-.203.177l-.002.002c-.018.019-.028.035-.047.053l-3.959 5.09-3.05-.979a141.684 141.684 0 0 0 3.177-3.084 5 5 0 0 1-.103-.015 5 5 0 0 1-.149-.024 5 5 0 0 1-.115-.025 5 5 0 0 1-3.57-3.04 5.072 5.072 0 0 1-.206-.661 5 5 0 0 1-.033-.147c-.025-.118-.036-.24-.054-.36-.987.993-1.964 1.993-2.954 3.05l-.98-3.053 5.092-3.957c.043-.044.082-.07.125-.11a5 5 0 0 1 .71-.634c.18-.13.367-.25.561-.356a5 5 0 0 1 .16-.08 4.94 4.94 0 0 1 .516-.222 5 5 0 0 1 .147-.057c.211-.07.43-.123.654-.164a5 5 0 0 1 .172-.027c.236-.035.476-.058.722-.059zM12 9a3 3 0 0 0-.053.002 3 3 0 0 0-.166.01 3 3 0 0 0-.133.011 3 3 0 0 0-.17.026 3 3 0 0 0-.113.021 3 3 0 0 0-.19.05 3 3 0 0 0-.103.03 3 3 0 0 0-.16.057 3 3 0 0 0-.129.053 3 3 0 0 0-.146.072 3 3 0 0 0-.12.063 3 3 0 0 0-.132.082 3 3 0 0 0-.123.08 3 3 0 0 0-.116.088 3 3 0 0 0-.126.105 3 3 0 0 0-.1.094 3 3 0 0 0-.111.111 3 3 0 0 0-.096.107 3 3 0 0 0-.094.116 3 3 0 0 0-.098.136 3 3 0 0 0-.072.11 3 3 0 0 0-.076.133 3 3 0 0 0-.07.132 3 3 0 0 0-.063.14 3 3 0 0 0-.054.14 3 3 0 0 0-.077.228 3 3 0 0 0-.007.026 3 3 0 0 0-.03.138 3 3 0 0 0-.031.149 3 3 0 0 0-.014.11 3 3 0 0 0-.02.183 3 3 0 0 0-.001.052A3 3 0 0 0 9 12a3 3 0 0 0 .002.053 3 3 0 0 0 .01.166 3 3 0 0 0 .011.133 3 3 0 0 0 .026.17 3 3 0 0 0 .021.113 3 3 0 0 0 .05.19 3 3 0 0 0 .03.103 3 3 0 0 0 .057.16 3 3 0 0 0 .053.129 3 3 0 0 0 .072.146 3 3 0 0 0 .063.12 3 3 0 0 0 .082.132 3 3 0 0 0 .08.123 3 3 0 0 0 .088.116 3 3 0 0 0 .105.126 3 3 0 0 0 .094.1 3 3 0 0 0 .111.111 3 3 0 0 0 .107.096 3 3 0 0 0 .116.094 3 3 0 0 0 .136.098 3 3 0 0 0 .11.072 3 3 0 0 0 .133.076 3 3 0 0 0 .132.07 3 3 0 0 0 .135.06 3 3 0 0 0 .153.061 3 3 0 0 0 .216.07 3 3 0 0 0 .004.003 3 3 0 0 0 .026.007 3 3 0 0 0 .138.03 3 3 0 0 0 .149.031 3 3 0 0 0 .11.014 3 3 0 0 0 .183.02 3 3 0 0 0 .011.001 3 3 0 0 0 .041 0A3 3 0 0 0 12 15a3 3 0 0 0 .053-.002 3 3 0 0 0 .166-.01 3 3 0 0 0 .133-.011 3 3 0 0 0 .17-.026 3 3 0 0 0 .113-.021 3 3 0 0 0 .19-.05 3 3 0 0 0 .103-.03 3 3 0 0 0 .16-.057 3 3 0 0 0 .129-.053 3 3 0 0 0 .146-.072 3 3 0 0 0 .12-.063 3 3 0 0 0 .132-.082 3 3 0 0 0 .123-.08 3 3 0 0 0 .116-.088 3 3 0 0 0 .126-.105 3 3 0 0 0 .1-.094 3 3 0 0 0 .111-.111 3 3 0 0 0 .096-.107 3 3 0 0 0 .094-.116 3 3 0 0 0 .098-.136 3 3 0 0 0 .072-.11 3 3 0 0 0 .076-.133 3 3 0 0 0 .07-.132 3 3 0 0 0 .06-.135 3 3 0 0 0 .061-.153 3 3 0 0 0 .07-.216 3 3 0 0 0 .003-.004 3 3 0 0 0 .007-.026 3 3 0 0 0 .03-.138 3 3 0 0 0 .031-.149 3 3 0 0 0 .002-.008 3 3 0 0 0 .012-.101 3 3 0 0 0 .02-.184 3 3 0 0 0 .001-.011 3 3 0 0 0 0-.041A3 3 0 0 0 15 12a3 3 0 0 0-.002-.053 3 3 0 0 0-.01-.166 3 3 0 0 0-.011-.133 3 3 0 0 0-.026-.17 3 3 0 0 0-.021-.113 3 3 0 0 0-.05-.19 3 3 0 0 0-.03-.103 3 3 0 0 0-.057-.16 3 3 0 0 0-.053-.129 3 3 0 0 0-.072-.146 3 3 0 0 0-.063-.12 3 3 0 0 0-.082-.132 3 3 0 0 0-.08-.123 3 3 0 0 0-.088-.116 3 3 0 0 0-.105-.126 3 3 0 0 0-.094-.1 3 3 0 0 0-.111-.111 3 3 0 0 0-.107-.096 3 3 0 0 0-.116-.094 3 3 0 0 0-.136-.098 3 3 0 0 0-.11-.072 3 3 0 0 0-.133-.076 3 3 0 0 0-.132-.07 3 3 0 0 0-.14-.063 3 3 0 0 0-.14-.054 3 3 0 0 0-.228-.077 3 3 0 0 0-.026-.007 3 3 0 0 0-.138-.03 3 3 0 0 0-.149-.031 3 3 0 0 0-.008-.002 3 3 0 0 0-.101-.012 3 3 0 0 0-.184-.02 3 3 0 0 0-.011-.001 3 3 0 0 0-.041 0A3 3 0 0 0 12 9z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 720 720" id="arduino" xmlns="http://www.w3.org/2000/svg"><defs><symbol id="ana" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg"><path fill="none" stroke-opacity="100%" stroke-width="60" stroke="#00979c" d="M174 30a10.5 10.1 0 0 0 0 280C364 320 344 30 544 30a10.5 10.1 0 0 1 0 280C354 320 374 30 174 30"/><path d="M528 205v-32.8h-32.5v-13.7H528V126h13.9v32.5h32.5v13.7h-32.5V205H528z" text-anchor="middle" fill="#00979c" stroke-width="20" stroke="#00979c" font-family="sans-serif" font-size="167"/><path fill="#00979c" stroke="#00979c" stroke-width="23.6" transform="matrix(1.56 0 0 .64 -366 .528)" d="M321 266v-17.4h53.3V266H321z"/></symbol></defs><title>Layer 1</title><use x="20.063" y="360.85" transform="matrix(.997 0 0 .997 -18.596 -159.19)" xlink:href="#ana"/></symbol><symbol viewBox="0 0 24 24" id="assembly" xmlns="http://www.w3.org/2000/svg"><path d="M1.746 1.566v20.905H5.13v-2.088H3.438V3.656h1.69v-2.09H1.747zm17.219 0v2.09h1.693v16.727h-1.693v2.09h3.383V1.566h-3.383zM15.196 3.988c-.5 0-.93.076-1.29.225-.359.15-.652.372-.877.671-.226.302-.39.673-.494 1.108a6.715 6.715 0 0 0-.155 1.54c0 .573.049 1.083.15 1.528.1.442.264.811.49 1.11.222.298.512.524.872.676.36.153.795.23 1.304.23.518 0 .954-.075 1.308-.224.353-.153.643-.376.869-.671.219-.29.38-.661.484-1.112.104-.454.156-.967.156-1.54 0-.573-.052-1.079-.152-1.515a2.92 2.92 0 0 0-.485-1.106 2.09 2.09 0 0 0-.868-.686c-.354-.155-.79-.234-1.312-.234zm-6.814.12a.941.941 0 0 1-.138.458.849.849 0 0 1-.356.296A1.71 1.71 0 0 1 7.385 5a5.244 5.244 0 0 1-.631.037v1.11H8.19v3.6H6.754v1.188h4.545V9.745H9.894V4.11H8.382zm6.814 1.138c.375 0 .643.176.805.527.161.348.241.933.241 1.756 0 .814-.082 1.399-.247 1.756-.164.356-.43.534-.799.534-.369 0-.636-.178-.8-.534-.165-.357-.248-.941-.248-1.749 0-.829.082-1.415.243-1.763.162-.35.43-.527.805-.527zm-6.33 7.64c-.5 0-.93.073-1.29.223-.359.15-.651.374-.877.673-.225.302-.39.67-.494 1.106a6.715 6.715 0 0 0-.155 1.54c0 .573.05 1.082.15 1.527.1.442.264.814.49 1.112.222.3.514.525.874.677.36.152.793.229 1.302.229.519 0 .954-.076 1.308-.225.354-.153.643-.376.869-.672.22-.29.38-.66.484-1.111.104-.455.156-.967.156-1.54 0-.573-.05-1.079-.15-1.515a2.923 2.923 0 0 0-.487-1.106 2.084 2.084 0 0 0-.867-.686c-.353-.156-.791-.232-1.313-.232zm5.846.119a.941.941 0 0 1-.138.457.85.85 0 0 1-.356.296 1.71 1.71 0 0 1-.503.137 5.245 5.245 0 0 1-.631.037v1.112h1.435v3.597h-1.435v1.189h4.545v-1.189h-1.405v-5.636h-1.512zm-5.846 1.137c.375 0 .643.176.805.527.162.347.241.933.241 1.756 0 .813-.08 1.399-.245 1.755-.164.357-.432.534-.8.534-.37 0-.637-.177-.802-.534-.164-.356-.245-.939-.245-1.746 0-.83.08-1.418.242-1.765.161-.35.43-.527.804-.527z" fill="#ff6e40"/></symbol><symbol viewBox="0 0 24 24" id="aurelia" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="api" x1="-31.824" x2="19.682" y1="-11.741" y2="35.548" gradientTransform="scale(.95818 1.0436)" gradientUnits="userSpaceOnUse" xlink:href="#apa"/><linearGradient id="apa" x1="-3.881" x2="2.377" y1="-1.442" y2="4.304"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="apj" x1="12.022" x2="-15.716" y1="13.922" y2="-23.952" gradientTransform="scale(.96226 1.0392)" gradientUnits="userSpaceOnUse" xlink:href="#apb"/><linearGradient id="apb" x1=".729" x2="-.971" y1=".844" y2="-1.477"><stop stop-color="#6E4D9B" offset="0"/><stop stop-color="#77327A" offset=".14"/><stop stop-color="#B31777" offset=".29"/><stop stop-color="#CD0F7E" offset=".84"/><stop stop-color="#ED2C89" offset="1"/></linearGradient><linearGradient id="apk" x1="-23.39" x2="23.931" y1="-57.289" y2="8.573" gradientTransform="scale(1.0429 .95884)" gradientUnits="userSpaceOnUse" xlink:href="#apc"/><linearGradient id="apc" x1="-2.839" x2="2.875" y1="-6.936" y2="1.017"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="apl" x1="-53.331" x2="6.771" y1="-30.517" y2="18.785" gradientTransform="scale(.99898 1.001)" gradientUnits="userSpaceOnUse" xlink:href="#apd"/><linearGradient id="apd" x1="-8.212" x2="1.02" y1="-4.691" y2="2.882"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="apm" x1="-14.029" x2="41.998" y1="-23.111" y2="26.259" gradientTransform="scale(1.0003 .99965)" gradientUnits="userSpaceOnUse" xlink:href="#ape"/><linearGradient id="ape" x1="-1.404" x2="4.19" y1="-2.309" y2="2.62"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="apn" x1="31.177" x2="3.37" y1="41.442" y2="3.402" gradientTransform="scale(.96254 1.0389)" gradientUnits="userSpaceOnUse" xlink:href="#apf"/><linearGradient id="apf" x1="1.911" x2=".204" y1="2.539" y2=".204"><stop stop-color="#6E4D9B" offset="0"/><stop stop-color="#77327A" offset=".14"/><stop stop-color="#B31777" offset=".29"/><stop stop-color="#CD0F7E" offset=".84"/><stop stop-color="#ED2C89" offset="1"/></linearGradient><linearGradient id="apo" x1="-31.905" x2="19.599" y1="-14.258" y2="42.767" gradientTransform="scale(.95823 1.0436)" gradientUnits="userSpaceOnUse" xlink:href="#apg"/><linearGradient id="apg" x1="-3.881" x2="2.377" y1="-1.738" y2="5.19"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="app" x1="4.301" x2="34.534" y1="34.41" y2="4.514" gradientTransform="scale(1.002 .99796)" gradientUnits="userSpaceOnUse" xlink:href="#aph"/><linearGradient id="aph" x1=".112" x2=".901" y1=".897" y2=".116"><stop stop-color="#6E4D9B" offset="0"/><stop stop-color="#77327A" offset=".14"/><stop stop-color="#B31777" offset=".53"/><stop stop-color="#CD0F7E" offset=".79"/><stop stop-color="#ED2C89" offset="1"/></linearGradient></defs><g transform="rotate(11.282 -1.694 21.569) scale(.47102)" clip-rule="evenodd" fill="none" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path d="M8.002 6.127L4.117 8.719.116 2.723 4 .13z" transform="rotate(-11.284 17.839 -78.732)" fill="url(#api)"/><path d="M9.179 1.887l6.637 9.946-7.906 5.276-6.637-9.946L.115 5.43 8.02.153z" transform="rotate(-11.284 129.49 -99.884)" fill="url(#apj)"/><path d="M7.3 1.88l1.462 2.189-6.018 4.015L.124 4.16l1.315-.877L6.143.144z" transform="rotate(-11.284 167.2 -62.32)" fill="url(#apk)"/><path d="M2.328 1.146L4.016.02l2.619 3.925L2.75 6.537 1.29 4.347l2.197-1.466zm-1.04 3.201L.132 2.612l2.197-1.466 1.158 1.735z" transform="rotate(-11.284 104.37 -149.22)" fill="url(#apl)"/><path d="M5.346 9.155l-1.315.877L.03 4.035 6.047.019l2.805 4.204L4.15 7.36l4.703-3.138 1.197 1.793z" transform="rotate(-11.284 81.819 7.645)" fill="url(#apm)"/><path d="M14.533 9.934l1.197 1.793-7.907 5.276-1.196-1.793L.052 5.358 7.958.082z" transform="rotate(-11.284 17.141 -7.825)" fill="url(#apn)"/><path d="M6.235 7.177L4.038 8.643 2.84 6.849.036 2.646 3.92.053 7.923 6.05z" transform="rotate(-11.284 18.188 -79.174)" fill="url(#apo)"/><path d="M18.955 35.925L17.48 34.45l3.998-3.998 1.475 1.475z" fill="#714896"/><path d="M33.33 21.55l-1.475-1.474 1.867-1.868 1.475 1.475z" fill="#6f4795"/><path d="M7.12 24.09l-1.525-1.525 3.998-3.998 1.525 1.525z" fill="#88519f"/><path d="M21.495 9.714L19.97 8.19l1.868-1.868 1.524 1.525z" fill="#85509e"/><path d="M31.418 23.462l-6.72 6.72-1.475-1.474 6.72-6.721z" fill="#8d166a"/><path d="M18.058 10.101l1.525 1.525-6.721 6.72-1.525-1.524z" fill="#a70d6f"/><path d="M2.375 11.769l1.9 1.9-1.9 1.901-1.901-1.9z" fill="#9e61ad"/><path d="M15.523 36.482l1.9 1.9-1.9 1.901-1.9-1.9z" fill="#8053a3"/><path d="M8.372 38.294L.017 29.876 29.749.08l8.636 8.201z" transform="translate(1.823 1.548)" fill="url(#app)"/></g></symbol><symbol viewBox="0 0 24 24" id="autohotkey" xmlns="http://www.w3.org/2000/svg"><path d="M5 3c-1.11 0-2 .89-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5zm3.668 3.447a.9.9 0 0 1 .652.256.84.84 0 0 1 .262.625c0 .34-.014.852-.041 1.537-.022.68-.033 1.19-.033 1.53 0 .111-.016.326-.047.644a6.149 6.149 0 0 0-.033.68l2.578-.485c1.007-.179 1.874-.281 2.603-.308.018-.3.048-1.105.088-2.416.01-.345.115-.742.317-1.19.25-.55.533-.826.851-.826.237 0 .448.08.631.236.197.17.295.382.295.637a.775.775 0 0 1-.025.201c-.09.327-.135.612-.135.854 0 .125-.014.32-.041.584-.023.26-.033.453-.033.578 0 .425-.022 1.056-.067 1.893a38.963 38.963 0 0 0-.068 1.892c0 .327.025.816.074 1.465.05.649.074 1.136.074 1.463a.84.84 0 0 1-.261.625.893.893 0 0 1-.65.254 1 1 0 0 1-.686-.254.777.777 0 0 1-.29-.611c0-.327-.015-.818-.046-1.471a39.552 39.552 0 0 1-.041-1.47c0-.256.004-.482.013-.679-.702.032-1.57.142-2.603.33-.86.157-1.719.316-2.578.477-.01.304-.042.812-.096 1.523a22.354 22.354 0 0 0-.066 1.538.84.84 0 0 1-.262.625.893.893 0 0 1-.65.253.898.898 0 0 1-.653-.253.84.84 0 0 1-.262-.625c0-.452.038-1.128.114-2.028.08-.9.12-1.575.12-2.027 0-.573.015-1.436.042-2.586.027-1.155.04-2.017.04-2.59a.84.84 0 0 1 .263-.625.895.895 0 0 1 .65-.256z" fill="#4caf50"/></symbol><symbol viewBox="0 0 24 24" id="autoit" xmlns="http://www.w3.org/2000/svg"><defs id="ardefs8"><style id="arstyle4482">.cls-1{fill:#5d83ac}.cls-2{fill:#f0f0f0;fill-rule:evenodd}</style><style id="arstyle4510">.cls-1{fill:#5d83ac}.cls-2{fill:#f0f0f0;fill-rule:evenodd}</style></defs><g id="arg4522" transform="translate(-59.538 -26.404) scale(.0555)"><path d="M12.8 2.133A10.666 10.666 0 0 0 2.136 12.799 10.666 10.666 0 0 0 12.8 23.465a10.666 10.666 0 0 0 10.668-10.666A10.666 10.666 0 0 0 12.8 2.133zm.15 4.713c.456 0 .836.105 1.142.314.306.21.565.469.78.78l6.089 8.812H9.627l1.82-2.506h3.36c.315 0 .589.01.822.03a11.93 11.93 0 0 1-.473-.663 39.13 39.13 0 0 0-.517-.75l-1.748-2.578-4.577 6.467H4.746l6.25-8.813c.204-.281.46-.534.772-.757.31-.224.705-.336 1.181-.336z" transform="matrix(16.89188 0 0 16.89188 1072.761 475.745)" id="arcircle4514" fill="#1976d2" stroke-width=".026"/></g></symbol><symbol viewBox="0 0 213.33333 213.33333" id="babel" xmlns="http://www.w3.org/2000/svg"><path d="M50.22 199.659c-.875-.406-1.261-1.6-.857-2.652.404-1.053.12-1.914-.63-1.914s-1.615.748-1.92 1.663c-.328.983-1.27.302-2.304-1.667-.962-1.831-3.718-5.533-6.126-8.226-9.418-10.535-7.71-27.444 5.432-53.77 12.459-24.96 23.117-39.033 45.966-60.696 30.229-28.66 52.679-46.223 70.587-55.22 10.98-5.518 13.025-5.059 2.778.624-11.004 6.102-11.378 6.359-10.512 7.226.33.33 7.306-2.67 15.504-6.667 15.87-7.737 16.34-7.912 16.34-6.082 0 .652-4.95 3.738-11 6.858-13.062 6.736-12.722 6.48-10.472 7.872 1.117.69 5.428-.582 11.54-3.406 5.367-2.48 10.397-4.508 11.179-4.508 2.755 0-3.928 5.302-11.541 9.157-20.437 10.35-68.937 46.043-68.07 50.097.166.777-5.792 7.639-13.241 15.248-15.257 15.587-26.14 30.002-33.748 44.706-6.379 12.326-7.457 17.734-5.385 26.996 3.482 15.56 11.592 18.366 31.482 10.895 28.228-10.603 45.758-28.704 47.022-48.556.602-9.442-1.317-13.479-8.52-17.93-4.01-2.48-5.268-2.621-12.065-1.365-4.173.771-10.153 2.906-13.289 4.744s-6.455 3.34-7.377 3.34c-.922 0-3.216 1.336-5.096 2.968-1.88 1.633.48-1.13 5.247-6.14 6.82-7.167 7.956-8.9 5.333-8.132-5.208 1.525-10.194 4.33-15.649 8.803-2.76 2.264-.923.175 4.08-4.641 11.565-11.131 21.183-15.97 33.088-16.641 17.097-.966 27.254 5.805 31.964 21.31 2.435 8.017 2.609 10.24 1.353 17.37-1.65 9.361-7.034 21.553-15.593 35.307-4.398 7.067-8.434 11.427-15.588 16.844-9.166 6.94-15.654 11.02-15.654 9.845 0-.295 2.455-2.161 5.455-4.147 8.818-5.835 5.075-5.377-8.326 1.02-6.854 3.27-15.199 6.593-18.542 7.38-7.106 1.675-30.527 3.164-32.846 2.089zm-8.408-19.899c0-1.1-.6-2-1.333-2-.734 0-1.334.9-1.334 2s.6 2 1.333 2c.734 0 1.334-.9 1.334-2zm89.255-8.204c1.53-1.945 2.473-3.845 2.097-4.222-.377-.377-.836-.435-1.02-.13-.182.306-1.787 2.206-3.565 4.223-1.778 2.016-2.571 3.666-1.763 3.666s2.72-1.591 4.25-3.536zm-77.644-1.745c-.82-2.172-1.74-3.7-2.045-3.396-.951.952 1.088 7.345 2.343 7.345.656 0 .522-1.777-.298-3.95zm82.303-27.915c-.837-.837-3.217 2.55-3.184 4.53.012.734.896.178 1.965-1.235 1.07-1.413 1.618-2.896 1.219-3.295zm-66.238-36.904c-1.312-1.312-3.676.702-3.676 3.133 0 2.035.175 2.031 2.254-.047 1.24-1.24 1.88-2.628 1.422-3.086zm39.657.768c4.403-2.196 6.8-3.986 5.333-3.982-2.838.01-16.667 6.028-16.667 7.254 0 1.6 3.717.527 11.333-3.272zm16.667-5.333c0-.733-.9-1.333-2-1.333s-2 .6-2 1.333.9 1.333 2 1.333 2-.6 2-1.333zm-3.334-3.923l5.334-1.104-7.334-.133c-4.033-.073-8.233.45-9.333 1.16-2.539 1.64 3.572 1.682 11.333.077zm35.738-63.976c2.788-1.69 4.765-3.376 4.393-3.748-.947-.947-11.942 5.654-14.237 8.548-1.792 2.258-1.714 2.276 1.44.329a1452.76 1452.76 0 0 1 8.403-5.13z" fill="#ffca28" stroke-width="1.333"/></symbol><symbol viewBox="0 0 400 400" fill-opacity=".05" id="bithound" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(.88 0 0 .88 24.121 2.895)" fill="#e53935" fill-opacity="1"><path d="M370.5 207c-1.5-14.8-4.8-29.9-9.5-44-13.5-40.3-38.6-81.6-70.3-110.1-1.4-1.2-6.7-4.4-8.7-3.3-5.2 2.9 4.6 22.8 5.8 26.4 7.4 22 12.1 45.3 6.8 68.3-7.1 30.4-30.4 51.7-61.5 54.3-17.1 1.4-34.3-.5-51.4 1.5-25.6 3-51.7 11.8-68 32.8-1.9 2.4-3.6 5.1-5.2 7.9h-.4c-6.3.7-12.6-2-15.7-3.7-.8-.5-1.6-.9-2.2-1.2-19-10.5-33-34-41.6-53.4-3.9-9-7.2-18.4-9.3-27.9-1-4.3-1.1-8.8-1.3-13.2-.1-2.7.3-6.5-1.2-8.9-3.3-5.2-7.5-.2-8.2 4-1.1 6.9-2.1 13.7-1.8 20.7.5 11.8 3.8 23.5 8 34.5 6.2 16.2 14.9 31.1 26.2 44.4 4.7 5.5 9.7 10.6 15.1 15.3 4.8 4.3 10.9 7.7 14.5 13.2 4.2 6.3 4.9 14.1 4.5 21.4-1 19.3-1.6 37.4 3.9 56.2 4.8 16.7 10.8 33.8 20.8 48.1 5 7.1 11.2 14.6 18 19.9 4.6 3.6 13.3 4 8.3-9.2-11.1-29.3-12.1-59.7 5.2-87.1 14.5-22.8 40.1-43.1 69-39.5 42.5 5.3 72.1 44.3 70 86-.6 11.7-1 21.7-4.7 32.7-1.5 4.4-2.6 10-1.5 14.6 1.8 7.8 10.5 4.9 14.3-.2 10.3-14 21.1-27.6 30.8-42 31.6-47.2 47-101.8 41.3-158.5z"/><path d="M132.4 92.1c.7 2.3 1.4 4.8 1.9 7.5.1 1.1.4 2.3 1 3.4 2.6 6.8 8.9 10.5 14.8 14 3.6 2.2 10.1 4.3 14.1 5.9 5.2 2.1 16.4-.6 21.7-1 12.2-1 23.5-5.3 34.7 1.2-57.4 67.3-3.2 82.3 38.8 49.9 48-37 2.8-124.3 2.8-124.3s-1-6.8-19.2-10.8c-1.7-.9-3.4-1.7-5.1-2.4-18-8.3-34.2 5.3-47.2 16.4-3.8 3.2-7.5 6.4-11.5 9.4-5.4 4-11.2 7.3-17.3 10.2-6.4 3-14 6.4-21.1 6.7-1 0-2.9.2-4.9.6-3.1.3-4.7 1.1-5.4 2.5-1.2 1-2 2.4-1.8 4.2.2 2.5 1.4 4.6 2.7 6.2.4.1.7.3 1 .4z"/></g></symbol><symbol viewBox="0 0 400.00001 399.99999" id="bower" xmlns="http://www.w3.org/2000/svg"><g transform="translate(12.061 33.203) scale(.81733)"><path d="M447.61 200.08c-23.139-22.234-138.85-36.114-175.36-40.154a107.137 107.137 0 0 0 4.517-12.944 146.107 146.107 0 0 1 15.905-5.901c.677 1.997 3.865 9.648 5.682 13.279 73.415 2.025 77.184-54.557 80.17-70.058 2.92-15.157 2.771-29.802 27.953-56.575-37.516-10.933-91.467 16.945-109.54 58.437-6.79-2.545-13.597-4.424-20.328-5.586-4.824-19.46-29.944-73.672-95.863-73.672-83.46 0-174.43 68.853-174.43 185.41 0 97.976 66.891 183.84 104.68 183.84 16.505 0 30.703-12.36 34.036-23.44 2.795 7.597 11.368 31.213 14.184 37.225 4.162 8.89 23.41 16.583 31.833 7.357 10.83 6.017 30.703 9.641 41.534-6.405 20.86 4.412 39.3-8.026 39.702-22.868 10.235-.546 15.256-14.918 13.021-26.363-1.647-8.426-19.248-38.66-26.113-49.098 13.59 11.054 48.013 14.183 52.194.007 21.911 17.198 56.057 8.171 58.765-5.815 26.624 6.917 57.16-8.276 52.146-26.676 42.771-2.958 37.296-48.464 25.296-59.996z" fill="#543729" stroke-width=".973"/><path d="M328.514 103.025c9.212-18.277 20.788-38.234 35.409-50.58-16.093 6.485-31.981 25.873-41.375 46.595a144.914 144.914 0 0 0-14.552-8.132c13.105-27.972 43.555-51.332 77.112-53.157-22.477 20.385-14.498 62.754-32.979 85.183-5.288-5.311-17.43-15.562-23.615-19.909zm-14.53 29.762c.01-.7.272-6.094.763-8.557-1.288-.304-9.3-1.87-13.476-1.772-.304 5.245 2.204 14.17 4.684 19.541 17.075-.358 29.408-5.471 36.667-10.172-6.18-2.88-16.726-5.442-24.745-6.974-.894 1.851-3.097 6.568-3.892 7.934z" fill="#00acee"/><g stroke-width=".973"><path d="M250.54 277.39c.004.024.015.057.018.082-2.165-4.657-4.463-10.314-7.208-17.708 10.688 15.557 44.184 7.533 42.427-6.407 16.395 12.336 50.143-2.055 42.471-19.353 16.423 7.653 35.168-7.745 30.964-14.455 28 5.4 54.832 10.783 63.256 12.938-5.595 9.123-18.339 15.566-37.549 11.089 10.38 14.14-9.773 31.105-37.844 21.76 6.18 13.883-18.814 26.38-47.22 11.91.361 13.889-35.24 15.488-49.315.143zm55.543-70.194c32.497 2.495 86.238 7.34 119.51 11.997-2.102-10.828-7.844-13.921-25.905-18.772-19.425 2.072-68.706 6.913-93.604 6.776z" fill="#2baf2b"/><path d="M285.78 253.36c16.395 12.336 50.143-2.055 42.471-19.353 16.423 7.653 35.168-7.745 30.964-14.455-33.103-6.383-67.84-12.788-75.719-13.908 4.78.254 12.702.797 22.59 1.556 24.899.137 74.18-4.704 93.604-6.775-31.452-7.975-95.666-19.613-140.01-22.48-2.055 3.003-5.833 8.097-12.413 13.51-19.403 41.053-54.557 68.34-93.454 68.34-11.335 0-24.018-1.912-38.233-6.456-8.865 9.497-46.661 16.694-77.329 1.641 24.326 56.961 80.74 94.984 143.19 94.984 52.591 0 75.912-53.704 70.808-67.914-1.238-3.45-6.145-14.889-8.891-22.283 10.689 15.556 44.185 7.532 42.429-6.408z" fill="#ffcc2f"/><path d="M253.91 145.27c4.644-2.526 20.69-12.253 35.981-15.908a67.843 67.843 0 0 1-.536-5.12c-10.032 2.403-28.945 10.51-39.784-.661 22.866 6.9 34.283-6.149 51.09-6.149 10.014 0 24.305 2.798 35.57 7.22-9.061-8.37-38.772-33.63-75.558-33.717-8.213 9.957-17.09 31.526-6.764 54.334z" fill="#cecece"/><path d="M115.58 253.33c14.215 4.544 26.898 6.457 38.233 6.457 38.896 0 74.05-27.29 93.454-68.341-14.351 11.978-39.291 22.228-78.241 22.228 34.694-7.866 64.56-25.156 79.753-50.427-10.68-16.998-22.263-54.603 7.07-84.33-4.512-14.497-26.475-52.766-75.095-52.766-84.85 0-155.17 71.001-155.17 166.15 0 22.525 4.547 43.65 12.67 62.664 30.666 15.054 68.462 7.858 77.327-1.64z" fill="#ef5734"/><path d="M141.03 108.45c0 21.644 17.546 39.191 39.19 39.191s39.192-17.548 39.192-39.191c0-21.644-17.548-39.191-39.192-39.191-21.644 0-39.19 17.547-39.19 39.191z" fill="#ffcc2f"/><path d="M156.76 108.45c0 12.958 10.507 23.463 23.463 23.463 12.96 0 23.464-10.506 23.464-23.463 0-12.959-10.504-23.464-23.464-23.464-12.957 0-23.463 10.506-23.463 23.464z" fill="#543729"/><ellipse cx="180.22" cy="98.044" rx="13.673" ry="8.501" fill="#fff"/></g></g></symbol><symbol viewBox="0 0 140 140" id="browserlist" xmlns="http://www.w3.org/2000/svg"><title>Browserslist logo</title><path d="M70.314 10.066a59.828 59.828 0 0 0-59.828 59.828 59.828 59.828 0 0 0 59.828 59.828 59.828 59.828 0 0 0 59.828-59.828 59.828 59.828 0 0 0-59.828-59.828zm-4.836 8.785c.496 4.043 1.352 7.322 2.572 10.223 4.779-4.287 10.265-7.546 16.041-9.02-.981 3.938-1.357 7.295-1.261 10.43 6.026-2.314 12.349-3.404 18.3-2.706-3.182 2.413-5.482 4.717-7.128 7.015-2.201 12.074 6.858 20.43 14.779 24.551a5.128 5.128 0 0 1 5.183-3.888 5.128 5.128 0 0 1 3.7 8.435v.002c-.487 1.055-2.002 2.343-3.497 3.219-4.075 2.39-11.172 5.736-20.914 7.39.045 1.214.077 2.453.077 3.747 0 4.817-.485 8.291-1.385 10.699-3.3 13.313-12.648 26.76-24.695 31.95.357-4.083.197-7.485-.402-10.591-5.582 3.218-11.646 5.278-17.623 5.52h-.002c1.785-3.662 2.855-6.878 3.412-9.976-6.347.996-12.727.742-18.377-1.17 2.93-2.732 5.054-5.314 6.673-7.96-6.292-1.344-12.169-3.87-16.766-7.686 3.822-1.544 6.795-3.239 9.3-5.197-5.426-3.517-10.034-7.998-12.972-13.23 4.012-.07 7.321-.568 10.3-1.453-3.786-5.215-6.468-11.032-7.333-16.951 3.861 1.405 7.196 2.133 10.36 2.355-1.662-6.22-2.081-12.605-.768-18.436 3.03 2.634 5.824 4.48 8.63 5.815.678-6.406 2.576-12.52 5.893-17.496 1.926 3.622 3.914 6.391 6.111 8.672 2.93-5.754 6.9-10.798 11.791-14.262zm26.465 19.557c-2.395 5.514-1.665 11.297-.555 18.732a2.138 2.138 0 0 0 .28-4.178 3.419 3.419 0 1 1 .092 6.704c.574 3.882 1.157 8.18 1.421 13.125a67.143 67.143 0 0 0 3.25-.649c6.616-1.487 12.258-3.801 16.871-6.506.45-.264.884-.563 1.276-.867.366-.557.333-.957.035-1.285-4.831-1.245-10.891-4.53-15.258-8.795-4.764-4.653-7.428-10.164-7.412-16.281z" fill="#ffca28" stroke-width=".855"/></symbol><symbol viewBox="0 0 140 140" id="browserlist_light" xmlns="http://www.w3.org/2000/svg"><title>Browserslist logo</title><g transform="translate(10.823 10.1)" stroke-width=".855"><circle cx="59.492" cy="59.795" r="59.828" fill="#ffca28"/><path d="M54.656 8.752c-4.89 3.464-8.862 8.508-11.791 14.262-2.198-2.28-4.185-5.05-6.111-8.672-3.318 4.976-5.216 11.09-5.893 17.496-2.807-1.335-5.6-3.18-8.63-5.814-1.314 5.83-.895 12.216.767 18.436-3.164-.223-6.498-.95-10.36-2.356.865 5.92 3.548 11.737 7.333 16.951-2.978.885-6.287 1.383-10.3 1.453 2.939 5.233 7.547 9.714 12.972 13.23-2.505 1.959-5.478 3.654-9.299 5.198 4.596 3.815 10.474 6.341 16.766 7.685-1.62 2.647-3.743 5.228-6.674 7.96 5.65 1.912 12.03 2.166 18.377 1.17-.556 3.098-1.626 6.314-3.412 9.975h.002c5.977-.24 12.042-2.3 17.623-5.52.6 3.108.76 6.51.402 10.593 12.047-5.19 21.395-18.638 24.695-31.951.9-2.408 1.385-5.881 1.385-10.7 0-1.293-.031-2.531-.076-3.745 9.742-1.655 16.839-5.001 20.914-7.39 1.494-.877 3.01-2.165 3.496-3.22v-.002a5.128 5.128 0 0 0-3.7-8.435 5.128 5.128 0 0 0-5.183 3.889c-7.92-4.122-16.98-12.477-14.779-24.551 1.646-2.299 3.947-4.603 7.13-7.016-5.952-.698-12.276.392-18.302 2.707-.095-3.135.28-6.492 1.262-10.43-5.776 1.473-11.262 4.733-16.041 9.02-1.22-2.902-2.076-6.18-2.572-10.223zm26.465 19.557c-.015 6.117 2.648 11.628 7.412 16.281 4.366 4.265 10.426 7.55 15.258 8.795.298.328.331.728-.035 1.285-.392.304-.825.603-1.275.867-4.613 2.704-10.256 5.019-16.871 6.506-1.071.24-2.154.458-3.25.649-.265-4.945-.848-9.243-1.422-13.125a3.419 3.419 0 1 0-.092-6.703 2.138 2.138 0 0 1-.28 4.177c-1.11-7.435-1.84-13.218.555-18.732z" fill="#37474f"/></g></symbol><symbol viewBox="0 0 24 24" id="bucklescript" xmlns="http://www.w3.org/2000/svg"><path d="M3 3v18h18V3H3zm14.1 8.858a5.5 5.5 0 0 1 1.26.145c.417.093.778.213 1.082.357v1.723h-.18a3.281 3.281 0 0 0-.959-.603 2.867 2.867 0 0 0-1.155-.247c-.14 0-.277.011-.416.035a1.4 1.4 0 0 0-.395.12.756.756 0 0 0-.291.231.54.54 0 0 0-.123.348c0 .198.065.35.196.456.13.104.376.2.738.288.237.057.466.11.683.164.22.054.455.128.706.222.496.188.86.444 1.095.77.238.32.357.738.357 1.253 0 .737-.271 1.336-.813 1.798-.538.46-1.27.689-2.197.689a5.447 5.447 0 0 1-1.402-.161 6.725 6.725 0 0 1-1.117-.416v-1.794h.183c.344.318.73.563 1.155.734.429.17.839.256 1.233.256.1 0 .235-.01.4-.03.166-.02.3-.055.403-.102a.97.97 0 0 0 .313-.225c.084-.09.127-.223.127-.4a.568.568 0 0 0-.183-.424c-.119-.12-.294-.213-.526-.276-.243-.067-.5-.128-.773-.185a5.523 5.523 0 0 1-.76-.227c-.544-.204-.936-.48-1.177-.828-.237-.351-.357-.786-.357-1.305 0-.697.27-1.265.81-1.703.54-.442 1.235-.663 2.083-.663zm-8.981.135h2.51c.521 0 .903.02 1.143.06.243.041.484.13.721.266.246.144.43.338.548.583.121.24.181.518.181.83 0 .36-.082.68-.247.959a1.697 1.697 0 0 1-.7.642v.04c.423.098.758.298 1.004.603.249.305.373.706.373 1.205 0 .361-.063.686-.19.97-.125.285-.296.52-.516.707a2.31 2.31 0 0 1-.845.472c-.304.094-.69.141-1.159.141H8.12v-7.478zm1.659 1.372v1.582h.262c.263 0 .486-.007.672-.017.185-.01.332-.043.44-.1.15-.077.248-.175.294-.295.046-.124.07-.266.07-.427a.91.91 0 0 0-.083-.371.518.518 0 0 0-.282-.277 1.187 1.187 0 0 0-.456-.086c-.18-.007-.433-.01-.76-.01h-.157zm0 2.873V18.1H9.9c.469 0 .804-.002 1.007-.006.202-.003.39-.046.56-.13a.712.712 0 0 0 .357-.33c.067-.142.099-.302.099-.483 0-.237-.04-.42-.121-.547-.078-.13-.214-.228-.405-.291a1.842 1.842 0 0 0-.538-.072 49.47 49.47 0 0 0-.716-.003h-.366z" fill="#26a69a" stroke-width="1.067"/></symbol><symbol viewBox="0 0 24 24" id="c" xmlns="http://www.w3.org/2000/svg"><path d="M15.45 15.97l.42 2.44c-.26.14-.68.27-1.24.39-.57.13-1.24.2-2.01.2-2.21-.04-3.87-.7-4.98-1.96-1.14-1.27-1.68-2.88-1.68-4.83C6 9.9 6.68 8.13 8 6.89 9.28 5.64 10.92 5 12.9 5c.75 0 1.4.07 1.94.19s.94.25 1.2.4l-.6 2.49-1.04-.34c-.4-.1-.87-.15-1.4-.15-1.15-.01-2.11.36-2.86 1.1-.76.73-1.14 1.85-1.18 3.34.01 1.36.37 2.42 1.08 3.2.71.77 1.7 1.17 2.99 1.18l1.33-.12c.43-.08.79-.19 1.09-.32z" fill="#0277bd"/></symbol><symbol viewBox="0 0 300 300" id="cabal" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -822.52)" fill-rule="evenodd" color="#000"><rect transform="matrix(-.98339 .18149 .60192 .79856 0 0)" x="405.55" y="967.22" width="107.25" height="156.59" rx="12.306" ry="12.31" fill="#2d9bbd"/><rect transform="matrix(-.98528 .17093 -.59175 .80612 0 0)" x="-1156.5" y="1461.9" width="108.34" height="123.15" rx="10.69" ry="12.31" fill="#4a4bcd"/><path d="M52.112 965.158c-1.343 3.515-26.292 23.248-25.744 27.277.548 4.03 29.812 16.023 32.04 19.027s10.545 41.668 13.603 42.5 18.828-31.274 21.548-32.932c2.72-1.658 32.808 2.503 34.15-1.01 1.343-3.515-18.174-35.352-18.721-39.381-.548-4.03 9.732-40.12 7.502-43.125-2.229-3.005-30.06 9.427-33.118 8.594-3.059-.833-26.793-27.3-29.514-25.643-2.72 1.657-.405 41.177-1.747 44.693z" fill="#2e5bc1"/></g></symbol><symbol viewBox="0 0 24 24" id="cake" xmlns="http://www.w3.org/2000/svg"><path d="M12.254 6.621a1.807 1.807 0 0 0 1.808-1.807c0-.344-.09-.66-.262-.932l-1.546-2.684-1.546 2.684a1.72 1.72 0 0 0-.262.932 1.808 1.808 0 0 0 1.808 1.807m4.158 9.04l-.967-.976-.976.976c-1.175 1.166-3.236 1.175-4.42 0l-.959-.976-.994.976a3.134 3.134 0 0 1-3.977.353v4.167a.904.904 0 0 0 .904.904h14.463a.904.904 0 0 0 .904-.904v-4.167a3.134 3.134 0 0 1-3.977-.353m1.265-6.328h-4.52V7.525H11.35v1.808H6.83a2.712 2.712 0 0 0-2.711 2.712v1.392c0 .977.795 1.772 1.771 1.772.489 0 .94-.18 1.248-.515l1.952-1.926 1.908 1.926c.669.669 1.835.669 2.504 0l1.916-1.926 1.944 1.926c.316.334.768.515 1.247.515.976 0 1.78-.795 1.78-1.772v-1.392a2.712 2.712 0 0 0-2.711-2.712z" fill="#ff7043" stroke-width=".904"/></symbol><symbol viewBox="0 0 24 24" id="certificate" xmlns="http://www.w3.org/2000/svg"><path d="M4 3c-1.11 0-2 .89-2 2v10a2 2 0 0 0 2 2h8v5l3-3 3 3v-5h2a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H4m8 2l3 2 3-2v3.5l3 1.5-3 1.5V15l-3-2-3 2v-3.5L9 10l3-1.5V5M4 5h5v2H4V5m0 4h3v2H4V9m0 4h5v2H4v-2z" fill="#ff5722"/></symbol><symbol viewBox="0 0 24 24" id="changelog" xmlns="http://www.w3.org/2000/svg"><path d="M11 7v5.11l4.71 2.79.79-1.28-4-2.37V7m0-5C8.97 2 5.91 3.92 4.27 6.77L2 4.5V11h6.5L5.75 8.25C6.96 5.73 9.5 4 12.5 4a7.5 7.5 0 0 1 7.5 7.5 7.5 7.5 0 0 1-7.5 7.5c-3.27 0-6.03-2.09-7.06-5h-2.1c1.1 4.03 4.77 7 9.16 7 5.24 0 9.5-4.25 9.5-9.5A9.5 9.5 0 0 0 12.5 2z" fill="#8bc34a"/></symbol><symbol viewBox="0 0 24 24" id="clojure" xmlns="http://www.w3.org/2000/svg"><path d="M3.355 1.78c-.845 0-1.525.68-1.525 1.525v17.441c0 .845.68 1.525 1.525 1.525h17.442c.845 0 1.525-.68 1.525-1.525V3.305c0-.845-.68-1.526-1.525-1.526H3.355zm6.168 2.572h1.963l6.368 14.931H15.93l-3.38-8.086-3.349 8.086H7.21l4.346-10.38-2.032-4.551z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="cmake" xmlns="http://www.w3.org/2000/svg"><path d="M11.99 2.965L2.977 20.999l9.874-8.47-.863-9.564z" fill="#1e88e5"/><path d="M12.007 2.963l.002.29 1.312 14.498-.001.006.023.26 7.362 2.979h.416l-.158-.311-.114-.228h-.002l-8.84-17.494z" fill="#e53935"/><path d="M8.607 16.11L2.98 20.995h17.743v-.016L8.607 16.11z" fill="#7cb342"/></symbol><symbol class="bfmain_logo__svg" viewBox="0 0 300 300.00001" id="code-climate" xmlns="http://www.w3.org/2000/svg"><path class="bfsymbol" d="M196.19 75.562l-51.846 51.561 30.766 30.766 21.08-21.08 59.252 59.537 30.481-30.766zm-61.246 60.961l-30.481-30.481-78.053 78.053-11.964 11.964 30.766 30.766 11.964-12.249 39.596-39.312 7.691-7.691 30.481 30.48 28.772 28.773 30.766-30.766-28.772-28.772z" fill="#eee" stroke-width="2.849"/></symbol><symbol class="bgmain_logo__svg" viewBox="0 0 300 300.00001" id="code-climate_light" xmlns="http://www.w3.org/2000/svg"><path class="bgsymbol" d="M196.19 75.562l-51.846 51.561 30.766 30.766 21.08-21.08 59.252 59.537 30.481-30.766zm-61.246 60.961l-30.481-30.481-78.053 78.053-11.964 11.964 30.766 30.766 11.964-12.249 39.596-39.312 7.691-7.691 30.481 30.48 28.772 28.773 30.766-30.766-28.772-28.772z" fill="#455a64" stroke-width="2.849"/></symbol><symbol viewBox="0 0 24 24" id="coffee" xmlns="http://www.w3.org/2000/svg"><path d="M2 21h18v-2H2M20 8h-2V5h2m0-2H4v10a4 4 0 0 0 4 4h6a4 4 0 0 0 4-4v-3h2a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="coldfusion" xmlns="http://www.w3.org/2000/svg"><rect transform="rotate(90)" x="2.283" y="-21.86" width="19.487" height="19.487" ry="0" fill="#0d3858" stroke="#4dd0e1" stroke-width=".7"/><text x="6.653" y="16.426" fill="#4dd0e1" font-family="Calibri" font-size="29.001" font-weight="bold" letter-spacing="0" stroke-width=".725" word-spacing="0" style="line-height:1.25"><tspan x="6.653" y="16.426" font-family="'Segoe UI'" font-size="10.634" font-weight="normal">C<tspan font-size="11.844">f</tspan></tspan></text></symbol><symbol viewBox="0 0 24 24" id="conduct" xmlns="http://www.w3.org/2000/svg"><path d="M10 17l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9m-6-6a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m7 0h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z" fill="#cddc39"/></symbol><symbol viewBox="0 0 24 24" id="console" xmlns="http://www.w3.org/2000/svg"><path d="M20 19V7H4v12h16m0-16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16m-7 14v-2h5v2h-5m-3.42-4L5.57 9H8.4l3.3 3.3c.39.39.39 1.03 0 1.42L8.42 17H5.59z" fill="#ff7043"/></symbol><symbol viewBox="0 0 24 24" id="contributing" xmlns="http://www.w3.org/2000/svg"><path d="M17 9H7V7h10m0 6H7v-2h10m-3 6H7v-2h7M12 3a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m7 0h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z" fill="#ffca28"/></symbol><symbol viewBox="0 0 24 24" id="cpp" xmlns="http://www.w3.org/2000/svg"><path d="M10.5 15.97l.41 2.44c-.26.14-.68.27-1.24.39-.57.13-1.24.2-2.01.2-2.21-.04-3.87-.7-4.98-1.96C1.56 15.77 1 14.16 1 12.21c.05-2.31.72-4.08 2-5.32C4.32 5.64 5.96 5 7.94 5c.75 0 1.4.07 1.94.19s.94.25 1.2.4l-.58 2.49-1.06-.34c-.4-.1-.86-.15-1.39-.15-1.16-.01-2.12.36-2.87 1.1-.76.73-1.15 1.85-1.18 3.34 0 1.36.37 2.42 1.08 3.2.71.77 1.71 1.17 2.99 1.18l1.33-.12c.43-.08.79-.19 1.1-.32M11 11h2V9h2v2h2v2h-2v2h-2v-2h-2v-2m7 0h2V9h2v2h2v2h-2v2h-2v-2h-2v-2z" fill="#0277bd"/></symbol><symbol viewBox="0 0 24 24" id="credits" xmlns="http://www.w3.org/2000/svg"><path d="M3 3h18v2H3V3m4 4h10v2H7V7m-4 4h18v2H3v-2m4 4h10v2H7v-2m-4 4h18v2H3v-2z" fill="#9ccc65"/></symbol><symbol viewBox="0 0 200 200" id="crystal" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:none}</style><path d="M179.363 121.67l-57.623 57.507c-.23.23-.576.346-.806.23l-78.713-21.09c-.346-.115-.577-.345-.577-.576L20.44 79.144c-.115-.345 0-.576.23-.806L78.294 20.83c.23-.23.576-.346.807-.23l78.713 21.09c.345.114.576.345.576.575l21.09 78.597c.23.346.115.577-.115.807zM102.148 59.09l-77.33 20.63c-.115 0-.23.23-.115.345l56.586 56.47c.115.115.346.115.346-.115l20.744-77.215c.115 0-.115-.23-.23-.116z" stroke-width="1.153" fill="#cfd8dc"/></symbol><symbol viewBox="0 0 200 200" id="crystal_light" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:none}</style><path d="M179.363 121.67l-57.623 57.507c-.23.23-.576.346-.806.23l-78.713-21.09c-.346-.115-.577-.345-.577-.576L20.44 79.144c-.115-.345 0-.576.23-.806L78.294 20.83c.23-.23.576-.346.807-.23l78.713 21.09c.345.114.576.345.576.575l21.09 78.597c.23.346.115.577-.115.807zM102.148 59.09l-77.33 20.63c-.115 0-.23.23-.115.345l56.586 56.47c.115.115.346.115.346-.115l20.744-77.215c.115 0-.115-.23-.23-.116z" fill="#37474f" stroke-width="1.153"/></symbol><symbol viewBox="0 0 24 24" id="csharp" xmlns="http://www.w3.org/2000/svg"><path d="M11.5 15.97l.41 2.44c-.26.14-.68.27-1.24.39-.57.13-1.24.2-2.01.2-2.21-.04-3.87-.7-4.98-1.96C2.56 15.77 2 14.16 2 12.21c.05-2.31.72-4.08 2-5.32C5.32 5.64 6.96 5 8.94 5c.75 0 1.4.07 1.94.19s.94.25 1.2.4l-.58 2.49-1.06-.34c-.4-.1-.86-.15-1.39-.15-1.16-.01-2.12.36-2.87 1.1-.76.73-1.15 1.85-1.18 3.34 0 1.36.37 2.42 1.08 3.2.71.77 1.71 1.17 2.99 1.18l1.33-.12c.43-.08.79-.19 1.1-.32M13.89 19l.61-4H13l.34-2h1.5l.32-2h-1.5L14 9h1.5l.61-4h2l-.61 4h1l.61-4h2l-.61 4H22l-.34 2h-1.5l-.32 2h1.5L21 15h-1.5l-.61 4h-2l.61-4h-1l-.61 4h-2m2.95-6h1l.32-2h-1l-.32 2z" fill="#0277bd"/></symbol><symbol viewBox="0 0 24 24" id="css" xmlns="http://www.w3.org/2000/svg"><path d="M5 3l-.65 3.34h13.59L17.5 8.5H3.92l-.66 3.33h13.59l-.76 3.81-5.48 1.81-4.75-1.81.33-1.64H2.85l-.79 4 7.85 3 9.05-3 1.2-6.03.24-1.21L21.94 3H5z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="css-map" xmlns="http://www.w3.org/2000/svg"><path d="M18 8v2h2v10H10v-2H8v4h14V8h-4z" fill="#42a5f5"/><path d="M4.676 3l-.488 2.51h10.211l-.33 1.623H3.864l-.496 2.502H13.58l-.57 2.863-4.119 1.36-3.569-1.36.248-1.232H3.06l-.593 3.005 5.898 2.254 6.8-2.254.902-4.53.18-.91L17.406 3H4.675z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 33 33" id="cucumber" xmlns="http://www.w3.org/2000/svg"><title>cucumber-mark-transparent-pips</title><g transform="translate(0 -5)" fill="none" fill-rule="evenodd"><path d="M-4-1h40v40H-4z"/><path d="M16.641 7.092c-7.028 0-12.714 5.686-12.714 12.714 0 6.187 4.435 11.327 10.288 12.471v3.64C21.824 34.77 28.561 28.73 29.063 20.8c.303-4.772-2.076-9.644-6.09-12.01a10.575 10.575 0 0 0-1.455-.728l-.243-.097c-.223-.082-.448-.175-.68-.242a12.614 12.614 0 0 0-3.954-.632zm2.62 4.707a1.387 1.387 0 0 0-1.213.485c-.233.31-.379.611-.534.923-.466 1.087-.31 2.251.388 3.105 1.087-.233 2.01-.927 2.475-2.014a2.45 2.45 0 0 0 .243-1.02c.048-.824-.634-1.404-1.359-1.479zm-5.654.073c-.708.068-1.382.63-1.382 1.407 0 .31.087.709.243 1.02.466 1.086 1.46 1.78 2.546 2.013.621-.854.782-2.018.316-3.105-.155-.311-.3-.617-.534-.85a1.364 1.364 0 0 0-1.188-.485zm-3.809 3.735c-1.224.063-1.77 1.602-.752 2.402.31.233.612.403.922.559 1.087.466 2.344.306 3.275-.316-.233-1.009-1.023-1.936-2.11-2.402-.388-.155-.703-.243-1.092-.243-.087-.009-.161-.004-.243 0zm11.961 4.708a3.551 3.551 0 0 0-2.013.582c.233 1.01 1.023 1.936 2.11 2.401.389.156.705.244 1.093.244 1.397.077 2.08-1.65.994-2.427-.31-.233-.611-.379-.922-.534a3.354 3.354 0 0 0-1.262-.266zm-10.603.072a3.376 3.376 0 0 0-1.261.267c-.389.155-.69.325-.923.558-1.009.854-.33 2.48 1.068 2.402.388 0 .782-.087 1.092-.243 1.087-.465 1.859-1.392 2.014-2.401a3.474 3.474 0 0 0-1.99-.582zm3.931 2.378c-1.087.233-2.009.927-2.475 2.014-.155.31-.243.684-.243.995-.077 1.32 1.724 2.028 2.5 1.02.233-.312.378-.613.534-.923.466-1.01.306-2.174-.316-3.106zm2.887.073c-.621.854-.781 2.019-.315 3.106.155.31.3.615.534.848.854.932 2.65.243 2.572-.921 0-.31-.088-.71-.243-1.02-.466-1.087-1.46-1.78-2.547-2.013z" fill="#4caf50" stroke-width=".776"/></g></symbol><symbol id="cuda" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"><style>.bust0{fill:#76b900}</style><title>NVIDIA-Logo</title><path id="buEye_Mark" class="bust0" d="M76.362 75.199V64.116c1.095-.068 2.19-.137 3.284-.137 30.377-.958 50.286 26.135 50.286 26.135s-21.483 29.83-44.539 29.83c-3.079 0-6.089-.48-8.962-1.438v-33.66c11.836 1.436 14.23 6.636 21.277 18.471l15.804-13.273s-11.562-15.12-30.992-15.12c-2.053-.068-4.105.069-6.158.274m0-36.67v16.556l3.284-.205c42.213-1.437 69.784 34.618 69.784 34.618s-31.608 38.45-64.516 38.45c-2.873 0-5.678-.274-8.483-.753v10.262c2.326.274 4.72.48 7.046.48 30.65 0 52.817-15.668 74.3-34.14 3.558 2.874 18.13 9.784 21.14 12.794-20.388 17.104-67.937 30.856-94.893 30.856-2.6 0-5.062-.137-7.525-.41v14.436h116.44V38.532zm0 79.977v8.757C48.038 122.2 40.17 92.712 40.17 92.712s13.615-15.05 36.192-17.514v9.579h-.068c-11.836-1.437-21.14 9.646-21.14 9.646s5.268 18.678 21.209 24.082M26.077 91.481S42.839 66.714 76.43 64.115v-9.03C39.213 58.094 7.057 89.565 7.057 89.565s18.199 52.68 69.305 57.47v-9.579c-37.492-4.652-50.286-45.975-50.286-45.975z" fill="#8bc34a" stroke-width=".684"/></symbol><symbol viewBox="0 0 24 24" id="dart" xmlns="http://www.w3.org/2000/svg"><title>Dart</title><path d="M12.486 1.385a.978.978 0 0 0-.682.281l-.01.007-6.387 3.692 6.371 6.372v.004l7.659 7.659 1.46-2.63-5.265-12.64-2.456-2.457a.972.972 0 0 0-.69-.288z" fill="#00ca94"/><path d="M5.422 5.35L1.73 11.733l-.007.01a.967.967 0 0 0 .006 1.371l3.059 3.061 11.963 4.706 2.704-1.502-.073-.073-.018.002-7.5-7.512h-.01L5.423 5.35z" fill="#1565c0"/><path d="M5.405 5.353l6.518 6.525h.01l7.502 7.51 2.855-.544.005-8.449-3.016-2.955c-.66-.647-1.675-1.064-2.695-1.202l.002-.032-11.181-.853z" fill="#1565c0"/><path d="M5.414 5.361l6.521 6.522v.009l7.506 7.506-.546 2.855h-8.448l-2.954-3.017c-.647-.66-1.064-1.676-1.2-2.696l-.033.003L5.414 5.36z" fill="#00ee94"/></symbol><symbol viewBox="0 0 24 24" id="database" xmlns="http://www.w3.org/2000/svg"><path d="M12 3C7.58 3 4 4.79 4 7s3.58 4 8 4 8-1.79 8-4-3.58-4-8-4M4 9v3c0 2.21 3.58 4 8 4s8-1.79 8-4V9c0 2.21-3.58 4-8 4s-8-1.79-8-4m0 5v3c0 2.21 3.58 4 8 4s8-1.79 8-4v-3c0 2.21-3.58 4-8 4s-8-1.79-8-4z" fill="#ffca28"/></symbol><symbol viewBox="0 0 24 24" id="diff" xmlns="http://www.w3.org/2000/svg"><path d="M3 1c-1.11 0-2 .89-2 2v11c0 1.11.89 2 2 2h2v-2H3V3h11v2h2V3c0-1.11-.89-2-2-2H3m6 6c-1.11 0-2 .89-2 2v2h2V9h2V7H9m4 0v2h1v1h2V7h-3m5 0v2h2v11H9v-2H7v2c0 1.11.89 2 2 2h11c1.11 0 2-.89 2-2V9c0-1.11-.89-2-2-2h-2m-4 5v2h-2v2h2c1.11 0 2-.89 2-2v-2h-2m-7 1v3h3v-2H9v-1H7z" fill="#42a5f5"/></symbol><symbol id="docker" viewBox="0 0 41 34.5" xmlns="http://www.w3.org/2000/svg"><style id="bystyle2">.byst0{fill:#fff}.byst1{clip-path:url(#bySVGID_4_)}</style><g id="byg34" transform="translate(.292 1.9)" fill="#0087c9"><g id="byg32"><g id="byg30"><g id="byg28"><g id="byg26"><g id="byg9"><path id="bySVGID_1_" class="byst0" d="M8.7 24c-1.1 0-2.1-.9-2.1-2s.9-2 2.1-2c1.2 0 2.1.9 2.1 2s-1 2-2.1 2zm25.8-10.9c-.2-1.6-1.2-2.9-2.5-3.9l-.5-.4-.4.5c-.8.9-1.1 2.5-1 3.7.1.9.4 1.8.9 2.5-.4.2-.9.4-1.3.6-.9.3-1.8.4-2.7.4H1.1l-.1.6c-.2 1.9.1 3.9.9 5.7l.4.7v.1c2.4 4 6.7 5.8 11.4 5.8 9 0 16.4-3.9 19.9-12.3 2.3.1 4.6-.5 5.7-2.7l.3-.5-.5-.3c-1.3-.8-3.1-.9-4.6-.5zm-12.9-1.6h-3.9v3.9h3.9zm0-4.9h-3.9v3.9h3.9zm0-5h-3.9v3.9h3.9zm4.8 9.9h-3.9v3.9h3.9zm-14.5 0H8v3.9h3.9zm4.9 0h-3.9v3.9h3.9zm-9.7 0H3.2v3.9h3.9zm9.7-4.9h-3.9v3.9h3.9zm-4.9 0H8v3.9h3.9z"/></g></g></g></g></g></g></symbol><symbol viewBox="0 0 24 24" id="document" xmlns="http://www.w3.org/2000/svg"><path d="M13 9h5.5L13 3.5V9M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m9 16v-2H6v2h9m3-4v-2H6v2h12z" fill="#42a5f5"/></symbol><symbol preserveAspectRatio="xMidYMid" viewBox="0 0 200 200" id="drone" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(9.063 22.346) scale(.71044)"><path d="M128.22.723C32.095.723.39 84.566.39 115.222h77.928S89.36 75.275 128.22 75.275s49.906 39.947 49.906 39.947h77.476c0-30.66-31.257-114.5-127.38-114.5m98.82 134.45h-48.914s-8.55 39.946-49.906 39.946c-41.355 0-49.902-39.948-49.902-39.948H30.255c0 10.25 37.727 82.708 98.443 82.708 60.714 0 98.344-59.604 98.344-82.708"/><circle cx="128" cy="126.08" r="32.768"/></g></symbol><symbol preserveAspectRatio="xMidYMid" viewBox="0 0 200 200" id="drone_light" xmlns="http://www.w3.org/2000/svg"><g fill="#424242" transform="translate(9.063 22.346) scale(.71044)"><path d="M128.22.723C32.095.723.39 84.566.39 115.222h77.928S89.36 75.275 128.22 75.275s49.906 39.947 49.906 39.947h77.476c0-30.66-31.257-114.5-127.38-114.5m98.82 134.45h-48.914s-8.55 39.946-49.906 39.946c-41.355 0-49.902-39.948-49.902-39.948H30.255c0 10.25 37.727 82.708 98.443 82.708 60.714 0 98.344-59.604 98.344-82.708"/><circle cx="128" cy="126.08" r="32.768"/></g></symbol><symbol viewBox="0 0 3473 3473" id="editorconfig" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" xmlns="http://www.w3.org/2000/svg"><defs id="ccdefs4"><style id="ccstyle2">.ccfil2{fill:#020202}.ccfil0{fill:#e3e3f8}.ccfil5{fill:#efefef}.ccfil6{fill:#faf1f1}.ccfil3{fill:#fdf2f2}.ccfil1{fill:#fdfdfd}.ccfil4{fill:#fef3f3}</style></defs><g id="ccLayer_x0020_1" transform="matrix(.8945 0 0 .8945 138.649 275.985)"><g id="cc_631799120"><g id="ccg11"><path class="ccfil0" d="M967 1895c46-30 84-105 61-158-63 27-60 89-61 158z" id="ccpath7" fill="#e3e3f8"/><path class="ccfil0" d="M1679 2067c50-16 98-72 71-130-39 27-64 64-71 130z" id="ccpath9" fill="#e3e3f8"/></g><g id="ccg21"><path class="ccfil1" d="M280 2895c0 63 16 131 60 155 162 91 730 20 923-23 101-23 183-98 278-139 214-93 369-168 540-293 124-91 321-347 342-500l-169-38c-4 172-43 211-196 251-103 28-304 34-409 16-139-23-202-96-265-179-122-162 27-275-166-286-203 249-561 70-718 45-67 97-224 727-222 871 97-33 158 3 245 37 308 119 39 224-84 193-84-20-110-75-159-110z" id="ccpath13" fill="#fdfdfd"/><path class="ccfil1" d="M683 1458c125 24 236 76 342 129 173 86 204 74 220 194 2 22-2 34 61 54 106 33-61-26 223-25 169 1 556 69 681 148 52 33 42 75 218 70-2-207-57-516-138-706-99-230-230-265-497-351-156-50-614-105-756-17-133 83-158 182-282 356-36 51-49 90-72 148z" id="ccpath15" fill="#fdfdfd"/><path class="ccfil1" d="M1784 1883c100 41-5 306-144 242-45-127 62-199 91-256-60-9-231-36-282-17-66 25-81 166-47 232 160 314 867 247 792 3-30-99-58-115-159-149-81-27-162-55-251-55z" id="ccpath17" fill="#fdfdfd"/><path class="ccfil1" d="M527 1848c80 77 261 89 378 95 15-155 28-271 152-262 61 83 29 181-35 244 109-1 172-83 156-202-92-66-371-198-511-217-39 42-135 272-140 342z" id="ccpath19" fill="#fdfdfd"/></g><path class="ccfil2" d="M339 2838c66-6 238 44 252 100-107 13-243 3-252-100zm-59 57c49 35 75 90 159 110 123 31 392-74 84-193-87-34-148-70-245-37-2-144 155-774 222-871 157 25 515 204 718-45 193 11 44 124 166 286 63 83 126 156 265 179 105 18 306 12 409-16 153-40 192-79 196-251l169 38c-21 153-218 409-342 500-171 125-326 200-540 293-95 41-177 116-278 139-193 43-761 114-923 23-44-24-60-92-60-155zm1399-828c7-66 32-103 71-130 27 58-21 114-71 130zm105-184c89 0 170 28 251 55 101 34 129 50 159 149 75 244-632 311-792-3-34-66-19-207 47-232 51-19 222 8 282 17-29 57-136 129-91 256 139 64 244-201 144-242zm-817 12c1-69-2-131 61-158 23 53-15 128-61 158zm-440-47c5-70 101-300 140-342 140 19 419 151 511 217 16 119-47 201-156 202 64-63 96-161 35-244-124-9-137 107-152 262-117-6-298-18-378-95zm-100-80c-37-102-37-261 120-274l-80 223c-21 48-21 37-40 51zm256-310c23-58 36-97 72-148 124-174 149-273 282-356 142-88 600-33 756 17 267 86 398 121 497 351 81 190 136 499 138 706-176 5-166-37-218-70-125-79-512-147-681-148-284-1-117 58-223 25-63-20-59-32-61-54-16-120-47-108-220-194-106-53-217-105-342-129zm1770-49c-19-63 16-59 77-102 35-25 63-51 106-75 161-90 461-105 589 2 52 43 137 127 124 237-27 219-177 339-300 439-125 102-333 207-548 137-18-44-4-323-25-426-19-92-9-102 44-157 156-162 494-280 686-141 81 60 58 83 100 129 52-56-45-244-403-232-243 8-348 198-450 189zM997 840c5-139 133-427 261-527 155-120 317-233 555-98 59 33 56 50 62 132 5 79-2 108-22 172-158 510-290 217-796 338 19-166 163-314 243-391 137-133 236-219 442-191 57 95 63 155-6 266-92 148-115 139-101 240 72-18 94-88 127-158 201-420-91-471-270-394-120 51-334 287-404 429-14 28-29 64-42 95zm792 21c21-125 145-156 145-541 0-166-204-315-471-204-229 94-264 166-386 350-115 174-111 365-210 526-29 46-55 62-87 108-23 34-40 77-63 117-47 77-95 133-133 225-120 3-221 5-233 129-16 170 64 212 64 276-1 69-281 765-203 1180 22 114 97 115 217 129 289 35 664 23 923-81l470-225c119-67 319-194 408-287 63-65 96-120 150-197 74-108 76-106 92-253 98 18 281 61 342 114-7 69-41 36-41 98 39 1 104-48 120-102-41-60-84-50-143-98 47-37 132-54 197-81 140-58 379-234 438-394 47-129 12-344-64-428-80-88-266-133-418-133-181 0-368 130-514 186-56-49-60-105-101-159-47-64-353-224-499-255z" id="ccpath23" fill="#020202"/><path class="ccfil3" d="M2453 1409c102 9 207-181 450-189 358-12 455 176 403 232-42-46-19-69-100-129-192-139-530-21-686 141-53 55-63 65-44 157 21 103 7 382 25 426 215 70 423-35 548-137 123-100 273-220 300-439 13-110-72-194-124-237-128-107-428-92-589-2-43 24-71 50-106 75-61 43-96 39-77 102z" id="ccpath25" fill="#fdf2f2"/><path class="ccfil4" d="M997 840l49-87c13-31 28-67 42-95 70-142 284-378 404-429 179-77 471-26 270 394-33 70-55 140-127 158-14-101 9-92 101-240 69-111 63-171 6-266-206-28-305 58-442 191-80 77-224 225-243 391 506-121 638 172 796-338 20-64 27-93 22-172-6-82-3-99-62-132-238-135-400-22-555 98-128 100-256 388-261 527z" id="ccpath27" fill="#fef3f3"/><path class="ccfil5" d="M427 1768c19-14 19-3 40-51l80-223c-157 13-157 172-120 274z" id="ccpath29" fill="#efefef"/><path class="ccfil6" d="M591 2938c-14-56-186-106-252-100 9 103 145 113 252 100z" id="ccpath31" fill="#faf1f1"/></g></g></symbol><symbol viewBox="0 0 24 24" id="elixir" xmlns="http://www.w3.org/2000/svg"><path d="M12.431 22.383c-3.86 0-6.99-3.64-6.99-8.13 0-3.678 2.774-8.172 4.916-10.91 1.014-1.295 2.931-2.321 2.931-2.321s-.982 5.238 1.683 7.318c2.365 1.847 4.105 4.25 4.105 6.363 0 4.232-2.784 7.68-6.645 7.68z" fill="#9575cd" stroke-width="1.256"/></symbol><symbol viewBox="0 0 323.00001 322.99999" id="elm" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(.8053 0 0 .8053 30.106 31.524)"><path fill="#f0ad00" d="M160.8 153.865l68.028-68.03H92.77z"/><path fill="#7fd13b" d="M160.983 5.098H12.033l68.524 68.525H229.51z"/><path fill="#7fd13b" stroke-width=".974" d="M243.906 88.021l74.136 74.137-74.474 74.475-74.137-74.137z"/><path fill="#60b5cc" d="M318.2 145.045V5.098H178.252z"/><path fill="#5a6378" d="M152.164 162.499L3.4 13.733v297.533z"/><path fill="#f0ad00" d="M252.205 245.27l65.995 65.996v-131.99z"/><path fill="#60b5cc" d="M160.8 171.134L12.034 319.899h297.53z"/></g></symbol><symbol viewBox="0 0 24 24" id="email" xmlns="http://www.w3.org/2000/svg"><path d="M20 8l-8 5-8-5V6l8 5 8-5m0-2H4c-1.11 0-2 .89-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 30 30" id="erlang" xmlns="http://www.w3.org/2000/svg"><path style="line-height:1.25;-inkscape-font-specification:'Wide Latin'" d="M5.217 4.367c-.048.052-.097.1-.144.153C2.697 7.182 1.51 10.798 1.51 15.366c0 4.418 1.156 7.862 3.46 10.34h19.414c2.553-1.152 4.127-3.43 4.127-3.43l-3.147-2.52-1.454 1.381c-.866.773-.845.931-2.314 1.78-1.496.674-3.04.966-4.634.966-2.516 0-4.423-.909-5.723-2.059-1.286-1.15-1.985-4.511-2.097-6.68l17.458.067-.182-1.472s-.847-7.129-2.542-9.372zm8.76.846c1.565 0 3.22.535 3.96 1.471.742.937.932 1.667.974 3.524H9.12c.111-1.955.436-2.81 1.372-3.697.937-.888 2.03-1.298 3.484-1.298z" font-weight="400" font-size="48" font-family="Wide Latin" letter-spacing="0" word-spacing="0" fill="#f44336" stroke-width=".97"/></symbol><symbol viewBox="0 0 299.99999 300.00001" id="eslint" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-2.88 18.438) scale(1.0344)"><path d="M97.021 99.016l48.432-27.962c1.212-.7 2.706-.7 3.918 0l48.433 27.962a3.92 3.92 0 0 1 1.959 3.393v55.924a3.924 3.924 0 0 1-1.959 3.394l-48.433 27.962c-1.212.7-2.706.7-3.918 0l-48.432-27.962a3.92 3.92 0 0 1-1.959-3.394v-55.924a3.922 3.922 0 0 1 1.959-3.393" fill="#7986cb"/><path d="M273.34 124.49L215.473 23.82c-2.102-3.64-5.985-6.325-10.188-6.325H89.545c-4.204 0-8.088 2.685-10.19 6.325L21.488 124.27c-2.102 3.641-2.102 8.236 0 11.877l57.867 99.847c2.102 3.64 5.986 5.501 10.19 5.501h115.74c4.203 0 8.087-1.805 10.188-5.446l57.867-100.01c2.104-3.639 2.104-7.907.001-11.547m-47.917 48.41c0 1.48-.891 2.849-2.174 3.59l-73.71 42.527a4.194 4.194 0 0 1-4.17 0l-73.767-42.527c-1.282-.741-2.179-2.109-2.179-3.59V87.847c0-1.481.884-2.849 2.167-3.59l73.707-42.527a4.185 4.185 0 0 1 4.168 0l73.772 42.527c1.283.741 2.186 2.109 2.186 3.59z" fill="#3f51b5"/></g></symbol><symbol viewBox="0 0 24 24" id="exe" xmlns="http://www.w3.org/2000/svg"><path d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h14m0 14V8H5v10h14z" fill="#e64a19"/></symbol><symbol viewBox="0 0 24 24" id="favicon" xmlns="http://www.w3.org/2000/svg"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.62L12 2 9.19 8.62 2 9.24l5.45 4.73L5.82 21 12 17.27z" fill="#ffd54f"/></symbol><symbol viewBox="0 0 24 24" id="file" xmlns="http://www.w3.org/2000/svg"><path d="M13 9h5.5L13 3.5V9M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m5 2H6v16h12v-9h-7V4z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 400 400" id="firebase" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 103)"><path d="M72.55 208.77l44.456-292.29 56.209 90.445L195.49-37.57 330.6 209.28z" fill="#ffa712"/><path d="M195.7 276.73l134.9-67.45-46.5-224.83L72.55 208.77z" fill="#fcca3f"/><path d="M173.22 6.932L72.56 208.772l136.35-144.58z" fill="#f6820c"/></g></symbol><symbol viewBox="0 0 24 24" id="flash" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="cma"><stop offset="0" stop-color="#d92f3c"/><stop offset="1" stop-color="#791223"/></linearGradient><linearGradient xlink:href="#cma" id="cmb" x1="2.373" y1="12.027" x2="21.86" y2="12.027" gradientUnits="userSpaceOnUse" gradientTransform="translate(-.09 -24.144)"/></defs><rect width="19.487" height="19.487" x="2.283" y="-21.86" transform="rotate(90)" ry="0" fill="url(#cmb)"/><path style="line-height:125%" d="M16.802 5.768l-.013.002a6.43 6.43 0 0 0-1.182.192 5.062 5.062 0 0 0-1.494.718c-.428.323-.817.72-1.17 1.191-.34.48-.682 1.032-1.022 1.66-.12.228-.233.424-.35.636v.002h-.004l-1.34 2.394-.005-.002c-.238.443-.461.847-.665 1.198a4.358 4.358 0 0 1-.716.94 2.79 2.79 0 0 1-.907.594c-.072.027-.161.042-.242.063h-.989v2.414h.989v-.002a6.427 6.427 0 0 0 1.185-.192 5.062 5.062 0 0 0 1.494-.718 5.94 5.94 0 0 0 1.171-1.191c.34-.48.681-1.033 1.021-1.66.12-.228.235-.425.353-.637l.006.002.003-.005.037-.066h2.53v.002h1.124v-2.408h-.33v-.001h-1.98c.22-.407.432-.789.621-1.115.214-.37.452-.682.717-.94a2.79 2.79 0 0 1 .906-.594c.07-.027.16-.041.239-.061h.992V8.18h-.002V5.77h-.977v-.002z" font-weight="400" font-size="40" font-family="sans-serif" letter-spacing="0" word-spacing="0" fill="#fff"/></symbol><symbol class="cnflow-logo" viewBox="0 0 299.99999 300" id="flow" xmlns="http://www.w3.org/2000/svg"><title>Flow logo</title><path d="M38.75 33.427l77.461 77.47H54.436l61.145 61.16H38.437l93.462 93.478v-77.158l.01-.01v-77.47h-.01V66.982h46.691l20.394 20.393H153.57v76.531h22.05l24.474 24.473h-15.806l-.01-.01v.01h-31.665l-.01-.01v.01h-.313l.313.313v77.148h109.149l-39.2-39.2v-15.806l8.465 8.466v-77.37h-15.682l.017-38.191 30.09 30.086V56.362h-64.874l-22.94-22.934H113.71z" fill="#fbc02d" fill-opacity=".976" stroke-width=".955" class="cnflow-logo-mark"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-aurelia" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="coa" x1="-388.15%" x2="237.68%" y1="-144.18%" y2="430.41%"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="cob" x1="72.945%" x2="-97.052%" y1="84.424%" y2="-147.7%"><stop stop-color="#6E4D9B" offset="0"/><stop stop-color="#77327A" offset=".14"/><stop stop-color="#B31777" offset=".29"/><stop stop-color="#CD0F7E" offset=".84"/><stop stop-color="#ED2C89" offset="1"/></linearGradient><linearGradient id="coc" x1="-283.88%" x2="287.54%" y1="-693.6%" y2="101.71%"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="cod" x1="-821.19%" x2="101.99%" y1="-469.05%" y2="288.24%"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="coe" x1="-140.36%" x2="419.01%" y1="-230.93%" y2="261.98%"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="cof" x1="191.08%" x2="20.358%" y1="253.95%" y2="20.403%"><stop stop-color="#6E4D9B" offset="0"/><stop stop-color="#77327A" offset=".14"/><stop stop-color="#B31777" offset=".29"/><stop stop-color="#CD0F7E" offset=".84"/><stop stop-color="#ED2C89" offset="1"/></linearGradient><linearGradient id="cog" x1="-388.09%" x2="237.67%" y1="-173.85%" y2="518.99%"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="coi" x1="-31.824" x2="19.682" y1="-11.741" y2="35.548" gradientTransform="scale(.95818 1.0436)" gradientUnits="userSpaceOnUse" xlink:href="#coa"/><linearGradient id="coj" x1="12.022" x2="-15.716" y1="13.922" y2="-23.952" gradientTransform="scale(.96226 1.0392)" gradientUnits="userSpaceOnUse" xlink:href="#cob"/><linearGradient id="cok" x1="-23.39" x2="23.931" y1="-57.289" y2="8.573" gradientTransform="scale(1.0429 .95884)" gradientUnits="userSpaceOnUse" xlink:href="#coc"/><linearGradient id="col" x1="-53.331" x2="6.771" y1="-30.517" y2="18.785" gradientTransform="scale(.99898 1.001)" gradientUnits="userSpaceOnUse" xlink:href="#cod"/><linearGradient id="com" x1="-14.029" x2="41.998" y1="-23.111" y2="26.259" gradientTransform="scale(1.0003 .99965)" gradientUnits="userSpaceOnUse" xlink:href="#coe"/><linearGradient id="con" x1="31.177" x2="3.37" y1="41.442" y2="3.402" gradientTransform="scale(.96254 1.0389)" gradientUnits="userSpaceOnUse" xlink:href="#cof"/><linearGradient id="coo" x1="-31.905" x2="19.599" y1="-14.258" y2="42.767" gradientTransform="scale(.95823 1.0436)" gradientUnits="userSpaceOnUse" xlink:href="#cog"/><linearGradient id="cop" x1="4.301" x2="34.534" y1="34.41" y2="4.514" gradientTransform="scale(1.002 .99796)" gradientUnits="userSpaceOnUse" xlink:href="#coh"/><linearGradient id="coh" x1=".112" x2=".901" y1=".897" y2=".116"><stop stop-color="#6E4D9B" offset="0"/><stop stop-color="#77327A" offset=".14"/><stop stop-color="#B31777" offset=".53"/><stop stop-color="#CD0F7E" offset=".79"/><stop stop-color="#ED2C89" offset="1"/></linearGradient></defs><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#f06292" fill-rule="nonzero"/><g transform="matrix(.31022 .0619 -.0619 .31022 11.807 7.546)" fill="none"><path d="M8.002 6.127L4.117 8.719.116 2.723 4 .13z" transform="rotate(-11.284 17.839 -78.732)" fill="url(#coi)"/><path d="M9.179 1.887l6.637 9.946-7.906 5.276-6.637-9.946L.115 5.43 8.02.153z" transform="rotate(-11.284 129.49 -99.884)" fill="url(#coj)"/><path d="M7.3 1.88l1.462 2.189-6.018 4.015L.124 4.16l1.315-.877L6.143.144z" transform="rotate(-11.284 167.2 -62.32)" fill="url(#cok)"/><path d="M2.328 1.146L4.016.02l2.619 3.925L2.75 6.537 1.29 4.347l2.197-1.466zm-1.04 3.201L.132 2.612l2.197-1.466 1.158 1.735z" transform="rotate(-11.284 104.37 -149.22)" fill="url(#col)"/><path d="M5.346 9.155l-1.315.877L.03 4.035 6.047.019l2.805 4.204L4.15 7.36l4.703-3.138 1.197 1.793z" transform="rotate(-11.284 81.819 7.645)" fill="url(#com)"/><path d="M14.533 9.934l1.197 1.793-7.907 5.276-1.196-1.793L.052 5.358 7.958.082z" transform="rotate(-11.284 17.141 -7.825)" fill="url(#con)"/><path d="M6.235 7.177L4.038 8.643 2.84 6.849.036 2.646 3.92.053 7.923 6.05z" transform="rotate(-11.284 18.188 -79.174)" fill="url(#coo)"/><path d="M18.955 35.925L17.48 34.45l3.998-3.998 1.475 1.475z" fill="#714896"/><path d="M33.33 21.55l-1.475-1.474 1.867-1.868 1.475 1.475z" fill="#6f4795"/><path d="M7.12 24.09l-1.525-1.525 3.998-3.998 1.525 1.525z" fill="#88519f"/><path d="M21.495 9.714L19.97 8.19l1.868-1.868 1.524 1.525z" fill="#85509e"/><path d="M31.418 23.462l-6.72 6.72-1.475-1.474 6.72-6.721z" fill="#8d166a"/><path d="M18.058 10.101l1.525 1.525-6.721 6.72-1.525-1.524z" fill="#a70d6f"/><path d="M2.375 11.769l1.9 1.9-1.9 1.901-1.901-1.9z" fill="#9e61ad"/><path d="M15.523 36.482l1.9 1.9-1.9 1.901-1.9-1.9z" fill="#8053a3"/><path d="M8.372 38.294L.017 29.876 29.749.08l8.636 8.201z" transform="translate(1.823 1.548)" fill="url(#cop)"/></g></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-aurelia-open" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="cpi" x1="-31.824" x2="19.682" y1="-11.741" y2="35.548" gradientTransform="scale(.95818 1.0436)" gradientUnits="userSpaceOnUse" xlink:href="#cpa"/><linearGradient id="cpa" x1="-3.881" x2="2.377" y1="-1.442" y2="4.304"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="cpj" x1="12.022" x2="-15.716" y1="13.922" y2="-23.952" gradientTransform="scale(.96226 1.0392)" gradientUnits="userSpaceOnUse" xlink:href="#cpb"/><linearGradient id="cpb" x1=".729" x2="-.971" y1=".844" y2="-1.477"><stop stop-color="#6E4D9B" offset="0"/><stop stop-color="#77327A" offset=".14"/><stop stop-color="#B31777" offset=".29"/><stop stop-color="#CD0F7E" offset=".84"/><stop stop-color="#ED2C89" offset="1"/></linearGradient><linearGradient id="cpk" x1="-23.39" x2="23.931" y1="-57.289" y2="8.573" gradientTransform="scale(1.0429 .95884)" gradientUnits="userSpaceOnUse" xlink:href="#cpc"/><linearGradient id="cpc" x1="-2.839" x2="2.875" y1="-6.936" y2="1.017"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="cpl" x1="-53.331" x2="6.771" y1="-30.517" y2="18.785" gradientTransform="scale(.99898 1.001)" gradientUnits="userSpaceOnUse" xlink:href="#cpd"/><linearGradient id="cpd" x1="-8.212" x2="1.02" y1="-4.691" y2="2.882"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="cpm" x1="-14.029" x2="41.998" y1="-23.111" y2="26.259" gradientTransform="scale(1.0003 .99965)" gradientUnits="userSpaceOnUse" xlink:href="#cpe"/><linearGradient id="cpe" x1="-1.404" x2="4.19" y1="-2.309" y2="2.62"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="cpn" x1="31.177" x2="3.37" y1="41.442" y2="3.402" gradientTransform="scale(.96254 1.0389)" gradientUnits="userSpaceOnUse" xlink:href="#cpf"/><linearGradient id="cpf" x1="1.911" x2=".204" y1="2.539" y2=".204"><stop stop-color="#6E4D9B" offset="0"/><stop stop-color="#77327A" offset=".14"/><stop stop-color="#B31777" offset=".29"/><stop stop-color="#CD0F7E" offset=".84"/><stop stop-color="#ED2C89" offset="1"/></linearGradient><linearGradient id="cpo" x1="-31.905" x2="19.599" y1="-14.258" y2="42.767" gradientTransform="scale(.95823 1.0436)" gradientUnits="userSpaceOnUse" xlink:href="#cpg"/><linearGradient id="cpg" x1="-3.881" x2="2.377" y1="-1.738" y2="5.19"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="cpp" x1="4.301" x2="34.534" y1="34.41" y2="4.514" gradientTransform="scale(1.002 .99796)" gradientUnits="userSpaceOnUse" xlink:href="#cph"/><linearGradient id="cph" x1=".112" x2=".901" y1=".897" y2=".116"><stop stop-color="#6E4D9B" offset="0"/><stop stop-color="#77327A" offset=".14"/><stop stop-color="#B31777" offset=".53"/><stop stop-color="#CD0F7E" offset=".79"/><stop stop-color="#ED2C89" offset="1"/></linearGradient></defs><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#f06292" fill-rule="nonzero"/><g transform="matrix(.31022 .0619 -.0619 .31022 11.807 7.546)" fill="none"><path d="M8.002 6.127L4.117 8.719.116 2.723 4 .13z" transform="rotate(-11.284 17.839 -78.732)" fill="url(#cpi)"/><path d="M9.179 1.887l6.637 9.946-7.906 5.276-6.637-9.946L.115 5.43 8.02.153z" transform="rotate(-11.284 129.49 -99.884)" fill="url(#cpj)"/><path d="M7.3 1.88l1.462 2.189-6.018 4.015L.124 4.16l1.315-.877L6.143.144z" transform="rotate(-11.284 167.2 -62.32)" fill="url(#cpk)"/><path d="M2.328 1.146L4.016.02l2.619 3.925L2.75 6.537 1.29 4.347l2.197-1.466zm-1.04 3.201L.132 2.612l2.197-1.466 1.158 1.735z" transform="rotate(-11.284 104.37 -149.22)" fill="url(#cpl)"/><path d="M5.346 9.155l-1.315.877L.03 4.035 6.047.019l2.805 4.204L4.15 7.36l4.703-3.138 1.197 1.793z" transform="rotate(-11.284 81.819 7.645)" fill="url(#cpm)"/><path d="M14.533 9.934l1.197 1.793-7.907 5.276-1.196-1.793L.052 5.358 7.958.082z" transform="rotate(-11.284 17.141 -7.825)" fill="url(#cpn)"/><path d="M6.235 7.177L4.038 8.643 2.84 6.849.036 2.646 3.92.053 7.923 6.05z" transform="rotate(-11.284 18.188 -79.174)" fill="url(#cpo)"/><path d="M18.955 35.925L17.48 34.45l3.998-3.998 1.475 1.475z" fill="#714896"/><path d="M33.33 21.55l-1.475-1.474 1.867-1.868 1.475 1.475z" fill="#6f4795"/><path d="M7.12 24.09l-1.525-1.525 3.998-3.998 1.525 1.525z" fill="#88519f"/><path d="M21.495 9.714L19.97 8.19l1.868-1.868 1.524 1.525z" fill="#85509e"/><path d="M31.418 23.462l-6.72 6.72-1.475-1.474 6.72-6.721z" fill="#8d166a"/><path d="M18.058 10.101l1.525 1.525-6.721 6.72-1.525-1.524z" fill="#a70d6f"/><path d="M2.375 11.769l1.9 1.9-1.9 1.901-1.901-1.9z" fill="#9e61ad"/><path d="M15.523 36.482l1.9 1.9-1.9 1.901-1.9-1.9z" fill="#8053a3"/><path d="M8.372 38.294L.017 29.876 29.749.08l8.636 8.201z" transform="translate(1.823 1.548)" fill="url(#cpp)"/></g></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-components" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#cddc39" fill-rule="nonzero"/><path d="M11.185 9.613h5.346v2.9l3.782-3.775 3.775 3.775-3.775 3.782h2.9v5.346h-5.346v-5.346h2.446l-3.782-3.782v2.446h-5.346V9.613m0 6.682h5.346v5.346h-5.346z" fill="#f0f4c3" stroke-width=".668"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-components-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#cddc39"/><path d="M11.185 9.613h5.346v2.9l3.782-3.775 3.775 3.775-3.775 3.782h2.9v5.346h-5.346v-5.346h2.446l-3.782-3.782v2.446h-5.346V9.613m0 6.682h5.346v5.346h-5.346z" fill="#f0f4c3" stroke-width=".668"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-config" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#00acc1" fill-rule="nonzero"/><path d="M17.293 17.786a2.308 2.308 0 0 1-2.308-2.308 2.308 2.308 0 0 1 2.308-2.307 2.308 2.308 0 0 1 2.308 2.307 2.308 2.308 0 0 1-2.308 2.308m4.899-1.668c.026-.211.046-.422.046-.64 0-.217-.02-.435-.046-.659l1.391-1.075a.333.333 0 0 0 .08-.422l-1.32-2.28c-.079-.146-.257-.205-.402-.146l-1.641.66a4.779 4.779 0 0 0-1.115-.647l-.244-1.747a.333.333 0 0 0-.33-.277h-2.637a.333.333 0 0 0-.33.277l-.243 1.747a4.78 4.78 0 0 0-1.114.646l-1.642-.659a.324.324 0 0 0-.402.145l-1.319 2.281a.325.325 0 0 0 .08.422l1.39 1.075c-.026.224-.046.442-.046.66s.02.428.046.639l-1.39 1.094a.325.325 0 0 0-.08.422l1.319 2.282c.079.145.257.197.402.145l1.642-.666c.342.264.698.488 1.114.653l.244 1.747a.333.333 0 0 0 .33.277h2.637a.333.333 0 0 0 .33-.277l.243-1.747a4.802 4.802 0 0 0 1.115-.653l1.641.666c.145.052.323 0 .403-.145l1.318-2.282a.333.333 0 0 0-.079-.422z" fill="#80deea" stroke-width=".659"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-config-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#00acc1"/><path d="M17.293 17.786a2.308 2.308 0 0 1-2.308-2.308 2.308 2.308 0 0 1 2.308-2.307 2.308 2.308 0 0 1 2.308 2.307 2.308 2.308 0 0 1-2.308 2.308m4.899-1.668c.026-.211.046-.422.046-.64 0-.217-.02-.435-.046-.659l1.391-1.075a.333.333 0 0 0 .08-.422l-1.32-2.28c-.079-.146-.257-.205-.402-.146l-1.641.66a4.779 4.779 0 0 0-1.115-.647l-.244-1.747a.333.333 0 0 0-.33-.277h-2.637a.333.333 0 0 0-.33.277l-.243 1.747a4.78 4.78 0 0 0-1.114.646l-1.642-.659a.324.324 0 0 0-.402.145l-1.319 2.281a.325.325 0 0 0 .08.422l1.39 1.075c-.026.224-.046.442-.046.66s.02.428.046.639l-1.39 1.094a.325.325 0 0 0-.08.422l1.319 2.282c.079.145.257.197.402.145l1.642-.666c.342.264.698.488 1.114.653l.244 1.747a.333.333 0 0 0 .33.277h2.637a.333.333 0 0 0 .33-.277l.243-1.747a4.802 4.802 0 0 0 1.115-.653l1.641.666c.145.052.323 0 .403-.145l1.318-2.282a.333.333 0 0 0-.079-.422z" fill="#80deea" stroke-width=".659"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-css" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#42a5f5" fill-rule="nonzero"/><path d="M12.488 9.415l-.44 2.259h9.188l-.298 1.46h-9.18l-.447 2.251H20.5l-.514 2.576-3.705 1.224-3.211-1.224.223-1.109h-2.258l-.534 2.704 5.307 2.029 6.118-2.029.812-4.076.162-.818 1.041-5.247H12.488z" fill-rule="nonzero" fill="#bbdefb"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-css-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#42a5f5" fill-rule="nonzero"/><path d="M12.488 9.415l-.44 2.259h9.188l-.298 1.46h-9.18l-.447 2.251H20.5l-.514 2.576-3.705 1.224-3.211-1.224.223-1.109h-2.258l-.534 2.704 5.307 2.029 6.118-2.029.812-4.076.162-.818 1.041-5.247H12.488z" fill-rule="nonzero" fill="#bbdefb"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-dist" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#e57373" fill-rule="nonzero"/><path d="M18.575 11.113h-2.576V9.825h2.576m3.864 1.288h-2.576V9.825l-1.288-1.288h-2.576L14.71 9.825v1.288h-2.577c-.715 0-1.288.573-1.288 1.288v7.085a1.288 1.288 0 0 0 1.288 1.288H22.44a1.288 1.288 0 0 0 1.288-1.288V12.4c0-.715-.58-1.288-1.288-1.288z" fill="#ffcdd2" stroke-width=".644"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-dist-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#e57373"/><path d="M18.575 11.113h-2.576V9.825h2.576m3.864 1.288h-2.576V9.825l-1.288-1.288h-2.576L14.71 9.825v1.288h-2.577c-.715 0-1.288.573-1.288 1.288v7.085a1.288 1.288 0 0 0 1.288 1.288H22.44a1.288 1.288 0 0 0 1.288-1.288V12.4c0-.715-.58-1.288-1.288-1.288z" fill="#ffcdd2" fill-rule="evenodd" stroke-width=".644"/></symbol><symbol id="folder-docker" clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><defs id="cydefs10"><path id="cySVGID_2_" d="M8.7 24c-1.1 0-2.1-.9-2.1-2s.9-2 2.1-2 2.1.9 2.1 2-1 2-2.1 2zm25.8-10.9c-.2-1.6-1.2-2.9-2.5-3.9l-.5-.4-.4.5c-.8.9-1.1 2.5-1 3.7.1.9.4 1.8.9 2.5-.4.2-.9.4-1.3.6-.9.3-1.8.4-2.7.4H1.1l-.1.6c-.2 1.9.1 3.9.9 5.7l.4.7v.1c2.4 4 6.7 5.8 11.4 5.8 9 0 16.4-3.9 19.9-12.3 2.3.1 4.6-.5 5.7-2.7l.3-.5-.5-.3c-1.3-.8-3.1-.9-4.6-.5zm-12.9-1.6h-3.9v3.9h3.9zm0-4.9h-3.9v3.9h3.9zm0-5h-3.9v3.9h3.9zm4.8 9.9h-3.9v3.9h3.9zm-14.5 0H8v3.9h3.9zm4.9 0h-3.9v3.9h3.9zm-9.7 0H3.2v3.9h3.9zm9.7-4.9h-3.9v3.9h3.9zm-4.9 0H8v3.9h3.9z"/></defs><path id="cypath2" d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#039be5" fill-rule="nonzero"/><style id="cystyle2">.cyst0{fill:#fff}.cyst1{clip-path:url(#cySVGID_4_)}</style><g id="cyg34" transform="translate(8.319 9.626) scale(.39491)" fill="#b3e5fc"><g id="cyg32"><g id="cyg30"><title id="cytitle4">Group 3</title><g id="cyg28"><g id="cyg26"><g id="cyg9"><path id="cySVGID_1_" class="cyst0" d="M8.7 24c-1.1 0-2.1-.9-2.1-2s.9-2 2.1-2 2.1.9 2.1 2-1 2-2.1 2zm25.8-10.9c-.2-1.6-1.2-2.9-2.5-3.9l-.5-.4-.4.5c-.8.9-1.1 2.5-1 3.7.1.9.4 1.8.9 2.5-.4.2-.9.4-1.3.6-.9.3-1.8.4-2.7.4H1.1l-.1.6c-.2 1.9.1 3.9.9 5.7l.4.7v.1c2.4 4 6.7 5.8 11.4 5.8 9 0 16.4-3.9 19.9-12.3 2.3.1 4.6-.5 5.7-2.7l.3-.5-.5-.3c-1.3-.8-3.1-.9-4.6-.5zm-12.9-1.6h-3.9v3.9h3.9zm0-4.9h-3.9v3.9h3.9zm0-5h-3.9v3.9h3.9zm4.8 9.9h-3.9v3.9h3.9zm-14.5 0H8v3.9h3.9zm4.9 0h-3.9v3.9h3.9zm-9.7 0H3.2v3.9h3.9zm9.7-4.9h-3.9v3.9h3.9zm-4.9 0H8v3.9h3.9z"/></g><g id="cyg24"><clipPath id="cySVGID_4_"><use id="cyuse14" width="100%" height="100%" xlink:href="#cySVGID_2_"/></clipPath><g id="cyg22" class="cyst1" clip-path="url(#cySVGID_4_)"><g id="cyg20"><g id="cyg18"><path id="cySVGID_3_" class="cyst0" d="M-48.8-21H1226v151.4H-48.8z"/></g></g></g></g></g></g></g></g></g></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-docker-open" xmlns="http://www.w3.org/2000/svg"><defs><clipPath id="cza"><use width="100%" height="100%" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#SVGID_2_"/></clipPath></defs><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#039be5"/><g transform="matrix(.3949 0 0 .39489 8.319 9.626)" fill="#b3e5fc"><title>Group 3</title><path class="czst0" d="M8.7 24c-1.1 0-2.1-.9-2.1-2s.9-2 2.1-2 2.1.9 2.1 2-1 2-2.1 2zm25.8-10.9c-.2-1.6-1.2-2.9-2.5-3.9l-.5-.4-.4.5c-.8.9-1.1 2.5-1 3.7.1.9.4 1.8.9 2.5-.4.2-.9.4-1.3.6-.9.3-1.8.4-2.7.4H1.1l-.1.6c-.2 1.9.1 3.9.9 5.7l.4.7v.1c2.4 4 6.7 5.8 11.4 5.8 9 0 16.4-3.9 19.9-12.3 2.3.1 4.6-.5 5.7-2.7l.3-.5-.5-.3c-1.3-.8-3.1-.9-4.6-.5zm-12.9-1.6h-3.9v3.9h3.9zm0-4.9h-3.9v3.9h3.9zm0-5h-3.9v3.9h3.9zm4.8 9.9h-3.9v3.9h3.9zm-14.5 0H8v3.9h3.9zm4.9 0h-3.9v3.9h3.9zm-9.7 0H3.2v3.9h3.9zm9.7-4.9h-3.9v3.9h3.9zm-4.9 0H8v3.9h3.9z"/><g class="czst1" clip-path="url(#cza)"><path class="czst0" d="M-48.8-21H1226v151.4H-48.8z"/></g></g></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-docs" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#0277bd" fill-rule="nonzero"/><path d="M18.575 12.859h3.713l-3.713-3.713v3.713M13.85 8.134h5.4l4.05 4.05v8.1c0 .74-.61 1.35-1.35 1.35h-8.1a1.35 1.35 0 0 1-1.35-1.35v-10.8c0-.75.6-1.35 1.35-1.35m6.075 10.8v-1.35H13.85v1.35h6.075m2.025-2.7v-1.35h-8.1v1.35h8.1z" fill-rule="nonzero" fill="#b3e5fc"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-docs-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#0277bd" fill-rule="nonzero"/><path d="M18.575 12.859h3.713l-3.713-3.713v3.713M13.85 8.134h5.4l4.05 4.05v8.1c0 .74-.61 1.35-1.35 1.35h-8.1a1.35 1.35 0 0 1-1.35-1.35v-10.8c0-.75.6-1.35 1.35-1.35m6.075 10.8v-1.35H13.85v1.35h6.075m2.025-2.7v-1.35h-8.1v1.35h8.1z" fill-rule="nonzero" fill="#b3e5fc"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-expo" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#01579b" fill-rule="nonzero"/><style>.dcst0{fill:#1173b6}.st1{fill:#585d67}</style><path class="dcst0" d="M18.575 9.82c-.489-.745-.605-.844-1.6-.844h-.024c-.996 0-1.106.099-1.601.844-.46.699-5.024 9.058-5.024 9.291 0 .338.087.658.402 1.112.32.46.873.716 1.275.309.273-.274 3.201-5.321 4.616-7.23a.425.425 0 0 1 .693 0c1.414 1.909 4.343 6.956 4.616 7.23.402.407.955.15 1.275-.309.314-.454.402-.774.402-1.112-.006-.233-4.57-8.598-5.03-9.291z" fill="#1173b6" stroke-width=".058"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-expo-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#01579b"/><path class="ddst0" d="M18.575 9.82c-.489-.745-.605-.844-1.6-.844h-.024c-.996 0-1.106.099-1.601.844-.46.699-5.024 9.058-5.024 9.291 0 .338.087.658.402 1.112.32.46.873.716 1.275.309.273-.274 3.201-5.321 4.616-7.23a.425.425 0 0 1 .693 0c1.414 1.909 4.343 6.956 4.616 7.23.402.407.955.15 1.275-.309.314-.454.402-.774.402-1.112-.006-.233-4.57-8.598-5.03-9.291z" fill="#1173b6" stroke-width=".058" fill-rule="evenodd"/></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="folder-font" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#ef9a9a" fill-rule="nonzero"/><path d="M14.62 17.403l2.38-6.33 2.37 6.33m-3.37-9l-5.5 14h2.25l1.12-3h6.25l1.13 3h2.25l-5.5-14h-2z" fill="#f44336" fill-rule="nonzero"/></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="folder-font-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#ef9a9a" fill-rule="nonzero"/><path d="M14.62 17.403l2.38-6.33 2.37 6.33m-3.37-9l-5.5 14h2.25l1.12-3h6.25l1.13 3h2.25l-5.5-14h-2z" fill="#f44336" fill-rule="nonzero"/></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="folder-git" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#ff8a65" fill-rule="nonzero"/><path d="M10.43 14.14l4.044-4.052 1.183 1.19a1.387 1.387 0 0 0 .65 1.56v3.877c-.42.238-.699.693-.699 1.21 0 .768.632 1.4 1.4 1.4.767 0 1.4-.632 1.4-1.4 0-.517-.28-.972-.7-1.21v-3.4l1.448 1.462c-.05.105-.05.224-.05.35 0 .767.633 1.399 1.4 1.399.768 0 1.4-.632 1.4-1.4 0-.767-.632-1.4-1.4-1.4-.126 0-.245 0-.35.05l-1.798-1.799a1.385 1.385 0 0 0-.805-1.637c-.3-.112-.615-.14-.895-.063l-1.19-1.183.553-.545a1.381 1.381 0 0 1 1.973 0l5.591 5.59a1.381 1.381 0 0 1 0 1.974l-5.59 5.591a1.381 1.381 0 0 1-1.974 0l-5.591-5.59a1.381 1.381 0 0 1 0-1.974z" fill="#e64a19" fill-rule="nonzero"/></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="folder-git-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#ff8a65" fill-rule="nonzero"/><path d="M10.43 14.14l4.044-4.052 1.183 1.19a1.387 1.387 0 0 0 .65 1.56v3.877c-.42.238-.699.693-.699 1.21 0 .768.632 1.4 1.4 1.4.767 0 1.4-.632 1.4-1.4 0-.517-.28-.972-.7-1.21v-3.4l1.448 1.462c-.05.105-.05.224-.05.35 0 .767.633 1.399 1.4 1.399.768 0 1.4-.632 1.4-1.4 0-.767-.632-1.4-1.4-1.4-.126 0-.245 0-.35.05l-1.798-1.799a1.385 1.385 0 0 0-.805-1.637c-.3-.112-.615-.14-.895-.063l-1.19-1.183.553-.545a1.381 1.381 0 0 1 1.973 0l5.591 5.59a1.381 1.381 0 0 1 0 1.974l-5.59 5.591a1.381 1.381 0 0 1-1.974 0l-5.591-5.59a1.381 1.381 0 0 1 0-1.974z" fill="#e64a19" fill-rule="nonzero"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-global" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#5c6bc0" fill-rule="nonzero"/><path d="M21.132 18.585a1.22 1.22 0 0 0-1.156-.846h-.609v-1.825a.608.608 0 0 0-.608-.609h-3.65v-1.217h1.216a.608.608 0 0 0 .609-.608v-1.217h1.217a1.217 1.217 0 0 0 1.216-1.217v-.25a4.858 4.858 0 0 1 1.765 7.79m-4.198 1.545a4.86 4.86 0 0 1-4.26-4.826c0-.377.049-.742.128-1.089l2.915 2.915v.608a1.217 1.217 0 0 0 1.217 1.217m.608-9.735a6.085 6.085 0 0 0-6.085 6.084 6.085 6.085 0 0 0 6.085 6.085 6.085 6.085 0 0 0 6.085-6.085 6.085 6.085 0 0 0-6.085-6.084z" fill="#c5cae9" stroke-width=".608"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-global-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#5c6bc0"/><path d="M21.133 18.585a1.22 1.22 0 0 0-1.156-.846h-.609v-1.825a.608.608 0 0 0-.608-.609h-3.65v-1.217h1.216a.608.608 0 0 0 .609-.608v-1.217h1.217a1.217 1.217 0 0 0 1.216-1.217v-.25a4.858 4.858 0 0 1 1.765 7.79m-4.198 1.545a4.86 4.86 0 0 1-4.26-4.826c0-.377.049-.742.128-1.089l2.915 2.915v.608a1.217 1.217 0 0 0 1.216 1.217m.609-9.735a6.085 6.085 0 0 0-6.085 6.084 6.085 6.085 0 0 0 6.085 6.085 6.085 6.085 0 0 0 6.085-6.085 6.085 6.085 0 0 0-6.085-6.084z" fill="#c5cae9" stroke-width=".608"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-i18n" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#5c6bc0" fill-rule="nonzero"/><path d="M17.293 17.786l-1.53-1.512.018-.018a10.555 10.555 0 0 0 2.235-3.934h1.765v-1.205h-4.217V9.912h-1.205v1.205h-4.217v1.205h6.73a9.5 9.5 0 0 1-1.91 3.223 9.424 9.424 0 0 1-1.392-2.018h-1.205c.44.982 1.042 1.91 1.795 2.747l-3.067 3.024.856.856 3.012-3.013 1.874 1.874.458-1.229m3.392-3.054H19.48l-2.711 7.23h1.205l.674-1.808h2.862l.68 1.807h1.206l-2.711-7.23m-1.579 4.218l.976-2.609.976 2.609z" fill="#c5cae9" stroke-width=".602"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-i18n-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#5c6bc0"/><path d="M17.293 17.786l-1.53-1.512.018-.018a10.555 10.555 0 0 0 2.235-3.934h1.765v-1.205h-4.217V9.912h-1.205v1.205h-4.217v1.205h6.73a9.5 9.5 0 0 1-1.91 3.223 9.424 9.424 0 0 1-1.392-2.018h-1.205c.44.982 1.042 1.91 1.795 2.747l-3.067 3.024.856.856 3.012-3.013 1.874 1.874.458-1.229m3.392-3.054H19.48l-2.711 7.23h1.205l.674-1.808h2.862l.68 1.807h1.206l-2.711-7.23m-1.579 4.218l.976-2.609.976 2.609z" fill="#c5cae9" stroke-width=".602"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-images" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#009688" fill-rule="nonzero"/><path d="M18.575 12.859h3.713l-3.713-3.713v3.713M13.85 8.134h5.4l4.05 4.05v8.1c0 .74-.61 1.35-1.35 1.35h-8.1a1.35 1.35 0 0 1-1.35-1.35v-10.8c0-.75.6-1.35 1.35-1.35m0 12.15h8.1v-5.4l-2.7 2.7-1.35-1.35-4.05 4.05m1.35-7.425c-.74 0-1.35.61-1.35 1.35s.61 1.35 1.35 1.35 1.35-.61 1.35-1.35-.61-1.35-1.35-1.35z" fill-rule="nonzero" fill="#b2dfdb"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-images-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#009688" fill-rule="nonzero"/><path d="M18.575 12.859h3.713l-3.713-3.713v3.713M13.85 8.134h5.4l4.05 4.05v8.1c0 .74-.61 1.35-1.35 1.35h-8.1a1.35 1.35 0 0 1-1.35-1.35v-10.8c0-.75.6-1.35 1.35-1.35m0 12.15h8.1v-5.4l-2.7 2.7-1.35-1.35-4.05 4.05m1.35-7.425c-.74 0-1.35.61-1.35 1.35s.61 1.35 1.35 1.35 1.35-.61 1.35-1.35-.61-1.35-1.35-1.35z" fill-rule="nonzero" fill="#b2dfdb"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-include" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#039be5" fill-rule="nonzero"/><path d="M20.788 15.981h-2.434v2.434h-1.217V15.98h-2.434v-1.217h2.434V12.33h1.217v2.434h2.434m-3.042-5.476a6.085 6.085 0 0 0-6.085 6.084 6.085 6.085 0 0 0 6.085 6.085 6.085 6.085 0 0 0 6.084-6.085 6.085 6.085 0 0 0-6.084-6.084z" fill="#b3e5fc" stroke-width=".608"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-include-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#039be5"/><path d="M20.788 15.981h-2.434v2.434h-1.217V15.98h-2.434v-1.217h2.434V12.33h1.217v2.434h2.434m-3.042-5.476a6.085 6.085 0 0 0-6.085 6.084 6.085 6.085 0 0 0 6.085 6.085 6.085 6.085 0 0 0 6.084-6.085 6.085 6.085 0 0 0-6.084-6.084z" fill="#b3e5fc" stroke-width=".608"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-javascript" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#ffca28" fill-rule="nonzero"/><path d="M17.935 18.374a2.18 2.18 0 0 0 1.972 1.213c.829 0 1.354-.415 1.354-.987 0-.682-.542-.927-1.452-1.324l-.502-.216c-1.435-.613-2.404-1.378-2.404-3.005 0-1.5 1.167-2.638 2.917-2.638a2.957 2.957 0 0 1 2.842 1.599l-1.552.999a1.362 1.362 0 0 0-1.29-.858.873.873 0 0 0-.957.858c0 .583.374.84 1.226 1.213l.502.216c1.697.733 2.654 1.47 2.654 3.139 0 1.798-1.411 2.783-3.308 2.783a3.839 3.839 0 0 1-3.618-2.046zm-7.048.175c.315.583.583 1.027 1.283 1.027s1.066-.256 1.066-1.255v-6.774h1.998v6.804c0 2.064-1.214 3.01-2.982 3.01a3.104 3.104 0 0 1-2.993-1.826z" fill-rule="nonzero" fill="#ffecb3"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-javascript-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#ffca28"/><path d="M17.935 18.374a2.18 2.18 0 0 0 1.972 1.213c.829 0 1.354-.415 1.354-.987 0-.682-.542-.927-1.452-1.324l-.502-.216c-1.435-.613-2.404-1.378-2.404-3.005 0-1.5 1.167-2.638 2.917-2.638a2.957 2.957 0 0 1 2.842 1.599l-1.552.999a1.362 1.362 0 0 0-1.29-.858.873.873 0 0 0-.957.858c0 .583.374.84 1.226 1.213l.502.216c1.697.733 2.654 1.47 2.654 3.139 0 1.798-1.412 2.783-3.308 2.783a3.839 3.839 0 0 1-3.618-2.046zm-7.048.175c.315.583.583 1.027 1.283 1.027s1.066-.256 1.066-1.255v-6.774h1.998v6.804c0 2.064-1.214 3.01-2.982 3.01a3.104 3.104 0 0 1-2.993-1.826z" fill="#ffecb3"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-lib" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#c0ca33" fill-rule="nonzero"/><path d="M17.39 12.544a2.05 2.05 0 0 0 2.05-2.05 2.05 2.05 0 0 0-2.05-2.052 2.05 2.05 0 0 0-2.05 2.051 2.05 2.05 0 0 0 2.05 2.051m0 2.42a8.992 8.992 0 0 0-6.152-2.42v7.52c2.392 0 4.539.923 6.152 2.42a8.992 8.992 0 0 1 6.152-2.42v-7.52c-2.392 0-4.539.923-6.152 2.42z" fill="#f0f4c3" stroke-width=".684"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-lib-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#c0ca33"/><path d="M17.391 12.543a2.05 2.05 0 0 0 2.05-2.05 2.05 2.05 0 0 0-2.05-2.052 2.05 2.05 0 0 0-2.05 2.051 2.05 2.05 0 0 0 2.05 2.051m0 2.42a8.992 8.992 0 0 0-6.152-2.42v7.52c2.392 0 4.539.923 6.152 2.42a8.992 8.992 0 0 1 6.152-2.42v-7.52c-2.392 0-4.539.923-6.152 2.42z" fill="#f0f4c3" stroke-width=".684"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-ngrx-actions" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#ab47bc" fill-rule="nonzero"/><path d="M17.655 8.39l-6.152 2.193.933 8.142 5.219 2.888 5.219-2.888.932-8.142zm-1.278 2.067c.234-.004.487.07.768.223.124.066.498.16.83.21 1.183.17 2.586 1.073 3.03 1.95.306.602.243.927-.225 1.169-.404.209-1.23.108-2.43-.297l-1.012-.342-.36.137c-.522.2-1.044.694-1.258 1.19-.154.359-.177.527-.149 1.116.028.59.071.761.28 1.132.239.422.786.96.88.866.026-.026-.03-.197-.124-.38-.093-.183-.148-.368-.122-.41.026-.042.273.114.548.347.611.518 1.326.848 1.981.917.538.056.661-.044.258-.211a1.238 1.238 0 0 1-.374-.25c-.157-.173-.166-.168.504-.318.417-.094 1.24-.531 1.29-.685.016-.05-.118-.07-.338-.053-.2.016-.363-.004-.363-.046 0-.04.164-.243.363-.451.748-.781 1.004-1.365 1.083-2.474l.055-.767.176.365c.194.401.23.98.091 1.478-.115.416-.038.462.173.104.261-.443.345-.373.299.251-.05.678-.283 1.187-.808 1.762-.429.468-.377.552.141.233.5-.308.567-.26.31.224-.487.914-1.516 1.69-2.585 1.948-.647.158-1.106.187-1.7.11-1.55-.204-3.018-1.249-3.718-2.648a8.736 8.736 0 0 0-.572-.989c-.275-.373-.298-.54-.113-.823.093-.141.114-.286.076-.502-.176-.999-.17-1.03.23-1.437.35-.353.371-.4.371-.813 0-.358.036-.475.198-.637.109-.108.282-.199.384-.2.296-.003.807-.277 1.11-.595.252-.265.52-.4.822-.404z" fill="#e1bee7" stroke-width=".696"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-ngrx-actions-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#ab47bc"/><path d="M17.655 8.39l-6.152 2.192.933 8.143 5.219 2.888 5.219-2.888.932-8.143zm-1.278 2.067c.234-.004.487.07.768.222.124.067.498.162.83.21 1.183.171 2.586 1.074 3.03 1.95.306.603.243.928-.225 1.17-.404.208-1.23.107-2.43-.298l-1.012-.341-.36.137c-.522.2-1.044.694-1.258 1.19-.154.359-.177.527-.149 1.116.028.59.071.761.28 1.132.239.422.786.96.88.866.026-.026-.03-.197-.124-.38-.093-.183-.148-.368-.122-.41.026-.042.273.114.548.347.611.517 1.326.848 1.981.917.538.056.661-.044.258-.211a1.238 1.238 0 0 1-.374-.25c-.157-.173-.166-.168.504-.318.417-.094 1.24-.531 1.29-.685.016-.05-.118-.07-.338-.053-.2.016-.363-.005-.363-.046 0-.04.164-.243.363-.452.748-.78 1.004-1.364 1.083-2.474l.055-.766.176.364c.194.402.23.981.091 1.479-.115.416-.038.462.173.103.261-.442.345-.372.299.252-.05.678-.283 1.186-.808 1.761-.429.47-.377.553.141.234.5-.308.567-.26.31.224-.487.914-1.516 1.689-2.585 1.948-.647.158-1.106.187-1.7.109-1.55-.203-3.018-1.248-3.718-2.647a8.736 8.736 0 0 0-.572-.989c-.275-.373-.298-.54-.113-.823.093-.142.114-.286.076-.502-.176-.999-.17-1.03.23-1.437.35-.353.371-.4.371-.813 0-.358.036-.475.198-.637.109-.109.282-.2.384-.2.296-.003.807-.277 1.11-.595.252-.265.52-.4.822-.404z" fill="#e1bee7" stroke-width=".696"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-ngrx-effects" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#00bcd4" fill-rule="nonzero"/><path d="M17.655 8.39l-6.152 2.193.933 8.142 5.219 2.888 5.219-2.888.932-8.142zm-1.278 2.067c.234-.004.487.07.768.223.124.066.498.16.83.21 1.183.17 2.586 1.073 3.03 1.95.306.602.243.927-.225 1.169-.404.209-1.23.108-2.43-.297l-1.012-.342-.36.137c-.522.2-1.044.694-1.258 1.19-.154.359-.177.527-.149 1.116.028.59.071.761.28 1.132.239.422.786.96.88.866.026-.026-.03-.197-.124-.38-.093-.183-.148-.368-.122-.41.026-.042.273.114.548.347.611.518 1.326.848 1.981.917.538.056.661-.044.258-.211a1.238 1.238 0 0 1-.374-.25c-.157-.173-.166-.168.504-.318.417-.094 1.24-.531 1.29-.685.016-.05-.118-.07-.338-.053-.2.016-.363-.004-.363-.046 0-.04.164-.243.363-.451.748-.781 1.004-1.365 1.083-2.474l.055-.767.176.365c.194.401.23.98.091 1.478-.115.416-.038.462.173.104.261-.443.345-.373.299.251-.05.678-.283 1.187-.808 1.762-.429.468-.377.552.141.233.5-.308.567-.26.31.224-.487.914-1.516 1.69-2.585 1.948-.647.158-1.106.187-1.7.11-1.55-.204-3.018-1.249-3.718-2.648a8.736 8.736 0 0 0-.572-.989c-.275-.373-.298-.54-.113-.823.093-.141.114-.286.076-.502-.176-.999-.17-1.03.23-1.437.35-.353.371-.4.371-.813 0-.358.036-.475.198-.637.109-.108.282-.199.384-.2.296-.003.807-.277 1.11-.595.252-.265.52-.4.822-.404z" fill="#b2ebf2" stroke-width=".696"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-ngrx-effects-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#00bcd4"/><path d="M17.655 8.39l-6.152 2.192.933 8.143 5.219 2.888 5.219-2.888.932-8.143zm-1.278 2.067c.234-.004.487.07.768.222.124.067.498.162.83.21 1.183.171 2.586 1.074 3.03 1.95.306.603.243.928-.225 1.17-.404.208-1.23.107-2.43-.298l-1.012-.341-.36.137c-.522.2-1.044.694-1.258 1.19-.154.359-.177.527-.149 1.116.028.59.071.761.28 1.132.239.422.786.96.88.866.026-.026-.03-.197-.124-.38-.093-.183-.148-.368-.122-.41.026-.042.273.114.548.347.611.517 1.326.848 1.981.917.538.056.661-.044.258-.211a1.238 1.238 0 0 1-.374-.25c-.157-.173-.166-.168.504-.318.417-.094 1.24-.531 1.29-.685.016-.05-.118-.07-.338-.053-.2.016-.363-.005-.363-.046 0-.04.164-.243.363-.452.748-.78 1.004-1.364 1.083-2.474l.055-.766.176.364c.194.402.23.981.091 1.479-.115.416-.038.462.173.103.261-.442.345-.372.299.252-.05.678-.283 1.186-.808 1.761-.429.47-.377.553.141.234.5-.308.567-.26.31.224-.487.914-1.516 1.689-2.585 1.948-.647.158-1.106.187-1.7.109-1.55-.203-3.018-1.248-3.718-2.647a8.736 8.736 0 0 0-.572-.989c-.275-.373-.298-.54-.113-.823.093-.142.114-.286.076-.502-.176-.999-.17-1.03.23-1.437.35-.353.371-.4.371-.813 0-.358.036-.475.198-.637.109-.109.282-.2.384-.2.296-.003.807-.277 1.11-.595.252-.265.52-.4.822-.404z" fill="#b2ebf2" stroke-width=".696"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-ngrx-reducer" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#ef5350" fill-rule="nonzero"/><path d="M17.655 8.39l-6.152 2.193.933 8.142 5.219 2.888 5.219-2.888.932-8.142zm-1.278 2.067c.234-.004.487.07.768.223.124.066.498.16.83.21 1.183.17 2.586 1.073 3.03 1.95.306.602.243.927-.225 1.169-.404.209-1.23.108-2.43-.297l-1.012-.342-.36.137c-.522.2-1.044.694-1.258 1.19-.154.359-.177.527-.149 1.116.028.59.071.761.28 1.132.239.422.786.96.88.866.026-.026-.03-.197-.124-.38-.093-.183-.148-.368-.122-.41.026-.042.273.114.548.347.611.518 1.326.848 1.981.917.538.056.661-.044.258-.211a1.238 1.238 0 0 1-.374-.25c-.157-.173-.166-.168.504-.318.417-.094 1.24-.531 1.29-.685.016-.05-.118-.07-.338-.053-.2.016-.363-.004-.363-.046 0-.04.164-.243.363-.451.748-.781 1.004-1.365 1.083-2.474l.055-.767.176.365c.194.401.23.98.091 1.478-.115.416-.038.462.173.104.261-.443.345-.373.299.251-.05.678-.283 1.187-.808 1.762-.429.468-.377.552.141.233.5-.308.567-.26.31.224-.487.914-1.516 1.69-2.585 1.948-.647.158-1.106.187-1.7.11-1.55-.204-3.018-1.249-3.718-2.648a8.736 8.736 0 0 0-.572-.989c-.275-.373-.298-.54-.113-.823.093-.141.114-.286.076-.502-.176-.999-.17-1.03.23-1.437.35-.353.371-.4.371-.813 0-.358.036-.475.198-.637.109-.108.282-.199.384-.2.296-.003.807-.277 1.11-.595.252-.265.52-.4.822-.404z" fill="#ffcdd2" stroke-width=".696"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-ngrx-reducer-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#ef5350"/><path d="M17.655 8.39l-6.152 2.192.933 8.143 5.219 2.888 5.219-2.888.932-8.143zm-1.278 2.067c.234-.004.487.07.768.222.124.067.498.162.83.21 1.183.171 2.586 1.074 3.03 1.95.306.603.243.928-.225 1.17-.404.208-1.23.107-2.43-.298l-1.012-.341-.36.137c-.522.2-1.044.694-1.258 1.19-.154.359-.177.527-.149 1.116.028.59.071.761.28 1.132.239.422.786.96.88.866.026-.026-.03-.197-.124-.38-.093-.183-.148-.368-.122-.41.026-.042.273.114.548.347.611.517 1.326.848 1.981.917.538.056.661-.044.258-.211a1.238 1.238 0 0 1-.374-.25c-.157-.173-.166-.168.504-.318.417-.094 1.24-.531 1.29-.685.016-.05-.118-.07-.338-.053-.2.016-.363-.005-.363-.046 0-.04.164-.243.363-.452.748-.78 1.004-1.364 1.083-2.474l.055-.766.176.364c.194.402.23.981.091 1.479-.115.416-.038.462.173.103.261-.442.345-.372.299.252-.05.678-.283 1.186-.808 1.761-.429.47-.377.553.141.234.5-.308.567-.26.31.224-.487.914-1.516 1.689-2.585 1.948-.647.158-1.106.187-1.7.109-1.55-.203-3.018-1.248-3.718-2.647a8.736 8.736 0 0 0-.572-.989c-.275-.373-.298-.54-.113-.823.093-.142.114-.286.076-.502-.176-.999-.17-1.03.23-1.437.35-.353.371-.4.371-.813 0-.358.036-.475.198-.637.109-.109.282-.2.384-.2.296-.003.807-.277 1.11-.595.252-.265.52-.4.822-.404z" fill="#ffcdd2" stroke-width=".696"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-ngrx-state" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#8bc34a" fill-rule="nonzero"/><path d="M17.655 8.39l-6.152 2.193.933 8.142 5.219 2.888 5.219-2.888.932-8.142zm-1.278 2.067c.234-.004.487.07.768.223.124.066.498.16.83.21 1.183.17 2.586 1.073 3.03 1.95.306.602.243.927-.225 1.169-.404.209-1.23.108-2.43-.297l-1.012-.342-.36.137c-.522.2-1.044.694-1.258 1.19-.154.359-.177.527-.149 1.116.028.59.071.761.28 1.132.239.422.786.96.88.866.026-.026-.03-.197-.124-.38-.093-.183-.148-.368-.122-.41.026-.042.273.114.548.347.611.518 1.326.848 1.981.917.538.056.661-.044.258-.211a1.238 1.238 0 0 1-.374-.25c-.157-.173-.166-.168.504-.318.417-.094 1.24-.531 1.29-.685.016-.05-.118-.07-.338-.053-.2.016-.363-.004-.363-.046 0-.04.164-.243.363-.451.748-.781 1.004-1.365 1.083-2.474l.055-.767.176.365c.194.401.23.98.091 1.478-.115.416-.038.462.173.104.261-.443.345-.373.299.251-.05.678-.283 1.187-.808 1.762-.429.468-.377.552.141.233.5-.308.567-.26.31.224-.487.914-1.516 1.69-2.585 1.948-.647.158-1.106.187-1.7.11-1.55-.204-3.018-1.249-3.718-2.648a8.736 8.736 0 0 0-.572-.989c-.275-.373-.298-.54-.113-.823.093-.141.114-.286.076-.502-.176-.999-.17-1.03.23-1.437.35-.353.371-.4.371-.813 0-.358.036-.475.198-.637.109-.108.282-.199.384-.2.296-.003.807-.277 1.11-.595.252-.265.52-.4.822-.404z" fill="#dcedc8" stroke-width=".696"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-ngrx-state-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#8bc34a"/><path d="M17.655 8.39l-6.152 2.192.933 8.143 5.219 2.888 5.219-2.888.932-8.143zm-1.278 2.067c.234-.004.487.07.768.222.124.067.498.162.83.21 1.183.171 2.586 1.074 3.03 1.95.306.603.243.928-.225 1.17-.404.208-1.23.107-2.43-.298l-1.012-.341-.36.137c-.522.2-1.044.694-1.258 1.19-.154.359-.177.527-.149 1.116.028.59.071.761.28 1.132.239.422.786.96.88.866.026-.026-.03-.197-.124-.38-.093-.183-.148-.368-.122-.41.026-.042.273.114.548.347.611.517 1.326.848 1.981.917.538.056.661-.044.258-.211a1.238 1.238 0 0 1-.374-.25c-.157-.173-.166-.168.504-.318.417-.094 1.24-.531 1.29-.685.016-.05-.118-.07-.338-.053-.2.016-.363-.005-.363-.046 0-.04.164-.243.363-.452.748-.78 1.004-1.364 1.083-2.474l.055-.766.176.364c.194.402.23.981.091 1.479-.115.416-.038.462.173.103.261-.442.345-.372.299.252-.05.678-.283 1.186-.808 1.761-.429.47-.377.553.141.234.5-.308.567-.26.31.224-.487.914-1.516 1.689-2.585 1.948-.647.158-1.106.187-1.7.109-1.55-.203-3.018-1.248-3.718-2.647a8.736 8.736 0 0 0-.572-.989c-.275-.373-.298-.54-.113-.823.093-.142.114-.286.076-.502-.176-.999-.17-1.03.23-1.437.35-.353.371-.4.371-.813 0-.358.036-.475.198-.637.109-.109.282-.2.384-.2.296-.003.807-.277 1.11-.595.252-.265.52-.4.822-.404z" fill="#dcedc8" stroke-width=".696"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-node" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#8bc34a" fill-rule="nonzero"/><path d="M17.25 8.403c-.188 0-.382.048-.542.139l-5.166 2.986a1.096 1.096 0 0 0-.542.944v5.959c0 .388.208.75.542.944l1.354.778c.66.32.882.326 1.187.326.973 0 1.535-.59 1.535-1.618V12.98a.154.154 0 0 0-.153-.153h-.646c-.09 0-.16.07-.16.153v5.882c0 .458-.472.91-1.228.528l-1.424-.813a.181.181 0 0 1-.076-.145v-5.959c0-.062.027-.118.076-.146l5.167-2.979a.15.15 0 0 1 .152 0l5.167 2.98a.164.164 0 0 1 .076.145v5.959a.181.181 0 0 1-.076.145l-5.167 2.98c-.041.027-.11.027-.16 0l-1.305-.792c-.055-.021-.111-.028-.146-.007-.368.208-.437.25-.778.354-.083.028-.215.076.05.222l1.721 1.021c.167.097.348.146.542.146s.375-.049.542-.146l5.166-2.979c.334-.194.542-.556.542-.944v-5.959c0-.389-.208-.75-.542-.944l-5.166-2.986a1.103 1.103 0 0 0-.542-.14m1.389 4.272c-1.472 0-2.354.618-2.354 1.66 0 1.117.875 1.444 2.291 1.583 1.688.166 1.82.416 1.82.75 0 .576-.465.82-1.549.82-1.375 0-1.666-.341-1.77-1.022a.157.157 0 0 0-.153-.125h-.667c-.083 0-.146.063-.146.153 0 .861.472 1.903 2.736 1.903 1.632 0 2.57-.646 2.57-1.771 0-1.118-.75-1.41-2.34-1.625-1.605-.208-1.765-.32-1.765-.694 0-.313.14-.73 1.327-.73 1.042 0 1.451.23 1.611.945.014.07.076.118.146.118h.673a.134.134 0 0 0 .105-.049c.027-.028.048-.07.034-.11-.097-1.237-.916-1.806-2.57-1.806z" fill-rule="nonzero" fill="#f1f8e9"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-node-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#8bc34a" fill-rule="nonzero"/><path d="M17.25 8.403c-.188 0-.382.048-.542.139l-5.166 2.986a1.096 1.096 0 0 0-.542.944v5.959c0 .388.208.75.542.944l1.354.778c.66.32.882.326 1.187.326.973 0 1.535-.59 1.535-1.618V12.98a.154.154 0 0 0-.153-.153h-.646c-.09 0-.16.07-.16.153v5.882c0 .458-.472.91-1.228.528l-1.424-.813a.181.181 0 0 1-.076-.145v-5.959c0-.062.027-.118.076-.146l5.167-2.979a.15.15 0 0 1 .152 0l5.167 2.98a.164.164 0 0 1 .076.145v5.959a.181.181 0 0 1-.076.145l-5.167 2.98c-.041.027-.11.027-.16 0l-1.305-.792c-.055-.021-.111-.028-.146-.007-.368.208-.437.25-.778.354-.083.028-.215.076.05.222l1.721 1.021c.167.097.348.146.542.146s.375-.049.542-.146l5.166-2.979c.334-.194.542-.556.542-.944v-5.959c0-.389-.208-.75-.542-.944l-5.166-2.986a1.103 1.103 0 0 0-.542-.14m1.389 4.272c-1.472 0-2.354.618-2.354 1.66 0 1.117.875 1.444 2.291 1.583 1.688.166 1.82.416 1.82.75 0 .576-.465.82-1.549.82-1.375 0-1.666-.341-1.77-1.022a.157.157 0 0 0-.153-.125h-.667c-.083 0-.146.063-.146.153 0 .861.472 1.903 2.736 1.903 1.632 0 2.57-.646 2.57-1.771 0-1.118-.75-1.41-2.34-1.625-1.605-.208-1.765-.32-1.765-.694 0-.313.14-.73 1.327-.73 1.042 0 1.451.23 1.611.945.014.07.076.118.146.118h.673a.134.134 0 0 0 .105-.049c.027-.028.048-.07.034-.11-.097-1.237-.916-1.806-2.57-1.806z" fill-rule="nonzero" fill="#f1f8e9"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-public" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#039be5" fill-rule="nonzero"/><path d="M20.036 16.746c.05-.408.087-.817.087-1.237s-.037-.83-.087-1.238h2.091c.099.396.16.81.16 1.238a5.1 5.1 0 0 1-.16 1.237m-3.186 3.44c.371-.687.656-1.43.854-2.203h1.825a4.968 4.968 0 0 1-2.679 2.203m-.155-3.44h-2.895c-.062-.408-.099-.817-.099-1.237s.037-.835.1-1.238h2.894c.056.403.1.817.1 1.238s-.044.829-.1 1.237m-1.447 3.687a8.39 8.39 0 0 1-1.182-2.45h2.363a8.39 8.39 0 0 1-1.181 2.45m-2.475-7.399h-1.806a4.902 4.902 0 0 1 2.672-2.202c-.37.686-.65 1.429-.866 2.202m-1.806 4.95h1.806c.217.773.495 1.515.866 2.202a4.954 4.954 0 0 1-2.672-2.203m-.508-1.237a5.099 5.099 0 0 1-.16-1.237 5.1 5.1 0 0 1 .16-1.238h2.091c-.049.409-.086.817-.086 1.238s.037.829.086 1.237m2.698-6.168a8.425 8.425 0 0 1 1.181 2.456h-2.363a8.426 8.426 0 0 1 1.182-2.456m4.28 2.456h-1.824a9.682 9.682 0 0 0-.854-2.202 4.94 4.94 0 0 1 2.679 2.202m-4.281-3.712a6.193 6.193 0 0 0-6.187 6.187 6.186 6.186 0 0 0 6.187 6.186 6.186 6.186 0 0 0 6.186-6.186 6.186 6.186 0 0 0-6.186-6.187z" fill="#b3e5fc" stroke-width=".619"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-public-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#039be5"/><path d="M20.037 16.746c.05-.408.087-.817.087-1.237s-.037-.83-.087-1.238h2.091c.099.396.16.81.16 1.238a5.1 5.1 0 0 1-.16 1.237m-3.186 3.44c.371-.687.656-1.43.854-2.203h1.825a4.967 4.967 0 0 1-2.68 2.203m-.154-3.44h-2.895c-.062-.408-.099-.817-.099-1.237s.037-.835.099-1.238h2.895c.056.403.1.817.1 1.238s-.044.829-.1 1.237m-1.447 3.687a8.39 8.39 0 0 1-1.182-2.45h2.363a8.39 8.39 0 0 1-1.181 2.45m-2.475-7.399H13.06a4.902 4.902 0 0 1 2.672-2.202c-.371.686-.65 1.429-.866 2.202m-1.806 4.95h1.806c.217.773.495 1.515.866 2.202a4.954 4.954 0 0 1-2.672-2.203m-.508-1.237a5.099 5.099 0 0 1-.16-1.237 5.1 5.1 0 0 1 .16-1.238h2.091c-.05.409-.086.817-.086 1.238s.037.829.086 1.237m2.698-6.168a8.425 8.425 0 0 1 1.181 2.456h-2.363a8.426 8.426 0 0 1 1.182-2.456m4.28 2.456h-1.824a9.682 9.682 0 0 0-.854-2.202 4.941 4.941 0 0 1 2.679 2.202M17.34 9.322a6.193 6.193 0 0 0-6.187 6.187 6.186 6.186 0 0 0 6.187 6.186 6.186 6.186 0 0 0 6.186-6.186 6.186 6.186 0 0 0-6.186-6.187z" fill="#b3e5fc" stroke-width=".619"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-react-components" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#00bcd4" fill-rule="nonzero"/><path d="M16.473 13.927c.723 0 1.313.59 1.313 1.327 0 .703-.59 1.3-1.313 1.3a1.318 1.318 0 0 1-1.313-1.3c0-.737.59-1.327 1.313-1.327m-3.252 6.946c.443.267 1.412-.14 2.529-1.194a17.015 17.015 0 0 1-1.06-1.335 15.945 15.945 0 0 1-1.686-.252c-.358 1.502-.225 2.535.217 2.78m.499-4.03l-.204-.359a5.558 5.558 0 0 0-.203.604c.19.042.4.078.618.113l-.211-.359m4.593-.533l.569-1.054-.569-1.053c-.21-.372-.435-.702-.639-1.032-.38-.022-.78-.022-1.2-.022-.422 0-.823 0-1.202.022-.204.33-.428.66-.639 1.032l-.569 1.053.57 1.054c.21.372.434.702.638 1.032.38.021.78.021 1.201.021.421 0 .822 0 1.201-.02.204-.331.428-.661.639-1.033m-1.84-4.72c-.133.155-.274.316-.414.506h.828c-.14-.19-.28-.351-.414-.506m0 7.332c.133-.154.274-.316.414-.505h-.828c.14.19.28.35.414.505m3.245-9.284c-.436-.267-1.405.14-2.522 1.194.366.414.724.864 1.06 1.334.577.057 1.146.14 1.686.253.359-1.503.225-2.535-.224-2.78m-.492 4.03l.204.358c.077-.203.154-.407.203-.604-.19-.042-.4-.077-.618-.112l.211.358m1.018-4.95c1.033.589 1.145 2.141.71 3.953 1.784.527 3.069 1.398 3.069 2.584 0 1.187-1.285 2.058-3.07 2.585.436 1.812.324 3.364-.709 3.954-1.025.59-2.423-.085-3.77-1.37-1.35 1.285-2.747 1.96-3.78 1.37-1.025-.59-1.137-2.142-.702-3.954-1.783-.527-3.069-1.398-3.069-2.585s1.286-2.057 3.07-2.584c-.436-1.812-.324-3.364.702-3.954 1.032-.59 2.43.084 3.778 1.37 1.348-1.286 2.746-1.96 3.771-1.37m-.203 6.538c.239.527.45 1.054.625 1.588 1.475-.443 2.303-1.075 2.303-1.588 0-.512-.828-1.144-2.303-1.587a15.81 15.81 0 0 1-.625 1.587m-7.136 0a15.806 15.806 0 0 1-.625-1.587c-1.474.443-2.303 1.075-2.303 1.587 0 .513.829 1.145 2.303 1.588.176-.534.387-1.06.625-1.588m6.321 1.588l-.21.358c.217-.035.428-.07.617-.113-.049-.196-.126-.4-.203-.604l-.204.359m-2.03 2.837c1.117 1.053 2.086 1.46 2.522 1.194.45-.246.583-1.278.224-2.781-.54.112-1.11.196-1.685.253-.337.47-.695.92-1.06 1.334m-3.477-6.012l.21-.358c-.217.035-.428.07-.617.113.049.196.126.4.203.604l.204-.359m2.03-2.837c-1.117-1.053-2.086-1.46-2.529-1.194-.442.246-.576 1.278-.217 2.781.54-.112 1.11-.196 1.685-.253.337-.47.695-.92 1.06-1.334z" fill="#b2ebf2" stroke-width=".702"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-react-components-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#00bcd4"/><path d="M16.473 13.928c.723 0 1.313.59 1.313 1.327 0 .703-.59 1.3-1.313 1.3a1.318 1.318 0 0 1-1.313-1.3c0-.737.59-1.327 1.313-1.327m-3.252 6.946c.443.267 1.412-.14 2.529-1.194a16.997 16.997 0 0 1-1.06-1.335 15.945 15.945 0 0 1-1.686-.252c-.358 1.502-.225 2.535.217 2.78m.499-4.03l-.204-.359c-.077.204-.154.408-.203.604.19.042.4.078.618.113l-.211-.359m4.593-.533l.569-1.054-.57-1.053c-.21-.372-.434-.702-.638-1.032-.38-.022-.78-.022-1.201-.022-.421 0-.822 0-1.2.022-.205.33-.43.66-.64 1.032l-.569 1.053.569 1.054c.21.372.435.702.64 1.032.378.021.779.021 1.2.021.421 0 .822 0 1.2-.02.205-.33.43-.661.64-1.033m-1.84-4.72c-.133.155-.274.316-.414.506h.828c-.14-.19-.28-.351-.414-.506m0 7.332c.133-.154.274-.316.414-.505h-.828c.14.19.28.35.414.505m3.244-9.284c-.435-.267-1.404.14-2.52 1.194.364.414.723.864 1.06 1.334.575.057 1.144.14 1.685.253.358-1.503.225-2.535-.225-2.78m-.491 4.03l.203.358c.078-.203.155-.407.204-.604-.19-.042-.4-.077-.618-.112l.21.358m1.02-4.95c1.032.589 1.144 2.141.708 3.953 1.784.527 3.07 1.398 3.07 2.584 0 1.187-1.286 2.058-3.07 2.585.436 1.812.323 3.364-.709 3.954-1.025.59-2.423-.085-3.771-1.37-1.348 1.285-2.746 1.96-3.778 1.37-1.026-.59-1.138-2.142-.703-3.954-1.783-.527-3.069-1.398-3.069-2.585s1.286-2.057 3.07-2.584c-.436-1.812-.324-3.364.702-3.954 1.032-.59 2.43.084 3.778 1.37 1.348-1.286 2.746-1.96 3.771-1.37m-.204 6.538c.24.527.45 1.054.625 1.588 1.475-.443 2.304-1.075 2.304-1.588 0-.512-.829-1.144-2.304-1.587a15.81 15.81 0 0 1-.625 1.587m-7.135 0a15.808 15.808 0 0 1-.625-1.587c-1.475.443-2.303 1.075-2.303 1.587 0 .513.828 1.145 2.303 1.588.176-.534.386-1.06.625-1.588m6.32 1.588l-.21.358c.218-.035.428-.07.618-.113a5.56 5.56 0 0 0-.204-.604l-.203.359m-2.03 2.837c1.117 1.053 2.086 1.46 2.521 1.194.45-.246.583-1.278.225-2.781-.54.112-1.11.196-1.685.253-.338.47-.696.92-1.06 1.334m-3.477-6.012l.21-.358c-.217.035-.428.07-.617.112.049.197.126.4.203.604l.204-.358m2.03-2.837c-1.117-1.053-2.086-1.46-2.529-1.194-.442.246-.576 1.278-.217 2.781.54-.112 1.11-.196 1.685-.253.337-.47.695-.92 1.06-1.334z" fill="#b2ebf2" stroke-width=".702"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-redux-actions" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#ab47bc" fill-rule="nonzero"/><g transform="translate(8.378 6.436) scale(.17228)" fill="#e1bee7" stroke="#e1bee7" stroke-miterlimit="4" stroke-width="1.702"><path d="M65.6 65.4c2.9-.3 5.1-2.8 5-5.8S68 54.2 65 54.2h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 1.5.7 2.8 1.6 3.7-3.4 6.7-8.6 11.6-16.4 15.7-5.3 2.8-10.8 3.8-16.3 3.1-4.5-.6-8-2.6-10.2-5.9-3.2-4.9-3.5-10.2-.8-15.5 1.9-3.8 4.9-6.6 6.8-8-.4-1.3-1-3.5-1.3-5.1-14.5 10.5-13 24.7-8.6 31.4 3.3 5 10 8.1 17.4 8.1 2 0 4-.2 6-.7 12.8-2.5 22.5-10.1 28-21.4z"/><path d="M83.2 53c-7.6-8.9-18.8-13.8-31.6-13.8H50c-.9-1.8-2.8-3-4.9-3h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 3 2.6 5.4 5.6 5.4h.2c2.2-.1 4.1-1.5 4.9-3.4H52c7.6 0 14.8 2.2 21.3 6.5 5 3.3 8.6 7.6 10.6 12.8 1.7 4.2 1.6 8.3-.2 11.8-2.8 5.3-7.5 8.2-13.7 8.2-4 0-7.8-1.2-9.8-2.1-1.1 1-3.1 2.6-4.5 3.6 4.3 2 8.7 3.1 12.9 3.1 9.6 0 16.7-5.3 19.4-10.6 2.9-5.8 2.7-15.8-4.8-24.3z"/><path d="M32.4 67.1c.1 3 2.6 5.4 5.6 5.4h.2c3.1-.1 5.5-2.7 5.4-5.8-.1-3-2.6-5.4-5.6-5.4h-.2c-.2 0-.5 0-.7.1-4.1-6.8-5.8-14.2-5.2-22.2.4-6 2.4-11.2 5.9-15.5 2.9-3.7 8.5-5.5 12.3-5.6 10.6-.2 15.1 13 15.4 18.3 1.3.3 3.5 1 5 1.5-1.2-16.2-11.2-24.6-20.8-24.6-9 0-17.3 6.5-20.6 16.1-4.6 12.8-1.6 25.1 4 34.8-.5.7-.8 1.8-.7 2.9z"/></g></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-redux-actions-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#ab47bc"/><g transform="translate(8.378 6.436) scale(.17228)" fill="#e1bee7" stroke="#e1bee7" stroke-miterlimit="4" stroke-width="1.702"><path d="M65.6 65.4c2.9-.3 5.1-2.8 5-5.8S68 54.2 65 54.2h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 1.5.7 2.8 1.6 3.7-3.4 6.7-8.6 11.6-16.4 15.7-5.3 2.8-10.8 3.8-16.3 3.1-4.5-.6-8-2.6-10.2-5.9-3.2-4.9-3.5-10.2-.8-15.5 1.9-3.8 4.9-6.6 6.8-8-.4-1.3-1-3.5-1.3-5.1-14.5 10.5-13 24.7-8.6 31.4 3.3 5 10 8.1 17.4 8.1 2 0 4-.2 6-.7 12.8-2.5 22.5-10.1 28-21.4z"/><path d="M83.2 53c-7.6-8.9-18.8-13.8-31.6-13.8H50c-.9-1.8-2.8-3-4.9-3h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 3 2.6 5.4 5.6 5.4h.2c2.2-.1 4.1-1.5 4.9-3.4H52c7.6 0 14.8 2.2 21.3 6.5 5 3.3 8.6 7.6 10.6 12.8 1.7 4.2 1.6 8.3-.2 11.8-2.8 5.3-7.5 8.2-13.7 8.2-4 0-7.8-1.2-9.8-2.1-1.1 1-3.1 2.6-4.5 3.6 4.3 2 8.7 3.1 12.9 3.1 9.6 0 16.7-5.3 19.4-10.6 2.9-5.8 2.7-15.8-4.8-24.3z"/><path d="M32.4 67.1c.1 3 2.6 5.4 5.6 5.4h.2c3.1-.1 5.5-2.7 5.4-5.8-.1-3-2.6-5.4-5.6-5.4h-.2c-.2 0-.5 0-.7.1-4.1-6.8-5.8-14.2-5.2-22.2.4-6 2.4-11.2 5.9-15.5 2.9-3.7 8.5-5.5 12.3-5.6 10.6-.2 15.1 13 15.4 18.3 1.3.3 3.5 1 5 1.5-1.2-16.2-11.2-24.6-20.8-24.6-9 0-17.3 6.5-20.6 16.1-4.6 12.8-1.6 25.1 4 34.8-.5.7-.8 1.8-.7 2.9z"/></g></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-redux-reducer" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#ef5350" fill-rule="nonzero"/><g transform="translate(8.378 6.436) scale(.17228)" fill="#ffcdd2" stroke="#ffcdd2" stroke-miterlimit="4" stroke-width="1.702"><path d="M65.6 65.4c2.9-.3 5.1-2.8 5-5.8S68 54.2 65 54.2h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 1.5.7 2.8 1.6 3.7-3.4 6.7-8.6 11.6-16.4 15.7-5.3 2.8-10.8 3.8-16.3 3.1-4.5-.6-8-2.6-10.2-5.9-3.2-4.9-3.5-10.2-.8-15.5 1.9-3.8 4.9-6.6 6.8-8-.4-1.3-1-3.5-1.3-5.1-14.5 10.5-13 24.7-8.6 31.4 3.3 5 10 8.1 17.4 8.1 2 0 4-.2 6-.7 12.8-2.5 22.5-10.1 28-21.4z"/><path d="M83.2 53c-7.6-8.9-18.8-13.8-31.6-13.8H50c-.9-1.8-2.8-3-4.9-3h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 3 2.6 5.4 5.6 5.4h.2c2.2-.1 4.1-1.5 4.9-3.4H52c7.6 0 14.8 2.2 21.3 6.5 5 3.3 8.6 7.6 10.6 12.8 1.7 4.2 1.6 8.3-.2 11.8-2.8 5.3-7.5 8.2-13.7 8.2-4 0-7.8-1.2-9.8-2.1-1.1 1-3.1 2.6-4.5 3.6 4.3 2 8.7 3.1 12.9 3.1 9.6 0 16.7-5.3 19.4-10.6 2.9-5.8 2.7-15.8-4.8-24.3z"/><path d="M32.4 67.1c.1 3 2.6 5.4 5.6 5.4h.2c3.1-.1 5.5-2.7 5.4-5.8-.1-3-2.6-5.4-5.6-5.4h-.2c-.2 0-.5 0-.7.1-4.1-6.8-5.8-14.2-5.2-22.2.4-6 2.4-11.2 5.9-15.5 2.9-3.7 8.5-5.5 12.3-5.6 10.6-.2 15.1 13 15.4 18.3 1.3.3 3.5 1 5 1.5-1.2-16.2-11.2-24.6-20.8-24.6-9 0-17.3 6.5-20.6 16.1-4.6 12.8-1.6 25.1 4 34.8-.5.7-.8 1.8-.7 2.9z"/></g></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-redux-reducer-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#ef5350"/><g transform="translate(8.378 6.436) scale(.17228)" fill="#ffcdd2" stroke="#ffcdd2" stroke-miterlimit="4" stroke-width="1.702"><path d="M65.6 65.4c2.9-.3 5.1-2.8 5-5.8S68 54.2 65 54.2h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 1.5.7 2.8 1.6 3.7-3.4 6.7-8.6 11.6-16.4 15.7-5.3 2.8-10.8 3.8-16.3 3.1-4.5-.6-8-2.6-10.2-5.9-3.2-4.9-3.5-10.2-.8-15.5 1.9-3.8 4.9-6.6 6.8-8-.4-1.3-1-3.5-1.3-5.1-14.5 10.5-13 24.7-8.6 31.4 3.3 5 10 8.1 17.4 8.1 2 0 4-.2 6-.7 12.8-2.5 22.5-10.1 28-21.4z"/><path d="M83.2 53c-7.6-8.9-18.8-13.8-31.6-13.8H50c-.9-1.8-2.8-3-4.9-3h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 3 2.6 5.4 5.6 5.4h.2c2.2-.1 4.1-1.5 4.9-3.4H52c7.6 0 14.8 2.2 21.3 6.5 5 3.3 8.6 7.6 10.6 12.8 1.7 4.2 1.6 8.3-.2 11.8-2.8 5.3-7.5 8.2-13.7 8.2-4 0-7.8-1.2-9.8-2.1-1.1 1-3.1 2.6-4.5 3.6 4.3 2 8.7 3.1 12.9 3.1 9.6 0 16.7-5.3 19.4-10.6 2.9-5.8 2.7-15.8-4.8-24.3z"/><path d="M32.4 67.1c.1 3 2.6 5.4 5.6 5.4h.2c3.1-.1 5.5-2.7 5.4-5.8-.1-3-2.6-5.4-5.6-5.4h-.2c-.2 0-.5 0-.7.1-4.1-6.8-5.8-14.2-5.2-22.2.4-6 2.4-11.2 5.9-15.5 2.9-3.7 8.5-5.5 12.3-5.6 10.6-.2 15.1 13 15.4 18.3 1.3.3 3.5 1 5 1.5-1.2-16.2-11.2-24.6-20.8-24.6-9 0-17.3 6.5-20.6 16.1-4.6 12.8-1.6 25.1 4 34.8-.5.7-.8 1.8-.7 2.9z"/></g></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-redux-store" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#8bc34a" fill-rule="nonzero"/><g transform="translate(8.378 6.436) scale(.17228)" fill="#dcedc8" stroke="#dcedc8" stroke-miterlimit="4" stroke-width="1.702"><path d="M65.6 65.4c2.9-.3 5.1-2.8 5-5.8S68 54.2 65 54.2h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 1.5.7 2.8 1.6 3.7-3.4 6.7-8.6 11.6-16.4 15.7-5.3 2.8-10.8 3.8-16.3 3.1-4.5-.6-8-2.6-10.2-5.9-3.2-4.9-3.5-10.2-.8-15.5 1.9-3.8 4.9-6.6 6.8-8-.4-1.3-1-3.5-1.3-5.1-14.5 10.5-13 24.7-8.6 31.4 3.3 5 10 8.1 17.4 8.1 2 0 4-.2 6-.7 12.8-2.5 22.5-10.1 28-21.4z"/><path d="M83.2 53c-7.6-8.9-18.8-13.8-31.6-13.8H50c-.9-1.8-2.8-3-4.9-3h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 3 2.6 5.4 5.6 5.4h.2c2.2-.1 4.1-1.5 4.9-3.4H52c7.6 0 14.8 2.2 21.3 6.5 5 3.3 8.6 7.6 10.6 12.8 1.7 4.2 1.6 8.3-.2 11.8-2.8 5.3-7.5 8.2-13.7 8.2-4 0-7.8-1.2-9.8-2.1-1.1 1-3.1 2.6-4.5 3.6 4.3 2 8.7 3.1 12.9 3.1 9.6 0 16.7-5.3 19.4-10.6 2.9-5.8 2.7-15.8-4.8-24.3z"/><path d="M32.4 67.1c.1 3 2.6 5.4 5.6 5.4h.2c3.1-.1 5.5-2.7 5.4-5.8-.1-3-2.6-5.4-5.6-5.4h-.2c-.2 0-.5 0-.7.1-4.1-6.8-5.8-14.2-5.2-22.2.4-6 2.4-11.2 5.9-15.5 2.9-3.7 8.5-5.5 12.3-5.6 10.6-.2 15.1 13 15.4 18.3 1.3.3 3.5 1 5 1.5-1.2-16.2-11.2-24.6-20.8-24.6-9 0-17.3 6.5-20.6 16.1-4.6 12.8-1.6 25.1 4 34.8-.5.7-.8 1.8-.7 2.9z"/></g></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-redux-store-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#8bc34a"/><g transform="translate(8.378 6.436) scale(.17228)" fill="#dcedc8" stroke="#dcedc8" stroke-miterlimit="4" stroke-width="1.702"><path d="M65.6 65.4c2.9-.3 5.1-2.8 5-5.8S68 54.2 65 54.2h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 1.5.7 2.8 1.6 3.7-3.4 6.7-8.6 11.6-16.4 15.7-5.3 2.8-10.8 3.8-16.3 3.1-4.5-.6-8-2.6-10.2-5.9-3.2-4.9-3.5-10.2-.8-15.5 1.9-3.8 4.9-6.6 6.8-8-.4-1.3-1-3.5-1.3-5.1-14.5 10.5-13 24.7-8.6 31.4 3.3 5 10 8.1 17.4 8.1 2 0 4-.2 6-.7 12.8-2.5 22.5-10.1 28-21.4z"/><path d="M83.2 53c-7.6-8.9-18.8-13.8-31.6-13.8H50c-.9-1.8-2.8-3-4.9-3h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 3 2.6 5.4 5.6 5.4h.2c2.2-.1 4.1-1.5 4.9-3.4H52c7.6 0 14.8 2.2 21.3 6.5 5 3.3 8.6 7.6 10.6 12.8 1.7 4.2 1.6 8.3-.2 11.8-2.8 5.3-7.5 8.2-13.7 8.2-4 0-7.8-1.2-9.8-2.1-1.1 1-3.1 2.6-4.5 3.6 4.3 2 8.7 3.1 12.9 3.1 9.6 0 16.7-5.3 19.4-10.6 2.9-5.8 2.7-15.8-4.8-24.3z"/><path d="M32.4 67.1c.1 3 2.6 5.4 5.6 5.4h.2c3.1-.1 5.5-2.7 5.4-5.8-.1-3-2.6-5.4-5.6-5.4h-.2c-.2 0-.5 0-.7.1-4.1-6.8-5.8-14.2-5.2-22.2.4-6 2.4-11.2 5.9-15.5 2.9-3.7 8.5-5.5 12.3-5.6 10.6-.2 15.1 13 15.4 18.3 1.3.3 3.5 1 5 1.5-1.2-16.2-11.2-24.6-20.8-24.6-9 0-17.3 6.5-20.6 16.1-4.6 12.8-1.6 25.1 4 34.8-.5.7-.8 1.8-.7 2.9z"/></g></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-resource" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#fbc02d" fill-rule="nonzero"/><path d="M21.598 12.059h-6.085v-1.217h6.085m-2.434 6.085h-3.65V15.71h3.65m2.434-1.217h-6.085v-1.217h6.085m.608-4.26h-7.301a1.217 1.217 0 0 0-1.217 1.218v7.301a1.217 1.217 0 0 0 1.217 1.217h7.301a1.217 1.217 0 0 0 1.217-1.217v-7.301a1.217 1.217 0 0 0-1.217-1.217m-9.735 2.434h-1.217v8.518a1.217 1.217 0 0 0 1.217 1.217h8.519v-1.217H12.47z" fill="#fff9c4" stroke-width=".608"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-resource-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#fbc02d"/><path d="M21.598 12.059h-6.085v-1.217h6.085m-2.434 6.085h-3.65V15.71h3.65m2.434-1.217h-6.085v-1.217h6.085m.608-4.26h-7.301a1.217 1.217 0 0 0-1.217 1.218v7.301a1.217 1.217 0 0 0 1.217 1.217h7.301a1.217 1.217 0 0 0 1.217-1.217v-7.301a1.217 1.217 0 0 0-1.217-1.217m-9.735 2.433h-1.217v8.519a1.217 1.217 0 0 0 1.217 1.217h8.519v-1.217H12.47z" fill="#fff9c4" stroke-width=".608"/></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" id="folder-sass" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#f8bbd0" fill-rule="nonzero"/><path d="M23.36 10.506c-.39-1.527-2.922-2.03-5.319-1.178-1.426.507-2.97 1.302-4.08 2.34-1.32 1.235-1.53 2.31-1.444 2.759.306 1.584 2.477 2.62 3.37 3.388v.005c-.264.13-2.19 1.104-2.64 2.1-.476 1.052.075 1.806.44 1.908 1.131.315 2.292-.251 2.916-1.182.602-.897.551-2.056.29-2.633.36-.095.781-.138 1.316-.076 1.508.177 1.804 1.118 1.748 1.513-.057.394-.373.61-.48.676-.105.065-.137.088-.129.137.013.07.062.068.152.053.125-.021.792-.321.821-1.048.037-.924-.849-1.958-2.416-1.93-.646.01-1.052.072-1.345.181-.022-.024-.044-.05-.067-.073-.969-1.034-2.76-1.765-2.684-3.156.027-.505.203-1.835 3.442-3.45 2.653-1.322 4.777-.957 5.145-.151.524 1.152-1.136 3.293-3.891 3.601-1.05.118-1.603-.289-1.74-.44-.145-.16-.166-.167-.22-.137-.088.049-.033.19 0 .274.082.214.42.594.995.782.506.166 1.739.258 3.23-.319 1.669-.646 2.972-2.443 2.59-3.944zm-7.103 7.783a2.2 2.2 0 0 1-.065 1.413 2.405 2.405 0 0 1-.453.704c-.5.546-1.198.752-1.497.579-.323-.188-.161-.956.418-1.568.623-.66 1.52-1.083 1.52-1.083l-.002-.002.079-.043z" fill="#ec407a" fill-rule="nonzero" stroke="#ec407a" stroke-width=".5199012000000001"/></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" id="folder-sass-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#f8bbd0" fill-rule="nonzero"/><path d="M23.36 10.506c-.39-1.527-2.922-2.03-5.319-1.178-1.426.507-2.97 1.302-4.08 2.34-1.32 1.235-1.53 2.31-1.444 2.759.306 1.584 2.477 2.62 3.37 3.388v.005c-.264.13-2.19 1.104-2.64 2.1-.476 1.052.075 1.806.44 1.908 1.131.315 2.292-.251 2.916-1.182.602-.897.551-2.056.29-2.633.36-.095.781-.138 1.316-.076 1.508.177 1.804 1.118 1.748 1.513-.057.394-.373.61-.48.676-.105.065-.137.088-.129.137.013.07.062.068.152.053.125-.021.792-.321.821-1.048.037-.924-.849-1.958-2.416-1.93-.646.01-1.052.072-1.345.181-.022-.024-.044-.05-.067-.073-.969-1.034-2.76-1.765-2.684-3.156.027-.505.203-1.835 3.442-3.45 2.653-1.322 4.777-.957 5.145-.151.524 1.152-1.136 3.293-3.891 3.601-1.05.118-1.603-.289-1.74-.44-.145-.16-.166-.167-.22-.137-.088.049-.033.19 0 .274.082.214.42.594.995.782.506.166 1.739.258 3.23-.319 1.669-.646 2.972-2.443 2.59-3.944zm-7.103 7.783a2.2 2.2 0 0 1-.065 1.413 2.405 2.405 0 0 1-.453.704c-.5.546-1.198.752-1.497.579-.323-.188-.161-.956.418-1.568.623-.66 1.52-1.083 1.52-1.083l-.002-.002.079-.043z" fill="#ec407a" fill-rule="nonzero" stroke="#ec407a" stroke-width=".5199012000000001"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-scripts" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#546e7a" fill-rule="nonzero"/><path d="M18.466 20.241c.69 0 1.259-.568 1.259-1.258v-8.18H15.32a.632.632 0 0 0-.63.63v6.292h-1.887v-6.922c0-1.036.852-1.888 1.888-1.888h6.921c1.036 0 1.888.852 1.888 1.888v.63h-2.517v8.18a1.896 1.896 0 0 1-1.888 1.887h-6.292a1.896 1.896 0 0 1-1.888-1.888v-.629h6.293c0 .69.568 1.258 1.258 1.258z" fill-rule="nonzero" fill="#cfd8dc"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-scripts-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#546e7a" fill-rule="nonzero"/><path d="M18.466 20.241c.69 0 1.259-.568 1.259-1.258v-8.18H15.32a.632.632 0 0 0-.63.63v6.292h-1.887v-6.922c0-1.036.852-1.888 1.888-1.888h6.921c1.036 0 1.888.852 1.888 1.888v.63h-2.517v8.18a1.896 1.896 0 0 1-1.888 1.887h-6.292a1.896 1.896 0 0 1-1.888-1.888v-.629h6.293c0 .69.568 1.258 1.258 1.258z" fill-rule="nonzero" fill="#cfd8dc"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-src" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#4caf50" fill-rule="nonzero"/><g fill="#c8e6c9" transform="translate(2.065 -.225) scale(.70678)"><path d="M19.146 30.989a.902.902 0 0 1-.207-.025 1.045 1.045 0 0 1-.726-1.213l2.709-14.431c.049-.279.209-.525.444-.683a.891.891 0 0 1 .7-.122c.519.152.837.684.727 1.213L20.077 30.16a1.032 1.032 0 0 1-.442.681.895.895 0 0 1-.489.148zM24.578 28.944h-.068a.932.932 0 0 1-.668-.377 1.104 1.104 0 0 1 .1-1.419l4.658-4.553-4.638-4.239a1.105 1.105 0 0 1-.141-1.416.938.938 0 0 1 .661-.4.9.9 0 0 1 .709.237l5.47 5c.386.372.448.974.144 1.416a1.05 1.05 0 0 1-.142.163l-5.447 5.324a.913.913 0 0 1-.638.264zM16.423 28.947a.917.917 0 0 1-.639-.267l-5.452-5.327a.874.874 0 0 1-.132-.153 1.097 1.097 0 0 1 .141-1.414l5.471-5a.882.882 0 0 1 .7-.238.939.939 0 0 1 .665.4 1.104 1.104 0 0 1-.14 1.417L12.4 22.6l4.659 4.551c.377.382.42.988.1 1.419a.928.928 0 0 1-.669.377z" fill-rule="nonzero"/></g></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-src-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#4caf50"/><g fill="#c8e6c9" fill-rule="evenodd" transform="translate(2.064 -.224) scale(.70678)"><path d="M19.146 30.989a.902.902 0 0 1-.207-.025 1.045 1.045 0 0 1-.726-1.213l2.709-14.431c.049-.279.209-.525.444-.683a.891.891 0 0 1 .7-.122c.519.152.837.684.727 1.213L20.077 30.16a1.032 1.032 0 0 1-.442.681.895.895 0 0 1-.489.148zM24.578 28.944h-.068a.932.932 0 0 1-.668-.377 1.104 1.104 0 0 1 .1-1.419l4.658-4.553-4.638-4.239a1.105 1.105 0 0 1-.141-1.416.938.938 0 0 1 .661-.4.9.9 0 0 1 .709.237l5.47 5c.386.372.448.974.144 1.416a1.05 1.05 0 0 1-.142.163l-5.447 5.324a.913.913 0 0 1-.638.264zM16.423 28.947a.917.917 0 0 1-.639-.267l-5.452-5.327a.874.874 0 0 1-.132-.153 1.097 1.097 0 0 1 .141-1.414l5.471-5a.882.882 0 0 1 .7-.238.939.939 0 0 1 .665.4 1.104 1.104 0 0 1-.14 1.417L12.4 22.6l4.659 4.551c.377.382.42.988.1 1.419a.928.928 0 0 1-.669.377z" fill-rule="nonzero"/></g></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="folder-test" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#1de9b6" fill-rule="nonzero"/><path d="M14 8.097v1.39h.695v9.732A2.794 2.794 0 0 0 17.475 22a2.794 2.794 0 0 0 2.781-2.78V9.486h.695v-1.39H14m2.78 9.732c-.417 0-.695-.278-.695-.695 0-.417.278-.695.696-.695.417 0 .695.278.695.695 0 .417-.278.695-.695.695m1.39-2.78c-.417 0-.695-.278-.695-.696 0-.417.278-.695.695-.695.417 0 .695.278.695.695 0 .418-.278.696-.695.696m.695-3.476h-2.78V9.487h2.78v2.086z" fill="#00897b" fill-rule="nonzero"/></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="folder-test-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#1de9b6" fill-rule="nonzero"/><path d="M14 8.097v1.39h.695v9.732A2.794 2.794 0 0 0 17.475 22a2.794 2.794 0 0 0 2.781-2.78V9.486h.695v-1.39H14m2.78 9.732c-.417 0-.695-.278-.695-.695 0-.417.278-.695.696-.695.417 0 .695.278.695.695 0 .417-.278.695-.695.695m1.39-2.78c-.417 0-.695-.278-.695-.696 0-.417.278-.695.695-.695.417 0 .695.278.695.695 0 .418-.278.696-.695.696m.695-3.476h-2.78V9.487h2.78v2.086z" fill="#00897b" fill-rule="nonzero"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-tools" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#1e88e5" fill-rule="nonzero"/><path d="M21.043 15.266a1.07 1.07 0 0 1-1.07-1.07 1.07 1.07 0 0 1 1.07-1.071 1.07 1.07 0 0 1 1.07 1.07 1.07 1.07 0 0 1-1.07 1.071m-2.141-2.855a1.07 1.07 0 0 1-1.07-1.07 1.07 1.07 0 0 1 1.07-1.071 1.07 1.07 0 0 1 1.07 1.07 1.07 1.07 0 0 1-1.07 1.071m-3.569 0a1.07 1.07 0 0 1-1.07-1.07 1.07 1.07 0 0 1 1.07-1.071 1.07 1.07 0 0 1 1.07 1.07 1.07 1.07 0 0 1-1.07 1.071m-2.141 2.855a1.07 1.07 0 0 1-1.07-1.07 1.07 1.07 0 0 1 1.07-1.071 1.07 1.07 0 0 1 1.07 1.07 1.07 1.07 0 0 1-1.07 1.071m3.925-6.424a6.424 6.424 0 0 0-6.423 6.424 6.424 6.424 0 0 0 6.423 6.424 1.07 1.07 0 0 0 1.071-1.07c0-.28-.107-.53-.278-.715a1.105 1.105 0 0 1-.271-.713 1.07 1.07 0 0 1 1.07-1.071h1.263a3.569 3.569 0 0 0 3.57-3.569c0-3.154-2.877-5.71-6.425-5.71z" fill="#bbdefb" stroke-width=".714"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-tools-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#1e88e5"/><path d="M21.043 15.266a1.07 1.07 0 0 1-1.07-1.07 1.07 1.07 0 0 1 1.07-1.071 1.07 1.07 0 0 1 1.07 1.07 1.07 1.07 0 0 1-1.07 1.071m-2.141-2.855a1.07 1.07 0 0 1-1.07-1.07 1.07 1.07 0 0 1 1.07-1.071 1.07 1.07 0 0 1 1.07 1.07 1.07 1.07 0 0 1-1.07 1.071m-3.569 0a1.07 1.07 0 0 1-1.07-1.07 1.07 1.07 0 0 1 1.07-1.071 1.07 1.07 0 0 1 1.07 1.07 1.07 1.07 0 0 1-1.07 1.071m-2.141 2.855a1.07 1.07 0 0 1-1.07-1.07 1.07 1.07 0 0 1 1.07-1.071 1.07 1.07 0 0 1 1.07 1.07 1.07 1.07 0 0 1-1.07 1.071m3.925-6.424a6.424 6.424 0 0 0-6.423 6.424 6.424 6.424 0 0 0 6.423 6.424 1.07 1.07 0 0 0 1.071-1.07c0-.28-.107-.53-.278-.715a1.105 1.105 0 0 1-.271-.713 1.07 1.07 0 0 1 1.07-1.071h1.263a3.569 3.569 0 0 0 3.57-3.569c0-3.154-2.877-5.71-6.425-5.71z" fill="#bbdefb" stroke-width=".714"/></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="folder-views" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#ff8a65" fill-rule="nonzero"/><path d="M12.487 21.868L11.384 9.5H23.5l-1.104 12.366-4.961 1.375-4.948-1.373zm4.464-3.2l-3.926-2.36v-.855l3.926-2.361v1.323l-2.504 1.465 2.504 1.465v1.323zm.982-.001v-1.323l2.522-1.464-2.522-1.464v-1.323l3.926 2.35v.874l-3.926 2.35z" fill="#e44d26"/></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="folder-views-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#ff8a65" fill-rule="nonzero"/><path d="M12.487 21.868L11.384 9.5H23.5l-1.104 12.366-4.961 1.375-4.948-1.373zm4.464-3.2l-3.926-2.36v-.855l3.926-2.361v1.323l-2.504 1.465 2.504 1.465v1.323zm.982-.001v-1.323l2.522-1.464-2.522-1.464v-1.323l3.926 2.35v.874l-3.926 2.35z" fill="#e44d26"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-vscode" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#42a5f5" fill-rule="nonzero"/><path d="M20.811 8.52l-5.988 5.506-3.346-2.522-1.383.805 3.298 3.03-3.298 3.032 1.383.807 3.346-2.522 5.988 5.503 2.921-1.419V9.94zm0 3.622v6.396l-4.245-3.198z" fill="#bbdefb" stroke-width=".974"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-vscode-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#42a5f5" fill-rule="nonzero"/><path d="M20.81 8.52l-5.988 5.506-3.346-2.522-1.384.805 3.3 3.03-3.3 3.032 1.384.807 3.346-2.522 5.988 5.503 2.921-1.419V9.94zm0 3.621v6.397l-4.245-3.198z" fill="#bbdefb" stroke-width=".974"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-vue" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#009688" fill-rule="nonzero"/><g transform="translate(8.459 6.362) scale(.69572)"><path d="M1.821 4.15l10.21 17.618L22.239 4.235v-.084h-7.692l-2.434 4.178-2.422-4.178z" fill="#41b883"/><path d="M5.937 4.15l6.152 10.616 6.18-10.617h-3.722l-2.434 4.179-2.422-4.179z" fill="#35495e"/></g></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-vue-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#009688"/><g transform="translate(8.458 6.362) scale(.69572)"><path d="M1.821 4.15l10.21 17.618L22.239 4.235v-.084h-7.692l-2.434 4.178-2.422-4.178z" fill="#41b883"/><path d="M5.937 4.15l6.152 10.616 6.18-10.617h-3.722l-2.434 4.179-2.422-4.179z" fill="#35495e"/></g></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-webpack" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#03a9f4" fill-rule="nonzero"/><g transform="translate(9.192 7.48) scale(.66328)"><path d="M19.376 15.988l-7.708 4.45-7.709-4.45v-8.9l7.709-4.451 7.708 4.45z" fill="#fff" fill-opacity=".785"/><path d="M12.286 1.98c-.21 0-.41.059-.57.179l-7.9 4.44c-.32.17-.53.5-.53.88v9c0 .38.21.711.53.881l7.9 4.44c.16.12.36.18.57.18s.41-.06.57-.18l7.9-4.44c.32-.17.53-.5.53-.88v-9c0-.38-.21-.712-.53-.882l-7.9-4.44a.945.945 0 0 0-.57-.179zm0 2.15l7 3.94v2.103h-.016v5.177h.016v.54l-7 3.939-7-3.94V8.07zm0 2.08l-4.9 2.83 4.9 2.83 4.9-2.83zm-5 5.08v3.58l4 2.309v-3.58zm10 0l-4 2.308v3.58l4-2.308z" fill="#8ed6fb"/><path d="M12.286 6.21l-4.9 2.83 4.9 2.83 4.9-2.83zm-5 5.08v3.58l4 2.309v-3.58zm10 0l-4 2.308v3.58l4-2.308z" fill="#1c78c0"/></g></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-webpack-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#03a9f4"/><g transform="translate(9.193 7.48) scale(.66328)"><path d="M19.376 15.988l-7.708 4.45-7.709-4.45v-8.9l7.709-4.451 7.708 4.45z" fill="#fff" fill-opacity=".785"/><path d="M12.286 1.98c-.21 0-.41.059-.57.179l-7.9 4.44c-.32.17-.53.5-.53.88v9c0 .38.21.711.53.881l7.9 4.44c.16.12.36.18.57.18s.41-.06.57-.18l7.9-4.44c.32-.17.53-.5.53-.88v-9c0-.38-.21-.712-.53-.882l-7.9-4.44a.945.945 0 0 0-.57-.179zm0 2.15l7 3.94v2.103h-.016v5.177h.016v.54l-7 3.939-7-3.94V8.07zm0 2.08l-4.9 2.83 4.9 2.83 4.9-2.83zm-5 5.08v3.58l4 2.309v-3.58zm10 0l-4 2.308v3.58l4-2.308z" fill="#8ed6fb"/><path d="M12.286 6.21l-4.9 2.83 4.9 2.83 4.9-2.83zm-5 5.08v3.58l4 2.309v-3.58zm10 0l-4 2.308v3.58l4-2.308z" fill="#1c78c0"/></g></symbol><symbol viewBox="0 0 24 24" id="font" xmlns="http://www.w3.org/2000/svg"><path d="M9.62 12L12 5.67 14.37 12M11 3L5.5 17h2.25l1.12-3h6.25l1.13 3h2.25L13 3h-2z" fill="#f44336"/></symbol><symbol viewBox="0 0 500 500" id="fsharp" xmlns="http://www.w3.org/2000/svg"><path d="M235.906 36.66L21.963 250.601l213.943 213.943v-84.36L106.209 250.487l129.697-129.696z" fill="#378bba" stroke-width="14.706"/><path d="M235.906 156.614l-93.622 93.62 93.622 93.622z" fill="#378bba" stroke-width="15.006"/><path d="M263.417 36.64L477.36 250.583 263.417 464.526v-84.36l129.696-129.697-129.696-129.696z" fill="#30b9db" stroke-width="14.706"/></symbol><symbol viewBox="0 0 152.99 160.01" id="fusebox" xmlns="http://www.w3.org/2000/svg"><defs id="fkdefs4"><style id="fkstyle2">.fkcls-1{fill:#fff}.fkcls-2{fill:#515151}.fkcls-3{fill:#1d79bf}.fkcls-4{fill:#383838}</style></defs><title id="fktitle6">Asset 3</title><g id="fkLayer_2" data-name="Layer 2" transform="matrix(.87285 0 0 .87285 10.17 10.175)"><g id="fkFuse_Box" data-name="Fuse Box"><g id="fkLOGO"><path class="fkcls-1" id="fkpolygon8" fill="#fff" d="M76.56 2.19l74.22 24.93-7.7 87.77-65.41 42.66-69.79-43.93-5.7-86.13z"/><path class="fkcls-2" d="M77.69 160L5.87 114.81 0 26 76.55 0 153 25.67l-7.94 90.4zM9.88 112.43l67.77 42.66 63.45-41.39 7.47-85.13-72-24.18L4.36 28.95z" id="fkpath10" fill="#515151"/><path class="fkcls-3" id="fkpolygon12" fill="#1d79bf" d="M76.4 148.8V61.68l66.93-29.82-5.99 78.77z"/><path id="fkF" class="fkcls-4" fill="#383838" d="M76.4 148.8l-60.35-37.39L9.63 31.8 76.4 61.68z"/><path class="fkcls-1" d="M25.58 52.73l.54 15.93 37.35 18.18.12 14.69-37-18.21 1.64 37.1-14.56-9-5.05-80.55 67.79 30.82v15.46z" id="fkpath15" fill="#fff"/><path class="fkcls-1" d="M135.91 90.77c-.08 13.12-6.33 26.59-16.77 33.12l-42.8 27.93V61.71l42.27-18.84c5.16-2.41 9.51-1.43 12.4 3.11 1.9 3 2.89 7.23 2.86 12.21A35.69 35.69 0 0 1 129.34 76c4.29 2 6.66 6.55 6.57 14.77zM123 63.76c0-4.64-2-6.93-4.92-5.45l-29 14.48L89 90l29.44-15.59c2.5-1.32 4.56-5.91 4.56-10.65zM125.15 96c0-5.71-2.42-8.24-6.55-5.93L89 106.64v19.58l29.34-17.46c4.43-2.64 6.79-7.27 6.81-12.76z" id="fkpath17" fill="#fff"/><path id="fkTOP" class="fkcls-4" fill="#383838" d="M76.4 8.82L9.71 31.77l109.77 2.38-84.02 9.21L76.4 61.68l20.76-9.25-27.73-1.37 49.78-8.46 24.12-10.74z"/></g></g></g></symbol><symbol viewBox="0 0 24 24" id="git" xmlns="http://www.w3.org/2000/svg"><path d="M2.6 10.59L8.38 4.8l1.69 1.7c-.24.85.15 1.78.93 2.23v5.54c-.6.34-1 .99-1 1.73a2 2 0 0 0 2 2 2 2 0 0 0 2-2c0-.74-.4-1.39-1-1.73V9.41l2.07 2.09c-.07.15-.07.32-.07.5a2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0-2-2c-.18 0-.35 0-.5.07L13.93 7.5a1.98 1.98 0 0 0-1.15-2.34c-.43-.16-.88-.2-1.28-.09L9.8 3.38l.79-.78c.78-.79 2.04-.79 2.82 0l7.99 7.99c.79.78.79 2.04 0 2.82l-7.99 7.99c-.78.79-2.04.79-2.82 0L2.6 13.41c-.79-.78-.79-2.04 0-2.82z" fill="#e64a19"/></symbol><symbol viewBox="0 0 494 455" id="gitlab" xmlns="http://www.w3.org/2000/svg"><title>logo</title><defs><path id="fma" d="M0 1173.3h2000V0H0v1173.3z"/></defs><g transform="matrix(.88256 0 0 -.88256 -286.767 742.766)" fill="none" fill-rule="evenodd"><mask id="fmb" fill="#fff"><use width="100%" height="100%" xlink:href="#fma"/></mask><g><g transform="translate(358.67 358.67)"><path d="M492.532 195.445l-27.559 84.815-54.617 168.1c-2.81 8.648-15.045 8.648-17.856 0l-54.619-168.1h-181.37l-54.62 168.1c-2.81 8.648-15.045 8.648-17.856 0l-54.617-168.1-27.557-84.815a18.775 18.775 0 0 1 6.82-20.992l238.51-173.29 238.51 173.29a18.777 18.777 0 0 1 6.82 20.992" fill="#fc6d26"/><path d="M247.2 1.16l90.684 279.1h-181.37z" fill="#e24329"/><path d="M247.201 1.16l-90.684 279.09H29.427z" fill="#fc6d26"/><path d="M29.422 280.256L1.862 195.44a18.774 18.774 0 0 1 6.822-20.991L247.194 1.16z" fill="#fca326"/><path d="M29.422 280.26h127.09l-54.619 168.1c-2.81 8.65-15.047 8.65-17.856 0z" fill="#e24329"/><path d="M247.2 1.16l90.684 279.09h127.09z" fill="#fc6d26"/><path d="M464.98 280.256l27.559-84.815a18.774 18.774 0 0 0-6.821-20.991L247.208 1.16z" fill="#fca326"/><path d="M464.97 280.26H337.88l54.619 168.1c2.81 8.65 15.047 8.65 17.856 0z" fill="#e24329"/></g></g></g></symbol><symbol viewBox="0 0 24 24" id="go" xmlns="http://www.w3.org/2000/svg"><path d="M10.575 1.695c-2.634 0-4.756 2.453-4.756 5.502v4.6l-.027-.003v4.71c0 3.05 2.123 5.502 4.757 5.502h2.286c2.634 0 4.757-2.453 4.757-5.502v-4.6a5.1 5.1 0 0 0 .026.003v-4.71c0-3.049-2.122-5.502-4.756-5.502h-2.287z" fill="#73cddc"/><rect width="2.289" height="3.335" x="-1.178" y="6.092" ry="1.125" transform="matrix(.4849 -.87457 .85979 .51065 0 0)" fill="#73cddc"/><rect width="2.297" height="3.39" x="10.261" y="-15.076" ry="1.143" transform="matrix(.44646 .8948 -.89204 .45195 0 0)" fill="#73cddc"/><circle cx="9.267" cy="5.13" r="2.054" fill="#fff" stroke="#5e5d5b" stroke-width=".1"/><circle cx="14.214" cy="5.116" r="2.054" fill="#fff" stroke="#5e5d5b" stroke-width=".1"/><ellipse cx="8.039" cy="5.051" rx=".792" ry=".901" fill="#030d18"/><path d="M11.792 9.556l.763.138a.403.689 0 0 1 .008.138.403.689 0 0 1-.402.69.403.689 0 0 1-.404-.69.403.689 0 0 1 .035-.276z" fill="#fff" stroke="#fff" stroke-width=".155"/><ellipse cx="8.51" cy="5.365" rx=".138" ry=".166" fill="#fff"/><ellipse cx="12.945" cy="5.189" rx=".792" ry=".901" fill="#030d18"/><ellipse cx="13.414" cy="5.446" rx=".138" ry=".166" fill="#fff"/><ellipse cx="-12.982" cy="-3.409" rx=".708" ry="1.026" transform="rotate(-129.403)" fill="#f6d2a1" stroke-width=".4"/><path d="M11.772 9.553l-.757.135a.4.672 0 0 0-.008.135.4.672 0 0 0 .4.672.4.672 0 0 0 .4-.672.4.672 0 0 0-.035-.27z" fill="#fff" stroke="#fff" stroke-width=".153"/><ellipse cx="1.841" cy="-21.563" rx=".707" ry="1.026" transform="scale(1 -1) rotate(50.597)" fill="#f6d2a1" stroke-width=".4"/><ellipse cx="-17.281" cy="-21.784" rx=".864" ry="1.27" transform="matrix(.3054 -.95222 -.97065 -.2405 0 0)" fill="#f6d2a1" stroke-width=".4"/><ellipse cx="22.885" cy="2.587" rx=".864" ry="1.27" transform="matrix(.22652 .974 .95652 -.29167 0 0)" fill="#f6d2a1" stroke-width=".4"/><path d="M10.708 8.392a.594.594 0 0 0-.594.597v.115c0 .331.264.598.594.598h.386a.973.772 0 0 1 .697-.235.973.772 0 0 1 .698.235h.334c.33 0 .594-.267.594-.598V8.99a.595.595 0 0 0-.594-.597h-2.115z" fill="#f6d2a1" stroke="#657075" stroke-width=".1"/><ellipse cx="11.734" cy="8.203" rx="1.208" ry=".68" fill="#030d18" stroke="#fff" stroke-width=".162"/></symbol><symbol viewBox="0 0 24 24" id="gradle" xmlns="http://www.w3.org/2000/svg"><path d="M21.718 5.503c-.731-1.315-2.04-1.708-2.963-1.727-1.133-.023-2.065.605-1.888 1.017.037.088.25.55.38.741.19.275.527.064.646 0 .353-.187.73-.248 1.16-.198.409.048.954.3 1.319 1.001.859 1.652-1.794 5.05-5.114 2.697-3.32-2.353-6.548-1.574-8.01-1.1-1.462.475-2.135.952-1.556 2.055.785 1.498.524 1.038 1.285 2.28 1.21 1.97 3.856-.908 3.856-.908-1.972 2.906-3.662 2.204-4.31 1.188a15.864 15.864 0 0 1-1.038-1.97c-4.993 1.76-3.642 9.534-3.642 9.534h2.48c.632-2.862 2.892-2.757 3.28 0h1.892c1.673-5.59 5.914 0 5.914 0h2.466c-.69-3.812 1.388-5.01 2.697-7.246 1.31-2.235 2.551-4.969 1.146-7.364zm-6.362 7.362c-1.304-.426-.837-1.723-.837-1.723s1.139.368 2.68.87c-.09.403-.856 1.175-1.843.853z" fill="#0097a7" stroke-width=".47"/></symbol><symbol preserveAspectRatio="xMidYMid" viewBox="0 0 300 300" id="graphcool" xmlns="http://www.w3.org/2000/svg"><path d="M246.886 107.727c-12.237-6.892-27.616 2.1-30.081 3.646l-52.834 29.965c-7.8-6.196-18.914-5.933-26.412.625-7.499 6.558-9.24 17.537-4.14 26.094 5.102 8.556 15.588 12.246 24.923 8.768 9.335-3.478 14.852-13.129 13.111-22.937l52.688-29.9.321-.196c3.464-2.188 11.5-5.462 15.256-3.34 2.706 1.524 4.252 6.629 4.376 14.148h-.066v66.092a17.313 17.313 0 0 1-8.635 14.95l-75.739 43.755a17.312 17.312 0 0 1-17.261 0l-75.74-43.756a17.312 17.312 0 0 1-8.634-14.95V113.22c.01-6.165 3.3-11.86 8.634-14.95l68.549-39.562c6.522 7.482 17.451 9.25 26 4.206s12.283-15.468 8.886-24.794c-3.397-9.327-12.962-14.904-22.751-13.27-9.79 1.636-17.022 10.02-17.204 19.944L59.397 85.632a31.932 31.932 0 0 0-15.978 27.588v87.454a31.933 31.933 0 0 0 15.927 27.602l75.74 43.755a31.934 31.934 0 0 0 31.846 0l75.74-43.755a31.933 31.933 0 0 0 15.927-27.58V137.12h.05c.373-14.913-3.616-24.794-11.762-29.389z" fill="#27ae60" stroke="#27ae60" stroke-width="7.883622079999999"/></symbol><symbol viewBox="0 0 400 400" id="graphql" xmlns="http://www.w3.org/2000/svg"><path d="M67.008 293.022l-13.143-7.588L200.282 31.839l13.143 7.588z" fill="#ec407a" stroke-width="6.803" stroke="#ec407a"/><path d="M50.855 265.174H343.69v15.177H50.855z" fill="#ec407a" stroke-width="6.803" stroke="#ec407a"/><path d="M203.122 358.269L56.649 273.7l7.589-13.143 146.472 84.568zm127.24-220.407L183.889 53.293l7.589-13.143 146.472 84.568z" fill="#ec407a" stroke-width="6.803" stroke="#ec407a"/><path d="M64.278 137.803l-7.588-13.142 146.472-84.568 7.588 13.143z" fill="#ec407a" stroke-width="6.803" stroke="#ec407a"/><path d="M327.661 293.025L181.244 39.43l13.143-7.589 146.417 253.596zM62.466 114.597h15.176v169.136H62.466zm254.528 0h15.176v169.136h-15.176z" fill="#ec407a" stroke-width="6.803" stroke="#ec407a"/><path d="M200.538 351.845l-6.628-11.481L321.3 266.812l6.629 11.48z" fill="#ec407a" stroke-width="6.803" stroke="#ec407a"/><path d="M352.284 288.67c-8.777 15.268-28.342 20.48-43.61 11.703-15.268-8.777-20.48-28.342-11.703-43.61 8.777-15.268 28.342-20.48 43.61-11.703 15.36 8.869 20.57 28.342 11.703 43.61M97.574 141.567c-8.778 15.268-28.343 20.48-43.61 11.703-15.269-8.777-20.48-28.342-11.703-43.61 8.777-15.268 28.342-20.48 43.61-11.703 15.268 8.869 20.479 28.342 11.702 43.61M42.353 288.67c-8.777-15.268-3.566-34.741 11.702-43.61 15.268-8.776 34.741-3.565 43.61 11.703 8.776 15.268 3.565 34.741-11.703 43.61-15.36 8.776-34.833 3.565-43.61-11.703m254.71-147.103c-8.776-15.268-3.565-34.741 11.703-43.61 15.268-8.776 34.742-3.565 43.61 11.703 8.777 15.268 3.566 34.741-11.702 43.61-15.268 8.776-34.833 3.565-43.61-11.703m-99.745 236.608c-17.645 0-31.907-14.262-31.907-31.907s14.262-31.907 31.907-31.907 31.907 14.262 31.907 31.907c0 17.554-14.262 31.907-31.907 31.907m0-294.206c-17.645 0-31.907-14.262-31.907-31.907s14.262-31.907 31.907-31.907 31.907 14.262 31.907 31.907-14.262 31.907-31.907 31.907" fill="#ec407a" stroke-width="6.803" stroke="#ec407a"/></symbol><symbol viewBox="0 0 24 24" id="groovy" xmlns="http://www.w3.org/2000/svg"><path d="M12 1.982a10.119 10.119 0 0 0-10.12 10.12A10.119 10.119 0 0 0 12 22.22 10.119 10.119 0 0 0 22.12 12.1 10.119 10.119 0 0 0 12 1.983zm1.254 2.422c.91 0 1.647.261 2.213.78.571.518.857 1.188.857 2.013 0 .889-.319 1.673-.959 2.35-.64.677-1.376 1.015-2.207 1.015-.486 0-.89-.119-1.213-.357-.317-.238-.476-.532-.476-.88 0-.212.06-.4.181-.563.127-.164.274-.246.438-.246.159 0 .238.092.238.277 0 .164.06.29.182.38.121.09.261.136.42.136.423 0 .828-.29 1.215-.866.391-.582.587-1.202.587-1.863 0-.465-.151-.844-.453-1.135-.301-.296-.69-.445-1.166-.445-.714 0-1.406.318-2.078.953-.666.635-1.211 1.47-1.635 2.506-.417 1.031-.627 2.014-.627 2.945 0 .857.185 1.54.555 2.047.37.503.863.754 1.477.754 1.037 0 2.027-.734 2.974-2.2l1.493-.212c.185-.026.277.018.277.135 0 .053-.072.28-.215.681-.143.402-.337 1.074-.586 2.016.82-.476 1.455-1.003 1.904-1.58v.914c-.36.418-1.046.888-2.062 1.412-.212 1.407-.682 2.493-1.406 3.26-.725.772-1.54 1.16-2.444 1.16-.433 0-.775-.102-1.023-.303-.243-.2-.365-.477-.365-.832 0-.984.955-1.94 2.865-2.865.2-.714.395-1.356.586-1.928-.333.482-.817.907-1.451 1.278-.635.37-1.225.554-1.77.554-.889 0-1.628-.383-2.22-1.15-.588-.772-.881-1.748-.881-2.928 0-1.243.333-2.42 1-3.531a7.747 7.747 0 0 1 2.625-2.674c1.084-.672 2.134-1.008 3.15-1.008zM12.03 16.592c-1.375.687-2.062 1.365-2.062 2.031 0 .354.169.533.508.533.666 0 1.184-.856 1.554-2.564z" fill="#26c6da"/></symbol><symbol viewBox="0 0 24 24" id="gulp" xmlns="http://www.w3.org/2000/svg"><path d="M8.37 15.94a596.238 596.238 0 0 1-.482-4.982c.002-.042-.225-.077-.505-.077h-.508V8.95h3.966V5.198l1.871-1.124c1.14-.685 1.978-1.125 2.144-1.125.4 0 .866.506.866.939 0 .19-.057.422-.127.517-.07.095-.722.53-1.45.966l-1.321.792-.029 1.393-.028 1.393h3.972v1.932h-.98l-.495 4.983-.495 4.983H8.854l-.485-4.906z" fill="#e53935"/></symbol><symbol viewBox="0 0 24 24" id="h" xmlns="http://www.w3.org/2000/svg"><path d="M16.745 19.818h-3.007v-5.882q0-2.381-1.736-2.381-.869 0-1.438.663-.56.662-.56 1.718v5.882H6.988V4.533h3.016v6.508h.037q1.186-1.802 3.193-1.802 3.511 0 3.511 4.239z" stroke-width=".478" fill="#0277bd"/></symbol><symbol viewBox="0 0 253.6 253.6" id="hack" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-29.243 -29.515) scale(1.2301)"><path fill="#607d8b" d="M69.496 159.551v52.576l51.77-52.576zM123.507 41.523l-54.01 52.755v55.084l54.01-54.009z"/><path fill="#eceff1" d="M130.023 95.663v51.501l52.128-51.5z"/><path fill="#607d8b" d="M185.465 101.867l-55.442 55.174v55.083l55.442-55.262z"/><path fill="#ffa000" d="M73.068 154.283l50.427.09v-50.248z"/></g></symbol><symbol viewBox="0 0 300 300.00001" id="haml" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 165.6)"><path d="M78.42-132.307c-12.047-.302-26.924 5.998-26.924 5.998l49.195 99.791L74.605 85.005c23.81 20.134 50.07 10.504 50.07 10.504L136.76 9.212c1.526 1.446 3.146 2.77 4.777 3.995 5.244 3.714 10.925 6.553 16.606 8.738 5.68 2.185 11.583 3.933 17.482 5.244 3.933.874 7.645 1.53 11.578 1.967-1.748 3.933-2.84 8.083-2.621 12.672 0 .437.22.873.656 1.092h.217c4.152 2.185 8.521 3.934 13.328 5.027 4.589.874 9.615 1.312 14.422.656 5.026-.655 10.051-2.623 13.984-5.9 3.933-3.278 6.774-7.648 8.522-12.237l.219-.218v-.217l.656-5.899v-.22c2.185-1.311 4.37-2.621 6.555-4.37 2.622-2.184 5.025-4.589 6.773-7.648 1.748-3.059 2.84-6.774 2.621-10.488-.218-3.496-1.53-6.99-3.06-10.049-1.53-3.059-3.495-5.901-5.68-8.523-4.37-5.026-9.614-9.176-15.295-12.454-5.462-3.496-11.581-6.338-17.7-8.304l-2.404-.656-1.962-.655c-1.311-.437-2.406-1.092-3.498-1.53-2.185-1.31-3.717-2.622-4.809-4.37-2.185-3.278-2.403-8.301-1.31-13.545.218-1.311.656-2.623 1.093-3.934a96.064 96.064 0 0 0 1.31-4.152c.314-1.412.51-2.829.598-4.402l29.203-25.553c-2.275-8.404-27.488-17.158-27.488-17.158l-74.931 63.726-43.243-81.584c-1.553-.35-3.218-.527-4.94-.57zm107.682 73.14c-.449 2.336-.647 4.795-.647 7.258.219 3.715 1.311 7.87 3.715 11.366 2.403 3.496 5.68 6.117 8.957 7.646a29.663 29.663 0 0 0 5.027 1.967l2.623.654 2.184.438c5.68 1.53 11.142 3.714 16.168 6.554 5.025 2.84 9.833 6.337 13.766 10.27s6.992 8.959 7.43 13.984c.218 3.496-.22 6.118-1.313 8.303-1.093 2.404-2.84 4.588-4.807 6.555-.874.874-1.966 1.747-2.84 2.402a27.11 27.11 0 0 0-.654-5.898c-.219-1.093-.438-1.966-.875-3.059-.437-.874-.872-1.966-1.965-2.621-.218 0-.44-.001-.44.217-1.31 3.277-3.494 6.12-5.898 8.086-2.403 1.966-5.462 2.84-8.521 3.058-3.06.219-6.338-.436-9.616-1.31-3.277-.874-6.552-1.968-9.83-3.06l-.439-.22c-.656-.218-1.526.002-1.963.44-1.748 2.185-3.06 4.149-4.59 6.334a58.435 58.435 0 0 0-2.84 5.027c-3.933-1.53-7.649-2.841-11.582-4.37-5.462-2.186-10.925-4.37-15.95-6.991-5.245-2.404-10.268-5.246-14.638-8.524-3.15-2.363-6.062-4.845-8.185-7.681l2.404-17.172z" fill="#f4511e" stroke-width="0" stroke-linejoin="round"/></g></symbol><symbol viewBox="0 0 24 24" id="handlebars" xmlns="http://www.w3.org/2000/svg"><path d="M8.55 10.32c-2.753 0-4.202 3.48-5.793 3.48-.98 0-1.126-.677-1.126-.915 0-.332.236-.706.564-.706.59 0 .414.77.414.77s.798-.555.272-1.298c-.42-.595-1.31-.623-1.92-.17-.617.458-1.057 1.146-.853 2.287.1.551.468 1.35 1.233 1.805.764.455 1.925.566 2.335.566 2.194 0 4.342-1.633 6.639-2.322a5.513 5.513 0 0 1 1.497-.222 6.19 6.19 0 0 1 1.92.226c2.296.689 4.444 2.323 6.638 2.323.41 0 1.57-.11 2.335-.566.765-.455 1.132-1.256 1.231-1.807.204-1.14-.235-1.829-.853-2.287-.61-.453-1.497-.423-1.918.172-.526.743.27 1.297.27 1.297s-.176-.77.414-.77c.329 0 .565.373.565.705 0 .238-.147.914-1.126.914-1.592 0-3.04-3.478-5.794-3.478-2.565 0-3.076 1.177-3.462 1.718-.004.005-.005.011-.008.016-.005-.006-.007-.013-.012-.02-.386-.54-.896-1.717-3.461-1.717z" fill="#ff7043" fill-rule="evenodd" stroke-width=".3"/></symbol><symbol viewBox="0 0 300.00001 300" id="haskell" xmlns="http://www.w3.org/2000/svg"><g stroke-width="2.422"><path d="M23.928 240.5l59.94-89.852-59.94-89.855h44.955l59.94 89.855-59.94 89.852z" fill="#ef5350"/><path d="M83.869 240.5l59.94-89.852-59.94-89.855h44.955l119.88 179.71h-44.95l-37.46-56.156-37.468 56.156z" fill="#ffa726"/><path d="M228.72 188.08l-19.98-29.953h69.93v29.956h-49.95zm-29.97-44.924l-19.98-29.953h99.901v29.953z" fill="#ffee58"/></g></symbol><symbol viewBox="0 0 210 210" id="haxe" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -87)"><path fill="#f68712" stroke-width=".221" d="M42.78 191.545l63.431-63.43 63.431 63.43-63.431 63.431z"/><path d="M42.8 191.592L31.193 148.28 19.59 104.97 62.9 116.575l43.311 11.605-31.706 31.706z" fill="#fab20b" stroke-width=".266"/><path d="M105.956 128.111l-43.19-11.544-43.177-11.597 22.927.185 23.228.294 20.264 11.36z" fill="#fbc707" stroke-width=".265"/><path d="M19.59 104.97l11.596 43.176 11.545 43.19-11.303-19.948-11.36-20.263-.294-23.228z" fill="#fff200" stroke-width=".265"/><path d="M106.23 128.133l43.312-11.605 43.311-11.605-11.605 43.31-11.605 43.312-31.706-31.706z" fill="#f47216" stroke-width=".266"/><path d="M169.711 191.289l11.545-43.19 11.597-43.176-.185 22.927-.294 23.228-11.36 20.263z" fill="#f1471d" stroke-width=".265"/><path d="M192.853 104.923l-43.176 11.597-43.19 11.544 19.947-11.303 20.264-11.36 23.228-.293z" fill="#fbc707" stroke-width=".265"/><path d="M169.643 191.545l11.605 43.31 11.605 43.312-43.311-11.605-43.311-11.606 31.706-31.705z" fill="#f25c19" stroke-width=".266"/><path d="M106.487 255.025l43.19 11.544 43.176 11.598-22.927-.185-23.228-.294-20.264-11.36z" fill="#f68712" stroke-width=".265"/><path d="M192.853 278.167l-11.597-43.176-11.545-43.19 11.303 19.947 11.36 20.264.294 23.228z" fill="#f1471d" stroke-width=".265"/><path d="M106.211 254.976l-43.31 11.605-43.312 11.605 11.605-43.31L42.8 191.563l31.706 31.706z" fill="#f89c0e" stroke-width=".266"/><path d="M42.731 191.82l-11.545 43.19-11.597 43.176.185-22.927.294-23.228 11.36-20.263z" fill="#fff200" stroke-width=".265"/><path d="M19.59 278.186l43.175-11.597 43.19-11.544-19.947 11.303-20.264 11.36-23.228.293z" fill="#f25c19" stroke-width=".265"/></g></symbol><symbol viewBox="0 0 144 152" id="heroku" xmlns="http://www.w3.org/2000/svg"><path d="M118.68 13.279H26.865c-6.337 0-11.476 5.139-11.476 11.476V129.32c0 6.338 5.139 11.477 11.476 11.477h91.813c6.338 0 11.477-5.14 11.477-11.477V24.755c0-6.337-5.139-11.476-11.477-11.476zM44.08 121.669V96.165l14.346 12.752zm44.632 0v-38.08c-.063-2.976-1.496-6.551-7.97-6.551-12.966 0-27.51 6.52-27.654 6.586l-9.008 4.08V32.407h12.752v36.201c6.366-2.072 15.266-4.321 23.91-4.321 7.882 0 12.6 3.099 15.17 5.698 5.484 5.547 5.56 12.613 5.551 13.43v38.255zm3.188-68.54H79.149c5.011-6.576 8.158-13.496 9.564-20.723h12.751c-.86 7.243-3.796 14.187-9.563 20.722z" fill="#6963b9"/></symbol><symbol viewBox="0 0 24 24" id="hpp" xmlns="http://www.w3.org/2000/svg"><path d="M9.757 19.818H6.751v-5.882q0-2.381-1.737-2.381-.868 0-1.438.663-.56.662-.56 1.718v5.882H0V4.533h3.016v6.508h.037Q4.24 9.239 6.247 9.239q3.51 0 3.51 4.239z" stroke-width=".478" fill="#0277bd"/><path d="M13.073 11.448v2h-2v2h2v2h2v-2h2v-2h-2v-2zm7 0v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#0277bd"/></symbol><symbol viewBox="0 0 24 24" id="html" xmlns="http://www.w3.org/2000/svg"><path d="M12 17.56l4.07-1.13.55-6.1H9.38L9.2 8.3h7.6l.2-1.99H7l.56 6.01h6.89l-.23 2.58-2.22.6-2.22-.6-.14-1.66h-2l.29 3.19L12 17.56M4.07 3h15.86L18.5 19.2 12 21l-6.5-1.8L4.07 3z" fill="#e44d26"/></symbol><symbol viewBox="0 0 24 24" id="http" xmlns="http://www.w3.org/2000/svg"><path d="M16.046 13.784c.074-.613.13-1.225.13-1.856s-.056-1.244-.13-1.856h3.137c.148.594.241 1.215.241 1.856a7.65 7.65 0 0 1-.241 1.856m-4.78 5.16c.557-1.03.984-2.144 1.281-3.304h2.738a7.452 7.452 0 0 1-4.019 3.304m-.232-5.16H9.828a12.314 12.314 0 0 1-.149-1.856c0-.631.056-1.253.149-1.856h4.343c.084.603.149 1.225.149 1.856 0 .63-.065 1.243-.149 1.856M12 19.315c-.77-1.113-1.393-2.348-1.773-3.675h3.545c-.38 1.327-1.002 2.562-1.773 3.675m-3.712-11.1h-2.71a7.353 7.353 0 0 1 4.01-3.304c-.557 1.03-.975 2.144-1.3 3.304m-2.71 7.425h2.71c.325 1.16.743 2.274 1.3 3.304a7.433 7.433 0 0 1-4.01-3.304m-.761-1.856a7.65 7.65 0 0 1-.241-1.856c0-.64.093-1.262.241-1.856h3.137c-.074.612-.13 1.225-.13 1.856 0 .63.056 1.243.13 1.856m4.046-9.253c.77 1.114 1.393 2.357 1.773 3.684h-3.545c.38-1.327 1.002-2.57 1.773-3.684m6.422 3.684h-2.738a14.523 14.523 0 0 0-1.28-3.304 7.412 7.412 0 0 1 4.018 3.304m-6.423-5.568c-5.132 0-9.28 4.176-9.28 9.28a9.28 9.28 0 0 0 9.28 9.282 9.28 9.28 0 0 0 9.281-9.281A9.28 9.28 0 0 0 12 2.647z" fill="#e53935" stroke-width=".928"/></symbol><symbol viewBox="0 0 24 24" id="image" xmlns="http://www.w3.org/2000/svg"><path d="M13.009 9.202h5.368l-5.368-5.368v5.368M6.177 2.37h7.808l5.856 5.856v11.711a1.952 1.952 0 0 1-1.952 1.952H6.178a1.951 1.951 0 0 1-1.952-1.952V4.322c0-1.083.868-1.952 1.952-1.952m0 17.567h11.71V12.13l-3.903 3.903-1.952-1.951-5.856 5.855M8.13 9.202a1.952 1.952 0 0 0-1.952 1.952 1.952 1.952 0 0 0 1.952 1.952 1.952 1.952 0 0 0 1.952-1.952A1.952 1.952 0 0 0 8.13 9.202z" fill="#26a69a" stroke-width=".976"/></symbol><symbol viewBox="0 0 512 512" id="ionic" xmlns="http://www.w3.org/2000/svg"><g fill="#4f8ff7"><path d="M423.592 132.804A31.855 31.855 0 0 0 429 115c0-17.675-14.33-32-32-32a31.853 31.853 0 0 0-17.805 5.409C344.709 63.015 302.11 48 256 48 141.125 48 48 141.125 48 256c0 114.877 93.125 208 208 208 114.873 0 208-93.123 208-208 0-46.111-15.016-88.71-40.408-123.196zM391.83 391.832c-17.646 17.646-38.191 31.499-61.064 41.174-23.672 10.012-48.826 15.089-74.766 15.089-25.94 0-51.095-5.077-74.767-15.089-22.873-9.675-43.417-23.527-61.064-41.174s-31.5-38.191-41.174-61.064C68.982 307.096 63.905 281.94 63.905 256c0-25.94 5.077-51.095 15.089-74.767 9.674-22.873 23.527-43.417 41.174-61.064s38.191-31.5 61.064-41.174c23.673-10.013 48.828-15.09 74.768-15.09 25.939 0 51.094 5.077 74.766 15.089a191.221 191.221 0 0 1 37.802 21.327A31.853 31.853 0 0 0 365 115c0 17.675 14.327 32 32 32 5.293 0 10.28-1.293 14.678-3.568a191.085 191.085 0 0 1 21.327 37.801c10.013 23.672 15.09 48.827 15.09 74.767 0 25.939-5.077 51.096-15.09 74.768-9.675 22.873-23.527 43.418-41.175 61.064z"/><circle cx="256.003" cy="256" r="96"/></g></symbol><symbol viewBox="0 0 24 24" id="java" xmlns="http://www.w3.org/2000/svg"><path d="M2 21h18v-2H2M20 8h-2V5h2m0-2H4v10a4 4 0 0 0 4 4h6a4 4 0 0 0 4-4v-3h2a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z" fill="#f44336"/></symbol><symbol viewBox="0 0 24 24" id="javascript" xmlns="http://www.w3.org/2000/svg"><path d="M3 3h18v18H3V3m4.73 15.04c.4.85 1.19 1.55 2.54 1.55 1.5 0 2.53-.8 2.53-2.55v-5.78h-1.7V17c0 .86-.35 1.08-.9 1.08-.58 0-.82-.4-1.09-.87l-1.38.83m5.98-.18c.5.98 1.51 1.73 3.09 1.73 1.6 0 2.8-.83 2.8-2.36 0-1.41-.81-2.04-2.25-2.66l-.42-.18c-.73-.31-1.04-.52-1.04-1.02 0-.41.31-.73.81-.73.48 0 .8.21 1.09.73l1.31-.87c-.55-.96-1.33-1.33-2.4-1.33-1.51 0-2.48.96-2.48 2.23 0 1.38.81 2.03 2.03 2.55l.42.18c.78.34 1.24.55 1.24 1.13 0 .48-.45.83-1.15.83-.83 0-1.31-.43-1.67-1.03l-1.38.8z" fill="#ffca28"/></symbol><symbol viewBox="0 0 24 24" id="javascript-map" xmlns="http://www.w3.org/2000/svg"><path d="M18 8v2h2v10H10v-2H8v4h14V8h-4z" fill="#ffca28"/><path d="M2.444 2.506h14.135v14.136H2.444V2.506m3.714 11.811c.315.668.935 1.218 1.995 1.218 1.178 0 1.987-.629 1.987-2.003V8.993H8.805v4.508c0 .675-.275.848-.707.848-.455 0-.644-.314-.856-.683l-1.084.651m4.697-.14c.392.769 1.185 1.358 2.426 1.358 1.257 0 2.199-.652 2.199-1.854 0-1.107-.636-1.602-1.767-2.089l-.33-.141c-.573-.243-.816-.408-.816-.801 0-.322.243-.573.636-.573.377 0 .628.165.856.573l1.028-.683c-.432-.754-1.044-1.045-1.884-1.045-1.186 0-1.948.754-1.948 1.752 0 1.083.636 1.594 1.594 2.002l.33.141c.613.267.974.432.974.888 0 .377-.354.652-.903.652-.652 0-1.029-.338-1.312-.81l-1.083.63z" fill="#ffca28"/></symbol><symbol viewBox="0 0 180 180" id="jenkins" xmlns="http://www.w3.org/2000/svg"><defs><clipPath id="gia"><path transform="scale(1 -1)" fill="#37474f" d="M.899-144.42h144.42V0H.899z"/></clipPath></defs><g transform="matrix(1.0691 0 0 -1.0691 9.4 166.143)" clip-path="url(#gia)"><g fill-rule="evenodd"><path d="M107.96 30.661l-12.506-1.876-16.883-1.876-10.943-.312-10.629.312-8.13 2.502-7.19 7.815-5.628 15.945-1.25 3.44-7.504 2.5-4.377 7.191-3.126 10.317 3.44 9.067 8.128 2.814 6.565-3.127 3.127-6.878 3.752.626 1.25 1.563-1.25 7.19-.313 9.068 1.876 12.505-.074 7.143 5.701 9.114 10.005 7.19 17.508 7.504 19.383-2.814 16.883-12.193 7.817-12.505 5.002-9.067 1.25-22.51-3.752-19.384-6.877-17.195-6.566-9.066" fill="#f0d6b7"/><path d="M97.334-23.425l-44.709-1.876v-7.503l3.752-26.262-1.876-2.19-31.264 10.63-2.19 3.752-3.126 35.328-7.19 21.26-1.563 5.002 25.01 17.195 7.818 3.127 6.877-8.441 5.94-5.315 6.88-2.188 3.125-.938L68.57 1.899l2.814-3.44 7.19 2.502-5.002-9.693 27.2-12.818-3.439-1.876" fill="#335061"/><path d="M23.238 85.687l8.128 2.814 6.566-3.127 3.127-6.878 3.751.626.938 3.751-1.876 7.19 1.876 17.197-1.563 9.379 5.627 6.565 12.193 9.692-3.44 4.69-17.194-8.442-7.191-5.627-4.064-8.754-6.253-8.442-1.876-10.005 1.251-10.63" fill="#6d6b6d"/><path d="M36.055 115.07s4.69 11.567 23.448 17.195c18.759 5.628.938 4.065.938 4.065l-20.321-7.817-7.817-7.816-3.438-6.253 7.19.626M26.676 87.875s-6.566 21.886 18.446 25.012l-.938 3.752-17.195-4.065-5.003-16.257 1.251-10.63 3.439 2.188" fill="#dcd9d8"/></g><g fill="#f7e4cd"><path d="M36.681 58.799l4.094 3.966s1.847-.214 2.16-2.402c.312-2.19 1.25-21.886 14.693-32.516 1.227-.97-10.004 1.564-10.004 1.564L37.62 45.042M94.209 64.739s.729 9.477 3.28 8.748c2.553-.729 2.553-3.28 2.553-3.28s-6.198-4.01-5.833-5.468" fill-rule="evenodd"/><path d="M120.16 99.442s-5.153-1.088-5.628-5.628c-.474-4.54 5.628-.938 6.566-.625M82.327 99.129s-6.879-.938-6.879-5.314c0-4.378 7.817-4.065 10.005-2.19"/><g fill-rule="evenodd"><path d="M39.807 78.808s-11.881 7.191-13.131.312c-1.25-6.877-4.065-11.88 1.876-19.07l-4.064 1.25-3.752 9.691-1.25 9.38 7.19 7.504 8.129-.626 4.69-3.751.312-4.69M45.435 98.504s5.315 27.512 32.203 32.827c22.136 4.375 33.765-.938 38.142-5.94 0 0-19.696 23.447-38.455 16.257-18.759-7.191-32.514-20.322-32.202-28.762.532-14.377.313-14.382.313-14.382M117.97 122.27s-9.066.312-9.38-7.817c0 0 0-1.25.625-2.5 0 0 7.192 8.129 11.568 3.751"/><path d="M78.268 111.1s-1.56 12.477-12.199 5.223c-6.878-4.69-6.252-11.255-5.002-12.505s.91-3.77 1.862-2.04c.952 1.728.638 7.356 4.078 8.918 3.439 1.564 9.077 3.31 11.26.404"/></g></g><g fill="#49728b" fill-rule="evenodd"><path d="M48.874 26.597L19.486 13.466s12.193-48.46 5.94-63.467l-4.377 1.563-.313 18.446-8.128 35.015-3.44 9.692 30.639 20.633 9.067-8.753M51.896-.206l4.17-5.087v-18.76h-5.003s-.625 13.132-.625 14.696c0 1.563.624 7.19.624 7.19M52-26.866l-14.069-.625 4.065-2.813L52-31.868"/></g><g fill-rule="evenodd"><path d="M100.15-23.739l11.567.313 2.814-28.764-11.881-1.563-2.5 30.014" fill="#335061"/><path d="M103.27-23.739l17.508.938s7.19 18.133 7.19 19.07c0 .939 6.253 26.263 6.253 26.263l-14.069 14.694-2.813 2.501-7.504-7.503V3.148l-6.565-26.887" fill="#335061"/><path d="M111.09-21.55l-10.942-2.188 1.563-8.755c4.064-1.876 10.943 3.127 10.943 3.127M111.4 33.162l21.885-16.257.626 7.503-16.57 15.32-5.94-6.566" fill="#49728b"/><path d="M62.85-85.332l-6.473 26.266-3.22 19.38-.531 14.385 29.296 1.56 18.226.003-1.658-32.83 2.814-25.324-.312-4.69-23.76-1.876-14.382 3.126" fill="#fff"/><path d="M96.083-23.426s-1.563-32.515 3.127-55.65c0 0-9.38-5.94-23.136-7.503l26.262.938 3.126 1.875-3.752 51.273-.938 10.944" fill="#dcd9d8"/><path d="M115.06-49.691l12.193 3.44 23.135 1.25 3.44 10.629-6.254 18.446-7.19.938-10.005-3.127-9.599-4.686-5.095.935-3.972-1.56" fill="#fff"/><path d="M114.84-43.435s8.128 3.751 9.38 3.438L120.78-22.8l4.065 1.563s2.814-16.257 2.814-18.133c0 0 17.507-.938 19.07-.938 0 0 3.752 7.191 2.814 14.694l3.44-10.005.312-5.628-5.002-7.503-5.627-1.25-9.38.312-3.126 4.064-10.943-1.563-3.44-1.25" fill="#dcd9d8"/></g><path d="M102.56-21.241L95.682-3.733l-7.19 10.317s1.562 4.377 3.75 4.377h7.192l6.878-2.501-.625-11.568-3.127-18.134" fill="#fff"/><path d="M103.9-15.297S95.145 1.585 95.145 4.086c0 0 1.563 3.752 3.752 2.814 2.19-.938 6.879-3.439 6.879-3.439v5.94l-10.63 2.19-7.19-.939 12.193-28.763 2.5-.313" fill="#dcd9d8" fill-rule="evenodd"/><path d="M65.664 25.968l-8.661.942-8.13 2.501v-2.814l3.972-4.38 12.506-5.627" fill="#fff"/><path d="M51.689 25.031s9.693-4.065 12.819-3.127l.311-3.748-8.752 1.872-5.316 3.752.938 1.251" fill="#dcd9d8" fill-rule="evenodd"/><path d="M115.03 9.897c-5.305.156-10.098.786-14.294 1.97.285 1.72-.249 3.408.18 4.647 1.17.843 3.13.83 4.898 1.027-1.529.752-3.677 1.049-5.44.615-.042 1.194-.578 1.934-.902 2.868 2.982 1.064 10.024 8.044 13.984 5.732 1.887-1.099 2.689-7.377 2.835-10.43.122-2.533-.23-5.088-1.261-6.43" fill="#d33833" fill-rule="evenodd"/><path d="M115.03 9.897c-5.305.156-10.098.786-14.294 1.97.285 1.72-.249 3.408.18 4.647 1.17.843 3.13.83 4.898 1.027-1.529.752-3.677 1.049-5.44.615-.042 1.194-.578 1.934-.902 2.868 2.982 1.064 10.024 8.044 13.984 5.732 1.887-1.099 2.689-7.377 2.835-10.43.122-2.533-.23-5.088-1.261-6.43z" fill="none" stroke="#d33833" stroke-width="2"/><path d="M89.66 18.569c-.014-.401-.03-.806-.047-1.21-1.656-1.089-4.33-1.076-6.148-1.99 2.68-.117 4.79-.763 6.614-1.672l-.118-3.033c-3.036-2.078-5.81-5.173-9.384-7.122-1.69-.922-7.622-3.294-9.42-2.875-1.017.236-1.109 1.499-1.516 2.689-.866 2.548-2.861 6.605-3.035 10.44-.222 4.846-.71 12.967 4.51 11.969 4.213-.804 9.113-2.745 12.375-4.527 1.993-1.09 3.146-2.436 6.17-2.669" fill="#d33833" fill-rule="evenodd"/><path d="M89.66 18.569c-.014-.401-.03-.806-.047-1.21-1.656-1.089-4.33-1.076-6.148-1.99 2.68-.117 4.79-.763 6.614-1.672l-.118-3.033c-3.036-2.078-5.81-5.173-9.384-7.122-1.69-.922-7.622-3.294-9.42-2.875-1.017.236-1.109 1.499-1.516 2.689-.866 2.548-2.861 6.605-3.035 10.44-.222 4.846-.71 12.967 4.51 11.969 4.213-.804 9.113-2.745 12.375-4.527 1.993-1.09 3.146-2.436 6.17-2.669z" fill="none" stroke="#d33833" stroke-width="2"/><path d="M92.675 12.788c-.463 2.64-.999 3.393-.792 5.695 7.04 4.693 8.361-8.061.792-5.695" fill="#d33833" fill-rule="evenodd"/><path d="M92.675 12.788c-.463 2.64-.999 3.393-.792 5.695 7.04 4.693 8.361-8.061.792-5.695z" fill="none" stroke="#d33833" stroke-width="2"/><path d="M102.87 10.649s-2.19 3.127-.626 4.065c1.564.938 3.127 0 4.065 1.563s0 2.501.313 4.377 1.877 2.189 3.44 2.501c1.562.313 5.94.938 6.565-.625l-1.876 5.627-3.752 1.25-11.88-6.877-.626-3.44v-6.877M70.041.331c-.376 4.88-.773 9.752-1.215 14.626-.662 7.279 1.748 6.009 8.057 6.009.964 0 5.933-1.15 6.289-1.876 1.705-3.483-2.851-2.709 1.964-5.335 4.065-2.216 11.246 1.346 9.603 6.273-.919 1.095-4.789.341-6.176 1.06l-7.327 3.8c-3.108 1.612-10.29 3.962-13.603 1.709-8.395-5.71.53-19.974 3.524-25.93" fill="#ef3d3a" fill-rule="evenodd"/><g fill="#231f20" fill-rule="evenodd"><path d="M78.268 111.1c-8.521 1.985-12.755-3.566-15.338-9.323-2.306.559-1.389 3.695-.806 5.294 1.525 4.194 7.672 9.778 12.694 9.02 2.161-.325 5.086-2.301 3.45-4.99M119.79 101.4l.404-.016c1.926-4 3.593-8.238 6.022-11.769-1.628-3.79-12.322-7.144-12.157-.338 2.313 1.01 6.305.206 8.356 1.497-1.186 3.254-2.897 6.024-2.625 10.626M82.63 101.29c1.827-3.35 2.422-6.868 5.019-9.4 1.17-1.14 3.444-2.529 2.316-5.698-.263-.747-2.189-2.414-3.3-2.741-4.06-1.2-13.521-.248-10.317 4.814 3.358-.157 7.871-2.18 10.38.257-1.927 3.081-5.363 9.177-4.098 12.768M118.26 67.253c-6.113-3.927-12.93-8.197-22.947-7.207-2.14 1.86-2.956 6.002-.877 8.737 1.082-1.861.402-5.284 3.419-5.799 5.684-.972 12.299 3.477 16.387 5.032 2.535 4.275-.219 5.847-2.503 8.597-4.675 5.636-10.947 12.622-10.72 21.06 1.89 1.37 2.053-2.092 2.325-2.722 2.44-5.714 8.585-13.021 13.07-17.912 1.1-1.205 2.914-2.36 3.115-3.157.582-2.315-1.513-5.09-1.27-6.63M37.668 71.387c-1.916 1.094-2.372 5.91-4.622 6.048-3.215.195-2.629-6.25-2.616-10.018-2.213 2.009-2.602 8.194-.976 11.37-1.853.91-2.68-1.003-3.708-1.677 1.32 9.595 14.036 4.45 11.922-5.723M122.15 63.257c-2.846-5.417-6.871-11.382-15.222-11.555-.17 1.75-.3 4.411.009 5.464 6.384.614 10.325 3.863 15.212 6.091M82.149 59.745c5.326-2.8 15.114-3.102 22.353-2.89.388-1.586.379-3.545.394-5.48-9.305-.463-20.307 1.84-22.747 8.37M81.136 54.523c3.683-9.247 16.341-8.182 27.016-7.927-.47-1.2-1.489-2.62-2.755-3.132-3.42-1.392-12.855-2.448-17.604.074-3.011 1.601-4.946 5.219-6.596 7.34-.797 1.024-4.765 3.64-.06 3.645"/></g><path d="M117.82 3.516c-4.322-7.402-8.457-15.005-13.585-21.534 2.15 6.32 3.07 16.9 3.394 24.965 4.498 2.105 8.349-.474 10.191-3.43" fill="#81b0c4" fill-rule="evenodd"/><g fill="#231f20" fill-rule="evenodd"><path d="M141.07-23.089c-4.839-.969-8.239-5.671-12.959-5.37 2.594 3.658 7.14 5.2 12.959 5.37M143.21-30.661c-3.944-.417-8.576-1.055-12.577-.726 1.894 2.892 9.19 1.894 12.577.726M144.58-37.19c-4.433-.096-9.942-.008-14.155.346 2.492 2.677 11.28.993 14.155-.346"/></g><g fill-rule="evenodd"><path d="M109.48-55.057c.636-5.567 2.843-11.207 2.566-17.304-2.45-.827-3.858-1.55-7.142-1.545-.232 5.181-.925 13.102-.718 18.041 1.615-.107 3.997 1.154 5.294.808" fill="#dcd9d8"/><path d="M102.33 26.985c-2.226-1.453-4.121-3.267-6.259-4.818-4.74-.235-7.327.328-10.81 3.05.057.219.407.121.42.39 5.075-2.262 11.524.92 16.648 1.378" fill="#f0d6b7"/><path d="M75.694-7.603c1.394 6.04 6.857 9.17 11.817 12.497 5.12-6.498 8.234-14.855 11.663-22.92-8.102 2.443-16.38 6.406-23.481 10.423" fill="#81b0c4"/><path d="M104.18-55.865c-.207-4.94.486-12.86.718-18.041 3.283-.004 4.691.718 7.142 1.545.276 6.096-1.93 11.737-2.566 17.304-1.298.346-3.679-.914-5.294-.808zm-51.13 28.09c2.165-19.906 5.301-36.639 11.054-54.266 12.766-3.876 28.157-4.214 39.441-.716-2.072 9.948-1.167 22.06-2.378 32.677-.912 7.98-.447 16.009-1.698 24.15-13.673 2.844-33 .665-46.418-1.845zm49.651 1.72c-.115-8.549.383-16.982 1.036-25.542 3.282.493 5.51.822 8.56 1.49-.99 8.241-.869 17.514-2.886 24.804-2.332-.023-4.385.027-6.71-.752zm16.653 1.378c-1.558.357-3.372.014-4.86-.015.7-6.969 2.397-14.659 2.995-21.974 2.342-.073 3.593 1.032 5.52 1.403.102 6.421-.562 15.268-3.655 20.586zm25.215-23.038c4.882 1.186 7.952 7.165 6.586 13.305-.916 4.127-2.548 11.898-4.295 14.538-1.29 1.953-4.79 4.51-7.584 2.72-4.545-2.91-12.552-3.755-15.867-7.278 1.662-5.534 2.178-13.135 2.864-20.146 5.678-.354 12.665 1.562 17.387-.471-3.297-1.068-7.575-1.077-10.423-2.633 2.328-1.125 7.778-.897 11.332-.035zM99.17-18.025c-3.43 8.063-6.543 16.42-11.663 22.918-4.96-3.327-10.423-6.456-11.817-12.497 7.1-4.017 15.379-7.98 23.481-10.422zm8.453 24.971c-.325-8.065-1.245-18.644-3.395-24.965 5.128 6.53 9.263 14.132 13.585 21.534-1.842 2.957-5.693 5.536-10.19 3.431zm-9.582 3.405c-1.943.21-3.592-2.233-6.117-1.177-.58-.64-1.105-1.333-1.695-1.958 5.579-6.723 8.114-16.262 12.423-24.163 2.312 7.59 2.045 15.904 2.555 24.188-3.177-.201-4.94 2.873-7.166 3.11zm-6.161 8.132c-.208-2.303.328-3.056.791-5.695 7.57-2.367 6.248 10.388-.791 5.695zm-8.394 2.755c-3.261 1.782-8.161 3.723-12.374 4.527-5.222.999-4.732-7.123-4.51-11.968.173-3.836 2.168-7.893 3.035-10.441.406-1.19.498-2.453 1.515-2.69 1.798-.418 7.73 1.954 9.42 2.875 3.575 1.95 6.348 5.045 9.384 7.123.04 1.011.078 2.021.119 3.032-1.826.91-3.935 1.555-6.615 1.673 1.818.914 4.492.901 6.148 1.989.016.405.033.81.047 1.21-3.024.234-4.176 1.58-6.17 2.67zm-31.152 5.659c-2.707-2.748 7.592-6.494 10.871-6.696-.018 1.739.991 3.378.788 4.626-3.895.684-9.013.232-11.66 2.07zm33.345-1.29c-.013-.27-.363-.172-.42-.39 3.482-2.722 6.07-3.285 10.81-3.05 2.137 1.551 4.033 3.365 6.259 4.818-5.124-.458-11.574-3.64-16.648-1.379zm30.606-9.282c-.146 3.053-.948 9.332-2.835 10.431-3.961 2.312-11.002-4.668-13.984-5.732.324-.934.86-1.674.901-2.868 1.764.434 3.912.137 5.44-.615-1.767-.198-3.727-.185-4.897-1.027-.429-1.239.105-2.927-.18-4.647 4.196-1.184 8.989-1.814 14.294-1.97 1.032 1.341 1.383 3.896 1.261 6.429zM47.777 24.24c-.85.606-6.6 8.087-7.388 7.777-10.405-4.103-20.134-11.199-28.828-17.91 8.29-17.787 11.635-39.579 12.227-60.582 9.496-4.441 17.836-10.844 30.722-11.512-1.491 10.55-2.852 19.962-3.699 29.895-3.237 1.365-7.882-.062-10.913.423-.025 3.651 4.628 1.6 5.015 4.054.292 1.858-2.56 1.998-1.631 4.923 2.368-.861 3.612-2.763 6.138-3.477 2.309 5.05-.032 13.985.3 18.205.064.792.397 4.39 2.172 3.759 1.57-.559-.09-9.569.082-13.563.157-3.68-.444-7.242 1.046-9.552a355.817 355.817 0 0 0 38.576 3.16c-2.964 1.272-6.485 2.475-10.345 4.651-2.093 1.18-8.69 3.635-9.293 5.622-.964 3.167 2.528 4.855 3.125 7.57-6.285-3.428-7.511 3.286-8.998 8.042-1.347 4.308-2.114 7.526-2.445 10.01-5.414 2.581-11.203 5.195-15.863 8.505zm63.009 6.872c8.67 4.204 10.232-15.711 6.834-22.127.525-1.914 2.331-2.646 3.069-4.366-4.838-8.667-10.211-16.756-15.148-25.32 3.672 2.286 8.917.409 13.238 2.12 1.58.624 2.722 4.24 3.918 7.133 3.29 7.958 6.743 17.99 8.28 25.586.346 1.73 1.292 5.5 1.08 7.04-.378 2.758-4.12 4.803-6.022 6.508-3.506 3.15-5.714 5.921-9.371 8.866-1.483-2.189-4.666-3.66-5.878-5.44zM27.95 107.99c-4.13-4.545-3.266-13.062-2.766-19.121 7.467 4.697 17.377-.372 17.284-8.36 3.565.094 1.332 4.452.687 7.259-2.107 9.169 3.55 19.13.256 27.516-6.395-.485-11.649-3.097-15.46-7.294zm29.558 26.38c-9.352-2.65-21.337-9.446-25.18-17.847 2.976.432 5.041 1.933 7.977 2.119 1.11.072 2.563-.466 3.838-.148 2.54.63 4.685 6.327 6.602 8.447 1.868 2.07 4.114 2.954 5.651 4.841.988.477 2.448.444 2.504 1.927-.428.457-.879.806-1.392.66zm48.681-2.493c-9.707 5.477-26.136 9.596-36.462 4.449-8.331-4.155-19.593-11.027-23.433-19.737 3.587-8.405-1.062-16.106-1.36-24.64-.157-4.54 2.139-8.504 2.315-13.446-1.228-2.025-4.978-2.275-7.574-2.136-.873 4.372-2.403 9.287-6.906 9.78-6.371.697-11.03-4.576-11.319-10.085-.342-6.48 4.978-17.22 12.517-16.475 2.913.287 3.629 3.207 6.802 3.177 1.72-3.432-2.653-4.51-3.103-6.964-.117-.634.363-3.112.642-4.274 1.37-5.658 4.422-12.982 7.427-17.29 3.814-5.464 11.307-6.288 19.37-6.823 1.44 3.101 6.743 2.846 10.2 2.035-4.143 1.64-7.993 5.617-11.185 9.137-3.665 4.039-7.378 8.371-7.566 13.65 6.927-9.61 12.65-18.003 25.246-22.23 9.53-3.196 20.662 1.465 27.986 6.608 3.039 2.137 4.853 5.529 7.013 8.634 8.082 11.626 11.854 28.219 11.024 44.303-.342 6.633-.327 13.244-2.552 17.706-2.326 4.666-10.193 8.84-14.8 4.62-.853 4.537 3.83 7.344 9.331 5.71-3.922 5.063-8.039 11.145-13.614 14.29zm18.084-149.66c7.585 3.77 21.757 10.149 26.512-.014 1.755-3.746 3.814-10.079 4.723-13.946 1.284-5.456-1.392-16.923-7-18.754-4.953-1.617-10.733-1.518-16.7-.32-.702.585-1.484 1.603-2.03 2.665-4.261.165-8.25-.229-11.615-1.98.319-3.15-1.812-3.656-3.81-4.305-1.48-5.872 2.963-13.541 1.9-18.896-.76-3.815-5.453-4.405-8.902-5.118-.113-2.12.15-3.89.386-5.683-.789-2.907-4.327-4.561-7.679-4.967-11.029-1.326-27.775-1.922-38.384 1.893-2.96 7.261-5.292 16.093-7.758 24.384-10.346-1.105-18.715 4.464-26.603 8.113-2.731 1.266-6.51 1.964-7.53 4.138-.99 2.105-.584 6.14-.83 9.95-.625 9.733-1.16 19.12-3.73 29.086-1.154 4.472-3.165 8.418-4.568 12.727C9.358 5.184 7.092 10.12 6.5 14.1c-.877 5.903 4.681 6.232 8.235 8.79 5.494 3.954 9.806 6.142 15.756 9.711 1.762 1.057 7.077 3.733 7.681 4.966 1.202 2.443-2.062 5.888-2.935 7.803-1.38 3.03-2.1 5.602-2.298 8.59-4.992.789-8.775 3.76-11.06 7.109-3.781 5.543-6.403 15.798-3.132 23.599.257.614 1.536 1.822 1.725 2.765.372 1.858-.7 4.329-.768 6.305-.343 10.14 1.716 18.875 8.541 21.932 2.771 11.038 12.688 14.71 22.032 20.195 3.493 2.05 7.343 3.36 11.32 4.824 14.263 5.25 36.15 4.261 47.987-4.692 5.02-3.797 13.044-11.813 15.914-17.617 7.58-15.323 7.042-40.931 1.74-59.571-.712-2.503-1.746-6.181-3.19-9.187-1.006-2.1-4.134-6.3-3.754-8.153.391-1.916 7.132-7.034 8.577-8.428 2.603-2.51 7.548-5.843 7.948-9.012.43-3.372-1.485-7.984-2.456-11.238-3.245-10.858-6.412-20.895-10.091-30.576" fill="#231f20"/><path d="M73.674 57.38c.411.548 2.674 1.38 5.84-.144 0 0-3.752-.626-3.44-6.881l-1.564.313s-1.615 5.672-.836 6.712" fill="#f7e4cd"/><path d="M101.09 3.617a1.72 1.72 0 1 0-3.44.001 1.72 1.72 0 0 0 3.44-.001M102.81-4.355a1.72 1.72 0 1 0-3.44 0 1.72 1.72 0 0 0 3.44 0" fill="#1d1919"/></g><g><rect transform="matrix(.8 0 0 -.8 0 144)" x="16.854" y="177.38" width="70.412" height="4.12" rx=".983" ry=".983"/><rect transform="scale(1 -1)" x="78.502" y="-2.097" width="50.037" height="3.296" rx=".786" ry=".786"/><rect transform="scale(1 -1)" x="13.483" y="-3.697" width="54.831" height="3.296" rx=".786" ry=".786"/><rect transform="scale(1 -1)" x="83.296" y="-3.697" width="45.243" height="3.296" rx=".786" ry=".786"/></g></g></symbol><symbol viewBox="0 0 24 24" id="json" xmlns="http://www.w3.org/2000/svg"><path d="M5 3h2v2H5v5a2 2 0 0 1-2 2 2 2 0 0 1 2 2v5h2v2H5c-1.07-.27-2-.9-2-2v-4a2 2 0 0 0-2-2H0v-2h1a2 2 0 0 0 2-2V5a2 2 0 0 1 2-2m14 0a2 2 0 0 1 2 2v4a2 2 0 0 0 2 2h1v2h-1a2 2 0 0 0-2 2v4a2 2 0 0 1-2 2h-2v-2h2v-5a2 2 0 0 1 2-2 2 2 0 0 1-2-2V5h-2V3h2m-7 12a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m-4 0a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m8 0a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1z" fill="#fbc02d"/></symbol><symbol viewBox="0 0 50 50" id="julia" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -247)" stroke-width="5.673"><circle cx="13.497" cy="281.632" r="9.555" fill="#bc342d"/><circle cx="36.081" cy="281.632" r="9.555" fill="#864e9f"/><circle cx="24.722" cy="262.389" r="9.555" fill="#328a22"/></g></symbol><symbol viewBox="0 0 64 64" id="karma" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -233)"><path d="M38.556 288.413l-20.29-26.687 9.532-7.246 20.29 26.686h-.001.002l5.527 7.247z" fill="#359b8b" stroke-width=".173"/><path d="M35.681 241.172L24.92 255.327v-14.13H12.947v13.817l7.84 33.235h4.132v-13.147l.003.003 20.29-26.686-.008-.006 5.504-7.24H35.84v.12z" fill="#3cbeae" stroke-width=".206"/></g></symbol><symbol viewBox="0 0 24 24" id="key" xmlns="http://www.w3.org/2000/svg"><path d="M7 14a2 2 0 0 1-2-2 2 2 0 0 1 2-2 2 2 0 0 1 2 2 2 2 0 0 1-2 2m5.65-4A5.99 5.99 0 0 0 7 6a6 6 0 0 0-6 6 6 6 0 0 0 6 6 5.99 5.99 0 0 0 5.65-4H17v4h4v-4h2v-4H12.65z" fill="#26a69a"/></symbol><symbol viewBox="0 0 24 24" id="kivy" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(1.89 0 0 1.89 -12.157 -11.429)" fill="#90a4ae"><path d="M7.026 8.63v4.474l1.928-1.928a.437.437 0 0 0 0-.619zM9.38 16.072v-4.474l-1.927 1.927a.437.437 0 0 0 0 .62zM18.576 10.412l-5.346.564-.017.018 2.39 2.39zM9.922 8.502s.023 3.304-.003 4.452c-.02.856.371 1.114.746 1.507.538.564 1.599 1.57 1.599 1.57a.53.53 0 0 0 .75 0l1.843-1.844a.53.53 0 0 0 0-.75z"/></g></symbol><symbol viewBox="0 0 24 24" id="kl" xmlns="http://www.w3.org/2000/svg"><defs><style>.a{fill:#3aaae1}.b{fill:#fdfeff}</style></defs><title>kl</title><path d="M12.033 1.737c-.25-.003-.5.11-.729.337C8.225 5.15 5.15 8.227 2.078 11.31c-.144.144-.229.346-.341.521v.41c.16.223.294.474.485.666a3259.51 3259.51 0 0 0 8.936 8.937c.193.192.443.325.666.486h.41c.205-.142.436-.256.609-.428 3.046-3.041 6.09-6.083 9.133-9.127.47-.47.472-1.005.006-1.472l-9.218-9.217c-.23-.23-.48-.347-.731-.35zm-1.062 4.545l1.386.832c.702.422 1.403.846 2.109 1.262a.544.544 0 0 1 .04.026l.016.013.017.013c.061.056.089.123.088.224a510.281 510.281 0 0 0 0 3.794.463.463 0 0 1-.007.094c-.015.069-.054.103-.142.109a.464.464 0 0 1-.044.002c-.045-.002-.09-.002-.136-.003-.323-.006-.648-.001-.998-.001v-.527-1.34-.671-.003l.004-.668c0-.147-.039-.231-.17-.308-.893-.528-1.78-1.066-2.67-1.6-.051-.03-.101-.065-.173-.111l.001-.003h-.001zm.362 3.39c.068-.003.119.043.173.138.085.148.174.293.264.44l.015.025c.096.154.194.31.292.47l-1.915 1.176c-.337.207-.673.417-1.014.617-.113.067-.154.143-.154.277.01.977.01 1.955.014 2.932V16H7.7V16h-.002c-.004-.053-.014-.112-.014-.17-.005-1.25-.006-2.501-.015-3.751 0-.142.045-.222.164-.294a467.13 467.13 0 0 0 3.353-2.054l.016-.01a.606.606 0 0 1 .032-.017l.016-.008a.308.308 0 0 1 .033-.013l.012-.004a.157.157 0 0 1 .028-.005l.01-.001zm5.677 3.126l.314.54.346.594v.001c-.158.094-.298.178-.438.259l-3.097 1.798c-.106.062-.189.071-.3.01l-.893-.496-1.524-.843-.895-.493c-.035-.02-.068-.044-.129-.085h.001l.137-.25.495-.902 1.446.795c.442.243.886.483 1.323.734.121.07.212.072.334 0 .894-.525 1.792-1.043 2.689-1.563.057-.034.118-.061.191-.1z" fill="#29b6f6" stroke-width=".041"/></symbol><symbol viewBox="0 0 24 24" id="kotlin" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="gpb"><stop offset="0" stop-color="#cb55c0"/><stop offset="1" stop-color="#f28e0e"/></linearGradient><linearGradient id="gpa"><stop offset="0" stop-color="#0296d8"/><stop offset="1" stop-color="#8371d9"/></linearGradient><linearGradient xlink:href="#gpa" id="gpc" x1="1.725" y1="22.67" x2="22.185" y2="1.982" gradientUnits="userSpaceOnUse" gradientTransform="translate(1.638 1.155) scale(.89324)"/><linearGradient xlink:href="#gpb" id="gpd" x1="1.869" y1="22.382" x2="22.798" y2="3.377" gradientUnits="userSpaceOnUse" gradientTransform="translate(1.638 1.155) scale(.89324)"/></defs><path d="M3.307 3.003v18.048h18.05v-.03L16.88 16.51l-4.48-4.515 4.48-4.515 4.443-4.477H3.307z" fill="url(#gpc)"/><path d="M12.538 3.003l-9.23 9.23v8.818h.083l9.032-9.032-.025-.024 4.48-4.515 4.444-4.477h-8.784z" fill="url(#gpd)"/></symbol><symbol viewBox="0 0 240 240" id="laravel" xmlns="http://www.w3.org/2000/svg"><path d="M216.05 119.036c-1.433.343-24.945 6.673-24.945 6.673l-19.227-28.622c-.537-.828-.99-1.656.359-1.849 1.345-.196 23.195-4.477 24.182-4.723.99-.245 1.837-.536 3.053 1.267 1.21 1.8 17.836 24.626 18.464 25.506.627.877-.447 1.41-1.883 1.748m-4.101 49.326c.588 1.003 1.176 1.64-.67 2.367-1.843.73-62.243 22.847-63.418 23.39-1.173.546-2.092.73-3.607-1.637-1.51-2.362-21.16-39.264-21.16-39.264l64.03-18.075c1.876-.644 2.317-.405 3.103.822 1.074 1.68 21.143 31.403 21.726 32.4m-103.7-21.087c-.78.202-37.566 9.733-39.525 10.22-1.965.485-1.965.246-2.188-.49-.226-.727-43.728-98.053-44.333-99.271-.605-1.214-.574-2.177 0-2.177.571 0 34.734-3.313 35.944-3.383 1.207-.07 1.08.205 1.526 1.033l49.025 91.818c.84 1.58 1.239 1.81-.452 2.248m94.588-59.77c-3.5-4.58-5.2-3.751-7.357-3.41-2.154.336-27.277 4.915-30.194 5.449-2.918.536-4.758 1.803-2.963 4.53 1.597 2.422 18.113 27.824 21.751 33.42l-65.663 17.066L66.18 49.832c-2.075-3.342-2.507-4.514-7.236-4.28-4.735.23-40.969 3.495-43.55 3.731-2.58.233-5.416 1.479-2.835 8.09 2.583 6.612 43.734 102.82 44.88 105.62 1.149 2.803 4.128 7.345 11.11 5.527 7.157-1.871 31.969-8.894 45.52-12.742 7.163 14.07 21.77 42.619 24.473 46.707 3.607 5.459 6.089 4.56 11.626 2.738 4.325-1.42 67.65-26.129 70.502-27.4 2.855-1.273 4.613-2.184 2.685-5.275-1.419-2.28-18.124-26.558-26.876-39.26 5.993-1.733 27.305-7.888 29.575-8.557 2.646-.779 3.008-2.19 1.572-3.94-1.436-1.755-21.293-28.72-24.79-33.296z" fill="#ff5722" stroke="#ff5722" stroke-width="8.852" fill-rule="evenodd"/></symbol><symbol viewBox="0 0 24 24" id="less" xmlns="http://www.w3.org/2000/svg"><path d="M13.696 2.999V5h2.002v5a2 2 0 0 0 1.999 2 2 2 0 0 0-2 2v5h-2v2h2a2 2 0 0 0 2-2v-4a2 2 0 0 1 2-2h1V11h-1a2 2 0 0 1-2-2V5a2 2 0 0 0-2-2.001zm-.03 12.766v.47a1 1 0 0 0 .03-.236 1 1 0 0 0-.03-.234zM10.566 21v-2.001H8.565v-5a2 2 0 0 0-2-2 2 2 0 0 0 2-2V5h2.001v-2H8.565a2 2 0 0 0-2 2v4a2 2 0 0 1-2 2h-.999V13h1a2 2 0 0 1 2 2v3.999A2 2 0 0 0 8.564 21zm.03-12.766v-.47a1 1 0 0 0-.03.236 1 1 0 0 0 .03.234z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="lib" xmlns="http://www.w3.org/2000/svg"><path d="M19 7H9V5h10m-4 10H9v-2h6m4-2H9V9h10m1-7H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2M4 6H2v14a2 2 0 0 0 2 2h14v-2H4V6z" fill="#8bc34a"/></symbol><symbol viewBox="0 0 40 40" id="livescript" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -257)" fill="#317eac"><path stroke-width="3.299" d="M5.419 260.18h3.685v34.207H5.419z"/><path stroke-width="3.299" d="M37.074 288.197v3.685H2.867v-3.685z"/><path stroke-width="2.894" d="M29.612 265.658l2.004 2.005L7.428 291.85l-2.004-2.005z"/><path stroke-width="2.325" d="M10.73 262.471h2.835v22.08H10.73z"/><path stroke-width="2.063" d="M15.36 262.519h2.835v17.382H15.36z"/><path stroke-width="1.77" d="M19.99 262.471h2.835v12.802H19.99z"/><path stroke-width="1.422" d="M24.526 262.491h2.835v8.254h-2.835z"/><path stroke-width="1.128" d="M28.783 262.463h2.835v5.197h-2.835z"/><path stroke-width="2.325" d="M34.801 286.545v-2.835h-22.08v2.835z"/><path stroke-width="2.063" d="M34.753 281.914v-2.835H17.371v2.835z"/><path stroke-width="1.77" d="M34.801 277.284v-2.835H21.999v2.835z"/><path stroke-width="1.422" d="M34.781 272.749v-2.835h-8.254v2.835z"/><path stroke-width="1.128" d="M34.809 268.492v-2.835h-5.197v2.835z"/></g></symbol><symbol viewBox="0 0 24 24" id="lock" xmlns="http://www.w3.org/2000/svg"><path d="M12 17a2 2 0 0 0 2-2 2 2 0 0 0-2-2 2 2 0 0 0-2 2 2 2 0 0 0 2 2m6-9a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V10a2 2 0 0 1 2-2h1V6a5 5 0 0 1 5-5 5 5 0 0 1 5 5v2h1m-6-5a3 3 0 0 0-3 3v2h6V6a3 3 0 0 0-3-3z" fill="#ffd54f"/></symbol><symbol viewBox="0 0 24 24" id="lua" xmlns="http://www.w3.org/2000/svg"><circle cx="12.203" cy="12.102" r="10.322" fill="none" stroke="#42a5f5"/><path d="M12.33 5.746a6.483 6.381 0 0 0-6.482 6.381 6.483 6.381 0 0 0 6.482 6.38 6.483 6.381 0 0 0 6.484-6.38 6.483 6.381 0 0 0-6.484-6.38zm1.86 1.916a2.329 2.292 0 0 1 2.33 2.293 2.329 2.292 0 0 1-2.33 2.291 2.329 2.292 0 0 1-2.329-2.29 2.329 2.292 0 0 1 2.328-2.294z" fill="#42a5f5" fill-rule="evenodd"/><ellipse cy="4.615" cx="19.631" rx="2.329" ry="2.292" fill="#42a5f5" fill-rule="evenodd"/></symbol><symbol viewBox="0 0 24 24" id="markdown" xmlns="http://www.w3.org/2000/svg"><path d="M2 16V8h2l3 3 3-3h2v8h-2v-5.17l-3 3-3-3V16H2m14-8h3v4h2.5l-4 4.5-4-4.5H16V8z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" preserveAspectRatio="xMidYMid" id="markojs" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -120.96)" stroke-width=".984"><path d="M4.002 126.482c-.655 1.07-1.32 2.14-1.976 3.21-.655 1.06-1.308 2.142-1.963 3.212l.002.002-.002.002c.655 1.07 1.308 2.15 1.963 3.211.655 1.07 1.32 2.141 1.976 3.211h3.33c-.664-1.07-1.318-2.14-1.974-3.21-.653-1.069-1.307-2.145-1.961-3.214.654-1.068 1.308-2.146 1.961-3.215a601.93 601.93 0 0 1 1.974-3.209z" fill="#2196f3"/><path d="M3.999 126.482l-.002.002c.655 1.07 1.31 2.15 1.964 3.212.655 1.07 1.32 2.14 1.974 3.21h3.331c-.664-1.07-1.319-2.14-1.974-3.21-.653-1.068-1.306-2.146-1.96-3.214z" fill="#26a69a"/><path d="M15.203 126.482l.002.002c-.655 1.07-1.31 2.15-1.965 3.212-.655 1.07-1.319 2.14-1.974 3.21h-3.33c.664-1.07 1.318-2.14 1.973-3.21.654-1.069 1.307-2.146 1.961-3.214z" fill="#8bc34a"/><path d="M11.874 126.484c.664 1.07 1.318 2.14 1.974 3.21.653 1.068 1.307 2.146 1.961 3.214-.654 1.069-1.308 2.145-1.961 3.213-.656 1.07-1.31 2.14-1.974 3.21h3.33c.655-1.07 1.319-2.14 1.974-3.21.655-1.06 1.31-2.14 1.966-3.21l-.002-.003.002-.002c-.656-1.07-1.311-2.152-1.966-3.213-.655-1.07-1.319-2.138-1.974-3.209z" fill="#ffc107"/><path d="M16.74 126.482c.665 1.07 1.319 2.14 1.974 3.21.654 1.068 1.306 2.146 1.96 3.214-.654 1.069-1.306 2.145-1.96 3.213-.655 1.07-1.31 2.141-1.974 3.211h3.33c.656-1.07 1.32-2.14 1.974-3.21.655-1.062 1.31-2.141 1.966-3.212l-.002-.002.002-.002c-.655-1.07-1.31-2.152-1.966-3.213-.655-1.07-1.318-2.138-1.973-3.209z" fill="#f44336"/></g></symbol><symbol viewBox="0 0 23 24" id="mathematica" xmlns="http://www.w3.org/2000/svg"><path d="M11.512 1.523l-.073.025-.46.794-.454.763-1.217 2.09H9.29L5.435 3.5l-.1-.047h-.018v.092l.025.163v.086l.132 1.226v.082l.032.252v.082l.22 2.137v.075l.018.082v.06l-2.348.507-.04.015-.457.1-.025.01h-.042l-1.096.244-.04.007-.17.036v.082l.018.01 1.859 2.086.053.052.114.132.804.909v.005l-.053.05-.22.257-2.564 2.875-.01.007v.082l.071.006.295.075 1.697.366v.006l2.139.472h.015v.047l-.036.252v.08l-.046.412v.082l-.036.244v.082l-.045.412v.08l-.05.41v.08l-.036.244v.082l-.046.412v.082l-.05.407v.082l-.032.248V20l-.05.407v.104h.037l3.642-1.6.294-.134h.018l.177.312.539.911.015.032.854 1.465.16.262.404.695.007.022h.092l.005-.022.017-.025.56-.947.014-.042.6-1.033.316-.539.644-1.091.05.013 3.906 1.721h.035v-.085l-.138-1.32v-.082l-.032-.244v-.082l-.035-.245v-.085l-.033-.244v-.081l-.032-.245v-.082l-.032-.244v-.085l-.035-.245v-.082l-.032-.245v-.082l-.033-.244v-.085l-.025-.17v-.053l1.632-.354.043-.008.458-.107h.028v-.01l.23-.05.03-.01h.042l.382-.09.025-.01h.043l.194-.05h.033l1.015-.23.07-.007v-.064l-.015-.013-1.19-1.342-.028-.028-.197-.22-1.428-1.604v-.006l.295-.323.4-.457 2.148-2.408.015-.01v-.065l-.035-.008-1.288-.28-.372-.084-.047-.01-2.481-.544v-.045l.432-4.265v-.02h-.042l-.302.135-.01.014h-.025l-3.307 1.45-.297.135h-.015l-2.028-3.483-.099-.145-.014-.045zm-.001 1.114l1.365 2.323.34.592-.008.025-1.18 1.511-.517.66-.012-.01-.258-.335-.04-.05-1.397-1.787.03-.063 1.378-2.365.287-.491zm4.908 2.039l-.007.025-.168.225-.538.066zm-9.817.004l.053.02.677.3h-.499l-.224-.3zM16.947 5l-.123 1.248-.113-.928.226-.307zm-9.26.156l.053.024.705.309-.757-.175zm7.388.116l.02.168-1.318.403.003-.003.16-.071 1.015-.444zM9.669 6.388l.944 1.204v.01L9.483 7.2zm3.55.172l.21.682-.234.084-.089.022-.702.255.008-.022.776-.982zm-5 .836l.986.356.898.312.048.02 1.054.373.011 3.086-.362-.117-.67-.224-.081-.038-.735-.245-.77-.256-.29-.1-.011-.255-.032-1.195-.01-.287-.015-.894-.013-.297zm6.583 0l-.011.227-.028.9-.008.303-.032 1.475-.01.262-.337.117-.734.245-.77.256-.712.245-.355.117.01-3.086 1.632-.578zm.585.437l.09.735.79-.097-.915 1.302-.018.006.01-.183.018-.877zm-9.451.536l.152.22 1.447 2.049-2.607.968-.05.015-1.972-2.214-.28-.312.003-.01.115-.018.424-.1.14-.021.337-.078.042-.01zm11.146.003l3.284.713.029.01-.022.025-1.954 2.192-.277.312-.092-.036-2.564-.95.475-.681.152-.216zM6.787 8.52h.86l.036 1.258-.013-.006-.763-1.078zm1.358 2.625l.152.06.77.252.712.245.746.247.49.167-.065.092-1.723 2.334-1.015-.302-.082-.017-.035-.015-1.902-.56.938-1.22.981-1.277zm6.73 0l.033.006 1.787 2.327.132.17-.128.036-.032.014-2.196.642-.105.032-.564.17-.018-.003-1.053-1.44-.174-.239-.547-.726-.007-.018.469-.16.769-.254.713-.245.77-.252zm-7.766.305l-.007.02-.405.523-.291-.291.657-.245zm8.802 0l.043.007.578.212.714.27-.661.394-.375-.479-.03-.042-.262-.342zm-10.843.75l-.67.668.355-.397.207-.23zm12.911.016l.068.025.045.042.554.627.042.043.204.228-.255.135zm-6.473.265l.022.015 1.38 1.872.032.05.343.465.008.031-.088.117-.422.629-.047.074-.245.343-.97 1.43-.013.007-1.18-1.72-.096-.16-.493-.708-.008-.037 1.618-2.191.007-.01zm7.827 1.194l.565.633.063.082-.272-.093-.037-.013zm-15.785.148l.297.299-.637.218-.152.05.038-.058zm13.224.47l-.855.448.346.66-.185-.058-.27-.088-1.092-.348.012-.01zm-9.687.255l1.222.356-.006.007-.458.145-.443.135-.032.01-.49.157zm-2.765.048l.318.32 2.007.517-.567.18-.055.004-2.103-.469-.744-.156.007-.006zm14.966.205l.548.188v.003l-.457.1-.043.014-1.069.23zm-10.23.507l.007.227.01.347.025 1.363.025.691-.007.255-.24.107-2.863 1.255.032-.372.033-.255.017-.227.031-.256.037-.407.045-.42.018-.23.032-.251.032-.412.05-.414.013-.14 1.455-.457.003-.014.301-.098zm4.908 0l1.245.39v.014l.312.1 1.146.362.022.23.03.255.043.408.04.42.017.23.033.251.032.412.042.325.078.848-.078-.04-3.025-1.322-.004-.305.06-2.368zm-4.295.617l.015.007.067.107.6.875-.64.531-.034-1.438zm3.671 0h.008l-.005.06-.02.678-.005.214-.479-.223zm-2.888 3.605l.763.915.001.37-.017-.006-.025-.05-.464-.791-.012-.018zm1.53.61l.184.083-.343.586-.018.007.002-.532z" fill="#f44336" fill-rule="evenodd" stroke="#f44336" stroke-width=".7747499999999999" stroke-linejoin="round"/></symbol><symbol viewBox="0 0 720 720" id="matlab" xmlns="http://www.w3.org/2000/svg"><title>Layer 1</title><path d="M209.247 329.98L52.368 387.638l121.325 85.822 96.752-95.804-61.198-47.674z" fill="#4db6ac" fill-rule="evenodd" stroke-width=".3"/><path d="M480.193 71.446c-13.123 1.784-9.565 1.013-28.4 16.09-18.008 14.418-69.925 100.347-97.673 129.256-24.688 25.722-34.46 12.199-60.102 33.661-25.68 21.494-65.273 64.464-65.273 64.464l63.978 47.32L394.15 222.754c23.948-32.932 23.694-37.266 36.744-71.82 6.384-16.907 17.76-29.9 27.756-45.809 12.488-19.874 30.186-34.855 21.543-33.68z" fill="#00897b" fill-rule="evenodd" stroke-width=".3"/><path d="M478.206 69.796c-31.268-.189-62.068 137.245-115.56 242.691-54.543 107.519-162.235 176.82-162.235 176.82 18.156 8.243 34.681 4.91 54.236 23.394 13.375 16.164 52.09 95.976 75.174 146.117 0 0 18.964-10.297 42.994-27.695 24.03-17.397 53.124-41.896 73.384-70.3 26.883-37.692 47.897-61.043 65.703-75.271 17.806-14.23 32.404-19.336 46.458-20.54 50.238-4.305 124.582 85.792 124.582 85.792S527.267 70.09 478.206 69.796z" fill="#ffb74d" fill-rule="evenodd" stroke-width=".3"/></symbol><symbol viewBox="0 0 24 24" id="merlin" xmlns="http://www.w3.org/2000/svg"><text style="line-height:1.25;-inkscape-font-specification:'Century Gothic Bold'" x="1.953" y="21.178" transform="scale(.99582 1.0042)" font-weight="700" font-size="30.255" font-family="Century Gothic" letter-spacing="0" word-spacing="0" fill="#42a5f5" stroke-width=".756"><tspan x="1.953" y="21.178" style="-inkscape-font-specification:'Century Gothic Bold'" font-size="22.745">M</tspan></text></symbol><symbol viewBox="0 0 192 191.99999" id="mocha" xmlns="http://www.w3.org/2000/svg"><title>Mocha Logo</title><g transform="translate(-354.75 -262.42) scale(4.835)" fill="#a1887f"><path d="M103.6 69.6c0-.5-.4-1-1-1H83.8c-.5 0-1 .4-1 1 0 3.4.5 15.1 5.5 20.8.2.2.4.3.7.3h8.4c.3 0 .5-.1.7-.3 5-5.6 5.5-17.3 5.5-20.8zm-7.4 18.2h-5.9c-.3 0-.5-.1-.7-.3-3.4-4-3.8-12-3.9-14.8 0-.5.4-1 1-1h13.2c.5 0 1 .4 1 1 0 2.8-.5 10.7-3.9 14.8-.3.2-.5.3-.8.3zM95.1 66.6s3.6-2.1 1.4-5.9c-1.3-2-1.9-3.7-1.4-4.4-1.3 1.6-3.5 3.3-1.1 6.9.8.9 1.2 2.8 1.1 3.4zM91.1 66.9s2.4-1.4.9-4c-.9-1.3-1.3-2.5-.9-2.9-.9 1.1-2.3 2.2-.7 4.7.5.5.7 1.8.7 2.2z"/><path d="M99.3 78.5c-.4 2.7-1.2 5.8-2.9 7.8-.2.2-.4.3-.6.3h-5c-.2 0-.5-.1-.6-.3-1.2-1.5-2-3.5-2.5-5.6 0 0 5.8.8 9.1-.4 2.4-.9 2.5-1.8 2.5-1.8z"/></g></symbol><symbol viewBox="0 0 24 24" id="movie" xmlns="http://www.w3.org/2000/svg"><path d="M18 4l2 4h-3l-2-4h-2l2 4h-3l-2-4H8l2 4H7L5 4H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4h-4z" fill="#ff9800"/></symbol><symbol viewBox="0 0 24 24" id="music" xmlns="http://www.w3.org/2000/svg"><path d="M16 9V7h-4v5.5c-.42-.31-.93-.5-1.5-.5A2.5 2.5 0 0 0 8 14.5a2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5V9h3m-4-7a10 10 0 0 1 10 10 10 10 0 0 1-10 10A10 10 0 0 1 2 12 10 10 0 0 1 12 2z" fill="#ef5350"/></symbol><symbol viewBox="0 0 24 24" id="mxml" xmlns="http://www.w3.org/2000/svg"><path d="M13 9h5.5L13 3.5V9M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m.12 13.5l3.74 3.74 1.42-1.41-2.33-2.33 2.33-2.33-1.42-1.41-3.74 3.74m11.16 0l-3.74-3.74-1.42 1.41 2.33 2.33-2.33 2.33 1.42 1.41 3.74-3.74z" fill="#ffa726"/></symbol><symbol viewBox="0 0 300 300" id="ngrx-actions" xmlns="http://www.w3.org/2000/svg"><path d="M150 27.324L35.85 68.006l17.303 151.09 96.843 53.586 96.843-53.586 17.303-151.09zm-23.719 38.349c4.346-.075 9.04 1.316 14.265 4.131 2.3 1.24 9.235 2.994 15.407 3.889 21.936 3.18 47.975 19.934 56.21 36.186 5.667 11.183 4.508 17.209-4.18 21.702-7.492 3.874-22.822 2-45.08-5.517l-18.785-6.343-6.683 2.552c-9.683 3.698-19.366 12.877-23.33 22.09-2.858 6.645-3.293 9.768-2.77 20.705.523 10.955 1.315 14.12 5.2 20.997 4.423 7.829 14.576 17.818 16.331 16.064.473-.473-.574-3.648-2.308-7.048-1.735-3.4-2.744-6.825-2.26-7.606.482-.781 5.054 2.123 10.157 6.44 11.35 9.6 24.608 15.74 36.77 17.01 9.985 1.045 12.266-.814 4.787-3.912-2.41-.998-5.544-3.088-6.95-4.641-2.907-3.212-3.072-3.12 9.356-5.906 7.736-1.733 23.026-9.849 23.937-12.71.29-.91-2.195-1.296-6.27-.972-3.706.295-6.732-.087-6.732-.85 0-.76 3.032-4.523 6.732-8.385 13.883-14.489 18.62-25.32 20.098-45.906l1.02-14.217 3.257 6.756c3.601 7.452 4.265 18.202 1.701 27.437-2.141 7.711-.712 8.564 3.208 1.92 4.845-8.212 6.39-6.905 5.54 4.666-.924 12.587-5.243 22.017-14.993 32.686-7.95 8.699-7.001 10.254 2.624 4.326 9.273-5.711 10.511-4.815 5.736 4.155-9.031 16.964-28.122 31.35-47.948 36.161-12.016 2.917-20.537 3.461-31.544 2.018-28.78-3.775-56.001-23.157-68.993-49.114-3.378-6.748-8.154-14.994-10.62-18.348-5.092-6.924-5.529-10.038-2.09-15.286 1.715-2.618 2.116-5.307 1.41-9.308-3.273-18.531-3.167-19.11 4.276-26.659 6.468-6.56 6.878-7.44 6.878-15.092 0-6.637.671-8.813 3.67-11.811 2.02-2.02 5.23-3.7 7.12-3.718 5.49-.05 14.97-5.135 20.584-11.033 4.687-4.927 9.674-7.417 15.262-7.51z" fill="#ab47bc" stroke-width="12.914"/></symbol><symbol viewBox="0 0 300 300" id="ngrx-effects" xmlns="http://www.w3.org/2000/svg"><path d="M150 27.324L35.85 68.006l17.303 151.09 96.843 53.586 96.843-53.586 17.303-151.09zm-23.719 38.349c4.346-.075 9.04 1.316 14.265 4.131 2.3 1.24 9.235 2.994 15.407 3.889 21.936 3.18 47.975 19.934 56.21 36.186 5.667 11.183 4.508 17.209-4.18 21.702-7.492 3.874-22.822 2-45.08-5.517l-18.785-6.343-6.683 2.552c-9.683 3.698-19.366 12.877-23.33 22.09-2.858 6.645-3.293 9.768-2.77 20.705.523 10.955 1.315 14.12 5.2 20.997 4.423 7.829 14.576 17.818 16.331 16.064.473-.473-.574-3.648-2.308-7.048-1.735-3.4-2.744-6.825-2.26-7.606.482-.781 5.054 2.123 10.157 6.44 11.35 9.6 24.608 15.74 36.77 17.01 9.985 1.045 12.266-.814 4.787-3.912-2.41-.998-5.544-3.088-6.95-4.641-2.907-3.212-3.072-3.12 9.356-5.906 7.736-1.733 23.026-9.849 23.937-12.71.29-.91-2.195-1.296-6.27-.972-3.706.295-6.732-.087-6.732-.85 0-.76 3.032-4.523 6.732-8.385 13.883-14.489 18.62-25.32 20.098-45.906l1.02-14.217 3.257 6.756c3.601 7.452 4.265 18.202 1.701 27.437-2.141 7.711-.712 8.564 3.208 1.92 4.845-8.212 6.39-6.905 5.54 4.666-.924 12.587-5.243 22.017-14.993 32.686-7.95 8.699-7.001 10.254 2.624 4.326 9.273-5.711 10.511-4.815 5.736 4.155-9.031 16.964-28.122 31.35-47.948 36.161-12.016 2.917-20.537 3.461-31.544 2.018-28.78-3.775-56.001-23.157-68.993-49.114-3.378-6.748-8.154-14.994-10.62-18.348-5.092-6.924-5.529-10.038-2.09-15.286 1.715-2.618 2.116-5.307 1.41-9.308-3.273-18.531-3.167-19.11 4.276-26.659 6.468-6.56 6.878-7.44 6.878-15.092 0-6.637.671-8.813 3.67-11.811 2.02-2.02 5.23-3.7 7.12-3.718 5.49-.05 14.97-5.135 20.584-11.033 4.687-4.927 9.674-7.417 15.262-7.51z" fill="#26c6da" stroke-width="12.914"/></symbol><symbol viewBox="0 0 300 300" id="ngrx-reducer" xmlns="http://www.w3.org/2000/svg"><path d="M150 27.324L35.85 68.006l17.303 151.09 96.843 53.586 96.843-53.586 17.303-151.09zm-23.719 38.349c4.346-.075 9.04 1.316 14.265 4.131 2.3 1.24 9.235 2.994 15.407 3.889 21.936 3.18 47.975 19.934 56.21 36.186 5.667 11.183 4.508 17.209-4.18 21.702-7.492 3.874-22.822 2-45.08-5.517l-18.785-6.343-6.683 2.552c-9.683 3.698-19.366 12.877-23.33 22.09-2.858 6.645-3.293 9.768-2.77 20.705.523 10.955 1.315 14.12 5.2 20.997 4.423 7.829 14.576 17.818 16.331 16.064.473-.473-.574-3.648-2.308-7.048-1.735-3.4-2.744-6.825-2.26-7.606.482-.781 5.054 2.123 10.157 6.44 11.35 9.6 24.608 15.74 36.77 17.01 9.985 1.045 12.266-.814 4.787-3.912-2.41-.998-5.544-3.088-6.95-4.641-2.907-3.212-3.072-3.12 9.356-5.906 7.736-1.733 23.026-9.849 23.937-12.71.29-.91-2.195-1.296-6.27-.972-3.706.295-6.732-.087-6.732-.85 0-.76 3.032-4.523 6.732-8.385 13.883-14.489 18.62-25.32 20.098-45.906l1.02-14.217 3.257 6.756c3.601 7.452 4.265 18.202 1.701 27.437-2.141 7.711-.712 8.564 3.208 1.92 4.845-8.212 6.39-6.905 5.54 4.666-.924 12.587-5.243 22.017-14.993 32.686-7.95 8.699-7.001 10.254 2.624 4.326 9.273-5.711 10.511-4.815 5.736 4.155-9.031 16.964-28.122 31.35-47.948 36.161-12.016 2.917-20.537 3.461-31.544 2.018-28.78-3.775-56.001-23.157-68.993-49.114-3.378-6.748-8.154-14.994-10.62-18.348-5.092-6.924-5.529-10.038-2.09-15.286 1.715-2.618 2.116-5.307 1.41-9.308-3.273-18.531-3.167-19.11 4.276-26.659 6.468-6.56 6.878-7.44 6.878-15.092 0-6.637.671-8.813 3.67-11.811 2.02-2.02 5.23-3.7 7.12-3.718 5.49-.05 14.97-5.135 20.584-11.033 4.687-4.927 9.674-7.417 15.262-7.51z" fill="#e53935" stroke-width="12.914"/></symbol><symbol viewBox="0 0 300 300" id="ngrx-state" xmlns="http://www.w3.org/2000/svg"><path d="M150 27.324L35.85 68.006l17.303 151.09 96.843 53.586 96.843-53.586 17.303-151.09zm-23.719 38.349c4.346-.075 9.04 1.316 14.265 4.131 2.3 1.24 9.235 2.994 15.407 3.889 21.936 3.18 47.975 19.934 56.21 36.186 5.667 11.183 4.508 17.209-4.18 21.702-7.492 3.874-22.822 2-45.08-5.517l-18.785-6.343-6.683 2.552c-9.683 3.698-19.366 12.877-23.33 22.09-2.858 6.645-3.293 9.768-2.77 20.705.523 10.955 1.315 14.12 5.2 20.997 4.423 7.829 14.576 17.818 16.331 16.064.473-.473-.574-3.648-2.308-7.048-1.735-3.4-2.744-6.825-2.26-7.606.482-.781 5.054 2.123 10.157 6.44 11.35 9.6 24.608 15.74 36.77 17.01 9.985 1.045 12.266-.814 4.787-3.912-2.41-.998-5.544-3.088-6.95-4.641-2.907-3.212-3.072-3.12 9.356-5.906 7.736-1.733 23.026-9.849 23.937-12.71.29-.91-2.195-1.296-6.27-.972-3.706.295-6.732-.087-6.732-.85 0-.76 3.032-4.523 6.732-8.385 13.883-14.489 18.62-25.32 20.098-45.906l1.02-14.217 3.257 6.756c3.601 7.452 4.265 18.202 1.701 27.437-2.141 7.711-.712 8.564 3.208 1.92 4.845-8.212 6.39-6.905 5.54 4.666-.924 12.587-5.243 22.017-14.993 32.686-7.95 8.699-7.001 10.254 2.624 4.326 9.273-5.711 10.511-4.815 5.736 4.155-9.031 16.964-28.122 31.35-47.948 36.161-12.016 2.917-20.537 3.461-31.544 2.018-28.78-3.775-56.001-23.157-68.993-49.114-3.378-6.748-8.154-14.994-10.62-18.348-5.092-6.924-5.529-10.038-2.09-15.286 1.715-2.618 2.116-5.307 1.41-9.308-3.273-18.531-3.167-19.11 4.276-26.659 6.468-6.56 6.878-7.44 6.878-15.092 0-6.637.671-8.813 3.67-11.811 2.02-2.02 5.23-3.7 7.12-3.718 5.49-.05 14.97-5.135 20.584-11.033 4.687-4.927 9.674-7.417 15.262-7.51z" fill="#9ccc65" stroke-width="12.914"/></symbol><symbol viewBox="0 0 24 24" id="nim" xmlns="http://www.w3.org/2000/svg"><path d="M4.464 15.75L2.288 3.78l5.985 7.617L12.08 3.78l3.809 7.617 5.985-7.617-2.177 11.97H4.464m15.234 3.264a1.088 1.088 0 0 1-1.088 1.088H5.553a1.088 1.088 0 0 1-1.089-1.088v-1.089h15.234z" stroke-width="1.088" fill="#ffca28"/></symbol><symbol viewBox="0 0 500 500" id="nix" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-1.965 36.302)" stroke-width=".395"><path d="M135.59 415.7c0-.295-2.752-5.283-6.116-11.084-3.364-5.801-6.116-10.776-6.116-11.055s9.514-16.889 21.143-36.912c11.629-20.022 21.323-36.798 21.542-37.279.346-.76-1.608-4.363-14.896-27.466-8.412-14.625-15.294-26.785-15.294-27.023 0-.5 24.46-43.501 25.206-44.31.414-.45.592-.384 1.078.395.32.513 16.876 29.256 36.791 63.87 62.62 108.85 74.852 130.01 75.41 130.46.3.242.544.554.544.694 0 .14-11.836.21-26.302.154-23.023-.09-26.313-.175-26.393-.694-.11-.714-27.662-48.825-28.86-50.392-.746-.978-.906-1.035-1.426-.51-.688.696-28.954 49.323-29.49 50.733l-.365.96h-13.229c-10.896 0-13.229-.095-13.229-.538zm167.58-125.61c-.134-.216 1.188-2.863 2.938-5.882 6.924-11.944 84.291-145.75 96.491-166.88 7.143-12.371 13.142-22.465 13.333-22.433.363.062 25.861 43.105 25.861 43.655 0 .174-6.761 11.952-15.026 26.173-8.46 14.557-14.932 26.104-14.81 26.421.185.483 4.564.564 30.213.564h29.996l.958 1.48c.526.814 3.296 5.547 6.155 10.518 2.859 4.971 5.45 9.29 5.756 9.597.706.705.704.724-.16 1.572-.395.388-3.36 5.323-6.587 10.965-3.228 5.643-6.056 10.387-6.285 10.543-.23.156-19.695.171-43.256.034l-42.84-.249-.804 1.15c-.441.632-7.504 12.736-15.696 26.897l-14.892 25.747H339.03c-8.517 0-20.015.116-25.55.259-6.55.168-10.15.121-10.309-.135zM169.42 132.23c-56.373-.055-102.5-.182-102.5-.282 0-.1 5.617-10.132 12.481-22.294l12.481-22.112h30.332c27.113 0 30.332-.065 30.332-.611 0-.336-6.659-12.228-14.797-26.427-8.139-14.199-14.797-25.917-14.797-26.04 0-.123 2.682-4.853 5.96-10.51s6.003-10.578 6.055-10.934c.086-.586 1.376-.648 13.572-.648 7.413 0 13.463.143 13.446.317-.017.174.222.707.531 1.184.31.476 9.763 16.937 21.007 36.578 11.244 19.64 20.71 36.022 21.036 36.4.554.647 2.549.691 31.428.691h30.837l12.896 22.145c7.093 12.18 12.8 22.301 12.682 22.492-.118.19-4.776.303-10.352.249-5.575-.054-56.26-.143-112.63-.198z" fill="#5075c1"/><path d="M25.289 203.14c-6.098 10.563-6.69 11.711-6.225 12.078.283.224 3.18 5.044 6.44 10.712 3.261 5.668 6.017 10.355 6.124 10.417.106.061 13.585.153 29.95.204 16.367.052 29.994.23 30.285.399.472.273-1.08 3.094-14.637 26.574L62.06 289.793l12.907 21.865c7.1 12.026 12.982 21.906 13.068 21.956.086.05 23.257-39.831 51.492-88.624 11.352-19.617 21.214-36.64 30.37-52.442 23.308-40.452 30.68-53.468 30.73-54.132-1.097-.11-6.141-.187-13.006-.216-3.945-.01-7.82-.02-12.75-.002l-25.341.092-15.42 26.706c-14.256 24.693-15.445 26.663-16.278 26.86l-.024.037c-.011.003-1.62-.001-1.825 0-4.29.062-20.453.063-40.226-.01-22.632-.082-41.615-.125-42.183-.096-.568.03-1.147-.03-1.29-.132-.142-.102-3.29 5.066-6.996 11.485zm205.16-190.3c-.123.149 5.62 10.392 12.761 22.763 12.199 21.131 89.393 155.03 96.276 167 1.502 2.613 2.92 4.803 3.443 5.348.9-1.249 3.531-5.63 7.954-13.219a1342.88 1342.88 0 0 1 10.049-17.76l6.606-11.443c.692-1.403.754-1.818.653-2.117-.162-.48-6.904-12.332-14.982-26.337-8.078-14.005-14.824-25.849-14.991-26.32a.73.73 0 0 1-.009-.366l-.426-.913L359.42 72.5c3.69-6.307 6.425-11.042 9.47-16.29 9.159-15.948 12.037-21.189 11.896-21.55-.126-.324-2.7-4.83-5.72-10.017-3.021-5.185-5.845-10.148-6.275-11.026-.483-.987-.734-1.364-1.1-1.456-.054.014-.083.018-.145.035-.42.112-5.454.195-11.189.185-5.734-.01-11.22.024-12.188.073l-1.76.089-14.997 25.978c-12.824 22.212-15.084 25.964-15.595 25.883-.024-.004-.15-.189-.235-.301-.109.066-.2.09-.272.05-.255-.148-7.143-11.902-15.306-26.119l-14.36-25.016c-.115-.186-.444-.744-.457-.752-.477-.275-50.502.287-50.737.57zm-18.646 283.09c-.047.109-.026.262.042.48.329 1.05 25.338 43.735 25.772 43.985.207.119 14.178.239 31.05.266 26.651.044 30.75.152 31.234.832.308.43 9.988 17.214 21.513 37.296s21.152 36.627 21.394 36.767c.242.14 5.927.243 12.633.23 6.706-.013 12.401.099 12.657.246.132.076.382-.141.852-.795l6.008-10.406c5.234-9.065 6.62-11.684 6.294-11.888-.575-.36-15.597-26.643-23.859-41.482-3.09-5.45-5.37-9.516-5.441-9.774-.195-.712-.065-.822 1.156-.98 1.956-.252 57.397-.057 58.07.205.238.092.79-.569 2.594-3.497 1.866-3.067 5.03-8.524 11-18.866 7.22-12.505 13.044-22.784 12.942-22.843-.102-.059-.771-.051-1.489.016l-.046.001c-4.452.204-33.918.203-149.74.025-38.96-.06-69.786-.09-71.912-.072-1.121.01-2.095.076-2.66.172a.25.25 0 0 0-.062.083z" fill="#7db7e1"/></g></symbol><symbol viewBox="0 0 24 24" id="nodejs" xmlns="http://www.w3.org/2000/svg"><path d="M12 1.85c-.27 0-.55.07-.78.2l-7.44 4.3c-.48.28-.78.8-.78 1.36v8.58c0 .56.3 1.08.78 1.36l1.95 1.12c.95.46 1.27.47 1.71.47 1.4 0 2.21-.85 2.21-2.33V8.44c0-.12-.1-.22-.22-.22H8.5c-.13 0-.23.1-.23.22v8.47c0 .66-.68 1.31-1.77.76L4.45 16.5a.26.26 0 0 1-.11-.21V7.71c0-.09.04-.17.11-.21l7.44-4.29c.06-.04.16-.04.22 0l7.44 4.29c.07.04.11.12.11.21v8.58c0 .08-.04.16-.11.21l-7.44 4.29c-.06.04-.16.04-.23 0L10 19.65c-.08-.03-.16-.04-.21-.01-.53.3-.63.36-1.12.51-.12.04-.31.11.07.32l2.48 1.47c.24.14.5.21.78.21s.54-.07.78-.21l7.44-4.29c.48-.28.78-.8.78-1.36V7.71c0-.56-.3-1.08-.78-1.36l-7.44-4.3c-.23-.13-.5-.2-.78-.2M14 8c-2.12 0-3.39.89-3.39 2.39 0 1.61 1.26 2.08 3.3 2.28 2.43.24 2.62.6 2.62 1.08 0 .83-.67 1.18-2.23 1.18-1.98 0-2.4-.49-2.55-1.47a.226.226 0 0 0-.22-.18h-.96c-.12 0-.21.09-.21.22 0 1.24.68 2.74 3.94 2.74 2.35 0 3.7-.93 3.7-2.55 0-1.61-1.08-2.03-3.37-2.34-2.31-.3-2.54-.46-2.54-1 0-.45.2-1.05 1.91-1.05 1.5 0 2.09.33 2.32 1.36.02.1.11.17.21.17h.97c.05 0 .11-.02.15-.07.04-.04.07-.1.05-.16C17.56 8.82 16.38 8 14 8z" fill="#8bc34a"/></symbol><symbol viewBox="0 0 300 300" id="nodemon" xmlns="http://www.w3.org/2000/svg"><title>nodemon</title><path d="M149.868 20.62c-2.124 0-4.25.55-6.154 1.648L41.899 81.083a12.306 12.306 0 0 0-6.15 10.652v117.633a12.29 12.29 0 0 0 6.152 10.646l101.815 58.766h.001a12.282 12.282 0 0 0 12.291 0l101.84-58.766a12.29 12.29 0 0 0 6.153-10.652V91.738a12.31 12.31 0 0 0-6.146-10.652L156.015 22.27a12.302 12.302 0 0 0-6.153-1.648zM83.303 70.93s11.789 33.031 35.477 31.934l27.74-15.961a7.348 7.348 0 0 1 3.414-.99h.641a7.233 7.233 0 0 1 3.404.99l27.738 15.961c23.69 1.094 35.475-31.934 35.475-31.934 5.233 23.154 1.06 38.641-5.924 48.942l4.541 2.614h.002c2.321 1.327 3.734 3.795 3.737 6.49l-.12 95.811a3.724 3.724 0 0 1-1.855 3.227 3.624 3.624 0 0 1-3.735 0L177.1 206.971c-2.311-1.363-3.742-3.818-3.742-6.48v-44.763a7.44 7.44 0 0 0-3.737-6.465l-15.642-9.01a7.28 7.28 0 0 0-3.715-1.01 7.378 7.378 0 0 0-3.742 1.01l-15.648 9.01c-2.316 1.323-3.729 3.798-3.729 6.467v44.762c0 2.663-1.413 5.1-3.738 6.48l-36.748 21.041a3.571 3.571 0 0 1-3.71 0c-1.173-.65-1.864-1.887-1.864-3.224l-.137-95.812a7.483 7.483 0 0 1 3.74-6.49l4.541-2.615c-6.982-10.302-11.16-25.79-5.925-48.942z" fill="#8bc34a"/></symbol><symbol viewBox="0 0 990 990" id="npm" xmlns="http://www.w3.org/2000/svg"><defs><style>.hncls-1{fill:#cb3837}.cls-2{fill:#fff}</style></defs><title>n</title><path class="hncls-1" d="M113.26 876.74V113.27h763.47v763.47zm143.59-620.4v476.18h240.61V355.63h140.21v376.96h95.457V256.34z" fill="#e53935" stroke-width=".771"/></symbol><symbol id="nunjucks" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>.host0{fill:#388e3c}</style><path class="host0" d="M11.2 21.1H8.1l-2.3-7.9v7.9H2.7V2.9h3.1l2.3 7.4V2.9h3.1zM21.3 19.2c0 1-.8 1.9-1.9 1.9h-4.8c-1 0-1.9-.8-1.9-1.9v-3.8l3.2-.7V18h2.3V7.2h3.1v12z"/></symbol><symbol viewBox="0 0 150 150.00001" id="ocaml" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(.76136 0 0 .76136 11.616 19.98)"><path d="M83.02 101.645l.023-.062c-.035-.159-.047-.195-.024.062z" fill="none" stroke-width="1.028"/><linearGradient id="hpa" gradientUnits="userSpaceOnUse" x1="-696.735" y1="97.7" x2="-696.735" y2="142.997" gradientTransform="matrix(1.02783 0 0 1.02783 776.895 2.337)"><stop offset="0" stop-color="#f29100"/><stop offset="1" stop-color="#ec670f"/></linearGradient><path d="M82.313 138.79c-.471-1.004-1.904-3.621-2.624-4.46-1.562-1.828-1.927-1.966-2.386-4.275-.799-4.02-2.913-11.31-5.405-16.341-1.286-2.596-3.426-4.777-5.385-6.66-1.71-1.652-5.565-4.431-6.237-4.294-6.296 1.257-8.249 7.432-11.21 12.323-1.638 2.705-3.374 5.007-4.665 7.885-1.192 2.646-1.087 5.577-3.128 7.849-2.093 2.333-3.454 4.814-4.48 7.829-.194.574-.747 6.596-1.348 8.015l9.357-.659c8.719.594 6.2 3.936 19.81 3.208l21.487-.665c-.666-1.97-1.584-4.25-1.938-4.991-.599-1.248-1.352-3.69-1.848-4.763z" fill="url(#hpa)" stroke-width="1.028"/><linearGradient id="hpb" gradientUnits="userSpaceOnUse" x1="-666.972" y1="142.12" x2="-666.972" y2="142.12" gradientTransform="matrix(1.02783 0 0 1.02783 776.895 2.337)"><stop offset="0" stop-color="#f29100"/><stop offset="1" stop-color="#ec670f"/></linearGradient><linearGradient id="hpc" gradientUnits="userSpaceOnUse" x1="-675.228" y1="-1.28" x2="-675.228" y2="142.967" gradientTransform="matrix(1.02783 0 0 1.02783 776.895 2.337)"><stop offset="0" stop-color="#f29100"/><stop offset="1" stop-color="#ec670f"/></linearGradient><path d="M109.553 94.296c-1.652 1.193-4.88 4.06-11.902 5.145-3.152.487-6.1.527-9.335.365-1.584-.076-3.077-.157-4.665-.177-.936-.008-4.074-.107-3.919.193l-.349.871c.054.287.169 1.004.2 1.177.129.704.165 1.265.192 1.912.048 1.331-.11 2.719-.043 4.062.141 2.787 1.175 5.326 1.306 8.137.143 3.13 1.69 6.442 3.188 8.998.569.973 1.434 1.084 1.811 2.283.442 1.373.024 2.83.239 4.293.842 5.675 2.477 11.606 5.032 16.728.018.043.038.09.06.128 3.156-.53 6.318-1.665 10.418-2.271 7.517-1.115 17.972-.54 24.688-1.17 16.993-1.597 26.216 6.97 41.478 3.459V22.459c0-11.84-9.594-21.438-21.435-21.438H19.239C7.4 1.021-2.197 10.62-2.197 22.458v46.774c3.067-1.11 7.479-7.635 8.861-9.222 2.419-2.775 2.858-6.315 4.062-8.544 2.743-5.078 3.215-8.57 9.451-8.57 2.907 0 4.061.67 6.027 3.31 1.368 1.834 3.731 5.224 4.837 7.49 1.277 2.615 3.357 6.153 4.272 6.867.677.53 1.35.928 1.976 1.163 1.012.38 1.848-.316 2.525-.855.863-.687 1.235-2.088 2.035-3.957 1.152-2.696 2.408-5.926 3.122-7.054 1.237-1.949 1.658-4.261 2.993-5.381 1.97-1.652 4.54-1.768 5.246-1.908 3.957-.781 5.755 1.906 7.704 3.645 1.276 1.138 3.019 3.432 4.256 6.507.967 2.4 2.199 4.622 2.714 6.008.497 1.339 1.725 3.484 2.453 6.055.661 2.336 2.43 4.125 3.102 5.235 0 0 1.029 2.882 7.285 5.516 1.357.572 4.1 1.501 5.736 2.096 2.718.988 5.351.86 8.704.458 2.391 0 3.686-3.462 4.772-6.234.643-1.639 1.259-6.334 1.678-7.667.406-1.297-.544-2.3.265-3.437.946-1.327 1.508-1.399 2.054-3.129 1.172-3.704 7.95-3.89 11.761-3.89 3.176 0 2.772 3.083 8.16 2.028 3.086-.605 6.059.398 9.335 1.265 2.758.732 5.352 1.566 6.906 3.385 1.005 1.178 3.5 7.08.958 7.331.244.3.423.84.88 1.135-.566 2.226-3.03.64-4.4.355-1.845-.383-3.147.057-4.952.856-3.085 1.374-7.598 1.214-10.286 3.452-2.281 1.898-2.277 6.133-3.34 8.507-.002-.001-2.955 7.6-9.402 12.248z" fill="url(#hpc)" stroke-width="1.028"/><linearGradient id="hpd" gradientUnits="userSpaceOnUse" x1="-735.137" y1="90.833" x2="-735.137" y2="141.967" gradientTransform="matrix(1.02783 0 0 1.02783 776.895 2.337)"><stop offset="0" stop-color="#f29100"/><stop offset="1" stop-color="#ec670f"/></linearGradient><path d="M38.247 105.09c-1.467-.15-2.83-.317-4.256-.605-2.662-.536-5.57-1.06-8.193-1.688-1.592-.385-6.895-2.263-8.048-2.792-2.702-1.246-4.496-4.63-6.609-4.282-1.348.22-2.662.682-3.5 2.042-.685 1.11-.917 3.016-1.391 4.294-.55 1.485-1.5 2.87-2.331 4.284-1.53 2.595-4.282 4.941-5.468 7.469-.239.52-.45 1.101-.649 1.708V144.415a48.57 48.57 0 0 1 4.45.96c11.955 3.19 14.872 3.46 26.598 2.119l1.1-.146c.897-1.867 1.59-8.227 2.171-10.195.454-1.51 1.077-2.712 1.313-4.253.223-1.463-.02-2.858-.146-4.188-.329-3.332 2.427-4.522 3.742-7.384 1.186-2.589 1.871-5.535 2.853-8.181.941-2.54 2.41-6.13 4.918-7.408-.305-.355-5.237-.518-6.554-.65z" fill="url(#hpd)" stroke-width="1.028"/></g></symbol><symbol viewBox="0 0 24 24" id="pdf" xmlns="http://www.w3.org/2000/svg"><path d="M14 9h5.5L14 3.5V9M7 2h8l6 6v12a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2m4.93 10.44c.41.9.93 1.64 1.53 2.15l.41.32c-.87.16-2.07.44-3.34.93l-.11.04.5-1.04c.45-.87.78-1.66 1.01-2.4m6.48 3.81c.18-.18.27-.41.28-.66.03-.2-.02-.39-.12-.55-.29-.47-1.04-.69-2.28-.69l-1.29.07-.87-.58c-.63-.52-1.2-1.43-1.6-2.56l.04-.14c.33-1.33.64-2.94-.02-3.6a.853.853 0 0 0-.61-.24h-.24c-.37 0-.7.39-.79.77-.37 1.33-.15 2.06.22 3.27v.01c-.25.88-.57 1.9-1.08 2.93l-.96 1.8-.89.49c-1.2.75-1.77 1.59-1.88 2.12-.04.19-.02.36.05.54l.03.05.48.31.44.11c.81 0 1.73-.95 2.97-3.07l.18-.07c1.03-.33 2.31-.56 4.03-.75 1.03.51 2.24.74 3 .74.44 0 .74-.11.91-.3m-.41-.71l.09.11c-.01.1-.04.11-.09.13h-.04l-.19.02c-.46 0-1.17-.19-1.9-.51.09-.1.13-.1.23-.1 1.4 0 1.8.25 1.9.35M8.83 17c-.65 1.19-1.24 1.85-1.69 2 .05-.38.5-1.04 1.21-1.69l.48-.31m3.02-6.91c-.23-.9-.24-1.63-.07-2.05l.07-.12.15.05c.17.24.19.56.09 1.1l-.03.16-.16.82-.05.04z" fill="#f44336"/></symbol><symbol viewBox="0 0 24 24" id="perl" xmlns="http://www.w3.org/2000/svg"><path d="M12 14c-1 0-3 1-3 2 0 2 3 2 3 2v-1a1 1 0 0 1-1-1 1 1 0 0 1 1-1v-1m0 5s-4-.5-4-2.5c0-3 3-3.75 4-3.75V11.5c-1 0-5 1.5-5 4.5 0 4 5 4 5 4v-1M10.07 7.03l1.19.53c.43-2.44 1.58-4.06 1.58-4.06-.43 1.03-.71 1.88-.89 2.55C13.16 3.55 15.61 2 15.61 2a15.916 15.916 0 0 0-2.64 3.53c1.58-1.68 3.77-2.78 3.77-2.78-2.69 1.72-3.9 4.45-4.2 5.21l.55.08c0 .52 0 1 .25 1.38C14.1 11.31 18 11.47 18 16s-4.03 6-6.17 6C9.69 22 5 21.03 5 16s4.95-5.07 5.83-7.08c.12-.38-.76-1.89-.76-1.89z" fill="#9575cd"/></symbol><symbol viewBox="0 0 24 24" id="php" xmlns="http://www.w3.org/2000/svg"><path d="M12 18.08c-6.63 0-12-2.72-12-6.08s5.37-6.08 12-6.08S24 8.64 24 12s-5.37 6.08-12 6.08m-5.19-7.95c.54 0 .91.1 1.09.31.18.2.22.56.13 1.03-.1.53-.29.87-.58 1.09-.28.22-.71.33-1.29.33h-.87l.53-2.76h.99m-3.5 5.55h1.44l.34-1.75h1.23c.54 0 .98-.06 1.33-.17.35-.12.67-.31.96-.58.24-.22.43-.46.58-.73.15-.26.26-.56.31-.88.16-.78.05-1.39-.33-1.82-.39-.44-.99-.65-1.82-.65H4.59l-1.28 6.58m7.25-8.33l-1.28 6.58h1.42l.74-3.77h1.14c.36 0 .6.06.71.18.11.12.13.34.07.66l-.57 2.93h1.45l.59-3.07c.13-.62.03-1.07-.27-1.36-.3-.27-.85-.4-1.65-.4h-1.27L12 7.35h-1.44M18 10.13c.55 0 .91.1 1.09.31.18.2.22.56.13 1.03-.1.53-.29.87-.57 1.09-.29.22-.72.33-1.3.33h-.85l.5-2.76h1m-3.5 5.55h1.44l.34-1.75h1.22c.55 0 1-.06 1.35-.17.35-.12.65-.31.95-.58.24-.22.44-.46.58-.73.15-.26.26-.56.32-.88.15-.78.04-1.39-.34-1.82-.36-.44-.99-.65-1.82-.65h-2.75l-1.29 6.58z" fill="#1E88E5"/></symbol><symbol viewBox="0 0 79 78" id="postcss" xmlns="http://www.w3.org/2000/svg"><title>postcss-logo-symbol</title><g transform="translate(5.48 5.52) scale(.85425)" fill="#e53935" fill-rule="evenodd" stroke="#e53935" stroke-width="1.519"><path d="M15.447 32.623c.106.08.29.132.106.29-.132.184-.29.342-.395.553-.105.185-.184.237-.342.106.21-.343.42-.66.63-.95zM68.342 60.24c0 .078.026.13.026.21.053-.105.053-.158.08-.21zm0 .236v-.026zm-5.368 10.277l-4.58-25.402c-.078-.025-.183-.077-.368-.13.053.105.08.184.106.263.13-.026.184-.026.236-.052 0-.026 0-.052.027-.08l4.58 25.404zm-4.737-31.12c-.026.078-.026.158-.026.237 0-.08 0-.16.028-.238zm.026.526c-.026 0-.026 0-.052-.028v.026c.028.026.028.026.054 0zm-.052.21v-.185c-.077.026-.156.026-.262.053.132.05.264.078.264.13z"/><path d="M78.71 33.967c-.052-1.028-.078-2.056-.184-3.083-.184-1.397-.368-2.82-.684-4.19-.237-1.133-.63-2.214-1.026-3.294-.5-1.265-1-2.556-1.632-3.768-1.026-1.95-2.368-3.69-3.605-5.508-.818-1.16-1.87-2.108-2.66-3.294-.447-.685-1.105-1.264-1.763-1.79-1.053-.845-2.158-1.61-3.263-2.347a32.525 32.525 0 0 0-2.58-1.634c-.71-.397-1.473-.713-2.21-1.056-.842-.395-1.658-.87-2.605-1.054-.238-.05-.448-.13-.685-.21-.605-.21-1.184-.447-1.79-.632-.92-.29-1.815-.632-2.763-.87C50.342 1 49.394.843 48.446.71 47.394.555 46.316.5 45.262.397a26.83 26.83 0 0 0-2.026-.184C42.236.16 41.21.16 40.21.134c-.5-.027-1.026-.08-1.526-.053-.763.026-1.526.105-2.29.21-.736.08-1.473.21-2.183.317-.867.105-1.735.158-2.604.264-.816.106-1.658.264-2.473.396-.29.053-.58.158-.87.21-.63.132-1.288.185-1.92.396-1.13.344-2.263.74-3.368 1.16-1.027.422-2.027.87-3 1.397-1 .552-1.948 1.21-2.895 1.844a45.325 45.325 0 0 0-2.66 1.923c-.84.66-1.63 1.397-2.394 2.135-.42.42-.763.922-1.158 1.396-.657.765-1.315 1.502-1.947 2.293-.524.66-1 1.344-1.5 2.03-.893 1.21-1.656 2.502-2.366 3.794-.29.527-.553 1.054-.816 1.58-.395.79-.816 1.555-1.184 2.372-.264.554-.474 1.16-.632 1.766-.367 1.292-.736 2.61-1.078 3.9-.316 1.16-.395 2.372-.42 3.558-.027 1.054.078 2.082.183 3.136.027.264-.13.58.184.79-.105.29-.026.45.13.5-.182.29.08.476-.024.74-.027.052.08.157.13.236 0 .08-.025.185 0 .264.028.237.133.474.133.738 0 .184.157.395.21.58.026.078 0 .21-.053.263-.158.184-.132.342.105.448.133.342.08.5.054.66.052.236-.027.315 0 .368.21.422.29.896.315 1.37 0 .106.053.212.106.343.026 0 0 .5 0 .5.13-.078.237-.104.368-.157.08.342.158.66.263.95.132.21.132.314.08.34.105.474.157.922.34 1.37 0-.5-.05-1-.13-1.475.368.132.684.263.895.263.027-.08.053-.184.08-.237-.158-.157-.29-.394-.448-.552.053.21 0 .29 0 .37-.105-.054-.237-.107-.368-.16.105-.13.21-.263.368-.42 0-.238-.13-.45-.5-.423.158-.052.316-.13.5-.184.29-.157-.026-.447-.026-.816.026-.447-.237-.895-.316-1.37-.132-.737-.105-1.844-.184-2.582-.158-.132-.29.21-.316.237.08.632.158 1.264.21 1.897-.157-.527-.263-1.107-.394-1.74-.027.185-.053.264-.053.37-.13.13-.026.29.053.474-.184-.08-.395-.052-.395-.052v.738c-.262-.264-.34-.474-.473-.66-.052-.21-.08-.42-.13-.63.05-.133 0-.212 0-.29a15.968 15.968 0 0 1-.08-.634c.026-.026-.026-.42-.026-.42.21.025.343.05.474.05-.263-.34-.08-.552.027-.763.053-.106.237-.13.29-.238.21-.395.553-.71.553-1.212 0-.237.08-.5.105-.738.053-.448.105-.896.13-1.344.054-.58 0-1.16.133-1.713.212-.92.475-1.843.764-2.766.21-.66.448-1.29.71-1.95.395-1.028.764-2.056 1.264-3.03.71-1.424 1.526-2.794 2.316-4.19.5-.87 1.026-1.687 1.58-2.53.525-.817 1.05-1.66 1.657-2.425a21.452 21.452 0 0 1 2.79-2.978c1.053-.948 2.053-1.923 3.184-2.793a32.218 32.218 0 0 1 4.685-3.005c1.343-.71 2.737-1.266 4.132-1.793.895-.342 1.868-.5 2.79-.79 1.052-.343 2.105-.5 3.21-.527.71-.027 1.395-.106 2.105-.185.632-.05 1.263-.104 1.948-.183-.08.105-.106.158-.132.21-.288.422-.604.844-.894 1.265-.237.343-.5.712-.737 1.054-.422.555-.87 1.108-1.264 1.688-.605.87-1.158 1.766-1.79 2.635-.63.843-1.315 1.634-1.973 2.45-.868 1.134-1.684 2.293-2.552 3.426-.79 1.08-1.63 2.11-2.394 3.19-.684.947-1.29 1.95-1.948 2.923-.973 1.45-1.947 2.872-2.92 4.322a271.93 271.93 0 0 1-2.316 3.294c-.053.08-.132.104-.21.157-.21.342-.21.527-.29.685-.21.395-.42.79-.658 1.16-.132.21-.316.394-.474.605-.026-.316.42-.474.21-.87-.13.212-.263.396-.394.607l-.316.63c.105.08.29.133.105.29-.08.133-.158.29-.237.423a.954.954 0 0 0 .29-.264c0 .29-.158.526-.29.763-.105.21-.368.37-.552.527.026.027.21.106.237.132.237-.08.316-.21.343-.132.08-.105.158-.184.184-.263.104-.264.262-.474.525-.58.106-.053.184-.132.263-.21.79-.818 1.606-1.608 2.316-2.478 1.106-1.345 2.106-2.74 3.16-4.11.446-.58.973-1.16 1.446-1.714.078.606.026 1.185 0 1.74-.08.974-.132 1.95-.21 2.95-.027.395 0 .79-.027 1.186 0 .105-.08.184-.08.29 0 .263.08.553.08.817-.08.975-.186 1.923-.265 2.898-.027.21.078.422.13.607-.13 1.422.16 2.925-.078 4.427.184-.29.237-.474.237-.658.025-.158 0-.316 0-.5v-.264c.025-.475.13-.975.078-1.45-.053-.527-.053-1.027.053-1.528.053-.21-.026-.474.106-.738v.395c-.026 1.5.027 3.003-.183 4.505-.027.132.08.37-.21.343-.238.474.052.817-.21 1.08-.054.053.05.29.077.448-.106.317-.106.317.052.343.026.58.08 1.106.105 1.66.42-1 .21-2.03.396-3.058.026.422.053.844.026 1.29 0 .687-.026 1.345-.052 2.03 0 .132-.027.264-.053.396-.08.37-.105.738-.237 1.08-.105.264-.052.66-.052.975v1.003c.105.448-.027.685.052.948-.08.265-.105.344-.08.423l.08.395c.527-.053.29.343.5.553-.158.212-.105.29-.105.397 0 .237-.025.448-.052.685 0 .606-.026 1.212-.026 1.792 0 .08.026.157.026.236 0 .054-.026.74-.026.74.053.078 0 .157-.08.236-.025 0-.104-3.347-.104-3.347h-.395c-.052 1.58.08 3.003-.21 4.48-.316.025-.42.078-.764.078-.816 0-1.632 0-2.448.026-.974 0-1.92.026-2.895.026-.472 0-.972.054-1.446.054-.632 0-1.29-.08-1.92-.08-.975 0-1.922.08-2.896.106-.71.026-1.42.026-2.13.053-.475.025-.95.05-1.422.104-.21.026-.395.105-.658.184-.08 0-.263-.026-.42 0-.265.053-.5.21-.765.264-.395.08-.5.184-.448.58v.263c-.026.052.58-.08.58-.08-.054 0-.08.158-.16.29.212-.08.343-.132.475-.184.395.185.737.08 1.052.16 1.026.262 2.078.37 3.13.473.685.053 1.343.08 2.027.105.973.053 1.947.106 2.92.106.816 0 1.606-.08 2.42-.08 1.13 0 2.264.052 3.395.08.237 0 .5-.028.763-.028h1.92c1.712-.052 3.422-.08 5.133-.13.975-.028 1.975-.08 2.948-.107l3-.08c1.158-.026 2.316-.026 3.448-.05.868 0 1.71-.03 2.58-.055.972-.026 1.972-.105 2.946-.157.527-.027 1.054-.08 1.58-.132.632-.052 1.29-.13 1.92-.157.948-.054 1.922-.08 2.87-.133 1.184-.078 2.368-.183 3.578-.21 1.106-.052 2.237-.026 3.343-.052.974-.027 1.948-.08 2.948-.106l1.66-.08s1.104-.026 1.657-.08c.947-.052 1.894-.157 2.842-.183.604-.027 1.21 0 1.815-.027.973-.026 1.973-.08 2.947-.08.367 0 .762.054 1.236.08-.21.185-.342.29-.5.422.105.026.21.08.316.132a.71.71 0 0 1-.42.13c-.054.133-.107.186-.16.45h.474c-.184 0-.342.237-.526.395-.21-.054-.395 0-.5.29.184.104.158.183.132.29-.316.104-.553.21-.42.552-.107.052-.238.105-.37.184-.13.21-.368.263-.316.553.106.025.21.08.29.104-.132.053-.263.132-.395.184-.473.29-.262.422-.157.554-.08.053-.158.105-.237.132.052.237.13.29.157.29a9.3 9.3 0 0 0-.395.316c-.08.237-.185.342-.29.5s-.158.37-.29.527c-.552.607-.947 1.32-1.657 1.793-.264.185-.5.422-.737.66-.474.447-.895.948-1.395 1.37a29.595 29.595 0 0 1-2.052 1.554 151.56 151.56 0 0 1-2.604 1.792c-.474.315-1 .552-1.5.842s-.974.554-1.474.843c-.316.21-.606.5-.948.66-.868.37-1.79.685-2.684 1.028-.87.37-1.5.685-2.158.922-.605.21-1.237.37-1.868.5-.21.054-.448 0-.685.027-.448.08-.895.186-1.343.238-1.158.158-2.316.264-3.473.422-.685.08-1.343.21-2.027.29-.473.026-.973-.026-1.447-.026-.342 0-.71.08-1.053.027-.552-.08-1.105-.21-1.658-.316-.13-.026-.316-.08-.42-.026-.21.106-.396-.052-.607 0-.13.027-.262-.08-.394-.08-.106-.025-.238.028-.37 0-.29-.078-.552-.183-.87-.157-.313.026-.63-.132-.97-.21-.475-.106-.92-.21-1.396-.317a2.38 2.38 0 0 1-.525-.237c-.685 0-1.133-.026-1.554-.185-.368-.13-.71-.315-1.105-.262-.104.026-.183-.026-.29-.026-.08-.106-.157-.317-.235-.317-.526.027-.842-.42-1.29-.553-.236-.08-.42-.343-.657-.422-.58-.237-1.052-.737-1.71-.816-.21-.027-.42-.132-.658-.21.08.104.13.183.21.262-.763-.37-1.473-.79-2.184-1.186-.104-.026-.183-.13-.262-.184l-.71-.474c-.395.08-.553-.08-.66-.132-.71-.5-1.525-.817-2.21-1.37-.29-.238-.63-.396-.84-.686-.37-.448-.817-.764-1.317-1.027-.394-.21-.762-.448-1.13-.685-.185-.132-.37-.29-.37-.58 0-.185-.078-.37-.315-.264-.105-.158-.21-.342-.342-.395-.316-.13-.526-.37-.763-.58s-.42-.5-.71-.605c-.527-.21-.843-.658-1.158-1.027-.738-.87-1.396-1.82-2.08-2.74-.053-.08-.158-.133-.237-.212.105.29.237.527.368.79-.262-.105-.446-.29-.604-.474-.027.027 1.815 3.057 1.815 3.057.16.237.29.475.448.712a.813.813 0 0 1-.79-.422c-.236-.42-.5-.684-1.026-.63a4.588 4.588 0 0 1-.13-.58c-.107 0-.185 0-.37-.027.37.58.685 1.08 1.027 1.66-.133-.08-.21-.132-.265-.158.473.5.815 1.133 1.42 1.45.132.605.816.895.974 1.475-.13-.027-.238-.053-.37-.08-.21-.263-.447-.526-.683-.816.052.184.13.342.236.474.316.395.606.79.974 1.133.132.134.316.187.316.424.21.105.29.13.368.13.054.16-.025.397.29.344.21.395.42.395.71.264.343.343.528.37.764.16 0 .13.026.262.026.368.105-.053.08-.132.08-.264.13.105.21.158.262.21.263.37.5.712.868 1.002.5.422.948.87 1.42 1.265.922.765 1.95 1.398 2.975 1.977 1.264.712 2.475 1.476 3.764 2.16 1.552.818 3.21 1.372 4.92 1.767.632.132 1.237.263 1.87.42.55.16 1.104.397 1.657.528.842.185 1.71.343 2.552.5.183.027.37.054.58.08.235.053.524-.053.577.027.132.21.237.104.395.078.184-.053.395-.053.605-.053.737.026 1.447.184 2.184.132.16 0 .396-.133.528.13.236-.105.368-.105.473-.13.028.236 0 .236-.05.262-.054.026-.133.053-.238.132.947.184 1.842.21 2.63 0 1.37.105 2.554-.053 3.686-.448.105.132.184.316.342.053.052-.08.184-.107.29-.133.236-.053.526-.158.736-.08.238.08.317-.13.5-.13.317 0 .606-.027.896-.08.158-.026.316-.105.5-.158a1.285 1.285 0 0 0-.58-.133c.317-.158.606-.29.896-.42-.053.078-.106.183-.21.183h.367c-.08 0-.185.237-.316.395.946-.237 1.814-.448 2.657-.66-.29-.552.315-.367.526-.684-.263.08-.526.158-.79.21.895-.447 1.816-.842 2.71-1.237-.13.158-.29.237-.525.37.158.025.263.025.342.05.42.133.316-.262.447-.5.5 0 .71-.078.947-.158.263-.08.526-.158.79-.263.42-.184.815-.42 1.236-.63.08-.028.21 0 .316 0 .29-.186.394-.344.473-.318.37.053.63-.08.736-.42.184-.133.316-.238.447-.318.578-.316 1.13-.632 1.71-.948.21 0 .316 0 .368-.027.344-.16.66-.342.975-.527a2.258 2.258 0 0 1-.263-.13c.262-.054.34-.08.5-.133.63-.74 1.5-1.24 2.157-1.82.29-.026.29-.105.29-.157.104-.132.21-.29.34-.396.58-.527 1.21-.975 1.737-1.528a37.16 37.16 0 0 0 2.184-2.374c.63-.738 1.264-1.475 1.79-2.292.737-1.133 1.368-2.293 2.026-3.48.474-.842.895-1.685 1.37-2.528.05-.08.157-.185.236-.185.71-.08 1.422-.13 2.106-.21.158-.026.342-.13.5-.21-.08-.132-.132-.29-.21-.422-.106-.16-.264-.29-.37-.45-.104-.13-.183-.29-.262-.447-.08-.13-.158-.236-.237-.37a9.7 9.7 0 0 1-.45-.894c-.026-.08-.08-.21-.052-.29.474-1.027.658-2.134 1.105-3.162.447-1.054.58-2.24.79-3.373.184-1.08.29-2.16.42-3.24.08-.764.185-1.502.21-2.266.16-1.212.106-2.346.08-3.48-.026-1-.08-2.028-.13-3.03zM12.685 66.405c-.184-.21-.342-.448-.526-.658l.08-.08c.287.317.577.633.866.976-.158-.08-.342-.132-.42-.238zm.42.238c.08-.027.16-.027.238-.053.08.132.132.29.21.448-.368-.027-.552-.185-.447-.395zm27.37 10.883v-.08c.5-.052.973-.105 1.473-.157v.077c-.5.08-.973.13-1.473.158zm6.63-.685c-.367.08-.762.133-1.13.186-.132.026-.29.158-.342-.08-.053.027-.106.027-.158.054.13.394.447.078.71.236-.58.08-1.13.132-1.684.21v-.052c.16-.026.343-.053.5-.08v-.078a7.743 7.743 0 0 0-.79-.053c-.077 0-.183.106-.262.132-.105.026-.21.053-.342.053-.447.026-.894.026-1.316.052-.027 0-.08-.026-.106-.026v-.08c1.763-.236 3.5-.473 5.263-.71.027.052.027.105.053.157-.158 0-.263.055-.395.08zm.396-.262c.606-.08 1.16-.132 1.738-.21-1.21.342-1.605.394-1.737.21zM24.58 23.374c.84-1.16 1.71-2.32 2.552-3.505.263-.345.473-.714.736-1.056.08-.106.185-.158.316-.264l-.026-.05c.105-.133.21-.24.263-.344.134-.21.213-.448.318-.685a.385.385 0 0 1 .105-.103c.37.184.37-.21.5-.343.237-.264.474-.553.684-.817.158-.21.316-.395.448-.632.026-.08-.053-.21-.08-.317h-.078c.08-.052.158-.13.237-.184.026 0 .026 0 .052-.026.158-.238.316-.475.474-.686.315-.42.657-.842 1.025-1.21-.052.13-.105.263-.158.368.027 0 .027.027.053.027.316-.422.658-.817.974-1.24-.027-.025-.053-.052-.08-.052-.13.132-.236.264-.368.396-.026-.027-.052-.053-.08-.053.265-.343.528-.685.79-1.08.053.08.106.184.21.395.107-.263.212-.447.29-.632-.078.08-.183.158-.262.238l-.08-.08.474-.71c.5-.712 1-1.45 1.5-2.162.185-.263.42-.474.58-.738.5-1 1.29-1.792 1.894-2.714.132-.184.316-.342.474-.5.13-.16.237-.106.342.026.71.896 1.42 1.818 2.13 2.714.528.66 1.054 1.29 1.554 1.976.605.844 1.184 1.687 1.79 2.53.684.975 1.368 1.95 2.026 2.95 1 1.477 1.947 2.953 2.947 4.428.737 1.08 1.474 2.135 2.184 3.215h-1.344c-1.236-.025-2.5-.13-3.736-.078-1.684.08-3.394.264-5.078.396-2.132.185-4.29.21-6.42.21-.765 0-1.528.107-2.29.16-.922.052-1.817.105-2.738.13-1.08.054-2.13.08-3.21.107-.606.026-1.237 0-1.895 0zm30.183 12.12v.238c-.026 0-.052.027-.105.027-.105-.37-.21-.766-.342-1.135-.263-.765-.553-1.53-1.027-2.214-.528-.737-1-1.5-1.528-2.265-.13-.185-.316-.343-.474-.5-.553-.607-1.106-1.24-1.816-1.687a21.485 21.485 0 0 0-3.29-1.688 7.374 7.374 0 0 1-.92-.474h.63l4.5-.08c.974-.025 1.922-.025 2.895-.078.236 0 .368.08.5.29.236.395.473.79.736 1.186.027.052.08.13.08.21 0 .58 0 1.186.026 1.766.025.606.08 1.186.104 1.792 0 .606-.053 1.238-.026 1.87.027.897.053 1.82.053 2.74zM26.447 26.67c1.237-.053 2.42-.132 3.632-.185.945-.053 1.92-.08 2.866-.132.395-.025.764-.05 1.158 0-.42.212-.842.423-1.21.686-.474.316-.92.737-1.395 1.08-.475.342-.896.764-1.29 1.212-.5.605-1.053 1.132-1.58 1.712-.37.422-.79.817-1.105 1.265-.447.58-.842 1.21-1.263 1.87.132-2.504.29-4.98.184-7.51zm17.185 25.35c-.843.21-1.71.448-2.58.553-.736.106-1.5.08-2.263.08a25.42 25.42 0 0 1-2.028-.08c-.763-.078-1.526-.157-2.263-.5-.633-.29-1.29-.553-1.92-.87-.634-.316-1.265-.684-1.74-1.264-.34-.423-.815-.765-1.236-1.134.08.316.263.58.553.764-.132.158-.316.08-.58-.343-.078.053-.157.08-.21.106.08-.185.158-.37.237-.527-.105-.21-.237-.448-.342-.66-.21-.342-.42-.71-.605-1.053-.053-.08-.053-.158-.105-.237a5.893 5.893 0 0 1-.37-.475c-.21-.315-.394-.657-.657-.974 0 .08.027.158.027.264-.027 0-.053.026-.053.026l-.554-1.344c-.026 0-.026 0-.052.026l.473 1.74c-.026 0-.052.025-.08.025-.077-.104-.156-.21-.21-.34-.052-.212-.21-.212-.34-.133-.08.053-.133.237-.106.316.185.448.395.896.606 1.344.052.158.105.29.184.448.027.053.106.105.106.184.106.21.185.42.316.606.237.316.5.632.737.948.235.316.445.66.656.975.026.053.105.053.13.08.133.395.58.684.896.526.08.606.737.817 1 1.397a11.957 11.957 0 0 1-.763-.343c-.027.026-.027.052-.054.105.316.158.632.316.92.5.265.16.528.317.765.5.316.29.685.45 1.13.554a.282.282 0 0 0-.05-.107c.736.343 1.5.712 2.078 1-2.737.054-5.658.107-8.685.16 0-.5-.026-.975-.026-1.476 0-.21.052-.395.025-.606-.08-1.21-.08-2.424-.237-3.61-.157-1.264-.157-2.503-.13-3.77.025-.683-.027-1.394-.054-2.08 0-.922 0-1.82.028-2.74 0-.132.053-.237.106-.37h.08c.025.054 0 .133.05.16.08.08.212.21.265.184.157-.106.394-.21.447-.37.13-.315.184-.658.184-.974 0-.236.106-.394.21-.553.054-.08.08-.158.133-.263-.105-.08-.21-.132-.342-.237.106-.29.08-.633.475-.79.052-.027.052-.16.08-.238.025-.213.05-.45.078-.66.052.08.08.105.13.157a.42.42 0 0 1 .054-.08c0-.104-.026-.315 0-.315.316-.053.184-.395.342-.553.025-.028-.027-.107-.027-.16 0-.052 0-.13.026-.13.367-.08.315-.475.552-.66.08-.053.105-.13.21-.263.21.368-.158.553-.184.816.446-.263.578-.895.315-1.08.105-.08.21-.184.29-.29.29-.316.604-.606.868-.922.185-.236.29-.526.474-.763.106-.132.316-.237.474-.317.474-.262.92-.552 1.21-1 .053-.053.132-.105.21-.158.08-.053.238-.053.264-.132.027-.052-.052-.184-.105-.263.104-.053.21-.158.42-.264-.08.158-.105.264-.158.37l.13.13c.238-.184.606-.394.843-.552 0-.025-.132-.13-.132-.13-.157.08-.394.21-.63.316.05-.08.05-.132.08-.158.367-.237.735-.474 1.13-.66.92-.42 1.842-.842 2.763-1.237.158-.08.37-.026.553-.026.078 0 .13 0 .21-.026.42-.132.842-.264 1.263-.37.183-.052.393-.078.58-.078.787.025 1.577.025 2.366.078.342.026.658.105.974.21a9.88 9.88 0 0 1 1.184.5c.447.24.868.502 1.29.792.763.5 1.473 1.054 2.236 1.502.737.448 1.316 1.054 1.79 1.74.58.816 1.237 1.554 1.5 2.555l.394 1.74c.08.316.264.632.185 1-.133.66-.238 1.345-.343 2.004-.052.265-.105.53-.078.79.05.82-.265 1.53-.58 2.268-.106.237-.264.475-.395.738a.798.798 0 0 0 .21.106l.237-.474c.027 0 .027 0 .053.027-.132.368-.237.764-.37 1.133-.314.817-.63 1.66-1.025 2.45-.21.448-.58.817-.842 1.24-.262.368-.473.763-.736 1.106-.237.29-.473.58-.79.79-.71.527-1.447 1.054-2.21 1.476-.473.29-1.026.448-1.552.58zm-14.027-1.4l-.026.027c-.055-.026-.134-.052-.186-.105l-.632-.95c-.052-.078-.08-.157-.052-.262.29.448.58.87.895 1.29zm16.37 3.61c1.183-.5 2.157-1.21 3.05-2.028.133-.132.264-.263.422-.37 1.106-.684 1.92-1.633 2.658-2.687.842-1.212 1.395-2.582 2.08-3.873a2.73 2.73 0 0 1 .157-.29c-.053 3.004.29 5.955.684 8.933-2.973.105-6 .21-9.052.316zm26.683-.79c-.026.053-.08.106-.105.16-.027-.054-.027-.133-.053-.24-.158.423-.5.212-.737.212-1.42.027-2.868.027-4.29.027-1.368 0-2.762 0-4.13.024-.448 0-.922.105-1.37.132-1.078.052-2.157.08-3.236.105-.08 0-.158-.13-.29-.236a1.81 1.81 0 0 1-.158.237c-.028-.052-.08-.104-.133-.183-.026.08-.053.158-.08.21H58c-.053-.368-.158-.71-.158-1.08 0-.79.08-1.58.105-2.372.027-.368 0-.71 0-1.054.106.08.185.133.29.21.052-.103.105-.182.158-.26 0 0-.053-.028-.106-.08.05-.027.104-.08.104-.106.026-.08.08-.158.08-.21 0-.185-.054-.343-.08-.5.026 0 .052 0 .08-.028l.157.79h.08c-.106-.183.236-.342-.053-.552-.026-.027.026-.185.026-.264-.08-.157-.13-.315-.21-.526.026-.026.105-.053.184-.08-.105-.052-.184-.104-.263-.13.263-.238.263-.37.026-.633.054-.025.106-.025.106-.05 0-.238 0-.475-.052-.71-.053-.266.08-.58-.316-.74a.79.79 0 0 0 .105.21s-.08.027-.158.08c-.342-.317-.13-.74-.21-1.213.184.053.316.106.447.16-.053-.186-.184-.397-.263-.634h-.107v-1.74c0 .027.184.027.29.054 0-.027.025-.053.025-.08-.08-.105-.185-.21-.29-.342l.053-.053c-.21-.262-.105-.63-.105-.71V39.4c.264.264-.13.606.264.764v-.263h-.027c-.026-.395-.026-.79-.052-1.186h-.052c-.027.054-.027.08-.054.133h-.052l.158-6.298c.263.342.552.66.736 1 .606 1.108 1.395 2.057 2.132 3.058.632.87 1.21 1.818 1.79 2.714.71 1.08 1.394 2.16 2.105 3.24a81.41 81.41 0 0 0 1.63 2.426c.5.71 1.028 1.396 1.554 2.082.446.606.92 1.212 1.367 1.818.527.738 1.053 1.475 1.58 2.187.262.368.552.737.84 1.106.16.21.396.37.554.5-.025 0-.052 0-.104-.026.08.105.13.184.184.237.29.158.316.316.158.554zM74 46.854v-.185c0 .052.026.13 0 .184zm.895-11.62c-.027 0-.184-.16-.21-.186-.027.08 0 .158-.053.264-.027-.078-.21-.052-.21-.13-.027.368.157.737.13 1.106.08-.053.395-.08.474-.158.027.026.08.052.106.052-.527.396-.395.79-.158 1.24.052.104.21.315.052.526-.052.053.027.21.053.343h.077v.05l-.237.08c-.052-.08-.367-.236-.367-.37v1.346c.263.08.263.448.368.633a.768.768 0 0 0 .107-.21l.027.024c-.027.158-.053.316-.106.475-.052.236-.105.447-.13.684 0 .026.05.08.05.105-.288.66-.13 1.396-.235 2.08-.08.5 0 1.03-.053 1.556-.054.448-.16.922-.264 1.37-.027.08-.08.105-.21.158.052-.316.026-.527-.027-.817-.028 0-.37-.184-.397-.184 0 .37.21.87.29 1.29-.08-.026-.395-.21-.42-.21-.054.316-.054.738-.08 1.08-.027.264-.263.5-.29.79 0 .16.184.264.158.528h.21c0-.526.238-1 .238-1.554h.078c.027.053.106.106.08.132-.053.29-.16.606-.132.896 0 .158.13.316.08.5-.054.16-.08.317-.107.554-.027-.132-.053-.184-.053-.263-.026 0-.263-.027-.29-.027-.026.158.185.316.158.448-.026.026-.052.026-.105.053l-.868-1.266c-.686-1-1.37-2.003-2.054-3.03a6.312 6.312 0 0 1-.475-.79 37.09 37.09 0 0 0-2.71-4.033c-.762-.974-1.37-2.03-2.08-3.055-.656-.975-1.314-1.924-1.972-2.9-.237-.315-.526-.605-.737-.948-.683-1.08-1.29-2.187-1.972-3.267-.58-.897-1.21-1.767-1.816-2.636-.21-.29-.42-.607-.632-.923a.37.37 0 0 1-.052-.182c-.053-.58-.106-1.16-.132-1.713 0-.527.053-1.054.053-1.608v-.474c0-.132.025-.237.025-.37.025-.025.052-.078.078-.104-.763 0-1.553-.028-2.316 0-.5.025-.763-.186-1.105-.555-1-1.133-1.737-2.424-2.605-3.636a162.42 162.42 0 0 0-2.5-3.427c-.685-.922-1.37-1.818-2.053-2.74-.764-1.054-1.5-2.108-2.29-3.162a381.983 381.983 0 0 0-2.895-3.794c-.45-.58-.95-1.133-1.45-1.74.343.054.66.106.975.133l1.264.08c.947.077 1.894.13 2.84.26.79.107 1.58.265 2.396.396 1.738.29 3.448.765 5.106 1.318.974.316 1.92.738 2.87 1.133 2.13.87 4.157 1.924 6.157 3.03.63.343 1 .896 1.472 1.397.685.712 1.37 1.423 2.027 2.16.762.87 1.472 1.766 2.21 2.662.657.79 1.34 1.58 2 2.372.21.237.37.527.552.79.42.633.895 1.24 1.263 1.924.262.502.42 1.082.604 1.635.262.817.526 1.607.79 2.424.183.606.34 1.24.472 1.87.106.423.08.87.21 1.29.16.556 0 1.16.16 1.715.025.053.05.132.078.185.105.104.184.21.026.368-.025.026-.025.13 0 .21.054-.052.08-.105.133-.184 0 .053.025.08.025.105 0 .104-.027.21 0 .315 0 .052.052.13.078.184.053-.054.105-.08.21-.16.237.897.264 1.793.264 2.715 0 .87.157 1.74-.21 2.583.078-.29-.106-.555-.027-.818z"/><path d="M58.08 45.482c.025 0 .052.027.052.027l-.027-.03c0-.025 0-.025-.026 0zm4.157 26.036c-.29.21-.58.395-.948.474-.028-.026-.028-.053-.054-.08.29-.184.605-.368.895-.553.027.05.08.104.106.157zM12.895 35.81c.29-.367.58-.736.894-1.105.025.026.235.08.262.105-.29.37-.685.87-.974 1.265-.054-.053-.133-.237-.185-.264zM5.42 48.725c-.21-.448-.42-.923-.63-1.37a.91.91 0 0 1 .236-.106c.29.42.42.92.632 1.37 0 0-.21.105-.237.105zm6.712-12.65c-.158.238-.316.502-.474.74-.026-.028-.316.104-.342.078.158-.237.552-.66.71-.896.027.026.053.053.106.08zM59.422 72.6c.025 0 .025-.026.052-.026.184.026.394.052.605.052-.344.237-.555.21-.66-.026zm-47.24-35.418c.028-.08.08-.158.133-.237.052 0 .13-.027.13-.027.107-.184.107-.316.212-.474-.026-.026-.053-.026-.08-.053-.157.108-.315.24-.473.345.053.052.053.08.053.132-.21-.027-.29.08-.395.368-.026.08-.158.106-.29.21-.026.054-.052.186-.105.317l.027.028c-.053.053-.132.08-.132.08-.158.157-.342.29-.5.447-.026.08-.052.158-.052.237.185-.184.5-.527.737-.738l.027.027c.105-.158.184-.316.29-.474.025.026.025.052.052.08-.08.21-.158.446-.237.657-.055.026-.134.08-.134.053-.105.08-.184.184-.29.263l-.473.316c-.263.237-.526.447-.816.685-.184.29-.368.553-.58.896.317-.08.396.053.37.317.368.052.395-.237.5-.448.026-.054.053-.16.105-.186.237-.21.5-.394.763-.605.053-.053.053-.16.053-.238 0-.026-.133-.026-.212-.053.237-.264.58-.71.816-1 .132-.08.263-.186.263-.265-.026-.29.158-.368.37-.474-.106-.08-.133-.157-.133-.183z"/><path d="M12.71 36.892c-.105.184-.21.342-.315.527l-.158-.08c-.105.605-.474 1.132-.842 1.237.105.053.21.106.29.08.078-.027.13-.16.183-.238l.71-1.028.238-.396-.105-.105zM3.948 48.46c.132 0 .264.026.42.026 0-.105.133-.08.133-.184h.08c0 .132.026.237.026.37h-.552c-.027-.027-.132-.186-.106-.212zm-.21-1.212c-.08-.08-.21-.158-.21-.237-.027-.104.052-.235.13-.367.054.184.08.342.132.527-.027.025-.053.052-.053.078zm.658-1.687c.105.266.21.556.316.82a.798.798 0 0 0-.21.105c-.105-.264-.237-.554-.342-.817a.652.652 0 0 1 .237-.106zm58.58 25.194c.13-.052.288-.08.5-.13-.238.183-.422.315-.58.473-.027-.026-.053-.053-.08-.053.053-.105.106-.184.16-.29zM30.63 15.074c.157-.106.29-.185.447-.29l.052.052c-.16.21-.29.42-.475.685-.026-.183-.026-.29-.053-.42-.026 0 0 0 .027-.026zm7.71 13.333c.237-.106.474-.21.763-.343-.026.158-.026.264-.026.37a.927.927 0 0 0-.264-.054c-.158.027-.448.238-.58.264-.025 0 .106-.21.106-.237zm19.74 22.346c.052.263.552.395.052.658.08.055.157.08.236.134a.2.2 0 0 1-.052.106c-.053.025-.158.078-.21.05-.027 0-.08-.104-.08-.157 0-.237.027-.474.053-.79z"/></g></symbol><symbol viewBox="0 0 24 24" id="powerpoint" xmlns="http://www.w3.org/2000/svg"><path d="M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2m7 1.5V9h5.5L13 3.5M8 11v2h1v6H8v1h4v-1h-1v-2h2a3 3 0 0 0 3-3 3 3 0 0 0-3-3H8m5 2a1 1 0 0 1 1 1 1 1 0 0 1-1 1h-2v-2h2z" fill="#d14524"/></symbol><symbol viewBox="0 0 67.47 70" id="powershell" xmlns="http://www.w3.org/2000/svg"><path d="M18.545 12.4c-3.014 0-6.08 2.34-6.873 5.248L1.91 53.438c-.793 2.908.996 5.248 4.01 5.248h42.887c3.014 0 6.08-2.34 6.873-5.248l9.761-35.79c.794-2.908-.993-5.248-4.007-5.248h-42.89zm4.848 6.243c.652.04 1.29.33 1.76.86l7.96 9.013-3.957 3.246 3.957-3.244 4.832 5.47c.037.042.06.088.094.131.026.034.057.06.082.096.02.028.032.057.05.086.057.087.105.176.15.267.028.06.055.117.08.178a2.546 2.546 0 0 1 .171.764c.005.073.01.146.008.219-.002.09-.01.178-.021.267a2.53 2.53 0 0 1-.036.217 2.56 2.56 0 0 1-.07.252c-.024.076-.048.15-.08.224a2.547 2.547 0 0 1-.111.22 2.503 2.503 0 0 1-.133.218 2.546 2.546 0 0 1-.147.187c-.058.07-.118.137-.185.202-.027.026-.048.057-.076.082-.037.032-.077.054-.116.084-.038.03-.07.065-.11.093L16.8 52.271a2.552 2.552 0 0 1-3.563-.626 2.553 2.553 0 0 1 .63-3.563l18.349-12.853-3.06-3.467-7.839-8.873a2.549 2.549 0 0 1 .225-3.608 2.546 2.546 0 0 1 1.85-.638zm22.441 28.214c1.377 0 2.255 1.083 1.969 2.43-.287 1.347-1.627 2.433-3.004 2.434l-9.957.006c-1.378 0-2.256-1.083-1.969-2.43.287-1.347 1.626-2.433 3.004-2.434l9.957-.006z" fill="#03a9f4" stroke-width="5.342" stroke-linejoin="round"/></symbol><symbol viewBox="0 0 210 210" id="prettier" xmlns="http://www.w3.org/2000/svg"><title>prettier-icon-dark</title><g transform="matrix(.9 0 0 .9 10.5 10.5)" fill="none" fill-rule="evenodd"><rect fill="#56B3B4" x="165" y="40" width="20" height="10" rx="5"/><rect fill="#EA5E5E" x="15" y="200" width="60" height="10" rx="5"/><rect fill="#BF85BF" x="135" y="120" width="40" height="10" rx="5"/><rect fill="#EA5E5E" x="75" y="120" width="50" height="10" rx="5"/><rect fill="#56B3B4" x="15" y="120" width="50" height="10" rx="5"/><rect fill="#BF85BF" x="15" y="160" width="60" height="10" rx="5"/><rect fill="#BF85BF" x="15" y="80" width="60" height="10" rx="5"/><rect fill="#F7BA3E" x="65" y="20" width="110" height="10" rx="5"/><rect fill="#EA5E5E" x="15" y="20" width="40" height="10" rx="5"/><rect fill="#F7BA3E" x="55" y="180" width="20" height="10" rx="5"/><rect fill="#56B3B4" x="55" y="60" width="20" height="10" rx="5"/><rect fill="#56B3B4" x="15" y="180" width="30" height="10" rx="5"/><rect fill="#F7BA3E" x="15" y="60" width="30" height="10" rx="5"/><rect fill="#56B3B4" x="95" y="100" width="90" height="10" rx="5"/><rect fill="#F7BA3E" x="45" y="100" width="40" height="10" rx="5"/><rect fill="#EA5E5E" x="15" y="100" width="20" height="10" rx="5"/><rect fill="#BF85BF" x="105" y="40" width="50" height="10" rx="5"/><rect fill="#56B3B4" x="15" y="40" width="80" height="10" rx="5"/><rect fill="#F7BA3E" x="45" y="140" width="100" height="10" rx="5"/><rect fill="#BF85BF" x="15" y="140" width="20" height="10" rx="5"/><rect fill="#EA5E5E" x="135" y="60" width="60" height="10" rx="5"/><rect fill="#F7BA3E" x="135" y="80" width="60" height="10" rx="5"/><rect fill="#56B3B4" x="15" width="130" height="10" rx="5"/></g></symbol><symbol viewBox="0 0 80 80" id="protractor" xmlns="http://www.w3.org/2000/svg"><defs><clipPath id="hxa"><path transform="scale(1 -1)" fill="#564b55" stroke-width="27.224" d="M-2.983-69.251h69.412v67.108H-2.983z"/></clipPath></defs><g transform="matrix(1.13039 0 0 -1.13039 5.714 82.137)" clip-path="url(#hxa)"><g transform="scale(.1)"><path d="M1180.54 92.324c-5.53 0-9.93-1.797-13.23-5.39-3.29-3.614-5.22-8.594-5.81-14.97h36.02c0 6.583-1.47 11.622-4.4 15.126-2.93 3.496-7.12 5.234-12.58 5.234zm2.84-62.656c-10.19 0-18.22 3.086-24.11 9.297-5.88 6.21-8.83 14.824-8.83 25.84 0 11.101 2.73 19.922 8.21 26.464 5.45 6.524 12.81 9.805 22.02 9.805 8.63 0 15.46-2.851 20.48-8.523 5.03-5.676 7.55-13.157 7.55-22.461v-6.613h-47.45c.21-8.086 2.26-14.22 6.12-18.418 3.89-4.18 9.34-6.29 16.38-6.29 7.42 0 14.76 1.563 22 4.669V34.14c-3.68-1.602-7.18-2.746-10.48-3.438-3.28-.684-7.24-1.035-11.89-1.035M1272.34 30.918v44.57c0 5.606-1.28 9.805-3.82 12.559-2.56 2.773-6.56 4.16-12.02 4.16-7.2 0-12.49-1.953-15.84-5.851-3.34-3.895-5.03-10.32-5.03-19.286V30.918h-10.42v68.887h8.47l1.71-9.422h.5c2.14 3.387 5.14 6.023 8.99 7.887 3.85 1.867 8.15 2.804 12.88 2.804 8.29 0 14.54-2.011 18.73-6.015 4.19-3.985 6.28-10.391 6.28-19.192V30.918h-10.43M1328.96 38.406c7.1 0 12.27 1.938 15.48 5.813 3.22 3.879 4.81 10.129 4.81 18.758v2.199c0 9.765-1.62 16.726-4.87 20.898-3.25 4.18-8.44 6.25-15.56 6.25-6.11 0-10.79-2.383-14.04-7.129-3.26-4.746-4.88-11.472-4.88-20.136 0-8.797 1.61-15.45 4.84-19.93 3.23-4.484 7.97-6.723 14.22-6.723zm20.85 1.762h-.56c-4.83-7.004-12.02-10.5-21.62-10.5-9.01 0-16.03 3.066-21.04 9.238-5 6.153-7.5 14.922-7.5 26.27 0 11.355 2.51 20.176 7.54 26.465 5.03 6.289 12.03 9.433 21 9.433 9.34 0 16.5-3.398 21.49-10.195h.81l-.43 4.96-.25 4.845v28.039h10.43V30.918h-8.49l-1.38 9.25M1434.91 38.27c1.85 0 3.63.136 5.34.421 1.72.274 3.09.547 4.1.84v-7.976c-1.15-.559-2.81-.996-5.01-1.36-2.18-.351-4.17-.527-5.94-.527-13.32 0-19.97 7.012-19.97 21.055V91.71h-9.88v5.027l9.88 4.336 4.38 14.707h6.04V99.805h20V91.71h-20V51.16c0-4.15.98-7.333 2.96-9.56 1.97-2.206 4.67-3.331 8.1-3.331M1463.81 65.43c0-8.809 1.76-15.508 5.27-20.118 3.53-4.609 8.69-6.906 15.53-6.906s12.01 2.297 15.56 6.875c3.53 4.602 5.3 11.301 5.3 20.149 0 8.75-1.77 15.41-5.3 19.953-3.55 4.539-8.77 6.824-15.69 6.824-6.82 0-11.99-2.246-15.47-6.73-3.46-4.48-5.2-11.16-5.2-20.047zm52.47 0c0-11.23-2.83-20-8.48-26.309-5.66-6.309-13.47-9.453-23.44-9.453-6.17 0-11.64 1.445-16.42 4.336-4.78 2.89-8.46 7.031-11.06 12.45-2.59 5.401-3.88 11.73-3.88 18.976 0 11.23 2.8 19.968 8.41 26.242 5.61 6.258 13.4 9.402 23.38 9.402 9.64 0 17.3-3.222 22.97-9.62 5.69-6.415 8.52-15.087 8.52-26.024M1591.71 92.324c-5.54 0-9.94-1.797-13.23-5.39-3.3-3.614-5.24-8.594-5.81-14.97h36c0 6.583-1.46 11.622-4.39 15.126-2.93 3.496-7.13 5.234-12.57 5.234zm2.83-62.656c-10.19 0-18.22 3.086-24.11 9.297-5.89 6.21-8.83 14.824-8.83 25.84 0 11.101 2.74 19.922 8.2 26.464 5.46 6.524 12.81 9.805 22.04 9.805 8.62 0 15.45-2.851 20.48-8.523 5.03-5.676 7.54-13.157 7.54-22.461v-6.613h-47.45c.21-8.086 2.25-14.22 6.13-18.418 3.87-4.18 9.33-6.29 16.36-6.29 7.43 0 14.77 1.563 22.01 4.669V34.14c-3.69-1.602-7.17-2.746-10.46-3.438-3.3-.684-7.27-1.035-11.91-1.035M1683.5 30.918v44.57c0 5.606-1.27 9.805-3.83 12.559-2.55 2.773-6.55 4.16-12.01 4.16-7.2 0-12.48-1.953-15.83-5.851-3.35-3.895-5.03-10.32-5.03-19.286V30.918h-10.43v68.887h8.48l1.69-9.422h.51c2.14 3.387 5.14 6.023 8.99 7.887 3.84 1.867 8.15 2.804 12.88 2.804 8.3 0 14.54-2.011 18.74-6.015 4.19-3.985 6.29-10.391 6.29-19.192V30.918h-10.45M1740.11 38.406c7.12 0 12.28 1.938 15.49 5.813 3.21 3.879 4.81 10.129 4.81 18.758v2.199c0 9.765-1.62 16.726-4.87 20.898-3.25 4.18-8.43 6.25-15.56 6.25-6.12 0-10.8-2.383-14.05-7.129-3.24-4.746-4.88-11.472-4.88-20.136 0-8.797 1.64-15.45 4.85-19.93 3.22-4.484 7.96-6.723 14.21-6.723zm20.87 1.762h-.57c-4.82-7.004-12.03-10.5-21.62-10.5-9.01 0-16.02 3.066-21.03 9.238-5 6.153-7.52 14.922-7.52 26.27 0 11.355 2.52 20.176 7.55 26.465 5.02 6.289 12.02 9.433 21 9.433 9.34 0 16.5-3.398 21.48-10.195h.83l-.44 4.96-.25 4.845v28.039h10.43V30.918h-8.49l-1.37 9.25M1846.07 38.27c1.85 0 3.64.136 5.36.421 1.7.274 3.07.547 4.08.84v-7.976c-1.13-.559-2.8-.996-5-1.36-2.2-.351-4.18-.527-5.94-.527-13.33 0-19.99 7.012-19.99 21.055V91.71h-9.86v5.027l9.86 4.336 4.4 14.707h6.04V99.805H1855V91.71h-19.98V51.16c0-4.15.98-7.333 2.95-9.56 1.97-2.206 4.68-3.331 8.1-3.331M1894.26 92.324c-5.53 0-9.94-1.797-13.22-5.39-3.31-3.614-5.25-8.594-5.83-14.97h36.01c0 6.583-1.45 11.622-4.38 15.126-2.95 3.496-7.13 5.234-12.58 5.234zm2.83-62.656c-10.19 0-18.22 3.086-24.1 9.297-5.9 6.21-8.84 14.824-8.84 25.84 0 11.101 2.73 19.922 8.2 26.464 5.47 6.524 12.81 9.805 22.03 9.805 8.63 0 15.46-2.851 20.49-8.523 5.03-5.676 7.55-13.157 7.55-22.461v-6.613h-47.46c.22-8.086 2.26-14.22 6.13-18.418 3.87-4.18 9.33-6.29 16.37-6.29 7.42 0 14.75 1.563 22 4.669V34.14c-3.7-1.602-7.17-2.746-10.47-3.438-3.28-.684-7.25-1.035-11.9-1.035M1983.36 49.727c0-6.426-2.4-11.368-7.18-14.844-4.77-3.477-11.47-5.215-20.11-5.215-9.13 0-16.26 1.445-21.37 4.336v9.687a51.32 51.32 0 0 1 10.65-3.964c3.79-.977 7.45-1.457 10.97-1.457 5.46 0 9.64.87 12.57 2.609 2.95 1.738 4.41 4.394 4.41 7.95 0 2.694-1.17 4.98-3.5 6.894-2.32 1.914-6.85 4.152-13.6 6.757-6.41 2.383-10.97 4.473-13.67 6.25-2.71 1.778-4.72 3.81-6.04 6.067-1.31 2.254-1.98 4.96-1.98 8.113 0 5.606 2.29 10.04 6.86 13.281 4.57 3.25 10.84 4.883 18.79 4.883 7.42 0 14.66-1.515 21.74-4.531l-3.71-8.496c-6.9 2.851-13.17 4.277-18.79 4.277-4.94 0-8.67-.77-11.18-2.324-2.52-1.543-3.78-3.691-3.78-6.406 0-1.844.48-3.418 1.42-4.707.95-1.309 2.46-2.54 4.56-3.711 2.09-1.184 6.11-2.871 12.07-5.086 8.16-2.98 13.69-5.98 16.55-8.996 2.87-3.02 4.32-6.809 4.32-11.367M2021.28 38.27c1.85 0 3.64.136 5.35.421 1.71.274 3.09.547 4.09.84v-7.976c-1.14-.559-2.81-.996-5.01-1.36-2.18-.351-4.18-.527-5.93-.527-13.33 0-19.99 7.012-19.99 21.055V91.71h-9.87v5.027l9.87 4.336 4.4 14.707h6.02V99.805h20V91.71h-20V51.16c0-4.15 1-7.333 2.97-9.56 1.98-2.206 4.67-3.331 8.1-3.331M2053.61 30.918h-10.42v68.887h10.42zm-11.31 87.559c0 2.39.59 4.14 1.76 5.253 1.18 1.106 2.65 1.661 4.42 1.661 1.67 0 3.1-.567 4.32-1.7 1.22-1.132 1.82-2.871 1.82-5.214 0-2.344-.6-4.09-1.82-5.247-1.22-1.16-2.65-1.726-4.32-1.726-1.77 0-3.24.566-4.42 1.726-1.17 1.157-1.76 2.903-1.76 5.247M2121.59 30.918v44.57c0 5.606-1.27 9.805-3.83 12.559-2.55 2.773-6.55 4.16-12 4.16-7.21 0-12.49-1.953-15.84-5.851-3.35-3.895-5.03-10.32-5.03-19.286V30.918h-10.43v68.887h8.49l1.69-9.422h.5c2.15 3.387 5.14 6.023 8.99 7.887 3.85 1.867 8.16 2.804 12.88 2.804 8.3 0 14.54-2.011 18.74-6.015 4.19-3.985 6.29-10.391 6.29-19.192V30.918h-10.45M2159.29 77.742c0-4.812 1.35-8.465 4.08-10.926 2.72-2.48 6.51-3.71 11.37-3.71 10.19 0 15.28 4.953 15.28 14.831 0 10.344-5.16 15.532-15.47 15.532-4.9 0-8.67-1.32-11.31-3.965-2.63-2.649-3.95-6.555-3.95-11.762zm-5.67-58.387c0-3.73 1.58-6.55 4.72-8.488 3.14-1.922 7.65-2.879 13.52-2.879 8.75 0 15.24 1.309 19.45 3.926 4.21 2.617 6.31 6.172 6.31 10.652 0 3.723-1.15 6.32-3.45 7.754-2.31 1.457-6.65 2.168-13.01 2.168h-12.51c-4.74 0-8.43-1.12-11.06-3.386-2.65-2.266-3.97-5.508-3.97-9.747zm54.94 80.45v-6.582l-12.76-1.512c1.18-1.477 2.23-3.39 3.15-5.754.91-2.371 1.37-5.039 1.37-8.02 0-6.746-2.29-12.128-6.91-16.152-4.61-4.012-10.93-6.023-18.98-6.023-2.05 0-3.98.156-5.78.5-4.45-2.356-6.67-5.305-6.67-8.871 0-1.883.77-3.282 2.34-4.176 1.54-.902 4.21-1.36 7.97-1.36h12.2c7.46 0 13.19-1.574 17.19-4.707 4-3.144 6-7.714 6-13.71 0-7.618-3.06-13.426-9.17-17.43C2192.38 2.004 2183.46 0 2171.72 0c-9 0-15.95 1.68-20.82 5.027-4.88 3.352-7.34 8.079-7.34 14.211 0 4.18 1.35 7.813 4.03 10.88 2.68 3.046 6.45 5.116 11.32 6.21-1.77.8-3.24 2.031-4.44 3.711-1.19 1.68-1.78 3.633-1.78 5.84 0 2.52.66 4.707 2.01 6.602 1.34 1.882 3.44 3.71 6.34 5.468-3.56 1.465-6.46 3.953-8.71 7.48-2.23 3.516-3.35 7.54-3.35 12.06 0 7.55 2.26 13.37 6.79 17.452 4.52 4.082 10.93 6.133 19.22 6.133 3.6 0 6.86-.429 9.75-1.27h23.82M2284.61 91.71h-17.54V30.919h-10.43v60.793h-12.31v4.707l12.31 3.766v3.839c0 16.922 7.4 25.391 22.19 25.391 3.65 0 7.93-.73 12.82-2.195l-2.7-8.364c-4.03 1.301-7.46 1.946-10.31 1.946-3.93 0-6.85-1.309-8.73-3.926-1.89-2.617-2.84-6.816-2.84-12.598v-4.472h17.54V91.71M2302.87 65.43c0-8.809 1.76-15.508 5.28-20.118 3.52-4.609 8.7-6.906 15.52-6.906 6.84 0 12.02 2.297 15.57 6.875 3.54 4.602 5.3 11.301 5.3 20.149 0 8.75-1.76 15.41-5.3 19.953-3.55 4.539-8.78 6.824-15.69 6.824-6.83 0-11.99-2.246-15.46-6.73-3.48-4.48-5.22-11.16-5.22-20.047zm52.48 0c0-11.23-2.82-20-8.47-26.309-5.67-6.309-13.48-9.453-23.46-9.453-6.15 0-11.62 1.445-16.4 4.336-4.77 2.89-8.47 7.031-11.06 12.45-2.59 5.401-3.9 11.73-3.9 18.976 0 11.23 2.81 19.968 8.43 26.242 5.6 6.258 13.4 9.402 23.38 9.402 9.63 0 17.28-3.222 22.97-9.62 5.68-6.415 8.51-15.087 8.51-26.024M2403.79 101.074c3.07 0 5.8-.254 8.22-.761l-1.43-9.676c-2.86.633-5.37.933-7.55.933-5.58 0-10.33-2.261-14.3-6.785-3.95-4.531-5.94-10.156-5.94-16.902V30.918h-10.43v68.887h8.62l1.19-12.754h.5c2.56 4.48 5.63 7.949 9.23 10.37 3.61 2.423 7.56 3.653 11.89 3.653M2500.33 69.766l-10.68 28.476c-1.39 3.594-2.81 8.028-4.28 13.262-.93-4.024-2.24-8.438-3.96-13.262l-10.81-28.476zm14.77-38.848l-11.44 29.227h-36.83l-11.32-29.227h-10.81l36.34 92.273h8.98l36.13-92.273h-11.05M2583.07 30.918v44.57c0 5.606-1.27 9.805-3.83 12.559-2.55 2.773-6.55 4.16-12 4.16-7.21 0-12.49-1.953-15.84-5.851-3.35-3.895-5.03-10.32-5.03-19.286V30.918h-10.43v68.887h8.48l1.69-9.422h.51c2.14 3.387 5.14 6.023 8.99 7.887 3.84 1.867 8.15 2.804 12.88 2.804 8.3 0 14.54-2.011 18.74-6.015 4.19-3.985 6.29-10.391 6.29-19.192V30.918h-10.45M2620.76 77.742c0-4.812 1.36-8.465 4.08-10.926 2.73-2.48 6.53-3.71 11.37-3.71 10.2 0 15.28 4.953 15.28 14.831 0 10.344-5.15 15.532-15.45 15.532-4.91 0-8.68-1.32-11.32-3.965-2.64-2.649-3.96-6.555-3.96-11.762zm-5.66-58.387c0-3.73 1.57-6.55 4.71-8.488 3.15-1.922 7.65-2.879 13.53-2.879 8.75 0 15.23 1.309 19.44 3.926 4.21 2.617 6.31 6.172 6.31 10.652 0 3.723-1.14 6.32-3.45 7.754-2.31 1.457-6.64 2.168-13 2.168h-12.51c-4.74 0-8.43-1.12-11.07-3.386-2.63-2.266-3.96-5.508-3.96-9.747zm54.94 80.45v-6.582l-12.76-1.512c1.18-1.477 2.22-3.39 3.14-5.754.92-2.371 1.38-5.039 1.38-8.02 0-6.746-2.3-12.128-6.92-16.152-4.61-4.012-10.92-6.023-18.97-6.023-2.05 0-3.99.156-5.78.5-4.46-2.356-6.67-5.305-6.67-8.871 0-1.883.78-3.282 2.33-4.176 1.55-.902 4.21-1.36 7.98-1.36h12.2c7.46 0 13.18-1.574 17.18-4.707 4.01-3.144 6-7.714 6-13.71 0-7.618-3.06-13.426-9.17-17.43C2653.87 2.004 2644.94 0 2633.2 0c-9 0-15.95 1.68-20.83 5.027-4.88 3.352-7.33 8.079-7.33 14.211 0 4.18 1.35 7.813 4.02 10.88 2.69 3.046 6.47 5.116 11.32 6.21-1.77.8-3.23 2.031-4.43 3.711-1.19 1.68-1.79 3.633-1.79 5.84 0 2.52.66 4.707 2.01 6.602 1.35 1.882 3.45 3.71 6.35 5.468-3.56 1.465-6.47 3.953-8.71 7.48-2.23 3.516-3.35 7.54-3.35 12.06 0 7.55 2.25 13.37 6.79 17.452 4.52 4.082 10.92 6.133 19.21 6.133 3.62 0 6.86-.429 9.75-1.27h23.83M2692.7 99.805V55.117c0-5.605 1.27-9.805 3.83-12.566 2.56-2.766 6.57-4.145 12.01-4.145 7.2 0 12.47 1.965 15.81 5.903 3.33 3.945 4.99 10.379 4.99 19.304v36.192h10.44V30.918h-8.62l-1.5 9.25h-.58c-2.13-3.41-5.1-5.988-8.88-7.793-3.8-1.809-8.13-2.707-12.99-2.707-8.37 0-14.65 1.992-18.81 5.977-4.18 3.964-6.26 10.351-6.26 19.101v45.059h10.56M2760.61 30.918h10.43v97.805h-10.43zM2810.67 38.27c6.5 0 11.6 1.789 15.31 5.343 3.71 3.575 5.56 8.555 5.56 14.961v6.23l-10.44-.448c-8.3-.286-14.27-1.583-17.94-3.868-3.66-2.273-5.5-5.82-5.5-10.644 0-3.781 1.14-6.64 3.42-8.613 2.29-1.973 5.48-2.961 9.59-2.961zm23.57-7.352l-2.07 9.805h-.51c-3.44-4.305-6.86-7.227-10.27-8.77-3.42-1.523-7.68-2.285-12.8-2.285-6.83 0-12.17 1.758-16.05 5.273-3.87 3.528-5.81 8.536-5.81 15.032 0 13.906 11.12 21.199 33.37 21.875l11.7.359v4.277c0 5.418-1.17 9.395-3.5 11.985-2.32 2.566-6.03 3.855-11.15 3.855-5.74 0-12.24-1.758-19.49-5.273l-3.21 7.988c3.4 1.836 7.11 3.281 11.16 4.324a47.81 47.81 0 0 0 12.16 1.575c8.23 0 14.3-1.817 18.27-5.461 3.96-3.66 5.93-9.5 5.93-17.54V30.919h-7.73M2893.6 101.074c3.07 0 5.8-.254 8.25-.761l-1.46-9.676c-2.84.633-5.35.933-7.54.933-5.56 0-10.33-2.261-14.3-6.785-3.96-4.531-5.93-10.156-5.93-16.902V30.918h-10.44v68.887h8.61l1.19-12.754h.5c2.57 4.48 5.65 7.949 9.25 10.37 3.6 2.423 7.56 3.653 11.87 3.653M2901.63 6.727c-3.94 0-7.04.558-9.31 1.691v9.121c2.97-.84 6.08-1.25 9.31-1.25 4.14 0 7.3 1.25 9.45 3.77 2.16 2.507 3.24 6.132 3.24 10.859v91.895h10.69V31.797c0-7.95-2.01-14.121-6.04-18.496-4.02-4.383-9.8-6.574-17.34-6.574M2999.96 55.371c0-8.086-2.93-14.394-8.8-18.918-5.87-4.52-13.83-6.785-23.88-6.785-10.9 0-19.27 1.406-25.14 4.219v10.3c3.77-1.59 7.88-2.847 12.31-3.765 4.45-.93 8.85-1.399 13.21-1.399 7.12 0 12.49 1.36 16.09 4.063 3.59 2.695 5.4 6.465 5.4 11.277 0 3.196-.63 5.805-1.91 7.832-1.29 2.024-3.42 3.907-6.42 5.625-2.99 1.711-7.56 3.664-13.67 5.84-8.55 3.059-14.66 6.692-18.32 10.871-3.66 4.2-5.51 9.668-5.51 16.407 0 7.089 2.68 12.714 7.99 16.914 5.32 4.191 12.36 6.289 21.12 6.289 9.13 0 17.54-1.68 25.2-5.032l-3.32-9.304c-7.59 3.183-14.96 4.785-22.13 4.785-5.66 0-10.07-1.223-13.26-3.652-3.19-2.43-4.78-5.809-4.78-10.118 0-3.191.59-5.8 1.76-7.832 1.17-2.031 3.14-3.886 5.95-5.597 2.78-1.688 7.04-3.563 12.79-5.625 9.63-3.426 16.26-7.118 19.89-11.063 3.62-3.937 5.43-9.043 5.43-15.332M741.648 375.406h30c28.965 0 50.227 5.039 63.774 15.117 13.531 10.079 20.32 25.821 20.32 47.247 0 19.832-6.074 34.628-18.191 44.402-12.141 9.758-31.028 14.641-56.692 14.641h-39.211zm172.192 64.246c0-36.062-11.809-63.691-35.434-82.898-23.621-19.219-57.234-28.82-100.847-28.82h-35.911V198.73h-56.445v345.329h99.438c43.14 0 75.457-8.829 96.961-26.465 21.496-17.637 32.238-43.614 32.238-77.942M1099.26 464.691c11.17 0 20.39-.789 27.63-2.371l-5.43-51.718c-7.88 1.894-16.07 2.832-24.57 2.832-22.2 0-40.19-7.246-53.97-21.731-13.78-14.48-20.66-33.301-20.66-56.453V198.73h-55.514v261.227h43.464l7.32-46.055h2.83c8.66 15.594 19.96 27.95 33.9 37.09 13.93 9.141 28.93 13.699 45 13.699M1206.88 329.82c0-60.308 22.28-90.465 66.85-90.465 44.08 0 66.13 30.157 66.13 90.465 0 59.688-22.21 89.512-66.61 89.512-23.31 0-40.2-7.707-50.67-23.144-10.47-15.43-15.7-37.54-15.7-66.368zm190.13 0c0-42.672-10.95-75.972-32.83-99.898-21.89-23.945-52.35-35.918-91.41-35.918-24.41 0-45.97 5.508-64.7 16.543-18.75 11.016-33.16 26.836-43.23 47.48-10.08 20.625-15.11 44.551-15.11 71.793 0 42.364 10.86 75.43 32.58 99.2 21.73 23.777 52.36 35.671 91.89 35.671 37.79 0 67.7-12.156 89.75-36.492 22.05-24.328 33.06-57.121 33.06-98.379M1558.11 238.887c13.54 0 27.07 2.129 40.62 6.386v-41.816c-6.13-2.676-14.05-4.922-23.73-6.738-9.69-1.797-19.73-2.715-30.12-2.715-52.59 0-78.88 27.715-78.88 83.144v140.778h-35.68v24.558l38.26 20.325 18.9 55.261h34.26v-58.113h74.39v-42.031h-74.39v-139.84c0-13.379 3.34-23.242 10.03-29.629 6.69-6.387 15.48-9.57 26.34-9.57M1783.44 464.691c11.17 0 20.38-.789 27.62-2.371l-5.43-51.718c-7.88 1.894-16.06 2.832-24.56 2.832-22.2 0-40.2-7.246-53.97-21.731-13.78-14.48-20.66-33.301-20.66-56.453V198.73h-55.52v261.227h43.46l7.34-46.055h2.82c8.66 15.594 19.95 27.95 33.9 37.09 13.92 9.141 28.93 13.699 45 13.699M1925.05 236.523c20.15 0 36.32 5.625 48.52 16.895 12.21 11.25 18.31 27.051 18.31 47.344v22.676l-33.54-1.407c-26.13-.937-45.16-5.312-57.04-13.105-11.89-7.793-17.82-19.727-17.82-35.781 0-11.661 3.45-20.665 10.39-27.051 6.91-6.387 17.32-9.571 31.18-9.571zm82.66-37.793l-11.11 36.387h-1.87c-12.62-15.918-25.29-26.738-38.04-32.48-12.74-5.742-29.13-8.633-49.13-8.633-25.67 0-45.7 6.934-60.1 20.801-14.41 13.847-21.62 33.457-21.62 58.808 0 26.934 10 47.246 30 60.934 19.99 13.691 50.45 21.172 91.41 22.441l45.09 1.414v13.938c0 16.699-3.88 29.16-11.68 37.441-7.79 8.262-19.88 12.383-36.25 12.383-13.39 0-26.23-1.953-38.5-5.891a294.638 294.638 0 0 1-35.44-13.933l-17.94 39.668c14.17 7.41 29.68 13.035 46.52 16.894 16.85 3.868 32.77 5.789 47.72 5.789 33.22 0 58.31-7.246 75.22-21.726 16.94-14.492 25.4-37.246 25.4-68.262V198.73h-39.68M2220.04 194.004c-39.52 0-69.55 11.543-90.1 34.609-20.55 23.067-30.82 56.172-30.82 99.321 0 43.925 10.74 77.707 32.23 101.339 21.5 23.614 52.56 35.418 93.18 35.418 27.56 0 52.35-5.117 74.41-15.359l-16.78-44.641c-23.46 9.133-42.82 13.704-58.1 13.704-45.19 0-67.79-29.993-67.79-89.981 0-29.293 5.63-51.305 16.89-66.031 11.26-14.707 27.76-22.09 49.48-22.09 24.72 0 48.11 6.152 70.15 18.437v-48.417c-9.92-5.84-20.5-10-31.76-12.52-11.26-2.52-24.93-3.789-40.99-3.789M2451.52 238.887c13.54 0 27.08 2.129 40.63 6.386v-41.816c-6.15-2.676-14.05-4.922-23.73-6.738-9.69-1.797-19.73-2.715-30.12-2.715-52.6 0-78.9 27.715-78.9 83.144v140.778h-35.66v24.558l38.26 20.325 18.9 55.261h34.26v-58.113h74.39v-42.031h-74.39v-139.84c0-13.379 3.34-23.242 10.03-29.629 6.69-6.387 15.47-9.57 26.33-9.57M2585.92 329.82c0-60.308 22.28-90.465 66.84-90.465 44.09 0 66.15 30.157 66.15 90.465 0 59.688-22.22 89.512-66.62 89.512-23.31 0-40.2-7.707-50.67-23.144-10.47-15.43-15.7-37.54-15.7-66.368zm190.13 0c0-42.672-10.94-75.972-32.83-99.898-21.89-23.945-52.36-35.918-91.4-35.918-24.42 0-45.98 5.508-64.72 16.543-18.74 11.016-33.14 26.836-43.22 47.48-10.07 20.625-15.12 44.551-15.12 71.793 0 42.364 10.87 75.43 32.59 99.2 21.74 23.777 52.36 35.671 91.89 35.671 37.79 0 67.7-12.156 89.75-36.492 22.04-24.328 33.06-57.121 33.06-98.379M2972.33 464.691c11.18 0 20.38-.789 27.63-2.371l-5.43-51.718c-7.87 1.894-16.05 2.832-24.57 2.832-22.2 0-40.19-7.246-53.96-21.731-13.78-14.48-20.67-33.301-20.67-56.453V198.73h-55.51v261.227h43.46l7.33-46.055h2.83c8.66 15.594 19.96 27.95 33.89 37.09 13.94 9.141 28.94 13.699 45 13.699" fill="#100f0d"/><path d="M610.11 372.83c0-170.584-138.257-308.862-308.846-308.862-170.602 0-308.846 138.278-308.846 308.863 0 170.576 138.244 308.846 308.846 308.846 170.59 0 308.846-138.27 308.846-308.846" fill="#e53935" stroke-width="1.029"/><path d="M460.694 521.792l-105.04.958-61.415 61.415-72.096-47.883 12.445-12.438-29.207.26-99.129-166.817H67.357l24.39-24.402-24.57-41.363L294.66 64.049c2.192-.04 4.399-.08 6.603-.08 170.416 0 308.585 138.055 308.846 308.408L460.694 521.792" fill="#d51c2f" stroke-width="1.029"/><path d="M149.093 350.258c0 84.048 68.13 152.151 152.171 152.151 84.028 0 152.139-68.103 152.139-152.151zm342.063-7.017v14.046h44.015c-1.75 59.337-25.556 113.104-63.54 153.419L438.75 477.81l-9.925 9.94 32.875 32.887c-40.314 37.983-94.081 61.79-153.41 63.527l-.015-44.003h-14.035v44.003c-59.34-1.737-113.096-25.556-153.41-63.527l32.887-32.887-9.945-9.92-32.883 32.875c-37.975-40.315-61.781-94.082-63.53-153.419h44.002l-.008-14.034H67.176v-51.511h468.176v51.5h-44.196" fill="#f5f5f5" stroke-width="1.029"/></g></g></symbol><symbol id="pug" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#c1272d}.hyst1{fill:#efcca3}.st2{fill:#ed1c24}.hyst3{fill:#ccac8d}.hyst4{fill:#fff}.st5{fill:#ff931e}.st6{fill:#ffb81e}.hyst7{fill:#56332b}.hyst8{fill:#442823}.hyst9{fill:#7f4a41}.hyst10{fill:#331712}.st11{fill:#fc6}.st12{fill:#ccc}.st13{fill:#b3b3b3}.st14{fill:#989898}.st15{fill:#323232}.st16{fill:#1e1e1e}.st17{fill:#4c4c4c}.st18{fill:#e6e6e6}.st19{fill:#606060}</style><path class="hyst1" d="M107.4 50.9c-.2-4.4.4-8.3-1.6-11.6-4.8-8.2-16.8-13-40.8-13v.7h-.5.5v-.7c-24 0-36.6 4.8-41.4 13.1-1.9 3.4-1.7 7.2-2 11.6-.2 3.5-1.8 7.2-1.1 11.2.8 5.2 1.1 10.4 1.9 15.2.6 3.9 6 7.2 6.5 10.9 1.4 10.2 12 14.9 36 14.9v.8h-.6.7v-.8c24 0 34.2-4.7 35.5-14.9.5-3.8 5.5-7 6.1-10.9.8-4.8 1.1-10 1.9-15.2.7-4-.9-7.8-1.1-11.3z"/><path class="hyst3" d="M64.6 54.5c4.3.1 7.3 2.8 10.1 5.3 3.3 2.9 8.9 4.9 11.2 7.4 2.3 2.5 5.3 5 6.4 8.9 1.1 3.9 1.4 8.9 1.4 10.2 0 1.3.7 1 2.7 0 4.7-2.3 9.9-8.5 9.9-8.5-.6 3.9-5.7 7.4-6.2 11.1C98.9 99.1 89 104 64.5 104h-.1.6"/><path class="hyst3" d="M80.4 46.7c.9 3.1 4.1 13.6-2.1 10.1 0 0 2.6 1.5 4.2 7.2 1.7 5.7 5.8 6.4 5.8 6.4s6.7 1.3 11.7-3c4.2-3.6 4.9-10 3.1-14.9-1.8-4.8-5-6.3-9.7-7.3-4.7-1.1-14.1-2-13 1.5z"/><circle cx="92.3" cy="58.1" r="8.8"/><circle class="hyst4" cx="90" cy="54.2" r="2.3"/><path class="hyst1" d="M78.9 57.7s7.9 5.4 12.2 10.7c4.3 5.3 4.2 6.3 4.2 6.3l-3.1 1.4s-4.4-8.3-9.8-11.4c-5.5-3.1-6.1-5.7-6.1-5.7l2.6-1.3z"/><path class="hyst3" d="M64.9 54.5c-4.3.1-7.5 2.8-10.4 5.3-3.3 2.9-9.1 4.9-11.4 7.4-2.3 2.5-5.4 5-6.5 8.9-1.1 3.9-1.5 8.9-1.5 10.2 0 1.3.2 1.4-2.7 0-4.7-2.2-9.9-8.5-9.9-8.5.6 3.9 5.7 7.4 6.2 11.1C30.1 99.1 40 104 64.5 104h.5"/><path class="hyst7" d="M88.1 71.4C83.3 65.5 75.6 60 64.9 60h-.1c-10.7 0-18.4 5.5-23.2 11.4-5 6.1-4.6 8.5-4.6 14.3 0 21 7.4 15 12.3 17.6 5 2.5 10.2 1.7 15.5 1.7h.1c5.4 0 10.5.7 15.5-1.8 4.9-2.5 12.3 3.7 12.3-17.3.1-5.8.4-8.4-4.6-14.5z"/><path class="hyst8" d="M64.4 65.2s-.7 9.7-2.1 11.6l2.6-.6-.5-11z"/><path class="hyst8" d="M65.1 65.2s.7 9.7 2.1 11.6l-2.6-.6.5-11z"/><path class="hyst7" d="M56.7 62.9c-1-2.3 2.6-6 8.3-6.1 5.7 0 9.3 3.7 8.3 6.1-1 2.4-4.6 3.1-8.3 3.2-3.6-.1-7.3-.8-8.3-3.2z"/><path d="M65 65.2c0-.4 3.4-.5 5.2-1.7 0 0-3.7 1.2-4.5.7-.8-.4-1-1.6-1-1.6s-.3 1.2-.9 1.6c-.7.4-4.9-.7-4.9-.7s5.6 1.4 5.6 1.7c0 .3-.1 1.3-.1 2 0 2.5 0 8.7.4 9.2.6.9.4-6.7.4-9.2-.1-.8-.1-1.6-.2-2z"/><path class="hyst9" d="M65.2 78.6c1.7 0 4.7 1.2 7.4 3.1-2.6-2.9-5.7-4.9-7.4-4.9-1.8 0-5.6 2.2-8.3 5.4 2.8-2.2 6.4-3.6 8.3-3.6z"/><path class="hyst8" d="M64.5 96.3c-3.8 0-7.5-1.2-10.9-2.1-.7-.2-1.4.3-2.1.1-6.3-2-11.4-5.4-14.5-9.7v1c0 21 7.4 15.1 12.3 17.6 5 2.5 10.2 1.7 15.5 1.7h.1c5.4 0 10.5.7 15.5-1.8 4.9-2.5 12.3 3.6 12.3-17.4 0-.8 0-1.6.1-2.3-2.9 4.7-8.2 8.4-14.8 10.6-.6.2-2-.3-2.6-.2-3.6 1.2-6.8 2.5-10.9 2.5z"/><path class="hyst8" d="M55 85s-2.5 7.5-.8 10.8l-2.3-1s1.7-7.6 3.1-9.8zM74.8 85s2.5 7.5.8 10.8l2.3-1s-1.8-7.6-3.1-9.8z"/><path class="hyst3" d="M48.6 46.7c-.9 3.1-4.1 13.6 2.1 10.1 0 0-2.6 1.5-4.2 7.2s-5.8 6.4-5.8 6.4-6.7 1.3-11.7-3c-4.2-3.6-4.9-10-3.1-14.9s5-6.3 9.7-7.3c4.7-1.1 14-2 13 1.5z"/><path d="M64.9 76.8c2.7 0 11.1 5.8 11.2 12.9v-.4c0-7.4-6.8-13.3-11.2-13.3-4.4 0-11.2 6-11.2 13.3v.4c.1-7.1 8.5-12.9 11.2-12.9z"/><ellipse transform="rotate(-14.465 66.712 61.468)" class="hyst10" cx="66.7" cy="61.5" rx=".8" ry="1.5"/><ellipse transform="rotate(17.235 62.371 61.462)" class="hyst10" cx="62.4" cy="61.5" rx=".8" ry="1.5"/><circle cx="37.2" cy="58.1" r="8.8"/><circle class="hyst4" cx="39.5" cy="54.2" r="2.3"/><path class="hyst9" d="M67.5 58.2c0-.1-2.3 1-2.9 1.1-.6-.1-2.9-1.2-2.9-1.1h5.8z"/><path class="hyst1" d="M50 57.7s-7.9 5.4-12.2 10.7c-4.3 5.3-4.2 6.3-4.2 6.3l3.1 1.4s4.4-8.3 9.8-11.4 6.1-5.7 6.1-5.7L50 57.7z"/><path class="hyst3" d="M32.7 41.7S30 49.1 24 52.2c0 0 9.4-1.1 8.7-10.5zM95.8 41.7s2.7 7.4 8.7 10.5c0 0-9.4-1.1-8.7-10.5zM78.7 55.5s-5.9-6.2-13.8-6.4h.1.1c-8 .2-13.8 6.4-13.8 6.4 6.9-4.8 12.8-4.7 13.8-4.7-.1 0 6.7-.1 13.6 4.7zM71.8 42.5s-3-4.2-7-4.3h.2c-3 .1-6.9 4.3-6.9 4.3 3.4-3.3 6.9-3.2 6.9-3.2s3.3-.1 6.8 3.2zM37.2 73.2s-4.7 2.3-8.1.9H29c-3-1.7-4.5-6.8-4.5-6.8s3 9 12.7 5.9zM92 73.2s4.7 2.3 8.1.9c4-1.7 4.6-6.8 4.6-6.8s-3 9-12.7 5.9z"/><path class="hyst3" d="M42.6 41.2c2.6-.5 6.9-.6 10.3.5 4.3 1.5.8 7 1.7 7.3.9.3 2.1-3.8 10.1-3.4 8.1.4 9 4 10.1 3.4s-1.1-10 11-7.8c0 0-12.7-3.4-12.1 5.8 0 0-7.3-5.6-17.5-.6.1 0 2.7-8.6-13.6-5.2zM86.9 41.2c.2 0 .3.1.4.1.1 0-.1-.1-.4-.1zM86.9 41.2zM39.1 28.9S28.3 42.5 26.7 47.7c-1.6 5.3-2.8 27-4.2 30.1l-5-21.4 9.2-22.3 12.4-5.2zM89.9 28.9s10.8 13.6 12.4 18.8c1.6 5.3 2.8 27 4.2 30.1l5-21.4-9.2-22.3-12.4-5.2z"/><path class="hyst7" d="M89.4 28.9s11.6 9.7 15 20.9c3.4 11.2 2 24.8 4.6 26.5 3.7 2.4 7.9-11.9 9.3-13.4 2.2-2.4 9.5-8.5 10-9.6.5-1.1-14.8-17.8-21.5-21.1-8.1-3.8-18.1-4.1-17.4-3.3z"/><path class="hyst8" d="M99.3 34.9s13.7 17.5 13.5 39.3l5.5-11.2c-.1 0-4.9-14.3-19-28.1z"/><path class="hyst7" d="M39.1 28.9s-11.6 9.7-15 20.9-2 24.8-4.6 26.5c-3.7 2.4-7.9-11.9-9.3-13.4C8 60.5.7 54.4.2 53.3-.3 52.2 15 35.5 21.7 32.2c8.1-3.8 18.1-4.1 17.4-3.3z"/><path class="hyst8" d="M29.2 34.9S15.5 52.4 15.7 74.2L10.3 63s4.8-14.3 18.9-28.1z"/><path class="hyst3" d="M21.8 74.6s1 5.4 2.6 7.1.5-1.3.5-1.3-1.7-.9-1.4-7.8-1.7 2-1.7 2zM107.1 74.6s-1 5.4-2.6 7.1-.5-1.3-.5-1.3 1.7-.9 1.4-7.8 1.7 2 1.7 2z"/><g><circle class="hyst8" cx="54.5" cy="70.5" r=".8"/><circle class="hyst8" cx="49.9" cy="75.3" r=".8"/><circle class="hyst8" cx="48.4" cy="70.5" r=".8"/></g><g><circle class="hyst8" cx="74" cy="70.5" r=".8"/><circle class="hyst8" cx="78.6" cy="75.3" r=".8"/><circle class="hyst8" cx="80.1" cy="70.5" r=".8"/></g></symbol><symbol viewBox="0 0 50 50" id="puppet" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -247)" fill="#fbc02d"><path stroke-width=".283" d="M11.559 249.467h13.587v13.587H11.559zM27.435 265.056h13.587v13.587H27.435zM11.559 281.074h13.587v13.587H11.559z"/><path stroke-width=".256" d="M16.62 251.615l18.305 18.305-3.236 3.236-18.305-18.305z"/><path stroke-width=".256" d="M37.834 271.331L19.53 289.636l-3.237-3.237 18.305-18.304z"/></g></symbol><symbol viewBox="0 0 100 99.999997" id="purescript" xmlns="http://www.w3.org/2000/svg"><path clip-path="url(#SVGID_2_)" d="M98.079 38.548L79.22 19.68l-5.087 5.088L90.447 41.09 74.134 57.41l5.087 5.087 18.858-18.86a3.59 3.59 0 0 0 1.055-2.55 3.578 3.578 0 0 0-1.055-2.54M25.483 42.794l-5.09-5.089L1.53 56.568a3.566 3.566 0 0 0-1.05 2.545c0 .961.373 1.863 1.05 2.542L20.394 80.52l5.089-5.086L9.162 59.113z" fill="#42a5f5" stroke-width="1.192"/><path clip-path="url(#SVGID_2_)" transform="matrix(1.19175 0 0 1.19175 -306.84 -629.047)" fill="#42a5f5" d="M281.841 551.736l6.461 6.037h28.379l-6.461-6.037zM288.302 566.861l-6.463 6.035h28.381l6.463-6.035zM281.838 581.982l6.464 6.035h28.381l-6.463-6.035z"/></symbol><symbol viewBox="0 0 24 24" id="python" xmlns="http://www.w3.org/2000/svg"><path d="M19.14 7.5A2.86 2.86 0 0 1 22 10.36v3.78A2.86 2.86 0 0 1 19.14 17H12c0 .39.32.96.71.96H17v1.68a2.86 2.86 0 0 1-2.86 2.86H9.86A2.86 2.86 0 0 1 7 19.64v-3.75a2.85 2.85 0 0 1 2.86-2.85h5.25a2.85 2.85 0 0 0 2.85-2.86V7.5h1.18m-4.28 11.79c-.4 0-.72.3-.72.89 0 .59.32.71.72.71a.71.71 0 0 0 .71-.71c0-.59-.32-.89-.71-.89m-10-1.79A2.86 2.86 0 0 1 2 14.64v-3.78A2.86 2.86 0 0 1 4.86 8H12c0-.39-.32-.96-.71-.96H7V5.36A2.86 2.86 0 0 1 9.86 2.5h4.28A2.86 2.86 0 0 1 17 5.36v3.75a2.85 2.85 0 0 1-2.86 2.85H8.89a2.85 2.85 0 0 0-2.85 2.86v2.68H4.86M9.14 5.71c.4 0 .72-.3.72-.89 0-.59-.32-.71-.72-.71-.39 0-.71.12-.71.71s.32.89.71.89z"/><path d="M9.264 22.379c-.895-.24-1.581-.799-1.947-1.582-.228-.489-.237-.606-.238-2.957-.001-2.745.057-3.074.666-3.785.193-.226.568-.517.833-.648.47-.23.579-.239 3.839-.288 3.131-.048 3.386-.065 3.814-.264.626-.291 1.07-.687 1.4-1.247.27-.46.278-.522.311-2.29l.034-1.82.932.051c1.075.058 1.504.211 2.098.748.853.77.869.841.869 3.957 0 2.434-.02 2.783-.18 3.075a3.365 3.365 0 0 1-1.337 1.33l-.517.273-3.95.031-3.951.031.068.274c.037.151.164.377.282.503.209.224.262.229 2.433.229h2.22v1.05c0 1.653-.394 2.437-1.54 3.072l-.545.302-2.644.018c-1.455.01-2.782-.018-2.95-.063zm6.12-1.692c.22-.222.253-.325.206-.675-.07-.523-.278-.73-.732-.73-.467 0-.672.217-.735.78-.042.372-.012.496.163.672.3.3.77.28 1.097-.047z" fill="#fc0" stroke="#fc0" stroke-width=".102"/><path d="M9.349 22.38c-.911-.15-1.936-1.074-2.176-1.963-.073-.273-.101-1.279-.079-2.868.033-2.317.047-2.473.27-2.926.13-.263.401-.623.603-.8.674-.592.87-.63 3.484-.675 4.399-.076 4.927-.166 5.705-.967.642-.662.706-.9.774-2.883l.061-1.784.951.055c.523.031 1.11.122 1.304.204.54.225 1.358 1.042 1.472 1.47.153.572.243 3.18.16 4.617-.071 1.23-.093 1.327-.395 1.78-.193.288-.577.647-.966.903l-.647.425-3.922.008c-2.157.004-3.942.028-3.966.052-.115.115.354.82.587.883.14.038 1.181.073 2.314.079l2.06.01v.91c0 1.739-.326 2.446-1.454 3.162l-.631.4-2.543-.011c-1.398-.007-2.733-.043-2.966-.081zm5.98-1.718c.285-.256.313-.328.251-.658-.09-.483-.301-.682-.722-.682-.436 0-.625.193-.715.73-.065.384-.044.453.2.663.358.308.595.295.985-.053z" fill="#fdd835" stroke-width=".102"/><path d="M4.281 17.396c-.88-.215-1.714-.935-2.024-1.747-.149-.389-.168-.804-.142-3.041.027-2.26.054-2.638.215-2.962.259-.519.851-1.092 1.392-1.346.437-.206.632-.217 4.408-.245l3.95-.03-.067-.275a1.367 1.367 0 0 0-.282-.504c-.21-.224-.263-.23-2.433-.23h-2.22l.002-1.143c.003-1.338.157-1.795.84-2.493.746-.763 1.103-.838 4.025-.838 2.961 0 3.28.06 4.067.768.37.333.572.621.728 1.037.201.539.213.735.183 3.072-.035 2.777-.045 2.824-.78 3.598-.787.829-.76.824-4.59.883-3.812.06-3.797.057-4.61.806-.765.706-.917 1.2-.964 3.133l-.04 1.653-.677-.01c-.371-.007-.813-.045-.98-.086zM9.59 5.551c.237-.204.286-.326.286-.72 0-.547-.201-.763-.71-.763-.502 0-.765.248-.765.724 0 .492.141.782.439.902.345.14.444.12.75-.143z" fill="#3c78aa"/></symbol><symbol viewBox="0 0 24 24" id="r" xmlns="http://www.w3.org/2000/svg"><path d="M11.956 4.05c-5.694 0-10.354 3.106-10.354 6.947 0 3.396 3.686 6.212 8.531 6.813v2.205h3.53V17.82c.88-.093 1.699-.259 2.475-.497l1.43 2.692h3.996l-2.402-4.048c1.936-1.263 3.147-3.034 3.147-4.97 0-3.841-4.659-6.947-10.354-6.947m1.584 2.712c4.349 0 7.558 1.45 7.558 4.753 0 1.77-.952 3.013-2.505 3.779a1.081 1.081 0 0 1-.228-.156c-.373-.165-.994-.352-.994-.352s3.085-.227 3.085-3.302-3.23-3.127-3.23-3.127h-7.092v7.413c-2.64-.766-4.462-2.392-4.462-4.255 0-2.63 3.52-4.753 7.868-4.753m.156 4.12h2.143s.983-.05.983.974c0 1.004-.983 1.004-.983 1.004h-2.143v-1.977m-.031 4.566h.952c.186 0 .28.052.445.207.135.103.28.3.404.476-.57.073-1.17.104-1.801.104z" fill="#1976d2" stroke-width="1.035"/></symbol><symbol viewBox="0 0 24 24" id="raml" xmlns="http://www.w3.org/2000/svg"><path d="M5 3h2v2H5v5a2 2 0 0 1-2 2 2 2 0 0 1 2 2v5h2v2H5c-1.07-.27-2-.9-2-2v-4a2 2 0 0 0-2-2H0v-2h1a2 2 0 0 0 2-2V5a2 2 0 0 1 2-2m14 0a2 2 0 0 1 2 2v4a2 2 0 0 0 2 2h1v2h-1a2 2 0 0 0-2 2v4a2 2 0 0 1-2 2h-2v-2h2v-5a2 2 0 0 1 2-2 2 2 0 0 1-2-2V5h-2V3h2m-7 12a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m-4 0a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m8 0a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="razor" xmlns="http://www.w3.org/2000/svg"><path d="M15.45 11.91c-.11-2.21-1.75-3.54-3.73-3.54h-.08c-2.29 0-3.55 1.8-3.55 3.84 0 2.29 1.53 3.74 3.54 3.74 2.25 0 3.72-1.65 3.83-3.59m-3.81-5.97c1.53 0 2.97.68 4.02 1.74 0-.51.33-.89.83-.89h.11c.74 0 .89.7.89.92v7.9c-.04.52.54.78.87.44 1.27-1.29 2.78-6.69-.79-9.81-3.33-2.92-7.8-2.44-10.18-.8-2.52 1.74-4.14 5.61-2.57 9.22 1.71 3.95 6.61 5.13 9.52 3.95 1.48-.59 2.15 1.4.65 2.05-2.34.99-8.77.89-11.78-4.32-2.03-3.52-1.93-9.71 3.46-12.92C10.81 1.42 16.24 2.1 19.5 5.5c3.45 3.6 3.25 10.3-.1 12.91-1.51 1.18-3.76.03-3.74-1.7l-.02-.56a5.611 5.611 0 0 1-3.99 1.66C8.63 17.81 6 15.15 6 12.13c0-3.05 2.63-5.74 5.65-5.74z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="react" xmlns="http://www.w3.org/2000/svg"><path d="M12 10.11c1.03 0 1.87.84 1.87 1.89 0 1-.84 1.85-1.87 1.85-1.03 0-1.87-.85-1.87-1.85 0-1.05.84-1.89 1.87-1.89M7.37 20c.63.38 2.01-.2 3.6-1.7-.52-.59-1.03-1.23-1.51-1.9a22.7 22.7 0 0 1-2.4-.36c-.51 2.14-.32 3.61.31 3.96m.71-5.74l-.29-.51c-.11.29-.22.58-.29.86.27.06.57.11.88.16l-.3-.51m6.54-.76l.81-1.5-.81-1.5c-.3-.53-.62-1-.91-1.47C13.17 9 12.6 9 12 9c-.6 0-1.17 0-1.71.03-.29.47-.61.94-.91 1.47L8.57 12l.81 1.5c.3.53.62 1 .91 1.47.54.03 1.11.03 1.71.03.6 0 1.17 0 1.71-.03.29-.47.61-.94.91-1.47M12 6.78c-.19.22-.39.45-.59.72h1.18c-.2-.27-.4-.5-.59-.72m0 10.44c.19-.22.39-.45.59-.72h-1.18c.2.27.4.5.59.72M16.62 4c-.62-.38-2 .2-3.59 1.7.52.59 1.03 1.23 1.51 1.9.82.08 1.63.2 2.4.36.51-2.14.32-3.61-.32-3.96m-.7 5.74l.29.51c.11-.29.22-.58.29-.86-.27-.06-.57-.11-.88-.16l.3.51m1.45-7.05c1.47.84 1.63 3.05 1.01 5.63 2.54.75 4.37 1.99 4.37 3.68 0 1.69-1.83 2.93-4.37 3.68.62 2.58.46 4.79-1.01 5.63-1.46.84-3.45-.12-5.37-1.95-1.92 1.83-3.91 2.79-5.38 1.95-1.46-.84-1.62-3.05-1-5.63-2.54-.75-4.37-1.99-4.37-3.68 0-1.69 1.83-2.93 4.37-3.68-.62-2.58-.46-4.79 1-5.63 1.47-.84 3.46.12 5.38 1.95 1.92-1.83 3.91-2.79 5.37-1.95M17.08 12c.34.75.64 1.5.89 2.26 2.1-.63 3.28-1.53 3.28-2.26 0-.73-1.18-1.63-3.28-2.26-.25.76-.55 1.51-.89 2.26M6.92 12c-.34-.75-.64-1.5-.89-2.26-2.1.63-3.28 1.53-3.28 2.26 0 .73 1.18 1.63 3.28 2.26.25-.76.55-1.51.89-2.26m9 2.26l-.3.51c.31-.05.61-.1.88-.16-.07-.28-.18-.57-.29-.86l-.29.51m-2.89 4.04c1.59 1.5 2.97 2.08 3.59 1.7.64-.35.83-1.82.32-3.96-.77.16-1.58.28-2.4.36-.48.67-.99 1.31-1.51 1.9M8.08 9.74l.3-.51c-.31.05-.61.1-.88.16.07.28.18.57.29.86l.29-.51m2.89-4.04C9.38 4.2 8 3.62 7.37 4c-.63.35-.82 1.82-.31 3.96a22.7 22.7 0 0 1 2.4-.36c.48-.67.99-1.31 1.51-1.9z" fill="#00bcd4"/></symbol><symbol viewBox="0 0 24 24" id="readme" xmlns="http://www.w3.org/2000/svg"><path d="M13 9h-2V7h2m0 10h-2v-6h2m-1-9A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="reason" xmlns="http://www.w3.org/2000/svg"><path d="M3 3v18h18V3H3zm5.119 8.993h2.798c.382 0 .71.025.985.075.275.05.534.159.774.326.244.168.435.386.577.654.145.265.218.598.218 1 0 .552-.112 1.001-.335 1.35-.22.348-.536.638-.947.87l2.16 3.203H12.31l-1.763-2.742h-.77v2.742H8.12v-7.478zm6.594 0h4.676v1.447h-3.018v1.29h2.802v1.447h-2.802v1.848h3.018v1.446h-4.676v-7.478zM9.778 13.37v2.014h.513c.266 0 .49-.014.67-.044.18-.03.329-.1.45-.207a.96.96 0 0 0 .253-.34c.055-.128.082-.297.082-.508 0-.187-.034-.35-.1-.483a.698.698 0 0 0-.343-.317 1.086 1.086 0 0 0-.395-.095 6.012 6.012 0 0 0-.526-.02h-.604z" fill="#f44336" stroke-width="1.067"/></symbol><symbol viewBox="0 0 172 193" id="restql" xmlns="http://www.w3.org/2000/svg"><title>Group</title><g transform="translate(14.767 16.713) scale(.82795)" fill="none"><path d="M171.39 55.799c-.975-6.147-4.673-11.642-10.15-14.805L96.381 3.546C93.217 1.72 89.615.756 85.964.756s-7.253.964-10.415 2.788L10.69 40.992A20.896 20.896 0 0 0 .272 59.035v74.89a20.894 20.894 0 0 0 10.416 18.042l64.859 37.446c3.165 1.827 6.767 2.791 10.417 2.791s7.252-.964 10.415-2.79l64.859-37.445c5.479-3.166 9.178-8.66 10.152-14.808zm-16.516 85.147L90.017 178.39a8.104 8.104 0 0 1-8.108 0l-64.857-37.444a8.109 8.109 0 0 1-4.053-7.021v-74.89a8.109 8.109 0 0 1 4.053-7.021l64.857-37.446c1.254-.725 2.654-1.086 4.054-1.086s2.8.361 4.054 1.086l64.857 37.446a8.106 8.106 0 0 1 4.053 7.021v74.89a8.109 8.109 0 0 1-4.053 7.021z" fill="#83e8c2"/><path d="M158.93 59.035a8.109 8.109 0 0 0-4.053-7.021L90.02 14.568c-1.254-.725-2.654-1.086-4.054-1.086s-2.8.361-4.054 1.086L17.055 52.014a8.106 8.106 0 0 0-4.053 7.021v74.89a8.109 8.109 0 0 0 4.053 7.021l64.857 37.444a8.104 8.104 0 0 0 8.108 0l64.857-37.444a8.109 8.109 0 0 0 4.053-7.021zm-46.766 31.681c.119-.069.242-.118.365-.149.044-.012.088-.01.131-.018.076-.012.152-.029.228-.029l.015.001c.02.001.038.005.059.006.093.005.184.019.273.04l.1.03c.077.025.15.057.223.095.028.014.057.027.084.043.094.057.184.122.263.199.007.008.013.017.021.024.07.071.133.15.188.235.018.029.033.059.05.09.04.072.072.148.099.229a1.512 1.512 0 0 1 .081.46v16.209l-3.278 1.893a1.548 1.548 0 0 0-.678.83 1.533 1.533 0 0 0-.098.514v3.785l-14.038 8.104-.01.004a1.55 1.55 0 0 1-.354.146c-.045.012-.09.011-.135.018-.074.012-.15.029-.225.029l-.014-.001c-.02-.001-.039-.005-.059-.006a1.463 1.463 0 0 1-.273-.041c-.034-.008-.066-.019-.1-.03a1.318 1.318 0 0 1-.223-.094c-.029-.015-.057-.027-.084-.044a1.45 1.45 0 0 1-.263-.198c-.009-.008-.015-.019-.023-.027a1.495 1.495 0 0 1-.185-.232c-.019-.029-.034-.06-.051-.09a1.422 1.422 0 0 1-.098-.229 1.702 1.702 0 0 1-.033-.101 1.487 1.487 0 0 1-.048-.358l-.001-.002v-20.053a1.446 1.446 0 0 1 .727-1.255zM85.24 31.369a1.449 1.449 0 0 1 1.452 0l45.741 26.41a1.45 1.45 0 0 1 0 2.512l-17.366 10.027a1.457 1.457 0 0 1-1.452 0l-15.49-8.943 1.727-.996a1.552 1.552 0 0 0 0-2.688l-13.111-7.57c-.239-.139-.508-.207-.775-.207s-.535.068-.775.207l-3.278 1.893-14.038-8.104a1.451 1.451 0 0 1 0-2.513zM57.59 47.558c.251 0 .501.065.726.194l15.489 8.942-1.727.997a1.552 1.552 0 0 0 0 2.688l1.727.996-15.488 8.943a1.457 1.457 0 0 1-1.452 0L39.499 60.291a1.45 1.45 0 0 1 0-2.512l17.366-10.027c.225-.129.475-.194.725-.194zm-9.56 92.328c-.241 0-.489-.062-.724-.196l-17.365-10.026a1.45 1.45 0 0 1-.726-1.256V75.59c0-.847.694-1.453 1.452-1.453.242 0 .49.062.724.197l17.366 10.025c.449.26.726.738.726 1.257v17.886l-1.727-.997a1.552 1.552 0 0 0-2.327 1.344v15.139c0 .555.295 1.067.775 1.344l3.278 1.894v16.209a1.45 1.45 0 0 1-1.452 1.451zm29.828 14.929a1.452 1.452 0 0 1-2.177 1.257l-17.365-10.026a1.452 1.452 0 0 1-.726-1.257v-17.885l1.726.996c.25.145.515.211.773.211.811 0 1.554-.648 1.554-1.555v-1.993l15.489 8.942c.449.26.726.738.726 1.257zm0-32.768c0 .127-.02.246-.049.36-.009.035-.021.067-.032.101-.026.08-.059.157-.099.229-.017.03-.032.061-.05.09a1.48 1.48 0 0 1-.188.235l-.021.025a1.51 1.51 0 0 1-.264.199c-.026.016-.055.028-.082.043a1.597 1.597 0 0 1-.324.124 1.362 1.362 0 0 1-.278.041c-.018.001-.036.006-.055.006l-.015.001c-.077 0-.155-.018-.233-.03-.043-.007-.084-.005-.125-.017a1.484 1.484 0 0 1-.366-.149l-14.035-8.104v-3.784a1.545 1.545 0 0 0-.776-1.343l-3.276-1.892V91.976c0-.127.02-.246.049-.361.009-.034.021-.066.032-.1a1.33 1.33 0 0 1 .099-.229c.017-.03.032-.062.051-.091.054-.084.116-.163.187-.234l.021-.025c.079-.076.168-.142.263-.199.027-.016.056-.029.084-.043a1.476 1.476 0 0 1 .601-.166c.019 0 .036-.005.055-.005l.015-.001c.078 0 .157.018.236.03.04.007.081.005.122.017.124.031.246.08.366.149l17.361 10.023a1.456 1.456 0 0 1 .726 1.259zm-9.984-45.373a1.448 1.448 0 0 1-.544-.55 1.466 1.466 0 0 1 0-1.413c.121-.219.303-.41.544-.55l14.038-8.104 3.277 1.892c.48.276 1.071.276 1.551 0l3.278-1.893 14.038 8.105a1.45 1.45 0 0 1 0 2.513L86.691 86.7a1.447 1.447 0 0 1-1.452 0zm74.842 51.733c0 .518-.276.997-.726 1.256l-45.741 26.409a1.452 1.452 0 0 1-2.177-1.257v-20.053c0-.519.277-.997.727-1.257l15.488-8.941v1.992c0 .906.743 1.555 1.553 1.555.26 0 .523-.066.774-.21l13.11-7.57a1.55 1.55 0 0 0 .776-1.344v-3.784l14.038-8.105a1.452 1.452 0 0 1 2.177 1.257v20.052zm0-32.764c0 .519-.276.997-.726 1.256l-15.489 8.943v-1.993c0-.906-.744-1.554-1.554-1.554a1.519 1.519 0 0 0-.773.21l-1.727.996V85.616c0-.519.277-.997.727-1.257l17.365-10.025c.234-.135.482-.197.724-.197.758 0 1.453.606 1.453 1.453z" fill="#111d5a"/><g fill="#83e8c2"><path d="M59.402 90.568zM94.485 123.06zM94.771 123.29zM77.775 122.51zM77.072 123.33zM77.418 123.09zM77.856 122.05zM76.749 123.45zM94.119 122.41zM77.131 133.51l-15.489-8.942v1.993c0 .906-.743 1.555-1.554 1.555a1.53 1.53 0 0 1-.773-.211l-1.726-.996v17.885c0 .519.276.997.726 1.257l17.365 10.026a1.452 1.452 0 0 0 2.177-1.257v-20.053a1.454 1.454 0 0 0-.726-1.257zM94.25 122.74zM110.28 111.42zM94.494 100.98c.088-.089.189-.168.303-.232l17.365-10.026-17.365 10.026a1.392 1.392 0 0 0-.303.232zM77.627 122.83zM58.027 90.936zM58.374 90.693zM59.044 90.521l-.015.001c.083-.001.167.015.251.029-.079-.012-.158-.03-.236-.03zM57.819 91.195zM58.696 90.568zM57.589 91.977zM76.043 123.46zM57.67 91.516zM75.677 123.31l-14.035-8.11zM76.401 123.5l.015-.001c-.082.001-.166-.016-.248-.029.078.012.156.03.233.03zM112.16 90.716zM77.662 101.27zM113.64 90.734zM96.237 123.31zM113.33 90.597zM112.89 90.52c-.075 0-.151.018-.228.029.081-.014.162-.029.242-.028l-.014-.001zM141.26 74.137c-.241 0-.489.062-.724.197l-17.365 10.025c-.449.26-.727.738-.727 1.257v17.885l1.727-.996c.25-.145.515-.211.773-.21.81 0 1.554.647 1.554 1.554v1.993l15.489-8.943a1.45 1.45 0 0 0 .726-1.256V75.59c0-.847-.695-1.453-1.453-1.453zM112.96 90.526zM95.523 123.5c.074 0 .15-.018.225-.029-.08.013-.159.028-.238.028l.013.001zM95.451 123.5zM85.238 86.7zM95.078 123.43zM141.26 106.9c-.241 0-.489.062-.724.196l-14.038 8.105v3.784c0 .555-.296 1.067-.776 1.344l-13.11 7.57c-.251.144-.515.21-.774.21-.81 0-1.553-.648-1.553-1.555v-1.992l-15.488 8.941c-.449.26-.727.738-.727 1.257v20.053a1.452 1.452 0 0 0 2.177 1.257l45.741-26.409a1.45 1.45 0 0 0 .726-1.256v-20.053a1.454 1.454 0 0 0-1.454-1.452zM67.871 41.396a1.451 1.451 0 0 0 0 2.513l14.038 8.104 3.278-1.893c.24-.139.508-.207.775-.207s.536.068.775.207l13.111 7.57a1.552 1.552 0 0 1 0 2.688l-1.727.996 15.49 8.943a1.457 1.457 0 0 0 1.452 0l17.366-10.027a1.45 1.45 0 0 0 0-2.512l-45.741-26.41a1.449 1.449 0 0 0-1.452 0zM39.497 57.779a1.45 1.45 0 0 0 0 2.512l17.366 10.027a1.457 1.457 0 0 0 1.452 0l15.488-8.943-1.727-.996a1.552 1.552 0 0 1 0-2.688l1.727-.997-15.489-8.942a1.458 1.458 0 0 0-1.451 0zM49.481 138.43v-16.209l-3.278-1.894a1.55 1.55 0 0 1-.775-1.344v-15.139c0-.906.743-1.555 1.554-1.554.259 0 .523.065.773.21l1.727.997V85.611a1.45 1.45 0 0 0-.726-1.257L31.39 74.33a1.436 1.436 0 0 0-.724-.197c-.758 0-1.452.606-1.452 1.453v52.817c0 .518.276.997.726 1.256l17.365 10.026a1.45 1.45 0 0 0 2.176-1.255zM114.34 108.18l-3.278 1.893 3.278-1.893V91.971zM114.11 91.193zM114.16 91.283z"/></g><g fill="#de5941"><path d="M94.494 100.98a1.45 1.45 0 0 0-.424 1.023v20.053l.001.002c0 .126.02.244.048.358.01.034.021.066.033.101.026.08.059.156.098.229.017.03.032.061.051.09.055.084.115.162.185.232.009.009.015.02.023.027.079.077.169.142.263.198.027.017.055.029.084.044a1.46 1.46 0 0 0 .596.165c.02.001.039.005.059.006.079 0 .158-.016.238-.028.045-.007.09-.006.135-.018.119-.031.238-.08.354-.146l.01-.004 14.038-8.104v-3.785c0-.18.04-.35.098-.514.122-.343.353-.643.678-.83l3.278-1.893V91.977c0-.127-.021-.246-.049-.361-.009-.033-.021-.065-.032-.099a1.266 1.266 0 0 0-.099-.229c-.017-.031-.032-.061-.05-.09a1.425 1.425 0 0 0-.188-.235l-.021-.024a1.41 1.41 0 0 0-.263-.199c-.027-.016-.056-.029-.084-.043a1.509 1.509 0 0 0-.323-.125 1.591 1.591 0 0 0-.273-.04c-.021-.001-.039-.005-.059-.006-.08-.001-.161.015-.242.028-.043.008-.087.006-.131.018-.123.031-.246.08-.365.149l-17.365 10.026a1.447 1.447 0 0 0-.302.233zM77.13 100.74L59.769 90.717a1.424 1.424 0 0 0-.366-.149c-.041-.012-.082-.01-.122-.017-.084-.015-.168-.03-.251-.029-.019 0-.036.005-.055.005-.095.005-.188.02-.278.041-.034.009-.065.02-.099.03a1.406 1.406 0 0 0-.224.095c-.028.014-.057.027-.084.043a1.515 1.515 0 0 0-.263.199l-.021.025c-.07.071-.133.15-.187.234-.019.029-.034.061-.051.091-.04.073-.072.149-.099.229a1.463 1.463 0 0 0-.081.461v16.206l3.276 1.892a1.547 1.547 0 0 1 .776 1.343v3.784l14.035 8.104c.119.068.242.117.366.149.041.012.082.01.125.017.082.014.166.03.248.029.019 0 .037-.005.055-.006.095-.004.188-.019.278-.041.034-.008.065-.019.099-.029.077-.025.152-.058.225-.095.027-.015.056-.027.082-.043.095-.058.185-.123.264-.199l.021-.025c.07-.071.133-.15.188-.235.018-.029.033-.06.05-.09.04-.072.072-.149.099-.229a1.448 1.448 0 0 0 .081-.461v-20.047a1.456 1.456 0 0 0-.726-1.259zM86.689 86.7l17.365-10.026a1.45 1.45 0 0 0 0-2.513l-14.038-8.105-3.278 1.893a1.556 1.556 0 0 1-1.551 0l-3.277-1.892-14.038 8.104c-.241.14-.423.331-.544.55a1.466 1.466 0 0 0 0 1.413c.121.218.303.41.544.55L85.238 86.7a1.447 1.447 0 0 0 1.451 0z"/></g></g></symbol><symbol viewBox="0 0 24 24" id="riot" xmlns="http://www.w3.org/2000/svg"><defs><path d="M13.26 3.04l.58.05.54.07.52.09.49.11.46.13.44.14.41.16.39.17.36.19.33.21.32.22.29.23.26.25.22.22.2.22.19.24.17.24.15.25.15.26.12.27.12.28.1.29.08.31.07.31.05.32.04.34.02.35.01.37v.05l-.02.51-.05.49-.09.48-.13.45-.15.43-.19.4-.22.39-.26.37-.28.34-.31.33-.33.3-.37.28-.39.27-.41.24-.44.22L21 21h-7.04l-3.48-5.14H9.17V21H3V3h9.01l.64.01.61.03zm-4.09 8.52h2.66l.99-.11.75-.35.47-.55.16-.74v-.05l-.17-.75-.47-.54-.74-.32-.96-.11H9.17v3.52z" id="ija"/></defs><use xlink:href="#ija" fill="#ff1744"/><use xlink:href="#ija" fill-opacity="0" stroke="#000" stroke-opacity="0"/></symbol><symbol viewBox="0 0 24 24" id="robot" xmlns="http://www.w3.org/2000/svg"><path d="M12.05 2.804a1.787 1.787 0 0 1 1.788 1.788c0 .661-.357 1.242-.893 1.546v1.135h.893a6.256 6.256 0 0 1 6.256 6.256h.894a.894.894 0 0 1 .893.893v2.681a.894.894 0 0 1-.893.894h-.894v.894a1.787 1.787 0 0 1-1.787 1.787H5.795a1.787 1.787 0 0 1-1.787-1.787v-.894h-.894a.894.894 0 0 1-.894-.894v-2.68a.894.894 0 0 1 .894-.894h.894a6.256 6.256 0 0 1 6.255-6.256h.894V6.138a1.773 1.773 0 0 1-.894-1.546 1.787 1.787 0 0 1 1.788-1.788m-4.022 9.83a2.234 2.234 0 0 0-2.234 2.235 2.234 2.234 0 0 0 2.234 2.234 2.234 2.234 0 0 0 2.234-2.234 2.234 2.234 0 0 0-2.234-2.234m8.043 0a2.234 2.234 0 0 0-2.234 2.234 2.234 2.234 0 0 0 2.234 2.234 2.234 2.234 0 0 0 2.235-2.234 2.234 2.234 0 0 0-2.235-2.234z" fill="#ff5722" stroke-width=".894"/></symbol><symbol viewBox="100 100 800 800" id="rollup" xmlns="http://www.w3.org/2000/svg"><style>.ilst0{fill:url(#ilXMLID_4_)}.ilst1{fill:url(#ilXMLID_5_)}.ilst2{fill:url(#ilXMLID_8_)}.ilst3{fill:url(#ilXMLID_9_)}.ilst4{fill:url(#ilXMLID_11_)}.ilst5{opacity:.3;fill:url(#ilXMLID_16_)}</style><g id="ilXMLID_14_" transform="translate(-54.117 -62.353) scale(1.1129)"><linearGradient id="ilXMLID_4_" x1="444.47" x2="598.47" y1="526.05" y2="562.05" gradientUnits="userSpaceOnUse"><stop stop-color="#FF6533" offset="0"/><stop stop-color="#FF5633" offset=".157"/><stop stop-color="#FF4333" offset=".434"/><stop stop-color="#FF3733" offset=".714"/><stop stop-color="#F33" offset="1"/></linearGradient><path id="ilXMLID_15_" class="ilst0" d="M721 410c0-33.6-8.8-65.1-24.3-92.4-41.1-42.3-130.5-52.1-152.7-.2-22.8 53.2 38.3 112.4 65 107.7 34-6-6-84-6-84 52 98 40 68-54 158S359 779 345 787c-.6.4-1.2.7-1.9 1h368.7c6.5 0 10.7-6.9 7.8-12.7l-96.4-190.8c-2.1-4.1-.6-9.2 3.4-11.5C683 540.6 721 479.8 721 410z" fill="url(#ilXMLID_4_)"/></g><g id="ilXMLID_2_" transform="translate(-54.117 -62.353) scale(1.1129)"><linearGradient id="ilXMLID_5_" x1="420.38" x2="696.38" y1="475" y2="689" gradientUnits="userSpaceOnUse"><stop stop-color="#BF3338" offset="0"/><stop stop-color="#F33" offset="1"/></linearGradient><path id="ilXMLID_10_" class="ilst1" d="M721 410c0-33.6-8.8-65.1-24.3-92.4-41.1-42.3-130.5-52.1-152.7-.2-22.8 53.2 38.3 112.4 65 107.7 34-6-6-84-6-84 52 98 40 68-54 158S359 779 345 787c-.6.4-1.2.7-1.9 1h368.7c6.5 0 10.7-6.9 7.8-12.7l-96.4-190.8c-2.1-4.1-.6-9.2 3.4-11.5C683 540.6 721 479.8 721 410z" fill="url(#ilXMLID_5_)"/></g><linearGradient id="ilXMLID_8_" x1="429.39" x2="469.39" y1="517.16" y2="559.16" gradientTransform="translate(-54.117 -62.353) scale(1.1129)" gradientUnits="userSpaceOnUse"><stop stop-color="#FF6533" offset="0"/><stop stop-color="#FF5633" offset=".157"/><stop stop-color="#FF4333" offset=".434"/><stop stop-color="#FF3733" offset=".714"/><stop stop-color="#F33" offset="1"/></linearGradient><path id="ilXMLID_3_" class="ilst2" d="M329.82 813.46c15.58-8.903 122.41-220.34 227.02-320.5s117.96-66.771 60.094-175.83c0 0-221.46 310.49-301.58 464.06" fill="url(#ilXMLID_8_)" stroke-width="1.113"/><g id="ilXMLID_7_" transform="translate(-54.117 -62.353) scale(1.1129)"><linearGradient id="ilXMLID_9_" x1="502.11" x2="490.11" y1="589.46" y2="417.46" gradientUnits="userSpaceOnUse"><stop stop-color="#FF6533" offset="0"/><stop stop-color="#FF5633" offset=".157"/><stop stop-color="#FF4333" offset=".434"/><stop stop-color="#FF3733" offset=".714"/><stop stop-color="#F33" offset="1"/></linearGradient><path id="ilXMLID_12_" class="ilst3" d="M373 537c134.4-247.1 152-272 222-272 36.8 0 73.9 16.6 97.9 46.1-32.7-52.7-90.6-88-156.9-89H307.7c-4.8 0-8.7 3.9-8.7 8.7V691c13.6-35.1 36.7-85.3 74-154z" fill="url(#ilXMLID_9_)"/></g><linearGradient id="ilXMLID_11_" x1="450.12" x2="506.94" y1="514.21" y2="552.85" gradientTransform="translate(-54.117 -62.353) scale(1.1129)" gradientUnits="userSpaceOnUse"><stop stop-color="#FBB040" offset="0"/><stop stop-color="#FB8840" offset="1"/></linearGradient><path id="ilXMLID_6_" class="ilst4" d="M556.84 492.96c-104.61 100.16-211.44 311.6-227.02 320.5s-41.732 10.016-55.643-5.564c-14.801-16.582-37.837-43.401 86.802-272.65 149.57-274.99 169.15-302.7 247.05-302.7 40.953 0 82.24 18.473 108.95 51.302 1.447 2.337 2.893 4.785 4.34 7.233-45.738-47.074-145.23-57.98-169.93-.222-25.373 59.204 42.622 125.08 72.335 119.85 37.837-6.677-6.677-93.48-6.677-93.48 57.757 108.95 44.403 75.563-60.205 175.72z" fill="url(#ilXMLID_11_)" stroke-width="1.113"/><linearGradient id="ilXMLID_16_" x1="508.33" x2="450.33" y1="295.76" y2="933.76" gradientTransform="translate(-54.117 -62.353) scale(1.1129)" gradientUnits="userSpaceOnUse"><stop stop-color="#FFF" offset="0"/><stop stop-color="#FFF" stop-opacity="0" offset="1"/></linearGradient><path id="ilXMLID_13_" class="ilst5" d="M373.22 547.49c149.57-274.99 169.15-302.7 247.05-302.7 33.719 0 67.661 12.575 93.48 35.277-26.708-30.492-66.326-47.519-105.72-47.519-77.9 0-97.486 27.71-247.05 302.7-124.64 229.25-101.6 256.07-86.802 272.65 2.114 2.337 4.563 4.34 7.122 6.01-13.02-18.919-18.807-62.877 91.922-266.42z" fill="url(#ilXMLID_16_)" opacity=".3" stroke-width="1.113"/></symbol><symbol viewBox="0 0 24 24" id="ruby" xmlns="http://www.w3.org/2000/svg"><path d="M16 9h3l-5 7m-4-7h4l-2 8M5 9h3l2 7m5-12h2l2 3h-3m-5-3h2l1 3h-4M7 4h2L8 7H5m1-5L2 8l10 14L22 8l-4-6H6z" fill="#f44336"/></symbol><symbol viewBox="0 0 144 144" id="rust" xmlns="http://www.w3.org/2000/svg"><path d="M68.252 26.206a3.561 3.561 0 0 1 7.123 0 3.561 3.561 0 0 1-7.123 0M25.766 58.451a3.561 3.561 0 0 1 7.123 0 3.561 3.561 0 0 1-7.123 0m84.97.166a3.561 3.561 0 0 1 7.123 0 3.561 3.561 0 0 1-7.123 0m-74.661 4.88a3.252 3.252 0 0 0 1.651-4.29l-1.58-3.574h6.214v28.01H29.823a43.847 43.847 0 0 1-1.42-16.738zm25.994.688v-8.256h14.798c.764 0 5.397.883 5.397 4.347 0 2.877-3.553 3.908-6.475 3.908zm-20.203 44.452a3.561 3.561 0 0 1 7.123 0 3.561 3.561 0 0 1-7.123 0m52.769.166a3.561 3.561 0 0 1 7.123 0 3.561 3.561 0 0 1-7.123 0m1.101-8.076a3.246 3.246 0 0 0-3.856 2.498l-1.787 8.342a43.847 43.847 0 0 1-36.566-.175l-1.787-8.342a3.246 3.246 0 0 0-3.854-2.497l-7.365 1.581a43.847 43.847 0 0 1-3.808-4.488h35.834c.406 0 .676-.074.676-.443V84.527c0-.369-.27-.442-.676-.442h-10.48V76.05h11.335c1.035 0 5.532.296 6.97 6.045.45 1.768 1.44 7.519 2.116 9.36.674 2.065 3.417 6.19 6.34 6.19h18.501a43.847 43.847 0 0 1-4.06 4.7zm19.898-33.468a43.847 43.847 0 0 1 .093 7.612h-4.499c-.45 0-.631.296-.631.737v2.066c0 4.863-2.742 5.92-5.145 6.19-2.288.258-4.825-.958-5.138-2.358-1.35-7.593-3.6-9.214-7.152-12.016 4.409-2.8 8.996-6.93 8.996-12.457 0-5.97-4.092-9.729-6.881-11.572-3.914-2.58-8.246-3.096-9.415-3.096H39.336A43.847 43.847 0 0 1 63.867 28.52l5.484 5.753a3.243 3.243 0 0 0 4.59.105l6.137-5.869a43.847 43.847 0 0 1 30.017 21.38l-4.201 9.487a3.256 3.256 0 0 0 1.652 4.29zm10.477.154l-.143-1.467 4.327-4.036c.88-.82.55-2.472-.574-2.891l-5.532-2.068-.433-1.428 3.45-4.792c.704-.974.058-2.53-1.127-2.724l-5.833-.949-.7-1.31 2.45-5.38c.502-1.095-.43-2.496-1.636-2.45l-5.92.206-.935-1.135 1.36-5.766c.275-1.17-.913-2.36-2.084-2.085l-5.765 1.359-1.136-.935.207-5.92c.046-1.198-1.357-2.135-2.45-1.637l-5.379 2.452-1.31-.703-.95-5.833c-.193-1.183-1.75-1.83-2.723-1.128l-4.796 3.45-1.425-.432-2.068-5.532c-.42-1.127-2.072-1.452-2.89-.576l-4.036 4.33-1.467-.143-3.117-5.036c-.63-1.02-2.318-1.02-2.946 0l-3.117 5.036-1.467.143-4.037-4.33c-.819-.876-2.47-.551-2.89.576l-2.069 5.532-1.426.432-4.795-3.45c-.974-.703-2.53-.055-2.723 1.128l-.951 5.833-1.31.703-5.379-2.452c-1.093-.5-2.496.439-2.45 1.637l.206 5.92-1.136.935-5.765-1.36c-1.171-.272-2.36.915-2.086 2.086l1.358 5.766-.933 1.135-5.92-.206c-1.193-.035-2.134 1.355-1.637 2.45l2.453 5.38-.703 1.31-5.832.949c-1.185.192-1.827 1.75-1.128 2.724l3.45 4.792-.433 1.428-5.532 2.068c-1.123.42-1.452 2.07-.574 2.891l4.328 4.036-.143 1.467-5.035 3.116c-1.02.63-1.02 2.318 0 2.946l5.035 3.117.143 1.467-4.328 4.037c-.878.818-.549 2.468.574 2.89l5.532 2.068.433 1.428-3.45 4.793c-.701.976-.056 2.532 1.129 2.723l5.831.948.703 1.312-2.453 5.378c-.5 1.093.444 2.5 1.638 2.451l5.917-.207.935 1.136-1.358 5.768c-.275 1.168.915 2.355 2.086 2.08l5.765-1.357 1.137.932-.207 5.921c-.046 1.199 1.357 2.136 2.45 1.636l5.379-2.45 1.31.702.95 5.83c.193 1.187 1.75 1.829 2.725 1.13l4.792-3.453 1.427.435 2.069 5.53c.42 1.123 2.072 1.454 2.89.574l4.037-4.328 1.467.146 3.117 5.035c.628 1.016 2.316 1.018 2.946 0l3.117-5.035 1.467-.146 4.036 4.328c.818.88 2.47.549 2.89-.574l2.068-5.53 1.428-.435 4.793 3.453c.974.699 2.53.055 2.722-1.13l.952-5.83 1.31-.703 5.378 2.451c1.093.5 2.493-.435 2.45-1.636l-.206-5.92 1.135-.933 5.765 1.357c1.171.275 2.36-.912 2.085-2.08l-1.358-5.768.932-1.136 5.92.207c1.194.048 2.138-1.358 1.636-2.451l-2.45-5.378.7-1.312 5.833-.948c1.187-.19 1.831-1.747 1.127-2.723l-3.45-4.793.433-1.428 5.532-2.068c1.125-.422 1.454-2.072.574-2.89l-4.327-4.037.143-1.467 5.035-3.117c1.02-.628 1.021-2.315.001-2.946z" fill="#ff7043" stroke-width="1.146"/></symbol><symbol viewBox="0 0 500 500" id="sass" xmlns="http://www.w3.org/2000/svg"><path d="M422.676 96.573c-12.192-47.839-91.508-63.557-166.575-36.892-44.68 15.877-93.029 40.786-127.81 73.311-41.349 38.675-47.943 72.328-45.216 86.395 9.583 49.622 77.585 82.069 105.535 106.126v.144c-8.246 4.05-68.565 34.584-82.684 65.799-14.893 32.932 2.372 56.556 13.804 59.742 35.424 9.859 71.764-7.866 91.311-37.01 18.853-28.12 17.28-64.422 9.086-82.487 11.3-2.976 24.476-4.314 41.218-2.36 47.248 5.52 56.517 35.017 54.747 47.366-1.77 12.35-11.681 19.14-14.998 21.186-3.317 2.045-4.326 2.766-4.05 4.287.405 2.215 1.94 2.137 4.758 1.652 3.894-.656 24.804-10.042 25.709-32.828 1.14-28.933-26.587-61.302-75.684-60.45-20.216.354-32.933 2.268-42.123 5.69-.681-.774-1.363-1.547-2.084-2.307-30.35-32.382-86.46-55.285-84.088-98.824.866-15.823 6.372-57.5 107.817-108.052 83.104-41.415 149.637-30.009 161.135-4.76 16.427 36.08-35.554 103.137-121.858 112.812-32.88 3.684-50.198-9.059-54.498-13.804-4.536-4.995-5.204-5.218-6.909-4.287-2.753 1.533-1.01 5.938 0 8.574 2.583 6.712 13.15 18.603 31.176 24.515 15.863 5.205 54.459 8.063 101.156-9.99 52.283-20.255 93.12-76.523 81.125-123.548zM200.213 340.34c3.92 14.5 3.487 28.016-.564 40.248a65.289 65.289 0 0 1-3.225 7.97c-3.12 6.477-7.316 12.534-12.442 18.132-15.653 17.069-37.507 23.532-46.88 18.092-10.122-5.874-5.048-29.944 13.083-49.11 19.52-20.636 47.602-33.903 47.602-33.903l-.039-.079 2.465-1.35z" fill="#ec407a" stroke="#ec407a" stroke-width="16.286552999999998"/></symbol><symbol viewBox="0 0 300 300" id="sbt" xmlns="http://www.w3.org/2000/svg"><path d="M105.46 209.517c-7.875 0-13.452-7.521-13.452-15.37v-.327c0-7.848 5.578-13.735 13.452-13.735h164.05c1.476-4.905 2.625-11.446 3.281-17.986h-137.81c-7.875 0-14.273-6.05-14.273-13.898s6.398-13.898 14.273-13.898h137.31c-.82-6.54-1.969-13.081-3.773-17.986h-104.01c-7.875 0-14.273-6.05-14.273-13.898s6.398-13.898 14.273-13.898h91.87c-21.327-37.607-60.864-61.315-106.14-61.315-67.918 0-123.04 54.448-123.04 122.3 0 67.856 55.122 123.28 123.04 123.28 46.59 0 87.112-25.507 107.95-63.114h-152.73z" fill="#0277bd" stroke-width="1.638"/></symbol><symbol viewBox="0 0 256 256" id="scala" xmlns="http://www.w3.org/2000/svg"><path fill="#f44336" fill-rule="evenodd" stroke-width=".3" d="M59.607 50.647l149.097-21.982v49.488L59.607 100.135zM59.593 114.08L208.69 92.098v49.488L59.593 163.568zM59.587 177.358l149.097-21.982v49.488L59.587 226.846z"/><path fill="#f44336" fill-rule="evenodd" stroke-width=".3" d="M62.425 91.414l95.605 30.923-2.832 8.757-95.605-30.922zM113.084 61.13l95.604 30.922-2.832 8.757-95.605-30.922zM62.425 154.79l95.605 30.922-2.833 8.758-95.604-30.923zM113.097 124.408l95.604 30.923-2.832 8.757-95.605-30.922z"/></symbol><symbol viewBox="0 0 24 24" id="settings" xmlns="http://www.w3.org/2000/svg"><path d="M12 15.5A3.5 3.5 0 0 1 8.5 12 3.5 3.5 0 0 1 12 8.5a3.5 3.5 0 0 1 3.5 3.5 3.5 3.5 0 0 1-3.5 3.5m7.43-2.53c.04-.32.07-.64.07-.97 0-.33-.03-.66-.07-1l2.11-1.63c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.31-.61-.22l-2.49 1c-.52-.39-1.06-.73-1.69-.98l-.37-2.65A.506.506 0 0 0 14 2h-4c-.25 0-.46.18-.5.42l-.37 2.65c-.63.25-1.17.59-1.69.98l-2.49-1c-.22-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64L4.57 11c-.04.34-.07.67-.07 1 0 .33.03.65.07.97l-2.11 1.66c-.19.15-.25.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1.01c.52.4 1.06.74 1.69.99l.37 2.65c.04.24.25.42.5.42h4c.25 0 .46-.18.5-.42l.37-2.65c.63-.26 1.17-.59 1.69-.99l2.49 1.01c.22.08.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.66z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="shaderlab" xmlns="http://www.w3.org/2000/svg"><path d="M9.11 17H6.5l-4.91-5L6.5 7h2.61l1.31-2.26L17.21 3l1.87 6.74L17.77 12l1.31 2.26L17.21 21l-6.79-1.74L9.11 17m.14-.25l5.13 1.38L11.42 13H5.5l3.75 3.75m6.87.38L17.5 12l-1.38-5.13L13.15 12l2.97 5.13M9.25 7.25L5.5 11h5.92l2.96-5.13-5.13 1.38z" fill="#1976d2"/></symbol><symbol viewBox="0 0 24 24" id="slim" xmlns="http://www.w3.org/2000/svg"><path d="M6.959 2.5a4.605 4.605 0 0 0-4.615 4.615v9.957a4.605 4.605 0 0 0 4.615 4.615h9.957a4.605 4.605 0 0 0 4.615-4.615V7.115A4.605 4.605 0 0 0 16.916 2.5zm4.938 2.691a6.811 6.811 0 0 1 6.81 6.813H13.43L9.938 7.287l.699 4.717H5.086a6.811 6.811 0 0 1 6.81-6.813z" fill="#f57f17"/></symbol><symbol id="smarty" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>.iust0{fill:#ffce00}</style><path class="iust0" d="M9.14 20.606c0 .556.398.953.954.953h3.812c.556 0 .953-.397.953-.953v-.953H9.141zM12 2.5c-3.653 0-6.671 3.018-6.671 6.671 0 2.303 1.112 4.289 2.859 5.48v2.144c0 .556.397.953.953.953h5.718c.556 0 .953-.397.953-.953V14.65c1.747-1.191 2.86-3.177 2.86-5.48 0-3.653-3.019-6.671-6.672-6.671zm2.7 10.563l-.794.555v2.224h-3.812v-2.224l-.794-.555A4.712 4.712 0 0 1 7.235 9.17 4.78 4.78 0 0 1 12 4.405a4.78 4.78 0 0 1 4.765 4.765 4.712 4.712 0 0 1-2.065 3.892z"/></symbol><symbol viewBox="0 0 200 200" id="snyk" xmlns="http://www.w3.org/2000/svg"><title>Group 2</title><g transform="translate(15.255 18.22) scale(1.8477)" fill="none" fill-rule="evenodd"><path d="M65.161 24.997c-1.656 5.974-5.255 23.587-5.255 23.587s-6.618-2.464-14.148-2.476h-.055c-.413.002-.822.012-1.23.026v41.649h6.677v.003h5.815v-.003h20.858c.111-8.177-2.036-27.066-2.036-27.066-1.088-2.279.46-7.668.46-7.668-8.869-9.092-11.086-28.051-11.086-28.051zm-3.357 43.958c5.476 0 1.381 4.64.9 5.168H52.35c.944-1.18 4.504-5.168 9.453-5.168z" fill="#607d8b" stroke-width="1.6"/><path d="M26.366 24.995s-2.217 18.961-11.087 28.053c0 0 1.548 5.391.46 7.669 0 0-2.15 18.895-2.038 27.066h19.273v.003h7.079v-.003h5.744V46.107h-.025c-7.532.013-14.151 2.478-14.151 2.478s-3.6-17.615-5.255-23.59zm3.264 43.96c4.95 0 8.51 3.987 9.452 5.168H28.73c-.479-.528-4.573-5.168.9-5.168z" fill="#90a4ae" stroke-width="1.6"/><g transform="translate(23.76 77.45) scale(1.5998)"><g transform="translate(17.526)"><path d="M7.357.06H.177v.075C.177 2.64 2.345 4.67 4.89 4.67 7.431 4.67 9.6 2.64 9.6.135V.059z" fill="#455a64"/><path d="M1.972.06v.075a2.692 2.692 0 1 0 5.386 0V.059z" fill="#fff"/><path d="M5.496.06H4.234c-.012 0-.023.005-.034.007.157.033.243.388.21.624a.721.721 0 0 1-.71.617c.102.471.487.85.997.922a1.188 1.188 0 0 0 1.35-1.007C6.112.743 5.881.06 5.495.06z" fill="#37474f"/></g><path d="M7.552.06H.372v.075c0 2.505 2.17 4.535 4.712 4.535 2.544 0 4.712-2.03 4.712-4.535V.059z" fill="#455a64"/><path d="M2.168.06v.075a2.692 2.692 0 1 0 5.385 0V.059z" fill="#fff"/><path d="M5.692.06H4.428c-.01 0-.022.005-.032.007.156.033.242.388.21.624a.72.72 0 0 1-.712.617c.104.471.488.85.999.922A1.187 1.187 0 0 0 6.24 1.223C6.308.743 6.078.06 5.69.06z" fill="#37474f"/></g><path d="M25.514-.27l-4.202 7.697C19.838 10.17 6.858 34.465 6.858 43.243v.516L12.8 59.573c-.8 7.258-2.203 21.643-1.78 28.21h5.73c-.354-3.787.648-17.008 1.903-28.25l.076-.677-1.075-2.892c3.694-3.868 6.285-9.193 8.073-14.261l.174 1.235 5.869 9.629 2.291-.983c.058-.024 5.935-2.523 11.643-2.523 5.672 0 11.646 2.5 11.702 2.525l2.29.976 5.86-9.626.23-1.608c1.769 5.117 4.358 10.536 8.07 14.49l-1.127 3.035.076.678c1.259 11.286 2.266 24.564 1.916 28.252h5.677c.406-6.567-1.05-20.952-1.848-28.208l5.838-15.817v-.514c0-8.779-12.876-33.074-14.347-35.816L65.923-.27l-5.897 41.229-2.723 4.478c-2.628-.882-7.1-2.11-11.603-2.11-4.498 0-8.94 1.225-11.557 2.108l-2.722-4.476-2.07-14.452a.832.832 0 0 0 .006-.071l-.016-.004zm-3.166 18.39l1.206 8.407c-.46 3.143-2.561 15.47-8.198 23.24l-2.598-6.99c.325-4.554 5.067-15.462 9.59-24.656zm46.763 0c4.523 9.194 9.267 20.104 9.592 24.657L76.166 49.6c-6.09-8.553-8-22.459-8.166-23.73z" fill="#607d8b" stroke-width="1.6"/></g></symbol><symbol viewBox="0 0 24 24" id="solidity" xmlns="http://www.w3.org/2000/svg"><path d="M5.8 14.05l6.253 8.61 6.252-8.61-6.254 3.807z" fill="#0288d1" stroke-width="4.553" stroke-linejoin="round"/><path d="M12.051 1.347L5.8 11.833l6.252 3.807 6.254-3.807z" fill="#0288d1" stroke-width="5.025" stroke-linejoin="round"/></symbol><symbol viewBox="0 0 120 120" id="sonar" xmlns="http://www.w3.org/2000/svg"><style>.a,.b{fill:#fff}.b{stroke:#fff;stroke-miterlimit:10}</style><path d="M115.45 23.033S97.961 33.27 97.534 33.412c-.427.284-.852.57-1.137.854-1.422 1.421-1.848 3.41-1.422 5.26.285.852.711 1.849 1.422 2.56.711.71 1.564 1.137 2.559 1.422 1.848.426 3.84 0 5.262-1.422.426-.427.709-.853.851-1.28l.143-.427 2.56-4.692zm-39.102 9.242c-27.441 0-31.99 13.08-31.99 29.29 0 3.838.569 7.962-1.99 11.942-3.84 5.972-8.957 5.828-10.236 5.828-1.706 0-7.962-.993-8.246-2.841h.994c6.682 0 11.658-5.404 11.658-12.655v-2.56h-5.686c-4.123 0-7.82 1.849-10.238 5.12-2.417-3.271-6.113-5.12-10.236-5.12h-5.83v2.56c0 7.11 5.688 12.795 12.797 12.795h1.848c0 4.124 5.687 20.332 47.63 20.332 16.352 0 40.665-2.843 40.665-33.697 0-5.829-1.848-11.23-4.691-15.78-.996.284-1.992.568-3.13.568a8.92 8.92 0 0 1-8.956-8.957c0-.995.141-1.991.425-2.986-4.265-2.702-8.53-3.838-14.787-3.838z" fill="#1e88e5" stroke-width="1.422"/></symbol><symbol viewBox="0 0 412 395" id="stylelint" xmlns="http://www.w3.org/2000/svg"><title>stylelint-icon-white</title><g transform="translate(31.478 29.499) scale(.84775)" fill="#cfd8dc" fill-rule="evenodd"><path d="M208.8 393.05c45.057-161.12 43.75-161.85 76.32-276.73l7.832 4.523c4.255 2.458 7.738.448 7.738-4.455V61.602c8.643-30.27 15.416-53.66 17.4-60.693h35.287l58.618 54.304-38.498 33.27 29.11 31.473-191.86 273.09c-.938 1.542-2.244 1.19-1.947 0zm20.96-347.28c1.733 0 3.148.958 3.148 2.147v28.077c0 1.186-1.415 2.15-3.147 2.15h-47.396c-1.742 0-3.153-.96-3.153-2.15V47.917c0-1.185 1.41-2.147 3.153-2.147h47.396z"/><path d="M288.26 14.688l-52.14 30.1c.605.92.973 1.98.973 3.136v28.078c0 1.457-.565 2.77-1.496 3.83l52.663 30.402c3.59 2.073 6.535.377 6.535-3.764V18.456c0-4.145-2.944-5.836-6.535-3.768zM175.02 76V47.923c0-1.15.368-2.21.966-3.13l-52.14-30.105c-3.588-2.068-6.53-.376-6.53 3.768v88.013c0 4.14 2.938 5.84 6.53 3.76l52.66-30.405c-.926-1.06-1.487-2.37-1.487-3.827z"/><path d="M201.25 393.05h1.947c-45.05-161.12-43.753-161.85-76.32-276.73l-7.833 4.523c-4.253 2.458-7.737.448-7.737-4.455V61.602C102.662 31.332 95.892 7.942 93.902.909H58.619L.002 55.213l38.494 33.27-29.11 31.473z"/><circle cx="204.57" cy="122.54" r="14.231"/><circle cx="204.57" cy="207.16" r="14.231"/><circle cx="204.57" cy="291.78" r="14.23"/></g></symbol><symbol viewBox="0 0 412 395" id="stylelint_light" xmlns="http://www.w3.org/2000/svg"><title>stylelint-icon-black</title><g transform="translate(31.478 29.499) scale(.84775)" fill="#546e7a" fill-rule="evenodd"><path d="M208.8 393.05c45.057-161.12 43.75-161.85 76.32-276.73l7.832 4.523c4.255 2.458 7.738.448 7.738-4.455V61.602c8.643-30.27 15.416-53.66 17.4-60.693h35.287l58.618 54.304-38.498 33.27 29.11 31.473-191.86 273.09c-.938 1.542-2.244 1.19-1.947 0zm20.96-347.28c1.733 0 3.148.958 3.148 2.147v28.077c0 1.186-1.415 2.15-3.147 2.15h-47.396c-1.742 0-3.153-.96-3.153-2.15V47.917c0-1.185 1.41-2.147 3.153-2.147h47.396z"/><path d="M288.26 14.688l-52.14 30.1c.605.92.973 1.98.973 3.136v28.078c0 1.457-.565 2.77-1.496 3.83l52.663 30.402c3.59 2.073 6.535.377 6.535-3.764V18.456c0-4.145-2.944-5.836-6.535-3.768zM175.02 76V47.923c0-1.15.368-2.21.966-3.13l-52.14-30.105c-3.588-2.068-6.53-.376-6.53 3.768v88.013c0 4.14 2.938 5.84 6.53 3.76l52.66-30.405c-.926-1.06-1.487-2.37-1.487-3.827z"/><path d="M201.25 393.05h1.947c-45.05-161.12-43.753-161.85-76.32-276.73l-7.833 4.523c-4.253 2.458-7.737.448-7.737-4.455V61.602C102.662 31.332 95.892 7.942 93.902.909H58.619L.002 55.213l38.494 33.27-29.11 31.473z"/><circle cx="204.57" cy="122.54" r="14.231"/><circle cx="204.57" cy="207.16" r="14.231"/><circle cx="204.57" cy="291.78" r="14.23"/></g></symbol><symbol viewBox="0 0 200.00001 200.00001" id="stylus" xmlns="http://www.w3.org/2000/svg"><path d="M126.814 155.9c14.64-17.51 16.362-35.595 5.024-69.18-7.177-21.24-19.09-37.602-10.334-50.807 9.329-14.065 29.135-.43 12.63 18.371l3.301 2.297c19.806 2.296 29.566-24.83 14.783-32.58C113.179 3.621 79.02 42.803 94.09 88.156c6.458 19.232 15.5 39.613 8.18 55.83-6.314 13.923-18.514 22.103-26.695 22.39-17.079.862-5.74-38.32 13.922-48.08 1.722-.861 4.162-2.01 1.866-4.88-24.256-2.727-38.464 8.468-46.645 24.112-23.825 45.497 45.21 62.29 82.095 18.371z" fill="#c0ca33" stroke-width="1.435"/></symbol><symbol viewBox="0 0 24 24" id="swc" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="jba"><stop offset="0" stop-color="#791223"/><stop offset="1" stop-color="#d92f3c"/></linearGradient><linearGradient xlink:href="#jba" id="jbb" x1="12.356" y1="21.559" x2="12.356" y2="2.949" gradientUnits="userSpaceOnUse"/></defs><path d="M6 3c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6 3 6.5V19a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6.5c0-.5-.17-.93-.46-1.27l-1.39-1.68C18.88 3.21 18.47 3 18 3H6zm-.07 1h12l.94 1H5.12l.81-1z" fill="url(#jbb)"/><path style="line-height:125%" d="M11.053 11.918h-.008c-.244.022-.475.054-.676.11a2.9 2.9 0 0 0-.856.412 3.399 3.399 0 0 0-.67.683 9.36 9.36 0 0 0-.586.95c-.07.131-.134.244-.201.365v.001h-.002l-.768 1.372-.003-.001c-.136.253-.264.485-.38.686-.123.212-.26.39-.411.539a1.599 1.599 0 0 1-.52.34c-.04.016-.092.024-.138.036h-.567v1.383H5.834v-.001c.245-.02.477-.053.679-.11a2.9 2.9 0 0 0 .856-.411c.245-.185.469-.413.67-.683.195-.275.39-.591.585-.95.07-.131.135-.244.202-.366l.004.001.002-.002.02-.038H10.948v-1.378h-.19v-.001H9.624c.125-.234.246-.452.355-.64.123-.21.259-.39.41-.538.152-.148.325-.26.52-.34.04-.015.091-.024.136-.035h.57V13.3h-.002v-1.381h-.56v-.001z" font-weight="400" font-size="40" font-family="sans-serif" letter-spacing="0" word-spacing="0" fill="#fff"/></symbol><symbol viewBox="0 0 24 24" id="swift" xmlns="http://www.w3.org/2000/svg"><path d="M17.09 19.72c-2.36 1.36-5.59 1.5-8.86.1A13.807 13.807 0 0 1 2 14.5c.67.55 1.46 1 2.3 1.4 3.37 1.57 6.73 1.46 9.1 0-3.37-2.59-6.24-5.96-8.37-8.71-.45-.45-.78-1.01-1.12-1.51 8.28 6.05 7.92 7.59 2.41-1.01 4.89 4.94 9.43 7.74 9.43 7.74.16.09.25.16.36.22.1-.25.19-.51.26-.78.79-2.85-.11-6.12-2.08-8.81 4.55 2.75 7.25 7.91 6.12 12.24-.03.11-.06.22-.05.39 2.24 2.83 1.64 5.78 1.35 5.22-1.21-2.39-3.48-1.65-4.62-1.17z" fill="#fe5e2f"/></symbol><symbol viewBox="0 0 24 24" id="table" xmlns="http://www.w3.org/2000/svg"><path d="M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2m7 1.5V9h5.5L13 3.5m4 7.5h-4v2h1l-2 1.67L10 13h1v-2H7v2h1l3 2.5L8 18H7v2h4v-2h-1l2-1.67L14 18h-1v2h4v-2h-1l-3-2.5 3-2.5h1v-2z" fill="#8bc34a"/></symbol><symbol viewBox="0 0 200 200" id="terraform" xmlns="http://www.w3.org/2000/svg"><g transform="translate(177.03 -58.705) scale(.92881)" fill="#5c6bc0" stroke="#b0aff5" stroke-linejoin="round"><g stroke-width=".288"><path transform="skewY(26.439) scale(.89541 1)" d="M-203.8 170.95h64.714v51.88H-203.8zM-124.37 171.04h64.714v51.88h-64.714zM-124.37 236.09h64.714v51.88h-64.714z"/></g><path transform="skewY(-22.59) scale(-.92328 1)" stroke-width=".284" d="M-19.172 128.27h62.76v51.88h-62.76z"/></g></symbol><symbol viewBox="0 0 24 24" id="test-js" xmlns="http://www.w3.org/2000/svg"><path d="M5 19a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1c0-.21-.07-.41-.18-.57L13 8.35V4h-2v4.35L5.18 18.43c-.11.16-.18.36-.18.57m1 3a3 3 0 0 1-3-3c0-.6.18-1.16.5-1.63L9 7.81V6a1 1 0 0 1-1-1V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v1a1 1 0 0 1-1 1v1.81l5.5 9.56c.32.47.5 1.03.5 1.63a3 3 0 0 1-3 3H6m7-6l1.34-1.34L16.27 18H7.73l2.66-4.61L13 16m-.5-4a.5.5 0 0 1 .5.5.5.5 0 0 1-.5.5.5.5 0 0 1-.5-.5.5.5 0 0 1 .5-.5z" fill="#ffca28"/></symbol><symbol viewBox="0 0 24 24" id="test-jsx" xmlns="http://www.w3.org/2000/svg"><path d="M5 19a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1c0-.21-.07-.41-.18-.57L13 8.35V4h-2v4.35L5.18 18.43c-.11.16-.18.36-.18.57m1 3a3 3 0 0 1-3-3c0-.6.18-1.16.5-1.63L9 7.81V6a1 1 0 0 1-1-1V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v1a1 1 0 0 1-1 1v1.81l5.5 9.56c.32.47.5 1.03.5 1.63a3 3 0 0 1-3 3H6m7-6l1.34-1.34L16.27 18H7.73l2.66-4.61L13 16m-.5-4a.5.5 0 0 1 .5.5.5.5 0 0 1-.5.5.5.5 0 0 1-.5-.5.5.5 0 0 1 .5-.5z" fill="#00bcd4"/></symbol><symbol viewBox="0 0 24 24" id="test-ts" xmlns="http://www.w3.org/2000/svg"><path d="M5 19a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1c0-.21-.07-.41-.18-.57L13 8.35V4h-2v4.35L5.18 18.43c-.11.16-.18.36-.18.57m1 3a3 3 0 0 1-3-3c0-.6.18-1.16.5-1.63L9 7.81V6a1 1 0 0 1-1-1V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v1a1 1 0 0 1-1 1v1.81l5.5 9.56c.32.47.5 1.03.5 1.63a3 3 0 0 1-3 3H6m7-6l1.34-1.34L16.27 18H7.73l2.66-4.61L13 16m-.5-4a.5.5 0 0 1 .5.5.5.5 0 0 1-.5.5.5.5 0 0 1-.5-.5.5.5 0 0 1 .5-.5z" fill="#0288d1"/></symbol><symbol viewBox="0 0 500 500" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="tex" xmlns="http://www.w3.org/2000/svg"><g font-weight="400" font-size="40" font-family="sans-serif" letter-spacing="0" word-spacing="0" fill="#42a5f5" stroke-linejoin="miter"><text style="line-height:125%" x="9.914" y="364.919"><tspan x="9.914" y="364.919" font-size="287.5">T</tspan></text><text style="line-height:125%" x="136.374" y="435.558"><tspan x="136.374" y="435.558" font-size="287.5">E</tspan></text><text style="line-height:125%" x="307.819" y="361.201"><tspan x="307.819" y="361.201" font-size="287.5">X</tspan></text></g></symbol><symbol viewBox="0 0 24 24" id="todo" xmlns="http://www.w3.org/2000/svg"><path d="M3 5h6v6H3V5m2 2v2h2V7H5m6 0h10v2H11V7m0 8h10v2H11v-2m-6 5l-3.5-3.5 1.41-1.41L5 17.17l4.59-4.58L11 14l-6 6z" fill="#42a5f5"/></symbol><symbol id="travis" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"><style id="jkstyle2">.jkst0{fill:#cb3349}.jkst1{fill:#f4edae}.jkst2{fill:#e6ccad}.jkst3{fill:#656c67}.jkst4{fill:#e5caa3}.jkst5{fill:#c7b39a}.jkst6{fill:#ebd599}.jkst7{fill:#2d3136}.jkst8{fill:#edf6fa}.jkst9{opacity:.8}.jkst10{opacity:.75;fill:#ebd599}</style><g id="jkg99" transform="translate(11.017 12.484) scale(.8858)"><g id="jkg10"><path class="jkst0" d="M47.781 86.572s-31.118 21.903-32.335 30.247l2.335-.48S55.045 91.64 84.584 88.628l.669-3.749z" id="jkpath4" fill="#cb3349"/><path class="jkst0" d="M96.629 83.442l-24.511 17.385 1.325 1.063c.999-.806 43.539-13.798 43.539-13.798l8.969-5.623c-6.018.749-29.322.973-29.322.973z" id="jkpath6" fill="#cb3349"/><path class="jkst0" d="M117.932 104.469c17.405 0 43.495-17.046 43.495-17.046l-8.434-1.605c-.417.417-13.6-.462-13.6-.462l-6.258-1.738-14.951 17.036-1.217 2.956c1.075-.437.965.859.965.859z" id="jkpath8" fill="#cb3349"/></g><path class="jkst0" d="M174.728 158.832l-5.377 1.514-24.843-.537-15.541-12.085-18.784 4.7-21.726-1.88-12.166 13.294-22.828 6.819-11.398-3.534-.574-.494 5.116 12.527s11.588 12.424 18.061 13.885c6.472 1.461 18.165-.105 26.935-1.463 8.769-1.357 15.764-4.489 18.582-9.603 2.818-5.117 3.236-6.578 3.236-6.578s8.353 11.797 15.556 13.155c7.203 1.357 28.605-5.952 28.605-5.952s13.051-3.549 15.346-8.038c2.297-4.489 8.353-19.209 8.353-19.209zM44.456 169.038l-.361-.166-2.013-1.736z" id="jkpath12" fill="#cb3349"/><g id="jkg97"><path class="jkst1" d="M195.832 70.085a48.125 48.125 0 0 0-.21-2.009 26.472 26.472 0 0 0-.215-1.424c-1.793-1.509-3.831-2.851-5.952-4.071-2.299-1.343-4.704-2.546-7.159-3.663-2.438-1.15-4.942-2.191-7.461-3.207a134.313 134.313 0 0 0-3.798-1.477c-1.269-.495-2.55-.956-3.835-1.424 2.697.447 5.366 1.059 8.015 1.741 1.723.446 3.437.945 5.14 1.477-12.112-31.655-41.07-52.27-72.687-52.27-31.622 0-60.577 20.615-72.686 52.27a109.044 109.044 0 0 1 5.137-1.477c2.653-.682 5.323-1.294 8.018-1.741-1.289.468-2.567.929-3.84 1.424-1.267.472-2.536.967-3.798 1.477-2.519 1.016-5.016 2.057-7.46 3.207-2.45 1.117-4.857 2.32-7.156 3.663-2.121 1.219-4.157 2.562-5.957 4.071-.075.457-.151.951-.21 1.424a51.768 51.768 0 0 0-.21 2.009 51.354 51.354 0 0 0-.177 4.061 59.216 59.216 0 0 0 .5 8.11c.37 2.692.864 5.366 1.595 7.951.36 1.295.768 2.572 1.24 3.808.237.617.495 1.225.764 1.816.134.294.274.585.413.864l.172.328c.199.101.408.204.607.3l1.204.575c.671.305 1.6.746 2.368 1.09.043-.037.086-.075.123-.114l-2.235-8.513c.474-.13 4.718-1.225 12.032-2.617a38.816 38.816 0 0 1-1.772-.381c-1.665-.414-3.309-.919-4.899-1.564a22.415 22.415 0 0 1-2.309-1.115c-.742-.426-1.472-.908-2.037-1.548 8.036 2.622 24.64 1.434 39.399-.091 13.499-1.391 27.029-2.293 40.63-2.32 13.602.027 27.137.929 40.63 2.32 14.766 1.525 31.37 2.713 39.405.091-.564.64-1.293 1.123-2.035 1.548a22.5 22.5 0 0 1-2.308 1.115c-1.592.645-3.234 1.15-4.899 1.564-.247.059-.496.113-.743.166 8.02 1.488 12.689 2.697 13.188 2.831l-2.138 8.11c.43-.194.864-.381 1.29-.574l1.202-.575c.2-.097.403-.199.607-.3l.166-.328c.146-.279.286-.57.419-.864.27-.591.528-1.199.764-1.816a42.235 42.235 0 0 0 1.241-3.808c.731-2.585 1.225-5.259 1.595-7.951.345-2.685.526-5.398.501-8.11a50.874 50.874 0 0 0-.179-4.059z" id="jkpath14" fill="#f4edae"/><path class="jkst2" d="M116.787 182.661c-1.064.16-2.128.295-3.186.375-.682.033-1.404.102-2.059.102l-.242.005c.822-1.837 1.446-3.26 1.919-4.339.963 1.08 2.188 2.417 3.568 3.857z" id="jkpath16" fill="#e6ccad"/><path class="jkst2" d="M119.101 185.018c3.304 3.272 7.398 5.146 11.904 5.479-7.569 3.074-14.702 4.26-20.197 4.63-5.478.367-11.032-.279-16.474-1.771.456-.082.79-.14 1.193-.189.447-.054 10.206-1.327 14.605-7.868l.413.009 1.08-.009c.731 0 1.395-.06 2.094-.087a43.69 43.69 0 0 0 4.878-.703c.167.171.333.338.504.509z" id="jkpath18" fill="#e6ccad"/><path class="jkst3" d="M128.464 87.071a98.82 98.82 0 0 1-1.048 1.343c-1.933 2.444-4.614 5.57-7.794 8.627a369.585 369.585 0 0 0-11.404-.177c-6.46 0-12.655.171-18.537.457 8.311-3.449 18.296-6.818 29.109-8.842a113.323 113.323 0 0 1 9.674-1.408z" id="jkpath20" fill="#656c67"/><path class="jkst3" d="M79.821 90.792c-2.966 2.084-6.317 4.744-9.566 7.971a360.155 360.155 0 0 0-21.567 2.81c9.207-4.232 19.713-8.127 31.133-10.781z" id="jkpath22" fill="#656c67"/><path class="jkst3" d="M181.48 107.969l-3.384 23.679-16.212 11.355-42.283-4.807-6.365-20.961a1.383 1.383 0 0 0-1.108-.971c-1.567-.253-2.953-.382-4.108-.382-1.16 0-2.541.129-4.115.382-.522.086-.95.461-1.106.971l-6.209 20.45-42.047 9.357-16.662-11.672-3.283-26.572c.715-.404 1.441-.806 2.176-1.209 1.031-.222 2.191-.457 3.475-.704l3.094 25.073c.048.392.264.741.586.967l11.462 8.032a1.425 1.425 0 0 0 1.101.213l34.57-7.692c.119-.027.237-.069.344-.124a1.39 1.39 0 0 0 .682-.827l6.225-20.498c1.67-.43 5.947-1.429 9.706-1.429 3.749 0 8.03.999 9.701 1.429l6.225 20.498c.161.532.624.912 1.176.977l34.57 3.927c.335.037.677-.05.952-.242l11.469-8.025c.31-.22.52-.566.573-.946l3.062-21.421c2.301.444 4.224.846 5.733 1.172z" id="jkpath24" fill="#656c67"/><path class="jkst3" d="M185.751 93.119l-2.976 11.29c-6.086-1.342-19.456-3.975-37.654-5.747 5.946-2.535 12-5.715 17.531-9.69 10.829 1.53 18.78 3.169 23.099 4.147z" id="jkpath26" fill="#656c67"/><g id="jkg32"><path class="jkst4" d="M63.841 128.441c2.357-1.274 5.021-1.085 9.19-1.079.447.011.908.005 1.39-.005.41-.005.822-.011 1.258-.022 4.296-.042 7.869.366 7.806-6.381-.065-6.746-3.062-12.198-7.354-12.155-4.297.037-8.454 5.564-8.197 12.306.07 1.756.328 3.023.742 3.937-3.745.938-4.777 3.254-4.835 3.399zm51.657-27.749a46.634 46.634 0 0 1-5.249 3.712l-6.097 3.68a52.065 52.065 0 0 0-7.331 1.467 1.216 1.216 0 0 0-.317.14 1.406 1.406 0 0 0-.629.794l-6.209 20.46-33.185 7.38-10.452-7.321-3.041-24.634c5.936-1.09 13.874-2.352 23.41-3.42a56.802 56.802 0 0 0-2.955 3.855l-5.677 8.149 8.266-5.511c.123-.086 5.387-3.549 13.998-7.761a377.407 377.407 0 0 1 35.468-.99z" id="jkpath28" fill="#e5caa3"/><path class="jkst4" d="M151.835 125.675c-.042-.16-.945-2.873-4.942-2.397.461-1.003.666-2.356.521-4.21-.528-6.731-4.443-12.08-8.735-11.931-4.292.152-7.042 5.731-6.805 12.478.236 6.741 3.84 6.694 8.132 6.543 5.77-.107 8.939-1.88 11.829-.483zm21.18-19.385l-2.992 20.944-10.539 7.379-33.141-3.766-6.183-20.363a1.41 1.41 0 0 0-.945-.934c-.205-.06-4.308-1.23-8.659-1.607l.795-.053c.687-.049 12.118-1.451 25.767-6.157 15.115 1.161 27.458 3.02 35.897 4.557z" id="jkpath30" fill="#e5caa3"/></g><g id="jkg38"><path class="jkst5" d="M63.841 128.441c2.357-1.274 5.021-1.085 9.19-1.079.447.011.908.005 1.39-.005.41-.005.822-.011 1.258-.022 4.296-.042 7.869.366 7.806-6.381-.065-6.746-3.062-12.198-7.354-12.155-4.297.037-8.454 5.564-8.197 12.306.07 1.756.328 3.023.742 3.937-3.745.938-4.777 3.254-4.835 3.399zm51.657-27.749a46.634 46.634 0 0 1-5.249 3.712l-6.097 3.68a52.065 52.065 0 0 0-7.331 1.467 1.216 1.216 0 0 0-.317.14 1.406 1.406 0 0 0-.629.794l-6.209 20.46-33.185 7.38-10.452-7.321-3.041-24.634c5.936-1.09 13.874-2.352 23.41-3.42a56.802 56.802 0 0 0-2.955 3.855l-5.677 8.149 8.266-5.511c.123-.086 5.387-3.549 13.998-7.761a377.407 377.407 0 0 1 35.468-.99z" id="jkpath34" fill="#c7b39a"/><path class="jkst5" d="M151.835 125.675c-.042-.16-.945-2.873-4.942-2.397.461-1.003.666-2.356.521-4.21-.528-6.731-4.443-12.08-8.735-11.931-4.292.152-7.042 5.731-6.805 12.478.236 6.741 3.84 6.694 8.132 6.543 5.77-.107 8.939-1.88 11.829-.483zm21.18-19.385l-2.992 20.944-10.539 7.379-33.141-3.766-6.183-20.363a1.41 1.41 0 0 0-.945-.934c-.205-.06-4.308-1.23-8.659-1.607l.795-.053c.687-.049 12.118-1.451 25.767-6.157 15.115 1.161 27.458 3.02 35.897 4.557z" id="jkpath36" fill="#c7b39a"/></g><path class="jkst2" d="M187.481 115.502c.508.419.911 1.504.456 6.558-.559 6.188-3.16 17.049-4.771 18.8-1.778.344-5.505-.064-7.778-.595.393-1.559.505-2.306.822-3.9l3.975-2.781c.317-.22.526-.566.58-.941l2.778-19.466c1.686.912 3.421 1.899 3.938 2.325z" id="jkpath40" fill="#e6ccad"/><path class="jkst2" d="M40.937 140.908c.199.704.408 1.407.624 2.1-2.139.628-6.495 1.23-8.465.886-1.633-1.645-4.679-12.966-5.345-18.978-.543-4.871-.162-5.924.333-6.334.575-.483 2.728-1.708 4.593-2.707l2.519 20.449c.048.393.257.741.586.967z" id="jkpath42" fill="#e6ccad"/><path class="jkst2" d="M121.347 141.194l-.151 1.305s-4.581 4.248-11.956 5.199c-7.375.95-13.171-3.582-13.171-3.582.242.788.586 2.567 2.256 4.086a53.184 53.184 0 0 0-6.313-.393c-.804 0-1.616.023-2.401.061-4.539.237-10.924 7.1-15.414 14.014-2.203.697-9.089 2.883-17.06 5.237-7.44-10.309-11.098-20.842-11.469-21.932l.005-.006c-.15-.419-.301-.839-.441-1.268l1.913 1.338v.005l4.726 3.309 1.58 1.101c.236.167.515.253.794.253.102 0 .204-.011.305-.031l43.435-9.67a1.385 1.385 0 0 0 1.025-.95l6.194-20.39c1.069-.145 2.008-.22 2.814-.22.801 0 1.746.075 2.815.22l6.374 20.997c.162.532.624.919 1.171.977z" id="jkpath44" fill="#e6ccad"/><path class="jkst2" d="M170.926 140.066l1.402-.984c-.232.973-.484 1.94-.747 2.896-1.949 6.248-4.25 11.774-6.805 16.656-.565.039-1.161.061-1.8.061-1.972 0-3.986-.167-6.215-.371-3.868-.355-10.007-1.058-11.946-1.283-1.67-1.332-7.385-5.873-12.14-9.615-.187-.151-.348-.291-.505-.42-.837-.708-1.789-1.513-3.717-1.513-1.751 0-4.308.638-10.489 2.508 3.212-2.401 3.233-5.5 3.233-5.5l.151-1.305 40.748 4.629a1.41 1.41 0 0 0 .955-.241l4.094-2.868z" id="jkpath46" fill="#e6ccad"/><path class="jkst6" d="M140.937 54.337c.124 3.625.033 10.194-1.655 16.345a1.335 1.335 0 0 0 0 .704 259.298 259.298 0 0 0-6.446-.591c2.412-5.054 2.938-10.436 3.052-12.332 1.852-1.317 3.696-2.896 5.049-4.126z" id="jkpath48" fill="#ebd599"/><path class="jkst6" d="M79.456 58.462c.112 1.896.638 7.267 3.046 12.317-2.149.171-4.297.37-6.441.596a1.328 1.328 0 0 0 0-.694c-1.686-6.139-1.772-12.714-1.654-16.345 1.353 1.231 3.19 2.81 5.049 4.126z" id="jkpath50" fill="#ebd599"/><path class="jkst7" d="M151.835 125.675c-2.89-1.396-6.059.377-11.828.484-4.292.151-7.896.198-8.132-6.543-.237-6.747 2.513-12.326 6.805-12.478 4.292-.15 8.207 5.2 8.735 11.931.145 1.854-.06 3.207-.521 4.21 3.996-.477 4.899 2.235 4.941 2.396zm-13.488-9.878a2.203 2.203 0 0 0 2.154-2.235 2.186 2.186 0 0 0-2.235-2.153 2.194 2.194 0 0 0 .081 4.388z" id="jkpath52" fill="#2d3136"/><circle transform="rotate(-1.049 138.093 113.428)" class="jkst8" cx="138.307" cy="113.602" id="jkellipse54" r="2.194" fill="#edf6fa"/><path class="jkst7" d="M83.484 120.953c.063 6.747-3.509 6.339-7.806 6.381-.435.011-.848.016-1.258.022-.482.011-.944.016-1.39.005-4.168-.005-6.833-.194-9.19 1.079.058-.145 1.09-2.461 4.835-3.4-.414-.914-.673-2.181-.742-3.937-.257-6.741 3.9-12.269 8.197-12.306 4.292-.042 7.289 5.411 7.354 12.156zm-6.634-3.529a2.195 2.195 0 1 0-.122-4.388 2.195 2.195 0 0 0 .122 4.388z" id="jkpath56" fill="#2d3136"/><circle transform="rotate(-1.473 76.78 115.216)" class="jkst8" cx="76.79" cy="115.23" id="jkellipse58" r="2.195" fill="#edf6fa"/><g class="jkst9" id="jkg64" opacity=".8"><path class="jkst6" d="M50.691 75.155s.667-8.692 2.03-12.023c.702-1.717 4.996-2.81 8.276-3.591 3.278-.78 8.508-2.342 9.524 2.264 1.015 4.606 2.653 7.963 3.746 9.446l-1.404-18.97-22.562 5.464-1.484 16.786.703 1.327 1.171-.703" id="jkpath60" fill="#ebd599"/><path class="jkst6" d="M164.855 75.155s-.666-8.692-2.029-12.023c-.703-1.717-4.997-2.81-8.275-3.591-3.28-.78-8.51-2.342-9.526 2.264-1.013 4.606-2.654 7.963-3.748 9.446l1.407-18.97 22.562 5.464 1.483 16.786-.703 1.327-1.171-.703" id="jkpath62" fill="#ebd599"/></g><path class="jkst10" d="M132.965 18.378s-.598 45.49-11.224 45.49h-14.875-12.752c-10.626 0-11.484-45.47-11.484-45.47l-5.22 15.438.085 21.183 3.707 2.947 1.685 9.096 2.357 5.307 45.482.084 2.105-3.791 1.769-6.4.254-4.043 5.023-14.341z" id="jkpath66" opacity=".75" fill="#ebd599"/><path class="jkst10" d="M166.429 60.794s2.187 15.692 7.974 18.522c5.788 2.829 0 0 0 0l-8.103-2.444z" id="jkpath68" opacity=".75" fill="#ebd599"/><path class="jkst10" d="M48.908 60.794s-2.187 15.692-7.975 18.522c-5.788 2.829 0 0 0 0l8.104-2.444z" id="jkpath70" opacity=".75" fill="#ebd599"/><path class="jkst7" d="M167.987 76.8c2.755.902 5.526 1.858 8.036 3.325-1.343-.532-2.729-.913-4.126-1.257a70.385 70.385 0 0 0-4.201-.924c-2.82-.531-5.65-.982-8.498-1.327-2.841-.37-5.687-.682-8.546-.924-2.858-.241-5.709-.483-8.573-.65-11.446-.704-22.924-.88-34.41-.892-11.483.006-22.962.221-34.409.897-2.862.166-5.715.409-8.572.651-2.857.241-5.71.548-8.546.923-2.847.345-5.678.796-8.498 1.327-1.407.264-2.81.57-4.206.919-1.391.344-2.783.725-4.126 1.257 2.509-1.466 5.28-2.427 8.041-3.331.232-.075.467-.139.703-.214-.015-.059-.032-.113-.043-.177-.048-.317-1.069-7.859.709-18.645.086-.516.456-.935.962-1.075l2.917-.831c.634-22.625 9.952-33.266 10.243-33.594-8.326 13.397-8.25 29.286-8.106 32.986l18.128-5.152c.016-.005.026-.005.042-.01.076-.016.151-.027.226-.032.021 0 .049-.006.075-.006a1.19 1.19 0 0 1 .297.027c.015 0 .031.011.053.016.075.016.145.042.224.075.033.016.054.033.086.049.058.033.119.07.177.112.016.011.034.016.049.033l.032.032c.016.016.037.027.054.044.012.016.494.493 1.262 1.209-.182-5.973.102-23.108 8.262-37.31-.172.498-6.646 19.428-4.415 40.645.724.58 1.486 1.149 2.229 1.649.359.247.58.655.585 1.09.006.07.161 6.833 3.148 12.586.042.086.074.177.102.268 7.429-.505 14.878-.709 22.312-.714 7.436.005 14.88.22 22.307.731.027-.097.06-.193.109-.285 2.986-5.753 3.142-12.516 3.142-12.586.01-.436.231-.843.591-1.09.741-.5 1.493-1.069 2.224-1.649 2.234-21.217-4.24-40.147-4.411-40.645 8.153 14.201 8.444 31.336 8.262 37.31a62.536 62.536 0 0 0 1.261-1.209c.016-.016.039-.027.053-.044.012-.01.018-.021.033-.032.016-.016.033-.022.049-.033.06-.042.119-.079.177-.118.028-.01.054-.027.081-.043.081-.033.155-.059.236-.08.016 0 .033-.011.049-.011.096-.021.2-.032.296-.027.027 0 .049.006.07.006.075.005.156.016.231.032.012.006.028.006.042.01l18.129 5.152c.146-3.7.221-19.59-8.104-32.986.289.328 9.609 10.969 10.237 33.594l2.922.831c.499.14.875.559.962 1.075 1.777 10.786.752 18.328.708 18.645-.01.065-.026.124-.042.182.239.07.47.139.707.215zm-3.297-.968c.14-1.207.789-7.809-.591-16.801l-20.52-5.833c.184 3.475.265 11.012-1.707 18.199a1.619 1.619 0 0 1-.101.258c.203.021.408.037.606.064 5.769.661 11.511 1.584 17.189 2.83 1.712.398 3.426.823 5.124 1.283zm-25.409-5.151c1.688-6.15 1.779-12.72 1.655-16.345-1.353 1.23-3.197 2.809-5.049 4.125-.114 1.896-.64 7.278-3.052 12.332 2.149.173 4.298.366 6.446.591a1.33 1.33 0 0 1 0-.703zm-56.78.098c-2.408-5.05-2.934-10.422-3.046-12.317-1.858-1.316-3.696-2.895-5.049-4.125-.119 3.631-.032 10.206 1.654 16.345.065.237.058.473 0 .694 2.145-.227 4.292-.425 6.441-.597zm-8.933.864a1.65 1.65 0 0 1-.098-.247c-1.975-7.187-1.889-14.723-1.712-18.199L51.244 59.03c-1.38 8.982-.736 15.583-.597 16.797 1.703-.462 3.411-.887 5.131-1.284 2.835-.628 5.693-1.154 8.556-1.638 2.869-.478 5.747-.843 8.626-1.192.205-.027.404-.042.608-.07z" id="jkpath72" fill="#2d3136"/><g id="jkXMLID_1_"><g id="jkg78"><path class="jkst7" d="M129.293 18.973v17.025h-12.068v-4.974h-2.72v22.981h4.109v12.85H97.505v-12.85h4.092v-22.98h-2.711v4.974h-12.06V18.973zm-3.626 13.408v-9.789H90.443v9.789h4.816v-4.974h9.964v30.225h-4.1v5.606h13.865v-5.606h-4.1V27.407h9.964v4.974z" id="jkpath74" fill="#2d3136"/><path class="jkst0" id="jkpolygon76" fill="#cb3349" d="M101.123 57.632h4.1V27.407h-9.964v4.974h-4.816v-9.79h35.224v9.79h-4.816v-4.974h-9.964v30.225h4.1v5.606h-13.864z"/></g></g><path class="jkst3" d="M30.694 93.119c1.759-.399 4.136-.907 7.051-1.47a104.37 104.37 0 0 0-6.222 4.597z" id="jkpath83" fill="#656c67"/><path class="jkst5" d="M95.111 139.78s.492 3.165-3.938 4.519c-4.428 1.355-32.482 9.716-35.682 9.263-3.199-.451-11.319-5.874-11.319-5.874l-1.969-7.004 12.016 7.492z" id="jkpath85" fill="#c7b39a"/><path class="jkst5" d="M120.242 139.167s-.354 3.182 4.131 4.345c4.484 1.161 32.875 8.295 36.05 7.704 3.176-.591 11.053-6.361 11.053-6.361l1.663-7.084-11.045 6.588z" id="jkpath87" fill="#c7b39a"/><path class="jkst5" d="M28.412 133.956s3.887 7.775 10.166 5.083l4.485 1.645-.448 3.29-9.419 1.195-2.541-1.494z" id="jkpath89" fill="#c7b39a"/><path class="jkst5" d="M187.551 131.822s-6.353 8.115-12.632 5.424l-2.019 1.302.448 3.289 9.419 1.196 2.54-1.495z" id="jkpath91" fill="#c7b39a"/><path class="jkst5" d="M89.279 192.904s23.03 11.611 49.106-4.188l-8.374-.571s-18.272 7.232-32.738 3.235z" id="jkpath93" fill="#c7b39a"/><path class="jkst7" d="M112.626 171.509l1.594 1.899c.036.046 3.577 4.26 7.906 8.552 2.879 2.853 6.357 4.297 10.343 4.297 1.361 0 2.791-.175 4.235-.523 1.34-.326 2.796-.673 4.287-1.03 5.384-1.287 11.482-2.749 14.438-3.577.585-.166 1.238-.315 1.925-.472 3.935-.909 9.329-2.163 12.187-7.889 2.149-4.297 5.047-9.874 7.197-13.961-1.863.859-3.816 1.79-5.203 2.52-2.138 1.123-4.938 1.667-8.558 1.667-2.152 0-4.266-.181-6.605-.389-4.675-.43-12.586-1.361-12.667-1.372l-.606-.067-.478-.383c-.071-.052-7.003-5.575-12.606-9.981-.227-.186-.434-.358-.621-.513-.59-.503-.59-.503-.942-.503-1.797 0-7.02 1.62-18.462 5.167l-.703.223-.689-.26c-.078-.026-7.585-2.81-16.581-2.81-.736 0-1.47.019-2.185.056-.901.046-5.958 2.448-12.425 12.68l-.419.657-.741.238c-.107.037-11.238 3.63-23.042 7.005l-.766.218-.725-.337c-.077-.031-4.696-2.174-9.091-4.194 2.397 3.541 5.462 7.958 8.159 11.422 4.711 6.067 10.649 11.674 22.034 11.674 1.428 0 2.945-.088 4.503-.265 11.581-1.309 14.563-1.837 16.168-2.117.543-.092.973-.171 1.522-.238.088-.011 9.571-1.237 12.232-7.206 2.744-6.134 3.298-7.595 3.319-7.651l.968-2.583s.12-.669.317-.877c0 .005 0 .005.005.005l.019.016c.305.219.757.902.757.902zM40.499 55.71c-2.516 1.014-5.016 2.06-7.46 3.209-2.449 1.119-4.856 2.32-7.155 3.66-2.121 1.222-4.157 2.563-5.954 4.076-.077.455-.149.952-.211 1.423a51.357 51.357 0 0 0-.388 6.068c-.026 2.713.16 5.426.502 8.112.372 2.692.864 5.369 1.594 7.952a41.963 41.963 0 0 0 1.243 3.804c.233.623.492 1.228.762 1.818.134.294.274.585.413.864l.172.326c.201.104.409.207.605.3l1.206.574c.673.311 1.6.751 2.366 1.093.046-.037.088-.078.124-.114l-2.231-8.511c.471-.129 4.717-1.227 12.032-2.619a33.744 33.744 0 0 1-1.775-.379 36.704 36.704 0 0 1-4.898-1.563 22.857 22.857 0 0 1-2.309-1.119c-.741-.425-1.471-.905-2.035-1.547 8.035 2.624 24.637 1.433 39.398-.088 13.501-1.393 27.028-2.293 40.628-2.325 13.6.031 27.138.931 40.63 2.325 14.77 1.522 31.374 2.713 39.406.088-.564.642-1.293 1.122-2.034 1.547-.739.42-1.522.782-2.309 1.119a36.965 36.965 0 0 1-4.903 1.563c-.244.056-.492.114-.741.166 8.02 1.486 12.689 2.697 13.186 2.832l-2.138 8.107c.43-.192.864-.377 1.288-.574l1.207-.574c.196-.094.404-.196.606-.3l.166-.326c.144-.279.284-.57.419-.864.27-.591.528-1.196.767-1.818.471-1.231.879-2.51 1.236-3.804.731-2.583 1.228-5.26 1.595-7.952.346-2.686.528-5.4.502-8.112a52.755 52.755 0 0 0-.176-4.059 51.573 51.573 0 0 0-.213-2.009 29.83 29.83 0 0 0-.213-1.423c-1.797-1.513-3.831-2.853-5.954-4.076-2.299-1.34-4.704-2.541-7.159-3.66-2.438-1.149-4.943-2.195-7.46-3.209a140.105 140.105 0 0 0-3.801-1.476c-1.267-.491-2.552-.956-3.835-1.423 2.696.445 5.369 1.06 8.013 1.739 1.724.446 3.444.948 5.141 1.481-12.11-31.658-41.07-52.272-72.685-52.272-31.622 0-60.576 20.614-72.684 52.272a107.832 107.832 0 0 1 5.135-1.481c2.651-.678 5.322-1.294 8.02-1.739-1.29.466-2.568.931-3.842 1.423-1.268.47-2.535.967-3.799 1.475zm159.43 18.316a53.972 53.972 0 0 1-.258 8.733 55.462 55.462 0 0 1-1.619 8.605c-.4 1.414-.86 2.811-1.404 4.198a38.295 38.295 0 0 1-.89 2.071c-.161.341-.331.678-.523 1.025l-.284.512a8.975 8.975 0 0 1-.348.574l-.294.457-.461.237c-.492.254-.895.445-1.342.653l-1.298.585a88.22 88.22 0 0 1-2.62 1.065c-.611.239-1.15.457-1.662.674l-1.444 5.487c-.036-.009-.471-.12-1.283-.315l-.078.574c1.594.833 4.726 2.522 5.793 3.403 2.148 1.775 2.299 4.587 1.823 9.841-.244 2.697-1.139 7.946-2.381 12.767-2.144 8.298-3.283 9.273-4.753 9.649-.746.192-1.894.383-3.008.383-2.266 0-5.353.063-7.429-.439-.533 1.888-2.055 6.812-5.068 12.962.151-.073.3-.135.435-.207 3.717-1.952 10.861-5.064 11.162-5.199l5.643-2.452-2.89 5.435c-.067.118-6.264 11.773-10.059 19.383-3.769 7.538-10.835 9.179-15.065 10.151-.637.151-1.241.291-1.733.425-3.035.854-9.18 2.319-14.599 3.623-.064.016-.13.033-.197.042a64.057 64.057 0 0 1-10.955 5.411c-14.568 5.518-29.923 5.208-43.844.092a647.05 647.05 0 0 1-9.193 1.097 45.12 45.12 0 0 1-4.985.291c-13.264 0-20.294-6.736-25.425-13.331-5.493-7.062-12.212-17.546-12.497-17.985L31 158.426l6.585 2.961c3.152 1.419 12.524 5.757 15.205 7 .217-.061.43-.124.642-.186-4.457-6.357-8.112-13.605-10.695-21.634-2.195.662-5.576 1.175-8.206 1.175-.961 0-1.822-.072-2.484-.228-1.471-.336-3.148-1.754-5.431-9.795-1.325-4.668-2.314-9.764-2.603-12.387-.57-5.121-.466-7.864 1.662-9.636 1.283-1.071 5.611-3.344 6.507-3.809l-.192-1.58c-13.75 8.08-21.991 15.22-22.157 15.366L0 134.302l7.005-11.047c5.544-8.755 11.948-15.832 17.84-21.284-.244-.098-.471-.196-.71-.294l-1.299-.585a34.907 34.907 0 0 1-1.34-.653l-.461-.237-.295-.457c-.166-.249-.238-.388-.347-.574l-.29-.512c-.181-.347-.358-.684-.518-1.025a30.878 30.878 0 0 1-.89-2.071 44.74 44.74 0 0 1-1.404-4.198 54.745 54.745 0 0 1-1.62-8.605 54.664 54.664 0 0 1-.259-8.733c.078-1.455.218-2.909.419-4.354.104-.725.213-1.45.358-2.17.15-.734.296-1.418.518-2.221l.155-.564.404-.317c2.294-1.802 4.768-3.163 7.284-4.369a78.87 78.87 0 0 1 6.311-2.616c5.943-16.493 16.162-31.118 29.591-41.311C74.337 5.57 90.664 0 107.671 0s33.334 5.57 47.218 16.106c13.43 10.193 23.649 24.819 29.588 41.307a78.282 78.282 0 0 1 6.316 2.62c2.515 1.206 4.99 2.567 7.283 4.369l.404.317.156.564c.227.803.372 1.487.517 2.221.146.72.26 1.445.357 2.17.203 1.443.348 2.897.419 4.352zm-11.995 48.031c.456-5.052.058-6.139-.455-6.554-.513-.43-2.247-1.412-3.935-2.329l-2.779 19.464a1.39 1.39 0 0 1-.58.942l-3.977 2.781c-.315 1.593-.429 2.345-.817 3.903 2.273.528 5.999.938 7.775.595 1.612-1.748 4.214-12.61 4.768-18.802zm-5.161-17.648l2.977-11.29c-4.318-.978-12.27-2.615-23.1-4.148-5.53 3.976-11.582 7.155-17.53 9.691 18.199 1.771 31.57 4.406 37.653 5.747zm-4.68 27.237l3.385-23.676a240.127 240.127 0 0 0-5.731-1.169l-3.059 21.422a1.415 1.415 0 0 1-.575.943l-11.472 8.023c-.27.192-.616.28-.947.243l-34.572-3.929a1.391 1.391 0 0 1-1.176-.973l-6.227-20.5c-1.668-.431-5.949-1.43-9.696-1.43-3.764 0-8.041.999-9.708 1.43l-6.228 20.5a1.388 1.388 0 0 1-1.025.947l-34.572 7.692a1.483 1.483 0 0 1-.306.033 1.36 1.36 0 0 1-.792-.25l-11.467-8.029a1.396 1.396 0 0 1-.585-.968l-3.091-25.072c-1.284.249-2.443.487-3.479.703-.734.405-1.46.809-2.174 1.213l3.281 26.568 16.666 11.675 42.047-9.354 6.207-20.449a1.389 1.389 0 0 1 1.108-.975c1.574-.253 2.95-.382 4.116-.382 1.153 0 2.536.129 4.105.382.528.083.957.461 1.108.975l6.366 20.956 42.282 4.808zm-8.07-4.411l2.992-20.948c-8.439-1.536-20.78-3.394-35.897-4.554-13.647 4.707-25.077 6.108-25.766 6.155l-.797.057c4.353.374 8.454 1.544 8.66 1.605.452.135.804.481.944.933l6.186 20.366 33.138 3.764zm2.303 11.845l-1.404.983-3.779 2.651-4.095 2.868c-.279.192-.621.28-.954.243l-40.746-4.633-2.966-.337a1.39 1.39 0 0 1-1.171-.977l-6.377-20.998c-1.066-.145-2.014-.219-2.81-.219-.809 0-1.751.073-2.817.219l-6.192 20.392a1.383 1.383 0 0 1-1.025.946l-43.435 9.672c-.103.02-.206.03-.305.03-.279 0-.559-.083-.798-.253l-1.578-1.098-4.726-3.307v-.011l-1.91-1.335c.135.43.289.85.441 1.268l-.006.006c.368 1.092 4.028 11.622 11.467 21.929a873.96 873.96 0 0 0 17.057-5.234c4.488-6.917 10.877-13.777 15.418-14.014a51.12 51.12 0 0 1 2.402-.061c2.221 0 4.344.16 6.31.393-1.671-1.517-2.013-3.298-2.256-4.085 0 0 5.793 4.53 13.17 3.584 7.378-.953 11.959-5.204 11.959-5.204s-.021 3.102-3.236 5.503c6.182-1.869 8.739-2.511 10.489-2.511 1.931 0 2.883.808 3.717 1.519.161.129.322.268.507.419a3519.302 3519.302 0 0 1 12.141 9.614c1.936.227 8.075.926 11.943 1.283 2.23.201 4.245.372 6.217.372.637 0 1.233-.026 1.797-.063 2.558-4.88 4.857-10.411 6.808-16.653.261-.96.516-1.928.743-2.901zm-15.034-51.593c-.01-.006-.02-.012-.031-.012a551.624 551.624 0 0 0-9.826-.651 905.6 905.6 0 0 0-13.667-.668 72.95 72.95 0 0 1-1.574 2.225c-2.479 3.355-7.398 9.51-13.704 14.729 8.926-1.6 24.409-5.56 37.803-14.905.336-.238.668-.486.999-.718zm-29.876.926c.377-.471.729-.926 1.044-1.34-3.281.331-6.512.808-9.67 1.408-10.814 2.024-20.801 5.389-29.11 8.837a383.259 383.259 0 0 1 18.54-.455c3.908 0 7.708.067 11.404.176 3.179-3.056 5.861-6.182 7.792-8.626zm3.587 102.085c-4.503-.332-8.598-2.205-11.903-5.477a271.86 271.86 0 0 0-.502-.512 44.25 44.25 0 0 1-4.881.704c-.698.026-1.361.087-2.091.087l-1.083.011-.413-.011c-4.396 6.539-14.159 7.813-14.605 7.87-.403.046-.734.103-1.191.186 5.442 1.491 10.996 2.138 16.474 1.77 5.492-.367 12.627-1.558 20.195-4.628zm-17.4-7.461a45.604 45.604 0 0 0 3.184-.378 138.958 138.958 0 0 1-3.568-3.857 398.441 398.441 0 0 1-1.92 4.339h.243c.658.001 1.378-.071 2.061-.104zm-3.354-78.632c1.827-1.103 3.582-2.366 5.249-3.712a422.33 422.33 0 0 0-7.278-.072c-10.137 0-19.606.415-28.189 1.061-8.61 4.209-13.875 7.672-13.998 7.76l-8.268 5.514 5.679-8.149a52.452 52.452 0 0 1 2.956-3.857c-9.536 1.066-17.477 2.329-23.41 3.422l3.038 24.632 10.453 7.321 33.184-7.378 6.212-20.464c.104-.337.331-.621.627-.793.098-.063.202-.109.315-.14.192-.052 3.51-.999 7.336-1.465zm3.816-18.788c-2.31-.036-4.623-.057-6.933-.062h-.005c-3.39.005-6.787.041-10.189.109l-6.269 2.971c-.005.005-.041.021-.088.048-.942.46-9.174 4.613-16.919 12.021 6.943-3.65 17.146-8.418 29.153-12.115a144.186 144.186 0 0 1 11.25-2.972zM70.251 98.761c3.251-3.225 6.605-5.886 9.567-7.967-11.415 2.651-21.923 6.543-31.128 10.778a360.846 360.846 0 0 1 21.561-2.811zm2.159-9.949a150.122 150.122 0 0 1 11.813-2.796c-5.798.212-11.6.481-17.393.808-3.366.186-6.715.414-10.065.667-1.678.129-3.345.263-5.007.445-.476.046-.942.098-1.418.16-4.369 2.614-21.127 13.134-32.631 26.889 11.179-7.769 30.654-19.443 54.701-26.173zm-30.85 54.197a68.861 68.861 0 0 1-.621-2.102l-5.162-3.612a1.391 1.391 0 0 1-.586-.969l-2.516-20.449c-1.864.999-4.017 2.225-4.592 2.707-.497.409-.875 1.46-.336 6.332.668 6.01 3.712 17.333 5.348 18.979 1.968.347 6.327-.258 8.465-.886zm-3.815-51.36a229.005 229.005 0 0 0-7.051 1.47l.829 3.127a103.93 103.93 0 0 1 6.222-4.597z" id="jkpath95" fill="#2d3136"/></g></g></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="tune" xmlns="http://www.w3.org/2000/svg"><path d="M6.85 2.852h-2v6h2v-6m12 0h-2v10h2v-10m-16 10h2v8h2v-8h2v-2h-6v2m12-6h-2v-4h-2v4h-2v2h6v-2m-4 14h2v-10h-2v10m4-6v2h2v4h2v-4h2v-2h-6z" fill="#fbc02d" fill-rule="nonzero"/></symbol><symbol viewBox="0 0 50 50" id="twig" xmlns="http://www.w3.org/2000/svg"><path d="M9.727 47.556c-.125-.223-.297-2.168-.183-2.087.034.025.171.267.304.537.132.27.282.487.332.482.123-.011.075-1.196-.1-2.454-.331-2.398-1.176-4.435-2.358-5.69-.2-.212-.344-.4-.319-.419.093-.067 1.327.843 1.842 1.359.293.293.735.825.981 1.181.328.474.465.618.51.534.078-.147-.21-9.903-.376-12.701-.074-1.255.063-1.023.61 1.035 1.064 4.006 1.858 7.922 2.342 11.55.086.637.173 1.172.195 1.19.022.016.092.001.157-.034.888-.483 1.524-.667 2.55-.736.727-.048.945.062.35.178-1.15.222-1.99 1.013-2.344 2.201-.315 1.061-.327 2.707-.024 3.434.152.366.037.426-1.067.56-.716.088-.977.096-1.202.037-.356-.092-1.118-.098-1.195-.008-.031.036-.243.066-.47.066-.38 0-.423-.017-.535-.215zm1.974-3.233c.152-.205.072-.41-.204-.522-.225-.09-.263-.088-.437.025-.21.137-.252.43-.08.554.18.13.607.096.72-.057zm1.248.086a.763.763 0 0 0 .214-.203c.241-.33-.352-.622-.745-.366-.406.265.08.785.531.569zm2.288 3.094c-.033-.039.117-.387.334-.775.216-.387.411-.665.433-.618.07.152-.201 1.28-.33 1.372-.15.108-.354.117-.437.02zM8.2 47.092c-.29-.343-.221-.434.14-.182.176.123.321.263.321.31 0 .165-.279.087-.46-.128zm8.649-.145c0-.053.102-.18.227-.282.25-.204.312-.113.143.207-.095.18-.37.236-.37.075zm8.065-.827c-.243-.025-.48-.088-.527-.141-.11-.125-.114-3.043-.004-3.043.045 0 .132.149.193.331.127.38.228.42.31.124.094-.337.065-3.472-.039-4.297-.449-3.55-1.865-6.124-4.342-7.89-1.086-.774-2.653-1.436-4.047-1.711-.764-.15-.522-.224.598-.182 2.364.089 4.167.706 5.847 2.001a11.046 11.046 0 0 1 2.32 2.502c.453.682.64.854.64.584 0-.07.063-.882.139-1.805.679-8.26 2.396-15.1 4.984-19.86 1.86-3.422 5.108-6.817 7.885-8.244 1.397-.718 2.539-.988 4.02-.952.933.023 1.01.036 1.77.307a6.822 6.822 0 0 1 1.363.662c.612.407 1.309 1.004 1.235 1.058-.026.018-.343-.165-.705-.407-2.657-1.771-5.062-1.52-7.12.742-1.108 1.22-2.651 3.53-3.634 5.443-2.828 5.503-4.541 11.464-5.291 18.413-.163 1.509-.282 3.76-.195 3.703.032-.022.266-.52.518-1.108 1.597-3.723 3.578-6.428 5.79-7.908.672-.449 1.612-.904 1.715-.83.022.016-.172.22-.432.454-1.957 1.754-3.248 3.76-4.232 6.572-.938 2.68-1.366 5.588-1.368 9.3-.002 1.741.188 4.385.366 5.101.125.505.08.546-.585.546-.55 0-2.306.138-3.416.27-.414.05-.817.04-1.609-.036-.58-.056-1.129-.119-1.218-.14-.165-.037-.18-.014-.2.302-.01.186-.098.203-.728.139zm2.507-6.725c.294-.11.375-.22.375-.517 0-.63-1.309-.706-1.524-.088-.074.211.13.51.42.616.297.108.413.106.73-.011zm2.369-.052c.277-.222.318-.364.174-.611-.4-.691-1.755-.307-1.428.404.121.266.299.35.738.354.227 0 .387-.045.516-.147zm3.011 6.681c-.027-.05.088-.268.256-.484.879-1.135 1.22-1.544 1.284-1.544.04 0 .056.037.036.082l-.423.964c-.212.485-.445.924-.519.977-.169.122-.57.125-.634.005zm2.446-.596c0-.121.853-.683.896-.59.018.04-.056.209-.166.376-.168.259-.238.305-.464.305-.164 0-.266-.035-.266-.091zm-13.04-.124c-.177-.159-.493-.656-.462-.725.018-.038.248.1.512.309.264.207.457.405.428.438-.075.088-.371.074-.478-.022z" fill="#9bb92f" stroke-width=".078"/></symbol><symbol viewBox="0 0 500 500" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="typescript" xmlns="http://www.w3.org/2000/svg"><path d="M49 51h408v408H49V51zm246.669 314.879l19.463-1.702c.922 7.8 3.067 14.199 6.435 19.198 3.368 4.998 8.597 9.04 15.688 12.124 7.09 3.085 15.067 4.627 23.93 4.627 7.87 0 14.819-1.17 20.845-3.51 6.027-2.34 10.512-5.548 13.455-9.625 2.942-4.077 4.413-8.526 4.413-13.348 0-4.892-1.418-9.164-4.254-12.816-2.836-3.651-7.516-6.718-14.039-9.2-4.183-1.63-13.436-4.165-27.759-7.604s-24.355-6.683-30.099-9.732c-7.445-3.899-12.993-8.739-16.644-14.517-3.652-5.779-5.478-12.249-5.478-19.41 0-7.871 2.234-15.227 6.701-22.069 4.467-6.842 10.99-12.036 19.569-15.581 8.58-3.546 18.116-5.318 28.61-5.318 11.557 0 21.75 1.861 30.577 5.584 8.828 3.722 15.617 9.199 20.368 16.432 4.75 7.232 7.303 15.421 7.657 24.568l-19.782 1.489c-1.064-9.856-4.662-17.301-10.795-22.335-6.133-5.034-15.191-7.551-27.174-7.551-12.479 0-21.573 2.286-27.281 6.86-5.707 4.573-8.561 10.086-8.561 16.538 0 5.602 2.021 10.21 6.062 13.826 3.971 3.617 14.34 7.321 31.109 11.115 16.769 3.793 28.273 7.108 34.513 9.944 9.076 4.183 15.776 9.483 20.101 15.9 4.325 6.417 6.488 13.809 6.488 22.175 0 8.296-2.375 16.113-7.126 23.452-4.751 7.338-11.575 13.046-20.474 17.123-8.898 4.077-18.913 6.116-30.045 6.116-14.11 0-25.933-2.056-35.47-6.169-9.537-4.112-17.017-10.299-22.441-18.559-5.424-8.26-8.278-17.602-8.562-28.025zm-65.728 50.094V278.454h51.583v-18.399H157.938v18.399h51.37v137.519h20.633z" fill="#0288d1"/></symbol><symbol viewBox="0 0 500 500" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="typescript-def" xmlns="http://www.w3.org/2000/svg"><path d="M457 459H49V51h408v408zM69 71v368h368V71H69z" fill="#0288d1"/><text x="342.219" y="344.544" font-family="ArialMT" font-size="12" fill="#0288d1" transform="translate(-6058.94 -5838) scale(18.1514)"><tspan style="-inkscape-font-specification:sans-serif" font-family="sans-serif" font-weight="400">TS</tspan></text></symbol><symbol viewBox="0 0 24 24" id="url" xmlns="http://www.w3.org/2000/svg"><path d="M16 6h-3v1.9h3a4.1 4.1 0 0 1 4.1 4.1 4.1 4.1 0 0 1-4.1 4.1h-3V18h3a6 6 0 0 0 6-6c0-3.32-2.69-6-6-6M3.9 12A4.1 4.1 0 0 1 8 7.9h3V6H8a6 6 0 0 0-6 6 6 6 0 0 0 6 6h3v-1.9H8c-2.26 0-4.1-1.84-4.1-4.1M8 13h8v-2H8v2z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="verilog" xmlns="http://www.w3.org/2000/svg"><path d="M17.282 17.08H6.718V6.513h10.564m4.226 4.226V8.627h-2.113V6.514c0-1.173-.95-2.113-2.113-2.113H15.17V2.288h-2.113v2.113h-2.112V2.288H8.83v2.113H6.718c-1.173 0-2.113.94-2.113 2.113v2.113H2.492v2.113h2.113v2.113H2.492v2.113h2.113v2.113a2.113 2.113 0 0 0 2.113 2.113H8.83v2.113h2.113v-2.113h2.112v2.113h2.113v-2.113h2.113a2.113 2.113 0 0 0 2.113-2.113v-2.113h2.113v-2.113h-2.113V10.74m-6.339 2.113h-2.112V10.74h2.112m2.113-2.113H8.831v6.34h6.338z" fill="#ff7043" stroke-width="1.056"/></symbol><symbol viewBox="0 0 24 23.999999" id="vfl" xmlns="http://www.w3.org/2000/svg"><defs><style>.jra{fill:#f05223}.jrb{fill:url(#jra)}</style><radialGradient id="jra" cx="205.45" cy="208.29" r="225.35" gradientTransform="matrix(.04556 0 0 .0456 2.888 2.88)" gradientUnits="userSpaceOnUse"><stop stop-color="#ffd104" offset="0"/><stop stop-color="#faa60e" offset=".35"/><stop stop-color="#f05023" offset="1"/></radialGradient></defs><title>houdinibadge</title><g stroke-width=".046"><path class="jra" d="M19.97 3H4.03A1.03 1.031 0 0 0 3 4.031v4.135C4.548 6.977 6.563 6.21 8.948 6.21c5.107.003 8.35 3.574 8.348 8.081 0 3.13-1.46 5.485-3.746 6.71h6.42A1.03 1.031 0 0 0 21 19.968V4.031a1.03 1.031 0 0 0-1.03-1.03z" fill="#f4511e"/><path class="jrb" d="M3 17.722v2.247A1.03 1.031 0 0 0 4.03 21h1.837C4.474 20.21 3.49 19 3 17.722z" fill="url(#jra)"/><path class="jra" d="M8.948 8.231c-2.586-.09-4.598.86-5.948 2.264v3.163c.918-2.654 3.447-3.87 5.565-3.85 2.647.027 4.689 2.025 4.7 4.284.012 2.159-.892 3.748-3.33 4.14-1.33.213-3.411-.567-3.318-2.578.046-1.037.854-1.622 1.777-1.58-.905 1.213.293 2.102 1.139 1.921 1.048-.224 1.475-1.156 1.475-1.878 0-.762-.718-1.994-2.498-1.951-2.204.052-3.591 1.639-3.638 3.602-.056 2.468 2.253 4.091 4.622 4.121 3.48.046 5.543-2.24 5.539-5.586-.005-3.029-2.434-5.946-6.085-6.072z" fill="#f05223"/></g></symbol><symbol viewBox="0 0 24 24" id="virtual" xmlns="http://www.w3.org/2000/svg"><path d="M21 14H3V4h18m0-2H3c-1.11 0-2 .89-2 2v12a2 2 0 0 0 2 2h7l-2 3v1h8v-1l-2-3h7a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 281.25 281.25" id="visualstudio" xmlns="http://www.w3.org/2000/svg"><path d="M196.18 101.74l-52.778 42.444 52.778 40.889V101.74m-136.67 110l-30-18.889v-100L62.843 81.74l47.778 37 96.666-89.222 44.444 27.778v172.22l-55.555 22.222-85.111-81.555-51.555 41.555m3.333-48.889l20.667-19.111-20.667-19.778z" fill="#ab47bc" stroke-width="11.111"/></symbol><symbol viewBox="0 0 300 300" id="vscode" xmlns="http://www.w3.org/2000/svg"><defs><style>.icon-canvas-transparent{fill:#f6f6f6;opacity:0}.icon-white{fill:#fff}</style></defs><title>BrandVisualStudioCode</title><path d="M218.62 29.953l-105.41 96.92L54.301 82.47 29.955 96.64l58.068 53.359-58.068 53.359 24.346 14.212 58.909-44.402 105.41 96.878 51.424-24.976V54.93zm0 63.744v112.6l-74.719-56.302z" fill="#2196f3" stroke-width="17.15"/></symbol><symbol viewBox="0 0 24 24" id="vue" xmlns="http://www.w3.org/2000/svg"><path d="M1.821 4.15l10.21 17.618L22.24 4.235V4.15h-7.692L12.113 8.33 9.691 4.15H1.82z" fill="#41b883"/><path d="M5.937 4.15l6.152 10.616 6.18-10.617h-3.722l-2.434 4.179-2.422-4.179H5.937z" fill="#35495e"/></symbol><symbol viewBox="0 0 420 419" id="watchman" xmlns="http://www.w3.org/2000/svg"><g stroke="#fff" stroke-linecap="round" stroke-linejoin="bevel"><path d="M166.95 145.32a93.935 123.23 0 0 1 92.934 3.263" fill="none" stroke-width="18.467"/><path d="M162.92 137.96L44.63 256.25a174.07 173.93 0 0 0 5.705 16.486l123.68-123.68-11.096-11.096zM266.54 144.04l-11.096 11.096 117.16 117.16a174.07 173.93 0 0 0 5.691-16.5l-111.76-111.76zm170.65 170.65v22.193l17.1 17.1 11.096-11.098-28.195-28.195z" fill="#fff" stroke-width="1.963"/><path d="M167.52 273.36a93.935 123.23 0 0 1 92.934-3.263" fill="none" stroke-width="18.467"/><path d="M49.516 144.56a174.07 173.93 0 0 0-.809 2.213 174.07 173.93 0 0 0-4.757 14.344 174.07 173.93 0 0 0-.016.055l119.56 119.56 11.098-11.096-125.07-125.07zM454.87 64.703l-17.668 17.668v22.191l28.764-28.764-11.096-11.096zm-80.984 80.984l-117.86 117.86 11.098 11.096 112.18-112.18a174.07 173.93 0 0 0-5.416-16.777z" fill="#fff" stroke-width="1.963"/></g><image x="21.229" y="20.262" width="378" height="377.1" preserveAspectRatio="none" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAaQAAAGjCAYAAABjSWGNAAAgAElEQVR4AeydB3hUVdrH/+fOpNMF JAFUmivFXtZuIBRRQUUTil1RV3et6Lr6rSu6rg3B1dXVtXeBCCioCASIimLDhkFsgAIJSAkhPZmZ 8z3vjReGMJlMueeWmfc88MzMLaf8zp3855zznvcV4MQEkoxA7sVr01PrUrv4pdZNBNA1AHQRkJ0g ZAcJrYOA7Aipv8/Q6JgUKdBkG0iZISDSDVwSaAfAY3z+/bVSAD56L+mfwA5INAqgSkrUCKA2IOQO IcQOIUU5pNwhNZQLia2Q2OyH3OJBxqaiwk4VzfLlj0wg4QmIhG8hNzDJCEgxJH9DjgfevgGBAyCx vxSyh5DoAWA/CHQH0MEFUOoBbJbAeiHEBiED6wMSv0DgF02In1J2Vq+ZP78fXcOJCSQMARakhOnK 5GrICaO3tE3P8B0kERgkgP6Qop8E+gqgL4Bdo5gEphKAwHpIrIHAjxL4DpCrAo1yVfHsHhsSuN3c tAQmwIKUwJ2bGE2TYsjY33qLQOBwCHk4JA6HhgE08kmM9ilpRQUgvwPE1xD4MiC0r2R67dfFz/eq U1IaZ8oETCLAgmQSSM7GHAIj8td38sN7HAROkpDHATgMTWs15hSQvLn4JLBaQHwqEPgQQiwvmpHz XfLi4JY7kQALkhN7JYnqlDd2w4GQnuMk5AkCOBHAQQD4ubTgGZDAFg1ieQCBj6Dhg7SKmhW8LmUB eC6iRQL8xW8RDZ8wn4AUQ8eVHib9YjCELj4nAOhqfjmcY4wE6iGxAkIsCwDvSel5v7iwa1WMefFt TCBqAixIUSPjG6IhkDtmQw/N4xkKTQ4TEkNZgKKhZ/u1DZD4CAKLIMSik/p3WzF5sgjYXiuuQMIS YEFK2K61p2GTJ0tt2Xebj5EyMArAab+vAdlTGS7VVAI0xSeAd6QQb2uBtIW8V8pUvJwZz9XzM2AG AdpoKqpTh3uEdlYA8gwBdDEjX87D0QQaALlMCLzha5Rz2NTc0X3lmsrxCMk1XeWsig6/YFOWr0Ge JoBzICWNhNo6q4ZcGwsJkFOKT4TUZiOgzSqate8aC8vmohKIAAtSAnWm6qaMHPljWl2bzBGapk2A lKMBZKguk/N3JYHPpMCrHuGbuWj6fqWubAFX2hYCLEi2YHdToVIMKSg7SQAXABgDoJObas91tZWA H5DvCeCV2rrUwg/ndqm0tTZcuOMJsCA5vovsqeDwszd19af4LwbEZQAOtKcWXGoCEaiCwAwB7emi Gd0+TqB2cVNMJMCCZCJMt2dFFnIflJQNh8BEgKbkRIrb28T1dySBlULIpzyBwCsLCntud2QNuVK2 EGBBsgW7swqlvUIer+cSQE7UPWI7q3pcm8QlUAtgtibFU4sKu70PCJm4TeWWRUKABSkSSgl5DTkt 3XSqJuVfJDAiRFyfhGw1N8qxBH4AxJP+hrpnit/otcOxteSKKSXAgqQUr/My18216wMXCOB6AH9w Xg25RklOoEoI8bzw+R5ZNKvnj0nOIumaz4KUJF0+YsyWbL/Xdx0gr5BAxyRpNjfTvQQCkPIdDdqD iwqz33NvM7jm0RBgQYqGlguvbfKmrd2MJrPtNBc2gauc5ASElJ8EIO4/eWD2m+xLL7EfBhakBO3f wfmlR2oCtwI4G4CWoM3kZiURASmwGpAPVLTPeXnFk6IxiZqeNE1lQUqwrs4bW3Y0AoF/QIjT2Vdh gnUuN8cgsFYK3LNPoPzFwsKBDcZBfnU/ARYk9/eh3oIh+WXHaELeIZs8bCdIq7gZTCAsgXUQuK9T oPw5FqawnFxzkgXJNV0VuqJD8zcdDCHvlvpG1tDX8FEmkOAE1gohJp/Yv9vLvMbk7p5mQXJp/w0Z u7mPkP7JACbwGpFLO5GrbS4BiRII/H3xzOw3eZOtuWityo0FySrSJpWTO760s8cv7wQEeVVINSlb zoYJJBAB+bGQ4uaiwpxlCdSopGgKC5JLuvm4/PUZmcJ7NSD/DqCDS6rN1WQCdhKY45f+vxYX9vzJ zkpw2ZETYEGKnJVNV1L4h9JxAuI+9jNnUxdwsW4mQFZ4//E31N/NLomc340sSA7uo2H5Gw7zC+3f AjjFwdXkqjEBNxDYKgVuPbl/9rNs+ODc7mJBcmDf5J61toMnNfVfgLgCgNeBVeQqMQF3EpD4XGja NRyTyZndx4LkqH6RYkj+pouEkFMAdHZU1bgyTCBxCEgIPFvvabx52av7lydOs9zfEhYkh/Th0HM2 95Ye//8ADHVIlbgaTCDRCWwWENcWzcyemegNdUv7WJBs7qncXOnVum66XoBMuZFpc3W4eCaQdAQE xFyfz//n4tk9NiRd4x3WYBYkGzuEjBak0J6WwJE2VoOLZgJMANgJIW49qX+3J9jowb7HgQXJBva0 pyhLeO+QkJPYaMGGDuAimUDLBJYJgSuKZuR81/IlfEYVARYkVWRbyHfouLJcBPCUhOzbwiV8mAkw AXsJ1EOKe3Z07HYvh7mwtiNYkCzinXvx2nRvTdq9EriOw0JYBJ2LYQLxEfgCUlywuDB7VXzZ8N2R EmBBipRUHNcNGVt6hJB4CcCAOLLhW5kAE7CeQB1tqF0yI/thdtiqHj4LkkLG+fnSUy7KbpWQ/wBE isKiOGsmwASUEpBLPBouXji9+3qlxSR55ixIih6A3DEbemhe7WV2+6MIMGfLBKwnsA3AxMUzc96w vujkKJEFSUE/D87fOFoT4lkA+yjInrNkAkzAVgLyv/7MhknFz/eqs7UaCVg4C5KJnTpy5I9p9W3b TBGQf2HDBRPBclZMwHkEVnr8KFg4K2e186rm3hqxIJnUd0PGlO4vPHgdAkeZlCVnwwSYgLMJVEHI yxfP6D7d2dV0T+1YkEzoq6H5ZadLIV/gKToTYHIWTMBlBIQQj6bsrLpp/vx+9S6ruuOqy4IUR5fo VnRa2Z1S4jaeoosDJN/KBNxP4DMhcW5RYc6v7m+KfS1gQYqRvR6zKCXtVQiMjDELvo0JMIEEIiCB LR4p8hcVZr+XQM2ytCmapaUlSGF5+WUDvKnpn7EYJUiHcjOYgAkEBNAlIAKLho7deI0J2SVlFjxC irLbh+SXni0EXgTQJspb+XImwASShICAeC6lsuoqXleKrsNZkKLglVdQeiuAf/F6URTQ+FImkLwE lnkatXMWzun2W/IiiK7lLEgR8KL9RQ1tsyia60URXM6XMAEmwAQMAmsDHjFq6WvZJcYBfm2ZAAtS y2z0M7njSzt7/JgD4MRWLuXTTIAJMIFQBCqkkAVLZnRfGOokH9tNgI0adrPY611u/vq+Xr9YzmK0 Fxo+wASYQOQE2gsp3h4ytnRi5Lck55UsSC30+5D8smM8wvMhB9JrARAfZgJMIBoCXiHxVN7YjXcC kmemWiDHYEKAyRu76QzIALkDyQpxmg8xASbABGImQBZ4vt+6XVFcLHwxZ5KgN7IgNevYvPyNl0EI MmDwNDvFH5kAE2AC5hCQmJ9Zh3PnzcupMSfDxMiFp+yC+nFIQdlNEOIpFqMgKPyWCTAB8wkIjKxJ xyLy+GJ+5u7NkUdIet9JkVdQRvuLaJ8RJybABJiAVQS+9kvvqcWFXTdZVaCTy0l6QZo8WWrLVpU9 JoE/ObmjuG5MgAkkJgEB8ZNPw7Di6dnrErOFkbcqqQWJvHVvF2UU2fXCyJHxlUyACTAB0wn86pf+ vOLCnj+ZnrOLMkzaNaTcXOndLja9zGLkoqeVq8oEEpfAfh7hfW/4OaUHJW4TW29ZUo6Q8vNLUreh 42tCYEzriPgKJsAEmIBlBDZDiiGLC7NXWVaigwpKOkEiMSoXnQol5GgH9QNXhQkwASagE6C4SprU 8ooKu61MNiRJNWVH03Q0MmIxSrbHnNvLBNxDgOIqSREoGjq2tL97am1OTZNmhEQGDNtE6asCosAc dJwLE2ACTEAlAVkGIXMXz+jxg8pSnJR3UoyQfreme57FyEmPHteFCTCB8ARENqS2mJw8h78ucc4m gSBJUS7KHgVwfuJ0G7eECTCBJCHQwyM8i3LHbOiRDO1NeEEaMrbsHt70mgyPMreRCSQsgQM8Hu3d kfllXRK2hb83LKEFaUjBxluExN8SvRO5fUyACSQ4AYGBjQjMG5q/vX0itzRhBSlvbOmVAuLeRO48 bhsTYALJQ0AK8UcpamfT1pVEbXVCCtLg/I2jIfEYgKSxIkzUB5TbxQSYQDABMWS76Phsogb5SzhB Gjxu0x81IV7jEBLBDzG/ZwJMIIEInJc3tuyhBGrPrqYklCCReaQIBOYByNzVQn7DBJgAE0g0AhLX Dc0vTbj18YSZ0iILlEaBjyRk0tjsJ9p3jNvDBJhAVAQkpBy/uLD7jKjucvDFCTFCokW+Bsg3WIwc /KRx1ZgAEzCbgIAQz9IyhdkZ25VfAgiSFPoin8DxdkHkcpkAE2ACNhHI1AKBuYmycdb1gjS0oOz/ AJxn08PAxTIBJsAE7CbQ1ePV3kmEPUquFqS8/LJzJXCX3U8Dl88EmAATsJnAwVLUv+R2c3CPzRBj Ln5o/qaDIeRbABJ2k1jMcPhGJsAEkpHAH3oPrNTWlkxb6tbGu9LKLu/sDfsgRfsEQB+3gud6MwEm wAQUEJBC4NyiGTmzFeStPEvXTdlRKAmkaLTxlcVI+ePBBTABJuAyAkJKvKDPILms4lRd1wlSudj0 LwDDXMiaq8wEmAATsIJAG6kFZrnRyMFVgkQ+6iTkX63oUS6DCTABJuBaAhL9Aqhznc871wjS0HM2 99aEeIEdprr2K8IVZwJMwEICQmBMXsGmGy0sMu6iXGHUkHvx2nRPddpHEDg87hZzBkyACTCBpCEg G4UUQ4oKc5a5ocmuGCF5a9IeYjFyw+PEdWQCTMBZBESKFGKGbpnsrIqFrI3jBWno2NIxHII8ZN/x QSbABJhABARkDlI8z7lh06yjBWnImNL9IfF0BMT5EibABJgAE2iRgByVl192bYunHXLCsWtItN9o O8reBztNdcijwtVgAkzA5QTqhSaPK5re/UuntsOxI6RyUXo7i5FTHxuuFxNgAi4kkBaQ4tVRo0od G8DUkYI0JL/sGAlBXrw5MQEmwASYgEkEhMRBtZnifpOyMz0bx03ZDb9gU5a/PvAFgANNby1nyASY ABNgAlIKeeqSGd0XOg2F40ZI/nr/AyxGTntMuD5MgAkkEAEhpHh2RP76Tk5rk6MEacjYjcMBcZXT IHF9mAATYAIJRqC7X3gedVqbHDNld8LoLW3T0xu/BbCf0yBxfZgAE2ACiUhASoxZUpgzxyltc8wI KT29cQqLkVMeC64HE2ACyUBACPnYiRN+6eiUtjpCkIbll50C4AqnQOF6MAEmwASSg4DITvN7pzml rbZP2ZFNfE0GvuGAe055JLgeTIAJJB0BiZGLC3Petbvdto+QajPEP1iM7H4MuHwmwASSmoDA407Y MGurIOWNX3+IRMBV8TqS+qHlxjMBJpCoBA6oyRB32N042wRp8mSpwe99AhApdkPg8pkAE2ACTEDe OHjshkPt5GCbIC0r2XQlII+zs/FcNhNgAkyACewi4NWkeEIfLOw6ZO0bWwRpZH5ZFynkPdY2lUtj AkyACTCB8ATEse9/V3Zp+GvUnbVFkBqaxKiDumZxzkyACTABJhATAYl7cs9aa8vfZ8sFadi40qMA 2KbAMXUQ38QEmAATSBICAuiipabfZUdzLRYkKQIB+R8AFpdrB1oukwkwASbgTgIC8uph+RsOs7r2 lgrDkPxNFwHiWKsbyeUxASbABJhAVAQ8AWgPRXWHCRdb5qnhd48MPwDobkK9OQsmwASYABNQTEAI eVbRjO5vKi5mV/aWjZBq0sVNLEa7uPMbJsAEmIDjCUgpHjjyCmnZXlFLBGnEmC3ZEPJmx9PnCjIB JsAEmEAwgQM7lJddHXxA5XtLBMmX0vhPAG1UNoTzZgJMgAkwAQUEBG63KkSFckEafk7pQZC4SAEm zpIJMAEmwATUE9gn1Z/yV/XFWGB+7feARkdeKxrDZTABJsAEmID5BITENXnjN+9rfs575qh0hPT7 Jthz9iySPzEBJsAEmIDLCGSJQODvquusVJACAZC/OstMy1XD4vyZABNgAslKQEp5xfD8Tb1Utl+Z IA0pKD0ZwDCVlee8mQATYAJMwDICqX7NTwFVlSVlgiQgbQ/2pIwaZ8wEmAATSEYCUpw/ZOzmPqqa rkSQ8saVngSIIaoqzfkyASbABJiALQS8Aj5la0lKBAkBOdkWVFwoE2ACTIAJqCUgxflDz9ncW0Uh pgvS0PzSE3l0pKKrOE8mwASYgCMIeOFRY3FnuiBB4FZHIONKMAEmwASYgBICEvK84eM29jQ7c1MF KW/8+kMkMNLsSnJ+TIAJMAEm4CgCqb6AuMHsGpkqSPB7yL0E7zsyu5c4PybABJiAwwgI4PIR+es7 mVkt0wQpd1zZAQDGmlk5zosJMAEmwAQcS6CNT3j/bGbtTBMkLYAb2WedmV3DeTEBJsAEnE5AXntc /voMs2ppitPT3LPWdhCQl5hVKc6HCdhNwOsVaN9WQ1amQFaGQEaGhox0gdQUAaEBaali19x0Q6PU j1OdG30S/gDQ0CDh9wPVtQFUVUlUVgdQXRNATa20u2lcPhMwk0DnLOE5H8BTZmRqiiBpqekTAcnx jszoEc7DUgIkLL3396JvrxT03T8FPXK8yNnXgy77eJTUo7pG4tdSH9Zv9OGXDT78vK4Rq39uRFV1 QEl5nCkTUE1AAtcD8mlAxP1rK24DhNxc6fV0LfsZwH6qG875M4F4CXTqoOHQAWk4dGAqBv0hFQf0 NOU3WbzV0gXqu58asXJ1A75YWY/NW/xx58kZMAGrCAjg1KKZOQviLS/ub6O3a9mZksUo3n7g+xUR SEkROKR/Kv54eJr+v3t23I+8kpr27O4F/R9+StN0/MZNPnzxTQM++7oeK76pR31D3D8+ldSbM2UC REBKXAUgbkGKe4SUl1+6FAK53C1MwCkEaK3n2CPSMfiEdBx/VLpTqhVXPZZ9WocPP6vDxyvq9fWo uDLjm5mA+QQCwu/pVzRr3zXxZB2XIOXllw2AkCXxVIDvZQJmEKCR0PFHpWHw8Rk48ZjEEKGWuJAw LXq/Fp98WY/GRh45tcSJj1tLQEDcXzQz+2/xlBqfIBVsfBQQptqhx9MYvjf5CPQ5IAUjB2fgrFOz kq/xAN4qqsE7i2vww5rGpGw/N9pRBLZ2kuXdCwsHNsRaq5gFadSo0syaDGwE0CHWwvk+JhALAbKM yzsxA6OGZ6Jfr5RYski4e0iQ5i2qwdIPa1FXz6OmhOtglzRISHleUWH3V2OtbsyCNLRg46US4plY C+b7mEC0BPbt4sGoYZkYdybvMAjHbtbb1Zi7qAYby3zhLuNzTMB8AhIfLC7MoWjhMaWYBElKeeCM udULXp1TeQDtq+DEBFQSGHRQKkYPy8SQE03bEK6yuo7J+73ldZi7sBpfr4p5BsUxbeGKuIOApkE+ PLnTjQMOSv93LDWOWpBIjAB8T4XNW1iDp1/bCRalWNDzPa0ROO7IdH1a7pjD0lq7lM+HIfDNqgZ9 xFT8UW2Yq/gUE4iPAE2fP35fZyOTvwsh/mV8iPQ1FkG6F8AuSwoWpUhR83WREsg9PkMfER0yIDXS W/i6CAjQxtt5C6t1Cz3JExsREONLIiXQe78UPDlllxgZt3mFEFHt8I5KkKSU5E9lr4lpFiWDP7/G Q+CUY2lElIXDBrIQxcMxknsfeqoCbxfVRHIpX8MEwhJoQYzontOEEPPD3tzsZLSCdCqAkAWQKP3v 5Z1s4dMMMH9snQBNyZHFHE3RcbKOwKofGnTLPNrTxIkJxEIgjBhRdjOFEFGFJIpWkF4EcEFLFSdR eviZipZO83EmsAeBA3unYPTwTJw6OHOP4/zBWgLkmohMxskbBCcmECkB8gP59INdWru8vRBiZ2sX GecjFiQpJf3VqDZubOmVRaklMnzcINCxvaabbp9zuns3s1IYCWMdJjNDoLau6XNKCnaFojDa65ZX GimRVd53P/ImW7f0mV31pC0Y40a30Wc2WqnDJUKI51u5ZtfpaASJhl7Td90Z5g2LUhg4SXxKCGD8 WW1w6bi2jqZAISHWl/qwcZMf5OR0yzY/tu8IoKIygIqdgV1CFK4RXg/QsYMHnTtq6NTRg25dPdi/ hxf75XhBZuxOTrSPqfCtamzdHtV6tJObxHUzkUAUYkSlLhJCDI+0+GgE6U0AoyPNmEUpUlLJcR15 Vrj1Guc59aA/urRP59vVDbr7nTW/+pT7hyNh7pHtxYADU3BQ31TdiKNnjvO8kD8/sxKvzK6KSICT 4ynmVkYpRgawbCHEJuNDuNeIBElK2RHA9nAZhTrHohSKSnIdoz+8Z52a6Shfcx9/UY9PvqjDFysb 9BGQE3qka2cPjjg4DUcflgayNnRSuu/RHSj6gA0fnNQndtQlRjGiql4jhHg0kjpHKkgUnvzZSDJs fg2LUnMiyfP5vDFtcMlYZ0zP0R/UpR/V4qtvGxwfW4g8lx91SBpOOCYNp+Y6w+CDnLjSd/nnX3h9 KXm+wbtb2r6thosL2kayZrT7pt3vioUQg3d/bPldpIL0NtmUt5xN+DMsSuH5JNpZp3hYIKuxhe/V 6kHu3BqmgcSJggtS4D4nxHZ66fUqvPh6JU/jJdqXNkx7sjIFJo5vF6sYGTnvK4T4zfjQ0murgiSl bA9gR0sZRHqcRSlSUu69zuMBLhvXDgWj7bOeW7fBh/lLavQpJjJASKTUrq2GYSdl4KqL2tnerH8+ VI73PmYzcds7QnEFTBIjquWVQognW6tuJII0HkDM7sSDK8CiFEwjsd4POzkDt/zZPqMFGg3NXViD L1bWJxbYEK0ho4hDB6TqXi3sXG+a/U41XplTpVsehqgmH3I5ARPFiEgsFEKMaA1JJII0E0B+axlF ep5FKVJS7riOwoVfPLYtzjnNnlHRzHnVmLeoGmWbk9NEOWdfjy5M+WfYw5+e0keeqdB/DLjjieVa RkKA9tZdPiHuabrmRXUQQoT1nNCqIAUCcqYQ5gkS1ZBFqXk/ufOznaOiFwsrMXt+DaqqE2taLtYn gf6AnD0yyzYjkjcX1GD2/GqOwRRrBzrsvusuax/vmlGoFh0phPgi1AnjWKuCNOutquvHnJ71kHGD Wa8sSmaRtD4fWiuiX0/n2vCr/IXCSsycW+14Sznre6WpRK9XYMxpmbjiPHvWmZ54aSdef6tVhy52 4eFyIyCgSIyoZE0IEdbPPHnvDpu2+f5y7uqfGo/PO8nc4Gh/6JOCju09+OTLxJ/zDwvYZSfJ0uvZ aV0w4EBrvQ2QEP3ffeX63iF/cs7ORfSkBAJAyfeN+tpOba3EkYdYG0vqqEPT0KG9B6Wb/dhZyaPX iDrNQRepEqM/3bK14sWnMqesWnVnfILUa9Ckh0s3+Tuv/qkRLEoOenJsqArtKbpuIhldWpdmzK3C P6aU47Ov6sFCFDl38rNX8kMjXn2jGo0+icMHWSdM9GPzrFOzUF0r2S9e5F1m+5WqxOiav28lLyjp dahatGbV1F/DNTTsCGnI2M19hJR3UQbk14tFKRzKxD3X94AUfVOclc5Q58yvxgOPV2Dph3U8PRfH o0UjppXfNWDGvGpoAjjYQj96Rx+ahvbtPPh5nU93PhtHM/hWxQRUidH1d2zDqh9+30wtsGltydQl 4ZoSVpB6DbxxrADOMDIgUfplgw+nHMfTdwaTRH+lX7p33dwR/XqnWNLU5Svq8PgLO/HGuzU85WMi cRpdfvltAxYva9o71L+fNVOuB/VNAVkA/rYtgJ/WsZcHE7vUtKyuubQ9Ro8w3yMIiRH5iAxKaWtL pj4d9Hmvt2GNGobkl84SAmOa30V7H26/gdzbmZvY0MFcnvHmRhswrTTnfvQ5EiJnLoiTFdthA9NA 01H7dfcip5sHbTI1tMnSdMwNjVIfBZBn8A2lPtAG3a9K6rH2170CLMfbLabcT/uYRg/PwinHWec3 j4wdyOiBk3MIkBidaY0YUaP9XunvuqCwZ4t+UVsUpPx86dkuyrYCCLnbUZUokfnof54Na6runN5M 0JrQegMFzjvpj9b8saJ1ohdmVoH+qDsppaUKDD4hA8NPzsAhA2IbUWwvD+CDT+vwzmJn+oEbNSzT 0nXBjz6v04MB0pogJ3sJqBKjG+7YhpV7jox2N1SK/MWF2a/vPrDnuxYFKS9/w3EQ2kd7Xr7nJxal PXkkwieaXrnyAmtMht9bTt4VqvXwD05iRzvUzz29DS44t42p1fr863p9Ayn9UXZS0jToa4QTzja3 veHa+NyMptAW4a7hc+oIqBKj2+7djk/D/dgQeHLxjJwrW2pZi2tIvQbedJEQGNLSjXSc1pNUrCnR vDMthn7KJuHh8Jt+jqboLjjXGu/cT76yU18r2rzFOTbcNCKiP8r33baP7prHbMA53bz6iOsPfVJR XRvAxjJntJ0s8mh9icJy0B6zvr3UrxfSKJy+4zSlSdF3OVlH4M8Xt1MSDqZVMWpqYoe1JVMfaam1 LY6QhuaXLpACEUX645FSS3jdcZz2FNHUDXleUJ30Hf3vVDsmDhG1lzaTjh1tvZcDGimR/z0aOTkp 0ZoC/YK2Kt37nx1YvIzjLVnBm8SIPHqYnSIUI71YKf09lhT23BiqDiFHSLm50ivaVP0XQEQT5zxS CoXWHcdGDc/EnZM6os/+6n8VP/x0BV6aVYXKKmdsmKTRwLgz22DaHftYuk/HeDIoSuzQkzJ0I4kd lQE4ZbT4/c+NmPVONVJThCUboGmt0uMR+KpkD4ssAxO/mkTACWJETdEgVqxZNW1lqGaFFKRex151 tJDy6lA3tHSMRaklMs49ftn4tpg4Qf16EVnO0eZWChXuhETesmmt7N93ddajtNpdpwN6pmBEbia6 dfVie7kfW7fbL9iNjdBHbr+W+nGyBRFsDx63vWsAACAASURBVOmfqntuIevE6hqewjP7mVQlRpOn lmP5iihH+EJsXVsy9a1QbQwpSH37T5oAgWGhbgh3jEUpHB3nnOvYXsOV57eDFRtdyWKSgrrV1tn/ R4aEiPZVPfqvziAXN05LfQ5IwWl5mejU0YMt2wIor7BfmNat9+mjWlpfG/SHiCZMYsZKJvW0zWB9 qR9ULidzCKgSI4qJ9cEnMRnoZK0tmfpYqNaFXEPKKyibC8hRoW6I5BivKUVCyZ5rjjksDffc2kl5 4bQ2MnNuFTY5wGiBhIj+0N9wuXXrImYApvW2eQur9T1NZuQXbx4nHJ2OO28yf/9hqHqRN/cXX68K dYqPRUHgTxeocYIcb4DGVCm6zi/M3tK8KSFHSL0GTnpYADGvfPFIqTlmZ3ymxcxbrwm5rczUCj79 WiWeea0SVQ6YeqHQ3/+7vwsorLrbElmbjh6RpW++JWG321np+tKm0VJ6qoaBikdLhw5MA0XI/ea7 BvicYYzotscHThUjAtkoRPG6kqk/Noe6lyANz9/USwp5W/MLo/3MohQtMbXXTxzfFpeOU2vSvWRZ LR5+Zifo1e405MQMkH8uFRZFVreN3PzQVGN6uoYNZfavsaxYWY9fNvpwyrFqrTIP6puqm+GvXN2I Tb+xKkXz3CkTo3+bE7peCPnz2pJpxc3btJcgHXDwDacC4tzmF8bymUUpFmrm3pOWJnD1Re2Vxy4i bwsPP70Tv2219w8HucK59rL2utFC1857Pd7mwrU4NxqV0BoLWb+tXe9DXb1963L03SaHrRlpAqr9 4tEot6IyALL+49Q6AVViNOVxMs+Pac0oRKVFw9qSqS81P7HXN7b3oJsmAji2+YWxfmZRipVc/PfR lM+F57bF6UPNd5wYXLsHn6jQg+YFH7P6PcVposXb8We1Qbcuez3WVldHaXmDDkpFwag2ujB9v6YR ZBFnRyKHrZ99XY/ynQEce4TaKdE/Hp6u7xejDbycWiYwcUJbFIw23+MGidGCYlNnPjpflP/gA8XF e8ZH2suoIa9g43JAmCZIBjo2dDBIWPOad2KG8vUicoY7Y16VrdMpZC1HfvdIkJI1vTK7Cq+9UWXr iClnXw/yz2ijIuz1Ht1Khh5Pv7rTEVabe1TMAR9IjGhfndlJgRjpVfT40X/hrJzVwfXd46ckOVSt FVX/BmD6LkkeKQVjV/ueHkrVgfTojyB5bq6qtmfaiJydXj6haR8VbTBN5kR7eMjlEfXEdz82gmIg WZ0qq6Ue/ZnqQF7RVSUa9Xfr6sGOioDt08Oq2hhLvm4TI72NQi5vvkF2D0HKOfjKgwBcHwuQSO5h UYqEUnzXkPHChflqjRfuf2yHvpM/vprGdnf/vim4dFw7XH1RO9CGUjsTTR9R8Luff/FhQ5kfASn1 zZ121YmE4PwxbdDogx5M0w5h+mZVA35c68OQE9QZPPTaLwWnDs7E9h0BikRqF27HlKtKjMizyjtL TJ2m24OZEFi7pmTaouCDe0zZ5Y0tPQ8SLwdfoOL9iNwM3HyV+ebHyR66QtUGOOMZoCm619+2xw9d v14p+nTQaUPUrocZbW3p1fDYTYEEySlp89Q2S9MNSM4bY/7USfOyWvtMDmxnvV1tS+j3lBShj2DH nBbz7pHWmqeff3lWFZ6fWRnRtYl4kSoxeuSZCt3PokpmUorFSwqzhwaXsccIqffASRcBOD74AhXv KaTx5q1+0EY7M1Oyegnvso8Hl09ohzNPVfflnzm3Gv99YaflfugO6OnVR3yTrmwPEiW7Erk9euqV nfr+KtqP01KimE7kk418wdEIhabT7EpHHpKGC85pq6+30FSelYnaTgYPZAlI9VCVaOqW9iuFDXmg qnCb8724oK0+VWt2NawQI6qzEGi/tmTqA8H133OEVFBKw6c9FCv4YrPf80gpfqL0B2/a5H3izyhM DnZEcqV1IfJArvoXdphm66dKvm/QfynG6o2a3DSRqfa4s+wfMVE/vrmgOuTIrjUO8Zy3IuAjjd4L 36pC6WZ7tx3Ewymae0mMzj/H/GfKKjEy2iok9i8qzPl112fjDb3mFWwsBUR28DHV71WJ0pz51Xjs +cQOl2yFJd3N/9ymx8pR/RwY+dOUF5luF4xWN9ozymrt9YH/7sDC98yZQ9+3iwdnjshCwSj72/XQ UxV4u6imteabep6CAF51oZrQB8EVjSYMQvB9bnqfKGKkM5cYubgw512D/64puxMn/NLRG/DcbZyw 6lXV9B1t1mvbRkOihkomx6g3XKHONxv5orvlX9vx68aWp6fMfkbox8kjd3dW7pamtXrTH2zyTk7P plmJPFiv+KYeRR/U6lN5FIPKrkRulAb8IVWfygs3/Whm/Wi9jb6LZHBxxMHqpvDyTsrAth0B/Jig xg6qxOh/L+3EnPnW/kjRny8hvlpbMnW58aztEqQDD/rrURC41Dhh5SuLUnS06aGk0BGqEnldePyF naD1EKsSmS3/5RJ1AhtJO2hK6//u367UcovMo8kwYulHTUYRqr0ctNTunH29GHx8Bsj4wMrNpt+u brJKpLJVJRJcenLJ4i+REhnKXKTAgpbEqPCtaptQiQ1rS6bONQrfJUi9Dp40EsAZxgmrX1mUIiNO bkFUrkfQw0lB9KxMNNq74jz1cZlaahO1+dZ7t+um0i1dY/ZxcpRKI4YPP6unxV0c2Nseg42DD0rV nbeSAYJViUZlbxXVIC1NA4WcUJHIBD4zQ8Pn31jXLhXtMPIkMbpkrPk/Qu0VI2qdrF9bMu0Zo527 BKn3oEkXmOkyyCggmlcWpfC0/nJJO6WL/HdOK8f8peasmYRvye6zfQ9IsSykwe5Sm96RR3ISom+/ t9YCLbgeFPPo4y/qdXGiUOoUE8nqRKO01FSBL1ZaN6Kg+FiffFkP8rWoKs4STYt2bO9ByQ+Nlo72 ze6/xBUjIiXarS2Zep/BbJcg9Rk46RoA/YwTdr2yKO1Nnhb6aUGYFsVVJLJQuu/RHVi52ro/SEY7 aPqxn8Wjg+dmkBCV61M6ofYSGXWz8pWixH74WR2+WtUACoZn9aZf8o9nbFy3st0kghSm5OjD1Kwr 0QisXRtND3hIG2ndllSJ0bPTKzFjrl3TdHv0QlrvQ/76xNpvH9Qrs0uQeg2c9A8Anfe41KYPLEq7 we/X3YsJZ6nzETb7nWrQ2okdsXbItFvFBund9PZ890JhJf7vvnJ9zcQOLwZ71ib0p81b/Hj/kzpQ yIWMdIH9e1jnFql9O49pVoWhWxf6KO2RIiexZDWqItEPnjOGZeplbCxzj1m4KjGiH2SvzrF2Wj5c v2oy8Maakmnr6RpdkJp82FVOBcQugQqXgRXnWJSAwwel4rF7OiubZ6fQ4k+/at8ud/rCDein3tqM /O7d/sB2fP51gy1eC2L5vlD8n/eW12HVj43IzBCwwl8f+Yhb9UOjLXt5SCjeXlyL9FSh7Hknwftt WwA/rbNvijbSZyH/jCxMnGD+uiqJEX0fHJWE9t6akqlfU510Aeox8KoDpMCNjqokoJvdqvDo4AaT 8NzjM3D3X9WFGievC9PftPfBJFdH7dtqyh676W9UYfK0cny8ot62EA3xNo42epJF3k/rfPo2hpxu akdM6ekCxcvNinkTXeuNdSUKRKgqIi15hSfvEbSu5NREYnTlBUkiRmTWAJSsLZm6lPpDf7r98PcF 9nDa4Ji+MmJwmD21Y0QSdeLmWfJQoNJb9z8p6qNNf3SMB8vrgbJf/TPnVYOmIrdud8/0jMGlpdeP Pq8D/acfKqOHZYJc5qhIJx6Trlv92bm29uTLO1G+w6/kjzIxu+L8droFnhN94CWbGFF/aEAf41nW BUlqYn9h3ZYTo+yIX5NJlFQ9kAbsa2/fhlU/WG+8YJRvvHbsYP7sMDkSJQ8dm7YkjhAZvIzX4o9q Qf8piuqo4Vkg7+dmp306emwXc9oXQ/14x40dzW6enh+53UlPE3oIFSUFxJCpqu8+OaB13DRdEB8p sb/xUf+r0HvQjWcC4hTjoBNfk2FNidZUVMwbU3+SJR25VdlQZp73gXieE/pjkD/KHF9cNBp64L8V IH9zZLGVDIlCXsxfUqOviZgdnHDRB7Uod4BFGnkJ+fDzemiK9mmRWTgZcnz6pf17lc4ckYmrLzZ/ Y7grvKELYG3J1Ifoe6uPkITUekp9b7Ozv8qJPFJS5RKEetSJfv0aTJjCp82VJLQ//2JCZs5+9Fus 3btLa7CguAan5WXihsvN/4PWYsEWnfh5XaPuZd7nB+iPttmJ8iTBe+H1Sj3on9n5R5IfRTy+5lLz +84VYtQEKCc3V3qLi4VPHyEdMOCma4RA70jg2X1NIo6UKKYJuc5RkWio/uQr9lnStdQm2ogZT7hl cm1EFkO0sZQTdN9t5GFjZ6XEMYfHt6eHhN4JIySjX/1+6KMYVcYOtFcpI03Tpwgrdlr7PJEYXXtZ UosRdbOW0rby6Z+/nbZTN3ESQvY0Ot8NrzRSomiGZicydCDLLyuT7groTDVi9NQrlfofbSvbw2XZ R4AMEd54txpTHt9hXyUUlkzGDuRdQ0UaNTwTz0ztAnKlZFVSJUZkPetEg41wXGUA+9F5w+a2R7iL nXhu3qIaUOwOs5OVokTid+4Zarwv/PupCpCTVE5MIJEIvPZGFR58wvzvvcHooTv3gdlrckbewa8q xcjOvYXBbYzmfUBqetgjbdSoUpqYNX9yNpraxHgthUhwqyjRnLFheh5j81u87Z8PlevOK1u8gE8w ARcToHUzitOlKt11c0cMO1mN1wiqM4VZUTFNRyMjN4oRMZEIdKNXrTrTY2lAPrMfIpWiRNNpZidy B3PdZe2VLNBSXW+6axve+9iejY1ms+L8mEBLBChkxgXX/qYbtbR0TTzHb/lzB9AoxuykKiCpm8WI GAsNXejVK4Xs7OQ9SJE8ECRKlMz+1WFMpz3xkjmRZ7MyBSaObwearzY7kbXZ7Hersd7CgHpmt4Hz YwLRECjb7Mdjz1cgINVY4NHfE/JcMdMkJ6QsRmF6V4ocOuvVAgFXj5CMJjpdlLp29mD8mWqcpJIY Pf3aTlBUUk5MIF4CNbXWWprFU18yB//PsxXw+SQorpbZieJ0kfd18vsYT1IlRq+/Ve3aabpmPHXH 3l4BdEmUP2NOFaVuXTwYO1qNGJFVFXnr5sQEzCIg3aNHu5r8+Is7dR91tLnc7ERRWj2aiNlyjdw9 me36jNpIYmTW7I3ZzKLPT+xL93ghRQe4fc4uqPVOE6Xe+6XgySlqonok1gMZ1In8lgnEQID2pdXU Slx+nvmRVcnVkNeLqEcjpxybjr9f1yGG1oS/JfG++1KHpEnR9CZ88911lkRJhfUdrSlFY+jQr5c6 MaJFzMT5deSu54tr61wCtNVh2pNqzMJpI3c0338So9tvMN8XX+KJkf486aA0IPEEiZpntyhRBM7H 71MzMiKXIG4173TunzKuWaIQeGdxDf4xpVxJcyL9UapKjMgNWIL+EG0aIQkI8yVcyaMQfaZ2iRIF 1vv3nftEX+EI7qBpCbftwo6gWXwJEzCVAIXquO4favYqkSiF8+hysqKRkRN9UprYaem5F69NJ08N 5jtSMrGW8WZltSgdc1gaptyuRoz+99JOR7uRj7ev+H4mYCaBku8bcOmNW5TsVaJN7aEcotL3/x8K pukSXIyaur06q4NXAubv/jTzqTIhLxIlSqr3KdHDeM+taqK8PvxMhZIvlgl4OQsm4FgCFMLi+cIm /3dm7/8zPIXTd5OSqu9/UogRgFQEMryQSHdosFhTH3LVovTFynplYnT/Yzuw6P1aU3lwZkwgWQiQ B+9HnlWzgdYQueUr6pR8/5NFjOhZDABtvBCIz1e9i55qlaJkeHUwG8fkqeVY9im7AjKbK+eXXATI EzptoA0EpOk+JEmUDGEyk+qbC2rw2PPJs8fQ70EmBehL6DWk5g+IKlFqXo4ZnynC66df2R/N0oy2 cB5MwAkE6A88xVdS9QPSrDaSGJGAJlMSgUAaCVLSjJCMznWDKN04eRu++a7BqDK/MgEmYBIBMpuu b5BQ4dXBjComoxgRN02KtmRll24GRLflQaLk1OHw9XewGLnteeL6uosAbZ+g/XxOS8kqRkY/0Agp aRMtGHo9wJUKwkzECvWKm7diza+Nsd7O9zEBJhAhAdrP1+iTuGSs+a6GIqzCHpeRk+Rkm6YLBiAR aJPUgkQwCt+q1pnYLUr0ML65sBrr1vuC+4jfMwEmoJDAK7Or0NAgbf9RSt9/w3xcYXMdnbUAPCRI zvh5YCMqu0WJHsbpc6uweYvfRgpcNBNITgL0/acwFuG8L6gkw2K0my4JEq0jJX2yS5ToYXx5dhW2 lbMYJf1DyABsI0DT936/NH3zfGsNYjHak1DST9kF47BalOhh5MB6wT3A75mAfQTI0Ims71TELgrV Khajvanw6KgZExIl8hmnOrEYqSbM+TOB6AksKK7FPx9S4yk8uDb0/f/fy+r/zgSX6Yb3JEgujA+p Fq1qUWIxUtt/nDsTiIfAex/XKRUl4/tfV58osbrjob3nvSRITZ4H9zye1J+yMgVy9lU3m0luRkYO yUxqxtx4JuBkAocMUOcvgL7/+WeYH2rdyTwjrZu6v7qR1sBh15EYTRzfTolvquCmUuRJEWR2Hnwu Gd5npFPrOTEB5xG47rL2yr//FBKdEsc2293/EvCzIO3mAavEyCiS9j4JAcyc17QXyjieDK8eXr1M hm52VRszMwQun6D+x6gBhUXJINH0KqBV0Z8FdiUNWC5GRldccX47x/rUMurIr0wg0Ql0bK9ZKkYG TxKliwuSfiuogQM0Qkp6d9JWj4x20f/9DbkuSfEKHr43BxPmcy0vCIehw6eiIdCtiwdjR7dRPk3X Up14pNREJiBkJQlScvk4b/ZU0DDdijWjZsXu9ZEeSq8XePpVtjHZC06IA7SJkRMTiJdA7/1S8OSU zvFmE/f99P0nv3rkyihZk9S0eg0yuUdIVs4Zt/agjTuzDSZO4OF7a5z4PBMwg0D/fs4QI6MtNFPi 1JAYRh1Vvnr8qNEgkncNyQprmmg7kESJLPA4MQG7CGRkJL4F5CEDUvGfu+0fGTXv42QWJQ2o0gSQ lNuFnShGxsNJ0SztcvRo1IFf3UugPs64jhr9VUjgdPxR6Zh2xz6ObWGyilIDtNqkXENyshgZ35Kz R2aB/jAkc3wUgwW/RkegsZHX11oiNuzkDNzy5w4tnXbMcRIlSkm1ppRVvUOTkOodNzmmmwFVYvT6 73GVzGzqmSMy9fqmpyX2L1YzmXFeTKAlAqOHZyoTI4pAa3YiUco/I8vsbJ2aX13x873qvIDY4dQa ml0vVWJ0273b8elXTdbzNN1mZiI3I5QK36pC6WYOUWEmW84reQgUjMoC7flTkcgZK/m/o2SMbMwq xwgcakQiMCtfB+aj65AmZHIIkhVi9MRLO6FipESi9OIjXXFQ3xQHPkdcJSbgbAIXntvGEjGi6bWX Z5lvtk2ilAQjJX2mToOQCT9CskKMjK8kiZIqV0CP/qszjj5MndNHow38ygQShQBto7gwX81Witsf 2D0yMniRbzoWJYNGNK9NAyNNAluiuc1t11opRgabJ1/eielvmv9LifK/99ZOGHJChlEUvzIBJtAC Ado+QdsoVKS/3bMdy1eE9rqmUpTMXhJQwSa2POVmuk8LaFpZbBk4/y47xMigQh4XVPxSovxvu7YD Rg3j8BUGa35lAs0JXHNpe6j64339Hdvw+dfhPa6pEiUSWTLOSMC0ldrkFVLobxKtgXaKkcGSHkpy B2L2Qiflf93E9qANjDPnJp+ncIMvvzKB5gQ6ddBwwTltlfmlu/KWrfh5XWPzYkN+pu8/JcNXXciL Yjh47WXt9bso5HrCJCFLqS3erBp/WU2CzQA5QYyMB4UWOn0+4PLzzJ/HvuK8dsjK0KDC5NSoP78y AbcQ+EOfFDx2jxrvCxTldfa71Vi/0RcVDhIl8lFp9tRhoomSDDQtHWnz5uWQzCaM1DpJjIwnd8bc KvzvJTUOMcj31VUXqjFnNerPr0zA6QTI+4JKMZo+typqMTKY0fS9ijVlEqVEmb4T0DYRLyNM2gYD nptfad7Y2LdjZjuC9xnFmi/tI3jkGTWO1c85PQvU9pQU3kAba//wfe4lcFpeJu66uaOSBtDI6OnX dmLzlvj2AKoUpTOGun9NSRMB3ZZBjxgrpVgvhDxQSY9alCn9QSbPBmanux4q37XpNd68ac63vkHi 5qvMd11CbScXZLPnV2N9aXTTCvG2i+9nAnYRoDhGKqbDqT1vLqjBo89VQJrkickILWP29N31l7fX 16oXFNfa1Q1xlys0/EqZ6CMkoQXWx52jjRmoEiPagf3+7zuwzWoePTQkcioSjQ6fe6gLDh/Ee5VU 8OU8nUWAjIVUidGc+dW6H0mzxMggp2qkRD9yR+S61hjA37ApRx8hNU3ZSbhWkFSKkeEOxHiYzHol kbv5n9vNym6vfKbc3glDT3Ltw7lXe/gAE2hO4OqL2imLHUTeVh57Xs2aL7WDREmFRxcXi1JpcbHQ p3V0QZJC6MOl5p3u9M9uFCOD6Zff1uNPt2zFO4vV2JP87S8dcM5p5vrVM+ruhFdaxD7qEB4JOqEv rKxD504e3eHwGEXP9qtzqkDeVlQnVW7GXClKQQMifQ0JkL8C7loQd7MYGQ/7T+sa8eLrVfD7ocQY 46qL2qFDew3PvGa+J2KjDXa9nnB0Ouh/8Ue1mLuoBt+sijMIkF0NMbFcjwf6jxBVTkRNrGpMWR06 IBVTFcYxou0TVoZ7MITP7A28JEqNPmDJMpesKQUNiHRB8gY8P/pFIKaHxI6bEkGMDG5bt/vx3xeb fpGpsBAcf1YbZKQLPPqc+l99RpusfM09PgP0f+F7tZi3sBrf/RTZpkUr66i6LCEAGjEksvk/rY/Q H1pVibZl2OFRW5Uo3XZNB/h9cpcXclXczMlXrjHy8dCbIwZOqawVlbcCQv9snHTiayKJkcE3EAA+ +bIebdto6N8v1Ths2utBfVPRsb0Hm7b4UbHTGT88AhIgsTQr9TkgBWT+26mjB1u2BVBe4Yx2mtW+ UPmQEJ11ahZ0p7uHmjd9+eaCauxwyHNC7R53Vhtcc0mTd4JQHOI99u+nKvDGu2qmziOp2+ff1CMz Q8OAA8397p9yXAZ+2eDT/0dSD7uuEZDPrymZ9iWVrwvQqlV3yt4DbzofgHPj+gL6XhsVpt3B8Uzs 6hQq97Ov1DyYlDftYj9zRBbW/OrDr1HuNlfBhKYUzj2jjel7pw7snaL7+WvXVmsS4MrEFKbTh2bi v/d2xjGHmydERj/TNHJdvUm2zkamMb6SN5ILzjXvh0vzakyeWo6iD+yf2iJRUvGD1BWipImpa7+d qtsx7BoR9Rk4aSSAfs07zCmfE3FkFIotPZgej8Ah/c39tWSURdNbldUSqx0wtdW/Xwp65vy+jGlU 0KRXGhWSAGdladj0mx87qxJDmIafkoHrr1DnXLeqOoDnZ6rxVB9N12ZmCPzpwvagTd+q0rW3b8OK b8I7SVVVdqh86QdpMoqSP+C9bd2qKfpDt0uQeg2adAyAY0OBsvtYsoiRwfmrkgb9F+qRiqzIjjks TRc9KsfOJCFw8rHpSqswoF+qPq2Vnq5hQ5kP1TXO+OUfbaPph8S1l7bX14q6dNr1tY02m1avX/5F vel771ottNkFBx+UiosK2mLkYPM3ulNR5H2BRkY0neW0pFKUflzr078DDmvzzqWF3f5u1GnXk917 0KT9AZxhnHDKa7KJkcG95IdG/LY1gOOPVvMHm0ZgNK21YmW9aTvRjbpH+kpThxeca77T2VDlD/xD qm6BlpoisHa9zzFTUqHqGnzsxGPS8eeLm+L67Ntl19c1+BJT39Pifumm+NzkxFMhcoMzeVJH9NpP TXRk8r7wyLMVqKl17g8TVaJEcdRoZmSjjf0b4tn4Zm3J1KeM47ue8D4DJmVA4FLjhBNek1WMDPZk Fk4PUJ6iTa40rUW/trduD2BbufVTWrQLnkYsVkbBHXRQKgpGNa1d/bCmEY0ONcr74xFpuPrC9nro gpx91UxrGs+Z8frdj436pk3js9Wv5HlBpck6bUb97wvusDZVJUr0t8RhorR4bcnUN4xnbZcg9Rt4 fVVAaLcYJ+x+/csl7fSpFrPr4RQDhkjbRb9mPvi0DgJCN0yI9L5Ir+vbKwW0QL55qx8/r7N+CoP+ CLZv58FBfdX8Im6JA00LkZUfrddRHWgvmBPSUYem4U8XtsPFBW3RI9saITLa/ez0Sqz5xfpngJwC k+cF+qGgKlGwzKddth+PREnFd8NJoiQhX1tbMu1Do993CdLPqx6q7T3wxisBYc0cilGDEK80RXH2 SPMXM+9/bAeWfBg67HCIajjm0I6KAFaubkCbTE2JKFFDaZMppa9t2GBK0Tc7tPMoa1u4jqSpSwrh QRM4q35oBJng25EOGZCKyye0xcQJ7ZQZeoRr18x51SicZ32wx4EHpuLisW11k/1w9Yvn3JMv78Qr c+w31IilDZ9+mdiipEnt32tWTf3RYLNLkOhArwE3jxQCvY2TdryqEqMpj+/QN0/a0SYzyiQzaZV7 laiOhw5M09eVSJSsHDHQ1N2n9GuwrfUjJaNvDhuYpk+PEWea0rBKmPr3TcGl49rpI4QDelo7SjTa To5En/h9c7ZxzIrXkUOawkb03l9du+/9zw68VWTfHiMzOKoUpa9WNcQdWiOeNgrg1jWrpu6Ky7OH IPUeNOkQAMfHU0A896oUIze7Zg9mSsN4r1fgYEVm4bSuRCOGb75r0PfxBJet+j198eoaJFRZF0ZS /yMObhKm2jqJ739uVGbw0Wf/FN2SjEIH0KZeuxK5ynnyFetdS106ri2uPF9tYMnrbt+m/4izi62Z 5aoSpRG5mfji2wb8ttWWOettiwtzCjVkfQAAIABJREFU/i+Y056CNHBSVwBjgi+w6j2LUeSkv/y2 AVWKjQGGn5Jpy36lku8b8frb1boQqBLdSEjTWs4F57RFTZ3U15giuSeSa2jf1QXntMHNV3cAbeK1 Ky1fUYfHX9iJtxU5922pXZ06aLj8vHYw239bcHlk1v23e7Y70cQ5uJpRv1clSqcOtkeUpBTL166a +mIwiD0Eqc+gSWRz9OfgC6x4z2IUPWVaiCevC7Q/RVWi/UoZGZrlmwdp2oxEd96iGgT8AFnG2ZVI mC48ty12VjWNmGKtR86+Hpx/Tlvcek0HJe6hIq0X+fp7bnqlbk1ntfkvmbBTmHHyGqIqGaEjGhqc a9YdT9tJlMgNmNkM7RAlTcjZa0qmLQrmsYcgHTngwfJaUXUTAHVPTHDppH6KDBhozShRpumaIdv1 kfbxqLTAo4Jo0blrZ3tMw8l9DU0nLHivVl/Tor1EdiVy0UPCtG1HAD+uidxWvMs+TUL09+s7mu6r LFoW0/5XgUeeqcDPNljSnX9OG9D0pMr0YmElnplu/fSjyjaFypvWkhNBlITEY2tWTVsZ3Ma9Yk7k FWxcDghLPDawGAV3RezvyckmsSRHmyoT/TGjMOx2pe7ZXowelqnUnUwkbaNRBnkWX/R+bYtrTB3b a/pGXHIManci56E0NWd29NNI2kWbry/KbwsVPiiDy3/46Qp9RB18LNHfX3dZeyVha668ZSt+Xhf5 j65YOQuBAUUzcr4Lvn9vQRpb+m9IXBd8kYr3LEbmU504vq3uGdn8nHfnSFMihsv83Uetfdeze5Mw qdgaEG1LSJRopEpGEB4N6NhBQ98DUkBTfXYnCjlCnrvtECJqO7mF+scNHZVj+L/7tieM8UK0sFSJ 0hU3b8WaX5WKUsVJA7I7TZ68Z9yjEIK0cRykeC1aMNFcz2IUDa3orqXF4j9doNZ6iUK70wjBbl94 ZKlGMaTI3Qyn3QTI/Y9hGLL7qLXvaGMvTdOpTGS88PLsKmwrt8VCTGXTosrbpaK0aPHMnOHNG7rH GhKd7HPQLTXQpLIREotR8y4w9zNt7ly3wQdyO68qHdDDC7LCa2gEvv3ePgetFPPo4y/q9bAdZApv p/m0KtbR5EuRgW+9dzu+/V7pL9uwVdqvu1f3MpE/Su30MW3kJTdANDJN9kTfQRWb5unH3rJP69XE FhPylbUl04qb991eIyS6YEhB6W8C6NL84ng/sxjFSzDy+7t38+Lc07OUzDEH14KcVU5/swpbttn/ K5W8HdAak0rLw+C2O+X9C4WVeO2Navh89v5xpj9g9GtddbIruqvqdsWTf1amwMTx7ZR835VM3wlt 1OIZ3d5q3ua9Rkh0Qe+BN51EMd2aXxzPZxajeOhFf29lVUCfV8/KND8SZXBtyAcdCd9v2wIgZ7B2 ps1b/Hj/kzqQp3QK206/1hM5kX82GhF9sbLBMs8SoXimpQndKSo5R1Wd/jGlPOGtZ2NhSE6CVY6U Fr5Xq+99jKVuoe5Jlbj+p1VT97KQakGQbuwJiGGhMorlGDlOHHOa+UP4ZDDtjoV38D3kJ67BB5AH ApXp+KPS9TDMX5XUg8KT25nKNvtRvLwOZA1Hgd5UBQG0q43kXeH2B7brU5VWungK1V4ajf7v/s6g uFMqE60X3fVQue7WSWU5bs5bpSileIW+FGBSPLHvFhbmTAnFOqQg9Rn0Vz8gJ4a6IdpjtMCuIuoj mbLOX2J/6OFoedhx/berG/S9J4MVbqKldg04MFXf/PnLRp8jgp9RXJ+lH9Xhp3U+PRJnTjd3j5im v1GFO6eVY/mKekeEzZg4oa3ug0/1M134VjUee36na4MrquYTnD+JEq0jZ2WY64iZNuKmmidKs9eW TN1ruo7aEVKQ9usyZZOWVTUJQFw/e0iMVLgIof0wtIufU+QE1pf68M6SWqSlqgljEVyTU47NAE3j kLcFJyRqe9EHtfi11I8O7TRYEejOzHbTAv49/9mBDz6pc0RgwWOPSMNVF7XHqbnqrRtpi8FLr7vT U7eZz0A0eTU0Sn00QwJipkcHs0RJSPlQ8w2xRvtCCtK6dXcG+gyYdAoE+hgXRvuqUozs3JwZLQcn XU9RMmmXN8WfoXhAKtOgP6Tqng0oTLRTQkWvW+/TvT5s2uJHp44ePTihSgbx5j3r7Wrc/98KFH9U 65jRAe11u3Zie0tiNd3yr+1Y/AHPgsTyHNHUGlnbOlGU/H55/brvpoWMlBhSkAjAAQMn7S8EhsQC g8UoFmrW3UMjF4oSe9xRasKjB7eEzM8zMzR8/Z29C+/BdSLXOfOX1FjGILjsSN6/8W41pjxeoY/q yDjFCYnWCGktmLxDq07U/kl3bQeNbDnFTkC1KJERRdQRlwXWLH29+90ttapFQeo98AYfhLispRtb Os5i1BIZZx3/cW2jbpGmKhJtcGv1taUxbWyLShtcl+D3xOClWbSxMoDjjlQvzsFlh3pPcXumPlGh W5FV7HSGENH+LgoaSBGcaSuB6vTcjErQfiq7jTVUt9Oq/FWKEu19ilqUBApbWj8iJi0K0lEDp5bV iqprAUT8TWUxsuoxM6ecHTubTMPT0zRY4biUotKSb7MNZT49tIU5rYg/F3KWSsK0s1KCnKhancik lox0SJBos69T0ojcDDx+b2dLng1qM5l0v2NxOAynsFZZDxKlX0t9GGNyFG5aU4pWlATEA2tKppa0 1N6QG2ONi/MKSmcDONv4HO6VxSgcHeefOy0vEzdeoX5To0Hi6dcqQVZjTkvkqJb2VV2p2P0StZvW huYuqsE3NoSND8edfAWeOTxTubNeow40RUcjI/rDyUkdgd77peDJKZ1NL4BM8p9+LSIryIBX+rss KOy5vaVKtDhCohv6DLipEwROb+lm4ziLkUHCva80fbXkwzp4NHMtc1oiQvuiaCqPDC2ctlZAZrOv zKlCQ4Oa/VsffV6nmzFPf7Pa1vDRofrmgnPb4I4bO4IiB1uR6IfJs9Mro1+LsKJyCVYGjb7JFRB5 1DAzGSOllasbQLHMwqTPFxX2eCTMeYQdIeXmr+/rEZ4fw2XAYhSOjjvP0Y57CmNuVZozv1p3Bkqe FpyWPB6A9m+dPjQzbstEmpKjX5M//2KvR4tQjIeckKH/oVJtfWmU7RQHvUZ9kulV5Ujp4WcqwqG8 Z/HMPUOWN784rCDRxXkFpd8DOLD5jfSZxSgUlcQ4RtE9J09SHzogmBYFWCPvzQHnLKMEVw8d2ms4 8uA0HH5wKg7okYIe2R60ydL2uMb4QKbltFb2/U+NesTdVT80wOc8vdVDZYwengmasrUq0b6qJ18O afVrVRWSvhw7RElInFRUmLMsHPxIBOlBALRJdo/EYrQHjoT8QPuVaDf+OQrcPoUDZncgwHB1a36O XBNlpGtITxfw+yRq6qTugbqx0dnrISSk487MwrgzrRsJE7up/yMPK7ypvflzZMfnfr1S8Ph9ataU QoyUtneS2V0LC0XYn2Vh15AIUu+BN9H8wkXBwFiMgmkk7nsaqZAvvPKdARx7RMTGlnED+eMR6Ti4 f6rulYCC3zk50Zw5hUCg/UJVNRL1DdKxIzziqGnAhLPb4P7/64RBijdHB/cbGS7c8eAOfPOdM7x3 BNctWd9v3xHAF9824NTB5o6OaU2JQqzTJvygNOutwnazgj6HfNuqIHU64cGN6XW7zb9ZjEJyTOiD P/zciIXv18LjESDv3lak7K5e5B6Xgb69UnQT8dLNYX9YWVElV5dB1oMU4v4/d3fG4YOsNW0n9z/P z6zi2EUOfIJ+2+q3RJSkEHevLZm6qjUErU7ZUQZDC0pnSiCfpm9UDPEp0Nbsd6pbqyufdwABKyLS hmqmU02kQ9XVScdIiGh96IbLrTPpN9pPBhxvLqwGuWzi5GwCNFr+9537mF5Jipf2n2d3NAqZ0aWo sFNYiwcqPCJByhu7cdzE8e1eUyFGHGzL9GdAeYb79/DirBHqg/+FasiyT+t0x7orvtljOiDUpUl9 jIRoxCmZuOkq64WIwD/1SiVmzHXePrOkfihaabwqUVr6Ue36ISdk7tdK8frpiASp9LfGU7O7eOdH kmE017AYRUPLeddSWJGrLmxnS8U+/6ZeN6H+8LM6W8p3aqFkpj5qWJbu6seOOvKoyA7q5pV5+KBU TLnd/JESgH5CiJ9aq2lEgiSlfA3AuNYyi+Y8i1E0tJx7bbcuHj3ECK1P2JHW/NqoC9O7xbVwumWb Sj5tszR9H9Gl49RHbW2pHbRW9PpbPPXeEh+3HD/msDTcc2sns6vbTQixubVMIxWkCwG80FpmkZ5n MYqUlHuus9r1UCgy09+swluLakB7gJIl0X4S2nk/api5llLR8CMLOgqi58SNzdG0g6/dTcBkUSoW QgzenXvL7yIVpA4AylvOJvIzLEaRs3LblakpAhcXtEXBaHtGSwavT76ox4L3an6PrOrs/UBGnaN5 peCHucel47QhmZY5Pm2pfryvqCUy7j9uoihdI4R4NBIiEQkSZSSlfBPA6EgybekaFqOWyCTW8aMO SdN/tZN3b7sTWfkUfVCD1T81QrpYm8hI4ZD+qcg7McNSrwot9R+NRskHnVO9arRUbz4eHQGTRClb CLEpkpKjEaSxAKZHkmmoa1iMQlFJ7GMFo7Jwxfn2GD2EIkvrGxQGfNWPDa4QJxKhAf1SccIx6SCW TkhLljV5KP92NW9wdUJ/WFEH+mF5500xuxFbJIQYHmk9oxEkmqSOacWSxSjS7ki869q20XDe2W10 wwcnta7og1p8+mU9Vqysh1OC4RGfrEyBwwam4Y9HpOlTck5i9uhzO0HrRZySj8Apx6bj9htiEqVL hBDPR0osYkGiDKWULwK4INLM6ToWo2hoJe61hw5IxejhWTjlOPun8ZpTXrfBh5XfNej/v1/TiNJN PstGUB3bayBXKxQgkTwoWOUJozmDcJ9fnVOFFwo5ims4RslwLkZRai+EiNiTbrSCdCqAiPcjsRgl w2MaXRuHnZyBW/5MNjLOTuRzjTwMbNzkQ+kmP0o3+0ARdmMZTZGT2k4dNHTu6EGPHA96ZnuxXw+v 7mm7a+dWvXfZBmreoqZwGWRaz4kJEIEoRalQCFEQDbloBYm+PRH5AWExiqYbkutaWhspGNUGl59n 356ZWIn7/UBFZUDf80SOVBt9TZYSXo8Atcv4nJmu6Y5MMzMFaI+QmxJZKc5dVA165cQEmhOIQpRO F0K80/z+cJ+jEiTKSEp5L4C/hcuUxSgcHT5nEKCRw4Sz2oCilHJyBoEHn6jAu0s5PIQzesO5tYhw psMrRPhwE81bGIsg/QHA6uYZGZ/Zh5VBgl8jJdC+rYb8M7Iw7iwWpkiZmX0dGSy8uaDasrUzs+vP +VlPYERuBm6+qsXp9/uEELdGW6uoBYkKkFJ+AODE5oU9N6MSr8xmh4rNufDnyAjQesroYZksTJHh MuUqms14/W0WIlNgJmEmYUTpICEERRuPKsUqSJcCeCa4JBajYBr8Ph4CZHlGUWp5xBQPxfD3khDN nl8NWhPjxATiIRBClJYJIU6KJc9YBYl26e0aCrEYxYKe72mNAIXZPuvUTN0dUWvX8vnICDz8dAXe XlzDHhYiw8VXRUigmSidJ4R4NcJb97gsJkGiHKSU1wJ4+LHnd2LOfN4stwdV/mAqAa9X4PS8DFxz qT2xfUxtjA2Zfb2qAXMXVuP9j+t4jcgG/slSZJssbdurj+57aVaWmBtrm2MWJCrw7oe3n7j0wzpa T+LEBJQTILPqIw9Jw+jhmTj+KOdtsFUOIMoCFhTXYt6iat2PX5S38uVMIGoCAuL+opnZYS2wW8s0 LkGizPPyS5dCILe1gvg8EzCTABlAnDE0ExPOZsu85lzJ6ek7S2qwoyLQ/BR/ZgKqCASE39OvaNa+ a+IpwARBKjsXQhbGUwm+lwnESsDrAY45PB3DT8nAicck76jpvY/r9FhQX5XU87RcrA8T3xczAQEx t2hm9pkxZ/D7jXELUm6u9Hq6lv0MIKKY6fFWmO9nAi0RoP1Mg0/I0GMFDTootaXLEub4N6sasPjD Wn1tqLKKR0MJ07EubIgATi2ambMg3qrHLUhUgSEFZTcJyCnxVobvZwJmEdinowcn/TEdJx+brscR Mitfu/MhH3sffV6H95bXYcs2ttm2uz+4fJ3AqsUzswcBIu6IY6YIUu5Zazt4UtPWA+AJfX5CHUeA zMePPCQVfzw8HUcflgba5+SmRNNxH6+ow8df1INHQm7queSoqwCuKJqZ85QZrTVFkKgiQwrKHhGQ 15hRKc6DCagk0LO7F4f2T8XB/VP10VOXfZzjcZsct67+sRG0FvTFtw1Y84u7I92q7EfO2xEEttZI /37LC3vWmlEb0wRpeP6mXn4R+AGA14yKcR5MwCoC7dtpOLB3CvockIJ+vVLQM8eD7vt6kZZm2tcj ZFPKNvvx60Yfftnow/c/NYBiMW36jafhQsLig84kIMUdiwuz7zKrcqZ+4/IKSl8GcJ5ZleN8mICd BMhIonMnD9q1FaBpP4p+2yZT6EKV4hWgDbspv//8CgRoszjg+X2wVVsndW8IdQ0S9fUSOysD+nTb zqqAbo69dbsfPtYeO7uXy46fQJVX+vdfUNhze/xZNeVg7mjG438Afs8EAKYKnVmN5XyYQDQEaPqM /nNiAkxgbwISeMpMMaISTF3dXfxaz29EFBFl924iH2ECTIAJMAEXEGjwavIhs+tpqiBR5aSG+8yu JOfHBJgAE2ACziEgIF5ZOL07WVabmkwXpMXTcz4A5BJTa8mZMQEmwASYgFMI+ODX7lZRGdMFiSop Ie5UUVnOkwkwASbABGwmIOTL8fqsa6kFSgRpycyc9wEsbalQPs4EmAATYAKuJODzBwL/UlVzJYJE lZXAZFWV5nyZABNgAkzAFgKvFBf2/ElVycoE6fdR0iJVFed8mQATYAJMwFICDR6pKV2OUSZIhEnT cFvTYMlSaFwYE2ACTIAJmE5APrWwsNta07MNylCpIC2anvM5gFlB5fFbJsAEmAATcB+BGq8vVdna kYFDqSBRIR4/bgfgMwrkVybABJgAE3AXASnwyILZXcpU11q5IC2clbMaAi+obgjnzwSYABNgAkoI bGvwND6gJOdmmSoXJCrP25hCo6TqZmXzRybABJgAE3A4ASlw97JX9y+3opqWCBIN9SQER5S1oke5 DCbABJiAWQQEfqxon/2YWdm1lo8lgkSVyKqlEOeitLUK8XkmwASYABNwBgEZwC0rnhSNVtXGMkGa Ny+nRorA361qGJfDBJgAE2ACsROQwHtLCnPmxJ5D9HdaJkhUtZP757wACTIF58QEmAATYALOJeD3 yMD1VlfP8kB6eWPLjoaUH5sdi8lqcFweE2ACTCBRCUghH18yo/vVVrfP0hESNW7xjOzPADxrdUO5 PCbABJgAE2idgAS2BOobyMuO5clyQaIWpkpBjd1heWu5QCbABJgAEwhPQOC24jd62fL32RZBml+Y vQVC/F94KnyWCTABJsAErCQgpPzk5P7Zts1g2SJIBPik/t2eAPS1JCt5c1lMgAkwASYQmoDPr8kr J08WgdCn1R+13KghuEmDx244VJMaWd15g4/zeybABJgAE7CYgJBTFs/o/leLS92jONtGSFSLpTN6 fA2IaXvUiD8wASbABJiA1QTWeVI9SmMdRdIgWwWJKphZKwmC0hgbkYDga5gAE2ACyUpACnH1wpe6 2e5v1HZBIg8Omha4nAP5JetXgdvNBJiAzQReXjIje77NddCLt12QqBaLpvdYDOBJJwDhOjABJsAE kojAJq/0X+eU9jpCkAhGXV3KzQB+dQoYrgcTYAJMINEJSImrFxT23O6UdjpGkD6c26VSCslTd055 MrgeTIAJJDgBMd1q56mtAXWMIFFFl8zovhCQj7dWaT7PBJgAE2AC8RAQpV7p+3M8Oai411GCRA30 pHnIDv4HFY3lPJkAE2ACTABSQF7qpKk6o08cJ0hkehjQtAsB+IxK8isTYAJMgAmYRUD+t2hmzgKz cjMzH8cJEjVu6fRun0DIe8xsKOfFBJgAE0h2AlJgdWatsNUbQ7g+cKQgUYX9m3P+CYmPwlWezzEB JsAEmEDEBBoAnEd7PyO+w+ILHStIxcXCJ/2YIIByi5lwcUyACTCBxCMg8dclM3K+cHLDHCtIBG3J 7JxfpBRXOBkg140JMAEm4AICby8uzH7E6fV0tCARvMWF2a8L4Amng+T6MQEmwAScSUCU+j24GBDS mfXbXSvHCxJVtVr6b4TEl7urze+YABNgAkwgAgI+aHJc8Ws5WyO41vZLXCFIywt71krNkw+gwnZi XAEmwASYgEsISIhbF0/P+cAl1YUrBIlgLpmx789CyIvYK7hbHi2uJxNgAjYTmLNkZrepNtchquJd I0jUqqIZ3d+EkA9G1UK+mAkwASaQbAQEfhQy/RI3rBsFd42rBIkq3imQc6uUgsJVcGICTIAJMIG9 CVSLgHZOUWEn1y1xuE6QCguFPw0YD4Ff9u4HPsIEmAATSGoCUgAXFRV2W+lGCq4TJII8vzB7SwCB MwE4dsexGx8GrjMTYALuJiCBfxXNzJnl1la4UpAI9tIZPb6WQlzMRg5uffS43kyACZhKQMq3Th6Q fYepeVqcmbC4PNOLyysoux2Qd5meMWfIBJgAE3APgZVCpp/kxnWjYMSuFyRAiryCspfIaWBww/g9 E2ACTCAZCEhgS8AXOKJ4do8Nbm+va6fsdoMXspMsvxSQH+8+xu+YABNgAklBoEZq2qhEECPqrQQY ITU9dCPzy7o0CnwkIfsmxWPIjWQCTCDZCUgJed6Smd1fSxQQCTBCauoKsrzzSd9IGr4mSudwO5gA E2ACLREQErclkhhROxNmhGR02uBxm/6oBQJLAGQax/iVCTABJpBIBKSQjy+Z0f3qRGoTtSVhRkhG x1D484CU4ynorHGMX5kAE2ACCUTglX0COdckUHt2NSXhBIlatrSw+1wJ/IX3KO3qZ37DBJhAQhCQ S8iIizzWJERzmjUi4absgts3NL/0b1Lg3uBj/J4JMAEm4FICnwqZPtzte43CsU/IEZLR4KLCnPsE xP3GZ35lAkyACbiUwKpUKc5IZDGifknoEVLTg6dvnH0cwJUufRC52kyACSQzAYFf/I2BExNlr1G4 rkzoEVJTw2njbPafAbwSDgSfYwJMgAk4kMAGf8A/NBnEiNgnwQip6RHLz5eebaL0VQFR4MCHjqvE BJgAE2hGQJZByNzFM3r80OxEwn5MGkGiHjzyCpnSvrxsuhAYk7A9yg1jAkzA9QRog78mcErRjJzv XN+YKBqQBFN2u2mseFI07oPy8QJi7u6j/I4JMAEm4BwCuhhJLS/ZxIh6IKkEiRpcWDiwoaPcni8l ZjvnEeSaMAEmwAR0ApulRwx2a8TXePswqabsgmHl5kqvZ99NL0PKscHH+T0TYAJMwB4CotTjl3kL Z+Wstqd8+0tNuhGSgby4WPg6BbpRDKWXjWP8ygSYABOwicB6v/SdksxiRNyTVpCo8eR+o5PMpjDo /7PpIeRimQATSHICAuInvyZOLi7s+VOSo0ges+/wHS3FkLFl9wiJv4W/js8yASbABEwkIMU3fnhG FBd23WRirq7NKqlHSLt7TcglM3JuFVL8lR2y7qbC75gAE1BIQOKj+pSGXBaj3YyT1qhhN4I93w0Z WzpRSDwBwLPnGf7EBJgAEzCNwLuZtThn3rycGtNyTICMWJBCdOKQgo2jBASFBc4KcZoPMQEmwARi JiAgnivv0O1K2hcZcyYJeiMLUgsdS5FnRSAwTwBdWriEDzMBJsAEoiQg/7l4Zs4dgJBR3pgUl7Mg henm3Pz1fb3CO19C9g1zGZ9iAkyACbRGwC+Aq4pm5jzV2oXJfJ4FqZXezx1f2tnjxxwAJ7ZyKZ9m AkyACYQiUCGAsUUzcxaEOsnHdhNgK7vdLEK+K34tZ2tqZfVQ3kAbEg8fZAJMIDyBtQGPOIHFKDwk 4yyPkAwSEbzmFZTeCuBfyRS2IwIsfAkTYAIhCYjlnkZx1sI53X4LeZoP7kWABWkvJOEPDMkvPVsI vAigTfgr+SwTYAJJS0DI51N31vxp/vx+9UnLIIaGsyDFAG342E2DAlLOYWOHGODxLUwgsQn4hJA3 Fs3o/p/Ebqaa1rEgxcj1xAm/dEzzpbwK4NQYs+DbmAATSCACehwjTRQUTc8uTqBmWdoUNmqIEfey V/cv7ySzzwBwL7sbihEi38YEEoWAxOfw4WgWo/g6lEdI8fHT7x6aX3a6FPIFAPuYkB1nwQSYgIsI CCEeTdlZdROvF8XfaSxI8TPUcxiev6mXH4GZEDjKpCw5GybABJxNoAoCf1o8I+cVZ1fTPbXjKTuT +mphYbe1qVXVJ9KvJZ7CMwkqZ8MEnEtgpcePo1mMzO0gHiGZy1PPbejYjWdKKZ7hKTwFcDlLJmAz ASnk44GMhhuLn+9VZ3NVEq54FiRFXZo7ZkMPzau9LIBTFBXB2TIBJmAtge1SYuKSwhxyJcZJAQGe slMAlbIsnt1jwz4yOw8Q/wAku5lXxJmzZQIWEVgqJA5nMVJLm0dIavnquQ8bV3pUIACywhtgQXFc BBNgAuYRqBPAbScOyH548mQRMC9bzikUARakUFQUHDsuf31Gpua5FxLXsi88BYA5SyZgNgGJLwFx /uLC7FVmZ835hSbAghSai7KjeQVlgwXw5P+3d26xVVRRGP7/PbW2oqYgSIGC8a6QoPLgJYKppYL1 Fi+p0AcUrw/6oDHxHhU1XuOLiYmJqVGjRvAIGjERQ9GCGNEgmGgUlYhSORRRqQhKy5lZZho1EUs9 9zMz5386ObPXWnutb03yZ86Zvbe2HSoZYgUWgUIJDBj48K8NjQ/rVNdCUebmL0HKjVdRrAeflliz ALBbANQUJaiCiIAIFEzAgA/DPS8CAAAGbElEQVRovF5PRQWjzCuABCkvbMVxap275RQL2AlgWnEi KooIiECeBHYCvGvG5Man9V9RngSL4CZBKgLEQkI0N1uNO7z3ZsIeAFBfSCz5ioAI5EOAS/2Mf0P4 Zmw+3vIpHgEJUvFYFhSp9bJtRwUueIa0mQUFkrMIiEC2BLbB7KYVqQmLsnWQXWkJSJBKyzfH6MaW Oen5ND4OYHSOzjIXARHIjoABfK7GMre+k5r4S3YusioHAQlSOSjnOMfs9p5RGboHAV6vlx5yhCdz ERiewDrS3di1qHHN8GYarQQBCVIlqGc55+BLDz6fBDEjSxeZiYAIDE3gJxrunj5lXKdeWhgaUBSu SpCi0IVhczC2XJ6eS/BRAJOGNdWgCIjAvgQGQDzl9/c/2P3GkX37Dup7tAhIkKLVj/1mE65dGgHv JiNuB9CwX0MNiIAI/E3gdd/827pTEzf+fUGf0SYgQYp2f/6TXXNHerTn2/0ArgN4wH8MdEEEqpwA zT6C5+7QceLxuxEkSPHr2WDGze09x3j0FgDoAKBd22PaR6VdVAJfkLina9G41wFaUSMrWFkISJDK grl0k8zs6JmKjHsI5AWlm0WRRSDCBIjvYbxvlDW+lErRj3CmSu1/CEiQ/gdQXIZb5/SebkFwL4i2 uOSsPEWgQAKbaXx0JH55NpWaMlBgLLlHgIAEKQJNKGYKLe1bTyXtXgDnFzOuYolAhAh8R8MjI7Hj eQlRhLpShFQkSEWAGMUQ4aGAvo87SVys/5ii2CHllAeBrwh7fEfD+Bd1LEQe9GLgIkGKQZMKSfHs 9i3HO8dbYZgHoLaQWPIVgQoR+JjEY9NPHPeGFrVWqANlmlaCVCbQlZ7mnLmbxwfm3QzjdVrHVOlu aP4sCAQElhn4xIpXx72Xhb1MEkBAgpSAJuZSwqx5vSP8Absy3OUYwHG5+MpWBMpAYDdgL4D25IpF TV+XYT5NESECEqQINaOcqSxYYG7lF73nerAbDZgNwCvn/JpLBP5FgPjGjM8EA3s6tcXPv8hU1RcJ UlW1e+hiW9vTkwLyKsKu1n55QzPS1ZIQ6AfwGh07uxY2rtRi1pIwjlVQCVKs2lXaZMOnplVf9s5G YNeSdqG2Jiot7yqO/hkMz9bAf1HnEVXxXTBE6RKkIaDoEjCzY9tY8zPzSV4Dw7FiIgIFEtgF8FWY 37ki1fRhgbHknlACEqSENrZ4ZYXHX2ydQeIKGi41YGTxYitSwgkEAFbC7OXa2rrU2y8ftjPh9aq8 AglIkAoEWE3ubW3fHDhwyIg2g3UQvBBAfTXVr1qzJGBYC+AV52UWLl84KZ2ll8xEABIk3QR5ETjz ou2H1B04cB7Jyww4D8CIvALJKQkEDLCPaG4JAre4a/HYb5NQlGooPwEJUvmZJ27G8PDAg+iFr45f YkAbgTGJK1IF7UsgA9gqI5cGe4PXupc0/bCvgb6LQK4EJEi5EpP9sATa28372UufxoAXwHg+aFOH ddBgnAj8BGAZzN4i6pd1pUb9GqfklWv0CUiQot+jWGfYfOkPTTU1nGVw5xhspp6eYtXO8EiHNQSW +84tH+2PXavzhmLVv9glK0GKXcvim3C4zmn1hvRJ8F2rITgL5HTtqxepfvowrIfDKgZ8NwNvZXfq 8F2RylDJJJqABCnR7Y12ceHPezu89FTzeRaIGQBOBzAh2lknKrvdMKwDsdrI9/v/qFn9wZtjfktU hSomVgQkSLFqV/KTbWnvmeCcdxrMzjDwVAAnAzg0+ZWXvMKMARsIfGLAGs+CNXu3T/i8u5uZks+s CUQgSwISpCxByaxSBIwtc348CgimATaNNihQk7Xn3rD92EmzL438FMT6gO7Tg3cHny1dOv73Yb00 KAIVJiBBqnADNH1+BMJ1ULUH+ZO9wJ9ixAk0d7yZHQ3iaAB1+UWNlZcBCF+13mjARho2mLPPXcAN Xanxm2NViZIVgb8ISJB0KySMgHHW3HSTH7hjBp+iDEcYrYmGpsHvxMSY/AQY7oS9zYAewLYQDD83 G7DJkRsz9f2bup8/ck/CmqdyqpyABKnKb4BqLL95/qa62j21Y3xzjQDHGvwxNDfKYA2ObDCzBpg1 GFy9ozWY8QA4Oxhm9QT/efraz75+vxMIxQTh9gUg+mDYS2CXGcKxPwJaH8k+GnfArC8g+hyw3Rx+ 9PZie+DqtmqNTzXemar5T7boKrYfCqI6AAAAAElFTkSuQmCC"/></symbol><symbol viewBox="0 0 24 24" id="webpack" xmlns="http://www.w3.org/2000/svg"><path d="M19.376 15.988l-7.709 4.45-7.708-4.45V7.087l7.708-4.45 7.709 4.45z" fill="#fff" fill-opacity=".785" stroke-width="0"/><path d="M12.286 1.98c-.21 0-.41.059-.57.179l-7.9 4.44c-.32.17-.53.5-.53.88v9c0 .38.21.711.53.881l7.9 4.44c.16.12.36.18.57.18.21 0 .41-.06.57-.18l7.9-4.44c.32-.17.53-.5.53-.88v-9c0-.38-.21-.712-.53-.882l-7.9-4.44a.945.945 0 0 0-.57-.179zm0 2.15l7 3.939v2.104h-.016v5.177h.016v.54l-7 3.939-7-3.94V8.07l7-3.94zm0 2.08l-4.9 2.83 4.9 2.83 4.9-2.83-4.9-2.83zm-5 5.08v3.58l4 2.308v-3.58l-4-2.308zm10 0l-4 2.308v3.58l4-2.308v-3.58z" fill="#8ed6fb"/><path d="M12.286 6.21l-4.9 2.83 4.9 2.83 4.9-2.83-4.9-2.83zm-5 5.08v3.58l4 2.308v-3.58l-4-2.308zm10 0l-4 2.308v3.58l4-2.308v-3.58z" fill="#1c78c0"/></symbol><symbol viewBox="0 0 24 24" id="wolframlanguage" xmlns="http://www.w3.org/2000/svg"><title>wolframLanguage</title><g transform="scale(.12121)" fill="none" fill-rule="evenodd"><circle cx="99.197" cy="98.946" r="83.28" fill="#212121" stroke-width=".841"/><path d="M182.529 98.828a83.406 83.406 0 0 1-39.14 70.721.064.064 0 0 1-.038.019l-28.62-35.665 23.71 2.612s11.385 1.177 13.978 0c2.373-.938 15.175-18.963 15.175-18.963s-36.75-23.23-49.312-36.032c1.434-21.575-1.656-50.269-1.656-50.03-9.251 9.234-10.429 10.669-19.68 19.203-4.028-13.04-5.923-17.547-9.95-30.588-12.104 9.95-21.337 26.799-27.977 46.48a78.68 78.68 0 0 0-4.23 5.094 109.774 109.774 0 0 0-2.667 3.66 114.558 114.558 0 0 0-5.132 8.002 172.555 172.555 0 0 0-3.403 6.051c-7.706 14.475-14.034 31.066-19.515 46.001a.858.858 0 0 1-.092-.184c-14.988-30.912-9.502-67.85 13.822-93.072 23.325-25.223 59.723-33.575 91.71-21.045 31.988 12.53 53.029 43.382 53.017 77.736z" fill="#e53935"/><path d="M101.452 69.178s-1.416-8.295-2.373-11.367c6.401-6.18 7.357-7.118 13.52-13.04.477 11.845.238 18.006-.479 32.481-3.55-3.568-10.668-8.074-10.668-8.074zm-27.737 40.778s-6.64-4.029-11.624-4.728c1.435-3.329 5.223-7.596 6.18-8.773-1.913.699-15.653 6.86-17.087 12.084a74.804 74.804 0 0 1 11.385 3.79 35.993 35.993 0 0 0-8.774 20.158s21.815-3.33 38.185-1.196c.283.168.609.251.938.24l8.534.239 27.111 45.136.221.35c-.037.018-.055.037-.073.037-51.133 18.485-88.085-15.543-95.976-27.443.034-.102.058-.206.074-.313 7.1-30.017 15.855-65.939 30-76.552 7.356-12.82 9.49-31.783 22.751-41.734 3.33 9.951 8.553 30.588 12.103 40.539 15.653 15.652 39.361 35.094 55.234 43.15 1.656.956 3.79 7.596 3.79 7.596l-6.401 8.056-68.276-6.879a54.462 54.462 0 0 0-4.58-.183 86.848 86.848 0 0 0-14.144 1.36c3.311-8.295 10.43-14.935 10.43-14.935zm22.054-8.774c3.789-.46 7.817.956 12.323 3.568 4.267-1.195 4.745-1.434 9.013-2.612-5.463-4.028-11.386-8.295-19.442-7.118a47.249 47.249 0 0 0-1.894 6.162z" fill="#fff" stroke-width=".936"/></g></symbol><symbol viewBox="0 0 24 24" id="word" xmlns="http://www.w3.org/2000/svg"><path d="M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2m7 1.5V9h5.5L13 3.5M7 13l1.5 7h2l1.5-3 1.5 3h2l1.5-7h1v-2h-4v2h1l-.9 4.2L13 15h-2l-1.1 2.2L9 13h1v-2H6v2h1z" fill="#01579b"/></symbol><symbol viewBox="0 0 24 24" id="xaml" xmlns="http://www.w3.org/2000/svg"><path d="M18.93 12l-3.47 6H8.54l-3.47-6 3.47-6h6.92l3.47 6m4.84 0l-4.04 7L18 18l3.46-6L18 6l1.73-1 4.04 7M.23 12l4.04-7L6 6l-3.46 6L6 18l-1.73 1-4.04-7z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="xml" xmlns="http://www.w3.org/2000/svg"><path d="M13 9h5.5L13 3.5V9M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m.12 13.5l3.74 3.74 1.42-1.41-2.33-2.33 2.33-2.33-1.42-1.41-3.74 3.74m11.16 0l-3.74-3.74-1.42 1.41 2.33 2.33-2.33 2.33 1.42 1.41 3.74-3.74z" fill="#8bc34a"/></symbol><symbol viewBox="0 0 24 24" id="yaml" xmlns="http://www.w3.org/2000/svg"><path d="M5 3h2v2H5v5a2 2 0 0 1-2 2 2 2 0 0 1 2 2v5h2v2H5c-1.07-.27-2-.9-2-2v-4a2 2 0 0 0-2-2H0v-2h1a2 2 0 0 0 2-2V5a2 2 0 0 1 2-2m14 0a2 2 0 0 1 2 2v4a2 2 0 0 0 2 2h1v2h-1a2 2 0 0 0-2 2v4a2 2 0 0 1-2 2h-2v-2h2v-5a2 2 0 0 1 2-2 2 2 0 0 1-2-2V5h-2V3h2m-7 12a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m-4 0a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m8 0a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1z" fill="#f44336"/></symbol><symbol viewBox="0 0 24 24" id="yang" xmlns="http://www.w3.org/2000/svg"><path d="M12 2a10 10 0 0 1 10 10 10 10 0 0 1-10 10A10 10 0 0 1 2 12 10 10 0 0 1 12 2m0 2a8 8 0 0 0-8 8 8 8 0 0 0 8 8 4 4 0 0 1-4-4 4 4 0 0 1 4-4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 2.5A1.5 1.5 0 0 1 13.5 8 1.5 1.5 0 0 1 12 9.5 1.5 1.5 0 0 1 10.5 8 1.5 1.5 0 0 1 12 6.5m0 8a1.5 1.5 0 0 0-1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5-1.5 1.5 1.5 0 0 0-1.5-1.5z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 289.99999 290.00001" id="yarn" xmlns="http://www.w3.org/2000/svg"><path d="M250.733 218.418c-12.39 2.943-18.661 5.653-33.993 15.641-24.004 15.487-50.176 22.688-50.176 22.688s-2.168 3.252-8.44 4.723c-10.84 2.633-51.647 4.878-55.364 4.956-9.988.077-16.105-2.555-17.809-6.66-5.188-12.388 7.434-17.809 7.434-17.809s-2.788-1.703-4.414-3.252c-1.471-1.47-3.02-4.413-3.484-3.33-1.936 4.724-2.943 16.261-8.13 21.45-7.125 7.2-20.598 4.8-28.573.619-8.75-4.646.62-15.564.62-15.564s-4.724 2.788-8.518-2.942c-3.407-5.266-6.582-14.248-5.73-25.32 1.084-12.777 15.176-25.011 15.176-25.011s-2.477-18.661 5.653-37.787c7.356-17.422 27.179-31.437 27.179-31.437s-16.648-18.352-10.454-35c4.027-10.84 5.653-10.763 6.97-11.227 4.645-1.781 9.136-3.717 12.466-7.356 16.648-17.964 37.864-14.557 37.864-14.557s9.911-30.431 19.203-24.469c2.865 1.859 13.163 24.778 13.163 24.778s10.996-6.426 12.235-4.026c6.659 12.931 7.433 37.632 4.49 52.654-4.955 24.778-17.344 38.096-22.3 46.459-1.161 1.936 13.319 8.053 22.456 33.373 8.44 23.152.929 42.587 2.245 44.756.232.387.31.542.31.542s9.679.774 29.114-11.228c10.376-6.427 22.688-13.628 36.703-13.783 13.55-.232 14.247 15.719 4.104 18.12z" fill="#2c8ebb" stroke-width=".774"/></symbol><symbol viewBox="0 0 24 24" id="zip" xmlns="http://www.w3.org/2000/svg"><path d="M14 17h-2v-2h-2v-2h2v2h2m0-6h-2v2h2v2h-2v-2h-2V9h2V7h-2V5h2v2h2m5-4H5c-1.11 0-2 .89-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z" fill="#afb42b"/></symbol></svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol viewBox="0 0 24 24" id="actionscript" xmlns="http://www.w3.org/2000/svg"><text style="line-height:113.99999857%" x="5.605" y="15.892" transform="scale(.91325 1.095)" font-weight="400" font-size="42.822" font-family="sans-serif" letter-spacing="0" word-spacing="0" fill="#f44336"/><path style="line-height:125%" d="M4.744 2.031c-1.157 0-1.994.31-2.51.93-.515.612-.771 1.678-.771 3.197v2.467c0 1.408-.402 2.111-1.201 2.111v2.035c.8 0 1.2.679 1.2 2.036v2.654c0 1.512.26 2.562.78 3.152.52.59 1.355.885 2.502.885V19.43c-.447 0-.77-.151-.97-.453-.195-.303-.292-.815-.292-1.538v-2.267c0-1.807-.404-2.937-1.214-3.395v-.045c.81-.464 1.214-1.581 1.214-3.351V6.025c0-1.283.42-1.925 1.262-1.925V2.03zm14.66 0V4.1c.842 0 1.262.642 1.262 1.925v2.268c0 1.843.402 2.996 1.207 3.46v.046c-.805.442-1.207 1.544-1.207 3.306v2.356c0 .715-.099 1.22-.299 1.516-.2.302-.52.453-.963.453v2.068c1.152 0 1.984-.295 2.494-.885.516-.59.772-1.663.772-3.218V14.84c0-1.379.404-2.069 1.209-2.069v-2.035c-.805 0-1.21-.696-1.21-2.09V6.113c0-1.49-.255-2.54-.77-3.152-.516-.62-1.348-.93-2.495-.93zm-3.054 4.46c-.455 0-.886.057-1.293.173a3.056 3.056 0 0 0-1.078.527c-.308.241-.551.549-.731.924-.18.37-.27.817-.27 1.336 0 .663.165 1.227.493 1.695.33.468.831.864 1.502 1.188.263.125.509.249.736.37.227.12.422.244.586.374.168.13.299.271.394.424a.963.963 0 0 1 .145.521c0 .144-.03.28-.09.405a.9.9 0 0 1-.275.318c-.12.088-.272.158-.455.21a2.34 2.34 0 0 1-.635.075c-.415 0-.825-.083-1.233-.25a3.644 3.644 0 0 1-1.13-.763v2.222a3.68 3.68 0 0 0 1.101.418c.427.093.875.139 1.346.139.459 0 .894-.05 1.305-.152a3.002 3.002 0 0 0 1.09-.5c.31-.237.556-.543.736-.918.183-.38.275-.849.275-1.405 0-.403-.052-.755-.156-1.056a2.542 2.542 0 0 0-.45-.813 3.295 3.295 0 0 0-.704-.633 6.754 6.754 0 0 0-.922-.535 12.4 12.4 0 0 1-.676-.348c-.2-.115-.37-.231-.51-.347a1.502 1.502 0 0 1-.322-.375.91.91 0 0 1-.115-.453c0-.153.033-.288.101-.408a.948.948 0 0 1 .29-.32c.123-.089.275-.156.454-.202a2.18 2.18 0 0 1 .598-.078c.16 0 .326.015.502.043.18.028.36.07.539.13.18.056.354.13.522.218.171.088.329.188.472.304V6.871a4.039 4.039 0 0 0-.957-.285 6.448 6.448 0 0 0-1.185-.096zm-8.774.165l-3.123 9.967h2.094l.605-2.217h3.053l.61 2.217h2.107L9.869 6.656H7.576zm1.072 1.78h.047c.028.347.077.646.145.896l.922 3.35H7.564l.934-3.377c.08-.288.13-.578.15-.87z" font-weight="400" font-size="51.019" font-family="sans-serif" letter-spacing="0" word-spacing="0" fill="#f44336"/></symbol><symbol viewBox="0 0 24 24" id="android" xmlns="http://www.w3.org/2000/svg"><path d="M15 5h-1V4h1m-5 1H9V4h1m5.53-1.84L16.84.85c.19-.19.19-.51 0-.71a.513.513 0 0 0-.71 0l-1.48 1.48C13.85 1.23 12.95 1 12 1c-.96 0-1.86.23-2.66.63L7.85.14a.501.501 0 0 0-.7 0c-.2.2-.2.52 0 .71l1.31 1.31C6.97 3.26 6 5 6 7h12c0-2-1-3.75-2.47-4.84M20.5 8A1.5 1.5 0 0 0 19 9.5v7a1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5-1.5v-7A1.5 1.5 0 0 0 20.5 8m-17 0A1.5 1.5 0 0 0 2 9.5v7A1.5 1.5 0 0 0 3.5 18 1.5 1.5 0 0 0 5 16.5v-7A1.5 1.5 0 0 0 3.5 8M6 18a1 1 0 0 0 1 1h1v3.5A1.5 1.5 0 0 0 9.5 24a1.5 1.5 0 0 0 1.5-1.5V19h2v3.5a1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5-1.5V19h1a1 1 0 0 0 1-1V8H6v10z" fill="#c0ca33"/></symbol><symbol viewBox="0 0 24 24" id="angular" xmlns="http://www.w3.org/2000/svg"><path d="M12.102 2.625l8.84 3.15-1.34 11.7-7.5 4.15-7.5-4.15-1.34-11.7 8.84-3.15m0 2.1l-5.53 12.4h2.06l1.11-2.78h4.7l1.11 2.78h2.05l-5.5-12.4m1.62 7.9h-3.23l1.61-3.87z" fill="#e53935"/></symbol><symbol viewBox="0 0 24 24" id="angular-component" xmlns="http://www.w3.org/2000/svg"><path d="M12.102 2.625l8.84 3.15-1.34 11.7-7.5 4.15-7.5-4.15-1.34-11.7 8.84-3.15m0 2.1l-5.53 12.4h2.06l1.11-2.78h4.7l1.11 2.78h2.05l-5.5-12.4m1.62 7.9h-3.23l1.61-3.87z" fill="#0288d1"/></symbol><symbol viewBox="0 0 24 24" id="angular-directive" xmlns="http://www.w3.org/2000/svg"><path d="M12.102 2.625l8.84 3.15-1.34 11.7-7.5 4.15-7.5-4.15-1.34-11.7 8.84-3.15m0 2.1l-5.53 12.4h2.06l1.11-2.78h4.7l1.11 2.78h2.05l-5.5-12.4m1.62 7.9h-3.23l1.61-3.87z" fill="#ab47bc"/></symbol><symbol viewBox="0 0 24 24" id="angular-guard" xmlns="http://www.w3.org/2000/svg"><path d="M12.102 2.625l8.84 3.15-1.34 11.7-7.5 4.15-7.5-4.15-1.34-11.7 8.84-3.15m0 2.1l-5.53 12.4h2.06l1.11-2.78h4.7l1.11 2.78h2.05l-5.5-12.4m1.62 7.9h-3.23l1.61-3.87z" fill="#43a047"/></symbol><symbol viewBox="0 0 24 24" id="angular-pipe" xmlns="http://www.w3.org/2000/svg"><path d="M12.102 2.625l8.84 3.15-1.34 11.7-7.5 4.15-7.5-4.15-1.34-11.7 8.84-3.15m0 2.1l-5.53 12.4h2.06l1.11-2.78h4.7l1.11 2.78h2.05l-5.5-12.4m1.62 7.9h-3.23l1.61-3.87z" fill="#00897b"/></symbol><symbol viewBox="0 0 24 24" id="angular-resolver" xmlns="http://www.w3.org/2000/svg"><path d="M12.102 2.625l8.84 3.15-1.34 11.7-7.5 4.15-7.5-4.15-1.34-11.7 8.84-3.15m0 2.1l-5.53 12.4h2.06l1.11-2.78h4.7l1.11 2.78h2.05l-5.5-12.4m1.62 7.9h-3.23l1.61-3.87z" fill="#43a047"/></symbol><symbol viewBox="0 0 24 24" id="angular-routing" xmlns="http://www.w3.org/2000/svg"><path d="M11 10H5L3 8l2-2h6V3l1-1 1 1v1h6l2 2-2 2h-6v2h6l2 2-2 2h-6v6a2 2 0 0 1 2 2H9a2 2 0 0 1 2-2V10z" fill="#43a047"/></symbol><symbol viewBox="0 0 24 24" id="angular-service" xmlns="http://www.w3.org/2000/svg"><path d="M12.102 2.625l8.84 3.15-1.34 11.7-7.5 4.15-7.5-4.15-1.34-11.7 8.84-3.15m0 2.1l-5.53 12.4h2.06l1.11-2.78h4.7l1.11 2.78h2.05l-5.5-12.4m1.62 7.9h-3.23l1.61-3.87z" fill="#ffca28"/></symbol><symbol viewBox="0 0 100 100" id="apiblueprint" xmlns="http://www.w3.org/2000/svg"><title>api-blueprint</title><path d="M50.133 7.521A16.998 16.998 0 0 0 33.135 24.52a16.998 16.998 0 0 0 4.945 11.974L24.861 57.398a16.998 16.998 0 0 0-3.175-.308A16.998 16.998 0 0 0 4.688 74.088a16.998 16.998 0 0 0 16.998 16.998 16.998 16.998 0 0 0 16.998-16.998 16.998 16.998 0 0 0-7.063-13.773l12.576-19.89a16.998 16.998 0 0 0 5.936 1.093 16.998 16.998 0 0 0 6.154-1.155l12.537 19.83a16.998 16.998 0 0 0-7.244 13.895 16.998 16.998 0 0 0 16.998 17 16.998 16.998 0 0 0 16.998-17A16.998 16.998 0 0 0 78.578 57.09a16.998 16.998 0 0 0-2.95.262L62.337 36.327A16.998 16.998 0 0 0 67.13 24.52 16.998 16.998 0 0 0 50.132 7.522z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="applescript" xmlns="http://www.w3.org/2000/svg"><path d="M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z" fill="#78909c"/></symbol><symbol viewBox="0 0 24 24" id="appveyor" xmlns="http://www.w3.org/2000/svg"><path d="M12 2c-.084 0-.165.008-.248.01a10 10 0 0 0-.266.01 9.952 9.952 0 0 0-.754.066 10 10 0 0 0-.148.018 9.855 9.855 0 0 0-.93.177 10 10 0 0 0-.07.02c-.196.049-.392.1-.584.16v.012a10 10 0 0 0-2 .875V3.34c-.02.012-.038.027-.059.039a10 10 0 0 0-.953.635c-.09.067-.172.142-.26.213a10 10 0 0 0-.628.546c-.109.104-.211.211-.315.319a10 10 0 0 0-.476.539c-.1.12-.201.237-.295.361a10 10 0 0 0-.52.766c-.088.143-.17.288-.252.435a10 10 0 0 0-.363.723c-.072.161-.136.327-.2.492a10 10 0 0 0-.269.778c-.02.067-.044.131-.062.199a10 10 0 0 0-.008.027c-.098.364-.166.728-.22 1.09-.012.077-.024.153-.034.23a9.85 9.85 0 0 0-.08 1.182c0 .03-.006.057-.006.086a10 10 0 0 0 .008.148c.001.094-.002.188.002.282l.011.004a10 10 0 0 0 .333 2.158l-.012-.004c.012.047.033.091.047.139a10 10 0 0 0 .322.955c.02.052.037.106.059.158a10 10 0 0 0 .503 1.035c.065.116.14.226.21.34a10 10 0 0 0 .423.64c.092.128.187.252.285.375a10 10 0 0 0 .448.52c.112.123.222.248.341.365a10 10 0 0 0 .803.719 10 10 0 0 0 .01.006c.099.078.207.146.309.22a10 10 0 0 0 .648.442c.138.085.28.163.424.242a10 10 0 0 0 .715.358c.114.051.226.106.343.154a10 10 0 0 0 1.133.389c.016.004.031.01.047.015a10 10 0 0 0 .461.098 10 10 0 0 0 .482.103 10 10 0 0 0 .418.051 10 10 0 0 0 .575.065 10 10 0 0 0 .144.005A10 10 0 0 0 12 22a10 10 0 0 0 .197-.01 10 10 0 0 0 .496-.025 10 10 0 0 0 .49-.043 10 10 0 0 0 .489-.074 10 10 0 0 0 .51-.098 10 10 0 0 0 .47-.12 10 10 0 0 0 .477-.14 10 10 0 0 0 .47-.172 10 10 0 0 0 .481-.197 10 10 0 0 0 .414-.201 10 10 0 0 0 .475-.252 10 10 0 0 0 .39-.238 10 10 0 0 0 .452-.301 10 10 0 0 0 .38-.291 10 10 0 0 0 .385-.315 10 10 0 0 0 .375-.347 10 10 0 0 0 .36-.363 10 10 0 0 0 .293-.334 10 10 0 0 0 .353-.434 10 10 0 0 0 .28-.393 10 10 0 0 0 .263-.4 10 10 0 0 0 .264-.461 10 10 0 0 0 .228-.436 10 10 0 0 0 .195-.437 10 10 0 0 0 .196-.48 10 10 0 0 0 .228-.69 10 10 0 0 0 .028-.094 10 10 0 0 0 .021-.066 10 10 0 0 0 .098-.461 10 10 0 0 0 .103-.482 10 10 0 0 0 .051-.418 10 10 0 0 0 .065-.575 10 10 0 0 0 .005-.144A10 10 0 0 0 22 12a10 10 0 0 0-.01-.197 10 10 0 0 0-.025-.496 10 10 0 0 0-.043-.49 10 10 0 0 0-.074-.489 10 10 0 0 0-.098-.51 10 10 0 0 0-.12-.47 10 10 0 0 0-.14-.477 10 10 0 0 0-.172-.47 10 10 0 0 0-.197-.481 10 10 0 0 0-.201-.414 10 10 0 0 0-.252-.475 10 10 0 0 0-.238-.39 10 10 0 0 0-.301-.452 10 10 0 0 0-.291-.38 10 10 0 0 0-.315-.385 10 10 0 0 0-.347-.375 10 10 0 0 0-.363-.36 10 10 0 0 0-.334-.293 10 10 0 0 0-.434-.353 10 10 0 0 0-.393-.28 10 10 0 0 0-.4-.263 10 10 0 0 0-.461-.264 10 10 0 0 0-.436-.228 10 10 0 0 0-.437-.196 10 10 0 0 0-.48-.195 10 10 0 0 0-.69-.228 10 10 0 0 0-.094-.028 10 10 0 0 0-.066-.021 10 10 0 0 0-.461-.098 10 10 0 0 0-.482-.103 10 10 0 0 0-.418-.051 10 10 0 0 0-.575-.065 10 10 0 0 0-.144-.005A10 10 0 0 0 12 2zm-.016 5.002a5 5 0 0 1 .262.01 5 5 0 0 1 .227.011 5 5 0 0 1 .341.05 5 5 0 0 1 .135.019 5 5 0 0 1 .014.004 5 5 0 0 1 .115.025 5 5 0 0 1 .303.076 5 5 0 0 1 .265.086 5 5 0 0 1 .2.074 5 5 0 0 1 .242.106 5 5 0 0 1 .228.11 5 5 0 0 1 .196.109 5 5 0 0 1 .244.15 5 5 0 0 1 .17.12 5 5 0 0 1 .224.171 5 5 0 0 1 .186.16 5 5 0 0 1 .176.164 5 5 0 0 1 .172.18 5 5 0 0 1 .177.203 5 5 0 0 1 .133.172 5 5 0 0 1 .16.223 5 5 0 0 1 .133.214 5 5 0 0 1 .12.21 5 5 0 0 1 .107.216 5 5 0 0 1 .109.24 5 5 0 0 1 .084.223 5 5 0 0 1 .08.242 5 5 0 0 1 .07.264 5 5 0 0 1 .047.207 5 5 0 0 1 .045.277 5 5 0 0 1 .028.227 5 5 0 0 1 .02.351 5 5 0 0 1 .003.079 5 5 0 0 1-.012.271 5 5 0 0 1-.011.227 5 5 0 0 1-.05.341 5 5 0 0 1-.019.135 5 5 0 0 1-.004.014 5 5 0 0 1-.025.115 5 5 0 0 1-.076.303 5 5 0 0 1-.086.265 5 5 0 0 1-.074.2 5 5 0 0 1-.106.242 5 5 0 0 1-.11.228 5 5 0 0 1-.109.196 5 5 0 0 1-.15.244 5 5 0 0 1-.12.17 5 5 0 0 1-.171.224 5 5 0 0 1-.16.186 5 5 0 0 1-.164.176 5 5 0 0 1-.18.172 5 5 0 0 1-.203.177l-.002.002c-.018.019-.028.035-.047.053l-3.959 5.09-3.05-.979a141.684 141.684 0 0 0 3.177-3.084 5 5 0 0 1-.103-.015 5 5 0 0 1-.149-.024 5 5 0 0 1-.115-.025 5 5 0 0 1-3.57-3.04 5.072 5.072 0 0 1-.206-.661 5 5 0 0 1-.033-.147c-.025-.118-.036-.24-.054-.36-.987.993-1.964 1.993-2.954 3.05l-.98-3.053 5.092-3.957c.043-.044.082-.07.125-.11a5 5 0 0 1 .71-.634c.18-.13.367-.25.561-.356a5 5 0 0 1 .16-.08 4.94 4.94 0 0 1 .516-.222 5 5 0 0 1 .147-.057c.211-.07.43-.123.654-.164a5 5 0 0 1 .172-.027c.236-.035.476-.058.722-.059zM12 9a3 3 0 0 0-.053.002 3 3 0 0 0-.166.01 3 3 0 0 0-.133.011 3 3 0 0 0-.17.026 3 3 0 0 0-.113.021 3 3 0 0 0-.19.05 3 3 0 0 0-.103.03 3 3 0 0 0-.16.057 3 3 0 0 0-.129.053 3 3 0 0 0-.146.072 3 3 0 0 0-.12.063 3 3 0 0 0-.132.082 3 3 0 0 0-.123.08 3 3 0 0 0-.116.088 3 3 0 0 0-.126.105 3 3 0 0 0-.1.094 3 3 0 0 0-.111.111 3 3 0 0 0-.096.107 3 3 0 0 0-.094.116 3 3 0 0 0-.098.136 3 3 0 0 0-.072.11 3 3 0 0 0-.076.133 3 3 0 0 0-.07.132 3 3 0 0 0-.063.14 3 3 0 0 0-.054.14 3 3 0 0 0-.077.228 3 3 0 0 0-.007.026 3 3 0 0 0-.03.138 3 3 0 0 0-.031.149 3 3 0 0 0-.014.11 3 3 0 0 0-.02.183 3 3 0 0 0-.001.052A3 3 0 0 0 9 12a3 3 0 0 0 .002.053 3 3 0 0 0 .01.166 3 3 0 0 0 .011.133 3 3 0 0 0 .026.17 3 3 0 0 0 .021.113 3 3 0 0 0 .05.19 3 3 0 0 0 .03.103 3 3 0 0 0 .057.16 3 3 0 0 0 .053.129 3 3 0 0 0 .072.146 3 3 0 0 0 .063.12 3 3 0 0 0 .082.132 3 3 0 0 0 .08.123 3 3 0 0 0 .088.116 3 3 0 0 0 .105.126 3 3 0 0 0 .094.1 3 3 0 0 0 .111.111 3 3 0 0 0 .107.096 3 3 0 0 0 .116.094 3 3 0 0 0 .136.098 3 3 0 0 0 .11.072 3 3 0 0 0 .133.076 3 3 0 0 0 .132.07 3 3 0 0 0 .135.06 3 3 0 0 0 .153.061 3 3 0 0 0 .216.07 3 3 0 0 0 .004.003 3 3 0 0 0 .026.007 3 3 0 0 0 .138.03 3 3 0 0 0 .149.031 3 3 0 0 0 .11.014 3 3 0 0 0 .183.02 3 3 0 0 0 .011.001 3 3 0 0 0 .041 0A3 3 0 0 0 12 15a3 3 0 0 0 .053-.002 3 3 0 0 0 .166-.01 3 3 0 0 0 .133-.011 3 3 0 0 0 .17-.026 3 3 0 0 0 .113-.021 3 3 0 0 0 .19-.05 3 3 0 0 0 .103-.03 3 3 0 0 0 .16-.057 3 3 0 0 0 .129-.053 3 3 0 0 0 .146-.072 3 3 0 0 0 .12-.063 3 3 0 0 0 .132-.082 3 3 0 0 0 .123-.08 3 3 0 0 0 .116-.088 3 3 0 0 0 .126-.105 3 3 0 0 0 .1-.094 3 3 0 0 0 .111-.111 3 3 0 0 0 .096-.107 3 3 0 0 0 .094-.116 3 3 0 0 0 .098-.136 3 3 0 0 0 .072-.11 3 3 0 0 0 .076-.133 3 3 0 0 0 .07-.132 3 3 0 0 0 .06-.135 3 3 0 0 0 .061-.153 3 3 0 0 0 .07-.216 3 3 0 0 0 .003-.004 3 3 0 0 0 .007-.026 3 3 0 0 0 .03-.138 3 3 0 0 0 .031-.149 3 3 0 0 0 .002-.008 3 3 0 0 0 .012-.101 3 3 0 0 0 .02-.184 3 3 0 0 0 .001-.011 3 3 0 0 0 0-.041A3 3 0 0 0 15 12a3 3 0 0 0-.002-.053 3 3 0 0 0-.01-.166 3 3 0 0 0-.011-.133 3 3 0 0 0-.026-.17 3 3 0 0 0-.021-.113 3 3 0 0 0-.05-.19 3 3 0 0 0-.03-.103 3 3 0 0 0-.057-.16 3 3 0 0 0-.053-.129 3 3 0 0 0-.072-.146 3 3 0 0 0-.063-.12 3 3 0 0 0-.082-.132 3 3 0 0 0-.08-.123 3 3 0 0 0-.088-.116 3 3 0 0 0-.105-.126 3 3 0 0 0-.094-.1 3 3 0 0 0-.111-.111 3 3 0 0 0-.107-.096 3 3 0 0 0-.116-.094 3 3 0 0 0-.136-.098 3 3 0 0 0-.11-.072 3 3 0 0 0-.133-.076 3 3 0 0 0-.132-.07 3 3 0 0 0-.14-.063 3 3 0 0 0-.14-.054 3 3 0 0 0-.228-.077 3 3 0 0 0-.026-.007 3 3 0 0 0-.138-.03 3 3 0 0 0-.149-.031 3 3 0 0 0-.008-.002 3 3 0 0 0-.101-.012 3 3 0 0 0-.184-.02 3 3 0 0 0-.011-.001 3 3 0 0 0-.041 0A3 3 0 0 0 12 9z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 720 720" id="arduino" xmlns="http://www.w3.org/2000/svg"><defs><symbol id="ana" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg"><path fill="none" stroke-opacity="100%" stroke-width="60" stroke="#00979c" d="M174 30a10.5 10.1 0 0 0 0 280C364 320 344 30 544 30a10.5 10.1 0 0 1 0 280C354 320 374 30 174 30"/><path d="M528 205v-32.8h-32.5v-13.7H528V126h13.9v32.5h32.5v13.7h-32.5V205H528z" text-anchor="middle" fill="#00979c" stroke-width="20" stroke="#00979c" font-family="sans-serif" font-size="167"/><path fill="#00979c" stroke="#00979c" stroke-width="23.6" transform="matrix(1.56 0 0 .64 -366 .528)" d="M321 266v-17.4h53.3V266H321z"/></symbol></defs><title>Layer 1</title><use x="20.063" y="360.85" transform="matrix(.997 0 0 .997 -18.596 -159.19)" xlink:href="#ana"/></symbol><symbol viewBox="0 0 24 24" id="assembly" xmlns="http://www.w3.org/2000/svg"><path d="M1.746 1.566v20.905H5.13v-2.088H3.438V3.656h1.69v-2.09H1.747zm17.219 0v2.09h1.693v16.727h-1.693v2.09h3.383V1.566h-3.383zM15.196 3.988c-.5 0-.93.076-1.29.225-.359.15-.652.372-.877.671-.226.302-.39.673-.494 1.108a6.715 6.715 0 0 0-.155 1.54c0 .573.049 1.083.15 1.528.1.442.264.811.49 1.11.222.298.512.524.872.676.36.153.795.23 1.304.23.518 0 .954-.075 1.308-.224.353-.153.643-.376.869-.671.219-.29.38-.661.484-1.112.104-.454.156-.967.156-1.54 0-.573-.052-1.079-.152-1.515a2.92 2.92 0 0 0-.485-1.106 2.09 2.09 0 0 0-.868-.686c-.354-.155-.79-.234-1.312-.234zm-6.814.12a.941.941 0 0 1-.138.458.849.849 0 0 1-.356.296A1.71 1.71 0 0 1 7.385 5a5.244 5.244 0 0 1-.631.037v1.11H8.19v3.6H6.754v1.188h4.545V9.745H9.894V4.11H8.382zm6.814 1.138c.375 0 .643.176.805.527.161.348.241.933.241 1.756 0 .814-.082 1.399-.247 1.756-.164.356-.43.534-.799.534-.369 0-.636-.178-.8-.534-.165-.357-.248-.941-.248-1.749 0-.829.082-1.415.243-1.763.162-.35.43-.527.805-.527zm-6.33 7.64c-.5 0-.93.073-1.29.223-.359.15-.651.374-.877.673-.225.302-.39.67-.494 1.106a6.715 6.715 0 0 0-.155 1.54c0 .573.05 1.082.15 1.527.1.442.264.814.49 1.112.222.3.514.525.874.677.36.152.793.229 1.302.229.519 0 .954-.076 1.308-.225.354-.153.643-.376.869-.672.22-.29.38-.66.484-1.111.104-.455.156-.967.156-1.54 0-.573-.05-1.079-.15-1.515a2.923 2.923 0 0 0-.487-1.106 2.084 2.084 0 0 0-.867-.686c-.353-.156-.791-.232-1.313-.232zm5.846.119a.941.941 0 0 1-.138.457.85.85 0 0 1-.356.296 1.71 1.71 0 0 1-.503.137 5.245 5.245 0 0 1-.631.037v1.112h1.435v3.597h-1.435v1.189h4.545v-1.189h-1.405v-5.636h-1.512zm-5.846 1.137c.375 0 .643.176.805.527.162.347.241.933.241 1.756 0 .813-.08 1.399-.245 1.755-.164.357-.432.534-.8.534-.37 0-.637-.177-.802-.534-.164-.356-.245-.939-.245-1.746 0-.83.08-1.418.242-1.765.161-.35.43-.527.804-.527z" fill="#ff6e40"/></symbol><symbol viewBox="0 0 24 24" id="aurelia" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="api" x1="-31.824" x2="19.682" y1="-11.741" y2="35.548" gradientTransform="scale(.95818 1.0436)" gradientUnits="userSpaceOnUse" xlink:href="#apa"/><linearGradient id="apa" x1="-3.881" x2="2.377" y1="-1.442" y2="4.304"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="apj" x1="12.022" x2="-15.716" y1="13.922" y2="-23.952" gradientTransform="scale(.96226 1.0392)" gradientUnits="userSpaceOnUse" xlink:href="#apb"/><linearGradient id="apb" x1=".729" x2="-.971" y1=".844" y2="-1.477"><stop stop-color="#6E4D9B" offset="0"/><stop stop-color="#77327A" offset=".14"/><stop stop-color="#B31777" offset=".29"/><stop stop-color="#CD0F7E" offset=".84"/><stop stop-color="#ED2C89" offset="1"/></linearGradient><linearGradient id="apk" x1="-23.39" x2="23.931" y1="-57.289" y2="8.573" gradientTransform="scale(1.0429 .95884)" gradientUnits="userSpaceOnUse" xlink:href="#apc"/><linearGradient id="apc" x1="-2.839" x2="2.875" y1="-6.936" y2="1.017"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="apl" x1="-53.331" x2="6.771" y1="-30.517" y2="18.785" gradientTransform="scale(.99898 1.001)" gradientUnits="userSpaceOnUse" xlink:href="#apd"/><linearGradient id="apd" x1="-8.212" x2="1.02" y1="-4.691" y2="2.882"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="apm" x1="-14.029" x2="41.998" y1="-23.111" y2="26.259" gradientTransform="scale(1.0003 .99965)" gradientUnits="userSpaceOnUse" xlink:href="#ape"/><linearGradient id="ape" x1="-1.404" x2="4.19" y1="-2.309" y2="2.62"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="apn" x1="31.177" x2="3.37" y1="41.442" y2="3.402" gradientTransform="scale(.96254 1.0389)" gradientUnits="userSpaceOnUse" xlink:href="#apf"/><linearGradient id="apf" x1="1.911" x2=".204" y1="2.539" y2=".204"><stop stop-color="#6E4D9B" offset="0"/><stop stop-color="#77327A" offset=".14"/><stop stop-color="#B31777" offset=".29"/><stop stop-color="#CD0F7E" offset=".84"/><stop stop-color="#ED2C89" offset="1"/></linearGradient><linearGradient id="apo" x1="-31.905" x2="19.599" y1="-14.258" y2="42.767" gradientTransform="scale(.95823 1.0436)" gradientUnits="userSpaceOnUse" xlink:href="#apg"/><linearGradient id="apg" x1="-3.881" x2="2.377" y1="-1.738" y2="5.19"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="app" x1="4.301" x2="34.534" y1="34.41" y2="4.514" gradientTransform="scale(1.002 .99796)" gradientUnits="userSpaceOnUse" xlink:href="#aph"/><linearGradient id="aph" x1=".112" x2=".901" y1=".897" y2=".116"><stop stop-color="#6E4D9B" offset="0"/><stop stop-color="#77327A" offset=".14"/><stop stop-color="#B31777" offset=".53"/><stop stop-color="#CD0F7E" offset=".79"/><stop stop-color="#ED2C89" offset="1"/></linearGradient></defs><g transform="rotate(11.282 -1.694 21.569) scale(.47102)" clip-rule="evenodd" fill="none" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path d="M8.002 6.127L4.117 8.719.116 2.723 4 .13z" transform="rotate(-11.284 17.839 -78.732)" fill="url(#api)"/><path d="M9.179 1.887l6.637 9.946-7.906 5.276-6.637-9.946L.115 5.43 8.02.153z" transform="rotate(-11.284 129.49 -99.884)" fill="url(#apj)"/><path d="M7.3 1.88l1.462 2.189-6.018 4.015L.124 4.16l1.315-.877L6.143.144z" transform="rotate(-11.284 167.2 -62.32)" fill="url(#apk)"/><path d="M2.328 1.146L4.016.02l2.619 3.925L2.75 6.537 1.29 4.347l2.197-1.466zm-1.04 3.201L.132 2.612l2.197-1.466 1.158 1.735z" transform="rotate(-11.284 104.37 -149.22)" fill="url(#apl)"/><path d="M5.346 9.155l-1.315.877L.03 4.035 6.047.019l2.805 4.204L4.15 7.36l4.703-3.138 1.197 1.793z" transform="rotate(-11.284 81.819 7.645)" fill="url(#apm)"/><path d="M14.533 9.934l1.197 1.793-7.907 5.276-1.196-1.793L.052 5.358 7.958.082z" transform="rotate(-11.284 17.141 -7.825)" fill="url(#apn)"/><path d="M6.235 7.177L4.038 8.643 2.84 6.849.036 2.646 3.92.053 7.923 6.05z" transform="rotate(-11.284 18.188 -79.174)" fill="url(#apo)"/><path d="M18.955 35.925L17.48 34.45l3.998-3.998 1.475 1.475z" fill="#714896"/><path d="M33.33 21.55l-1.475-1.474 1.867-1.868 1.475 1.475z" fill="#6f4795"/><path d="M7.12 24.09l-1.525-1.525 3.998-3.998 1.525 1.525z" fill="#88519f"/><path d="M21.495 9.714L19.97 8.19l1.868-1.868 1.524 1.525z" fill="#85509e"/><path d="M31.418 23.462l-6.72 6.72-1.475-1.474 6.72-6.721z" fill="#8d166a"/><path d="M18.058 10.101l1.525 1.525-6.721 6.72-1.525-1.524z" fill="#a70d6f"/><path d="M2.375 11.769l1.9 1.9-1.9 1.901-1.901-1.9z" fill="#9e61ad"/><path d="M15.523 36.482l1.9 1.9-1.9 1.901-1.9-1.9z" fill="#8053a3"/><path d="M8.372 38.294L.017 29.876 29.749.08l8.636 8.201z" transform="translate(1.823 1.548)" fill="url(#app)"/></g></symbol><symbol viewBox="0 0 24 24" id="autohotkey" xmlns="http://www.w3.org/2000/svg"><path d="M5 3c-1.11 0-2 .89-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5zm3.668 3.447a.9.9 0 0 1 .652.256.84.84 0 0 1 .262.625c0 .34-.014.852-.041 1.537-.022.68-.033 1.19-.033 1.53 0 .111-.016.326-.047.644a6.149 6.149 0 0 0-.033.68l2.578-.485c1.007-.179 1.874-.281 2.603-.308.018-.3.048-1.105.088-2.416.01-.345.115-.742.317-1.19.25-.55.533-.826.851-.826.237 0 .448.08.631.236.197.17.295.382.295.637a.775.775 0 0 1-.025.201c-.09.327-.135.612-.135.854 0 .125-.014.32-.041.584-.023.26-.033.453-.033.578 0 .425-.022 1.056-.067 1.893a38.963 38.963 0 0 0-.068 1.892c0 .327.025.816.074 1.465.05.649.074 1.136.074 1.463a.84.84 0 0 1-.261.625.893.893 0 0 1-.65.254 1 1 0 0 1-.686-.254.777.777 0 0 1-.29-.611c0-.327-.015-.818-.046-1.471a39.552 39.552 0 0 1-.041-1.47c0-.256.004-.482.013-.679-.702.032-1.57.142-2.603.33-.86.157-1.719.316-2.578.477-.01.304-.042.812-.096 1.523a22.354 22.354 0 0 0-.066 1.538.84.84 0 0 1-.262.625.893.893 0 0 1-.65.253.898.898 0 0 1-.653-.253.84.84 0 0 1-.262-.625c0-.452.038-1.128.114-2.028.08-.9.12-1.575.12-2.027 0-.573.015-1.436.042-2.586.027-1.155.04-2.017.04-2.59a.84.84 0 0 1 .263-.625.895.895 0 0 1 .65-.256z" fill="#4caf50"/></symbol><symbol viewBox="0 0 24 24" id="autoit" xmlns="http://www.w3.org/2000/svg"><defs id="ardefs8"><style id="arstyle4482">.cls-1{fill:#5d83ac}.cls-2{fill:#f0f0f0;fill-rule:evenodd}</style><style id="arstyle4510">.cls-1{fill:#5d83ac}.cls-2{fill:#f0f0f0;fill-rule:evenodd}</style></defs><g id="arg4522" transform="translate(-59.538 -26.404) scale(.0555)"><path d="M12.8 2.133A10.666 10.666 0 0 0 2.136 12.799 10.666 10.666 0 0 0 12.8 23.465a10.666 10.666 0 0 0 10.668-10.666A10.666 10.666 0 0 0 12.8 2.133zm.15 4.713c.456 0 .836.105 1.142.314.306.21.565.469.78.78l6.089 8.812H9.627l1.82-2.506h3.36c.315 0 .589.01.822.03a11.93 11.93 0 0 1-.473-.663 39.13 39.13 0 0 0-.517-.75l-1.748-2.578-4.577 6.467H4.746l6.25-8.813c.204-.281.46-.534.772-.757.31-.224.705-.336 1.181-.336z" transform="matrix(16.89188 0 0 16.89188 1072.761 475.745)" id="arcircle4514" fill="#1976d2" stroke-width=".026"/></g></symbol><symbol viewBox="0 0 213.33333 213.33333" id="babel" xmlns="http://www.w3.org/2000/svg"><path d="M50.22 199.659c-.875-.406-1.261-1.6-.857-2.652.404-1.053.12-1.914-.63-1.914s-1.615.748-1.92 1.663c-.328.983-1.27.302-2.304-1.667-.962-1.831-3.718-5.533-6.126-8.226-9.418-10.535-7.71-27.444 5.432-53.77 12.459-24.96 23.117-39.033 45.966-60.696 30.229-28.66 52.679-46.223 70.587-55.22 10.98-5.518 13.025-5.059 2.778.624-11.004 6.102-11.378 6.359-10.512 7.226.33.33 7.306-2.67 15.504-6.667 15.87-7.737 16.34-7.912 16.34-6.082 0 .652-4.95 3.738-11 6.858-13.062 6.736-12.722 6.48-10.472 7.872 1.117.69 5.428-.582 11.54-3.406 5.367-2.48 10.397-4.508 11.179-4.508 2.755 0-3.928 5.302-11.541 9.157-20.437 10.35-68.937 46.043-68.07 50.097.166.777-5.792 7.639-13.241 15.248-15.257 15.587-26.14 30.002-33.748 44.706-6.379 12.326-7.457 17.734-5.385 26.996 3.482 15.56 11.592 18.366 31.482 10.895 28.228-10.603 45.758-28.704 47.022-48.556.602-9.442-1.317-13.479-8.52-17.93-4.01-2.48-5.268-2.621-12.065-1.365-4.173.771-10.153 2.906-13.289 4.744s-6.455 3.34-7.377 3.34c-.922 0-3.216 1.336-5.096 2.968-1.88 1.633.48-1.13 5.247-6.14 6.82-7.167 7.956-8.9 5.333-8.132-5.208 1.525-10.194 4.33-15.649 8.803-2.76 2.264-.923.175 4.08-4.641 11.565-11.131 21.183-15.97 33.088-16.641 17.097-.966 27.254 5.805 31.964 21.31 2.435 8.017 2.609 10.24 1.353 17.37-1.65 9.361-7.034 21.553-15.593 35.307-4.398 7.067-8.434 11.427-15.588 16.844-9.166 6.94-15.654 11.02-15.654 9.845 0-.295 2.455-2.161 5.455-4.147 8.818-5.835 5.075-5.377-8.326 1.02-6.854 3.27-15.199 6.593-18.542 7.38-7.106 1.675-30.527 3.164-32.846 2.089zm-8.408-19.899c0-1.1-.6-2-1.333-2-.734 0-1.334.9-1.334 2s.6 2 1.333 2c.734 0 1.334-.9 1.334-2zm89.255-8.204c1.53-1.945 2.473-3.845 2.097-4.222-.377-.377-.836-.435-1.02-.13-.182.306-1.787 2.206-3.565 4.223-1.778 2.016-2.571 3.666-1.763 3.666s2.72-1.591 4.25-3.536zm-77.644-1.745c-.82-2.172-1.74-3.7-2.045-3.396-.951.952 1.088 7.345 2.343 7.345.656 0 .522-1.777-.298-3.95zm82.303-27.915c-.837-.837-3.217 2.55-3.184 4.53.012.734.896.178 1.965-1.235 1.07-1.413 1.618-2.896 1.219-3.295zm-66.238-36.904c-1.312-1.312-3.676.702-3.676 3.133 0 2.035.175 2.031 2.254-.047 1.24-1.24 1.88-2.628 1.422-3.086zm39.657.768c4.403-2.196 6.8-3.986 5.333-3.982-2.838.01-16.667 6.028-16.667 7.254 0 1.6 3.717.527 11.333-3.272zm16.667-5.333c0-.733-.9-1.333-2-1.333s-2 .6-2 1.333.9 1.333 2 1.333 2-.6 2-1.333zm-3.334-3.923l5.334-1.104-7.334-.133c-4.033-.073-8.233.45-9.333 1.16-2.539 1.64 3.572 1.682 11.333.077zm35.738-63.976c2.788-1.69 4.765-3.376 4.393-3.748-.947-.947-11.942 5.654-14.237 8.548-1.792 2.258-1.714 2.276 1.44.329a1452.76 1452.76 0 0 1 8.403-5.13z" fill="#ffca28" stroke-width="1.333"/></symbol><symbol viewBox="0 0 400 400" fill-opacity=".05" id="bithound" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(.88 0 0 .88 24.121 2.895)" fill="#e53935" fill-opacity="1"><path d="M370.5 207c-1.5-14.8-4.8-29.9-9.5-44-13.5-40.3-38.6-81.6-70.3-110.1-1.4-1.2-6.7-4.4-8.7-3.3-5.2 2.9 4.6 22.8 5.8 26.4 7.4 22 12.1 45.3 6.8 68.3-7.1 30.4-30.4 51.7-61.5 54.3-17.1 1.4-34.3-.5-51.4 1.5-25.6 3-51.7 11.8-68 32.8-1.9 2.4-3.6 5.1-5.2 7.9h-.4c-6.3.7-12.6-2-15.7-3.7-.8-.5-1.6-.9-2.2-1.2-19-10.5-33-34-41.6-53.4-3.9-9-7.2-18.4-9.3-27.9-1-4.3-1.1-8.8-1.3-13.2-.1-2.7.3-6.5-1.2-8.9-3.3-5.2-7.5-.2-8.2 4-1.1 6.9-2.1 13.7-1.8 20.7.5 11.8 3.8 23.5 8 34.5 6.2 16.2 14.9 31.1 26.2 44.4 4.7 5.5 9.7 10.6 15.1 15.3 4.8 4.3 10.9 7.7 14.5 13.2 4.2 6.3 4.9 14.1 4.5 21.4-1 19.3-1.6 37.4 3.9 56.2 4.8 16.7 10.8 33.8 20.8 48.1 5 7.1 11.2 14.6 18 19.9 4.6 3.6 13.3 4 8.3-9.2-11.1-29.3-12.1-59.7 5.2-87.1 14.5-22.8 40.1-43.1 69-39.5 42.5 5.3 72.1 44.3 70 86-.6 11.7-1 21.7-4.7 32.7-1.5 4.4-2.6 10-1.5 14.6 1.8 7.8 10.5 4.9 14.3-.2 10.3-14 21.1-27.6 30.8-42 31.6-47.2 47-101.8 41.3-158.5z"/><path d="M132.4 92.1c.7 2.3 1.4 4.8 1.9 7.5.1 1.1.4 2.3 1 3.4 2.6 6.8 8.9 10.5 14.8 14 3.6 2.2 10.1 4.3 14.1 5.9 5.2 2.1 16.4-.6 21.7-1 12.2-1 23.5-5.3 34.7 1.2-57.4 67.3-3.2 82.3 38.8 49.9 48-37 2.8-124.3 2.8-124.3s-1-6.8-19.2-10.8c-1.7-.9-3.4-1.7-5.1-2.4-18-8.3-34.2 5.3-47.2 16.4-3.8 3.2-7.5 6.4-11.5 9.4-5.4 4-11.2 7.3-17.3 10.2-6.4 3-14 6.4-21.1 6.7-1 0-2.9.2-4.9.6-3.1.3-4.7 1.1-5.4 2.5-1.2 1-2 2.4-1.8 4.2.2 2.5 1.4 4.6 2.7 6.2.4.1.7.3 1 .4z"/></g></symbol><symbol viewBox="0 0 400.00001 399.99999" id="bower" xmlns="http://www.w3.org/2000/svg"><g transform="translate(12.061 33.203) scale(.81733)"><path d="M447.61 200.08c-23.139-22.234-138.85-36.114-175.36-40.154a107.137 107.137 0 0 0 4.517-12.944 146.107 146.107 0 0 1 15.905-5.901c.677 1.997 3.865 9.648 5.682 13.279 73.415 2.025 77.184-54.557 80.17-70.058 2.92-15.157 2.771-29.802 27.953-56.575-37.516-10.933-91.467 16.945-109.54 58.437-6.79-2.545-13.597-4.424-20.328-5.586-4.824-19.46-29.944-73.672-95.863-73.672-83.46 0-174.43 68.853-174.43 185.41 0 97.976 66.891 183.84 104.68 183.84 16.505 0 30.703-12.36 34.036-23.44 2.795 7.597 11.368 31.213 14.184 37.225 4.162 8.89 23.41 16.583 31.833 7.357 10.83 6.017 30.703 9.641 41.534-6.405 20.86 4.412 39.3-8.026 39.702-22.868 10.235-.546 15.256-14.918 13.021-26.363-1.647-8.426-19.248-38.66-26.113-49.098 13.59 11.054 48.013 14.183 52.194.007 21.911 17.198 56.057 8.171 58.765-5.815 26.624 6.917 57.16-8.276 52.146-26.676 42.771-2.958 37.296-48.464 25.296-59.996z" fill="#543729" stroke-width=".973"/><path d="M328.514 103.025c9.212-18.277 20.788-38.234 35.409-50.58-16.093 6.485-31.981 25.873-41.375 46.595a144.914 144.914 0 0 0-14.552-8.132c13.105-27.972 43.555-51.332 77.112-53.157-22.477 20.385-14.498 62.754-32.979 85.183-5.288-5.311-17.43-15.562-23.615-19.909zm-14.53 29.762c.01-.7.272-6.094.763-8.557-1.288-.304-9.3-1.87-13.476-1.772-.304 5.245 2.204 14.17 4.684 19.541 17.075-.358 29.408-5.471 36.667-10.172-6.18-2.88-16.726-5.442-24.745-6.974-.894 1.851-3.097 6.568-3.892 7.934z" fill="#00acee"/><g stroke-width=".973"><path d="M250.54 277.39c.004.024.015.057.018.082-2.165-4.657-4.463-10.314-7.208-17.708 10.688 15.557 44.184 7.533 42.427-6.407 16.395 12.336 50.143-2.055 42.471-19.353 16.423 7.653 35.168-7.745 30.964-14.455 28 5.4 54.832 10.783 63.256 12.938-5.595 9.123-18.339 15.566-37.549 11.089 10.38 14.14-9.773 31.105-37.844 21.76 6.18 13.883-18.814 26.38-47.22 11.91.361 13.889-35.24 15.488-49.315.143zm55.543-70.194c32.497 2.495 86.238 7.34 119.51 11.997-2.102-10.828-7.844-13.921-25.905-18.772-19.425 2.072-68.706 6.913-93.604 6.776z" fill="#2baf2b"/><path d="M285.78 253.36c16.395 12.336 50.143-2.055 42.471-19.353 16.423 7.653 35.168-7.745 30.964-14.455-33.103-6.383-67.84-12.788-75.719-13.908 4.78.254 12.702.797 22.59 1.556 24.899.137 74.18-4.704 93.604-6.775-31.452-7.975-95.666-19.613-140.01-22.48-2.055 3.003-5.833 8.097-12.413 13.51-19.403 41.053-54.557 68.34-93.454 68.34-11.335 0-24.018-1.912-38.233-6.456-8.865 9.497-46.661 16.694-77.329 1.641 24.326 56.961 80.74 94.984 143.19 94.984 52.591 0 75.912-53.704 70.808-67.914-1.238-3.45-6.145-14.889-8.891-22.283 10.689 15.556 44.185 7.532 42.429-6.408z" fill="#ffcc2f"/><path d="M253.91 145.27c4.644-2.526 20.69-12.253 35.981-15.908a67.843 67.843 0 0 1-.536-5.12c-10.032 2.403-28.945 10.51-39.784-.661 22.866 6.9 34.283-6.149 51.09-6.149 10.014 0 24.305 2.798 35.57 7.22-9.061-8.37-38.772-33.63-75.558-33.717-8.213 9.957-17.09 31.526-6.764 54.334z" fill="#cecece"/><path d="M115.58 253.33c14.215 4.544 26.898 6.457 38.233 6.457 38.896 0 74.05-27.29 93.454-68.341-14.351 11.978-39.291 22.228-78.241 22.228 34.694-7.866 64.56-25.156 79.753-50.427-10.68-16.998-22.263-54.603 7.07-84.33-4.512-14.497-26.475-52.766-75.095-52.766-84.85 0-155.17 71.001-155.17 166.15 0 22.525 4.547 43.65 12.67 62.664 30.666 15.054 68.462 7.858 77.327-1.64z" fill="#ef5734"/><path d="M141.03 108.45c0 21.644 17.546 39.191 39.19 39.191s39.192-17.548 39.192-39.191c0-21.644-17.548-39.191-39.192-39.191-21.644 0-39.19 17.547-39.19 39.191z" fill="#ffcc2f"/><path d="M156.76 108.45c0 12.958 10.507 23.463 23.463 23.463 12.96 0 23.464-10.506 23.464-23.463 0-12.959-10.504-23.464-23.464-23.464-12.957 0-23.463 10.506-23.463 23.464z" fill="#543729"/><ellipse cx="180.22" cy="98.044" rx="13.673" ry="8.501" fill="#fff"/></g></g></symbol><symbol viewBox="0 0 140 140" id="browserlist" xmlns="http://www.w3.org/2000/svg"><title>Browserslist logo</title><path d="M70.314 10.066a59.828 59.828 0 0 0-59.828 59.828 59.828 59.828 0 0 0 59.828 59.828 59.828 59.828 0 0 0 59.828-59.828 59.828 59.828 0 0 0-59.828-59.828zm-4.836 8.785c.496 4.043 1.352 7.322 2.572 10.223 4.779-4.287 10.265-7.546 16.041-9.02-.981 3.938-1.357 7.295-1.261 10.43 6.026-2.314 12.349-3.404 18.3-2.706-3.182 2.413-5.482 4.717-7.128 7.015-2.201 12.074 6.858 20.43 14.779 24.551a5.128 5.128 0 0 1 5.183-3.888 5.128 5.128 0 0 1 3.7 8.435v.002c-.487 1.055-2.002 2.343-3.497 3.219-4.075 2.39-11.172 5.736-20.914 7.39.045 1.214.077 2.453.077 3.747 0 4.817-.485 8.291-1.385 10.699-3.3 13.313-12.648 26.76-24.695 31.95.357-4.083.197-7.485-.402-10.591-5.582 3.218-11.646 5.278-17.623 5.52h-.002c1.785-3.662 2.855-6.878 3.412-9.976-6.347.996-12.727.742-18.377-1.17 2.93-2.732 5.054-5.314 6.673-7.96-6.292-1.344-12.169-3.87-16.766-7.686 3.822-1.544 6.795-3.239 9.3-5.197-5.426-3.517-10.034-7.998-12.972-13.23 4.012-.07 7.321-.568 10.3-1.453-3.786-5.215-6.468-11.032-7.333-16.951 3.861 1.405 7.196 2.133 10.36 2.355-1.662-6.22-2.081-12.605-.768-18.436 3.03 2.634 5.824 4.48 8.63 5.815.678-6.406 2.576-12.52 5.893-17.496 1.926 3.622 3.914 6.391 6.111 8.672 2.93-5.754 6.9-10.798 11.791-14.262zm26.465 19.557c-2.395 5.514-1.665 11.297-.555 18.732a2.138 2.138 0 0 0 .28-4.178 3.419 3.419 0 1 1 .092 6.704c.574 3.882 1.157 8.18 1.421 13.125a67.143 67.143 0 0 0 3.25-.649c6.616-1.487 12.258-3.801 16.871-6.506.45-.264.884-.563 1.276-.867.366-.557.333-.957.035-1.285-4.831-1.245-10.891-4.53-15.258-8.795-4.764-4.653-7.428-10.164-7.412-16.281z" fill="#ffca28" stroke-width=".855"/></symbol><symbol viewBox="0 0 140 140" id="browserlist_light" xmlns="http://www.w3.org/2000/svg"><title>Browserslist logo</title><g transform="translate(10.823 10.1)" stroke-width=".855"><circle cx="59.492" cy="59.795" r="59.828" fill="#ffca28"/><path d="M54.656 8.752c-4.89 3.464-8.862 8.508-11.791 14.262-2.198-2.28-4.185-5.05-6.111-8.672-3.318 4.976-5.216 11.09-5.893 17.496-2.807-1.335-5.6-3.18-8.63-5.814-1.314 5.83-.895 12.216.767 18.436-3.164-.223-6.498-.95-10.36-2.356.865 5.92 3.548 11.737 7.333 16.951-2.978.885-6.287 1.383-10.3 1.453 2.939 5.233 7.547 9.714 12.972 13.23-2.505 1.959-5.478 3.654-9.299 5.198 4.596 3.815 10.474 6.341 16.766 7.685-1.62 2.647-3.743 5.228-6.674 7.96 5.65 1.912 12.03 2.166 18.377 1.17-.556 3.098-1.626 6.314-3.412 9.975h.002c5.977-.24 12.042-2.3 17.623-5.52.6 3.108.76 6.51.402 10.593 12.047-5.19 21.395-18.638 24.695-31.951.9-2.408 1.385-5.881 1.385-10.7 0-1.293-.031-2.531-.076-3.745 9.742-1.655 16.839-5.001 20.914-7.39 1.494-.877 3.01-2.165 3.496-3.22v-.002a5.128 5.128 0 0 0-3.7-8.435 5.128 5.128 0 0 0-5.183 3.889c-7.92-4.122-16.98-12.477-14.779-24.551 1.646-2.299 3.947-4.603 7.13-7.016-5.952-.698-12.276.392-18.302 2.707-.095-3.135.28-6.492 1.262-10.43-5.776 1.473-11.262 4.733-16.041 9.02-1.22-2.902-2.076-6.18-2.572-10.223zm26.465 19.557c-.015 6.117 2.648 11.628 7.412 16.281 4.366 4.265 10.426 7.55 15.258 8.795.298.328.331.728-.035 1.285-.392.304-.825.603-1.275.867-4.613 2.704-10.256 5.019-16.871 6.506-1.071.24-2.154.458-3.25.649-.265-4.945-.848-9.243-1.422-13.125a3.419 3.419 0 1 0-.092-6.703 2.138 2.138 0 0 1-.28 4.177c-1.11-7.435-1.84-13.218.555-18.732z" fill="#37474f"/></g></symbol><symbol viewBox="0 0 24 24" id="bucklescript" xmlns="http://www.w3.org/2000/svg"><path d="M3 3v18h18V3H3zm14.1 8.858a5.5 5.5 0 0 1 1.26.145c.417.093.778.213 1.082.357v1.723h-.18a3.281 3.281 0 0 0-.959-.603 2.867 2.867 0 0 0-1.155-.247c-.14 0-.277.011-.416.035a1.4 1.4 0 0 0-.395.12.756.756 0 0 0-.291.231.54.54 0 0 0-.123.348c0 .198.065.35.196.456.13.104.376.2.738.288.237.057.466.11.683.164.22.054.455.128.706.222.496.188.86.444 1.095.77.238.32.357.738.357 1.253 0 .737-.271 1.336-.813 1.798-.538.46-1.27.689-2.197.689a5.447 5.447 0 0 1-1.402-.161 6.725 6.725 0 0 1-1.117-.416v-1.794h.183c.344.318.73.563 1.155.734.429.17.839.256 1.233.256.1 0 .235-.01.4-.03.166-.02.3-.055.403-.102a.97.97 0 0 0 .313-.225c.084-.09.127-.223.127-.4a.568.568 0 0 0-.183-.424c-.119-.12-.294-.213-.526-.276-.243-.067-.5-.128-.773-.185a5.523 5.523 0 0 1-.76-.227c-.544-.204-.936-.48-1.177-.828-.237-.351-.357-.786-.357-1.305 0-.697.27-1.265.81-1.703.54-.442 1.235-.663 2.083-.663zm-8.981.135h2.51c.521 0 .903.02 1.143.06.243.041.484.13.721.266.246.144.43.338.548.583.121.24.181.518.181.83 0 .36-.082.68-.247.959a1.697 1.697 0 0 1-.7.642v.04c.423.098.758.298 1.004.603.249.305.373.706.373 1.205 0 .361-.063.686-.19.97-.125.285-.296.52-.516.707a2.31 2.31 0 0 1-.845.472c-.304.094-.69.141-1.159.141H8.12v-7.478zm1.659 1.372v1.582h.262c.263 0 .486-.007.672-.017.185-.01.332-.043.44-.1.15-.077.248-.175.294-.295.046-.124.07-.266.07-.427a.91.91 0 0 0-.083-.371.518.518 0 0 0-.282-.277 1.187 1.187 0 0 0-.456-.086c-.18-.007-.433-.01-.76-.01h-.157zm0 2.873V18.1H9.9c.469 0 .804-.002 1.007-.006.202-.003.39-.046.56-.13a.712.712 0 0 0 .357-.33c.067-.142.099-.302.099-.483 0-.237-.04-.42-.121-.547-.078-.13-.214-.228-.405-.291a1.842 1.842 0 0 0-.538-.072 49.47 49.47 0 0 0-.716-.003h-.366z" fill="#26a69a" stroke-width="1.067"/></symbol><symbol viewBox="0 0 24 24" id="c" xmlns="http://www.w3.org/2000/svg"><path d="M15.45 15.97l.42 2.44c-.26.14-.68.27-1.24.39-.57.13-1.24.2-2.01.2-2.21-.04-3.87-.7-4.98-1.96-1.14-1.27-1.68-2.88-1.68-4.83C6 9.9 6.68 8.13 8 6.89 9.28 5.64 10.92 5 12.9 5c.75 0 1.4.07 1.94.19s.94.25 1.2.4l-.6 2.49-1.04-.34c-.4-.1-.87-.15-1.4-.15-1.15-.01-2.11.36-2.86 1.1-.76.73-1.14 1.85-1.18 3.34.01 1.36.37 2.42 1.08 3.2.71.77 1.7 1.17 2.99 1.18l1.33-.12c.43-.08.79-.19 1.09-.32z" fill="#0277bd"/></symbol><symbol viewBox="0 0 300 300" id="cabal" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -822.52)" fill-rule="evenodd" color="#000"><rect transform="matrix(-.98339 .18149 .60192 .79856 0 0)" x="405.55" y="967.22" width="107.25" height="156.59" rx="12.306" ry="12.31" fill="#2d9bbd"/><rect transform="matrix(-.98528 .17093 -.59175 .80612 0 0)" x="-1156.5" y="1461.9" width="108.34" height="123.15" rx="10.69" ry="12.31" fill="#4a4bcd"/><path d="M52.112 965.158c-1.343 3.515-26.292 23.248-25.744 27.277.548 4.03 29.812 16.023 32.04 19.027s10.545 41.668 13.603 42.5 18.828-31.274 21.548-32.932c2.72-1.658 32.808 2.503 34.15-1.01 1.343-3.515-18.174-35.352-18.721-39.381-.548-4.03 9.732-40.12 7.502-43.125-2.229-3.005-30.06 9.427-33.118 8.594-3.059-.833-26.793-27.3-29.514-25.643-2.72 1.657-.405 41.177-1.747 44.693z" fill="#2e5bc1"/></g></symbol><symbol viewBox="0 0 24 24" id="cake" xmlns="http://www.w3.org/2000/svg"><path d="M12.254 6.621a1.807 1.807 0 0 0 1.808-1.807c0-.344-.09-.66-.262-.932l-1.546-2.684-1.546 2.684a1.72 1.72 0 0 0-.262.932 1.808 1.808 0 0 0 1.808 1.807m4.158 9.04l-.967-.976-.976.976c-1.175 1.166-3.236 1.175-4.42 0l-.959-.976-.994.976a3.134 3.134 0 0 1-3.977.353v4.167a.904.904 0 0 0 .904.904h14.463a.904.904 0 0 0 .904-.904v-4.167a3.134 3.134 0 0 1-3.977-.353m1.265-6.328h-4.52V7.525H11.35v1.808H6.83a2.712 2.712 0 0 0-2.711 2.712v1.392c0 .977.795 1.772 1.771 1.772.489 0 .94-.18 1.248-.515l1.952-1.926 1.908 1.926c.669.669 1.835.669 2.504 0l1.916-1.926 1.944 1.926c.316.334.768.515 1.247.515.976 0 1.78-.795 1.78-1.772v-1.392a2.712 2.712 0 0 0-2.711-2.712z" fill="#ff7043" stroke-width=".904"/></symbol><symbol viewBox="0 0 24 24" id="certificate" xmlns="http://www.w3.org/2000/svg"><path d="M4 3c-1.11 0-2 .89-2 2v10a2 2 0 0 0 2 2h8v5l3-3 3 3v-5h2a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H4m8 2l3 2 3-2v3.5l3 1.5-3 1.5V15l-3-2-3 2v-3.5L9 10l3-1.5V5M4 5h5v2H4V5m0 4h3v2H4V9m0 4h5v2H4v-2z" fill="#ff5722"/></symbol><symbol viewBox="0 0 24 24" id="changelog" xmlns="http://www.w3.org/2000/svg"><path d="M11 7v5.11l4.71 2.79.79-1.28-4-2.37V7m0-5C8.97 2 5.91 3.92 4.27 6.77L2 4.5V11h6.5L5.75 8.25C6.96 5.73 9.5 4 12.5 4a7.5 7.5 0 0 1 7.5 7.5 7.5 7.5 0 0 1-7.5 7.5c-3.27 0-6.03-2.09-7.06-5h-2.1c1.1 4.03 4.77 7 9.16 7 5.24 0 9.5-4.25 9.5-9.5A9.5 9.5 0 0 0 12.5 2z" fill="#8bc34a"/></symbol><symbol viewBox="0 0 24 24" id="clojure" xmlns="http://www.w3.org/2000/svg"><path d="M3.355 1.78c-.845 0-1.525.68-1.525 1.525v17.441c0 .845.68 1.525 1.525 1.525h17.442c.845 0 1.525-.68 1.525-1.525V3.305c0-.845-.68-1.526-1.525-1.526H3.355zm6.168 2.572h1.963l6.368 14.931H15.93l-3.38-8.086-3.349 8.086H7.21l4.346-10.38-2.032-4.551z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="cmake" xmlns="http://www.w3.org/2000/svg"><path d="M11.99 2.965L2.977 20.999l9.874-8.47-.863-9.564z" fill="#1e88e5"/><path d="M12.007 2.963l.002.29 1.312 14.498-.001.006.023.26 7.362 2.979h.416l-.158-.311-.114-.228h-.002l-8.84-17.494z" fill="#e53935"/><path d="M8.607 16.11L2.98 20.995h17.743v-.016L8.607 16.11z" fill="#7cb342"/></symbol><symbol class="bfmain_logo__svg" viewBox="0 0 300 300.00001" id="code-climate" xmlns="http://www.w3.org/2000/svg"><path class="bfsymbol" d="M196.19 75.562l-51.846 51.561 30.766 30.766 21.08-21.08 59.252 59.537 30.481-30.766zm-61.246 60.961l-30.481-30.481-78.053 78.053-11.964 11.964 30.766 30.766 11.964-12.249 39.596-39.312 7.691-7.691 30.481 30.48 28.772 28.773 30.766-30.766-28.772-28.772z" fill="#eee" stroke-width="2.849"/></symbol><symbol class="bgmain_logo__svg" viewBox="0 0 300 300.00001" id="code-climate_light" xmlns="http://www.w3.org/2000/svg"><path class="bgsymbol" d="M196.19 75.562l-51.846 51.561 30.766 30.766 21.08-21.08 59.252 59.537 30.481-30.766zm-61.246 60.961l-30.481-30.481-78.053 78.053-11.964 11.964 30.766 30.766 11.964-12.249 39.596-39.312 7.691-7.691 30.481 30.48 28.772 28.773 30.766-30.766-28.772-28.772z" fill="#455a64" stroke-width="2.849"/></symbol><symbol viewBox="0 0 24 24" id="coffee" xmlns="http://www.w3.org/2000/svg"><path d="M2 21h18v-2H2M20 8h-2V5h2m0-2H4v10a4 4 0 0 0 4 4h6a4 4 0 0 0 4-4v-3h2a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="coldfusion" xmlns="http://www.w3.org/2000/svg"><rect transform="rotate(90)" x="2.283" y="-21.86" width="19.487" height="19.487" ry="0" fill="#0d3858" stroke="#4dd0e1" stroke-width=".7"/><text x="6.653" y="16.426" fill="#4dd0e1" font-family="Calibri" font-size="29.001" font-weight="bold" letter-spacing="0" stroke-width=".725" word-spacing="0" style="line-height:1.25"><tspan x="6.653" y="16.426" font-family="'Segoe UI'" font-size="10.634" font-weight="normal">C<tspan font-size="11.844">f</tspan></tspan></text></symbol><symbol viewBox="0 0 24 24" id="conduct" xmlns="http://www.w3.org/2000/svg"><path d="M10 17l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9m-6-6a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m7 0h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z" fill="#cddc39"/></symbol><symbol viewBox="0 0 24 24" id="console" xmlns="http://www.w3.org/2000/svg"><path d="M20 19V7H4v12h16m0-16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16m-7 14v-2h5v2h-5m-3.42-4L5.57 9H8.4l3.3 3.3c.39.39.39 1.03 0 1.42L8.42 17H5.59z" fill="#ff7043"/></symbol><symbol viewBox="0 0 24 24" id="contributing" xmlns="http://www.w3.org/2000/svg"><path d="M17 9H7V7h10m0 6H7v-2h10m-3 6H7v-2h7M12 3a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m7 0h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z" fill="#ffca28"/></symbol><symbol viewBox="0 0 24 24" id="cpp" xmlns="http://www.w3.org/2000/svg"><path d="M10.5 15.97l.41 2.44c-.26.14-.68.27-1.24.39-.57.13-1.24.2-2.01.2-2.21-.04-3.87-.7-4.98-1.96C1.56 15.77 1 14.16 1 12.21c.05-2.31.72-4.08 2-5.32C4.32 5.64 5.96 5 7.94 5c.75 0 1.4.07 1.94.19s.94.25 1.2.4l-.58 2.49-1.06-.34c-.4-.1-.86-.15-1.39-.15-1.16-.01-2.12.36-2.87 1.1-.76.73-1.15 1.85-1.18 3.34 0 1.36.37 2.42 1.08 3.2.71.77 1.71 1.17 2.99 1.18l1.33-.12c.43-.08.79-.19 1.1-.32M11 11h2V9h2v2h2v2h-2v2h-2v-2h-2v-2m7 0h2V9h2v2h2v2h-2v2h-2v-2h-2v-2z" fill="#0277bd"/></symbol><symbol viewBox="0 0 24 24" id="credits" xmlns="http://www.w3.org/2000/svg"><path d="M3 3h18v2H3V3m4 4h10v2H7V7m-4 4h18v2H3v-2m4 4h10v2H7v-2m-4 4h18v2H3v-2z" fill="#9ccc65"/></symbol><symbol viewBox="0 0 200 200" id="crystal" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:none}</style><path d="M179.363 121.67l-57.623 57.507c-.23.23-.576.346-.806.23l-78.713-21.09c-.346-.115-.577-.345-.577-.576L20.44 79.144c-.115-.345 0-.576.23-.806L78.294 20.83c.23-.23.576-.346.807-.23l78.713 21.09c.345.114.576.345.576.575l21.09 78.597c.23.346.115.577-.115.807zM102.148 59.09l-77.33 20.63c-.115 0-.23.23-.115.345l56.586 56.47c.115.115.346.115.346-.115l20.744-77.215c.115 0-.115-.23-.23-.116z" stroke-width="1.153" fill="#cfd8dc"/></symbol><symbol viewBox="0 0 200 200" id="crystal_light" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:none}</style><path d="M179.363 121.67l-57.623 57.507c-.23.23-.576.346-.806.23l-78.713-21.09c-.346-.115-.577-.345-.577-.576L20.44 79.144c-.115-.345 0-.576.23-.806L78.294 20.83c.23-.23.576-.346.807-.23l78.713 21.09c.345.114.576.345.576.575l21.09 78.597c.23.346.115.577-.115.807zM102.148 59.09l-77.33 20.63c-.115 0-.23.23-.115.345l56.586 56.47c.115.115.346.115.346-.115l20.744-77.215c.115 0-.115-.23-.23-.116z" fill="#37474f" stroke-width="1.153"/></symbol><symbol viewBox="0 0 24 24" id="csharp" xmlns="http://www.w3.org/2000/svg"><path d="M11.5 15.97l.41 2.44c-.26.14-.68.27-1.24.39-.57.13-1.24.2-2.01.2-2.21-.04-3.87-.7-4.98-1.96C2.56 15.77 2 14.16 2 12.21c.05-2.31.72-4.08 2-5.32C5.32 5.64 6.96 5 8.94 5c.75 0 1.4.07 1.94.19s.94.25 1.2.4l-.58 2.49-1.06-.34c-.4-.1-.86-.15-1.39-.15-1.16-.01-2.12.36-2.87 1.1-.76.73-1.15 1.85-1.18 3.34 0 1.36.37 2.42 1.08 3.2.71.77 1.71 1.17 2.99 1.18l1.33-.12c.43-.08.79-.19 1.1-.32M13.89 19l.61-4H13l.34-2h1.5l.32-2h-1.5L14 9h1.5l.61-4h2l-.61 4h1l.61-4h2l-.61 4H22l-.34 2h-1.5l-.32 2h1.5L21 15h-1.5l-.61 4h-2l.61-4h-1l-.61 4h-2m2.95-6h1l.32-2h-1l-.32 2z" fill="#0277bd"/></symbol><symbol viewBox="0 0 24 24" id="css" xmlns="http://www.w3.org/2000/svg"><path d="M5 3l-.65 3.34h13.59L17.5 8.5H3.92l-.66 3.33h13.59l-.76 3.81-5.48 1.81-4.75-1.81.33-1.64H2.85l-.79 4 7.85 3 9.05-3 1.2-6.03.24-1.21L21.94 3H5z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="css-map" xmlns="http://www.w3.org/2000/svg"><path d="M18 8v2h2v10H10v-2H8v4h14V8h-4z" fill="#42a5f5"/><path d="M4.676 3l-.488 2.51h10.211l-.33 1.623H3.864l-.496 2.502H13.58l-.57 2.863-4.119 1.36-3.569-1.36.248-1.232H3.06l-.593 3.005 5.898 2.254 6.8-2.254.902-4.53.18-.91L17.406 3H4.675z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 33 33" id="cucumber" xmlns="http://www.w3.org/2000/svg"><title>cucumber-mark-transparent-pips</title><g transform="translate(0 -5)" fill="none" fill-rule="evenodd"><path d="M-4-1h40v40H-4z"/><path d="M16.641 7.092c-7.028 0-12.714 5.686-12.714 12.714 0 6.187 4.435 11.327 10.288 12.471v3.64C21.824 34.77 28.561 28.73 29.063 20.8c.303-4.772-2.076-9.644-6.09-12.01a10.575 10.575 0 0 0-1.455-.728l-.243-.097c-.223-.082-.448-.175-.68-.242a12.614 12.614 0 0 0-3.954-.632zm2.62 4.707a1.387 1.387 0 0 0-1.213.485c-.233.31-.379.611-.534.923-.466 1.087-.31 2.251.388 3.105 1.087-.233 2.01-.927 2.475-2.014a2.45 2.45 0 0 0 .243-1.02c.048-.824-.634-1.404-1.359-1.479zm-5.654.073c-.708.068-1.382.63-1.382 1.407 0 .31.087.709.243 1.02.466 1.086 1.46 1.78 2.546 2.013.621-.854.782-2.018.316-3.105-.155-.311-.3-.617-.534-.85a1.364 1.364 0 0 0-1.188-.485zm-3.809 3.735c-1.224.063-1.77 1.602-.752 2.402.31.233.612.403.922.559 1.087.466 2.344.306 3.275-.316-.233-1.009-1.023-1.936-2.11-2.402-.388-.155-.703-.243-1.092-.243-.087-.009-.161-.004-.243 0zm11.961 4.708a3.551 3.551 0 0 0-2.013.582c.233 1.01 1.023 1.936 2.11 2.401.389.156.705.244 1.093.244 1.397.077 2.08-1.65.994-2.427-.31-.233-.611-.379-.922-.534a3.354 3.354 0 0 0-1.262-.266zm-10.603.072a3.376 3.376 0 0 0-1.261.267c-.389.155-.69.325-.923.558-1.009.854-.33 2.48 1.068 2.402.388 0 .782-.087 1.092-.243 1.087-.465 1.859-1.392 2.014-2.401a3.474 3.474 0 0 0-1.99-.582zm3.931 2.378c-1.087.233-2.009.927-2.475 2.014-.155.31-.243.684-.243.995-.077 1.32 1.724 2.028 2.5 1.02.233-.312.378-.613.534-.923.466-1.01.306-2.174-.316-3.106zm2.887.073c-.621.854-.781 2.019-.315 3.106.155.31.3.615.534.848.854.932 2.65.243 2.572-.921 0-.31-.088-.71-.243-1.02-.466-1.087-1.46-1.78-2.547-2.013z" fill="#4caf50" stroke-width=".776"/></g></symbol><symbol id="cuda" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"><style>.bust0{fill:#76b900}</style><title>NVIDIA-Logo</title><path id="buEye_Mark" class="bust0" d="M76.362 75.199V64.116c1.095-.068 2.19-.137 3.284-.137 30.377-.958 50.286 26.135 50.286 26.135s-21.483 29.83-44.539 29.83c-3.079 0-6.089-.48-8.962-1.438v-33.66c11.836 1.436 14.23 6.636 21.277 18.471l15.804-13.273s-11.562-15.12-30.992-15.12c-2.053-.068-4.105.069-6.158.274m0-36.67v16.556l3.284-.205c42.213-1.437 69.784 34.618 69.784 34.618s-31.608 38.45-64.516 38.45c-2.873 0-5.678-.274-8.483-.753v10.262c2.326.274 4.72.48 7.046.48 30.65 0 52.817-15.668 74.3-34.14 3.558 2.874 18.13 9.784 21.14 12.794-20.388 17.104-67.937 30.856-94.893 30.856-2.6 0-5.062-.137-7.525-.41v14.436h116.44V38.532zm0 79.977v8.757C48.038 122.2 40.17 92.712 40.17 92.712s13.615-15.05 36.192-17.514v9.579h-.068c-11.836-1.437-21.14 9.646-21.14 9.646s5.268 18.678 21.209 24.082M26.077 91.481S42.839 66.714 76.43 64.115v-9.03C39.213 58.094 7.057 89.565 7.057 89.565s18.199 52.68 69.305 57.47v-9.579c-37.492-4.652-50.286-45.975-50.286-45.975z" fill="#8bc34a" stroke-width=".684"/></symbol><symbol viewBox="0 0 24 24" id="dart" xmlns="http://www.w3.org/2000/svg"><title>Dart</title><path d="M12.486 1.385a.978.978 0 0 0-.682.281l-.01.007-6.387 3.692 6.371 6.372v.004l7.659 7.659 1.46-2.63-5.265-12.64-2.456-2.457a.972.972 0 0 0-.69-.288z" fill="#00ca94"/><path d="M5.422 5.35L1.73 11.733l-.007.01a.967.967 0 0 0 .006 1.371l3.059 3.061 11.963 4.706 2.704-1.502-.073-.073-.018.002-7.5-7.512h-.01L5.423 5.35z" fill="#1565c0"/><path d="M5.405 5.353l6.518 6.525h.01l7.502 7.51 2.855-.544.005-8.449-3.016-2.955c-.66-.647-1.675-1.064-2.695-1.202l.002-.032-11.181-.853z" fill="#1565c0"/><path d="M5.414 5.361l6.521 6.522v.009l7.506 7.506-.546 2.855h-8.448l-2.954-3.017c-.647-.66-1.064-1.676-1.2-2.696l-.033.003L5.414 5.36z" fill="#00ee94"/></symbol><symbol viewBox="0 0 24 24" id="database" xmlns="http://www.w3.org/2000/svg"><path d="M12 3C7.58 3 4 4.79 4 7s3.58 4 8 4 8-1.79 8-4-3.58-4-8-4M4 9v3c0 2.21 3.58 4 8 4s8-1.79 8-4V9c0 2.21-3.58 4-8 4s-8-1.79-8-4m0 5v3c0 2.21 3.58 4 8 4s8-1.79 8-4v-3c0 2.21-3.58 4-8 4s-8-1.79-8-4z" fill="#ffca28"/></symbol><symbol viewBox="0 0 24 24" id="diff" xmlns="http://www.w3.org/2000/svg"><path d="M3 1c-1.11 0-2 .89-2 2v11c0 1.11.89 2 2 2h2v-2H3V3h11v2h2V3c0-1.11-.89-2-2-2H3m6 6c-1.11 0-2 .89-2 2v2h2V9h2V7H9m4 0v2h1v1h2V7h-3m5 0v2h2v11H9v-2H7v2c0 1.11.89 2 2 2h11c1.11 0 2-.89 2-2V9c0-1.11-.89-2-2-2h-2m-4 5v2h-2v2h2c1.11 0 2-.89 2-2v-2h-2m-7 1v3h3v-2H9v-1H7z" fill="#42a5f5"/></symbol><symbol id="docker" viewBox="0 0 41 34.5" xmlns="http://www.w3.org/2000/svg"><style id="bystyle2">.byst0{fill:#fff}.byst1{clip-path:url(#bySVGID_4_)}</style><g id="byg34" transform="translate(.292 1.9)" fill="#0087c9"><g id="byg32"><g id="byg30"><g id="byg28"><g id="byg26"><g id="byg9"><path id="bySVGID_1_" class="byst0" d="M8.7 24c-1.1 0-2.1-.9-2.1-2s.9-2 2.1-2c1.2 0 2.1.9 2.1 2s-1 2-2.1 2zm25.8-10.9c-.2-1.6-1.2-2.9-2.5-3.9l-.5-.4-.4.5c-.8.9-1.1 2.5-1 3.7.1.9.4 1.8.9 2.5-.4.2-.9.4-1.3.6-.9.3-1.8.4-2.7.4H1.1l-.1.6c-.2 1.9.1 3.9.9 5.7l.4.7v.1c2.4 4 6.7 5.8 11.4 5.8 9 0 16.4-3.9 19.9-12.3 2.3.1 4.6-.5 5.7-2.7l.3-.5-.5-.3c-1.3-.8-3.1-.9-4.6-.5zm-12.9-1.6h-3.9v3.9h3.9zm0-4.9h-3.9v3.9h3.9zm0-5h-3.9v3.9h3.9zm4.8 9.9h-3.9v3.9h3.9zm-14.5 0H8v3.9h3.9zm4.9 0h-3.9v3.9h3.9zm-9.7 0H3.2v3.9h3.9zm9.7-4.9h-3.9v3.9h3.9zm-4.9 0H8v3.9h3.9z"/></g></g></g></g></g></g></symbol><symbol viewBox="0 0 24 24" id="document" xmlns="http://www.w3.org/2000/svg"><path d="M13 9h5.5L13 3.5V9M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m9 16v-2H6v2h9m3-4v-2H6v2h12z" fill="#42a5f5"/></symbol><symbol preserveAspectRatio="xMidYMid" viewBox="0 0 200 200" id="drone" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(9.063 22.346) scale(.71044)"><path d="M128.22.723C32.095.723.39 84.566.39 115.222h77.928S89.36 75.275 128.22 75.275s49.906 39.947 49.906 39.947h77.476c0-30.66-31.257-114.5-127.38-114.5m98.82 134.45h-48.914s-8.55 39.946-49.906 39.946c-41.355 0-49.902-39.948-49.902-39.948H30.255c0 10.25 37.727 82.708 98.443 82.708 60.714 0 98.344-59.604 98.344-82.708"/><circle cx="128" cy="126.08" r="32.768"/></g></symbol><symbol preserveAspectRatio="xMidYMid" viewBox="0 0 200 200" id="drone_light" xmlns="http://www.w3.org/2000/svg"><g fill="#424242" transform="translate(9.063 22.346) scale(.71044)"><path d="M128.22.723C32.095.723.39 84.566.39 115.222h77.928S89.36 75.275 128.22 75.275s49.906 39.947 49.906 39.947h77.476c0-30.66-31.257-114.5-127.38-114.5m98.82 134.45h-48.914s-8.55 39.946-49.906 39.946c-41.355 0-49.902-39.948-49.902-39.948H30.255c0 10.25 37.727 82.708 98.443 82.708 60.714 0 98.344-59.604 98.344-82.708"/><circle cx="128" cy="126.08" r="32.768"/></g></symbol><symbol viewBox="0 0 3473 3473" id="editorconfig" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" xmlns="http://www.w3.org/2000/svg"><defs id="ccdefs4"><style id="ccstyle2">.ccfil2{fill:#020202}.ccfil0{fill:#e3e3f8}.ccfil5{fill:#efefef}.ccfil6{fill:#faf1f1}.ccfil3{fill:#fdf2f2}.ccfil1{fill:#fdfdfd}.ccfil4{fill:#fef3f3}</style></defs><g id="ccLayer_x0020_1" transform="matrix(.8945 0 0 .8945 138.649 275.985)"><g id="cc_631799120"><g id="ccg11"><path class="ccfil0" d="M967 1895c46-30 84-105 61-158-63 27-60 89-61 158z" id="ccpath7" fill="#e3e3f8"/><path class="ccfil0" d="M1679 2067c50-16 98-72 71-130-39 27-64 64-71 130z" id="ccpath9" fill="#e3e3f8"/></g><g id="ccg21"><path class="ccfil1" d="M280 2895c0 63 16 131 60 155 162 91 730 20 923-23 101-23 183-98 278-139 214-93 369-168 540-293 124-91 321-347 342-500l-169-38c-4 172-43 211-196 251-103 28-304 34-409 16-139-23-202-96-265-179-122-162 27-275-166-286-203 249-561 70-718 45-67 97-224 727-222 871 97-33 158 3 245 37 308 119 39 224-84 193-84-20-110-75-159-110z" id="ccpath13" fill="#fdfdfd"/><path class="ccfil1" d="M683 1458c125 24 236 76 342 129 173 86 204 74 220 194 2 22-2 34 61 54 106 33-61-26 223-25 169 1 556 69 681 148 52 33 42 75 218 70-2-207-57-516-138-706-99-230-230-265-497-351-156-50-614-105-756-17-133 83-158 182-282 356-36 51-49 90-72 148z" id="ccpath15" fill="#fdfdfd"/><path class="ccfil1" d="M1784 1883c100 41-5 306-144 242-45-127 62-199 91-256-60-9-231-36-282-17-66 25-81 166-47 232 160 314 867 247 792 3-30-99-58-115-159-149-81-27-162-55-251-55z" id="ccpath17" fill="#fdfdfd"/><path class="ccfil1" d="M527 1848c80 77 261 89 378 95 15-155 28-271 152-262 61 83 29 181-35 244 109-1 172-83 156-202-92-66-371-198-511-217-39 42-135 272-140 342z" id="ccpath19" fill="#fdfdfd"/></g><path class="ccfil2" d="M339 2838c66-6 238 44 252 100-107 13-243 3-252-100zm-59 57c49 35 75 90 159 110 123 31 392-74 84-193-87-34-148-70-245-37-2-144 155-774 222-871 157 25 515 204 718-45 193 11 44 124 166 286 63 83 126 156 265 179 105 18 306 12 409-16 153-40 192-79 196-251l169 38c-21 153-218 409-342 500-171 125-326 200-540 293-95 41-177 116-278 139-193 43-761 114-923 23-44-24-60-92-60-155zm1399-828c7-66 32-103 71-130 27 58-21 114-71 130zm105-184c89 0 170 28 251 55 101 34 129 50 159 149 75 244-632 311-792-3-34-66-19-207 47-232 51-19 222 8 282 17-29 57-136 129-91 256 139 64 244-201 144-242zm-817 12c1-69-2-131 61-158 23 53-15 128-61 158zm-440-47c5-70 101-300 140-342 140 19 419 151 511 217 16 119-47 201-156 202 64-63 96-161 35-244-124-9-137 107-152 262-117-6-298-18-378-95zm-100-80c-37-102-37-261 120-274l-80 223c-21 48-21 37-40 51zm256-310c23-58 36-97 72-148 124-174 149-273 282-356 142-88 600-33 756 17 267 86 398 121 497 351 81 190 136 499 138 706-176 5-166-37-218-70-125-79-512-147-681-148-284-1-117 58-223 25-63-20-59-32-61-54-16-120-47-108-220-194-106-53-217-105-342-129zm1770-49c-19-63 16-59 77-102 35-25 63-51 106-75 161-90 461-105 589 2 52 43 137 127 124 237-27 219-177 339-300 439-125 102-333 207-548 137-18-44-4-323-25-426-19-92-9-102 44-157 156-162 494-280 686-141 81 60 58 83 100 129 52-56-45-244-403-232-243 8-348 198-450 189zM997 840c5-139 133-427 261-527 155-120 317-233 555-98 59 33 56 50 62 132 5 79-2 108-22 172-158 510-290 217-796 338 19-166 163-314 243-391 137-133 236-219 442-191 57 95 63 155-6 266-92 148-115 139-101 240 72-18 94-88 127-158 201-420-91-471-270-394-120 51-334 287-404 429-14 28-29 64-42 95zm792 21c21-125 145-156 145-541 0-166-204-315-471-204-229 94-264 166-386 350-115 174-111 365-210 526-29 46-55 62-87 108-23 34-40 77-63 117-47 77-95 133-133 225-120 3-221 5-233 129-16 170 64 212 64 276-1 69-281 765-203 1180 22 114 97 115 217 129 289 35 664 23 923-81l470-225c119-67 319-194 408-287 63-65 96-120 150-197 74-108 76-106 92-253 98 18 281 61 342 114-7 69-41 36-41 98 39 1 104-48 120-102-41-60-84-50-143-98 47-37 132-54 197-81 140-58 379-234 438-394 47-129 12-344-64-428-80-88-266-133-418-133-181 0-368 130-514 186-56-49-60-105-101-159-47-64-353-224-499-255z" id="ccpath23" fill="#020202"/><path class="ccfil3" d="M2453 1409c102 9 207-181 450-189 358-12 455 176 403 232-42-46-19-69-100-129-192-139-530-21-686 141-53 55-63 65-44 157 21 103 7 382 25 426 215 70 423-35 548-137 123-100 273-220 300-439 13-110-72-194-124-237-128-107-428-92-589-2-43 24-71 50-106 75-61 43-96 39-77 102z" id="ccpath25" fill="#fdf2f2"/><path class="ccfil4" d="M997 840l49-87c13-31 28-67 42-95 70-142 284-378 404-429 179-77 471-26 270 394-33 70-55 140-127 158-14-101 9-92 101-240 69-111 63-171 6-266-206-28-305 58-442 191-80 77-224 225-243 391 506-121 638 172 796-338 20-64 27-93 22-172-6-82-3-99-62-132-238-135-400-22-555 98-128 100-256 388-261 527z" id="ccpath27" fill="#fef3f3"/><path class="ccfil5" d="M427 1768c19-14 19-3 40-51l80-223c-157 13-157 172-120 274z" id="ccpath29" fill="#efefef"/><path class="ccfil6" d="M591 2938c-14-56-186-106-252-100 9 103 145 113 252 100z" id="ccpath31" fill="#faf1f1"/></g></g></symbol><symbol viewBox="0 0 24 24" id="elixir" xmlns="http://www.w3.org/2000/svg"><path d="M12.431 22.383c-3.86 0-6.99-3.64-6.99-8.13 0-3.678 2.774-8.172 4.916-10.91 1.014-1.295 2.931-2.321 2.931-2.321s-.982 5.238 1.683 7.318c2.365 1.847 4.105 4.25 4.105 6.363 0 4.232-2.784 7.68-6.645 7.68z" fill="#9575cd" stroke-width="1.256"/></symbol><symbol viewBox="0 0 323.00001 322.99999" id="elm" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(.8053 0 0 .8053 30.106 31.524)"><path fill="#f0ad00" d="M160.8 153.865l68.028-68.03H92.77z"/><path fill="#7fd13b" d="M160.983 5.098H12.033l68.524 68.525H229.51z"/><path fill="#7fd13b" stroke-width=".974" d="M243.906 88.021l74.136 74.137-74.474 74.475-74.137-74.137z"/><path fill="#60b5cc" d="M318.2 145.045V5.098H178.252z"/><path fill="#5a6378" d="M152.164 162.499L3.4 13.733v297.533z"/><path fill="#f0ad00" d="M252.205 245.27l65.995 65.996v-131.99z"/><path fill="#60b5cc" d="M160.8 171.134L12.034 319.899h297.53z"/></g></symbol><symbol viewBox="0 0 24 24" id="email" xmlns="http://www.w3.org/2000/svg"><path d="M20 8l-8 5-8-5V6l8 5 8-5m0-2H4c-1.11 0-2 .89-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 30 30" id="erlang" xmlns="http://www.w3.org/2000/svg"><path style="line-height:1.25;-inkscape-font-specification:'Wide Latin'" d="M5.217 4.367c-.048.052-.097.1-.144.153C2.697 7.182 1.51 10.798 1.51 15.366c0 4.418 1.156 7.862 3.46 10.34h19.414c2.553-1.152 4.127-3.43 4.127-3.43l-3.147-2.52-1.454 1.381c-.866.773-.845.931-2.314 1.78-1.496.674-3.04.966-4.634.966-2.516 0-4.423-.909-5.723-2.059-1.286-1.15-1.985-4.511-2.097-6.68l17.458.067-.182-1.472s-.847-7.129-2.542-9.372zm8.76.846c1.565 0 3.22.535 3.96 1.471.742.937.932 1.667.974 3.524H9.12c.111-1.955.436-2.81 1.372-3.697.937-.888 2.03-1.298 3.484-1.298z" font-weight="400" font-size="48" font-family="Wide Latin" letter-spacing="0" word-spacing="0" fill="#f44336" stroke-width=".97"/></symbol><symbol viewBox="0 0 299.99999 300.00001" id="eslint" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-2.88 18.438) scale(1.0344)"><path d="M97.021 99.016l48.432-27.962c1.212-.7 2.706-.7 3.918 0l48.433 27.962a3.92 3.92 0 0 1 1.959 3.393v55.924a3.924 3.924 0 0 1-1.959 3.394l-48.433 27.962c-1.212.7-2.706.7-3.918 0l-48.432-27.962a3.92 3.92 0 0 1-1.959-3.394v-55.924a3.922 3.922 0 0 1 1.959-3.393" fill="#7986cb"/><path d="M273.34 124.49L215.473 23.82c-2.102-3.64-5.985-6.325-10.188-6.325H89.545c-4.204 0-8.088 2.685-10.19 6.325L21.488 124.27c-2.102 3.641-2.102 8.236 0 11.877l57.867 99.847c2.102 3.64 5.986 5.501 10.19 5.501h115.74c4.203 0 8.087-1.805 10.188-5.446l57.867-100.01c2.104-3.639 2.104-7.907.001-11.547m-47.917 48.41c0 1.48-.891 2.849-2.174 3.59l-73.71 42.527a4.194 4.194 0 0 1-4.17 0l-73.767-42.527c-1.282-.741-2.179-2.109-2.179-3.59V87.847c0-1.481.884-2.849 2.167-3.59l73.707-42.527a4.185 4.185 0 0 1 4.168 0l73.772 42.527c1.283.741 2.186 2.109 2.186 3.59z" fill="#3f51b5"/></g></symbol><symbol viewBox="0 0 24 24" id="exe" xmlns="http://www.w3.org/2000/svg"><path d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h14m0 14V8H5v10h14z" fill="#e64a19"/></symbol><symbol viewBox="0 0 24 24" id="favicon" xmlns="http://www.w3.org/2000/svg"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.62L12 2 9.19 8.62 2 9.24l5.45 4.73L5.82 21 12 17.27z" fill="#ffd54f"/></symbol><symbol viewBox="0 0 24 24" id="file" xmlns="http://www.w3.org/2000/svg"><path d="M13 9h5.5L13 3.5V9M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m5 2H6v16h12v-9h-7V4z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 400 400" id="firebase" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 103)"><path d="M72.55 208.77l44.456-292.29 56.209 90.445L195.49-37.57 330.6 209.28z" fill="#ffa712"/><path d="M195.7 276.73l134.9-67.45-46.5-224.83L72.55 208.77z" fill="#fcca3f"/><path d="M173.22 6.932L72.56 208.772l136.35-144.58z" fill="#f6820c"/></g></symbol><symbol viewBox="0 0 24 24" id="flash" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="cma"><stop offset="0" stop-color="#d92f3c"/><stop offset="1" stop-color="#791223"/></linearGradient><linearGradient xlink:href="#cma" id="cmb" x1="2.373" y1="12.027" x2="21.86" y2="12.027" gradientUnits="userSpaceOnUse" gradientTransform="translate(-.09 -24.144)"/></defs><rect width="19.487" height="19.487" x="2.283" y="-21.86" transform="rotate(90)" ry="0" fill="url(#cmb)"/><path style="line-height:125%" d="M16.802 5.768l-.013.002a6.43 6.43 0 0 0-1.182.192 5.062 5.062 0 0 0-1.494.718c-.428.323-.817.72-1.17 1.191-.34.48-.682 1.032-1.022 1.66-.12.228-.233.424-.35.636v.002h-.004l-1.34 2.394-.005-.002c-.238.443-.461.847-.665 1.198a4.358 4.358 0 0 1-.716.94 2.79 2.79 0 0 1-.907.594c-.072.027-.161.042-.242.063h-.989v2.414h.989v-.002a6.427 6.427 0 0 0 1.185-.192 5.062 5.062 0 0 0 1.494-.718 5.94 5.94 0 0 0 1.171-1.191c.34-.48.681-1.033 1.021-1.66.12-.228.235-.425.353-.637l.006.002.003-.005.037-.066h2.53v.002h1.124v-2.408h-.33v-.001h-1.98c.22-.407.432-.789.621-1.115.214-.37.452-.682.717-.94a2.79 2.79 0 0 1 .906-.594c.07-.027.16-.041.239-.061h.992V8.18h-.002V5.77h-.977v-.002z" font-weight="400" font-size="40" font-family="sans-serif" letter-spacing="0" word-spacing="0" fill="#fff"/></symbol><symbol class="cnflow-logo" viewBox="0 0 299.99999 300" id="flow" xmlns="http://www.w3.org/2000/svg"><title>Flow logo</title><path d="M38.75 33.427l77.461 77.47H54.436l61.145 61.16H38.437l93.462 93.478v-77.158l.01-.01v-77.47h-.01V66.982h46.691l20.394 20.393H153.57v76.531h22.05l24.474 24.473h-15.806l-.01-.01v.01h-31.665l-.01-.01v.01h-.313l.313.313v77.148h109.149l-39.2-39.2v-15.806l8.465 8.466v-77.37h-15.682l.017-38.191 30.09 30.086V56.362h-64.874l-22.94-22.934H113.71z" fill="#fbc02d" fill-opacity=".976" stroke-width=".955" class="cnflow-logo-mark"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-aurelia" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="coa" x1="-388.15%" x2="237.68%" y1="-144.18%" y2="430.41%"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="cob" x1="72.945%" x2="-97.052%" y1="84.424%" y2="-147.7%"><stop stop-color="#6E4D9B" offset="0"/><stop stop-color="#77327A" offset=".14"/><stop stop-color="#B31777" offset=".29"/><stop stop-color="#CD0F7E" offset=".84"/><stop stop-color="#ED2C89" offset="1"/></linearGradient><linearGradient id="coc" x1="-283.88%" x2="287.54%" y1="-693.6%" y2="101.71%"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="cod" x1="-821.19%" x2="101.99%" y1="-469.05%" y2="288.24%"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="coe" x1="-140.36%" x2="419.01%" y1="-230.93%" y2="261.98%"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="cof" x1="191.08%" x2="20.358%" y1="253.95%" y2="20.403%"><stop stop-color="#6E4D9B" offset="0"/><stop stop-color="#77327A" offset=".14"/><stop stop-color="#B31777" offset=".29"/><stop stop-color="#CD0F7E" offset=".84"/><stop stop-color="#ED2C89" offset="1"/></linearGradient><linearGradient id="cog" x1="-388.09%" x2="237.67%" y1="-173.85%" y2="518.99%"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="coi" x1="-31.824" x2="19.682" y1="-11.741" y2="35.548" gradientTransform="scale(.95818 1.0436)" gradientUnits="userSpaceOnUse" xlink:href="#coa"/><linearGradient id="coj" x1="12.022" x2="-15.716" y1="13.922" y2="-23.952" gradientTransform="scale(.96226 1.0392)" gradientUnits="userSpaceOnUse" xlink:href="#cob"/><linearGradient id="cok" x1="-23.39" x2="23.931" y1="-57.289" y2="8.573" gradientTransform="scale(1.0429 .95884)" gradientUnits="userSpaceOnUse" xlink:href="#coc"/><linearGradient id="col" x1="-53.331" x2="6.771" y1="-30.517" y2="18.785" gradientTransform="scale(.99898 1.001)" gradientUnits="userSpaceOnUse" xlink:href="#cod"/><linearGradient id="com" x1="-14.029" x2="41.998" y1="-23.111" y2="26.259" gradientTransform="scale(1.0003 .99965)" gradientUnits="userSpaceOnUse" xlink:href="#coe"/><linearGradient id="con" x1="31.177" x2="3.37" y1="41.442" y2="3.402" gradientTransform="scale(.96254 1.0389)" gradientUnits="userSpaceOnUse" xlink:href="#cof"/><linearGradient id="coo" x1="-31.905" x2="19.599" y1="-14.258" y2="42.767" gradientTransform="scale(.95823 1.0436)" gradientUnits="userSpaceOnUse" xlink:href="#cog"/><linearGradient id="cop" x1="4.301" x2="34.534" y1="34.41" y2="4.514" gradientTransform="scale(1.002 .99796)" gradientUnits="userSpaceOnUse" xlink:href="#coh"/><linearGradient id="coh" x1=".112" x2=".901" y1=".897" y2=".116"><stop stop-color="#6E4D9B" offset="0"/><stop stop-color="#77327A" offset=".14"/><stop stop-color="#B31777" offset=".53"/><stop stop-color="#CD0F7E" offset=".79"/><stop stop-color="#ED2C89" offset="1"/></linearGradient></defs><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#f06292" fill-rule="nonzero"/><g transform="matrix(.31022 .0619 -.0619 .31022 11.807 7.546)" fill="none"><path d="M8.002 6.127L4.117 8.719.116 2.723 4 .13z" transform="rotate(-11.284 17.839 -78.732)" fill="url(#coi)"/><path d="M9.179 1.887l6.637 9.946-7.906 5.276-6.637-9.946L.115 5.43 8.02.153z" transform="rotate(-11.284 129.49 -99.884)" fill="url(#coj)"/><path d="M7.3 1.88l1.462 2.189-6.018 4.015L.124 4.16l1.315-.877L6.143.144z" transform="rotate(-11.284 167.2 -62.32)" fill="url(#cok)"/><path d="M2.328 1.146L4.016.02l2.619 3.925L2.75 6.537 1.29 4.347l2.197-1.466zm-1.04 3.201L.132 2.612l2.197-1.466 1.158 1.735z" transform="rotate(-11.284 104.37 -149.22)" fill="url(#col)"/><path d="M5.346 9.155l-1.315.877L.03 4.035 6.047.019l2.805 4.204L4.15 7.36l4.703-3.138 1.197 1.793z" transform="rotate(-11.284 81.819 7.645)" fill="url(#com)"/><path d="M14.533 9.934l1.197 1.793-7.907 5.276-1.196-1.793L.052 5.358 7.958.082z" transform="rotate(-11.284 17.141 -7.825)" fill="url(#con)"/><path d="M6.235 7.177L4.038 8.643 2.84 6.849.036 2.646 3.92.053 7.923 6.05z" transform="rotate(-11.284 18.188 -79.174)" fill="url(#coo)"/><path d="M18.955 35.925L17.48 34.45l3.998-3.998 1.475 1.475z" fill="#714896"/><path d="M33.33 21.55l-1.475-1.474 1.867-1.868 1.475 1.475z" fill="#6f4795"/><path d="M7.12 24.09l-1.525-1.525 3.998-3.998 1.525 1.525z" fill="#88519f"/><path d="M21.495 9.714L19.97 8.19l1.868-1.868 1.524 1.525z" fill="#85509e"/><path d="M31.418 23.462l-6.72 6.72-1.475-1.474 6.72-6.721z" fill="#8d166a"/><path d="M18.058 10.101l1.525 1.525-6.721 6.72-1.525-1.524z" fill="#a70d6f"/><path d="M2.375 11.769l1.9 1.9-1.9 1.901-1.901-1.9z" fill="#9e61ad"/><path d="M15.523 36.482l1.9 1.9-1.9 1.901-1.9-1.9z" fill="#8053a3"/><path d="M8.372 38.294L.017 29.876 29.749.08l8.636 8.201z" transform="translate(1.823 1.548)" fill="url(#cop)"/></g></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-aurelia-open" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="cpi" x1="-31.824" x2="19.682" y1="-11.741" y2="35.548" gradientTransform="scale(.95818 1.0436)" gradientUnits="userSpaceOnUse" xlink:href="#cpa"/><linearGradient id="cpa" x1="-3.881" x2="2.377" y1="-1.442" y2="4.304"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="cpj" x1="12.022" x2="-15.716" y1="13.922" y2="-23.952" gradientTransform="scale(.96226 1.0392)" gradientUnits="userSpaceOnUse" xlink:href="#cpb"/><linearGradient id="cpb" x1=".729" x2="-.971" y1=".844" y2="-1.477"><stop stop-color="#6E4D9B" offset="0"/><stop stop-color="#77327A" offset=".14"/><stop stop-color="#B31777" offset=".29"/><stop stop-color="#CD0F7E" offset=".84"/><stop stop-color="#ED2C89" offset="1"/></linearGradient><linearGradient id="cpk" x1="-23.39" x2="23.931" y1="-57.289" y2="8.573" gradientTransform="scale(1.0429 .95884)" gradientUnits="userSpaceOnUse" xlink:href="#cpc"/><linearGradient id="cpc" x1="-2.839" x2="2.875" y1="-6.936" y2="1.017"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="cpl" x1="-53.331" x2="6.771" y1="-30.517" y2="18.785" gradientTransform="scale(.99898 1.001)" gradientUnits="userSpaceOnUse" xlink:href="#cpd"/><linearGradient id="cpd" x1="-8.212" x2="1.02" y1="-4.691" y2="2.882"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="cpm" x1="-14.029" x2="41.998" y1="-23.111" y2="26.259" gradientTransform="scale(1.0003 .99965)" gradientUnits="userSpaceOnUse" xlink:href="#cpe"/><linearGradient id="cpe" x1="-1.404" x2="4.19" y1="-2.309" y2="2.62"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="cpn" x1="31.177" x2="3.37" y1="41.442" y2="3.402" gradientTransform="scale(.96254 1.0389)" gradientUnits="userSpaceOnUse" xlink:href="#cpf"/><linearGradient id="cpf" x1="1.911" x2=".204" y1="2.539" y2=".204"><stop stop-color="#6E4D9B" offset="0"/><stop stop-color="#77327A" offset=".14"/><stop stop-color="#B31777" offset=".29"/><stop stop-color="#CD0F7E" offset=".84"/><stop stop-color="#ED2C89" offset="1"/></linearGradient><linearGradient id="cpo" x1="-31.905" x2="19.599" y1="-14.258" y2="42.767" gradientTransform="scale(.95823 1.0436)" gradientUnits="userSpaceOnUse" xlink:href="#cpg"/><linearGradient id="cpg" x1="-3.881" x2="2.377" y1="-1.738" y2="5.19"><stop stop-color="#C06FBB" offset="0"/><stop stop-color="#6E4D9B" offset="1"/></linearGradient><linearGradient id="cpp" x1="4.301" x2="34.534" y1="34.41" y2="4.514" gradientTransform="scale(1.002 .99796)" gradientUnits="userSpaceOnUse" xlink:href="#cph"/><linearGradient id="cph" x1=".112" x2=".901" y1=".897" y2=".116"><stop stop-color="#6E4D9B" offset="0"/><stop stop-color="#77327A" offset=".14"/><stop stop-color="#B31777" offset=".53"/><stop stop-color="#CD0F7E" offset=".79"/><stop stop-color="#ED2C89" offset="1"/></linearGradient></defs><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#f06292" fill-rule="nonzero"/><g transform="matrix(.31022 .0619 -.0619 .31022 11.807 7.546)" fill="none"><path d="M8.002 6.127L4.117 8.719.116 2.723 4 .13z" transform="rotate(-11.284 17.839 -78.732)" fill="url(#cpi)"/><path d="M9.179 1.887l6.637 9.946-7.906 5.276-6.637-9.946L.115 5.43 8.02.153z" transform="rotate(-11.284 129.49 -99.884)" fill="url(#cpj)"/><path d="M7.3 1.88l1.462 2.189-6.018 4.015L.124 4.16l1.315-.877L6.143.144z" transform="rotate(-11.284 167.2 -62.32)" fill="url(#cpk)"/><path d="M2.328 1.146L4.016.02l2.619 3.925L2.75 6.537 1.29 4.347l2.197-1.466zm-1.04 3.201L.132 2.612l2.197-1.466 1.158 1.735z" transform="rotate(-11.284 104.37 -149.22)" fill="url(#cpl)"/><path d="M5.346 9.155l-1.315.877L.03 4.035 6.047.019l2.805 4.204L4.15 7.36l4.703-3.138 1.197 1.793z" transform="rotate(-11.284 81.819 7.645)" fill="url(#cpm)"/><path d="M14.533 9.934l1.197 1.793-7.907 5.276-1.196-1.793L.052 5.358 7.958.082z" transform="rotate(-11.284 17.141 -7.825)" fill="url(#cpn)"/><path d="M6.235 7.177L4.038 8.643 2.84 6.849.036 2.646 3.92.053 7.923 6.05z" transform="rotate(-11.284 18.188 -79.174)" fill="url(#cpo)"/><path d="M18.955 35.925L17.48 34.45l3.998-3.998 1.475 1.475z" fill="#714896"/><path d="M33.33 21.55l-1.475-1.474 1.867-1.868 1.475 1.475z" fill="#6f4795"/><path d="M7.12 24.09l-1.525-1.525 3.998-3.998 1.525 1.525z" fill="#88519f"/><path d="M21.495 9.714L19.97 8.19l1.868-1.868 1.524 1.525z" fill="#85509e"/><path d="M31.418 23.462l-6.72 6.72-1.475-1.474 6.72-6.721z" fill="#8d166a"/><path d="M18.058 10.101l1.525 1.525-6.721 6.72-1.525-1.524z" fill="#a70d6f"/><path d="M2.375 11.769l1.9 1.9-1.9 1.901-1.901-1.9z" fill="#9e61ad"/><path d="M15.523 36.482l1.9 1.9-1.9 1.901-1.9-1.9z" fill="#8053a3"/><path d="M8.372 38.294L.017 29.876 29.749.08l8.636 8.201z" transform="translate(1.823 1.548)" fill="url(#cpp)"/></g></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-components" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#cddc39" fill-rule="nonzero"/><path d="M11.185 9.613h5.346v2.9l3.782-3.775 3.775 3.775-3.775 3.782h2.9v5.346h-5.346v-5.346h2.446l-3.782-3.782v2.446h-5.346V9.613m0 6.682h5.346v5.346h-5.346z" fill="#f0f4c3" stroke-width=".668"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-components-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#cddc39"/><path d="M11.185 9.613h5.346v2.9l3.782-3.775 3.775 3.775-3.775 3.782h2.9v5.346h-5.346v-5.346h2.446l-3.782-3.782v2.446h-5.346V9.613m0 6.682h5.346v5.346h-5.346z" fill="#f0f4c3" stroke-width=".668"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-config" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#00acc1" fill-rule="nonzero"/><path d="M17.293 17.786a2.308 2.308 0 0 1-2.308-2.308 2.308 2.308 0 0 1 2.308-2.307 2.308 2.308 0 0 1 2.308 2.307 2.308 2.308 0 0 1-2.308 2.308m4.899-1.668c.026-.211.046-.422.046-.64 0-.217-.02-.435-.046-.659l1.391-1.075a.333.333 0 0 0 .08-.422l-1.32-2.28c-.079-.146-.257-.205-.402-.146l-1.641.66a4.779 4.779 0 0 0-1.115-.647l-.244-1.747a.333.333 0 0 0-.33-.277h-2.637a.333.333 0 0 0-.33.277l-.243 1.747a4.78 4.78 0 0 0-1.114.646l-1.642-.659a.324.324 0 0 0-.402.145l-1.319 2.281a.325.325 0 0 0 .08.422l1.39 1.075c-.026.224-.046.442-.046.66s.02.428.046.639l-1.39 1.094a.325.325 0 0 0-.08.422l1.319 2.282c.079.145.257.197.402.145l1.642-.666c.342.264.698.488 1.114.653l.244 1.747a.333.333 0 0 0 .33.277h2.637a.333.333 0 0 0 .33-.277l.243-1.747a4.802 4.802 0 0 0 1.115-.653l1.641.666c.145.052.323 0 .403-.145l1.318-2.282a.333.333 0 0 0-.079-.422z" fill="#80deea" stroke-width=".659"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-config-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#00acc1"/><path d="M17.293 17.786a2.308 2.308 0 0 1-2.308-2.308 2.308 2.308 0 0 1 2.308-2.307 2.308 2.308 0 0 1 2.308 2.307 2.308 2.308 0 0 1-2.308 2.308m4.899-1.668c.026-.211.046-.422.046-.64 0-.217-.02-.435-.046-.659l1.391-1.075a.333.333 0 0 0 .08-.422l-1.32-2.28c-.079-.146-.257-.205-.402-.146l-1.641.66a4.779 4.779 0 0 0-1.115-.647l-.244-1.747a.333.333 0 0 0-.33-.277h-2.637a.333.333 0 0 0-.33.277l-.243 1.747a4.78 4.78 0 0 0-1.114.646l-1.642-.659a.324.324 0 0 0-.402.145l-1.319 2.281a.325.325 0 0 0 .08.422l1.39 1.075c-.026.224-.046.442-.046.66s.02.428.046.639l-1.39 1.094a.325.325 0 0 0-.08.422l1.319 2.282c.079.145.257.197.402.145l1.642-.666c.342.264.698.488 1.114.653l.244 1.747a.333.333 0 0 0 .33.277h2.637a.333.333 0 0 0 .33-.277l.243-1.747a4.802 4.802 0 0 0 1.115-.653l1.641.666c.145.052.323 0 .403-.145l1.318-2.282a.333.333 0 0 0-.079-.422z" fill="#80deea" stroke-width=".659"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-css" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#42a5f5" fill-rule="nonzero"/><path d="M12.488 9.415l-.44 2.259h9.188l-.298 1.46h-9.18l-.447 2.251H20.5l-.514 2.576-3.705 1.224-3.211-1.224.223-1.109h-2.258l-.534 2.704 5.307 2.029 6.118-2.029.812-4.076.162-.818 1.041-5.247H12.488z" fill-rule="nonzero" fill="#bbdefb"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-css-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#42a5f5" fill-rule="nonzero"/><path d="M12.488 9.415l-.44 2.259h9.188l-.298 1.46h-9.18l-.447 2.251H20.5l-.514 2.576-3.705 1.224-3.211-1.224.223-1.109h-2.258l-.534 2.704 5.307 2.029 6.118-2.029.812-4.076.162-.818 1.041-5.247H12.488z" fill-rule="nonzero" fill="#bbdefb"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-dist" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#e57373" fill-rule="nonzero"/><path d="M18.575 11.113h-2.576V9.825h2.576m3.864 1.288h-2.576V9.825l-1.288-1.288h-2.576L14.71 9.825v1.288h-2.577c-.715 0-1.288.573-1.288 1.288v7.085a1.288 1.288 0 0 0 1.288 1.288H22.44a1.288 1.288 0 0 0 1.288-1.288V12.4c0-.715-.58-1.288-1.288-1.288z" fill="#ffcdd2" stroke-width=".644"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-dist-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#e57373"/><path d="M18.575 11.113h-2.576V9.825h2.576m3.864 1.288h-2.576V9.825l-1.288-1.288h-2.576L14.71 9.825v1.288h-2.577c-.715 0-1.288.573-1.288 1.288v7.085a1.288 1.288 0 0 0 1.288 1.288H22.44a1.288 1.288 0 0 0 1.288-1.288V12.4c0-.715-.58-1.288-1.288-1.288z" fill="#ffcdd2" fill-rule="evenodd" stroke-width=".644"/></symbol><symbol id="folder-docker" clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><defs id="cydefs10"><path id="cySVGID_2_" d="M8.7 24c-1.1 0-2.1-.9-2.1-2s.9-2 2.1-2 2.1.9 2.1 2-1 2-2.1 2zm25.8-10.9c-.2-1.6-1.2-2.9-2.5-3.9l-.5-.4-.4.5c-.8.9-1.1 2.5-1 3.7.1.9.4 1.8.9 2.5-.4.2-.9.4-1.3.6-.9.3-1.8.4-2.7.4H1.1l-.1.6c-.2 1.9.1 3.9.9 5.7l.4.7v.1c2.4 4 6.7 5.8 11.4 5.8 9 0 16.4-3.9 19.9-12.3 2.3.1 4.6-.5 5.7-2.7l.3-.5-.5-.3c-1.3-.8-3.1-.9-4.6-.5zm-12.9-1.6h-3.9v3.9h3.9zm0-4.9h-3.9v3.9h3.9zm0-5h-3.9v3.9h3.9zm4.8 9.9h-3.9v3.9h3.9zm-14.5 0H8v3.9h3.9zm4.9 0h-3.9v3.9h3.9zm-9.7 0H3.2v3.9h3.9zm9.7-4.9h-3.9v3.9h3.9zm-4.9 0H8v3.9h3.9z"/></defs><path id="cypath2" d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#039be5" fill-rule="nonzero"/><style id="cystyle2">.cyst0{fill:#fff}.cyst1{clip-path:url(#cySVGID_4_)}</style><g id="cyg34" transform="translate(8.319 9.626) scale(.39491)" fill="#b3e5fc"><g id="cyg32"><g id="cyg30"><title id="cytitle4">Group 3</title><g id="cyg28"><g id="cyg26"><g id="cyg9"><path id="cySVGID_1_" class="cyst0" d="M8.7 24c-1.1 0-2.1-.9-2.1-2s.9-2 2.1-2 2.1.9 2.1 2-1 2-2.1 2zm25.8-10.9c-.2-1.6-1.2-2.9-2.5-3.9l-.5-.4-.4.5c-.8.9-1.1 2.5-1 3.7.1.9.4 1.8.9 2.5-.4.2-.9.4-1.3.6-.9.3-1.8.4-2.7.4H1.1l-.1.6c-.2 1.9.1 3.9.9 5.7l.4.7v.1c2.4 4 6.7 5.8 11.4 5.8 9 0 16.4-3.9 19.9-12.3 2.3.1 4.6-.5 5.7-2.7l.3-.5-.5-.3c-1.3-.8-3.1-.9-4.6-.5zm-12.9-1.6h-3.9v3.9h3.9zm0-4.9h-3.9v3.9h3.9zm0-5h-3.9v3.9h3.9zm4.8 9.9h-3.9v3.9h3.9zm-14.5 0H8v3.9h3.9zm4.9 0h-3.9v3.9h3.9zm-9.7 0H3.2v3.9h3.9zm9.7-4.9h-3.9v3.9h3.9zm-4.9 0H8v3.9h3.9z"/></g><g id="cyg24"><clipPath id="cySVGID_4_"><use id="cyuse14" width="100%" height="100%" xlink:href="#cySVGID_2_"/></clipPath><g id="cyg22" class="cyst1" clip-path="url(#cySVGID_4_)"><g id="cyg20"><g id="cyg18"><path id="cySVGID_3_" class="cyst0" d="M-48.8-21H1226v151.4H-48.8z"/></g></g></g></g></g></g></g></g></g></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-docker-open" xmlns="http://www.w3.org/2000/svg"><defs><clipPath id="cza"><use width="100%" height="100%" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#SVGID_2_"/></clipPath></defs><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#039be5"/><g transform="matrix(.3949 0 0 .39489 8.319 9.626)" fill="#b3e5fc"><title>Group 3</title><path class="czst0" d="M8.7 24c-1.1 0-2.1-.9-2.1-2s.9-2 2.1-2 2.1.9 2.1 2-1 2-2.1 2zm25.8-10.9c-.2-1.6-1.2-2.9-2.5-3.9l-.5-.4-.4.5c-.8.9-1.1 2.5-1 3.7.1.9.4 1.8.9 2.5-.4.2-.9.4-1.3.6-.9.3-1.8.4-2.7.4H1.1l-.1.6c-.2 1.9.1 3.9.9 5.7l.4.7v.1c2.4 4 6.7 5.8 11.4 5.8 9 0 16.4-3.9 19.9-12.3 2.3.1 4.6-.5 5.7-2.7l.3-.5-.5-.3c-1.3-.8-3.1-.9-4.6-.5zm-12.9-1.6h-3.9v3.9h3.9zm0-4.9h-3.9v3.9h3.9zm0-5h-3.9v3.9h3.9zm4.8 9.9h-3.9v3.9h3.9zm-14.5 0H8v3.9h3.9zm4.9 0h-3.9v3.9h3.9zm-9.7 0H3.2v3.9h3.9zm9.7-4.9h-3.9v3.9h3.9zm-4.9 0H8v3.9h3.9z"/><g class="czst1" clip-path="url(#cza)"><path class="czst0" d="M-48.8-21H1226v151.4H-48.8z"/></g></g></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-docs" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#0277bd" fill-rule="nonzero"/><path d="M18.575 12.859h3.713l-3.713-3.713v3.713M13.85 8.134h5.4l4.05 4.05v8.1c0 .74-.61 1.35-1.35 1.35h-8.1a1.35 1.35 0 0 1-1.35-1.35v-10.8c0-.75.6-1.35 1.35-1.35m6.075 10.8v-1.35H13.85v1.35h6.075m2.025-2.7v-1.35h-8.1v1.35h8.1z" fill-rule="nonzero" fill="#b3e5fc"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-docs-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#0277bd" fill-rule="nonzero"/><path d="M18.575 12.859h3.713l-3.713-3.713v3.713M13.85 8.134h5.4l4.05 4.05v8.1c0 .74-.61 1.35-1.35 1.35h-8.1a1.35 1.35 0 0 1-1.35-1.35v-10.8c0-.75.6-1.35 1.35-1.35m6.075 10.8v-1.35H13.85v1.35h6.075m2.025-2.7v-1.35h-8.1v1.35h8.1z" fill-rule="nonzero" fill="#b3e5fc"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-expo" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#01579b" fill-rule="nonzero"/><style>.dcst0{fill:#1173b6}.st1{fill:#585d67}</style><path class="dcst0" d="M18.575 9.82c-.489-.745-.605-.844-1.6-.844h-.024c-.996 0-1.106.099-1.601.844-.46.699-5.024 9.058-5.024 9.291 0 .338.087.658.402 1.112.32.46.873.716 1.275.309.273-.274 3.201-5.321 4.616-7.23a.425.425 0 0 1 .693 0c1.414 1.909 4.343 6.956 4.616 7.23.402.407.955.15 1.275-.309.314-.454.402-.774.402-1.112-.006-.233-4.57-8.598-5.03-9.291z" fill="#1173b6" stroke-width=".058"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-expo-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#01579b"/><path class="ddst0" d="M18.575 9.82c-.489-.745-.605-.844-1.6-.844h-.024c-.996 0-1.106.099-1.601.844-.46.699-5.024 9.058-5.024 9.291 0 .338.087.658.402 1.112.32.46.873.716 1.275.309.273-.274 3.201-5.321 4.616-7.23a.425.425 0 0 1 .693 0c1.414 1.909 4.343 6.956 4.616 7.23.402.407.955.15 1.275-.309.314-.454.402-.774.402-1.112-.006-.233-4.57-8.598-5.03-9.291z" fill="#1173b6" stroke-width=".058" fill-rule="evenodd"/></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="folder-font" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#ef9a9a" fill-rule="nonzero"/><path d="M14.62 17.403l2.38-6.33 2.37 6.33m-3.37-9l-5.5 14h2.25l1.12-3h6.25l1.13 3h2.25l-5.5-14h-2z" fill="#f44336" fill-rule="nonzero"/></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="folder-font-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#ef9a9a" fill-rule="nonzero"/><path d="M14.62 17.403l2.38-6.33 2.37 6.33m-3.37-9l-5.5 14h2.25l1.12-3h6.25l1.13 3h2.25l-5.5-14h-2z" fill="#f44336" fill-rule="nonzero"/></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="folder-git" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#ff8a65" fill-rule="nonzero"/><path d="M10.43 14.14l4.044-4.052 1.183 1.19a1.387 1.387 0 0 0 .65 1.56v3.877c-.42.238-.699.693-.699 1.21 0 .768.632 1.4 1.4 1.4.767 0 1.4-.632 1.4-1.4 0-.517-.28-.972-.7-1.21v-3.4l1.448 1.462c-.05.105-.05.224-.05.35 0 .767.633 1.399 1.4 1.399.768 0 1.4-.632 1.4-1.4 0-.767-.632-1.4-1.4-1.4-.126 0-.245 0-.35.05l-1.798-1.799a1.385 1.385 0 0 0-.805-1.637c-.3-.112-.615-.14-.895-.063l-1.19-1.183.553-.545a1.381 1.381 0 0 1 1.973 0l5.591 5.59a1.381 1.381 0 0 1 0 1.974l-5.59 5.591a1.381 1.381 0 0 1-1.974 0l-5.591-5.59a1.381 1.381 0 0 1 0-1.974z" fill="#e64a19" fill-rule="nonzero"/></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="folder-git-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#ff8a65" fill-rule="nonzero"/><path d="M10.43 14.14l4.044-4.052 1.183 1.19a1.387 1.387 0 0 0 .65 1.56v3.877c-.42.238-.699.693-.699 1.21 0 .768.632 1.4 1.4 1.4.767 0 1.4-.632 1.4-1.4 0-.517-.28-.972-.7-1.21v-3.4l1.448 1.462c-.05.105-.05.224-.05.35 0 .767.633 1.399 1.4 1.399.768 0 1.4-.632 1.4-1.4 0-.767-.632-1.4-1.4-1.4-.126 0-.245 0-.35.05l-1.798-1.799a1.385 1.385 0 0 0-.805-1.637c-.3-.112-.615-.14-.895-.063l-1.19-1.183.553-.545a1.381 1.381 0 0 1 1.973 0l5.591 5.59a1.381 1.381 0 0 1 0 1.974l-5.59 5.591a1.381 1.381 0 0 1-1.974 0l-5.591-5.59a1.381 1.381 0 0 1 0-1.974z" fill="#e64a19" fill-rule="nonzero"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-global" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#5c6bc0" fill-rule="nonzero"/><path d="M21.132 18.585a1.22 1.22 0 0 0-1.156-.846h-.609v-1.825a.608.608 0 0 0-.608-.609h-3.65v-1.217h1.216a.608.608 0 0 0 .609-.608v-1.217h1.217a1.217 1.217 0 0 0 1.216-1.217v-.25a4.858 4.858 0 0 1 1.765 7.79m-4.198 1.545a4.86 4.86 0 0 1-4.26-4.826c0-.377.049-.742.128-1.089l2.915 2.915v.608a1.217 1.217 0 0 0 1.217 1.217m.608-9.735a6.085 6.085 0 0 0-6.085 6.084 6.085 6.085 0 0 0 6.085 6.085 6.085 6.085 0 0 0 6.085-6.085 6.085 6.085 0 0 0-6.085-6.084z" fill="#c5cae9" stroke-width=".608"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-global-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#5c6bc0"/><path d="M21.133 18.585a1.22 1.22 0 0 0-1.156-.846h-.609v-1.825a.608.608 0 0 0-.608-.609h-3.65v-1.217h1.216a.608.608 0 0 0 .609-.608v-1.217h1.217a1.217 1.217 0 0 0 1.216-1.217v-.25a4.858 4.858 0 0 1 1.765 7.79m-4.198 1.545a4.86 4.86 0 0 1-4.26-4.826c0-.377.049-.742.128-1.089l2.915 2.915v.608a1.217 1.217 0 0 0 1.216 1.217m.609-9.735a6.085 6.085 0 0 0-6.085 6.084 6.085 6.085 0 0 0 6.085 6.085 6.085 6.085 0 0 0 6.085-6.085 6.085 6.085 0 0 0-6.085-6.084z" fill="#c5cae9" stroke-width=".608"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-i18n" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#5c6bc0" fill-rule="nonzero"/><path d="M17.293 17.786l-1.53-1.512.018-.018a10.555 10.555 0 0 0 2.235-3.934h1.765v-1.205h-4.217V9.912h-1.205v1.205h-4.217v1.205h6.73a9.5 9.5 0 0 1-1.91 3.223 9.424 9.424 0 0 1-1.392-2.018h-1.205c.44.982 1.042 1.91 1.795 2.747l-3.067 3.024.856.856 3.012-3.013 1.874 1.874.458-1.229m3.392-3.054H19.48l-2.711 7.23h1.205l.674-1.808h2.862l.68 1.807h1.206l-2.711-7.23m-1.579 4.218l.976-2.609.976 2.609z" fill="#c5cae9" stroke-width=".602"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-i18n-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#5c6bc0"/><path d="M17.293 17.786l-1.53-1.512.018-.018a10.555 10.555 0 0 0 2.235-3.934h1.765v-1.205h-4.217V9.912h-1.205v1.205h-4.217v1.205h6.73a9.5 9.5 0 0 1-1.91 3.223 9.424 9.424 0 0 1-1.392-2.018h-1.205c.44.982 1.042 1.91 1.795 2.747l-3.067 3.024.856.856 3.012-3.013 1.874 1.874.458-1.229m3.392-3.054H19.48l-2.711 7.23h1.205l.674-1.808h2.862l.68 1.807h1.206l-2.711-7.23m-1.579 4.218l.976-2.609.976 2.609z" fill="#c5cae9" stroke-width=".602"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-images" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#009688" fill-rule="nonzero"/><path d="M18.575 12.859h3.713l-3.713-3.713v3.713M13.85 8.134h5.4l4.05 4.05v8.1c0 .74-.61 1.35-1.35 1.35h-8.1a1.35 1.35 0 0 1-1.35-1.35v-10.8c0-.75.6-1.35 1.35-1.35m0 12.15h8.1v-5.4l-2.7 2.7-1.35-1.35-4.05 4.05m1.35-7.425c-.74 0-1.35.61-1.35 1.35s.61 1.35 1.35 1.35 1.35-.61 1.35-1.35-.61-1.35-1.35-1.35z" fill-rule="nonzero" fill="#b2dfdb"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-images-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#009688" fill-rule="nonzero"/><path d="M18.575 12.859h3.713l-3.713-3.713v3.713M13.85 8.134h5.4l4.05 4.05v8.1c0 .74-.61 1.35-1.35 1.35h-8.1a1.35 1.35 0 0 1-1.35-1.35v-10.8c0-.75.6-1.35 1.35-1.35m0 12.15h8.1v-5.4l-2.7 2.7-1.35-1.35-4.05 4.05m1.35-7.425c-.74 0-1.35.61-1.35 1.35s.61 1.35 1.35 1.35 1.35-.61 1.35-1.35-.61-1.35-1.35-1.35z" fill-rule="nonzero" fill="#b2dfdb"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-include" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#039be5" fill-rule="nonzero"/><path d="M20.788 15.981h-2.434v2.434h-1.217V15.98h-2.434v-1.217h2.434V12.33h1.217v2.434h2.434m-3.042-5.476a6.085 6.085 0 0 0-6.085 6.084 6.085 6.085 0 0 0 6.085 6.085 6.085 6.085 0 0 0 6.084-6.085 6.085 6.085 0 0 0-6.084-6.084z" fill="#b3e5fc" stroke-width=".608"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-include-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#039be5"/><path d="M20.788 15.981h-2.434v2.434h-1.217V15.98h-2.434v-1.217h2.434V12.33h1.217v2.434h2.434m-3.042-5.476a6.085 6.085 0 0 0-6.085 6.084 6.085 6.085 0 0 0 6.085 6.085 6.085 6.085 0 0 0 6.084-6.085 6.085 6.085 0 0 0-6.084-6.084z" fill="#b3e5fc" stroke-width=".608"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-javascript" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#ffca28" fill-rule="nonzero"/><path d="M17.935 18.374a2.18 2.18 0 0 0 1.972 1.213c.829 0 1.354-.415 1.354-.987 0-.682-.542-.927-1.452-1.324l-.502-.216c-1.435-.613-2.404-1.378-2.404-3.005 0-1.5 1.167-2.638 2.917-2.638a2.957 2.957 0 0 1 2.842 1.599l-1.552.999a1.362 1.362 0 0 0-1.29-.858.873.873 0 0 0-.957.858c0 .583.374.84 1.226 1.213l.502.216c1.697.733 2.654 1.47 2.654 3.139 0 1.798-1.411 2.783-3.308 2.783a3.839 3.839 0 0 1-3.618-2.046zm-7.048.175c.315.583.583 1.027 1.283 1.027s1.066-.256 1.066-1.255v-6.774h1.998v6.804c0 2.064-1.214 3.01-2.982 3.01a3.104 3.104 0 0 1-2.993-1.826z" fill-rule="nonzero" fill="#ffecb3"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-javascript-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#ffca28"/><path d="M17.935 18.374a2.18 2.18 0 0 0 1.972 1.213c.829 0 1.354-.415 1.354-.987 0-.682-.542-.927-1.452-1.324l-.502-.216c-1.435-.613-2.404-1.378-2.404-3.005 0-1.5 1.167-2.638 2.917-2.638a2.957 2.957 0 0 1 2.842 1.599l-1.552.999a1.362 1.362 0 0 0-1.29-.858.873.873 0 0 0-.957.858c0 .583.374.84 1.226 1.213l.502.216c1.697.733 2.654 1.47 2.654 3.139 0 1.798-1.412 2.783-3.308 2.783a3.839 3.839 0 0 1-3.618-2.046zm-7.048.175c.315.583.583 1.027 1.283 1.027s1.066-.256 1.066-1.255v-6.774h1.998v6.804c0 2.064-1.214 3.01-2.982 3.01a3.104 3.104 0 0 1-2.993-1.826z" fill="#ffecb3"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-lib" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#c0ca33" fill-rule="nonzero"/><path d="M17.39 12.544a2.05 2.05 0 0 0 2.05-2.05 2.05 2.05 0 0 0-2.05-2.052 2.05 2.05 0 0 0-2.05 2.051 2.05 2.05 0 0 0 2.05 2.051m0 2.42a8.992 8.992 0 0 0-6.152-2.42v7.52c2.392 0 4.539.923 6.152 2.42a8.992 8.992 0 0 1 6.152-2.42v-7.52c-2.392 0-4.539.923-6.152 2.42z" fill="#f0f4c3" stroke-width=".684"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-lib-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#c0ca33"/><path d="M17.391 12.543a2.05 2.05 0 0 0 2.05-2.05 2.05 2.05 0 0 0-2.05-2.052 2.05 2.05 0 0 0-2.05 2.051 2.05 2.05 0 0 0 2.05 2.051m0 2.42a8.992 8.992 0 0 0-6.152-2.42v7.52c2.392 0 4.539.923 6.152 2.42a8.992 8.992 0 0 1 6.152-2.42v-7.52c-2.392 0-4.539.923-6.152 2.42z" fill="#f0f4c3" stroke-width=".684"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-ngrx-actions" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#ab47bc" fill-rule="nonzero"/><path d="M17.655 8.39l-6.152 2.193.933 8.142 5.219 2.888 5.219-2.888.932-8.142zm-1.278 2.067c.234-.004.487.07.768.223.124.066.498.16.83.21 1.183.17 2.586 1.073 3.03 1.95.306.602.243.927-.225 1.169-.404.209-1.23.108-2.43-.297l-1.012-.342-.36.137c-.522.2-1.044.694-1.258 1.19-.154.359-.177.527-.149 1.116.028.59.071.761.28 1.132.239.422.786.96.88.866.026-.026-.03-.197-.124-.38-.093-.183-.148-.368-.122-.41.026-.042.273.114.548.347.611.518 1.326.848 1.981.917.538.056.661-.044.258-.211a1.238 1.238 0 0 1-.374-.25c-.157-.173-.166-.168.504-.318.417-.094 1.24-.531 1.29-.685.016-.05-.118-.07-.338-.053-.2.016-.363-.004-.363-.046 0-.04.164-.243.363-.451.748-.781 1.004-1.365 1.083-2.474l.055-.767.176.365c.194.401.23.98.091 1.478-.115.416-.038.462.173.104.261-.443.345-.373.299.251-.05.678-.283 1.187-.808 1.762-.429.468-.377.552.141.233.5-.308.567-.26.31.224-.487.914-1.516 1.69-2.585 1.948-.647.158-1.106.187-1.7.11-1.55-.204-3.018-1.249-3.718-2.648a8.736 8.736 0 0 0-.572-.989c-.275-.373-.298-.54-.113-.823.093-.141.114-.286.076-.502-.176-.999-.17-1.03.23-1.437.35-.353.371-.4.371-.813 0-.358.036-.475.198-.637.109-.108.282-.199.384-.2.296-.003.807-.277 1.11-.595.252-.265.52-.4.822-.404z" fill="#e1bee7" stroke-width=".696"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-ngrx-actions-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#ab47bc"/><path d="M17.655 8.39l-6.152 2.192.933 8.143 5.219 2.888 5.219-2.888.932-8.143zm-1.278 2.067c.234-.004.487.07.768.222.124.067.498.162.83.21 1.183.171 2.586 1.074 3.03 1.95.306.603.243.928-.225 1.17-.404.208-1.23.107-2.43-.298l-1.012-.341-.36.137c-.522.2-1.044.694-1.258 1.19-.154.359-.177.527-.149 1.116.028.59.071.761.28 1.132.239.422.786.96.88.866.026-.026-.03-.197-.124-.38-.093-.183-.148-.368-.122-.41.026-.042.273.114.548.347.611.517 1.326.848 1.981.917.538.056.661-.044.258-.211a1.238 1.238 0 0 1-.374-.25c-.157-.173-.166-.168.504-.318.417-.094 1.24-.531 1.29-.685.016-.05-.118-.07-.338-.053-.2.016-.363-.005-.363-.046 0-.04.164-.243.363-.452.748-.78 1.004-1.364 1.083-2.474l.055-.766.176.364c.194.402.23.981.091 1.479-.115.416-.038.462.173.103.261-.442.345-.372.299.252-.05.678-.283 1.186-.808 1.761-.429.47-.377.553.141.234.5-.308.567-.26.31.224-.487.914-1.516 1.689-2.585 1.948-.647.158-1.106.187-1.7.109-1.55-.203-3.018-1.248-3.718-2.647a8.736 8.736 0 0 0-.572-.989c-.275-.373-.298-.54-.113-.823.093-.142.114-.286.076-.502-.176-.999-.17-1.03.23-1.437.35-.353.371-.4.371-.813 0-.358.036-.475.198-.637.109-.109.282-.2.384-.2.296-.003.807-.277 1.11-.595.252-.265.52-.4.822-.404z" fill="#e1bee7" stroke-width=".696"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-ngrx-effects" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#00bcd4" fill-rule="nonzero"/><path d="M17.655 8.39l-6.152 2.193.933 8.142 5.219 2.888 5.219-2.888.932-8.142zm-1.278 2.067c.234-.004.487.07.768.223.124.066.498.16.83.21 1.183.17 2.586 1.073 3.03 1.95.306.602.243.927-.225 1.169-.404.209-1.23.108-2.43-.297l-1.012-.342-.36.137c-.522.2-1.044.694-1.258 1.19-.154.359-.177.527-.149 1.116.028.59.071.761.28 1.132.239.422.786.96.88.866.026-.026-.03-.197-.124-.38-.093-.183-.148-.368-.122-.41.026-.042.273.114.548.347.611.518 1.326.848 1.981.917.538.056.661-.044.258-.211a1.238 1.238 0 0 1-.374-.25c-.157-.173-.166-.168.504-.318.417-.094 1.24-.531 1.29-.685.016-.05-.118-.07-.338-.053-.2.016-.363-.004-.363-.046 0-.04.164-.243.363-.451.748-.781 1.004-1.365 1.083-2.474l.055-.767.176.365c.194.401.23.98.091 1.478-.115.416-.038.462.173.104.261-.443.345-.373.299.251-.05.678-.283 1.187-.808 1.762-.429.468-.377.552.141.233.5-.308.567-.26.31.224-.487.914-1.516 1.69-2.585 1.948-.647.158-1.106.187-1.7.11-1.55-.204-3.018-1.249-3.718-2.648a8.736 8.736 0 0 0-.572-.989c-.275-.373-.298-.54-.113-.823.093-.141.114-.286.076-.502-.176-.999-.17-1.03.23-1.437.35-.353.371-.4.371-.813 0-.358.036-.475.198-.637.109-.108.282-.199.384-.2.296-.003.807-.277 1.11-.595.252-.265.52-.4.822-.404z" fill="#b2ebf2" stroke-width=".696"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-ngrx-effects-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#00bcd4"/><path d="M17.655 8.39l-6.152 2.192.933 8.143 5.219 2.888 5.219-2.888.932-8.143zm-1.278 2.067c.234-.004.487.07.768.222.124.067.498.162.83.21 1.183.171 2.586 1.074 3.03 1.95.306.603.243.928-.225 1.17-.404.208-1.23.107-2.43-.298l-1.012-.341-.36.137c-.522.2-1.044.694-1.258 1.19-.154.359-.177.527-.149 1.116.028.59.071.761.28 1.132.239.422.786.96.88.866.026-.026-.03-.197-.124-.38-.093-.183-.148-.368-.122-.41.026-.042.273.114.548.347.611.517 1.326.848 1.981.917.538.056.661-.044.258-.211a1.238 1.238 0 0 1-.374-.25c-.157-.173-.166-.168.504-.318.417-.094 1.24-.531 1.29-.685.016-.05-.118-.07-.338-.053-.2.016-.363-.005-.363-.046 0-.04.164-.243.363-.452.748-.78 1.004-1.364 1.083-2.474l.055-.766.176.364c.194.402.23.981.091 1.479-.115.416-.038.462.173.103.261-.442.345-.372.299.252-.05.678-.283 1.186-.808 1.761-.429.47-.377.553.141.234.5-.308.567-.26.31.224-.487.914-1.516 1.689-2.585 1.948-.647.158-1.106.187-1.7.109-1.55-.203-3.018-1.248-3.718-2.647a8.736 8.736 0 0 0-.572-.989c-.275-.373-.298-.54-.113-.823.093-.142.114-.286.076-.502-.176-.999-.17-1.03.23-1.437.35-.353.371-.4.371-.813 0-.358.036-.475.198-.637.109-.109.282-.2.384-.2.296-.003.807-.277 1.11-.595.252-.265.52-.4.822-.404z" fill="#b2ebf2" stroke-width=".696"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-ngrx-reducer" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#ef5350" fill-rule="nonzero"/><path d="M17.655 8.39l-6.152 2.193.933 8.142 5.219 2.888 5.219-2.888.932-8.142zm-1.278 2.067c.234-.004.487.07.768.223.124.066.498.16.83.21 1.183.17 2.586 1.073 3.03 1.95.306.602.243.927-.225 1.169-.404.209-1.23.108-2.43-.297l-1.012-.342-.36.137c-.522.2-1.044.694-1.258 1.19-.154.359-.177.527-.149 1.116.028.59.071.761.28 1.132.239.422.786.96.88.866.026-.026-.03-.197-.124-.38-.093-.183-.148-.368-.122-.41.026-.042.273.114.548.347.611.518 1.326.848 1.981.917.538.056.661-.044.258-.211a1.238 1.238 0 0 1-.374-.25c-.157-.173-.166-.168.504-.318.417-.094 1.24-.531 1.29-.685.016-.05-.118-.07-.338-.053-.2.016-.363-.004-.363-.046 0-.04.164-.243.363-.451.748-.781 1.004-1.365 1.083-2.474l.055-.767.176.365c.194.401.23.98.091 1.478-.115.416-.038.462.173.104.261-.443.345-.373.299.251-.05.678-.283 1.187-.808 1.762-.429.468-.377.552.141.233.5-.308.567-.26.31.224-.487.914-1.516 1.69-2.585 1.948-.647.158-1.106.187-1.7.11-1.55-.204-3.018-1.249-3.718-2.648a8.736 8.736 0 0 0-.572-.989c-.275-.373-.298-.54-.113-.823.093-.141.114-.286.076-.502-.176-.999-.17-1.03.23-1.437.35-.353.371-.4.371-.813 0-.358.036-.475.198-.637.109-.108.282-.199.384-.2.296-.003.807-.277 1.11-.595.252-.265.52-.4.822-.404z" fill="#ffcdd2" stroke-width=".696"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-ngrx-reducer-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#ef5350"/><path d="M17.655 8.39l-6.152 2.192.933 8.143 5.219 2.888 5.219-2.888.932-8.143zm-1.278 2.067c.234-.004.487.07.768.222.124.067.498.162.83.21 1.183.171 2.586 1.074 3.03 1.95.306.603.243.928-.225 1.17-.404.208-1.23.107-2.43-.298l-1.012-.341-.36.137c-.522.2-1.044.694-1.258 1.19-.154.359-.177.527-.149 1.116.028.59.071.761.28 1.132.239.422.786.96.88.866.026-.026-.03-.197-.124-.38-.093-.183-.148-.368-.122-.41.026-.042.273.114.548.347.611.517 1.326.848 1.981.917.538.056.661-.044.258-.211a1.238 1.238 0 0 1-.374-.25c-.157-.173-.166-.168.504-.318.417-.094 1.24-.531 1.29-.685.016-.05-.118-.07-.338-.053-.2.016-.363-.005-.363-.046 0-.04.164-.243.363-.452.748-.78 1.004-1.364 1.083-2.474l.055-.766.176.364c.194.402.23.981.091 1.479-.115.416-.038.462.173.103.261-.442.345-.372.299.252-.05.678-.283 1.186-.808 1.761-.429.47-.377.553.141.234.5-.308.567-.26.31.224-.487.914-1.516 1.689-2.585 1.948-.647.158-1.106.187-1.7.109-1.55-.203-3.018-1.248-3.718-2.647a8.736 8.736 0 0 0-.572-.989c-.275-.373-.298-.54-.113-.823.093-.142.114-.286.076-.502-.176-.999-.17-1.03.23-1.437.35-.353.371-.4.371-.813 0-.358.036-.475.198-.637.109-.109.282-.2.384-.2.296-.003.807-.277 1.11-.595.252-.265.52-.4.822-.404z" fill="#ffcdd2" stroke-width=".696"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-ngrx-state" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#8bc34a" fill-rule="nonzero"/><path d="M17.655 8.39l-6.152 2.193.933 8.142 5.219 2.888 5.219-2.888.932-8.142zm-1.278 2.067c.234-.004.487.07.768.223.124.066.498.16.83.21 1.183.17 2.586 1.073 3.03 1.95.306.602.243.927-.225 1.169-.404.209-1.23.108-2.43-.297l-1.012-.342-.36.137c-.522.2-1.044.694-1.258 1.19-.154.359-.177.527-.149 1.116.028.59.071.761.28 1.132.239.422.786.96.88.866.026-.026-.03-.197-.124-.38-.093-.183-.148-.368-.122-.41.026-.042.273.114.548.347.611.518 1.326.848 1.981.917.538.056.661-.044.258-.211a1.238 1.238 0 0 1-.374-.25c-.157-.173-.166-.168.504-.318.417-.094 1.24-.531 1.29-.685.016-.05-.118-.07-.338-.053-.2.016-.363-.004-.363-.046 0-.04.164-.243.363-.451.748-.781 1.004-1.365 1.083-2.474l.055-.767.176.365c.194.401.23.98.091 1.478-.115.416-.038.462.173.104.261-.443.345-.373.299.251-.05.678-.283 1.187-.808 1.762-.429.468-.377.552.141.233.5-.308.567-.26.31.224-.487.914-1.516 1.69-2.585 1.948-.647.158-1.106.187-1.7.11-1.55-.204-3.018-1.249-3.718-2.648a8.736 8.736 0 0 0-.572-.989c-.275-.373-.298-.54-.113-.823.093-.141.114-.286.076-.502-.176-.999-.17-1.03.23-1.437.35-.353.371-.4.371-.813 0-.358.036-.475.198-.637.109-.108.282-.199.384-.2.296-.003.807-.277 1.11-.595.252-.265.52-.4.822-.404z" fill="#dcedc8" stroke-width=".696"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-ngrx-state-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#8bc34a"/><path d="M17.655 8.39l-6.152 2.192.933 8.143 5.219 2.888 5.219-2.888.932-8.143zm-1.278 2.067c.234-.004.487.07.768.222.124.067.498.162.83.21 1.183.171 2.586 1.074 3.03 1.95.306.603.243.928-.225 1.17-.404.208-1.23.107-2.43-.298l-1.012-.341-.36.137c-.522.2-1.044.694-1.258 1.19-.154.359-.177.527-.149 1.116.028.59.071.761.28 1.132.239.422.786.96.88.866.026-.026-.03-.197-.124-.38-.093-.183-.148-.368-.122-.41.026-.042.273.114.548.347.611.517 1.326.848 1.981.917.538.056.661-.044.258-.211a1.238 1.238 0 0 1-.374-.25c-.157-.173-.166-.168.504-.318.417-.094 1.24-.531 1.29-.685.016-.05-.118-.07-.338-.053-.2.016-.363-.005-.363-.046 0-.04.164-.243.363-.452.748-.78 1.004-1.364 1.083-2.474l.055-.766.176.364c.194.402.23.981.091 1.479-.115.416-.038.462.173.103.261-.442.345-.372.299.252-.05.678-.283 1.186-.808 1.761-.429.47-.377.553.141.234.5-.308.567-.26.31.224-.487.914-1.516 1.689-2.585 1.948-.647.158-1.106.187-1.7.109-1.55-.203-3.018-1.248-3.718-2.647a8.736 8.736 0 0 0-.572-.989c-.275-.373-.298-.54-.113-.823.093-.142.114-.286.076-.502-.176-.999-.17-1.03.23-1.437.35-.353.371-.4.371-.813 0-.358.036-.475.198-.637.109-.109.282-.2.384-.2.296-.003.807-.277 1.11-.595.252-.265.52-.4.822-.404z" fill="#dcedc8" stroke-width=".696"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-node" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#8bc34a" fill-rule="nonzero"/><path d="M17.25 8.403c-.188 0-.382.048-.542.139l-5.166 2.986a1.096 1.096 0 0 0-.542.944v5.959c0 .388.208.75.542.944l1.354.778c.66.32.882.326 1.187.326.973 0 1.535-.59 1.535-1.618V12.98a.154.154 0 0 0-.153-.153h-.646c-.09 0-.16.07-.16.153v5.882c0 .458-.472.91-1.228.528l-1.424-.813a.181.181 0 0 1-.076-.145v-5.959c0-.062.027-.118.076-.146l5.167-2.979a.15.15 0 0 1 .152 0l5.167 2.98a.164.164 0 0 1 .076.145v5.959a.181.181 0 0 1-.076.145l-5.167 2.98c-.041.027-.11.027-.16 0l-1.305-.792c-.055-.021-.111-.028-.146-.007-.368.208-.437.25-.778.354-.083.028-.215.076.05.222l1.721 1.021c.167.097.348.146.542.146s.375-.049.542-.146l5.166-2.979c.334-.194.542-.556.542-.944v-5.959c0-.389-.208-.75-.542-.944l-5.166-2.986a1.103 1.103 0 0 0-.542-.14m1.389 4.272c-1.472 0-2.354.618-2.354 1.66 0 1.117.875 1.444 2.291 1.583 1.688.166 1.82.416 1.82.75 0 .576-.465.82-1.549.82-1.375 0-1.666-.341-1.77-1.022a.157.157 0 0 0-.153-.125h-.667c-.083 0-.146.063-.146.153 0 .861.472 1.903 2.736 1.903 1.632 0 2.57-.646 2.57-1.771 0-1.118-.75-1.41-2.34-1.625-1.605-.208-1.765-.32-1.765-.694 0-.313.14-.73 1.327-.73 1.042 0 1.451.23 1.611.945.014.07.076.118.146.118h.673a.134.134 0 0 0 .105-.049c.027-.028.048-.07.034-.11-.097-1.237-.916-1.806-2.57-1.806z" fill-rule="nonzero" fill="#f1f8e9"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-node-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#8bc34a" fill-rule="nonzero"/><path d="M17.25 8.403c-.188 0-.382.048-.542.139l-5.166 2.986a1.096 1.096 0 0 0-.542.944v5.959c0 .388.208.75.542.944l1.354.778c.66.32.882.326 1.187.326.973 0 1.535-.59 1.535-1.618V12.98a.154.154 0 0 0-.153-.153h-.646c-.09 0-.16.07-.16.153v5.882c0 .458-.472.91-1.228.528l-1.424-.813a.181.181 0 0 1-.076-.145v-5.959c0-.062.027-.118.076-.146l5.167-2.979a.15.15 0 0 1 .152 0l5.167 2.98a.164.164 0 0 1 .076.145v5.959a.181.181 0 0 1-.076.145l-5.167 2.98c-.041.027-.11.027-.16 0l-1.305-.792c-.055-.021-.111-.028-.146-.007-.368.208-.437.25-.778.354-.083.028-.215.076.05.222l1.721 1.021c.167.097.348.146.542.146s.375-.049.542-.146l5.166-2.979c.334-.194.542-.556.542-.944v-5.959c0-.389-.208-.75-.542-.944l-5.166-2.986a1.103 1.103 0 0 0-.542-.14m1.389 4.272c-1.472 0-2.354.618-2.354 1.66 0 1.117.875 1.444 2.291 1.583 1.688.166 1.82.416 1.82.75 0 .576-.465.82-1.549.82-1.375 0-1.666-.341-1.77-1.022a.157.157 0 0 0-.153-.125h-.667c-.083 0-.146.063-.146.153 0 .861.472 1.903 2.736 1.903 1.632 0 2.57-.646 2.57-1.771 0-1.118-.75-1.41-2.34-1.625-1.605-.208-1.765-.32-1.765-.694 0-.313.14-.73 1.327-.73 1.042 0 1.451.23 1.611.945.014.07.076.118.146.118h.673a.134.134 0 0 0 .105-.049c.027-.028.048-.07.034-.11-.097-1.237-.916-1.806-2.57-1.806z" fill-rule="nonzero" fill="#f1f8e9"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-public" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#039be5" fill-rule="nonzero"/><path d="M20.036 16.746c.05-.408.087-.817.087-1.237s-.037-.83-.087-1.238h2.091c.099.396.16.81.16 1.238a5.1 5.1 0 0 1-.16 1.237m-3.186 3.44c.371-.687.656-1.43.854-2.203h1.825a4.968 4.968 0 0 1-2.679 2.203m-.155-3.44h-2.895c-.062-.408-.099-.817-.099-1.237s.037-.835.1-1.238h2.894c.056.403.1.817.1 1.238s-.044.829-.1 1.237m-1.447 3.687a8.39 8.39 0 0 1-1.182-2.45h2.363a8.39 8.39 0 0 1-1.181 2.45m-2.475-7.399h-1.806a4.902 4.902 0 0 1 2.672-2.202c-.37.686-.65 1.429-.866 2.202m-1.806 4.95h1.806c.217.773.495 1.515.866 2.202a4.954 4.954 0 0 1-2.672-2.203m-.508-1.237a5.099 5.099 0 0 1-.16-1.237 5.1 5.1 0 0 1 .16-1.238h2.091c-.049.409-.086.817-.086 1.238s.037.829.086 1.237m2.698-6.168a8.425 8.425 0 0 1 1.181 2.456h-2.363a8.426 8.426 0 0 1 1.182-2.456m4.28 2.456h-1.824a9.682 9.682 0 0 0-.854-2.202 4.94 4.94 0 0 1 2.679 2.202m-4.281-3.712a6.193 6.193 0 0 0-6.187 6.187 6.186 6.186 0 0 0 6.187 6.186 6.186 6.186 0 0 0 6.186-6.186 6.186 6.186 0 0 0-6.186-6.187z" fill="#b3e5fc" stroke-width=".619"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-public-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#039be5"/><path d="M20.037 16.746c.05-.408.087-.817.087-1.237s-.037-.83-.087-1.238h2.091c.099.396.16.81.16 1.238a5.1 5.1 0 0 1-.16 1.237m-3.186 3.44c.371-.687.656-1.43.854-2.203h1.825a4.967 4.967 0 0 1-2.68 2.203m-.154-3.44h-2.895c-.062-.408-.099-.817-.099-1.237s.037-.835.099-1.238h2.895c.056.403.1.817.1 1.238s-.044.829-.1 1.237m-1.447 3.687a8.39 8.39 0 0 1-1.182-2.45h2.363a8.39 8.39 0 0 1-1.181 2.45m-2.475-7.399H13.06a4.902 4.902 0 0 1 2.672-2.202c-.371.686-.65 1.429-.866 2.202m-1.806 4.95h1.806c.217.773.495 1.515.866 2.202a4.954 4.954 0 0 1-2.672-2.203m-.508-1.237a5.099 5.099 0 0 1-.16-1.237 5.1 5.1 0 0 1 .16-1.238h2.091c-.05.409-.086.817-.086 1.238s.037.829.086 1.237m2.698-6.168a8.425 8.425 0 0 1 1.181 2.456h-2.363a8.426 8.426 0 0 1 1.182-2.456m4.28 2.456h-1.824a9.682 9.682 0 0 0-.854-2.202 4.941 4.941 0 0 1 2.679 2.202M17.34 9.322a6.193 6.193 0 0 0-6.187 6.187 6.186 6.186 0 0 0 6.187 6.186 6.186 6.186 0 0 0 6.186-6.186 6.186 6.186 0 0 0-6.186-6.187z" fill="#b3e5fc" stroke-width=".619"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-react-components" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#00bcd4" fill-rule="nonzero"/><path d="M16.473 13.927c.723 0 1.313.59 1.313 1.327 0 .703-.59 1.3-1.313 1.3a1.318 1.318 0 0 1-1.313-1.3c0-.737.59-1.327 1.313-1.327m-3.252 6.946c.443.267 1.412-.14 2.529-1.194a17.015 17.015 0 0 1-1.06-1.335 15.945 15.945 0 0 1-1.686-.252c-.358 1.502-.225 2.535.217 2.78m.499-4.03l-.204-.359a5.558 5.558 0 0 0-.203.604c.19.042.4.078.618.113l-.211-.359m4.593-.533l.569-1.054-.569-1.053c-.21-.372-.435-.702-.639-1.032-.38-.022-.78-.022-1.2-.022-.422 0-.823 0-1.202.022-.204.33-.428.66-.639 1.032l-.569 1.053.57 1.054c.21.372.434.702.638 1.032.38.021.78.021 1.201.021.421 0 .822 0 1.201-.02.204-.331.428-.661.639-1.033m-1.84-4.72c-.133.155-.274.316-.414.506h.828c-.14-.19-.28-.351-.414-.506m0 7.332c.133-.154.274-.316.414-.505h-.828c.14.19.28.35.414.505m3.245-9.284c-.436-.267-1.405.14-2.522 1.194.366.414.724.864 1.06 1.334.577.057 1.146.14 1.686.253.359-1.503.225-2.535-.224-2.78m-.492 4.03l.204.358c.077-.203.154-.407.203-.604-.19-.042-.4-.077-.618-.112l.211.358m1.018-4.95c1.033.589 1.145 2.141.71 3.953 1.784.527 3.069 1.398 3.069 2.584 0 1.187-1.285 2.058-3.07 2.585.436 1.812.324 3.364-.709 3.954-1.025.59-2.423-.085-3.77-1.37-1.35 1.285-2.747 1.96-3.78 1.37-1.025-.59-1.137-2.142-.702-3.954-1.783-.527-3.069-1.398-3.069-2.585s1.286-2.057 3.07-2.584c-.436-1.812-.324-3.364.702-3.954 1.032-.59 2.43.084 3.778 1.37 1.348-1.286 2.746-1.96 3.771-1.37m-.203 6.538c.239.527.45 1.054.625 1.588 1.475-.443 2.303-1.075 2.303-1.588 0-.512-.828-1.144-2.303-1.587a15.81 15.81 0 0 1-.625 1.587m-7.136 0a15.806 15.806 0 0 1-.625-1.587c-1.474.443-2.303 1.075-2.303 1.587 0 .513.829 1.145 2.303 1.588.176-.534.387-1.06.625-1.588m6.321 1.588l-.21.358c.217-.035.428-.07.617-.113-.049-.196-.126-.4-.203-.604l-.204.359m-2.03 2.837c1.117 1.053 2.086 1.46 2.522 1.194.45-.246.583-1.278.224-2.781-.54.112-1.11.196-1.685.253-.337.47-.695.92-1.06 1.334m-3.477-6.012l.21-.358c-.217.035-.428.07-.617.113.049.196.126.4.203.604l.204-.359m2.03-2.837c-1.117-1.053-2.086-1.46-2.529-1.194-.442.246-.576 1.278-.217 2.781.54-.112 1.11-.196 1.685-.253.337-.47.695-.92 1.06-1.334z" fill="#b2ebf2" stroke-width=".702"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-react-components-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#00bcd4"/><path d="M16.473 13.928c.723 0 1.313.59 1.313 1.327 0 .703-.59 1.3-1.313 1.3a1.318 1.318 0 0 1-1.313-1.3c0-.737.59-1.327 1.313-1.327m-3.252 6.946c.443.267 1.412-.14 2.529-1.194a16.997 16.997 0 0 1-1.06-1.335 15.945 15.945 0 0 1-1.686-.252c-.358 1.502-.225 2.535.217 2.78m.499-4.03l-.204-.359c-.077.204-.154.408-.203.604.19.042.4.078.618.113l-.211-.359m4.593-.533l.569-1.054-.57-1.053c-.21-.372-.434-.702-.638-1.032-.38-.022-.78-.022-1.201-.022-.421 0-.822 0-1.2.022-.205.33-.43.66-.64 1.032l-.569 1.053.569 1.054c.21.372.435.702.64 1.032.378.021.779.021 1.2.021.421 0 .822 0 1.2-.02.205-.33.43-.661.64-1.033m-1.84-4.72c-.133.155-.274.316-.414.506h.828c-.14-.19-.28-.351-.414-.506m0 7.332c.133-.154.274-.316.414-.505h-.828c.14.19.28.35.414.505m3.244-9.284c-.435-.267-1.404.14-2.52 1.194.364.414.723.864 1.06 1.334.575.057 1.144.14 1.685.253.358-1.503.225-2.535-.225-2.78m-.491 4.03l.203.358c.078-.203.155-.407.204-.604-.19-.042-.4-.077-.618-.112l.21.358m1.02-4.95c1.032.589 1.144 2.141.708 3.953 1.784.527 3.07 1.398 3.07 2.584 0 1.187-1.286 2.058-3.07 2.585.436 1.812.323 3.364-.709 3.954-1.025.59-2.423-.085-3.771-1.37-1.348 1.285-2.746 1.96-3.778 1.37-1.026-.59-1.138-2.142-.703-3.954-1.783-.527-3.069-1.398-3.069-2.585s1.286-2.057 3.07-2.584c-.436-1.812-.324-3.364.702-3.954 1.032-.59 2.43.084 3.778 1.37 1.348-1.286 2.746-1.96 3.771-1.37m-.204 6.538c.24.527.45 1.054.625 1.588 1.475-.443 2.304-1.075 2.304-1.588 0-.512-.829-1.144-2.304-1.587a15.81 15.81 0 0 1-.625 1.587m-7.135 0a15.808 15.808 0 0 1-.625-1.587c-1.475.443-2.303 1.075-2.303 1.587 0 .513.828 1.145 2.303 1.588.176-.534.386-1.06.625-1.588m6.32 1.588l-.21.358c.218-.035.428-.07.618-.113a5.56 5.56 0 0 0-.204-.604l-.203.359m-2.03 2.837c1.117 1.053 2.086 1.46 2.521 1.194.45-.246.583-1.278.225-2.781-.54.112-1.11.196-1.685.253-.338.47-.696.92-1.06 1.334m-3.477-6.012l.21-.358c-.217.035-.428.07-.617.112.049.197.126.4.203.604l.204-.358m2.03-2.837c-1.117-1.053-2.086-1.46-2.529-1.194-.442.246-.576 1.278-.217 2.781.54-.112 1.11-.196 1.685-.253.337-.47.695-.92 1.06-1.334z" fill="#b2ebf2" stroke-width=".702"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-redux-actions" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#ab47bc" fill-rule="nonzero"/><g transform="translate(8.378 6.436) scale(.17228)" fill="#e1bee7" stroke="#e1bee7" stroke-miterlimit="4" stroke-width="1.702"><path d="M65.6 65.4c2.9-.3 5.1-2.8 5-5.8S68 54.2 65 54.2h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 1.5.7 2.8 1.6 3.7-3.4 6.7-8.6 11.6-16.4 15.7-5.3 2.8-10.8 3.8-16.3 3.1-4.5-.6-8-2.6-10.2-5.9-3.2-4.9-3.5-10.2-.8-15.5 1.9-3.8 4.9-6.6 6.8-8-.4-1.3-1-3.5-1.3-5.1-14.5 10.5-13 24.7-8.6 31.4 3.3 5 10 8.1 17.4 8.1 2 0 4-.2 6-.7 12.8-2.5 22.5-10.1 28-21.4z"/><path d="M83.2 53c-7.6-8.9-18.8-13.8-31.6-13.8H50c-.9-1.8-2.8-3-4.9-3h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 3 2.6 5.4 5.6 5.4h.2c2.2-.1 4.1-1.5 4.9-3.4H52c7.6 0 14.8 2.2 21.3 6.5 5 3.3 8.6 7.6 10.6 12.8 1.7 4.2 1.6 8.3-.2 11.8-2.8 5.3-7.5 8.2-13.7 8.2-4 0-7.8-1.2-9.8-2.1-1.1 1-3.1 2.6-4.5 3.6 4.3 2 8.7 3.1 12.9 3.1 9.6 0 16.7-5.3 19.4-10.6 2.9-5.8 2.7-15.8-4.8-24.3z"/><path d="M32.4 67.1c.1 3 2.6 5.4 5.6 5.4h.2c3.1-.1 5.5-2.7 5.4-5.8-.1-3-2.6-5.4-5.6-5.4h-.2c-.2 0-.5 0-.7.1-4.1-6.8-5.8-14.2-5.2-22.2.4-6 2.4-11.2 5.9-15.5 2.9-3.7 8.5-5.5 12.3-5.6 10.6-.2 15.1 13 15.4 18.3 1.3.3 3.5 1 5 1.5-1.2-16.2-11.2-24.6-20.8-24.6-9 0-17.3 6.5-20.6 16.1-4.6 12.8-1.6 25.1 4 34.8-.5.7-.8 1.8-.7 2.9z"/></g></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-redux-actions-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#ab47bc"/><g transform="translate(8.378 6.436) scale(.17228)" fill="#e1bee7" stroke="#e1bee7" stroke-miterlimit="4" stroke-width="1.702"><path d="M65.6 65.4c2.9-.3 5.1-2.8 5-5.8S68 54.2 65 54.2h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 1.5.7 2.8 1.6 3.7-3.4 6.7-8.6 11.6-16.4 15.7-5.3 2.8-10.8 3.8-16.3 3.1-4.5-.6-8-2.6-10.2-5.9-3.2-4.9-3.5-10.2-.8-15.5 1.9-3.8 4.9-6.6 6.8-8-.4-1.3-1-3.5-1.3-5.1-14.5 10.5-13 24.7-8.6 31.4 3.3 5 10 8.1 17.4 8.1 2 0 4-.2 6-.7 12.8-2.5 22.5-10.1 28-21.4z"/><path d="M83.2 53c-7.6-8.9-18.8-13.8-31.6-13.8H50c-.9-1.8-2.8-3-4.9-3h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 3 2.6 5.4 5.6 5.4h.2c2.2-.1 4.1-1.5 4.9-3.4H52c7.6 0 14.8 2.2 21.3 6.5 5 3.3 8.6 7.6 10.6 12.8 1.7 4.2 1.6 8.3-.2 11.8-2.8 5.3-7.5 8.2-13.7 8.2-4 0-7.8-1.2-9.8-2.1-1.1 1-3.1 2.6-4.5 3.6 4.3 2 8.7 3.1 12.9 3.1 9.6 0 16.7-5.3 19.4-10.6 2.9-5.8 2.7-15.8-4.8-24.3z"/><path d="M32.4 67.1c.1 3 2.6 5.4 5.6 5.4h.2c3.1-.1 5.5-2.7 5.4-5.8-.1-3-2.6-5.4-5.6-5.4h-.2c-.2 0-.5 0-.7.1-4.1-6.8-5.8-14.2-5.2-22.2.4-6 2.4-11.2 5.9-15.5 2.9-3.7 8.5-5.5 12.3-5.6 10.6-.2 15.1 13 15.4 18.3 1.3.3 3.5 1 5 1.5-1.2-16.2-11.2-24.6-20.8-24.6-9 0-17.3 6.5-20.6 16.1-4.6 12.8-1.6 25.1 4 34.8-.5.7-.8 1.8-.7 2.9z"/></g></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-redux-reducer" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#ef5350" fill-rule="nonzero"/><g transform="translate(8.378 6.436) scale(.17228)" fill="#ffcdd2" stroke="#ffcdd2" stroke-miterlimit="4" stroke-width="1.702"><path d="M65.6 65.4c2.9-.3 5.1-2.8 5-5.8S68 54.2 65 54.2h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 1.5.7 2.8 1.6 3.7-3.4 6.7-8.6 11.6-16.4 15.7-5.3 2.8-10.8 3.8-16.3 3.1-4.5-.6-8-2.6-10.2-5.9-3.2-4.9-3.5-10.2-.8-15.5 1.9-3.8 4.9-6.6 6.8-8-.4-1.3-1-3.5-1.3-5.1-14.5 10.5-13 24.7-8.6 31.4 3.3 5 10 8.1 17.4 8.1 2 0 4-.2 6-.7 12.8-2.5 22.5-10.1 28-21.4z"/><path d="M83.2 53c-7.6-8.9-18.8-13.8-31.6-13.8H50c-.9-1.8-2.8-3-4.9-3h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 3 2.6 5.4 5.6 5.4h.2c2.2-.1 4.1-1.5 4.9-3.4H52c7.6 0 14.8 2.2 21.3 6.5 5 3.3 8.6 7.6 10.6 12.8 1.7 4.2 1.6 8.3-.2 11.8-2.8 5.3-7.5 8.2-13.7 8.2-4 0-7.8-1.2-9.8-2.1-1.1 1-3.1 2.6-4.5 3.6 4.3 2 8.7 3.1 12.9 3.1 9.6 0 16.7-5.3 19.4-10.6 2.9-5.8 2.7-15.8-4.8-24.3z"/><path d="M32.4 67.1c.1 3 2.6 5.4 5.6 5.4h.2c3.1-.1 5.5-2.7 5.4-5.8-.1-3-2.6-5.4-5.6-5.4h-.2c-.2 0-.5 0-.7.1-4.1-6.8-5.8-14.2-5.2-22.2.4-6 2.4-11.2 5.9-15.5 2.9-3.7 8.5-5.5 12.3-5.6 10.6-.2 15.1 13 15.4 18.3 1.3.3 3.5 1 5 1.5-1.2-16.2-11.2-24.6-20.8-24.6-9 0-17.3 6.5-20.6 16.1-4.6 12.8-1.6 25.1 4 34.8-.5.7-.8 1.8-.7 2.9z"/></g></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-redux-reducer-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#ef5350"/><g transform="translate(8.378 6.436) scale(.17228)" fill="#ffcdd2" stroke="#ffcdd2" stroke-miterlimit="4" stroke-width="1.702"><path d="M65.6 65.4c2.9-.3 5.1-2.8 5-5.8S68 54.2 65 54.2h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 1.5.7 2.8 1.6 3.7-3.4 6.7-8.6 11.6-16.4 15.7-5.3 2.8-10.8 3.8-16.3 3.1-4.5-.6-8-2.6-10.2-5.9-3.2-4.9-3.5-10.2-.8-15.5 1.9-3.8 4.9-6.6 6.8-8-.4-1.3-1-3.5-1.3-5.1-14.5 10.5-13 24.7-8.6 31.4 3.3 5 10 8.1 17.4 8.1 2 0 4-.2 6-.7 12.8-2.5 22.5-10.1 28-21.4z"/><path d="M83.2 53c-7.6-8.9-18.8-13.8-31.6-13.8H50c-.9-1.8-2.8-3-4.9-3h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 3 2.6 5.4 5.6 5.4h.2c2.2-.1 4.1-1.5 4.9-3.4H52c7.6 0 14.8 2.2 21.3 6.5 5 3.3 8.6 7.6 10.6 12.8 1.7 4.2 1.6 8.3-.2 11.8-2.8 5.3-7.5 8.2-13.7 8.2-4 0-7.8-1.2-9.8-2.1-1.1 1-3.1 2.6-4.5 3.6 4.3 2 8.7 3.1 12.9 3.1 9.6 0 16.7-5.3 19.4-10.6 2.9-5.8 2.7-15.8-4.8-24.3z"/><path d="M32.4 67.1c.1 3 2.6 5.4 5.6 5.4h.2c3.1-.1 5.5-2.7 5.4-5.8-.1-3-2.6-5.4-5.6-5.4h-.2c-.2 0-.5 0-.7.1-4.1-6.8-5.8-14.2-5.2-22.2.4-6 2.4-11.2 5.9-15.5 2.9-3.7 8.5-5.5 12.3-5.6 10.6-.2 15.1 13 15.4 18.3 1.3.3 3.5 1 5 1.5-1.2-16.2-11.2-24.6-20.8-24.6-9 0-17.3 6.5-20.6 16.1-4.6 12.8-1.6 25.1 4 34.8-.5.7-.8 1.8-.7 2.9z"/></g></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-redux-store" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#8bc34a" fill-rule="nonzero"/><g transform="translate(8.378 6.436) scale(.17228)" fill="#dcedc8" stroke="#dcedc8" stroke-miterlimit="4" stroke-width="1.702"><path d="M65.6 65.4c2.9-.3 5.1-2.8 5-5.8S68 54.2 65 54.2h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 1.5.7 2.8 1.6 3.7-3.4 6.7-8.6 11.6-16.4 15.7-5.3 2.8-10.8 3.8-16.3 3.1-4.5-.6-8-2.6-10.2-5.9-3.2-4.9-3.5-10.2-.8-15.5 1.9-3.8 4.9-6.6 6.8-8-.4-1.3-1-3.5-1.3-5.1-14.5 10.5-13 24.7-8.6 31.4 3.3 5 10 8.1 17.4 8.1 2 0 4-.2 6-.7 12.8-2.5 22.5-10.1 28-21.4z"/><path d="M83.2 53c-7.6-8.9-18.8-13.8-31.6-13.8H50c-.9-1.8-2.8-3-4.9-3h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 3 2.6 5.4 5.6 5.4h.2c2.2-.1 4.1-1.5 4.9-3.4H52c7.6 0 14.8 2.2 21.3 6.5 5 3.3 8.6 7.6 10.6 12.8 1.7 4.2 1.6 8.3-.2 11.8-2.8 5.3-7.5 8.2-13.7 8.2-4 0-7.8-1.2-9.8-2.1-1.1 1-3.1 2.6-4.5 3.6 4.3 2 8.7 3.1 12.9 3.1 9.6 0 16.7-5.3 19.4-10.6 2.9-5.8 2.7-15.8-4.8-24.3z"/><path d="M32.4 67.1c.1 3 2.6 5.4 5.6 5.4h.2c3.1-.1 5.5-2.7 5.4-5.8-.1-3-2.6-5.4-5.6-5.4h-.2c-.2 0-.5 0-.7.1-4.1-6.8-5.8-14.2-5.2-22.2.4-6 2.4-11.2 5.9-15.5 2.9-3.7 8.5-5.5 12.3-5.6 10.6-.2 15.1 13 15.4 18.3 1.3.3 3.5 1 5 1.5-1.2-16.2-11.2-24.6-20.8-24.6-9 0-17.3 6.5-20.6 16.1-4.6 12.8-1.6 25.1 4 34.8-.5.7-.8 1.8-.7 2.9z"/></g></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-redux-store-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#8bc34a"/><g transform="translate(8.378 6.436) scale(.17228)" fill="#dcedc8" stroke="#dcedc8" stroke-miterlimit="4" stroke-width="1.702"><path d="M65.6 65.4c2.9-.3 5.1-2.8 5-5.8S68 54.2 65 54.2h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 1.5.7 2.8 1.6 3.7-3.4 6.7-8.6 11.6-16.4 15.7-5.3 2.8-10.8 3.8-16.3 3.1-4.5-.6-8-2.6-10.2-5.9-3.2-4.9-3.5-10.2-.8-15.5 1.9-3.8 4.9-6.6 6.8-8-.4-1.3-1-3.5-1.3-5.1-14.5 10.5-13 24.7-8.6 31.4 3.3 5 10 8.1 17.4 8.1 2 0 4-.2 6-.7 12.8-2.5 22.5-10.1 28-21.4z"/><path d="M83.2 53c-7.6-8.9-18.8-13.8-31.6-13.8H50c-.9-1.8-2.8-3-4.9-3h-.2c-3.1.1-5.5 2.7-5.4 5.8.1 3 2.6 5.4 5.6 5.4h.2c2.2-.1 4.1-1.5 4.9-3.4H52c7.6 0 14.8 2.2 21.3 6.5 5 3.3 8.6 7.6 10.6 12.8 1.7 4.2 1.6 8.3-.2 11.8-2.8 5.3-7.5 8.2-13.7 8.2-4 0-7.8-1.2-9.8-2.1-1.1 1-3.1 2.6-4.5 3.6 4.3 2 8.7 3.1 12.9 3.1 9.6 0 16.7-5.3 19.4-10.6 2.9-5.8 2.7-15.8-4.8-24.3z"/><path d="M32.4 67.1c.1 3 2.6 5.4 5.6 5.4h.2c3.1-.1 5.5-2.7 5.4-5.8-.1-3-2.6-5.4-5.6-5.4h-.2c-.2 0-.5 0-.7.1-4.1-6.8-5.8-14.2-5.2-22.2.4-6 2.4-11.2 5.9-15.5 2.9-3.7 8.5-5.5 12.3-5.6 10.6-.2 15.1 13 15.4 18.3 1.3.3 3.5 1 5 1.5-1.2-16.2-11.2-24.6-20.8-24.6-9 0-17.3 6.5-20.6 16.1-4.6 12.8-1.6 25.1 4 34.8-.5.7-.8 1.8-.7 2.9z"/></g></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-resource" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#fbc02d" fill-rule="nonzero"/><path d="M21.598 12.059h-6.085v-1.217h6.085m-2.434 6.085h-3.65V15.71h3.65m2.434-1.217h-6.085v-1.217h6.085m.608-4.26h-7.301a1.217 1.217 0 0 0-1.217 1.218v7.301a1.217 1.217 0 0 0 1.217 1.217h7.301a1.217 1.217 0 0 0 1.217-1.217v-7.301a1.217 1.217 0 0 0-1.217-1.217m-9.735 2.434h-1.217v8.518a1.217 1.217 0 0 0 1.217 1.217h8.519v-1.217H12.47z" fill="#fff9c4" stroke-width=".608"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-resource-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#fbc02d"/><path d="M21.598 12.059h-6.085v-1.217h6.085m-2.434 6.085h-3.65V15.71h3.65m2.434-1.217h-6.085v-1.217h6.085m.608-4.26h-7.301a1.217 1.217 0 0 0-1.217 1.218v7.301a1.217 1.217 0 0 0 1.217 1.217h7.301a1.217 1.217 0 0 0 1.217-1.217v-7.301a1.217 1.217 0 0 0-1.217-1.217m-9.735 2.433h-1.217v8.519a1.217 1.217 0 0 0 1.217 1.217h8.519v-1.217H12.47z" fill="#fff9c4" stroke-width=".608"/></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" id="folder-sass" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#f8bbd0" fill-rule="nonzero"/><path d="M23.36 10.506c-.39-1.527-2.922-2.03-5.319-1.178-1.426.507-2.97 1.302-4.08 2.34-1.32 1.235-1.53 2.31-1.444 2.759.306 1.584 2.477 2.62 3.37 3.388v.005c-.264.13-2.19 1.104-2.64 2.1-.476 1.052.075 1.806.44 1.908 1.131.315 2.292-.251 2.916-1.182.602-.897.551-2.056.29-2.633.36-.095.781-.138 1.316-.076 1.508.177 1.804 1.118 1.748 1.513-.057.394-.373.61-.48.676-.105.065-.137.088-.129.137.013.07.062.068.152.053.125-.021.792-.321.821-1.048.037-.924-.849-1.958-2.416-1.93-.646.01-1.052.072-1.345.181-.022-.024-.044-.05-.067-.073-.969-1.034-2.76-1.765-2.684-3.156.027-.505.203-1.835 3.442-3.45 2.653-1.322 4.777-.957 5.145-.151.524 1.152-1.136 3.293-3.891 3.601-1.05.118-1.603-.289-1.74-.44-.145-.16-.166-.167-.22-.137-.088.049-.033.19 0 .274.082.214.42.594.995.782.506.166 1.739.258 3.23-.319 1.669-.646 2.972-2.443 2.59-3.944zm-7.103 7.783a2.2 2.2 0 0 1-.065 1.413 2.405 2.405 0 0 1-.453.704c-.5.546-1.198.752-1.497.579-.323-.188-.161-.956.418-1.568.623-.66 1.52-1.083 1.52-1.083l-.002-.002.079-.043z" fill="#ec407a" fill-rule="nonzero" stroke="#ec407a" stroke-width=".5199012000000001"/></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" id="folder-sass-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#f8bbd0" fill-rule="nonzero"/><path d="M23.36 10.506c-.39-1.527-2.922-2.03-5.319-1.178-1.426.507-2.97 1.302-4.08 2.34-1.32 1.235-1.53 2.31-1.444 2.759.306 1.584 2.477 2.62 3.37 3.388v.005c-.264.13-2.19 1.104-2.64 2.1-.476 1.052.075 1.806.44 1.908 1.131.315 2.292-.251 2.916-1.182.602-.897.551-2.056.29-2.633.36-.095.781-.138 1.316-.076 1.508.177 1.804 1.118 1.748 1.513-.057.394-.373.61-.48.676-.105.065-.137.088-.129.137.013.07.062.068.152.053.125-.021.792-.321.821-1.048.037-.924-.849-1.958-2.416-1.93-.646.01-1.052.072-1.345.181-.022-.024-.044-.05-.067-.073-.969-1.034-2.76-1.765-2.684-3.156.027-.505.203-1.835 3.442-3.45 2.653-1.322 4.777-.957 5.145-.151.524 1.152-1.136 3.293-3.891 3.601-1.05.118-1.603-.289-1.74-.44-.145-.16-.166-.167-.22-.137-.088.049-.033.19 0 .274.082.214.42.594.995.782.506.166 1.739.258 3.23-.319 1.669-.646 2.972-2.443 2.59-3.944zm-7.103 7.783a2.2 2.2 0 0 1-.065 1.413 2.405 2.405 0 0 1-.453.704c-.5.546-1.198.752-1.497.579-.323-.188-.161-.956.418-1.568.623-.66 1.52-1.083 1.52-1.083l-.002-.002.079-.043z" fill="#ec407a" fill-rule="nonzero" stroke="#ec407a" stroke-width=".5199012000000001"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-scripts" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#546e7a" fill-rule="nonzero"/><path d="M18.466 20.241c.69 0 1.259-.568 1.259-1.258v-8.18H15.32a.632.632 0 0 0-.63.63v6.292h-1.887v-6.922c0-1.036.852-1.888 1.888-1.888h6.921c1.036 0 1.888.852 1.888 1.888v.63h-2.517v8.18a1.896 1.896 0 0 1-1.888 1.887h-6.292a1.896 1.896 0 0 1-1.888-1.888v-.629h6.293c0 .69.568 1.258 1.258 1.258z" fill-rule="nonzero" fill="#cfd8dc"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-scripts-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#546e7a" fill-rule="nonzero"/><path d="M18.466 20.241c.69 0 1.259-.568 1.259-1.258v-8.18H15.32a.632.632 0 0 0-.63.63v6.292h-1.887v-6.922c0-1.036.852-1.888 1.888-1.888h6.921c1.036 0 1.888.852 1.888 1.888v.63h-2.517v8.18a1.896 1.896 0 0 1-1.888 1.887h-6.292a1.896 1.896 0 0 1-1.888-1.888v-.629h6.293c0 .69.568 1.258 1.258 1.258z" fill-rule="nonzero" fill="#cfd8dc"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-src" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#4caf50" fill-rule="nonzero"/><g fill="#c8e6c9" transform="translate(2.065 -.225) scale(.70678)"><path d="M19.146 30.989a.902.902 0 0 1-.207-.025 1.045 1.045 0 0 1-.726-1.213l2.709-14.431c.049-.279.209-.525.444-.683a.891.891 0 0 1 .7-.122c.519.152.837.684.727 1.213L20.077 30.16a1.032 1.032 0 0 1-.442.681.895.895 0 0 1-.489.148zM24.578 28.944h-.068a.932.932 0 0 1-.668-.377 1.104 1.104 0 0 1 .1-1.419l4.658-4.553-4.638-4.239a1.105 1.105 0 0 1-.141-1.416.938.938 0 0 1 .661-.4.9.9 0 0 1 .709.237l5.47 5c.386.372.448.974.144 1.416a1.05 1.05 0 0 1-.142.163l-5.447 5.324a.913.913 0 0 1-.638.264zM16.423 28.947a.917.917 0 0 1-.639-.267l-5.452-5.327a.874.874 0 0 1-.132-.153 1.097 1.097 0 0 1 .141-1.414l5.471-5a.882.882 0 0 1 .7-.238.939.939 0 0 1 .665.4 1.104 1.104 0 0 1-.14 1.417L12.4 22.6l4.659 4.551c.377.382.42.988.1 1.419a.928.928 0 0 1-.669.377z" fill-rule="nonzero"/></g></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-src-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#4caf50"/><g fill="#c8e6c9" fill-rule="evenodd" transform="translate(2.064 -.224) scale(.70678)"><path d="M19.146 30.989a.902.902 0 0 1-.207-.025 1.045 1.045 0 0 1-.726-1.213l2.709-14.431c.049-.279.209-.525.444-.683a.891.891 0 0 1 .7-.122c.519.152.837.684.727 1.213L20.077 30.16a1.032 1.032 0 0 1-.442.681.895.895 0 0 1-.489.148zM24.578 28.944h-.068a.932.932 0 0 1-.668-.377 1.104 1.104 0 0 1 .1-1.419l4.658-4.553-4.638-4.239a1.105 1.105 0 0 1-.141-1.416.938.938 0 0 1 .661-.4.9.9 0 0 1 .709.237l5.47 5c.386.372.448.974.144 1.416a1.05 1.05 0 0 1-.142.163l-5.447 5.324a.913.913 0 0 1-.638.264zM16.423 28.947a.917.917 0 0 1-.639-.267l-5.452-5.327a.874.874 0 0 1-.132-.153 1.097 1.097 0 0 1 .141-1.414l5.471-5a.882.882 0 0 1 .7-.238.939.939 0 0 1 .665.4 1.104 1.104 0 0 1-.14 1.417L12.4 22.6l4.659 4.551c.377.382.42.988.1 1.419a.928.928 0 0 1-.669.377z" fill-rule="nonzero"/></g></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="folder-test" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#1de9b6" fill-rule="nonzero"/><path d="M14 8.097v1.39h.695v9.732A2.794 2.794 0 0 0 17.475 22a2.794 2.794 0 0 0 2.781-2.78V9.486h.695v-1.39H14m2.78 9.732c-.417 0-.695-.278-.695-.695 0-.417.278-.695.696-.695.417 0 .695.278.695.695 0 .417-.278.695-.695.695m1.39-2.78c-.417 0-.695-.278-.695-.696 0-.417.278-.695.695-.695.417 0 .695.278.695.695 0 .418-.278.696-.695.696m.695-3.476h-2.78V9.487h2.78v2.086z" fill="#00897b" fill-rule="nonzero"/></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="folder-test-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#1de9b6" fill-rule="nonzero"/><path d="M14 8.097v1.39h.695v9.732A2.794 2.794 0 0 0 17.475 22a2.794 2.794 0 0 0 2.781-2.78V9.486h.695v-1.39H14m2.78 9.732c-.417 0-.695-.278-.695-.695 0-.417.278-.695.696-.695.417 0 .695.278.695.695 0 .417-.278.695-.695.695m1.39-2.78c-.417 0-.695-.278-.695-.696 0-.417.278-.695.695-.695.417 0 .695.278.695.695 0 .418-.278.696-.695.696m.695-3.476h-2.78V9.487h2.78v2.086z" fill="#00897b" fill-rule="nonzero"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-tools" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#1e88e5" fill-rule="nonzero"/><path d="M21.043 15.266a1.07 1.07 0 0 1-1.07-1.07 1.07 1.07 0 0 1 1.07-1.071 1.07 1.07 0 0 1 1.07 1.07 1.07 1.07 0 0 1-1.07 1.071m-2.141-2.855a1.07 1.07 0 0 1-1.07-1.07 1.07 1.07 0 0 1 1.07-1.071 1.07 1.07 0 0 1 1.07 1.07 1.07 1.07 0 0 1-1.07 1.071m-3.569 0a1.07 1.07 0 0 1-1.07-1.07 1.07 1.07 0 0 1 1.07-1.071 1.07 1.07 0 0 1 1.07 1.07 1.07 1.07 0 0 1-1.07 1.071m-2.141 2.855a1.07 1.07 0 0 1-1.07-1.07 1.07 1.07 0 0 1 1.07-1.071 1.07 1.07 0 0 1 1.07 1.07 1.07 1.07 0 0 1-1.07 1.071m3.925-6.424a6.424 6.424 0 0 0-6.423 6.424 6.424 6.424 0 0 0 6.423 6.424 1.07 1.07 0 0 0 1.071-1.07c0-.28-.107-.53-.278-.715a1.105 1.105 0 0 1-.271-.713 1.07 1.07 0 0 1 1.07-1.071h1.263a3.569 3.569 0 0 0 3.57-3.569c0-3.154-2.877-5.71-6.425-5.71z" fill="#bbdefb" stroke-width=".714"/></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-tools-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#1e88e5"/><path d="M21.043 15.266a1.07 1.07 0 0 1-1.07-1.07 1.07 1.07 0 0 1 1.07-1.071 1.07 1.07 0 0 1 1.07 1.07 1.07 1.07 0 0 1-1.07 1.071m-2.141-2.855a1.07 1.07 0 0 1-1.07-1.07 1.07 1.07 0 0 1 1.07-1.071 1.07 1.07 0 0 1 1.07 1.07 1.07 1.07 0 0 1-1.07 1.071m-3.569 0a1.07 1.07 0 0 1-1.07-1.07 1.07 1.07 0 0 1 1.07-1.071 1.07 1.07 0 0 1 1.07 1.07 1.07 1.07 0 0 1-1.07 1.071m-2.141 2.855a1.07 1.07 0 0 1-1.07-1.07 1.07 1.07 0 0 1 1.07-1.071 1.07 1.07 0 0 1 1.07 1.07 1.07 1.07 0 0 1-1.07 1.071m3.925-6.424a6.424 6.424 0 0 0-6.423 6.424 6.424 6.424 0 0 0 6.423 6.424 1.07 1.07 0 0 0 1.071-1.07c0-.28-.107-.53-.278-.715a1.105 1.105 0 0 1-.271-.713 1.07 1.07 0 0 1 1.07-1.071h1.263a3.569 3.569 0 0 0 3.57-3.569c0-3.154-2.877-5.71-6.425-5.71z" fill="#bbdefb" stroke-width=".714"/></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="folder-views" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#ff8a65" fill-rule="nonzero"/><path d="M12.487 21.868L11.384 9.5H23.5l-1.104 12.366-4.961 1.375-4.948-1.373zm4.464-3.2l-3.926-2.36v-.855l3.926-2.361v1.323l-2.504 1.465 2.504 1.465v1.323zm.982-.001v-1.323l2.522-1.464-2.522-1.464v-1.323l3.926 2.35v.874l-3.926 2.35z" fill="#e44d26"/></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="folder-views-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#ff8a65" fill-rule="nonzero"/><path d="M12.487 21.868L11.384 9.5H23.5l-1.104 12.366-4.961 1.375-4.948-1.373zm4.464-3.2l-3.926-2.36v-.855l3.926-2.361v1.323l-2.504 1.465 2.504 1.465v1.323zm.982-.001v-1.323l2.522-1.464-2.522-1.464v-1.323l3.926 2.35v.874l-3.926 2.35z" fill="#e44d26"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-vscode" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#42a5f5" fill-rule="nonzero"/><path d="M20.811 8.52l-5.988 5.506-3.346-2.522-1.383.805 3.298 3.03-3.298 3.032 1.383.807 3.346-2.522 5.988 5.503 2.921-1.419V9.94zm0 3.622v6.396l-4.245-3.198z" fill="#bbdefb" stroke-width=".974"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-vscode-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#42a5f5" fill-rule="nonzero"/><path d="M20.81 8.52l-5.988 5.506-3.346-2.522-1.384.805 3.3 3.03-3.3 3.032 1.384.807 3.346-2.522 5.988 5.503 2.921-1.419V9.94zm0 3.621v6.397l-4.245-3.198z" fill="#bbdefb" stroke-width=".974"/></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-vue" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#009688" fill-rule="nonzero"/><g transform="translate(8.459 6.362) scale(.69572)"><path d="M1.821 4.15l10.21 17.618L22.239 4.235v-.084h-7.692l-2.434 4.178-2.422-4.178z" fill="#41b883"/><path d="M5.937 4.15l6.152 10.616 6.18-10.617h-3.722l-2.434 4.179-2.422-4.179z" fill="#35495e"/></g></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-vue-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#009688"/><g transform="translate(8.458 6.362) scale(.69572)"><path d="M1.821 4.15l10.21 17.618L22.239 4.235v-.084h-7.692l-2.434 4.178-2.422-4.178z" fill="#41b883"/><path d="M5.937 4.15l6.152 10.616 6.18-10.617h-3.722l-2.434 4.179-2.422-4.179z" fill="#35495e"/></g></symbol><symbol clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-webpack" xmlns="http://www.w3.org/2000/svg"><path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#03a9f4" fill-rule="nonzero"/><g transform="translate(9.192 7.48) scale(.66328)"><path d="M19.376 15.988l-7.708 4.45-7.709-4.45v-8.9l7.709-4.451 7.708 4.45z" fill="#fff" fill-opacity=".785"/><path d="M12.286 1.98c-.21 0-.41.059-.57.179l-7.9 4.44c-.32.17-.53.5-.53.88v9c0 .38.21.711.53.881l7.9 4.44c.16.12.36.18.57.18s.41-.06.57-.18l7.9-4.44c.32-.17.53-.5.53-.88v-9c0-.38-.21-.712-.53-.882l-7.9-4.44a.945.945 0 0 0-.57-.179zm0 2.15l7 3.94v2.103h-.016v5.177h.016v.54l-7 3.939-7-3.94V8.07zm0 2.08l-4.9 2.83 4.9 2.83 4.9-2.83zm-5 5.08v3.58l4 2.309v-3.58zm10 0l-4 2.308v3.58l4-2.308z" fill="#8ed6fb"/><path d="M12.286 6.21l-4.9 2.83 4.9 2.83 4.9-2.83zm-5 5.08v3.58l4 2.309v-3.58zm10 0l-4 2.308v3.58l4-2.308z" fill="#1c78c0"/></g></symbol><symbol clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" id="folder-webpack-open" xmlns="http://www.w3.org/2000/svg"><path d="M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7c1.097 0 2 .903 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z" fill="#03a9f4"/><g transform="translate(9.193 7.48) scale(.66328)"><path d="M19.376 15.988l-7.708 4.45-7.709-4.45v-8.9l7.709-4.451 7.708 4.45z" fill="#fff" fill-opacity=".785"/><path d="M12.286 1.98c-.21 0-.41.059-.57.179l-7.9 4.44c-.32.17-.53.5-.53.88v9c0 .38.21.711.53.881l7.9 4.44c.16.12.36.18.57.18s.41-.06.57-.18l7.9-4.44c.32-.17.53-.5.53-.88v-9c0-.38-.21-.712-.53-.882l-7.9-4.44a.945.945 0 0 0-.57-.179zm0 2.15l7 3.94v2.103h-.016v5.177h.016v.54l-7 3.939-7-3.94V8.07zm0 2.08l-4.9 2.83 4.9 2.83 4.9-2.83zm-5 5.08v3.58l4 2.309v-3.58zm10 0l-4 2.308v3.58l4-2.308z" fill="#8ed6fb"/><path d="M12.286 6.21l-4.9 2.83 4.9 2.83 4.9-2.83zm-5 5.08v3.58l4 2.309v-3.58zm10 0l-4 2.308v3.58l4-2.308z" fill="#1c78c0"/></g></symbol><symbol viewBox="0 0 24 24" id="font" xmlns="http://www.w3.org/2000/svg"><path d="M9.62 12L12 5.67 14.37 12M11 3L5.5 17h2.25l1.12-3h6.25l1.13 3h2.25L13 3h-2z" fill="#f44336"/></symbol><symbol viewBox="0 0 500 500" id="fsharp" xmlns="http://www.w3.org/2000/svg"><path d="M235.906 36.66L21.963 250.601l213.943 213.943v-84.36L106.209 250.487l129.697-129.696z" fill="#378bba" stroke-width="14.706"/><path d="M235.906 156.614l-93.622 93.62 93.622 93.622z" fill="#378bba" stroke-width="15.006"/><path d="M263.417 36.64L477.36 250.583 263.417 464.526v-84.36l129.696-129.697-129.696-129.696z" fill="#30b9db" stroke-width="14.706"/></symbol><symbol viewBox="0 0 152.99 160.01" id="fusebox" xmlns="http://www.w3.org/2000/svg"><defs id="fkdefs4"><style id="fkstyle2">.fkcls-1{fill:#fff}.fkcls-2{fill:#515151}.fkcls-3{fill:#1d79bf}.fkcls-4{fill:#383838}</style></defs><title id="fktitle6">Asset 3</title><g id="fkLayer_2" data-name="Layer 2" transform="matrix(.87285 0 0 .87285 10.17 10.175)"><g id="fkFuse_Box" data-name="Fuse Box"><g id="fkLOGO"><path class="fkcls-1" id="fkpolygon8" fill="#fff" d="M76.56 2.19l74.22 24.93-7.7 87.77-65.41 42.66-69.79-43.93-5.7-86.13z"/><path class="fkcls-2" d="M77.69 160L5.87 114.81 0 26 76.55 0 153 25.67l-7.94 90.4zM9.88 112.43l67.77 42.66 63.45-41.39 7.47-85.13-72-24.18L4.36 28.95z" id="fkpath10" fill="#515151"/><path class="fkcls-3" id="fkpolygon12" fill="#1d79bf" d="M76.4 148.8V61.68l66.93-29.82-5.99 78.77z"/><path id="fkF" class="fkcls-4" fill="#383838" d="M76.4 148.8l-60.35-37.39L9.63 31.8 76.4 61.68z"/><path class="fkcls-1" d="M25.58 52.73l.54 15.93 37.35 18.18.12 14.69-37-18.21 1.64 37.1-14.56-9-5.05-80.55 67.79 30.82v15.46z" id="fkpath15" fill="#fff"/><path class="fkcls-1" d="M135.91 90.77c-.08 13.12-6.33 26.59-16.77 33.12l-42.8 27.93V61.71l42.27-18.84c5.16-2.41 9.51-1.43 12.4 3.11 1.9 3 2.89 7.23 2.86 12.21A35.69 35.69 0 0 1 129.34 76c4.29 2 6.66 6.55 6.57 14.77zM123 63.76c0-4.64-2-6.93-4.92-5.45l-29 14.48L89 90l29.44-15.59c2.5-1.32 4.56-5.91 4.56-10.65zM125.15 96c0-5.71-2.42-8.24-6.55-5.93L89 106.64v19.58l29.34-17.46c4.43-2.64 6.79-7.27 6.81-12.76z" id="fkpath17" fill="#fff"/><path id="fkTOP" class="fkcls-4" fill="#383838" d="M76.4 8.82L9.71 31.77l109.77 2.38-84.02 9.21L76.4 61.68l20.76-9.25-27.73-1.37 49.78-8.46 24.12-10.74z"/></g></g></g></symbol><symbol viewBox="0 0 24 24" id="git" xmlns="http://www.w3.org/2000/svg"><path d="M2.6 10.59L8.38 4.8l1.69 1.7c-.24.85.15 1.78.93 2.23v5.54c-.6.34-1 .99-1 1.73a2 2 0 0 0 2 2 2 2 0 0 0 2-2c0-.74-.4-1.39-1-1.73V9.41l2.07 2.09c-.07.15-.07.32-.07.5a2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0-2-2c-.18 0-.35 0-.5.07L13.93 7.5a1.98 1.98 0 0 0-1.15-2.34c-.43-.16-.88-.2-1.28-.09L9.8 3.38l.79-.78c.78-.79 2.04-.79 2.82 0l7.99 7.99c.79.78.79 2.04 0 2.82l-7.99 7.99c-.78.79-2.04.79-2.82 0L2.6 13.41c-.79-.78-.79-2.04 0-2.82z" fill="#e64a19"/></symbol><symbol viewBox="0 0 494 455" id="gitlab" xmlns="http://www.w3.org/2000/svg"><title>logo</title><defs><path id="fma" d="M0 1173.3h2000V0H0v1173.3z"/></defs><g transform="matrix(.88256 0 0 -.88256 -286.767 742.766)" fill="none" fill-rule="evenodd"><mask id="fmb" fill="#fff"><use width="100%" height="100%" xlink:href="#fma"/></mask><g><g transform="translate(358.67 358.67)"><path d="M492.532 195.445l-27.559 84.815-54.617 168.1c-2.81 8.648-15.045 8.648-17.856 0l-54.619-168.1h-181.37l-54.62 168.1c-2.81 8.648-15.045 8.648-17.856 0l-54.617-168.1-27.557-84.815a18.775 18.775 0 0 1 6.82-20.992l238.51-173.29 238.51 173.29a18.777 18.777 0 0 1 6.82 20.992" fill="#fc6d26"/><path d="M247.2 1.16l90.684 279.1h-181.37z" fill="#e24329"/><path d="M247.201 1.16l-90.684 279.09H29.427z" fill="#fc6d26"/><path d="M29.422 280.256L1.862 195.44a18.774 18.774 0 0 1 6.822-20.991L247.194 1.16z" fill="#fca326"/><path d="M29.422 280.26h127.09l-54.619 168.1c-2.81 8.65-15.047 8.65-17.856 0z" fill="#e24329"/><path d="M247.2 1.16l90.684 279.09h127.09z" fill="#fc6d26"/><path d="M464.98 280.256l27.559-84.815a18.774 18.774 0 0 0-6.821-20.991L247.208 1.16z" fill="#fca326"/><path d="M464.97 280.26H337.88l54.619 168.1c2.81 8.65 15.047 8.65 17.856 0z" fill="#e24329"/></g></g></g></symbol><symbol viewBox="0 0 24 24" id="go" xmlns="http://www.w3.org/2000/svg"><path d="M10.575 1.695c-2.634 0-4.756 2.453-4.756 5.502v4.6l-.027-.003v4.71c0 3.05 2.123 5.502 4.757 5.502h2.286c2.634 0 4.757-2.453 4.757-5.502v-4.6a5.1 5.1 0 0 0 .026.003v-4.71c0-3.049-2.122-5.502-4.756-5.502h-2.287z" fill="#73cddc"/><rect width="2.289" height="3.335" x="-1.178" y="6.092" ry="1.125" transform="matrix(.4849 -.87457 .85979 .51065 0 0)" fill="#73cddc"/><rect width="2.297" height="3.39" x="10.261" y="-15.076" ry="1.143" transform="matrix(.44646 .8948 -.89204 .45195 0 0)" fill="#73cddc"/><circle cx="9.267" cy="5.13" r="2.054" fill="#fff" stroke="#5e5d5b" stroke-width=".1"/><circle cx="14.214" cy="5.116" r="2.054" fill="#fff" stroke="#5e5d5b" stroke-width=".1"/><ellipse cx="8.039" cy="5.051" rx=".792" ry=".901" fill="#030d18"/><path d="M11.792 9.556l.763.138a.403.689 0 0 1 .008.138.403.689 0 0 1-.402.69.403.689 0 0 1-.404-.69.403.689 0 0 1 .035-.276z" fill="#fff" stroke="#fff" stroke-width=".155"/><ellipse cx="8.51" cy="5.365" rx=".138" ry=".166" fill="#fff"/><ellipse cx="12.945" cy="5.189" rx=".792" ry=".901" fill="#030d18"/><ellipse cx="13.414" cy="5.446" rx=".138" ry=".166" fill="#fff"/><ellipse cx="-12.982" cy="-3.409" rx=".708" ry="1.026" transform="rotate(-129.403)" fill="#f6d2a1" stroke-width=".4"/><path d="M11.772 9.553l-.757.135a.4.672 0 0 0-.008.135.4.672 0 0 0 .4.672.4.672 0 0 0 .4-.672.4.672 0 0 0-.035-.27z" fill="#fff" stroke="#fff" stroke-width=".153"/><ellipse cx="1.841" cy="-21.563" rx=".707" ry="1.026" transform="scale(1 -1) rotate(50.597)" fill="#f6d2a1" stroke-width=".4"/><ellipse cx="-17.281" cy="-21.784" rx=".864" ry="1.27" transform="matrix(.3054 -.95222 -.97065 -.2405 0 0)" fill="#f6d2a1" stroke-width=".4"/><ellipse cx="22.885" cy="2.587" rx=".864" ry="1.27" transform="matrix(.22652 .974 .95652 -.29167 0 0)" fill="#f6d2a1" stroke-width=".4"/><path d="M10.708 8.392a.594.594 0 0 0-.594.597v.115c0 .331.264.598.594.598h.386a.973.772 0 0 1 .697-.235.973.772 0 0 1 .698.235h.334c.33 0 .594-.267.594-.598V8.99a.595.595 0 0 0-.594-.597h-2.115z" fill="#f6d2a1" stroke="#657075" stroke-width=".1"/><ellipse cx="11.734" cy="8.203" rx="1.208" ry=".68" fill="#030d18" stroke="#fff" stroke-width=".162"/></symbol><symbol viewBox="0 0 24 24" id="gradle" xmlns="http://www.w3.org/2000/svg"><path d="M21.718 5.503c-.731-1.315-2.04-1.708-2.963-1.727-1.133-.023-2.065.605-1.888 1.017.037.088.25.55.38.741.19.275.527.064.646 0 .353-.187.73-.248 1.16-.198.409.048.954.3 1.319 1.001.859 1.652-1.794 5.05-5.114 2.697-3.32-2.353-6.548-1.574-8.01-1.1-1.462.475-2.135.952-1.556 2.055.785 1.498.524 1.038 1.285 2.28 1.21 1.97 3.856-.908 3.856-.908-1.972 2.906-3.662 2.204-4.31 1.188a15.864 15.864 0 0 1-1.038-1.97c-4.993 1.76-3.642 9.534-3.642 9.534h2.48c.632-2.862 2.892-2.757 3.28 0h1.892c1.673-5.59 5.914 0 5.914 0h2.466c-.69-3.812 1.388-5.01 2.697-7.246 1.31-2.235 2.551-4.969 1.146-7.364zm-6.362 7.362c-1.304-.426-.837-1.723-.837-1.723s1.139.368 2.68.87c-.09.403-.856 1.175-1.843.853z" fill="#0097a7" stroke-width=".47"/></symbol><symbol preserveAspectRatio="xMidYMid" viewBox="0 0 300 300" id="graphcool" xmlns="http://www.w3.org/2000/svg"><path d="M246.886 107.727c-12.237-6.892-27.616 2.1-30.081 3.646l-52.834 29.965c-7.8-6.196-18.914-5.933-26.412.625-7.499 6.558-9.24 17.537-4.14 26.094 5.102 8.556 15.588 12.246 24.923 8.768 9.335-3.478 14.852-13.129 13.111-22.937l52.688-29.9.321-.196c3.464-2.188 11.5-5.462 15.256-3.34 2.706 1.524 4.252 6.629 4.376 14.148h-.066v66.092a17.313 17.313 0 0 1-8.635 14.95l-75.739 43.755a17.312 17.312 0 0 1-17.261 0l-75.74-43.756a17.312 17.312 0 0 1-8.634-14.95V113.22c.01-6.165 3.3-11.86 8.634-14.95l68.549-39.562c6.522 7.482 17.451 9.25 26 4.206s12.283-15.468 8.886-24.794c-3.397-9.327-12.962-14.904-22.751-13.27-9.79 1.636-17.022 10.02-17.204 19.944L59.397 85.632a31.932 31.932 0 0 0-15.978 27.588v87.454a31.933 31.933 0 0 0 15.927 27.602l75.74 43.755a31.934 31.934 0 0 0 31.846 0l75.74-43.755a31.933 31.933 0 0 0 15.927-27.58V137.12h.05c.373-14.913-3.616-24.794-11.762-29.389z" fill="#27ae60" stroke="#27ae60" stroke-width="7.883622079999999"/></symbol><symbol viewBox="0 0 400 400" id="graphql" xmlns="http://www.w3.org/2000/svg"><path d="M67.008 293.022l-13.143-7.588L200.282 31.839l13.143 7.588z" fill="#ec407a" stroke-width="6.803" stroke="#ec407a"/><path d="M50.855 265.174H343.69v15.177H50.855z" fill="#ec407a" stroke-width="6.803" stroke="#ec407a"/><path d="M203.122 358.269L56.649 273.7l7.589-13.143 146.472 84.568zm127.24-220.407L183.889 53.293l7.589-13.143 146.472 84.568z" fill="#ec407a" stroke-width="6.803" stroke="#ec407a"/><path d="M64.278 137.803l-7.588-13.142 146.472-84.568 7.588 13.143z" fill="#ec407a" stroke-width="6.803" stroke="#ec407a"/><path d="M327.661 293.025L181.244 39.43l13.143-7.589 146.417 253.596zM62.466 114.597h15.176v169.136H62.466zm254.528 0h15.176v169.136h-15.176z" fill="#ec407a" stroke-width="6.803" stroke="#ec407a"/><path d="M200.538 351.845l-6.628-11.481L321.3 266.812l6.629 11.48z" fill="#ec407a" stroke-width="6.803" stroke="#ec407a"/><path d="M352.284 288.67c-8.777 15.268-28.342 20.48-43.61 11.703-15.268-8.777-20.48-28.342-11.703-43.61 8.777-15.268 28.342-20.48 43.61-11.703 15.36 8.869 20.57 28.342 11.703 43.61M97.574 141.567c-8.778 15.268-28.343 20.48-43.61 11.703-15.269-8.777-20.48-28.342-11.703-43.61 8.777-15.268 28.342-20.48 43.61-11.703 15.268 8.869 20.479 28.342 11.702 43.61M42.353 288.67c-8.777-15.268-3.566-34.741 11.702-43.61 15.268-8.776 34.741-3.565 43.61 11.703 8.776 15.268 3.565 34.741-11.703 43.61-15.36 8.776-34.833 3.565-43.61-11.703m254.71-147.103c-8.776-15.268-3.565-34.741 11.703-43.61 15.268-8.776 34.742-3.565 43.61 11.703 8.777 15.268 3.566 34.741-11.702 43.61-15.268 8.776-34.833 3.565-43.61-11.703m-99.745 236.608c-17.645 0-31.907-14.262-31.907-31.907s14.262-31.907 31.907-31.907 31.907 14.262 31.907 31.907c0 17.554-14.262 31.907-31.907 31.907m0-294.206c-17.645 0-31.907-14.262-31.907-31.907s14.262-31.907 31.907-31.907 31.907 14.262 31.907 31.907-14.262 31.907-31.907 31.907" fill="#ec407a" stroke-width="6.803" stroke="#ec407a"/></symbol><symbol viewBox="0 0 24 24" id="groovy" xmlns="http://www.w3.org/2000/svg"><path d="M12 1.982a10.119 10.119 0 0 0-10.12 10.12A10.119 10.119 0 0 0 12 22.22 10.119 10.119 0 0 0 22.12 12.1 10.119 10.119 0 0 0 12 1.983zm1.254 2.422c.91 0 1.647.261 2.213.78.571.518.857 1.188.857 2.013 0 .889-.319 1.673-.959 2.35-.64.677-1.376 1.015-2.207 1.015-.486 0-.89-.119-1.213-.357-.317-.238-.476-.532-.476-.88 0-.212.06-.4.181-.563.127-.164.274-.246.438-.246.159 0 .238.092.238.277 0 .164.06.29.182.38.121.09.261.136.42.136.423 0 .828-.29 1.215-.866.391-.582.587-1.202.587-1.863 0-.465-.151-.844-.453-1.135-.301-.296-.69-.445-1.166-.445-.714 0-1.406.318-2.078.953-.666.635-1.211 1.47-1.635 2.506-.417 1.031-.627 2.014-.627 2.945 0 .857.185 1.54.555 2.047.37.503.863.754 1.477.754 1.037 0 2.027-.734 2.974-2.2l1.493-.212c.185-.026.277.018.277.135 0 .053-.072.28-.215.681-.143.402-.337 1.074-.586 2.016.82-.476 1.455-1.003 1.904-1.58v.914c-.36.418-1.046.888-2.062 1.412-.212 1.407-.682 2.493-1.406 3.26-.725.772-1.54 1.16-2.444 1.16-.433 0-.775-.102-1.023-.303-.243-.2-.365-.477-.365-.832 0-.984.955-1.94 2.865-2.865.2-.714.395-1.356.586-1.928-.333.482-.817.907-1.451 1.278-.635.37-1.225.554-1.77.554-.889 0-1.628-.383-2.22-1.15-.588-.772-.881-1.748-.881-2.928 0-1.243.333-2.42 1-3.531a7.747 7.747 0 0 1 2.625-2.674c1.084-.672 2.134-1.008 3.15-1.008zM12.03 16.592c-1.375.687-2.062 1.365-2.062 2.031 0 .354.169.533.508.533.666 0 1.184-.856 1.554-2.564z" fill="#26c6da"/></symbol><symbol viewBox="0 0 24 24" id="gulp" xmlns="http://www.w3.org/2000/svg"><path d="M8.37 15.94a596.238 596.238 0 0 1-.482-4.982c.002-.042-.225-.077-.505-.077h-.508V8.95h3.966V5.198l1.871-1.124c1.14-.685 1.978-1.125 2.144-1.125.4 0 .866.506.866.939 0 .19-.057.422-.127.517-.07.095-.722.53-1.45.966l-1.321.792-.029 1.393-.028 1.393h3.972v1.932h-.98l-.495 4.983-.495 4.983H8.854l-.485-4.906z" fill="#e53935"/></symbol><symbol viewBox="0 0 24 24" id="h" xmlns="http://www.w3.org/2000/svg"><path d="M16.745 19.818h-3.007v-5.882q0-2.381-1.736-2.381-.869 0-1.438.663-.56.662-.56 1.718v5.882H6.988V4.533h3.016v6.508h.037q1.186-1.802 3.193-1.802 3.511 0 3.511 4.239z" stroke-width=".478" fill="#0277bd"/></symbol><symbol viewBox="0 0 253.6 253.6" id="hack" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-29.243 -29.515) scale(1.2301)"><path fill="#607d8b" d="M69.496 159.551v52.576l51.77-52.576zM123.507 41.523l-54.01 52.755v55.084l54.01-54.009z"/><path fill="#eceff1" d="M130.023 95.663v51.501l52.128-51.5z"/><path fill="#607d8b" d="M185.465 101.867l-55.442 55.174v55.083l55.442-55.262z"/><path fill="#ffa000" d="M73.068 154.283l50.427.09v-50.248z"/></g></symbol><symbol viewBox="0 0 300 300.00001" id="haml" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 165.6)"><path d="M78.42-132.307c-12.047-.302-26.924 5.998-26.924 5.998l49.195 99.791L74.605 85.005c23.81 20.134 50.07 10.504 50.07 10.504L136.76 9.212c1.526 1.446 3.146 2.77 4.777 3.995 5.244 3.714 10.925 6.553 16.606 8.738 5.68 2.185 11.583 3.933 17.482 5.244 3.933.874 7.645 1.53 11.578 1.967-1.748 3.933-2.84 8.083-2.621 12.672 0 .437.22.873.656 1.092h.217c4.152 2.185 8.521 3.934 13.328 5.027 4.589.874 9.615 1.312 14.422.656 5.026-.655 10.051-2.623 13.984-5.9 3.933-3.278 6.774-7.648 8.522-12.237l.219-.218v-.217l.656-5.899v-.22c2.185-1.311 4.37-2.621 6.555-4.37 2.622-2.184 5.025-4.589 6.773-7.648 1.748-3.059 2.84-6.774 2.621-10.488-.218-3.496-1.53-6.99-3.06-10.049-1.53-3.059-3.495-5.901-5.68-8.523-4.37-5.026-9.614-9.176-15.295-12.454-5.462-3.496-11.581-6.338-17.7-8.304l-2.404-.656-1.962-.655c-1.311-.437-2.406-1.092-3.498-1.53-2.185-1.31-3.717-2.622-4.809-4.37-2.185-3.278-2.403-8.301-1.31-13.545.218-1.311.656-2.623 1.093-3.934a96.064 96.064 0 0 0 1.31-4.152c.314-1.412.51-2.829.598-4.402l29.203-25.553c-2.275-8.404-27.488-17.158-27.488-17.158l-74.931 63.726-43.243-81.584c-1.553-.35-3.218-.527-4.94-.57zm107.682 73.14c-.449 2.336-.647 4.795-.647 7.258.219 3.715 1.311 7.87 3.715 11.366 2.403 3.496 5.68 6.117 8.957 7.646a29.663 29.663 0 0 0 5.027 1.967l2.623.654 2.184.438c5.68 1.53 11.142 3.714 16.168 6.554 5.025 2.84 9.833 6.337 13.766 10.27s6.992 8.959 7.43 13.984c.218 3.496-.22 6.118-1.313 8.303-1.093 2.404-2.84 4.588-4.807 6.555-.874.874-1.966 1.747-2.84 2.402a27.11 27.11 0 0 0-.654-5.898c-.219-1.093-.438-1.966-.875-3.059-.437-.874-.872-1.966-1.965-2.621-.218 0-.44-.001-.44.217-1.31 3.277-3.494 6.12-5.898 8.086-2.403 1.966-5.462 2.84-8.521 3.058-3.06.219-6.338-.436-9.616-1.31-3.277-.874-6.552-1.968-9.83-3.06l-.439-.22c-.656-.218-1.526.002-1.963.44-1.748 2.185-3.06 4.149-4.59 6.334a58.435 58.435 0 0 0-2.84 5.027c-3.933-1.53-7.649-2.841-11.582-4.37-5.462-2.186-10.925-4.37-15.95-6.991-5.245-2.404-10.268-5.246-14.638-8.524-3.15-2.363-6.062-4.845-8.185-7.681l2.404-17.172z" fill="#f4511e" stroke-width="0" stroke-linejoin="round"/></g></symbol><symbol viewBox="0 0 24 24" id="handlebars" xmlns="http://www.w3.org/2000/svg"><path d="M8.55 10.32c-2.753 0-4.202 3.48-5.793 3.48-.98 0-1.126-.677-1.126-.915 0-.332.236-.706.564-.706.59 0 .414.77.414.77s.798-.555.272-1.298c-.42-.595-1.31-.623-1.92-.17-.617.458-1.057 1.146-.853 2.287.1.551.468 1.35 1.233 1.805.764.455 1.925.566 2.335.566 2.194 0 4.342-1.633 6.639-2.322a5.513 5.513 0 0 1 1.497-.222 6.19 6.19 0 0 1 1.92.226c2.296.689 4.444 2.323 6.638 2.323.41 0 1.57-.11 2.335-.566.765-.455 1.132-1.256 1.231-1.807.204-1.14-.235-1.829-.853-2.287-.61-.453-1.497-.423-1.918.172-.526.743.27 1.297.27 1.297s-.176-.77.414-.77c.329 0 .565.373.565.705 0 .238-.147.914-1.126.914-1.592 0-3.04-3.478-5.794-3.478-2.565 0-3.076 1.177-3.462 1.718-.004.005-.005.011-.008.016-.005-.006-.007-.013-.012-.02-.386-.54-.896-1.717-3.461-1.717z" fill="#ff7043" fill-rule="evenodd" stroke-width=".3"/></symbol><symbol viewBox="0 0 300.00001 300" id="haskell" xmlns="http://www.w3.org/2000/svg"><g stroke-width="2.422"><path d="M23.928 240.5l59.94-89.852-59.94-89.855h44.955l59.94 89.855-59.94 89.852z" fill="#ef5350"/><path d="M83.869 240.5l59.94-89.852-59.94-89.855h44.955l119.88 179.71h-44.95l-37.46-56.156-37.468 56.156z" fill="#ffa726"/><path d="M228.72 188.08l-19.98-29.953h69.93v29.956h-49.95zm-29.97-44.924l-19.98-29.953h99.901v29.953z" fill="#ffee58"/></g></symbol><symbol viewBox="0 0 210 210" id="haxe" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -87)"><path fill="#f68712" stroke-width=".221" d="M42.78 191.545l63.431-63.43 63.431 63.43-63.431 63.431z"/><path d="M42.8 191.592L31.193 148.28 19.59 104.97 62.9 116.575l43.311 11.605-31.706 31.706z" fill="#fab20b" stroke-width=".266"/><path d="M105.956 128.111l-43.19-11.544-43.177-11.597 22.927.185 23.228.294 20.264 11.36z" fill="#fbc707" stroke-width=".265"/><path d="M19.59 104.97l11.596 43.176 11.545 43.19-11.303-19.948-11.36-20.263-.294-23.228z" fill="#fff200" stroke-width=".265"/><path d="M106.23 128.133l43.312-11.605 43.311-11.605-11.605 43.31-11.605 43.312-31.706-31.706z" fill="#f47216" stroke-width=".266"/><path d="M169.711 191.289l11.545-43.19 11.597-43.176-.185 22.927-.294 23.228-11.36 20.263z" fill="#f1471d" stroke-width=".265"/><path d="M192.853 104.923l-43.176 11.597-43.19 11.544 19.947-11.303 20.264-11.36 23.228-.293z" fill="#fbc707" stroke-width=".265"/><path d="M169.643 191.545l11.605 43.31 11.605 43.312-43.311-11.605-43.311-11.606 31.706-31.705z" fill="#f25c19" stroke-width=".266"/><path d="M106.487 255.025l43.19 11.544 43.176 11.598-22.927-.185-23.228-.294-20.264-11.36z" fill="#f68712" stroke-width=".265"/><path d="M192.853 278.167l-11.597-43.176-11.545-43.19 11.303 19.947 11.36 20.264.294 23.228z" fill="#f1471d" stroke-width=".265"/><path d="M106.211 254.976l-43.31 11.605-43.312 11.605 11.605-43.31L42.8 191.563l31.706 31.706z" fill="#f89c0e" stroke-width=".266"/><path d="M42.731 191.82l-11.545 43.19-11.597 43.176.185-22.927.294-23.228 11.36-20.263z" fill="#fff200" stroke-width=".265"/><path d="M19.59 278.186l43.175-11.597 43.19-11.544-19.947 11.303-20.264 11.36-23.228.293z" fill="#f25c19" stroke-width=".265"/></g></symbol><symbol viewBox="0 0 144 152" id="heroku" xmlns="http://www.w3.org/2000/svg"><path d="M118.68 13.279H26.865c-6.337 0-11.476 5.139-11.476 11.476V129.32c0 6.338 5.139 11.477 11.476 11.477h91.813c6.338 0 11.477-5.14 11.477-11.477V24.755c0-6.337-5.139-11.476-11.477-11.476zM44.08 121.669V96.165l14.346 12.752zm44.632 0v-38.08c-.063-2.976-1.496-6.551-7.97-6.551-12.966 0-27.51 6.52-27.654 6.586l-9.008 4.08V32.407h12.752v36.201c6.366-2.072 15.266-4.321 23.91-4.321 7.882 0 12.6 3.099 15.17 5.698 5.484 5.547 5.56 12.613 5.551 13.43v38.255zm3.188-68.54H79.149c5.011-6.576 8.158-13.496 9.564-20.723h12.751c-.86 7.243-3.796 14.187-9.563 20.722z" fill="#6963b9"/></symbol><symbol viewBox="0 0 24 24" id="hpp" xmlns="http://www.w3.org/2000/svg"><path d="M9.757 19.818H6.751v-5.882q0-2.381-1.737-2.381-.868 0-1.438.663-.56.662-.56 1.718v5.882H0V4.533h3.016v6.508h.037Q4.24 9.239 6.247 9.239q3.51 0 3.51 4.239z" stroke-width=".478" fill="#0277bd"/><path d="M13.073 11.448v2h-2v2h2v2h2v-2h2v-2h-2v-2zm7 0v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#0277bd"/></symbol><symbol viewBox="0 0 24 24" id="html" xmlns="http://www.w3.org/2000/svg"><path d="M12 17.56l4.07-1.13.55-6.1H9.38L9.2 8.3h7.6l.2-1.99H7l.56 6.01h6.89l-.23 2.58-2.22.6-2.22-.6-.14-1.66h-2l.29 3.19L12 17.56M4.07 3h15.86L18.5 19.2 12 21l-6.5-1.8L4.07 3z" fill="#e44d26"/></symbol><symbol viewBox="0 0 24 24" id="http" xmlns="http://www.w3.org/2000/svg"><path d="M16.046 13.784c.074-.613.13-1.225.13-1.856s-.056-1.244-.13-1.856h3.137c.148.594.241 1.215.241 1.856a7.65 7.65 0 0 1-.241 1.856m-4.78 5.16c.557-1.03.984-2.144 1.281-3.304h2.738a7.452 7.452 0 0 1-4.019 3.304m-.232-5.16H9.828a12.314 12.314 0 0 1-.149-1.856c0-.631.056-1.253.149-1.856h4.343c.084.603.149 1.225.149 1.856 0 .63-.065 1.243-.149 1.856M12 19.315c-.77-1.113-1.393-2.348-1.773-3.675h3.545c-.38 1.327-1.002 2.562-1.773 3.675m-3.712-11.1h-2.71a7.353 7.353 0 0 1 4.01-3.304c-.557 1.03-.975 2.144-1.3 3.304m-2.71 7.425h2.71c.325 1.16.743 2.274 1.3 3.304a7.433 7.433 0 0 1-4.01-3.304m-.761-1.856a7.65 7.65 0 0 1-.241-1.856c0-.64.093-1.262.241-1.856h3.137c-.074.612-.13 1.225-.13 1.856 0 .63.056 1.243.13 1.856m4.046-9.253c.77 1.114 1.393 2.357 1.773 3.684h-3.545c.38-1.327 1.002-2.57 1.773-3.684m6.422 3.684h-2.738a14.523 14.523 0 0 0-1.28-3.304 7.412 7.412 0 0 1 4.018 3.304m-6.423-5.568c-5.132 0-9.28 4.176-9.28 9.28a9.28 9.28 0 0 0 9.28 9.282 9.28 9.28 0 0 0 9.281-9.281A9.28 9.28 0 0 0 12 2.647z" fill="#e53935" stroke-width=".928"/></symbol><symbol viewBox="0 0 24 24" id="image" xmlns="http://www.w3.org/2000/svg"><path d="M13.009 9.202h5.368l-5.368-5.368v5.368M6.177 2.37h7.808l5.856 5.856v11.711a1.952 1.952 0 0 1-1.952 1.952H6.178a1.951 1.951 0 0 1-1.952-1.952V4.322c0-1.083.868-1.952 1.952-1.952m0 17.567h11.71V12.13l-3.903 3.903-1.952-1.951-5.856 5.855M8.13 9.202a1.952 1.952 0 0 0-1.952 1.952 1.952 1.952 0 0 0 1.952 1.952 1.952 1.952 0 0 0 1.952-1.952A1.952 1.952 0 0 0 8.13 9.202z" fill="#26a69a" stroke-width=".976"/></symbol><symbol viewBox="0 0 512 512" id="ionic" xmlns="http://www.w3.org/2000/svg"><g fill="#4f8ff7"><path d="M423.592 132.804A31.855 31.855 0 0 0 429 115c0-17.675-14.33-32-32-32a31.853 31.853 0 0 0-17.805 5.409C344.709 63.015 302.11 48 256 48 141.125 48 48 141.125 48 256c0 114.877 93.125 208 208 208 114.873 0 208-93.123 208-208 0-46.111-15.016-88.71-40.408-123.196zM391.83 391.832c-17.646 17.646-38.191 31.499-61.064 41.174-23.672 10.012-48.826 15.089-74.766 15.089-25.94 0-51.095-5.077-74.767-15.089-22.873-9.675-43.417-23.527-61.064-41.174s-31.5-38.191-41.174-61.064C68.982 307.096 63.905 281.94 63.905 256c0-25.94 5.077-51.095 15.089-74.767 9.674-22.873 23.527-43.417 41.174-61.064s38.191-31.5 61.064-41.174c23.673-10.013 48.828-15.09 74.768-15.09 25.939 0 51.094 5.077 74.766 15.089a191.221 191.221 0 0 1 37.802 21.327A31.853 31.853 0 0 0 365 115c0 17.675 14.327 32 32 32 5.293 0 10.28-1.293 14.678-3.568a191.085 191.085 0 0 1 21.327 37.801c10.013 23.672 15.09 48.827 15.09 74.767 0 25.939-5.077 51.096-15.09 74.768-9.675 22.873-23.527 43.418-41.175 61.064z"/><circle cx="256.003" cy="256" r="96"/></g></symbol><symbol viewBox="0 0 24 24" id="java" xmlns="http://www.w3.org/2000/svg"><path d="M2 21h18v-2H2M20 8h-2V5h2m0-2H4v10a4 4 0 0 0 4 4h6a4 4 0 0 0 4-4v-3h2a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z" fill="#f44336"/></symbol><symbol viewBox="0 0 24 24" id="javascript" xmlns="http://www.w3.org/2000/svg"><path d="M3 3h18v18H3V3m4.73 15.04c.4.85 1.19 1.55 2.54 1.55 1.5 0 2.53-.8 2.53-2.55v-5.78h-1.7V17c0 .86-.35 1.08-.9 1.08-.58 0-.82-.4-1.09-.87l-1.38.83m5.98-.18c.5.98 1.51 1.73 3.09 1.73 1.6 0 2.8-.83 2.8-2.36 0-1.41-.81-2.04-2.25-2.66l-.42-.18c-.73-.31-1.04-.52-1.04-1.02 0-.41.31-.73.81-.73.48 0 .8.21 1.09.73l1.31-.87c-.55-.96-1.33-1.33-2.4-1.33-1.51 0-2.48.96-2.48 2.23 0 1.38.81 2.03 2.03 2.55l.42.18c.78.34 1.24.55 1.24 1.13 0 .48-.45.83-1.15.83-.83 0-1.31-.43-1.67-1.03l-1.38.8z" fill="#ffca28"/></symbol><symbol viewBox="0 0 24 24" id="javascript-map" xmlns="http://www.w3.org/2000/svg"><path d="M18 8v2h2v10H10v-2H8v4h14V8h-4z" fill="#ffca28"/><path d="M2.444 2.506h14.135v14.136H2.444V2.506m3.714 11.811c.315.668.935 1.218 1.995 1.218 1.178 0 1.987-.629 1.987-2.003V8.993H8.805v4.508c0 .675-.275.848-.707.848-.455 0-.644-.314-.856-.683l-1.084.651m4.697-.14c.392.769 1.185 1.358 2.426 1.358 1.257 0 2.199-.652 2.199-1.854 0-1.107-.636-1.602-1.767-2.089l-.33-.141c-.573-.243-.816-.408-.816-.801 0-.322.243-.573.636-.573.377 0 .628.165.856.573l1.028-.683c-.432-.754-1.044-1.045-1.884-1.045-1.186 0-1.948.754-1.948 1.752 0 1.083.636 1.594 1.594 2.002l.33.141c.613.267.974.432.974.888 0 .377-.354.652-.903.652-.652 0-1.029-.338-1.312-.81l-1.083.63z" fill="#ffca28"/></symbol><symbol viewBox="0 0 180 180" id="jenkins" xmlns="http://www.w3.org/2000/svg"><defs><clipPath id="gia"><path transform="scale(1 -1)" fill="#37474f" d="M.899-144.42h144.42V0H.899z"/></clipPath></defs><g transform="matrix(1.0691 0 0 -1.0691 9.4 166.143)" clip-path="url(#gia)"><g fill-rule="evenodd"><path d="M107.96 30.661l-12.506-1.876-16.883-1.876-10.943-.312-10.629.312-8.13 2.502-7.19 7.815-5.628 15.945-1.25 3.44-7.504 2.5-4.377 7.191-3.126 10.317 3.44 9.067 8.128 2.814 6.565-3.127 3.127-6.878 3.752.626 1.25 1.563-1.25 7.19-.313 9.068 1.876 12.505-.074 7.143 5.701 9.114 10.005 7.19 17.508 7.504 19.383-2.814 16.883-12.193 7.817-12.505 5.002-9.067 1.25-22.51-3.752-19.384-6.877-17.195-6.566-9.066" fill="#f0d6b7"/><path d="M97.334-23.425l-44.709-1.876v-7.503l3.752-26.262-1.876-2.19-31.264 10.63-2.19 3.752-3.126 35.328-7.19 21.26-1.563 5.002 25.01 17.195 7.818 3.127 6.877-8.441 5.94-5.315 6.88-2.188 3.125-.938L68.57 1.899l2.814-3.44 7.19 2.502-5.002-9.693 27.2-12.818-3.439-1.876" fill="#335061"/><path d="M23.238 85.687l8.128 2.814 6.566-3.127 3.127-6.878 3.751.626.938 3.751-1.876 7.19 1.876 17.197-1.563 9.379 5.627 6.565 12.193 9.692-3.44 4.69-17.194-8.442-7.191-5.627-4.064-8.754-6.253-8.442-1.876-10.005 1.251-10.63" fill="#6d6b6d"/><path d="M36.055 115.07s4.69 11.567 23.448 17.195c18.759 5.628.938 4.065.938 4.065l-20.321-7.817-7.817-7.816-3.438-6.253 7.19.626M26.676 87.875s-6.566 21.886 18.446 25.012l-.938 3.752-17.195-4.065-5.003-16.257 1.251-10.63 3.439 2.188" fill="#dcd9d8"/></g><g fill="#f7e4cd"><path d="M36.681 58.799l4.094 3.966s1.847-.214 2.16-2.402c.312-2.19 1.25-21.886 14.693-32.516 1.227-.97-10.004 1.564-10.004 1.564L37.62 45.042M94.209 64.739s.729 9.477 3.28 8.748c2.553-.729 2.553-3.28 2.553-3.28s-6.198-4.01-5.833-5.468" fill-rule="evenodd"/><path d="M120.16 99.442s-5.153-1.088-5.628-5.628c-.474-4.54 5.628-.938 6.566-.625M82.327 99.129s-6.879-.938-6.879-5.314c0-4.378 7.817-4.065 10.005-2.19"/><g fill-rule="evenodd"><path d="M39.807 78.808s-11.881 7.191-13.131.312c-1.25-6.877-4.065-11.88 1.876-19.07l-4.064 1.25-3.752 9.691-1.25 9.38 7.19 7.504 8.129-.626 4.69-3.751.312-4.69M45.435 98.504s5.315 27.512 32.203 32.827c22.136 4.375 33.765-.938 38.142-5.94 0 0-19.696 23.447-38.455 16.257-18.759-7.191-32.514-20.322-32.202-28.762.532-14.377.313-14.382.313-14.382M117.97 122.27s-9.066.312-9.38-7.817c0 0 0-1.25.625-2.5 0 0 7.192 8.129 11.568 3.751"/><path d="M78.268 111.1s-1.56 12.477-12.199 5.223c-6.878-4.69-6.252-11.255-5.002-12.505s.91-3.77 1.862-2.04c.952 1.728.638 7.356 4.078 8.918 3.439 1.564 9.077 3.31 11.26.404"/></g></g><g fill="#49728b" fill-rule="evenodd"><path d="M48.874 26.597L19.486 13.466s12.193-48.46 5.94-63.467l-4.377 1.563-.313 18.446-8.128 35.015-3.44 9.692 30.639 20.633 9.067-8.753M51.896-.206l4.17-5.087v-18.76h-5.003s-.625 13.132-.625 14.696c0 1.563.624 7.19.624 7.19M52-26.866l-14.069-.625 4.065-2.813L52-31.868"/></g><g fill-rule="evenodd"><path d="M100.15-23.739l11.567.313 2.814-28.764-11.881-1.563-2.5 30.014" fill="#335061"/><path d="M103.27-23.739l17.508.938s7.19 18.133 7.19 19.07c0 .939 6.253 26.263 6.253 26.263l-14.069 14.694-2.813 2.501-7.504-7.503V3.148l-6.565-26.887" fill="#335061"/><path d="M111.09-21.55l-10.942-2.188 1.563-8.755c4.064-1.876 10.943 3.127 10.943 3.127M111.4 33.162l21.885-16.257.626 7.503-16.57 15.32-5.94-6.566" fill="#49728b"/><path d="M62.85-85.332l-6.473 26.266-3.22 19.38-.531 14.385 29.296 1.56 18.226.003-1.658-32.83 2.814-25.324-.312-4.69-23.76-1.876-14.382 3.126" fill="#fff"/><path d="M96.083-23.426s-1.563-32.515 3.127-55.65c0 0-9.38-5.94-23.136-7.503l26.262.938 3.126 1.875-3.752 51.273-.938 10.944" fill="#dcd9d8"/><path d="M115.06-49.691l12.193 3.44 23.135 1.25 3.44 10.629-6.254 18.446-7.19.938-10.005-3.127-9.599-4.686-5.095.935-3.972-1.56" fill="#fff"/><path d="M114.84-43.435s8.128 3.751 9.38 3.438L120.78-22.8l4.065 1.563s2.814-16.257 2.814-18.133c0 0 17.507-.938 19.07-.938 0 0 3.752 7.191 2.814 14.694l3.44-10.005.312-5.628-5.002-7.503-5.627-1.25-9.38.312-3.126 4.064-10.943-1.563-3.44-1.25" fill="#dcd9d8"/></g><path d="M102.56-21.241L95.682-3.733l-7.19 10.317s1.562 4.377 3.75 4.377h7.192l6.878-2.501-.625-11.568-3.127-18.134" fill="#fff"/><path d="M103.9-15.297S95.145 1.585 95.145 4.086c0 0 1.563 3.752 3.752 2.814 2.19-.938 6.879-3.439 6.879-3.439v5.94l-10.63 2.19-7.19-.939 12.193-28.763 2.5-.313" fill="#dcd9d8" fill-rule="evenodd"/><path d="M65.664 25.968l-8.661.942-8.13 2.501v-2.814l3.972-4.38 12.506-5.627" fill="#fff"/><path d="M51.689 25.031s9.693-4.065 12.819-3.127l.311-3.748-8.752 1.872-5.316 3.752.938 1.251" fill="#dcd9d8" fill-rule="evenodd"/><path d="M115.03 9.897c-5.305.156-10.098.786-14.294 1.97.285 1.72-.249 3.408.18 4.647 1.17.843 3.13.83 4.898 1.027-1.529.752-3.677 1.049-5.44.615-.042 1.194-.578 1.934-.902 2.868 2.982 1.064 10.024 8.044 13.984 5.732 1.887-1.099 2.689-7.377 2.835-10.43.122-2.533-.23-5.088-1.261-6.43" fill="#d33833" fill-rule="evenodd"/><path d="M115.03 9.897c-5.305.156-10.098.786-14.294 1.97.285 1.72-.249 3.408.18 4.647 1.17.843 3.13.83 4.898 1.027-1.529.752-3.677 1.049-5.44.615-.042 1.194-.578 1.934-.902 2.868 2.982 1.064 10.024 8.044 13.984 5.732 1.887-1.099 2.689-7.377 2.835-10.43.122-2.533-.23-5.088-1.261-6.43z" fill="none" stroke="#d33833" stroke-width="2"/><path d="M89.66 18.569c-.014-.401-.03-.806-.047-1.21-1.656-1.089-4.33-1.076-6.148-1.99 2.68-.117 4.79-.763 6.614-1.672l-.118-3.033c-3.036-2.078-5.81-5.173-9.384-7.122-1.69-.922-7.622-3.294-9.42-2.875-1.017.236-1.109 1.499-1.516 2.689-.866 2.548-2.861 6.605-3.035 10.44-.222 4.846-.71 12.967 4.51 11.969 4.213-.804 9.113-2.745 12.375-4.527 1.993-1.09 3.146-2.436 6.17-2.669" fill="#d33833" fill-rule="evenodd"/><path d="M89.66 18.569c-.014-.401-.03-.806-.047-1.21-1.656-1.089-4.33-1.076-6.148-1.99 2.68-.117 4.79-.763 6.614-1.672l-.118-3.033c-3.036-2.078-5.81-5.173-9.384-7.122-1.69-.922-7.622-3.294-9.42-2.875-1.017.236-1.109 1.499-1.516 2.689-.866 2.548-2.861 6.605-3.035 10.44-.222 4.846-.71 12.967 4.51 11.969 4.213-.804 9.113-2.745 12.375-4.527 1.993-1.09 3.146-2.436 6.17-2.669z" fill="none" stroke="#d33833" stroke-width="2"/><path d="M92.675 12.788c-.463 2.64-.999 3.393-.792 5.695 7.04 4.693 8.361-8.061.792-5.695" fill="#d33833" fill-rule="evenodd"/><path d="M92.675 12.788c-.463 2.64-.999 3.393-.792 5.695 7.04 4.693 8.361-8.061.792-5.695z" fill="none" stroke="#d33833" stroke-width="2"/><path d="M102.87 10.649s-2.19 3.127-.626 4.065c1.564.938 3.127 0 4.065 1.563s0 2.501.313 4.377 1.877 2.189 3.44 2.501c1.562.313 5.94.938 6.565-.625l-1.876 5.627-3.752 1.25-11.88-6.877-.626-3.44v-6.877M70.041.331c-.376 4.88-.773 9.752-1.215 14.626-.662 7.279 1.748 6.009 8.057 6.009.964 0 5.933-1.15 6.289-1.876 1.705-3.483-2.851-2.709 1.964-5.335 4.065-2.216 11.246 1.346 9.603 6.273-.919 1.095-4.789.341-6.176 1.06l-7.327 3.8c-3.108 1.612-10.29 3.962-13.603 1.709-8.395-5.71.53-19.974 3.524-25.93" fill="#ef3d3a" fill-rule="evenodd"/><g fill="#231f20" fill-rule="evenodd"><path d="M78.268 111.1c-8.521 1.985-12.755-3.566-15.338-9.323-2.306.559-1.389 3.695-.806 5.294 1.525 4.194 7.672 9.778 12.694 9.02 2.161-.325 5.086-2.301 3.45-4.99M119.79 101.4l.404-.016c1.926-4 3.593-8.238 6.022-11.769-1.628-3.79-12.322-7.144-12.157-.338 2.313 1.01 6.305.206 8.356 1.497-1.186 3.254-2.897 6.024-2.625 10.626M82.63 101.29c1.827-3.35 2.422-6.868 5.019-9.4 1.17-1.14 3.444-2.529 2.316-5.698-.263-.747-2.189-2.414-3.3-2.741-4.06-1.2-13.521-.248-10.317 4.814 3.358-.157 7.871-2.18 10.38.257-1.927 3.081-5.363 9.177-4.098 12.768M118.26 67.253c-6.113-3.927-12.93-8.197-22.947-7.207-2.14 1.86-2.956 6.002-.877 8.737 1.082-1.861.402-5.284 3.419-5.799 5.684-.972 12.299 3.477 16.387 5.032 2.535 4.275-.219 5.847-2.503 8.597-4.675 5.636-10.947 12.622-10.72 21.06 1.89 1.37 2.053-2.092 2.325-2.722 2.44-5.714 8.585-13.021 13.07-17.912 1.1-1.205 2.914-2.36 3.115-3.157.582-2.315-1.513-5.09-1.27-6.63M37.668 71.387c-1.916 1.094-2.372 5.91-4.622 6.048-3.215.195-2.629-6.25-2.616-10.018-2.213 2.009-2.602 8.194-.976 11.37-1.853.91-2.68-1.003-3.708-1.677 1.32 9.595 14.036 4.45 11.922-5.723M122.15 63.257c-2.846-5.417-6.871-11.382-15.222-11.555-.17 1.75-.3 4.411.009 5.464 6.384.614 10.325 3.863 15.212 6.091M82.149 59.745c5.326-2.8 15.114-3.102 22.353-2.89.388-1.586.379-3.545.394-5.48-9.305-.463-20.307 1.84-22.747 8.37M81.136 54.523c3.683-9.247 16.341-8.182 27.016-7.927-.47-1.2-1.489-2.62-2.755-3.132-3.42-1.392-12.855-2.448-17.604.074-3.011 1.601-4.946 5.219-6.596 7.34-.797 1.024-4.765 3.64-.06 3.645"/></g><path d="M117.82 3.516c-4.322-7.402-8.457-15.005-13.585-21.534 2.15 6.32 3.07 16.9 3.394 24.965 4.498 2.105 8.349-.474 10.191-3.43" fill="#81b0c4" fill-rule="evenodd"/><g fill="#231f20" fill-rule="evenodd"><path d="M141.07-23.089c-4.839-.969-8.239-5.671-12.959-5.37 2.594 3.658 7.14 5.2 12.959 5.37M143.21-30.661c-3.944-.417-8.576-1.055-12.577-.726 1.894 2.892 9.19 1.894 12.577.726M144.58-37.19c-4.433-.096-9.942-.008-14.155.346 2.492 2.677 11.28.993 14.155-.346"/></g><g fill-rule="evenodd"><path d="M109.48-55.057c.636-5.567 2.843-11.207 2.566-17.304-2.45-.827-3.858-1.55-7.142-1.545-.232 5.181-.925 13.102-.718 18.041 1.615-.107 3.997 1.154 5.294.808" fill="#dcd9d8"/><path d="M102.33 26.985c-2.226-1.453-4.121-3.267-6.259-4.818-4.74-.235-7.327.328-10.81 3.05.057.219.407.121.42.39 5.075-2.262 11.524.92 16.648 1.378" fill="#f0d6b7"/><path d="M75.694-7.603c1.394 6.04 6.857 9.17 11.817 12.497 5.12-6.498 8.234-14.855 11.663-22.92-8.102 2.443-16.38 6.406-23.481 10.423" fill="#81b0c4"/><path d="M104.18-55.865c-.207-4.94.486-12.86.718-18.041 3.283-.004 4.691.718 7.142 1.545.276 6.096-1.93 11.737-2.566 17.304-1.298.346-3.679-.914-5.294-.808zm-51.13 28.09c2.165-19.906 5.301-36.639 11.054-54.266 12.766-3.876 28.157-4.214 39.441-.716-2.072 9.948-1.167 22.06-2.378 32.677-.912 7.98-.447 16.009-1.698 24.15-13.673 2.844-33 .665-46.418-1.845zm49.651 1.72c-.115-8.549.383-16.982 1.036-25.542 3.282.493 5.51.822 8.56 1.49-.99 8.241-.869 17.514-2.886 24.804-2.332-.023-4.385.027-6.71-.752zm16.653 1.378c-1.558.357-3.372.014-4.86-.015.7-6.969 2.397-14.659 2.995-21.974 2.342-.073 3.593 1.032 5.52 1.403.102 6.421-.562 15.268-3.655 20.586zm25.215-23.038c4.882 1.186 7.952 7.165 6.586 13.305-.916 4.127-2.548 11.898-4.295 14.538-1.29 1.953-4.79 4.51-7.584 2.72-4.545-2.91-12.552-3.755-15.867-7.278 1.662-5.534 2.178-13.135 2.864-20.146 5.678-.354 12.665 1.562 17.387-.471-3.297-1.068-7.575-1.077-10.423-2.633 2.328-1.125 7.778-.897 11.332-.035zM99.17-18.025c-3.43 8.063-6.543 16.42-11.663 22.918-4.96-3.327-10.423-6.456-11.817-12.497 7.1-4.017 15.379-7.98 23.481-10.422zm8.453 24.971c-.325-8.065-1.245-18.644-3.395-24.965 5.128 6.53 9.263 14.132 13.585 21.534-1.842 2.957-5.693 5.536-10.19 3.431zm-9.582 3.405c-1.943.21-3.592-2.233-6.117-1.177-.58-.64-1.105-1.333-1.695-1.958 5.579-6.723 8.114-16.262 12.423-24.163 2.312 7.59 2.045 15.904 2.555 24.188-3.177-.201-4.94 2.873-7.166 3.11zm-6.161 8.132c-.208-2.303.328-3.056.791-5.695 7.57-2.367 6.248 10.388-.791 5.695zm-8.394 2.755c-3.261 1.782-8.161 3.723-12.374 4.527-5.222.999-4.732-7.123-4.51-11.968.173-3.836 2.168-7.893 3.035-10.441.406-1.19.498-2.453 1.515-2.69 1.798-.418 7.73 1.954 9.42 2.875 3.575 1.95 6.348 5.045 9.384 7.123.04 1.011.078 2.021.119 3.032-1.826.91-3.935 1.555-6.615 1.673 1.818.914 4.492.901 6.148 1.989.016.405.033.81.047 1.21-3.024.234-4.176 1.58-6.17 2.67zm-31.152 5.659c-2.707-2.748 7.592-6.494 10.871-6.696-.018 1.739.991 3.378.788 4.626-3.895.684-9.013.232-11.66 2.07zm33.345-1.29c-.013-.27-.363-.172-.42-.39 3.482-2.722 6.07-3.285 10.81-3.05 2.137 1.551 4.033 3.365 6.259 4.818-5.124-.458-11.574-3.64-16.648-1.379zm30.606-9.282c-.146 3.053-.948 9.332-2.835 10.431-3.961 2.312-11.002-4.668-13.984-5.732.324-.934.86-1.674.901-2.868 1.764.434 3.912.137 5.44-.615-1.767-.198-3.727-.185-4.897-1.027-.429-1.239.105-2.927-.18-4.647 4.196-1.184 8.989-1.814 14.294-1.97 1.032 1.341 1.383 3.896 1.261 6.429zM47.777 24.24c-.85.606-6.6 8.087-7.388 7.777-10.405-4.103-20.134-11.199-28.828-17.91 8.29-17.787 11.635-39.579 12.227-60.582 9.496-4.441 17.836-10.844 30.722-11.512-1.491 10.55-2.852 19.962-3.699 29.895-3.237 1.365-7.882-.062-10.913.423-.025 3.651 4.628 1.6 5.015 4.054.292 1.858-2.56 1.998-1.631 4.923 2.368-.861 3.612-2.763 6.138-3.477 2.309 5.05-.032 13.985.3 18.205.064.792.397 4.39 2.172 3.759 1.57-.559-.09-9.569.082-13.563.157-3.68-.444-7.242 1.046-9.552a355.817 355.817 0 0 0 38.576 3.16c-2.964 1.272-6.485 2.475-10.345 4.651-2.093 1.18-8.69 3.635-9.293 5.622-.964 3.167 2.528 4.855 3.125 7.57-6.285-3.428-7.511 3.286-8.998 8.042-1.347 4.308-2.114 7.526-2.445 10.01-5.414 2.581-11.203 5.195-15.863 8.505zm63.009 6.872c8.67 4.204 10.232-15.711 6.834-22.127.525-1.914 2.331-2.646 3.069-4.366-4.838-8.667-10.211-16.756-15.148-25.32 3.672 2.286 8.917.409 13.238 2.12 1.58.624 2.722 4.24 3.918 7.133 3.29 7.958 6.743 17.99 8.28 25.586.346 1.73 1.292 5.5 1.08 7.04-.378 2.758-4.12 4.803-6.022 6.508-3.506 3.15-5.714 5.921-9.371 8.866-1.483-2.189-4.666-3.66-5.878-5.44zM27.95 107.99c-4.13-4.545-3.266-13.062-2.766-19.121 7.467 4.697 17.377-.372 17.284-8.36 3.565.094 1.332 4.452.687 7.259-2.107 9.169 3.55 19.13.256 27.516-6.395-.485-11.649-3.097-15.46-7.294zm29.558 26.38c-9.352-2.65-21.337-9.446-25.18-17.847 2.976.432 5.041 1.933 7.977 2.119 1.11.072 2.563-.466 3.838-.148 2.54.63 4.685 6.327 6.602 8.447 1.868 2.07 4.114 2.954 5.651 4.841.988.477 2.448.444 2.504 1.927-.428.457-.879.806-1.392.66zm48.681-2.493c-9.707 5.477-26.136 9.596-36.462 4.449-8.331-4.155-19.593-11.027-23.433-19.737 3.587-8.405-1.062-16.106-1.36-24.64-.157-4.54 2.139-8.504 2.315-13.446-1.228-2.025-4.978-2.275-7.574-2.136-.873 4.372-2.403 9.287-6.906 9.78-6.371.697-11.03-4.576-11.319-10.085-.342-6.48 4.978-17.22 12.517-16.475 2.913.287 3.629 3.207 6.802 3.177 1.72-3.432-2.653-4.51-3.103-6.964-.117-.634.363-3.112.642-4.274 1.37-5.658 4.422-12.982 7.427-17.29 3.814-5.464 11.307-6.288 19.37-6.823 1.44 3.101 6.743 2.846 10.2 2.035-4.143 1.64-7.993 5.617-11.185 9.137-3.665 4.039-7.378 8.371-7.566 13.65 6.927-9.61 12.65-18.003 25.246-22.23 9.53-3.196 20.662 1.465 27.986 6.608 3.039 2.137 4.853 5.529 7.013 8.634 8.082 11.626 11.854 28.219 11.024 44.303-.342 6.633-.327 13.244-2.552 17.706-2.326 4.666-10.193 8.84-14.8 4.62-.853 4.537 3.83 7.344 9.331 5.71-3.922 5.063-8.039 11.145-13.614 14.29zm18.084-149.66c7.585 3.77 21.757 10.149 26.512-.014 1.755-3.746 3.814-10.079 4.723-13.946 1.284-5.456-1.392-16.923-7-18.754-4.953-1.617-10.733-1.518-16.7-.32-.702.585-1.484 1.603-2.03 2.665-4.261.165-8.25-.229-11.615-1.98.319-3.15-1.812-3.656-3.81-4.305-1.48-5.872 2.963-13.541 1.9-18.896-.76-3.815-5.453-4.405-8.902-5.118-.113-2.12.15-3.89.386-5.683-.789-2.907-4.327-4.561-7.679-4.967-11.029-1.326-27.775-1.922-38.384 1.893-2.96 7.261-5.292 16.093-7.758 24.384-10.346-1.105-18.715 4.464-26.603 8.113-2.731 1.266-6.51 1.964-7.53 4.138-.99 2.105-.584 6.14-.83 9.95-.625 9.733-1.16 19.12-3.73 29.086-1.154 4.472-3.165 8.418-4.568 12.727C9.358 5.184 7.092 10.12 6.5 14.1c-.877 5.903 4.681 6.232 8.235 8.79 5.494 3.954 9.806 6.142 15.756 9.711 1.762 1.057 7.077 3.733 7.681 4.966 1.202 2.443-2.062 5.888-2.935 7.803-1.38 3.03-2.1 5.602-2.298 8.59-4.992.789-8.775 3.76-11.06 7.109-3.781 5.543-6.403 15.798-3.132 23.599.257.614 1.536 1.822 1.725 2.765.372 1.858-.7 4.329-.768 6.305-.343 10.14 1.716 18.875 8.541 21.932 2.771 11.038 12.688 14.71 22.032 20.195 3.493 2.05 7.343 3.36 11.32 4.824 14.263 5.25 36.15 4.261 47.987-4.692 5.02-3.797 13.044-11.813 15.914-17.617 7.58-15.323 7.042-40.931 1.74-59.571-.712-2.503-1.746-6.181-3.19-9.187-1.006-2.1-4.134-6.3-3.754-8.153.391-1.916 7.132-7.034 8.577-8.428 2.603-2.51 7.548-5.843 7.948-9.012.43-3.372-1.485-7.984-2.456-11.238-3.245-10.858-6.412-20.895-10.091-30.576" fill="#231f20"/><path d="M73.674 57.38c.411.548 2.674 1.38 5.84-.144 0 0-3.752-.626-3.44-6.881l-1.564.313s-1.615 5.672-.836 6.712" fill="#f7e4cd"/><path d="M101.09 3.617a1.72 1.72 0 1 0-3.44.001 1.72 1.72 0 0 0 3.44-.001M102.81-4.355a1.72 1.72 0 1 0-3.44 0 1.72 1.72 0 0 0 3.44 0" fill="#1d1919"/></g><g><rect transform="matrix(.8 0 0 -.8 0 144)" x="16.854" y="177.38" width="70.412" height="4.12" rx=".983" ry=".983"/><rect transform="scale(1 -1)" x="78.502" y="-2.097" width="50.037" height="3.296" rx=".786" ry=".786"/><rect transform="scale(1 -1)" x="13.483" y="-3.697" width="54.831" height="3.296" rx=".786" ry=".786"/><rect transform="scale(1 -1)" x="83.296" y="-3.697" width="45.243" height="3.296" rx=".786" ry=".786"/></g></g></symbol><symbol viewBox="0 0 24 24" id="json" xmlns="http://www.w3.org/2000/svg"><path d="M5 3h2v2H5v5a2 2 0 0 1-2 2 2 2 0 0 1 2 2v5h2v2H5c-1.07-.27-2-.9-2-2v-4a2 2 0 0 0-2-2H0v-2h1a2 2 0 0 0 2-2V5a2 2 0 0 1 2-2m14 0a2 2 0 0 1 2 2v4a2 2 0 0 0 2 2h1v2h-1a2 2 0 0 0-2 2v4a2 2 0 0 1-2 2h-2v-2h2v-5a2 2 0 0 1 2-2 2 2 0 0 1-2-2V5h-2V3h2m-7 12a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m-4 0a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m8 0a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1z" fill="#fbc02d"/></symbol><symbol viewBox="0 0 50 50" id="julia" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -247)" stroke-width="5.673"><circle cx="13.497" cy="281.632" r="9.555" fill="#bc342d"/><circle cx="36.081" cy="281.632" r="9.555" fill="#864e9f"/><circle cx="24.722" cy="262.389" r="9.555" fill="#328a22"/></g></symbol><symbol viewBox="0 0 64 64" id="karma" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -233)"><path d="M38.556 288.413l-20.29-26.687 9.532-7.246 20.29 26.686h-.001.002l5.527 7.247z" fill="#359b8b" stroke-width=".173"/><path d="M35.681 241.172L24.92 255.327v-14.13H12.947v13.817l7.84 33.235h4.132v-13.147l.003.003 20.29-26.686-.008-.006 5.504-7.24H35.84v.12z" fill="#3cbeae" stroke-width=".206"/></g></symbol><symbol viewBox="0 0 24 24" id="key" xmlns="http://www.w3.org/2000/svg"><path d="M7 14a2 2 0 0 1-2-2 2 2 0 0 1 2-2 2 2 0 0 1 2 2 2 2 0 0 1-2 2m5.65-4A5.99 5.99 0 0 0 7 6a6 6 0 0 0-6 6 6 6 0 0 0 6 6 5.99 5.99 0 0 0 5.65-4H17v4h4v-4h2v-4H12.65z" fill="#26a69a"/></symbol><symbol viewBox="0 0 24 24" id="kivy" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(1.89 0 0 1.89 -12.157 -11.429)" fill="#90a4ae"><path d="M7.026 8.63v4.474l1.928-1.928a.437.437 0 0 0 0-.619zM9.38 16.072v-4.474l-1.927 1.927a.437.437 0 0 0 0 .62zM18.576 10.412l-5.346.564-.017.018 2.39 2.39zM9.922 8.502s.023 3.304-.003 4.452c-.02.856.371 1.114.746 1.507.538.564 1.599 1.57 1.599 1.57a.53.53 0 0 0 .75 0l1.843-1.844a.53.53 0 0 0 0-.75z"/></g></symbol><symbol viewBox="0 0 24 24" id="kl" xmlns="http://www.w3.org/2000/svg"><defs><style>.a{fill:#3aaae1}.b{fill:#fdfeff}</style></defs><title>kl</title><path d="M12.033 1.737c-.25-.003-.5.11-.729.337C8.225 5.15 5.15 8.227 2.078 11.31c-.144.144-.229.346-.341.521v.41c.16.223.294.474.485.666a3259.51 3259.51 0 0 0 8.936 8.937c.193.192.443.325.666.486h.41c.205-.142.436-.256.609-.428 3.046-3.041 6.09-6.083 9.133-9.127.47-.47.472-1.005.006-1.472l-9.218-9.217c-.23-.23-.48-.347-.731-.35zm-1.062 4.545l1.386.832c.702.422 1.403.846 2.109 1.262a.544.544 0 0 1 .04.026l.016.013.017.013c.061.056.089.123.088.224a510.281 510.281 0 0 0 0 3.794.463.463 0 0 1-.007.094c-.015.069-.054.103-.142.109a.464.464 0 0 1-.044.002c-.045-.002-.09-.002-.136-.003-.323-.006-.648-.001-.998-.001v-.527-1.34-.671-.003l.004-.668c0-.147-.039-.231-.17-.308-.893-.528-1.78-1.066-2.67-1.6-.051-.03-.101-.065-.173-.111l.001-.003h-.001zm.362 3.39c.068-.003.119.043.173.138.085.148.174.293.264.44l.015.025c.096.154.194.31.292.47l-1.915 1.176c-.337.207-.673.417-1.014.617-.113.067-.154.143-.154.277.01.977.01 1.955.014 2.932V16H7.7V16h-.002c-.004-.053-.014-.112-.014-.17-.005-1.25-.006-2.501-.015-3.751 0-.142.045-.222.164-.294a467.13 467.13 0 0 0 3.353-2.054l.016-.01a.606.606 0 0 1 .032-.017l.016-.008a.308.308 0 0 1 .033-.013l.012-.004a.157.157 0 0 1 .028-.005l.01-.001zm5.677 3.126l.314.54.346.594v.001c-.158.094-.298.178-.438.259l-3.097 1.798c-.106.062-.189.071-.3.01l-.893-.496-1.524-.843-.895-.493c-.035-.02-.068-.044-.129-.085h.001l.137-.25.495-.902 1.446.795c.442.243.886.483 1.323.734.121.07.212.072.334 0 .894-.525 1.792-1.043 2.689-1.563.057-.034.118-.061.191-.1z" fill="#29b6f6" stroke-width=".041"/></symbol><symbol viewBox="0 0 500 500" id="kotlin" xmlns="http://www.w3.org/2000/svg"><path d="M500 500H0V0h500L250 250z" fill="#7F52FF"></path></symbol><symbol viewBox="0 0 240 240" id="laravel" xmlns="http://www.w3.org/2000/svg"><path d="M216.05 119.036c-1.433.343-24.945 6.673-24.945 6.673l-19.227-28.622c-.537-.828-.99-1.656.359-1.849 1.345-.196 23.195-4.477 24.182-4.723.99-.245 1.837-.536 3.053 1.267 1.21 1.8 17.836 24.626 18.464 25.506.627.877-.447 1.41-1.883 1.748m-4.101 49.326c.588 1.003 1.176 1.64-.67 2.367-1.843.73-62.243 22.847-63.418 23.39-1.173.546-2.092.73-3.607-1.637-1.51-2.362-21.16-39.264-21.16-39.264l64.03-18.075c1.876-.644 2.317-.405 3.103.822 1.074 1.68 21.143 31.403 21.726 32.4m-103.7-21.087c-.78.202-37.566 9.733-39.525 10.22-1.965.485-1.965.246-2.188-.49-.226-.727-43.728-98.053-44.333-99.271-.605-1.214-.574-2.177 0-2.177.571 0 34.734-3.313 35.944-3.383 1.207-.07 1.08.205 1.526 1.033l49.025 91.818c.84 1.58 1.239 1.81-.452 2.248m94.588-59.77c-3.5-4.58-5.2-3.751-7.357-3.41-2.154.336-27.277 4.915-30.194 5.449-2.918.536-4.758 1.803-2.963 4.53 1.597 2.422 18.113 27.824 21.751 33.42l-65.663 17.066L66.18 49.832c-2.075-3.342-2.507-4.514-7.236-4.28-4.735.23-40.969 3.495-43.55 3.731-2.58.233-5.416 1.479-2.835 8.09 2.583 6.612 43.734 102.82 44.88 105.62 1.149 2.803 4.128 7.345 11.11 5.527 7.157-1.871 31.969-8.894 45.52-12.742 7.163 14.07 21.77 42.619 24.473 46.707 3.607 5.459 6.089 4.56 11.626 2.738 4.325-1.42 67.65-26.129 70.502-27.4 2.855-1.273 4.613-2.184 2.685-5.275-1.419-2.28-18.124-26.558-26.876-39.26 5.993-1.733 27.305-7.888 29.575-8.557 2.646-.779 3.008-2.19 1.572-3.94-1.436-1.755-21.293-28.72-24.79-33.296z" fill="#ff5722" stroke="#ff5722" stroke-width="8.852" fill-rule="evenodd"/></symbol><symbol viewBox="0 0 24 24" id="less" xmlns="http://www.w3.org/2000/svg"><path d="M13.696 2.999V5h2.002v5a2 2 0 0 0 1.999 2 2 2 0 0 0-2 2v5h-2v2h2a2 2 0 0 0 2-2v-4a2 2 0 0 1 2-2h1V11h-1a2 2 0 0 1-2-2V5a2 2 0 0 0-2-2.001zm-.03 12.766v.47a1 1 0 0 0 .03-.236 1 1 0 0 0-.03-.234zM10.566 21v-2.001H8.565v-5a2 2 0 0 0-2-2 2 2 0 0 0 2-2V5h2.001v-2H8.565a2 2 0 0 0-2 2v4a2 2 0 0 1-2 2h-.999V13h1a2 2 0 0 1 2 2v3.999A2 2 0 0 0 8.564 21zm.03-12.766v-.47a1 1 0 0 0-.03.236 1 1 0 0 0 .03.234z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="lib" xmlns="http://www.w3.org/2000/svg"><path d="M19 7H9V5h10m-4 10H9v-2h6m4-2H9V9h10m1-7H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2M4 6H2v14a2 2 0 0 0 2 2h14v-2H4V6z" fill="#8bc34a"/></symbol><symbol viewBox="0 0 40 40" id="livescript" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -257)" fill="#317eac"><path stroke-width="3.299" d="M5.419 260.18h3.685v34.207H5.419z"/><path stroke-width="3.299" d="M37.074 288.197v3.685H2.867v-3.685z"/><path stroke-width="2.894" d="M29.612 265.658l2.004 2.005L7.428 291.85l-2.004-2.005z"/><path stroke-width="2.325" d="M10.73 262.471h2.835v22.08H10.73z"/><path stroke-width="2.063" d="M15.36 262.519h2.835v17.382H15.36z"/><path stroke-width="1.77" d="M19.99 262.471h2.835v12.802H19.99z"/><path stroke-width="1.422" d="M24.526 262.491h2.835v8.254h-2.835z"/><path stroke-width="1.128" d="M28.783 262.463h2.835v5.197h-2.835z"/><path stroke-width="2.325" d="M34.801 286.545v-2.835h-22.08v2.835z"/><path stroke-width="2.063" d="M34.753 281.914v-2.835H17.371v2.835z"/><path stroke-width="1.77" d="M34.801 277.284v-2.835H21.999v2.835z"/><path stroke-width="1.422" d="M34.781 272.749v-2.835h-8.254v2.835z"/><path stroke-width="1.128" d="M34.809 268.492v-2.835h-5.197v2.835z"/></g></symbol><symbol viewBox="0 0 24 24" id="lock" xmlns="http://www.w3.org/2000/svg"><path d="M12 17a2 2 0 0 0 2-2 2 2 0 0 0-2-2 2 2 0 0 0-2 2 2 2 0 0 0 2 2m6-9a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V10a2 2 0 0 1 2-2h1V6a5 5 0 0 1 5-5 5 5 0 0 1 5 5v2h1m-6-5a3 3 0 0 0-3 3v2h6V6a3 3 0 0 0-3-3z" fill="#ffd54f"/></symbol><symbol viewBox="0 0 24 24" id="lua" xmlns="http://www.w3.org/2000/svg"><circle cx="12.203" cy="12.102" r="10.322" fill="none" stroke="#42a5f5"/><path d="M12.33 5.746a6.483 6.381 0 0 0-6.482 6.381 6.483 6.381 0 0 0 6.482 6.38 6.483 6.381 0 0 0 6.484-6.38 6.483 6.381 0 0 0-6.484-6.38zm1.86 1.916a2.329 2.292 0 0 1 2.33 2.293 2.329 2.292 0 0 1-2.33 2.291 2.329 2.292 0 0 1-2.329-2.29 2.329 2.292 0 0 1 2.328-2.294z" fill="#42a5f5" fill-rule="evenodd"/><ellipse cy="4.615" cx="19.631" rx="2.329" ry="2.292" fill="#42a5f5" fill-rule="evenodd"/></symbol><symbol viewBox="0 0 24 24" id="markdown" xmlns="http://www.w3.org/2000/svg"><path d="M2 16V8h2l3 3 3-3h2v8h-2v-5.17l-3 3-3-3V16H2m14-8h3v4h2.5l-4 4.5-4-4.5H16V8z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" preserveAspectRatio="xMidYMid" id="markojs" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -120.96)" stroke-width=".984"><path d="M4.002 126.482c-.655 1.07-1.32 2.14-1.976 3.21-.655 1.06-1.308 2.142-1.963 3.212l.002.002-.002.002c.655 1.07 1.308 2.15 1.963 3.211.655 1.07 1.32 2.141 1.976 3.211h3.33c-.664-1.07-1.318-2.14-1.974-3.21-.653-1.069-1.307-2.145-1.961-3.214.654-1.068 1.308-2.146 1.961-3.215a601.93 601.93 0 0 1 1.974-3.209z" fill="#2196f3"/><path d="M3.999 126.482l-.002.002c.655 1.07 1.31 2.15 1.964 3.212.655 1.07 1.32 2.14 1.974 3.21h3.331c-.664-1.07-1.319-2.14-1.974-3.21-.653-1.068-1.306-2.146-1.96-3.214z" fill="#26a69a"/><path d="M15.203 126.482l.002.002c-.655 1.07-1.31 2.15-1.965 3.212-.655 1.07-1.319 2.14-1.974 3.21h-3.33c.664-1.07 1.318-2.14 1.973-3.21.654-1.069 1.307-2.146 1.961-3.214z" fill="#8bc34a"/><path d="M11.874 126.484c.664 1.07 1.318 2.14 1.974 3.21.653 1.068 1.307 2.146 1.961 3.214-.654 1.069-1.308 2.145-1.961 3.213-.656 1.07-1.31 2.14-1.974 3.21h3.33c.655-1.07 1.319-2.14 1.974-3.21.655-1.06 1.31-2.14 1.966-3.21l-.002-.003.002-.002c-.656-1.07-1.311-2.152-1.966-3.213-.655-1.07-1.319-2.138-1.974-3.209z" fill="#ffc107"/><path d="M16.74 126.482c.665 1.07 1.319 2.14 1.974 3.21.654 1.068 1.306 2.146 1.96 3.214-.654 1.069-1.306 2.145-1.96 3.213-.655 1.07-1.31 2.141-1.974 3.211h3.33c.656-1.07 1.32-2.14 1.974-3.21.655-1.062 1.31-2.141 1.966-3.212l-.002-.002.002-.002c-.655-1.07-1.31-2.152-1.966-3.213-.655-1.07-1.318-2.138-1.973-3.209z" fill="#f44336"/></g></symbol><symbol viewBox="0 0 23 24" id="mathematica" xmlns="http://www.w3.org/2000/svg"><path d="M11.512 1.523l-.073.025-.46.794-.454.763-1.217 2.09H9.29L5.435 3.5l-.1-.047h-.018v.092l.025.163v.086l.132 1.226v.082l.032.252v.082l.22 2.137v.075l.018.082v.06l-2.348.507-.04.015-.457.1-.025.01h-.042l-1.096.244-.04.007-.17.036v.082l.018.01 1.859 2.086.053.052.114.132.804.909v.005l-.053.05-.22.257-2.564 2.875-.01.007v.082l.071.006.295.075 1.697.366v.006l2.139.472h.015v.047l-.036.252v.08l-.046.412v.082l-.036.244v.082l-.045.412v.08l-.05.41v.08l-.036.244v.082l-.046.412v.082l-.05.407v.082l-.032.248V20l-.05.407v.104h.037l3.642-1.6.294-.134h.018l.177.312.539.911.015.032.854 1.465.16.262.404.695.007.022h.092l.005-.022.017-.025.56-.947.014-.042.6-1.033.316-.539.644-1.091.05.013 3.906 1.721h.035v-.085l-.138-1.32v-.082l-.032-.244v-.082l-.035-.245v-.085l-.033-.244v-.081l-.032-.245v-.082l-.032-.244v-.085l-.035-.245v-.082l-.032-.245v-.082l-.033-.244v-.085l-.025-.17v-.053l1.632-.354.043-.008.458-.107h.028v-.01l.23-.05.03-.01h.042l.382-.09.025-.01h.043l.194-.05h.033l1.015-.23.07-.007v-.064l-.015-.013-1.19-1.342-.028-.028-.197-.22-1.428-1.604v-.006l.295-.323.4-.457 2.148-2.408.015-.01v-.065l-.035-.008-1.288-.28-.372-.084-.047-.01-2.481-.544v-.045l.432-4.265v-.02h-.042l-.302.135-.01.014h-.025l-3.307 1.45-.297.135h-.015l-2.028-3.483-.099-.145-.014-.045zm-.001 1.114l1.365 2.323.34.592-.008.025-1.18 1.511-.517.66-.012-.01-.258-.335-.04-.05-1.397-1.787.03-.063 1.378-2.365.287-.491zm4.908 2.039l-.007.025-.168.225-.538.066zm-9.817.004l.053.02.677.3h-.499l-.224-.3zM16.947 5l-.123 1.248-.113-.928.226-.307zm-9.26.156l.053.024.705.309-.757-.175zm7.388.116l.02.168-1.318.403.003-.003.16-.071 1.015-.444zM9.669 6.388l.944 1.204v.01L9.483 7.2zm3.55.172l.21.682-.234.084-.089.022-.702.255.008-.022.776-.982zm-5 .836l.986.356.898.312.048.02 1.054.373.011 3.086-.362-.117-.67-.224-.081-.038-.735-.245-.77-.256-.29-.1-.011-.255-.032-1.195-.01-.287-.015-.894-.013-.297zm6.583 0l-.011.227-.028.9-.008.303-.032 1.475-.01.262-.337.117-.734.245-.77.256-.712.245-.355.117.01-3.086 1.632-.578zm.585.437l.09.735.79-.097-.915 1.302-.018.006.01-.183.018-.877zm-9.451.536l.152.22 1.447 2.049-2.607.968-.05.015-1.972-2.214-.28-.312.003-.01.115-.018.424-.1.14-.021.337-.078.042-.01zm11.146.003l3.284.713.029.01-.022.025-1.954 2.192-.277.312-.092-.036-2.564-.95.475-.681.152-.216zM6.787 8.52h.86l.036 1.258-.013-.006-.763-1.078zm1.358 2.625l.152.06.77.252.712.245.746.247.49.167-.065.092-1.723 2.334-1.015-.302-.082-.017-.035-.015-1.902-.56.938-1.22.981-1.277zm6.73 0l.033.006 1.787 2.327.132.17-.128.036-.032.014-2.196.642-.105.032-.564.17-.018-.003-1.053-1.44-.174-.239-.547-.726-.007-.018.469-.16.769-.254.713-.245.77-.252zm-7.766.305l-.007.02-.405.523-.291-.291.657-.245zm8.802 0l.043.007.578.212.714.27-.661.394-.375-.479-.03-.042-.262-.342zm-10.843.75l-.67.668.355-.397.207-.23zm12.911.016l.068.025.045.042.554.627.042.043.204.228-.255.135zm-6.473.265l.022.015 1.38 1.872.032.05.343.465.008.031-.088.117-.422.629-.047.074-.245.343-.97 1.43-.013.007-1.18-1.72-.096-.16-.493-.708-.008-.037 1.618-2.191.007-.01zm7.827 1.194l.565.633.063.082-.272-.093-.037-.013zm-15.785.148l.297.299-.637.218-.152.05.038-.058zm13.224.47l-.855.448.346.66-.185-.058-.27-.088-1.092-.348.012-.01zm-9.687.255l1.222.356-.006.007-.458.145-.443.135-.032.01-.49.157zm-2.765.048l.318.32 2.007.517-.567.18-.055.004-2.103-.469-.744-.156.007-.006zm14.966.205l.548.188v.003l-.457.1-.043.014-1.069.23zm-10.23.507l.007.227.01.347.025 1.363.025.691-.007.255-.24.107-2.863 1.255.032-.372.033-.255.017-.227.031-.256.037-.407.045-.42.018-.23.032-.251.032-.412.05-.414.013-.14 1.455-.457.003-.014.301-.098zm4.908 0l1.245.39v.014l.312.1 1.146.362.022.23.03.255.043.408.04.42.017.23.033.251.032.412.042.325.078.848-.078-.04-3.025-1.322-.004-.305.06-2.368zm-4.295.617l.015.007.067.107.6.875-.64.531-.034-1.438zm3.671 0h.008l-.005.06-.02.678-.005.214-.479-.223zm-2.888 3.605l.763.915.001.37-.017-.006-.025-.05-.464-.791-.012-.018zm1.53.61l.184.083-.343.586-.018.007.002-.532z" fill="#f44336" fill-rule="evenodd" stroke="#f44336" stroke-width=".7747499999999999" stroke-linejoin="round"/></symbol><symbol viewBox="0 0 720 720" id="matlab" xmlns="http://www.w3.org/2000/svg"><title>Layer 1</title><path d="M209.247 329.98L52.368 387.638l121.325 85.822 96.752-95.804-61.198-47.674z" fill="#4db6ac" fill-rule="evenodd" stroke-width=".3"/><path d="M480.193 71.446c-13.123 1.784-9.565 1.013-28.4 16.09-18.008 14.418-69.925 100.347-97.673 129.256-24.688 25.722-34.46 12.199-60.102 33.661-25.68 21.494-65.273 64.464-65.273 64.464l63.978 47.32L394.15 222.754c23.948-32.932 23.694-37.266 36.744-71.82 6.384-16.907 17.76-29.9 27.756-45.809 12.488-19.874 30.186-34.855 21.543-33.68z" fill="#00897b" fill-rule="evenodd" stroke-width=".3"/><path d="M478.206 69.796c-31.268-.189-62.068 137.245-115.56 242.691-54.543 107.519-162.235 176.82-162.235 176.82 18.156 8.243 34.681 4.91 54.236 23.394 13.375 16.164 52.09 95.976 75.174 146.117 0 0 18.964-10.297 42.994-27.695 24.03-17.397 53.124-41.896 73.384-70.3 26.883-37.692 47.897-61.043 65.703-75.271 17.806-14.23 32.404-19.336 46.458-20.54 50.238-4.305 124.582 85.792 124.582 85.792S527.267 70.09 478.206 69.796z" fill="#ffb74d" fill-rule="evenodd" stroke-width=".3"/></symbol><symbol viewBox="0 0 24 24" id="merlin" xmlns="http://www.w3.org/2000/svg"><text style="line-height:1.25;-inkscape-font-specification:'Century Gothic Bold'" x="1.953" y="21.178" transform="scale(.99582 1.0042)" font-weight="700" font-size="30.255" font-family="Century Gothic" letter-spacing="0" word-spacing="0" fill="#42a5f5" stroke-width=".756"><tspan x="1.953" y="21.178" style="-inkscape-font-specification:'Century Gothic Bold'" font-size="22.745">M</tspan></text></symbol><symbol viewBox="0 0 192 191.99999" id="mocha" xmlns="http://www.w3.org/2000/svg"><title>Mocha Logo</title><g transform="translate(-354.75 -262.42) scale(4.835)" fill="#a1887f"><path d="M103.6 69.6c0-.5-.4-1-1-1H83.8c-.5 0-1 .4-1 1 0 3.4.5 15.1 5.5 20.8.2.2.4.3.7.3h8.4c.3 0 .5-.1.7-.3 5-5.6 5.5-17.3 5.5-20.8zm-7.4 18.2h-5.9c-.3 0-.5-.1-.7-.3-3.4-4-3.8-12-3.9-14.8 0-.5.4-1 1-1h13.2c.5 0 1 .4 1 1 0 2.8-.5 10.7-3.9 14.8-.3.2-.5.3-.8.3zM95.1 66.6s3.6-2.1 1.4-5.9c-1.3-2-1.9-3.7-1.4-4.4-1.3 1.6-3.5 3.3-1.1 6.9.8.9 1.2 2.8 1.1 3.4zM91.1 66.9s2.4-1.4.9-4c-.9-1.3-1.3-2.5-.9-2.9-.9 1.1-2.3 2.2-.7 4.7.5.5.7 1.8.7 2.2z"/><path d="M99.3 78.5c-.4 2.7-1.2 5.8-2.9 7.8-.2.2-.4.3-.6.3h-5c-.2 0-.5-.1-.6-.3-1.2-1.5-2-3.5-2.5-5.6 0 0 5.8.8 9.1-.4 2.4-.9 2.5-1.8 2.5-1.8z"/></g></symbol><symbol viewBox="0 0 24 24" id="movie" xmlns="http://www.w3.org/2000/svg"><path d="M18 4l2 4h-3l-2-4h-2l2 4h-3l-2-4H8l2 4H7L5 4H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4h-4z" fill="#ff9800"/></symbol><symbol viewBox="0 0 24 24" id="music" xmlns="http://www.w3.org/2000/svg"><path d="M16 9V7h-4v5.5c-.42-.31-.93-.5-1.5-.5A2.5 2.5 0 0 0 8 14.5a2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5V9h3m-4-7a10 10 0 0 1 10 10 10 10 0 0 1-10 10A10 10 0 0 1 2 12 10 10 0 0 1 12 2z" fill="#ef5350"/></symbol><symbol viewBox="0 0 24 24" id="mxml" xmlns="http://www.w3.org/2000/svg"><path d="M13 9h5.5L13 3.5V9M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m.12 13.5l3.74 3.74 1.42-1.41-2.33-2.33 2.33-2.33-1.42-1.41-3.74 3.74m11.16 0l-3.74-3.74-1.42 1.41 2.33 2.33-2.33 2.33 1.42 1.41 3.74-3.74z" fill="#ffa726"/></symbol><symbol viewBox="0 0 300 300" id="ngrx-actions" xmlns="http://www.w3.org/2000/svg"><path d="M150 27.324L35.85 68.006l17.303 151.09 96.843 53.586 96.843-53.586 17.303-151.09zm-23.719 38.349c4.346-.075 9.04 1.316 14.265 4.131 2.3 1.24 9.235 2.994 15.407 3.889 21.936 3.18 47.975 19.934 56.21 36.186 5.667 11.183 4.508 17.209-4.18 21.702-7.492 3.874-22.822 2-45.08-5.517l-18.785-6.343-6.683 2.552c-9.683 3.698-19.366 12.877-23.33 22.09-2.858 6.645-3.293 9.768-2.77 20.705.523 10.955 1.315 14.12 5.2 20.997 4.423 7.829 14.576 17.818 16.331 16.064.473-.473-.574-3.648-2.308-7.048-1.735-3.4-2.744-6.825-2.26-7.606.482-.781 5.054 2.123 10.157 6.44 11.35 9.6 24.608 15.74 36.77 17.01 9.985 1.045 12.266-.814 4.787-3.912-2.41-.998-5.544-3.088-6.95-4.641-2.907-3.212-3.072-3.12 9.356-5.906 7.736-1.733 23.026-9.849 23.937-12.71.29-.91-2.195-1.296-6.27-.972-3.706.295-6.732-.087-6.732-.85 0-.76 3.032-4.523 6.732-8.385 13.883-14.489 18.62-25.32 20.098-45.906l1.02-14.217 3.257 6.756c3.601 7.452 4.265 18.202 1.701 27.437-2.141 7.711-.712 8.564 3.208 1.92 4.845-8.212 6.39-6.905 5.54 4.666-.924 12.587-5.243 22.017-14.993 32.686-7.95 8.699-7.001 10.254 2.624 4.326 9.273-5.711 10.511-4.815 5.736 4.155-9.031 16.964-28.122 31.35-47.948 36.161-12.016 2.917-20.537 3.461-31.544 2.018-28.78-3.775-56.001-23.157-68.993-49.114-3.378-6.748-8.154-14.994-10.62-18.348-5.092-6.924-5.529-10.038-2.09-15.286 1.715-2.618 2.116-5.307 1.41-9.308-3.273-18.531-3.167-19.11 4.276-26.659 6.468-6.56 6.878-7.44 6.878-15.092 0-6.637.671-8.813 3.67-11.811 2.02-2.02 5.23-3.7 7.12-3.718 5.49-.05 14.97-5.135 20.584-11.033 4.687-4.927 9.674-7.417 15.262-7.51z" fill="#ab47bc" stroke-width="12.914"/></symbol><symbol viewBox="0 0 300 300" id="ngrx-effects" xmlns="http://www.w3.org/2000/svg"><path d="M150 27.324L35.85 68.006l17.303 151.09 96.843 53.586 96.843-53.586 17.303-151.09zm-23.719 38.349c4.346-.075 9.04 1.316 14.265 4.131 2.3 1.24 9.235 2.994 15.407 3.889 21.936 3.18 47.975 19.934 56.21 36.186 5.667 11.183 4.508 17.209-4.18 21.702-7.492 3.874-22.822 2-45.08-5.517l-18.785-6.343-6.683 2.552c-9.683 3.698-19.366 12.877-23.33 22.09-2.858 6.645-3.293 9.768-2.77 20.705.523 10.955 1.315 14.12 5.2 20.997 4.423 7.829 14.576 17.818 16.331 16.064.473-.473-.574-3.648-2.308-7.048-1.735-3.4-2.744-6.825-2.26-7.606.482-.781 5.054 2.123 10.157 6.44 11.35 9.6 24.608 15.74 36.77 17.01 9.985 1.045 12.266-.814 4.787-3.912-2.41-.998-5.544-3.088-6.95-4.641-2.907-3.212-3.072-3.12 9.356-5.906 7.736-1.733 23.026-9.849 23.937-12.71.29-.91-2.195-1.296-6.27-.972-3.706.295-6.732-.087-6.732-.85 0-.76 3.032-4.523 6.732-8.385 13.883-14.489 18.62-25.32 20.098-45.906l1.02-14.217 3.257 6.756c3.601 7.452 4.265 18.202 1.701 27.437-2.141 7.711-.712 8.564 3.208 1.92 4.845-8.212 6.39-6.905 5.54 4.666-.924 12.587-5.243 22.017-14.993 32.686-7.95 8.699-7.001 10.254 2.624 4.326 9.273-5.711 10.511-4.815 5.736 4.155-9.031 16.964-28.122 31.35-47.948 36.161-12.016 2.917-20.537 3.461-31.544 2.018-28.78-3.775-56.001-23.157-68.993-49.114-3.378-6.748-8.154-14.994-10.62-18.348-5.092-6.924-5.529-10.038-2.09-15.286 1.715-2.618 2.116-5.307 1.41-9.308-3.273-18.531-3.167-19.11 4.276-26.659 6.468-6.56 6.878-7.44 6.878-15.092 0-6.637.671-8.813 3.67-11.811 2.02-2.02 5.23-3.7 7.12-3.718 5.49-.05 14.97-5.135 20.584-11.033 4.687-4.927 9.674-7.417 15.262-7.51z" fill="#26c6da" stroke-width="12.914"/></symbol><symbol viewBox="0 0 300 300" id="ngrx-reducer" xmlns="http://www.w3.org/2000/svg"><path d="M150 27.324L35.85 68.006l17.303 151.09 96.843 53.586 96.843-53.586 17.303-151.09zm-23.719 38.349c4.346-.075 9.04 1.316 14.265 4.131 2.3 1.24 9.235 2.994 15.407 3.889 21.936 3.18 47.975 19.934 56.21 36.186 5.667 11.183 4.508 17.209-4.18 21.702-7.492 3.874-22.822 2-45.08-5.517l-18.785-6.343-6.683 2.552c-9.683 3.698-19.366 12.877-23.33 22.09-2.858 6.645-3.293 9.768-2.77 20.705.523 10.955 1.315 14.12 5.2 20.997 4.423 7.829 14.576 17.818 16.331 16.064.473-.473-.574-3.648-2.308-7.048-1.735-3.4-2.744-6.825-2.26-7.606.482-.781 5.054 2.123 10.157 6.44 11.35 9.6 24.608 15.74 36.77 17.01 9.985 1.045 12.266-.814 4.787-3.912-2.41-.998-5.544-3.088-6.95-4.641-2.907-3.212-3.072-3.12 9.356-5.906 7.736-1.733 23.026-9.849 23.937-12.71.29-.91-2.195-1.296-6.27-.972-3.706.295-6.732-.087-6.732-.85 0-.76 3.032-4.523 6.732-8.385 13.883-14.489 18.62-25.32 20.098-45.906l1.02-14.217 3.257 6.756c3.601 7.452 4.265 18.202 1.701 27.437-2.141 7.711-.712 8.564 3.208 1.92 4.845-8.212 6.39-6.905 5.54 4.666-.924 12.587-5.243 22.017-14.993 32.686-7.95 8.699-7.001 10.254 2.624 4.326 9.273-5.711 10.511-4.815 5.736 4.155-9.031 16.964-28.122 31.35-47.948 36.161-12.016 2.917-20.537 3.461-31.544 2.018-28.78-3.775-56.001-23.157-68.993-49.114-3.378-6.748-8.154-14.994-10.62-18.348-5.092-6.924-5.529-10.038-2.09-15.286 1.715-2.618 2.116-5.307 1.41-9.308-3.273-18.531-3.167-19.11 4.276-26.659 6.468-6.56 6.878-7.44 6.878-15.092 0-6.637.671-8.813 3.67-11.811 2.02-2.02 5.23-3.7 7.12-3.718 5.49-.05 14.97-5.135 20.584-11.033 4.687-4.927 9.674-7.417 15.262-7.51z" fill="#e53935" stroke-width="12.914"/></symbol><symbol viewBox="0 0 300 300" id="ngrx-state" xmlns="http://www.w3.org/2000/svg"><path d="M150 27.324L35.85 68.006l17.303 151.09 96.843 53.586 96.843-53.586 17.303-151.09zm-23.719 38.349c4.346-.075 9.04 1.316 14.265 4.131 2.3 1.24 9.235 2.994 15.407 3.889 21.936 3.18 47.975 19.934 56.21 36.186 5.667 11.183 4.508 17.209-4.18 21.702-7.492 3.874-22.822 2-45.08-5.517l-18.785-6.343-6.683 2.552c-9.683 3.698-19.366 12.877-23.33 22.09-2.858 6.645-3.293 9.768-2.77 20.705.523 10.955 1.315 14.12 5.2 20.997 4.423 7.829 14.576 17.818 16.331 16.064.473-.473-.574-3.648-2.308-7.048-1.735-3.4-2.744-6.825-2.26-7.606.482-.781 5.054 2.123 10.157 6.44 11.35 9.6 24.608 15.74 36.77 17.01 9.985 1.045 12.266-.814 4.787-3.912-2.41-.998-5.544-3.088-6.95-4.641-2.907-3.212-3.072-3.12 9.356-5.906 7.736-1.733 23.026-9.849 23.937-12.71.29-.91-2.195-1.296-6.27-.972-3.706.295-6.732-.087-6.732-.85 0-.76 3.032-4.523 6.732-8.385 13.883-14.489 18.62-25.32 20.098-45.906l1.02-14.217 3.257 6.756c3.601 7.452 4.265 18.202 1.701 27.437-2.141 7.711-.712 8.564 3.208 1.92 4.845-8.212 6.39-6.905 5.54 4.666-.924 12.587-5.243 22.017-14.993 32.686-7.95 8.699-7.001 10.254 2.624 4.326 9.273-5.711 10.511-4.815 5.736 4.155-9.031 16.964-28.122 31.35-47.948 36.161-12.016 2.917-20.537 3.461-31.544 2.018-28.78-3.775-56.001-23.157-68.993-49.114-3.378-6.748-8.154-14.994-10.62-18.348-5.092-6.924-5.529-10.038-2.09-15.286 1.715-2.618 2.116-5.307 1.41-9.308-3.273-18.531-3.167-19.11 4.276-26.659 6.468-6.56 6.878-7.44 6.878-15.092 0-6.637.671-8.813 3.67-11.811 2.02-2.02 5.23-3.7 7.12-3.718 5.49-.05 14.97-5.135 20.584-11.033 4.687-4.927 9.674-7.417 15.262-7.51z" fill="#9ccc65" stroke-width="12.914"/></symbol><symbol viewBox="0 0 24 24" id="nim" xmlns="http://www.w3.org/2000/svg"><path d="M4.464 15.75L2.288 3.78l5.985 7.617L12.08 3.78l3.809 7.617 5.985-7.617-2.177 11.97H4.464m15.234 3.264a1.088 1.088 0 0 1-1.088 1.088H5.553a1.088 1.088 0 0 1-1.089-1.088v-1.089h15.234z" stroke-width="1.088" fill="#ffca28"/></symbol><symbol viewBox="0 0 500 500" id="nix" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-1.965 36.302)" stroke-width=".395"><path d="M135.59 415.7c0-.295-2.752-5.283-6.116-11.084-3.364-5.801-6.116-10.776-6.116-11.055s9.514-16.889 21.143-36.912c11.629-20.022 21.323-36.798 21.542-37.279.346-.76-1.608-4.363-14.896-27.466-8.412-14.625-15.294-26.785-15.294-27.023 0-.5 24.46-43.501 25.206-44.31.414-.45.592-.384 1.078.395.32.513 16.876 29.256 36.791 63.87 62.62 108.85 74.852 130.01 75.41 130.46.3.242.544.554.544.694 0 .14-11.836.21-26.302.154-23.023-.09-26.313-.175-26.393-.694-.11-.714-27.662-48.825-28.86-50.392-.746-.978-.906-1.035-1.426-.51-.688.696-28.954 49.323-29.49 50.733l-.365.96h-13.229c-10.896 0-13.229-.095-13.229-.538zm167.58-125.61c-.134-.216 1.188-2.863 2.938-5.882 6.924-11.944 84.291-145.75 96.491-166.88 7.143-12.371 13.142-22.465 13.333-22.433.363.062 25.861 43.105 25.861 43.655 0 .174-6.761 11.952-15.026 26.173-8.46 14.557-14.932 26.104-14.81 26.421.185.483 4.564.564 30.213.564h29.996l.958 1.48c.526.814 3.296 5.547 6.155 10.518 2.859 4.971 5.45 9.29 5.756 9.597.706.705.704.724-.16 1.572-.395.388-3.36 5.323-6.587 10.965-3.228 5.643-6.056 10.387-6.285 10.543-.23.156-19.695.171-43.256.034l-42.84-.249-.804 1.15c-.441.632-7.504 12.736-15.696 26.897l-14.892 25.747H339.03c-8.517 0-20.015.116-25.55.259-6.55.168-10.15.121-10.309-.135zM169.42 132.23c-56.373-.055-102.5-.182-102.5-.282 0-.1 5.617-10.132 12.481-22.294l12.481-22.112h30.332c27.113 0 30.332-.065 30.332-.611 0-.336-6.659-12.228-14.797-26.427-8.139-14.199-14.797-25.917-14.797-26.04 0-.123 2.682-4.853 5.96-10.51s6.003-10.578 6.055-10.934c.086-.586 1.376-.648 13.572-.648 7.413 0 13.463.143 13.446.317-.017.174.222.707.531 1.184.31.476 9.763 16.937 21.007 36.578 11.244 19.64 20.71 36.022 21.036 36.4.554.647 2.549.691 31.428.691h30.837l12.896 22.145c7.093 12.18 12.8 22.301 12.682 22.492-.118.19-4.776.303-10.352.249-5.575-.054-56.26-.143-112.63-.198z" fill="#5075c1"/><path d="M25.289 203.14c-6.098 10.563-6.69 11.711-6.225 12.078.283.224 3.18 5.044 6.44 10.712 3.261 5.668 6.017 10.355 6.124 10.417.106.061 13.585.153 29.95.204 16.367.052 29.994.23 30.285.399.472.273-1.08 3.094-14.637 26.574L62.06 289.793l12.907 21.865c7.1 12.026 12.982 21.906 13.068 21.956.086.05 23.257-39.831 51.492-88.624 11.352-19.617 21.214-36.64 30.37-52.442 23.308-40.452 30.68-53.468 30.73-54.132-1.097-.11-6.141-.187-13.006-.216-3.945-.01-7.82-.02-12.75-.002l-25.341.092-15.42 26.706c-14.256 24.693-15.445 26.663-16.278 26.86l-.024.037c-.011.003-1.62-.001-1.825 0-4.29.062-20.453.063-40.226-.01-22.632-.082-41.615-.125-42.183-.096-.568.03-1.147-.03-1.29-.132-.142-.102-3.29 5.066-6.996 11.485zm205.16-190.3c-.123.149 5.62 10.392 12.761 22.763 12.199 21.131 89.393 155.03 96.276 167 1.502 2.613 2.92 4.803 3.443 5.348.9-1.249 3.531-5.63 7.954-13.219a1342.88 1342.88 0 0 1 10.049-17.76l6.606-11.443c.692-1.403.754-1.818.653-2.117-.162-.48-6.904-12.332-14.982-26.337-8.078-14.005-14.824-25.849-14.991-26.32a.73.73 0 0 1-.009-.366l-.426-.913L359.42 72.5c3.69-6.307 6.425-11.042 9.47-16.29 9.159-15.948 12.037-21.189 11.896-21.55-.126-.324-2.7-4.83-5.72-10.017-3.021-5.185-5.845-10.148-6.275-11.026-.483-.987-.734-1.364-1.1-1.456-.054.014-.083.018-.145.035-.42.112-5.454.195-11.189.185-5.734-.01-11.22.024-12.188.073l-1.76.089-14.997 25.978c-12.824 22.212-15.084 25.964-15.595 25.883-.024-.004-.15-.189-.235-.301-.109.066-.2.09-.272.05-.255-.148-7.143-11.902-15.306-26.119l-14.36-25.016c-.115-.186-.444-.744-.457-.752-.477-.275-50.502.287-50.737.57zm-18.646 283.09c-.047.109-.026.262.042.48.329 1.05 25.338 43.735 25.772 43.985.207.119 14.178.239 31.05.266 26.651.044 30.75.152 31.234.832.308.43 9.988 17.214 21.513 37.296s21.152 36.627 21.394 36.767c.242.14 5.927.243 12.633.23 6.706-.013 12.401.099 12.657.246.132.076.382-.141.852-.795l6.008-10.406c5.234-9.065 6.62-11.684 6.294-11.888-.575-.36-15.597-26.643-23.859-41.482-3.09-5.45-5.37-9.516-5.441-9.774-.195-.712-.065-.822 1.156-.98 1.956-.252 57.397-.057 58.07.205.238.092.79-.569 2.594-3.497 1.866-3.067 5.03-8.524 11-18.866 7.22-12.505 13.044-22.784 12.942-22.843-.102-.059-.771-.051-1.489.016l-.046.001c-4.452.204-33.918.203-149.74.025-38.96-.06-69.786-.09-71.912-.072-1.121.01-2.095.076-2.66.172a.25.25 0 0 0-.062.083z" fill="#7db7e1"/></g></symbol><symbol viewBox="0 0 24 24" id="nodejs" xmlns="http://www.w3.org/2000/svg"><path d="M12 1.85c-.27 0-.55.07-.78.2l-7.44 4.3c-.48.28-.78.8-.78 1.36v8.58c0 .56.3 1.08.78 1.36l1.95 1.12c.95.46 1.27.47 1.71.47 1.4 0 2.21-.85 2.21-2.33V8.44c0-.12-.1-.22-.22-.22H8.5c-.13 0-.23.1-.23.22v8.47c0 .66-.68 1.31-1.77.76L4.45 16.5a.26.26 0 0 1-.11-.21V7.71c0-.09.04-.17.11-.21l7.44-4.29c.06-.04.16-.04.22 0l7.44 4.29c.07.04.11.12.11.21v8.58c0 .08-.04.16-.11.21l-7.44 4.29c-.06.04-.16.04-.23 0L10 19.65c-.08-.03-.16-.04-.21-.01-.53.3-.63.36-1.12.51-.12.04-.31.11.07.32l2.48 1.47c.24.14.5.21.78.21s.54-.07.78-.21l7.44-4.29c.48-.28.78-.8.78-1.36V7.71c0-.56-.3-1.08-.78-1.36l-7.44-4.3c-.23-.13-.5-.2-.78-.2M14 8c-2.12 0-3.39.89-3.39 2.39 0 1.61 1.26 2.08 3.3 2.28 2.43.24 2.62.6 2.62 1.08 0 .83-.67 1.18-2.23 1.18-1.98 0-2.4-.49-2.55-1.47a.226.226 0 0 0-.22-.18h-.96c-.12 0-.21.09-.21.22 0 1.24.68 2.74 3.94 2.74 2.35 0 3.7-.93 3.7-2.55 0-1.61-1.08-2.03-3.37-2.34-2.31-.3-2.54-.46-2.54-1 0-.45.2-1.05 1.91-1.05 1.5 0 2.09.33 2.32 1.36.02.1.11.17.21.17h.97c.05 0 .11-.02.15-.07.04-.04.07-.1.05-.16C17.56 8.82 16.38 8 14 8z" fill="#8bc34a"/></symbol><symbol viewBox="0 0 300 300" id="nodemon" xmlns="http://www.w3.org/2000/svg"><title>nodemon</title><path d="M149.868 20.62c-2.124 0-4.25.55-6.154 1.648L41.899 81.083a12.306 12.306 0 0 0-6.15 10.652v117.633a12.29 12.29 0 0 0 6.152 10.646l101.815 58.766h.001a12.282 12.282 0 0 0 12.291 0l101.84-58.766a12.29 12.29 0 0 0 6.153-10.652V91.738a12.31 12.31 0 0 0-6.146-10.652L156.015 22.27a12.302 12.302 0 0 0-6.153-1.648zM83.303 70.93s11.789 33.031 35.477 31.934l27.74-15.961a7.348 7.348 0 0 1 3.414-.99h.641a7.233 7.233 0 0 1 3.404.99l27.738 15.961c23.69 1.094 35.475-31.934 35.475-31.934 5.233 23.154 1.06 38.641-5.924 48.942l4.541 2.614h.002c2.321 1.327 3.734 3.795 3.737 6.49l-.12 95.811a3.724 3.724 0 0 1-1.855 3.227 3.624 3.624 0 0 1-3.735 0L177.1 206.971c-2.311-1.363-3.742-3.818-3.742-6.48v-44.763a7.44 7.44 0 0 0-3.737-6.465l-15.642-9.01a7.28 7.28 0 0 0-3.715-1.01 7.378 7.378 0 0 0-3.742 1.01l-15.648 9.01c-2.316 1.323-3.729 3.798-3.729 6.467v44.762c0 2.663-1.413 5.1-3.738 6.48l-36.748 21.041a3.571 3.571 0 0 1-3.71 0c-1.173-.65-1.864-1.887-1.864-3.224l-.137-95.812a7.483 7.483 0 0 1 3.74-6.49l4.541-2.615c-6.982-10.302-11.16-25.79-5.925-48.942z" fill="#8bc34a"/></symbol><symbol viewBox="0 0 990 990" id="npm" xmlns="http://www.w3.org/2000/svg"><defs><style>.hncls-1{fill:#cb3837}.cls-2{fill:#fff}</style></defs><title>n</title><path class="hncls-1" d="M113.26 876.74V113.27h763.47v763.47zm143.59-620.4v476.18h240.61V355.63h140.21v376.96h95.457V256.34z" fill="#e53935" stroke-width=".771"/></symbol><symbol id="nunjucks" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>.host0{fill:#388e3c}</style><path class="host0" d="M11.2 21.1H8.1l-2.3-7.9v7.9H2.7V2.9h3.1l2.3 7.4V2.9h3.1zM21.3 19.2c0 1-.8 1.9-1.9 1.9h-4.8c-1 0-1.9-.8-1.9-1.9v-3.8l3.2-.7V18h2.3V7.2h3.1v12z"/></symbol><symbol viewBox="0 0 150 150.00001" id="ocaml" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(.76136 0 0 .76136 11.616 19.98)"><path d="M83.02 101.645l.023-.062c-.035-.159-.047-.195-.024.062z" fill="none" stroke-width="1.028"/><linearGradient id="hpa" gradientUnits="userSpaceOnUse" x1="-696.735" y1="97.7" x2="-696.735" y2="142.997" gradientTransform="matrix(1.02783 0 0 1.02783 776.895 2.337)"><stop offset="0" stop-color="#f29100"/><stop offset="1" stop-color="#ec670f"/></linearGradient><path d="M82.313 138.79c-.471-1.004-1.904-3.621-2.624-4.46-1.562-1.828-1.927-1.966-2.386-4.275-.799-4.02-2.913-11.31-5.405-16.341-1.286-2.596-3.426-4.777-5.385-6.66-1.71-1.652-5.565-4.431-6.237-4.294-6.296 1.257-8.249 7.432-11.21 12.323-1.638 2.705-3.374 5.007-4.665 7.885-1.192 2.646-1.087 5.577-3.128 7.849-2.093 2.333-3.454 4.814-4.48 7.829-.194.574-.747 6.596-1.348 8.015l9.357-.659c8.719.594 6.2 3.936 19.81 3.208l21.487-.665c-.666-1.97-1.584-4.25-1.938-4.991-.599-1.248-1.352-3.69-1.848-4.763z" fill="url(#hpa)" stroke-width="1.028"/><linearGradient id="hpb" gradientUnits="userSpaceOnUse" x1="-666.972" y1="142.12" x2="-666.972" y2="142.12" gradientTransform="matrix(1.02783 0 0 1.02783 776.895 2.337)"><stop offset="0" stop-color="#f29100"/><stop offset="1" stop-color="#ec670f"/></linearGradient><linearGradient id="hpc" gradientUnits="userSpaceOnUse" x1="-675.228" y1="-1.28" x2="-675.228" y2="142.967" gradientTransform="matrix(1.02783 0 0 1.02783 776.895 2.337)"><stop offset="0" stop-color="#f29100"/><stop offset="1" stop-color="#ec670f"/></linearGradient><path d="M109.553 94.296c-1.652 1.193-4.88 4.06-11.902 5.145-3.152.487-6.1.527-9.335.365-1.584-.076-3.077-.157-4.665-.177-.936-.008-4.074-.107-3.919.193l-.349.871c.054.287.169 1.004.2 1.177.129.704.165 1.265.192 1.912.048 1.331-.11 2.719-.043 4.062.141 2.787 1.175 5.326 1.306 8.137.143 3.13 1.69 6.442 3.188 8.998.569.973 1.434 1.084 1.811 2.283.442 1.373.024 2.83.239 4.293.842 5.675 2.477 11.606 5.032 16.728.018.043.038.09.06.128 3.156-.53 6.318-1.665 10.418-2.271 7.517-1.115 17.972-.54 24.688-1.17 16.993-1.597 26.216 6.97 41.478 3.459V22.459c0-11.84-9.594-21.438-21.435-21.438H19.239C7.4 1.021-2.197 10.62-2.197 22.458v46.774c3.067-1.11 7.479-7.635 8.861-9.222 2.419-2.775 2.858-6.315 4.062-8.544 2.743-5.078 3.215-8.57 9.451-8.57 2.907 0 4.061.67 6.027 3.31 1.368 1.834 3.731 5.224 4.837 7.49 1.277 2.615 3.357 6.153 4.272 6.867.677.53 1.35.928 1.976 1.163 1.012.38 1.848-.316 2.525-.855.863-.687 1.235-2.088 2.035-3.957 1.152-2.696 2.408-5.926 3.122-7.054 1.237-1.949 1.658-4.261 2.993-5.381 1.97-1.652 4.54-1.768 5.246-1.908 3.957-.781 5.755 1.906 7.704 3.645 1.276 1.138 3.019 3.432 4.256 6.507.967 2.4 2.199 4.622 2.714 6.008.497 1.339 1.725 3.484 2.453 6.055.661 2.336 2.43 4.125 3.102 5.235 0 0 1.029 2.882 7.285 5.516 1.357.572 4.1 1.501 5.736 2.096 2.718.988 5.351.86 8.704.458 2.391 0 3.686-3.462 4.772-6.234.643-1.639 1.259-6.334 1.678-7.667.406-1.297-.544-2.3.265-3.437.946-1.327 1.508-1.399 2.054-3.129 1.172-3.704 7.95-3.89 11.761-3.89 3.176 0 2.772 3.083 8.16 2.028 3.086-.605 6.059.398 9.335 1.265 2.758.732 5.352 1.566 6.906 3.385 1.005 1.178 3.5 7.08.958 7.331.244.3.423.84.88 1.135-.566 2.226-3.03.64-4.4.355-1.845-.383-3.147.057-4.952.856-3.085 1.374-7.598 1.214-10.286 3.452-2.281 1.898-2.277 6.133-3.34 8.507-.002-.001-2.955 7.6-9.402 12.248z" fill="url(#hpc)" stroke-width="1.028"/><linearGradient id="hpd" gradientUnits="userSpaceOnUse" x1="-735.137" y1="90.833" x2="-735.137" y2="141.967" gradientTransform="matrix(1.02783 0 0 1.02783 776.895 2.337)"><stop offset="0" stop-color="#f29100"/><stop offset="1" stop-color="#ec670f"/></linearGradient><path d="M38.247 105.09c-1.467-.15-2.83-.317-4.256-.605-2.662-.536-5.57-1.06-8.193-1.688-1.592-.385-6.895-2.263-8.048-2.792-2.702-1.246-4.496-4.63-6.609-4.282-1.348.22-2.662.682-3.5 2.042-.685 1.11-.917 3.016-1.391 4.294-.55 1.485-1.5 2.87-2.331 4.284-1.53 2.595-4.282 4.941-5.468 7.469-.239.52-.45 1.101-.649 1.708V144.415a48.57 48.57 0 0 1 4.45.96c11.955 3.19 14.872 3.46 26.598 2.119l1.1-.146c.897-1.867 1.59-8.227 2.171-10.195.454-1.51 1.077-2.712 1.313-4.253.223-1.463-.02-2.858-.146-4.188-.329-3.332 2.427-4.522 3.742-7.384 1.186-2.589 1.871-5.535 2.853-8.181.941-2.54 2.41-6.13 4.918-7.408-.305-.355-5.237-.518-6.554-.65z" fill="url(#hpd)" stroke-width="1.028"/></g></symbol><symbol viewBox="0 0 24 24" id="pdf" xmlns="http://www.w3.org/2000/svg"><path d="M14 9h5.5L14 3.5V9M7 2h8l6 6v12a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2m4.93 10.44c.41.9.93 1.64 1.53 2.15l.41.32c-.87.16-2.07.44-3.34.93l-.11.04.5-1.04c.45-.87.78-1.66 1.01-2.4m6.48 3.81c.18-.18.27-.41.28-.66.03-.2-.02-.39-.12-.55-.29-.47-1.04-.69-2.28-.69l-1.29.07-.87-.58c-.63-.52-1.2-1.43-1.6-2.56l.04-.14c.33-1.33.64-2.94-.02-3.6a.853.853 0 0 0-.61-.24h-.24c-.37 0-.7.39-.79.77-.37 1.33-.15 2.06.22 3.27v.01c-.25.88-.57 1.9-1.08 2.93l-.96 1.8-.89.49c-1.2.75-1.77 1.59-1.88 2.12-.04.19-.02.36.05.54l.03.05.48.31.44.11c.81 0 1.73-.95 2.97-3.07l.18-.07c1.03-.33 2.31-.56 4.03-.75 1.03.51 2.24.74 3 .74.44 0 .74-.11.91-.3m-.41-.71l.09.11c-.01.1-.04.11-.09.13h-.04l-.19.02c-.46 0-1.17-.19-1.9-.51.09-.1.13-.1.23-.1 1.4 0 1.8.25 1.9.35M8.83 17c-.65 1.19-1.24 1.85-1.69 2 .05-.38.5-1.04 1.21-1.69l.48-.31m3.02-6.91c-.23-.9-.24-1.63-.07-2.05l.07-.12.15.05c.17.24.19.56.09 1.1l-.03.16-.16.82-.05.04z" fill="#f44336"/></symbol><symbol viewBox="0 0 24 24" id="perl" xmlns="http://www.w3.org/2000/svg"><path d="M12 14c-1 0-3 1-3 2 0 2 3 2 3 2v-1a1 1 0 0 1-1-1 1 1 0 0 1 1-1v-1m0 5s-4-.5-4-2.5c0-3 3-3.75 4-3.75V11.5c-1 0-5 1.5-5 4.5 0 4 5 4 5 4v-1M10.07 7.03l1.19.53c.43-2.44 1.58-4.06 1.58-4.06-.43 1.03-.71 1.88-.89 2.55C13.16 3.55 15.61 2 15.61 2a15.916 15.916 0 0 0-2.64 3.53c1.58-1.68 3.77-2.78 3.77-2.78-2.69 1.72-3.9 4.45-4.2 5.21l.55.08c0 .52 0 1 .25 1.38C14.1 11.31 18 11.47 18 16s-4.03 6-6.17 6C9.69 22 5 21.03 5 16s4.95-5.07 5.83-7.08c.12-.38-.76-1.89-.76-1.89z" fill="#9575cd"/></symbol><symbol viewBox="0 0 24 24" id="php" xmlns="http://www.w3.org/2000/svg"><path d="M12 18.08c-6.63 0-12-2.72-12-6.08s5.37-6.08 12-6.08S24 8.64 24 12s-5.37 6.08-12 6.08m-5.19-7.95c.54 0 .91.1 1.09.31.18.2.22.56.13 1.03-.1.53-.29.87-.58 1.09-.28.22-.71.33-1.29.33h-.87l.53-2.76h.99m-3.5 5.55h1.44l.34-1.75h1.23c.54 0 .98-.06 1.33-.17.35-.12.67-.31.96-.58.24-.22.43-.46.58-.73.15-.26.26-.56.31-.88.16-.78.05-1.39-.33-1.82-.39-.44-.99-.65-1.82-.65H4.59l-1.28 6.58m7.25-8.33l-1.28 6.58h1.42l.74-3.77h1.14c.36 0 .6.06.71.18.11.12.13.34.07.66l-.57 2.93h1.45l.59-3.07c.13-.62.03-1.07-.27-1.36-.3-.27-.85-.4-1.65-.4h-1.27L12 7.35h-1.44M18 10.13c.55 0 .91.1 1.09.31.18.2.22.56.13 1.03-.1.53-.29.87-.57 1.09-.29.22-.72.33-1.3.33h-.85l.5-2.76h1m-3.5 5.55h1.44l.34-1.75h1.22c.55 0 1-.06 1.35-.17.35-.12.65-.31.95-.58.24-.22.44-.46.58-.73.15-.26.26-.56.32-.88.15-.78.04-1.39-.34-1.82-.36-.44-.99-.65-1.82-.65h-2.75l-1.29 6.58z" fill="#1E88E5"/></symbol><symbol viewBox="0 0 79 78" id="postcss" xmlns="http://www.w3.org/2000/svg"><title>postcss-logo-symbol</title><g transform="translate(5.48 5.52) scale(.85425)" fill="#e53935" fill-rule="evenodd" stroke="#e53935" stroke-width="1.519"><path d="M15.447 32.623c.106.08.29.132.106.29-.132.184-.29.342-.395.553-.105.185-.184.237-.342.106.21-.343.42-.66.63-.95zM68.342 60.24c0 .078.026.13.026.21.053-.105.053-.158.08-.21zm0 .236v-.026zm-5.368 10.277l-4.58-25.402c-.078-.025-.183-.077-.368-.13.053.105.08.184.106.263.13-.026.184-.026.236-.052 0-.026 0-.052.027-.08l4.58 25.404zm-4.737-31.12c-.026.078-.026.158-.026.237 0-.08 0-.16.028-.238zm.026.526c-.026 0-.026 0-.052-.028v.026c.028.026.028.026.054 0zm-.052.21v-.185c-.077.026-.156.026-.262.053.132.05.264.078.264.13z"/><path d="M78.71 33.967c-.052-1.028-.078-2.056-.184-3.083-.184-1.397-.368-2.82-.684-4.19-.237-1.133-.63-2.214-1.026-3.294-.5-1.265-1-2.556-1.632-3.768-1.026-1.95-2.368-3.69-3.605-5.508-.818-1.16-1.87-2.108-2.66-3.294-.447-.685-1.105-1.264-1.763-1.79-1.053-.845-2.158-1.61-3.263-2.347a32.525 32.525 0 0 0-2.58-1.634c-.71-.397-1.473-.713-2.21-1.056-.842-.395-1.658-.87-2.605-1.054-.238-.05-.448-.13-.685-.21-.605-.21-1.184-.447-1.79-.632-.92-.29-1.815-.632-2.763-.87C50.342 1 49.394.843 48.446.71 47.394.555 46.316.5 45.262.397a26.83 26.83 0 0 0-2.026-.184C42.236.16 41.21.16 40.21.134c-.5-.027-1.026-.08-1.526-.053-.763.026-1.526.105-2.29.21-.736.08-1.473.21-2.183.317-.867.105-1.735.158-2.604.264-.816.106-1.658.264-2.473.396-.29.053-.58.158-.87.21-.63.132-1.288.185-1.92.396-1.13.344-2.263.74-3.368 1.16-1.027.422-2.027.87-3 1.397-1 .552-1.948 1.21-2.895 1.844a45.325 45.325 0 0 0-2.66 1.923c-.84.66-1.63 1.397-2.394 2.135-.42.42-.763.922-1.158 1.396-.657.765-1.315 1.502-1.947 2.293-.524.66-1 1.344-1.5 2.03-.893 1.21-1.656 2.502-2.366 3.794-.29.527-.553 1.054-.816 1.58-.395.79-.816 1.555-1.184 2.372-.264.554-.474 1.16-.632 1.766-.367 1.292-.736 2.61-1.078 3.9-.316 1.16-.395 2.372-.42 3.558-.027 1.054.078 2.082.183 3.136.027.264-.13.58.184.79-.105.29-.026.45.13.5-.182.29.08.476-.024.74-.027.052.08.157.13.236 0 .08-.025.185 0 .264.028.237.133.474.133.738 0 .184.157.395.21.58.026.078 0 .21-.053.263-.158.184-.132.342.105.448.133.342.08.5.054.66.052.236-.027.315 0 .368.21.422.29.896.315 1.37 0 .106.053.212.106.343.026 0 0 .5 0 .5.13-.078.237-.104.368-.157.08.342.158.66.263.95.132.21.132.314.08.34.105.474.157.922.34 1.37 0-.5-.05-1-.13-1.475.368.132.684.263.895.263.027-.08.053-.184.08-.237-.158-.157-.29-.394-.448-.552.053.21 0 .29 0 .37-.105-.054-.237-.107-.368-.16.105-.13.21-.263.368-.42 0-.238-.13-.45-.5-.423.158-.052.316-.13.5-.184.29-.157-.026-.447-.026-.816.026-.447-.237-.895-.316-1.37-.132-.737-.105-1.844-.184-2.582-.158-.132-.29.21-.316.237.08.632.158 1.264.21 1.897-.157-.527-.263-1.107-.394-1.74-.027.185-.053.264-.053.37-.13.13-.026.29.053.474-.184-.08-.395-.052-.395-.052v.738c-.262-.264-.34-.474-.473-.66-.052-.21-.08-.42-.13-.63.05-.133 0-.212 0-.29a15.968 15.968 0 0 1-.08-.634c.026-.026-.026-.42-.026-.42.21.025.343.05.474.05-.263-.34-.08-.552.027-.763.053-.106.237-.13.29-.238.21-.395.553-.71.553-1.212 0-.237.08-.5.105-.738.053-.448.105-.896.13-1.344.054-.58 0-1.16.133-1.713.212-.92.475-1.843.764-2.766.21-.66.448-1.29.71-1.95.395-1.028.764-2.056 1.264-3.03.71-1.424 1.526-2.794 2.316-4.19.5-.87 1.026-1.687 1.58-2.53.525-.817 1.05-1.66 1.657-2.425a21.452 21.452 0 0 1 2.79-2.978c1.053-.948 2.053-1.923 3.184-2.793a32.218 32.218 0 0 1 4.685-3.005c1.343-.71 2.737-1.266 4.132-1.793.895-.342 1.868-.5 2.79-.79 1.052-.343 2.105-.5 3.21-.527.71-.027 1.395-.106 2.105-.185.632-.05 1.263-.104 1.948-.183-.08.105-.106.158-.132.21-.288.422-.604.844-.894 1.265-.237.343-.5.712-.737 1.054-.422.555-.87 1.108-1.264 1.688-.605.87-1.158 1.766-1.79 2.635-.63.843-1.315 1.634-1.973 2.45-.868 1.134-1.684 2.293-2.552 3.426-.79 1.08-1.63 2.11-2.394 3.19-.684.947-1.29 1.95-1.948 2.923-.973 1.45-1.947 2.872-2.92 4.322a271.93 271.93 0 0 1-2.316 3.294c-.053.08-.132.104-.21.157-.21.342-.21.527-.29.685-.21.395-.42.79-.658 1.16-.132.21-.316.394-.474.605-.026-.316.42-.474.21-.87-.13.212-.263.396-.394.607l-.316.63c.105.08.29.133.105.29-.08.133-.158.29-.237.423a.954.954 0 0 0 .29-.264c0 .29-.158.526-.29.763-.105.21-.368.37-.552.527.026.027.21.106.237.132.237-.08.316-.21.343-.132.08-.105.158-.184.184-.263.104-.264.262-.474.525-.58.106-.053.184-.132.263-.21.79-.818 1.606-1.608 2.316-2.478 1.106-1.345 2.106-2.74 3.16-4.11.446-.58.973-1.16 1.446-1.714.078.606.026 1.185 0 1.74-.08.974-.132 1.95-.21 2.95-.027.395 0 .79-.027 1.186 0 .105-.08.184-.08.29 0 .263.08.553.08.817-.08.975-.186 1.923-.265 2.898-.027.21.078.422.13.607-.13 1.422.16 2.925-.078 4.427.184-.29.237-.474.237-.658.025-.158 0-.316 0-.5v-.264c.025-.475.13-.975.078-1.45-.053-.527-.053-1.027.053-1.528.053-.21-.026-.474.106-.738v.395c-.026 1.5.027 3.003-.183 4.505-.027.132.08.37-.21.343-.238.474.052.817-.21 1.08-.054.053.05.29.077.448-.106.317-.106.317.052.343.026.58.08 1.106.105 1.66.42-1 .21-2.03.396-3.058.026.422.053.844.026 1.29 0 .687-.026 1.345-.052 2.03 0 .132-.027.264-.053.396-.08.37-.105.738-.237 1.08-.105.264-.052.66-.052.975v1.003c.105.448-.027.685.052.948-.08.265-.105.344-.08.423l.08.395c.527-.053.29.343.5.553-.158.212-.105.29-.105.397 0 .237-.025.448-.052.685 0 .606-.026 1.212-.026 1.792 0 .08.026.157.026.236 0 .054-.026.74-.026.74.053.078 0 .157-.08.236-.025 0-.104-3.347-.104-3.347h-.395c-.052 1.58.08 3.003-.21 4.48-.316.025-.42.078-.764.078-.816 0-1.632 0-2.448.026-.974 0-1.92.026-2.895.026-.472 0-.972.054-1.446.054-.632 0-1.29-.08-1.92-.08-.975 0-1.922.08-2.896.106-.71.026-1.42.026-2.13.053-.475.025-.95.05-1.422.104-.21.026-.395.105-.658.184-.08 0-.263-.026-.42 0-.265.053-.5.21-.765.264-.395.08-.5.184-.448.58v.263c-.026.052.58-.08.58-.08-.054 0-.08.158-.16.29.212-.08.343-.132.475-.184.395.185.737.08 1.052.16 1.026.262 2.078.37 3.13.473.685.053 1.343.08 2.027.105.973.053 1.947.106 2.92.106.816 0 1.606-.08 2.42-.08 1.13 0 2.264.052 3.395.08.237 0 .5-.028.763-.028h1.92c1.712-.052 3.422-.08 5.133-.13.975-.028 1.975-.08 2.948-.107l3-.08c1.158-.026 2.316-.026 3.448-.05.868 0 1.71-.03 2.58-.055.972-.026 1.972-.105 2.946-.157.527-.027 1.054-.08 1.58-.132.632-.052 1.29-.13 1.92-.157.948-.054 1.922-.08 2.87-.133 1.184-.078 2.368-.183 3.578-.21 1.106-.052 2.237-.026 3.343-.052.974-.027 1.948-.08 2.948-.106l1.66-.08s1.104-.026 1.657-.08c.947-.052 1.894-.157 2.842-.183.604-.027 1.21 0 1.815-.027.973-.026 1.973-.08 2.947-.08.367 0 .762.054 1.236.08-.21.185-.342.29-.5.422.105.026.21.08.316.132a.71.71 0 0 1-.42.13c-.054.133-.107.186-.16.45h.474c-.184 0-.342.237-.526.395-.21-.054-.395 0-.5.29.184.104.158.183.132.29-.316.104-.553.21-.42.552-.107.052-.238.105-.37.184-.13.21-.368.263-.316.553.106.025.21.08.29.104-.132.053-.263.132-.395.184-.473.29-.262.422-.157.554-.08.053-.158.105-.237.132.052.237.13.29.157.29a9.3 9.3 0 0 0-.395.316c-.08.237-.185.342-.29.5s-.158.37-.29.527c-.552.607-.947 1.32-1.657 1.793-.264.185-.5.422-.737.66-.474.447-.895.948-1.395 1.37a29.595 29.595 0 0 1-2.052 1.554 151.56 151.56 0 0 1-2.604 1.792c-.474.315-1 .552-1.5.842s-.974.554-1.474.843c-.316.21-.606.5-.948.66-.868.37-1.79.685-2.684 1.028-.87.37-1.5.685-2.158.922-.605.21-1.237.37-1.868.5-.21.054-.448 0-.685.027-.448.08-.895.186-1.343.238-1.158.158-2.316.264-3.473.422-.685.08-1.343.21-2.027.29-.473.026-.973-.026-1.447-.026-.342 0-.71.08-1.053.027-.552-.08-1.105-.21-1.658-.316-.13-.026-.316-.08-.42-.026-.21.106-.396-.052-.607 0-.13.027-.262-.08-.394-.08-.106-.025-.238.028-.37 0-.29-.078-.552-.183-.87-.157-.313.026-.63-.132-.97-.21-.475-.106-.92-.21-1.396-.317a2.38 2.38 0 0 1-.525-.237c-.685 0-1.133-.026-1.554-.185-.368-.13-.71-.315-1.105-.262-.104.026-.183-.026-.29-.026-.08-.106-.157-.317-.235-.317-.526.027-.842-.42-1.29-.553-.236-.08-.42-.343-.657-.422-.58-.237-1.052-.737-1.71-.816-.21-.027-.42-.132-.658-.21.08.104.13.183.21.262-.763-.37-1.473-.79-2.184-1.186-.104-.026-.183-.13-.262-.184l-.71-.474c-.395.08-.553-.08-.66-.132-.71-.5-1.525-.817-2.21-1.37-.29-.238-.63-.396-.84-.686-.37-.448-.817-.764-1.317-1.027-.394-.21-.762-.448-1.13-.685-.185-.132-.37-.29-.37-.58 0-.185-.078-.37-.315-.264-.105-.158-.21-.342-.342-.395-.316-.13-.526-.37-.763-.58s-.42-.5-.71-.605c-.527-.21-.843-.658-1.158-1.027-.738-.87-1.396-1.82-2.08-2.74-.053-.08-.158-.133-.237-.212.105.29.237.527.368.79-.262-.105-.446-.29-.604-.474-.027.027 1.815 3.057 1.815 3.057.16.237.29.475.448.712a.813.813 0 0 1-.79-.422c-.236-.42-.5-.684-1.026-.63a4.588 4.588 0 0 1-.13-.58c-.107 0-.185 0-.37-.027.37.58.685 1.08 1.027 1.66-.133-.08-.21-.132-.265-.158.473.5.815 1.133 1.42 1.45.132.605.816.895.974 1.475-.13-.027-.238-.053-.37-.08-.21-.263-.447-.526-.683-.816.052.184.13.342.236.474.316.395.606.79.974 1.133.132.134.316.187.316.424.21.105.29.13.368.13.054.16-.025.397.29.344.21.395.42.395.71.264.343.343.528.37.764.16 0 .13.026.262.026.368.105-.053.08-.132.08-.264.13.105.21.158.262.21.263.37.5.712.868 1.002.5.422.948.87 1.42 1.265.922.765 1.95 1.398 2.975 1.977 1.264.712 2.475 1.476 3.764 2.16 1.552.818 3.21 1.372 4.92 1.767.632.132 1.237.263 1.87.42.55.16 1.104.397 1.657.528.842.185 1.71.343 2.552.5.183.027.37.054.58.08.235.053.524-.053.577.027.132.21.237.104.395.078.184-.053.395-.053.605-.053.737.026 1.447.184 2.184.132.16 0 .396-.133.528.13.236-.105.368-.105.473-.13.028.236 0 .236-.05.262-.054.026-.133.053-.238.132.947.184 1.842.21 2.63 0 1.37.105 2.554-.053 3.686-.448.105.132.184.316.342.053.052-.08.184-.107.29-.133.236-.053.526-.158.736-.08.238.08.317-.13.5-.13.317 0 .606-.027.896-.08.158-.026.316-.105.5-.158a1.285 1.285 0 0 0-.58-.133c.317-.158.606-.29.896-.42-.053.078-.106.183-.21.183h.367c-.08 0-.185.237-.316.395.946-.237 1.814-.448 2.657-.66-.29-.552.315-.367.526-.684-.263.08-.526.158-.79.21.895-.447 1.816-.842 2.71-1.237-.13.158-.29.237-.525.37.158.025.263.025.342.05.42.133.316-.262.447-.5.5 0 .71-.078.947-.158.263-.08.526-.158.79-.263.42-.184.815-.42 1.236-.63.08-.028.21 0 .316 0 .29-.186.394-.344.473-.318.37.053.63-.08.736-.42.184-.133.316-.238.447-.318.578-.316 1.13-.632 1.71-.948.21 0 .316 0 .368-.027.344-.16.66-.342.975-.527a2.258 2.258 0 0 1-.263-.13c.262-.054.34-.08.5-.133.63-.74 1.5-1.24 2.157-1.82.29-.026.29-.105.29-.157.104-.132.21-.29.34-.396.58-.527 1.21-.975 1.737-1.528a37.16 37.16 0 0 0 2.184-2.374c.63-.738 1.264-1.475 1.79-2.292.737-1.133 1.368-2.293 2.026-3.48.474-.842.895-1.685 1.37-2.528.05-.08.157-.185.236-.185.71-.08 1.422-.13 2.106-.21.158-.026.342-.13.5-.21-.08-.132-.132-.29-.21-.422-.106-.16-.264-.29-.37-.45-.104-.13-.183-.29-.262-.447-.08-.13-.158-.236-.237-.37a9.7 9.7 0 0 1-.45-.894c-.026-.08-.08-.21-.052-.29.474-1.027.658-2.134 1.105-3.162.447-1.054.58-2.24.79-3.373.184-1.08.29-2.16.42-3.24.08-.764.185-1.502.21-2.266.16-1.212.106-2.346.08-3.48-.026-1-.08-2.028-.13-3.03zM12.685 66.405c-.184-.21-.342-.448-.526-.658l.08-.08c.287.317.577.633.866.976-.158-.08-.342-.132-.42-.238zm.42.238c.08-.027.16-.027.238-.053.08.132.132.29.21.448-.368-.027-.552-.185-.447-.395zm27.37 10.883v-.08c.5-.052.973-.105 1.473-.157v.077c-.5.08-.973.13-1.473.158zm6.63-.685c-.367.08-.762.133-1.13.186-.132.026-.29.158-.342-.08-.053.027-.106.027-.158.054.13.394.447.078.71.236-.58.08-1.13.132-1.684.21v-.052c.16-.026.343-.053.5-.08v-.078a7.743 7.743 0 0 0-.79-.053c-.077 0-.183.106-.262.132-.105.026-.21.053-.342.053-.447.026-.894.026-1.316.052-.027 0-.08-.026-.106-.026v-.08c1.763-.236 3.5-.473 5.263-.71.027.052.027.105.053.157-.158 0-.263.055-.395.08zm.396-.262c.606-.08 1.16-.132 1.738-.21-1.21.342-1.605.394-1.737.21zM24.58 23.374c.84-1.16 1.71-2.32 2.552-3.505.263-.345.473-.714.736-1.056.08-.106.185-.158.316-.264l-.026-.05c.105-.133.21-.24.263-.344.134-.21.213-.448.318-.685a.385.385 0 0 1 .105-.103c.37.184.37-.21.5-.343.237-.264.474-.553.684-.817.158-.21.316-.395.448-.632.026-.08-.053-.21-.08-.317h-.078c.08-.052.158-.13.237-.184.026 0 .026 0 .052-.026.158-.238.316-.475.474-.686.315-.42.657-.842 1.025-1.21-.052.13-.105.263-.158.368.027 0 .027.027.053.027.316-.422.658-.817.974-1.24-.027-.025-.053-.052-.08-.052-.13.132-.236.264-.368.396-.026-.027-.052-.053-.08-.053.265-.343.528-.685.79-1.08.053.08.106.184.21.395.107-.263.212-.447.29-.632-.078.08-.183.158-.262.238l-.08-.08.474-.71c.5-.712 1-1.45 1.5-2.162.185-.263.42-.474.58-.738.5-1 1.29-1.792 1.894-2.714.132-.184.316-.342.474-.5.13-.16.237-.106.342.026.71.896 1.42 1.818 2.13 2.714.528.66 1.054 1.29 1.554 1.976.605.844 1.184 1.687 1.79 2.53.684.975 1.368 1.95 2.026 2.95 1 1.477 1.947 2.953 2.947 4.428.737 1.08 1.474 2.135 2.184 3.215h-1.344c-1.236-.025-2.5-.13-3.736-.078-1.684.08-3.394.264-5.078.396-2.132.185-4.29.21-6.42.21-.765 0-1.528.107-2.29.16-.922.052-1.817.105-2.738.13-1.08.054-2.13.08-3.21.107-.606.026-1.237 0-1.895 0zm30.183 12.12v.238c-.026 0-.052.027-.105.027-.105-.37-.21-.766-.342-1.135-.263-.765-.553-1.53-1.027-2.214-.528-.737-1-1.5-1.528-2.265-.13-.185-.316-.343-.474-.5-.553-.607-1.106-1.24-1.816-1.687a21.485 21.485 0 0 0-3.29-1.688 7.374 7.374 0 0 1-.92-.474h.63l4.5-.08c.974-.025 1.922-.025 2.895-.078.236 0 .368.08.5.29.236.395.473.79.736 1.186.027.052.08.13.08.21 0 .58 0 1.186.026 1.766.025.606.08 1.186.104 1.792 0 .606-.053 1.238-.026 1.87.027.897.053 1.82.053 2.74zM26.447 26.67c1.237-.053 2.42-.132 3.632-.185.945-.053 1.92-.08 2.866-.132.395-.025.764-.05 1.158 0-.42.212-.842.423-1.21.686-.474.316-.92.737-1.395 1.08-.475.342-.896.764-1.29 1.212-.5.605-1.053 1.132-1.58 1.712-.37.422-.79.817-1.105 1.265-.447.58-.842 1.21-1.263 1.87.132-2.504.29-4.98.184-7.51zm17.185 25.35c-.843.21-1.71.448-2.58.553-.736.106-1.5.08-2.263.08a25.42 25.42 0 0 1-2.028-.08c-.763-.078-1.526-.157-2.263-.5-.633-.29-1.29-.553-1.92-.87-.634-.316-1.265-.684-1.74-1.264-.34-.423-.815-.765-1.236-1.134.08.316.263.58.553.764-.132.158-.316.08-.58-.343-.078.053-.157.08-.21.106.08-.185.158-.37.237-.527-.105-.21-.237-.448-.342-.66-.21-.342-.42-.71-.605-1.053-.053-.08-.053-.158-.105-.237a5.893 5.893 0 0 1-.37-.475c-.21-.315-.394-.657-.657-.974 0 .08.027.158.027.264-.027 0-.053.026-.053.026l-.554-1.344c-.026 0-.026 0-.052.026l.473 1.74c-.026 0-.052.025-.08.025-.077-.104-.156-.21-.21-.34-.052-.212-.21-.212-.34-.133-.08.053-.133.237-.106.316.185.448.395.896.606 1.344.052.158.105.29.184.448.027.053.106.105.106.184.106.21.185.42.316.606.237.316.5.632.737.948.235.316.445.66.656.975.026.053.105.053.13.08.133.395.58.684.896.526.08.606.737.817 1 1.397a11.957 11.957 0 0 1-.763-.343c-.027.026-.027.052-.054.105.316.158.632.316.92.5.265.16.528.317.765.5.316.29.685.45 1.13.554a.282.282 0 0 0-.05-.107c.736.343 1.5.712 2.078 1-2.737.054-5.658.107-8.685.16 0-.5-.026-.975-.026-1.476 0-.21.052-.395.025-.606-.08-1.21-.08-2.424-.237-3.61-.157-1.264-.157-2.503-.13-3.77.025-.683-.027-1.394-.054-2.08 0-.922 0-1.82.028-2.74 0-.132.053-.237.106-.37h.08c.025.054 0 .133.05.16.08.08.212.21.265.184.157-.106.394-.21.447-.37.13-.315.184-.658.184-.974 0-.236.106-.394.21-.553.054-.08.08-.158.133-.263-.105-.08-.21-.132-.342-.237.106-.29.08-.633.475-.79.052-.027.052-.16.08-.238.025-.213.05-.45.078-.66.052.08.08.105.13.157a.42.42 0 0 1 .054-.08c0-.104-.026-.315 0-.315.316-.053.184-.395.342-.553.025-.028-.027-.107-.027-.16 0-.052 0-.13.026-.13.367-.08.315-.475.552-.66.08-.053.105-.13.21-.263.21.368-.158.553-.184.816.446-.263.578-.895.315-1.08.105-.08.21-.184.29-.29.29-.316.604-.606.868-.922.185-.236.29-.526.474-.763.106-.132.316-.237.474-.317.474-.262.92-.552 1.21-1 .053-.053.132-.105.21-.158.08-.053.238-.053.264-.132.027-.052-.052-.184-.105-.263.104-.053.21-.158.42-.264-.08.158-.105.264-.158.37l.13.13c.238-.184.606-.394.843-.552 0-.025-.132-.13-.132-.13-.157.08-.394.21-.63.316.05-.08.05-.132.08-.158.367-.237.735-.474 1.13-.66.92-.42 1.842-.842 2.763-1.237.158-.08.37-.026.553-.026.078 0 .13 0 .21-.026.42-.132.842-.264 1.263-.37.183-.052.393-.078.58-.078.787.025 1.577.025 2.366.078.342.026.658.105.974.21a9.88 9.88 0 0 1 1.184.5c.447.24.868.502 1.29.792.763.5 1.473 1.054 2.236 1.502.737.448 1.316 1.054 1.79 1.74.58.816 1.237 1.554 1.5 2.555l.394 1.74c.08.316.264.632.185 1-.133.66-.238 1.345-.343 2.004-.052.265-.105.53-.078.79.05.82-.265 1.53-.58 2.268-.106.237-.264.475-.395.738a.798.798 0 0 0 .21.106l.237-.474c.027 0 .027 0 .053.027-.132.368-.237.764-.37 1.133-.314.817-.63 1.66-1.025 2.45-.21.448-.58.817-.842 1.24-.262.368-.473.763-.736 1.106-.237.29-.473.58-.79.79-.71.527-1.447 1.054-2.21 1.476-.473.29-1.026.448-1.552.58zm-14.027-1.4l-.026.027c-.055-.026-.134-.052-.186-.105l-.632-.95c-.052-.078-.08-.157-.052-.262.29.448.58.87.895 1.29zm16.37 3.61c1.183-.5 2.157-1.21 3.05-2.028.133-.132.264-.263.422-.37 1.106-.684 1.92-1.633 2.658-2.687.842-1.212 1.395-2.582 2.08-3.873a2.73 2.73 0 0 1 .157-.29c-.053 3.004.29 5.955.684 8.933-2.973.105-6 .21-9.052.316zm26.683-.79c-.026.053-.08.106-.105.16-.027-.054-.027-.133-.053-.24-.158.423-.5.212-.737.212-1.42.027-2.868.027-4.29.027-1.368 0-2.762 0-4.13.024-.448 0-.922.105-1.37.132-1.078.052-2.157.08-3.236.105-.08 0-.158-.13-.29-.236a1.81 1.81 0 0 1-.158.237c-.028-.052-.08-.104-.133-.183-.026.08-.053.158-.08.21H58c-.053-.368-.158-.71-.158-1.08 0-.79.08-1.58.105-2.372.027-.368 0-.71 0-1.054.106.08.185.133.29.21.052-.103.105-.182.158-.26 0 0-.053-.028-.106-.08.05-.027.104-.08.104-.106.026-.08.08-.158.08-.21 0-.185-.054-.343-.08-.5.026 0 .052 0 .08-.028l.157.79h.08c-.106-.183.236-.342-.053-.552-.026-.027.026-.185.026-.264-.08-.157-.13-.315-.21-.526.026-.026.105-.053.184-.08-.105-.052-.184-.104-.263-.13.263-.238.263-.37.026-.633.054-.025.106-.025.106-.05 0-.238 0-.475-.052-.71-.053-.266.08-.58-.316-.74a.79.79 0 0 0 .105.21s-.08.027-.158.08c-.342-.317-.13-.74-.21-1.213.184.053.316.106.447.16-.053-.186-.184-.397-.263-.634h-.107v-1.74c0 .027.184.027.29.054 0-.027.025-.053.025-.08-.08-.105-.185-.21-.29-.342l.053-.053c-.21-.262-.105-.63-.105-.71V39.4c.264.264-.13.606.264.764v-.263h-.027c-.026-.395-.026-.79-.052-1.186h-.052c-.027.054-.027.08-.054.133h-.052l.158-6.298c.263.342.552.66.736 1 .606 1.108 1.395 2.057 2.132 3.058.632.87 1.21 1.818 1.79 2.714.71 1.08 1.394 2.16 2.105 3.24a81.41 81.41 0 0 0 1.63 2.426c.5.71 1.028 1.396 1.554 2.082.446.606.92 1.212 1.367 1.818.527.738 1.053 1.475 1.58 2.187.262.368.552.737.84 1.106.16.21.396.37.554.5-.025 0-.052 0-.104-.026.08.105.13.184.184.237.29.158.316.316.158.554zM74 46.854v-.185c0 .052.026.13 0 .184zm.895-11.62c-.027 0-.184-.16-.21-.186-.027.08 0 .158-.053.264-.027-.078-.21-.052-.21-.13-.027.368.157.737.13 1.106.08-.053.395-.08.474-.158.027.026.08.052.106.052-.527.396-.395.79-.158 1.24.052.104.21.315.052.526-.052.053.027.21.053.343h.077v.05l-.237.08c-.052-.08-.367-.236-.367-.37v1.346c.263.08.263.448.368.633a.768.768 0 0 0 .107-.21l.027.024c-.027.158-.053.316-.106.475-.052.236-.105.447-.13.684 0 .026.05.08.05.105-.288.66-.13 1.396-.235 2.08-.08.5 0 1.03-.053 1.556-.054.448-.16.922-.264 1.37-.027.08-.08.105-.21.158.052-.316.026-.527-.027-.817-.028 0-.37-.184-.397-.184 0 .37.21.87.29 1.29-.08-.026-.395-.21-.42-.21-.054.316-.054.738-.08 1.08-.027.264-.263.5-.29.79 0 .16.184.264.158.528h.21c0-.526.238-1 .238-1.554h.078c.027.053.106.106.08.132-.053.29-.16.606-.132.896 0 .158.13.316.08.5-.054.16-.08.317-.107.554-.027-.132-.053-.184-.053-.263-.026 0-.263-.027-.29-.027-.026.158.185.316.158.448-.026.026-.052.026-.105.053l-.868-1.266c-.686-1-1.37-2.003-2.054-3.03a6.312 6.312 0 0 1-.475-.79 37.09 37.09 0 0 0-2.71-4.033c-.762-.974-1.37-2.03-2.08-3.055-.656-.975-1.314-1.924-1.972-2.9-.237-.315-.526-.605-.737-.948-.683-1.08-1.29-2.187-1.972-3.267-.58-.897-1.21-1.767-1.816-2.636-.21-.29-.42-.607-.632-.923a.37.37 0 0 1-.052-.182c-.053-.58-.106-1.16-.132-1.713 0-.527.053-1.054.053-1.608v-.474c0-.132.025-.237.025-.37.025-.025.052-.078.078-.104-.763 0-1.553-.028-2.316 0-.5.025-.763-.186-1.105-.555-1-1.133-1.737-2.424-2.605-3.636a162.42 162.42 0 0 0-2.5-3.427c-.685-.922-1.37-1.818-2.053-2.74-.764-1.054-1.5-2.108-2.29-3.162a381.983 381.983 0 0 0-2.895-3.794c-.45-.58-.95-1.133-1.45-1.74.343.054.66.106.975.133l1.264.08c.947.077 1.894.13 2.84.26.79.107 1.58.265 2.396.396 1.738.29 3.448.765 5.106 1.318.974.316 1.92.738 2.87 1.133 2.13.87 4.157 1.924 6.157 3.03.63.343 1 .896 1.472 1.397.685.712 1.37 1.423 2.027 2.16.762.87 1.472 1.766 2.21 2.662.657.79 1.34 1.58 2 2.372.21.237.37.527.552.79.42.633.895 1.24 1.263 1.924.262.502.42 1.082.604 1.635.262.817.526 1.607.79 2.424.183.606.34 1.24.472 1.87.106.423.08.87.21 1.29.16.556 0 1.16.16 1.715.025.053.05.132.078.185.105.104.184.21.026.368-.025.026-.025.13 0 .21.054-.052.08-.105.133-.184 0 .053.025.08.025.105 0 .104-.027.21 0 .315 0 .052.052.13.078.184.053-.054.105-.08.21-.16.237.897.264 1.793.264 2.715 0 .87.157 1.74-.21 2.583.078-.29-.106-.555-.027-.818z"/><path d="M58.08 45.482c.025 0 .052.027.052.027l-.027-.03c0-.025 0-.025-.026 0zm4.157 26.036c-.29.21-.58.395-.948.474-.028-.026-.028-.053-.054-.08.29-.184.605-.368.895-.553.027.05.08.104.106.157zM12.895 35.81c.29-.367.58-.736.894-1.105.025.026.235.08.262.105-.29.37-.685.87-.974 1.265-.054-.053-.133-.237-.185-.264zM5.42 48.725c-.21-.448-.42-.923-.63-1.37a.91.91 0 0 1 .236-.106c.29.42.42.92.632 1.37 0 0-.21.105-.237.105zm6.712-12.65c-.158.238-.316.502-.474.74-.026-.028-.316.104-.342.078.158-.237.552-.66.71-.896.027.026.053.053.106.08zM59.422 72.6c.025 0 .025-.026.052-.026.184.026.394.052.605.052-.344.237-.555.21-.66-.026zm-47.24-35.418c.028-.08.08-.158.133-.237.052 0 .13-.027.13-.027.107-.184.107-.316.212-.474-.026-.026-.053-.026-.08-.053-.157.108-.315.24-.473.345.053.052.053.08.053.132-.21-.027-.29.08-.395.368-.026.08-.158.106-.29.21-.026.054-.052.186-.105.317l.027.028c-.053.053-.132.08-.132.08-.158.157-.342.29-.5.447-.026.08-.052.158-.052.237.185-.184.5-.527.737-.738l.027.027c.105-.158.184-.316.29-.474.025.026.025.052.052.08-.08.21-.158.446-.237.657-.055.026-.134.08-.134.053-.105.08-.184.184-.29.263l-.473.316c-.263.237-.526.447-.816.685-.184.29-.368.553-.58.896.317-.08.396.053.37.317.368.052.395-.237.5-.448.026-.054.053-.16.105-.186.237-.21.5-.394.763-.605.053-.053.053-.16.053-.238 0-.026-.133-.026-.212-.053.237-.264.58-.71.816-1 .132-.08.263-.186.263-.265-.026-.29.158-.368.37-.474-.106-.08-.133-.157-.133-.183z"/><path d="M12.71 36.892c-.105.184-.21.342-.315.527l-.158-.08c-.105.605-.474 1.132-.842 1.237.105.053.21.106.29.08.078-.027.13-.16.183-.238l.71-1.028.238-.396-.105-.105zM3.948 48.46c.132 0 .264.026.42.026 0-.105.133-.08.133-.184h.08c0 .132.026.237.026.37h-.552c-.027-.027-.132-.186-.106-.212zm-.21-1.212c-.08-.08-.21-.158-.21-.237-.027-.104.052-.235.13-.367.054.184.08.342.132.527-.027.025-.053.052-.053.078zm.658-1.687c.105.266.21.556.316.82a.798.798 0 0 0-.21.105c-.105-.264-.237-.554-.342-.817a.652.652 0 0 1 .237-.106zm58.58 25.194c.13-.052.288-.08.5-.13-.238.183-.422.315-.58.473-.027-.026-.053-.053-.08-.053.053-.105.106-.184.16-.29zM30.63 15.074c.157-.106.29-.185.447-.29l.052.052c-.16.21-.29.42-.475.685-.026-.183-.026-.29-.053-.42-.026 0 0 0 .027-.026zm7.71 13.333c.237-.106.474-.21.763-.343-.026.158-.026.264-.026.37a.927.927 0 0 0-.264-.054c-.158.027-.448.238-.58.264-.025 0 .106-.21.106-.237zm19.74 22.346c.052.263.552.395.052.658.08.055.157.08.236.134a.2.2 0 0 1-.052.106c-.053.025-.158.078-.21.05-.027 0-.08-.104-.08-.157 0-.237.027-.474.053-.79z"/></g></symbol><symbol viewBox="0 0 24 24" id="powerpoint" xmlns="http://www.w3.org/2000/svg"><path d="M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2m7 1.5V9h5.5L13 3.5M8 11v2h1v6H8v1h4v-1h-1v-2h2a3 3 0 0 0 3-3 3 3 0 0 0-3-3H8m5 2a1 1 0 0 1 1 1 1 1 0 0 1-1 1h-2v-2h2z" fill="#d14524"/></symbol><symbol viewBox="0 0 67.47 70" id="powershell" xmlns="http://www.w3.org/2000/svg"><path d="M18.545 12.4c-3.014 0-6.08 2.34-6.873 5.248L1.91 53.438c-.793 2.908.996 5.248 4.01 5.248h42.887c3.014 0 6.08-2.34 6.873-5.248l9.761-35.79c.794-2.908-.993-5.248-4.007-5.248h-42.89zm4.848 6.243c.652.04 1.29.33 1.76.86l7.96 9.013-3.957 3.246 3.957-3.244 4.832 5.47c.037.042.06.088.094.131.026.034.057.06.082.096.02.028.032.057.05.086.057.087.105.176.15.267.028.06.055.117.08.178a2.546 2.546 0 0 1 .171.764c.005.073.01.146.008.219-.002.09-.01.178-.021.267a2.53 2.53 0 0 1-.036.217 2.56 2.56 0 0 1-.07.252c-.024.076-.048.15-.08.224a2.547 2.547 0 0 1-.111.22 2.503 2.503 0 0 1-.133.218 2.546 2.546 0 0 1-.147.187c-.058.07-.118.137-.185.202-.027.026-.048.057-.076.082-.037.032-.077.054-.116.084-.038.03-.07.065-.11.093L16.8 52.271a2.552 2.552 0 0 1-3.563-.626 2.553 2.553 0 0 1 .63-3.563l18.349-12.853-3.06-3.467-7.839-8.873a2.549 2.549 0 0 1 .225-3.608 2.546 2.546 0 0 1 1.85-.638zm22.441 28.214c1.377 0 2.255 1.083 1.969 2.43-.287 1.347-1.627 2.433-3.004 2.434l-9.957.006c-1.378 0-2.256-1.083-1.969-2.43.287-1.347 1.626-2.433 3.004-2.434l9.957-.006z" fill="#03a9f4" stroke-width="5.342" stroke-linejoin="round"/></symbol><symbol viewBox="0 0 210 210" id="prettier" xmlns="http://www.w3.org/2000/svg"><title>prettier-icon-dark</title><g transform="matrix(.9 0 0 .9 10.5 10.5)" fill="none" fill-rule="evenodd"><rect fill="#56B3B4" x="165" y="40" width="20" height="10" rx="5"/><rect fill="#EA5E5E" x="15" y="200" width="60" height="10" rx="5"/><rect fill="#BF85BF" x="135" y="120" width="40" height="10" rx="5"/><rect fill="#EA5E5E" x="75" y="120" width="50" height="10" rx="5"/><rect fill="#56B3B4" x="15" y="120" width="50" height="10" rx="5"/><rect fill="#BF85BF" x="15" y="160" width="60" height="10" rx="5"/><rect fill="#BF85BF" x="15" y="80" width="60" height="10" rx="5"/><rect fill="#F7BA3E" x="65" y="20" width="110" height="10" rx="5"/><rect fill="#EA5E5E" x="15" y="20" width="40" height="10" rx="5"/><rect fill="#F7BA3E" x="55" y="180" width="20" height="10" rx="5"/><rect fill="#56B3B4" x="55" y="60" width="20" height="10" rx="5"/><rect fill="#56B3B4" x="15" y="180" width="30" height="10" rx="5"/><rect fill="#F7BA3E" x="15" y="60" width="30" height="10" rx="5"/><rect fill="#56B3B4" x="95" y="100" width="90" height="10" rx="5"/><rect fill="#F7BA3E" x="45" y="100" width="40" height="10" rx="5"/><rect fill="#EA5E5E" x="15" y="100" width="20" height="10" rx="5"/><rect fill="#BF85BF" x="105" y="40" width="50" height="10" rx="5"/><rect fill="#56B3B4" x="15" y="40" width="80" height="10" rx="5"/><rect fill="#F7BA3E" x="45" y="140" width="100" height="10" rx="5"/><rect fill="#BF85BF" x="15" y="140" width="20" height="10" rx="5"/><rect fill="#EA5E5E" x="135" y="60" width="60" height="10" rx="5"/><rect fill="#F7BA3E" x="135" y="80" width="60" height="10" rx="5"/><rect fill="#56B3B4" x="15" width="130" height="10" rx="5"/></g></symbol><symbol viewBox="0 0 80 80" id="protractor" xmlns="http://www.w3.org/2000/svg"><defs><clipPath id="hxa"><path transform="scale(1 -1)" fill="#564b55" stroke-width="27.224" d="M-2.983-69.251h69.412v67.108H-2.983z"/></clipPath></defs><g transform="matrix(1.13039 0 0 -1.13039 5.714 82.137)" clip-path="url(#hxa)"><g transform="scale(.1)"><path d="M1180.54 92.324c-5.53 0-9.93-1.797-13.23-5.39-3.29-3.614-5.22-8.594-5.81-14.97h36.02c0 6.583-1.47 11.622-4.4 15.126-2.93 3.496-7.12 5.234-12.58 5.234zm2.84-62.656c-10.19 0-18.22 3.086-24.11 9.297-5.88 6.21-8.83 14.824-8.83 25.84 0 11.101 2.73 19.922 8.21 26.464 5.45 6.524 12.81 9.805 22.02 9.805 8.63 0 15.46-2.851 20.48-8.523 5.03-5.676 7.55-13.157 7.55-22.461v-6.613h-47.45c.21-8.086 2.26-14.22 6.12-18.418 3.89-4.18 9.34-6.29 16.38-6.29 7.42 0 14.76 1.563 22 4.669V34.14c-3.68-1.602-7.18-2.746-10.48-3.438-3.28-.684-7.24-1.035-11.89-1.035M1272.34 30.918v44.57c0 5.606-1.28 9.805-3.82 12.559-2.56 2.773-6.56 4.16-12.02 4.16-7.2 0-12.49-1.953-15.84-5.851-3.34-3.895-5.03-10.32-5.03-19.286V30.918h-10.42v68.887h8.47l1.71-9.422h.5c2.14 3.387 5.14 6.023 8.99 7.887 3.85 1.867 8.15 2.804 12.88 2.804 8.29 0 14.54-2.011 18.73-6.015 4.19-3.985 6.28-10.391 6.28-19.192V30.918h-10.43M1328.96 38.406c7.1 0 12.27 1.938 15.48 5.813 3.22 3.879 4.81 10.129 4.81 18.758v2.199c0 9.765-1.62 16.726-4.87 20.898-3.25 4.18-8.44 6.25-15.56 6.25-6.11 0-10.79-2.383-14.04-7.129-3.26-4.746-4.88-11.472-4.88-20.136 0-8.797 1.61-15.45 4.84-19.93 3.23-4.484 7.97-6.723 14.22-6.723zm20.85 1.762h-.56c-4.83-7.004-12.02-10.5-21.62-10.5-9.01 0-16.03 3.066-21.04 9.238-5 6.153-7.5 14.922-7.5 26.27 0 11.355 2.51 20.176 7.54 26.465 5.03 6.289 12.03 9.433 21 9.433 9.34 0 16.5-3.398 21.49-10.195h.81l-.43 4.96-.25 4.845v28.039h10.43V30.918h-8.49l-1.38 9.25M1434.91 38.27c1.85 0 3.63.136 5.34.421 1.72.274 3.09.547 4.1.84v-7.976c-1.15-.559-2.81-.996-5.01-1.36-2.18-.351-4.17-.527-5.94-.527-13.32 0-19.97 7.012-19.97 21.055V91.71h-9.88v5.027l9.88 4.336 4.38 14.707h6.04V99.805h20V91.71h-20V51.16c0-4.15.98-7.333 2.96-9.56 1.97-2.206 4.67-3.331 8.1-3.331M1463.81 65.43c0-8.809 1.76-15.508 5.27-20.118 3.53-4.609 8.69-6.906 15.53-6.906s12.01 2.297 15.56 6.875c3.53 4.602 5.3 11.301 5.3 20.149 0 8.75-1.77 15.41-5.3 19.953-3.55 4.539-8.77 6.824-15.69 6.824-6.82 0-11.99-2.246-15.47-6.73-3.46-4.48-5.2-11.16-5.2-20.047zm52.47 0c0-11.23-2.83-20-8.48-26.309-5.66-6.309-13.47-9.453-23.44-9.453-6.17 0-11.64 1.445-16.42 4.336-4.78 2.89-8.46 7.031-11.06 12.45-2.59 5.401-3.88 11.73-3.88 18.976 0 11.23 2.8 19.968 8.41 26.242 5.61 6.258 13.4 9.402 23.38 9.402 9.64 0 17.3-3.222 22.97-9.62 5.69-6.415 8.52-15.087 8.52-26.024M1591.71 92.324c-5.54 0-9.94-1.797-13.23-5.39-3.3-3.614-5.24-8.594-5.81-14.97h36c0 6.583-1.46 11.622-4.39 15.126-2.93 3.496-7.13 5.234-12.57 5.234zm2.83-62.656c-10.19 0-18.22 3.086-24.11 9.297-5.89 6.21-8.83 14.824-8.83 25.84 0 11.101 2.74 19.922 8.2 26.464 5.46 6.524 12.81 9.805 22.04 9.805 8.62 0 15.45-2.851 20.48-8.523 5.03-5.676 7.54-13.157 7.54-22.461v-6.613h-47.45c.21-8.086 2.25-14.22 6.13-18.418 3.87-4.18 9.33-6.29 16.36-6.29 7.43 0 14.77 1.563 22.01 4.669V34.14c-3.69-1.602-7.17-2.746-10.46-3.438-3.3-.684-7.27-1.035-11.91-1.035M1683.5 30.918v44.57c0 5.606-1.27 9.805-3.83 12.559-2.55 2.773-6.55 4.16-12.01 4.16-7.2 0-12.48-1.953-15.83-5.851-3.35-3.895-5.03-10.32-5.03-19.286V30.918h-10.43v68.887h8.48l1.69-9.422h.51c2.14 3.387 5.14 6.023 8.99 7.887 3.84 1.867 8.15 2.804 12.88 2.804 8.3 0 14.54-2.011 18.74-6.015 4.19-3.985 6.29-10.391 6.29-19.192V30.918h-10.45M1740.11 38.406c7.12 0 12.28 1.938 15.49 5.813 3.21 3.879 4.81 10.129 4.81 18.758v2.199c0 9.765-1.62 16.726-4.87 20.898-3.25 4.18-8.43 6.25-15.56 6.25-6.12 0-10.8-2.383-14.05-7.129-3.24-4.746-4.88-11.472-4.88-20.136 0-8.797 1.64-15.45 4.85-19.93 3.22-4.484 7.96-6.723 14.21-6.723zm20.87 1.762h-.57c-4.82-7.004-12.03-10.5-21.62-10.5-9.01 0-16.02 3.066-21.03 9.238-5 6.153-7.52 14.922-7.52 26.27 0 11.355 2.52 20.176 7.55 26.465 5.02 6.289 12.02 9.433 21 9.433 9.34 0 16.5-3.398 21.48-10.195h.83l-.44 4.96-.25 4.845v28.039h10.43V30.918h-8.49l-1.37 9.25M1846.07 38.27c1.85 0 3.64.136 5.36.421 1.7.274 3.07.547 4.08.84v-7.976c-1.13-.559-2.8-.996-5-1.36-2.2-.351-4.18-.527-5.94-.527-13.33 0-19.99 7.012-19.99 21.055V91.71h-9.86v5.027l9.86 4.336 4.4 14.707h6.04V99.805H1855V91.71h-19.98V51.16c0-4.15.98-7.333 2.95-9.56 1.97-2.206 4.68-3.331 8.1-3.331M1894.26 92.324c-5.53 0-9.94-1.797-13.22-5.39-3.31-3.614-5.25-8.594-5.83-14.97h36.01c0 6.583-1.45 11.622-4.38 15.126-2.95 3.496-7.13 5.234-12.58 5.234zm2.83-62.656c-10.19 0-18.22 3.086-24.1 9.297-5.9 6.21-8.84 14.824-8.84 25.84 0 11.101 2.73 19.922 8.2 26.464 5.47 6.524 12.81 9.805 22.03 9.805 8.63 0 15.46-2.851 20.49-8.523 5.03-5.676 7.55-13.157 7.55-22.461v-6.613h-47.46c.22-8.086 2.26-14.22 6.13-18.418 3.87-4.18 9.33-6.29 16.37-6.29 7.42 0 14.75 1.563 22 4.669V34.14c-3.7-1.602-7.17-2.746-10.47-3.438-3.28-.684-7.25-1.035-11.9-1.035M1983.36 49.727c0-6.426-2.4-11.368-7.18-14.844-4.77-3.477-11.47-5.215-20.11-5.215-9.13 0-16.26 1.445-21.37 4.336v9.687a51.32 51.32 0 0 1 10.65-3.964c3.79-.977 7.45-1.457 10.97-1.457 5.46 0 9.64.87 12.57 2.609 2.95 1.738 4.41 4.394 4.41 7.95 0 2.694-1.17 4.98-3.5 6.894-2.32 1.914-6.85 4.152-13.6 6.757-6.41 2.383-10.97 4.473-13.67 6.25-2.71 1.778-4.72 3.81-6.04 6.067-1.31 2.254-1.98 4.96-1.98 8.113 0 5.606 2.29 10.04 6.86 13.281 4.57 3.25 10.84 4.883 18.79 4.883 7.42 0 14.66-1.515 21.74-4.531l-3.71-8.496c-6.9 2.851-13.17 4.277-18.79 4.277-4.94 0-8.67-.77-11.18-2.324-2.52-1.543-3.78-3.691-3.78-6.406 0-1.844.48-3.418 1.42-4.707.95-1.309 2.46-2.54 4.56-3.711 2.09-1.184 6.11-2.871 12.07-5.086 8.16-2.98 13.69-5.98 16.55-8.996 2.87-3.02 4.32-6.809 4.32-11.367M2021.28 38.27c1.85 0 3.64.136 5.35.421 1.71.274 3.09.547 4.09.84v-7.976c-1.14-.559-2.81-.996-5.01-1.36-2.18-.351-4.18-.527-5.93-.527-13.33 0-19.99 7.012-19.99 21.055V91.71h-9.87v5.027l9.87 4.336 4.4 14.707h6.02V99.805h20V91.71h-20V51.16c0-4.15 1-7.333 2.97-9.56 1.98-2.206 4.67-3.331 8.1-3.331M2053.61 30.918h-10.42v68.887h10.42zm-11.31 87.559c0 2.39.59 4.14 1.76 5.253 1.18 1.106 2.65 1.661 4.42 1.661 1.67 0 3.1-.567 4.32-1.7 1.22-1.132 1.82-2.871 1.82-5.214 0-2.344-.6-4.09-1.82-5.247-1.22-1.16-2.65-1.726-4.32-1.726-1.77 0-3.24.566-4.42 1.726-1.17 1.157-1.76 2.903-1.76 5.247M2121.59 30.918v44.57c0 5.606-1.27 9.805-3.83 12.559-2.55 2.773-6.55 4.16-12 4.16-7.21 0-12.49-1.953-15.84-5.851-3.35-3.895-5.03-10.32-5.03-19.286V30.918h-10.43v68.887h8.49l1.69-9.422h.5c2.15 3.387 5.14 6.023 8.99 7.887 3.85 1.867 8.16 2.804 12.88 2.804 8.3 0 14.54-2.011 18.74-6.015 4.19-3.985 6.29-10.391 6.29-19.192V30.918h-10.45M2159.29 77.742c0-4.812 1.35-8.465 4.08-10.926 2.72-2.48 6.51-3.71 11.37-3.71 10.19 0 15.28 4.953 15.28 14.831 0 10.344-5.16 15.532-15.47 15.532-4.9 0-8.67-1.32-11.31-3.965-2.63-2.649-3.95-6.555-3.95-11.762zm-5.67-58.387c0-3.73 1.58-6.55 4.72-8.488 3.14-1.922 7.65-2.879 13.52-2.879 8.75 0 15.24 1.309 19.45 3.926 4.21 2.617 6.31 6.172 6.31 10.652 0 3.723-1.15 6.32-3.45 7.754-2.31 1.457-6.65 2.168-13.01 2.168h-12.51c-4.74 0-8.43-1.12-11.06-3.386-2.65-2.266-3.97-5.508-3.97-9.747zm54.94 80.45v-6.582l-12.76-1.512c1.18-1.477 2.23-3.39 3.15-5.754.91-2.371 1.37-5.039 1.37-8.02 0-6.746-2.29-12.128-6.91-16.152-4.61-4.012-10.93-6.023-18.98-6.023-2.05 0-3.98.156-5.78.5-4.45-2.356-6.67-5.305-6.67-8.871 0-1.883.77-3.282 2.34-4.176 1.54-.902 4.21-1.36 7.97-1.36h12.2c7.46 0 13.19-1.574 17.19-4.707 4-3.144 6-7.714 6-13.71 0-7.618-3.06-13.426-9.17-17.43C2192.38 2.004 2183.46 0 2171.72 0c-9 0-15.95 1.68-20.82 5.027-4.88 3.352-7.34 8.079-7.34 14.211 0 4.18 1.35 7.813 4.03 10.88 2.68 3.046 6.45 5.116 11.32 6.21-1.77.8-3.24 2.031-4.44 3.711-1.19 1.68-1.78 3.633-1.78 5.84 0 2.52.66 4.707 2.01 6.602 1.34 1.882 3.44 3.71 6.34 5.468-3.56 1.465-6.46 3.953-8.71 7.48-2.23 3.516-3.35 7.54-3.35 12.06 0 7.55 2.26 13.37 6.79 17.452 4.52 4.082 10.93 6.133 19.22 6.133 3.6 0 6.86-.429 9.75-1.27h23.82M2284.61 91.71h-17.54V30.919h-10.43v60.793h-12.31v4.707l12.31 3.766v3.839c0 16.922 7.4 25.391 22.19 25.391 3.65 0 7.93-.73 12.82-2.195l-2.7-8.364c-4.03 1.301-7.46 1.946-10.31 1.946-3.93 0-6.85-1.309-8.73-3.926-1.89-2.617-2.84-6.816-2.84-12.598v-4.472h17.54V91.71M2302.87 65.43c0-8.809 1.76-15.508 5.28-20.118 3.52-4.609 8.7-6.906 15.52-6.906 6.84 0 12.02 2.297 15.57 6.875 3.54 4.602 5.3 11.301 5.3 20.149 0 8.75-1.76 15.41-5.3 19.953-3.55 4.539-8.78 6.824-15.69 6.824-6.83 0-11.99-2.246-15.46-6.73-3.48-4.48-5.22-11.16-5.22-20.047zm52.48 0c0-11.23-2.82-20-8.47-26.309-5.67-6.309-13.48-9.453-23.46-9.453-6.15 0-11.62 1.445-16.4 4.336-4.77 2.89-8.47 7.031-11.06 12.45-2.59 5.401-3.9 11.73-3.9 18.976 0 11.23 2.81 19.968 8.43 26.242 5.6 6.258 13.4 9.402 23.38 9.402 9.63 0 17.28-3.222 22.97-9.62 5.68-6.415 8.51-15.087 8.51-26.024M2403.79 101.074c3.07 0 5.8-.254 8.22-.761l-1.43-9.676c-2.86.633-5.37.933-7.55.933-5.58 0-10.33-2.261-14.3-6.785-3.95-4.531-5.94-10.156-5.94-16.902V30.918h-10.43v68.887h8.62l1.19-12.754h.5c2.56 4.48 5.63 7.949 9.23 10.37 3.61 2.423 7.56 3.653 11.89 3.653M2500.33 69.766l-10.68 28.476c-1.39 3.594-2.81 8.028-4.28 13.262-.93-4.024-2.24-8.438-3.96-13.262l-10.81-28.476zm14.77-38.848l-11.44 29.227h-36.83l-11.32-29.227h-10.81l36.34 92.273h8.98l36.13-92.273h-11.05M2583.07 30.918v44.57c0 5.606-1.27 9.805-3.83 12.559-2.55 2.773-6.55 4.16-12 4.16-7.21 0-12.49-1.953-15.84-5.851-3.35-3.895-5.03-10.32-5.03-19.286V30.918h-10.43v68.887h8.48l1.69-9.422h.51c2.14 3.387 5.14 6.023 8.99 7.887 3.84 1.867 8.15 2.804 12.88 2.804 8.3 0 14.54-2.011 18.74-6.015 4.19-3.985 6.29-10.391 6.29-19.192V30.918h-10.45M2620.76 77.742c0-4.812 1.36-8.465 4.08-10.926 2.73-2.48 6.53-3.71 11.37-3.71 10.2 0 15.28 4.953 15.28 14.831 0 10.344-5.15 15.532-15.45 15.532-4.91 0-8.68-1.32-11.32-3.965-2.64-2.649-3.96-6.555-3.96-11.762zm-5.66-58.387c0-3.73 1.57-6.55 4.71-8.488 3.15-1.922 7.65-2.879 13.53-2.879 8.75 0 15.23 1.309 19.44 3.926 4.21 2.617 6.31 6.172 6.31 10.652 0 3.723-1.14 6.32-3.45 7.754-2.31 1.457-6.64 2.168-13 2.168h-12.51c-4.74 0-8.43-1.12-11.07-3.386-2.63-2.266-3.96-5.508-3.96-9.747zm54.94 80.45v-6.582l-12.76-1.512c1.18-1.477 2.22-3.39 3.14-5.754.92-2.371 1.38-5.039 1.38-8.02 0-6.746-2.3-12.128-6.92-16.152-4.61-4.012-10.92-6.023-18.97-6.023-2.05 0-3.99.156-5.78.5-4.46-2.356-6.67-5.305-6.67-8.871 0-1.883.78-3.282 2.33-4.176 1.55-.902 4.21-1.36 7.98-1.36h12.2c7.46 0 13.18-1.574 17.18-4.707 4.01-3.144 6-7.714 6-13.71 0-7.618-3.06-13.426-9.17-17.43C2653.87 2.004 2644.94 0 2633.2 0c-9 0-15.95 1.68-20.83 5.027-4.88 3.352-7.33 8.079-7.33 14.211 0 4.18 1.35 7.813 4.02 10.88 2.69 3.046 6.47 5.116 11.32 6.21-1.77.8-3.23 2.031-4.43 3.711-1.19 1.68-1.79 3.633-1.79 5.84 0 2.52.66 4.707 2.01 6.602 1.35 1.882 3.45 3.71 6.35 5.468-3.56 1.465-6.47 3.953-8.71 7.48-2.23 3.516-3.35 7.54-3.35 12.06 0 7.55 2.25 13.37 6.79 17.452 4.52 4.082 10.92 6.133 19.21 6.133 3.62 0 6.86-.429 9.75-1.27h23.83M2692.7 99.805V55.117c0-5.605 1.27-9.805 3.83-12.566 2.56-2.766 6.57-4.145 12.01-4.145 7.2 0 12.47 1.965 15.81 5.903 3.33 3.945 4.99 10.379 4.99 19.304v36.192h10.44V30.918h-8.62l-1.5 9.25h-.58c-2.13-3.41-5.1-5.988-8.88-7.793-3.8-1.809-8.13-2.707-12.99-2.707-8.37 0-14.65 1.992-18.81 5.977-4.18 3.964-6.26 10.351-6.26 19.101v45.059h10.56M2760.61 30.918h10.43v97.805h-10.43zM2810.67 38.27c6.5 0 11.6 1.789 15.31 5.343 3.71 3.575 5.56 8.555 5.56 14.961v6.23l-10.44-.448c-8.3-.286-14.27-1.583-17.94-3.868-3.66-2.273-5.5-5.82-5.5-10.644 0-3.781 1.14-6.64 3.42-8.613 2.29-1.973 5.48-2.961 9.59-2.961zm23.57-7.352l-2.07 9.805h-.51c-3.44-4.305-6.86-7.227-10.27-8.77-3.42-1.523-7.68-2.285-12.8-2.285-6.83 0-12.17 1.758-16.05 5.273-3.87 3.528-5.81 8.536-5.81 15.032 0 13.906 11.12 21.199 33.37 21.875l11.7.359v4.277c0 5.418-1.17 9.395-3.5 11.985-2.32 2.566-6.03 3.855-11.15 3.855-5.74 0-12.24-1.758-19.49-5.273l-3.21 7.988c3.4 1.836 7.11 3.281 11.16 4.324a47.81 47.81 0 0 0 12.16 1.575c8.23 0 14.3-1.817 18.27-5.461 3.96-3.66 5.93-9.5 5.93-17.54V30.919h-7.73M2893.6 101.074c3.07 0 5.8-.254 8.25-.761l-1.46-9.676c-2.84.633-5.35.933-7.54.933-5.56 0-10.33-2.261-14.3-6.785-3.96-4.531-5.93-10.156-5.93-16.902V30.918h-10.44v68.887h8.61l1.19-12.754h.5c2.57 4.48 5.65 7.949 9.25 10.37 3.6 2.423 7.56 3.653 11.87 3.653M2901.63 6.727c-3.94 0-7.04.558-9.31 1.691v9.121c2.97-.84 6.08-1.25 9.31-1.25 4.14 0 7.3 1.25 9.45 3.77 2.16 2.507 3.24 6.132 3.24 10.859v91.895h10.69V31.797c0-7.95-2.01-14.121-6.04-18.496-4.02-4.383-9.8-6.574-17.34-6.574M2999.96 55.371c0-8.086-2.93-14.394-8.8-18.918-5.87-4.52-13.83-6.785-23.88-6.785-10.9 0-19.27 1.406-25.14 4.219v10.3c3.77-1.59 7.88-2.847 12.31-3.765 4.45-.93 8.85-1.399 13.21-1.399 7.12 0 12.49 1.36 16.09 4.063 3.59 2.695 5.4 6.465 5.4 11.277 0 3.196-.63 5.805-1.91 7.832-1.29 2.024-3.42 3.907-6.42 5.625-2.99 1.711-7.56 3.664-13.67 5.84-8.55 3.059-14.66 6.692-18.32 10.871-3.66 4.2-5.51 9.668-5.51 16.407 0 7.089 2.68 12.714 7.99 16.914 5.32 4.191 12.36 6.289 21.12 6.289 9.13 0 17.54-1.68 25.2-5.032l-3.32-9.304c-7.59 3.183-14.96 4.785-22.13 4.785-5.66 0-10.07-1.223-13.26-3.652-3.19-2.43-4.78-5.809-4.78-10.118 0-3.191.59-5.8 1.76-7.832 1.17-2.031 3.14-3.886 5.95-5.597 2.78-1.688 7.04-3.563 12.79-5.625 9.63-3.426 16.26-7.118 19.89-11.063 3.62-3.937 5.43-9.043 5.43-15.332M741.648 375.406h30c28.965 0 50.227 5.039 63.774 15.117 13.531 10.079 20.32 25.821 20.32 47.247 0 19.832-6.074 34.628-18.191 44.402-12.141 9.758-31.028 14.641-56.692 14.641h-39.211zm172.192 64.246c0-36.062-11.809-63.691-35.434-82.898-23.621-19.219-57.234-28.82-100.847-28.82h-35.911V198.73h-56.445v345.329h99.438c43.14 0 75.457-8.829 96.961-26.465 21.496-17.637 32.238-43.614 32.238-77.942M1099.26 464.691c11.17 0 20.39-.789 27.63-2.371l-5.43-51.718c-7.88 1.894-16.07 2.832-24.57 2.832-22.2 0-40.19-7.246-53.97-21.731-13.78-14.48-20.66-33.301-20.66-56.453V198.73h-55.514v261.227h43.464l7.32-46.055h2.83c8.66 15.594 19.96 27.95 33.9 37.09 13.93 9.141 28.93 13.699 45 13.699M1206.88 329.82c0-60.308 22.28-90.465 66.85-90.465 44.08 0 66.13 30.157 66.13 90.465 0 59.688-22.21 89.512-66.61 89.512-23.31 0-40.2-7.707-50.67-23.144-10.47-15.43-15.7-37.54-15.7-66.368zm190.13 0c0-42.672-10.95-75.972-32.83-99.898-21.89-23.945-52.35-35.918-91.41-35.918-24.41 0-45.97 5.508-64.7 16.543-18.75 11.016-33.16 26.836-43.23 47.48-10.08 20.625-15.11 44.551-15.11 71.793 0 42.364 10.86 75.43 32.58 99.2 21.73 23.777 52.36 35.671 91.89 35.671 37.79 0 67.7-12.156 89.75-36.492 22.05-24.328 33.06-57.121 33.06-98.379M1558.11 238.887c13.54 0 27.07 2.129 40.62 6.386v-41.816c-6.13-2.676-14.05-4.922-23.73-6.738-9.69-1.797-19.73-2.715-30.12-2.715-52.59 0-78.88 27.715-78.88 83.144v140.778h-35.68v24.558l38.26 20.325 18.9 55.261h34.26v-58.113h74.39v-42.031h-74.39v-139.84c0-13.379 3.34-23.242 10.03-29.629 6.69-6.387 15.48-9.57 26.34-9.57M1783.44 464.691c11.17 0 20.38-.789 27.62-2.371l-5.43-51.718c-7.88 1.894-16.06 2.832-24.56 2.832-22.2 0-40.2-7.246-53.97-21.731-13.78-14.48-20.66-33.301-20.66-56.453V198.73h-55.52v261.227h43.46l7.34-46.055h2.82c8.66 15.594 19.95 27.95 33.9 37.09 13.92 9.141 28.93 13.699 45 13.699M1925.05 236.523c20.15 0 36.32 5.625 48.52 16.895 12.21 11.25 18.31 27.051 18.31 47.344v22.676l-33.54-1.407c-26.13-.937-45.16-5.312-57.04-13.105-11.89-7.793-17.82-19.727-17.82-35.781 0-11.661 3.45-20.665 10.39-27.051 6.91-6.387 17.32-9.571 31.18-9.571zm82.66-37.793l-11.11 36.387h-1.87c-12.62-15.918-25.29-26.738-38.04-32.48-12.74-5.742-29.13-8.633-49.13-8.633-25.67 0-45.7 6.934-60.1 20.801-14.41 13.847-21.62 33.457-21.62 58.808 0 26.934 10 47.246 30 60.934 19.99 13.691 50.45 21.172 91.41 22.441l45.09 1.414v13.938c0 16.699-3.88 29.16-11.68 37.441-7.79 8.262-19.88 12.383-36.25 12.383-13.39 0-26.23-1.953-38.5-5.891a294.638 294.638 0 0 1-35.44-13.933l-17.94 39.668c14.17 7.41 29.68 13.035 46.52 16.894 16.85 3.868 32.77 5.789 47.72 5.789 33.22 0 58.31-7.246 75.22-21.726 16.94-14.492 25.4-37.246 25.4-68.262V198.73h-39.68M2220.04 194.004c-39.52 0-69.55 11.543-90.1 34.609-20.55 23.067-30.82 56.172-30.82 99.321 0 43.925 10.74 77.707 32.23 101.339 21.5 23.614 52.56 35.418 93.18 35.418 27.56 0 52.35-5.117 74.41-15.359l-16.78-44.641c-23.46 9.133-42.82 13.704-58.1 13.704-45.19 0-67.79-29.993-67.79-89.981 0-29.293 5.63-51.305 16.89-66.031 11.26-14.707 27.76-22.09 49.48-22.09 24.72 0 48.11 6.152 70.15 18.437v-48.417c-9.92-5.84-20.5-10-31.76-12.52-11.26-2.52-24.93-3.789-40.99-3.789M2451.52 238.887c13.54 0 27.08 2.129 40.63 6.386v-41.816c-6.15-2.676-14.05-4.922-23.73-6.738-9.69-1.797-19.73-2.715-30.12-2.715-52.6 0-78.9 27.715-78.9 83.144v140.778h-35.66v24.558l38.26 20.325 18.9 55.261h34.26v-58.113h74.39v-42.031h-74.39v-139.84c0-13.379 3.34-23.242 10.03-29.629 6.69-6.387 15.47-9.57 26.33-9.57M2585.92 329.82c0-60.308 22.28-90.465 66.84-90.465 44.09 0 66.15 30.157 66.15 90.465 0 59.688-22.22 89.512-66.62 89.512-23.31 0-40.2-7.707-50.67-23.144-10.47-15.43-15.7-37.54-15.7-66.368zm190.13 0c0-42.672-10.94-75.972-32.83-99.898-21.89-23.945-52.36-35.918-91.4-35.918-24.42 0-45.98 5.508-64.72 16.543-18.74 11.016-33.14 26.836-43.22 47.48-10.07 20.625-15.12 44.551-15.12 71.793 0 42.364 10.87 75.43 32.59 99.2 21.74 23.777 52.36 35.671 91.89 35.671 37.79 0 67.7-12.156 89.75-36.492 22.04-24.328 33.06-57.121 33.06-98.379M2972.33 464.691c11.18 0 20.38-.789 27.63-2.371l-5.43-51.718c-7.87 1.894-16.05 2.832-24.57 2.832-22.2 0-40.19-7.246-53.96-21.731-13.78-14.48-20.67-33.301-20.67-56.453V198.73h-55.51v261.227h43.46l7.33-46.055h2.83c8.66 15.594 19.96 27.95 33.89 37.09 13.94 9.141 28.94 13.699 45 13.699" fill="#100f0d"/><path d="M610.11 372.83c0-170.584-138.257-308.862-308.846-308.862-170.602 0-308.846 138.278-308.846 308.863 0 170.576 138.244 308.846 308.846 308.846 170.59 0 308.846-138.27 308.846-308.846" fill="#e53935" stroke-width="1.029"/><path d="M460.694 521.792l-105.04.958-61.415 61.415-72.096-47.883 12.445-12.438-29.207.26-99.129-166.817H67.357l24.39-24.402-24.57-41.363L294.66 64.049c2.192-.04 4.399-.08 6.603-.08 170.416 0 308.585 138.055 308.846 308.408L460.694 521.792" fill="#d51c2f" stroke-width="1.029"/><path d="M149.093 350.258c0 84.048 68.13 152.151 152.171 152.151 84.028 0 152.139-68.103 152.139-152.151zm342.063-7.017v14.046h44.015c-1.75 59.337-25.556 113.104-63.54 153.419L438.75 477.81l-9.925 9.94 32.875 32.887c-40.314 37.983-94.081 61.79-153.41 63.527l-.015-44.003h-14.035v44.003c-59.34-1.737-113.096-25.556-153.41-63.527l32.887-32.887-9.945-9.92-32.883 32.875c-37.975-40.315-61.781-94.082-63.53-153.419h44.002l-.008-14.034H67.176v-51.511h468.176v51.5h-44.196" fill="#f5f5f5" stroke-width="1.029"/></g></g></symbol><symbol id="pug" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#c1272d}.hyst1{fill:#efcca3}.st2{fill:#ed1c24}.hyst3{fill:#ccac8d}.hyst4{fill:#fff}.st5{fill:#ff931e}.st6{fill:#ffb81e}.hyst7{fill:#56332b}.hyst8{fill:#442823}.hyst9{fill:#7f4a41}.hyst10{fill:#331712}.st11{fill:#fc6}.st12{fill:#ccc}.st13{fill:#b3b3b3}.st14{fill:#989898}.st15{fill:#323232}.st16{fill:#1e1e1e}.st17{fill:#4c4c4c}.st18{fill:#e6e6e6}.st19{fill:#606060}</style><path class="hyst1" d="M107.4 50.9c-.2-4.4.4-8.3-1.6-11.6-4.8-8.2-16.8-13-40.8-13v.7h-.5.5v-.7c-24 0-36.6 4.8-41.4 13.1-1.9 3.4-1.7 7.2-2 11.6-.2 3.5-1.8 7.2-1.1 11.2.8 5.2 1.1 10.4 1.9 15.2.6 3.9 6 7.2 6.5 10.9 1.4 10.2 12 14.9 36 14.9v.8h-.6.7v-.8c24 0 34.2-4.7 35.5-14.9.5-3.8 5.5-7 6.1-10.9.8-4.8 1.1-10 1.9-15.2.7-4-.9-7.8-1.1-11.3z"/><path class="hyst3" d="M64.6 54.5c4.3.1 7.3 2.8 10.1 5.3 3.3 2.9 8.9 4.9 11.2 7.4 2.3 2.5 5.3 5 6.4 8.9 1.1 3.9 1.4 8.9 1.4 10.2 0 1.3.7 1 2.7 0 4.7-2.3 9.9-8.5 9.9-8.5-.6 3.9-5.7 7.4-6.2 11.1C98.9 99.1 89 104 64.5 104h-.1.6"/><path class="hyst3" d="M80.4 46.7c.9 3.1 4.1 13.6-2.1 10.1 0 0 2.6 1.5 4.2 7.2 1.7 5.7 5.8 6.4 5.8 6.4s6.7 1.3 11.7-3c4.2-3.6 4.9-10 3.1-14.9-1.8-4.8-5-6.3-9.7-7.3-4.7-1.1-14.1-2-13 1.5z"/><circle cx="92.3" cy="58.1" r="8.8"/><circle class="hyst4" cx="90" cy="54.2" r="2.3"/><path class="hyst1" d="M78.9 57.7s7.9 5.4 12.2 10.7c4.3 5.3 4.2 6.3 4.2 6.3l-3.1 1.4s-4.4-8.3-9.8-11.4c-5.5-3.1-6.1-5.7-6.1-5.7l2.6-1.3z"/><path class="hyst3" d="M64.9 54.5c-4.3.1-7.5 2.8-10.4 5.3-3.3 2.9-9.1 4.9-11.4 7.4-2.3 2.5-5.4 5-6.5 8.9-1.1 3.9-1.5 8.9-1.5 10.2 0 1.3.2 1.4-2.7 0-4.7-2.2-9.9-8.5-9.9-8.5.6 3.9 5.7 7.4 6.2 11.1C30.1 99.1 40 104 64.5 104h.5"/><path class="hyst7" d="M88.1 71.4C83.3 65.5 75.6 60 64.9 60h-.1c-10.7 0-18.4 5.5-23.2 11.4-5 6.1-4.6 8.5-4.6 14.3 0 21 7.4 15 12.3 17.6 5 2.5 10.2 1.7 15.5 1.7h.1c5.4 0 10.5.7 15.5-1.8 4.9-2.5 12.3 3.7 12.3-17.3.1-5.8.4-8.4-4.6-14.5z"/><path class="hyst8" d="M64.4 65.2s-.7 9.7-2.1 11.6l2.6-.6-.5-11z"/><path class="hyst8" d="M65.1 65.2s.7 9.7 2.1 11.6l-2.6-.6.5-11z"/><path class="hyst7" d="M56.7 62.9c-1-2.3 2.6-6 8.3-6.1 5.7 0 9.3 3.7 8.3 6.1-1 2.4-4.6 3.1-8.3 3.2-3.6-.1-7.3-.8-8.3-3.2z"/><path d="M65 65.2c0-.4 3.4-.5 5.2-1.7 0 0-3.7 1.2-4.5.7-.8-.4-1-1.6-1-1.6s-.3 1.2-.9 1.6c-.7.4-4.9-.7-4.9-.7s5.6 1.4 5.6 1.7c0 .3-.1 1.3-.1 2 0 2.5 0 8.7.4 9.2.6.9.4-6.7.4-9.2-.1-.8-.1-1.6-.2-2z"/><path class="hyst9" d="M65.2 78.6c1.7 0 4.7 1.2 7.4 3.1-2.6-2.9-5.7-4.9-7.4-4.9-1.8 0-5.6 2.2-8.3 5.4 2.8-2.2 6.4-3.6 8.3-3.6z"/><path class="hyst8" d="M64.5 96.3c-3.8 0-7.5-1.2-10.9-2.1-.7-.2-1.4.3-2.1.1-6.3-2-11.4-5.4-14.5-9.7v1c0 21 7.4 15.1 12.3 17.6 5 2.5 10.2 1.7 15.5 1.7h.1c5.4 0 10.5.7 15.5-1.8 4.9-2.5 12.3 3.6 12.3-17.4 0-.8 0-1.6.1-2.3-2.9 4.7-8.2 8.4-14.8 10.6-.6.2-2-.3-2.6-.2-3.6 1.2-6.8 2.5-10.9 2.5z"/><path class="hyst8" d="M55 85s-2.5 7.5-.8 10.8l-2.3-1s1.7-7.6 3.1-9.8zM74.8 85s2.5 7.5.8 10.8l2.3-1s-1.8-7.6-3.1-9.8z"/><path class="hyst3" d="M48.6 46.7c-.9 3.1-4.1 13.6 2.1 10.1 0 0-2.6 1.5-4.2 7.2s-5.8 6.4-5.8 6.4-6.7 1.3-11.7-3c-4.2-3.6-4.9-10-3.1-14.9s5-6.3 9.7-7.3c4.7-1.1 14-2 13 1.5z"/><path d="M64.9 76.8c2.7 0 11.1 5.8 11.2 12.9v-.4c0-7.4-6.8-13.3-11.2-13.3-4.4 0-11.2 6-11.2 13.3v.4c.1-7.1 8.5-12.9 11.2-12.9z"/><ellipse transform="rotate(-14.465 66.712 61.468)" class="hyst10" cx="66.7" cy="61.5" rx=".8" ry="1.5"/><ellipse transform="rotate(17.235 62.371 61.462)" class="hyst10" cx="62.4" cy="61.5" rx=".8" ry="1.5"/><circle cx="37.2" cy="58.1" r="8.8"/><circle class="hyst4" cx="39.5" cy="54.2" r="2.3"/><path class="hyst9" d="M67.5 58.2c0-.1-2.3 1-2.9 1.1-.6-.1-2.9-1.2-2.9-1.1h5.8z"/><path class="hyst1" d="M50 57.7s-7.9 5.4-12.2 10.7c-4.3 5.3-4.2 6.3-4.2 6.3l3.1 1.4s4.4-8.3 9.8-11.4 6.1-5.7 6.1-5.7L50 57.7z"/><path class="hyst3" d="M32.7 41.7S30 49.1 24 52.2c0 0 9.4-1.1 8.7-10.5zM95.8 41.7s2.7 7.4 8.7 10.5c0 0-9.4-1.1-8.7-10.5zM78.7 55.5s-5.9-6.2-13.8-6.4h.1.1c-8 .2-13.8 6.4-13.8 6.4 6.9-4.8 12.8-4.7 13.8-4.7-.1 0 6.7-.1 13.6 4.7zM71.8 42.5s-3-4.2-7-4.3h.2c-3 .1-6.9 4.3-6.9 4.3 3.4-3.3 6.9-3.2 6.9-3.2s3.3-.1 6.8 3.2zM37.2 73.2s-4.7 2.3-8.1.9H29c-3-1.7-4.5-6.8-4.5-6.8s3 9 12.7 5.9zM92 73.2s4.7 2.3 8.1.9c4-1.7 4.6-6.8 4.6-6.8s-3 9-12.7 5.9z"/><path class="hyst3" d="M42.6 41.2c2.6-.5 6.9-.6 10.3.5 4.3 1.5.8 7 1.7 7.3.9.3 2.1-3.8 10.1-3.4 8.1.4 9 4 10.1 3.4s-1.1-10 11-7.8c0 0-12.7-3.4-12.1 5.8 0 0-7.3-5.6-17.5-.6.1 0 2.7-8.6-13.6-5.2zM86.9 41.2c.2 0 .3.1.4.1.1 0-.1-.1-.4-.1zM86.9 41.2zM39.1 28.9S28.3 42.5 26.7 47.7c-1.6 5.3-2.8 27-4.2 30.1l-5-21.4 9.2-22.3 12.4-5.2zM89.9 28.9s10.8 13.6 12.4 18.8c1.6 5.3 2.8 27 4.2 30.1l5-21.4-9.2-22.3-12.4-5.2z"/><path class="hyst7" d="M89.4 28.9s11.6 9.7 15 20.9c3.4 11.2 2 24.8 4.6 26.5 3.7 2.4 7.9-11.9 9.3-13.4 2.2-2.4 9.5-8.5 10-9.6.5-1.1-14.8-17.8-21.5-21.1-8.1-3.8-18.1-4.1-17.4-3.3z"/><path class="hyst8" d="M99.3 34.9s13.7 17.5 13.5 39.3l5.5-11.2c-.1 0-4.9-14.3-19-28.1z"/><path class="hyst7" d="M39.1 28.9s-11.6 9.7-15 20.9-2 24.8-4.6 26.5c-3.7 2.4-7.9-11.9-9.3-13.4C8 60.5.7 54.4.2 53.3-.3 52.2 15 35.5 21.7 32.2c8.1-3.8 18.1-4.1 17.4-3.3z"/><path class="hyst8" d="M29.2 34.9S15.5 52.4 15.7 74.2L10.3 63s4.8-14.3 18.9-28.1z"/><path class="hyst3" d="M21.8 74.6s1 5.4 2.6 7.1.5-1.3.5-1.3-1.7-.9-1.4-7.8-1.7 2-1.7 2zM107.1 74.6s-1 5.4-2.6 7.1-.5-1.3-.5-1.3 1.7-.9 1.4-7.8 1.7 2 1.7 2z"/><g><circle class="hyst8" cx="54.5" cy="70.5" r=".8"/><circle class="hyst8" cx="49.9" cy="75.3" r=".8"/><circle class="hyst8" cx="48.4" cy="70.5" r=".8"/></g><g><circle class="hyst8" cx="74" cy="70.5" r=".8"/><circle class="hyst8" cx="78.6" cy="75.3" r=".8"/><circle class="hyst8" cx="80.1" cy="70.5" r=".8"/></g></symbol><symbol viewBox="0 0 50 50" id="puppet" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -247)" fill="#fbc02d"><path stroke-width=".283" d="M11.559 249.467h13.587v13.587H11.559zM27.435 265.056h13.587v13.587H27.435zM11.559 281.074h13.587v13.587H11.559z"/><path stroke-width=".256" d="M16.62 251.615l18.305 18.305-3.236 3.236-18.305-18.305z"/><path stroke-width=".256" d="M37.834 271.331L19.53 289.636l-3.237-3.237 18.305-18.304z"/></g></symbol><symbol viewBox="0 0 100 99.999997" id="purescript" xmlns="http://www.w3.org/2000/svg"><path clip-path="url(#SVGID_2_)" d="M98.079 38.548L79.22 19.68l-5.087 5.088L90.447 41.09 74.134 57.41l5.087 5.087 18.858-18.86a3.59 3.59 0 0 0 1.055-2.55 3.578 3.578 0 0 0-1.055-2.54M25.483 42.794l-5.09-5.089L1.53 56.568a3.566 3.566 0 0 0-1.05 2.545c0 .961.373 1.863 1.05 2.542L20.394 80.52l5.089-5.086L9.162 59.113z" fill="#42a5f5" stroke-width="1.192"/><path clip-path="url(#SVGID_2_)" transform="matrix(1.19175 0 0 1.19175 -306.84 -629.047)" fill="#42a5f5" d="M281.841 551.736l6.461 6.037h28.379l-6.461-6.037zM288.302 566.861l-6.463 6.035h28.381l6.463-6.035zM281.838 581.982l6.464 6.035h28.381l-6.463-6.035z"/></symbol><symbol viewBox="0 0 24 24" id="python" xmlns="http://www.w3.org/2000/svg"><path d="M19.14 7.5A2.86 2.86 0 0 1 22 10.36v3.78A2.86 2.86 0 0 1 19.14 17H12c0 .39.32.96.71.96H17v1.68a2.86 2.86 0 0 1-2.86 2.86H9.86A2.86 2.86 0 0 1 7 19.64v-3.75a2.85 2.85 0 0 1 2.86-2.85h5.25a2.85 2.85 0 0 0 2.85-2.86V7.5h1.18m-4.28 11.79c-.4 0-.72.3-.72.89 0 .59.32.71.72.71a.71.71 0 0 0 .71-.71c0-.59-.32-.89-.71-.89m-10-1.79A2.86 2.86 0 0 1 2 14.64v-3.78A2.86 2.86 0 0 1 4.86 8H12c0-.39-.32-.96-.71-.96H7V5.36A2.86 2.86 0 0 1 9.86 2.5h4.28A2.86 2.86 0 0 1 17 5.36v3.75a2.85 2.85 0 0 1-2.86 2.85H8.89a2.85 2.85 0 0 0-2.85 2.86v2.68H4.86M9.14 5.71c.4 0 .72-.3.72-.89 0-.59-.32-.71-.72-.71-.39 0-.71.12-.71.71s.32.89.71.89z"/><path d="M9.264 22.379c-.895-.24-1.581-.799-1.947-1.582-.228-.489-.237-.606-.238-2.957-.001-2.745.057-3.074.666-3.785.193-.226.568-.517.833-.648.47-.23.579-.239 3.839-.288 3.131-.048 3.386-.065 3.814-.264.626-.291 1.07-.687 1.4-1.247.27-.46.278-.522.311-2.29l.034-1.82.932.051c1.075.058 1.504.211 2.098.748.853.77.869.841.869 3.957 0 2.434-.02 2.783-.18 3.075a3.365 3.365 0 0 1-1.337 1.33l-.517.273-3.95.031-3.951.031.068.274c.037.151.164.377.282.503.209.224.262.229 2.433.229h2.22v1.05c0 1.653-.394 2.437-1.54 3.072l-.545.302-2.644.018c-1.455.01-2.782-.018-2.95-.063zm6.12-1.692c.22-.222.253-.325.206-.675-.07-.523-.278-.73-.732-.73-.467 0-.672.217-.735.78-.042.372-.012.496.163.672.3.3.77.28 1.097-.047z" fill="#fc0" stroke="#fc0" stroke-width=".102"/><path d="M9.349 22.38c-.911-.15-1.936-1.074-2.176-1.963-.073-.273-.101-1.279-.079-2.868.033-2.317.047-2.473.27-2.926.13-.263.401-.623.603-.8.674-.592.87-.63 3.484-.675 4.399-.076 4.927-.166 5.705-.967.642-.662.706-.9.774-2.883l.061-1.784.951.055c.523.031 1.11.122 1.304.204.54.225 1.358 1.042 1.472 1.47.153.572.243 3.18.16 4.617-.071 1.23-.093 1.327-.395 1.78-.193.288-.577.647-.966.903l-.647.425-3.922.008c-2.157.004-3.942.028-3.966.052-.115.115.354.82.587.883.14.038 1.181.073 2.314.079l2.06.01v.91c0 1.739-.326 2.446-1.454 3.162l-.631.4-2.543-.011c-1.398-.007-2.733-.043-2.966-.081zm5.98-1.718c.285-.256.313-.328.251-.658-.09-.483-.301-.682-.722-.682-.436 0-.625.193-.715.73-.065.384-.044.453.2.663.358.308.595.295.985-.053z" fill="#fdd835" stroke-width=".102"/><path d="M4.281 17.396c-.88-.215-1.714-.935-2.024-1.747-.149-.389-.168-.804-.142-3.041.027-2.26.054-2.638.215-2.962.259-.519.851-1.092 1.392-1.346.437-.206.632-.217 4.408-.245l3.95-.03-.067-.275a1.367 1.367 0 0 0-.282-.504c-.21-.224-.263-.23-2.433-.23h-2.22l.002-1.143c.003-1.338.157-1.795.84-2.493.746-.763 1.103-.838 4.025-.838 2.961 0 3.28.06 4.067.768.37.333.572.621.728 1.037.201.539.213.735.183 3.072-.035 2.777-.045 2.824-.78 3.598-.787.829-.76.824-4.59.883-3.812.06-3.797.057-4.61.806-.765.706-.917 1.2-.964 3.133l-.04 1.653-.677-.01c-.371-.007-.813-.045-.98-.086zM9.59 5.551c.237-.204.286-.326.286-.72 0-.547-.201-.763-.71-.763-.502 0-.765.248-.765.724 0 .492.141.782.439.902.345.14.444.12.75-.143z" fill="#3c78aa"/></symbol><symbol viewBox="0 0 24 24" id="r" xmlns="http://www.w3.org/2000/svg"><path d="M11.956 4.05c-5.694 0-10.354 3.106-10.354 6.947 0 3.396 3.686 6.212 8.531 6.813v2.205h3.53V17.82c.88-.093 1.699-.259 2.475-.497l1.43 2.692h3.996l-2.402-4.048c1.936-1.263 3.147-3.034 3.147-4.97 0-3.841-4.659-6.947-10.354-6.947m1.584 2.712c4.349 0 7.558 1.45 7.558 4.753 0 1.77-.952 3.013-2.505 3.779a1.081 1.081 0 0 1-.228-.156c-.373-.165-.994-.352-.994-.352s3.085-.227 3.085-3.302-3.23-3.127-3.23-3.127h-7.092v7.413c-2.64-.766-4.462-2.392-4.462-4.255 0-2.63 3.52-4.753 7.868-4.753m.156 4.12h2.143s.983-.05.983.974c0 1.004-.983 1.004-.983 1.004h-2.143v-1.977m-.031 4.566h.952c.186 0 .28.052.445.207.135.103.28.3.404.476-.57.073-1.17.104-1.801.104z" fill="#1976d2" stroke-width="1.035"/></symbol><symbol viewBox="0 0 24 24" id="raml" xmlns="http://www.w3.org/2000/svg"><path d="M5 3h2v2H5v5a2 2 0 0 1-2 2 2 2 0 0 1 2 2v5h2v2H5c-1.07-.27-2-.9-2-2v-4a2 2 0 0 0-2-2H0v-2h1a2 2 0 0 0 2-2V5a2 2 0 0 1 2-2m14 0a2 2 0 0 1 2 2v4a2 2 0 0 0 2 2h1v2h-1a2 2 0 0 0-2 2v4a2 2 0 0 1-2 2h-2v-2h2v-5a2 2 0 0 1 2-2 2 2 0 0 1-2-2V5h-2V3h2m-7 12a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m-4 0a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m8 0a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="razor" xmlns="http://www.w3.org/2000/svg"><path d="M15.45 11.91c-.11-2.21-1.75-3.54-3.73-3.54h-.08c-2.29 0-3.55 1.8-3.55 3.84 0 2.29 1.53 3.74 3.54 3.74 2.25 0 3.72-1.65 3.83-3.59m-3.81-5.97c1.53 0 2.97.68 4.02 1.74 0-.51.33-.89.83-.89h.11c.74 0 .89.7.89.92v7.9c-.04.52.54.78.87.44 1.27-1.29 2.78-6.69-.79-9.81-3.33-2.92-7.8-2.44-10.18-.8-2.52 1.74-4.14 5.61-2.57 9.22 1.71 3.95 6.61 5.13 9.52 3.95 1.48-.59 2.15 1.4.65 2.05-2.34.99-8.77.89-11.78-4.32-2.03-3.52-1.93-9.71 3.46-12.92C10.81 1.42 16.24 2.1 19.5 5.5c3.45 3.6 3.25 10.3-.1 12.91-1.51 1.18-3.76.03-3.74-1.7l-.02-.56a5.611 5.611 0 0 1-3.99 1.66C8.63 17.81 6 15.15 6 12.13c0-3.05 2.63-5.74 5.65-5.74z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="react" xmlns="http://www.w3.org/2000/svg"><path d="M12 10.11c1.03 0 1.87.84 1.87 1.89 0 1-.84 1.85-1.87 1.85-1.03 0-1.87-.85-1.87-1.85 0-1.05.84-1.89 1.87-1.89M7.37 20c.63.38 2.01-.2 3.6-1.7-.52-.59-1.03-1.23-1.51-1.9a22.7 22.7 0 0 1-2.4-.36c-.51 2.14-.32 3.61.31 3.96m.71-5.74l-.29-.51c-.11.29-.22.58-.29.86.27.06.57.11.88.16l-.3-.51m6.54-.76l.81-1.5-.81-1.5c-.3-.53-.62-1-.91-1.47C13.17 9 12.6 9 12 9c-.6 0-1.17 0-1.71.03-.29.47-.61.94-.91 1.47L8.57 12l.81 1.5c.3.53.62 1 .91 1.47.54.03 1.11.03 1.71.03.6 0 1.17 0 1.71-.03.29-.47.61-.94.91-1.47M12 6.78c-.19.22-.39.45-.59.72h1.18c-.2-.27-.4-.5-.59-.72m0 10.44c.19-.22.39-.45.59-.72h-1.18c.2.27.4.5.59.72M16.62 4c-.62-.38-2 .2-3.59 1.7.52.59 1.03 1.23 1.51 1.9.82.08 1.63.2 2.4.36.51-2.14.32-3.61-.32-3.96m-.7 5.74l.29.51c.11-.29.22-.58.29-.86-.27-.06-.57-.11-.88-.16l.3.51m1.45-7.05c1.47.84 1.63 3.05 1.01 5.63 2.54.75 4.37 1.99 4.37 3.68 0 1.69-1.83 2.93-4.37 3.68.62 2.58.46 4.79-1.01 5.63-1.46.84-3.45-.12-5.37-1.95-1.92 1.83-3.91 2.79-5.38 1.95-1.46-.84-1.62-3.05-1-5.63-2.54-.75-4.37-1.99-4.37-3.68 0-1.69 1.83-2.93 4.37-3.68-.62-2.58-.46-4.79 1-5.63 1.47-.84 3.46.12 5.38 1.95 1.92-1.83 3.91-2.79 5.37-1.95M17.08 12c.34.75.64 1.5.89 2.26 2.1-.63 3.28-1.53 3.28-2.26 0-.73-1.18-1.63-3.28-2.26-.25.76-.55 1.51-.89 2.26M6.92 12c-.34-.75-.64-1.5-.89-2.26-2.1.63-3.28 1.53-3.28 2.26 0 .73 1.18 1.63 3.28 2.26.25-.76.55-1.51.89-2.26m9 2.26l-.3.51c.31-.05.61-.1.88-.16-.07-.28-.18-.57-.29-.86l-.29.51m-2.89 4.04c1.59 1.5 2.97 2.08 3.59 1.7.64-.35.83-1.82.32-3.96-.77.16-1.58.28-2.4.36-.48.67-.99 1.31-1.51 1.9M8.08 9.74l.3-.51c-.31.05-.61.1-.88.16.07.28.18.57.29.86l.29-.51m2.89-4.04C9.38 4.2 8 3.62 7.37 4c-.63.35-.82 1.82-.31 3.96a22.7 22.7 0 0 1 2.4-.36c.48-.67.99-1.31 1.51-1.9z" fill="#00bcd4"/></symbol><symbol viewBox="0 0 24 24" id="readme" xmlns="http://www.w3.org/2000/svg"><path d="M13 9h-2V7h2m0 10h-2v-6h2m-1-9A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="reason" xmlns="http://www.w3.org/2000/svg"><path d="M3 3v18h18V3H3zm5.119 8.993h2.798c.382 0 .71.025.985.075.275.05.534.159.774.326.244.168.435.386.577.654.145.265.218.598.218 1 0 .552-.112 1.001-.335 1.35-.22.348-.536.638-.947.87l2.16 3.203H12.31l-1.763-2.742h-.77v2.742H8.12v-7.478zm6.594 0h4.676v1.447h-3.018v1.29h2.802v1.447h-2.802v1.848h3.018v1.446h-4.676v-7.478zM9.778 13.37v2.014h.513c.266 0 .49-.014.67-.044.18-.03.329-.1.45-.207a.96.96 0 0 0 .253-.34c.055-.128.082-.297.082-.508 0-.187-.034-.35-.1-.483a.698.698 0 0 0-.343-.317 1.086 1.086 0 0 0-.395-.095 6.012 6.012 0 0 0-.526-.02h-.604z" fill="#f44336" stroke-width="1.067"/></symbol><symbol viewBox="0 0 172 193" id="restql" xmlns="http://www.w3.org/2000/svg"><title>Group</title><g transform="translate(14.767 16.713) scale(.82795)" fill="none"><path d="M171.39 55.799c-.975-6.147-4.673-11.642-10.15-14.805L96.381 3.546C93.217 1.72 89.615.756 85.964.756s-7.253.964-10.415 2.788L10.69 40.992A20.896 20.896 0 0 0 .272 59.035v74.89a20.894 20.894 0 0 0 10.416 18.042l64.859 37.446c3.165 1.827 6.767 2.791 10.417 2.791s7.252-.964 10.415-2.79l64.859-37.445c5.479-3.166 9.178-8.66 10.152-14.808zm-16.516 85.147L90.017 178.39a8.104 8.104 0 0 1-8.108 0l-64.857-37.444a8.109 8.109 0 0 1-4.053-7.021v-74.89a8.109 8.109 0 0 1 4.053-7.021l64.857-37.446c1.254-.725 2.654-1.086 4.054-1.086s2.8.361 4.054 1.086l64.857 37.446a8.106 8.106 0 0 1 4.053 7.021v74.89a8.109 8.109 0 0 1-4.053 7.021z" fill="#83e8c2"/><path d="M158.93 59.035a8.109 8.109 0 0 0-4.053-7.021L90.02 14.568c-1.254-.725-2.654-1.086-4.054-1.086s-2.8.361-4.054 1.086L17.055 52.014a8.106 8.106 0 0 0-4.053 7.021v74.89a8.109 8.109 0 0 0 4.053 7.021l64.857 37.444a8.104 8.104 0 0 0 8.108 0l64.857-37.444a8.109 8.109 0 0 0 4.053-7.021zm-46.766 31.681c.119-.069.242-.118.365-.149.044-.012.088-.01.131-.018.076-.012.152-.029.228-.029l.015.001c.02.001.038.005.059.006.093.005.184.019.273.04l.1.03c.077.025.15.057.223.095.028.014.057.027.084.043.094.057.184.122.263.199.007.008.013.017.021.024.07.071.133.15.188.235.018.029.033.059.05.09.04.072.072.148.099.229a1.512 1.512 0 0 1 .081.46v16.209l-3.278 1.893a1.548 1.548 0 0 0-.678.83 1.533 1.533 0 0 0-.098.514v3.785l-14.038 8.104-.01.004a1.55 1.55 0 0 1-.354.146c-.045.012-.09.011-.135.018-.074.012-.15.029-.225.029l-.014-.001c-.02-.001-.039-.005-.059-.006a1.463 1.463 0 0 1-.273-.041c-.034-.008-.066-.019-.1-.03a1.318 1.318 0 0 1-.223-.094c-.029-.015-.057-.027-.084-.044a1.45 1.45 0 0 1-.263-.198c-.009-.008-.015-.019-.023-.027a1.495 1.495 0 0 1-.185-.232c-.019-.029-.034-.06-.051-.09a1.422 1.422 0 0 1-.098-.229 1.702 1.702 0 0 1-.033-.101 1.487 1.487 0 0 1-.048-.358l-.001-.002v-20.053a1.446 1.446 0 0 1 .727-1.255zM85.24 31.369a1.449 1.449 0 0 1 1.452 0l45.741 26.41a1.45 1.45 0 0 1 0 2.512l-17.366 10.027a1.457 1.457 0 0 1-1.452 0l-15.49-8.943 1.727-.996a1.552 1.552 0 0 0 0-2.688l-13.111-7.57c-.239-.139-.508-.207-.775-.207s-.535.068-.775.207l-3.278 1.893-14.038-8.104a1.451 1.451 0 0 1 0-2.513zM57.59 47.558c.251 0 .501.065.726.194l15.489 8.942-1.727.997a1.552 1.552 0 0 0 0 2.688l1.727.996-15.488 8.943a1.457 1.457 0 0 1-1.452 0L39.499 60.291a1.45 1.45 0 0 1 0-2.512l17.366-10.027c.225-.129.475-.194.725-.194zm-9.56 92.328c-.241 0-.489-.062-.724-.196l-17.365-10.026a1.45 1.45 0 0 1-.726-1.256V75.59c0-.847.694-1.453 1.452-1.453.242 0 .49.062.724.197l17.366 10.025c.449.26.726.738.726 1.257v17.886l-1.727-.997a1.552 1.552 0 0 0-2.327 1.344v15.139c0 .555.295 1.067.775 1.344l3.278 1.894v16.209a1.45 1.45 0 0 1-1.452 1.451zm29.828 14.929a1.452 1.452 0 0 1-2.177 1.257l-17.365-10.026a1.452 1.452 0 0 1-.726-1.257v-17.885l1.726.996c.25.145.515.211.773.211.811 0 1.554-.648 1.554-1.555v-1.993l15.489 8.942c.449.26.726.738.726 1.257zm0-32.768c0 .127-.02.246-.049.36-.009.035-.021.067-.032.101-.026.08-.059.157-.099.229-.017.03-.032.061-.05.09a1.48 1.48 0 0 1-.188.235l-.021.025a1.51 1.51 0 0 1-.264.199c-.026.016-.055.028-.082.043a1.597 1.597 0 0 1-.324.124 1.362 1.362 0 0 1-.278.041c-.018.001-.036.006-.055.006l-.015.001c-.077 0-.155-.018-.233-.03-.043-.007-.084-.005-.125-.017a1.484 1.484 0 0 1-.366-.149l-14.035-8.104v-3.784a1.545 1.545 0 0 0-.776-1.343l-3.276-1.892V91.976c0-.127.02-.246.049-.361.009-.034.021-.066.032-.1a1.33 1.33 0 0 1 .099-.229c.017-.03.032-.062.051-.091.054-.084.116-.163.187-.234l.021-.025c.079-.076.168-.142.263-.199.027-.016.056-.029.084-.043a1.476 1.476 0 0 1 .601-.166c.019 0 .036-.005.055-.005l.015-.001c.078 0 .157.018.236.03.04.007.081.005.122.017.124.031.246.08.366.149l17.361 10.023a1.456 1.456 0 0 1 .726 1.259zm-9.984-45.373a1.448 1.448 0 0 1-.544-.55 1.466 1.466 0 0 1 0-1.413c.121-.219.303-.41.544-.55l14.038-8.104 3.277 1.892c.48.276 1.071.276 1.551 0l3.278-1.893 14.038 8.105a1.45 1.45 0 0 1 0 2.513L86.691 86.7a1.447 1.447 0 0 1-1.452 0zm74.842 51.733c0 .518-.276.997-.726 1.256l-45.741 26.409a1.452 1.452 0 0 1-2.177-1.257v-20.053c0-.519.277-.997.727-1.257l15.488-8.941v1.992c0 .906.743 1.555 1.553 1.555.26 0 .523-.066.774-.21l13.11-7.57a1.55 1.55 0 0 0 .776-1.344v-3.784l14.038-8.105a1.452 1.452 0 0 1 2.177 1.257v20.052zm0-32.764c0 .519-.276.997-.726 1.256l-15.489 8.943v-1.993c0-.906-.744-1.554-1.554-1.554a1.519 1.519 0 0 0-.773.21l-1.727.996V85.616c0-.519.277-.997.727-1.257l17.365-10.025c.234-.135.482-.197.724-.197.758 0 1.453.606 1.453 1.453z" fill="#111d5a"/><g fill="#83e8c2"><path d="M59.402 90.568zM94.485 123.06zM94.771 123.29zM77.775 122.51zM77.072 123.33zM77.418 123.09zM77.856 122.05zM76.749 123.45zM94.119 122.41zM77.131 133.51l-15.489-8.942v1.993c0 .906-.743 1.555-1.554 1.555a1.53 1.53 0 0 1-.773-.211l-1.726-.996v17.885c0 .519.276.997.726 1.257l17.365 10.026a1.452 1.452 0 0 0 2.177-1.257v-20.053a1.454 1.454 0 0 0-.726-1.257zM94.25 122.74zM110.28 111.42zM94.494 100.98c.088-.089.189-.168.303-.232l17.365-10.026-17.365 10.026a1.392 1.392 0 0 0-.303.232zM77.627 122.83zM58.027 90.936zM58.374 90.693zM59.044 90.521l-.015.001c.083-.001.167.015.251.029-.079-.012-.158-.03-.236-.03zM57.819 91.195zM58.696 90.568zM57.589 91.977zM76.043 123.46zM57.67 91.516zM75.677 123.31l-14.035-8.11zM76.401 123.5l.015-.001c-.082.001-.166-.016-.248-.029.078.012.156.03.233.03zM112.16 90.716zM77.662 101.27zM113.64 90.734zM96.237 123.31zM113.33 90.597zM112.89 90.52c-.075 0-.151.018-.228.029.081-.014.162-.029.242-.028l-.014-.001zM141.26 74.137c-.241 0-.489.062-.724.197l-17.365 10.025c-.449.26-.727.738-.727 1.257v17.885l1.727-.996c.25-.145.515-.211.773-.21.81 0 1.554.647 1.554 1.554v1.993l15.489-8.943a1.45 1.45 0 0 0 .726-1.256V75.59c0-.847-.695-1.453-1.453-1.453zM112.96 90.526zM95.523 123.5c.074 0 .15-.018.225-.029-.08.013-.159.028-.238.028l.013.001zM95.451 123.5zM85.238 86.7zM95.078 123.43zM141.26 106.9c-.241 0-.489.062-.724.196l-14.038 8.105v3.784c0 .555-.296 1.067-.776 1.344l-13.11 7.57c-.251.144-.515.21-.774.21-.81 0-1.553-.648-1.553-1.555v-1.992l-15.488 8.941c-.449.26-.727.738-.727 1.257v20.053a1.452 1.452 0 0 0 2.177 1.257l45.741-26.409a1.45 1.45 0 0 0 .726-1.256v-20.053a1.454 1.454 0 0 0-1.454-1.452zM67.871 41.396a1.451 1.451 0 0 0 0 2.513l14.038 8.104 3.278-1.893c.24-.139.508-.207.775-.207s.536.068.775.207l13.111 7.57a1.552 1.552 0 0 1 0 2.688l-1.727.996 15.49 8.943a1.457 1.457 0 0 0 1.452 0l17.366-10.027a1.45 1.45 0 0 0 0-2.512l-45.741-26.41a1.449 1.449 0 0 0-1.452 0zM39.497 57.779a1.45 1.45 0 0 0 0 2.512l17.366 10.027a1.457 1.457 0 0 0 1.452 0l15.488-8.943-1.727-.996a1.552 1.552 0 0 1 0-2.688l1.727-.997-15.489-8.942a1.458 1.458 0 0 0-1.451 0zM49.481 138.43v-16.209l-3.278-1.894a1.55 1.55 0 0 1-.775-1.344v-15.139c0-.906.743-1.555 1.554-1.554.259 0 .523.065.773.21l1.727.997V85.611a1.45 1.45 0 0 0-.726-1.257L31.39 74.33a1.436 1.436 0 0 0-.724-.197c-.758 0-1.452.606-1.452 1.453v52.817c0 .518.276.997.726 1.256l17.365 10.026a1.45 1.45 0 0 0 2.176-1.255zM114.34 108.18l-3.278 1.893 3.278-1.893V91.971zM114.11 91.193zM114.16 91.283z"/></g><g fill="#de5941"><path d="M94.494 100.98a1.45 1.45 0 0 0-.424 1.023v20.053l.001.002c0 .126.02.244.048.358.01.034.021.066.033.101.026.08.059.156.098.229.017.03.032.061.051.09.055.084.115.162.185.232.009.009.015.02.023.027.079.077.169.142.263.198.027.017.055.029.084.044a1.46 1.46 0 0 0 .596.165c.02.001.039.005.059.006.079 0 .158-.016.238-.028.045-.007.09-.006.135-.018.119-.031.238-.08.354-.146l.01-.004 14.038-8.104v-3.785c0-.18.04-.35.098-.514.122-.343.353-.643.678-.83l3.278-1.893V91.977c0-.127-.021-.246-.049-.361-.009-.033-.021-.065-.032-.099a1.266 1.266 0 0 0-.099-.229c-.017-.031-.032-.061-.05-.09a1.425 1.425 0 0 0-.188-.235l-.021-.024a1.41 1.41 0 0 0-.263-.199c-.027-.016-.056-.029-.084-.043a1.509 1.509 0 0 0-.323-.125 1.591 1.591 0 0 0-.273-.04c-.021-.001-.039-.005-.059-.006-.08-.001-.161.015-.242.028-.043.008-.087.006-.131.018-.123.031-.246.08-.365.149l-17.365 10.026a1.447 1.447 0 0 0-.302.233zM77.13 100.74L59.769 90.717a1.424 1.424 0 0 0-.366-.149c-.041-.012-.082-.01-.122-.017-.084-.015-.168-.03-.251-.029-.019 0-.036.005-.055.005-.095.005-.188.02-.278.041-.034.009-.065.02-.099.03a1.406 1.406 0 0 0-.224.095c-.028.014-.057.027-.084.043a1.515 1.515 0 0 0-.263.199l-.021.025c-.07.071-.133.15-.187.234-.019.029-.034.061-.051.091-.04.073-.072.149-.099.229a1.463 1.463 0 0 0-.081.461v16.206l3.276 1.892a1.547 1.547 0 0 1 .776 1.343v3.784l14.035 8.104c.119.068.242.117.366.149.041.012.082.01.125.017.082.014.166.03.248.029.019 0 .037-.005.055-.006.095-.004.188-.019.278-.041.034-.008.065-.019.099-.029.077-.025.152-.058.225-.095.027-.015.056-.027.082-.043.095-.058.185-.123.264-.199l.021-.025c.07-.071.133-.15.188-.235.018-.029.033-.06.05-.09.04-.072.072-.149.099-.229a1.448 1.448 0 0 0 .081-.461v-20.047a1.456 1.456 0 0 0-.726-1.259zM86.689 86.7l17.365-10.026a1.45 1.45 0 0 0 0-2.513l-14.038-8.105-3.278 1.893a1.556 1.556 0 0 1-1.551 0l-3.277-1.892-14.038 8.104c-.241.14-.423.331-.544.55a1.466 1.466 0 0 0 0 1.413c.121.218.303.41.544.55L85.238 86.7a1.447 1.447 0 0 0 1.451 0z"/></g></g></symbol><symbol viewBox="0 0 24 24" id="riot" xmlns="http://www.w3.org/2000/svg"><defs><path d="M13.26 3.04l.58.05.54.07.52.09.49.11.46.13.44.14.41.16.39.17.36.19.33.21.32.22.29.23.26.25.22.22.2.22.19.24.17.24.15.25.15.26.12.27.12.28.1.29.08.31.07.31.05.32.04.34.02.35.01.37v.05l-.02.51-.05.49-.09.48-.13.45-.15.43-.19.4-.22.39-.26.37-.28.34-.31.33-.33.3-.37.28-.39.27-.41.24-.44.22L21 21h-7.04l-3.48-5.14H9.17V21H3V3h9.01l.64.01.61.03zm-4.09 8.52h2.66l.99-.11.75-.35.47-.55.16-.74v-.05l-.17-.75-.47-.54-.74-.32-.96-.11H9.17v3.52z" id="ija"/></defs><use xlink:href="#ija" fill="#ff1744"/><use xlink:href="#ija" fill-opacity="0" stroke="#000" stroke-opacity="0"/></symbol><symbol viewBox="0 0 24 24" id="robot" xmlns="http://www.w3.org/2000/svg"><path d="M12.05 2.804a1.787 1.787 0 0 1 1.788 1.788c0 .661-.357 1.242-.893 1.546v1.135h.893a6.256 6.256 0 0 1 6.256 6.256h.894a.894.894 0 0 1 .893.893v2.681a.894.894 0 0 1-.893.894h-.894v.894a1.787 1.787 0 0 1-1.787 1.787H5.795a1.787 1.787 0 0 1-1.787-1.787v-.894h-.894a.894.894 0 0 1-.894-.894v-2.68a.894.894 0 0 1 .894-.894h.894a6.256 6.256 0 0 1 6.255-6.256h.894V6.138a1.773 1.773 0 0 1-.894-1.546 1.787 1.787 0 0 1 1.788-1.788m-4.022 9.83a2.234 2.234 0 0 0-2.234 2.235 2.234 2.234 0 0 0 2.234 2.234 2.234 2.234 0 0 0 2.234-2.234 2.234 2.234 0 0 0-2.234-2.234m8.043 0a2.234 2.234 0 0 0-2.234 2.234 2.234 2.234 0 0 0 2.234 2.234 2.234 2.234 0 0 0 2.235-2.234 2.234 2.234 0 0 0-2.235-2.234z" fill="#ff5722" stroke-width=".894"/></symbol><symbol viewBox="100 100 800 800" id="rollup" xmlns="http://www.w3.org/2000/svg"><style>.ilst0{fill:url(#ilXMLID_4_)}.ilst1{fill:url(#ilXMLID_5_)}.ilst2{fill:url(#ilXMLID_8_)}.ilst3{fill:url(#ilXMLID_9_)}.ilst4{fill:url(#ilXMLID_11_)}.ilst5{opacity:.3;fill:url(#ilXMLID_16_)}</style><g id="ilXMLID_14_" transform="translate(-54.117 -62.353) scale(1.1129)"><linearGradient id="ilXMLID_4_" x1="444.47" x2="598.47" y1="526.05" y2="562.05" gradientUnits="userSpaceOnUse"><stop stop-color="#FF6533" offset="0"/><stop stop-color="#FF5633" offset=".157"/><stop stop-color="#FF4333" offset=".434"/><stop stop-color="#FF3733" offset=".714"/><stop stop-color="#F33" offset="1"/></linearGradient><path id="ilXMLID_15_" class="ilst0" d="M721 410c0-33.6-8.8-65.1-24.3-92.4-41.1-42.3-130.5-52.1-152.7-.2-22.8 53.2 38.3 112.4 65 107.7 34-6-6-84-6-84 52 98 40 68-54 158S359 779 345 787c-.6.4-1.2.7-1.9 1h368.7c6.5 0 10.7-6.9 7.8-12.7l-96.4-190.8c-2.1-4.1-.6-9.2 3.4-11.5C683 540.6 721 479.8 721 410z" fill="url(#ilXMLID_4_)"/></g><g id="ilXMLID_2_" transform="translate(-54.117 -62.353) scale(1.1129)"><linearGradient id="ilXMLID_5_" x1="420.38" x2="696.38" y1="475" y2="689" gradientUnits="userSpaceOnUse"><stop stop-color="#BF3338" offset="0"/><stop stop-color="#F33" offset="1"/></linearGradient><path id="ilXMLID_10_" class="ilst1" d="M721 410c0-33.6-8.8-65.1-24.3-92.4-41.1-42.3-130.5-52.1-152.7-.2-22.8 53.2 38.3 112.4 65 107.7 34-6-6-84-6-84 52 98 40 68-54 158S359 779 345 787c-.6.4-1.2.7-1.9 1h368.7c6.5 0 10.7-6.9 7.8-12.7l-96.4-190.8c-2.1-4.1-.6-9.2 3.4-11.5C683 540.6 721 479.8 721 410z" fill="url(#ilXMLID_5_)"/></g><linearGradient id="ilXMLID_8_" x1="429.39" x2="469.39" y1="517.16" y2="559.16" gradientTransform="translate(-54.117 -62.353) scale(1.1129)" gradientUnits="userSpaceOnUse"><stop stop-color="#FF6533" offset="0"/><stop stop-color="#FF5633" offset=".157"/><stop stop-color="#FF4333" offset=".434"/><stop stop-color="#FF3733" offset=".714"/><stop stop-color="#F33" offset="1"/></linearGradient><path id="ilXMLID_3_" class="ilst2" d="M329.82 813.46c15.58-8.903 122.41-220.34 227.02-320.5s117.96-66.771 60.094-175.83c0 0-221.46 310.49-301.58 464.06" fill="url(#ilXMLID_8_)" stroke-width="1.113"/><g id="ilXMLID_7_" transform="translate(-54.117 -62.353) scale(1.1129)"><linearGradient id="ilXMLID_9_" x1="502.11" x2="490.11" y1="589.46" y2="417.46" gradientUnits="userSpaceOnUse"><stop stop-color="#FF6533" offset="0"/><stop stop-color="#FF5633" offset=".157"/><stop stop-color="#FF4333" offset=".434"/><stop stop-color="#FF3733" offset=".714"/><stop stop-color="#F33" offset="1"/></linearGradient><path id="ilXMLID_12_" class="ilst3" d="M373 537c134.4-247.1 152-272 222-272 36.8 0 73.9 16.6 97.9 46.1-32.7-52.7-90.6-88-156.9-89H307.7c-4.8 0-8.7 3.9-8.7 8.7V691c13.6-35.1 36.7-85.3 74-154z" fill="url(#ilXMLID_9_)"/></g><linearGradient id="ilXMLID_11_" x1="450.12" x2="506.94" y1="514.21" y2="552.85" gradientTransform="translate(-54.117 -62.353) scale(1.1129)" gradientUnits="userSpaceOnUse"><stop stop-color="#FBB040" offset="0"/><stop stop-color="#FB8840" offset="1"/></linearGradient><path id="ilXMLID_6_" class="ilst4" d="M556.84 492.96c-104.61 100.16-211.44 311.6-227.02 320.5s-41.732 10.016-55.643-5.564c-14.801-16.582-37.837-43.401 86.802-272.65 149.57-274.99 169.15-302.7 247.05-302.7 40.953 0 82.24 18.473 108.95 51.302 1.447 2.337 2.893 4.785 4.34 7.233-45.738-47.074-145.23-57.98-169.93-.222-25.373 59.204 42.622 125.08 72.335 119.85 37.837-6.677-6.677-93.48-6.677-93.48 57.757 108.95 44.403 75.563-60.205 175.72z" fill="url(#ilXMLID_11_)" stroke-width="1.113"/><linearGradient id="ilXMLID_16_" x1="508.33" x2="450.33" y1="295.76" y2="933.76" gradientTransform="translate(-54.117 -62.353) scale(1.1129)" gradientUnits="userSpaceOnUse"><stop stop-color="#FFF" offset="0"/><stop stop-color="#FFF" stop-opacity="0" offset="1"/></linearGradient><path id="ilXMLID_13_" class="ilst5" d="M373.22 547.49c149.57-274.99 169.15-302.7 247.05-302.7 33.719 0 67.661 12.575 93.48 35.277-26.708-30.492-66.326-47.519-105.72-47.519-77.9 0-97.486 27.71-247.05 302.7-124.64 229.25-101.6 256.07-86.802 272.65 2.114 2.337 4.563 4.34 7.122 6.01-13.02-18.919-18.807-62.877 91.922-266.42z" fill="url(#ilXMLID_16_)" opacity=".3" stroke-width="1.113"/></symbol><symbol viewBox="0 0 24 24" id="ruby" xmlns="http://www.w3.org/2000/svg"><path d="M16 9h3l-5 7m-4-7h4l-2 8M5 9h3l2 7m5-12h2l2 3h-3m-5-3h2l1 3h-4M7 4h2L8 7H5m1-5L2 8l10 14L22 8l-4-6H6z" fill="#f44336"/></symbol><symbol viewBox="0 0 144 144" id="rust" xmlns="http://www.w3.org/2000/svg"><path d="M68.252 26.206a3.561 3.561 0 0 1 7.123 0 3.561 3.561 0 0 1-7.123 0M25.766 58.451a3.561 3.561 0 0 1 7.123 0 3.561 3.561 0 0 1-7.123 0m84.97.166a3.561 3.561 0 0 1 7.123 0 3.561 3.561 0 0 1-7.123 0m-74.661 4.88a3.252 3.252 0 0 0 1.651-4.29l-1.58-3.574h6.214v28.01H29.823a43.847 43.847 0 0 1-1.42-16.738zm25.994.688v-8.256h14.798c.764 0 5.397.883 5.397 4.347 0 2.877-3.553 3.908-6.475 3.908zm-20.203 44.452a3.561 3.561 0 0 1 7.123 0 3.561 3.561 0 0 1-7.123 0m52.769.166a3.561 3.561 0 0 1 7.123 0 3.561 3.561 0 0 1-7.123 0m1.101-8.076a3.246 3.246 0 0 0-3.856 2.498l-1.787 8.342a43.847 43.847 0 0 1-36.566-.175l-1.787-8.342a3.246 3.246 0 0 0-3.854-2.497l-7.365 1.581a43.847 43.847 0 0 1-3.808-4.488h35.834c.406 0 .676-.074.676-.443V84.527c0-.369-.27-.442-.676-.442h-10.48V76.05h11.335c1.035 0 5.532.296 6.97 6.045.45 1.768 1.44 7.519 2.116 9.36.674 2.065 3.417 6.19 6.34 6.19h18.501a43.847 43.847 0 0 1-4.06 4.7zm19.898-33.468a43.847 43.847 0 0 1 .093 7.612h-4.499c-.45 0-.631.296-.631.737v2.066c0 4.863-2.742 5.92-5.145 6.19-2.288.258-4.825-.958-5.138-2.358-1.35-7.593-3.6-9.214-7.152-12.016 4.409-2.8 8.996-6.93 8.996-12.457 0-5.97-4.092-9.729-6.881-11.572-3.914-2.58-8.246-3.096-9.415-3.096H39.336A43.847 43.847 0 0 1 63.867 28.52l5.484 5.753a3.243 3.243 0 0 0 4.59.105l6.137-5.869a43.847 43.847 0 0 1 30.017 21.38l-4.201 9.487a3.256 3.256 0 0 0 1.652 4.29zm10.477.154l-.143-1.467 4.327-4.036c.88-.82.55-2.472-.574-2.891l-5.532-2.068-.433-1.428 3.45-4.792c.704-.974.058-2.53-1.127-2.724l-5.833-.949-.7-1.31 2.45-5.38c.502-1.095-.43-2.496-1.636-2.45l-5.92.206-.935-1.135 1.36-5.766c.275-1.17-.913-2.36-2.084-2.085l-5.765 1.359-1.136-.935.207-5.92c.046-1.198-1.357-2.135-2.45-1.637l-5.379 2.452-1.31-.703-.95-5.833c-.193-1.183-1.75-1.83-2.723-1.128l-4.796 3.45-1.425-.432-2.068-5.532c-.42-1.127-2.072-1.452-2.89-.576l-4.036 4.33-1.467-.143-3.117-5.036c-.63-1.02-2.318-1.02-2.946 0l-3.117 5.036-1.467.143-4.037-4.33c-.819-.876-2.47-.551-2.89.576l-2.069 5.532-1.426.432-4.795-3.45c-.974-.703-2.53-.055-2.723 1.128l-.951 5.833-1.31.703-5.379-2.452c-1.093-.5-2.496.439-2.45 1.637l.206 5.92-1.136.935-5.765-1.36c-1.171-.272-2.36.915-2.086 2.086l1.358 5.766-.933 1.135-5.92-.206c-1.193-.035-2.134 1.355-1.637 2.45l2.453 5.38-.703 1.31-5.832.949c-1.185.192-1.827 1.75-1.128 2.724l3.45 4.792-.433 1.428-5.532 2.068c-1.123.42-1.452 2.07-.574 2.891l4.328 4.036-.143 1.467-5.035 3.116c-1.02.63-1.02 2.318 0 2.946l5.035 3.117.143 1.467-4.328 4.037c-.878.818-.549 2.468.574 2.89l5.532 2.068.433 1.428-3.45 4.793c-.701.976-.056 2.532 1.129 2.723l5.831.948.703 1.312-2.453 5.378c-.5 1.093.444 2.5 1.638 2.451l5.917-.207.935 1.136-1.358 5.768c-.275 1.168.915 2.355 2.086 2.08l5.765-1.357 1.137.932-.207 5.921c-.046 1.199 1.357 2.136 2.45 1.636l5.379-2.45 1.31.702.95 5.83c.193 1.187 1.75 1.829 2.725 1.13l4.792-3.453 1.427.435 2.069 5.53c.42 1.123 2.072 1.454 2.89.574l4.037-4.328 1.467.146 3.117 5.035c.628 1.016 2.316 1.018 2.946 0l3.117-5.035 1.467-.146 4.036 4.328c.818.88 2.47.549 2.89-.574l2.068-5.53 1.428-.435 4.793 3.453c.974.699 2.53.055 2.722-1.13l.952-5.83 1.31-.703 5.378 2.451c1.093.5 2.493-.435 2.45-1.636l-.206-5.92 1.135-.933 5.765 1.357c1.171.275 2.36-.912 2.085-2.08l-1.358-5.768.932-1.136 5.92.207c1.194.048 2.138-1.358 1.636-2.451l-2.45-5.378.7-1.312 5.833-.948c1.187-.19 1.831-1.747 1.127-2.723l-3.45-4.793.433-1.428 5.532-2.068c1.125-.422 1.454-2.072.574-2.89l-4.327-4.037.143-1.467 5.035-3.117c1.02-.628 1.021-2.315.001-2.946z" fill="#ff7043" stroke-width="1.146"/></symbol><symbol viewBox="0 0 500 500" id="sass" xmlns="http://www.w3.org/2000/svg"><path d="M422.676 96.573c-12.192-47.839-91.508-63.557-166.575-36.892-44.68 15.877-93.029 40.786-127.81 73.311-41.349 38.675-47.943 72.328-45.216 86.395 9.583 49.622 77.585 82.069 105.535 106.126v.144c-8.246 4.05-68.565 34.584-82.684 65.799-14.893 32.932 2.372 56.556 13.804 59.742 35.424 9.859 71.764-7.866 91.311-37.01 18.853-28.12 17.28-64.422 9.086-82.487 11.3-2.976 24.476-4.314 41.218-2.36 47.248 5.52 56.517 35.017 54.747 47.366-1.77 12.35-11.681 19.14-14.998 21.186-3.317 2.045-4.326 2.766-4.05 4.287.405 2.215 1.94 2.137 4.758 1.652 3.894-.656 24.804-10.042 25.709-32.828 1.14-28.933-26.587-61.302-75.684-60.45-20.216.354-32.933 2.268-42.123 5.69-.681-.774-1.363-1.547-2.084-2.307-30.35-32.382-86.46-55.285-84.088-98.824.866-15.823 6.372-57.5 107.817-108.052 83.104-41.415 149.637-30.009 161.135-4.76 16.427 36.08-35.554 103.137-121.858 112.812-32.88 3.684-50.198-9.059-54.498-13.804-4.536-4.995-5.204-5.218-6.909-4.287-2.753 1.533-1.01 5.938 0 8.574 2.583 6.712 13.15 18.603 31.176 24.515 15.863 5.205 54.459 8.063 101.156-9.99 52.283-20.255 93.12-76.523 81.125-123.548zM200.213 340.34c3.92 14.5 3.487 28.016-.564 40.248a65.289 65.289 0 0 1-3.225 7.97c-3.12 6.477-7.316 12.534-12.442 18.132-15.653 17.069-37.507 23.532-46.88 18.092-10.122-5.874-5.048-29.944 13.083-49.11 19.52-20.636 47.602-33.903 47.602-33.903l-.039-.079 2.465-1.35z" fill="#ec407a" stroke="#ec407a" stroke-width="16.286552999999998"/></symbol><symbol viewBox="0 0 300 300" id="sbt" xmlns="http://www.w3.org/2000/svg"><path d="M105.46 209.517c-7.875 0-13.452-7.521-13.452-15.37v-.327c0-7.848 5.578-13.735 13.452-13.735h164.05c1.476-4.905 2.625-11.446 3.281-17.986h-137.81c-7.875 0-14.273-6.05-14.273-13.898s6.398-13.898 14.273-13.898h137.31c-.82-6.54-1.969-13.081-3.773-17.986h-104.01c-7.875 0-14.273-6.05-14.273-13.898s6.398-13.898 14.273-13.898h91.87c-21.327-37.607-60.864-61.315-106.14-61.315-67.918 0-123.04 54.448-123.04 122.3 0 67.856 55.122 123.28 123.04 123.28 46.59 0 87.112-25.507 107.95-63.114h-152.73z" fill="#0277bd" stroke-width="1.638"/></symbol><symbol viewBox="0 0 256 256" id="scala" xmlns="http://www.w3.org/2000/svg"><path fill="#f44336" fill-rule="evenodd" stroke-width=".3" d="M59.607 50.647l149.097-21.982v49.488L59.607 100.135zM59.593 114.08L208.69 92.098v49.488L59.593 163.568zM59.587 177.358l149.097-21.982v49.488L59.587 226.846z"/><path fill="#f44336" fill-rule="evenodd" stroke-width=".3" d="M62.425 91.414l95.605 30.923-2.832 8.757-95.605-30.922zM113.084 61.13l95.604 30.922-2.832 8.757-95.605-30.922zM62.425 154.79l95.605 30.922-2.833 8.758-95.604-30.923zM113.097 124.408l95.604 30.923-2.832 8.757-95.605-30.922z"/></symbol><symbol viewBox="0 0 24 24" id="settings" xmlns="http://www.w3.org/2000/svg"><path d="M12 15.5A3.5 3.5 0 0 1 8.5 12 3.5 3.5 0 0 1 12 8.5a3.5 3.5 0 0 1 3.5 3.5 3.5 3.5 0 0 1-3.5 3.5m7.43-2.53c.04-.32.07-.64.07-.97 0-.33-.03-.66-.07-1l2.11-1.63c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.31-.61-.22l-2.49 1c-.52-.39-1.06-.73-1.69-.98l-.37-2.65A.506.506 0 0 0 14 2h-4c-.25 0-.46.18-.5.42l-.37 2.65c-.63.25-1.17.59-1.69.98l-2.49-1c-.22-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64L4.57 11c-.04.34-.07.67-.07 1 0 .33.03.65.07.97l-2.11 1.66c-.19.15-.25.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1.01c.52.4 1.06.74 1.69.99l.37 2.65c.04.24.25.42.5.42h4c.25 0 .46-.18.5-.42l.37-2.65c.63-.26 1.17-.59 1.69-.99l2.49 1.01c.22.08.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.66z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="shaderlab" xmlns="http://www.w3.org/2000/svg"><path d="M9.11 17H6.5l-4.91-5L6.5 7h2.61l1.31-2.26L17.21 3l1.87 6.74L17.77 12l1.31 2.26L17.21 21l-6.79-1.74L9.11 17m.14-.25l5.13 1.38L11.42 13H5.5l3.75 3.75m6.87.38L17.5 12l-1.38-5.13L13.15 12l2.97 5.13M9.25 7.25L5.5 11h5.92l2.96-5.13-5.13 1.38z" fill="#1976d2"/></symbol><symbol viewBox="0 0 24 24" id="slim" xmlns="http://www.w3.org/2000/svg"><path d="M6.959 2.5a4.605 4.605 0 0 0-4.615 4.615v9.957a4.605 4.605 0 0 0 4.615 4.615h9.957a4.605 4.605 0 0 0 4.615-4.615V7.115A4.605 4.605 0 0 0 16.916 2.5zm4.938 2.691a6.811 6.811 0 0 1 6.81 6.813H13.43L9.938 7.287l.699 4.717H5.086a6.811 6.811 0 0 1 6.81-6.813z" fill="#f57f17"/></symbol><symbol id="smarty" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>.iust0{fill:#ffce00}</style><path class="iust0" d="M9.14 20.606c0 .556.398.953.954.953h3.812c.556 0 .953-.397.953-.953v-.953H9.141zM12 2.5c-3.653 0-6.671 3.018-6.671 6.671 0 2.303 1.112 4.289 2.859 5.48v2.144c0 .556.397.953.953.953h5.718c.556 0 .953-.397.953-.953V14.65c1.747-1.191 2.86-3.177 2.86-5.48 0-3.653-3.019-6.671-6.672-6.671zm2.7 10.563l-.794.555v2.224h-3.812v-2.224l-.794-.555A4.712 4.712 0 0 1 7.235 9.17 4.78 4.78 0 0 1 12 4.405a4.78 4.78 0 0 1 4.765 4.765 4.712 4.712 0 0 1-2.065 3.892z"/></symbol><symbol viewBox="0 0 200 200" id="snyk" xmlns="http://www.w3.org/2000/svg"><title>Group 2</title><g transform="translate(15.255 18.22) scale(1.8477)" fill="none" fill-rule="evenodd"><path d="M65.161 24.997c-1.656 5.974-5.255 23.587-5.255 23.587s-6.618-2.464-14.148-2.476h-.055c-.413.002-.822.012-1.23.026v41.649h6.677v.003h5.815v-.003h20.858c.111-8.177-2.036-27.066-2.036-27.066-1.088-2.279.46-7.668.46-7.668-8.869-9.092-11.086-28.051-11.086-28.051zm-3.357 43.958c5.476 0 1.381 4.64.9 5.168H52.35c.944-1.18 4.504-5.168 9.453-5.168z" fill="#607d8b" stroke-width="1.6"/><path d="M26.366 24.995s-2.217 18.961-11.087 28.053c0 0 1.548 5.391.46 7.669 0 0-2.15 18.895-2.038 27.066h19.273v.003h7.079v-.003h5.744V46.107h-.025c-7.532.013-14.151 2.478-14.151 2.478s-3.6-17.615-5.255-23.59zm3.264 43.96c4.95 0 8.51 3.987 9.452 5.168H28.73c-.479-.528-4.573-5.168.9-5.168z" fill="#90a4ae" stroke-width="1.6"/><g transform="translate(23.76 77.45) scale(1.5998)"><g transform="translate(17.526)"><path d="M7.357.06H.177v.075C.177 2.64 2.345 4.67 4.89 4.67 7.431 4.67 9.6 2.64 9.6.135V.059z" fill="#455a64"/><path d="M1.972.06v.075a2.692 2.692 0 1 0 5.386 0V.059z" fill="#fff"/><path d="M5.496.06H4.234c-.012 0-.023.005-.034.007.157.033.243.388.21.624a.721.721 0 0 1-.71.617c.102.471.487.85.997.922a1.188 1.188 0 0 0 1.35-1.007C6.112.743 5.881.06 5.495.06z" fill="#37474f"/></g><path d="M7.552.06H.372v.075c0 2.505 2.17 4.535 4.712 4.535 2.544 0 4.712-2.03 4.712-4.535V.059z" fill="#455a64"/><path d="M2.168.06v.075a2.692 2.692 0 1 0 5.385 0V.059z" fill="#fff"/><path d="M5.692.06H4.428c-.01 0-.022.005-.032.007.156.033.242.388.21.624a.72.72 0 0 1-.712.617c.104.471.488.85.999.922A1.187 1.187 0 0 0 6.24 1.223C6.308.743 6.078.06 5.69.06z" fill="#37474f"/></g><path d="M25.514-.27l-4.202 7.697C19.838 10.17 6.858 34.465 6.858 43.243v.516L12.8 59.573c-.8 7.258-2.203 21.643-1.78 28.21h5.73c-.354-3.787.648-17.008 1.903-28.25l.076-.677-1.075-2.892c3.694-3.868 6.285-9.193 8.073-14.261l.174 1.235 5.869 9.629 2.291-.983c.058-.024 5.935-2.523 11.643-2.523 5.672 0 11.646 2.5 11.702 2.525l2.29.976 5.86-9.626.23-1.608c1.769 5.117 4.358 10.536 8.07 14.49l-1.127 3.035.076.678c1.259 11.286 2.266 24.564 1.916 28.252h5.677c.406-6.567-1.05-20.952-1.848-28.208l5.838-15.817v-.514c0-8.779-12.876-33.074-14.347-35.816L65.923-.27l-5.897 41.229-2.723 4.478c-2.628-.882-7.1-2.11-11.603-2.11-4.498 0-8.94 1.225-11.557 2.108l-2.722-4.476-2.07-14.452a.832.832 0 0 0 .006-.071l-.016-.004zm-3.166 18.39l1.206 8.407c-.46 3.143-2.561 15.47-8.198 23.24l-2.598-6.99c.325-4.554 5.067-15.462 9.59-24.656zm46.763 0c4.523 9.194 9.267 20.104 9.592 24.657L76.166 49.6c-6.09-8.553-8-22.459-8.166-23.73z" fill="#607d8b" stroke-width="1.6"/></g></symbol><symbol viewBox="0 0 24 24" id="solidity" xmlns="http://www.w3.org/2000/svg"><path d="M5.8 14.05l6.253 8.61 6.252-8.61-6.254 3.807z" fill="#0288d1" stroke-width="4.553" stroke-linejoin="round"/><path d="M12.051 1.347L5.8 11.833l6.252 3.807 6.254-3.807z" fill="#0288d1" stroke-width="5.025" stroke-linejoin="round"/></symbol><symbol viewBox="0 0 120 120" id="sonar" xmlns="http://www.w3.org/2000/svg"><style>.a,.b{fill:#fff}.b{stroke:#fff;stroke-miterlimit:10}</style><path d="M115.45 23.033S97.961 33.27 97.534 33.412c-.427.284-.852.57-1.137.854-1.422 1.421-1.848 3.41-1.422 5.26.285.852.711 1.849 1.422 2.56.711.71 1.564 1.137 2.559 1.422 1.848.426 3.84 0 5.262-1.422.426-.427.709-.853.851-1.28l.143-.427 2.56-4.692zm-39.102 9.242c-27.441 0-31.99 13.08-31.99 29.29 0 3.838.569 7.962-1.99 11.942-3.84 5.972-8.957 5.828-10.236 5.828-1.706 0-7.962-.993-8.246-2.841h.994c6.682 0 11.658-5.404 11.658-12.655v-2.56h-5.686c-4.123 0-7.82 1.849-10.238 5.12-2.417-3.271-6.113-5.12-10.236-5.12h-5.83v2.56c0 7.11 5.688 12.795 12.797 12.795h1.848c0 4.124 5.687 20.332 47.63 20.332 16.352 0 40.665-2.843 40.665-33.697 0-5.829-1.848-11.23-4.691-15.78-.996.284-1.992.568-3.13.568a8.92 8.92 0 0 1-8.956-8.957c0-.995.141-1.991.425-2.986-4.265-2.702-8.53-3.838-14.787-3.838z" fill="#1e88e5" stroke-width="1.422"/></symbol><symbol viewBox="0 0 412 395" id="stylelint" xmlns="http://www.w3.org/2000/svg"><title>stylelint-icon-white</title><g transform="translate(31.478 29.499) scale(.84775)" fill="#cfd8dc" fill-rule="evenodd"><path d="M208.8 393.05c45.057-161.12 43.75-161.85 76.32-276.73l7.832 4.523c4.255 2.458 7.738.448 7.738-4.455V61.602c8.643-30.27 15.416-53.66 17.4-60.693h35.287l58.618 54.304-38.498 33.27 29.11 31.473-191.86 273.09c-.938 1.542-2.244 1.19-1.947 0zm20.96-347.28c1.733 0 3.148.958 3.148 2.147v28.077c0 1.186-1.415 2.15-3.147 2.15h-47.396c-1.742 0-3.153-.96-3.153-2.15V47.917c0-1.185 1.41-2.147 3.153-2.147h47.396z"/><path d="M288.26 14.688l-52.14 30.1c.605.92.973 1.98.973 3.136v28.078c0 1.457-.565 2.77-1.496 3.83l52.663 30.402c3.59 2.073 6.535.377 6.535-3.764V18.456c0-4.145-2.944-5.836-6.535-3.768zM175.02 76V47.923c0-1.15.368-2.21.966-3.13l-52.14-30.105c-3.588-2.068-6.53-.376-6.53 3.768v88.013c0 4.14 2.938 5.84 6.53 3.76l52.66-30.405c-.926-1.06-1.487-2.37-1.487-3.827z"/><path d="M201.25 393.05h1.947c-45.05-161.12-43.753-161.85-76.32-276.73l-7.833 4.523c-4.253 2.458-7.737.448-7.737-4.455V61.602C102.662 31.332 95.892 7.942 93.902.909H58.619L.002 55.213l38.494 33.27-29.11 31.473z"/><circle cx="204.57" cy="122.54" r="14.231"/><circle cx="204.57" cy="207.16" r="14.231"/><circle cx="204.57" cy="291.78" r="14.23"/></g></symbol><symbol viewBox="0 0 412 395" id="stylelint_light" xmlns="http://www.w3.org/2000/svg"><title>stylelint-icon-black</title><g transform="translate(31.478 29.499) scale(.84775)" fill="#546e7a" fill-rule="evenodd"><path d="M208.8 393.05c45.057-161.12 43.75-161.85 76.32-276.73l7.832 4.523c4.255 2.458 7.738.448 7.738-4.455V61.602c8.643-30.27 15.416-53.66 17.4-60.693h35.287l58.618 54.304-38.498 33.27 29.11 31.473-191.86 273.09c-.938 1.542-2.244 1.19-1.947 0zm20.96-347.28c1.733 0 3.148.958 3.148 2.147v28.077c0 1.186-1.415 2.15-3.147 2.15h-47.396c-1.742 0-3.153-.96-3.153-2.15V47.917c0-1.185 1.41-2.147 3.153-2.147h47.396z"/><path d="M288.26 14.688l-52.14 30.1c.605.92.973 1.98.973 3.136v28.078c0 1.457-.565 2.77-1.496 3.83l52.663 30.402c3.59 2.073 6.535.377 6.535-3.764V18.456c0-4.145-2.944-5.836-6.535-3.768zM175.02 76V47.923c0-1.15.368-2.21.966-3.13l-52.14-30.105c-3.588-2.068-6.53-.376-6.53 3.768v88.013c0 4.14 2.938 5.84 6.53 3.76l52.66-30.405c-.926-1.06-1.487-2.37-1.487-3.827z"/><path d="M201.25 393.05h1.947c-45.05-161.12-43.753-161.85-76.32-276.73l-7.833 4.523c-4.253 2.458-7.737.448-7.737-4.455V61.602C102.662 31.332 95.892 7.942 93.902.909H58.619L.002 55.213l38.494 33.27-29.11 31.473z"/><circle cx="204.57" cy="122.54" r="14.231"/><circle cx="204.57" cy="207.16" r="14.231"/><circle cx="204.57" cy="291.78" r="14.23"/></g></symbol><symbol viewBox="0 0 200.00001 200.00001" id="stylus" xmlns="http://www.w3.org/2000/svg"><path d="M126.814 155.9c14.64-17.51 16.362-35.595 5.024-69.18-7.177-21.24-19.09-37.602-10.334-50.807 9.329-14.065 29.135-.43 12.63 18.371l3.301 2.297c19.806 2.296 29.566-24.83 14.783-32.58C113.179 3.621 79.02 42.803 94.09 88.156c6.458 19.232 15.5 39.613 8.18 55.83-6.314 13.923-18.514 22.103-26.695 22.39-17.079.862-5.74-38.32 13.922-48.08 1.722-.861 4.162-2.01 1.866-4.88-24.256-2.727-38.464 8.468-46.645 24.112-23.825 45.497 45.21 62.29 82.095 18.371z" fill="#c0ca33" stroke-width="1.435"/></symbol><symbol viewBox="0 0 24 24" id="swc" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="jba"><stop offset="0" stop-color="#791223"/><stop offset="1" stop-color="#d92f3c"/></linearGradient><linearGradient xlink:href="#jba" id="jbb" x1="12.356" y1="21.559" x2="12.356" y2="2.949" gradientUnits="userSpaceOnUse"/></defs><path d="M6 3c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6 3 6.5V19a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6.5c0-.5-.17-.93-.46-1.27l-1.39-1.68C18.88 3.21 18.47 3 18 3H6zm-.07 1h12l.94 1H5.12l.81-1z" fill="url(#jbb)"/><path style="line-height:125%" d="M11.053 11.918h-.008c-.244.022-.475.054-.676.11a2.9 2.9 0 0 0-.856.412 3.399 3.399 0 0 0-.67.683 9.36 9.36 0 0 0-.586.95c-.07.131-.134.244-.201.365v.001h-.002l-.768 1.372-.003-.001c-.136.253-.264.485-.38.686-.123.212-.26.39-.411.539a1.599 1.599 0 0 1-.52.34c-.04.016-.092.024-.138.036h-.567v1.383H5.834v-.001c.245-.02.477-.053.679-.11a2.9 2.9 0 0 0 .856-.411c.245-.185.469-.413.67-.683.195-.275.39-.591.585-.95.07-.131.135-.244.202-.366l.004.001.002-.002.02-.038H10.948v-1.378h-.19v-.001H9.624c.125-.234.246-.452.355-.64.123-.21.259-.39.41-.538.152-.148.325-.26.52-.34.04-.015.091-.024.136-.035h.57V13.3h-.002v-1.381h-.56v-.001z" font-weight="400" font-size="40" font-family="sans-serif" letter-spacing="0" word-spacing="0" fill="#fff"/></symbol><symbol viewBox="0 0 24 24" id="swift" xmlns="http://www.w3.org/2000/svg"><path d="M17.09 19.72c-2.36 1.36-5.59 1.5-8.86.1A13.807 13.807 0 0 1 2 14.5c.67.55 1.46 1 2.3 1.4 3.37 1.57 6.73 1.46 9.1 0-3.37-2.59-6.24-5.96-8.37-8.71-.45-.45-.78-1.01-1.12-1.51 8.28 6.05 7.92 7.59 2.41-1.01 4.89 4.94 9.43 7.74 9.43 7.74.16.09.25.16.36.22.1-.25.19-.51.26-.78.79-2.85-.11-6.12-2.08-8.81 4.55 2.75 7.25 7.91 6.12 12.24-.03.11-.06.22-.05.39 2.24 2.83 1.64 5.78 1.35 5.22-1.21-2.39-3.48-1.65-4.62-1.17z" fill="#fe5e2f"/></symbol><symbol viewBox="0 0 24 24" id="table" xmlns="http://www.w3.org/2000/svg"><path d="M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2m7 1.5V9h5.5L13 3.5m4 7.5h-4v2h1l-2 1.67L10 13h1v-2H7v2h1l3 2.5L8 18H7v2h4v-2h-1l2-1.67L14 18h-1v2h4v-2h-1l-3-2.5 3-2.5h1v-2z" fill="#8bc34a"/></symbol><symbol viewBox="0 0 200 200" id="terraform" xmlns="http://www.w3.org/2000/svg"><g transform="translate(177.03 -58.705) scale(.92881)" fill="#5c6bc0" stroke="#b0aff5" stroke-linejoin="round"><g stroke-width=".288"><path transform="skewY(26.439) scale(.89541 1)" d="M-203.8 170.95h64.714v51.88H-203.8zM-124.37 171.04h64.714v51.88h-64.714zM-124.37 236.09h64.714v51.88h-64.714z"/></g><path transform="skewY(-22.59) scale(-.92328 1)" stroke-width=".284" d="M-19.172 128.27h62.76v51.88h-62.76z"/></g></symbol><symbol viewBox="0 0 24 24" id="test-js" xmlns="http://www.w3.org/2000/svg"><path d="M5 19a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1c0-.21-.07-.41-.18-.57L13 8.35V4h-2v4.35L5.18 18.43c-.11.16-.18.36-.18.57m1 3a3 3 0 0 1-3-3c0-.6.18-1.16.5-1.63L9 7.81V6a1 1 0 0 1-1-1V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v1a1 1 0 0 1-1 1v1.81l5.5 9.56c.32.47.5 1.03.5 1.63a3 3 0 0 1-3 3H6m7-6l1.34-1.34L16.27 18H7.73l2.66-4.61L13 16m-.5-4a.5.5 0 0 1 .5.5.5.5 0 0 1-.5.5.5.5 0 0 1-.5-.5.5.5 0 0 1 .5-.5z" fill="#ffca28"/></symbol><symbol viewBox="0 0 24 24" id="test-jsx" xmlns="http://www.w3.org/2000/svg"><path d="M5 19a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1c0-.21-.07-.41-.18-.57L13 8.35V4h-2v4.35L5.18 18.43c-.11.16-.18.36-.18.57m1 3a3 3 0 0 1-3-3c0-.6.18-1.16.5-1.63L9 7.81V6a1 1 0 0 1-1-1V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v1a1 1 0 0 1-1 1v1.81l5.5 9.56c.32.47.5 1.03.5 1.63a3 3 0 0 1-3 3H6m7-6l1.34-1.34L16.27 18H7.73l2.66-4.61L13 16m-.5-4a.5.5 0 0 1 .5.5.5.5 0 0 1-.5.5.5.5 0 0 1-.5-.5.5.5 0 0 1 .5-.5z" fill="#00bcd4"/></symbol><symbol viewBox="0 0 24 24" id="test-ts" xmlns="http://www.w3.org/2000/svg"><path d="M5 19a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1c0-.21-.07-.41-.18-.57L13 8.35V4h-2v4.35L5.18 18.43c-.11.16-.18.36-.18.57m1 3a3 3 0 0 1-3-3c0-.6.18-1.16.5-1.63L9 7.81V6a1 1 0 0 1-1-1V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v1a1 1 0 0 1-1 1v1.81l5.5 9.56c.32.47.5 1.03.5 1.63a3 3 0 0 1-3 3H6m7-6l1.34-1.34L16.27 18H7.73l2.66-4.61L13 16m-.5-4a.5.5 0 0 1 .5.5.5.5 0 0 1-.5.5.5.5 0 0 1-.5-.5.5.5 0 0 1 .5-.5z" fill="#0288d1"/></symbol><symbol viewBox="0 0 500 500" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="tex" xmlns="http://www.w3.org/2000/svg"><g font-weight="400" font-size="40" font-family="sans-serif" letter-spacing="0" word-spacing="0" fill="#42a5f5" stroke-linejoin="miter"><text style="line-height:125%" x="9.914" y="364.919"><tspan x="9.914" y="364.919" font-size="287.5">T</tspan></text><text style="line-height:125%" x="136.374" y="435.558"><tspan x="136.374" y="435.558" font-size="287.5">E</tspan></text><text style="line-height:125%" x="307.819" y="361.201"><tspan x="307.819" y="361.201" font-size="287.5">X</tspan></text></g></symbol><symbol viewBox="0 0 24 24" id="todo" xmlns="http://www.w3.org/2000/svg"><path d="M3 5h6v6H3V5m2 2v2h2V7H5m6 0h10v2H11V7m0 8h10v2H11v-2m-6 5l-3.5-3.5 1.41-1.41L5 17.17l4.59-4.58L11 14l-6 6z" fill="#42a5f5"/></symbol><symbol id="travis" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"><style id="jkstyle2">.jkst0{fill:#cb3349}.jkst1{fill:#f4edae}.jkst2{fill:#e6ccad}.jkst3{fill:#656c67}.jkst4{fill:#e5caa3}.jkst5{fill:#c7b39a}.jkst6{fill:#ebd599}.jkst7{fill:#2d3136}.jkst8{fill:#edf6fa}.jkst9{opacity:.8}.jkst10{opacity:.75;fill:#ebd599}</style><g id="jkg99" transform="translate(11.017 12.484) scale(.8858)"><g id="jkg10"><path class="jkst0" d="M47.781 86.572s-31.118 21.903-32.335 30.247l2.335-.48S55.045 91.64 84.584 88.628l.669-3.749z" id="jkpath4" fill="#cb3349"/><path class="jkst0" d="M96.629 83.442l-24.511 17.385 1.325 1.063c.999-.806 43.539-13.798 43.539-13.798l8.969-5.623c-6.018.749-29.322.973-29.322.973z" id="jkpath6" fill="#cb3349"/><path class="jkst0" d="M117.932 104.469c17.405 0 43.495-17.046 43.495-17.046l-8.434-1.605c-.417.417-13.6-.462-13.6-.462l-6.258-1.738-14.951 17.036-1.217 2.956c1.075-.437.965.859.965.859z" id="jkpath8" fill="#cb3349"/></g><path class="jkst0" d="M174.728 158.832l-5.377 1.514-24.843-.537-15.541-12.085-18.784 4.7-21.726-1.88-12.166 13.294-22.828 6.819-11.398-3.534-.574-.494 5.116 12.527s11.588 12.424 18.061 13.885c6.472 1.461 18.165-.105 26.935-1.463 8.769-1.357 15.764-4.489 18.582-9.603 2.818-5.117 3.236-6.578 3.236-6.578s8.353 11.797 15.556 13.155c7.203 1.357 28.605-5.952 28.605-5.952s13.051-3.549 15.346-8.038c2.297-4.489 8.353-19.209 8.353-19.209zM44.456 169.038l-.361-.166-2.013-1.736z" id="jkpath12" fill="#cb3349"/><g id="jkg97"><path class="jkst1" d="M195.832 70.085a48.125 48.125 0 0 0-.21-2.009 26.472 26.472 0 0 0-.215-1.424c-1.793-1.509-3.831-2.851-5.952-4.071-2.299-1.343-4.704-2.546-7.159-3.663-2.438-1.15-4.942-2.191-7.461-3.207a134.313 134.313 0 0 0-3.798-1.477c-1.269-.495-2.55-.956-3.835-1.424 2.697.447 5.366 1.059 8.015 1.741 1.723.446 3.437.945 5.14 1.477-12.112-31.655-41.07-52.27-72.687-52.27-31.622 0-60.577 20.615-72.686 52.27a109.044 109.044 0 0 1 5.137-1.477c2.653-.682 5.323-1.294 8.018-1.741-1.289.468-2.567.929-3.84 1.424-1.267.472-2.536.967-3.798 1.477-2.519 1.016-5.016 2.057-7.46 3.207-2.45 1.117-4.857 2.32-7.156 3.663-2.121 1.219-4.157 2.562-5.957 4.071-.075.457-.151.951-.21 1.424a51.768 51.768 0 0 0-.21 2.009 51.354 51.354 0 0 0-.177 4.061 59.216 59.216 0 0 0 .5 8.11c.37 2.692.864 5.366 1.595 7.951.36 1.295.768 2.572 1.24 3.808.237.617.495 1.225.764 1.816.134.294.274.585.413.864l.172.328c.199.101.408.204.607.3l1.204.575c.671.305 1.6.746 2.368 1.09.043-.037.086-.075.123-.114l-2.235-8.513c.474-.13 4.718-1.225 12.032-2.617a38.816 38.816 0 0 1-1.772-.381c-1.665-.414-3.309-.919-4.899-1.564a22.415 22.415 0 0 1-2.309-1.115c-.742-.426-1.472-.908-2.037-1.548 8.036 2.622 24.64 1.434 39.399-.091 13.499-1.391 27.029-2.293 40.63-2.32 13.602.027 27.137.929 40.63 2.32 14.766 1.525 31.37 2.713 39.405.091-.564.64-1.293 1.123-2.035 1.548a22.5 22.5 0 0 1-2.308 1.115c-1.592.645-3.234 1.15-4.899 1.564-.247.059-.496.113-.743.166 8.02 1.488 12.689 2.697 13.188 2.831l-2.138 8.11c.43-.194.864-.381 1.29-.574l1.202-.575c.2-.097.403-.199.607-.3l.166-.328c.146-.279.286-.57.419-.864.27-.591.528-1.199.764-1.816a42.235 42.235 0 0 0 1.241-3.808c.731-2.585 1.225-5.259 1.595-7.951.345-2.685.526-5.398.501-8.11a50.874 50.874 0 0 0-.179-4.059z" id="jkpath14" fill="#f4edae"/><path class="jkst2" d="M116.787 182.661c-1.064.16-2.128.295-3.186.375-.682.033-1.404.102-2.059.102l-.242.005c.822-1.837 1.446-3.26 1.919-4.339.963 1.08 2.188 2.417 3.568 3.857z" id="jkpath16" fill="#e6ccad"/><path class="jkst2" d="M119.101 185.018c3.304 3.272 7.398 5.146 11.904 5.479-7.569 3.074-14.702 4.26-20.197 4.63-5.478.367-11.032-.279-16.474-1.771.456-.082.79-.14 1.193-.189.447-.054 10.206-1.327 14.605-7.868l.413.009 1.08-.009c.731 0 1.395-.06 2.094-.087a43.69 43.69 0 0 0 4.878-.703c.167.171.333.338.504.509z" id="jkpath18" fill="#e6ccad"/><path class="jkst3" d="M128.464 87.071a98.82 98.82 0 0 1-1.048 1.343c-1.933 2.444-4.614 5.57-7.794 8.627a369.585 369.585 0 0 0-11.404-.177c-6.46 0-12.655.171-18.537.457 8.311-3.449 18.296-6.818 29.109-8.842a113.323 113.323 0 0 1 9.674-1.408z" id="jkpath20" fill="#656c67"/><path class="jkst3" d="M79.821 90.792c-2.966 2.084-6.317 4.744-9.566 7.971a360.155 360.155 0 0 0-21.567 2.81c9.207-4.232 19.713-8.127 31.133-10.781z" id="jkpath22" fill="#656c67"/><path class="jkst3" d="M181.48 107.969l-3.384 23.679-16.212 11.355-42.283-4.807-6.365-20.961a1.383 1.383 0 0 0-1.108-.971c-1.567-.253-2.953-.382-4.108-.382-1.16 0-2.541.129-4.115.382-.522.086-.95.461-1.106.971l-6.209 20.45-42.047 9.357-16.662-11.672-3.283-26.572c.715-.404 1.441-.806 2.176-1.209 1.031-.222 2.191-.457 3.475-.704l3.094 25.073c.048.392.264.741.586.967l11.462 8.032a1.425 1.425 0 0 0 1.101.213l34.57-7.692c.119-.027.237-.069.344-.124a1.39 1.39 0 0 0 .682-.827l6.225-20.498c1.67-.43 5.947-1.429 9.706-1.429 3.749 0 8.03.999 9.701 1.429l6.225 20.498c.161.532.624.912 1.176.977l34.57 3.927c.335.037.677-.05.952-.242l11.469-8.025c.31-.22.52-.566.573-.946l3.062-21.421c2.301.444 4.224.846 5.733 1.172z" id="jkpath24" fill="#656c67"/><path class="jkst3" d="M185.751 93.119l-2.976 11.29c-6.086-1.342-19.456-3.975-37.654-5.747 5.946-2.535 12-5.715 17.531-9.69 10.829 1.53 18.78 3.169 23.099 4.147z" id="jkpath26" fill="#656c67"/><g id="jkg32"><path class="jkst4" d="M63.841 128.441c2.357-1.274 5.021-1.085 9.19-1.079.447.011.908.005 1.39-.005.41-.005.822-.011 1.258-.022 4.296-.042 7.869.366 7.806-6.381-.065-6.746-3.062-12.198-7.354-12.155-4.297.037-8.454 5.564-8.197 12.306.07 1.756.328 3.023.742 3.937-3.745.938-4.777 3.254-4.835 3.399zm51.657-27.749a46.634 46.634 0 0 1-5.249 3.712l-6.097 3.68a52.065 52.065 0 0 0-7.331 1.467 1.216 1.216 0 0 0-.317.14 1.406 1.406 0 0 0-.629.794l-6.209 20.46-33.185 7.38-10.452-7.321-3.041-24.634c5.936-1.09 13.874-2.352 23.41-3.42a56.802 56.802 0 0 0-2.955 3.855l-5.677 8.149 8.266-5.511c.123-.086 5.387-3.549 13.998-7.761a377.407 377.407 0 0 1 35.468-.99z" id="jkpath28" fill="#e5caa3"/><path class="jkst4" d="M151.835 125.675c-.042-.16-.945-2.873-4.942-2.397.461-1.003.666-2.356.521-4.21-.528-6.731-4.443-12.08-8.735-11.931-4.292.152-7.042 5.731-6.805 12.478.236 6.741 3.84 6.694 8.132 6.543 5.77-.107 8.939-1.88 11.829-.483zm21.18-19.385l-2.992 20.944-10.539 7.379-33.141-3.766-6.183-20.363a1.41 1.41 0 0 0-.945-.934c-.205-.06-4.308-1.23-8.659-1.607l.795-.053c.687-.049 12.118-1.451 25.767-6.157 15.115 1.161 27.458 3.02 35.897 4.557z" id="jkpath30" fill="#e5caa3"/></g><g id="jkg38"><path class="jkst5" d="M63.841 128.441c2.357-1.274 5.021-1.085 9.19-1.079.447.011.908.005 1.39-.005.41-.005.822-.011 1.258-.022 4.296-.042 7.869.366 7.806-6.381-.065-6.746-3.062-12.198-7.354-12.155-4.297.037-8.454 5.564-8.197 12.306.07 1.756.328 3.023.742 3.937-3.745.938-4.777 3.254-4.835 3.399zm51.657-27.749a46.634 46.634 0 0 1-5.249 3.712l-6.097 3.68a52.065 52.065 0 0 0-7.331 1.467 1.216 1.216 0 0 0-.317.14 1.406 1.406 0 0 0-.629.794l-6.209 20.46-33.185 7.38-10.452-7.321-3.041-24.634c5.936-1.09 13.874-2.352 23.41-3.42a56.802 56.802 0 0 0-2.955 3.855l-5.677 8.149 8.266-5.511c.123-.086 5.387-3.549 13.998-7.761a377.407 377.407 0 0 1 35.468-.99z" id="jkpath34" fill="#c7b39a"/><path class="jkst5" d="M151.835 125.675c-.042-.16-.945-2.873-4.942-2.397.461-1.003.666-2.356.521-4.21-.528-6.731-4.443-12.08-8.735-11.931-4.292.152-7.042 5.731-6.805 12.478.236 6.741 3.84 6.694 8.132 6.543 5.77-.107 8.939-1.88 11.829-.483zm21.18-19.385l-2.992 20.944-10.539 7.379-33.141-3.766-6.183-20.363a1.41 1.41 0 0 0-.945-.934c-.205-.06-4.308-1.23-8.659-1.607l.795-.053c.687-.049 12.118-1.451 25.767-6.157 15.115 1.161 27.458 3.02 35.897 4.557z" id="jkpath36" fill="#c7b39a"/></g><path class="jkst2" d="M187.481 115.502c.508.419.911 1.504.456 6.558-.559 6.188-3.16 17.049-4.771 18.8-1.778.344-5.505-.064-7.778-.595.393-1.559.505-2.306.822-3.9l3.975-2.781c.317-.22.526-.566.58-.941l2.778-19.466c1.686.912 3.421 1.899 3.938 2.325z" id="jkpath40" fill="#e6ccad"/><path class="jkst2" d="M40.937 140.908c.199.704.408 1.407.624 2.1-2.139.628-6.495 1.23-8.465.886-1.633-1.645-4.679-12.966-5.345-18.978-.543-4.871-.162-5.924.333-6.334.575-.483 2.728-1.708 4.593-2.707l2.519 20.449c.048.393.257.741.586.967z" id="jkpath42" fill="#e6ccad"/><path class="jkst2" d="M121.347 141.194l-.151 1.305s-4.581 4.248-11.956 5.199c-7.375.95-13.171-3.582-13.171-3.582.242.788.586 2.567 2.256 4.086a53.184 53.184 0 0 0-6.313-.393c-.804 0-1.616.023-2.401.061-4.539.237-10.924 7.1-15.414 14.014-2.203.697-9.089 2.883-17.06 5.237-7.44-10.309-11.098-20.842-11.469-21.932l.005-.006c-.15-.419-.301-.839-.441-1.268l1.913 1.338v.005l4.726 3.309 1.58 1.101c.236.167.515.253.794.253.102 0 .204-.011.305-.031l43.435-9.67a1.385 1.385 0 0 0 1.025-.95l6.194-20.39c1.069-.145 2.008-.22 2.814-.22.801 0 1.746.075 2.815.22l6.374 20.997c.162.532.624.919 1.171.977z" id="jkpath44" fill="#e6ccad"/><path class="jkst2" d="M170.926 140.066l1.402-.984c-.232.973-.484 1.94-.747 2.896-1.949 6.248-4.25 11.774-6.805 16.656-.565.039-1.161.061-1.8.061-1.972 0-3.986-.167-6.215-.371-3.868-.355-10.007-1.058-11.946-1.283-1.67-1.332-7.385-5.873-12.14-9.615-.187-.151-.348-.291-.505-.42-.837-.708-1.789-1.513-3.717-1.513-1.751 0-4.308.638-10.489 2.508 3.212-2.401 3.233-5.5 3.233-5.5l.151-1.305 40.748 4.629a1.41 1.41 0 0 0 .955-.241l4.094-2.868z" id="jkpath46" fill="#e6ccad"/><path class="jkst6" d="M140.937 54.337c.124 3.625.033 10.194-1.655 16.345a1.335 1.335 0 0 0 0 .704 259.298 259.298 0 0 0-6.446-.591c2.412-5.054 2.938-10.436 3.052-12.332 1.852-1.317 3.696-2.896 5.049-4.126z" id="jkpath48" fill="#ebd599"/><path class="jkst6" d="M79.456 58.462c.112 1.896.638 7.267 3.046 12.317-2.149.171-4.297.37-6.441.596a1.328 1.328 0 0 0 0-.694c-1.686-6.139-1.772-12.714-1.654-16.345 1.353 1.231 3.19 2.81 5.049 4.126z" id="jkpath50" fill="#ebd599"/><path class="jkst7" d="M151.835 125.675c-2.89-1.396-6.059.377-11.828.484-4.292.151-7.896.198-8.132-6.543-.237-6.747 2.513-12.326 6.805-12.478 4.292-.15 8.207 5.2 8.735 11.931.145 1.854-.06 3.207-.521 4.21 3.996-.477 4.899 2.235 4.941 2.396zm-13.488-9.878a2.203 2.203 0 0 0 2.154-2.235 2.186 2.186 0 0 0-2.235-2.153 2.194 2.194 0 0 0 .081 4.388z" id="jkpath52" fill="#2d3136"/><circle transform="rotate(-1.049 138.093 113.428)" class="jkst8" cx="138.307" cy="113.602" id="jkellipse54" r="2.194" fill="#edf6fa"/><path class="jkst7" d="M83.484 120.953c.063 6.747-3.509 6.339-7.806 6.381-.435.011-.848.016-1.258.022-.482.011-.944.016-1.39.005-4.168-.005-6.833-.194-9.19 1.079.058-.145 1.09-2.461 4.835-3.4-.414-.914-.673-2.181-.742-3.937-.257-6.741 3.9-12.269 8.197-12.306 4.292-.042 7.289 5.411 7.354 12.156zm-6.634-3.529a2.195 2.195 0 1 0-.122-4.388 2.195 2.195 0 0 0 .122 4.388z" id="jkpath56" fill="#2d3136"/><circle transform="rotate(-1.473 76.78 115.216)" class="jkst8" cx="76.79" cy="115.23" id="jkellipse58" r="2.195" fill="#edf6fa"/><g class="jkst9" id="jkg64" opacity=".8"><path class="jkst6" d="M50.691 75.155s.667-8.692 2.03-12.023c.702-1.717 4.996-2.81 8.276-3.591 3.278-.78 8.508-2.342 9.524 2.264 1.015 4.606 2.653 7.963 3.746 9.446l-1.404-18.97-22.562 5.464-1.484 16.786.703 1.327 1.171-.703" id="jkpath60" fill="#ebd599"/><path class="jkst6" d="M164.855 75.155s-.666-8.692-2.029-12.023c-.703-1.717-4.997-2.81-8.275-3.591-3.28-.78-8.51-2.342-9.526 2.264-1.013 4.606-2.654 7.963-3.748 9.446l1.407-18.97 22.562 5.464 1.483 16.786-.703 1.327-1.171-.703" id="jkpath62" fill="#ebd599"/></g><path class="jkst10" d="M132.965 18.378s-.598 45.49-11.224 45.49h-14.875-12.752c-10.626 0-11.484-45.47-11.484-45.47l-5.22 15.438.085 21.183 3.707 2.947 1.685 9.096 2.357 5.307 45.482.084 2.105-3.791 1.769-6.4.254-4.043 5.023-14.341z" id="jkpath66" opacity=".75" fill="#ebd599"/><path class="jkst10" d="M166.429 60.794s2.187 15.692 7.974 18.522c5.788 2.829 0 0 0 0l-8.103-2.444z" id="jkpath68" opacity=".75" fill="#ebd599"/><path class="jkst10" d="M48.908 60.794s-2.187 15.692-7.975 18.522c-5.788 2.829 0 0 0 0l8.104-2.444z" id="jkpath70" opacity=".75" fill="#ebd599"/><path class="jkst7" d="M167.987 76.8c2.755.902 5.526 1.858 8.036 3.325-1.343-.532-2.729-.913-4.126-1.257a70.385 70.385 0 0 0-4.201-.924c-2.82-.531-5.65-.982-8.498-1.327-2.841-.37-5.687-.682-8.546-.924-2.858-.241-5.709-.483-8.573-.65-11.446-.704-22.924-.88-34.41-.892-11.483.006-22.962.221-34.409.897-2.862.166-5.715.409-8.572.651-2.857.241-5.71.548-8.546.923-2.847.345-5.678.796-8.498 1.327-1.407.264-2.81.57-4.206.919-1.391.344-2.783.725-4.126 1.257 2.509-1.466 5.28-2.427 8.041-3.331.232-.075.467-.139.703-.214-.015-.059-.032-.113-.043-.177-.048-.317-1.069-7.859.709-18.645.086-.516.456-.935.962-1.075l2.917-.831c.634-22.625 9.952-33.266 10.243-33.594-8.326 13.397-8.25 29.286-8.106 32.986l18.128-5.152c.016-.005.026-.005.042-.01.076-.016.151-.027.226-.032.021 0 .049-.006.075-.006a1.19 1.19 0 0 1 .297.027c.015 0 .031.011.053.016.075.016.145.042.224.075.033.016.054.033.086.049.058.033.119.07.177.112.016.011.034.016.049.033l.032.032c.016.016.037.027.054.044.012.016.494.493 1.262 1.209-.182-5.973.102-23.108 8.262-37.31-.172.498-6.646 19.428-4.415 40.645.724.58 1.486 1.149 2.229 1.649.359.247.58.655.585 1.09.006.07.161 6.833 3.148 12.586.042.086.074.177.102.268 7.429-.505 14.878-.709 22.312-.714 7.436.005 14.88.22 22.307.731.027-.097.06-.193.109-.285 2.986-5.753 3.142-12.516 3.142-12.586.01-.436.231-.843.591-1.09.741-.5 1.493-1.069 2.224-1.649 2.234-21.217-4.24-40.147-4.411-40.645 8.153 14.201 8.444 31.336 8.262 37.31a62.536 62.536 0 0 0 1.261-1.209c.016-.016.039-.027.053-.044.012-.01.018-.021.033-.032.016-.016.033-.022.049-.033.06-.042.119-.079.177-.118.028-.01.054-.027.081-.043.081-.033.155-.059.236-.08.016 0 .033-.011.049-.011.096-.021.2-.032.296-.027.027 0 .049.006.07.006.075.005.156.016.231.032.012.006.028.006.042.01l18.129 5.152c.146-3.7.221-19.59-8.104-32.986.289.328 9.609 10.969 10.237 33.594l2.922.831c.499.14.875.559.962 1.075 1.777 10.786.752 18.328.708 18.645-.01.065-.026.124-.042.182.239.07.47.139.707.215zm-3.297-.968c.14-1.207.789-7.809-.591-16.801l-20.52-5.833c.184 3.475.265 11.012-1.707 18.199a1.619 1.619 0 0 1-.101.258c.203.021.408.037.606.064 5.769.661 11.511 1.584 17.189 2.83 1.712.398 3.426.823 5.124 1.283zm-25.409-5.151c1.688-6.15 1.779-12.72 1.655-16.345-1.353 1.23-3.197 2.809-5.049 4.125-.114 1.896-.64 7.278-3.052 12.332 2.149.173 4.298.366 6.446.591a1.33 1.33 0 0 1 0-.703zm-56.78.098c-2.408-5.05-2.934-10.422-3.046-12.317-1.858-1.316-3.696-2.895-5.049-4.125-.119 3.631-.032 10.206 1.654 16.345.065.237.058.473 0 .694 2.145-.227 4.292-.425 6.441-.597zm-8.933.864a1.65 1.65 0 0 1-.098-.247c-1.975-7.187-1.889-14.723-1.712-18.199L51.244 59.03c-1.38 8.982-.736 15.583-.597 16.797 1.703-.462 3.411-.887 5.131-1.284 2.835-.628 5.693-1.154 8.556-1.638 2.869-.478 5.747-.843 8.626-1.192.205-.027.404-.042.608-.07z" id="jkpath72" fill="#2d3136"/><g id="jkXMLID_1_"><g id="jkg78"><path class="jkst7" d="M129.293 18.973v17.025h-12.068v-4.974h-2.72v22.981h4.109v12.85H97.505v-12.85h4.092v-22.98h-2.711v4.974h-12.06V18.973zm-3.626 13.408v-9.789H90.443v9.789h4.816v-4.974h9.964v30.225h-4.1v5.606h13.865v-5.606h-4.1V27.407h9.964v4.974z" id="jkpath74" fill="#2d3136"/><path class="jkst0" id="jkpolygon76" fill="#cb3349" d="M101.123 57.632h4.1V27.407h-9.964v4.974h-4.816v-9.79h35.224v9.79h-4.816v-4.974h-9.964v30.225h4.1v5.606h-13.864z"/></g></g><path class="jkst3" d="M30.694 93.119c1.759-.399 4.136-.907 7.051-1.47a104.37 104.37 0 0 0-6.222 4.597z" id="jkpath83" fill="#656c67"/><path class="jkst5" d="M95.111 139.78s.492 3.165-3.938 4.519c-4.428 1.355-32.482 9.716-35.682 9.263-3.199-.451-11.319-5.874-11.319-5.874l-1.969-7.004 12.016 7.492z" id="jkpath85" fill="#c7b39a"/><path class="jkst5" d="M120.242 139.167s-.354 3.182 4.131 4.345c4.484 1.161 32.875 8.295 36.05 7.704 3.176-.591 11.053-6.361 11.053-6.361l1.663-7.084-11.045 6.588z" id="jkpath87" fill="#c7b39a"/><path class="jkst5" d="M28.412 133.956s3.887 7.775 10.166 5.083l4.485 1.645-.448 3.29-9.419 1.195-2.541-1.494z" id="jkpath89" fill="#c7b39a"/><path class="jkst5" d="M187.551 131.822s-6.353 8.115-12.632 5.424l-2.019 1.302.448 3.289 9.419 1.196 2.54-1.495z" id="jkpath91" fill="#c7b39a"/><path class="jkst5" d="M89.279 192.904s23.03 11.611 49.106-4.188l-8.374-.571s-18.272 7.232-32.738 3.235z" id="jkpath93" fill="#c7b39a"/><path class="jkst7" d="M112.626 171.509l1.594 1.899c.036.046 3.577 4.26 7.906 8.552 2.879 2.853 6.357 4.297 10.343 4.297 1.361 0 2.791-.175 4.235-.523 1.34-.326 2.796-.673 4.287-1.03 5.384-1.287 11.482-2.749 14.438-3.577.585-.166 1.238-.315 1.925-.472 3.935-.909 9.329-2.163 12.187-7.889 2.149-4.297 5.047-9.874 7.197-13.961-1.863.859-3.816 1.79-5.203 2.52-2.138 1.123-4.938 1.667-8.558 1.667-2.152 0-4.266-.181-6.605-.389-4.675-.43-12.586-1.361-12.667-1.372l-.606-.067-.478-.383c-.071-.052-7.003-5.575-12.606-9.981-.227-.186-.434-.358-.621-.513-.59-.503-.59-.503-.942-.503-1.797 0-7.02 1.62-18.462 5.167l-.703.223-.689-.26c-.078-.026-7.585-2.81-16.581-2.81-.736 0-1.47.019-2.185.056-.901.046-5.958 2.448-12.425 12.68l-.419.657-.741.238c-.107.037-11.238 3.63-23.042 7.005l-.766.218-.725-.337c-.077-.031-4.696-2.174-9.091-4.194 2.397 3.541 5.462 7.958 8.159 11.422 4.711 6.067 10.649 11.674 22.034 11.674 1.428 0 2.945-.088 4.503-.265 11.581-1.309 14.563-1.837 16.168-2.117.543-.092.973-.171 1.522-.238.088-.011 9.571-1.237 12.232-7.206 2.744-6.134 3.298-7.595 3.319-7.651l.968-2.583s.12-.669.317-.877c0 .005 0 .005.005.005l.019.016c.305.219.757.902.757.902zM40.499 55.71c-2.516 1.014-5.016 2.06-7.46 3.209-2.449 1.119-4.856 2.32-7.155 3.66-2.121 1.222-4.157 2.563-5.954 4.076-.077.455-.149.952-.211 1.423a51.357 51.357 0 0 0-.388 6.068c-.026 2.713.16 5.426.502 8.112.372 2.692.864 5.369 1.594 7.952a41.963 41.963 0 0 0 1.243 3.804c.233.623.492 1.228.762 1.818.134.294.274.585.413.864l.172.326c.201.104.409.207.605.3l1.206.574c.673.311 1.6.751 2.366 1.093.046-.037.088-.078.124-.114l-2.231-8.511c.471-.129 4.717-1.227 12.032-2.619a33.744 33.744 0 0 1-1.775-.379 36.704 36.704 0 0 1-4.898-1.563 22.857 22.857 0 0 1-2.309-1.119c-.741-.425-1.471-.905-2.035-1.547 8.035 2.624 24.637 1.433 39.398-.088 13.501-1.393 27.028-2.293 40.628-2.325 13.6.031 27.138.931 40.63 2.325 14.77 1.522 31.374 2.713 39.406.088-.564.642-1.293 1.122-2.034 1.547-.739.42-1.522.782-2.309 1.119a36.965 36.965 0 0 1-4.903 1.563c-.244.056-.492.114-.741.166 8.02 1.486 12.689 2.697 13.186 2.832l-2.138 8.107c.43-.192.864-.377 1.288-.574l1.207-.574c.196-.094.404-.196.606-.3l.166-.326c.144-.279.284-.57.419-.864.27-.591.528-1.196.767-1.818.471-1.231.879-2.51 1.236-3.804.731-2.583 1.228-5.26 1.595-7.952.346-2.686.528-5.4.502-8.112a52.755 52.755 0 0 0-.176-4.059 51.573 51.573 0 0 0-.213-2.009 29.83 29.83 0 0 0-.213-1.423c-1.797-1.513-3.831-2.853-5.954-4.076-2.299-1.34-4.704-2.541-7.159-3.66-2.438-1.149-4.943-2.195-7.46-3.209a140.105 140.105 0 0 0-3.801-1.476c-1.267-.491-2.552-.956-3.835-1.423 2.696.445 5.369 1.06 8.013 1.739 1.724.446 3.444.948 5.141 1.481-12.11-31.658-41.07-52.272-72.685-52.272-31.622 0-60.576 20.614-72.684 52.272a107.832 107.832 0 0 1 5.135-1.481c2.651-.678 5.322-1.294 8.02-1.739-1.29.466-2.568.931-3.842 1.423-1.268.47-2.535.967-3.799 1.475zm159.43 18.316a53.972 53.972 0 0 1-.258 8.733 55.462 55.462 0 0 1-1.619 8.605c-.4 1.414-.86 2.811-1.404 4.198a38.295 38.295 0 0 1-.89 2.071c-.161.341-.331.678-.523 1.025l-.284.512a8.975 8.975 0 0 1-.348.574l-.294.457-.461.237c-.492.254-.895.445-1.342.653l-1.298.585a88.22 88.22 0 0 1-2.62 1.065c-.611.239-1.15.457-1.662.674l-1.444 5.487c-.036-.009-.471-.12-1.283-.315l-.078.574c1.594.833 4.726 2.522 5.793 3.403 2.148 1.775 2.299 4.587 1.823 9.841-.244 2.697-1.139 7.946-2.381 12.767-2.144 8.298-3.283 9.273-4.753 9.649-.746.192-1.894.383-3.008.383-2.266 0-5.353.063-7.429-.439-.533 1.888-2.055 6.812-5.068 12.962.151-.073.3-.135.435-.207 3.717-1.952 10.861-5.064 11.162-5.199l5.643-2.452-2.89 5.435c-.067.118-6.264 11.773-10.059 19.383-3.769 7.538-10.835 9.179-15.065 10.151-.637.151-1.241.291-1.733.425-3.035.854-9.18 2.319-14.599 3.623-.064.016-.13.033-.197.042a64.057 64.057 0 0 1-10.955 5.411c-14.568 5.518-29.923 5.208-43.844.092a647.05 647.05 0 0 1-9.193 1.097 45.12 45.12 0 0 1-4.985.291c-13.264 0-20.294-6.736-25.425-13.331-5.493-7.062-12.212-17.546-12.497-17.985L31 158.426l6.585 2.961c3.152 1.419 12.524 5.757 15.205 7 .217-.061.43-.124.642-.186-4.457-6.357-8.112-13.605-10.695-21.634-2.195.662-5.576 1.175-8.206 1.175-.961 0-1.822-.072-2.484-.228-1.471-.336-3.148-1.754-5.431-9.795-1.325-4.668-2.314-9.764-2.603-12.387-.57-5.121-.466-7.864 1.662-9.636 1.283-1.071 5.611-3.344 6.507-3.809l-.192-1.58c-13.75 8.08-21.991 15.22-22.157 15.366L0 134.302l7.005-11.047c5.544-8.755 11.948-15.832 17.84-21.284-.244-.098-.471-.196-.71-.294l-1.299-.585a34.907 34.907 0 0 1-1.34-.653l-.461-.237-.295-.457c-.166-.249-.238-.388-.347-.574l-.29-.512c-.181-.347-.358-.684-.518-1.025a30.878 30.878 0 0 1-.89-2.071 44.74 44.74 0 0 1-1.404-4.198 54.745 54.745 0 0 1-1.62-8.605 54.664 54.664 0 0 1-.259-8.733c.078-1.455.218-2.909.419-4.354.104-.725.213-1.45.358-2.17.15-.734.296-1.418.518-2.221l.155-.564.404-.317c2.294-1.802 4.768-3.163 7.284-4.369a78.87 78.87 0 0 1 6.311-2.616c5.943-16.493 16.162-31.118 29.591-41.311C74.337 5.57 90.664 0 107.671 0s33.334 5.57 47.218 16.106c13.43 10.193 23.649 24.819 29.588 41.307a78.282 78.282 0 0 1 6.316 2.62c2.515 1.206 4.99 2.567 7.283 4.369l.404.317.156.564c.227.803.372 1.487.517 2.221.146.72.26 1.445.357 2.17.203 1.443.348 2.897.419 4.352zm-11.995 48.031c.456-5.052.058-6.139-.455-6.554-.513-.43-2.247-1.412-3.935-2.329l-2.779 19.464a1.39 1.39 0 0 1-.58.942l-3.977 2.781c-.315 1.593-.429 2.345-.817 3.903 2.273.528 5.999.938 7.775.595 1.612-1.748 4.214-12.61 4.768-18.802zm-5.161-17.648l2.977-11.29c-4.318-.978-12.27-2.615-23.1-4.148-5.53 3.976-11.582 7.155-17.53 9.691 18.199 1.771 31.57 4.406 37.653 5.747zm-4.68 27.237l3.385-23.676a240.127 240.127 0 0 0-5.731-1.169l-3.059 21.422a1.415 1.415 0 0 1-.575.943l-11.472 8.023c-.27.192-.616.28-.947.243l-34.572-3.929a1.391 1.391 0 0 1-1.176-.973l-6.227-20.5c-1.668-.431-5.949-1.43-9.696-1.43-3.764 0-8.041.999-9.708 1.43l-6.228 20.5a1.388 1.388 0 0 1-1.025.947l-34.572 7.692a1.483 1.483 0 0 1-.306.033 1.36 1.36 0 0 1-.792-.25l-11.467-8.029a1.396 1.396 0 0 1-.585-.968l-3.091-25.072c-1.284.249-2.443.487-3.479.703-.734.405-1.46.809-2.174 1.213l3.281 26.568 16.666 11.675 42.047-9.354 6.207-20.449a1.389 1.389 0 0 1 1.108-.975c1.574-.253 2.95-.382 4.116-.382 1.153 0 2.536.129 4.105.382.528.083.957.461 1.108.975l6.366 20.956 42.282 4.808zm-8.07-4.411l2.992-20.948c-8.439-1.536-20.78-3.394-35.897-4.554-13.647 4.707-25.077 6.108-25.766 6.155l-.797.057c4.353.374 8.454 1.544 8.66 1.605.452.135.804.481.944.933l6.186 20.366 33.138 3.764zm2.303 11.845l-1.404.983-3.779 2.651-4.095 2.868c-.279.192-.621.28-.954.243l-40.746-4.633-2.966-.337a1.39 1.39 0 0 1-1.171-.977l-6.377-20.998c-1.066-.145-2.014-.219-2.81-.219-.809 0-1.751.073-2.817.219l-6.192 20.392a1.383 1.383 0 0 1-1.025.946l-43.435 9.672c-.103.02-.206.03-.305.03-.279 0-.559-.083-.798-.253l-1.578-1.098-4.726-3.307v-.011l-1.91-1.335c.135.43.289.85.441 1.268l-.006.006c.368 1.092 4.028 11.622 11.467 21.929a873.96 873.96 0 0 0 17.057-5.234c4.488-6.917 10.877-13.777 15.418-14.014a51.12 51.12 0 0 1 2.402-.061c2.221 0 4.344.16 6.31.393-1.671-1.517-2.013-3.298-2.256-4.085 0 0 5.793 4.53 13.17 3.584 7.378-.953 11.959-5.204 11.959-5.204s-.021 3.102-3.236 5.503c6.182-1.869 8.739-2.511 10.489-2.511 1.931 0 2.883.808 3.717 1.519.161.129.322.268.507.419a3519.302 3519.302 0 0 1 12.141 9.614c1.936.227 8.075.926 11.943 1.283 2.23.201 4.245.372 6.217.372.637 0 1.233-.026 1.797-.063 2.558-4.88 4.857-10.411 6.808-16.653.261-.96.516-1.928.743-2.901zm-15.034-51.593c-.01-.006-.02-.012-.031-.012a551.624 551.624 0 0 0-9.826-.651 905.6 905.6 0 0 0-13.667-.668 72.95 72.95 0 0 1-1.574 2.225c-2.479 3.355-7.398 9.51-13.704 14.729 8.926-1.6 24.409-5.56 37.803-14.905.336-.238.668-.486.999-.718zm-29.876.926c.377-.471.729-.926 1.044-1.34-3.281.331-6.512.808-9.67 1.408-10.814 2.024-20.801 5.389-29.11 8.837a383.259 383.259 0 0 1 18.54-.455c3.908 0 7.708.067 11.404.176 3.179-3.056 5.861-6.182 7.792-8.626zm3.587 102.085c-4.503-.332-8.598-2.205-11.903-5.477a271.86 271.86 0 0 0-.502-.512 44.25 44.25 0 0 1-4.881.704c-.698.026-1.361.087-2.091.087l-1.083.011-.413-.011c-4.396 6.539-14.159 7.813-14.605 7.87-.403.046-.734.103-1.191.186 5.442 1.491 10.996 2.138 16.474 1.77 5.492-.367 12.627-1.558 20.195-4.628zm-17.4-7.461a45.604 45.604 0 0 0 3.184-.378 138.958 138.958 0 0 1-3.568-3.857 398.441 398.441 0 0 1-1.92 4.339h.243c.658.001 1.378-.071 2.061-.104zm-3.354-78.632c1.827-1.103 3.582-2.366 5.249-3.712a422.33 422.33 0 0 0-7.278-.072c-10.137 0-19.606.415-28.189 1.061-8.61 4.209-13.875 7.672-13.998 7.76l-8.268 5.514 5.679-8.149a52.452 52.452 0 0 1 2.956-3.857c-9.536 1.066-17.477 2.329-23.41 3.422l3.038 24.632 10.453 7.321 33.184-7.378 6.212-20.464c.104-.337.331-.621.627-.793.098-.063.202-.109.315-.14.192-.052 3.51-.999 7.336-1.465zm3.816-18.788c-2.31-.036-4.623-.057-6.933-.062h-.005c-3.39.005-6.787.041-10.189.109l-6.269 2.971c-.005.005-.041.021-.088.048-.942.46-9.174 4.613-16.919 12.021 6.943-3.65 17.146-8.418 29.153-12.115a144.186 144.186 0 0 1 11.25-2.972zM70.251 98.761c3.251-3.225 6.605-5.886 9.567-7.967-11.415 2.651-21.923 6.543-31.128 10.778a360.846 360.846 0 0 1 21.561-2.811zm2.159-9.949a150.122 150.122 0 0 1 11.813-2.796c-5.798.212-11.6.481-17.393.808-3.366.186-6.715.414-10.065.667-1.678.129-3.345.263-5.007.445-.476.046-.942.098-1.418.16-4.369 2.614-21.127 13.134-32.631 26.889 11.179-7.769 30.654-19.443 54.701-26.173zm-30.85 54.197a68.861 68.861 0 0 1-.621-2.102l-5.162-3.612a1.391 1.391 0 0 1-.586-.969l-2.516-20.449c-1.864.999-4.017 2.225-4.592 2.707-.497.409-.875 1.46-.336 6.332.668 6.01 3.712 17.333 5.348 18.979 1.968.347 6.327-.258 8.465-.886zm-3.815-51.36a229.005 229.005 0 0 0-7.051 1.47l.829 3.127a103.93 103.93 0 0 1 6.222-4.597z" id="jkpath95" fill="#2d3136"/></g></g></symbol><symbol viewBox="0 0 24 24" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="tune" xmlns="http://www.w3.org/2000/svg"><path d="M6.85 2.852h-2v6h2v-6m12 0h-2v10h2v-10m-16 10h2v8h2v-8h2v-2h-6v2m12-6h-2v-4h-2v4h-2v2h6v-2m-4 14h2v-10h-2v10m4-6v2h2v4h2v-4h2v-2h-6z" fill="#fbc02d" fill-rule="nonzero"/></symbol><symbol viewBox="0 0 50 50" id="twig" xmlns="http://www.w3.org/2000/svg"><path d="M9.727 47.556c-.125-.223-.297-2.168-.183-2.087.034.025.171.267.304.537.132.27.282.487.332.482.123-.011.075-1.196-.1-2.454-.331-2.398-1.176-4.435-2.358-5.69-.2-.212-.344-.4-.319-.419.093-.067 1.327.843 1.842 1.359.293.293.735.825.981 1.181.328.474.465.618.51.534.078-.147-.21-9.903-.376-12.701-.074-1.255.063-1.023.61 1.035 1.064 4.006 1.858 7.922 2.342 11.55.086.637.173 1.172.195 1.19.022.016.092.001.157-.034.888-.483 1.524-.667 2.55-.736.727-.048.945.062.35.178-1.15.222-1.99 1.013-2.344 2.201-.315 1.061-.327 2.707-.024 3.434.152.366.037.426-1.067.56-.716.088-.977.096-1.202.037-.356-.092-1.118-.098-1.195-.008-.031.036-.243.066-.47.066-.38 0-.423-.017-.535-.215zm1.974-3.233c.152-.205.072-.41-.204-.522-.225-.09-.263-.088-.437.025-.21.137-.252.43-.08.554.18.13.607.096.72-.057zm1.248.086a.763.763 0 0 0 .214-.203c.241-.33-.352-.622-.745-.366-.406.265.08.785.531.569zm2.288 3.094c-.033-.039.117-.387.334-.775.216-.387.411-.665.433-.618.07.152-.201 1.28-.33 1.372-.15.108-.354.117-.437.02zM8.2 47.092c-.29-.343-.221-.434.14-.182.176.123.321.263.321.31 0 .165-.279.087-.46-.128zm8.649-.145c0-.053.102-.18.227-.282.25-.204.312-.113.143.207-.095.18-.37.236-.37.075zm8.065-.827c-.243-.025-.48-.088-.527-.141-.11-.125-.114-3.043-.004-3.043.045 0 .132.149.193.331.127.38.228.42.31.124.094-.337.065-3.472-.039-4.297-.449-3.55-1.865-6.124-4.342-7.89-1.086-.774-2.653-1.436-4.047-1.711-.764-.15-.522-.224.598-.182 2.364.089 4.167.706 5.847 2.001a11.046 11.046 0 0 1 2.32 2.502c.453.682.64.854.64.584 0-.07.063-.882.139-1.805.679-8.26 2.396-15.1 4.984-19.86 1.86-3.422 5.108-6.817 7.885-8.244 1.397-.718 2.539-.988 4.02-.952.933.023 1.01.036 1.77.307a6.822 6.822 0 0 1 1.363.662c.612.407 1.309 1.004 1.235 1.058-.026.018-.343-.165-.705-.407-2.657-1.771-5.062-1.52-7.12.742-1.108 1.22-2.651 3.53-3.634 5.443-2.828 5.503-4.541 11.464-5.291 18.413-.163 1.509-.282 3.76-.195 3.703.032-.022.266-.52.518-1.108 1.597-3.723 3.578-6.428 5.79-7.908.672-.449 1.612-.904 1.715-.83.022.016-.172.22-.432.454-1.957 1.754-3.248 3.76-4.232 6.572-.938 2.68-1.366 5.588-1.368 9.3-.002 1.741.188 4.385.366 5.101.125.505.08.546-.585.546-.55 0-2.306.138-3.416.27-.414.05-.817.04-1.609-.036-.58-.056-1.129-.119-1.218-.14-.165-.037-.18-.014-.2.302-.01.186-.098.203-.728.139zm2.507-6.725c.294-.11.375-.22.375-.517 0-.63-1.309-.706-1.524-.088-.074.211.13.51.42.616.297.108.413.106.73-.011zm2.369-.052c.277-.222.318-.364.174-.611-.4-.691-1.755-.307-1.428.404.121.266.299.35.738.354.227 0 .387-.045.516-.147zm3.011 6.681c-.027-.05.088-.268.256-.484.879-1.135 1.22-1.544 1.284-1.544.04 0 .056.037.036.082l-.423.964c-.212.485-.445.924-.519.977-.169.122-.57.125-.634.005zm2.446-.596c0-.121.853-.683.896-.59.018.04-.056.209-.166.376-.168.259-.238.305-.464.305-.164 0-.266-.035-.266-.091zm-13.04-.124c-.177-.159-.493-.656-.462-.725.018-.038.248.1.512.309.264.207.457.405.428.438-.075.088-.371.074-.478-.022z" fill="#9bb92f" stroke-width=".078"/></symbol><symbol viewBox="0 0 500 500" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="typescript" xmlns="http://www.w3.org/2000/svg"><path d="M49 51h408v408H49V51zm246.669 314.879l19.463-1.702c.922 7.8 3.067 14.199 6.435 19.198 3.368 4.998 8.597 9.04 15.688 12.124 7.09 3.085 15.067 4.627 23.93 4.627 7.87 0 14.819-1.17 20.845-3.51 6.027-2.34 10.512-5.548 13.455-9.625 2.942-4.077 4.413-8.526 4.413-13.348 0-4.892-1.418-9.164-4.254-12.816-2.836-3.651-7.516-6.718-14.039-9.2-4.183-1.63-13.436-4.165-27.759-7.604s-24.355-6.683-30.099-9.732c-7.445-3.899-12.993-8.739-16.644-14.517-3.652-5.779-5.478-12.249-5.478-19.41 0-7.871 2.234-15.227 6.701-22.069 4.467-6.842 10.99-12.036 19.569-15.581 8.58-3.546 18.116-5.318 28.61-5.318 11.557 0 21.75 1.861 30.577 5.584 8.828 3.722 15.617 9.199 20.368 16.432 4.75 7.232 7.303 15.421 7.657 24.568l-19.782 1.489c-1.064-9.856-4.662-17.301-10.795-22.335-6.133-5.034-15.191-7.551-27.174-7.551-12.479 0-21.573 2.286-27.281 6.86-5.707 4.573-8.561 10.086-8.561 16.538 0 5.602 2.021 10.21 6.062 13.826 3.971 3.617 14.34 7.321 31.109 11.115 16.769 3.793 28.273 7.108 34.513 9.944 9.076 4.183 15.776 9.483 20.101 15.9 4.325 6.417 6.488 13.809 6.488 22.175 0 8.296-2.375 16.113-7.126 23.452-4.751 7.338-11.575 13.046-20.474 17.123-8.898 4.077-18.913 6.116-30.045 6.116-14.11 0-25.933-2.056-35.47-6.169-9.537-4.112-17.017-10.299-22.441-18.559-5.424-8.26-8.278-17.602-8.562-28.025zm-65.728 50.094V278.454h51.583v-18.399H157.938v18.399h51.37v137.519h20.633z" fill="#0288d1"/></symbol><symbol viewBox="0 0 500 500" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" id="typescript-def" xmlns="http://www.w3.org/2000/svg"><path d="M457 459H49V51h408v408zM69 71v368h368V71H69z" fill="#0288d1"/><text x="342.219" y="344.544" font-family="ArialMT" font-size="12" fill="#0288d1" transform="translate(-6058.94 -5838) scale(18.1514)"><tspan style="-inkscape-font-specification:sans-serif" font-family="sans-serif" font-weight="400">TS</tspan></text></symbol><symbol viewBox="0 0 24 24" id="url" xmlns="http://www.w3.org/2000/svg"><path d="M16 6h-3v1.9h3a4.1 4.1 0 0 1 4.1 4.1 4.1 4.1 0 0 1-4.1 4.1h-3V18h3a6 6 0 0 0 6-6c0-3.32-2.69-6-6-6M3.9 12A4.1 4.1 0 0 1 8 7.9h3V6H8a6 6 0 0 0-6 6 6 6 0 0 0 6 6h3v-1.9H8c-2.26 0-4.1-1.84-4.1-4.1M8 13h8v-2H8v2z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="verilog" xmlns="http://www.w3.org/2000/svg"><path d="M17.282 17.08H6.718V6.513h10.564m4.226 4.226V8.627h-2.113V6.514c0-1.173-.95-2.113-2.113-2.113H15.17V2.288h-2.113v2.113h-2.112V2.288H8.83v2.113H6.718c-1.173 0-2.113.94-2.113 2.113v2.113H2.492v2.113h2.113v2.113H2.492v2.113h2.113v2.113a2.113 2.113 0 0 0 2.113 2.113H8.83v2.113h2.113v-2.113h2.112v2.113h2.113v-2.113h2.113a2.113 2.113 0 0 0 2.113-2.113v-2.113h2.113v-2.113h-2.113V10.74m-6.339 2.113h-2.112V10.74h2.112m2.113-2.113H8.831v6.34h6.338z" fill="#ff7043" stroke-width="1.056"/></symbol><symbol viewBox="0 0 24 23.999999" id="vfl" xmlns="http://www.w3.org/2000/svg"><defs><style>.jra{fill:#f05223}.jrb{fill:url(#jra)}</style><radialGradient id="jra" cx="205.45" cy="208.29" r="225.35" gradientTransform="matrix(.04556 0 0 .0456 2.888 2.88)" gradientUnits="userSpaceOnUse"><stop stop-color="#ffd104" offset="0"/><stop stop-color="#faa60e" offset=".35"/><stop stop-color="#f05023" offset="1"/></radialGradient></defs><title>houdinibadge</title><g stroke-width=".046"><path class="jra" d="M19.97 3H4.03A1.03 1.031 0 0 0 3 4.031v4.135C4.548 6.977 6.563 6.21 8.948 6.21c5.107.003 8.35 3.574 8.348 8.081 0 3.13-1.46 5.485-3.746 6.71h6.42A1.03 1.031 0 0 0 21 19.968V4.031a1.03 1.031 0 0 0-1.03-1.03z" fill="#f4511e"/><path class="jrb" d="M3 17.722v2.247A1.03 1.031 0 0 0 4.03 21h1.837C4.474 20.21 3.49 19 3 17.722z" fill="url(#jra)"/><path class="jra" d="M8.948 8.231c-2.586-.09-4.598.86-5.948 2.264v3.163c.918-2.654 3.447-3.87 5.565-3.85 2.647.027 4.689 2.025 4.7 4.284.012 2.159-.892 3.748-3.33 4.14-1.33.213-3.411-.567-3.318-2.578.046-1.037.854-1.622 1.777-1.58-.905 1.213.293 2.102 1.139 1.921 1.048-.224 1.475-1.156 1.475-1.878 0-.762-.718-1.994-2.498-1.951-2.204.052-3.591 1.639-3.638 3.602-.056 2.468 2.253 4.091 4.622 4.121 3.48.046 5.543-2.24 5.539-5.586-.005-3.029-2.434-5.946-6.085-6.072z" fill="#f05223"/></g></symbol><symbol viewBox="0 0 24 24" id="virtual" xmlns="http://www.w3.org/2000/svg"><path d="M21 14H3V4h18m0-2H3c-1.11 0-2 .89-2 2v12a2 2 0 0 0 2 2h7l-2 3v1h8v-1l-2-3h7a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 281.25 281.25" id="visualstudio" xmlns="http://www.w3.org/2000/svg"><path d="M196.18 101.74l-52.778 42.444 52.778 40.889V101.74m-136.67 110l-30-18.889v-100L62.843 81.74l47.778 37 96.666-89.222 44.444 27.778v172.22l-55.555 22.222-85.111-81.555-51.555 41.555m3.333-48.889l20.667-19.111-20.667-19.778z" fill="#ab47bc" stroke-width="11.111"/></symbol><symbol viewBox="0 0 300 300" id="vscode" xmlns="http://www.w3.org/2000/svg"><defs><style>.icon-canvas-transparent{fill:#f6f6f6;opacity:0}.icon-white{fill:#fff}</style></defs><title>BrandVisualStudioCode</title><path d="M218.62 29.953l-105.41 96.92L54.301 82.47 29.955 96.64l58.068 53.359-58.068 53.359 24.346 14.212 58.909-44.402 105.41 96.878 51.424-24.976V54.93zm0 63.744v112.6l-74.719-56.302z" fill="#2196f3" stroke-width="17.15"/></symbol><symbol viewBox="0 0 24 24" id="vue" xmlns="http://www.w3.org/2000/svg"><path d="M1.821 4.15l10.21 17.618L22.24 4.235V4.15h-7.692L12.113 8.33 9.691 4.15H1.82z" fill="#41b883"/><path d="M5.937 4.15l6.152 10.616 6.18-10.617h-3.722l-2.434 4.179-2.422-4.179H5.937z" fill="#35495e"/></symbol><symbol viewBox="0 0 420 419" id="watchman" xmlns="http://www.w3.org/2000/svg"><g stroke="#fff" stroke-linecap="round" stroke-linejoin="bevel"><path d="M166.95 145.32a93.935 123.23 0 0 1 92.934 3.263" fill="none" stroke-width="18.467"/><path d="M162.92 137.96L44.63 256.25a174.07 173.93 0 0 0 5.705 16.486l123.68-123.68-11.096-11.096zM266.54 144.04l-11.096 11.096 117.16 117.16a174.07 173.93 0 0 0 5.691-16.5l-111.76-111.76zm170.65 170.65v22.193l17.1 17.1 11.096-11.098-28.195-28.195z" fill="#fff" stroke-width="1.963"/><path d="M167.52 273.36a93.935 123.23 0 0 1 92.934-3.263" fill="none" stroke-width="18.467"/><path d="M49.516 144.56a174.07 173.93 0 0 0-.809 2.213 174.07 173.93 0 0 0-4.757 14.344 174.07 173.93 0 0 0-.016.055l119.56 119.56 11.098-11.096-125.07-125.07zM454.87 64.703l-17.668 17.668v22.191l28.764-28.764-11.096-11.096zm-80.984 80.984l-117.86 117.86 11.098 11.096 112.18-112.18a174.07 173.93 0 0 0-5.416-16.777z" fill="#fff" stroke-width="1.963"/></g><image x="21.229" y="20.262" width="378" height="377.1" preserveAspectRatio="none" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAaQAAAGjCAYAAABjSWGNAAAgAElEQVR4AeydB3hUVdrH/+fOpNMF JAFUmivFXtZuIBRRQUUTil1RV3et6Lr6rSu6rg3B1dXVtXeBCCioCASIimLDhkFsgAIJSAkhPZmZ 8z3vjReGMJlMueeWmfc88MzMLaf8zp3855zznvcV4MQEkoxA7sVr01PrUrv4pdZNBNA1AHQRkJ0g ZAcJrYOA7Aipv8/Q6JgUKdBkG0iZISDSDVwSaAfAY3z+/bVSAD56L+mfwA5INAqgSkrUCKA2IOQO IcQOIUU5pNwhNZQLia2Q2OyH3OJBxqaiwk4VzfLlj0wg4QmIhG8hNzDJCEgxJH9DjgfevgGBAyCx vxSyh5DoAWA/CHQH0MEFUOoBbJbAeiHEBiED6wMSv0DgF02In1J2Vq+ZP78fXcOJCSQMARakhOnK 5GrICaO3tE3P8B0kERgkgP6Qop8E+gqgL4Bdo5gEphKAwHpIrIHAjxL4DpCrAo1yVfHsHhsSuN3c tAQmwIKUwJ2bGE2TYsjY33qLQOBwCHk4JA6HhgE08kmM9ilpRQUgvwPE1xD4MiC0r2R67dfFz/eq U1IaZ8oETCLAgmQSSM7GHAIj8td38sN7HAROkpDHATgMTWs15hSQvLn4JLBaQHwqEPgQQiwvmpHz XfLi4JY7kQALkhN7JYnqlDd2w4GQnuMk5AkCOBHAQQD4ubTgGZDAFg1ieQCBj6Dhg7SKmhW8LmUB eC6iRQL8xW8RDZ8wn4AUQ8eVHib9YjCELj4nAOhqfjmcY4wE6iGxAkIsCwDvSel5v7iwa1WMefFt TCBqAixIUSPjG6IhkDtmQw/N4xkKTQ4TEkNZgKKhZ/u1DZD4CAKLIMSik/p3WzF5sgjYXiuuQMIS YEFK2K61p2GTJ0tt2Xebj5EyMArAab+vAdlTGS7VVAI0xSeAd6QQb2uBtIW8V8pUvJwZz9XzM2AG AdpoKqpTh3uEdlYA8gwBdDEjX87D0QQaALlMCLzha5Rz2NTc0X3lmsrxCMk1XeWsig6/YFOWr0Ge JoBzICWNhNo6q4ZcGwsJkFOKT4TUZiOgzSqate8aC8vmohKIAAtSAnWm6qaMHPljWl2bzBGapk2A lKMBZKguk/N3JYHPpMCrHuGbuWj6fqWubAFX2hYCLEi2YHdToVIMKSg7SQAXABgDoJObas91tZWA H5DvCeCV2rrUwg/ndqm0tTZcuOMJsCA5vovsqeDwszd19af4LwbEZQAOtKcWXGoCEaiCwAwB7emi Gd0+TqB2cVNMJMCCZCJMt2dFFnIflJQNh8BEgKbkRIrb28T1dySBlULIpzyBwCsLCntud2QNuVK2 EGBBsgW7swqlvUIer+cSQE7UPWI7q3pcm8QlUAtgtibFU4sKu70PCJm4TeWWRUKABSkSSgl5DTkt 3XSqJuVfJDAiRFyfhGw1N8qxBH4AxJP+hrpnit/otcOxteSKKSXAgqQUr/My18216wMXCOB6AH9w Xg25RklOoEoI8bzw+R5ZNKvnj0nOIumaz4KUJF0+YsyWbL/Xdx0gr5BAxyRpNjfTvQQCkPIdDdqD iwqz33NvM7jm0RBgQYqGlguvbfKmrd2MJrPtNBc2gauc5ASElJ8EIO4/eWD2m+xLL7EfBhakBO3f wfmlR2oCtwI4G4CWoM3kZiURASmwGpAPVLTPeXnFk6IxiZqeNE1lQUqwrs4bW3Y0AoF/QIjT2Vdh gnUuN8cgsFYK3LNPoPzFwsKBDcZBfnU/ARYk9/eh3oIh+WXHaELeIZs8bCdIq7gZTCAsgXUQuK9T oPw5FqawnFxzkgXJNV0VuqJD8zcdDCHvlvpG1tDX8FEmkOAE1gohJp/Yv9vLvMbk7p5mQXJp/w0Z u7mPkP7JACbwGpFLO5GrbS4BiRII/H3xzOw3eZOtuWityo0FySrSJpWTO760s8cv7wQEeVVINSlb zoYJJBAB+bGQ4uaiwpxlCdSopGgKC5JLuvm4/PUZmcJ7NSD/DqCDS6rN1WQCdhKY45f+vxYX9vzJ zkpw2ZETYEGKnJVNV1L4h9JxAuI+9jNnUxdwsW4mQFZ4//E31N/NLomc340sSA7uo2H5Gw7zC+3f AjjFwdXkqjEBNxDYKgVuPbl/9rNs+ODc7mJBcmDf5J61toMnNfVfgLgCgNeBVeQqMQF3EpD4XGja NRyTyZndx4LkqH6RYkj+pouEkFMAdHZU1bgyTCBxCEgIPFvvabx52av7lydOs9zfEhYkh/Th0HM2 95Ye//8ADHVIlbgaTCDRCWwWENcWzcyemegNdUv7WJBs7qncXOnVum66XoBMuZFpc3W4eCaQdAQE xFyfz//n4tk9NiRd4x3WYBYkGzuEjBak0J6WwJE2VoOLZgJMANgJIW49qX+3J9jowb7HgQXJBva0 pyhLeO+QkJPYaMGGDuAimUDLBJYJgSuKZuR81/IlfEYVARYkVWRbyHfouLJcBPCUhOzbwiV8mAkw AXsJ1EOKe3Z07HYvh7mwtiNYkCzinXvx2nRvTdq9EriOw0JYBJ2LYQLxEfgCUlywuDB7VXzZ8N2R EmBBipRUHNcNGVt6hJB4CcCAOLLhW5kAE7CeQB1tqF0yI/thdtiqHj4LkkLG+fnSUy7KbpWQ/wBE isKiOGsmwASUEpBLPBouXji9+3qlxSR55ixIih6A3DEbemhe7WV2+6MIMGfLBKwnsA3AxMUzc96w vujkKJEFSUE/D87fOFoT4lkA+yjInrNkAkzAVgLyv/7MhknFz/eqs7UaCVg4C5KJnTpy5I9p9W3b TBGQf2HDBRPBclZMwHkEVnr8KFg4K2e186rm3hqxIJnUd0PGlO4vPHgdAkeZlCVnwwSYgLMJVEHI yxfP6D7d2dV0T+1YkEzoq6H5ZadLIV/gKToTYHIWTMBlBIQQj6bsrLpp/vx+9S6ruuOqy4IUR5fo VnRa2Z1S4jaeoosDJN/KBNxP4DMhcW5RYc6v7m+KfS1gQYqRvR6zKCXtVQiMjDELvo0JMIEEIiCB LR4p8hcVZr+XQM2ytCmapaUlSGF5+WUDvKnpn7EYJUiHcjOYgAkEBNAlIAKLho7deI0J2SVlFjxC irLbh+SXni0EXgTQJspb+XImwASShICAeC6lsuoqXleKrsNZkKLglVdQeiuAf/F6URTQ+FImkLwE lnkatXMWzun2W/IiiK7lLEgR8KL9RQ1tsyia60URXM6XMAEmwAQMAmsDHjFq6WvZJcYBfm2ZAAtS y2z0M7njSzt7/JgD4MRWLuXTTIAJMIFQBCqkkAVLZnRfGOokH9tNgI0adrPY611u/vq+Xr9YzmK0 Fxo+wASYQOQE2gsp3h4ytnRi5Lck55UsSC30+5D8smM8wvMhB9JrARAfZgJMIBoCXiHxVN7YjXcC kmemWiDHYEKAyRu76QzIALkDyQpxmg8xASbABGImQBZ4vt+6XVFcLHwxZ5KgN7IgNevYvPyNl0EI MmDwNDvFH5kAE2AC5hCQmJ9Zh3PnzcupMSfDxMiFp+yC+nFIQdlNEOIpFqMgKPyWCTAB8wkIjKxJ xyLy+GJ+5u7NkUdIet9JkVdQRvuLaJ8RJybABJiAVQS+9kvvqcWFXTdZVaCTy0l6QZo8WWrLVpU9 JoE/ObmjuG5MgAkkJgEB8ZNPw7Di6dnrErOFkbcqqQWJvHVvF2UU2fXCyJHxlUyACTAB0wn86pf+ vOLCnj+ZnrOLMkzaNaTcXOndLja9zGLkoqeVq8oEEpfAfh7hfW/4OaUHJW4TW29ZUo6Q8vNLUreh 42tCYEzriPgKJsAEmIBlBDZDiiGLC7NXWVaigwpKOkEiMSoXnQol5GgH9QNXhQkwASagE6C4SprU 8ooKu61MNiRJNWVH03Q0MmIxSrbHnNvLBNxDgOIqSREoGjq2tL97am1OTZNmhEQGDNtE6asCosAc dJwLE2ACTEAlAVkGIXMXz+jxg8pSnJR3UoyQfreme57FyEmPHteFCTCB8ARENqS2mJw8h78ucc4m gSBJUS7KHgVwfuJ0G7eECTCBJCHQwyM8i3LHbOiRDO1NeEEaMrbsHt70mgyPMreRCSQsgQM8Hu3d kfllXRK2hb83LKEFaUjBxluExN8SvRO5fUyACSQ4AYGBjQjMG5q/vX0itzRhBSlvbOmVAuLeRO48 bhsTYALJQ0AK8UcpamfT1pVEbXVCCtLg/I2jIfEYgKSxIkzUB5TbxQSYQDABMWS76Phsogb5SzhB Gjxu0x81IV7jEBLBDzG/ZwJMIIEInJc3tuyhBGrPrqYklCCReaQIBOYByNzVQn7DBJgAE0g0AhLX Dc0vTbj18YSZ0iILlEaBjyRk0tjsJ9p3jNvDBJhAVAQkpBy/uLD7jKjucvDFCTFCokW+Bsg3WIwc /KRx1ZgAEzCbgIAQz9IyhdkZ25VfAgiSFPoin8DxdkHkcpkAE2ACNhHI1AKBuYmycdb1gjS0oOz/ AJxn08PAxTIBJsAE7CbQ1ePV3kmEPUquFqS8/LJzJXCX3U8Dl88EmAATsJnAwVLUv+R2c3CPzRBj Ln5o/qaDIeRbABJ2k1jMcPhGJsAEkpHAH3oPrNTWlkxb6tbGu9LKLu/sDfsgRfsEQB+3gud6MwEm wAQUEJBC4NyiGTmzFeStPEvXTdlRKAmkaLTxlcVI+ePBBTABJuAyAkJKvKDPILms4lRd1wlSudj0 LwDDXMiaq8wEmAATsIJAG6kFZrnRyMFVgkQ+6iTkX63oUS6DCTABJuBaAhL9Aqhznc871wjS0HM2 99aEeIEdprr2K8IVZwJMwEICQmBMXsGmGy0sMu6iXGHUkHvx2nRPddpHEDg87hZzBkyACTCBpCEg G4UUQ4oKc5a5ocmuGCF5a9IeYjFyw+PEdWQCTMBZBESKFGKGbpnsrIqFrI3jBWno2NIxHII8ZN/x QSbABJhABARkDlI8z7lh06yjBWnImNL9IfF0BMT5EibABJgAE2iRgByVl192bYunHXLCsWtItN9o O8reBztNdcijwtVgAkzA5QTqhSaPK5re/UuntsOxI6RyUXo7i5FTHxuuFxNgAi4kkBaQ4tVRo0od G8DUkYI0JL/sGAlBXrw5MQEmwASYgEkEhMRBtZnifpOyMz0bx03ZDb9gU5a/PvAFgANNby1nyASY ABNgAlIKeeqSGd0XOg2F40ZI/nr/AyxGTntMuD5MgAkkEAEhpHh2RP76Tk5rk6MEacjYjcMBcZXT IHF9mAATYAIJRqC7X3gedVqbHDNld8LoLW3T0xu/BbCf0yBxfZgAE2ACiUhASoxZUpgzxyltc8wI KT29cQqLkVMeC64HE2ACyUBACPnYiRN+6eiUtjpCkIbll50C4AqnQOF6MAEmwASSg4DITvN7pzml rbZP2ZFNfE0GvuGAe055JLgeTIAJJB0BiZGLC3Petbvdto+QajPEP1iM7H4MuHwmwASSmoDA407Y MGurIOWNX3+IRMBV8TqS+qHlxjMBJpCoBA6oyRB32N042wRp8mSpwe99AhApdkPg8pkAE2ACTEDe OHjshkPt5GCbIC0r2XQlII+zs/FcNhNgAkyACewi4NWkeEIfLOw6ZO0bWwRpZH5ZFynkPdY2lUtj AkyACTCB8ATEse9/V3Zp+GvUnbVFkBqaxKiDumZxzkyACTABJhATAYl7cs9aa8vfZ8sFadi40qMA 2KbAMXUQ38QEmAATSBICAuiipabfZUdzLRYkKQIB+R8AFpdrB1oukwkwASbgTgIC8uph+RsOs7r2 lgrDkPxNFwHiWKsbyeUxASbABJhAVAQ8AWgPRXWHCRdb5qnhd48MPwDobkK9OQsmwASYABNQTEAI eVbRjO5vKi5mV/aWjZBq0sVNLEa7uPMbJsAEmIDjCUgpHjjyCmnZXlFLBGnEmC3ZEPJmx9PnCjIB JsAEmEAwgQM7lJddHXxA5XtLBMmX0vhPAG1UNoTzZgJMgAkwAQUEBG63KkSFckEafk7pQZC4SAEm zpIJMAEmwATUE9gn1Z/yV/XFWGB+7feARkdeKxrDZTABJsAEmID5BITENXnjN+9rfs575qh0hPT7 Jthz9iySPzEBJsAEmIDLCGSJQODvquusVJACAZC/OstMy1XD4vyZABNgAslKQEp5xfD8Tb1Utl+Z IA0pKD0ZwDCVlee8mQATYAJMwDICqX7NTwFVlSVlgiQgbQ/2pIwaZ8wEmAATSEYCUpw/ZOzmPqqa rkSQ8saVngSIIaoqzfkyASbABJiALQS8Aj5la0lKBAkBOdkWVFwoE2ACTIAJqCUgxflDz9ncW0Uh pgvS0PzSE3l0pKKrOE8mwASYgCMIeOFRY3FnuiBB4FZHIONKMAEmwASYgBICEvK84eM29jQ7c1MF KW/8+kMkMNLsSnJ+TIAJMAEm4CgCqb6AuMHsGpkqSPB7yL0E7zsyu5c4PybABJiAwwgI4PIR+es7 mVkt0wQpd1zZAQDGmlk5zosJMAEmwAQcS6CNT3j/bGbtTBMkLYAb2WedmV3DeTEBJsAEnE5AXntc /voMs2ppitPT3LPWdhCQl5hVKc6HCdhNwOsVaN9WQ1amQFaGQEaGhox0gdQUAaEBaali19x0Q6PU j1OdG30S/gDQ0CDh9wPVtQFUVUlUVgdQXRNATa20u2lcPhMwk0DnLOE5H8BTZmRqiiBpqekTAcnx jszoEc7DUgIkLL3396JvrxT03T8FPXK8yNnXgy77eJTUo7pG4tdSH9Zv9OGXDT78vK4Rq39uRFV1 QEl5nCkTUE1AAtcD8mlAxP1rK24DhNxc6fV0LfsZwH6qG875M4F4CXTqoOHQAWk4dGAqBv0hFQf0 NOU3WbzV0gXqu58asXJ1A75YWY/NW/xx58kZMAGrCAjg1KKZOQviLS/ub6O3a9mZksUo3n7g+xUR SEkROKR/Kv54eJr+v3t23I+8kpr27O4F/R9+StN0/MZNPnzxTQM++7oeK76pR31D3D8+ldSbM2UC REBKXAUgbkGKe4SUl1+6FAK53C1MwCkEaK3n2CPSMfiEdBx/VLpTqhVXPZZ9WocPP6vDxyvq9fWo uDLjm5mA+QQCwu/pVzRr3zXxZB2XIOXllw2AkCXxVIDvZQJmEKCR0PFHpWHw8Rk48ZjEEKGWuJAw LXq/Fp98WY/GRh45tcSJj1tLQEDcXzQz+2/xlBqfIBVsfBQQptqhx9MYvjf5CPQ5IAUjB2fgrFOz kq/xAN4qqsE7i2vww5rGpGw/N9pRBLZ2kuXdCwsHNsRaq5gFadSo0syaDGwE0CHWwvk+JhALAbKM yzsxA6OGZ6Jfr5RYski4e0iQ5i2qwdIPa1FXz6OmhOtglzRISHleUWH3V2OtbsyCNLRg46US4plY C+b7mEC0BPbt4sGoYZkYdybvMAjHbtbb1Zi7qAYby3zhLuNzTMB8AhIfLC7MoWjhMaWYBElKeeCM udULXp1TeQDtq+DEBFQSGHRQKkYPy8SQE03bEK6yuo7J+73ldZi7sBpfr4p5BsUxbeGKuIOApkE+ PLnTjQMOSv93LDWOWpBIjAB8T4XNW1iDp1/bCRalWNDzPa0ROO7IdH1a7pjD0lq7lM+HIfDNqgZ9 xFT8UW2Yq/gUE4iPAE2fP35fZyOTvwsh/mV8iPQ1FkG6F8AuSwoWpUhR83WREsg9PkMfER0yIDXS W/i6CAjQxtt5C6t1Cz3JExsREONLIiXQe78UPDlllxgZt3mFEFHt8I5KkKSU5E9lr4lpFiWDP7/G Q+CUY2lElIXDBrIQxcMxknsfeqoCbxfVRHIpX8MEwhJoQYzontOEEPPD3tzsZLSCdCqAkAWQKP3v 5Z1s4dMMMH9snQBNyZHFHE3RcbKOwKofGnTLPNrTxIkJxEIgjBhRdjOFEFGFJIpWkF4EcEFLFSdR eviZipZO83EmsAeBA3unYPTwTJw6OHOP4/zBWgLkmohMxskbBCcmECkB8gP59INdWru8vRBiZ2sX GecjFiQpJf3VqDZubOmVRaklMnzcINCxvaabbp9zuns3s1IYCWMdJjNDoLau6XNKCnaFojDa65ZX GimRVd53P/ImW7f0mV31pC0Y40a30Wc2WqnDJUKI51u5ZtfpaASJhl7Td90Z5g2LUhg4SXxKCGD8 WW1w6bi2jqZAISHWl/qwcZMf5OR0yzY/tu8IoKIygIqdgV1CFK4RXg/QsYMHnTtq6NTRg25dPdi/ hxf75XhBZuxOTrSPqfCtamzdHtV6tJObxHUzkUAUYkSlLhJCDI+0+GgE6U0AoyPNmEUpUlLJcR15 Vrj1Guc59aA/urRP59vVDbr7nTW/+pT7hyNh7pHtxYADU3BQ31TdiKNnjvO8kD8/sxKvzK6KSICT 4ynmVkYpRgawbCHEJuNDuNeIBElK2RHA9nAZhTrHohSKSnIdoz+8Z52a6Shfcx9/UY9PvqjDFysb 9BGQE3qka2cPjjg4DUcflgayNnRSuu/RHSj6gA0fnNQndtQlRjGiql4jhHg0kjpHKkgUnvzZSDJs fg2LUnMiyfP5vDFtcMlYZ0zP0R/UpR/V4qtvGxwfW4g8lx91SBpOOCYNp+Y6w+CDnLjSd/nnX3h9 KXm+wbtb2r6thosL2kayZrT7pt3vioUQg3d/bPldpIL0NtmUt5xN+DMsSuH5JNpZp3hYIKuxhe/V 6kHu3BqmgcSJggtS4D4nxHZ66fUqvPh6JU/jJdqXNkx7sjIFJo5vF6sYGTnvK4T4zfjQ0murgiSl bA9gR0sZRHqcRSlSUu69zuMBLhvXDgWj7bOeW7fBh/lLavQpJjJASKTUrq2GYSdl4KqL2tnerH8+ VI73PmYzcds7QnEFTBIjquWVQognW6tuJII0HkDM7sSDK8CiFEwjsd4POzkDt/zZPqMFGg3NXViD L1bWJxbYEK0ho4hDB6TqXi3sXG+a/U41XplTpVsehqgmH3I5ARPFiEgsFEKMaA1JJII0E0B+axlF ep5FKVJS7riOwoVfPLYtzjnNnlHRzHnVmLeoGmWbk9NEOWdfjy5M+WfYw5+e0keeqdB/DLjjieVa RkKA9tZdPiHuabrmRXUQQoT1nNCqIAUCcqYQ5gkS1ZBFqXk/ufOznaOiFwsrMXt+DaqqE2taLtYn gf6AnD0yyzYjkjcX1GD2/GqOwRRrBzrsvusuax/vmlGoFh0phPgi1AnjWKuCNOutquvHnJ71kHGD Wa8sSmaRtD4fWiuiX0/n2vCr/IXCSsycW+14Sznre6WpRK9XYMxpmbjiPHvWmZ54aSdef6tVhy52 4eFyIyCgSIyoZE0IEdbPPHnvDpu2+f5y7uqfGo/PO8nc4Gh/6JOCju09+OTLxJ/zDwvYZSfJ0uvZ aV0w4EBrvQ2QEP3ffeX63iF/cs7ORfSkBAJAyfeN+tpOba3EkYdYG0vqqEPT0KG9B6Wb/dhZyaPX iDrNQRepEqM/3bK14sWnMqesWnVnfILUa9Ckh0s3+Tuv/qkRLEoOenJsqArtKbpuIhldWpdmzK3C P6aU47Ov6sFCFDl38rNX8kMjXn2jGo0+icMHWSdM9GPzrFOzUF0r2S9e5F1m+5WqxOiav28lLyjp dahatGbV1F/DNTTsCGnI2M19hJR3UQbk14tFKRzKxD3X94AUfVOclc5Q58yvxgOPV2Dph3U8PRfH o0UjppXfNWDGvGpoAjjYQj96Rx+ahvbtPPh5nU93PhtHM/hWxQRUidH1d2zDqh9+30wtsGltydQl 4ZoSVpB6DbxxrADOMDIgUfplgw+nHMfTdwaTRH+lX7p33dwR/XqnWNLU5Svq8PgLO/HGuzU85WMi cRpdfvltAxYva9o71L+fNVOuB/VNAVkA/rYtgJ/WsZcHE7vUtKyuubQ9Ro8w3yMIiRH5iAxKaWtL pj4d9Hmvt2GNGobkl84SAmOa30V7H26/gdzbmZvY0MFcnvHmRhswrTTnfvQ5EiJnLoiTFdthA9NA 01H7dfcip5sHbTI1tMnSdMwNjVIfBZBn8A2lPtAG3a9K6rH2170CLMfbLabcT/uYRg/PwinHWec3 j4wdyOiBk3MIkBidaY0YUaP9XunvuqCwZ4t+UVsUpPx86dkuyrYCCLnbUZUokfnof54Na6runN5M 0JrQegMFzjvpj9b8saJ1ohdmVoH+qDsppaUKDD4hA8NPzsAhA2IbUWwvD+CDT+vwzmJn+oEbNSzT 0nXBjz6v04MB0pogJ3sJqBKjG+7YhpV7jox2N1SK/MWF2a/vPrDnuxYFKS9/w3EQ2kd7Xr7nJxal PXkkwieaXrnyAmtMht9bTt4VqvXwD05iRzvUzz29DS44t42p1fr863p9Ayn9UXZS0jToa4QTzja3 veHa+NyMptAW4a7hc+oIqBKj2+7djk/D/dgQeHLxjJwrW2pZi2tIvQbedJEQGNLSjXSc1pNUrCnR vDMthn7KJuHh8Jt+jqboLjjXGu/cT76yU18r2rzFOTbcNCKiP8r33baP7prHbMA53bz6iOsPfVJR XRvAxjJntJ0s8mh9icJy0B6zvr3UrxfSKJy+4zSlSdF3OVlH4M8Xt1MSDqZVMWpqYoe1JVMfaam1 LY6QhuaXLpACEUX645FSS3jdcZz2FNHUDXleUJ30Hf3vVDsmDhG1lzaTjh1tvZcDGimR/z0aOTkp 0ZoC/YK2Kt37nx1YvIzjLVnBm8SIPHqYnSIUI71YKf09lhT23BiqDiFHSLm50ivaVP0XQEQT5zxS CoXWHcdGDc/EnZM6os/+6n8VP/x0BV6aVYXKKmdsmKTRwLgz22DaHftYuk/HeDIoSuzQkzJ0I4kd lQE4ZbT4/c+NmPVONVJThCUboGmt0uMR+KpkD4ssAxO/mkTACWJETdEgVqxZNW1lqGaFFKRex151 tJDy6lA3tHSMRaklMs49ftn4tpg4Qf16EVnO0eZWChXuhETesmmt7N93ddajtNpdpwN6pmBEbia6 dfVie7kfW7fbL9iNjdBHbr+W+nGyBRFsDx63vWsAACAASURBVOmfqntuIevE6hqewjP7mVQlRpOn lmP5iihH+EJsXVsy9a1QbQwpSH37T5oAgWGhbgh3jEUpHB3nnOvYXsOV57eDFRtdyWKSgrrV1tn/ R4aEiPZVPfqvziAXN05LfQ5IwWl5mejU0YMt2wIor7BfmNat9+mjWlpfG/SHiCZMYsZKJvW0zWB9 qR9ULidzCKgSI4qJ9cEnMRnoZK0tmfpYqNaFXEPKKyibC8hRoW6I5BivKUVCyZ5rjjksDffc2kl5 4bQ2MnNuFTY5wGiBhIj+0N9wuXXrImYApvW2eQur9T1NZuQXbx4nHJ2OO28yf/9hqHqRN/cXX68K dYqPRUHgTxeocYIcb4DGVCm6zi/M3tK8KSFHSL0GTnpYADGvfPFIqTlmZ3ymxcxbrwm5rczUCj79 WiWeea0SVQ6YeqHQ3/+7vwsorLrbElmbjh6RpW++JWG321np+tKm0VJ6qoaBikdLhw5MA0XI/ea7 BvicYYzotscHThUjAtkoRPG6kqk/Noe6lyANz9/USwp5W/MLo/3MohQtMbXXTxzfFpeOU2vSvWRZ LR5+Zifo1e405MQMkH8uFRZFVreN3PzQVGN6uoYNZfavsaxYWY9fNvpwyrFqrTIP6puqm+GvXN2I Tb+xKkXz3CkTo3+bE7peCPnz2pJpxc3btJcgHXDwDacC4tzmF8bymUUpFmrm3pOWJnD1Re2Vxy4i bwsPP70Tv2219w8HucK59rL2utFC1857Pd7mwrU4NxqV0BoLWb+tXe9DXb1963L03SaHrRlpAqr9 4tEot6IyALL+49Q6AVViNOVxMs+Pac0oRKVFw9qSqS81P7HXN7b3oJsmAji2+YWxfmZRipVc/PfR lM+F57bF6UPNd5wYXLsHn6jQg+YFH7P6PcVposXb8We1Qbcuez3WVldHaXmDDkpFwag2ujB9v6YR ZBFnRyKHrZ99XY/ynQEce4TaKdE/Hp6u7xejDbycWiYwcUJbFIw23+MGidGCYlNnPjpflP/gA8XF e8ZH2suoIa9g43JAmCZIBjo2dDBIWPOad2KG8vUicoY7Y16VrdMpZC1HfvdIkJI1vTK7Cq+9UWXr iClnXw/yz2ijIuz1Ht1Khh5Pv7rTEVabe1TMAR9IjGhfndlJgRjpVfT40X/hrJzVwfXd46ckOVSt FVX/BmD6LkkeKQVjV/ueHkrVgfTojyB5bq6qtmfaiJydXj6haR8VbTBN5kR7eMjlEfXEdz82gmIg WZ0qq6Ue/ZnqQF7RVSUa9Xfr6sGOioDt08Oq2hhLvm4TI72NQi5vvkF2D0HKOfjKgwBcHwuQSO5h UYqEUnzXkPHChflqjRfuf2yHvpM/vprGdnf/vim4dFw7XH1RO9CGUjsTTR9R8Luff/FhQ5kfASn1 zZ121YmE4PwxbdDogx5M0w5h+mZVA35c68OQE9QZPPTaLwWnDs7E9h0BikRqF27HlKtKjMizyjtL TJ2m24OZEFi7pmTaouCDe0zZ5Y0tPQ8SLwdfoOL9iNwM3HyV+ebHyR66QtUGOOMZoCm619+2xw9d v14p+nTQaUPUrocZbW3p1fDYTYEEySlp89Q2S9MNSM4bY/7USfOyWvtMDmxnvV1tS+j3lBShj2DH nBbz7pHWmqeff3lWFZ6fWRnRtYl4kSoxeuSZCt3PokpmUorFSwqzhwaXsccIqffASRcBOD74AhXv KaTx5q1+0EY7M1Oyegnvso8Hl09ohzNPVfflnzm3Gv99YaflfugO6OnVR3yTrmwPEiW7Erk9euqV nfr+KtqP01KimE7kk418wdEIhabT7EpHHpKGC85pq6+30FSelYnaTgYPZAlI9VCVaOqW9iuFDXmg qnCb8724oK0+VWt2NawQI6qzEGi/tmTqA8H133OEVFBKw6c9FCv4YrPf80gpfqL0B2/a5H3izyhM DnZEcqV1IfJArvoXdphm66dKvm/QfynG6o2a3DSRqfa4s+wfMVE/vrmgOuTIrjUO8Zy3IuAjjd4L 36pC6WZ7tx3Ewymae0mMzj/H/GfKKjEy2iok9i8qzPl112fjDb3mFWwsBUR28DHV71WJ0pz51Xjs +cQOl2yFJd3N/9ymx8pR/RwY+dOUF5luF4xWN9ozymrt9YH/7sDC98yZQ9+3iwdnjshCwSj72/XQ UxV4u6imteabep6CAF51oZrQB8EVjSYMQvB9bnqfKGKkM5cYubgw512D/64puxMn/NLRG/DcbZyw 6lXV9B1t1mvbRkOihkomx6g3XKHONxv5orvlX9vx68aWp6fMfkbox8kjd3dW7pamtXrTH2zyTk7P plmJPFiv+KYeRR/U6lN5FIPKrkRulAb8IVWfygs3/Whm/Wi9jb6LZHBxxMHqpvDyTsrAth0B/Jig xg6qxOh/L+3EnPnW/kjRny8hvlpbMnW58aztEqQDD/rrURC41Dhh5SuLUnS06aGk0BGqEnldePyF naD1EKsSmS3/5RJ1AhtJO2hK6//u367UcovMo8kwYulHTUYRqr0ctNTunH29GHx8Bsj4wMrNpt+u brJKpLJVJRJcenLJ4i+REhnKXKTAgpbEqPCtaptQiQ1rS6bONQrfJUi9Dp40EsAZxgmrX1mUIiNO bkFUrkfQw0lB9KxMNNq74jz1cZlaahO1+dZ7t+um0i1dY/ZxcpRKI4YPP6unxV0c2Nseg42DD0rV nbeSAYJViUZlbxXVIC1NA4WcUJHIBD4zQ8Pn31jXLhXtMPIkMbpkrPk/Qu0VI2qdrF9bMu0Zo527 BKn3oEkXmOkyyCggmlcWpfC0/nJJO6WL/HdOK8f8peasmYRvye6zfQ9IsSykwe5Sm96RR3ISom+/ t9YCLbgeFPPo4y/qdXGiUOoUE8nqRKO01FSBL1ZaN6Kg+FiffFkP8rWoKs4STYt2bO9ByQ+Nlo72 ze6/xBUjIiXarS2Zep/BbJcg9Rk46RoA/YwTdr2yKO1Nnhb6aUGYFsVVJLJQuu/RHVi52ro/SEY7 aPqxn8Wjg+dmkBCV61M6ofYSGXWz8pWixH74WR2+WtUACoZn9aZf8o9nbFy3st0kghSm5OjD1Kwr 0QisXRtND3hIG2ndllSJ0bPTKzFjrl3TdHv0QlrvQ/76xNpvH9Qrs0uQeg2c9A8Anfe41KYPLEq7 we/X3YsJZ6nzETb7nWrQ2okdsXbItFvFBund9PZ890JhJf7vvnJ9zcQOLwZ71ib0p81b/Hj/kzpQ yIWMdIH9e1jnFql9O49pVoWhWxf6KO2RIiexZDWqItEPnjOGZeplbCxzj1m4KjGiH2SvzrF2Wj5c v2oy8Maakmnr6RpdkJp82FVOBcQugQqXgRXnWJSAwwel4rF7OiubZ6fQ4k+/at8ud/rCDein3tqM /O7d/sB2fP51gy1eC2L5vlD8n/eW12HVj43IzBCwwl8f+Yhb9UOjLXt5SCjeXlyL9FSh7Hknwftt WwA/rbNvijbSZyH/jCxMnGD+uiqJEX0fHJWE9t6akqlfU510Aeox8KoDpMCNjqokoJvdqvDo4AaT 8NzjM3D3X9WFGievC9PftPfBJFdH7dtqyh676W9UYfK0cny8ot62EA3xNo42epJF3k/rfPo2hpxu akdM6ekCxcvNinkTXeuNdSUKRKgqIi15hSfvEbSu5NREYnTlBUkiRmTWAJSsLZm6lPpDf7r98PcF 9nDa4Ji+MmJwmD21Y0QSdeLmWfJQoNJb9z8p6qNNf3SMB8vrgbJf/TPnVYOmIrdud8/0jMGlpdeP Pq8D/acfKqOHZYJc5qhIJx6Trlv92bm29uTLO1G+w6/kjzIxu+L8droFnhN94CWbGFF/aEAf41nW BUlqYn9h3ZYTo+yIX5NJlFQ9kAbsa2/fhlU/WG+8YJRvvHbsYP7sMDkSJQ8dm7YkjhAZvIzX4o9q Qf8piuqo4Vkg7+dmp306emwXc9oXQ/14x40dzW6enh+53UlPE3oIFSUFxJCpqu8+OaB13DRdEB8p sb/xUf+r0HvQjWcC4hTjoBNfk2FNidZUVMwbU3+SJR25VdlQZp73gXieE/pjkD/KHF9cNBp64L8V IH9zZLGVDIlCXsxfUqOviZgdnHDRB7Uod4BFGnkJ+fDzemiK9mmRWTgZcnz6pf17lc4ckYmrLzZ/ Y7grvKELYG3J1Ifoe6uPkITUekp9b7Ozv8qJPFJS5RKEetSJfv0aTJjCp82VJLQ//2JCZs5+9Fus 3btLa7CguAan5WXihsvN/4PWYsEWnfh5XaPuZd7nB+iPttmJ8iTBe+H1Sj3on9n5R5IfRTy+5lLz +84VYtQEKCc3V3qLi4VPHyEdMOCma4RA70jg2X1NIo6UKKYJuc5RkWio/uQr9lnStdQm2ogZT7hl cm1EFkO0sZQTdN9t5GFjZ6XEMYfHt6eHhN4JIySjX/1+6KMYVcYOtFcpI03Tpwgrdlr7PJEYXXtZ UosRdbOW0rby6Z+/nbZTN3ESQvY0Ot8NrzRSomiGZicydCDLLyuT7groTDVi9NQrlfofbSvbw2XZ R4AMEd54txpTHt9hXyUUlkzGDuRdQ0UaNTwTz0ztAnKlZFVSJUZkPetEg41wXGUA+9F5w+a2R7iL nXhu3qIaUOwOs5OVokTid+4Zarwv/PupCpCTVE5MIJEIvPZGFR58wvzvvcHooTv3gdlrckbewa8q xcjOvYXBbYzmfUBqetgjbdSoUpqYNX9yNpraxHgthUhwqyjRnLFheh5j81u87Z8PlevOK1u8gE8w ARcToHUzitOlKt11c0cMO1mN1wiqM4VZUTFNRyMjN4oRMZEIdKNXrTrTY2lAPrMfIpWiRNNpZidy B3PdZe2VLNBSXW+6axve+9iejY1ms+L8mEBLBChkxgXX/qYbtbR0TTzHb/lzB9AoxuykKiCpm8WI GAsNXejVK4Xs7OQ9SJE8ECRKlMz+1WFMpz3xkjmRZ7MyBSaObwearzY7kbXZ7Hersd7CgHpmt4Hz YwLRECjb7Mdjz1cgINVY4NHfE/JcMdMkJ6QsRmF6V4ocOuvVAgFXj5CMJjpdlLp29mD8mWqcpJIY Pf3aTlBUUk5MIF4CNbXWWprFU18yB//PsxXw+SQorpbZieJ0kfd18vsYT1IlRq+/Ve3aabpmPHXH 3l4BdEmUP2NOFaVuXTwYO1qNGJFVFXnr5sQEzCIg3aNHu5r8+Is7dR91tLnc7ERRWj2aiNlyjdw9 me36jNpIYmTW7I3ZzKLPT+xL93ghRQe4fc4uqPVOE6Xe+6XgySlqonok1gMZ1In8lgnEQID2pdXU Slx+nvmRVcnVkNeLqEcjpxybjr9f1yGG1oS/JfG++1KHpEnR9CZ88911lkRJhfUdrSlFY+jQr5c6 MaJFzMT5deSu54tr61wCtNVh2pNqzMJpI3c0338So9tvMN8XX+KJkf486aA0IPEEiZpntyhRBM7H 71MzMiKXIG4173TunzKuWaIQeGdxDf4xpVxJcyL9UapKjMgNWIL+EG0aIQkI8yVcyaMQfaZ2iRIF 1vv3nftEX+EI7qBpCbftwo6gWXwJEzCVAIXquO4favYqkSiF8+hysqKRkRN9UprYaem5F69NJ08N 5jtSMrGW8WZltSgdc1gaptyuRoz+99JOR7uRj7ev+H4mYCaBku8bcOmNW5TsVaJN7aEcotL3/x8K pukSXIyaur06q4NXAubv/jTzqTIhLxIlSqr3KdHDeM+taqK8PvxMhZIvlgl4OQsm4FgCFMLi+cIm /3dm7/8zPIXTd5OSqu9/UogRgFQEMryQSHdosFhTH3LVovTFynplYnT/Yzuw6P1aU3lwZkwgWQiQ B+9HnlWzgdYQueUr6pR8/5NFjOhZDABtvBCIz1e9i55qlaJkeHUwG8fkqeVY9im7AjKbK+eXXATI EzptoA0EpOk+JEmUDGEyk+qbC2rw2PPJs8fQ70EmBehL6DWk5g+IKlFqXo4ZnynC66df2R/N0oy2 cB5MwAkE6A88xVdS9QPSrDaSGJGAJlMSgUAaCVLSjJCMznWDKN04eRu++a7BqDK/MgEmYBIBMpuu b5BQ4dXBjComoxgRN02KtmRll24GRLflQaLk1OHw9XewGLnteeL6uosAbZ+g/XxOS8kqRkY/0Agp aRMtGHo9wJUKwkzECvWKm7diza+Nsd7O9zEBJhAhAdrP1+iTuGSs+a6GIqzCHpeRk+Rkm6YLBiAR aJPUgkQwCt+q1pnYLUr0ML65sBrr1vuC+4jfMwEmoJDAK7Or0NAgbf9RSt9/w3xcYXMdnbUAPCRI zvh5YCMqu0WJHsbpc6uweYvfRgpcNBNITgL0/acwFuG8L6gkw2K0my4JEq0jJX2yS5ToYXx5dhW2 lbMYJf1DyABsI0DT936/NH3zfGsNYjHak1DST9kF47BalOhh5MB6wT3A75mAfQTI0Ims71TELgrV Khajvanw6KgZExIl8hmnOrEYqSbM+TOB6AksKK7FPx9S4yk8uDb0/f/fy+r/zgSX6Yb3JEgujA+p Fq1qUWIxUtt/nDsTiIfAex/XKRUl4/tfV58osbrjob3nvSRITZ4H9zye1J+yMgVy9lU3m0luRkYO yUxqxtx4JuBkAocMUOcvgL7/+WeYH2rdyTwjrZu6v7qR1sBh15EYTRzfTolvquCmUuRJEWR2Hnwu Gd5npFPrOTEB5xG47rL2yr//FBKdEsc2293/EvCzIO3mAavEyCiS9j4JAcyc17QXyjieDK8eXr1M hm52VRszMwQun6D+x6gBhUXJINH0KqBV0Z8FdiUNWC5GRldccX47x/rUMurIr0wg0Ql0bK9ZKkYG TxKliwuSfiuogQM0Qkp6d9JWj4x20f/9DbkuSfEKHr43BxPmcy0vCIehw6eiIdCtiwdjR7dRPk3X Up14pNREJiBkJQlScvk4b/ZU0DDdijWjZsXu9ZEeSq8XePpVtjHZC06IA7SJkRMTiJdA7/1S8OSU zvFmE/f99P0nv3rkyihZk9S0eg0yuUdIVs4Zt/agjTuzDSZO4OF7a5z4PBMwg0D/fs4QI6MtNFPi 1JAYRh1Vvnr8qNEgkncNyQprmmg7kESJLPA4MQG7CGRkJL4F5CEDUvGfu+0fGTXv42QWJQ2o0gSQ lNuFnShGxsNJ0SztcvRo1IFf3UugPs64jhr9VUjgdPxR6Zh2xz6ObWGyilIDtNqkXENyshgZ35Kz R2aB/jAkc3wUgwW/RkegsZHX11oiNuzkDNzy5w4tnXbMcRIlSkm1ppRVvUOTkOodNzmmmwFVYvT6 73GVzGzqmSMy9fqmpyX2L1YzmXFeTKAlAqOHZyoTI4pAa3YiUco/I8vsbJ2aX13x873qvIDY4dQa ml0vVWJ0273b8elXTdbzNN1mZiI3I5QK36pC6WYOUWEmW84reQgUjMoC7flTkcgZK/m/o2SMbMwq xwgcakQiMCtfB+aj65AmZHIIkhVi9MRLO6FipESi9OIjXXFQ3xQHPkdcJSbgbAIXntvGEjGi6bWX Z5lvtk2ilAQjJX2mToOQCT9CskKMjK8kiZIqV0CP/qszjj5MndNHow38ygQShQBto7gwX81Witsf 2D0yMniRbzoWJYNGNK9NAyNNAluiuc1t11opRgabJ1/eielvmv9LifK/99ZOGHJChlEUvzIBJtAC Ado+QdsoVKS/3bMdy1eE9rqmUpTMXhJQwSa2POVmuk8LaFpZbBk4/y47xMigQh4XVPxSovxvu7YD Rg3j8BUGa35lAs0JXHNpe6j64339Hdvw+dfhPa6pEiUSWTLOSMC0ldrkFVLobxKtgXaKkcGSHkpy B2L2Qiflf93E9qANjDPnJp+ncIMvvzKB5gQ6ddBwwTltlfmlu/KWrfh5XWPzYkN+pu8/JcNXXciL Yjh47WXt9bso5HrCJCFLqS3erBp/WU2CzQA5QYyMB4UWOn0+4PLzzJ/HvuK8dsjK0KDC5NSoP78y AbcQ+EOfFDx2jxrvCxTldfa71Vi/0RcVDhIl8lFp9tRhoomSDDQtHWnz5uWQzCaM1DpJjIwnd8bc KvzvJTUOMcj31VUXqjFnNerPr0zA6QTI+4JKMZo+typqMTKY0fS9ijVlEqVEmb4T0DYRLyNM2gYD nptfad7Y2LdjZjuC9xnFmi/tI3jkGTWO1c85PQvU9pQU3kAba//wfe4lcFpeJu66uaOSBtDI6OnX dmLzlvj2AKoUpTOGun9NSRMB3ZZBjxgrpVgvhDxQSY9alCn9QSbPBmanux4q37XpNd68ac63vkHi 5qvMd11CbScXZLPnV2N9aXTTCvG2i+9nAnYRoDhGKqbDqT1vLqjBo89VQJrkickILWP29N31l7fX 16oXFNfa1Q1xlys0/EqZ6CMkoQXWx52jjRmoEiPagf3+7zuwzWoePTQkcioSjQ6fe6gLDh/Ee5VU 8OU8nUWAjIVUidGc+dW6H0mzxMggp2qkRD9yR+S61hjA37ApRx8hNU3ZSbhWkFSKkeEOxHiYzHol kbv5n9vNym6vfKbc3glDT3Ltw7lXe/gAE2hO4OqL2imLHUTeVh57Xs2aL7WDREmFRxcXi1JpcbHQ p3V0QZJC6MOl5p3u9M9uFCOD6Zff1uNPt2zFO4vV2JP87S8dcM5p5vrVM+ruhFdaxD7qEB4JOqEv rKxD504e3eHwGEXP9qtzqkDeVlQnVW7GXClKQQMifQ0JkL8C7loQd7MYGQ/7T+sa8eLrVfD7ocQY 46qL2qFDew3PvGa+J2KjDXa9nnB0Ouh/8Ue1mLuoBt+sijMIkF0NMbFcjwf6jxBVTkRNrGpMWR06 IBVTFcYxou0TVoZ7MITP7A28JEqNPmDJMpesKQUNiHRB8gY8P/pFIKaHxI6bEkGMDG5bt/vx3xeb fpGpsBAcf1YbZKQLPPqc+l99RpusfM09PgP0f+F7tZi3sBrf/RTZpkUr66i6LCEAGjEksvk/rY/Q H1pVibZl2OFRW5Uo3XZNB/h9cpcXclXczMlXrjHy8dCbIwZOqawVlbcCQv9snHTiayKJkcE3EAA+ +bIebdto6N8v1Ths2utBfVPRsb0Hm7b4UbHTGT88AhIgsTQr9TkgBWT+26mjB1u2BVBe4Yx2mtW+ UPmQEJ11ahZ0p7uHmjd9+eaCauxwyHNC7R53Vhtcc0mTd4JQHOI99u+nKvDGu2qmziOp2+ff1CMz Q8OAA8397p9yXAZ+2eDT/0dSD7uuEZDPrymZ9iWVrwvQqlV3yt4DbzofgHPj+gL6XhsVpt3B8Uzs 6hQq97Ov1DyYlDftYj9zRBbW/OrDr1HuNlfBhKYUzj2jjel7pw7snaL7+WvXVmsS4MrEFKbTh2bi v/d2xjGHmydERj/TNHJdvUm2zkamMb6SN5ILzjXvh0vzakyeWo6iD+yf2iJRUvGD1BWipImpa7+d qtsx7BoR9Rk4aSSAfs07zCmfE3FkFIotPZgej8Ah/c39tWSURdNbldUSqx0wtdW/Xwp65vy+jGlU 0KRXGhWSAGdladj0mx87qxJDmIafkoHrr1DnXLeqOoDnZ6rxVB9N12ZmCPzpwvagTd+q0rW3b8OK b8I7SVVVdqh86QdpMoqSP+C9bd2qKfpDt0uQeg2adAyAY0OBsvtYsoiRwfmrkgb9F+qRiqzIjjks TRc9KsfOJCFw8rHpSqswoF+qPq2Vnq5hQ5kP1TXO+OUfbaPph8S1l7bX14q6dNr1tY02m1avX/5F vel771ottNkFBx+UiosK2mLkYPM3ulNR5H2BRkY0neW0pFKUflzr078DDmvzzqWF3f5u1GnXk917 0KT9AZxhnHDKa7KJkcG95IdG/LY1gOOPVvMHm0ZgNK21YmW9aTvRjbpH+kpThxeca77T2VDlD/xD qm6BlpoisHa9zzFTUqHqGnzsxGPS8eeLm+L67Ntl19c1+BJT39Pifumm+NzkxFMhcoMzeVJH9NpP TXRk8r7wyLMVqKl17g8TVaJEcdRoZmSjjf0b4tn4Zm3J1KeM47ue8D4DJmVA4FLjhBNek1WMDPZk Fk4PUJ6iTa40rUW/trduD2BbufVTWrQLnkYsVkbBHXRQKgpGNa1d/bCmEY0ONcr74xFpuPrC9nro gpx91UxrGs+Z8frdj436pk3js9Wv5HlBpck6bUb97wvusDZVJUr0t8RhorR4bcnUN4xnbZcg9Rt4 fVVAaLcYJ+x+/csl7fSpFrPr4RQDhkjbRb9mPvi0DgJCN0yI9L5Ir+vbKwW0QL55qx8/r7N+CoP+ CLZv58FBfdX8Im6JA00LkZUfrddRHWgvmBPSUYem4U8XtsPFBW3RI9saITLa/ez0Sqz5xfpngJwC k+cF+qGgKlGwzKddth+PREnFd8NJoiQhX1tbMu1Do993CdLPqx6q7T3wxisBYc0cilGDEK80RXH2 SPMXM+9/bAeWfBg67HCIajjm0I6KAFaubkCbTE2JKFFDaZMppa9t2GBK0Tc7tPMoa1u4jqSpSwrh QRM4q35oBJng25EOGZCKyye0xcQJ7ZQZeoRr18x51SicZ32wx4EHpuLisW11k/1w9Yvn3JMv78Qr c+w31IilDZ9+mdiipEnt32tWTf3RYLNLkOhArwE3jxQCvY2TdryqEqMpj+/QN0/a0SYzyiQzaZV7 laiOhw5M09eVSJSsHDHQ1N2n9GuwrfUjJaNvDhuYpk+PEWea0rBKmPr3TcGl49rpI4QDelo7SjTa To5En/h9c7ZxzIrXkUOawkb03l9du+/9zw68VWTfHiMzOKoUpa9WNcQdWiOeNgrg1jWrpu6Ky7OH IPUeNOkQAMfHU0A896oUIze7Zg9mSsN4r1fgYEVm4bSuRCOGb75r0PfxBJet+j198eoaJFRZF0ZS /yMObhKm2jqJ739uVGbw0Wf/FN2SjEIH0KZeuxK5ynnyFetdS106ri2uPF9tYMnrbt+m/4izi62Z 5aoSpRG5mfji2wb8ttWWOettiwtzCjVkfQAAIABJREFU/i+Y056CNHBSVwBjgi+w6j2LUeSkv/y2 AVWKjQGGn5Jpy36lku8b8frb1boQqBLdSEjTWs4F57RFTZ3U15giuSeSa2jf1QXntMHNV3cAbeK1 Ky1fUYfHX9iJtxU5922pXZ06aLj8vHYw239bcHlk1v23e7Y70cQ5uJpRv1clSqcOtkeUpBTL166a +mIwiD0Eqc+gSWRz9OfgC6x4z2IUPWVaiCevC7Q/RVWi/UoZGZrlmwdp2oxEd96iGgT8AFnG2ZVI mC48ty12VjWNmGKtR86+Hpx/Tlvcek0HJe6hIq0X+fp7bnqlbk1ntfkvmbBTmHHyGqIqGaEjGhqc a9YdT9tJlMgNmNkM7RAlTcjZa0qmLQrmsYcgHTngwfJaUXUTAHVPTHDppH6KDBhozShRpumaIdv1 kfbxqLTAo4Jo0blrZ3tMw8l9DU0nLHivVl/Tor1EdiVy0UPCtG1HAD+uidxWvMs+TUL09+s7mu6r LFoW0/5XgUeeqcDPNljSnX9OG9D0pMr0YmElnplu/fSjyjaFypvWkhNBlITEY2tWTVsZ3Ma9Yk7k FWxcDghLPDawGAV3RezvyckmsSRHmyoT/TGjMOx2pe7ZXowelqnUnUwkbaNRBnkWX/R+bYtrTB3b a/pGXHIManci56E0NWd29NNI2kWbry/KbwsVPiiDy3/46Qp9RB18LNHfX3dZeyVha668ZSt+Xhf5 j65YOQuBAUUzcr4Lvn9vQRpb+m9IXBd8kYr3LEbmU504vq3uGdn8nHfnSFMihsv83Uetfdeze5Mw qdgaEG1LSJRopEpGEB4N6NhBQ98DUkBTfXYnCjlCnrvtECJqO7mF+scNHZVj+L/7tieM8UK0sFSJ 0hU3b8WaX5WKUsVJA7I7TZ68Z9yjEIK0cRykeC1aMNFcz2IUDa3orqXF4j9doNZ6iUK70wjBbl94 ZKlGMaTI3Qyn3QTI/Y9hGLL7qLXvaGMvTdOpTGS88PLsKmwrt8VCTGXTosrbpaK0aPHMnOHNG7rH GhKd7HPQLTXQpLIREotR8y4w9zNt7ly3wQdyO68qHdDDC7LCa2gEvv3ePgetFPPo4y/q9bAdZApv p/m0KtbR5EuRgW+9dzu+/V7pL9uwVdqvu1f3MpE/Su30MW3kJTdANDJN9kTfQRWb5unH3rJP69XE FhPylbUl04qb991eIyS6YEhB6W8C6NL84ng/sxjFSzDy+7t38+Lc07OUzDEH14KcVU5/swpbttn/ K5W8HdAak0rLw+C2O+X9C4WVeO2Navh89v5xpj9g9GtddbIruqvqdsWTf1amwMTx7ZR835VM3wlt 1OIZ3d5q3ua9Rkh0Qe+BN51EMd2aXxzPZxajeOhFf29lVUCfV8/KND8SZXBtyAcdCd9v2wIgZ7B2 ps1b/Hj/kzqQp3QK206/1hM5kX82GhF9sbLBMs8SoXimpQndKSo5R1Wd/jGlPOGtZ2NhSE6CVY6U Fr5Xq+99jKVuoe5Jlbj+p1VT97KQakGQbuwJiGGhMorlGDlOHHOa+UP4ZDDtjoV38D3kJ67BB5AH ApXp+KPS9TDMX5XUg8KT25nKNvtRvLwOZA1Hgd5UBQG0q43kXeH2B7brU5VWungK1V4ajf7v/s6g uFMqE60X3fVQue7WSWU5bs5bpSileIW+FGBSPLHvFhbmTAnFOqQg9Rn0Vz8gJ4a6IdpjtMCuIuoj mbLOX2J/6OFoedhx/berG/S9J4MVbqKldg04MFXf/PnLRp8jgp9RXJ+lH9Xhp3U+PRJnTjd3j5im v1GFO6eVY/mKekeEzZg4oa3ug0/1M134VjUee36na4MrquYTnD+JEq0jZ2WY64iZNuKmmidKs9eW TN1ruo7aEVKQ9usyZZOWVTUJQFw/e0iMVLgIof0wtIufU+QE1pf68M6SWqSlqgljEVyTU47NAE3j kLcFJyRqe9EHtfi11I8O7TRYEejOzHbTAv49/9mBDz6pc0RgwWOPSMNVF7XHqbnqrRtpi8FLr7vT U7eZz0A0eTU0Sn00QwJipkcHs0RJSPlQ8w2xRvtCCtK6dXcG+gyYdAoE+hgXRvuqUozs3JwZLQcn XU9RMmmXN8WfoXhAKtOgP6Tqng0oTLRTQkWvW+/TvT5s2uJHp44ePTihSgbx5j3r7Wrc/98KFH9U 65jRAe11u3Zie0tiNd3yr+1Y/AHPgsTyHNHUGlnbOlGU/H55/brvpoWMlBhSkAjAAQMn7S8EhsQC g8UoFmrW3UMjF4oSe9xRasKjB7eEzM8zMzR8/Z29C+/BdSLXOfOX1FjGILjsSN6/8W41pjxeoY/q yDjFCYnWCGktmLxDq07U/kl3bQeNbDnFTkC1KJERRdQRlwXWLH29+90ttapFQeo98AYfhLispRtb Os5i1BIZZx3/cW2jbpGmKhJtcGv1taUxbWyLShtcl+D3xOClWbSxMoDjjlQvzsFlh3pPcXumPlGh W5FV7HSGENH+LgoaSBGcaSuB6vTcjErQfiq7jTVUt9Oq/FWKEu19ilqUBApbWj8iJi0K0lEDp5bV iqprAUT8TWUxsuoxM6ecHTubTMPT0zRY4biUotKSb7MNZT49tIU5rYg/F3KWSsK0s1KCnKhancik lox0SJBos69T0ojcDDx+b2dLng1qM5l0v2NxOAynsFZZDxKlX0t9GGNyFG5aU4pWlATEA2tKppa0 1N6QG2ONi/MKSmcDONv4HO6VxSgcHeefOy0vEzdeoX5To0Hi6dcqQVZjTkvkqJb2VV2p2P0StZvW huYuqsE3NoSND8edfAWeOTxTubNeow40RUcjI/rDyUkdgd77peDJKZ1NL4BM8p9+LSIryIBX+rss KOy5vaVKtDhCohv6DLipEwROb+lm4ziLkUHCva80fbXkwzp4NHMtc1oiQvuiaCqPDC2ctlZAZrOv zKlCQ4Oa/VsffV6nmzFPf7Pa1vDRofrmgnPb4I4bO4IiB1uR6IfJs9Mro1+LsKJyCVYGjb7JFRB5 1DAzGSOllasbQLHMwqTPFxX2eCTMeYQdIeXmr+/rEZ4fw2XAYhSOjjvP0Y57CmNuVZozv1p3Bkqe FpyWPB6A9m+dPjQzbstEmpKjX5M//2KvR4tQjIeckKH/oVJtfWmU7RQHvUZ9kulV5Ujp4WcqwqG8 Z/HMPUOWN784rCDRxXkFpd8DOLD5jfSZxSgUlcQ4RtE9J09SHzogmBYFWCPvzQHnLKMEVw8d2ms4 8uA0HH5wKg7okYIe2R60ydL2uMb4QKbltFb2/U+NesTdVT80wOc8vdVDZYwengmasrUq0b6qJ18O afVrVRWSvhw7RElInFRUmLMsHPxIBOlBALRJdo/EYrQHjoT8QPuVaDf+OQrcPoUDZncgwHB1a36O XBNlpGtITxfw+yRq6qTugbqx0dnrISSk487MwrgzrRsJE7up/yMPK7ypvflzZMfnfr1S8Ph9ataU QoyUtneS2V0LC0XYn2Vh15AIUu+BN9H8wkXBwFiMgmkk7nsaqZAvvPKdARx7RMTGlnED+eMR6Ti4 f6rulYCC3zk50Zw5hUCg/UJVNRL1DdKxIzziqGnAhLPb4P7/64RBijdHB/cbGS7c8eAOfPOdM7x3 BNctWd9v3xHAF9824NTB5o6OaU2JQqzTJvygNOutwnazgj6HfNuqIHU64cGN6XW7zb9ZjEJyTOiD P/zciIXv18LjESDv3lak7K5e5B6Xgb69UnQT8dLNYX9YWVElV5dB1oMU4v4/d3fG4YOsNW0n9z/P z6zi2EUOfIJ+2+q3RJSkEHevLZm6qjUErU7ZUQZDC0pnSiCfpm9UDPEp0Nbsd6pbqyufdwABKyLS hmqmU02kQ9XVScdIiGh96IbLrTPpN9pPBhxvLqwGuWzi5GwCNFr+9537mF5Jipf2n2d3NAqZ0aWo sFNYiwcqPCJByhu7cdzE8e1eUyFGHGzL9GdAeYb79/DirBHqg/+FasiyT+t0x7orvtljOiDUpUl9 jIRoxCmZuOkq64WIwD/1SiVmzHXePrOkfihaabwqUVr6Ue36ISdk7tdK8frpiASp9LfGU7O7eOdH kmE017AYRUPLeddSWJGrLmxnS8U+/6ZeN6H+8LM6W8p3aqFkpj5qWJbu6seOOvKoyA7q5pV5+KBU TLnd/JESgH5CiJ9aq2lEgiSlfA3AuNYyi+Y8i1E0tJx7bbcuHj3ECK1P2JHW/NqoC9O7xbVwumWb Sj5tszR9H9Gl49RHbW2pHbRW9PpbPPXeEh+3HD/msDTcc2sns6vbTQixubVMIxWkCwG80FpmkZ5n MYqUlHuus9r1UCgy09+swluLakB7gJIl0X4S2nk/api5llLR8CMLOgqi58SNzdG0g6/dTcBkUSoW QgzenXvL7yIVpA4AylvOJvIzLEaRs3LblakpAhcXtEXBaHtGSwavT76ox4L3an6PrOrs/UBGnaN5 peCHucel47QhmZY5Pm2pfryvqCUy7j9uoihdI4R4NBIiEQkSZSSlfBPA6EgybekaFqOWyCTW8aMO SdN/tZN3b7sTWfkUfVCD1T81QrpYm8hI4ZD+qcg7McNSrwot9R+NRskHnVO9arRUbz4eHQGTRClb CLEpkpKjEaSxAKZHkmmoa1iMQlFJ7GMFo7Jwxfn2GD2EIkvrGxQGfNWPDa4QJxKhAf1SccIx6SCW TkhLljV5KP92NW9wdUJ/WFEH+mF5500xuxFbJIQYHmk9oxEkmqSOacWSxSjS7ki869q20XDe2W10 wwcnta7og1p8+mU9Vqysh1OC4RGfrEyBwwam4Y9HpOlTck5i9uhzO0HrRZySj8Apx6bj9htiEqVL hBDPR0osYkGiDKWULwK4INLM6ToWo2hoJe61hw5IxejhWTjlOPun8ZpTXrfBh5XfNej/v1/TiNJN PstGUB3bayBXKxQgkTwoWOUJozmDcJ9fnVOFFwo5ims4RslwLkZRai+EiNiTbrSCdCqAiPcjsRgl w2MaXRuHnZyBW/5MNjLOTuRzjTwMbNzkQ+kmP0o3+0ARdmMZTZGT2k4dNHTu6EGPHA96ZnuxXw+v 7mm7a+dWvXfZBmreoqZwGWRaz4kJEIEoRalQCFEQDbloBYm+PRH5AWExiqYbkutaWhspGNUGl59n 356ZWIn7/UBFZUDf80SOVBt9TZYSXo8Atcv4nJmu6Y5MMzMFaI+QmxJZKc5dVA165cQEmhOIQpRO F0K80/z+cJ+jEiTKSEp5L4C/hcuUxSgcHT5nEKCRw4Sz2oCilHJyBoEHn6jAu0s5PIQzesO5tYhw psMrRPhwE81bGIsg/QHA6uYZGZ/Zh5VBgl8jJdC+rYb8M7Iw7iwWpkiZmX0dGSy8uaDasrUzs+vP +VlPYERuBm6+qsXp9/uEELdGW6uoBYkKkFJ+AODE5oU9N6MSr8xmh4rNufDnyAjQesroYZksTJHh MuUqms14/W0WIlNgJmEmYUTpICEERRuPKsUqSJcCeCa4JBajYBr8Ph4CZHlGUWp5xBQPxfD3khDN nl8NWhPjxATiIRBClJYJIU6KJc9YBYl26e0aCrEYxYKe72mNAIXZPuvUTN0dUWvX8vnICDz8dAXe XlzDHhYiw8VXRUigmSidJ4R4NcJb97gsJkGiHKSU1wJ4+LHnd2LOfN4stwdV/mAqAa9X4PS8DFxz qT2xfUxtjA2Zfb2qAXMXVuP9j+t4jcgG/slSZJssbdurj+57aVaWmBtrm2MWJCrw7oe3n7j0wzpa T+LEBJQTILPqIw9Jw+jhmTj+KOdtsFUOIMoCFhTXYt6iat2PX5S38uVMIGoCAuL+opnZYS2wW8s0 LkGizPPyS5dCILe1gvg8EzCTABlAnDE0ExPOZsu85lzJ6ek7S2qwoyLQ/BR/ZgKqCASE39OvaNa+ a+IpwARBKjsXQhbGUwm+lwnESsDrAY45PB3DT8nAicck76jpvY/r9FhQX5XU87RcrA8T3xczAQEx t2hm9pkxZ/D7jXELUm6u9Hq6lv0MIKKY6fFWmO9nAi0RoP1Mg0/I0GMFDTootaXLEub4N6sasPjD Wn1tqLKKR0MJ07EubIgATi2ambMg3qrHLUhUgSEFZTcJyCnxVobvZwJmEdinowcn/TEdJx+brscR Mitfu/MhH3sffV6H95bXYcs2ttm2uz+4fJ3AqsUzswcBIu6IY6YIUu5Zazt4UtPWA+AJfX5CHUeA zMePPCQVfzw8HUcflgba5+SmRNNxH6+ow8df1INHQm7queSoqwCuKJqZ85QZrTVFkKgiQwrKHhGQ 15hRKc6DCagk0LO7F4f2T8XB/VP10VOXfZzjcZsct67+sRG0FvTFtw1Y84u7I92q7EfO2xEEttZI /37LC3vWmlEb0wRpeP6mXn4R+AGA14yKcR5MwCoC7dtpOLB3CvockIJ+vVLQM8eD7vt6kZZm2tcj ZFPKNvvx60Yfftnow/c/NYBiMW36jafhQsLig84kIMUdiwuz7zKrcqZ+4/IKSl8GcJ5ZleN8mICd BMhIonMnD9q1FaBpP4p+2yZT6EKV4hWgDbspv//8CgRoszjg+X2wVVsndW8IdQ0S9fUSOysD+nTb zqqAbo69dbsfPtYeO7uXy46fQJVX+vdfUNhze/xZNeVg7mjG438Afs8EAKYKnVmN5XyYQDQEaPqM /nNiAkxgbwISeMpMMaISTF3dXfxaz29EFBFl924iH2ECTIAJMAEXEGjwavIhs+tpqiBR5aSG+8yu JOfHBJgAE2ACziEgIF5ZOL07WVabmkwXpMXTcz4A5BJTa8mZMQEmwASYgFMI+ODX7lZRGdMFiSop Ie5UUVnOkwkwASbABGwmIOTL8fqsa6kFSgRpycyc9wEsbalQPs4EmAATYAKuJODzBwL/UlVzJYJE lZXAZFWV5nyZABNgAkzAFgKvFBf2/ElVycoE6fdR0iJVFed8mQATYAJMwFICDR6pKV2OUSZIhEnT cFvTYMlSaFwYE2ACTIAJmE5APrWwsNta07MNylCpIC2anvM5gFlB5fFbJsAEmAATcB+BGq8vVdna kYFDqSBRIR4/bgfgMwrkVybABJgAE3AXASnwyILZXcpU11q5IC2clbMaAi+obgjnzwSYABNgAkoI bGvwND6gJOdmmSoXJCrP25hCo6TqZmXzRybABJgAE3A4ASlw97JX9y+3opqWCBIN9SQER5S1oke5 DCbABJiAWQQEfqxon/2YWdm1lo8lgkSVyKqlEOeitLUK8XkmwASYABNwBgEZwC0rnhSNVtXGMkGa Ny+nRorA361qGJfDBJgAE2ACsROQwHtLCnPmxJ5D9HdaJkhUtZP757wACTIF58QEmAATYALOJeD3 yMD1VlfP8kB6eWPLjoaUH5sdi8lqcFweE2ACTCBRCUghH18yo/vVVrfP0hESNW7xjOzPADxrdUO5 PCbABJgAE2idgAS2BOobyMuO5clyQaIWpkpBjd1heWu5QCbABJgAEwhPQOC24jd62fL32RZBml+Y vQVC/F94KnyWCTABJsAErCQgpPzk5P7Zts1g2SJIBPik/t2eAPS1JCt5c1lMgAkwASYQmoDPr8kr J08WgdCn1R+13KghuEmDx244VJMaWd15g4/zeybABJgAE7CYgJBTFs/o/leLS92jONtGSFSLpTN6 fA2IaXvUiD8wASbABJiA1QTWeVI9SmMdRdIgWwWJKphZKwmC0hgbkYDga5gAE2ACyUpACnH1wpe6 2e5v1HZBIg8Omha4nAP5JetXgdvNBJiAzQReXjIje77NddCLt12QqBaLpvdYDOBJJwDhOjABJsAE kojAJq/0X+eU9jpCkAhGXV3KzQB+dQoYrgcTYAJMINEJSImrFxT23O6UdjpGkD6c26VSCslTd055 MrgeTIAJJDgBMd1q56mtAXWMIFFFl8zovhCQj7dWaT7PBJgAE2AC8RAQpV7p+3M8Oai411GCRA30 pHnIDv4HFY3lPJkAE2ACTABSQF7qpKk6o08cJ0hkehjQtAsB+IxK8isTYAJMgAmYRUD+t2hmzgKz cjMzH8cJEjVu6fRun0DIe8xsKOfFBJgAE0h2AlJgdWatsNUbQ7g+cKQgUYX9m3P+CYmPwlWezzEB JsAEmEDEBBoAnEd7PyO+w+ILHStIxcXCJ/2YIIByi5lwcUyACTCBxCMg8dclM3K+cHLDHCtIBG3J 7JxfpBRXOBkg140JMAEm4AICby8uzH7E6fV0tCARvMWF2a8L4Amng+T6MQEmwAScSUCU+j24GBDS mfXbXSvHCxJVtVr6b4TEl7urze+YABNgAkwgAgI+aHJc8Ws5WyO41vZLXCFIywt71krNkw+gwnZi XAEmwASYgEsISIhbF0/P+cAl1YUrBIlgLpmx789CyIvYK7hbHi2uJxNgAjYTmLNkZrepNtchquJd I0jUqqIZ3d+EkA9G1UK+mAkwASaQbAQEfhQy/RI3rBsFd42rBIkq3imQc6uUgsJVcGICTIAJMIG9 CVSLgHZOUWEn1y1xuE6QCguFPw0YD4Ff9u4HPsIEmAATSGoCUgAXFRV2W+lGCq4TJII8vzB7SwCB MwE4dsexGx8GrjMTYALuJiCBfxXNzJnl1la4UpAI9tIZPb6WQlzMRg5uffS43kyACZhKQMq3Th6Q fYepeVqcmbC4PNOLyysoux2Qd5meMWfIBJgAE3APgZVCpp/kxnWjYMSuFyRAiryCspfIaWBww/g9 E2ACTCAZCEhgS8AXOKJ4do8Nbm+va6fsdoMXspMsvxSQH+8+xu+YABNgAklBoEZq2qhEECPqrQQY ITU9dCPzy7o0CnwkIfsmxWPIjWQCTCDZCUgJed6Smd1fSxQQCTBCauoKsrzzSd9IGr4mSudwO5gA E2ACLREQErclkhhROxNmhGR02uBxm/6oBQJLAGQax/iVCTABJpBIBKSQjy+Z0f3qRGoTtSVhRkhG x1D484CU4ynorHGMX5kAE2ACCUTglX0COdckUHt2NSXhBIlatrSw+1wJ/IX3KO3qZ37DBJhAQhCQ S8iIizzWJERzmjUi4absgts3NL/0b1Lg3uBj/J4JMAEm4FICnwqZPtzte43CsU/IEZLR4KLCnPsE xP3GZ35lAkyACbiUwKpUKc5IZDGifknoEVLTg6dvnH0cwJUufRC52kyACSQzAYFf/I2BExNlr1G4 rkzoEVJTw2njbPafAbwSDgSfYwJMgAk4kMAGf8A/NBnEiNgnwQip6RHLz5eebaL0VQFR4MCHjqvE BJgAE2hGQJZByNzFM3r80OxEwn5MGkGiHjzyCpnSvrxsuhAYk7A9yg1jAkzA9QRog78mcErRjJzv XN+YKBqQBFN2u2mseFI07oPy8QJi7u6j/I4JMAEm4BwCuhhJLS/ZxIh6IKkEiRpcWDiwoaPcni8l ZjvnEeSaMAEmwAR0ApulRwx2a8TXePswqabsgmHl5kqvZ99NL0PKscHH+T0TYAJMwB4CotTjl3kL Z+Wstqd8+0tNuhGSgby4WPg6BbpRDKWXjWP8ygSYABOwicB6v/SdksxiRNyTVpCo8eR+o5PMpjDo /7PpIeRimQATSHICAuInvyZOLi7s+VOSo0ges+/wHS3FkLFl9wiJv4W/js8yASbABEwkIMU3fnhG FBd23WRirq7NKqlHSLt7TcglM3JuFVL8lR2y7qbC75gAE1BIQOKj+pSGXBaj3YyT1qhhN4I93w0Z WzpRSDwBwLPnGf7EBJgAEzCNwLuZtThn3rycGtNyTICMWJBCdOKQgo2jBASFBc4KcZoPMQEmwARi JiAgnivv0O1K2hcZcyYJeiMLUgsdS5FnRSAwTwBdWriEDzMBJsAEoiQg/7l4Zs4dgJBR3pgUl7Mg henm3Pz1fb3CO19C9g1zGZ9iAkyACbRGwC+Aq4pm5jzV2oXJfJ4FqZXezx1f2tnjxxwAJ7ZyKZ9m AkyACYQiUCGAsUUzcxaEOsnHdhNgK7vdLEK+K34tZ2tqZfVQ3kAbEg8fZAJMIDyBtQGPOIHFKDwk 4yyPkAwSEbzmFZTeCuBfyRS2IwIsfAkTYAIhCYjlnkZx1sI53X4LeZoP7kWABWkvJOEPDMkvPVsI vAigTfgr+SwTYAJJS0DI51N31vxp/vx+9UnLIIaGsyDFAG342E2DAlLOYWOHGODxLUwgsQn4hJA3 Fs3o/p/Ebqaa1rEgxcj1xAm/dEzzpbwK4NQYs+DbmAATSCACehwjTRQUTc8uTqBmWdoUNmqIEfey V/cv7ySzzwBwL7sbihEi38YEEoWAxOfw4WgWo/g6lEdI8fHT7x6aX3a6FPIFAPuYkB1nwQSYgIsI CCEeTdlZdROvF8XfaSxI8TPUcxiev6mXH4GZEDjKpCw5GybABJxNoAoCf1o8I+cVZ1fTPbXjKTuT +mphYbe1qVXVJ9KvJZ7CMwkqZ8MEnEtgpcePo1mMzO0gHiGZy1PPbejYjWdKKZ7hKTwFcDlLJmAz ASnk44GMhhuLn+9VZ3NVEq54FiRFXZo7ZkMPzau9LIBTFBXB2TIBJmAtge1SYuKSwhxyJcZJAQGe slMAlbIsnt1jwz4yOw8Q/wAku5lXxJmzZQIWEVgqJA5nMVJLm0dIavnquQ8bV3pUIACywhtgQXFc BBNgAuYRqBPAbScOyH548mQRMC9bzikUARakUFQUHDsuf31Gpua5FxLXsi88BYA5SyZgNgGJLwFx /uLC7FVmZ835hSbAghSai7KjeQVlgwXw5P+3d26xVVRRGP7/PbW2oqYgSIGC8a6QoPLgJYKppYL1 Fi+p0AcUrw/6oDHxHhU1XuOLiYmJqVGjRvAIGjERQ9GCGNEgmGgUlYhSORRRqQhKy5lZZho1EUs9 9zMz5386ObPXWnutb03yZ86Zvbe2HSoZYgUWgUIJDBj48K8NjQ/rVNdCUebmL0HKjVdRrAeflliz ALBbANQUJaiCiIAIFEzAgA/DPS8CAAAGbElEQVRovF5PRQWjzCuABCkvbMVxap275RQL2AlgWnEi KooIiECeBHYCvGvG5Man9V9RngSL4CZBKgLEQkI0N1uNO7z3ZsIeAFBfSCz5ioAI5EOAS/2Mf0P4 Zmw+3vIpHgEJUvFYFhSp9bJtRwUueIa0mQUFkrMIiEC2BLbB7KYVqQmLsnWQXWkJSJBKyzfH6MaW Oen5ND4OYHSOzjIXARHIjoABfK7GMre+k5r4S3YusioHAQlSOSjnOMfs9p5RGboHAV6vlx5yhCdz ERiewDrS3di1qHHN8GYarQQBCVIlqGc55+BLDz6fBDEjSxeZiYAIDE3gJxrunj5lXKdeWhgaUBSu SpCi0IVhczC2XJ6eS/BRAJOGNdWgCIjAvgQGQDzl9/c/2P3GkX37Dup7tAhIkKLVj/1mE65dGgHv JiNuB9CwX0MNiIAI/E3gdd/827pTEzf+fUGf0SYgQYp2f/6TXXNHerTn2/0ArgN4wH8MdEEEqpwA zT6C5+7QceLxuxEkSPHr2WDGze09x3j0FgDoAKBd22PaR6VdVAJfkLina9G41wFaUSMrWFkISJDK grl0k8zs6JmKjHsI5AWlm0WRRSDCBIjvYbxvlDW+lErRj3CmSu1/CEiQ/gdQXIZb5/SebkFwL4i2 uOSsPEWgQAKbaXx0JH55NpWaMlBgLLlHgIAEKQJNKGYKLe1bTyXtXgDnFzOuYolAhAh8R8MjI7Hj eQlRhLpShFQkSEWAGMUQ4aGAvo87SVys/5ii2CHllAeBrwh7fEfD+Bd1LEQe9GLgIkGKQZMKSfHs 9i3HO8dbYZgHoLaQWPIVgQoR+JjEY9NPHPeGFrVWqANlmlaCVCbQlZ7mnLmbxwfm3QzjdVrHVOlu aP4sCAQElhn4xIpXx72Xhb1MEkBAgpSAJuZSwqx5vSP8Absy3OUYwHG5+MpWBMpAYDdgL4D25IpF TV+XYT5NESECEqQINaOcqSxYYG7lF73nerAbDZgNwCvn/JpLBP5FgPjGjM8EA3s6tcXPv8hU1RcJ UlW1e+hiW9vTkwLyKsKu1n55QzPS1ZIQ6AfwGh07uxY2rtRi1pIwjlVQCVKs2lXaZMOnplVf9s5G YNeSdqG2Jiot7yqO/hkMz9bAf1HnEVXxXTBE6RKkIaDoEjCzY9tY8zPzSV4Dw7FiIgIFEtgF8FWY 37ki1fRhgbHknlACEqSENrZ4ZYXHX2ydQeIKGi41YGTxYitSwgkEAFbC7OXa2rrU2y8ftjPh9aq8 AglIkAoEWE3ubW3fHDhwyIg2g3UQvBBAfTXVr1qzJGBYC+AV52UWLl84KZ2ll8xEABIk3QR5ETjz ou2H1B04cB7Jyww4D8CIvALJKQkEDLCPaG4JAre4a/HYb5NQlGooPwEJUvmZJ27G8PDAg+iFr45f YkAbgTGJK1IF7UsgA9gqI5cGe4PXupc0/bCvgb6LQK4EJEi5EpP9sATa28372UufxoAXwHg+aFOH ddBgnAj8BGAZzN4i6pd1pUb9GqfklWv0CUiQot+jWGfYfOkPTTU1nGVw5xhspp6eYtXO8EiHNQSW +84tH+2PXavzhmLVv9glK0GKXcvim3C4zmn1hvRJ8F2rITgL5HTtqxepfvowrIfDKgZ8NwNvZXfq 8F2RylDJJJqABCnR7Y12ceHPezu89FTzeRaIGQBOBzAh2lknKrvdMKwDsdrI9/v/qFn9wZtjfktU hSomVgQkSLFqV/KTbWnvmeCcdxrMzjDwVAAnAzg0+ZWXvMKMARsIfGLAGs+CNXu3T/i8u5uZks+s CUQgSwISpCxByaxSBIwtc348CgimATaNNihQk7Xn3rD92EmzL438FMT6gO7Tg3cHny1dOv73Yb00 KAIVJiBBqnADNH1+BMJ1ULUH+ZO9wJ9ixAk0d7yZHQ3iaAB1+UWNlZcBCF+13mjARho2mLPPXcAN Xanxm2NViZIVgb8ISJB0KySMgHHW3HSTH7hjBp+iDEcYrYmGpsHvxMSY/AQY7oS9zYAewLYQDD83 G7DJkRsz9f2bup8/ck/CmqdyqpyABKnKb4BqLL95/qa62j21Y3xzjQDHGvwxNDfKYA2ObDCzBpg1 GFy9ozWY8QA4Oxhm9QT/efraz75+vxMIxQTh9gUg+mDYS2CXGcKxPwJaH8k+GnfArC8g+hyw3Rx+ 9PZie+DqtmqNTzXemar5T7boKrYfCqI6AAAAAElFTkSuQmCC"/></symbol><symbol viewBox="0 0 24 24" id="webpack" xmlns="http://www.w3.org/2000/svg"><path d="M19.376 15.988l-7.709 4.45-7.708-4.45V7.087l7.708-4.45 7.709 4.45z" fill="#fff" fill-opacity=".785" stroke-width="0"/><path d="M12.286 1.98c-.21 0-.41.059-.57.179l-7.9 4.44c-.32.17-.53.5-.53.88v9c0 .38.21.711.53.881l7.9 4.44c.16.12.36.18.57.18.21 0 .41-.06.57-.18l7.9-4.44c.32-.17.53-.5.53-.88v-9c0-.38-.21-.712-.53-.882l-7.9-4.44a.945.945 0 0 0-.57-.179zm0 2.15l7 3.939v2.104h-.016v5.177h.016v.54l-7 3.939-7-3.94V8.07l7-3.94zm0 2.08l-4.9 2.83 4.9 2.83 4.9-2.83-4.9-2.83zm-5 5.08v3.58l4 2.308v-3.58l-4-2.308zm10 0l-4 2.308v3.58l4-2.308v-3.58z" fill="#8ed6fb"/><path d="M12.286 6.21l-4.9 2.83 4.9 2.83 4.9-2.83-4.9-2.83zm-5 5.08v3.58l4 2.308v-3.58l-4-2.308zm10 0l-4 2.308v3.58l4-2.308v-3.58z" fill="#1c78c0"/></symbol><symbol viewBox="0 0 24 24" id="wolframlanguage" xmlns="http://www.w3.org/2000/svg"><title>wolframLanguage</title><g transform="scale(.12121)" fill="none" fill-rule="evenodd"><circle cx="99.197" cy="98.946" r="83.28" fill="#212121" stroke-width=".841"/><path d="M182.529 98.828a83.406 83.406 0 0 1-39.14 70.721.064.064 0 0 1-.038.019l-28.62-35.665 23.71 2.612s11.385 1.177 13.978 0c2.373-.938 15.175-18.963 15.175-18.963s-36.75-23.23-49.312-36.032c1.434-21.575-1.656-50.269-1.656-50.03-9.251 9.234-10.429 10.669-19.68 19.203-4.028-13.04-5.923-17.547-9.95-30.588-12.104 9.95-21.337 26.799-27.977 46.48a78.68 78.68 0 0 0-4.23 5.094 109.774 109.774 0 0 0-2.667 3.66 114.558 114.558 0 0 0-5.132 8.002 172.555 172.555 0 0 0-3.403 6.051c-7.706 14.475-14.034 31.066-19.515 46.001a.858.858 0 0 1-.092-.184c-14.988-30.912-9.502-67.85 13.822-93.072 23.325-25.223 59.723-33.575 91.71-21.045 31.988 12.53 53.029 43.382 53.017 77.736z" fill="#e53935"/><path d="M101.452 69.178s-1.416-8.295-2.373-11.367c6.401-6.18 7.357-7.118 13.52-13.04.477 11.845.238 18.006-.479 32.481-3.55-3.568-10.668-8.074-10.668-8.074zm-27.737 40.778s-6.64-4.029-11.624-4.728c1.435-3.329 5.223-7.596 6.18-8.773-1.913.699-15.653 6.86-17.087 12.084a74.804 74.804 0 0 1 11.385 3.79 35.993 35.993 0 0 0-8.774 20.158s21.815-3.33 38.185-1.196c.283.168.609.251.938.24l8.534.239 27.111 45.136.221.35c-.037.018-.055.037-.073.037-51.133 18.485-88.085-15.543-95.976-27.443.034-.102.058-.206.074-.313 7.1-30.017 15.855-65.939 30-76.552 7.356-12.82 9.49-31.783 22.751-41.734 3.33 9.951 8.553 30.588 12.103 40.539 15.653 15.652 39.361 35.094 55.234 43.15 1.656.956 3.79 7.596 3.79 7.596l-6.401 8.056-68.276-6.879a54.462 54.462 0 0 0-4.58-.183 86.848 86.848 0 0 0-14.144 1.36c3.311-8.295 10.43-14.935 10.43-14.935zm22.054-8.774c3.789-.46 7.817.956 12.323 3.568 4.267-1.195 4.745-1.434 9.013-2.612-5.463-4.028-11.386-8.295-19.442-7.118a47.249 47.249 0 0 0-1.894 6.162z" fill="#fff" stroke-width=".936"/></g></symbol><symbol viewBox="0 0 24 24" id="word" xmlns="http://www.w3.org/2000/svg"><path d="M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2m7 1.5V9h5.5L13 3.5M7 13l1.5 7h2l1.5-3 1.5 3h2l1.5-7h1v-2h-4v2h1l-.9 4.2L13 15h-2l-1.1 2.2L9 13h1v-2H6v2h1z" fill="#01579b"/></symbol><symbol viewBox="0 0 24 24" id="xaml" xmlns="http://www.w3.org/2000/svg"><path d="M18.93 12l-3.47 6H8.54l-3.47-6 3.47-6h6.92l3.47 6m4.84 0l-4.04 7L18 18l3.46-6L18 6l1.73-1 4.04 7M.23 12l4.04-7L6 6l-3.46 6L6 18l-1.73 1-4.04-7z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 24 24" id="xml" xmlns="http://www.w3.org/2000/svg"><path d="M13 9h5.5L13 3.5V9M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m.12 13.5l3.74 3.74 1.42-1.41-2.33-2.33 2.33-2.33-1.42-1.41-3.74 3.74m11.16 0l-3.74-3.74-1.42 1.41 2.33 2.33-2.33 2.33 1.42 1.41 3.74-3.74z" fill="#8bc34a"/></symbol><symbol viewBox="0 0 24 24" id="yaml" xmlns="http://www.w3.org/2000/svg"><path d="M5 3h2v2H5v5a2 2 0 0 1-2 2 2 2 0 0 1 2 2v5h2v2H5c-1.07-.27-2-.9-2-2v-4a2 2 0 0 0-2-2H0v-2h1a2 2 0 0 0 2-2V5a2 2 0 0 1 2-2m14 0a2 2 0 0 1 2 2v4a2 2 0 0 0 2 2h1v2h-1a2 2 0 0 0-2 2v4a2 2 0 0 1-2 2h-2v-2h2v-5a2 2 0 0 1 2-2 2 2 0 0 1-2-2V5h-2V3h2m-7 12a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m-4 0a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m8 0a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1z" fill="#f44336"/></symbol><symbol viewBox="0 0 24 24" id="yang" xmlns="http://www.w3.org/2000/svg"><path d="M12 2a10 10 0 0 1 10 10 10 10 0 0 1-10 10A10 10 0 0 1 2 12 10 10 0 0 1 12 2m0 2a8 8 0 0 0-8 8 8 8 0 0 0 8 8 4 4 0 0 1-4-4 4 4 0 0 1 4-4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 2.5A1.5 1.5 0 0 1 13.5 8 1.5 1.5 0 0 1 12 9.5 1.5 1.5 0 0 1 10.5 8 1.5 1.5 0 0 1 12 6.5m0 8a1.5 1.5 0 0 0-1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5-1.5 1.5 1.5 0 0 0-1.5-1.5z" fill="#42a5f5"/></symbol><symbol viewBox="0 0 289.99999 290.00001" id="yarn" xmlns="http://www.w3.org/2000/svg"><path d="M250.733 218.418c-12.39 2.943-18.661 5.653-33.993 15.641-24.004 15.487-50.176 22.688-50.176 22.688s-2.168 3.252-8.44 4.723c-10.84 2.633-51.647 4.878-55.364 4.956-9.988.077-16.105-2.555-17.809-6.66-5.188-12.388 7.434-17.809 7.434-17.809s-2.788-1.703-4.414-3.252c-1.471-1.47-3.02-4.413-3.484-3.33-1.936 4.724-2.943 16.261-8.13 21.45-7.125 7.2-20.598 4.8-28.573.619-8.75-4.646.62-15.564.62-15.564s-4.724 2.788-8.518-2.942c-3.407-5.266-6.582-14.248-5.73-25.32 1.084-12.777 15.176-25.011 15.176-25.011s-2.477-18.661 5.653-37.787c7.356-17.422 27.179-31.437 27.179-31.437s-16.648-18.352-10.454-35c4.027-10.84 5.653-10.763 6.97-11.227 4.645-1.781 9.136-3.717 12.466-7.356 16.648-17.964 37.864-14.557 37.864-14.557s9.911-30.431 19.203-24.469c2.865 1.859 13.163 24.778 13.163 24.778s10.996-6.426 12.235-4.026c6.659 12.931 7.433 37.632 4.49 52.654-4.955 24.778-17.344 38.096-22.3 46.459-1.161 1.936 13.319 8.053 22.456 33.373 8.44 23.152.929 42.587 2.245 44.756.232.387.31.542.31.542s9.679.774 29.114-11.228c10.376-6.427 22.688-13.628 36.703-13.783 13.55-.232 14.247 15.719 4.104 18.12z" fill="#2c8ebb" stroke-width=".774"/></symbol><symbol viewBox="0 0 24 24" id="zip" xmlns="http://www.w3.org/2000/svg"><path d="M14 17h-2v-2h-2v-2h2v2h2m0-6h-2v2h2v2h-2v-2h-2V9h2V7h-2V5h2v2h2m5-4H5c-1.11 0-2 .89-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z" fill="#afb42b"/></symbol></svg>
diff --git a/app/assets/javascripts/admin/users/components/user_actions.vue b/app/assets/javascripts/admin/users/components/user_actions.vue
index 567d7151847..f5d21ece138 100644
--- a/app/assets/javascripts/admin/users/components/user_actions.vue
+++ b/app/assets/javascripts/admin/users/components/user_actions.vue
@@ -109,12 +109,13 @@ export default {
<div v-if="hasDropdownActions" class="gl-p-2">
<gl-dropdown
data-testid="dropdown-toggle"
- right
:text="$options.i18n.userAdministration"
:text-sr-only="!showButtonLabels"
icon="ellipsis_h"
data-qa-selector="user_actions_dropdown_toggle"
:data-qa-username="user.username"
+ no-caret
+ right
>
<gl-dropdown-section-header>{{
$options.i18n.userAdministration
diff --git a/app/assets/javascripts/analytics/shared/components/projects_dropdown_filter.vue b/app/assets/javascripts/analytics/shared/components/projects_dropdown_filter.vue
index 0bdb45d35c9..b3ae671d611 100644
--- a/app/assets/javascripts/analytics/shared/components/projects_dropdown_filter.vue
+++ b/app/assets/javascripts/analytics/shared/components/projects_dropdown_filter.vue
@@ -31,7 +31,8 @@ export default {
props: {
groupId: {
type: Number,
- required: true,
+ required: false,
+ default: null,
},
groupNamespace: {
type: String,
@@ -57,6 +58,11 @@ export default {
required: false,
default: () => [],
},
+ loadingDefaultProjects: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
return {
@@ -111,6 +117,9 @@ export default {
searchTerm() {
this.search();
},
+ defaultProjects(projects) {
+ this.selectedProjects = [...projects];
+ },
},
mounted() {
this.search();
@@ -202,6 +211,7 @@ export default {
ref="projectsDropdown"
class="dropdown dropdown-projects"
toggle-class="gl-shadow-none"
+ :loading="loadingDefaultProjects"
:show-clear-all="hasSelectedProjects"
show-highlighted-items-title
highlighted-items-title-class="gl-p-3"
@@ -209,6 +219,7 @@ export default {
@hide="onHide"
>
<template #button-content>
+ <gl-loading-icon v-if="loadingDefaultProjects" class="gl-mr-2" />
<div class="gl-display-flex gl-flex-grow-1">
<gl-avatar
v-if="isOnlyOneProjectSelected"
diff --git a/app/assets/javascripts/api/packages_api.js b/app/assets/javascripts/api/packages_api.js
index 47f51c7e80e..138843a910a 100644
--- a/app/assets/javascripts/api/packages_api.js
+++ b/app/assets/javascripts/api/packages_api.js
@@ -19,13 +19,7 @@ export function publishPackage(
status: 'default',
};
- const formData = new FormData();
- formData.append('file', files[0]);
-
- return axios.put(url, formData, {
- headers: {
- 'Content-Type': 'multipart/form-data',
- },
+ return axios.put(url, files[0], {
params: Object.assign(defaults, options),
...axiosOptions,
});
diff --git a/app/assets/javascripts/behaviors/copy_code.js b/app/assets/javascripts/behaviors/copy_code.js
index a6e203ea5a2..6d2a4c245cc 100644
--- a/app/assets/javascripts/behaviors/copy_code.js
+++ b/app/assets/javascripts/behaviors/copy_code.js
@@ -29,7 +29,8 @@ class CopyCodeButton extends HTMLElement {
}
function addCodeButton() {
- [...document.querySelectorAll('pre.code.js-syntax-highlight')]
+ [...document.querySelectorAll('pre.code.js-syntax-highlight:not(.content-editor-code-block)')]
+ .filter((el) => el.getAttribute('lang') !== 'mermaid')
.filter((el) => !el.closest('.js-markdown-code'))
.forEach((el) => {
const copyCodeEl = document.createElement('copy-code');
diff --git a/app/assets/javascripts/behaviors/copy_to_clipboard.js b/app/assets/javascripts/behaviors/copy_to_clipboard.js
index de248340738..c3c28aeafc0 100644
--- a/app/assets/javascripts/behaviors/copy_to_clipboard.js
+++ b/app/assets/javascripts/behaviors/copy_to_clipboard.js
@@ -1,7 +1,13 @@
-import Clipboard from 'clipboard';
+import ClipboardJS from 'clipboard';
import $ from 'jquery';
-import { sprintf, __ } from '~/locale';
-import { fixTitle, add, show, once } from '~/tooltips';
+
+import { parseBoolean } from '~/lib/utils/common_utils';
+import { __ } from '~/locale';
+import { fixTitle, add, show, hide, once } from '~/tooltips';
+
+const CLIPBOARD_SUCCESS_EVENT = 'clipboard-success';
+const CLIPBOARD_ERROR_EVENT = 'clipboard-error';
+const I18N_ERROR_MESSAGE = __('Copy failed. Please manually copy the value.');
function showTooltip(target, title) {
const { title: originalTitle } = target.dataset;
@@ -9,20 +15,31 @@ function showTooltip(target, title) {
once('hidden', (tooltip) => {
if (tooltip.target === target) {
target.setAttribute('title', originalTitle);
+ target.setAttribute('aria-label', originalTitle);
fixTitle(target);
}
});
target.setAttribute('title', title);
+ target.setAttribute('aria-label', title);
fixTitle(target);
show(target);
- setTimeout(() => target.blur(), 1000);
+ setTimeout(() => {
+ hide(target);
+ }, 1000);
}
function genericSuccess(e) {
- // Clear the selection and blur the trigger so it loses its border
+ // Clear the selection
e.clearSelection();
- showTooltip(e.trigger, __('Copied'));
+ e.trigger.focus();
+ e.trigger.dispatchEvent(new Event(CLIPBOARD_SUCCESS_EVENT));
+
+ const { clipboardHandleTooltip = true } = e.trigger.dataset;
+ if (parseBoolean(clipboardHandleTooltip)) {
+ // Update tooltip
+ showTooltip(e.trigger, __('Copied'));
+ }
}
/**
@@ -30,17 +47,16 @@ function genericSuccess(e) {
* See http://clipboardjs.com/#browser-support
*/
function genericError(e) {
- let key;
- if (/Mac/i.test(navigator.userAgent)) {
- key = '&#8984;'; // Command
- } else {
- key = 'Ctrl';
+ e.trigger.dispatchEvent(new Event(CLIPBOARD_ERROR_EVENT));
+
+ const { clipboardHandleTooltip = true } = e.trigger.dataset;
+ if (parseBoolean(clipboardHandleTooltip)) {
+ showTooltip(e.trigger, I18N_ERROR_MESSAGE);
}
- showTooltip(e.trigger, sprintf(__(`Press %{key}-C to copy`), { key }));
}
export default function initCopyToClipboard() {
- const clipboard = new Clipboard('[data-clipboard-target], [data-clipboard-text]');
+ const clipboard = new ClipboardJS('[data-clipboard-target], [data-clipboard-text]');
clipboard.on('success', genericSuccess);
clipboard.on('error', genericError);
@@ -74,6 +90,8 @@ export default function initCopyToClipboard() {
clipboardData.setData('text/plain', json.text);
clipboardData.setData('text/x-gfm', json.gfm);
});
+
+ return clipboard;
}
/**
@@ -89,3 +107,5 @@ export function clickCopyToClipboardButton(btnElement) {
btnElement.click();
}
+
+export { CLIPBOARD_SUCCESS_EVENT, CLIPBOARD_ERROR_EVENT, I18N_ERROR_MESSAGE };
diff --git a/app/assets/javascripts/behaviors/markdown/render_gfm.js b/app/assets/javascripts/behaviors/markdown/render_gfm.js
index 4698fcd4d42..c4e09efe263 100644
--- a/app/assets/javascripts/behaviors/markdown/render_gfm.js
+++ b/app/assets/javascripts/behaviors/markdown/render_gfm.js
@@ -4,6 +4,7 @@ import initUserPopovers from '../../user_popovers';
import highlightCurrentUser from './highlight_current_user';
import renderMath from './render_math';
import renderMermaid from './render_mermaid';
+import renderSandboxedMermaid from './render_sandboxed_mermaid';
import renderMetrics from './render_metrics';
// Render GitLab flavoured Markdown
@@ -13,7 +14,11 @@ import renderMetrics from './render_metrics';
$.fn.renderGFM = function renderGFM() {
syntaxHighlight(this.find('.js-syntax-highlight').get());
renderMath(this.find('.js-render-math'));
- renderMermaid(this.find('.js-render-mermaid'));
+ if (gon.features?.sandboxedMermaid) {
+ renderSandboxedMermaid(this.find('.js-render-mermaid'));
+ } else {
+ renderMermaid(this.find('.js-render-mermaid'));
+ }
highlightCurrentUser(this.find('.gfm-project_member').get());
initUserPopovers(this.find('.js-user-link').get());
diff --git a/app/assets/javascripts/behaviors/markdown/render_sandboxed_mermaid.js b/app/assets/javascripts/behaviors/markdown/render_sandboxed_mermaid.js
new file mode 100644
index 00000000000..1d54a1b0c04
--- /dev/null
+++ b/app/assets/javascripts/behaviors/markdown/render_sandboxed_mermaid.js
@@ -0,0 +1,234 @@
+import $ from 'jquery';
+import { once, countBy } from 'lodash';
+import { __ } from '~/locale';
+import {
+ getBaseURL,
+ relativePathToAbsolute,
+ setUrlParams,
+ joinPaths,
+} from '~/lib/utils/url_utility';
+import { darkModeEnabled } from '~/lib/utils/color_utils';
+import { setAttributes } from '~/lib/utils/dom_utils';
+
+// Renders diagrams and flowcharts from text using Mermaid in any element with the
+// `js-render-mermaid` class.
+//
+// Example markup:
+//
+// <pre class="js-render-mermaid">
+// graph TD;
+// A-- > B;
+// A-- > C;
+// B-- > D;
+// C-- > D;
+// </pre>
+//
+
+const SANDBOX_FRAME_PATH = '/-/sandbox/mermaid';
+// This is an arbitrary number; Can be iterated upon when suitable.
+const MAX_CHAR_LIMIT = 2000;
+// Max # of mermaid blocks that can be rendered in a page.
+const MAX_MERMAID_BLOCK_LIMIT = 50;
+// Max # of `&` allowed in Chaining of links syntax
+const MAX_CHAINING_OF_LINKS_LIMIT = 30;
+const BUFFER_IFRAME_HEIGHT = 10;
+// Keep a map of mermaid blocks we've already rendered.
+const elsProcessingMap = new WeakMap();
+let renderedMermaidBlocks = 0;
+
+// Pages without any restrictions on mermaid rendering
+const PAGES_WITHOUT_RESTRICTIONS = [
+ // Group wiki
+ 'groups:wikis:show',
+ 'groups:wikis:edit',
+ 'groups:wikis:create',
+
+ // Project wiki
+ 'projects:wikis:show',
+ 'projects:wikis:edit',
+ 'projects:wikis:create',
+
+ // Project files
+ 'projects:show',
+ 'projects:blob:show',
+];
+
+function shouldLazyLoadMermaidBlock(source) {
+ /**
+ * If source contains `&`, which means that it might
+ * contain Chaining of links a new syntax in Mermaid.
+ */
+ if (countBy(source)['&'] > MAX_CHAINING_OF_LINKS_LIMIT) {
+ return true;
+ }
+
+ return false;
+}
+
+function fixElementSource(el) {
+ // Mermaid doesn't like `<br />` tags, so collapse all like tags into `<br>`, which is parsed correctly.
+ const source = el.textContent?.replace(/<br\s*\/>/g, '<br>');
+
+ // Remove any extra spans added by the backend syntax highlighting.
+ Object.assign(el, { textContent: source });
+
+ return { source };
+}
+
+function getSandboxFrameSrc() {
+ const path = joinPaths(gon.relative_url_root || '', SANDBOX_FRAME_PATH);
+ if (!darkModeEnabled()) {
+ return path;
+ }
+ const absoluteUrl = relativePathToAbsolute(path, getBaseURL());
+ return setUrlParams({ darkMode: darkModeEnabled() }, absoluteUrl);
+}
+
+function renderMermaidEl(el, source) {
+ const iframeEl = document.createElement('iframe');
+ setAttributes(iframeEl, {
+ src: getSandboxFrameSrc(),
+ sandbox: 'allow-scripts',
+ frameBorder: 0,
+ scrolling: 'no',
+ width: '100%',
+ });
+
+ // Add the original source into the DOM
+ // to allow Copy-as-GFM to access it.
+ const sourceEl = document.createElement('text');
+ sourceEl.textContent = source;
+ sourceEl.classList.add('gl-display-none');
+
+ const wrapper = document.createElement('div');
+ wrapper.appendChild(iframeEl);
+ wrapper.appendChild(sourceEl);
+
+ el.closest('pre').replaceWith(wrapper);
+
+ // Event Listeners
+ iframeEl.addEventListener('load', () => {
+ // Potential risk associated with '*' discussed in below thread
+ // https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74414#note_735183398
+ iframeEl.contentWindow.postMessage(source, '*');
+ });
+
+ window.addEventListener(
+ 'message',
+ (event) => {
+ if (event.origin !== 'null' || event.source !== iframeEl.contentWindow) {
+ return;
+ }
+ const { h } = event.data;
+ iframeEl.height = `${h + BUFFER_IFRAME_HEIGHT}px`;
+ },
+ false,
+ );
+}
+
+function renderMermaids($els) {
+ if (!$els.length) return;
+
+ const pageName = document.querySelector('body').dataset.page;
+
+ // A diagram may have been truncated in search results which will cause errors, so abort the render.
+ if (pageName === 'search:show') return;
+
+ let renderedChars = 0;
+
+ $els.each((i, el) => {
+ // Skipping all the elements which we've already queued in requestIdleCallback
+ if (elsProcessingMap.has(el)) {
+ return;
+ }
+
+ const { source } = fixElementSource(el);
+ /**
+ * Restrict the rendering to a certain amount of character
+ * and mermaid blocks to prevent mermaidjs from hanging
+ * up the entire thread and causing a DoS.
+ */
+ if (
+ !PAGES_WITHOUT_RESTRICTIONS.includes(pageName) &&
+ ((source && source.length > MAX_CHAR_LIMIT) ||
+ renderedChars > MAX_CHAR_LIMIT ||
+ renderedMermaidBlocks >= MAX_MERMAID_BLOCK_LIMIT ||
+ shouldLazyLoadMermaidBlock(source))
+ ) {
+ const html = `
+ <div class="alert gl-alert gl-alert-warning alert-dismissible lazy-render-mermaid-container js-lazy-render-mermaid-container fade show" role="alert">
+ <div>
+ <div>
+ <div class="js-warning-text"></div>
+ <div class="gl-alert-actions">
+ <button type="button" class="js-lazy-render-mermaid btn gl-alert-action btn-warning btn-md gl-button">Display</button>
+ </div>
+ </div>
+ <button type="button" class="close" data-dismiss="alert" aria-label="Close">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ </div>
+ </div>
+ `;
+
+ const $parent = $(el).parent();
+
+ if (!$parent.hasClass('lazy-alert-shown')) {
+ $parent.after(html);
+ $parent
+ .siblings()
+ .find('.js-warning-text')
+ .text(
+ __('Warning: Displaying this diagram might cause performance issues on this page.'),
+ );
+ $parent.addClass('lazy-alert-shown');
+ }
+
+ return;
+ }
+
+ renderedChars += source.length;
+ renderedMermaidBlocks += 1;
+
+ const requestId = window.requestIdleCallback(() => {
+ renderMermaidEl(el, source);
+ });
+
+ elsProcessingMap.set(el, requestId);
+ });
+}
+
+const hookLazyRenderMermaidEvent = once(() => {
+ $(document.body).on('click', '.js-lazy-render-mermaid', function eventHandler() {
+ const parent = $(this).closest('.js-lazy-render-mermaid-container');
+ const pre = parent.prev();
+
+ const el = pre.find('.js-render-mermaid');
+
+ parent.remove();
+
+ // sandbox update
+ const element = el.get(0);
+ const { source } = fixElementSource(element);
+
+ renderMermaidEl(element, source);
+ });
+});
+
+export default function renderMermaid($els) {
+ if (!$els.length) return;
+
+ const visibleMermaids = $els.filter(function filter() {
+ return $(this).closest('details').length === 0 && $(this).is(':visible');
+ });
+
+ renderMermaids(visibleMermaids);
+
+ $els.closest('details').one('toggle', function toggle() {
+ if (this.open) {
+ renderMermaids($(this).find('.js-render-mermaid'));
+ }
+ });
+
+ hookLazyRenderMermaidEvent();
+}
diff --git a/app/assets/javascripts/behaviors/preview_markdown.js b/app/assets/javascripts/behaviors/preview_markdown.js
index a548b283142..679940d1317 100644
--- a/app/assets/javascripts/behaviors/preview_markdown.js
+++ b/app/assets/javascripts/behaviors/preview_markdown.js
@@ -124,13 +124,6 @@ const writeButtonSelector = '.js-md-write-button';
lastTextareaPreviewed = null;
const markdownToolbar = $('.md-header-toolbar');
-$.fn.setupMarkdownPreview = function () {
- const $form = $(this);
- $form.find('textarea.markdown-area').on('input', () => {
- markdownPreview.hideReferencedUsers($form);
- });
-};
-
$(document).on('markdown-preview:show', (e, $form) => {
if (!$form) {
return;
diff --git a/app/assets/javascripts/blob/blob_line_permalink_updater.js b/app/assets/javascripts/blob/blob_line_permalink_updater.js
index 11089b299c5..a3dd241604d 100644
--- a/app/assets/javascripts/blob/blob_line_permalink_updater.js
+++ b/app/assets/javascripts/blob/blob_line_permalink_updater.js
@@ -1,6 +1,6 @@
import { getLocationHash } from '../lib/utils/url_utility';
-const lineNumberRe = /^L[0-9]+/;
+const lineNumberRe = /^(L|LC)[0-9]+/;
const updateLineNumbersOnBlobPermalinks = (linksToUpdate) => {
const hash = getLocationHash();
diff --git a/app/assets/javascripts/blob/components/blob_header.vue b/app/assets/javascripts/blob/components/blob_header.vue
index 933ad448c77..1645469a218 100644
--- a/app/assets/javascripts/blob/components/blob_header.vue
+++ b/app/assets/javascripts/blob/components/blob_header.vue
@@ -81,7 +81,7 @@ export default {
</blob-filepath>
</div>
- <div class="gl-display-none gl-sm-display-flex">
+ <div class="gl-sm-display-flex file-actions">
<viewer-switcher v-if="showViewerSwitcher" v-model="viewer" />
<slot name="actions"></slot>
diff --git a/app/assets/javascripts/blob/components/blob_header_filepath.vue b/app/assets/javascripts/blob/components/blob_header_filepath.vue
index cb441a7e491..90d01358451 100644
--- a/app/assets/javascripts/blob/components/blob_header_filepath.vue
+++ b/app/assets/javascripts/blob/components/blob_header_filepath.vue
@@ -1,4 +1,5 @@
<script>
+import { GlBadge } from '@gitlab/ui';
import { numberToHumanSize } from '~/lib/utils/number_utils';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import FileIcon from '~/vue_shared/components/file_icon.vue';
@@ -7,6 +8,7 @@ export default {
components: {
FileIcon,
ClipboardButton,
+ GlBadge,
},
props: {
blob: {
@@ -21,6 +23,9 @@ export default {
gfmCopyText() {
return `\`${this.blob.path}\``;
},
+ showLfsBadge() {
+ return this.blob.storedExternally && this.blob.externalStorage === 'lfs';
+ },
},
};
</script>
@@ -37,8 +42,6 @@ export default {
>
</template>
- <small class="mr-2">{{ blobSize }}</small>
-
<clipboard-button
:text="blob.path"
:gfm="gfmCopyText"
@@ -46,5 +49,9 @@ export default {
category="tertiary"
css-class="btn-clipboard btn-transparent lh-100 position-static"
/>
+
+ <small class="mr-2">{{ blobSize }}</small>
+
+ <gl-badge v-if="showLfsBadge">{{ __('LFS') }}</gl-badge>
</div>
</template>
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 a5b594fbd88..b2546d47694 100644
--- a/app/assets/javascripts/blob/components/blob_header_viewer_switcher.vue
+++ b/app/assets/javascripts/blob/components/blob_header_viewer_switcher.vue
@@ -53,6 +53,8 @@ export default {
icon="code"
category="primary"
variant="default"
+ class="js-blob-viewer-switch-btn"
+ data-viewer="simple"
@click="switchToViewer($options.SIMPLE_BLOB_VIEWER)"
/>
<gl-button
@@ -63,6 +65,8 @@ export default {
icon="document"
category="primary"
variant="default"
+ class="js-blob-viewer-switch-btn"
+ data-viewer="rich"
@click="switchToViewer($options.RICH_BLOB_VIEWER)"
/>
</gl-button-group>
diff --git a/app/assets/javascripts/line_highlighter.js b/app/assets/javascripts/blob/line_highlighter.js
index a1f59aa1b54..a1f59aa1b54 100644
--- a/app/assets/javascripts/line_highlighter.js
+++ b/app/assets/javascripts/blob/line_highlighter.js
diff --git a/app/assets/javascripts/boards/components/board_card.vue b/app/assets/javascripts/boards/components/board_card.vue
index 563bed6a6b8..dc821cb9f58 100644
--- a/app/assets/javascripts/boards/components/board_card.vue
+++ b/app/assets/javascripts/boards/components/board_card.vue
@@ -72,7 +72,7 @@ export default {
data-qa-selector="board_card"
:class="{
'multi-select': multiSelectVisible,
- 'user-can-drag': isDraggable,
+ 'gl-cursor-grab': isDraggable,
'is-disabled': isDisabled,
'is-active': isActive,
'gl-cursor-not-allowed gl-bg-gray-10': item.isLoading,
diff --git a/app/assets/javascripts/boards/components/board_content_sidebar.vue b/app/assets/javascripts/boards/components/board_content_sidebar.vue
index f89f8e5feb8..156029b62b0 100644
--- a/app/assets/javascripts/boards/components/board_content_sidebar.vue
+++ b/app/assets/javascripts/boards/components/board_content_sidebar.vue
@@ -6,11 +6,12 @@ import SidebarDropdownWidget from 'ee_else_ce/sidebar/components/sidebar_dropdow
import { __, sprintf } from '~/locale';
import BoardSidebarTimeTracker from '~/boards/components/sidebar/board_sidebar_time_tracker.vue';
import BoardSidebarTitle from '~/boards/components/sidebar/board_sidebar_title.vue';
-import { ISSUABLE } from '~/boards/constants';
+import { ISSUABLE, INCIDENT } from '~/boards/constants';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import SidebarAssigneesWidget from '~/sidebar/components/assignees/sidebar_assignees_widget.vue';
import SidebarConfidentialityWidget from '~/sidebar/components/confidential/sidebar_confidentiality_widget.vue';
import SidebarDateWidget from '~/sidebar/components/date/sidebar_date_widget.vue';
+import SidebarSeverity from '~/sidebar/components/severity/sidebar_severity.vue';
import SidebarSubscriptionsWidget from '~/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue';
import SidebarTodoWidget from '~/sidebar/components/todo_toggle/sidebar_todo_widget.vue';
import SidebarLabelsWidget from '~/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue';
@@ -29,6 +30,7 @@ export default {
SidebarSubscriptionsWidget,
SidebarDropdownWidget,
SidebarTodoWidget,
+ SidebarSeverity,
MountingPortal,
SidebarWeightWidget: () =>
import('ee_component/sidebar/components/weight/sidebar_weight_widget.vue'),
@@ -69,9 +71,15 @@ export default {
isIssuableSidebar() {
return this.sidebarType === ISSUABLE;
},
+ isIncidentSidebar() {
+ return this.activeBoardItem.type === INCIDENT;
+ },
showSidebar() {
return this.isIssuableSidebar && this.isSidebarOpen;
},
+ sidebarTitle() {
+ return this.isIncidentSidebar ? __('Incident details') : __('Issue details');
+ },
fullPath() {
return this.activeBoardItem?.referencePath?.split('#')[0] || '';
},
@@ -138,7 +146,7 @@ export default {
@close="handleClose"
>
<template #title>
- <h2 class="gl-my-0 gl-font-size-h2 gl-line-height-24">{{ __('Issue details') }}</h2>
+ <h2 class="gl-my-0 gl-font-size-h2 gl-line-height-24">{{ sidebarTitle }}</h2>
</template>
<template #header>
<sidebar-todo-widget
@@ -159,7 +167,7 @@ export default {
@assignees-updated="setAssignees"
/>
<sidebar-dropdown-widget
- v-if="epicFeatureAvailable"
+ v-if="epicFeatureAvailable && !isIncidentSidebar"
:iid="activeBoardItem.iid"
issuable-attribute="epic"
:workspace-path="projectPathForActiveIssue"
@@ -178,7 +186,7 @@ export default {
/>
<template v-if="!glFeatures.iterationCadences">
<sidebar-dropdown-widget
- v-if="iterationFeatureAvailable"
+ v-if="iterationFeatureAvailable && !isIncidentSidebar"
:iid="activeBoardItem.iid"
issuable-attribute="iteration"
:workspace-path="projectPathForActiveIssue"
@@ -190,7 +198,7 @@ export default {
</template>
<template v-else>
<iteration-sidebar-dropdown-widget
- v-if="iterationFeatureAvailable"
+ v-if="iterationFeatureAvailable && !isIncidentSidebar"
:iid="activeBoardItem.iid"
:workspace-path="projectPathForActiveIssue"
:attr-workspace-path="groupPathForActiveIssue"
@@ -200,7 +208,7 @@ export default {
/>
</template>
</div>
- <board-sidebar-time-tracker class="swimlanes-sidebar-time-tracker" />
+ <board-sidebar-time-tracker />
<sidebar-date-widget
:iid="activeBoardItem.iid"
:full-path="fullPath"
@@ -209,7 +217,6 @@ export default {
/>
<sidebar-labels-widget
class="block labels"
- data-testid="sidebar-labels"
:iid="activeBoardItem.iid"
:full-path="projectPathForActiveIssue"
:allow-label-remove="allowLabelEdit"
@@ -227,8 +234,14 @@ export default {
>
{{ __('None') }}
</sidebar-labels-widget>
+ <sidebar-severity
+ v-if="isIncidentSidebar"
+ :iid="activeBoardItem.iid"
+ :project-path="fullPath"
+ :initial-severity="activeBoardItem.severity"
+ />
<sidebar-weight-widget
- v-if="weightFeatureAvailable"
+ v-if="weightFeatureAvailable && !isIncidentSidebar"
:iid="activeBoardItem.iid"
:full-path="fullPath"
:issuable-type="issuableType"
diff --git a/app/assets/javascripts/boards/components/board_filtered_search.vue b/app/assets/javascripts/boards/components/board_filtered_search.vue
index 09ec385bbba..2599d1c80b8 100644
--- a/app/assets/javascripts/boards/components/board_filtered_search.vue
+++ b/app/assets/javascripts/boards/components/board_filtered_search.vue
@@ -6,6 +6,7 @@ import { updateHistory, setUrlParams } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import { FILTERED_SEARCH_TERM } from '~/vue_shared/components/filtered_search_bar/constants';
import FilteredSearch from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
+import { AssigneeFilterType } from '~/boards/constants';
export default {
i18n: {
@@ -37,6 +38,7 @@ export default {
authorUsername,
labelName,
assigneeUsername,
+ assigneeId,
search,
milestoneTitle,
iterationId,
@@ -63,6 +65,13 @@ export default {
});
}
+ if (assigneeId) {
+ filteredSearchValue.push({
+ type: 'assignee',
+ value: { data: assigneeId, operator: '=' },
+ });
+ }
+
if (types) {
filteredSearchValue.push({
type: 'type',
@@ -211,6 +220,7 @@ export default {
authorUsername,
labelName,
assigneeUsername,
+ assigneeId,
search,
milestoneTitle,
types,
@@ -246,6 +256,7 @@ export default {
author_username: authorUsername,
'label_name[]': labelName,
assignee_username: assigneeUsername,
+ assignee_id: assigneeId,
milestone_title: milestoneTitle,
iteration_id: iterationId,
search,
@@ -295,7 +306,11 @@ export default {
filterParams.authorUsername = filter.value.data;
break;
case 'assignee':
- filterParams.assigneeUsername = filter.value.data;
+ if (Object.values(AssigneeFilterType).includes(filter.value.data)) {
+ filterParams.assigneeId = filter.value.data;
+ } else {
+ filterParams.assigneeUsername = filter.value.data;
+ }
break;
case 'type':
filterParams.types = filter.value.data;
diff --git a/app/assets/javascripts/boards/components/board_list_header.vue b/app/assets/javascripts/boards/components/board_list_header.vue
index 19004518edf..6835d83a66c 100644
--- a/app/assets/javascripts/boards/components/board_list_header.vue
+++ b/app/assets/javascripts/boards/components/board_list_header.vue
@@ -263,7 +263,7 @@ export default {
>
<h3
:class="{
- 'user-can-drag': userCanDrag,
+ 'gl-cursor-grab': userCanDrag,
'gl-py-3 gl-h-full': list.collapsed && !isSwimlanesHeader,
'gl-border-b-0': list.collapsed || isSwimlanesHeader,
'gl-py-2': list.collapsed && isSwimlanesHeader,
diff --git a/app/assets/javascripts/boards/components/sidebar/board_sidebar_title.vue b/app/assets/javascripts/boards/components/sidebar/board_sidebar_title.vue
index e77aadfa50e..9d19fe57e7a 100644
--- a/app/assets/javascripts/boards/components/sidebar/board_sidebar_title.vue
+++ b/app/assets/javascripts/boards/components/sidebar/board_sidebar_title.vue
@@ -150,7 +150,7 @@ export default {
<div class="gl-display-flex gl-w-full gl-justify-content-space-between gl-mt-5">
<gl-button
- variant="success"
+ variant="confirm"
size="small"
data-testid="submit-button"
:disabled="!title"
diff --git a/app/assets/javascripts/boards/constants.js b/app/assets/javascripts/boards/constants.js
index 851b5eca40d..0f290f566ba 100644
--- a/app/assets/javascripts/boards/constants.js
+++ b/app/assets/javascripts/boards/constants.js
@@ -50,10 +50,13 @@ export const toggleFormEventPrefix = {
issue: 'toggle-issue-form-',
};
+export const active = 'active';
+
export const inactiveId = 0;
export const ISSUABLE = 'issuable';
export const LIST = 'list';
+export const INCIDENT = 'INCIDENT';
export const flashAnimationDuration = 2000;
@@ -119,6 +122,7 @@ export const FilterFields = {
/* eslint-disable @gitlab/require-i18n-strings */
export const AssigneeFilterType = {
any: 'Any',
+ none: 'None',
};
export const MilestoneFilterType = {
diff --git a/app/assets/javascripts/boards/graphql/group_board_milestones.query.graphql b/app/assets/javascripts/boards/graphql/group_board_milestones.query.graphql
index 0963b3fbfaa..6fe8bb799d6 100644
--- a/app/assets/javascripts/boards/graphql/group_board_milestones.query.graphql
+++ b/app/assets/javascripts/boards/graphql/group_board_milestones.query.graphql
@@ -1,7 +1,7 @@
-query GroupBoardMilestones($fullPath: ID!, $searchTerm: String) {
+query GroupBoardMilestones($fullPath: ID!, $searchTerm: String, $state: MilestoneStateEnum) {
group(fullPath: $fullPath) {
id
- milestones(includeAncestors: true, searchTitle: $searchTerm) {
+ milestones(includeAncestors: true, searchTitle: $searchTerm, state: $state) {
nodes {
id
title
diff --git a/app/assets/javascripts/boards/graphql/issue.fragment.graphql b/app/assets/javascripts/boards/graphql/issue.fragment.graphql
index 314faae89f8..53fe6fdc59e 100644
--- a/app/assets/javascripts/boards/graphql/issue.fragment.graphql
+++ b/app/assets/javascripts/boards/graphql/issue.fragment.graphql
@@ -1,35 +1,6 @@
-#import "~/graphql_shared/fragments/milestone.fragment.graphql"
-#import "~/graphql_shared/fragments/user.fragment.graphql"
+#import "~/graphql_shared/fragments/issue.fragment.graphql"
-fragment IssueNode on Issue {
+fragment Issue on Issue {
id
- iid
- title
- referencePath: reference(full: true)
- dueDate
- timeEstimate
- totalTimeSpent
- humanTimeEstimate
- humanTotalTimeSpent
- emailsDisabled
- confidential
- hidden
- webUrl
- relativePosition
- milestone {
- ...MilestoneFragment
- }
- assignees {
- nodes {
- ...User
- }
- }
- labels {
- nodes {
- id
- title
- color
- description
- }
- }
+ ...IssueNode
}
diff --git a/app/assets/javascripts/boards/graphql/issue_create.mutation.graphql b/app/assets/javascripts/boards/graphql/issue_create.mutation.graphql
index c1a2361a4e8..643d5dcfe4c 100644
--- a/app/assets/javascripts/boards/graphql/issue_create.mutation.graphql
+++ b/app/assets/javascripts/boards/graphql/issue_create.mutation.graphql
@@ -3,7 +3,7 @@
mutation CreateIssue($input: CreateIssueInput!) {
createIssue(input: $input) {
issue {
- ...IssueNode
+ ...Issue
}
errors
}
diff --git a/app/assets/javascripts/boards/graphql/issue_move_list.mutation.graphql b/app/assets/javascripts/boards/graphql/issue_move_list.mutation.graphql
index 570731ecac6..1658cf09085 100644
--- a/app/assets/javascripts/boards/graphql/issue_move_list.mutation.graphql
+++ b/app/assets/javascripts/boards/graphql/issue_move_list.mutation.graphql
@@ -21,7 +21,7 @@ mutation issueMoveList(
}
) {
issue {
- ...IssueNode
+ ...Issue
}
errors
}
diff --git a/app/assets/javascripts/boards/graphql/lists_issues.query.graphql b/app/assets/javascripts/boards/graphql/lists_issues.query.graphql
index 105f2931caa..994ea894be3 100644
--- a/app/assets/javascripts/boards/graphql/lists_issues.query.graphql
+++ b/app/assets/javascripts/boards/graphql/lists_issues.query.graphql
@@ -22,7 +22,7 @@ query BoardListsEE(
issues(first: $first, filters: $filters, after: $after) {
edges {
node {
- ...IssueNode
+ ...Issue
}
}
pageInfo {
@@ -46,7 +46,7 @@ query BoardListsEE(
issues(first: $first, filters: $filters, after: $after) {
edges {
node {
- ...IssueNode
+ ...Issue
}
}
pageInfo {
diff --git a/app/assets/javascripts/boards/graphql/project_board_milestones.query.graphql b/app/assets/javascripts/boards/graphql/project_board_milestones.query.graphql
index e456823d78a..d917c7e809d 100644
--- a/app/assets/javascripts/boards/graphql/project_board_milestones.query.graphql
+++ b/app/assets/javascripts/boards/graphql/project_board_milestones.query.graphql
@@ -1,7 +1,7 @@
-query ProjectBoardMilestones($fullPath: ID!, $searchTerm: String) {
+query ProjectBoardMilestones($fullPath: ID!, $searchTerm: String, $state: MilestoneStateEnum) {
project(fullPath: $fullPath) {
id
- milestones(searchTitle: $searchTerm, includeAncestors: true) {
+ milestones(searchTitle: $searchTerm, includeAncestors: true, state: $state) {
nodes {
id
title
diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js
index 1ebfcfc331b..48ca3239cfd 100644
--- a/app/assets/javascripts/boards/stores/actions.js
+++ b/app/assets/javascripts/boards/stores/actions.js
@@ -15,6 +15,7 @@ import {
FilterFields,
ListTypeTitles,
DraggableItemTypes,
+ active,
} from 'ee_else_ce/boards/constants';
import {
formatIssueInput,
@@ -209,6 +210,7 @@ export default {
const variables = {
fullPath,
searchTerm,
+ state: active,
};
let query;
diff --git a/app/assets/javascripts/branches/branches_delete_modal.js b/app/assets/javascripts/branches/branches_delete_modal.js
deleted file mode 100644
index f4c3fa185d8..00000000000
--- a/app/assets/javascripts/branches/branches_delete_modal.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import $ from 'jquery';
-
-const MODAL_SELECTOR = '#modal-delete-branch';
-
-class DeleteModal {
- constructor() {
- this.$modal = $(MODAL_SELECTOR);
- this.$toggleBtns = $(`[data-target="${MODAL_SELECTOR}"]`);
- this.$branchName = $('.js-branch-name', this.$modal);
- this.$confirmInput = $('.js-delete-branch-input', this.$modal);
- this.$deleteBtn = $('.js-delete-branch', this.$modal);
- this.$notMerged = $('.js-not-merged', this.$modal);
- this.bindEvents();
- }
-
- bindEvents() {
- this.$toggleBtns.on('click', this.setModalData.bind(this));
- this.$confirmInput.on('input', this.setDeleteDisabled.bind(this));
- this.$deleteBtn.on('click', this.setDisableDeleteButton.bind(this));
- }
-
- setModalData(e) {
- const branchData = e.currentTarget.dataset;
- this.branchName = branchData.branchName || '';
- this.deletePath = branchData.deletePath || '';
- this.isMerged = Boolean(branchData.isMerged);
- this.updateModal();
- }
-
- setDeleteDisabled(e) {
- this.$deleteBtn.attr('disabled', e.currentTarget.value !== this.branchName);
- }
-
- setDisableDeleteButton(e) {
- if (this.$deleteBtn.is('[disabled]')) {
- e.preventDefault();
- e.stopPropagation();
- return false;
- }
-
- return true;
- }
-
- updateModal() {
- this.$branchName.text(this.branchName);
- this.$confirmInput.val('');
- this.$deleteBtn.attr('href', this.deletePath);
- this.$deleteBtn.attr('disabled', true);
- this.$notMerged.toggleClass('hidden', this.isMerged);
- }
-}
-
-export default DeleteModal;
diff --git a/app/assets/javascripts/clusters/agents/components/show.vue b/app/assets/javascripts/clusters/agents/components/show.vue
index 9109c010500..a53bba6992d 100644
--- a/app/assets/javascripts/clusters/agents/components/show.vue
+++ b/app/assets/javascripts/clusters/agents/components/show.vue
@@ -51,16 +51,7 @@ export default {
TokenTable,
ActivityEvents,
},
- props: {
- agentName: {
- required: true,
- type: String,
- },
- projectPath: {
- required: true,
- type: String,
- },
- },
+ inject: ['agentName', 'projectPath'],
data() {
return {
cursor: {
@@ -135,7 +126,7 @@ export default {
<activity-events :agent-name="agentName" :project-path="projectPath" />
</gl-tab>
- <slot name="ee-security-tab"></slot>
+ <slot name="ee-security-tab" :cluster-agent-id="clusterAgent.id"></slot>
<gl-tab query-param-value="tokens">
<template #title>
diff --git a/app/assets/javascripts/clusters/agents/graphql/provider.js b/app/assets/javascripts/clusters/agents/graphql/provider.js
new file mode 100644
index 00000000000..8b068fa1eee
--- /dev/null
+++ b/app/assets/javascripts/clusters/agents/graphql/provider.js
@@ -0,0 +1,26 @@
+import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import createDefaultClient from '~/lib/graphql';
+import { vulnerabilityLocationTypes } from '~/graphql_shared/fragment_types/vulnerability_location_types';
+
+Vue.use(VueApollo);
+
+// We create a fragment matcher so that we can create a fragment from an interface
+// Without this, Apollo throws a heuristic fragment matcher warning
+const fragmentMatcher = new IntrospectionFragmentMatcher({
+ introspectionQueryResultData: vulnerabilityLocationTypes,
+});
+
+const defaultClient = createDefaultClient(
+ {},
+ {
+ cacheConfig: {
+ fragmentMatcher,
+ },
+ },
+);
+
+export default new VueApollo({
+ defaultClient,
+});
diff --git a/app/assets/javascripts/clusters/agents/index.js b/app/assets/javascripts/clusters/agents/index.js
index 5796c9e308d..6c7fae274f8 100644
--- a/app/assets/javascripts/clusters/agents/index.js
+++ b/app/assets/javascripts/clusters/agents/index.js
@@ -1,9 +1,6 @@
import Vue from 'vue';
-import VueApollo from 'vue-apollo';
-import createDefaultClient from '~/lib/graphql';
import AgentShowPage from 'ee_else_ce/clusters/agents/components/show.vue';
-
-Vue.use(VueApollo);
+import apolloProvider from './graphql/provider';
export default () => {
const el = document.querySelector('#js-cluster-agent-details');
@@ -12,20 +9,19 @@ export default () => {
return null;
}
- const defaultClient = createDefaultClient();
- const { agentName, projectPath, activityEmptyStateImage } = el.dataset;
+ const { activityEmptyStateImage, agentName, emptyStateSvgPath, projectPath } = el.dataset;
return new Vue({
el,
- apolloProvider: new VueApollo({ defaultClient }),
- provide: { agentName, projectPath, activityEmptyStateImage },
+ apolloProvider,
+ provide: {
+ activityEmptyStateImage,
+ agentName,
+ emptyStateSvgPath,
+ projectPath,
+ },
render(createElement) {
- return createElement(AgentShowPage, {
- props: {
- agentName,
- projectPath,
- },
- });
+ return createElement(AgentShowPage);
},
});
};
diff --git a/app/assets/javascripts/clusters_list/components/agent_options.vue b/app/assets/javascripts/clusters_list/components/agent_options.vue
new file mode 100644
index 00000000000..a364122ba56
--- /dev/null
+++ b/app/assets/javascripts/clusters_list/components/agent_options.vue
@@ -0,0 +1,200 @@
+<script>
+import {
+ GlDropdown,
+ GlDropdownItem,
+ GlModal,
+ GlModalDirective,
+ GlSprintf,
+ GlFormGroup,
+ GlFormInput,
+} from '@gitlab/ui';
+import { s__, __, sprintf } from '~/locale';
+import { DELETE_AGENT_MODAL_ID } from '../constants';
+import deleteAgent from '../graphql/mutations/delete_agent.mutation.graphql';
+import getAgentsQuery from '../graphql/queries/get_agents.query.graphql';
+import { removeAgentFromStore } from '../graphql/cache_update';
+
+export default {
+ i18n: {
+ dropdownText: __('More options'),
+ deleteButton: s__('ClusterAgents|Delete agent'),
+ modalTitle: __('Are you sure?'),
+ modalBody: s__(
+ 'ClusterAgents|Are you sure you want to delete this agent? You cannot undo this.',
+ ),
+ modalInputLabel: s__('ClusterAgents|To delete the agent, type %{name} to confirm:'),
+ modalAction: s__('ClusterAgents|Delete'),
+ modalCancel: __('Cancel'),
+ successMessage: s__('ClusterAgents|%{name} successfully deleted'),
+ defaultError: __('An error occurred. Please try again.'),
+ },
+ components: {
+ GlDropdown,
+ GlDropdownItem,
+ GlModal,
+ GlSprintf,
+ GlFormGroup,
+ GlFormInput,
+ },
+ directives: {
+ GlModalDirective,
+ },
+ inject: ['projectPath'],
+ props: {
+ agent: {
+ required: true,
+ type: Object,
+ validator: (value) => ['id', 'name'].every((prop) => value[prop]),
+ },
+ defaultBranchName: {
+ default: '.noBranch',
+ required: false,
+ type: String,
+ },
+ maxAgents: {
+ default: null,
+ required: false,
+ type: Number,
+ },
+ },
+ data() {
+ return {
+ loading: false,
+ error: null,
+ deleteConfirmText: null,
+ agentName: this.agent.name,
+ };
+ },
+ computed: {
+ getAgentsQueryVariables() {
+ return {
+ defaultBranchName: this.defaultBranchName,
+ first: this.maxAgents,
+ last: null,
+ projectPath: this.projectPath,
+ };
+ },
+ modalId() {
+ return sprintf(DELETE_AGENT_MODAL_ID, {
+ agentName: this.agent.name,
+ });
+ },
+ primaryModalProps() {
+ return {
+ text: this.$options.i18n.modalAction,
+ attributes: [
+ { disabled: this.loading || this.disableModalSubmit, loading: this.loading },
+ { variant: 'danger' },
+ ],
+ };
+ },
+ cancelModalProps() {
+ return {
+ text: this.$options.i18n.modalCancel,
+ attributes: [],
+ };
+ },
+ disableModalSubmit() {
+ return this.deleteConfirmText !== this.agent.name;
+ },
+ },
+ methods: {
+ async deleteAgent() {
+ if (this.disableModalSubmit || this.loading) {
+ return;
+ }
+
+ this.loading = true;
+ this.error = null;
+
+ try {
+ const { errors } = await this.deleteAgentMutation();
+
+ if (errors.length) {
+ throw new Error(errors[0]);
+ }
+ } catch (error) {
+ this.error = error?.message || this.$options.i18n.defaultError;
+ } finally {
+ this.loading = false;
+ const successMessage = sprintf(this.$options.i18n.successMessage, { name: this.agentName });
+
+ this.$toast.show(this.error || successMessage);
+
+ this.$refs.modal.hide();
+ }
+ },
+ deleteAgentMutation() {
+ return this.$apollo
+ .mutate({
+ mutation: deleteAgent,
+ variables: {
+ input: {
+ id: this.agent.id,
+ },
+ },
+ update: (store) => {
+ const deleteClusterAgent = this.agent;
+ removeAgentFromStore(
+ store,
+ deleteClusterAgent,
+ getAgentsQuery,
+ this.getAgentsQueryVariables,
+ );
+ },
+ })
+
+ .then(({ data: { clusterAgentDelete } }) => {
+ return clusterAgentDelete;
+ });
+ },
+ hideModal() {
+ this.loading = false;
+ this.error = null;
+ this.deleteConfirmText = null;
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <gl-dropdown
+ icon="ellipsis_v"
+ right
+ :disabled="loading"
+ :text="$options.i18n.dropdownText"
+ text-sr-only
+ category="tertiary"
+ no-caret
+ >
+ <gl-dropdown-item v-gl-modal-directive="modalId">
+ {{ $options.i18n.deleteButton }}
+ </gl-dropdown-item>
+ </gl-dropdown>
+
+ <gl-modal
+ ref="modal"
+ :modal-id="modalId"
+ :title="$options.i18n.modalTitle"
+ :action-primary="primaryModalProps"
+ :action-cancel="cancelModalProps"
+ size="sm"
+ @primary="deleteAgent"
+ @hide="hideModal"
+ >
+ <p>{{ $options.i18n.modalBody }}</p>
+
+ <gl-form-group>
+ <template #label>
+ <gl-sprintf :message="$options.i18n.modalInputLabel">
+ <template #name>
+ <code>{{ agent.name }}</code>
+ </template>
+ </gl-sprintf>
+ </template>
+ <gl-form-input v-model="deleteConfirmText" @keydown.enter="deleteAgent" />
+ </gl-form-group>
+ </gl-modal>
+ </div>
+</template>
diff --git a/app/assets/javascripts/clusters_list/components/agent_table.vue b/app/assets/javascripts/clusters_list/components/agent_table.vue
index 000730ac1ba..695e16b7b4b 100644
--- a/app/assets/javascripts/clusters_list/components/agent_table.vue
+++ b/app/assets/javascripts/clusters_list/components/agent_table.vue
@@ -1,21 +1,23 @@
<script>
-import {
- GlLink,
- GlModalDirective,
- GlTable,
- GlIcon,
- GlSprintf,
- GlTooltip,
- GlPopover,
-} from '@gitlab/ui';
-import { s__ } from '~/locale';
+import { GlLink, GlTable, GlIcon, GlSprintf, GlTooltip, GlPopover } from '@gitlab/ui';
+import { s__, __ } from '~/locale';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import timeagoMixin from '~/vue_shared/mixins/timeago';
import { helpPagePath } from '~/helpers/help_page_helper';
-import { INSTALL_AGENT_MODAL_ID, AGENT_STATUSES } from '../constants';
+import { AGENT_STATUSES } from '../constants';
import { getAgentConfigPath } from '../clusters_util';
+import AgentOptions from './agent_options.vue';
export default {
+ i18n: {
+ nameLabel: s__('ClusterAgents|Name'),
+ statusLabel: s__('ClusterAgents|Connection status'),
+ lastContactLabel: s__('ClusterAgents|Last contact'),
+ configurationLabel: s__('ClusterAgents|Configuration'),
+ optionsLabel: __('Options'),
+ troubleshootingText: s__('ClusterAgents|Learn how to troubleshoot'),
+ neverConnectedText: s__('ClusterAgents|Never'),
+ },
components: {
GlLink,
GlTable,
@@ -24,14 +26,10 @@ export default {
GlTooltip,
GlPopover,
TimeAgoTooltip,
- },
- directives: {
- GlModalDirective,
+ AgentOptions,
},
mixins: [timeagoMixin],
- INSTALL_AGENT_MODAL_ID,
AGENT_STATUSES,
-
troubleshooting_link: helpPagePath('user/clusters/agent/index', {
anchor: 'troubleshooting',
}),
@@ -40,6 +38,16 @@ export default {
required: true,
type: Array,
},
+ defaultBranchName: {
+ default: '.noBranch',
+ required: false,
+ type: String,
+ },
+ maxAgents: {
+ default: null,
+ required: false,
+ type: Number,
+ },
},
computed: {
fields() {
@@ -47,22 +55,27 @@ export default {
return [
{
key: 'name',
- label: s__('ClusterAgents|Name'),
+ label: this.$options.i18n.nameLabel,
tdClass,
},
{
key: 'status',
- label: s__('ClusterAgents|Connection status'),
+ label: this.$options.i18n.statusLabel,
tdClass,
},
{
key: 'lastContact',
- label: s__('ClusterAgents|Last contact'),
+ label: this.$options.i18n.lastContactLabel,
tdClass,
},
{
key: 'configuration',
- label: s__('ClusterAgents|Configuration'),
+ label: this.$options.i18n.configurationLabel,
+ tdClass,
+ },
+ {
+ key: 'options',
+ label: this.$options.i18n.optionsLabel,
tdClass,
},
];
@@ -118,7 +131,7 @@ export default {
</p>
<p class="gl-mb-0">
<gl-link :href="$options.troubleshooting_link" target="_blank" class="gl-font-sm">
- {{ s__('ClusterAgents|Learn how to troubleshoot') }}</gl-link
+ {{ $options.i18n.troubleshootingText }}</gl-link
>
</p>
</gl-popover>
@@ -127,7 +140,7 @@ export default {
<template #cell(lastContact)="{ item }">
<span data-testid="cluster-agent-last-contact">
<time-ago-tooltip v-if="item.lastContact" :time="item.lastContact" />
- <span v-else>{{ s__('ClusterAgents|Never') }}</span>
+ <span v-else>{{ $options.i18n.neverConnectedText }}</span>
</span>
</template>
@@ -140,5 +153,13 @@ export default {
<span v-else>{{ getAgentConfigPath(item.name) }}</span>
</span>
</template>
+
+ <template #cell(options)="{ item }">
+ <agent-options
+ :agent="item"
+ :default-branch-name="defaultBranchName"
+ :max-agents="maxAgents"
+ />
+ </template>
</gl-table>
</template>
diff --git a/app/assets/javascripts/clusters_list/components/agents.vue b/app/assets/javascripts/clusters_list/components/agents.vue
index 45108a28e37..4fc421e7c31 100644
--- a/app/assets/javascripts/clusters_list/components/agents.vue
+++ b/app/assets/javascripts/clusters_list/components/agents.vue
@@ -151,7 +151,11 @@ export default {
<section v-else-if="agentList">
<div v-if="agentList.length">
- <agent-table :agents="agentList" />
+ <agent-table
+ :agents="agentList"
+ :default-branch-name="defaultBranchName"
+ :max-agents="cursor.first"
+ />
<div v-if="showPagination" class="gl-display-flex gl-justify-content-center gl-mt-5">
<gl-keyset-pagination v-bind="agentPageInfo" @prev="prevPage" @next="nextPage" />
diff --git a/app/assets/javascripts/clusters_list/constants.js b/app/assets/javascripts/clusters_list/constants.js
index 9b52df74fc5..380a5d0aada 100644
--- a/app/assets/javascripts/clusters_list/constants.js
+++ b/app/assets/javascripts/clusters_list/constants.js
@@ -106,7 +106,7 @@ export const I18N_AGENT_MODAL = {
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}What's the agent's configuration file?%{linkEnd}",
+ "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.",
@@ -242,3 +242,5 @@ export const EVENT_ACTIONS_CHANGE = 'change_tab';
export const MODAL_TYPE_EMPTY = 'empty_state';
export const MODAL_TYPE_REGISTER = 'agent_registration';
+
+export const DELETE_AGENT_MODAL_ID = 'delete-agent-modal-%{agentName}';
diff --git a/app/assets/javascripts/clusters_list/graphql/cache_update.js b/app/assets/javascripts/clusters_list/graphql/cache_update.js
index 4d12bc8151c..6476b7a6c2f 100644
--- a/app/assets/javascripts/clusters_list/graphql/cache_update.js
+++ b/app/assets/javascripts/clusters_list/graphql/cache_update.js
@@ -63,3 +63,25 @@ export function addAgentConfigToStore(
});
}
}
+
+export function removeAgentFromStore(store, deleteClusterAgent, query, variables) {
+ if (!hasErrors(deleteClusterAgent)) {
+ const sourceData = store.readQuery({
+ query,
+ variables,
+ });
+
+ const data = produce(sourceData, (draftData) => {
+ draftData.project.clusterAgents.nodes = draftData.project.clusterAgents.nodes.filter(
+ ({ id }) => id !== deleteClusterAgent.id,
+ );
+ draftData.project.clusterAgents.count -= 1;
+ });
+
+ store.writeQuery({
+ query,
+ variables,
+ data,
+ });
+ }
+}
diff --git a/app/assets/javascripts/clusters_list/graphql/mutations/delete_agent.mutation.graphql b/app/assets/javascripts/clusters_list/graphql/mutations/delete_agent.mutation.graphql
new file mode 100644
index 00000000000..28387b2a36c
--- /dev/null
+++ b/app/assets/javascripts/clusters_list/graphql/mutations/delete_agent.mutation.graphql
@@ -0,0 +1,5 @@
+mutation deleteClusterAgent($input: ClusterAgentDeleteInput!) {
+ clusterAgentDelete(input: $input) {
+ errors
+ }
+}
diff --git a/app/assets/javascripts/clusters_list/index.js b/app/assets/javascripts/clusters_list/index.js
index 7f1ef37814b..6148483dcb0 100644
--- a/app/assets/javascripts/clusters_list/index.js
+++ b/app/assets/javascripts/clusters_list/index.js
@@ -1,8 +1,10 @@
+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';
+Vue.use(GlToast);
Vue.use(VueApollo);
export default () => {
diff --git a/app/assets/javascripts/confirm_danger_modal.js b/app/assets/javascripts/confirm_danger_modal.js
deleted file mode 100644
index ad70d9be16f..00000000000
--- a/app/assets/javascripts/confirm_danger_modal.js
+++ /dev/null
@@ -1,64 +0,0 @@
-import $ from 'jquery';
-import { Rails } from '~/lib/utils/rails_ujs';
-import { rstrip } from './lib/utils/common_utils';
-
-function openConfirmDangerModal($form, $modal, text) {
- const $input = $('.js-legacy-confirm-danger-input', $modal);
- $input.val('');
-
- $('.js-confirm-text', $modal).text(text || '');
- $modal.modal('show');
-
- const confirmTextMatch = $('.js-legacy-confirm-danger-match', $modal).text();
- const $submit = $('.js-legacy-confirm-danger-submit', $modal);
- $submit.disable();
- $input.focus();
-
- // eslint-disable-next-line @gitlab/no-global-event-off
- $input.off('input').on('input', function handleInput() {
- const confirmText = rstrip($(this).val());
- if (confirmText === confirmTextMatch) {
- $submit.enable();
- } else {
- $submit.disable();
- }
- });
-
- // eslint-disable-next-line @gitlab/no-global-event-off
- $('.js-legacy-confirm-danger-submit', $modal)
- .off('click')
- .on('click', () => {
- if ($form.data('remote')) {
- Rails.fire($form[0], 'submit');
- } else {
- $form.submit();
- }
- });
-}
-
-function getModal($btn) {
- const $modal = $btn.prev('.modal');
-
- if ($modal.length) {
- return $modal;
- }
-
- return $('#modal-confirm-danger');
-}
-
-export default function initConfirmDangerModal() {
- $(document).on('click', '.js-legacy-confirm-danger', (e) => {
- const $btn = $(e.target);
- const checkFieldName = $btn.data('checkFieldName');
- const checkFieldCompareValue = $btn.data('checkCompareValue');
- const checkFieldVal = parseInt($(`[name="${checkFieldName}"]`).val(), 10);
-
- if (!checkFieldName || checkFieldVal < checkFieldCompareValue) {
- e.preventDefault();
- const $form = $btn.closest('form');
- const $modal = getModal($btn);
- const text = $btn.data('confirmDangerMessage');
- openConfirmDangerModal($form, $modal, text);
- }
- });
-}
diff --git a/app/assets/javascripts/content_editor/components/wrappers/frontmatter.vue b/app/assets/javascripts/content_editor/components/wrappers/frontmatter.vue
index 97b69afd12e..e8829d00986 100644
--- a/app/assets/javascripts/content_editor/components/wrappers/frontmatter.vue
+++ b/app/assets/javascripts/content_editor/components/wrappers/frontmatter.vue
@@ -20,7 +20,7 @@ export default {
};
</script>
<template>
- <node-view-wrapper class="gl-relative code highlight" as="pre">
+ <node-view-wrapper class="content-editor-code-block gl-relative code highlight" as="pre">
<span
data-testid="frontmatter-label"
class="gl-absolute gl-top-0 gl-right-3"
diff --git a/app/assets/javascripts/content_editor/constants.js b/app/assets/javascripts/content_editor/constants.js
index 4af9dc8e405..5e56078df01 100644
--- a/app/assets/javascripts/content_editor/constants.js
+++ b/app/assets/javascripts/content_editor/constants.js
@@ -49,3 +49,10 @@ export const LOADING_ERROR_EVENT = 'loadingError';
export const PARSE_HTML_PRIORITY_LOWEST = 1;
export const PARSE_HTML_PRIORITY_DEFAULT = 50;
export const PARSE_HTML_PRIORITY_HIGHEST = 100;
+
+export const EXTENSION_PRIORITY_LOWER = 75;
+/**
+ * 100 is the default priority in Tiptap
+ * https://tiptap.dev/guide/custom-extensions/#priority
+ */
+export const EXTENSION_PRIORITY_DEFAULT = 100;
diff --git a/app/assets/javascripts/content_editor/extensions/code.js b/app/assets/javascripts/content_editor/extensions/code.js
index f93c22ad10e..53f6d9b995c 100644
--- a/app/assets/javascripts/content_editor/extensions/code.js
+++ b/app/assets/javascripts/content_editor/extensions/code.js
@@ -1 +1,12 @@
-export { Code as default } from '@tiptap/extension-code';
+import Code from '@tiptap/extension-code';
+import { EXTENSION_PRIORITY_LOWER } from '../constants';
+
+export default Code.extend({
+ excludes: null,
+ /**
+ * Reduce the rendering priority of the code mark to
+ * ensure the bold, italic, and strikethrough marks
+ * are rendered first.
+ */
+ priority: EXTENSION_PRIORITY_LOWER,
+});
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 ea51bee3ba9..9dc17fcd570 100644
--- a/app/assets/javascripts/content_editor/extensions/code_block_highlight.js
+++ b/app/assets/javascripts/content_editor/extensions/code_block_highlight.js
@@ -19,7 +19,14 @@ export default CodeBlockLowlight.extend({
};
},
renderHTML({ HTMLAttributes }) {
- return ['div', ['pre', HTMLAttributes, ['code', {}, 0]]];
+ return [
+ 'pre',
+ {
+ ...HTMLAttributes,
+ class: `content-editor-code-block ${HTMLAttributes.class}`,
+ },
+ ['code', {}, 0],
+ ];
},
}).configure({
lowlight,
diff --git a/app/assets/javascripts/content_editor/extensions/frontmatter.js b/app/assets/javascripts/content_editor/extensions/frontmatter.js
index c09c10bc524..9842027e192 100644
--- a/app/assets/javascripts/content_editor/extensions/frontmatter.js
+++ b/app/assets/javascripts/content_editor/extensions/frontmatter.js
@@ -14,9 +14,20 @@ export default CodeBlockHighlight.extend({
},
];
},
+ addCommands() {
+ return {
+ setFrontmatter: (attributes) => ({ commands }) => {
+ return commands.setNode(this.name, attributes);
+ },
+ toggleFrontmatter: (attributes) => ({ commands }) => {
+ return commands.toggleNode(this.name, 'paragraph', attributes);
+ },
+ };
+ },
addNodeView() {
return new VueNodeViewRenderer(FrontmatterWrapper);
},
+
addInputRules() {
return [];
},
diff --git a/app/assets/javascripts/content_editor/extensions/image.js b/app/assets/javascripts/content_editor/extensions/image.js
index d7fb617f7ee..519f7f168ce 100644
--- a/app/assets/javascripts/content_editor/extensions/image.js
+++ b/app/assets/javascripts/content_editor/extensions/image.js
@@ -66,6 +66,17 @@ export default Image.extend({
},
];
},
+ renderHTML({ HTMLAttributes }) {
+ return [
+ 'img',
+ {
+ src: HTMLAttributes.src,
+ alt: HTMLAttributes.alt,
+ title: HTMLAttributes.title,
+ 'data-canonical-src': HTMLAttributes.canonicalSrc,
+ },
+ ];
+ },
addNodeView() {
return VueNodeViewRenderer(ImageWrapper);
},
diff --git a/app/assets/javascripts/content_editor/services/markdown_serializer.js b/app/assets/javascripts/content_editor/services/markdown_serializer.js
index 278ef326c7a..d54fb7cded2 100644
--- a/app/assets/javascripts/content_editor/services/markdown_serializer.js
+++ b/app/assets/javascripts/content_editor/services/markdown_serializer.js
@@ -65,8 +65,8 @@ import {
const defaultSerializerConfig = {
marks: {
[Bold.name]: defaultMarkdownSerializer.marks.strong,
- [Code.name]: defaultMarkdownSerializer.marks.code,
[Italic.name]: { open: '_', close: '_', mixable: true, expelEnclosingWhitespace: true },
+ [Code.name]: defaultMarkdownSerializer.marks.code,
[Subscript.name]: { open: '<sub>', close: '</sub>', mixable: true },
[Superscript.name]: { open: '<sup>', close: '</sup>', mixable: true },
[InlineDiff.name]: {
diff --git a/app/assets/javascripts/content_editor/services/serialization_helpers.js b/app/assets/javascripts/content_editor/services/serialization_helpers.js
index ed5910fca18..4d5a54c0347 100644
--- a/app/assets/javascripts/content_editor/services/serialization_helpers.js
+++ b/app/assets/javascripts/content_editor/services/serialization_helpers.js
@@ -1,4 +1,4 @@
-import { uniq } from 'lodash';
+import { uniq, isString } from 'lodash';
const defaultAttrs = {
td: { colspan: 1, rowspan: 1, colwidth: null },
@@ -325,9 +325,12 @@ export function renderHardBreak(state, node, parent, index) {
export function renderImage(state, node) {
const { alt, canonicalSrc, src, title } = node.attrs;
- const quotedTitle = title ? ` ${state.quote(title)}` : '';
- state.write(`![${state.esc(alt || '')}](${state.esc(canonicalSrc || src)}${quotedTitle})`);
+ if (isString(src) || isString(canonicalSrc)) {
+ const quotedTitle = title ? ` ${state.quote(title)}` : '';
+
+ state.write(`![${state.esc(alt || '')}](${state.esc(canonicalSrc || src)}${quotedTitle})`);
+ }
}
export function renderPlayable(state, node) {
diff --git a/app/assets/javascripts/content_editor/services/track_input_rules_and_shortcuts.js b/app/assets/javascripts/content_editor/services/track_input_rules_and_shortcuts.js
index 9b1cb76f845..eb1e4885ba6 100644
--- a/app/assets/javascripts/content_editor/services/track_input_rules_and_shortcuts.js
+++ b/app/assets/javascripts/content_editor/services/track_input_rules_and_shortcuts.js
@@ -35,31 +35,33 @@ const trackInputRule = (contentType, inputRule) => {
};
const trackInputRulesAndShortcuts = (tiptapExtension) => {
- return tiptapExtension.extend({
- addKeyboardShortcuts() {
- const shortcuts = this.parent?.() || {};
- const { name } = this;
- /**
- * We don’t want to track keyboard shortcuts
- * that are not deliberately executed to create
- * new types of content
- */
- const dotNotTrackKeys = [ENTER_KEY, BACKSPACE_KEY];
- const decorated = mapValues(shortcuts, (commandFn, shortcut) =>
- dotNotTrackKeys.includes(shortcut)
- ? commandFn
- : trackKeyboardShortcut(name, commandFn, shortcut),
- );
+ return tiptapExtension
+ .extend({
+ addKeyboardShortcuts() {
+ const shortcuts = this.parent?.() || {};
+ const { name } = this;
+ /**
+ * We don’t want to track keyboard shortcuts
+ * that are not deliberately executed to create
+ * new types of content
+ */
+ const dotNotTrackKeys = [ENTER_KEY, BACKSPACE_KEY];
+ const decorated = mapValues(shortcuts, (commandFn, shortcut) =>
+ dotNotTrackKeys.includes(shortcut)
+ ? commandFn
+ : trackKeyboardShortcut(name, commandFn, shortcut),
+ );
- return decorated;
- },
- addInputRules() {
- const inputRules = this.parent?.() || [];
- const { name } = this;
+ return decorated;
+ },
+ addInputRules() {
+ const inputRules = this.parent?.() || [];
+ const { name } = this;
- return inputRules.map((inputRule) => trackInputRule(name, inputRule));
- },
- });
+ return inputRules.map((inputRule) => trackInputRule(name, inputRule));
+ },
+ })
+ .configure(tiptapExtension.options);
};
export default trackInputRulesAndShortcuts;
diff --git a/app/assets/javascripts/create_merge_request_dropdown.js b/app/assets/javascripts/create_merge_request_dropdown.js
deleted file mode 100644
index ae6e6bf02e4..00000000000
--- a/app/assets/javascripts/create_merge_request_dropdown.js
+++ /dev/null
@@ -1,566 +0,0 @@
-import { debounce } from 'lodash';
-import {
- init as initConfidentialMergeRequest,
- isConfidentialIssue,
- canCreateConfidentialMergeRequest,
-} from './confidential_merge_request';
-import confidentialMergeRequestState from './confidential_merge_request/state';
-import DropLab from './filtered_search/droplab/drop_lab_deprecated';
-import ISetter from './filtered_search/droplab/plugins/input_setter';
-import createFlash from './flash';
-import axios from './lib/utils/axios_utils';
-import { __, sprintf } from './locale';
-
-// Todo: Remove this when fixing issue in input_setter plugin
-const InputSetter = { ...ISetter };
-
-const CREATE_MERGE_REQUEST = 'create-mr';
-const CREATE_BRANCH = 'create-branch';
-
-function createEndpoint(projectPath, endpoint) {
- if (canCreateConfidentialMergeRequest()) {
- return endpoint.replace(
- projectPath,
- confidentialMergeRequestState.selectedProject.pathWithNamespace,
- );
- }
-
- return endpoint;
-}
-
-export default class CreateMergeRequestDropdown {
- constructor(wrapperEl) {
- this.wrapperEl = wrapperEl;
- this.availableButton = this.wrapperEl.querySelector('.available');
- this.branchInput = this.wrapperEl.querySelector('.js-branch-name');
- this.branchMessage = this.wrapperEl.querySelector('.js-branch-message');
- this.createMergeRequestButton = this.wrapperEl.querySelector('.js-create-merge-request');
- this.createMergeRequestLoading = this.createMergeRequestButton.querySelector('.js-spinner');
- this.createTargetButton = this.wrapperEl.querySelector('.js-create-target');
- this.dropdownList = this.wrapperEl.querySelector('.dropdown-menu');
- this.dropdownToggle = this.wrapperEl.querySelector('.js-dropdown-toggle');
- this.refInput = this.wrapperEl.querySelector('.js-ref');
- this.refMessage = this.wrapperEl.querySelector('.js-ref-message');
- this.unavailableButton = this.wrapperEl.querySelector('.unavailable');
- this.unavailableButtonSpinner = this.unavailableButton.querySelector('.gl-spinner');
- this.unavailableButtonText = this.unavailableButton.querySelector('.text');
-
- this.branchCreated = false;
- this.branchIsValid = true;
- this.canCreatePath = this.wrapperEl.dataset.canCreatePath;
- this.createBranchPath = this.wrapperEl.dataset.createBranchPath;
- this.createMrPath = this.wrapperEl.dataset.createMrPath;
- this.droplabInitialized = false;
- this.isCreatingBranch = false;
- this.isCreatingMergeRequest = false;
- this.isGettingRef = false;
- this.refCancelToken = null;
- this.mergeRequestCreated = false;
- this.refDebounce = debounce((value, target) => this.getRef(value, target), 500);
- this.refIsValid = true;
- this.refsPath = this.wrapperEl.dataset.refsPath;
- this.suggestedRef = this.refInput.value;
- this.projectPath = this.wrapperEl.dataset.projectPath;
- this.projectId = this.wrapperEl.dataset.projectId;
-
- // These regexps are used to replace
- // a backend generated new branch name and its source (ref)
- // with user's inputs.
- this.regexps = {
- branch: {
- createBranchPath: new RegExp('(branch_name=)(.+?)(?=&issue)'),
- createMrPath: new RegExp('(branch_name=)(.+?)(?=&ref)'),
- },
- ref: {
- createBranchPath: new RegExp('(ref=)(.+?)$'),
- createMrPath: new RegExp('(ref=)(.+?)$'),
- },
- };
-
- this.init();
-
- if (isConfidentialIssue()) {
- this.createMergeRequestButton.setAttribute(
- 'data-dropdown-trigger',
- '#create-merge-request-dropdown',
- );
- initConfidentialMergeRequest();
- }
- }
-
- available() {
- this.availableButton.classList.remove('hidden');
- this.unavailableButton.classList.add('hidden');
- }
-
- bindEvents() {
- this.createMergeRequestButton.addEventListener(
- 'click',
- this.onClickCreateMergeRequestButton.bind(this),
- );
- this.createTargetButton.addEventListener(
- 'click',
- this.onClickCreateMergeRequestButton.bind(this),
- );
- this.branchInput.addEventListener('input', this.onChangeInput.bind(this));
- this.branchInput.addEventListener('keyup', this.onChangeInput.bind(this));
- this.dropdownToggle.addEventListener('click', this.onClickSetFocusOnBranchNameInput.bind(this));
- // Detect for example when user pastes ref using the mouse
- this.refInput.addEventListener('input', this.onChangeInput.bind(this));
- // Detect for example when user presses right arrow to apply the suggested ref
- this.refInput.addEventListener('keyup', this.onChangeInput.bind(this));
- // Detect when user clicks inside the input to apply the suggested ref
- this.refInput.addEventListener('click', this.onChangeInput.bind(this));
- // Detect when user clicks outside the input to apply the suggested ref
- this.refInput.addEventListener('blur', this.onChangeInput.bind(this));
- // Detect when user presses tab to apply the suggested ref
- this.refInput.addEventListener('keydown', CreateMergeRequestDropdown.processTab.bind(this));
- }
-
- checkAbilityToCreateBranch() {
- this.setUnavailableButtonState();
-
- axios
- .get(this.canCreatePath)
- .then(({ data }) => {
- this.setUnavailableButtonState(false);
-
- if (data.can_create_branch) {
- this.available();
- this.enable();
- this.updateBranchName(data.suggested_branch_name);
-
- if (!this.droplabInitialized) {
- this.droplabInitialized = true;
- this.initDroplab();
- this.bindEvents();
- }
- } else {
- this.hide();
- }
- })
- .catch(() => {
- this.unavailable();
- this.disable();
- createFlash({
- message: __('Failed to check related branches.'),
- });
- });
- }
-
- createBranch() {
- this.isCreatingBranch = true;
-
- return axios
- .post(createEndpoint(this.projectPath, this.createBranchPath), {
- confidential_issue_project_id: canCreateConfidentialMergeRequest() ? this.projectId : null,
- })
- .then(({ data }) => {
- this.branchCreated = true;
- window.location.href = data.url;
- })
- .catch(() =>
- createFlash({
- message: __('Failed to create a branch for this issue. Please try again.'),
- }),
- );
- }
-
- createMergeRequest() {
- this.isCreatingMergeRequest = true;
-
- return axios
- .post(this.createMrPath, {
- target_project_id: canCreateConfidentialMergeRequest()
- ? confidentialMergeRequestState.selectedProject.id
- : null,
- })
- .then(({ data }) => {
- this.mergeRequestCreated = true;
- window.location.href = data.url;
- })
- .catch(() =>
- createFlash({
- message: __('Failed to create merge request. Please try again.'),
- }),
- );
- }
-
- disable() {
- this.disableCreateAction();
- }
-
- setLoading(loading) {
- this.createMergeRequestLoading.classList.toggle('gl-display-none', !loading);
- }
-
- disableCreateAction() {
- this.createMergeRequestButton.classList.add('disabled');
- this.createMergeRequestButton.setAttribute('disabled', 'disabled');
-
- this.createTargetButton.classList.add('disabled');
- this.createTargetButton.setAttribute('disabled', 'disabled');
- }
-
- enable() {
- if (isConfidentialIssue() && !canCreateConfidentialMergeRequest()) return;
-
- this.createMergeRequestButton.classList.remove('disabled');
- this.createMergeRequestButton.removeAttribute('disabled');
-
- this.createTargetButton.classList.remove('disabled');
- this.createTargetButton.removeAttribute('disabled');
- }
-
- static findByValue(objects, ref, returnFirstMatch = false) {
- if (!objects || !objects.length) return false;
- if (objects.indexOf(ref) > -1) return ref;
- if (returnFirstMatch) return objects.find((item) => new RegExp(`^${ref}`).test(item));
-
- return false;
- }
-
- getDroplabConfig() {
- return {
- addActiveClassToDropdownButton: true,
- InputSetter: [
- {
- input: this.createMergeRequestButton,
- valueAttribute: 'data-value',
- inputAttribute: 'data-action',
- },
- {
- input: this.createMergeRequestButton,
- valueAttribute: 'data-text',
- },
- {
- input: this.createTargetButton,
- valueAttribute: 'data-value',
- inputAttribute: 'data-action',
- },
- {
- input: this.createTargetButton,
- valueAttribute: 'data-text',
- },
- ],
- hideOnClick: false,
- };
- }
-
- static getInputSelectedText(input) {
- const start = input.selectionStart;
- const end = input.selectionEnd;
-
- return input.value.substr(start, end - start);
- }
-
- getRef(ref, target = 'all') {
- if (!ref) return false;
-
- this.refCancelToken = axios.CancelToken.source();
-
- return axios
- .get(`${createEndpoint(this.projectPath, this.refsPath)}${encodeURIComponent(ref)}`, {
- cancelToken: this.refCancelToken.token,
- })
- .then(({ data }) => {
- const branches = data[Object.keys(data)[0]];
- const tags = data[Object.keys(data)[1]];
- let result;
-
- if (target === 'branch') {
- result = CreateMergeRequestDropdown.findByValue(branches, ref);
- } else {
- result =
- CreateMergeRequestDropdown.findByValue(branches, ref, true) ||
- CreateMergeRequestDropdown.findByValue(tags, ref, true);
- this.suggestedRef = result;
- }
-
- this.isGettingRef = false;
-
- return this.updateInputState(target, ref, result);
- })
- .catch((thrown) => {
- if (axios.isCancel(thrown)) {
- return false;
- }
- this.unavailable();
- this.disable();
- createFlash({
- message: __('Failed to get ref.'),
- });
-
- this.isGettingRef = false;
-
- return false;
- });
- }
-
- getTargetData(target) {
- return {
- input: this[`${target}Input`],
- message: this[`${target}Message`],
- };
- }
-
- hide() {
- this.wrapperEl.classList.add('hidden');
- }
-
- init() {
- this.checkAbilityToCreateBranch();
- }
-
- initDroplab() {
- this.droplab = new DropLab();
-
- this.droplab.init(
- this.dropdownToggle,
- this.dropdownList,
- [InputSetter],
- this.getDroplabConfig(),
- );
- }
-
- inputsAreValid() {
- return this.branchIsValid && this.refIsValid;
- }
-
- isBusy() {
- return (
- this.isCreatingMergeRequest ||
- this.mergeRequestCreated ||
- this.isCreatingBranch ||
- this.branchCreated ||
- this.isGettingRef
- );
- }
-
- onChangeInput(event) {
- this.disable();
- let target;
- let value;
-
- // User changed input, cancel to prevent previous request from interfering
- if (this.refCancelToken !== null) {
- this.refCancelToken.cancel();
- }
-
- if (event.target === this.branchInput) {
- target = 'branch';
- ({ value } = this.branchInput);
- } else if (event.target === this.refInput) {
- target = 'ref';
- if (event.target === document.activeElement) {
- value =
- event.target.value.slice(0, event.target.selectionStart) +
- event.target.value.slice(event.target.selectionEnd);
- } else {
- value = event.target.value;
- }
- } else {
- return false;
- }
-
- if (this.isGettingRef) return false;
-
- // `ENTER` key submits the data.
- if (event.keyCode === 13 && this.inputsAreValid()) {
- event.preventDefault();
- return this.createMergeRequestButton.click();
- }
-
- // If the input is empty, use the original value generated by the backend.
- if (!value) {
- this.createBranchPath = this.wrapperEl.dataset.createBranchPath;
- this.createMrPath = this.wrapperEl.dataset.createMrPath;
-
- if (target === 'branch') {
- this.branchIsValid = true;
- } else {
- this.refIsValid = true;
- }
-
- this.enable();
- this.showAvailableMessage(target);
- this.refDebounce(value, target);
- return true;
- }
-
- this.showCheckingMessage(target);
- this.refDebounce(value, target);
-
- return true;
- }
-
- onClickCreateMergeRequestButton(event) {
- let xhr = null;
- event.preventDefault();
-
- if (isConfidentialIssue() && !event.target.classList.contains('js-create-target')) {
- this.droplab.hooks.forEach((hook) => hook.list.toggle());
-
- return;
- }
-
- if (this.isBusy()) {
- return;
- }
-
- if (event.target.dataset.action === CREATE_MERGE_REQUEST) {
- xhr = this.createMergeRequest();
- } else if (event.target.dataset.action === CREATE_BRANCH) {
- xhr = this.createBranch();
- }
-
- xhr.catch(() => {
- this.isCreatingMergeRequest = false;
- this.isCreatingBranch = false;
-
- this.enable();
- this.setLoading(false);
- });
-
- this.setLoading(true);
- this.disable();
- }
-
- onClickSetFocusOnBranchNameInput() {
- this.branchInput.focus();
- }
-
- // `TAB` autocompletes the source.
- static processTab(event) {
- if (event.keyCode !== 9 || this.isGettingRef) return;
-
- const selectedText = CreateMergeRequestDropdown.getInputSelectedText(this.refInput);
-
- // if nothing selected, we don't need to autocomplete anything. Do the default TAB action.
- // If a user manually selected text, don't autocomplete anything. Do the default TAB action.
- if (!selectedText || this.refInput.dataset.value === this.suggestedRef) return;
-
- event.preventDefault();
- const caretPositionEnd = this.refInput.value.length;
- this.refInput.setSelectionRange(caretPositionEnd, caretPositionEnd);
- }
-
- removeMessage(target) {
- const { input, message } = this.getTargetData(target);
- const inputClasses = ['gl-field-error-outline', 'gl-field-success-outline'];
- const messageClasses = ['text-muted', 'text-danger', 'text-success'];
-
- inputClasses.forEach((cssClass) => input.classList.remove(cssClass));
- messageClasses.forEach((cssClass) => message.classList.remove(cssClass));
- message.style.display = 'none';
- }
-
- setUnavailableButtonState(isLoading = true) {
- if (isLoading) {
- this.unavailableButtonSpinner.classList.remove('hide');
- this.unavailableButtonText.textContent = __('Checking branch availability...');
- } else {
- this.unavailableButtonSpinner.classList.add('hide');
- this.unavailableButtonText.textContent = __('New branch unavailable');
- }
- }
-
- showAvailableMessage(target) {
- const { input, message } = this.getTargetData(target);
- const text = target === 'branch' ? __('Branch name') : __('Source');
-
- this.removeMessage(target);
- input.classList.add('gl-field-success-outline');
- message.classList.add('text-success');
- message.textContent = sprintf(__('%{text} is available'), { text });
- message.style.display = 'inline-block';
- }
-
- showCheckingMessage(target) {
- const { message } = this.getTargetData(target);
- const text = target === 'branch' ? __('branch name') : __('source');
-
- this.removeMessage(target);
- message.classList.add('text-muted');
- message.textContent = sprintf(__('Checking %{text} availability…'), { text });
- message.style.display = 'inline-block';
- }
-
- showNotAvailableMessage(target) {
- const { input, message } = this.getTargetData(target);
- const text =
- target === 'branch' ? __('Branch is already taken') : __('Source is not available');
-
- this.removeMessage(target);
- input.classList.add('gl-field-error-outline');
- message.classList.add('text-danger');
- message.textContent = text;
- message.style.display = 'inline-block';
- }
-
- unavailable() {
- this.availableButton.classList.add('hidden');
- this.unavailableButton.classList.remove('hidden');
- }
-
- updateBranchName(suggestedBranchName) {
- this.branchInput.value = suggestedBranchName;
- this.updateCreatePaths('branch', suggestedBranchName);
- }
-
- updateInputState(target, ref, result) {
- // target - 'branch' or 'ref' - which the input field we are searching a ref for.
- // ref - string - what a user typed.
- // result - string - what has been found on backend.
-
- // If a found branch equals exact the same text a user typed,
- // that means a new branch cannot be created as it already exists.
- if (ref === result) {
- if (target === 'branch') {
- this.branchIsValid = false;
- this.showNotAvailableMessage('branch');
- } else {
- this.refIsValid = true;
- this.refInput.dataset.value = ref;
- this.showAvailableMessage('ref');
- this.updateCreatePaths(target, ref);
- }
- } else if (target === 'branch') {
- this.branchIsValid = true;
- this.showAvailableMessage('branch');
- this.updateCreatePaths(target, ref);
- } else {
- this.refIsValid = false;
- this.refInput.dataset.value = ref;
- this.disableCreateAction();
- this.showNotAvailableMessage('ref');
-
- // Show ref hint.
- if (result) {
- this.refInput.value = result;
- this.refInput.setSelectionRange(ref.length, result.length);
- }
- }
-
- if (this.inputsAreValid()) {
- this.enable();
- } else {
- this.disableCreateAction();
- }
- }
-
- // target - 'branch' or 'ref'
- // ref - string - the new value to use as branch or ref
- updateCreatePaths(target, ref) {
- const pathReplacement = `$1${encodeURIComponent(ref)}`;
-
- this.createBranchPath = this.createBranchPath.replace(
- this.regexps[target].createBranchPath,
- pathReplacement,
- );
- this.createMrPath = this.createMrPath.replace(
- this.regexps[target].createMrPath,
- pathReplacement,
- );
- }
-}
diff --git a/app/assets/javascripts/crm/components/form.vue b/app/assets/javascripts/crm/components/form.vue
new file mode 100644
index 00000000000..b24de1e95e8
--- /dev/null
+++ b/app/assets/javascripts/crm/components/form.vue
@@ -0,0 +1,232 @@
+<script>
+import { GlAlert, GlButton, GlDrawer, GlFormGroup, GlFormInput } from '@gitlab/ui';
+import { get as getPropValueByPath, isEmpty } from 'lodash';
+import { produce } from 'immer';
+import { MountingPortal } from 'portal-vue';
+import { __ } from '~/locale';
+import { logError } from '~/lib/logger';
+import { getFirstPropertyValue } from '~/lib/utils/common_utils';
+import { INDEX_ROUTE_NAME } from '../constants';
+
+const MSG_SAVE_CHANGES = __('Save changes');
+const MSG_ERROR = __('Something went wrong. Please try again.');
+const MSG_OPTIONAL = __('(optional)');
+const MSG_CANCEL = __('Cancel');
+
+/**
+ * This component is a first iteration towards a general reusable Create/Update component
+ *
+ * There's some opportunity to improve cohesion of this module which we are planning
+ * to address after solidifying the abstraction's requirements.
+ *
+ * Please see https://gitlab.com/gitlab-org/gitlab/-/issues/349441
+ */
+export default {
+ components: {
+ GlAlert,
+ GlButton,
+ GlDrawer,
+ GlFormGroup,
+ GlFormInput,
+ MountingPortal,
+ },
+ props: {
+ drawerOpen: {
+ type: Boolean,
+ required: true,
+ },
+ fields: {
+ type: Array,
+ required: true,
+ },
+ title: {
+ type: String,
+ required: true,
+ },
+ successMessage: {
+ type: String,
+ required: true,
+ },
+ mutation: {
+ type: Object,
+ required: true,
+ },
+ getQuery: {
+ type: Object,
+ required: false,
+ default: null,
+ },
+ getQueryNodePath: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ existingModel: {
+ type: Object,
+ required: false,
+ default: () => ({}),
+ },
+ additionalCreateParams: {
+ type: Object,
+ required: false,
+ default: () => ({}),
+ },
+ buttonLabel: {
+ type: String,
+ required: false,
+ default: () => MSG_SAVE_CHANGES,
+ },
+ },
+ data() {
+ const initialModel = this.fields.reduce(
+ (map, field) =>
+ Object.assign(map, {
+ [field.name]: this.existingModel ? this.existingModel[field.name] : null,
+ }),
+ {},
+ );
+
+ return {
+ model: initialModel,
+ submitting: false,
+ errorMessages: [],
+ };
+ },
+ computed: {
+ isEditMode() {
+ return this.existingModel?.id;
+ },
+ isInvalid() {
+ const { fields, model } = this;
+
+ return fields.some((field) => {
+ return field.required && isEmpty(model[field.name]);
+ });
+ },
+ variables() {
+ const { additionalCreateParams, fields, isEditMode, model } = this;
+
+ const variables = fields.reduce(
+ (map, field) =>
+ Object.assign(map, {
+ [field.name]: this.formatValue(model, field),
+ }),
+ {},
+ );
+
+ if (isEditMode) {
+ return { input: { id: this.existingModel.id, ...variables } };
+ }
+
+ return { input: { ...additionalCreateParams, ...variables } };
+ },
+ },
+ methods: {
+ formatValue(model, field) {
+ if (!isEmpty(model[field.name]) && field.input?.type === 'number') {
+ return parseFloat(model[field.name]);
+ }
+
+ return model[field.name];
+ },
+ save() {
+ const { mutation, variables, close } = this;
+
+ this.submitting = true;
+
+ return this.$apollo
+ .mutate({
+ mutation,
+ variables,
+ update: (store, { data }) => {
+ const { errors, ...result } = getFirstPropertyValue(data);
+
+ if (errors?.length) {
+ this.errorMessages = errors;
+ } else {
+ this.updateCache(store, result);
+ close(true);
+ }
+ },
+ })
+ .catch((e) => {
+ logError(e);
+ this.errorMessages = [MSG_ERROR];
+ })
+ .finally(() => {
+ this.submitting = false;
+ });
+ },
+ close(success) {
+ if (success) {
+ // This is needed so toast perists when route is changed
+ this.$root.$toast.show(this.successMessage);
+ }
+
+ this.$router.replace({ name: this.$options.INDEX_ROUTE_NAME });
+ },
+ updateCache(store, result) {
+ const { getQuery, isEditMode, getQueryNodePath } = this;
+
+ if (isEditMode || !getQuery) return;
+
+ const sourceData = store.readQuery(getQuery);
+
+ const newData = produce(sourceData, (draftState) => {
+ getPropValueByPath(draftState, getQueryNodePath).nodes.push(getFirstPropertyValue(result));
+ });
+
+ store.writeQuery({
+ ...getQuery,
+ data: newData,
+ });
+ },
+ getFieldLabel(field) {
+ const optionalSuffix = field.required ? '' : ` ${MSG_OPTIONAL}`;
+ return field.label + optionalSuffix;
+ },
+ },
+ MSG_CANCEL,
+ INDEX_ROUTE_NAME,
+};
+</script>
+
+<template>
+ <mounting-portal mount-to="#js-crm-form-portal" append>
+ <gl-drawer class="gl-drawer-responsive gl-absolute" :open="drawerOpen" @close="close(false)">
+ <template #title>
+ <h3>{{ title }}</h3>
+ </template>
+ <gl-alert v-if="errorMessages.length" variant="danger" @dismiss="errorMessages = []">
+ <ul class="gl-mb-0! gl-ml-5">
+ <li v-for="error in errorMessages" :key="error">
+ {{ error }}
+ </li>
+ </ul>
+ </gl-alert>
+ <form @submit.prevent="save">
+ <gl-form-group
+ v-for="field in fields"
+ :key="field.name"
+ :label="getFieldLabel(field)"
+ :label-for="field.name"
+ >
+ <gl-form-input :id="field.name" v-bind="field.input" v-model="model[field.name]" />
+ </gl-form-group>
+ <span class="gl-float-right">
+ <gl-button data-testid="cancel-button" @click="close(false)">
+ {{ $options.MSG_CANCEL }}
+ </gl-button>
+ <gl-button
+ variant="confirm"
+ :disabled="isInvalid"
+ :loading="submitting"
+ data-testid="save-button"
+ type="submit"
+ >{{ buttonLabel }}</gl-button
+ >
+ </span>
+ </form>
+ </gl-drawer>
+ </mounting-portal>
+</template>
diff --git a/app/assets/javascripts/cycle_analytics/components/base.vue b/app/assets/javascripts/cycle_analytics/components/base.vue
index 36430e51dd2..bdfabb8e846 100644
--- a/app/assets/javascripts/cycle_analytics/components/base.vue
+++ b/app/assets/javascripts/cycle_analytics/components/base.vue
@@ -153,7 +153,7 @@ export default {
};
</script>
<template>
- <div class="cycle-analytics">
+ <div>
<h3>{{ $options.i18n.pageTitle }}</h3>
<div class="gl-display-flex gl-flex-direction-column gl-md-flex-direction-row">
<path-navigation
diff --git a/app/assets/javascripts/cycle_analytics/components/path_navigation.vue b/app/assets/javascripts/cycle_analytics/components/path_navigation.vue
index f8f89772fd6..af7334ecf2e 100644
--- a/app/assets/javascripts/cycle_analytics/components/path_navigation.vue
+++ b/app/assets/javascripts/cycle_analytics/components/path_navigation.vue
@@ -57,7 +57,7 @@ export default {
};
</script>
<template>
- <gl-skeleton-loading v-if="loading" :lines="2" class="h-auto pt-2 pb-1" />
+ <gl-skeleton-loading v-if="loading" :lines="2" />
<gl-path v-else :key="selectedStage.id" :items="stages" @selected="onSelectStage">
<template #default="{ pathItem, pathId }">
<gl-popover
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_table.vue b/app/assets/javascripts/cycle_analytics/components/stage_table.vue
index fc4dfafb809..8f7a3f99bab 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_table.vue
+++ b/app/assets/javascripts/cycle_analytics/components/stage_table.vue
@@ -32,6 +32,9 @@ const WORKFLOW_COLUMN_TITLES = {
mergeRequests: { ...DEFAULT_WORKFLOW_TITLE_PROPERTIES, label: __('Merge requests') },
};
+const fullProjectPath = ({ namespaceFullPath = '', projectPath }) =>
+ namespaceFullPath.split('/').length > 1 ? `${namespaceFullPath}/${projectPath}` : projectPath;
+
export default {
name: 'StageTable',
components: {
@@ -89,6 +92,11 @@ export default {
required: false,
default: true,
},
+ includeProjectName: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
if (this.pagination) {
@@ -144,8 +152,15 @@ export default {
isMrLink(url = '') {
return url.includes('/merge_request');
},
- itemId({ url, iid }) {
- return this.isMrLink(url) ? `!${iid}` : `#${iid}`;
+ itemId({ iid, projectPath, namespaceFullPath = '' }, separator = '#') {
+ const prefix = this.includeProjectName
+ ? fullProjectPath({ namespaceFullPath, projectPath })
+ : '';
+ return `${prefix}${separator}${iid}`;
+ },
+ itemDisplayName(item) {
+ const separator = this.isMrLink(item.url) ? '!' : '#';
+ return this.itemId(item, separator);
},
itemTitle(item) {
return item.title || item.name;
@@ -201,8 +216,11 @@ export default {
<div data-testid="vsa-stage-event">
<div v-if="item.id" data-testid="vsa-stage-content">
<p class="gl-m-0">
- <gl-link class="gl-text-black-normal pipeline-id" :href="item.url"
- >#{{ item.id }}</gl-link
+ <gl-link
+ data-testid="vsa-stage-event-link"
+ class="gl-text-black-normal"
+ :href="item.url"
+ >{{ itemId(item.id, '#') }}</gl-link
>
<gl-icon :size="16" name="fork" />
<gl-link
@@ -240,7 +258,12 @@ export default {
<gl-link class="gl-text-black-normal" :href="item.url">{{ itemTitle(item) }}</gl-link>
</h5>
<p class="gl-m-0">
- <gl-link class="gl-text-black-normal" :href="item.url">{{ itemId(item) }}</gl-link>
+ <gl-link
+ data-testid="vsa-stage-event-link"
+ class="gl-text-black-normal"
+ :href="item.url"
+ >{{ itemDisplayName(item) }}</gl-link
+ >
<span class="gl-font-lg">&middot;</span>
<span data-testid="vsa-stage-event-date">
{{ s__('OpenedNDaysAgo|Opened') }}
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 8610dfc2b03..64461797c46 100644
--- a/app/assets/javascripts/cycle_analytics/components/value_stream_filters.vue
+++ b/app/assets/javascripts/cycle_analytics/components/value_stream_filters.vue
@@ -59,7 +59,9 @@ export default {
};
</script>
<template>
- <div class="gl-mt-3 gl-py-2 gl-px-3 bg-gray-light border-top border-bottom">
+ <div
+ class="gl-mt-3 gl-py-2 gl-px-3 gl-bg-gray-10 gl-border-b-1 gl-border-b-solid gl-border-t-1 gl-border-t-solid gl-border-gray-100"
+ >
<filter-bar
data-testid="vsa-filter-bar"
class="filtered-search-box gl-display-flex gl-mb-2 gl-mr-3 gl-border-none"
diff --git a/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue b/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue
index 10976202d06..7fefbab977d 100644
--- a/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue
+++ b/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue
@@ -7,6 +7,7 @@ import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vu
import { updateGlobalTodoCount } from '~/vue_shared/components/sidebar/todo_toggle/utils';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import DesignNotePin from '~/vue_shared/components/design_management/design_note_pin.vue';
+import { isLoggedIn } from '~/lib/utils/common_utils';
import { ACTIVE_DISCUSSION_SOURCE_TYPES } from '../../constants';
import createNoteMutation from '../../graphql/mutations/create_note.mutation.graphql';
import toggleResolveDiscussionMutation from '../../graphql/mutations/toggle_resolve_discussion.mutation.graphql';
@@ -17,6 +18,7 @@ import { hasErrors } from '../../utils/cache_update';
import { extractDesign } from '../../utils/design_management_utils';
import { ADD_DISCUSSION_COMMENT_ERROR } from '../../utils/error_messages';
import DesignNote from './design_note.vue';
+import DesignNoteSignedOut from './design_note_signed_out.vue';
import DesignReplyForm from './design_reply_form.vue';
import ToggleRepliesWidget from './toggle_replies_widget.vue';
@@ -24,6 +26,7 @@ export default {
components: {
ApolloMutation,
DesignNote,
+ DesignNoteSignedOut,
ReplyPlaceholder,
DesignReplyForm,
GlIcon,
@@ -55,6 +58,14 @@ export default {
required: false,
default: '',
},
+ registerPath: {
+ type: String,
+ required: true,
+ },
+ signInPath: {
+ type: String,
+ required: true,
+ },
resolvedDiscussionsExpanded: {
type: Boolean,
required: true,
@@ -93,6 +104,7 @@ export default {
isResolving: false,
shouldChangeResolvedStatus: false,
areRepliesCollapsed: this.discussion.resolved,
+ isLoggedIn: isLoggedIn(),
};
},
computed: {
@@ -226,7 +238,7 @@ export default {
:class="{ 'gl-bg-blue-50': isDiscussionActive }"
@error="$emit('update-note-error', $event)"
>
- <template v-if="discussion.resolvable" #resolve-discussion>
+ <template v-if="isLoggedIn && discussion.resolvable" #resolve-discussion>
<button
v-gl-tooltip
:class="{ 'is-active': discussion.resolved }"
@@ -269,38 +281,47 @@ export default {
:class="{ 'gl-bg-blue-50': isDiscussionActive }"
@error="$emit('update-note-error', $event)"
/>
- <li v-show="isReplyPlaceholderVisible" class="reply-wrapper discussion-reply-holder">
- <reply-placeholder
- v-if="!isFormVisible"
- class="qa-discussion-reply"
- :placeholder-text="__('Reply…')"
- @focus="showForm"
- />
- <apollo-mutation
- v-else
- #default="{ mutate, loading }"
- :mutation="$options.createNoteMutation"
- :variables="{
- input: mutationPayload,
- }"
- @done="onDone"
- @error="onCreateNoteError"
- >
- <design-reply-form
- v-model="discussionComment"
- :is-saving="loading"
- :markdown-preview-path="markdownPreviewPath"
- @submit-form="mutate"
- @cancel-form="hideForm"
+ <li
+ v-show="isReplyPlaceholderVisible"
+ class="reply-wrapper discussion-reply-holder"
+ :class="{ 'gl-bg-gray-10': !isLoggedIn }"
+ >
+ <template v-if="!isLoggedIn">
+ <design-note-signed-out :register-path="registerPath" :sign-in-path="signInPath" />
+ </template>
+ <template v-else>
+ <reply-placeholder
+ v-if="!isFormVisible"
+ class="qa-discussion-reply"
+ :placeholder-text="__('Reply…')"
+ @focus="showForm"
+ />
+ <apollo-mutation
+ v-else
+ #default="{ mutate, loading }"
+ :mutation="$options.createNoteMutation"
+ :variables="{
+ input: mutationPayload,
+ }"
+ @done="onDone"
+ @error="onCreateNoteError"
>
- <template v-if="discussion.resolvable" #resolve-checkbox>
- <label data-testid="resolve-checkbox">
- <input v-model="shouldChangeResolvedStatus" type="checkbox" />
- {{ resolveCheckboxText }}
- </label>
- </template>
- </design-reply-form>
- </apollo-mutation>
+ <design-reply-form
+ v-model="discussionComment"
+ :is-saving="loading"
+ :markdown-preview-path="markdownPreviewPath"
+ @submit-form="mutate"
+ @cancel-form="hideForm"
+ >
+ <template v-if="discussion.resolvable" #resolve-checkbox>
+ <label data-testid="resolve-checkbox">
+ <input v-model="shouldChangeResolvedStatus" type="checkbox" />
+ {{ resolveCheckboxText }}
+ </label>
+ </template>
+ </design-reply-form>
+ </apollo-mutation>
+ </template>
</li>
</ul>
</div>
diff --git a/app/assets/javascripts/design_management/components/design_notes/design_note_signed_out.vue b/app/assets/javascripts/design_management/components/design_notes/design_note_signed_out.vue
new file mode 100644
index 00000000000..f0812e62bba
--- /dev/null
+++ b/app/assets/javascripts/design_management/components/design_notes/design_note_signed_out.vue
@@ -0,0 +1,50 @@
+<script>
+import { GlSprintf, GlLink } from '@gitlab/ui';
+import { __ } from '~/locale';
+
+export default {
+ components: {
+ GlSprintf,
+ GlLink,
+ },
+ props: {
+ registerPath: {
+ type: String,
+ required: true,
+ },
+ signInPath: {
+ type: String,
+ required: true,
+ },
+ isAddDiscussion: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ computed: {
+ signedOutText() {
+ return this.isAddDiscussion
+ ? __(
+ 'Please %{registerLinkStart}register%{registerLinkEnd} or %{signInLinkStart}sign in%{signInLinkEnd} to start a new discussion.',
+ )
+ : __(
+ 'Please %{registerLinkStart}register%{registerLinkEnd} or %{signInLinkStart}sign in%{signInLinkEnd} to reply.',
+ );
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="disabled-comment text-center">
+ <gl-sprintf :message="signedOutText">
+ <template #registerLink="{ content }">
+ <gl-link :href="registerPath">{{ content }}</gl-link>
+ </template>
+ <template #signInLink="{ content }">
+ <gl-link :href="signInPath">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </div>
+</template>
diff --git a/app/assets/javascripts/design_management/components/design_presentation.vue b/app/assets/javascripts/design_management/components/design_presentation.vue
index 11d2f3b2e37..5116bacefa5 100644
--- a/app/assets/javascripts/design_management/components/design_presentation.vue
+++ b/app/assets/javascripts/design_management/components/design_presentation.vue
@@ -1,5 +1,6 @@
<script>
import { throttle } from 'lodash';
+import { isLoggedIn } from '~/lib/utils/common_utils';
import DesignOverlay from './design_overlay.vue';
import DesignImage from './image.vue';
@@ -54,6 +55,7 @@ export default {
initialLoad: true,
lastDragPosition: null,
isDraggingDesign: false,
+ isLoggedIn: isLoggedIn(),
};
},
computed: {
@@ -311,7 +313,7 @@ export default {
:position="overlayPosition"
:notes="discussionStartingNotes"
:current-comment-form="currentCommentForm"
- :disable-commenting="isDraggingDesign"
+ :disable-commenting="!isLoggedIn || isDraggingDesign"
:resolved-discussions-expanded="resolvedDiscussionsExpanded"
@openCommentForm="openCommentForm"
@closeCommentForm="closeCommentForm"
diff --git a/app/assets/javascripts/design_management/components/design_sidebar.vue b/app/assets/javascripts/design_management/components/design_sidebar.vue
index ced76eb4843..6d0ed3b08a3 100644
--- a/app/assets/javascripts/design_management/components/design_sidebar.vue
+++ b/app/assets/javascripts/design_management/components/design_sidebar.vue
@@ -1,7 +1,7 @@
<script>
import { GlCollapse, GlButton, GlPopover } from '@gitlab/ui';
import Cookies from 'js-cookie';
-import { parseBoolean } from '~/lib/utils/common_utils';
+import { parseBoolean, isLoggedIn } from '~/lib/utils/common_utils';
import { s__ } from '~/locale';
import Participants from '~/sidebar/components/participants/participants.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
@@ -9,11 +9,13 @@ import { ACTIVE_DISCUSSION_SOURCE_TYPES } from '../constants';
import updateActiveDiscussionMutation from '../graphql/mutations/update_active_discussion.mutation.graphql';
import { extractDiscussions, extractParticipants } from '../utils/design_management_utils';
import DesignDiscussion from './design_notes/design_discussion.vue';
+import DesignNoteSignedOut from './design_notes/design_note_signed_out.vue';
import DesignTodoButton from './design_todo_button.vue';
export default {
components: {
DesignDiscussion,
+ DesignNoteSignedOut,
Participants,
GlCollapse,
GlButton,
@@ -28,6 +30,12 @@ export default {
issueIid: {
default: '',
},
+ registerPath: {
+ default: '',
+ },
+ signInPath: {
+ default: '',
+ },
},
props: {
design: {
@@ -47,6 +55,7 @@ export default {
return {
isResolvedCommentsPopoverHidden: parseBoolean(Cookies.get(this.$options.cookieKey)),
discussionWithOpenForm: '',
+ isLoggedIn: isLoggedIn(),
};
},
computed: {
@@ -134,12 +143,19 @@ export default {
class="gl-mb-4"
/>
<h2
- v-if="unresolvedDiscussions.length === 0"
+ v-if="isLoggedIn && unresolvedDiscussions.length === 0"
class="new-discussion-disclaimer gl-font-base gl-m-0 gl-mb-4"
data-testid="new-discussion-disclaimer"
>
{{ s__("DesignManagement|Click the image where you'd like to start a new discussion") }}
</h2>
+ <design-note-signed-out
+ v-if="!isLoggedIn"
+ class="gl-mb-4"
+ :register-path="registerPath"
+ :sign-in-path="signInPath"
+ :is-add-discussion="true"
+ />
<design-discussion
v-for="discussion in unresolvedDiscussions"
:key="discussion.id"
@@ -147,6 +163,8 @@ export default {
:design-id="$route.params.id"
:noteable-id="design.id"
:markdown-preview-path="markdownPreviewPath"
+ :register-path="registerPath"
+ :sign-in-path="signInPath"
:resolved-discussions-expanded="resolvedDiscussionsExpanded"
:discussion-with-open-form="discussionWithOpenForm"
data-testid="unresolved-discussion"
@@ -197,6 +215,8 @@ export default {
:design-id="$route.params.id"
:noteable-id="design.id"
:markdown-preview-path="markdownPreviewPath"
+ :register-path="registerPath"
+ :sign-in-path="signInPath"
:resolved-discussions-expanded="resolvedDiscussionsExpanded"
:discussion-with-open-form="discussionWithOpenForm"
data-testid="resolved-discussion"
diff --git a/app/assets/javascripts/design_management/index.js b/app/assets/javascripts/design_management/index.js
index 11666587265..4ae76050aa5 100644
--- a/app/assets/javascripts/design_management/index.js
+++ b/app/assets/javascripts/design_management/index.js
@@ -8,7 +8,7 @@ import createRouter from './router';
export default () => {
const el = document.querySelector('.js-design-management');
- const { issueIid, projectPath, issuePath } = el.dataset;
+ const { issueIid, projectPath, issuePath, registerPath, signInPath } = el.dataset;
const router = createRouter(issuePath);
apolloProvider.clients.defaultClient.cache.writeQuery({
@@ -29,6 +29,8 @@ export default () => {
provide: {
projectPath,
issueIid,
+ registerPath,
+ signInPath,
},
mounted() {
performanceMarkAndMeasure({
diff --git a/app/assets/javascripts/diffs/components/compare_versions.vue b/app/assets/javascripts/diffs/components/compare_versions.vue
index da918947cc5..442807587d5 100644
--- a/app/assets/javascripts/diffs/components/compare_versions.vue
+++ b/app/assets/javascripts/diffs/components/compare_versions.vue
@@ -182,7 +182,7 @@ export default {
class="gl-mr-3"
@click="expandAllFiles"
>
- {{ __('Expand all') }}
+ {{ __('Expand all files') }}
</gl-button>
<settings-dropdown />
</div>
diff --git a/app/assets/javascripts/diffs/components/image_diff_overlay.vue b/app/assets/javascripts/diffs/components/image_diff_overlay.vue
index 5572338908f..eede8e52292 100644
--- a/app/assets/javascripts/diffs/components/image_diff_overlay.vue
+++ b/app/assets/javascripts/diffs/components/image_diff_overlay.vue
@@ -4,8 +4,8 @@ import { isArray } from 'lodash';
import { mapActions, mapGetters } from 'vuex';
import imageDiffMixin from 'ee_else_ce/diffs/mixins/image_diff';
-function calcPercent(pos, size, renderedSize) {
- return (((pos / size) * 100) / ((renderedSize / size) * 100)) * 100;
+function calcPercent(pos, renderedSize) {
+ return (100 * pos) / renderedSize;
}
export default {
@@ -65,8 +65,8 @@ export default {
...mapActions('diffs', ['openDiffFileCommentForm']),
getImageDimensions() {
return {
- width: this.$parent.width,
- height: this.$parent.height,
+ width: Math.round(this.$parent.width),
+ height: Math.round(this.$parent.height),
};
},
getPositionForObject(meta) {
@@ -87,15 +87,15 @@ export default {
},
clickedImage(x, y) {
const { width, height } = this.getImageDimensions();
- const xPercent = calcPercent(x, width, this.renderedWidth);
- const yPercent = calcPercent(y, height, this.renderedHeight);
+ const xPercent = calcPercent(x, this.renderedWidth);
+ const yPercent = calcPercent(y, this.renderedHeight);
this.openDiffFileCommentForm({
fileHash: this.fileHash,
width,
height,
- x: width * (xPercent / 100),
- y: height * (yPercent / 100),
+ x: Math.round(width * (xPercent / 100)),
+ y: Math.round(height * (yPercent / 100)),
xPercent,
yPercent,
});
diff --git a/app/assets/javascripts/dropzone_input.js b/app/assets/javascripts/dropzone_input.js
index 7c7127dfa44..491c2ced358 100644
--- a/app/assets/javascripts/dropzone_input.js
+++ b/app/assets/javascripts/dropzone_input.js
@@ -51,7 +51,6 @@ export default function dropzoneInput(form, config = { parallelUploads: 2 }) {
// Add dropzone area to the form.
const $mdArea = formTextarea.closest('.md-area');
- form.setupMarkdownPreview();
const $formDropzone = form.find('.div-dropzone');
$formDropzone.parent().addClass('div-dropzone-wrapper');
$formDropzone.append(divHover);
diff --git a/app/assets/javascripts/editor/source_editor.js b/app/assets/javascripts/editor/source_editor.js
index 57e2b0da565..fa749112ab5 100644
--- a/app/assets/javascripts/editor/source_editor.js
+++ b/app/assets/javascripts/editor/source_editor.js
@@ -149,7 +149,7 @@ export default class SourceEditor {
});
this.instances.push(instance);
- el.dispatchEvent(new CustomEvent(EDITOR_READY_EVENT, { instance }));
+ el.dispatchEvent(new CustomEvent(EDITOR_READY_EVENT, { detail: { instance } }));
return instance;
}
diff --git a/app/assets/javascripts/emoji/components/picker.vue b/app/assets/javascripts/emoji/components/picker.vue
index dc3eac0cd0c..686b5ffff9e 100644
--- a/app/assets/javascripts/emoji/components/picker.vue
+++ b/app/assets/javascripts/emoji/components/picker.vue
@@ -28,6 +28,16 @@ export default {
required: false,
default: () => [],
},
+ right: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
+ boundary: {
+ type: String,
+ required: false,
+ default: '',
+ },
},
data() {
return {
@@ -62,7 +72,7 @@ export default {
addToFrequentlyUsed(name);
},
getBoundaryElement() {
- return document.querySelector('.content-wrapper') || 'scrollParent';
+ return this.boundary || document.querySelector('.content-wrapper') || 'scrollParent';
},
onSearchInput() {
this.$refs.virtualScoller.setScrollTop(0);
@@ -87,7 +97,7 @@ export default {
menu-class="dropdown-extended-height"
category="secondary"
no-flip
- right
+ :right="right"
lazy
@shown="$emit('shown')"
@hidden="$emit('hidden')"
@@ -115,7 +125,7 @@ export default {
:aria-label="category.name"
@click="scrollToCategory(category.name)"
>
- <gl-icon :name="category.icon" :size="12" />
+ <gl-icon :name="category.icon" />
</button>
</div>
<emoji-list :search-value="searchValue">
diff --git a/app/assets/javascripts/environments/components/confirm_rollback_modal.vue b/app/assets/javascripts/environments/components/confirm_rollback_modal.vue
index 0e556f093e2..ce919f73858 100644
--- a/app/assets/javascripts/environments/components/confirm_rollback_modal.vue
+++ b/app/assets/javascripts/environments/components/confirm_rollback_modal.vue
@@ -99,8 +99,7 @@ export default {
};
},
isLastDeployment() {
- // eslint-disable-next-line @gitlab/require-i18n-strings
- return this.environment?.isLastDeployment || this.environment?.lastDeployment?.['last?'];
+ return this.environment?.isLastDeployment || this.environment?.lastDeployment?.isLast;
},
},
methods: {
diff --git a/app/assets/javascripts/environments/components/deployment.vue b/app/assets/javascripts/environments/components/deployment.vue
new file mode 100644
index 00000000000..ef43ca6bc33
--- /dev/null
+++ b/app/assets/javascripts/environments/components/deployment.vue
@@ -0,0 +1,25 @@
+<script>
+import DeploymentStatusBadge from './deployment_status_badge.vue';
+
+export default {
+ components: {
+ DeploymentStatusBadge,
+ },
+ props: {
+ deployment: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ status() {
+ return this.deployment?.status;
+ },
+ },
+};
+</script>
+<template>
+ <div>
+ <deployment-status-badge v-if="status" :status="status" />
+ </div>
+</template>
diff --git a/app/assets/javascripts/environments/components/deployment_status_badge.vue b/app/assets/javascripts/environments/components/deployment_status_badge.vue
new file mode 100644
index 00000000000..5a026911766
--- /dev/null
+++ b/app/assets/javascripts/environments/components/deployment_status_badge.vue
@@ -0,0 +1,60 @@
+<script>
+import { GlBadge } from '@gitlab/ui';
+import { s__ } from '~/locale';
+
+const STATUS_TEXT = {
+ created: s__('Deployment|Created'),
+ running: s__('Deployment|Running'),
+ success: s__('Deployment|Success'),
+ failed: s__('Deployment|Failed'),
+ canceled: s__('Deployment|Cancelled'),
+ skipped: s__('Deployment|Skipped'),
+ blocked: s__('Deployment|Waiting'),
+};
+
+const STATUS_VARIANT = {
+ success: 'success',
+ running: 'info',
+ failed: 'danger',
+ created: 'neutral',
+ canceled: 'neutral',
+ skipped: 'neutral',
+ blocked: 'neutral',
+};
+
+const STATUS_ICON = {
+ success: 'status_success',
+ running: 'status_running',
+ failed: 'status_failed',
+ created: 'status_created',
+ canceled: 'status_canceled',
+ skipped: 'status_skipped',
+ blocked: 'status_manual',
+};
+
+export default {
+ components: {
+ GlBadge,
+ },
+ props: {
+ status: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ icon() {
+ return STATUS_ICON[this.status];
+ },
+ text() {
+ return STATUS_TEXT[this.status];
+ },
+ variant() {
+ return STATUS_VARIANT[this.status];
+ },
+ },
+};
+</script>
+<template>
+ <gl-badge v-if="status" :icon="icon" :variant="variant">{{ text }}</gl-badge>
+</template>
diff --git a/app/assets/javascripts/environments/components/environment_actions.vue b/app/assets/javascripts/environments/components/environment_actions.vue
index 2d98f00433a..98c95507168 100644
--- a/app/assets/javascripts/environments/components/environment_actions.vue
+++ b/app/assets/javascripts/environments/components/environment_actions.vue
@@ -1,8 +1,9 @@
<script>
-import { GlDropdown, GlDropdownItem, GlIcon, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui';
+import { GlDropdown, GlDropdownItem, GlIcon, GlTooltipDirective } from '@gitlab/ui';
import { formatTime } from '~/lib/utils/datetime_utility';
import { __, s__, sprintf } from '~/locale';
import eventHub from '../event_hub';
+import actionMutation from '../graphql/mutations/action.mutation.graphql';
export default {
directives: {
@@ -12,7 +13,6 @@ export default {
GlDropdown,
GlDropdownItem,
GlIcon,
- GlLoadingIcon,
},
props: {
actions: {
@@ -20,6 +20,11 @@ export default {
required: false,
default: () => [],
},
+ graphql: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
return {
@@ -49,7 +54,11 @@ export default {
this.isLoading = true;
- eventHub.$emit('postAction', { endpoint: action.playPath });
+ if (this.graphql) {
+ this.$apollo.mutate({ mutation: actionMutation, variables: { action } });
+ } else {
+ eventHub.$emit('postAction', { endpoint: action.playPath });
+ }
},
isActionDisabled(action) {
@@ -70,18 +79,16 @@ export default {
<template>
<gl-dropdown
v-gl-tooltip
+ :text="title"
:title="title"
+ :loading="isLoading"
:aria-label="title"
- :disabled="isLoading"
+ icon="play"
+ text-sr-only
right
data-container="body"
data-testid="environment-actions-button"
>
- <template #button-content>
- <gl-icon name="play" />
- <gl-icon name="chevron-down" />
- <gl-loading-icon v-if="isLoading" size="sm" />
- </template>
<gl-dropdown-item
v-for="(action, i) in actions"
:key="i"
diff --git a/app/assets/javascripts/environments/components/environment_item.vue b/app/assets/javascripts/environments/components/environment_item.vue
index be9bfb50de5..cfe35d26b94 100644
--- a/app/assets/javascripts/environments/components/environment_item.vue
+++ b/app/assets/javascripts/environments/components/environment_item.vue
@@ -1,5 +1,5 @@
<script>
-import { GlDropdown, GlTooltipDirective, GlIcon, GlLink, GlSprintf } from '@gitlab/ui';
+import { GlDropdown, GlTooltipDirective, GlIcon, GlLink, GlSprintf, GlBadge } from '@gitlab/ui';
import { isEmpty } from 'lodash';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { __, s__, sprintf } from '~/locale';
@@ -30,6 +30,7 @@ export default {
CommitComponent,
ExternalUrlComponent,
GlDropdown,
+ GlBadge,
GlIcon,
GlLink,
GlSprintf,
@@ -621,9 +622,9 @@ export default {
<span v-if="model.size === 1">{{ model.name }}</span>
<span v-else>{{ model.name_without_type }}</span>
</a>
- <span v-if="isProtected" class="badge badge-success">
- {{ s__('Environments|protected') }}
- </span>
+ <gl-badge v-if="isProtected" variant="success">{{
+ s__('Environments|protected')
+ }}</gl-badge>
</span>
<span
v-else
@@ -639,7 +640,7 @@ export default {
<span> {{ model.folderName }} </span>
- <span class="badge badge-pill"> {{ model.size }} </span>
+ <gl-badge>{{ model.size }}</gl-badge>
</span>
</div>
diff --git a/app/assets/javascripts/environments/components/environment_stop.vue b/app/assets/javascripts/environments/components/environment_stop.vue
index 0d4a1e76eb8..17a70fd0c34 100644
--- a/app/assets/javascripts/environments/components/environment_stop.vue
+++ b/app/assets/javascripts/environments/components/environment_stop.vue
@@ -8,6 +8,8 @@ import { GlTooltipDirective, GlButton, GlModalDirective } from '@gitlab/ui';
import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants';
import { s__ } from '~/locale';
import eventHub from '../event_hub';
+import setEnvironmentToStopMutation from '../graphql/mutations/set_environment_to_stop.mutation.graphql';
+import isEnvironmentStoppingQuery from '../graphql/queries/is_environment_stopping.query.graphql';
export default {
components: {
@@ -22,6 +24,19 @@ export default {
type: Object,
required: true,
},
+ graphql: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ apollo: {
+ isEnvironmentStopping: {
+ query: isEnvironmentStoppingQuery,
+ variables() {
+ return { environment: this.environment };
+ },
+ },
},
i18n: {
title: s__('Environments|Stop environment'),
@@ -30,6 +45,7 @@ export default {
data() {
return {
isLoading: false,
+ isEnvironmentStopping: false,
};
},
mounted() {
@@ -41,7 +57,14 @@ export default {
methods: {
onClick() {
this.$root.$emit(BV_HIDE_TOOLTIP, this.$options.stopEnvironmentTooltipId);
- eventHub.$emit('requestStopEnvironment', this.environment);
+ if (this.graphql) {
+ this.$apollo.mutate({
+ mutation: setEnvironmentToStopMutation,
+ variables: { environment: this.environment },
+ });
+ } else {
+ eventHub.$emit('requestStopEnvironment', this.environment);
+ }
},
onStopEnvironment(environment) {
if (this.environment.id === environment.id) {
@@ -56,7 +79,7 @@ export default {
<gl-button
v-gl-tooltip="{ id: $options.stopEnvironmentTooltipId }"
v-gl-modal-directive="'stop-environment-modal'"
- :loading="isLoading"
+ :loading="isLoading || isEnvironmentStopping"
:title="$options.i18n.title"
:aria-label="$options.i18n.title"
icon="stop"
diff --git a/app/assets/javascripts/environments/components/new_environment_folder.vue b/app/assets/javascripts/environments/components/new_environment_folder.vue
index fe3d6f1e8ca..0d3867a4d74 100644
--- a/app/assets/javascripts/environments/components/new_environment_folder.vue
+++ b/app/assets/javascripts/environments/components/new_environment_folder.vue
@@ -2,9 +2,11 @@
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,
@@ -51,17 +53,26 @@ export default {
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-border-b-solid gl-border-gray-100 gl-border-1 gl-px-3 gl-pt-3 gl-pb-5">
- <div class="gl-w-full gl-display-flex gl-align-items-center">
+ <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"
@@ -77,6 +88,15 @@ export default {
<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" />
+ <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
new file mode 100644
index 00000000000..d3624103c13
--- /dev/null
+++ b/app/assets/javascripts/environments/components/new_environment_item.vue
@@ -0,0 +1,265 @@
+<script>
+import {
+ GlCollapse,
+ GlDropdown,
+ GlButton,
+ GlLink,
+ GlTooltipDirective as GlTooltip,
+} from '@gitlab/ui';
+import { __ } from '~/locale';
+import { truncate } from '~/lib/utils/text_utility';
+import isLastDeployment from '../graphql/queries/is_last_deployment.query.graphql';
+import ExternalUrl from './environment_external_url.vue';
+import Actions from './environment_actions.vue';
+import StopComponent from './environment_stop.vue';
+import Rollback from './environment_rollback.vue';
+import Pin from './environment_pin.vue';
+import Monitoring from './environment_monitoring.vue';
+import Terminal from './environment_terminal_button.vue';
+import Delete from './environment_delete.vue';
+import Deployment from './deployment.vue';
+
+export default {
+ components: {
+ GlCollapse,
+ GlDropdown,
+ GlButton,
+ GlLink,
+ Actions,
+ Deployment,
+ ExternalUrl,
+ StopComponent,
+ Rollback,
+ Monitoring,
+ Pin,
+ Terminal,
+ Delete,
+ },
+ directives: {
+ GlTooltip,
+ },
+ props: {
+ environment: {
+ required: true,
+ type: Object,
+ },
+ inFolder: {
+ required: false,
+ default: false,
+ type: Boolean,
+ },
+ },
+ apollo: {
+ isLastDeployment: {
+ query: isLastDeployment,
+ variables() {
+ return { environment: this.environment };
+ },
+ },
+ },
+ i18n: {
+ collapse: __('Collapse'),
+ expand: __('Expand'),
+ },
+ data() {
+ return { visible: false };
+ },
+ computed: {
+ icon() {
+ return this.visible ? 'angle-down' : 'angle-right';
+ },
+ externalUrl() {
+ return this.environment.externalUrl;
+ },
+ name() {
+ return this.inFolder ? this.environment.nameWithoutType : this.environment.name;
+ },
+ label() {
+ return this.visible ? this.$options.i18n.collapse : this.$options.i18n.expand;
+ },
+ lastDeployment() {
+ return this.environment?.lastDeployment;
+ },
+ upcomingDeployment() {
+ return this.environment?.upcomingDeployment;
+ },
+ actions() {
+ if (!this.lastDeployment) {
+ return [];
+ }
+ const { manualActions = [], scheduledActions = [] } = this.lastDeployment;
+ const combinedActions = [...manualActions, ...scheduledActions];
+ return combinedActions.map((action) => ({
+ ...action,
+ }));
+ },
+ canStop() {
+ return this.environment?.canStop;
+ },
+ retryPath() {
+ return this.lastDeployment?.deployable?.retryPath;
+ },
+ hasExtraActions() {
+ return Boolean(
+ this.retryPath ||
+ this.canShowAutoStopDate ||
+ this.metricsPath ||
+ this.terminalPath ||
+ this.canDeleteEnvironment,
+ );
+ },
+ canShowAutoStopDate() {
+ if (!this.environment?.autoStopAt) {
+ return false;
+ }
+
+ const autoStopDate = new Date(this.environment?.autoStopAt);
+ const now = new Date();
+
+ return now < autoStopDate;
+ },
+ autoStopPath() {
+ return this.environment?.cancelAutoStopPath ?? '';
+ },
+ metricsPath() {
+ return this.environment?.metricsPath ?? '';
+ },
+ terminalPath() {
+ return this.environment?.terminalPath ?? '';
+ },
+ canDeleteEnvironment() {
+ return Boolean(this.environment?.canDelete && this.environment?.deletePath);
+ },
+ displayName() {
+ return truncate(this.name, 80);
+ },
+ },
+ methods: {
+ toggleCollapse() {
+ this.visible = !this.visible;
+ },
+ },
+ deploymentClasses: [
+ 'gl-border-gray-100',
+ 'gl-border-t-solid',
+ 'gl-border-1',
+ 'gl-py-5',
+ 'gl-pl-7',
+ 'gl-bg-gray-10',
+ ],
+};
+</script>
+<template>
+ <div>
+ <div
+ class="gl-px-3 gl-pt-3 gl-pb-5 gl-display-flex gl-justify-content-space-between gl-align-items-center"
+ >
+ <div
+ :class="{ 'gl-ml-7': inFolder }"
+ class="gl-min-w-0 gl-mr-4 gl-display-flex gl-align-items-center"
+ >
+ <gl-button
+ class="gl-mr-4 gl-min-w-fit-content"
+ :icon="icon"
+ :aria-label="label"
+ size="small"
+ category="tertiary"
+ @click="toggleCollapse"
+ />
+ <gl-link
+ v-gl-tooltip
+ :href="environment.environmentPath"
+ class="gl-text-blue-500 gl-text-truncate"
+ :class="{ 'gl-font-weight-bold': visible }"
+ :title="name"
+ >
+ {{ displayName }}
+ </gl-link>
+ </div>
+ <div>
+ <div class="btn-group table-action-buttons" role="group">
+ <external-url
+ v-if="externalUrl"
+ :external-url="externalUrl"
+ data-track-action="click_button"
+ data-track-label="environment_url"
+ />
+
+ <actions
+ v-if="actions.length > 0"
+ :actions="actions"
+ data-track-action="click_dropdown"
+ data-track-label="environment_actions"
+ graphql
+ />
+
+ <stop-component
+ v-if="canStop"
+ :environment="environment"
+ class="gl-z-index-2"
+ data-track-action="click_button"
+ data-track-label="environment_stop"
+ graphql
+ />
+
+ <gl-dropdown
+ v-if="hasExtraActions"
+ icon="ellipsis_v"
+ text-sr-only
+ :text="__('More actions')"
+ category="secondary"
+ no-caret
+ right
+ >
+ <rollback
+ v-if="retryPath"
+ :environment="environment"
+ :is-last-deployment="isLastDeployment"
+ :retry-url="retryPath"
+ graphql
+ data-track-action="click_button"
+ data-track-label="environment_rollback"
+ />
+
+ <pin
+ v-if="canShowAutoStopDate"
+ :auto-stop-url="autoStopPath"
+ data-track-action="click_button"
+ data-track-label="environment_pin"
+ />
+
+ <monitoring
+ v-if="metricsPath"
+ :monitoring-url="metricsPath"
+ data-track-action="click_button"
+ data-track-label="environment_monitoring"
+ />
+
+ <terminal
+ v-if="terminalPath"
+ :terminal-path="terminalPath"
+ data-track-action="click_button"
+ data-track-label="environment_terminal"
+ />
+
+ <delete
+ v-if="canDeleteEnvironment"
+ :environment="environment"
+ data-track-action="click_button"
+ data-track-label="environment_delete"
+ graphql
+ />
+ </gl-dropdown>
+ </div>
+ </div>
+ </div>
+ <gl-collapse :visible="visible">
+ <div v-if="lastDeployment" :class="$options.deploymentClasses">
+ <deployment :deployment="lastDeployment" :class="{ 'gl-ml-7': inFolder }" />
+ </div>
+ <div v-if="upcomingDeployment" :class="$options.deploymentClasses">
+ <deployment :deployment="upcomingDeployment" :class="{ 'gl-ml-7': inFolder }" />
+ </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
index 8d94e7021ca..cb36e226d0e 100644
--- a/app/assets/javascripts/environments/components/new_environments_app.vue
+++ b/app/assets/javascripts/environments/components/new_environments_app.vue
@@ -5,13 +5,24 @@ import { updateHistory, setUrlParams, queryToObject } from '~/lib/utils/url_util
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 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';
export default {
components: {
+ DeleteEnvironmentModal,
+ ConfirmRollbackModal,
EnvironmentFolder,
EnableReviewAppModal,
+ EnvironmentItem,
+ StopEnvironmentModal,
GlBadge,
GlPagination,
GlTab,
@@ -36,6 +47,15 @@ export default {
pageInfo: {
query: pageInfoQuery,
},
+ environmentToDelete: {
+ query: environmentToDeleteQuery,
+ },
+ environmentToRollback: {
+ query: environmentToRollbackQuery,
+ },
+ environmentToStop: {
+ query: environmentToStopQuery,
+ },
},
inject: ['newEnvironmentPath', 'canCreateEnvironment'],
i18n: {
@@ -57,6 +77,9 @@ export default {
isReviewAppModalVisible: false,
page: parseInt(page, 10),
scope,
+ environmentToDelete: {},
+ environmentToRollback: {},
+ environmentToStop: {},
};
},
computed: {
@@ -64,7 +87,10 @@ export default {
return this.environmentApp?.reviewApp?.canSetupReviewApp;
},
folders() {
- return this.environmentApp?.environments.filter((e) => e.size > 1) ?? [];
+ return this.environmentApp?.environments?.filter((e) => e.size > 1) ?? [];
+ },
+ environments() {
+ return this.environmentApp?.environments?.filter((e) => e.size === 1) ?? [];
},
availableCount() {
return this.environmentApp?.availableCount;
@@ -119,7 +145,7 @@ export default {
},
setScope(scope) {
this.scope = scope;
- this.resetPolling();
+ this.moveToPage(1);
},
movePage(direction) {
this.moveToPage(this.pageInfo[`${direction}Page`]);
@@ -157,6 +183,9 @@ export default {
: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 />
<gl-tabs
:action-secondary="addEnvironment"
:action-primary="openReviewAppModal"
@@ -187,6 +216,12 @@ export default {
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"
diff --git a/app/assets/javascripts/environments/components/stop_environment_modal.vue b/app/assets/javascripts/environments/components/stop_environment_modal.vue
index 7a9233048a9..162ad598c8c 100644
--- a/app/assets/javascripts/environments/components/stop_environment_modal.vue
+++ b/app/assets/javascripts/environments/components/stop_environment_modal.vue
@@ -2,6 +2,7 @@
import { GlSprintf, GlTooltipDirective, GlModal } from '@gitlab/ui';
import { __, s__ } from '~/locale';
import eventHub from '../event_hub';
+import stopEnvironmentMutation from '../graphql/mutations/stop_environment.mutation.graphql';
export default {
id: 'stop-environment-modal',
@@ -21,6 +22,11 @@ export default {
type: Object,
required: true,
},
+ graphql: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
computed: {
@@ -39,7 +45,14 @@ export default {
methods: {
onSubmit() {
- eventHub.$emit('stopEnvironment', this.environment);
+ if (this.graphql) {
+ this.$apollo.mutate({
+ mutation: stopEnvironmentMutation,
+ variables: { environment: this.environment },
+ });
+ } else {
+ eventHub.$emit('stopEnvironment', this.environment);
+ }
},
},
};
diff --git a/app/assets/javascripts/environments/graphql/mutations/action.mutation.graphql b/app/assets/javascripts/environments/graphql/mutations/action.mutation.graphql
new file mode 100644
index 00000000000..bc2c9b33367
--- /dev/null
+++ b/app/assets/javascripts/environments/graphql/mutations/action.mutation.graphql
@@ -0,0 +1,5 @@
+mutation action($action: LocalAction) {
+ action(action: $action) @client {
+ errors
+ }
+}
diff --git a/app/assets/javascripts/environments/graphql/mutations/set_environment_to_stop.mutation.graphql b/app/assets/javascripts/environments/graphql/mutations/set_environment_to_stop.mutation.graphql
new file mode 100644
index 00000000000..2891f4c5101
--- /dev/null
+++ b/app/assets/javascripts/environments/graphql/mutations/set_environment_to_stop.mutation.graphql
@@ -0,0 +1,3 @@
+mutation SetEnvironmentToStop($environment: LocalEnvironmentInput) {
+ setEnvironmentToStop(environment: $environment) @client
+}
diff --git a/app/assets/javascripts/environments/graphql/queries/environment_to_stop.query.graphql b/app/assets/javascripts/environments/graphql/queries/environment_to_stop.query.graphql
new file mode 100644
index 00000000000..128846145e8
--- /dev/null
+++ b/app/assets/javascripts/environments/graphql/queries/environment_to_stop.query.graphql
@@ -0,0 +1,3 @@
+query environmentToStop {
+ environmentToStop @client
+}
diff --git a/app/assets/javascripts/environments/graphql/queries/is_environment_stopping.query.graphql b/app/assets/javascripts/environments/graphql/queries/is_environment_stopping.query.graphql
new file mode 100644
index 00000000000..ad05e252e6f
--- /dev/null
+++ b/app/assets/javascripts/environments/graphql/queries/is_environment_stopping.query.graphql
@@ -0,0 +1,3 @@
+query isEnvironmentStopping($environment: LocalEnvironment) {
+ isEnvironmentStopping(environment: $environment) @client
+}
diff --git a/app/assets/javascripts/environments/graphql/queries/is_last_deployment.query.graphql b/app/assets/javascripts/environments/graphql/queries/is_last_deployment.query.graphql
new file mode 100644
index 00000000000..5eda2f18567
--- /dev/null
+++ b/app/assets/javascripts/environments/graphql/queries/is_last_deployment.query.graphql
@@ -0,0 +1,3 @@
+query isLastDeployment($environment: LocalEnvironment) {
+ isLastDeployment(environment: $environment) @client
+}
diff --git a/app/assets/javascripts/environments/graphql/resolvers.js b/app/assets/javascripts/environments/graphql/resolvers.js
index 9ebbc0ad1f8..812fa0c81f0 100644
--- a/app/assets/javascripts/environments/graphql/resolvers.js
+++ b/app/assets/javascripts/environments/graphql/resolvers.js
@@ -8,6 +8,7 @@ import {
import pollIntervalQuery from './queries/poll_interval.query.graphql';
import environmentToRollbackQuery from './queries/environment_to_rollback.query.graphql';
+import environmentToStopQuery from './queries/environment_to_stop.query.graphql';
import environmentToDeleteQuery from './queries/environment_to_delete.query.graphql';
import pageInfoQuery from './queries/page_info.query.graphql';
@@ -65,8 +66,7 @@ export const resolvers = (endpoint) => ({
}));
},
isLastDeployment(_, { environment }) {
- // eslint-disable-next-line @gitlab/require-i18n-strings
- return environment?.lastDeployment?.['last?'];
+ return environment?.lastDeployment?.isLast;
},
},
Mutation: {
@@ -108,6 +108,20 @@ export const resolvers = (endpoint) => ({
]);
});
},
+ setEnvironmentToStop(_, { environment }, { client }) {
+ client.writeQuery({
+ query: environmentToStopQuery,
+ data: { environmentToStop: environment },
+ });
+ },
+ action(_, { action: { playPath } }) {
+ return axios
+ .post(playPath)
+ .then(() => buildErrors())
+ .catch(() =>
+ buildErrors([s__('Environments|An error occurred while making the request.')]),
+ );
+ },
setEnvironmentToDelete(_, { environment }, { client }) {
client.writeQuery({
query: environmentToDeleteQuery,
diff --git a/app/assets/javascripts/environments/graphql/typedefs.graphql b/app/assets/javascripts/environments/graphql/typedefs.graphql
index 4a3abb0e89f..c02f6b2838a 100644
--- a/app/assets/javascripts/environments/graphql/typedefs.graphql
+++ b/app/assets/javascripts/environments/graphql/typedefs.graphql
@@ -68,7 +68,9 @@ extend type Query {
environmentToDelete: LocalEnvironment
pageInfo: LocalPageInfo
environmentToRollback: LocalEnvironment
- isLastDeployment: Boolean
+ environmentToStop: LocalEnvironment
+ isEnvironmentStopping(environment: LocalEnvironmentInput): Boolean
+ isLastDeployment(environment: LocalEnvironmentInput): Boolean
}
extend type Mutation {
@@ -78,4 +80,6 @@ extend type Mutation {
cancelAutoStop(environment: LocalEnvironmentInput): LocalErrors
setEnvironmentToDelete(environment: LocalEnvironmentInput): LocalErrors
setEnvironmentToRollback(environment: LocalEnvironmentInput): LocalErrors
+ setEnvironmentToStop(environment: LocalEnvironmentInput): LocalErrors
+ action(environment: LocalEnvironmentInput): LocalErrors
}
diff --git a/app/assets/javascripts/experimental_flags.js b/app/assets/javascripts/experimental_flags.js
deleted file mode 100644
index 1d60847147b..00000000000
--- a/app/assets/javascripts/experimental_flags.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import $ from 'jquery';
-import Cookies from 'js-cookie';
-
-export default () => {
- $('.js-experiment-feature-toggle').on('change', (e) => {
- const el = e.target;
-
- Cookies.set(el.name, el.value, {
- expires: 365 * 10,
- });
-
- document.body.scrollTop = 0;
- window.location.reload();
- });
-};
diff --git a/app/assets/javascripts/flash.js b/app/assets/javascripts/flash.js
index f0ef55f73eb..d9c2e55cffe 100644
--- a/app/assets/javascripts/flash.js
+++ b/app/assets/javascripts/flash.js
@@ -1,5 +1,8 @@
import * as Sentry from '@sentry/browser';
import { escape } from 'lodash';
+import Vue from 'vue';
+import { GlAlert } from '@gitlab/ui';
+import { __ } from '~/locale';
import { spriteIcon } from './lib/utils/common_utils';
const FLASH_TYPES = {
@@ -9,6 +12,12 @@ const FLASH_TYPES = {
WARNING: 'warning',
};
+const VARIANT_SUCCESS = 'success';
+const VARIANT_WARNING = 'warning';
+const VARIANT_DANGER = 'danger';
+const VARIANT_INFO = 'info';
+const VARIANT_TIP = 'tip';
+
const FLASH_CLOSED_EVENT = 'flashClosed';
const getCloseEl = (flashEl) => {
@@ -68,6 +77,126 @@ const addDismissFlashClickListener = (flashEl, fadeTransition) => {
getCloseEl(flashEl)?.addEventListener('click', () => hideFlash(flashEl, fadeTransition));
};
+/**
+ * Render an alert at the top of the page, or, optionally an
+ * arbitrary existing container.
+ *
+ * This alert is always dismissible.
+ *
+ * Usage:
+ *
+ * 1. Render a new alert
+ *
+ * import { createAlert, ALERT_VARIANTS } from '~/flash';
+ *
+ * createAlert({ message: 'My error message' });
+ * createAlert({ message: 'My warning message', variant: ALERT_VARIANTS.WARNING });
+ *
+ * 2. Dismiss this alert programmatically
+ *
+ * const alert = createAlert({ message: 'Message' });
+ *
+ * // ...
+ *
+ * alert.dismiss();
+ *
+ * 3. Respond to the alert being dismissed
+ *
+ * createAlert({ message: 'Message', onDismiss: () => { ... }});
+ *
+ * @param {Object} options Options to control the flash message
+ * @param {String} options.message Alert message text
+ * @param {String?} options.variant Which GlAlert variant to use, should be VARIANT_SUCCESS, VARIANT_WARNING, VARIANT_DANGER, VARIANT_INFO or VARIANT_TIP. Defaults to VARIANT_DANGER.
+ * @param {Object?} options.parent Reference to parent element under which alert needs to appear. Defaults to `document`.
+ * @param {Function?} options.onDismiss Handler to call when this alert is dismissed.
+ * @param {Object?} options.containerSelector Selector for the container of the alert
+ * @param {Object?} options.primaryButton Object describing primary button of alert
+ * @param {String?} link Href of primary button
+ * @param {String?} text Text of primary button
+ * @param {Function?} clickHandler Handler to call when primary button is clicked on. The click event is sent as an argument.
+ * @param {Object?} options.secondaryButton Object describing secondary button of alert
+ * @param {String?} link Href of secondary button
+ * @param {String?} text Text of secondary button
+ * @param {Function?} clickHandler Handler to call when secondary button is clicked on. The click event is sent as an argument.
+ * @param {Boolean?} options.captureError Whether to send error to Sentry
+ * @param {Object} options.error Error to be captured in Sentry
+ * @returns
+ */
+const createAlert = function createAlert({
+ message,
+ variant = VARIANT_DANGER,
+ parent = document,
+ containerSelector = '.flash-container',
+ primaryButton = null,
+ secondaryButton = null,
+ onDismiss = null,
+ captureError = false,
+ error = null,
+}) {
+ if (captureError && error) Sentry.captureException(error);
+
+ const alertContainer = parent.querySelector(containerSelector);
+ if (!alertContainer) return null;
+
+ const el = document.createElement('div');
+ alertContainer.appendChild(el);
+
+ return new Vue({
+ el,
+ components: {
+ GlAlert,
+ },
+ methods: {
+ /**
+ * Public method to dismiss this alert and removes
+ * this Vue instance.
+ */
+ dismiss() {
+ if (onDismiss) {
+ onDismiss();
+ }
+ this.$destroy();
+ this.$el.parentNode.removeChild(this.$el);
+ },
+ },
+ render(h) {
+ const on = {};
+
+ on.dismiss = () => {
+ this.dismiss();
+ };
+
+ if (primaryButton?.clickHandler) {
+ on.primaryAction = (e) => {
+ primaryButton.clickHandler(e);
+ };
+ }
+ if (secondaryButton?.clickHandler) {
+ on.secondaryAction = (e) => {
+ secondaryButton.clickHandler(e);
+ };
+ }
+
+ return h(
+ GlAlert,
+ {
+ props: {
+ dismissible: true,
+ dismissLabel: __('Dismiss'),
+ variant,
+ primaryButtonLink: primaryButton?.link,
+ primaryButtonText: primaryButton?.text,
+ secondaryButtonLink: secondaryButton?.link,
+ secondaryButtonText: secondaryButton?.text,
+ },
+ on,
+ },
+ message,
+ );
+ },
+ });
+};
+
/*
* Flash banner supports different types of Flash configurations
* along with ability to provide actionConfig which can be used to show
@@ -82,8 +211,8 @@ const addDismissFlashClickListener = (flashEl, fadeTransition) => {
* @param {String} title Title of action
* @param {Function} clickHandler Method to call when action is clicked on
* @param {Boolean} options.fadeTransition Boolean to determine whether to fade the alert out
- * @param {Boolean} options.captureError Boolean to determine whether to send error to sentry
- * @param {Object} options.error Error to be captured in sentry
+ * @param {Boolean} options.captureError Boolean to determine whether to send error to Sentry
+ * @param {Object} options.error Error to be captured in Sentry
*/
const createFlash = function createFlash({
message,
@@ -134,4 +263,10 @@ export {
addDismissFlashClickListener,
FLASH_TYPES,
FLASH_CLOSED_EVENT,
+ createAlert,
+ VARIANT_SUCCESS,
+ VARIANT_WARNING,
+ VARIANT_DANGER,
+ VARIANT_INFO,
+ VARIANT_TIP,
};
diff --git a/app/assets/javascripts/gitlab_version_check.js b/app/assets/javascripts/gitlab_version_check.js
new file mode 100644
index 00000000000..2892aded7c5
--- /dev/null
+++ b/app/assets/javascripts/gitlab_version_check.js
@@ -0,0 +1,20 @@
+import Vue from 'vue';
+import GitlabVersionCheck from '~/vue_shared/components/gitlab_version_check.vue';
+
+const mountGitlabVersionCheck = (el) => {
+ const { size } = el.dataset;
+
+ return new Vue({
+ el,
+ render(createElement) {
+ return createElement(GitlabVersionCheck, {
+ props: {
+ size,
+ },
+ });
+ },
+ });
+};
+
+export default () =>
+ [...document.querySelectorAll('.js-gitlab-version-check')].map(mountGitlabVersionCheck);
diff --git a/app/assets/javascripts/google_cloud/components/deployments_service_table.vue b/app/assets/javascripts/google_cloud/components/deployments_service_table.vue
new file mode 100644
index 00000000000..7d27d7cf6b2
--- /dev/null
+++ b/app/assets/javascripts/google_cloud/components/deployments_service_table.vue
@@ -0,0 +1,61 @@
+<script>
+import { GlButton, GlTable } from '@gitlab/ui';
+import { __ } from '~/locale';
+
+const i18n = {
+ cloudRun: __('Cloud Run'),
+ cloudRunDescription: __('Deploy container based web apps on Google managed clusters'),
+ cloudStorage: __('Cloud Storage'),
+ cloudStorageDescription: __('Deploy static assets and resources to Google managed CDN'),
+ deployments: __('Deployments'),
+ deploymentsDescription: __(
+ 'Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud',
+ ),
+ configureViaMergeRequest: __('Configure via Merge Request'),
+ service: __('Service'),
+ description: __('Description'),
+};
+
+export default {
+ components: { GlButton, GlTable },
+ props: {
+ cloudRunUrl: {
+ type: String,
+ required: true,
+ },
+ cloudStorageUrl: {
+ type: String,
+ required: true,
+ },
+ },
+ fields: [
+ { key: 'title', label: i18n.service },
+ { key: 'description', label: i18n.description },
+ { key: 'action', label: '' },
+ ],
+ items: [
+ {
+ title: i18n.cloudRun,
+ description: i18n.cloudRunDescription,
+ action: { title: i18n.configureViaMergeRequest, disabled: true },
+ },
+ {
+ title: i18n.cloudStorage,
+ description: i18n.cloudStorageDescription,
+ action: { title: i18n.configureViaMergeRequest, disabled: true },
+ },
+ ],
+ i18n,
+};
+</script>
+<template>
+ <div class="gl-mx-3">
+ <h2 class="gl-font-size-h2">{{ $options.i18n.deployments }}</h2>
+ <p>{{ $options.i18n.deploymentsDescription }}</p>
+ <gl-table :fields="$options.fields" :items="$options.items">
+ <template #cell(action)="{ value }">
+ <gl-button :disabled="value.disabled">{{ value.title }}</gl-button>
+ </template>
+ </gl-table>
+ </div>
+</template>
diff --git a/app/assets/javascripts/google_cloud/components/home.vue b/app/assets/javascripts/google_cloud/components/home.vue
index 05f39de66ee..8ef110dcf22 100644
--- a/app/assets/javascripts/google_cloud/components/home.vue
+++ b/app/assets/javascripts/google_cloud/components/home.vue
@@ -1,11 +1,13 @@
<script>
import { GlTabs, GlTab } from '@gitlab/ui';
+import DeploymentsServiceTable from './deployments_service_table.vue';
import ServiceAccountsList from './service_accounts_list.vue';
export default {
components: {
GlTabs,
GlTab,
+ DeploymentsServiceTable,
ServiceAccountsList,
},
props: {
@@ -21,6 +23,14 @@ export default {
type: String,
required: true,
},
+ deploymentsCloudRunUrl: {
+ type: String,
+ required: true,
+ },
+ deploymentsCloudStorageUrl: {
+ type: String,
+ required: true,
+ },
},
};
</script>
@@ -35,7 +45,12 @@ export default {
:empty-illustration-url="emptyIllustrationUrl"
/>
</gl-tab>
- <gl-tab :title="__('Deployments')" disabled />
+ <gl-tab :title="__('Deployments')">
+ <deployments-service-table
+ :cloud-run-url="deploymentsCloudRunUrl"
+ :cloud-storage-url="deploymentsCloudStorageUrl"
+ />
+ </gl-tab>
<gl-tab :title="__('Services')" disabled />
</gl-tabs>
</template>
diff --git a/app/assets/javascripts/google_tag_manager/index.js b/app/assets/javascripts/google_tag_manager/index.js
new file mode 100644
index 00000000000..ab80e15c2ec
--- /dev/null
+++ b/app/assets/javascripts/google_tag_manager/index.js
@@ -0,0 +1,122 @@
+import { logError } from '~/lib/logger';
+
+const isSupported = () => Boolean(window.dataLayer) && gon.features?.gitlabGtmDatalayer;
+
+const pushEvent = (event, args = {}) => {
+ if (!window.dataLayer) {
+ return;
+ }
+
+ try {
+ window.dataLayer.push({
+ event,
+ ...args,
+ });
+ } catch (e) {
+ logError('Unexpected error while pushing to dataLayer', e);
+ }
+};
+
+const pushAccountSubmit = (accountType, accountMethod) =>
+ pushEvent('accountSubmit', { accountType, accountMethod });
+
+const trackFormSubmission = (accountType) => {
+ const form = document.getElementById('new_new_user');
+ form.addEventListener('submit', () => {
+ pushAccountSubmit(accountType, 'form');
+ });
+};
+
+const trackOmniAuthSubmission = (accountType) => {
+ const links = document.querySelectorAll('.js-oauth-login');
+ links.forEach((link) => {
+ const { provider } = link.dataset;
+ link.addEventListener('click', () => {
+ pushAccountSubmit(accountType, provider);
+ });
+ });
+};
+
+export const trackFreeTrialAccountSubmissions = () => {
+ if (!isSupported()) {
+ return;
+ }
+
+ trackFormSubmission('freeThirtyDayTrial');
+ trackOmniAuthSubmission('freeThirtyDayTrial');
+};
+
+export const trackNewRegistrations = () => {
+ if (!isSupported()) {
+ return;
+ }
+
+ trackFormSubmission('standardSignUp');
+ trackOmniAuthSubmission('standardSignUp');
+};
+
+export const trackSaasTrialSubmit = () => {
+ if (!isSupported()) {
+ return;
+ }
+
+ pushEvent('saasTrialSubmit');
+};
+
+export const trackSaasTrialSkip = () => {
+ if (!isSupported()) {
+ return;
+ }
+
+ const skipLink = document.querySelector('.js-skip-trial');
+ skipLink.addEventListener('click', () => {
+ pushEvent('saasTrialSkip');
+ });
+};
+
+export const trackSaasTrialGroup = () => {
+ if (!isSupported()) {
+ return;
+ }
+
+ const form = document.querySelector('.js-saas-trial-group');
+ form.addEventListener('submit', () => {
+ pushEvent('saasTrialGroup');
+ });
+};
+
+export const trackSaasTrialProject = () => {
+ if (!isSupported()) {
+ return;
+ }
+
+ const form = document.getElementById('new_project');
+ form.addEventListener('submit', () => {
+ pushEvent('saasTrialProject');
+ });
+};
+
+export const trackSaasTrialProjectImport = () => {
+ if (!isSupported()) {
+ return;
+ }
+
+ const importButtons = document.querySelectorAll('.js-import-project-btn');
+ importButtons.forEach((button) => {
+ button.addEventListener('click', () => {
+ const { platform } = button.dataset;
+ pushEvent('saasTrialProjectImport', { saasProjectImport: platform });
+ });
+ });
+};
+
+export const trackSaasTrialGetStarted = () => {
+ if (!isSupported()) {
+ return;
+ }
+
+ const getStartedButton = document.querySelector('.js-get-started-btn');
+ getStartedButton.addEventListener('click', () => {
+ pushEvent('saasTrialGetStarted');
+ });
+};
diff --git a/app/assets/javascripts/graphql_shared/fragment_types/vulnerability_location_types.js b/app/assets/javascripts/graphql_shared/fragment_types/vulnerability_location_types.js
new file mode 100644
index 00000000000..30888e20a46
--- /dev/null
+++ b/app/assets/javascripts/graphql_shared/fragment_types/vulnerability_location_types.js
@@ -0,0 +1,17 @@
+export const vulnerabilityLocationTypes = {
+ __schema: {
+ types: [
+ {
+ kind: 'UNION',
+ name: 'VulnerabilityLocation',
+ possibleTypes: [
+ { name: 'VulnerabilityLocationContainerScanning' },
+ { name: 'VulnerabilityLocationDast' },
+ { name: 'VulnerabilityLocationDependencyScanning' },
+ { name: 'VulnerabilityLocationSast' },
+ { name: 'VulnerabilityLocationSecretDetection' },
+ ],
+ },
+ ],
+ },
+};
diff --git a/app/assets/javascripts/graphql_shared/fragments/issue.fragment.graphql b/app/assets/javascripts/graphql_shared/fragments/issue.fragment.graphql
new file mode 100644
index 00000000000..85a28fe1f71
--- /dev/null
+++ b/app/assets/javascripts/graphql_shared/fragments/issue.fragment.graphql
@@ -0,0 +1,37 @@
+#import "~/graphql_shared/fragments/milestone.fragment.graphql"
+#import "~/graphql_shared/fragments/user.fragment.graphql"
+
+fragment IssueNode on Issue {
+ id
+ iid
+ title
+ referencePath: reference(full: true)
+ dueDate
+ timeEstimate
+ totalTimeSpent
+ humanTimeEstimate
+ humanTotalTimeSpent
+ emailsDisabled
+ confidential
+ hidden
+ webUrl
+ relativePosition
+ type
+ severity
+ milestone {
+ ...MilestoneFragment
+ }
+ assignees {
+ nodes {
+ ...User
+ }
+ }
+ labels {
+ nodes {
+ id
+ title
+ color
+ description
+ }
+ }
+}
diff --git a/app/assets/javascripts/group.js b/app/assets/javascripts/group.js
index f255f8a084c..b6a6720e7a1 100644
--- a/app/assets/javascripts/group.js
+++ b/app/assets/javascripts/group.js
@@ -13,11 +13,8 @@ export default class Group {
this.updateGroupPathSlugHandler = this.updateGroupPathSlug.bind(this);
this.groupNames.forEach((groupName) => {
- if (groupName.value === '') {
- groupName.addEventListener('keyup', this.updateHandler);
-
- groupName.addEventListener('keyup', this.updateGroupPathSlugHandler);
- }
+ groupName.addEventListener('keyup', this.updateHandler);
+ groupName.addEventListener('keyup', this.updateGroupPathSlugHandler);
});
this.groupPaths.forEach((groupPath) => {
diff --git a/app/assets/javascripts/groups/components/item_stats.vue b/app/assets/javascripts/groups/components/item_stats.vue
index 46e9d2bec99..c24eeed9f03 100644
--- a/app/assets/javascripts/groups/components/item_stats.vue
+++ b/app/assets/javascripts/groups/components/item_stats.vue
@@ -83,7 +83,7 @@ export default {
<gl-badge variant="warning">{{ __('pending deletion') }}</gl-badge>
</div>
<div v-if="isProject" class="last-updated">
- <time-ago-tooltip :time="item.updatedAt" tooltip-placement="bottom" />
+ <time-ago-tooltip :time="item.lastActivityAt" tooltip-placement="bottom" />
</div>
</div>
</template>
diff --git a/app/assets/javascripts/groups/groups_list.js b/app/assets/javascripts/groups/groups_list.js
new file mode 100644
index 00000000000..866dd7a61ff
--- /dev/null
+++ b/app/assets/javascripts/groups/groups_list.js
@@ -0,0 +1,18 @@
+import FilterableList from '~/filterable_list';
+
+/**
+ * Makes search request for groups when user types a value in the search input.
+ * Updates the html content of the page with the received one.
+ */
+export default class GroupsList {
+ constructor() {
+ const form = document.querySelector('form#group-filter-form');
+ const filter = document.querySelector('.js-groups-list-filter');
+ const holder = document.querySelector('.js-groups-list-holder');
+
+ if (form && filter && holder) {
+ const list = new FilterableList(form, filter, holder);
+ list.initSearch();
+ }
+ }
+}
diff --git a/app/assets/javascripts/landing.js b/app/assets/javascripts/groups/landing.js
index bfb4d9ce67b..bfb4d9ce67b 100644
--- a/app/assets/javascripts/landing.js
+++ b/app/assets/javascripts/groups/landing.js
diff --git a/app/assets/javascripts/groups/store/groups_store.js b/app/assets/javascripts/groups/store/groups_store.js
index 93fbd8be47d..d3600bd223a 100644
--- a/app/assets/javascripts/groups/store/groups_store.js
+++ b/app/assets/javascripts/groups/store/groups_store.js
@@ -98,6 +98,9 @@ export default class GroupsStore {
updatedAt: rawGroupItem.updated_at,
pendingRemoval: rawGroupItem.marked_for_deletion,
microdata: this.showSchemaMarkup ? getGroupItemMicrodata(rawGroupItem) : {},
+ lastActivityAt: rawGroupItem.last_activity_at
+ ? rawGroupItem.last_activity_at
+ : rawGroupItem.updated_at,
};
if (!isEmpty(rawGroupItem.compliance_management_framework)) {
diff --git a/app/assets/javascripts/transfer_edit.js b/app/assets/javascripts/groups/transfer_edit.js
index bb15e11fd4c..bb15e11fd4c 100644
--- a/app/assets/javascripts/transfer_edit.js
+++ b/app/assets/javascripts/groups/transfer_edit.js
diff --git a/app/assets/javascripts/groups_list.js b/app/assets/javascripts/groups_list.js
deleted file mode 100644
index 56a8cbf6d03..00000000000
--- a/app/assets/javascripts/groups_list.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import FilterableList from './filterable_list';
-
-/**
- * Makes search request for groups when user types a value in the search input.
- * Updates the html content of the page with the received one.
- */
-export default class GroupsList {
- constructor() {
- const form = document.querySelector('form#group-filter-form');
- const filter = document.querySelector('.js-groups-list-filter');
- const holder = document.querySelector('.js-groups-list-holder');
-
- if (form && filter && holder) {
- const list = new FilterableList(form, filter, holder);
- list.initSearch();
- }
- }
-}
diff --git a/app/assets/javascripts/header_search/components/app.vue b/app/assets/javascripts/header_search/components/app.vue
index edc6573a489..36fc48a2ba8 100644
--- a/app/assets/javascripts/header_search/components/app.vue
+++ b/app/assets/javascripts/header_search/components/app.vue
@@ -19,8 +19,7 @@ import HeaderSearchScopedItems from './header_search_scoped_items.vue';
export default {
name: 'HeaderSearchApp',
i18n: {
- searchPlaceholder: s__('GlobalSearch|Search or jump to...'),
- searchAria: s__('GlobalSearch|Search GitLab'),
+ searchGitlab: s__('GlobalSearch|Search GitLab'),
searchInputDescribeByNoDropdown: s__(
'GlobalSearch|Type and press the enter key to submit search.',
),
@@ -136,7 +135,7 @@ export default {
<form
v-outside="closeDropdown"
role="search"
- :aria-label="$options.i18n.searchAria"
+ :aria-label="$options.i18n.searchGitlab"
class="header-search gl-relative"
>
<gl-search-box-by-type
@@ -145,7 +144,7 @@ export default {
role="searchbox"
class="gl-z-index-1"
autocomplete="off"
- :placeholder="$options.i18n.searchPlaceholder"
+ :placeholder="$options.i18n.searchGitlab"
:aria-activedescendant="currentFocusedId"
:aria-describedby="$options.SEARCH_INPUT_DESCRIPTION"
@focus="openDropdown"
diff --git a/app/assets/javascripts/helpers/event_hub_factory.js b/app/assets/javascripts/helpers/event_hub_factory.js
index 62af67d3ef3..ddfae7e9de3 100644
--- a/app/assets/javascripts/helpers/event_hub_factory.js
+++ b/app/assets/javascripts/helpers/event_hub_factory.js
@@ -1,16 +1,12 @@
/**
* An event hub with a Vue instance like API
*
- * NOTE: There's an [issue open][4] to eventually remove this when some
- * coupling in our codebase has been fixed.
- *
* NOTE: This is a derivative work from [mitt][1] v1.2.0 which is licensed by
* [MIT License][2] © [Jason Miller][3]
*
* [1]: https://github.com/developit/mitt
* [2]: https://opensource.org/licenses/MIT
* [3]: https://jasonformat.com/
- * [4]: https://gitlab.com/gitlab-org/gitlab/-/issues/223864
*/
class EventHub {
constructor() {
@@ -91,9 +87,6 @@ class EventHub {
* - $once
* - $emit
*
- * Please note, this was once implemented with `mitt`, but since then has been reverted
- * because of some API issues. https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35074
- *
* We'd like to shy away from using a full fledged Vue instance from this in the future.
*/
export default () => {
diff --git a/app/assets/javascripts/ide/components/jobs/stage.vue b/app/assets/javascripts/ide/components/jobs/stage.vue
index 938385f0b81..796ca1349c5 100644
--- a/app/assets/javascripts/ide/components/jobs/stage.vue
+++ b/app/assets/javascripts/ide/components/jobs/stage.vue
@@ -1,5 +1,5 @@
<script>
-import { GlLoadingIcon, GlIcon, GlTooltipDirective } from '@gitlab/ui';
+import { GlLoadingIcon, GlIcon, GlTooltipDirective, GlBadge } from '@gitlab/ui';
import CiIcon from '../../../vue_shared/components/ci_icon.vue';
import Item from './item.vue';
@@ -9,6 +9,7 @@ export default {
},
components: {
GlIcon,
+ GlBadge,
CiIcon,
Item,
GlLoadingIcon,
@@ -74,7 +75,7 @@ export default {
{{ stage.name }}
</strong>
<div v-if="!stage.isLoading || stage.jobs.length" class="gl-mr-3 gl-ml-2">
- <span class="badge badge-pill"> {{ jobsCount }} </span>
+ <gl-badge>{{ jobsCount }}</gl-badge>
</div>
<gl-icon :name="collapseIcon" class="ide-stage-collapse-icon" />
</div>
diff --git a/app/assets/javascripts/ide/stores/modules/pipelines/actions.js b/app/assets/javascripts/ide/stores/modules/pipelines/actions.js
index 9cf8d5a360e..51872993f16 100644
--- a/app/assets/javascripts/ide/stores/modules/pipelines/actions.js
+++ b/app/assets/javascripts/ide/stores/modules/pipelines/actions.js
@@ -53,9 +53,15 @@ export const receiveLatestPipelineSuccess = ({ rootGetters, commit }, { pipeline
commit(types.RECEIVE_LASTEST_PIPELINE_SUCCESS, lastCommitPipeline);
};
-export const fetchLatestPipeline = ({ dispatch, rootGetters }) => {
+export const fetchLatestPipeline = ({ commit, dispatch, rootGetters }) => {
if (eTagPoll) return;
+ if (!rootGetters.lastCommit) {
+ commit(types.RECEIVE_LASTEST_PIPELINE_SUCCESS, null);
+ dispatch('stopPipelinePolling');
+ return;
+ }
+
dispatch('requestLatestPipeline');
eTagPoll = new Poll({
diff --git a/app/assets/javascripts/init_confirm_danger.js b/app/assets/javascripts/init_confirm_danger.js
index a8833a17467..98bfa48740c 100644
--- a/app/assets/javascripts/init_confirm_danger.js
+++ b/app/assets/javascripts/init_confirm_danger.js
@@ -1,4 +1,5 @@
import Vue from 'vue';
+import { pickBy } from 'lodash';
import { parseBoolean } from './lib/utils/common_utils';
import ConfirmDanger from './vue_shared/components/confirm_danger/confirm_danger.vue';
@@ -12,21 +13,32 @@ export default () => {
buttonText,
buttonClass = '',
buttonTestid = null,
+ buttonVariant = null,
confirmDangerMessage,
+ confirmButtonText = null,
disabled = false,
+ additionalInformation,
+ htmlConfirmationMessage,
} = el.dataset;
return new Vue({
el,
- provide: {
- confirmDangerMessage,
- },
+ provide: pickBy(
+ {
+ htmlConfirmationMessage,
+ confirmDangerMessage,
+ additionalInformation,
+ confirmButtonText,
+ },
+ (v) => Boolean(v),
+ ),
render: (createElement) =>
createElement(ConfirmDanger, {
props: {
phrase,
buttonText,
buttonClass,
+ buttonVariant,
buttonTestid,
disabled: parseBoolean(disabled),
},
diff --git a/app/assets/javascripts/integrations/constants.js b/app/assets/javascripts/integrations/constants.js
index 84656bd41bb..b90658fb13c 100644
--- a/app/assets/javascripts/integrations/constants.js
+++ b/app/assets/javascripts/integrations/constants.js
@@ -23,3 +23,8 @@ export const I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE = s__(
);
export const I18N_DEFAULT_ERROR_MESSAGE = __('Something went wrong on our end.');
export const I18N_SUCCESSFUL_CONNECTION_MESSAGE = s__('Integrations|Connection successful.');
+
+export const settingsTabTitle = __('Settings');
+export const overridesTabTitle = s__('Integrations|Projects using custom settings');
+
+export const INTEGRATION_FORM_SELECTOR = '.js-integration-settings-form';
diff --git a/app/assets/javascripts/integrations/edit/components/dynamic_field.vue b/app/assets/javascripts/integrations/edit/components/dynamic_field.vue
index 258cd1bf365..4b0579a5beb 100644
--- a/app/assets/javascripts/integrations/edit/components/dynamic_field.vue
+++ b/app/assets/javascripts/integrations/edit/components/dynamic_field.vue
@@ -153,7 +153,7 @@ export default {
:invalid-feedback="__('This field is required.')"
:state="valid"
>
- <template #description>
+ <template v-if="!isCheckbox" #description>
<span v-safe-html:[$options.helpHtmlConfig]="help"></span>
</template>
@@ -161,6 +161,9 @@ export default {
<input :name="fieldName" type="hidden" :value="model || false" />
<gl-form-checkbox :id="fieldId" v-model="model" :disabled="isInheriting">
{{ checkboxLabel || humanizedTitle }}
+ <template #help>
+ <span v-safe-html:[$options.helpHtmlConfig]="help"></span>
+ </template>
</gl-form-checkbox>
</template>
<template v-else-if="isSelect">
diff --git a/app/assets/javascripts/integrations/edit/components/integration_form.vue b/app/assets/javascripts/integrations/edit/components/integration_form.vue
index e570a468944..c3cc35adfa5 100644
--- a/app/assets/javascripts/integrations/edit/components/integration_form.vue
+++ b/app/assets/javascripts/integrations/edit/components/integration_form.vue
@@ -1,5 +1,6 @@
<script>
-import { GlButton, GlModalDirective, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
+import { GlButton, GlModalDirective, GlSafeHtmlDirective as SafeHtml, GlForm } from '@gitlab/ui';
+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';
@@ -8,8 +9,11 @@ import {
I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE,
I18N_DEFAULT_ERROR_MESSAGE,
I18N_SUCCESSFUL_CONNECTION_MESSAGE,
+ INTEGRATION_FORM_SELECTOR,
integrationLevels,
} from '~/integrations/constants';
+import { refreshCurrentPage } from '~/lib/utils/url_utility';
+import csrf from '~/lib/utils/csrf';
import eventHub from '../event_hub';
import { testIntegrationSettings } from '../api';
import ActiveCheckbox from './active_checkbox.vue';
@@ -33,6 +37,7 @@ export default {
ConfirmationModal,
ResetConfirmationModal,
GlButton,
+ GlForm,
},
directives: {
GlModal: GlModalDirective,
@@ -40,10 +45,6 @@ export default {
},
mixins: [glFeatureFlagsMixin()],
props: {
- formSelector: {
- type: String,
- required: true,
- },
helpHtml: {
type: String,
required: false,
@@ -55,11 +56,12 @@ export default {
integrationActive: false,
isTesting: false,
isSaving: false,
+ isResetting: false,
};
},
computed: {
...mapGetters(['currentKey', 'propsSource']),
- ...mapState(['defaultState', 'customState', 'override', 'isResetting']),
+ ...mapState(['defaultState', 'customState', 'override']),
isEditable() {
return this.propsSource.editable;
},
@@ -81,10 +83,28 @@ export default {
disableButtons() {
return Boolean(this.isSaving || this.isResetting || this.isTesting);
},
+ useVueForm() {
+ return this.glFeatures?.vueIntegrationForm;
+ },
+ formContainerProps() {
+ return this.useVueForm
+ ? {
+ ref: 'integrationForm',
+ method: 'post',
+ class: 'gl-mb-3 gl-show-field-errors integration-settings-form',
+ action: this.propsSource.formPath,
+ novalidate: !this.integrationActive,
+ }
+ : {};
+ },
+ formContainer() {
+ return this.useVueForm ? GlForm : 'div';
+ },
},
mounted() {
- // this form element is defined in Haml
- this.form = document.querySelector(this.formSelector);
+ this.form = this.useVueForm
+ ? this.$refs.integrationForm.$el
+ : document.querySelector(INTEGRATION_FORM_SELECTOR);
},
methods: {
...mapActions(['setOverride', 'fetchResetIntegration', 'requestJiraIssueTypes']),
@@ -126,7 +146,20 @@ export default {
});
},
onResetClick() {
- this.fetchResetIntegration();
+ this.isResetting = true;
+
+ return axios
+ .post(this.propsSource.resetPath)
+ .then(() => {
+ refreshCurrentPage();
+ })
+ .catch((error) => {
+ this.$toast.show(I18N_DEFAULT_ERROR_MESSAGE);
+ Sentry.captureException(error);
+ })
+ .finally(() => {
+ this.isResetting = false;
+ });
},
onRequestJiraIssueTypes() {
this.requestJiraIssueTypes(this.getFormData());
@@ -136,7 +169,7 @@ export default {
},
onToggleIntegrationState(integrationActive) {
this.integrationActive = integrationActive;
- if (!this.form) {
+ if (!this.form || this.useVueForm) {
return;
}
@@ -153,11 +186,23 @@ export default {
ADD_TAGS: ['use'], // to support icon SVGs
FORBID_ATTR: [], // This is trusted input so we can override the default config to allow data-* attributes
},
+ csrf,
};
</script>
<template>
- <div class="gl-mb-3">
+ <component :is="formContainer" v-bind="formContainerProps">
+ <template v-if="useVueForm">
+ <input type="hidden" name="_method" value="put" />
+ <input type="hidden" name="authenticity_token" :value="$options.csrf.token" />
+ <input
+ type="hidden"
+ name="redirect_to"
+ :value="propsSource.redirectTo"
+ data-testid="redirect-to-field"
+ />
+ </template>
+
<override-dropdown
v-if="defaultState !== null"
:inherit-from-id="defaultState.id"
@@ -200,63 +245,71 @@ export default {
v-bind="propsSource.jiraIssuesProps"
@request-jira-issue-types="onRequestJiraIssueTypes"
/>
- <div v-if="isEditable" class="footer-block row-content-block">
- <template v-if="isInstanceOrGroupLevel">
+
+ <div
+ v-if="isEditable"
+ class="footer-block row-content-block gl-display-flex gl-justify-content-space-between"
+ >
+ <div>
+ <template v-if="isInstanceOrGroupLevel">
+ <gl-button
+ v-gl-modal.confirmSaveIntegration
+ category="primary"
+ variant="confirm"
+ :loading="isSaving"
+ :disabled="disableButtons"
+ data-testid="save-button-instance-group"
+ data-qa-selector="save_changes_button"
+ >
+ {{ __('Save changes') }}
+ </gl-button>
+ <confirmation-modal @submit="onSaveClick" />
+ </template>
<gl-button
- v-gl-modal.confirmSaveIntegration
+ v-else
category="primary"
variant="confirm"
+ type="submit"
:loading="isSaving"
:disabled="disableButtons"
+ data-testid="save-button"
data-qa-selector="save_changes_button"
+ @click.prevent="onSaveClick"
>
{{ __('Save changes') }}
</gl-button>
- <confirmation-modal @submit="onSaveClick" />
- </template>
- <gl-button
- v-else
- category="primary"
- variant="confirm"
- type="submit"
- :loading="isSaving"
- :disabled="disableButtons"
- data-testid="save-button"
- data-qa-selector="save_changes_button"
- @click.prevent="onSaveClick"
- >
- {{ __('Save changes') }}
- </gl-button>
- <gl-button
- v-if="showTestButton"
- category="secondary"
- variant="confirm"
- :loading="isTesting"
- :disabled="disableButtons"
- data-testid="test-button"
- @click.prevent="onTestClick"
- >
- {{ __('Test settings') }}
- </gl-button>
+ <gl-button
+ v-if="showTestButton"
+ category="secondary"
+ variant="confirm"
+ :loading="isTesting"
+ :disabled="disableButtons"
+ data-testid="test-button"
+ @click.prevent="onTestClick"
+ >
+ {{ __('Test settings') }}
+ </gl-button>
+
+ <gl-button :href="propsSource.cancelPath">{{ __('Cancel') }}</gl-button>
+ </div>
<template v-if="showResetButton">
<gl-button
v-gl-modal.confirmResetIntegration
- category="secondary"
- variant="confirm"
+ category="tertiary"
+ variant="danger"
:loading="isResetting"
:disabled="disableButtons"
data-testid="reset-button"
>
{{ __('Reset') }}
</gl-button>
+
<reset-confirmation-modal @reset="onResetClick" />
</template>
-
- <gl-button :href="propsSource.cancelPath">{{ __('Cancel') }}</gl-button>
</div>
</div>
</div>
- </div>
+ </component>
</template>
diff --git a/app/assets/javascripts/integrations/edit/components/reset_confirmation_modal.vue b/app/assets/javascripts/integrations/edit/components/reset_confirmation_modal.vue
index 5a445235219..403bad3db11 100644
--- a/app/assets/javascripts/integrations/edit/components/reset_confirmation_modal.vue
+++ b/app/assets/javascripts/integrations/edit/components/reset_confirmation_modal.vue
@@ -11,7 +11,7 @@ export default {
primaryProps() {
return {
text: __('Reset'),
- attributes: [{ variant: 'warning' }, { category: 'primary' }],
+ attributes: [{ variant: 'danger' }, { category: 'primary' }],
};
},
cancelProps() {
diff --git a/app/assets/javascripts/integrations/edit/index.js b/app/assets/javascripts/integrations/edit/index.js
index 9c9e3edbeb8..fbda8c1e3d0 100644
--- a/app/assets/javascripts/integrations/edit/index.js
+++ b/app/assets/javascripts/integrations/edit/index.js
@@ -28,9 +28,11 @@ function parseDatasetToProps(data) {
cancelPath,
testPath,
resetPath,
+ formPath,
vulnerabilitiesIssuetype,
jiraIssueTransitionAutomatic,
jiraIssueTransitionId,
+ redirectTo,
...booleanAttributes
} = data;
const {
@@ -57,6 +59,7 @@ function parseDatasetToProps(data) {
canTest,
testPath,
resetPath,
+ formPath,
triggerFieldsProps: {
initialTriggerCommit: commitEvents,
initialTriggerMergeRequest: mergeRequestEvents,
@@ -82,10 +85,11 @@ function parseDatasetToProps(data) {
inheritFromId: parseInt(inheritFromId, 10),
integrationLevel,
id: parseInt(id, 10),
+ redirectTo,
};
}
-export default function initIntegrationSettingsForm(formSelector) {
+export default function initIntegrationSettingsForm() {
const customSettingsEl = document.querySelector('.js-vue-integration-settings');
const defaultSettingsEl = document.querySelector('.js-vue-default-integration-settings');
@@ -115,7 +119,6 @@ export default function initIntegrationSettingsForm(formSelector) {
return createElement(IntegrationForm, {
props: {
helpHtml,
- formSelector,
},
});
},
diff --git a/app/assets/javascripts/integrations/edit/store/actions.js b/app/assets/javascripts/integrations/edit/store/actions.js
index 97565a3a69c..1398b710d1d 100644
--- a/app/assets/javascripts/integrations/edit/store/actions.js
+++ b/app/assets/javascripts/integrations/edit/store/actions.js
@@ -1,5 +1,3 @@
-import axios from 'axios';
-import { refreshCurrentPage } from '~/lib/utils/url_utility';
import {
VALIDATE_INTEGRATION_FORM_EVENT,
I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE,
@@ -10,27 +8,6 @@ import eventHub from '../event_hub';
import * as types from './mutation_types';
export const setOverride = ({ commit }, override) => commit(types.SET_OVERRIDE, override);
-export const setIsResetting = ({ commit }, isResetting) =>
- commit(types.SET_IS_RESETTING, isResetting);
-
-export const requestResetIntegration = ({ commit }) => {
- commit(types.REQUEST_RESET_INTEGRATION);
-};
-export const receiveResetIntegrationSuccess = () => {
- refreshCurrentPage();
-};
-export const receiveResetIntegrationError = ({ commit }) => {
- commit(types.RECEIVE_RESET_INTEGRATION_ERROR);
-};
-
-export const fetchResetIntegration = ({ dispatch, getters }) => {
- dispatch('requestResetIntegration');
-
- return axios
- .post(getters.propsSource.resetPath, { params: { format: 'json' } })
- .then(() => dispatch('receiveResetIntegrationSuccess'))
- .catch(() => dispatch('receiveResetIntegrationError'));
-};
export const requestJiraIssueTypes = ({ commit, dispatch, getters }, formData) => {
commit(types.SET_JIRA_ISSUE_TYPES_ERROR_MESSAGE, '');
diff --git a/app/assets/javascripts/integrations/edit/store/mutations.js b/app/assets/javascripts/integrations/edit/store/mutations.js
index e7e312ce650..6ca644f8821 100644
--- a/app/assets/javascripts/integrations/edit/store/mutations.js
+++ b/app/assets/javascripts/integrations/edit/store/mutations.js
@@ -4,15 +4,6 @@ export default {
[types.SET_OVERRIDE](state, override) {
state.override = override;
},
- [types.SET_IS_RESETTING](state, isResetting) {
- state.isResetting = isResetting;
- },
- [types.REQUEST_RESET_INTEGRATION](state) {
- state.isResetting = true;
- },
- [types.RECEIVE_RESET_INTEGRATION_ERROR](state) {
- state.isResetting = false;
- },
[types.SET_JIRA_ISSUE_TYPES](state, jiraIssueTypes) {
state.jiraIssueTypes = jiraIssueTypes;
},
diff --git a/app/assets/javascripts/integrations/edit/store/state.js b/app/assets/javascripts/integrations/edit/store/state.js
index 3d40d1b90d5..088476b2b37 100644
--- a/app/assets/javascripts/integrations/edit/store/state.js
+++ b/app/assets/javascripts/integrations/edit/store/state.js
@@ -5,8 +5,6 @@ export default ({ defaultState = null, customState = {} } = {}) => {
override,
defaultState,
customState,
- isSaving: false,
- isResetting: false,
isLoadingJiraIssueTypes: false,
loadingJiraIssueTypesErrorMessage: '',
jiraIssueTypes: [],
diff --git a/app/assets/javascripts/integrations/overrides/components/integration_overrides.vue b/app/assets/javascripts/integrations/overrides/components/integration_overrides.vue
index 3fc554c5371..f2d3e6489ee 100644
--- a/app/assets/javascripts/integrations/overrides/components/integration_overrides.vue
+++ b/app/assets/javascripts/integrations/overrides/components/integration_overrides.vue
@@ -11,6 +11,8 @@ import { __, s__ } from '~/locale';
import ProjectAvatar from '~/vue_shared/components/project_avatar.vue';
import UrlSync from '~/vue_shared/components/url_sync.vue';
+import IntegrationTabs from './integration_tabs.vue';
+
const DEFAULT_PAGE = 1;
export default {
@@ -23,6 +25,7 @@ export default {
GlAlert,
ProjectAvatar,
UrlSync,
+ IntegrationTabs,
},
props: {
overridesPath: {
@@ -46,6 +49,9 @@ export default {
};
},
computed: {
+ overridesCount() {
+ return this.isLoading ? null : this.totalItems;
+ },
showPagination() {
return this.totalItems > this.$options.DEFAULT_PER_PAGE && this.overrides.length > 0;
},
@@ -100,6 +106,7 @@ export default {
<template>
<div>
+ <integration-tabs :project-overrides-count="overridesCount" />
<gl-alert v-if="errorMessage" variant="danger" :dismissible="false">
{{ errorMessage }}
</gl-alert>
diff --git a/app/assets/javascripts/integrations/overrides/components/integration_tabs.vue b/app/assets/javascripts/integrations/overrides/components/integration_tabs.vue
new file mode 100644
index 00000000000..3f67c987231
--- /dev/null
+++ b/app/assets/javascripts/integrations/overrides/components/integration_tabs.vue
@@ -0,0 +1,52 @@
+<script>
+import { GlBadge, GlNavItem, GlTabs, GlTab } from '@gitlab/ui';
+import { settingsTabTitle, overridesTabTitle } from '~/integrations/constants';
+
+export default {
+ components: {
+ GlBadge,
+ GlNavItem,
+ GlTabs,
+ GlTab,
+ },
+ inject: {
+ editPath: {
+ default: '',
+ },
+ },
+ props: {
+ projectOverridesCount: {
+ type: [Number, String],
+ required: false,
+ default: null,
+ },
+ },
+ i18n: {
+ settingsTabTitle,
+ overridesTabTitle,
+ },
+};
+</script>
+
+<template>
+ <gl-tabs>
+ <template #tabs-start>
+ <gl-nav-item role="presentation" link-classes="gl-tab-nav-item" :href="editPath">{{
+ $options.i18n.settingsTabTitle
+ }}</gl-nav-item>
+ </template>
+
+ <gl-tab active>
+ <template #title>
+ {{ $options.i18n.overridesTabTitle }}
+ <gl-badge
+ v-if="projectOverridesCount !== null"
+ variant="muted"
+ size="sm"
+ class="gl-tab-counter-badge"
+ >{{ projectOverridesCount }}</gl-badge
+ >
+ </template>
+ </gl-tab>
+ </gl-tabs>
+</template>
diff --git a/app/assets/javascripts/integrations/overrides/index.js b/app/assets/javascripts/integrations/overrides/index.js
index 0f03b23ba21..f289a2d3d1a 100644
--- a/app/assets/javascripts/integrations/overrides/index.js
+++ b/app/assets/javascripts/integrations/overrides/index.js
@@ -8,10 +8,13 @@ export default () => {
return null;
}
- const { overridesPath } = el.dataset;
+ const { editPath, overridesPath } = el.dataset;
return new Vue({
el,
+ provide: {
+ editPath,
+ },
render(createElement) {
return createElement(IntegrationOverrides, {
props: {
diff --git a/app/assets/javascripts/issuable/bulk_update_sidebar/index.js b/app/assets/javascripts/issuable/bulk_update_sidebar/index.js
new file mode 100644
index 00000000000..dca606556d0
--- /dev/null
+++ b/app/assets/javascripts/issuable/bulk_update_sidebar/index.js
@@ -0,0 +1,28 @@
+import Vue from 'vue';
+import StatusSelect from './components/status_select.vue';
+import issuableBulkUpdateActions from './issuable_bulk_update_actions';
+import IssuableBulkUpdateSidebar from './issuable_bulk_update_sidebar';
+
+export function initBulkUpdateSidebar(prefixId) {
+ const el = document.querySelector('.issues-bulk-update');
+
+ if (!el) {
+ return;
+ }
+
+ issuableBulkUpdateActions.init({ prefixId });
+ new IssuableBulkUpdateSidebar(); // eslint-disable-line no-new
+}
+
+export function initIssueStatusSelect() {
+ const el = document.querySelector('.js-issue-status');
+
+ if (!el) {
+ return null;
+ }
+
+ return new Vue({
+ el,
+ render: (createElement) => createElement(StatusSelect),
+ });
+}
diff --git a/app/assets/javascripts/issuable/bulk_update_sidebar/init_issue_status_select.js b/app/assets/javascripts/issuable/bulk_update_sidebar/init_issue_status_select.js
deleted file mode 100644
index 43179a86d70..00000000000
--- a/app/assets/javascripts/issuable/bulk_update_sidebar/init_issue_status_select.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import Vue from 'vue';
-import StatusSelect from './components/status_select.vue';
-
-export default function initIssueStatusSelect() {
- const el = document.querySelector('.js-issue-status');
-
- if (!el) {
- return null;
- }
-
- return new Vue({
- el,
- render(h) {
- return h(StatusSelect);
- },
- });
-}
diff --git a/app/assets/javascripts/issuable/bulk_update_sidebar/issuable_bulk_update_sidebar.js b/app/assets/javascripts/issuable/bulk_update_sidebar/issuable_bulk_update_sidebar.js
index 1eb3ffc9808..d46354e240a 100644
--- a/app/assets/javascripts/issuable/bulk_update_sidebar/issuable_bulk_update_sidebar.js
+++ b/app/assets/javascripts/issuable/bulk_update_sidebar/issuable_bulk_update_sidebar.js
@@ -1,12 +1,9 @@
/* eslint-disable class-methods-use-this, no-new */
import $ from 'jquery';
-import { property } from 'lodash';
-
-import issuableEventHub from '~/issues_list/eventhub';
+import issuableEventHub from '~/issues/list/eventhub';
import LabelsSelect from '~/labels/labels_select';
import MilestoneSelect from '~/milestones/milestone_select';
-import initIssueStatusSelect from './init_issue_status_select';
import IssuableBulkUpdateActions from './issuable_bulk_update_actions';
import subscriptionSelect from './subscription_select';
@@ -17,8 +14,6 @@ const SIDEBAR_COLLAPSED_CLASS = 'right-sidebar-collapsed issuable-bulk-update-si
export default class IssuableBulkUpdateSidebar {
constructor() {
- this.vueIssuablesListFeature = property(['gon', 'features', 'vueIssuablesList'])(window);
-
this.initDomElements();
this.bindEvents();
this.initDropdowns();
@@ -57,7 +52,6 @@ export default class IssuableBulkUpdateSidebar {
initDropdowns() {
new LabelsSelect();
new MilestoneSelect();
- initIssueStatusSelect();
subscriptionSelect();
if (IS_EE) {
@@ -145,7 +139,7 @@ export default class IssuableBulkUpdateSidebar {
}
toggleCheckboxDisplay(show) {
- this.$checkAllContainer.toggleClass(HIDDEN_CLASS, !show || this.vueIssuablesListFeature);
+ this.$checkAllContainer.toggleClass(HIDDEN_CLASS, !show);
this.$issueChecks.toggleClass(HIDDEN_CLASS, !show);
}
diff --git a/app/assets/javascripts/issuable/bulk_update_sidebar/issuable_init_bulk_update_sidebar.js b/app/assets/javascripts/issuable/bulk_update_sidebar/issuable_init_bulk_update_sidebar.js
deleted file mode 100644
index 179c2b83c6c..00000000000
--- a/app/assets/javascripts/issuable/bulk_update_sidebar/issuable_init_bulk_update_sidebar.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import issuableBulkUpdateActions from './issuable_bulk_update_actions';
-import IssuableBulkUpdateSidebar from './issuable_bulk_update_sidebar';
-
-export default {
- bulkUpdateSidebar: null,
-
- init(prefixId) {
- const bulkUpdateEl = document.querySelector('.issues-bulk-update');
- const alreadyInitialized = Boolean(this.bulkUpdateSidebar);
-
- if (bulkUpdateEl && !alreadyInitialized) {
- issuableBulkUpdateActions.init({ prefixId });
-
- this.bulkUpdateSidebar = new IssuableBulkUpdateSidebar();
- }
-
- return this.bulkUpdateSidebar;
- },
-};
diff --git a/app/assets/javascripts/issuable/components/csv_import_modal.vue b/app/assets/javascripts/issuable/components/csv_import_modal.vue
index b72abe14ee1..7e2cbf03801 100644
--- a/app/assets/javascripts/issuable/components/csv_import_modal.vue
+++ b/app/assets/javascripts/issuable/components/csv_import_modal.vue
@@ -60,7 +60,11 @@ export default {
<form ref="form" :action="importCsvIssuesPath" enctype="multipart/form-data" method="post">
<input :value="$options.csrf.token" type="hidden" name="authenticity_token" />
<p>{{ $options.i18n.mainText }}</p>
- <gl-form-group :label="$options.i18n.uploadCsvFileText" label-for="file">
+ <gl-form-group
+ :label="$options.i18n.uploadCsvFileText"
+ class="gl-text-truncate"
+ label-for="file"
+ >
<input id="file" type="file" name="file" accept=".csv,text/csv" />
</gl-form-group>
<p class="text-secondary">
diff --git a/app/assets/javascripts/issuable/index.js b/app/assets/javascripts/issuable/index.js
index 072422944f5..57bad5182e7 100644
--- a/app/assets/javascripts/issuable/index.js
+++ b/app/assets/javascripts/issuable/index.js
@@ -11,7 +11,9 @@ import IssuableHeaderWarnings from './components/issuable_header_warnings.vue';
export function initCsvImportExportButtons() {
const el = document.querySelector('.js-csv-import-export-buttons');
- if (!el) return null;
+ if (!el) {
+ return null;
+ }
const {
showExportButton,
@@ -42,23 +44,24 @@ export function initCsvImportExportButtons() {
maxAttachmentSize,
showLabel,
},
- render(h) {
- return h(CsvImportExportButtons, {
+ render: (createElement) =>
+ createElement(CsvImportExportButtons, {
props: {
exportCsvPath,
issuableCount: parseInt(issuableCount, 10),
},
- });
- },
+ }),
});
}
export function initIssuableByEmail() {
- Vue.use(GlToast);
-
const el = document.querySelector('.js-issuable-by-email');
- if (!el) return null;
+ if (!el) {
+ return null;
+ }
+
+ Vue.use(GlToast);
const {
initialEmail,
@@ -79,9 +82,7 @@ export function initIssuableByEmail() {
markdownHelpPath,
resetPath,
},
- render(h) {
- return h(IssuableByEmail);
- },
+ render: (createElement) => createElement(IssuableByEmail),
});
}
@@ -89,7 +90,7 @@ export function initIssuableHeaderWarnings(store) {
const el = document.getElementById('js-issuable-header-warnings');
if (!el) {
- return false;
+ return null;
}
const { hidden } = el.dataset;
@@ -98,18 +99,18 @@ export function initIssuableHeaderWarnings(store) {
el,
store,
provide: { hidden: parseBoolean(hidden) },
- render(createElement) {
- return createElement(IssuableHeaderWarnings);
- },
+ render: (createElement) => createElement(IssuableHeaderWarnings),
});
}
export function initIssuableSidebar() {
- const sidebarOptEl = document.querySelector('.js-sidebar-options');
+ const el = document.querySelector('.js-sidebar-options');
- if (!sidebarOptEl) return;
+ if (!el) {
+ return;
+ }
- const sidebarOptions = getSidebarOptions(sidebarOptEl);
+ const sidebarOptions = getSidebarOptions(el);
new IssuableContext(sidebarOptions.currentUser); // eslint-disable-line no-new
Sidebar.initialize();
diff --git a/app/assets/javascripts/issues/constants.js b/app/assets/javascripts/issues/constants.js
index b7b123dfd5f..4b9a42da178 100644
--- a/app/assets/javascripts/issues/constants.js
+++ b/app/assets/javascripts/issues/constants.js
@@ -19,6 +19,12 @@ export const IssuableType = {
Alert: 'alert',
};
+export const IssueType = {
+ Issue: 'issue',
+ Incident: 'incident',
+ TestCase: 'test_case',
+};
+
export const WorkspaceType = {
project: 'project',
group: 'group',
diff --git a/app/assets/javascripts/issues/create_merge_request_dropdown.js b/app/assets/javascripts/issues/create_merge_request_dropdown.js
new file mode 100644
index 00000000000..5d36396bc6e
--- /dev/null
+++ b/app/assets/javascripts/issues/create_merge_request_dropdown.js
@@ -0,0 +1,566 @@
+import { debounce } from 'lodash';
+import {
+ init as initConfidentialMergeRequest,
+ isConfidentialIssue,
+ canCreateConfidentialMergeRequest,
+} from '~/confidential_merge_request';
+import confidentialMergeRequestState from '~/confidential_merge_request/state';
+import DropLab from '~/filtered_search/droplab/drop_lab_deprecated';
+import ISetter from '~/filtered_search/droplab/plugins/input_setter';
+import createFlash from '~/flash';
+import axios from '~/lib/utils/axios_utils';
+import { __, sprintf } from '~/locale';
+
+// Todo: Remove this when fixing issue in input_setter plugin
+const InputSetter = { ...ISetter };
+
+const CREATE_MERGE_REQUEST = 'create-mr';
+const CREATE_BRANCH = 'create-branch';
+
+function createEndpoint(projectPath, endpoint) {
+ if (canCreateConfidentialMergeRequest()) {
+ return endpoint.replace(
+ projectPath,
+ confidentialMergeRequestState.selectedProject.pathWithNamespace,
+ );
+ }
+
+ return endpoint;
+}
+
+export default class CreateMergeRequestDropdown {
+ constructor(wrapperEl) {
+ this.wrapperEl = wrapperEl;
+ this.availableButton = this.wrapperEl.querySelector('.available');
+ this.branchInput = this.wrapperEl.querySelector('.js-branch-name');
+ this.branchMessage = this.wrapperEl.querySelector('.js-branch-message');
+ this.createMergeRequestButton = this.wrapperEl.querySelector('.js-create-merge-request');
+ this.createMergeRequestLoading = this.createMergeRequestButton.querySelector('.js-spinner');
+ this.createTargetButton = this.wrapperEl.querySelector('.js-create-target');
+ this.dropdownList = this.wrapperEl.querySelector('.dropdown-menu');
+ this.dropdownToggle = this.wrapperEl.querySelector('.js-dropdown-toggle');
+ this.refInput = this.wrapperEl.querySelector('.js-ref');
+ this.refMessage = this.wrapperEl.querySelector('.js-ref-message');
+ this.unavailableButton = this.wrapperEl.querySelector('.unavailable');
+ this.unavailableButtonSpinner = this.unavailableButton.querySelector('.gl-spinner');
+ this.unavailableButtonText = this.unavailableButton.querySelector('.text');
+
+ this.branchCreated = false;
+ this.branchIsValid = true;
+ this.canCreatePath = this.wrapperEl.dataset.canCreatePath;
+ this.createBranchPath = this.wrapperEl.dataset.createBranchPath;
+ this.createMrPath = this.wrapperEl.dataset.createMrPath;
+ this.droplabInitialized = false;
+ this.isCreatingBranch = false;
+ this.isCreatingMergeRequest = false;
+ this.isGettingRef = false;
+ this.refCancelToken = null;
+ this.mergeRequestCreated = false;
+ this.refDebounce = debounce((value, target) => this.getRef(value, target), 500);
+ this.refIsValid = true;
+ this.refsPath = this.wrapperEl.dataset.refsPath;
+ this.suggestedRef = this.refInput.value;
+ this.projectPath = this.wrapperEl.dataset.projectPath;
+ this.projectId = this.wrapperEl.dataset.projectId;
+
+ // These regexps are used to replace
+ // a backend generated new branch name and its source (ref)
+ // with user's inputs.
+ this.regexps = {
+ branch: {
+ createBranchPath: new RegExp('(branch_name=)(.+?)(?=&issue)'),
+ createMrPath: new RegExp('(branch_name=)(.+?)(?=&ref)'),
+ },
+ ref: {
+ createBranchPath: new RegExp('(ref=)(.+?)$'),
+ createMrPath: new RegExp('(ref=)(.+?)$'),
+ },
+ };
+
+ this.init();
+
+ if (isConfidentialIssue()) {
+ this.createMergeRequestButton.setAttribute(
+ 'data-dropdown-trigger',
+ '#create-merge-request-dropdown',
+ );
+ initConfidentialMergeRequest();
+ }
+ }
+
+ available() {
+ this.availableButton.classList.remove('hidden');
+ this.unavailableButton.classList.add('hidden');
+ }
+
+ bindEvents() {
+ this.createMergeRequestButton.addEventListener(
+ 'click',
+ this.onClickCreateMergeRequestButton.bind(this),
+ );
+ this.createTargetButton.addEventListener(
+ 'click',
+ this.onClickCreateMergeRequestButton.bind(this),
+ );
+ this.branchInput.addEventListener('input', this.onChangeInput.bind(this));
+ this.branchInput.addEventListener('keyup', this.onChangeInput.bind(this));
+ this.dropdownToggle.addEventListener('click', this.onClickSetFocusOnBranchNameInput.bind(this));
+ // Detect for example when user pastes ref using the mouse
+ this.refInput.addEventListener('input', this.onChangeInput.bind(this));
+ // Detect for example when user presses right arrow to apply the suggested ref
+ this.refInput.addEventListener('keyup', this.onChangeInput.bind(this));
+ // Detect when user clicks inside the input to apply the suggested ref
+ this.refInput.addEventListener('click', this.onChangeInput.bind(this));
+ // Detect when user clicks outside the input to apply the suggested ref
+ this.refInput.addEventListener('blur', this.onChangeInput.bind(this));
+ // Detect when user presses tab to apply the suggested ref
+ this.refInput.addEventListener('keydown', CreateMergeRequestDropdown.processTab.bind(this));
+ }
+
+ checkAbilityToCreateBranch() {
+ this.setUnavailableButtonState();
+
+ axios
+ .get(this.canCreatePath)
+ .then(({ data }) => {
+ this.setUnavailableButtonState(false);
+
+ if (data.can_create_branch) {
+ this.available();
+ this.enable();
+ this.updateBranchName(data.suggested_branch_name);
+
+ if (!this.droplabInitialized) {
+ this.droplabInitialized = true;
+ this.initDroplab();
+ this.bindEvents();
+ }
+ } else {
+ this.hide();
+ }
+ })
+ .catch(() => {
+ this.unavailable();
+ this.disable();
+ createFlash({
+ message: __('Failed to check related branches.'),
+ });
+ });
+ }
+
+ createBranch() {
+ this.isCreatingBranch = true;
+
+ return axios
+ .post(createEndpoint(this.projectPath, this.createBranchPath), {
+ confidential_issue_project_id: canCreateConfidentialMergeRequest() ? this.projectId : null,
+ })
+ .then(({ data }) => {
+ this.branchCreated = true;
+ window.location.href = data.url;
+ })
+ .catch(() =>
+ createFlash({
+ message: __('Failed to create a branch for this issue. Please try again.'),
+ }),
+ );
+ }
+
+ createMergeRequest() {
+ this.isCreatingMergeRequest = true;
+
+ return axios
+ .post(this.createMrPath, {
+ target_project_id: canCreateConfidentialMergeRequest()
+ ? confidentialMergeRequestState.selectedProject.id
+ : null,
+ })
+ .then(({ data }) => {
+ this.mergeRequestCreated = true;
+ window.location.href = data.url;
+ })
+ .catch(() =>
+ createFlash({
+ message: __('Failed to create merge request. Please try again.'),
+ }),
+ );
+ }
+
+ disable() {
+ this.disableCreateAction();
+ }
+
+ setLoading(loading) {
+ this.createMergeRequestLoading.classList.toggle('gl-display-none', !loading);
+ }
+
+ disableCreateAction() {
+ this.createMergeRequestButton.classList.add('disabled');
+ this.createMergeRequestButton.setAttribute('disabled', 'disabled');
+
+ this.createTargetButton.classList.add('disabled');
+ this.createTargetButton.setAttribute('disabled', 'disabled');
+ }
+
+ enable() {
+ if (isConfidentialIssue() && !canCreateConfidentialMergeRequest()) return;
+
+ this.createMergeRequestButton.classList.remove('disabled');
+ this.createMergeRequestButton.removeAttribute('disabled');
+
+ this.createTargetButton.classList.remove('disabled');
+ this.createTargetButton.removeAttribute('disabled');
+ }
+
+ static findByValue(objects, ref, returnFirstMatch = false) {
+ if (!objects || !objects.length) return false;
+ if (objects.indexOf(ref) > -1) return ref;
+ if (returnFirstMatch) return objects.find((item) => new RegExp(`^${ref}`).test(item));
+
+ return false;
+ }
+
+ getDroplabConfig() {
+ return {
+ addActiveClassToDropdownButton: true,
+ InputSetter: [
+ {
+ input: this.createMergeRequestButton,
+ valueAttribute: 'data-value',
+ inputAttribute: 'data-action',
+ },
+ {
+ input: this.createMergeRequestButton,
+ valueAttribute: 'data-text',
+ },
+ {
+ input: this.createTargetButton,
+ valueAttribute: 'data-value',
+ inputAttribute: 'data-action',
+ },
+ {
+ input: this.createTargetButton,
+ valueAttribute: 'data-text',
+ },
+ ],
+ hideOnClick: false,
+ };
+ }
+
+ static getInputSelectedText(input) {
+ const start = input.selectionStart;
+ const end = input.selectionEnd;
+
+ return input.value.substr(start, end - start);
+ }
+
+ getRef(ref, target = 'all') {
+ if (!ref) return false;
+
+ this.refCancelToken = axios.CancelToken.source();
+
+ return axios
+ .get(`${createEndpoint(this.projectPath, this.refsPath)}${encodeURIComponent(ref)}`, {
+ cancelToken: this.refCancelToken.token,
+ })
+ .then(({ data }) => {
+ const branches = data[Object.keys(data)[0]];
+ const tags = data[Object.keys(data)[1]];
+ let result;
+
+ if (target === 'branch') {
+ result = CreateMergeRequestDropdown.findByValue(branches, ref);
+ } else {
+ result =
+ CreateMergeRequestDropdown.findByValue(branches, ref, true) ||
+ CreateMergeRequestDropdown.findByValue(tags, ref, true);
+ this.suggestedRef = result;
+ }
+
+ this.isGettingRef = false;
+
+ return this.updateInputState(target, ref, result);
+ })
+ .catch((thrown) => {
+ if (axios.isCancel(thrown)) {
+ return false;
+ }
+ this.unavailable();
+ this.disable();
+ createFlash({
+ message: __('Failed to get ref.'),
+ });
+
+ this.isGettingRef = false;
+
+ return false;
+ });
+ }
+
+ getTargetData(target) {
+ return {
+ input: this[`${target}Input`],
+ message: this[`${target}Message`],
+ };
+ }
+
+ hide() {
+ this.wrapperEl.classList.add('hidden');
+ }
+
+ init() {
+ this.checkAbilityToCreateBranch();
+ }
+
+ initDroplab() {
+ this.droplab = new DropLab();
+
+ this.droplab.init(
+ this.dropdownToggle,
+ this.dropdownList,
+ [InputSetter],
+ this.getDroplabConfig(),
+ );
+ }
+
+ inputsAreValid() {
+ return this.branchIsValid && this.refIsValid;
+ }
+
+ isBusy() {
+ return (
+ this.isCreatingMergeRequest ||
+ this.mergeRequestCreated ||
+ this.isCreatingBranch ||
+ this.branchCreated ||
+ this.isGettingRef
+ );
+ }
+
+ onChangeInput(event) {
+ this.disable();
+ let target;
+ let value;
+
+ // User changed input, cancel to prevent previous request from interfering
+ if (this.refCancelToken !== null) {
+ this.refCancelToken.cancel();
+ }
+
+ if (event.target === this.branchInput) {
+ target = 'branch';
+ ({ value } = this.branchInput);
+ } else if (event.target === this.refInput) {
+ target = 'ref';
+ if (event.target === document.activeElement) {
+ value =
+ event.target.value.slice(0, event.target.selectionStart) +
+ event.target.value.slice(event.target.selectionEnd);
+ } else {
+ value = event.target.value;
+ }
+ } else {
+ return false;
+ }
+
+ if (this.isGettingRef) return false;
+
+ // `ENTER` key submits the data.
+ if (event.keyCode === 13 && this.inputsAreValid()) {
+ event.preventDefault();
+ return this.createMergeRequestButton.click();
+ }
+
+ // If the input is empty, use the original value generated by the backend.
+ if (!value) {
+ this.createBranchPath = this.wrapperEl.dataset.createBranchPath;
+ this.createMrPath = this.wrapperEl.dataset.createMrPath;
+
+ if (target === 'branch') {
+ this.branchIsValid = true;
+ } else {
+ this.refIsValid = true;
+ }
+
+ this.enable();
+ this.showAvailableMessage(target);
+ this.refDebounce(value, target);
+ return true;
+ }
+
+ this.showCheckingMessage(target);
+ this.refDebounce(value, target);
+
+ return true;
+ }
+
+ onClickCreateMergeRequestButton(event) {
+ let xhr = null;
+ event.preventDefault();
+
+ if (isConfidentialIssue() && !event.target.classList.contains('js-create-target')) {
+ this.droplab.hooks.forEach((hook) => hook.list.toggle());
+
+ return;
+ }
+
+ if (this.isBusy()) {
+ return;
+ }
+
+ if (event.target.dataset.action === CREATE_MERGE_REQUEST) {
+ xhr = this.createMergeRequest();
+ } else if (event.target.dataset.action === CREATE_BRANCH) {
+ xhr = this.createBranch();
+ }
+
+ xhr.catch(() => {
+ this.isCreatingMergeRequest = false;
+ this.isCreatingBranch = false;
+
+ this.enable();
+ this.setLoading(false);
+ });
+
+ this.setLoading(true);
+ this.disable();
+ }
+
+ onClickSetFocusOnBranchNameInput() {
+ this.branchInput.focus();
+ }
+
+ // `TAB` autocompletes the source.
+ static processTab(event) {
+ if (event.keyCode !== 9 || this.isGettingRef) return;
+
+ const selectedText = CreateMergeRequestDropdown.getInputSelectedText(this.refInput);
+
+ // if nothing selected, we don't need to autocomplete anything. Do the default TAB action.
+ // If a user manually selected text, don't autocomplete anything. Do the default TAB action.
+ if (!selectedText || this.refInput.dataset.value === this.suggestedRef) return;
+
+ event.preventDefault();
+ const caretPositionEnd = this.refInput.value.length;
+ this.refInput.setSelectionRange(caretPositionEnd, caretPositionEnd);
+ }
+
+ removeMessage(target) {
+ const { input, message } = this.getTargetData(target);
+ const inputClasses = ['gl-field-error-outline', 'gl-field-success-outline'];
+ const messageClasses = ['text-muted', 'text-danger', 'text-success'];
+
+ inputClasses.forEach((cssClass) => input.classList.remove(cssClass));
+ messageClasses.forEach((cssClass) => message.classList.remove(cssClass));
+ message.style.display = 'none';
+ }
+
+ setUnavailableButtonState(isLoading = true) {
+ if (isLoading) {
+ this.unavailableButtonSpinner.classList.remove('hide');
+ this.unavailableButtonText.textContent = __('Checking branch availability...');
+ } else {
+ this.unavailableButtonSpinner.classList.add('hide');
+ this.unavailableButtonText.textContent = __('New branch unavailable');
+ }
+ }
+
+ showAvailableMessage(target) {
+ const { input, message } = this.getTargetData(target);
+ const text = target === 'branch' ? __('Branch name') : __('Source');
+
+ this.removeMessage(target);
+ input.classList.add('gl-field-success-outline');
+ message.classList.add('text-success');
+ message.textContent = sprintf(__('%{text} is available'), { text });
+ message.style.display = 'inline-block';
+ }
+
+ showCheckingMessage(target) {
+ const { message } = this.getTargetData(target);
+ const text = target === 'branch' ? __('branch name') : __('source');
+
+ this.removeMessage(target);
+ message.classList.add('text-muted');
+ message.textContent = sprintf(__('Checking %{text} availability…'), { text });
+ message.style.display = 'inline-block';
+ }
+
+ showNotAvailableMessage(target) {
+ const { input, message } = this.getTargetData(target);
+ const text =
+ target === 'branch' ? __('Branch is already taken') : __('Source is not available');
+
+ this.removeMessage(target);
+ input.classList.add('gl-field-error-outline');
+ message.classList.add('text-danger');
+ message.textContent = text;
+ message.style.display = 'inline-block';
+ }
+
+ unavailable() {
+ this.availableButton.classList.add('hidden');
+ this.unavailableButton.classList.remove('hidden');
+ }
+
+ updateBranchName(suggestedBranchName) {
+ this.branchInput.value = suggestedBranchName;
+ this.updateCreatePaths('branch', suggestedBranchName);
+ }
+
+ updateInputState(target, ref, result) {
+ // target - 'branch' or 'ref' - which the input field we are searching a ref for.
+ // ref - string - what a user typed.
+ // result - string - what has been found on backend.
+
+ // If a found branch equals exact the same text a user typed,
+ // that means a new branch cannot be created as it already exists.
+ if (ref === result) {
+ if (target === 'branch') {
+ this.branchIsValid = false;
+ this.showNotAvailableMessage('branch');
+ } else {
+ this.refIsValid = true;
+ this.refInput.dataset.value = ref;
+ this.showAvailableMessage('ref');
+ this.updateCreatePaths(target, ref);
+ }
+ } else if (target === 'branch') {
+ this.branchIsValid = true;
+ this.showAvailableMessage('branch');
+ this.updateCreatePaths(target, ref);
+ } else {
+ this.refIsValid = false;
+ this.refInput.dataset.value = ref;
+ this.disableCreateAction();
+ this.showNotAvailableMessage('ref');
+
+ // Show ref hint.
+ if (result) {
+ this.refInput.value = result;
+ this.refInput.setSelectionRange(ref.length, result.length);
+ }
+ }
+
+ if (this.inputsAreValid()) {
+ this.enable();
+ } else {
+ this.disableCreateAction();
+ }
+ }
+
+ // target - 'branch' or 'ref'
+ // ref - string - the new value to use as branch or ref
+ updateCreatePaths(target, ref) {
+ const pathReplacement = `$1${encodeURIComponent(ref)}`;
+
+ this.createBranchPath = this.createBranchPath.replace(
+ this.regexps[target].createBranchPath,
+ pathReplacement,
+ );
+ this.createMrPath = this.createMrPath.replace(
+ this.regexps[target].createMrPath,
+ pathReplacement,
+ );
+ }
+}
diff --git a/app/assets/javascripts/issues/form.js b/app/assets/javascripts/issues/form.js
deleted file mode 100644
index 33371d065f9..00000000000
--- a/app/assets/javascripts/issues/form.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* eslint-disable no-new */
-
-import $ from 'jquery';
-import IssuableForm from 'ee_else_ce/issuable/issuable_form';
-import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
-import GLForm from '~/gl_form';
-import { initTitleSuggestions, initTypePopover } from '~/issues/new';
-import LabelsSelect from '~/labels/labels_select';
-import MilestoneSelect from '~/milestones/milestone_select';
-import IssuableTemplateSelectors from '~/issuable/issuable_template_selectors';
-
-export default () => {
- new ShortcutsNavigation();
- new GLForm($('.issue-form'));
- new IssuableForm($('.issue-form'));
- new LabelsSelect();
- new MilestoneSelect();
- new IssuableTemplateSelectors({
- warnTemplateOverride: true,
- });
-
- initTitleSuggestions();
- initTypePopover();
-};
diff --git a/app/assets/javascripts/issues/index.js b/app/assets/javascripts/issues/index.js
new file mode 100644
index 00000000000..2ee9ac2a682
--- /dev/null
+++ b/app/assets/javascripts/issues/index.js
@@ -0,0 +1,88 @@
+import $ from 'jquery';
+import IssuableForm from 'ee_else_ce/issuable/issuable_form';
+import loadAwardsHandler from '~/awards_handler';
+import ShortcutsIssuable from '~/behaviors/shortcuts/shortcuts_issuable';
+import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
+import GLForm from '~/gl_form';
+import { initIssuableHeaderWarnings, initIssuableSidebar } from '~/issuable';
+import IssuableTemplateSelectors from '~/issuable/issuable_template_selectors';
+import { IssueType } from '~/issues/constants';
+import Issue from '~/issues/issue';
+import { initTitleSuggestions, initTypePopover } from '~/issues/new';
+import { initRelatedMergeRequests } from '~/issues/related_merge_requests';
+import {
+ initHeaderActions,
+ initIncidentApp,
+ initIssueApp,
+ initSentryErrorStackTrace,
+} from '~/issues/show';
+import { parseIssuableData } from '~/issues/show/utils/parse_data';
+import LabelsSelect from '~/labels/labels_select';
+import MilestoneSelect from '~/milestones/milestone_select';
+import initNotesApp from '~/notes';
+import { store } from '~/notes/stores';
+import ZenMode from '~/zen_mode';
+import FilteredSearchServiceDesk from './filtered_search_service_desk';
+
+export function initFilteredSearchServiceDesk() {
+ if (document.querySelector('.filtered-search')) {
+ const supportBotData = JSON.parse(
+ document.querySelector('.js-service-desk-issues').dataset.supportBot,
+ );
+ const filteredSearchManager = new FilteredSearchServiceDesk(supportBotData);
+ filteredSearchManager.setup();
+ }
+}
+
+export function initForm() {
+ new GLForm($('.issue-form')); // eslint-disable-line no-new
+ new IssuableForm($('.issue-form')); // eslint-disable-line no-new
+ new IssuableTemplateSelectors({ warnTemplateOverride: true }); // eslint-disable-line no-new
+ new LabelsSelect(); // eslint-disable-line no-new
+ new MilestoneSelect(); // eslint-disable-line no-new
+ new ShortcutsNavigation(); // eslint-disable-line no-new
+
+ initTitleSuggestions();
+ initTypePopover();
+}
+
+export function initShow() {
+ const el = document.getElementById('js-issuable-app');
+
+ if (!el) {
+ return;
+ }
+
+ const { issueType, ...issuableData } = parseIssuableData(el);
+
+ if (issueType === IssueType.Incident) {
+ initIncidentApp(issuableData);
+ initHeaderActions(store, IssueType.Incident);
+ } else {
+ initIssueApp(issuableData, store);
+ initHeaderActions(store);
+ }
+
+ new Issue(); // eslint-disable-line no-new
+ new ShortcutsIssuable(); // eslint-disable-line no-new
+ new ZenMode(); // eslint-disable-line no-new
+ initIssuableHeaderWarnings(store);
+ initIssuableSidebar();
+ initNotesApp();
+ initRelatedMergeRequests();
+ initSentryErrorStackTrace();
+
+ const awardEmojiEl = document.getElementById('js-vue-awards-block');
+
+ if (awardEmojiEl) {
+ import('~/emoji/awards_app')
+ .then((m) => m.default(awardEmojiEl))
+ .catch(() => {});
+ } else {
+ loadAwardsHandler();
+ }
+
+ import(/* webpackChunkName: 'design_management' */ '~/design_management')
+ .then((module) => module.default())
+ .catch(() => {});
+}
diff --git a/app/assets/javascripts/issues/init_filtered_search_service_desk.js b/app/assets/javascripts/issues/init_filtered_search_service_desk.js
deleted file mode 100644
index 1901802c11c..00000000000
--- a/app/assets/javascripts/issues/init_filtered_search_service_desk.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import FilteredSearchServiceDesk from './filtered_search_service_desk';
-
-export function initFilteredSearchServiceDesk() {
- if (document.querySelector('.filtered-search')) {
- const supportBotData = JSON.parse(
- document.querySelector('.js-service-desk-issues').dataset.supportBot,
- );
- const filteredSearchManager = new FilteredSearchServiceDesk(supportBotData);
- filteredSearchManager.setup();
- }
-}
diff --git a/app/assets/javascripts/issues/issue.js b/app/assets/javascripts/issues/issue.js
index c471875654b..8e27f547b5c 100644
--- a/app/assets/javascripts/issues/issue.js
+++ b/app/assets/javascripts/issues/issue.js
@@ -1,11 +1,11 @@
import $ from 'jquery';
import { joinPaths } from '~/lib/utils/url_utility';
-import CreateMergeRequestDropdown from '~/create_merge_request_dropdown';
import createFlash from '~/flash';
import { EVENT_ISSUABLE_VUE_APP_CHANGE } from '~/issuable/constants';
import axios from '~/lib/utils/axios_utils';
import { addDelimiter } from '~/lib/utils/text_utility';
import { __ } from '~/locale';
+import CreateMergeRequestDropdown from './create_merge_request_dropdown';
export default class Issue {
constructor() {
diff --git a/app/assets/javascripts/issues_list/components/issue_card_time_info.vue b/app/assets/javascripts/issues/list/components/issue_card_time_info.vue
index aece7372182..aece7372182 100644
--- a/app/assets/javascripts/issues_list/components/issue_card_time_info.vue
+++ b/app/assets/javascripts/issues/list/components/issue_card_time_info.vue
diff --git a/app/assets/javascripts/issues/list/components/issues_list_app.vue b/app/assets/javascripts/issues/list/components/issues_list_app.vue
new file mode 100644
index 00000000000..8b15e801f02
--- /dev/null
+++ b/app/assets/javascripts/issues/list/components/issues_list_app.vue
@@ -0,0 +1,821 @@
+<script>
+import {
+ GlButton,
+ GlEmptyState,
+ GlFilteredSearchToken,
+ GlIcon,
+ GlLink,
+ GlSprintf,
+ GlTooltipDirective,
+} from '@gitlab/ui';
+import * as Sentry from '@sentry/browser';
+import fuzzaldrinPlus from 'fuzzaldrin-plus';
+import { orderBy } from 'lodash';
+import getIssuesQuery from 'ee_else_ce/issues/list/queries/get_issues.query.graphql';
+import getIssuesCountsQuery from 'ee_else_ce/issues/list/queries/get_issues_counts.query.graphql';
+import IssueCardTimeInfo from 'ee_else_ce/issues/list/components/issue_card_time_info.vue';
+import createFlash, { FLASH_TYPES } from '~/flash';
+import { TYPE_USER } from '~/graphql_shared/constants';
+import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
+import { ITEM_TYPE } from '~/groups/constants';
+import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue';
+import IssuableByEmail from '~/issuable/components/issuable_by_email.vue';
+import IssuableList from '~/vue_shared/issuable/list/components/issuable_list_root.vue';
+import { IssuableListTabs, IssuableStates } from '~/vue_shared/issuable/list/constants';
+import {
+ CREATED_DESC,
+ i18n,
+ MAX_LIST_SIZE,
+ PAGE_SIZE,
+ PARAM_DUE_DATE,
+ PARAM_SORT,
+ PARAM_STATE,
+ RELATIVE_POSITION_ASC,
+ TOKEN_TYPE_ASSIGNEE,
+ TOKEN_TYPE_AUTHOR,
+ TOKEN_TYPE_CONFIDENTIAL,
+ TOKEN_TYPE_LABEL,
+ TOKEN_TYPE_MILESTONE,
+ TOKEN_TYPE_MY_REACTION,
+ TOKEN_TYPE_RELEASE,
+ TOKEN_TYPE_TYPE,
+ UPDATED_DESC,
+ urlSortParams,
+} from '~/issues/list/constants';
+import {
+ convertToApiParams,
+ convertToSearchQuery,
+ convertToUrlParams,
+ getDueDateValue,
+ getFilterTokens,
+ getInitialPageParams,
+ getSortKey,
+ getSortOptions,
+} from '~/issues/list/utils';
+import axios from '~/lib/utils/axios_utils';
+import { scrollUp } from '~/lib/utils/scroll_utils';
+import { getParameterByName, joinPaths } from '~/lib/utils/url_utility';
+import {
+ DEFAULT_NONE_ANY,
+ OPERATOR_IS_ONLY,
+ TOKEN_TITLE_ASSIGNEE,
+ TOKEN_TITLE_AUTHOR,
+ TOKEN_TITLE_CONFIDENTIAL,
+ TOKEN_TITLE_LABEL,
+ TOKEN_TITLE_MILESTONE,
+ TOKEN_TITLE_MY_REACTION,
+ TOKEN_TITLE_RELEASE,
+ TOKEN_TITLE_TYPE,
+} from '~/vue_shared/components/filtered_search_bar/constants';
+import eventHub from '../eventhub';
+import reorderIssuesMutation from '../queries/reorder_issues.mutation.graphql';
+import searchLabelsQuery from '../queries/search_labels.query.graphql';
+import searchMilestonesQuery from '../queries/search_milestones.query.graphql';
+import searchUsersQuery from '../queries/search_users.query.graphql';
+import NewIssueDropdown from './new_issue_dropdown.vue';
+
+const AuthorToken = () =>
+ import('~/vue_shared/components/filtered_search_bar/tokens/author_token.vue');
+const EmojiToken = () =>
+ import('~/vue_shared/components/filtered_search_bar/tokens/emoji_token.vue');
+const LabelToken = () =>
+ import('~/vue_shared/components/filtered_search_bar/tokens/label_token.vue');
+const MilestoneToken = () =>
+ import('~/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue');
+const ReleaseToken = () =>
+ import('~/vue_shared/components/filtered_search_bar/tokens/release_token.vue');
+
+export default {
+ i18n,
+ IssuableListTabs,
+ components: {
+ CsvImportExportButtons,
+ GlButton,
+ GlEmptyState,
+ GlIcon,
+ GlLink,
+ GlSprintf,
+ IssuableByEmail,
+ IssuableList,
+ IssueCardTimeInfo,
+ NewIssueDropdown,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
+ inject: {
+ autocompleteAwardEmojisPath: {
+ default: '',
+ },
+ calendarPath: {
+ default: '',
+ },
+ canBulkUpdate: {
+ default: false,
+ },
+ emptyStateSvgPath: {
+ default: '',
+ },
+ exportCsvPath: {
+ default: '',
+ },
+ fullPath: {
+ default: '',
+ },
+ hasAnyIssues: {
+ default: false,
+ },
+ hasAnyProjects: {
+ default: false,
+ },
+ hasBlockedIssuesFeature: {
+ default: false,
+ },
+ hasIssueWeightsFeature: {
+ default: false,
+ },
+ hasMultipleIssueAssigneesFeature: {
+ default: false,
+ },
+ initialEmail: {
+ default: '',
+ },
+ isAnonymousSearchDisabled: {
+ default: false,
+ },
+ isIssueRepositioningDisabled: {
+ default: false,
+ },
+ isProject: {
+ default: false,
+ },
+ isSignedIn: {
+ default: false,
+ },
+ jiraIntegrationPath: {
+ default: '',
+ },
+ newIssuePath: {
+ default: '',
+ },
+ releasesPath: {
+ default: '',
+ },
+ rssPath: {
+ default: '',
+ },
+ showNewIssueLink: {
+ default: false,
+ },
+ signInPath: {
+ default: '',
+ },
+ },
+ props: {
+ eeSearchTokens: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
+ },
+ data() {
+ const state = getParameterByName(PARAM_STATE);
+ const defaultSortKey = state === IssuableStates.Closed ? UPDATED_DESC : CREATED_DESC;
+ let sortKey = getSortKey(getParameterByName(PARAM_SORT)) || defaultSortKey;
+
+ if (this.isIssueRepositioningDisabled && sortKey === RELATIVE_POSITION_ASC) {
+ this.showIssueRepositioningMessage();
+ sortKey = defaultSortKey;
+ }
+
+ const isSearchDisabled =
+ this.isAnonymousSearchDisabled &&
+ !this.isSignedIn &&
+ window.location.search.includes('search=');
+
+ if (isSearchDisabled) {
+ this.showAnonymousSearchingMessage();
+ }
+
+ return {
+ dueDateFilter: getDueDateValue(getParameterByName(PARAM_DUE_DATE)),
+ exportCsvPathWithQuery: this.getExportCsvPathWithQuery(),
+ filterTokens: isSearchDisabled ? [] : getFilterTokens(window.location.search),
+ issues: [],
+ issuesCounts: {},
+ issuesError: null,
+ pageInfo: {},
+ pageParams: getInitialPageParams(sortKey),
+ showBulkEditSidebar: false,
+ sortKey,
+ state: state || IssuableStates.Opened,
+ };
+ },
+ apollo: {
+ issues: {
+ query: getIssuesQuery,
+ variables() {
+ return this.queryVariables;
+ },
+ update(data) {
+ return data[this.namespace]?.issues.nodes ?? [];
+ },
+ result({ data }) {
+ this.pageInfo = data[this.namespace]?.issues.pageInfo ?? {};
+ this.exportCsvPathWithQuery = this.getExportCsvPathWithQuery();
+ },
+ error(error) {
+ this.issuesError = this.$options.i18n.errorFetchingIssues;
+ Sentry.captureException(error);
+ },
+ skip() {
+ return !this.hasAnyIssues;
+ },
+ debounce: 200,
+ },
+ issuesCounts: {
+ query: getIssuesCountsQuery,
+ variables() {
+ return this.queryVariables;
+ },
+ update(data) {
+ return data[this.namespace] ?? {};
+ },
+ error(error) {
+ this.issuesError = this.$options.i18n.errorFetchingCounts;
+ Sentry.captureException(error);
+ },
+ skip() {
+ return !this.hasAnyIssues;
+ },
+ debounce: 200,
+ context: {
+ isSingleRequest: true,
+ },
+ },
+ },
+ computed: {
+ queryVariables() {
+ return {
+ fullPath: this.fullPath,
+ isProject: this.isProject,
+ isSignedIn: this.isSignedIn,
+ search: this.searchQuery,
+ sort: this.sortKey,
+ state: this.state,
+ ...this.pageParams,
+ ...this.apiFilterParams,
+ };
+ },
+ namespace() {
+ return this.isProject ? ITEM_TYPE.PROJECT : ITEM_TYPE.GROUP;
+ },
+ hasSearch() {
+ return this.searchQuery || Object.keys(this.urlFilterParams).length;
+ },
+ isBulkEditButtonDisabled() {
+ return this.showBulkEditSidebar || !this.issues.length;
+ },
+ isManualOrdering() {
+ return this.sortKey === RELATIVE_POSITION_ASC;
+ },
+ isOpenTab() {
+ return this.state === IssuableStates.Opened;
+ },
+ showCsvButtons() {
+ return this.isProject && this.isSignedIn;
+ },
+ showNewIssueDropdown() {
+ return !this.isProject && this.hasAnyProjects;
+ },
+ apiFilterParams() {
+ return convertToApiParams(this.filterTokens);
+ },
+ urlFilterParams() {
+ return convertToUrlParams(this.filterTokens);
+ },
+ searchQuery() {
+ return convertToSearchQuery(this.filterTokens) || undefined;
+ },
+ searchTokens() {
+ const preloadedAuthors = [];
+
+ if (gon.current_user_id) {
+ preloadedAuthors.push({
+ id: convertToGraphQLId(TYPE_USER, gon.current_user_id),
+ name: gon.current_user_fullname,
+ username: gon.current_username,
+ avatar_url: gon.current_user_avatar_url,
+ });
+ }
+
+ const tokens = [
+ {
+ type: TOKEN_TYPE_AUTHOR,
+ title: TOKEN_TITLE_AUTHOR,
+ icon: 'pencil',
+ token: AuthorToken,
+ dataType: 'user',
+ unique: true,
+ defaultAuthors: [],
+ fetchAuthors: this.fetchUsers,
+ recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-author`,
+ preloadedAuthors,
+ },
+ {
+ type: TOKEN_TYPE_ASSIGNEE,
+ title: TOKEN_TITLE_ASSIGNEE,
+ icon: 'user',
+ token: AuthorToken,
+ dataType: 'user',
+ unique: !this.hasMultipleIssueAssigneesFeature,
+ defaultAuthors: DEFAULT_NONE_ANY,
+ fetchAuthors: this.fetchUsers,
+ recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-assignee`,
+ preloadedAuthors,
+ },
+ {
+ type: TOKEN_TYPE_MILESTONE,
+ title: TOKEN_TITLE_MILESTONE,
+ icon: 'clock',
+ token: MilestoneToken,
+ fetchMilestones: this.fetchMilestones,
+ recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-milestone`,
+ },
+ {
+ type: TOKEN_TYPE_LABEL,
+ title: TOKEN_TITLE_LABEL,
+ icon: 'labels',
+ token: LabelToken,
+ defaultLabels: DEFAULT_NONE_ANY,
+ fetchLabels: this.fetchLabels,
+ recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-label`,
+ },
+ {
+ type: TOKEN_TYPE_TYPE,
+ title: TOKEN_TITLE_TYPE,
+ icon: 'issues',
+ token: GlFilteredSearchToken,
+ options: [
+ { icon: 'issue-type-issue', title: 'issue', value: 'issue' },
+ { icon: 'issue-type-incident', title: 'incident', value: 'incident' },
+ { icon: 'issue-type-test-case', title: 'test_case', value: 'test_case' },
+ ],
+ },
+ ];
+
+ if (this.isProject) {
+ tokens.push({
+ type: TOKEN_TYPE_RELEASE,
+ title: TOKEN_TITLE_RELEASE,
+ icon: 'rocket',
+ token: ReleaseToken,
+ fetchReleases: this.fetchReleases,
+ recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-release`,
+ });
+ }
+
+ if (this.isSignedIn) {
+ tokens.push({
+ type: TOKEN_TYPE_MY_REACTION,
+ title: TOKEN_TITLE_MY_REACTION,
+ icon: 'thumb-up',
+ token: EmojiToken,
+ unique: true,
+ fetchEmojis: this.fetchEmojis,
+ recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-my_reaction`,
+ });
+
+ tokens.push({
+ type: TOKEN_TYPE_CONFIDENTIAL,
+ title: TOKEN_TITLE_CONFIDENTIAL,
+ icon: 'eye-slash',
+ token: GlFilteredSearchToken,
+ unique: true,
+ operators: OPERATOR_IS_ONLY,
+ options: [
+ { icon: 'eye-slash', value: 'yes', title: this.$options.i18n.confidentialYes },
+ { icon: 'eye', value: 'no', title: this.$options.i18n.confidentialNo },
+ ],
+ });
+ }
+
+ if (this.eeSearchTokens.length) {
+ tokens.push(...this.eeSearchTokens);
+ }
+
+ tokens.sort((a, b) => a.title.localeCompare(b.title));
+
+ return orderBy(tokens, ['title']);
+ },
+ showPaginationControls() {
+ return this.issues.length > 0 && (this.pageInfo.hasNextPage || this.pageInfo.hasPreviousPage);
+ },
+ sortOptions() {
+ return getSortOptions(this.hasIssueWeightsFeature, this.hasBlockedIssuesFeature);
+ },
+ tabCounts() {
+ const { openedIssues, closedIssues, allIssues } = this.issuesCounts;
+ return {
+ [IssuableStates.Opened]: openedIssues?.count,
+ [IssuableStates.Closed]: closedIssues?.count,
+ [IssuableStates.All]: allIssues?.count,
+ };
+ },
+ currentTabCount() {
+ return this.tabCounts[this.state] ?? 0;
+ },
+ urlParams() {
+ return {
+ due_date: this.dueDateFilter,
+ search: this.searchQuery,
+ sort: urlSortParams[this.sortKey],
+ state: this.state,
+ ...this.urlFilterParams,
+ };
+ },
+ },
+ created() {
+ this.cache = {};
+ },
+ mounted() {
+ eventHub.$on('issuables:toggleBulkEdit', this.toggleBulkEditSidebar);
+ },
+ beforeDestroy() {
+ eventHub.$off('issuables:toggleBulkEdit', this.toggleBulkEditSidebar);
+ },
+ methods: {
+ fetchWithCache(path, cacheName, searchKey, search, wrapData = false) {
+ if (this.cache[cacheName]) {
+ const data = search
+ ? fuzzaldrinPlus.filter(this.cache[cacheName], search, { key: searchKey })
+ : this.cache[cacheName].slice(0, MAX_LIST_SIZE);
+ return wrapData ? Promise.resolve({ data }) : Promise.resolve(data);
+ }
+
+ return axios.get(path).then(({ data }) => {
+ this.cache[cacheName] = data;
+ const result = data.slice(0, MAX_LIST_SIZE);
+ return wrapData ? { data: result } : result;
+ });
+ },
+ fetchEmojis(search) {
+ return this.fetchWithCache(this.autocompleteAwardEmojisPath, 'emojis', 'name', search);
+ },
+ fetchReleases(search) {
+ return this.fetchWithCache(this.releasesPath, 'releases', 'tag', search);
+ },
+ fetchLabels(search) {
+ return this.$apollo
+ .query({
+ query: searchLabelsQuery,
+ variables: { fullPath: this.fullPath, search, isProject: this.isProject },
+ })
+ .then(({ data }) => data[this.namespace]?.labels.nodes)
+ .then((labels) =>
+ // TODO remove once we can search by title-only on the backend
+ // https://gitlab.com/gitlab-org/gitlab/-/issues/346353
+ labels.filter((label) => label.title.toLowerCase().includes(search.toLowerCase())),
+ );
+ },
+ fetchMilestones(search) {
+ return this.$apollo
+ .query({
+ query: searchMilestonesQuery,
+ variables: { fullPath: this.fullPath, search, isProject: this.isProject },
+ })
+ .then(({ data }) => data[this.namespace]?.milestones.nodes);
+ },
+ fetchUsers(search) {
+ return this.$apollo
+ .query({
+ query: searchUsersQuery,
+ variables: { fullPath: this.fullPath, search, isProject: this.isProject },
+ })
+ .then(({ data }) =>
+ data[this.namespace]?.[`${this.namespace}Members`].nodes.map((member) => member.user),
+ );
+ },
+ getExportCsvPathWithQuery() {
+ return `${this.exportCsvPath}${window.location.search}`;
+ },
+ getStatus(issue) {
+ if (issue.closedAt && issue.moved) {
+ return this.$options.i18n.closedMoved;
+ }
+ if (issue.closedAt) {
+ return this.$options.i18n.closed;
+ }
+ return undefined;
+ },
+ handleUpdateLegacyBulkEdit() {
+ // If "select all" checkbox was checked, wait for all checkboxes
+ // to be checked before updating IssuableBulkUpdateSidebar class
+ this.$nextTick(() => {
+ eventHub.$emit('issuables:updateBulkEdit');
+ });
+ },
+ async handleBulkUpdateClick() {
+ if (!this.hasInitBulkEdit) {
+ const bulkUpdateSidebar = await import('~/issuable/bulk_update_sidebar');
+ bulkUpdateSidebar.initBulkUpdateSidebar('issuable_');
+ bulkUpdateSidebar.initIssueStatusSelect();
+
+ const usersSelect = await import('~/users_select');
+ const UsersSelect = usersSelect.default;
+ new UsersSelect(); // eslint-disable-line no-new
+
+ this.hasInitBulkEdit = true;
+ }
+
+ eventHub.$emit('issuables:enableBulkEdit');
+ },
+ handleClickTab(state) {
+ if (this.state !== state) {
+ this.pageParams = getInitialPageParams(this.sortKey);
+ }
+ this.state = state;
+ },
+ handleDismissAlert() {
+ this.issuesError = null;
+ },
+ handleFilter(filter) {
+ if (this.isAnonymousSearchDisabled && !this.isSignedIn) {
+ this.showAnonymousSearchingMessage();
+ return;
+ }
+ this.pageParams = getInitialPageParams(this.sortKey);
+ this.filterTokens = filter;
+ },
+ handleNextPage() {
+ this.pageParams = {
+ afterCursor: this.pageInfo.endCursor,
+ firstPageSize: PAGE_SIZE,
+ };
+ scrollUp();
+ },
+ handlePreviousPage() {
+ this.pageParams = {
+ beforeCursor: this.pageInfo.startCursor,
+ lastPageSize: PAGE_SIZE,
+ };
+ scrollUp();
+ },
+ handleReorder({ newIndex, oldIndex }) {
+ const issueToMove = this.issues[oldIndex];
+ const isDragDropDownwards = newIndex > oldIndex;
+ const isMovingToBeginning = newIndex === 0;
+ const isMovingToEnd = newIndex === this.issues.length - 1;
+
+ let moveBeforeId;
+ let moveAfterId;
+
+ if (isDragDropDownwards) {
+ const afterIndex = isMovingToEnd ? newIndex : newIndex + 1;
+ moveBeforeId = this.issues[newIndex].id;
+ moveAfterId = this.issues[afterIndex].id;
+ } else {
+ const beforeIndex = isMovingToBeginning ? newIndex : newIndex - 1;
+ moveBeforeId = this.issues[beforeIndex].id;
+ moveAfterId = this.issues[newIndex].id;
+ }
+
+ return axios
+ .put(joinPaths(issueToMove.webPath, 'reorder'), {
+ move_before_id: isMovingToBeginning ? null : getIdFromGraphQLId(moveBeforeId),
+ move_after_id: isMovingToEnd ? null : getIdFromGraphQLId(moveAfterId),
+ group_full_path: this.isProject ? undefined : this.fullPath,
+ })
+ .then(() => {
+ const serializedVariables = JSON.stringify(this.queryVariables);
+ return this.$apollo.mutate({
+ mutation: reorderIssuesMutation,
+ variables: { oldIndex, newIndex, namespace: this.namespace, serializedVariables },
+ });
+ })
+ .catch((error) => {
+ this.issuesError = this.$options.i18n.reorderError;
+ Sentry.captureException(error);
+ });
+ },
+ handleSort(sortKey) {
+ if (this.isIssueRepositioningDisabled && sortKey === RELATIVE_POSITION_ASC) {
+ this.showIssueRepositioningMessage();
+ return;
+ }
+
+ if (this.sortKey !== sortKey) {
+ this.pageParams = getInitialPageParams(sortKey);
+ }
+ this.sortKey = sortKey;
+ },
+ showAnonymousSearchingMessage() {
+ createFlash({
+ message: this.$options.i18n.anonymousSearchingMessage,
+ type: FLASH_TYPES.NOTICE,
+ });
+ },
+ showIssueRepositioningMessage() {
+ createFlash({
+ message: this.$options.i18n.issueRepositioningMessage,
+ type: FLASH_TYPES.NOTICE,
+ });
+ },
+ toggleBulkEditSidebar(showBulkEditSidebar) {
+ this.showBulkEditSidebar = showBulkEditSidebar;
+ },
+ },
+};
+</script>
+
+<template>
+ <div v-if="hasAnyIssues">
+ <issuable-list
+ :namespace="fullPath"
+ recent-searches-storage-key="issues"
+ :search-input-placeholder="$options.i18n.searchPlaceholder"
+ :search-tokens="searchTokens"
+ :initial-filter-value="filterTokens"
+ :sort-options="sortOptions"
+ :initial-sort-by="sortKey"
+ :issuables="issues"
+ :error="issuesError"
+ label-filter-param="label_name"
+ :tabs="$options.IssuableListTabs"
+ :current-tab="state"
+ :tab-counts="tabCounts"
+ :issuables-loading="$apollo.queries.issues.loading"
+ :is-manual-ordering="isManualOrdering"
+ :show-bulk-edit-sidebar="showBulkEditSidebar"
+ :show-pagination-controls="showPaginationControls"
+ :use-keyset-pagination="true"
+ :has-next-page="pageInfo.hasNextPage"
+ :has-previous-page="pageInfo.hasPreviousPage"
+ :url-params="urlParams"
+ @click-tab="handleClickTab"
+ @dismiss-alert="handleDismissAlert"
+ @filter="handleFilter"
+ @next-page="handleNextPage"
+ @previous-page="handlePreviousPage"
+ @reorder="handleReorder"
+ @sort="handleSort"
+ @update-legacy-bulk-edit="handleUpdateLegacyBulkEdit"
+ >
+ <template #nav-actions>
+ <gl-button
+ v-gl-tooltip
+ :href="rssPath"
+ icon="rss"
+ :title="$options.i18n.rssLabel"
+ :aria-label="$options.i18n.rssLabel"
+ />
+ <gl-button
+ v-gl-tooltip
+ :href="calendarPath"
+ icon="calendar"
+ :title="$options.i18n.calendarLabel"
+ :aria-label="$options.i18n.calendarLabel"
+ />
+ <csv-import-export-buttons
+ v-if="showCsvButtons"
+ class="gl-md-mr-3"
+ :export-csv-path="exportCsvPathWithQuery"
+ :issuable-count="currentTabCount"
+ />
+ <gl-button
+ v-if="canBulkUpdate"
+ :disabled="isBulkEditButtonDisabled"
+ @click="handleBulkUpdateClick"
+ >
+ {{ $options.i18n.editIssues }}
+ </gl-button>
+ <gl-button v-if="showNewIssueLink" :href="newIssuePath" variant="confirm">
+ {{ $options.i18n.newIssueLabel }}
+ </gl-button>
+ <new-issue-dropdown v-if="showNewIssueDropdown" />
+ </template>
+
+ <template #timeframe="{ issuable = {} }">
+ <issue-card-time-info :issue="issuable" />
+ </template>
+
+ <template #status="{ issuable = {} }">
+ {{ getStatus(issuable) }}
+ </template>
+
+ <template #statistics="{ issuable = {} }">
+ <li
+ v-if="issuable.mergeRequestsCount"
+ v-gl-tooltip
+ class="gl-display-none gl-sm-display-block"
+ :title="$options.i18n.relatedMergeRequests"
+ data-testid="merge-requests"
+ >
+ <gl-icon name="merge-request" />
+ {{ issuable.mergeRequestsCount }}
+ </li>
+ <li
+ v-if="issuable.upvotes"
+ v-gl-tooltip
+ class="issuable-upvotes gl-display-none gl-sm-display-block"
+ :title="$options.i18n.upvotes"
+ data-testid="issuable-upvotes"
+ >
+ <gl-icon name="thumb-up" />
+ {{ issuable.upvotes }}
+ </li>
+ <li
+ v-if="issuable.downvotes"
+ v-gl-tooltip
+ class="issuable-downvotes gl-display-none gl-sm-display-block"
+ :title="$options.i18n.downvotes"
+ data-testid="issuable-downvotes"
+ >
+ <gl-icon name="thumb-down" />
+ {{ issuable.downvotes }}
+ </li>
+ <slot :issuable="issuable"></slot>
+ </template>
+
+ <template #empty-state>
+ <gl-empty-state
+ v-if="hasSearch"
+ :description="$options.i18n.noSearchResultsDescription"
+ :title="$options.i18n.noSearchResultsTitle"
+ :svg-path="emptyStateSvgPath"
+ >
+ <template #actions>
+ <gl-button v-if="showNewIssueLink" :href="newIssuePath" variant="confirm">
+ {{ $options.i18n.newIssueLabel }}
+ </gl-button>
+ </template>
+ </gl-empty-state>
+
+ <gl-empty-state
+ v-else-if="isOpenTab"
+ :description="$options.i18n.noOpenIssuesDescription"
+ :title="$options.i18n.noOpenIssuesTitle"
+ :svg-path="emptyStateSvgPath"
+ >
+ <template #actions>
+ <gl-button v-if="showNewIssueLink" :href="newIssuePath" variant="confirm">
+ {{ $options.i18n.newIssueLabel }}
+ </gl-button>
+ </template>
+ </gl-empty-state>
+
+ <gl-empty-state
+ v-else
+ :title="$options.i18n.noClosedIssuesTitle"
+ :svg-path="emptyStateSvgPath"
+ />
+ </template>
+ </issuable-list>
+
+ <issuable-by-email v-if="initialEmail" class="gl-text-center gl-pt-5 gl-pb-7" />
+ </div>
+
+ <div v-else-if="isSignedIn">
+ <gl-empty-state
+ :description="$options.i18n.noIssuesSignedInDescription"
+ :title="$options.i18n.noIssuesSignedInTitle"
+ :svg-path="emptyStateSvgPath"
+ >
+ <template #actions>
+ <gl-button v-if="showNewIssueLink" :href="newIssuePath" variant="confirm">
+ {{ $options.i18n.newIssueLabel }}
+ </gl-button>
+ <csv-import-export-buttons
+ v-if="showCsvButtons"
+ class="gl-mr-3"
+ :export-csv-path="exportCsvPathWithQuery"
+ :issuable-count="currentTabCount"
+ />
+ <new-issue-dropdown v-if="showNewIssueDropdown" />
+ </template>
+ </gl-empty-state>
+ <hr />
+ <p class="gl-text-center gl-font-weight-bold gl-mb-0">
+ {{ $options.i18n.jiraIntegrationTitle }}
+ </p>
+ <p class="gl-text-center gl-mb-0">
+ <gl-sprintf :message="$options.i18n.jiraIntegrationMessage">
+ <template #jiraDocsLink="{ content }">
+ <gl-link :href="jiraIntegrationPath">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
+ <p class="gl-text-center gl-text-gray-500">
+ {{ $options.i18n.jiraIntegrationSecondaryMessage }}
+ </p>
+ </div>
+
+ <gl-empty-state
+ v-else
+ :description="$options.i18n.noIssuesSignedOutDescription"
+ :title="$options.i18n.noIssuesSignedOutTitle"
+ :svg-path="emptyStateSvgPath"
+ :primary-button-text="$options.i18n.noIssuesSignedOutButtonText"
+ :primary-button-link="signInPath"
+ />
+</template>
diff --git a/app/assets/javascripts/issues_list/components/jira_issues_import_status_app.vue b/app/assets/javascripts/issues/list/components/jira_issues_import_status_app.vue
index fb1dbef666c..fb1dbef666c 100644
--- a/app/assets/javascripts/issues_list/components/jira_issues_import_status_app.vue
+++ b/app/assets/javascripts/issues/list/components/jira_issues_import_status_app.vue
diff --git a/app/assets/javascripts/issues/list/components/new_issue_dropdown.vue b/app/assets/javascripts/issues/list/components/new_issue_dropdown.vue
new file mode 100644
index 00000000000..71f84050ba8
--- /dev/null
+++ b/app/assets/javascripts/issues/list/components/new_issue_dropdown.vue
@@ -0,0 +1,127 @@
+<script>
+import {
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownText,
+ GlLoadingIcon,
+ GlSearchBoxByType,
+} from '@gitlab/ui';
+import createFlash from '~/flash';
+import searchProjectsQuery from '~/issues/list/queries/search_projects.query.graphql';
+import { DASH_SCOPE, joinPaths } from '~/lib/utils/url_utility';
+import { __, sprintf } from '~/locale';
+import { DEBOUNCE_DELAY } from '~/vue_shared/components/filtered_search_bar/constants';
+
+export default {
+ i18n: {
+ defaultDropdownText: __('Select project to create issue'),
+ noMatchesFound: __('No matches found'),
+ toggleButtonLabel: __('Toggle project select'),
+ },
+ components: {
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownText,
+ GlLoadingIcon,
+ GlSearchBoxByType,
+ },
+ inject: ['fullPath'],
+ data() {
+ return {
+ projects: [],
+ search: '',
+ selectedProject: {},
+ shouldSkipQuery: true,
+ };
+ },
+ apollo: {
+ projects: {
+ query: searchProjectsQuery,
+ variables() {
+ return {
+ fullPath: this.fullPath,
+ search: this.search,
+ };
+ },
+ update: ({ group }) => group.projects.nodes ?? [],
+ error(error) {
+ createFlash({
+ message: __('An error occurred while loading projects.'),
+ captureError: true,
+ error,
+ });
+ },
+ skip() {
+ return this.shouldSkipQuery;
+ },
+ debounce: DEBOUNCE_DELAY,
+ },
+ },
+ computed: {
+ dropdownHref() {
+ return this.hasSelectedProject
+ ? joinPaths(this.selectedProject.webUrl, DASH_SCOPE, 'issues/new')
+ : undefined;
+ },
+ dropdownText() {
+ return this.hasSelectedProject
+ ? sprintf(__('New issue in %{project}'), { project: this.selectedProject.name })
+ : this.$options.i18n.defaultDropdownText;
+ },
+ hasSelectedProject() {
+ return this.selectedProject.id;
+ },
+ projectsWithIssuesEnabled() {
+ return this.projects.filter((project) => project.issuesEnabled);
+ },
+ showNoSearchResultsText() {
+ return !this.projectsWithIssuesEnabled.length && this.search;
+ },
+ },
+ methods: {
+ handleDropdownClick() {
+ if (!this.dropdownHref) {
+ this.$refs.dropdown.show();
+ }
+ },
+ handleDropdownShown() {
+ if (this.shouldSkipQuery) {
+ this.shouldSkipQuery = false;
+ }
+ this.$refs.search.focusInput();
+ },
+ selectProject(project) {
+ this.selectedProject = project;
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-dropdown
+ ref="dropdown"
+ right
+ split
+ :split-href="dropdownHref"
+ :text="dropdownText"
+ :toggle-text="$options.i18n.toggleButtonLabel"
+ variant="confirm"
+ @click="handleDropdownClick"
+ @shown="handleDropdownShown"
+ >
+ <gl-search-box-by-type ref="search" v-model.trim="search" />
+ <gl-loading-icon v-if="$apollo.queries.projects.loading" />
+ <template v-else>
+ <gl-dropdown-item
+ v-for="project of projectsWithIssuesEnabled"
+ :key="project.id"
+ @click="selectProject(project)"
+ >
+ {{ project.nameWithNamespace }}
+ </gl-dropdown-item>
+ <gl-dropdown-text v-if="showNoSearchResultsText">
+ {{ $options.i18n.noMatchesFound }}
+ </gl-dropdown-text>
+ </template>
+ </gl-dropdown>
+</template>
diff --git a/app/assets/javascripts/issues/list/constants.js b/app/assets/javascripts/issues/list/constants.js
new file mode 100644
index 00000000000..4a380848b4f
--- /dev/null
+++ b/app/assets/javascripts/issues/list/constants.js
@@ -0,0 +1,316 @@
+import { __, s__ } from '~/locale';
+import {
+ FILTER_ANY,
+ FILTER_CURRENT,
+ FILTER_NONE,
+ FILTER_STARTED,
+ FILTER_UPCOMING,
+ OPERATOR_IS,
+ OPERATOR_IS_NOT,
+} from '~/vue_shared/components/filtered_search_bar/constants';
+
+export const i18n = {
+ anonymousSearchingMessage: __('You must sign in to search for specific terms.'),
+ calendarLabel: __('Subscribe to calendar'),
+ closed: __('CLOSED'),
+ closedMoved: __('CLOSED (MOVED)'),
+ confidentialNo: __('No'),
+ confidentialYes: __('Yes'),
+ downvotes: __('Downvotes'),
+ editIssues: __('Edit issues'),
+ errorFetchingCounts: __('An error occurred while getting issue counts'),
+ errorFetchingIssues: __('An error occurred while loading issues'),
+ issueRepositioningMessage: __(
+ 'Issues are being rebalanced at the moment, so manual reordering is disabled.',
+ ),
+ jiraIntegrationMessage: s__(
+ 'JiraService|%{jiraDocsLinkStart}Enable the Jira integration%{jiraDocsLinkEnd} to view your Jira issues in GitLab.',
+ ),
+ jiraIntegrationSecondaryMessage: s__('JiraService|This feature requires a Premium plan.'),
+ jiraIntegrationTitle: s__('JiraService|Using Jira for issue tracking?'),
+ newIssueLabel: __('New issue'),
+ noClosedIssuesTitle: __('There are no closed issues'),
+ noOpenIssuesDescription: __('To keep this project going, create a new issue'),
+ noOpenIssuesTitle: __('There are no open issues'),
+ noIssuesSignedInDescription: __(
+ 'Issues can be bugs, tasks or ideas to be discussed. Also, issues are searchable and filterable.',
+ ),
+ noIssuesSignedInTitle: __(
+ 'The Issue Tracker is the place to add things that need to be improved or solved in a project',
+ ),
+ noIssuesSignedOutButtonText: __('Register / Sign In'),
+ noIssuesSignedOutDescription: __(
+ '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.',
+ ),
+ noIssuesSignedOutTitle: __('There are no issues to show'),
+ noSearchResultsDescription: __('To widen your search, change or remove filters above'),
+ noSearchResultsTitle: __('Sorry, your filter produced no results'),
+ relatedMergeRequests: __('Related merge requests'),
+ reorderError: __('An error occurred while reordering issues.'),
+ rssLabel: __('Subscribe to RSS feed'),
+ searchPlaceholder: __('Search or filter results...'),
+ upvotes: __('Upvotes'),
+};
+
+export const MAX_LIST_SIZE = 10;
+export const PAGE_SIZE = 20;
+export const PAGE_SIZE_MANUAL = 100;
+export const PARAM_DUE_DATE = 'due_date';
+export const PARAM_SORT = 'sort';
+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 DUE_DATE_NONE = '0';
+export const DUE_DATE_ANY = '';
+export const DUE_DATE_OVERDUE = 'overdue';
+export const DUE_DATE_WEEK = 'week';
+export const DUE_DATE_MONTH = 'month';
+export const DUE_DATE_NEXT_MONTH_AND_PREVIOUS_TWO_WEEKS = 'next_month_and_previous_two_weeks';
+export const DUE_DATE_VALUES = [
+ DUE_DATE_NONE,
+ DUE_DATE_ANY,
+ DUE_DATE_OVERDUE,
+ DUE_DATE_WEEK,
+ DUE_DATE_MONTH,
+ DUE_DATE_NEXT_MONTH_AND_PREVIOUS_TWO_WEEKS,
+];
+
+export const BLOCKING_ISSUES_ASC = 'BLOCKING_ISSUES_ASC';
+export const BLOCKING_ISSUES_DESC = 'BLOCKING_ISSUES_DESC';
+export const CREATED_ASC = 'CREATED_ASC';
+export const CREATED_DESC = 'CREATED_DESC';
+export const DUE_DATE_ASC = 'DUE_DATE_ASC';
+export const DUE_DATE_DESC = 'DUE_DATE_DESC';
+export const LABEL_PRIORITY_ASC = 'LABEL_PRIORITY_ASC';
+export const LABEL_PRIORITY_DESC = 'LABEL_PRIORITY_DESC';
+export const MILESTONE_DUE_ASC = 'MILESTONE_DUE_ASC';
+export const MILESTONE_DUE_DESC = 'MILESTONE_DUE_DESC';
+export const POPULARITY_ASC = 'POPULARITY_ASC';
+export const POPULARITY_DESC = 'POPULARITY_DESC';
+export const PRIORITY_ASC = 'PRIORITY_ASC';
+export const PRIORITY_DESC = 'PRIORITY_DESC';
+export const RELATIVE_POSITION_ASC = 'RELATIVE_POSITION_ASC';
+export const TITLE_ASC = 'TITLE_ASC';
+export const TITLE_DESC = 'TITLE_DESC';
+export const UPDATED_ASC = 'UPDATED_ASC';
+export const UPDATED_DESC = 'UPDATED_DESC';
+export const WEIGHT_ASC = 'WEIGHT_ASC';
+export const WEIGHT_DESC = 'WEIGHT_DESC';
+
+export const urlSortParams = {
+ [PRIORITY_ASC]: 'priority',
+ [PRIORITY_DESC]: 'priority_desc',
+ [CREATED_ASC]: 'created_asc',
+ [CREATED_DESC]: 'created_date',
+ [UPDATED_ASC]: 'updated_asc',
+ [UPDATED_DESC]: 'updated_desc',
+ [MILESTONE_DUE_ASC]: 'milestone',
+ [MILESTONE_DUE_DESC]: 'milestone_due_desc',
+ [DUE_DATE_ASC]: 'due_date',
+ [DUE_DATE_DESC]: 'due_date_desc',
+ [POPULARITY_ASC]: 'popularity_asc',
+ [POPULARITY_DESC]: 'popularity',
+ [LABEL_PRIORITY_ASC]: 'label_priority',
+ [LABEL_PRIORITY_DESC]: 'label_priority_desc',
+ [RELATIVE_POSITION_ASC]: RELATIVE_POSITION,
+ [WEIGHT_ASC]: 'weight',
+ [WEIGHT_DESC]: 'weight_desc',
+ [BLOCKING_ISSUES_ASC]: 'blocking_issues_asc',
+ [BLOCKING_ISSUES_DESC]: 'blocking_issues_desc',
+ [TITLE_ASC]: 'title_asc',
+ [TITLE_DESC]: 'title_desc',
+};
+
+export const API_PARAM = 'apiParam';
+export const URL_PARAM = 'urlParam';
+export const NORMAL_FILTER = 'normalFilter';
+export const SPECIAL_FILTER = 'specialFilter';
+export const ALTERNATIVE_FILTER = 'alternativeFilter';
+export const SPECIAL_FILTER_VALUES = [
+ FILTER_NONE,
+ FILTER_ANY,
+ FILTER_CURRENT,
+ FILTER_UPCOMING,
+ FILTER_STARTED,
+];
+
+export const TOKEN_TYPE_AUTHOR = 'author_username';
+export const TOKEN_TYPE_ASSIGNEE = 'assignee_username';
+export const TOKEN_TYPE_MILESTONE = 'milestone';
+export const TOKEN_TYPE_LABEL = 'labels';
+export const TOKEN_TYPE_TYPE = 'type';
+export const TOKEN_TYPE_RELEASE = 'release';
+export const TOKEN_TYPE_MY_REACTION = 'my_reaction_emoji';
+export const TOKEN_TYPE_CONFIDENTIAL = 'confidential';
+export const TOKEN_TYPE_ITERATION = 'iteration';
+export const TOKEN_TYPE_EPIC = 'epic_id';
+export const TOKEN_TYPE_WEIGHT = 'weight';
+
+export const filters = {
+ [TOKEN_TYPE_AUTHOR]: {
+ [API_PARAM]: {
+ [NORMAL_FILTER]: 'authorUsername',
+ },
+ [URL_PARAM]: {
+ [OPERATOR_IS]: {
+ [NORMAL_FILTER]: 'author_username',
+ },
+ [OPERATOR_IS_NOT]: {
+ [NORMAL_FILTER]: 'not[author_username]',
+ },
+ },
+ },
+ [TOKEN_TYPE_ASSIGNEE]: {
+ [API_PARAM]: {
+ [NORMAL_FILTER]: 'assigneeUsernames',
+ [SPECIAL_FILTER]: 'assigneeId',
+ },
+ [URL_PARAM]: {
+ [OPERATOR_IS]: {
+ [NORMAL_FILTER]: 'assignee_username[]',
+ [SPECIAL_FILTER]: 'assignee_id',
+ [ALTERNATIVE_FILTER]: 'assignee_username',
+ },
+ [OPERATOR_IS_NOT]: {
+ [NORMAL_FILTER]: 'not[assignee_username][]',
+ },
+ },
+ },
+ [TOKEN_TYPE_MILESTONE]: {
+ [API_PARAM]: {
+ [NORMAL_FILTER]: 'milestoneTitle',
+ [SPECIAL_FILTER]: 'milestoneWildcardId',
+ },
+ [URL_PARAM]: {
+ [OPERATOR_IS]: {
+ [NORMAL_FILTER]: 'milestone_title',
+ [SPECIAL_FILTER]: 'milestone_title',
+ },
+ [OPERATOR_IS_NOT]: {
+ [NORMAL_FILTER]: 'not[milestone_title]',
+ },
+ },
+ },
+ [TOKEN_TYPE_LABEL]: {
+ [API_PARAM]: {
+ [NORMAL_FILTER]: 'labelName',
+ [SPECIAL_FILTER]: 'labelName',
+ },
+ [URL_PARAM]: {
+ [OPERATOR_IS]: {
+ [NORMAL_FILTER]: 'label_name[]',
+ [SPECIAL_FILTER]: 'label_name[]',
+ [ALTERNATIVE_FILTER]: 'label_name',
+ },
+ [OPERATOR_IS_NOT]: {
+ [NORMAL_FILTER]: 'not[label_name][]',
+ },
+ },
+ },
+ [TOKEN_TYPE_TYPE]: {
+ [API_PARAM]: {
+ [NORMAL_FILTER]: 'types',
+ },
+ [URL_PARAM]: {
+ [OPERATOR_IS]: {
+ [NORMAL_FILTER]: 'type[]',
+ },
+ [OPERATOR_IS_NOT]: {
+ [NORMAL_FILTER]: 'not[type][]',
+ },
+ },
+ },
+ [TOKEN_TYPE_RELEASE]: {
+ [API_PARAM]: {
+ [NORMAL_FILTER]: 'releaseTag',
+ [SPECIAL_FILTER]: 'releaseTagWildcardId',
+ },
+ [URL_PARAM]: {
+ [OPERATOR_IS]: {
+ [NORMAL_FILTER]: 'release_tag',
+ [SPECIAL_FILTER]: 'release_tag',
+ },
+ [OPERATOR_IS_NOT]: {
+ [NORMAL_FILTER]: 'not[release_tag]',
+ },
+ },
+ },
+ [TOKEN_TYPE_MY_REACTION]: {
+ [API_PARAM]: {
+ [NORMAL_FILTER]: 'myReactionEmoji',
+ [SPECIAL_FILTER]: 'myReactionEmoji',
+ },
+ [URL_PARAM]: {
+ [OPERATOR_IS]: {
+ [NORMAL_FILTER]: 'my_reaction_emoji',
+ [SPECIAL_FILTER]: 'my_reaction_emoji',
+ },
+ [OPERATOR_IS_NOT]: {
+ [NORMAL_FILTER]: 'not[my_reaction_emoji]',
+ },
+ },
+ },
+ [TOKEN_TYPE_CONFIDENTIAL]: {
+ [API_PARAM]: {
+ [NORMAL_FILTER]: 'confidential',
+ },
+ [URL_PARAM]: {
+ [OPERATOR_IS]: {
+ [NORMAL_FILTER]: 'confidential',
+ },
+ },
+ },
+ [TOKEN_TYPE_ITERATION]: {
+ [API_PARAM]: {
+ [NORMAL_FILTER]: 'iterationId',
+ [SPECIAL_FILTER]: 'iterationWildcardId',
+ },
+ [URL_PARAM]: {
+ [OPERATOR_IS]: {
+ [NORMAL_FILTER]: 'iteration_id',
+ [SPECIAL_FILTER]: 'iteration_id',
+ },
+ [OPERATOR_IS_NOT]: {
+ [NORMAL_FILTER]: 'not[iteration_id]',
+ },
+ },
+ },
+ [TOKEN_TYPE_EPIC]: {
+ [API_PARAM]: {
+ [NORMAL_FILTER]: 'epicId',
+ [SPECIAL_FILTER]: 'epicId',
+ },
+ [URL_PARAM]: {
+ [OPERATOR_IS]: {
+ [NORMAL_FILTER]: 'epic_id',
+ [SPECIAL_FILTER]: 'epic_id',
+ },
+ [OPERATOR_IS_NOT]: {
+ [NORMAL_FILTER]: 'not[epic_id]',
+ },
+ },
+ },
+ [TOKEN_TYPE_WEIGHT]: {
+ [API_PARAM]: {
+ [NORMAL_FILTER]: 'weight',
+ [SPECIAL_FILTER]: 'weight',
+ },
+ [URL_PARAM]: {
+ [OPERATOR_IS]: {
+ [NORMAL_FILTER]: 'weight',
+ [SPECIAL_FILTER]: 'weight',
+ },
+ [OPERATOR_IS_NOT]: {
+ [NORMAL_FILTER]: 'not[weight]',
+ },
+ },
+ },
+};
diff --git a/app/assets/javascripts/issues_list/eventhub.js b/app/assets/javascripts/issues/list/eventhub.js
index e31806ad199..e31806ad199 100644
--- a/app/assets/javascripts/issues_list/eventhub.js
+++ b/app/assets/javascripts/issues/list/eventhub.js
diff --git a/app/assets/javascripts/issues/list/index.js b/app/assets/javascripts/issues/list/index.js
new file mode 100644
index 00000000000..01cc82ed8fd
--- /dev/null
+++ b/app/assets/javascripts/issues/list/index.js
@@ -0,0 +1,165 @@
+import produce from 'immer';
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import getIssuesQuery from 'ee_else_ce/issues/list/queries/get_issues.query.graphql';
+import IssuesListApp from 'ee_else_ce/issues/list/components/issues_list_app.vue';
+import createDefaultClient from '~/lib/graphql';
+import { parseBoolean } from '~/lib/utils/common_utils';
+import JiraIssuesImportStatusRoot from './components/jira_issues_import_status_app.vue';
+
+export function mountJiraIssuesListApp() {
+ const el = document.querySelector('.js-jira-issues-import-status');
+
+ if (!el) {
+ return false;
+ }
+
+ const { issuesPath, projectPath } = el.dataset;
+ const canEdit = parseBoolean(el.dataset.canEdit);
+ const isJiraConfigured = parseBoolean(el.dataset.isJiraConfigured);
+
+ if (!isJiraConfigured || !canEdit) {
+ return false;
+ }
+
+ Vue.use(VueApollo);
+ const defaultClient = createDefaultClient();
+ const apolloProvider = new VueApollo({
+ defaultClient,
+ });
+
+ return new Vue({
+ el,
+ apolloProvider,
+ render(createComponent) {
+ return createComponent(JiraIssuesImportStatusRoot, {
+ props: {
+ canEdit,
+ isJiraConfigured,
+ issuesPath,
+ projectPath,
+ },
+ });
+ },
+ });
+}
+
+export function mountIssuesListApp() {
+ const el = document.querySelector('.js-issues-list');
+
+ if (!el) {
+ return false;
+ }
+
+ Vue.use(VueApollo);
+
+ const resolvers = {
+ Mutation: {
+ reorderIssues: (_, { oldIndex, newIndex, namespace, serializedVariables }, { cache }) => {
+ const variables = JSON.parse(serializedVariables);
+ const sourceData = cache.readQuery({ query: getIssuesQuery, variables });
+
+ const data = produce(sourceData, (draftData) => {
+ const issues = draftData[namespace].issues.nodes.slice();
+ const issueToMove = issues[oldIndex];
+ issues.splice(oldIndex, 1);
+ issues.splice(newIndex, 0, issueToMove);
+
+ draftData[namespace].issues.nodes = issues;
+ });
+
+ cache.writeQuery({ query: getIssuesQuery, variables, data });
+ },
+ },
+ };
+
+ const defaultClient = createDefaultClient(resolvers);
+ const apolloProvider = new VueApollo({
+ defaultClient,
+ });
+
+ const {
+ autocompleteAwardEmojisPath,
+ calendarPath,
+ canBulkUpdate,
+ canEdit,
+ canImportIssues,
+ email,
+ emailsHelpPagePath,
+ emptyStateSvgPath,
+ exportCsvPath,
+ fullPath,
+ groupPath,
+ hasAnyIssues,
+ hasAnyProjects,
+ hasBlockedIssuesFeature,
+ hasIssuableHealthStatusFeature,
+ hasIssueWeightsFeature,
+ hasIterationsFeature,
+ hasMultipleIssueAssigneesFeature,
+ importCsvIssuesPath,
+ initialEmail,
+ isAnonymousSearchDisabled,
+ isIssueRepositioningDisabled,
+ isProject,
+ isSignedIn,
+ jiraIntegrationPath,
+ markdownHelpPath,
+ maxAttachmentSize,
+ newIssuePath,
+ projectImportJiraPath,
+ quickActionsHelpPath,
+ releasesPath,
+ resetPath,
+ rssPath,
+ showNewIssueLink,
+ signInPath,
+ } = el.dataset;
+
+ return new Vue({
+ el,
+ apolloProvider,
+ provide: {
+ autocompleteAwardEmojisPath,
+ calendarPath,
+ canBulkUpdate: parseBoolean(canBulkUpdate),
+ emptyStateSvgPath,
+ fullPath,
+ groupPath,
+ hasAnyIssues: parseBoolean(hasAnyIssues),
+ hasAnyProjects: parseBoolean(hasAnyProjects),
+ hasBlockedIssuesFeature: parseBoolean(hasBlockedIssuesFeature),
+ hasIssuableHealthStatusFeature: parseBoolean(hasIssuableHealthStatusFeature),
+ hasIssueWeightsFeature: parseBoolean(hasIssueWeightsFeature),
+ hasIterationsFeature: parseBoolean(hasIterationsFeature),
+ hasMultipleIssueAssigneesFeature: parseBoolean(hasMultipleIssueAssigneesFeature),
+ isAnonymousSearchDisabled: parseBoolean(isAnonymousSearchDisabled),
+ isIssueRepositioningDisabled: parseBoolean(isIssueRepositioningDisabled),
+ isProject: parseBoolean(isProject),
+ isSignedIn: parseBoolean(isSignedIn),
+ jiraIntegrationPath,
+ newIssuePath,
+ releasesPath,
+ rssPath,
+ showNewIssueLink: parseBoolean(showNewIssueLink),
+ signInPath,
+ // For CsvImportExportButtons component
+ canEdit: parseBoolean(canEdit),
+ email,
+ exportCsvPath,
+ importCsvIssuesPath,
+ maxAttachmentSize,
+ projectImportJiraPath,
+ showExportButton: parseBoolean(hasAnyIssues),
+ showImportButton: parseBoolean(canImportIssues),
+ showLabel: !parseBoolean(hasAnyIssues),
+ // For IssuableByEmail component
+ emailsHelpPagePath,
+ initialEmail,
+ markdownHelpPath,
+ quickActionsHelpPath,
+ resetPath,
+ },
+ render: (createComponent) => createComponent(IssuesListApp),
+ });
+}
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..be8deb3fe97 100644
--- a/app/assets/javascripts/issues_list/queries/get_issues.query.graphql
+++ b/app/assets/javascripts/issues/list/queries/get_issues.query.graphql
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..1a345fd2877 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
diff --git a/app/assets/javascripts/issues_list/queries/get_issues_list_details.query.graphql b/app/assets/javascripts/issues/list/queries/get_issues_list_details.query.graphql
index a53dba8c7c8..a53dba8c7c8 100644
--- a/app/assets/javascripts/issues_list/queries/get_issues_list_details.query.graphql
+++ b/app/assets/javascripts/issues/list/queries/get_issues_list_details.query.graphql
diff --git a/app/assets/javascripts/issues_list/queries/issue.fragment.graphql b/app/assets/javascripts/issues/list/queries/issue.fragment.graphql
index 07dae3fd756..07dae3fd756 100644
--- a/app/assets/javascripts/issues_list/queries/issue.fragment.graphql
+++ b/app/assets/javascripts/issues/list/queries/issue.fragment.graphql
diff --git a/app/assets/javascripts/issues_list/queries/label.fragment.graphql b/app/assets/javascripts/issues/list/queries/label.fragment.graphql
index bb1d8f1ac9b..bb1d8f1ac9b 100644
--- a/app/assets/javascripts/issues_list/queries/label.fragment.graphql
+++ b/app/assets/javascripts/issues/list/queries/label.fragment.graphql
diff --git a/app/assets/javascripts/issues_list/queries/milestone.fragment.graphql b/app/assets/javascripts/issues/list/queries/milestone.fragment.graphql
index 3cdf69bf585..3cdf69bf585 100644
--- a/app/assets/javascripts/issues_list/queries/milestone.fragment.graphql
+++ b/app/assets/javascripts/issues/list/queries/milestone.fragment.graphql
diff --git a/app/assets/javascripts/issues_list/queries/reorder_issues.mutation.graphql b/app/assets/javascripts/issues/list/queries/reorder_issues.mutation.graphql
index 160026a4742..160026a4742 100644
--- a/app/assets/javascripts/issues_list/queries/reorder_issues.mutation.graphql
+++ b/app/assets/javascripts/issues/list/queries/reorder_issues.mutation.graphql
diff --git a/app/assets/javascripts/issues_list/queries/search_labels.query.graphql b/app/assets/javascripts/issues/list/queries/search_labels.query.graphql
index 44b57317161..44b57317161 100644
--- a/app/assets/javascripts/issues_list/queries/search_labels.query.graphql
+++ b/app/assets/javascripts/issues/list/queries/search_labels.query.graphql
diff --git a/app/assets/javascripts/issues_list/queries/search_milestones.query.graphql b/app/assets/javascripts/issues/list/queries/search_milestones.query.graphql
index e7eb08104a6..e7eb08104a6 100644
--- a/app/assets/javascripts/issues_list/queries/search_milestones.query.graphql
+++ b/app/assets/javascripts/issues/list/queries/search_milestones.query.graphql
diff --git a/app/assets/javascripts/issues_list/queries/search_projects.query.graphql b/app/assets/javascripts/issues/list/queries/search_projects.query.graphql
index bd2f9bc2340..bd2f9bc2340 100644
--- a/app/assets/javascripts/issues_list/queries/search_projects.query.graphql
+++ b/app/assets/javascripts/issues/list/queries/search_projects.query.graphql
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..92517ad35d0 100644
--- a/app/assets/javascripts/issues_list/queries/search_users.query.graphql
+++ b/app/assets/javascripts/issues/list/queries/search_users.query.graphql
diff --git a/app/assets/javascripts/issues_list/queries/user.fragment.graphql b/app/assets/javascripts/issues/list/queries/user.fragment.graphql
index 3e5bc0f7b93..3e5bc0f7b93 100644
--- a/app/assets/javascripts/issues_list/queries/user.fragment.graphql
+++ b/app/assets/javascripts/issues/list/queries/user.fragment.graphql
diff --git a/app/assets/javascripts/issues/list/utils.js b/app/assets/javascripts/issues/list/utils.js
new file mode 100644
index 00000000000..2919bbbfef8
--- /dev/null
+++ b/app/assets/javascripts/issues/list/utils.js
@@ -0,0 +1,261 @@
+import {
+ API_PARAM,
+ BLOCKING_ISSUES_ASC,
+ BLOCKING_ISSUES_DESC,
+ CREATED_ASC,
+ CREATED_DESC,
+ defaultPageSizeParams,
+ DUE_DATE_ASC,
+ DUE_DATE_DESC,
+ DUE_DATE_VALUES,
+ filters,
+ LABEL_PRIORITY_ASC,
+ LABEL_PRIORITY_DESC,
+ largePageSizeParams,
+ MILESTONE_DUE_ASC,
+ MILESTONE_DUE_DESC,
+ NORMAL_FILTER,
+ POPULARITY_ASC,
+ POPULARITY_DESC,
+ PRIORITY_ASC,
+ PRIORITY_DESC,
+ RELATIVE_POSITION_ASC,
+ SPECIAL_FILTER,
+ SPECIAL_FILTER_VALUES,
+ TITLE_ASC,
+ TITLE_DESC,
+ TOKEN_TYPE_ASSIGNEE,
+ TOKEN_TYPE_CONFIDENTIAL,
+ TOKEN_TYPE_ITERATION,
+ TOKEN_TYPE_MILESTONE,
+ TOKEN_TYPE_RELEASE,
+ TOKEN_TYPE_TYPE,
+ UPDATED_ASC,
+ UPDATED_DESC,
+ URL_PARAM,
+ urlSortParams,
+ WEIGHT_ASC,
+ WEIGHT_DESC,
+} from '~/issues/list/constants';
+import { isPositiveInteger } from '~/lib/utils/number_utils';
+import { __ } from '~/locale';
+import {
+ FILTERED_SEARCH_TERM,
+ OPERATOR_IS_NOT,
+} from '~/vue_shared/components/filtered_search_bar/constants';
+
+export const getInitialPageParams = (sortKey) =>
+ sortKey === RELATIVE_POSITION_ASC ? largePageSizeParams : defaultPageSizeParams;
+
+export const getSortKey = (sort) =>
+ Object.keys(urlSortParams).find((key) => urlSortParams[key] === sort);
+
+export const getDueDateValue = (value) => (DUE_DATE_VALUES.includes(value) ? value : undefined);
+
+export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature) => {
+ const sortOptions = [
+ {
+ id: 1,
+ title: __('Priority'),
+ sortDirection: {
+ ascending: PRIORITY_ASC,
+ descending: PRIORITY_DESC,
+ },
+ },
+ {
+ id: 2,
+ title: __('Created date'),
+ sortDirection: {
+ ascending: CREATED_ASC,
+ descending: CREATED_DESC,
+ },
+ },
+ {
+ id: 3,
+ title: __('Updated date'),
+ sortDirection: {
+ ascending: UPDATED_ASC,
+ descending: UPDATED_DESC,
+ },
+ },
+ {
+ id: 4,
+ title: __('Milestone due date'),
+ sortDirection: {
+ ascending: MILESTONE_DUE_ASC,
+ descending: MILESTONE_DUE_DESC,
+ },
+ },
+ {
+ id: 5,
+ title: __('Due date'),
+ sortDirection: {
+ ascending: DUE_DATE_ASC,
+ descending: DUE_DATE_DESC,
+ },
+ },
+ {
+ id: 6,
+ title: __('Popularity'),
+ sortDirection: {
+ ascending: POPULARITY_ASC,
+ descending: POPULARITY_DESC,
+ },
+ },
+ {
+ id: 7,
+ title: __('Label priority'),
+ sortDirection: {
+ ascending: LABEL_PRIORITY_ASC,
+ descending: LABEL_PRIORITY_DESC,
+ },
+ },
+ {
+ id: 8,
+ title: __('Manual'),
+ sortDirection: {
+ ascending: RELATIVE_POSITION_ASC,
+ descending: RELATIVE_POSITION_ASC,
+ },
+ },
+ {
+ id: 9,
+ title: __('Title'),
+ sortDirection: {
+ ascending: TITLE_ASC,
+ descending: TITLE_DESC,
+ },
+ },
+ ];
+
+ if (hasIssueWeightsFeature) {
+ sortOptions.push({
+ id: sortOptions.length + 1,
+ title: __('Weight'),
+ sortDirection: {
+ ascending: WEIGHT_ASC,
+ descending: WEIGHT_DESC,
+ },
+ });
+ }
+
+ if (hasBlockedIssuesFeature) {
+ sortOptions.push({
+ id: sortOptions.length + 1,
+ title: __('Blocking'),
+ sortDirection: {
+ ascending: BLOCKING_ISSUES_ASC,
+ descending: BLOCKING_ISSUES_DESC,
+ },
+ });
+ }
+
+ return sortOptions;
+};
+
+const tokenTypes = Object.keys(filters);
+
+const getUrlParams = (tokenType) =>
+ Object.values(filters[tokenType][URL_PARAM]).flatMap((filterObj) => Object.values(filterObj));
+
+const urlParamKeys = tokenTypes.flatMap(getUrlParams);
+
+const getTokenTypeFromUrlParamKey = (urlParamKey) =>
+ tokenTypes.find((tokenType) => getUrlParams(tokenType).includes(urlParamKey));
+
+const getOperatorFromUrlParamKey = (tokenType, urlParamKey) =>
+ Object.entries(filters[tokenType][URL_PARAM]).find(([, filterObj]) =>
+ Object.values(filterObj).includes(urlParamKey),
+ )[0];
+
+const convertToFilteredTokens = (locationSearch) =>
+ Array.from(new URLSearchParams(locationSearch).entries())
+ .filter(([key]) => urlParamKeys.includes(key))
+ .map(([key, data]) => {
+ const type = getTokenTypeFromUrlParamKey(key);
+ const operator = getOperatorFromUrlParamKey(type, key);
+ return {
+ type,
+ value: { data, operator },
+ };
+ });
+
+const convertToFilteredSearchTerms = (locationSearch) =>
+ new URLSearchParams(locationSearch)
+ .get('search')
+ ?.split(' ')
+ .map((word) => ({
+ type: FILTERED_SEARCH_TERM,
+ value: {
+ data: word,
+ },
+ })) || [];
+
+export const getFilterTokens = (locationSearch) => {
+ if (!locationSearch) {
+ return [];
+ }
+ const filterTokens = convertToFilteredTokens(locationSearch);
+ const searchTokens = convertToFilteredSearchTerms(locationSearch);
+ return filterTokens.concat(searchTokens);
+};
+
+const getFilterType = (data, tokenType = '') =>
+ SPECIAL_FILTER_VALUES.includes(data) ||
+ (tokenType === TOKEN_TYPE_ASSIGNEE && isPositiveInteger(data))
+ ? SPECIAL_FILTER
+ : NORMAL_FILTER;
+
+const wildcardTokens = [TOKEN_TYPE_ITERATION, TOKEN_TYPE_MILESTONE, TOKEN_TYPE_RELEASE];
+
+const isWildcardValue = (tokenType, value) =>
+ wildcardTokens.includes(tokenType) && SPECIAL_FILTER_VALUES.includes(value);
+
+const requiresUpperCaseValue = (tokenType, value) =>
+ tokenType === TOKEN_TYPE_TYPE || isWildcardValue(tokenType, value);
+
+const formatData = (token) => {
+ if (requiresUpperCaseValue(token.type, token.value.data)) {
+ return token.value.data.toUpperCase();
+ }
+ if (token.type === TOKEN_TYPE_CONFIDENTIAL) {
+ return token.value.data === 'yes';
+ }
+ return token.value.data;
+};
+
+export const convertToApiParams = (filterTokens) => {
+ const params = {};
+ const not = {};
+
+ filterTokens
+ .filter((token) => token.type !== FILTERED_SEARCH_TERM)
+ .forEach((token) => {
+ const filterType = getFilterType(token.value.data, token.type);
+ const field = filters[token.type][API_PARAM][filterType];
+ const obj = token.value.operator === OPERATOR_IS_NOT ? not : params;
+ const data = formatData(token);
+ Object.assign(obj, {
+ [field]: obj[field] ? [obj[field], data].flat() : data,
+ });
+ });
+
+ return Object.keys(not).length ? Object.assign(params, { not }) : params;
+};
+
+export const convertToUrlParams = (filterTokens) =>
+ filterTokens
+ .filter((token) => token.type !== FILTERED_SEARCH_TERM)
+ .reduce((acc, token) => {
+ const filterType = getFilterType(token.value.data, token.type);
+ const param = filters[token.type][URL_PARAM][token.value.operator]?.[filterType];
+ return Object.assign(acc, {
+ [param]: acc[param] ? [acc[param], token.value.data].flat() : token.value.data,
+ });
+ }, {});
+
+export const convertToSearchQuery = (filterTokens) =>
+ filterTokens
+ .filter((token) => token.type === FILTERED_SEARCH_TERM && token.value.data)
+ .map((token) => token.value.data)
+ .join(' ');
diff --git a/app/assets/javascripts/issues/manual_ordering.js b/app/assets/javascripts/issues/manual_ordering.js
index 9613246d6a6..c78505d0610 100644
--- a/app/assets/javascripts/issues/manual_ordering.js
+++ b/app/assets/javascripts/issues/manual_ordering.js
@@ -20,7 +20,7 @@ const updateIssue = (url, issueList, { move_before_id, move_after_id }) =>
});
});
-const initManualOrdering = (draggableSelector = 'li.issue') => {
+const initManualOrdering = () => {
const issueList = document.querySelector('.manual-ordering');
if (!issueList || !(gon.current_user_id > 0)) {
@@ -37,14 +37,14 @@ const initManualOrdering = (draggableSelector = 'li.issue') => {
group: {
name: 'issues',
},
- draggable: draggableSelector,
+ draggable: 'li.issue',
onStart: () => {
sortableStart();
},
onUpdate: (event) => {
const el = event.item;
- const url = el.getAttribute('url') || el.dataset.url;
+ const url = el.getAttribute('url');
const prev = el.previousElementSibling;
const next = el.nextElementSibling;
diff --git a/app/assets/javascripts/issues/new/index.js b/app/assets/javascripts/issues/new/index.js
index 59a7cbec627..f96cacf2595 100644
--- a/app/assets/javascripts/issues/new/index.js
+++ b/app/assets/javascripts/issues/new/index.js
@@ -5,8 +5,6 @@ import TitleSuggestions from './components/title_suggestions.vue';
import TypePopover from './components/type_popover.vue';
export function initTitleSuggestions() {
- Vue.use(VueApollo);
-
const el = document.getElementById('js-suggestions');
const issueTitle = document.getElementById('issue_title');
@@ -14,6 +12,8 @@ export function initTitleSuggestions() {
return undefined;
}
+ Vue.use(VueApollo);
+
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
});
diff --git a/app/assets/javascripts/issues/related_merge_requests/index.js b/app/assets/javascripts/issues/related_merge_requests/index.js
index ce33cf7df1d..5045f7e1a2a 100644
--- a/app/assets/javascripts/issues/related_merge_requests/index.js
+++ b/app/assets/javascripts/issues/related_merge_requests/index.js
@@ -2,23 +2,21 @@ import Vue from 'vue';
import RelatedMergeRequests from './components/related_merge_requests.vue';
import createStore from './store';
-export default function initRelatedMergeRequests() {
- const relatedMergeRequestsElement = document.querySelector('#js-related-merge-requests');
+export function initRelatedMergeRequests() {
+ const el = document.querySelector('#js-related-merge-requests');
- if (relatedMergeRequestsElement) {
- const { endpoint, projectPath, projectNamespace } = relatedMergeRequestsElement.dataset;
-
- // eslint-disable-next-line no-new
- new Vue({
- el: relatedMergeRequestsElement,
- components: {
- RelatedMergeRequests,
- },
- store: createStore(),
- render: (createElement) =>
- createElement('related-merge-requests', {
- props: { endpoint, projectNamespace, projectPath },
- }),
- });
+ if (!el) {
+ return undefined;
}
+
+ const { endpoint, projectPath, projectNamespace } = el.dataset;
+
+ return new Vue({
+ el,
+ store: createStore(),
+ render: (createElement) =>
+ createElement(RelatedMergeRequests, {
+ props: { endpoint, projectNamespace, projectPath },
+ }),
+ });
}
diff --git a/app/assets/javascripts/issues/sentry_error_stack_trace/index.js b/app/assets/javascripts/issues/sentry_error_stack_trace/index.js
deleted file mode 100644
index 8e9ee25e7a8..00000000000
--- a/app/assets/javascripts/issues/sentry_error_stack_trace/index.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import Vue from 'vue';
-import store from '~/error_tracking/store';
-import SentryErrorStackTrace from './components/sentry_error_stack_trace.vue';
-
-export default function initSentryErrorStacktrace() {
- const sentryErrorStackTraceEl = document.querySelector('#js-sentry-error-stack-trace');
- if (sentryErrorStackTraceEl) {
- const { issueStackTracePath } = sentryErrorStackTraceEl.dataset;
- // eslint-disable-next-line no-new
- new Vue({
- el: sentryErrorStackTraceEl,
- components: {
- SentryErrorStackTrace,
- },
- store,
- render: (createElement) =>
- createElement('sentry-error-stack-trace', {
- props: { issueStackTracePath },
- }),
- });
- }
-}
diff --git a/app/assets/javascripts/issues/show.js b/app/assets/javascripts/issues/show.js
deleted file mode 100644
index e43e56d7b4e..00000000000
--- a/app/assets/javascripts/issues/show.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import loadAwardsHandler from '~/awards_handler';
-import ShortcutsIssuable from '~/behaviors/shortcuts/shortcuts_issuable';
-import { initIssuableHeaderWarnings, initIssuableSidebar } from '~/issuable';
-import { IssuableType } from '~/vue_shared/issuable/show/constants';
-import Issue from '~/issues/issue';
-import { initIncidentApp, initIncidentHeaderActions } from '~/issues/show/incident';
-import { initIssuableApp, initIssueHeaderActions } from '~/issues/show/issue';
-import { parseIssuableData } from '~/issues/show/utils/parse_data';
-import initNotesApp from '~/notes';
-import { store } from '~/notes/stores';
-import initRelatedMergeRequestsApp from '~/issues/related_merge_requests';
-import initSentryErrorStackTraceApp from '~/issues/sentry_error_stack_trace';
-import ZenMode from '~/zen_mode';
-
-export default function initShowIssue() {
- initNotesApp();
-
- const initialDataEl = document.getElementById('js-issuable-app');
- const { issueType, ...issuableData } = parseIssuableData(initialDataEl);
-
- switch (issueType) {
- case IssuableType.Incident:
- initIncidentApp(issuableData);
- initIncidentHeaderActions(store);
- break;
- case IssuableType.Issue:
- initIssuableApp(issuableData, store);
- initIssueHeaderActions(store);
- break;
- default:
- initIssueHeaderActions(store);
- break;
- }
-
- initIssuableHeaderWarnings(store);
- initSentryErrorStackTraceApp();
- initRelatedMergeRequestsApp();
-
- import(/* webpackChunkName: 'design_management' */ '~/design_management')
- .then((module) => module.default())
- .catch(() => {});
-
- new ZenMode(); // eslint-disable-line no-new
-
- if (issueType !== IssuableType.TestCase) {
- const awardEmojiEl = document.getElementById('js-vue-awards-block');
-
- new Issue(); // eslint-disable-line no-new
- new ShortcutsIssuable(); // eslint-disable-line no-new
- initIssuableSidebar();
- if (awardEmojiEl) {
- import('~/emoji/awards_app')
- .then((m) => m.default(awardEmojiEl))
- .catch(() => {});
- } else {
- loadAwardsHandler();
- }
- }
-}
diff --git a/app/assets/javascripts/issues/show/components/app.vue b/app/assets/javascripts/issues/show/components/app.vue
index eeaf865a35f..0490728c6bc 100644
--- a/app/assets/javascripts/issues/show/components/app.vue
+++ b/app/assets/javascripts/issues/show/components/app.vue
@@ -6,7 +6,7 @@ import { IssuableStatus, IssuableStatusText, IssuableType } from '~/issues/const
import Poll from '~/lib/utils/poll';
import { visitUrl } from '~/lib/utils/url_utility';
import { __, sprintf } from '~/locale';
-import { IssueTypePath, IncidentTypePath, IncidentType, POLLING_DELAY } from '../constants';
+import { ISSUE_TYPE_PATH, INCIDENT_TYPE_PATH, INCIDENT_TYPE, POLLING_DELAY } from '../constants';
import eventHub from '../event_hub';
import getIssueStateQuery from '../queries/get_issue_state.query.graphql';
import Service from '../services/index';
@@ -378,15 +378,15 @@ export default {
.then((data) => {
if (
!window.location.pathname.includes(data.web_url) &&
- issueState.issueType !== IncidentType
+ issueState.issueType !== INCIDENT_TYPE
) {
visitUrl(data.web_url);
}
if (issueState.isDirty) {
const URI =
- issueState.issueType === IncidentType
- ? data.web_url.replace(IssueTypePath, IncidentTypePath)
+ issueState.issueType === INCIDENT_TYPE
+ ? data.web_url.replace(ISSUE_TYPE_PATH, INCIDENT_TYPE_PATH)
: data.web_url;
visitUrl(URI);
}
diff --git a/app/assets/javascripts/issues/show/components/fields/type.vue b/app/assets/javascripts/issues/show/components/fields/type.vue
index 9110a6924b4..75d0b9e5e76 100644
--- a/app/assets/javascripts/issues/show/components/fields/type.vue
+++ b/app/assets/javascripts/issues/show/components/fields/type.vue
@@ -2,7 +2,7 @@
import { GlFormGroup, GlDropdown, GlDropdownItem, GlIcon } from '@gitlab/ui';
import { capitalize } from 'lodash';
import { __ } from '~/locale';
-import { IssuableTypes, IncidentType } from '../../constants';
+import { issuableTypes, INCIDENT_TYPE } from '../../constants';
import getIssueStateQuery from '../../queries/get_issue_state.query.graphql';
import updateIssueStateMutation from '../../queries/update_issue_state.mutation.graphql';
@@ -12,7 +12,7 @@ export const i18n = {
export default {
i18n,
- IssuableTypes,
+ issuableTypes,
components: {
GlFormGroup,
GlIcon,
@@ -45,7 +45,7 @@ export default {
return capitalize(issueType);
},
shouldShowIncident() {
- return this.issueType === IncidentType || this.canCreateIncident;
+ return this.issueType === INCIDENT_TYPE || this.canCreateIncident;
},
},
methods: {
@@ -59,7 +59,7 @@ export default {
});
},
isShown(type) {
- return type.value !== IncidentType || this.shouldShowIncident;
+ return type.value !== INCIDENT_TYPE || this.shouldShowIncident;
},
},
};
@@ -81,7 +81,7 @@ export default {
toggle-class="dropdown-menu-toggle"
>
<gl-dropdown-item
- v-for="type in $options.IssuableTypes"
+ v-for="type in $options.issuableTypes"
v-show="isShown(type)"
:key="type.value"
:is-checked="issueState.issueType === type.value"
diff --git a/app/assets/javascripts/issues/show/components/header_actions.vue b/app/assets/javascripts/issues/show/components/header_actions.vue
index 700ef92a0f3..8ba08472ea0 100644
--- a/app/assets/javascripts/issues/show/components/header_actions.vue
+++ b/app/assets/javascripts/issues/show/components/header_actions.vue
@@ -11,9 +11,8 @@ import {
import { mapActions, mapGetters, mapState } from 'vuex';
import createFlash, { FLASH_TYPES } from '~/flash';
import { EVENT_ISSUABLE_VUE_APP_CHANGE } from '~/issuable/constants';
-import { IssuableType } from '~/vue_shared/issuable/show/constants';
-import { IssuableStatus } from '~/issues/constants';
-import { IssueStateEvent } from '~/issues/show/constants';
+import { IssuableStatus, IssueType } from '~/issues/constants';
+import { ISSUE_STATE_EVENT_CLOSE, ISSUE_STATE_EVENT_REOPEN } from '~/issues/show/constants';
import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
import { visitUrl } from '~/lib/utils/url_utility';
import { s__, __, sprintf } from '~/locale';
@@ -83,7 +82,7 @@ export default {
default: '',
},
issueType: {
- default: IssuableType.Issue,
+ default: IssueType.Issue,
},
newIssuePath: {
default: '',
@@ -106,8 +105,8 @@ export default {
},
issueTypeText() {
const issueTypeTexts = {
- [IssuableType.Issue]: s__('HeaderAction|issue'),
- [IssuableType.Incident]: s__('HeaderAction|incident'),
+ [IssueType.Issue]: s__('HeaderAction|issue'),
+ [IssueType.Incident]: s__('HeaderAction|incident'),
};
return issueTypeTexts[this.issueType] ?? this.issueType;
@@ -163,7 +162,7 @@ export default {
input: {
iid: this.iid.toString(),
projectPath: this.projectPath,
- stateEvent: this.isClosed ? IssueStateEvent.Reopen : IssueStateEvent.Close,
+ stateEvent: this.isClosed ? ISSUE_STATE_EVENT_REOPEN : ISSUE_STATE_EVENT_CLOSE,
},
},
})
diff --git a/app/assets/javascripts/issues/sentry_error_stack_trace/components/sentry_error_stack_trace.vue b/app/assets/javascripts/issues/show/components/sentry_error_stack_trace.vue
index 1530e9a15b5..1530e9a15b5 100644
--- a/app/assets/javascripts/issues/sentry_error_stack_trace/components/sentry_error_stack_trace.vue
+++ b/app/assets/javascripts/issues/show/components/sentry_error_stack_trace.vue
diff --git a/app/assets/javascripts/issues/show/constants.js b/app/assets/javascripts/issues/show/constants.js
index 35f3bcdad70..a100aaf88ad 100644
--- a/app/assets/javascripts/issues/show/constants.js
+++ b/app/assets/javascripts/issues/show/constants.js
@@ -1,22 +1,20 @@
import { __ } from '~/locale';
-export const IssueStateEvent = {
- Close: 'CLOSE',
- Reopen: 'REOPEN',
-};
-
-export const STATUS_PAGE_PUBLISHED = __('Published on status page');
+export const INCIDENT_TYPE = 'incident';
+export const INCIDENT_TYPE_PATH = 'issues/incident';
+export const ISSUE_STATE_EVENT_CLOSE = 'CLOSE';
+export const ISSUE_STATE_EVENT_REOPEN = 'REOPEN';
+export const ISSUE_TYPE_PATH = 'issues';
export const JOIN_ZOOM_MEETING = __('Join Zoom meeting');
+export const POLLING_DELAY = 2000;
+export const STATUS_PAGE_PUBLISHED = __('Published on status page');
-export const IssuableTypes = [
+export const issuableTypes = [
{ value: 'issue', text: __('Issue'), icon: 'issue-type-issue' },
{ value: 'incident', text: __('Incident'), icon: 'issue-type-incident' },
];
-export const IssueTypePath = 'issues';
-export const IncidentTypePath = 'issues/incident';
-export const IncidentType = 'incident';
-
-export const issueState = { issueType: undefined, isDirty: false };
-
-export const POLLING_DELAY = 2000;
+export const issueState = {
+ issueType: undefined,
+ isDirty: false,
+};
diff --git a/app/assets/javascripts/issues/show/incident.js b/app/assets/javascripts/issues/show/incident.js
deleted file mode 100644
index a260c31e1da..00000000000
--- a/app/assets/javascripts/issues/show/incident.js
+++ /dev/null
@@ -1,101 +0,0 @@
-import Vue from 'vue';
-import { parseBoolean } from '~/lib/utils/common_utils';
-import issuableApp from './components/app.vue';
-import incidentTabs from './components/incidents/incident_tabs.vue';
-import { issueState, IncidentType } from './constants';
-import apolloProvider from './graphql';
-import getIssueStateQuery from './queries/get_issue_state.query.graphql';
-import HeaderActions from './components/header_actions.vue';
-
-const bootstrapApollo = (state = {}) => {
- return apolloProvider.clients.defaultClient.cache.writeQuery({
- query: getIssueStateQuery,
- data: {
- issueState: state,
- },
- });
-};
-
-export function initIncidentApp(issuableData = {}) {
- const el = document.getElementById('js-issuable-app');
-
- if (!el) {
- return undefined;
- }
-
- bootstrapApollo({ ...issueState, issueType: el.dataset.issueType });
-
- const {
- canCreateIncident,
- canUpdate,
- iid,
- projectNamespace,
- projectPath,
- projectId,
- slaFeatureAvailable,
- uploadMetricsFeatureAvailable,
- } = issuableData;
-
- const fullPath = `${projectNamespace}/${projectPath}`;
-
- return new Vue({
- el,
- apolloProvider,
- components: {
- issuableApp,
- },
- provide: {
- issueType: IncidentType,
- canCreateIncident,
- canUpdate,
- fullPath,
- iid,
- projectId,
- slaFeatureAvailable: parseBoolean(slaFeatureAvailable),
- uploadMetricsFeatureAvailable: parseBoolean(uploadMetricsFeatureAvailable),
- },
- render(createElement) {
- return createElement('issuable-app', {
- props: {
- ...issuableData,
- descriptionComponent: incidentTabs,
- showTitleBorder: false,
- },
- });
- },
- });
-}
-
-export function initIncidentHeaderActions(store) {
- const el = document.querySelector('.js-issue-header-actions');
-
- if (!el) {
- return undefined;
- }
-
- bootstrapApollo({ ...issueState, issueType: el.dataset.issueType });
-
- return new Vue({
- el,
- apolloProvider,
- store,
- provide: {
- canCreateIssue: parseBoolean(el.dataset.canCreateIncident),
- canDestroyIssue: parseBoolean(el.dataset.canDestroyIssue),
- canPromoteToEpic: parseBoolean(el.dataset.canPromoteToEpic),
- canReopenIssue: parseBoolean(el.dataset.canReopenIssue),
- canReportSpam: parseBoolean(el.dataset.canReportSpam),
- canUpdateIssue: parseBoolean(el.dataset.canUpdateIssue),
- iid: el.dataset.iid,
- isIssueAuthor: parseBoolean(el.dataset.isIssueAuthor),
- issuePath: el.dataset.issuePath,
- issueType: el.dataset.issueType,
- newIssuePath: el.dataset.newIssuePath,
- projectPath: el.dataset.projectPath,
- projectId: el.dataset.projectId,
- reportAbusePath: el.dataset.reportAbusePath,
- submitAsSpamPath: el.dataset.submitAsSpamPath,
- },
- render: (createElement) => createElement(HeaderActions),
- });
-}
diff --git a/app/assets/javascripts/issues/show/index.js b/app/assets/javascripts/issues/show/index.js
new file mode 100644
index 00000000000..7f5a0e32f72
--- /dev/null
+++ b/app/assets/javascripts/issues/show/index.js
@@ -0,0 +1,161 @@
+import Vue from 'vue';
+import { mapGetters } from 'vuex';
+import errorTrackingStore from '~/error_tracking/store';
+import { parseBoolean } from '~/lib/utils/common_utils';
+import { scrollToTargetOnResize } from '~/lib/utils/resize_observer';
+import IssueApp from './components/app.vue';
+import HeaderActions from './components/header_actions.vue';
+import IncidentTabs from './components/incidents/incident_tabs.vue';
+import SentryErrorStackTrace from './components/sentry_error_stack_trace.vue';
+import { INCIDENT_TYPE, issueState } from './constants';
+import apolloProvider from './graphql';
+import getIssueStateQuery from './queries/get_issue_state.query.graphql';
+
+const bootstrapApollo = (state = {}) => {
+ return apolloProvider.clients.defaultClient.cache.writeQuery({
+ query: getIssueStateQuery,
+ data: {
+ issueState: state,
+ },
+ });
+};
+
+export function initIncidentApp(issueData = {}) {
+ const el = document.getElementById('js-issuable-app');
+
+ if (!el) {
+ return undefined;
+ }
+
+ bootstrapApollo({ ...issueState, issueType: el.dataset.issueType });
+
+ const {
+ canCreateIncident,
+ canUpdate,
+ iid,
+ projectNamespace,
+ projectPath,
+ projectId,
+ slaFeatureAvailable,
+ uploadMetricsFeatureAvailable,
+ } = issueData;
+
+ const fullPath = `${projectNamespace}/${projectPath}`;
+
+ return new Vue({
+ el,
+ apolloProvider,
+ provide: {
+ issueType: INCIDENT_TYPE,
+ canCreateIncident,
+ canUpdate,
+ fullPath,
+ iid,
+ projectId,
+ slaFeatureAvailable: parseBoolean(slaFeatureAvailable),
+ uploadMetricsFeatureAvailable: parseBoolean(uploadMetricsFeatureAvailable),
+ },
+ render(createElement) {
+ return createElement(IssueApp, {
+ props: {
+ ...issueData,
+ descriptionComponent: IncidentTabs,
+ showTitleBorder: false,
+ },
+ });
+ },
+ });
+}
+
+export function initIssueApp(issueData, store) {
+ const el = document.getElementById('js-issuable-app');
+
+ if (!el) {
+ return undefined;
+ }
+
+ if (gon?.features?.fixCommentScroll) {
+ scrollToTargetOnResize();
+ }
+
+ bootstrapApollo({ ...issueState, issueType: el.dataset.issueType });
+
+ const { canCreateIncident, ...issueProps } = issueData;
+
+ return new Vue({
+ el,
+ apolloProvider,
+ store,
+ provide: {
+ canCreateIncident,
+ },
+ computed: {
+ ...mapGetters(['getNoteableData']),
+ },
+ render(createElement) {
+ return createElement(IssueApp, {
+ props: {
+ ...issueProps,
+ isConfidential: this.getNoteableData?.confidential,
+ isLocked: this.getNoteableData?.discussion_locked,
+ issuableStatus: this.getNoteableData?.state,
+ id: this.getNoteableData?.id,
+ },
+ });
+ },
+ });
+}
+
+export function initHeaderActions(store, type = '') {
+ const el = document.querySelector('.js-issue-header-actions');
+
+ if (!el) {
+ return undefined;
+ }
+
+ bootstrapApollo({ ...issueState, issueType: el.dataset.issueType });
+
+ const canCreate =
+ type === INCIDENT_TYPE ? el.dataset.canCreateIncident : el.dataset.canCreateIssue;
+
+ return new Vue({
+ el,
+ apolloProvider,
+ store,
+ provide: {
+ canCreateIssue: parseBoolean(canCreate),
+ canDestroyIssue: parseBoolean(el.dataset.canDestroyIssue),
+ canPromoteToEpic: parseBoolean(el.dataset.canPromoteToEpic),
+ canReopenIssue: parseBoolean(el.dataset.canReopenIssue),
+ canReportSpam: parseBoolean(el.dataset.canReportSpam),
+ canUpdateIssue: parseBoolean(el.dataset.canUpdateIssue),
+ iid: el.dataset.iid,
+ isIssueAuthor: parseBoolean(el.dataset.isIssueAuthor),
+ issuePath: el.dataset.issuePath,
+ issueType: el.dataset.issueType,
+ newIssuePath: el.dataset.newIssuePath,
+ projectPath: el.dataset.projectPath,
+ projectId: el.dataset.projectId,
+ reportAbusePath: el.dataset.reportAbusePath,
+ submitAsSpamPath: el.dataset.submitAsSpamPath,
+ },
+ render: (createElement) => createElement(HeaderActions),
+ });
+}
+
+export function initSentryErrorStackTrace() {
+ const el = document.querySelector('#js-sentry-error-stack-trace');
+
+ if (!el) {
+ return undefined;
+ }
+
+ const { issueStackTracePath } = el.dataset;
+
+ return new Vue({
+ el,
+ store: errorTrackingStore,
+ render: (createElement) =>
+ createElement(SentryErrorStackTrace, { props: { issueStackTracePath } }),
+ });
+}
diff --git a/app/assets/javascripts/issues/show/issue.js b/app/assets/javascripts/issues/show/issue.js
deleted file mode 100644
index 60e90934af8..00000000000
--- a/app/assets/javascripts/issues/show/issue.js
+++ /dev/null
@@ -1,86 +0,0 @@
-import Vue from 'vue';
-import { mapGetters } from 'vuex';
-import { parseBoolean } from '~/lib/utils/common_utils';
-import IssuableApp from './components/app.vue';
-import HeaderActions from './components/header_actions.vue';
-import { issueState } from './constants';
-import apolloProvider from './graphql';
-import getIssueStateQuery from './queries/get_issue_state.query.graphql';
-
-const bootstrapApollo = (state = {}) => {
- return apolloProvider.clients.defaultClient.cache.writeQuery({
- query: getIssueStateQuery,
- data: {
- issueState: state,
- },
- });
-};
-
-export function initIssuableApp(issuableData, store) {
- const el = document.getElementById('js-issuable-app');
-
- if (!el) {
- return undefined;
- }
-
- bootstrapApollo({ ...issueState, issueType: el.dataset.issueType });
-
- const { canCreateIncident, ...issuableProps } = issuableData;
-
- return new Vue({
- el,
- apolloProvider,
- store,
- provide: {
- canCreateIncident,
- },
- computed: {
- ...mapGetters(['getNoteableData']),
- },
- render(createElement) {
- return createElement(IssuableApp, {
- props: {
- ...issuableProps,
- isConfidential: this.getNoteableData?.confidential,
- isLocked: this.getNoteableData?.discussion_locked,
- issuableStatus: this.getNoteableData?.state,
- id: this.getNoteableData?.id,
- },
- });
- },
- });
-}
-
-export function initIssueHeaderActions(store) {
- const el = document.querySelector('.js-issue-header-actions');
-
- if (!el) {
- return undefined;
- }
-
- bootstrapApollo({ ...issueState, issueType: el.dataset.issueType });
-
- return new Vue({
- el,
- apolloProvider,
- store,
- provide: {
- canCreateIssue: parseBoolean(el.dataset.canCreateIssue),
- canDestroyIssue: parseBoolean(el.dataset.canDestroyIssue),
- canPromoteToEpic: parseBoolean(el.dataset.canPromoteToEpic),
- canReopenIssue: parseBoolean(el.dataset.canReopenIssue),
- canReportSpam: parseBoolean(el.dataset.canReportSpam),
- canUpdateIssue: parseBoolean(el.dataset.canUpdateIssue),
- iid: el.dataset.iid,
- isIssueAuthor: parseBoolean(el.dataset.isIssueAuthor),
- issuePath: el.dataset.issuePath,
- issueType: el.dataset.issueType,
- newIssuePath: el.dataset.newIssuePath,
- projectPath: el.dataset.projectPath,
- projectId: el.dataset.projectId,
- reportAbusePath: el.dataset.reportAbusePath,
- submitAsSpamPath: el.dataset.submitAsSpamPath,
- },
- render: (createElement) => createElement(HeaderActions),
- });
-}
diff --git a/app/assets/javascripts/issues_list/components/issuable.vue b/app/assets/javascripts/issues_list/components/issuable.vue
deleted file mode 100644
index 6476d5be38c..00000000000
--- a/app/assets/javascripts/issues_list/components/issuable.vue
+++ /dev/null
@@ -1,441 +0,0 @@
-<script>
-/*
- * This is tightly coupled to projects/issues/_issue.html.haml,
- * any changes done to the haml need to be reflected here.
- */
-
-// TODO: need to move this component to graphql - https://gitlab.com/gitlab-org/gitlab/-/issues/221246
-import jiraLogo from '@gitlab/svgs/dist/illustrations/logos/jira.svg';
-import {
- GlLink,
- GlTooltipDirective as GlTooltip,
- GlSprintf,
- GlLabel,
- GlIcon,
- GlSafeHtmlDirective as SafeHtml,
-} from '@gitlab/ui';
-import { escape, isNumber } from 'lodash';
-import { isScopedLabel } from '~/lib/utils/common_utils';
-import {
- dateInWords,
- formatDate,
- getDayDifference,
- getTimeago,
- timeFor,
- newDateAsLocaleTime,
-} from '~/lib/utils/datetime_utility';
-import { convertToCamelCase } from '~/lib/utils/text_utility';
-import { mergeUrlParams, setUrlFragment, isExternal } from '~/lib/utils/url_utility';
-import { sprintf, __ } from '~/locale';
-import initUserPopovers from '~/user_popovers';
-import IssueAssignees from '~/issuable/components/issue_assignees.vue';
-
-export default {
- i18n: {
- openedAgo: __('created %{timeAgoString} by %{user}'),
- openedAgoJira: __('created %{timeAgoString} by %{user} in Jira'),
- openedAgoServiceDesk: __('created %{timeAgoString} by %{email} via %{user}'),
- },
- components: {
- IssueAssignees,
- GlLink,
- GlLabel,
- GlIcon,
- GlSprintf,
- IssueHealthStatus: () =>
- import('ee_component/related_items_tree/components/issue_health_status.vue'),
- },
- directives: {
- GlTooltip,
- SafeHtml,
- },
- inject: ['scopedLabelsAvailable'],
- props: {
- issuable: {
- type: Object,
- required: true,
- },
- isBulkEditing: {
- type: Boolean,
- required: false,
- default: false,
- },
- selected: {
- type: Boolean,
- required: false,
- default: false,
- },
- baseUrl: {
- type: String,
- required: false,
- default() {
- return window.location.href;
- },
- },
- },
- data() {
- return {
- jiraLogo,
- };
- },
- computed: {
- milestoneLink() {
- const { title } = this.issuable.milestone;
-
- return this.issuableLink({ milestone_title: title });
- },
- hasWeight() {
- return isNumber(this.issuable.weight);
- },
- dueDate() {
- return this.issuable.due_date ? newDateAsLocaleTime(this.issuable.due_date) : undefined;
- },
- dueDateWords() {
- return this.dueDate ? dateInWords(this.dueDate, true) : undefined;
- },
- isOverdue() {
- return this.dueDate ? this.dueDate < new Date() : false;
- },
- isClosed() {
- return this.issuable.state === 'closed';
- },
- isJiraIssue() {
- return this.issuable.external_tracker === 'jira';
- },
- webUrl() {
- return this.issuable.gitlab_web_url || this.issuable.web_url;
- },
- isIssuableUrlExternal() {
- return isExternal(this.webUrl);
- },
- linkTarget() {
- return this.isIssuableUrlExternal ? '_blank' : null;
- },
- issueCreatedToday() {
- return getDayDifference(new Date(this.issuable.created_at), new Date()) < 1;
- },
- labelIdsString() {
- return JSON.stringify(this.issuable.labels.map((l) => l.id));
- },
- milestoneDueDate() {
- const { due_date: dueDate } = this.issuable.milestone || {};
-
- return dueDate ? newDateAsLocaleTime(dueDate) : undefined;
- },
- milestoneTooltipText() {
- if (this.milestoneDueDate) {
- return sprintf(__('%{primary} (%{secondary})'), {
- primary: formatDate(this.milestoneDueDate, 'mmm d, yyyy'),
- secondary: timeFor(this.milestoneDueDate),
- });
- }
- return __('Milestone');
- },
- issuableAuthor() {
- return this.issuable.author;
- },
- issuableCreatedAt() {
- return getTimeago().format(this.issuable.created_at);
- },
- popoverDataAttrs() {
- const { id, username, name, avatar_url } = this.issuableAuthor;
-
- return {
- 'data-user-id': id,
- 'data-username': username,
- 'data-name': name,
- 'data-avatar-url': avatar_url,
- };
- },
- referencePath() {
- return this.issuable.references.relative;
- },
- updatedDateString() {
- return formatDate(new Date(this.issuable.updated_at), 'mmm d, yyyy h:MMtt');
- },
- updatedDateAgo() {
- // snake_case because it's the same i18n string as the HAML view
- return sprintf(__('updated %{time_ago}'), {
- time_ago: escape(getTimeago().format(this.issuable.updated_at)),
- });
- },
- issuableMeta() {
- return [
- {
- key: 'merge-requests',
- visible: this.issuable.merge_requests_count > 0,
- value: this.issuable.merge_requests_count,
- title: __('Related merge requests'),
- dataTestId: 'merge-requests',
- class: 'js-merge-requests',
- icon: 'merge-request',
- },
- {
- key: 'upvotes',
- visible: this.issuable.upvotes > 0,
- value: this.issuable.upvotes,
- title: __('Upvotes'),
- dataTestId: 'upvotes',
- class: 'js-upvotes issuable-upvotes',
- icon: 'thumb-up',
- },
- {
- key: 'downvotes',
- visible: this.issuable.downvotes > 0,
- value: this.issuable.downvotes,
- title: __('Downvotes'),
- dataTestId: 'downvotes',
- class: 'js-downvotes issuable-downvotes',
- icon: 'thumb-down',
- },
- {
- key: 'blocking-issues',
- visible: this.issuable.blocking_issues_count > 0,
- value: this.issuable.blocking_issues_count,
- title: __('Blocking issues'),
- dataTestId: 'blocking-issues',
- href: setUrlFragment(this.webUrl, 'related-issues'),
- icon: 'issue-block',
- },
- {
- key: 'comments-count',
- visible: !this.isJiraIssue,
- value: this.issuable.user_notes_count,
- title: __('Comments'),
- dataTestId: 'notes-count',
- href: setUrlFragment(this.webUrl, 'notes'),
- class: { 'no-comments': !this.issuable.user_notes_count, 'issuable-comments': true },
- icon: 'comments',
- },
- ];
- },
- healthStatus() {
- return convertToCamelCase(this.issuable.health_status);
- },
- openedMessage() {
- if (this.isJiraIssue) return this.$options.i18n.openedAgoJira;
- if (this.issuable.service_desk_reply_to) return this.$options.i18n.openedAgoServiceDesk;
- return this.$options.i18n.openedAgo;
- },
- },
- mounted() {
- // TODO: Refactor user popover to use its own component instead of
- // spawning event listeners on Vue-rendered elements.
- initUserPopovers([this.$refs.openedAgoByContainer.$el]);
- },
- methods: {
- issuableLink(params) {
- return mergeUrlParams(params, this.baseUrl);
- },
- isScoped({ name }) {
- return isScopedLabel({ title: name }) && this.scopedLabelsAvailable;
- },
- labelHref({ name }) {
- if (this.isJiraIssue) {
- return this.issuableLink({ 'labels[]': name });
- }
-
- return this.issuableLink({ 'label_name[]': name });
- },
- onSelect(ev) {
- this.$emit('select', {
- issuable: this.issuable,
- selected: ev.target.checked,
- });
- },
- issuableMetaComponent(href) {
- return href ? 'gl-link' : 'span';
- },
- },
-
- confidentialTooltipText: __('Confidential'),
-};
-</script>
-<template>
- <li
- :id="`issue_${issuable.id}`"
- class="issue"
- :class="{ today: issueCreatedToday, closed: isClosed }"
- :data-id="issuable.id"
- :data-labels="labelIdsString"
- :data-url="webUrl"
- data-qa-selector="issue_container"
- :data-qa-issue-title="issuable.title"
- >
- <div class="gl-display-flex">
- <!-- Bulk edit checkbox -->
- <div v-if="isBulkEditing" class="gl-mr-3">
- <input
- :id="`selected_issue_${issuable.id}`"
- :checked="selected"
- class="selected-issuable"
- type="checkbox"
- :data-id="issuable.id"
- @input="onSelect"
- />
- </div>
-
- <!-- Issuable info container -->
- <!-- Issuable main info -->
- <div class="gl-flex-grow-1">
- <div class="title">
- <span class="issue-title-text">
- <gl-icon
- v-if="issuable.confidential"
- v-gl-tooltip
- name="eye-slash"
- class="gl-vertical-align-text-bottom"
- :size="16"
- :title="$options.confidentialTooltipText"
- :aria-label="$options.confidentialTooltipText"
- />
- <gl-link
- :href="webUrl"
- :target="linkTarget"
- data-testid="issuable-title"
- data-qa-selector="issue_link"
- >
- {{ issuable.title }}
- <gl-icon
- v-if="isIssuableUrlExternal"
- name="external-link"
- class="gl-vertical-align-text-bottom gl-ml-2"
- />
- </gl-link>
- </span>
- <span
- v-if="issuable.has_tasks"
- class="gl-ml-2 task-status gl-display-none d-sm-inline-block"
- >{{ issuable.task_status }}</span
- >
- </div>
-
- <div class="issuable-info">
- <span class="js-ref-path gl-mr-4 mr-sm-0">
- <span
- v-if="isJiraIssue"
- v-safe-html="jiraLogo"
- class="svg-container logo-container"
- data-testid="jira-logo"
- ></span>
- {{ referencePath }}
- </span>
-
- <span data-testid="openedByMessage" class="gl-display-none d-sm-inline-block gl-mr-4">
- &middot;
- <gl-sprintf :message="openedMessage">
- <template #timeAgoString>
- <span>{{ issuableCreatedAt }}</span>
- </template>
- <template #user>
- <gl-link
- ref="openedAgoByContainer"
- v-bind="popoverDataAttrs"
- :href="issuableAuthor.web_url"
- :target="linkTarget"
- >{{ issuableAuthor.name }}</gl-link
- >
- </template>
- <template #email>
- <span>{{ issuable.service_desk_reply_to }}</span>
- </template>
- </gl-sprintf>
- </span>
-
- <gl-link
- v-if="issuable.milestone"
- v-gl-tooltip
- class="gl-display-none d-sm-inline-block gl-mr-4 js-milestone milestone"
- :href="milestoneLink"
- :title="milestoneTooltipText"
- >
- <gl-icon name="clock" class="s16 gl-vertical-align-text-bottom" />
- {{ issuable.milestone.title }}
- </gl-link>
-
- <span
- v-if="dueDate"
- v-gl-tooltip
- class="gl-display-none d-sm-inline-block gl-mr-4 js-due-date"
- :class="{ cred: isOverdue }"
- :title="__('Due date')"
- >
- <gl-icon name="calendar" />
- {{ dueDateWords }}
- </span>
-
- <span
- v-if="hasWeight"
- v-gl-tooltip
- :title="__('Weight')"
- class="gl-display-none d-sm-inline-block gl-mr-4"
- data-testid="weight"
- data-qa-selector="issuable_weight_content"
- >
- <gl-icon name="weight" class="align-text-bottom" />
- {{ issuable.weight }}
- </span>
-
- <issue-health-status
- v-if="issuable.health_status"
- :health-status="healthStatus"
- class="gl-mr-4 issuable-tag-valign"
- />
-
- <gl-label
- v-for="label in issuable.labels"
- :key="label.id"
- data-qa-selector="issuable-label"
- :target="labelHref(label)"
- :background-color="label.color"
- :description="label.description"
- :color="label.text_color"
- :title="label.name"
- :scoped="isScoped(label)"
- size="sm"
- class="gl-mr-2 issuable-tag-valign"
- >{{ label.name }}</gl-label
- >
- </div>
- </div>
-
- <!-- Issuable meta -->
- <div
- class="gl-flex-shrink-0 gl-display-flex gl-flex-direction-column align-items-end gl-justify-content-center"
- >
- <div class="controls gl-display-flex">
- <span v-if="isJiraIssue" data-testid="issuable-status">{{ issuable.status }}</span>
- <span v-else-if="isClosed" class="issuable-status">{{ __('CLOSED') }}</span>
-
- <issue-assignees
- :assignees="issuable.assignees"
- class="gl-align-items-center gl-display-flex gl-ml-3"
- :icon-size="16"
- img-css-classes="gl-mr-2!"
- :max-visible="4"
- />
-
- <template v-for="meta in issuableMeta">
- <span
- v-if="meta.visible"
- :key="meta.key"
- v-gl-tooltip
- class="gl-display-none gl-sm-display-flex gl-align-items-center gl-ml-3"
- :class="meta.class"
- :data-testid="meta.dataTestId"
- :title="meta.title"
- >
- <component :is="issuableMetaComponent(meta.href)" :href="meta.href">
- <gl-icon v-if="meta.icon" :name="meta.icon" />
- {{ meta.value }}
- </component>
- </span>
- </template>
- </div>
- <div v-gl-tooltip class="issuable-updated-at" :title="updatedDateString">
- {{ updatedDateAgo }}
- </div>
- </div>
- </div>
- </li>
-</template>
diff --git a/app/assets/javascripts/issues_list/components/issuables_list_app.vue b/app/assets/javascripts/issues_list/components/issuables_list_app.vue
deleted file mode 100644
index 71136bf0159..00000000000
--- a/app/assets/javascripts/issues_list/components/issuables_list_app.vue
+++ /dev/null
@@ -1,426 +0,0 @@
-<script>
-import {
- GlEmptyState,
- GlPagination,
- GlDeprecatedSkeletonLoading as GlSkeletonLoading,
- GlSafeHtmlDirective as SafeHtml,
-} from '@gitlab/ui';
-import { toNumber, omit } from 'lodash';
-import createFlash from '~/flash';
-import axios from '~/lib/utils/axios_utils';
-import { scrollToElement, historyPushState } from '~/lib/utils/common_utils';
-import { setUrlParams, queryToObject, getParameterByName } from '~/lib/utils/url_utility';
-import { __ } from '~/locale';
-import initManualOrdering from '~/issues/manual_ordering';
-import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
-import {
- sortOrderMap,
- availableSortOptionsJira,
- RELATIVE_POSITION,
- PAGE_SIZE,
- PAGE_SIZE_MANUAL,
- LOADING_LIST_ITEMS_LENGTH,
-} from '../constants';
-import issuableEventHub from '../eventhub';
-import { emptyStateHelper } from '../service_desk_helper';
-import Issuable from './issuable.vue';
-
-/**
- * @deprecated Use app/assets/javascripts/vue_shared/issuable/list/components/issuable_list_root.vue instead
- */
-export default {
- LOADING_LIST_ITEMS_LENGTH,
- directives: {
- SafeHtml,
- },
- components: {
- GlEmptyState,
- GlPagination,
- GlSkeletonLoading,
- Issuable,
- FilteredSearchBar,
- },
- props: {
- canBulkEdit: {
- type: Boolean,
- required: false,
- default: false,
- },
- emptyStateMeta: {
- type: Object,
- required: true,
- },
- endpoint: {
- type: String,
- required: true,
- },
- projectPath: {
- type: String,
- required: false,
- default: '',
- },
- sortKey: {
- type: String,
- required: false,
- default: '',
- },
- type: {
- type: String,
- required: false,
- default: '',
- },
- },
- data() {
- return {
- availableSortOptionsJira,
- filters: {},
- isBulkEditing: false,
- issuables: [],
- loading: false,
- page: getParameterByName('page') !== null ? toNumber(getParameterByName('page')) : 1,
- selection: {},
- totalItems: 0,
- };
- },
- computed: {
- allIssuablesSelected() {
- // WARNING: Because we are only keeping track of selected values
- // this works, we will need to rethink this if we start tracking
- // [id]: false for not selected values.
- return this.issuables.length === Object.keys(this.selection).length;
- },
- emptyState() {
- if (this.issuables.length) {
- return {}; // Empty state shouldn't be shown here
- }
-
- if (this.isServiceDesk) {
- return emptyStateHelper(this.emptyStateMeta);
- }
-
- if (this.hasFilters) {
- return {
- title: __('Sorry, your filter produced no results'),
- svgPath: this.emptyStateMeta.svgPath,
- description: __('To widen your search, change or remove filters above'),
- primaryLink: this.emptyStateMeta.createIssuePath,
- primaryText: __('New issue'),
- };
- }
-
- if (this.filters.state === 'opened') {
- return {
- title: __('There are no open issues'),
- svgPath: this.emptyStateMeta.svgPath,
- description: __('To keep this project going, create a new issue'),
- primaryLink: this.emptyStateMeta.createIssuePath,
- primaryText: __('New issue'),
- };
- } else if (this.filters.state === 'closed') {
- return {
- title: __('There are no closed issues'),
- svgPath: this.emptyStateMeta.svgPath,
- };
- }
-
- return {
- title: __('There are no issues to show'),
- svgPath: this.emptyStateMeta.svgPath,
- description: __(
- '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.',
- ),
- };
- },
- hasFilters() {
- const ignored = ['utf8', 'state', 'scope', 'order_by', 'sort'];
- return Object.keys(omit(this.filters, ignored)).length > 0;
- },
- isManualOrdering() {
- return this.sortKey === RELATIVE_POSITION;
- },
- itemsPerPage() {
- return this.isManualOrdering ? PAGE_SIZE_MANUAL : PAGE_SIZE;
- },
- baseUrl() {
- return window.location.href.replace(/(\?.*)?(#.*)?$/, '');
- },
- paginationNext() {
- return this.page + 1;
- },
- paginationPrev() {
- return this.page - 1;
- },
- paginationProps() {
- const paginationProps = { value: this.page };
-
- if (this.totalItems) {
- return {
- ...paginationProps,
- perPage: this.itemsPerPage,
- totalItems: this.totalItems,
- };
- }
-
- return {
- ...paginationProps,
- prevPage: this.paginationPrev,
- nextPage: this.paginationNext,
- };
- },
- isServiceDesk() {
- return this.type === 'service_desk';
- },
- isJira() {
- return this.type === 'jira';
- },
- initialFilterValue() {
- const value = [];
- const { search } = this.getQueryObject();
-
- if (search) {
- value.push(search);
- }
- return value;
- },
- initialSortBy() {
- const { sort } = this.getQueryObject();
- return sort || 'created_desc';
- },
- },
- watch: {
- selection() {
- // We need to call nextTick here to wait for all of the boxes to be checked and rendered
- // before we query the dom in issuable_bulk_update_actions.js.
- this.$nextTick(() => {
- issuableEventHub.$emit('issuables:updateBulkEdit');
- });
- },
- issuables() {
- this.$nextTick(() => {
- initManualOrdering();
- });
- },
- },
- mounted() {
- if (this.canBulkEdit) {
- this.unsubscribeToggleBulkEdit = issuableEventHub.$on('issuables:toggleBulkEdit', (val) => {
- this.isBulkEditing = val;
- });
- }
- this.fetchIssuables();
- },
- beforeDestroy() {
- // eslint-disable-next-line @gitlab/no-global-event-off
- issuableEventHub.$off('issuables:toggleBulkEdit');
- },
- methods: {
- isSelected(issuableId) {
- return Boolean(this.selection[issuableId]);
- },
- setSelection(ids) {
- ids.forEach((id) => {
- this.select(id, true);
- });
- },
- clearSelection() {
- this.selection = {};
- },
- select(id, isSelect = true) {
- if (isSelect) {
- this.$set(this.selection, id, true);
- } else {
- this.$delete(this.selection, id);
- }
- },
- fetchIssuables(pageToFetch) {
- this.loading = true;
-
- this.clearSelection();
-
- this.setFilters();
-
- return axios
- .get(this.endpoint, {
- params: {
- ...this.filters,
-
- with_labels_details: true,
- page: pageToFetch || this.page,
- per_page: this.itemsPerPage,
- },
- })
- .then((response) => {
- this.loading = false;
- this.issuables = response.data;
- this.totalItems = Number(response.headers['x-total']);
- this.page = Number(response.headers['x-page']);
- })
- .catch(() => {
- this.loading = false;
- return createFlash({
- message: __('An error occurred while loading issues'),
- });
- });
- },
- getQueryObject() {
- return queryToObject(window.location.search, { gatherArrays: true });
- },
- onPaginate(newPage) {
- if (newPage === this.page) return;
-
- scrollToElement('#content-body');
-
- // NOTE: This allows for the params to be updated on pagination
- historyPushState(
- setUrlParams({ ...this.filters, page: newPage }, window.location.href, true),
- );
-
- this.fetchIssuables(newPage);
- },
- onSelectAll() {
- if (this.allIssuablesSelected) {
- this.selection = {};
- } else {
- this.setSelection(this.issuables.map(({ id }) => id));
- }
- },
- onSelectIssuable({ issuable, selected }) {
- if (!this.canBulkEdit) return;
-
- this.select(issuable.id, selected);
- },
- setFilters() {
- const {
- label_name: labels,
- milestone_title: milestoneTitle,
- 'not[label_name]': excludedLabels,
- 'not[milestone_title]': excludedMilestone,
- ...filters
- } = this.getQueryObject();
-
- // TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/227880
-
- if (milestoneTitle) {
- filters.milestone = milestoneTitle;
- }
- if (Array.isArray(labels)) {
- filters.labels = labels.join(',');
- }
- if (!filters.state) {
- filters.state = 'opened';
- }
-
- if (excludedLabels) {
- filters['not[labels]'] = excludedLabels;
- }
-
- if (excludedMilestone) {
- filters['not[milestone]'] = excludedMilestone;
- }
-
- Object.assign(filters, sortOrderMap[this.sortKey]);
-
- this.filters = filters;
- },
- refetchIssuables() {
- const ignored = ['utf8'];
- const params = omit(this.filters, ignored);
-
- historyPushState(setUrlParams(params, window.location.href, true, true));
- this.fetchIssuables();
- },
- handleFilter(filters) {
- const searchTokens = [];
-
- filters.forEach((filter) => {
- if (filter.type === 'filtered-search-term') {
- if (filter.value.data) {
- searchTokens.push(filter.value.data);
- }
- }
- });
-
- if (searchTokens.length) {
- this.filters.search = searchTokens.join(' ');
- }
- this.page = 1;
-
- this.refetchIssuables();
- },
- handleSort(sort) {
- this.filters.sort = sort;
- this.page = 1;
-
- this.refetchIssuables();
- },
- },
-};
-</script>
-
-<template>
- <div>
- <filtered-search-bar
- v-if="isJira"
- :namespace="projectPath"
- :search-input-placeholder="__('Search Jira issues')"
- :tokens="[]"
- :sort-options="availableSortOptionsJira"
- :initial-filter-value="initialFilterValue"
- :initial-sort-by="initialSortBy"
- class="row-content-block"
- @onFilter="handleFilter"
- @onSort="handleSort"
- />
- <ul v-if="loading" class="content-list">
- <li v-for="n in $options.LOADING_LIST_ITEMS_LENGTH" :key="n" class="issue gl-px-5! gl-py-5!">
- <gl-skeleton-loading />
- </li>
- </ul>
- <div v-else-if="issuables.length">
- <div v-if="isBulkEditing" class="issue px-3 py-3 border-bottom border-light">
- <input
- id="check-all-issues"
- type="checkbox"
- :checked="allIssuablesSelected"
- class="mr-2"
- @click="onSelectAll"
- />
- <strong>{{ __('Select all') }}</strong>
- </div>
- <ul
- class="content-list issuable-list issues-list"
- :class="{ 'manual-ordering': isManualOrdering }"
- >
- <issuable
- v-for="issuable in issuables"
- :key="issuable.id"
- class="pr-3"
- :class="{ 'user-can-drag': isManualOrdering }"
- :issuable="issuable"
- :is-bulk-editing="isBulkEditing"
- :selected="isSelected(issuable.id)"
- :base-url="baseUrl"
- @select="onSelectIssuable"
- />
- </ul>
- <div class="mt-3">
- <gl-pagination
- v-bind="paginationProps"
- class="gl-justify-content-center"
- @input="onPaginate"
- />
- </div>
- </div>
- <gl-empty-state
- v-else
- :title="emptyState.title"
- :svg-path="emptyState.svgPath"
- :primary-button-link="emptyState.primaryLink"
- :primary-button-text="emptyState.primaryText"
- >
- <template #description>
- <div v-safe-html="emptyState.description"></div>
- </template>
- </gl-empty-state>
- </div>
-</template>
diff --git a/app/assets/javascripts/issues_list/components/issues_list_app.vue b/app/assets/javascripts/issues_list/components/issues_list_app.vue
deleted file mode 100644
index 6ced1080b71..00000000000
--- a/app/assets/javascripts/issues_list/components/issues_list_app.vue
+++ /dev/null
@@ -1,822 +0,0 @@
-<script>
-import {
- GlButton,
- GlEmptyState,
- GlFilteredSearchToken,
- GlIcon,
- GlLink,
- GlSprintf,
- GlTooltipDirective,
-} from '@gitlab/ui';
-import * as Sentry from '@sentry/browser';
-import fuzzaldrinPlus from 'fuzzaldrin-plus';
-import { orderBy } from 'lodash';
-import getIssuesQuery from 'ee_else_ce/issues_list/queries/get_issues.query.graphql';
-import getIssuesCountsQuery from 'ee_else_ce/issues_list/queries/get_issues_counts.query.graphql';
-import IssueCardTimeInfo from 'ee_else_ce/issues_list/components/issue_card_time_info.vue';
-import createFlash, { FLASH_TYPES } from '~/flash';
-import { TYPE_USER } from '~/graphql_shared/constants';
-import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
-import { ITEM_TYPE } from '~/groups/constants';
-import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue';
-import IssuableByEmail from '~/issuable/components/issuable_by_email.vue';
-import IssuableList from '~/vue_shared/issuable/list/components/issuable_list_root.vue';
-import { IssuableListTabs, IssuableStates } from '~/vue_shared/issuable/list/constants';
-import {
- CREATED_DESC,
- i18n,
- MAX_LIST_SIZE,
- PAGE_SIZE,
- PARAM_DUE_DATE,
- PARAM_SORT,
- PARAM_STATE,
- RELATIVE_POSITION_ASC,
- TOKEN_TYPE_ASSIGNEE,
- TOKEN_TYPE_AUTHOR,
- TOKEN_TYPE_CONFIDENTIAL,
- TOKEN_TYPE_LABEL,
- TOKEN_TYPE_MILESTONE,
- TOKEN_TYPE_MY_REACTION,
- TOKEN_TYPE_RELEASE,
- TOKEN_TYPE_TYPE,
- UPDATED_DESC,
- urlSortParams,
-} from '~/issues_list/constants';
-import {
- convertToApiParams,
- convertToSearchQuery,
- convertToUrlParams,
- getDueDateValue,
- getFilterTokens,
- getInitialPageParams,
- getSortKey,
- getSortOptions,
-} from '~/issues_list/utils';
-import axios from '~/lib/utils/axios_utils';
-import { scrollUp } from '~/lib/utils/scroll_utils';
-import { getParameterByName, joinPaths } from '~/lib/utils/url_utility';
-import {
- DEFAULT_NONE_ANY,
- OPERATOR_IS_ONLY,
- TOKEN_TITLE_ASSIGNEE,
- TOKEN_TITLE_AUTHOR,
- TOKEN_TITLE_CONFIDENTIAL,
- TOKEN_TITLE_LABEL,
- TOKEN_TITLE_MILESTONE,
- TOKEN_TITLE_MY_REACTION,
- TOKEN_TITLE_RELEASE,
- TOKEN_TITLE_TYPE,
-} from '~/vue_shared/components/filtered_search_bar/constants';
-import eventHub from '../eventhub';
-import reorderIssuesMutation from '../queries/reorder_issues.mutation.graphql';
-import searchLabelsQuery from '../queries/search_labels.query.graphql';
-import searchMilestonesQuery from '../queries/search_milestones.query.graphql';
-import searchUsersQuery from '../queries/search_users.query.graphql';
-import NewIssueDropdown from './new_issue_dropdown.vue';
-
-const AuthorToken = () =>
- import('~/vue_shared/components/filtered_search_bar/tokens/author_token.vue');
-const EmojiToken = () =>
- import('~/vue_shared/components/filtered_search_bar/tokens/emoji_token.vue');
-const LabelToken = () =>
- import('~/vue_shared/components/filtered_search_bar/tokens/label_token.vue');
-const MilestoneToken = () =>
- import('~/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue');
-const ReleaseToken = () =>
- import('~/vue_shared/components/filtered_search_bar/tokens/release_token.vue');
-
-export default {
- i18n,
- IssuableListTabs,
- components: {
- CsvImportExportButtons,
- GlButton,
- GlEmptyState,
- GlIcon,
- GlLink,
- GlSprintf,
- IssuableByEmail,
- IssuableList,
- IssueCardTimeInfo,
- NewIssueDropdown,
- },
- directives: {
- GlTooltip: GlTooltipDirective,
- },
- inject: {
- autocompleteAwardEmojisPath: {
- default: '',
- },
- calendarPath: {
- default: '',
- },
- canBulkUpdate: {
- default: false,
- },
- emptyStateSvgPath: {
- default: '',
- },
- exportCsvPath: {
- default: '',
- },
- fullPath: {
- default: '',
- },
- hasAnyIssues: {
- default: false,
- },
- hasAnyProjects: {
- default: false,
- },
- hasBlockedIssuesFeature: {
- default: false,
- },
- hasIssueWeightsFeature: {
- default: false,
- },
- hasMultipleIssueAssigneesFeature: {
- default: false,
- },
- initialEmail: {
- default: '',
- },
- isAnonymousSearchDisabled: {
- default: false,
- },
- isIssueRepositioningDisabled: {
- default: false,
- },
- isProject: {
- default: false,
- },
- isSignedIn: {
- default: false,
- },
- jiraIntegrationPath: {
- default: '',
- },
- newIssuePath: {
- default: '',
- },
- releasesPath: {
- default: '',
- },
- rssPath: {
- default: '',
- },
- showNewIssueLink: {
- default: false,
- },
- signInPath: {
- default: '',
- },
- },
- props: {
- eeSearchTokens: {
- type: Array,
- required: false,
- default: () => [],
- },
- },
- data() {
- const state = getParameterByName(PARAM_STATE);
- const defaultSortKey = state === IssuableStates.Closed ? UPDATED_DESC : CREATED_DESC;
- let sortKey = getSortKey(getParameterByName(PARAM_SORT)) || defaultSortKey;
-
- if (this.isIssueRepositioningDisabled && sortKey === RELATIVE_POSITION_ASC) {
- this.showIssueRepositioningMessage();
- sortKey = defaultSortKey;
- }
-
- const isSearchDisabled =
- this.isAnonymousSearchDisabled &&
- !this.isSignedIn &&
- window.location.search.includes('search=');
-
- if (isSearchDisabled) {
- this.showAnonymousSearchingMessage();
- }
-
- return {
- dueDateFilter: getDueDateValue(getParameterByName(PARAM_DUE_DATE)),
- exportCsvPathWithQuery: this.getExportCsvPathWithQuery(),
- filterTokens: isSearchDisabled ? [] : getFilterTokens(window.location.search),
- issues: [],
- issuesCounts: {},
- issuesError: null,
- pageInfo: {},
- pageParams: getInitialPageParams(sortKey),
- showBulkEditSidebar: false,
- sortKey,
- state: state || IssuableStates.Opened,
- };
- },
- apollo: {
- issues: {
- query: getIssuesQuery,
- variables() {
- return this.queryVariables;
- },
- update(data) {
- return data[this.namespace]?.issues.nodes ?? [];
- },
- result({ data }) {
- this.pageInfo = data[this.namespace]?.issues.pageInfo ?? {};
- this.exportCsvPathWithQuery = this.getExportCsvPathWithQuery();
- },
- error(error) {
- this.issuesError = this.$options.i18n.errorFetchingIssues;
- Sentry.captureException(error);
- },
- skip() {
- return !this.hasAnyIssues;
- },
- debounce: 200,
- },
- issuesCounts: {
- query: getIssuesCountsQuery,
- variables() {
- return this.queryVariables;
- },
- update(data) {
- return data[this.namespace] ?? {};
- },
- error(error) {
- this.issuesError = this.$options.i18n.errorFetchingCounts;
- Sentry.captureException(error);
- },
- skip() {
- return !this.hasAnyIssues;
- },
- debounce: 200,
- context: {
- isSingleRequest: true,
- },
- },
- },
- computed: {
- queryVariables() {
- return {
- fullPath: this.fullPath,
- isProject: this.isProject,
- isSignedIn: this.isSignedIn,
- search: this.searchQuery,
- sort: this.sortKey,
- state: this.state,
- ...this.pageParams,
- ...this.apiFilterParams,
- };
- },
- namespace() {
- return this.isProject ? ITEM_TYPE.PROJECT : ITEM_TYPE.GROUP;
- },
- hasSearch() {
- return this.searchQuery || Object.keys(this.urlFilterParams).length;
- },
- isBulkEditButtonDisabled() {
- return this.showBulkEditSidebar || !this.issues.length;
- },
- isManualOrdering() {
- return this.sortKey === RELATIVE_POSITION_ASC;
- },
- isOpenTab() {
- return this.state === IssuableStates.Opened;
- },
- showCsvButtons() {
- return this.isProject && this.isSignedIn;
- },
- showNewIssueDropdown() {
- return !this.isProject && this.hasAnyProjects;
- },
- apiFilterParams() {
- return convertToApiParams(this.filterTokens);
- },
- urlFilterParams() {
- return convertToUrlParams(this.filterTokens);
- },
- searchQuery() {
- return convertToSearchQuery(this.filterTokens) || undefined;
- },
- searchTokens() {
- const preloadedAuthors = [];
-
- if (gon.current_user_id) {
- preloadedAuthors.push({
- id: convertToGraphQLId(TYPE_USER, gon.current_user_id),
- name: gon.current_user_fullname,
- username: gon.current_username,
- avatar_url: gon.current_user_avatar_url,
- });
- }
-
- const tokens = [
- {
- type: TOKEN_TYPE_AUTHOR,
- title: TOKEN_TITLE_AUTHOR,
- icon: 'pencil',
- token: AuthorToken,
- dataType: 'user',
- unique: true,
- defaultAuthors: [],
- fetchAuthors: this.fetchUsers,
- recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-author`,
- preloadedAuthors,
- },
- {
- type: TOKEN_TYPE_ASSIGNEE,
- title: TOKEN_TITLE_ASSIGNEE,
- icon: 'user',
- token: AuthorToken,
- dataType: 'user',
- unique: !this.hasMultipleIssueAssigneesFeature,
- defaultAuthors: DEFAULT_NONE_ANY,
- fetchAuthors: this.fetchUsers,
- recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-assignee`,
- preloadedAuthors,
- },
- {
- type: TOKEN_TYPE_MILESTONE,
- title: TOKEN_TITLE_MILESTONE,
- icon: 'clock',
- token: MilestoneToken,
- fetchMilestones: this.fetchMilestones,
- recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-milestone`,
- },
- {
- type: TOKEN_TYPE_LABEL,
- title: TOKEN_TITLE_LABEL,
- icon: 'labels',
- token: LabelToken,
- defaultLabels: DEFAULT_NONE_ANY,
- fetchLabels: this.fetchLabels,
- recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-label`,
- },
- {
- type: TOKEN_TYPE_TYPE,
- title: TOKEN_TITLE_TYPE,
- icon: 'issues',
- token: GlFilteredSearchToken,
- options: [
- { icon: 'issue-type-issue', title: 'issue', value: 'issue' },
- { icon: 'issue-type-incident', title: 'incident', value: 'incident' },
- { icon: 'issue-type-test-case', title: 'test_case', value: 'test_case' },
- ],
- },
- ];
-
- if (this.isProject) {
- tokens.push({
- type: TOKEN_TYPE_RELEASE,
- title: TOKEN_TITLE_RELEASE,
- icon: 'rocket',
- token: ReleaseToken,
- fetchReleases: this.fetchReleases,
- recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-release`,
- });
- }
-
- if (this.isSignedIn) {
- tokens.push({
- type: TOKEN_TYPE_MY_REACTION,
- title: TOKEN_TITLE_MY_REACTION,
- icon: 'thumb-up',
- token: EmojiToken,
- unique: true,
- fetchEmojis: this.fetchEmojis,
- recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-my_reaction`,
- });
-
- tokens.push({
- type: TOKEN_TYPE_CONFIDENTIAL,
- title: TOKEN_TITLE_CONFIDENTIAL,
- icon: 'eye-slash',
- token: GlFilteredSearchToken,
- unique: true,
- operators: OPERATOR_IS_ONLY,
- options: [
- { icon: 'eye-slash', value: 'yes', title: this.$options.i18n.confidentialYes },
- { icon: 'eye', value: 'no', title: this.$options.i18n.confidentialNo },
- ],
- });
- }
-
- if (this.eeSearchTokens.length) {
- tokens.push(...this.eeSearchTokens);
- }
-
- tokens.sort((a, b) => a.title.localeCompare(b.title));
-
- return orderBy(tokens, ['title']);
- },
- showPaginationControls() {
- return this.issues.length > 0 && (this.pageInfo.hasNextPage || this.pageInfo.hasPreviousPage);
- },
- sortOptions() {
- return getSortOptions(this.hasIssueWeightsFeature, this.hasBlockedIssuesFeature);
- },
- tabCounts() {
- const { openedIssues, closedIssues, allIssues } = this.issuesCounts;
- return {
- [IssuableStates.Opened]: openedIssues?.count,
- [IssuableStates.Closed]: closedIssues?.count,
- [IssuableStates.All]: allIssues?.count,
- };
- },
- currentTabCount() {
- return this.tabCounts[this.state] ?? 0;
- },
- urlParams() {
- return {
- due_date: this.dueDateFilter,
- search: this.searchQuery,
- sort: urlSortParams[this.sortKey],
- state: this.state,
- ...this.urlFilterParams,
- };
- },
- },
- created() {
- this.cache = {};
- },
- mounted() {
- eventHub.$on('issuables:toggleBulkEdit', this.toggleBulkEditSidebar);
- },
- beforeDestroy() {
- eventHub.$off('issuables:toggleBulkEdit', this.toggleBulkEditSidebar);
- },
- methods: {
- fetchWithCache(path, cacheName, searchKey, search, wrapData = false) {
- if (this.cache[cacheName]) {
- const data = search
- ? fuzzaldrinPlus.filter(this.cache[cacheName], search, { key: searchKey })
- : this.cache[cacheName].slice(0, MAX_LIST_SIZE);
- return wrapData ? Promise.resolve({ data }) : Promise.resolve(data);
- }
-
- return axios.get(path).then(({ data }) => {
- this.cache[cacheName] = data;
- const result = data.slice(0, MAX_LIST_SIZE);
- return wrapData ? { data: result } : result;
- });
- },
- fetchEmojis(search) {
- return this.fetchWithCache(this.autocompleteAwardEmojisPath, 'emojis', 'name', search);
- },
- fetchReleases(search) {
- return this.fetchWithCache(this.releasesPath, 'releases', 'tag', search);
- },
- fetchLabels(search) {
- return this.$apollo
- .query({
- query: searchLabelsQuery,
- variables: { fullPath: this.fullPath, search, isProject: this.isProject },
- })
- .then(({ data }) => data[this.namespace]?.labels.nodes)
- .then((labels) =>
- // TODO remove once we can search by title-only on the backend
- // https://gitlab.com/gitlab-org/gitlab/-/issues/346353
- labels.filter((label) => label.title.toLowerCase().includes(search.toLowerCase())),
- );
- },
- fetchMilestones(search) {
- return this.$apollo
- .query({
- query: searchMilestonesQuery,
- variables: { fullPath: this.fullPath, search, isProject: this.isProject },
- })
- .then(({ data }) => data[this.namespace]?.milestones.nodes);
- },
- fetchUsers(search) {
- return this.$apollo
- .query({
- query: searchUsersQuery,
- variables: { fullPath: this.fullPath, search, isProject: this.isProject },
- })
- .then(({ data }) =>
- data[this.namespace]?.[`${this.namespace}Members`].nodes.map((member) => member.user),
- );
- },
- getExportCsvPathWithQuery() {
- return `${this.exportCsvPath}${window.location.search}`;
- },
- getStatus(issue) {
- if (issue.closedAt && issue.moved) {
- return this.$options.i18n.closedMoved;
- }
- if (issue.closedAt) {
- return this.$options.i18n.closed;
- }
- return undefined;
- },
- handleUpdateLegacyBulkEdit() {
- // If "select all" checkbox was checked, wait for all checkboxes
- // to be checked before updating IssuableBulkUpdateSidebar class
- this.$nextTick(() => {
- eventHub.$emit('issuables:updateBulkEdit');
- });
- },
- async handleBulkUpdateClick() {
- if (!this.hasInitBulkEdit) {
- const initBulkUpdateSidebar = await import(
- '~/issuable/bulk_update_sidebar/issuable_init_bulk_update_sidebar'
- );
- initBulkUpdateSidebar.default.init('issuable_');
-
- const usersSelect = await import('~/users_select');
- const UsersSelect = usersSelect.default;
- new UsersSelect(); // eslint-disable-line no-new
-
- this.hasInitBulkEdit = true;
- }
-
- eventHub.$emit('issuables:enableBulkEdit');
- },
- handleClickTab(state) {
- if (this.state !== state) {
- this.pageParams = getInitialPageParams(this.sortKey);
- }
- this.state = state;
- },
- handleDismissAlert() {
- this.issuesError = null;
- },
- handleFilter(filter) {
- if (this.isAnonymousSearchDisabled && !this.isSignedIn) {
- this.showAnonymousSearchingMessage();
- return;
- }
- this.pageParams = getInitialPageParams(this.sortKey);
- this.filterTokens = filter;
- },
- handleNextPage() {
- this.pageParams = {
- afterCursor: this.pageInfo.endCursor,
- firstPageSize: PAGE_SIZE,
- };
- scrollUp();
- },
- handlePreviousPage() {
- this.pageParams = {
- beforeCursor: this.pageInfo.startCursor,
- lastPageSize: PAGE_SIZE,
- };
- scrollUp();
- },
- handleReorder({ newIndex, oldIndex }) {
- const issueToMove = this.issues[oldIndex];
- const isDragDropDownwards = newIndex > oldIndex;
- const isMovingToBeginning = newIndex === 0;
- const isMovingToEnd = newIndex === this.issues.length - 1;
-
- let moveBeforeId;
- let moveAfterId;
-
- if (isDragDropDownwards) {
- const afterIndex = isMovingToEnd ? newIndex : newIndex + 1;
- moveBeforeId = this.issues[newIndex].id;
- moveAfterId = this.issues[afterIndex].id;
- } else {
- const beforeIndex = isMovingToBeginning ? newIndex : newIndex - 1;
- moveBeforeId = this.issues[beforeIndex].id;
- moveAfterId = this.issues[newIndex].id;
- }
-
- return axios
- .put(joinPaths(issueToMove.webPath, 'reorder'), {
- move_before_id: isMovingToBeginning ? null : getIdFromGraphQLId(moveBeforeId),
- move_after_id: isMovingToEnd ? null : getIdFromGraphQLId(moveAfterId),
- group_full_path: this.isProject ? undefined : this.fullPath,
- })
- .then(() => {
- const serializedVariables = JSON.stringify(this.queryVariables);
- return this.$apollo.mutate({
- mutation: reorderIssuesMutation,
- variables: { oldIndex, newIndex, namespace: this.namespace, serializedVariables },
- });
- })
- .catch((error) => {
- this.issuesError = this.$options.i18n.reorderError;
- Sentry.captureException(error);
- });
- },
- handleSort(sortKey) {
- if (this.isIssueRepositioningDisabled && sortKey === RELATIVE_POSITION_ASC) {
- this.showIssueRepositioningMessage();
- return;
- }
-
- if (this.sortKey !== sortKey) {
- this.pageParams = getInitialPageParams(sortKey);
- }
- this.sortKey = sortKey;
- },
- showAnonymousSearchingMessage() {
- createFlash({
- message: this.$options.i18n.anonymousSearchingMessage,
- type: FLASH_TYPES.NOTICE,
- });
- },
- showIssueRepositioningMessage() {
- createFlash({
- message: this.$options.i18n.issueRepositioningMessage,
- type: FLASH_TYPES.NOTICE,
- });
- },
- toggleBulkEditSidebar(showBulkEditSidebar) {
- this.showBulkEditSidebar = showBulkEditSidebar;
- },
- },
-};
-</script>
-
-<template>
- <div v-if="hasAnyIssues">
- <issuable-list
- :namespace="fullPath"
- recent-searches-storage-key="issues"
- :search-input-placeholder="$options.i18n.searchPlaceholder"
- :search-tokens="searchTokens"
- :initial-filter-value="filterTokens"
- :sort-options="sortOptions"
- :initial-sort-by="sortKey"
- :issuables="issues"
- :error="issuesError"
- label-filter-param="label_name"
- :tabs="$options.IssuableListTabs"
- :current-tab="state"
- :tab-counts="tabCounts"
- :issuables-loading="$apollo.queries.issues.loading"
- :is-manual-ordering="isManualOrdering"
- :show-bulk-edit-sidebar="showBulkEditSidebar"
- :show-pagination-controls="showPaginationControls"
- :use-keyset-pagination="true"
- :has-next-page="pageInfo.hasNextPage"
- :has-previous-page="pageInfo.hasPreviousPage"
- :url-params="urlParams"
- @click-tab="handleClickTab"
- @dismiss-alert="handleDismissAlert"
- @filter="handleFilter"
- @next-page="handleNextPage"
- @previous-page="handlePreviousPage"
- @reorder="handleReorder"
- @sort="handleSort"
- @update-legacy-bulk-edit="handleUpdateLegacyBulkEdit"
- >
- <template #nav-actions>
- <gl-button
- v-gl-tooltip
- :href="rssPath"
- icon="rss"
- :title="$options.i18n.rssLabel"
- :aria-label="$options.i18n.rssLabel"
- />
- <gl-button
- v-gl-tooltip
- :href="calendarPath"
- icon="calendar"
- :title="$options.i18n.calendarLabel"
- :aria-label="$options.i18n.calendarLabel"
- />
- <csv-import-export-buttons
- v-if="showCsvButtons"
- class="gl-md-mr-3"
- :export-csv-path="exportCsvPathWithQuery"
- :issuable-count="currentTabCount"
- />
- <gl-button
- v-if="canBulkUpdate"
- :disabled="isBulkEditButtonDisabled"
- @click="handleBulkUpdateClick"
- >
- {{ $options.i18n.editIssues }}
- </gl-button>
- <gl-button v-if="showNewIssueLink" :href="newIssuePath" variant="confirm">
- {{ $options.i18n.newIssueLabel }}
- </gl-button>
- <new-issue-dropdown v-if="showNewIssueDropdown" />
- </template>
-
- <template #timeframe="{ issuable = {} }">
- <issue-card-time-info :issue="issuable" />
- </template>
-
- <template #status="{ issuable = {} }">
- {{ getStatus(issuable) }}
- </template>
-
- <template #statistics="{ issuable = {} }">
- <li
- v-if="issuable.mergeRequestsCount"
- v-gl-tooltip
- class="gl-display-none gl-sm-display-block"
- :title="$options.i18n.relatedMergeRequests"
- data-testid="merge-requests"
- >
- <gl-icon name="merge-request" />
- {{ issuable.mergeRequestsCount }}
- </li>
- <li
- v-if="issuable.upvotes"
- v-gl-tooltip
- class="issuable-upvotes gl-display-none gl-sm-display-block"
- :title="$options.i18n.upvotes"
- data-testid="issuable-upvotes"
- >
- <gl-icon name="thumb-up" />
- {{ issuable.upvotes }}
- </li>
- <li
- v-if="issuable.downvotes"
- v-gl-tooltip
- class="issuable-downvotes gl-display-none gl-sm-display-block"
- :title="$options.i18n.downvotes"
- data-testid="issuable-downvotes"
- >
- <gl-icon name="thumb-down" />
- {{ issuable.downvotes }}
- </li>
- <slot :issuable="issuable"></slot>
- </template>
-
- <template #empty-state>
- <gl-empty-state
- v-if="hasSearch"
- :description="$options.i18n.noSearchResultsDescription"
- :title="$options.i18n.noSearchResultsTitle"
- :svg-path="emptyStateSvgPath"
- >
- <template #actions>
- <gl-button v-if="showNewIssueLink" :href="newIssuePath" variant="confirm">
- {{ $options.i18n.newIssueLabel }}
- </gl-button>
- </template>
- </gl-empty-state>
-
- <gl-empty-state
- v-else-if="isOpenTab"
- :description="$options.i18n.noOpenIssuesDescription"
- :title="$options.i18n.noOpenIssuesTitle"
- :svg-path="emptyStateSvgPath"
- >
- <template #actions>
- <gl-button v-if="showNewIssueLink" :href="newIssuePath" variant="confirm">
- {{ $options.i18n.newIssueLabel }}
- </gl-button>
- </template>
- </gl-empty-state>
-
- <gl-empty-state
- v-else
- :title="$options.i18n.noClosedIssuesTitle"
- :svg-path="emptyStateSvgPath"
- />
- </template>
- </issuable-list>
-
- <issuable-by-email v-if="initialEmail" class="gl-text-center gl-pt-5 gl-pb-7" />
- </div>
-
- <div v-else-if="isSignedIn">
- <gl-empty-state
- :description="$options.i18n.noIssuesSignedInDescription"
- :title="$options.i18n.noIssuesSignedInTitle"
- :svg-path="emptyStateSvgPath"
- >
- <template #actions>
- <gl-button v-if="showNewIssueLink" :href="newIssuePath" variant="confirm">
- {{ $options.i18n.newIssueLabel }}
- </gl-button>
- <csv-import-export-buttons
- v-if="showCsvButtons"
- class="gl-mr-3"
- :export-csv-path="exportCsvPathWithQuery"
- :issuable-count="currentTabCount"
- />
- <new-issue-dropdown v-if="showNewIssueDropdown" />
- </template>
- </gl-empty-state>
- <hr />
- <p class="gl-text-center gl-font-weight-bold gl-mb-0">
- {{ $options.i18n.jiraIntegrationTitle }}
- </p>
- <p class="gl-text-center gl-mb-0">
- <gl-sprintf :message="$options.i18n.jiraIntegrationMessage">
- <template #jiraDocsLink="{ content }">
- <gl-link :href="jiraIntegrationPath">{{ content }}</gl-link>
- </template>
- </gl-sprintf>
- </p>
- <p class="gl-text-center gl-text-gray-500">
- {{ $options.i18n.jiraIntegrationSecondaryMessage }}
- </p>
- </div>
-
- <gl-empty-state
- v-else
- :description="$options.i18n.noIssuesSignedOutDescription"
- :title="$options.i18n.noIssuesSignedOutTitle"
- :svg-path="emptyStateSvgPath"
- :primary-button-text="$options.i18n.noIssuesSignedOutButtonText"
- :primary-button-link="signInPath"
- />
-</template>
diff --git a/app/assets/javascripts/issues_list/components/new_issue_dropdown.vue b/app/assets/javascripts/issues_list/components/new_issue_dropdown.vue
deleted file mode 100644
index e749579af80..00000000000
--- a/app/assets/javascripts/issues_list/components/new_issue_dropdown.vue
+++ /dev/null
@@ -1,127 +0,0 @@
-<script>
-import {
- GlDropdown,
- GlDropdownItem,
- GlDropdownText,
- GlLoadingIcon,
- GlSearchBoxByType,
-} from '@gitlab/ui';
-import createFlash from '~/flash';
-import searchProjectsQuery from '~/issues_list/queries/search_projects.query.graphql';
-import { DASH_SCOPE, joinPaths } from '~/lib/utils/url_utility';
-import { __, sprintf } from '~/locale';
-import { DEBOUNCE_DELAY } from '~/vue_shared/components/filtered_search_bar/constants';
-
-export default {
- i18n: {
- defaultDropdownText: __('Select project to create issue'),
- noMatchesFound: __('No matches found'),
- toggleButtonLabel: __('Toggle project select'),
- },
- components: {
- GlDropdown,
- GlDropdownItem,
- GlDropdownText,
- GlLoadingIcon,
- GlSearchBoxByType,
- },
- inject: ['fullPath'],
- data() {
- return {
- projects: [],
- search: '',
- selectedProject: {},
- shouldSkipQuery: true,
- };
- },
- apollo: {
- projects: {
- query: searchProjectsQuery,
- variables() {
- return {
- fullPath: this.fullPath,
- search: this.search,
- };
- },
- update: ({ group }) => group.projects.nodes ?? [],
- error(error) {
- createFlash({
- message: __('An error occurred while loading projects.'),
- captureError: true,
- error,
- });
- },
- skip() {
- return this.shouldSkipQuery;
- },
- debounce: DEBOUNCE_DELAY,
- },
- },
- computed: {
- dropdownHref() {
- return this.hasSelectedProject
- ? joinPaths(this.selectedProject.webUrl, DASH_SCOPE, 'issues/new')
- : undefined;
- },
- dropdownText() {
- return this.hasSelectedProject
- ? sprintf(__('New issue in %{project}'), { project: this.selectedProject.name })
- : this.$options.i18n.defaultDropdownText;
- },
- hasSelectedProject() {
- return this.selectedProject.id;
- },
- projectsWithIssuesEnabled() {
- return this.projects.filter((project) => project.issuesEnabled);
- },
- showNoSearchResultsText() {
- return !this.projectsWithIssuesEnabled.length && this.search;
- },
- },
- methods: {
- handleDropdownClick() {
- if (!this.dropdownHref) {
- this.$refs.dropdown.show();
- }
- },
- handleDropdownShown() {
- if (this.shouldSkipQuery) {
- this.shouldSkipQuery = false;
- }
- this.$refs.search.focusInput();
- },
- selectProject(project) {
- this.selectedProject = project;
- },
- },
-};
-</script>
-
-<template>
- <gl-dropdown
- ref="dropdown"
- right
- split
- :split-href="dropdownHref"
- :text="dropdownText"
- :toggle-text="$options.i18n.toggleButtonLabel"
- variant="confirm"
- @click="handleDropdownClick"
- @shown="handleDropdownShown"
- >
- <gl-search-box-by-type ref="search" v-model.trim="search" />
- <gl-loading-icon v-if="$apollo.queries.projects.loading" />
- <template v-else>
- <gl-dropdown-item
- v-for="project of projectsWithIssuesEnabled"
- :key="project.id"
- @click="selectProject(project)"
- >
- {{ project.nameWithNamespace }}
- </gl-dropdown-item>
- <gl-dropdown-text v-if="showNoSearchResultsText">
- {{ $options.i18n.noMatchesFound }}
- </gl-dropdown-text>
- </template>
- </gl-dropdown>
-</template>
diff --git a/app/assets/javascripts/issues_list/constants.js b/app/assets/javascripts/issues_list/constants.js
deleted file mode 100644
index c9eaf0b9908..00000000000
--- a/app/assets/javascripts/issues_list/constants.js
+++ /dev/null
@@ -1,372 +0,0 @@
-import { __, s__ } from '~/locale';
-import {
- FILTER_ANY,
- FILTER_CURRENT,
- FILTER_NONE,
- FILTER_STARTED,
- FILTER_UPCOMING,
- OPERATOR_IS,
- OPERATOR_IS_NOT,
-} from '~/vue_shared/components/filtered_search_bar/constants';
-
-// Maps sort order as it appears in the URL query to API `order_by` and `sort` params.
-const PRIORITY = 'priority';
-const ASC = 'asc';
-const DESC = 'desc';
-const CREATED_AT = 'created_at';
-const UPDATED_AT = 'updated_at';
-const DUE_DATE = 'due_date';
-const MILESTONE_DUE = 'milestone_due';
-const POPULARITY = 'popularity';
-const WEIGHT = 'weight';
-const LABEL_PRIORITY = 'label_priority';
-const TITLE = 'title';
-export const RELATIVE_POSITION = 'relative_position';
-export const LOADING_LIST_ITEMS_LENGTH = 8;
-export const PAGE_SIZE = 20;
-export const PAGE_SIZE_MANUAL = 100;
-
-export const sortOrderMap = {
- priority: { order_by: PRIORITY, sort: ASC }, // asc and desc are flipped for some reason
- created_date: { order_by: CREATED_AT, sort: DESC },
- created_asc: { order_by: CREATED_AT, sort: ASC },
- updated_desc: { order_by: UPDATED_AT, sort: DESC },
- updated_asc: { order_by: UPDATED_AT, sort: ASC },
- milestone_due_desc: { order_by: MILESTONE_DUE, sort: DESC },
- milestone: { order_by: MILESTONE_DUE, sort: ASC },
- due_date_desc: { order_by: DUE_DATE, sort: DESC },
- due_date: { order_by: DUE_DATE, sort: ASC },
- popularity: { order_by: POPULARITY, sort: DESC },
- popularity_asc: { order_by: POPULARITY, sort: ASC },
- label_priority: { order_by: LABEL_PRIORITY, sort: ASC }, // asc and desc are flipped
- relative_position: { order_by: RELATIVE_POSITION, sort: ASC },
- weight_desc: { order_by: WEIGHT, sort: DESC },
- weight: { order_by: WEIGHT, sort: ASC },
- title: { order_by: TITLE, sort: ASC },
- title_desc: { order_by: TITLE, sort: DESC },
-};
-
-export const availableSortOptionsJira = [
- {
- id: 1,
- title: __('Created date'),
- sortDirection: {
- descending: 'created_desc',
- ascending: 'created_asc',
- },
- },
- {
- id: 2,
- title: __('Last updated'),
- sortDirection: {
- descending: 'updated_desc',
- ascending: 'updated_asc',
- },
- },
-];
-
-export const i18n = {
- anonymousSearchingMessage: __('You must sign in to search for specific terms.'),
- calendarLabel: __('Subscribe to calendar'),
- closed: __('CLOSED'),
- closedMoved: __('CLOSED (MOVED)'),
- confidentialNo: __('No'),
- confidentialYes: __('Yes'),
- downvotes: __('Downvotes'),
- editIssues: __('Edit issues'),
- errorFetchingCounts: __('An error occurred while getting issue counts'),
- errorFetchingIssues: __('An error occurred while loading issues'),
- issueRepositioningMessage: __(
- 'Issues are being rebalanced at the moment, so manual reordering is disabled.',
- ),
- jiraIntegrationMessage: s__(
- 'JiraService|%{jiraDocsLinkStart}Enable the Jira integration%{jiraDocsLinkEnd} to view your Jira issues in GitLab.',
- ),
- jiraIntegrationSecondaryMessage: s__('JiraService|This feature requires a Premium plan.'),
- jiraIntegrationTitle: s__('JiraService|Using Jira for issue tracking?'),
- newIssueLabel: __('New issue'),
- noClosedIssuesTitle: __('There are no closed issues'),
- noOpenIssuesDescription: __('To keep this project going, create a new issue'),
- noOpenIssuesTitle: __('There are no open issues'),
- noIssuesSignedInDescription: __(
- 'Issues can be bugs, tasks or ideas to be discussed. Also, issues are searchable and filterable.',
- ),
- noIssuesSignedInTitle: __(
- 'The Issue Tracker is the place to add things that need to be improved or solved in a project',
- ),
- noIssuesSignedOutButtonText: __('Register / Sign In'),
- noIssuesSignedOutDescription: __(
- '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.',
- ),
- noIssuesSignedOutTitle: __('There are no issues to show'),
- noSearchResultsDescription: __('To widen your search, change or remove filters above'),
- noSearchResultsTitle: __('Sorry, your filter produced no results'),
- relatedMergeRequests: __('Related merge requests'),
- reorderError: __('An error occurred while reordering issues.'),
- rssLabel: __('Subscribe to RSS feed'),
- searchPlaceholder: __('Search or filter results...'),
- upvotes: __('Upvotes'),
-};
-
-export const JIRA_IMPORT_SUCCESS_ALERT_HIDE_MAP_KEY = 'jira-import-success-alert-hide-map';
-
-export const PARAM_DUE_DATE = 'due_date';
-export const PARAM_SORT = 'sort';
-export const PARAM_STATE = 'state';
-
-export const defaultPageSizeParams = {
- firstPageSize: PAGE_SIZE,
-};
-
-export const largePageSizeParams = {
- firstPageSize: PAGE_SIZE_MANUAL,
-};
-
-export const DUE_DATE_NONE = '0';
-export const DUE_DATE_ANY = '';
-export const DUE_DATE_OVERDUE = 'overdue';
-export const DUE_DATE_WEEK = 'week';
-export const DUE_DATE_MONTH = 'month';
-export const DUE_DATE_NEXT_MONTH_AND_PREVIOUS_TWO_WEEKS = 'next_month_and_previous_two_weeks';
-export const DUE_DATE_VALUES = [
- DUE_DATE_NONE,
- DUE_DATE_ANY,
- DUE_DATE_OVERDUE,
- DUE_DATE_WEEK,
- DUE_DATE_MONTH,
- DUE_DATE_NEXT_MONTH_AND_PREVIOUS_TWO_WEEKS,
-];
-
-export const BLOCKING_ISSUES_ASC = 'BLOCKING_ISSUES_ASC';
-export const BLOCKING_ISSUES_DESC = 'BLOCKING_ISSUES_DESC';
-export const CREATED_ASC = 'CREATED_ASC';
-export const CREATED_DESC = 'CREATED_DESC';
-export const DUE_DATE_ASC = 'DUE_DATE_ASC';
-export const DUE_DATE_DESC = 'DUE_DATE_DESC';
-export const LABEL_PRIORITY_ASC = 'LABEL_PRIORITY_ASC';
-export const LABEL_PRIORITY_DESC = 'LABEL_PRIORITY_DESC';
-export const MILESTONE_DUE_ASC = 'MILESTONE_DUE_ASC';
-export const MILESTONE_DUE_DESC = 'MILESTONE_DUE_DESC';
-export const POPULARITY_ASC = 'POPULARITY_ASC';
-export const POPULARITY_DESC = 'POPULARITY_DESC';
-export const PRIORITY_ASC = 'PRIORITY_ASC';
-export const PRIORITY_DESC = 'PRIORITY_DESC';
-export const RELATIVE_POSITION_ASC = 'RELATIVE_POSITION_ASC';
-export const TITLE_ASC = 'TITLE_ASC';
-export const TITLE_DESC = 'TITLE_DESC';
-export const UPDATED_ASC = 'UPDATED_ASC';
-export const UPDATED_DESC = 'UPDATED_DESC';
-export const WEIGHT_ASC = 'WEIGHT_ASC';
-export const WEIGHT_DESC = 'WEIGHT_DESC';
-
-export const urlSortParams = {
- [PRIORITY_ASC]: 'priority',
- [PRIORITY_DESC]: 'priority_desc',
- [CREATED_ASC]: 'created_asc',
- [CREATED_DESC]: 'created_date',
- [UPDATED_ASC]: 'updated_asc',
- [UPDATED_DESC]: 'updated_desc',
- [MILESTONE_DUE_ASC]: 'milestone',
- [MILESTONE_DUE_DESC]: 'milestone_due_desc',
- [DUE_DATE_ASC]: 'due_date',
- [DUE_DATE_DESC]: 'due_date_desc',
- [POPULARITY_ASC]: 'popularity_asc',
- [POPULARITY_DESC]: 'popularity',
- [LABEL_PRIORITY_ASC]: 'label_priority',
- [LABEL_PRIORITY_DESC]: 'label_priority_desc',
- [RELATIVE_POSITION_ASC]: RELATIVE_POSITION,
- [WEIGHT_ASC]: 'weight',
- [WEIGHT_DESC]: 'weight_desc',
- [BLOCKING_ISSUES_ASC]: 'blocking_issues_asc',
- [BLOCKING_ISSUES_DESC]: 'blocking_issues_desc',
- [TITLE_ASC]: 'title_asc',
- [TITLE_DESC]: 'title_desc',
-};
-
-export const MAX_LIST_SIZE = 10;
-
-export const API_PARAM = 'apiParam';
-export const URL_PARAM = 'urlParam';
-export const NORMAL_FILTER = 'normalFilter';
-export const SPECIAL_FILTER = 'specialFilter';
-export const ALTERNATIVE_FILTER = 'alternativeFilter';
-export const SPECIAL_FILTER_VALUES = [
- FILTER_NONE,
- FILTER_ANY,
- FILTER_CURRENT,
- FILTER_UPCOMING,
- FILTER_STARTED,
-];
-
-export const TOKEN_TYPE_AUTHOR = 'author_username';
-export const TOKEN_TYPE_ASSIGNEE = 'assignee_username';
-export const TOKEN_TYPE_MILESTONE = 'milestone';
-export const TOKEN_TYPE_LABEL = 'labels';
-export const TOKEN_TYPE_TYPE = 'type';
-export const TOKEN_TYPE_RELEASE = 'release';
-export const TOKEN_TYPE_MY_REACTION = 'my_reaction_emoji';
-export const TOKEN_TYPE_CONFIDENTIAL = 'confidential';
-export const TOKEN_TYPE_ITERATION = 'iteration';
-export const TOKEN_TYPE_EPIC = 'epic_id';
-export const TOKEN_TYPE_WEIGHT = 'weight';
-
-export const filters = {
- [TOKEN_TYPE_AUTHOR]: {
- [API_PARAM]: {
- [NORMAL_FILTER]: 'authorUsername',
- },
- [URL_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'author_username',
- },
- [OPERATOR_IS_NOT]: {
- [NORMAL_FILTER]: 'not[author_username]',
- },
- },
- },
- [TOKEN_TYPE_ASSIGNEE]: {
- [API_PARAM]: {
- [NORMAL_FILTER]: 'assigneeUsernames',
- [SPECIAL_FILTER]: 'assigneeId',
- },
- [URL_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'assignee_username[]',
- [SPECIAL_FILTER]: 'assignee_id',
- [ALTERNATIVE_FILTER]: 'assignee_username',
- },
- [OPERATOR_IS_NOT]: {
- [NORMAL_FILTER]: 'not[assignee_username][]',
- },
- },
- },
- [TOKEN_TYPE_MILESTONE]: {
- [API_PARAM]: {
- [NORMAL_FILTER]: 'milestoneTitle',
- [SPECIAL_FILTER]: 'milestoneWildcardId',
- },
- [URL_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'milestone_title',
- [SPECIAL_FILTER]: 'milestone_title',
- },
- [OPERATOR_IS_NOT]: {
- [NORMAL_FILTER]: 'not[milestone_title]',
- },
- },
- },
- [TOKEN_TYPE_LABEL]: {
- [API_PARAM]: {
- [NORMAL_FILTER]: 'labelName',
- [SPECIAL_FILTER]: 'labelName',
- },
- [URL_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'label_name[]',
- [SPECIAL_FILTER]: 'label_name[]',
- [ALTERNATIVE_FILTER]: 'label_name',
- },
- [OPERATOR_IS_NOT]: {
- [NORMAL_FILTER]: 'not[label_name][]',
- },
- },
- },
- [TOKEN_TYPE_TYPE]: {
- [API_PARAM]: {
- [NORMAL_FILTER]: 'types',
- },
- [URL_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'type[]',
- },
- [OPERATOR_IS_NOT]: {
- [NORMAL_FILTER]: 'not[type][]',
- },
- },
- },
- [TOKEN_TYPE_RELEASE]: {
- [API_PARAM]: {
- [NORMAL_FILTER]: 'releaseTag',
- [SPECIAL_FILTER]: 'releaseTagWildcardId',
- },
- [URL_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'release_tag',
- [SPECIAL_FILTER]: 'release_tag',
- },
- [OPERATOR_IS_NOT]: {
- [NORMAL_FILTER]: 'not[release_tag]',
- },
- },
- },
- [TOKEN_TYPE_MY_REACTION]: {
- [API_PARAM]: {
- [NORMAL_FILTER]: 'myReactionEmoji',
- [SPECIAL_FILTER]: 'myReactionEmoji',
- },
- [URL_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'my_reaction_emoji',
- [SPECIAL_FILTER]: 'my_reaction_emoji',
- },
- [OPERATOR_IS_NOT]: {
- [NORMAL_FILTER]: 'not[my_reaction_emoji]',
- },
- },
- },
- [TOKEN_TYPE_CONFIDENTIAL]: {
- [API_PARAM]: {
- [NORMAL_FILTER]: 'confidential',
- },
- [URL_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'confidential',
- },
- },
- },
- [TOKEN_TYPE_ITERATION]: {
- [API_PARAM]: {
- [NORMAL_FILTER]: 'iterationId',
- [SPECIAL_FILTER]: 'iterationWildcardId',
- },
- [URL_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'iteration_id',
- [SPECIAL_FILTER]: 'iteration_id',
- },
- [OPERATOR_IS_NOT]: {
- [NORMAL_FILTER]: 'not[iteration_id]',
- },
- },
- },
- [TOKEN_TYPE_EPIC]: {
- [API_PARAM]: {
- [NORMAL_FILTER]: 'epicId',
- [SPECIAL_FILTER]: 'epicId',
- },
- [URL_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'epic_id',
- [SPECIAL_FILTER]: 'epic_id',
- },
- [OPERATOR_IS_NOT]: {
- [NORMAL_FILTER]: 'not[epic_id]',
- },
- },
- },
- [TOKEN_TYPE_WEIGHT]: {
- [API_PARAM]: {
- [NORMAL_FILTER]: 'weight',
- [SPECIAL_FILTER]: 'weight',
- },
- [URL_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'weight',
- [SPECIAL_FILTER]: 'weight',
- },
- [OPERATOR_IS_NOT]: {
- [NORMAL_FILTER]: 'not[weight]',
- },
- },
- },
-};
diff --git a/app/assets/javascripts/issues_list/index.js b/app/assets/javascripts/issues_list/index.js
deleted file mode 100644
index 9d2ec8b32d2..00000000000
--- a/app/assets/javascripts/issues_list/index.js
+++ /dev/null
@@ -1,195 +0,0 @@
-import produce from 'immer';
-import Vue from 'vue';
-import VueApollo from 'vue-apollo';
-import getIssuesQuery from 'ee_else_ce/issues_list/queries/get_issues.query.graphql';
-import IssuesListApp from 'ee_else_ce/issues_list/components/issues_list_app.vue';
-import createDefaultClient from '~/lib/graphql';
-import { convertObjectPropsToCamelCase, parseBoolean } from '~/lib/utils/common_utils';
-import IssuablesListApp from './components/issuables_list_app.vue';
-import JiraIssuesImportStatusRoot from './components/jira_issues_import_status_app.vue';
-
-export function mountJiraIssuesListApp() {
- const el = document.querySelector('.js-jira-issues-import-status');
-
- if (!el) {
- return false;
- }
-
- const { issuesPath, projectPath } = el.dataset;
- const canEdit = parseBoolean(el.dataset.canEdit);
- const isJiraConfigured = parseBoolean(el.dataset.isJiraConfigured);
-
- if (!isJiraConfigured || !canEdit) {
- return false;
- }
-
- Vue.use(VueApollo);
- const defaultClient = createDefaultClient();
- const apolloProvider = new VueApollo({
- defaultClient,
- });
-
- return new Vue({
- el,
- apolloProvider,
- render(createComponent) {
- return createComponent(JiraIssuesImportStatusRoot, {
- props: {
- canEdit,
- isJiraConfigured,
- issuesPath,
- projectPath,
- },
- });
- },
- });
-}
-
-export function mountIssuablesListApp() {
- if (!gon.features?.vueIssuablesList) {
- return;
- }
-
- document.querySelectorAll('.js-issuables-list').forEach((el) => {
- const { canBulkEdit, emptyStateMeta = {}, scopedLabelsAvailable, ...data } = el.dataset;
-
- return new Vue({
- el,
- provide: {
- scopedLabelsAvailable: parseBoolean(scopedLabelsAvailable),
- },
- render(createElement) {
- return createElement(IssuablesListApp, {
- props: {
- ...data,
- emptyStateMeta:
- Object.keys(emptyStateMeta).length !== 0
- ? convertObjectPropsToCamelCase(JSON.parse(emptyStateMeta))
- : {},
- canBulkEdit: Boolean(canBulkEdit),
- },
- });
- },
- });
- });
-}
-
-export function mountIssuesListApp() {
- const el = document.querySelector('.js-issues-list');
-
- if (!el) {
- return false;
- }
-
- Vue.use(VueApollo);
-
- const resolvers = {
- Mutation: {
- reorderIssues: (_, { oldIndex, newIndex, namespace, serializedVariables }, { cache }) => {
- const variables = JSON.parse(serializedVariables);
- const sourceData = cache.readQuery({ query: getIssuesQuery, variables });
-
- const data = produce(sourceData, (draftData) => {
- const issues = draftData[namespace].issues.nodes.slice();
- const issueToMove = issues[oldIndex];
- issues.splice(oldIndex, 1);
- issues.splice(newIndex, 0, issueToMove);
-
- draftData[namespace].issues.nodes = issues;
- });
-
- cache.writeQuery({ query: getIssuesQuery, variables, data });
- },
- },
- };
-
- const defaultClient = createDefaultClient(resolvers);
- const apolloProvider = new VueApollo({
- defaultClient,
- });
-
- const {
- autocompleteAwardEmojisPath,
- calendarPath,
- canBulkUpdate,
- canEdit,
- canImportIssues,
- email,
- emailsHelpPagePath,
- emptyStateSvgPath,
- exportCsvPath,
- fullPath,
- groupPath,
- hasAnyIssues,
- hasAnyProjects,
- hasBlockedIssuesFeature,
- hasIssuableHealthStatusFeature,
- hasIssueWeightsFeature,
- hasIterationsFeature,
- hasMultipleIssueAssigneesFeature,
- importCsvIssuesPath,
- initialEmail,
- isAnonymousSearchDisabled,
- isIssueRepositioningDisabled,
- isProject,
- isSignedIn,
- jiraIntegrationPath,
- markdownHelpPath,
- maxAttachmentSize,
- newIssuePath,
- projectImportJiraPath,
- quickActionsHelpPath,
- releasesPath,
- resetPath,
- rssPath,
- showNewIssueLink,
- signInPath,
- } = el.dataset;
-
- return new Vue({
- el,
- apolloProvider,
- provide: {
- autocompleteAwardEmojisPath,
- calendarPath,
- canBulkUpdate: parseBoolean(canBulkUpdate),
- emptyStateSvgPath,
- fullPath,
- groupPath,
- hasAnyIssues: parseBoolean(hasAnyIssues),
- hasAnyProjects: parseBoolean(hasAnyProjects),
- hasBlockedIssuesFeature: parseBoolean(hasBlockedIssuesFeature),
- hasIssuableHealthStatusFeature: parseBoolean(hasIssuableHealthStatusFeature),
- hasIssueWeightsFeature: parseBoolean(hasIssueWeightsFeature),
- hasIterationsFeature: parseBoolean(hasIterationsFeature),
- hasMultipleIssueAssigneesFeature: parseBoolean(hasMultipleIssueAssigneesFeature),
- isAnonymousSearchDisabled: parseBoolean(isAnonymousSearchDisabled),
- isIssueRepositioningDisabled: parseBoolean(isIssueRepositioningDisabled),
- isProject: parseBoolean(isProject),
- isSignedIn: parseBoolean(isSignedIn),
- jiraIntegrationPath,
- newIssuePath,
- releasesPath,
- rssPath,
- showNewIssueLink: parseBoolean(showNewIssueLink),
- signInPath,
- // For CsvImportExportButtons component
- canEdit: parseBoolean(canEdit),
- email,
- exportCsvPath,
- importCsvIssuesPath,
- maxAttachmentSize,
- projectImportJiraPath,
- showExportButton: parseBoolean(hasAnyIssues),
- showImportButton: parseBoolean(canImportIssues),
- showLabel: !parseBoolean(hasAnyIssues),
- // For IssuableByEmail component
- emailsHelpPagePath,
- initialEmail,
- markdownHelpPath,
- quickActionsHelpPath,
- resetPath,
- },
- render: (createComponent) => createComponent(IssuesListApp),
- });
-}
diff --git a/app/assets/javascripts/issues_list/service_desk_helper.js b/app/assets/javascripts/issues_list/service_desk_helper.js
deleted file mode 100644
index 815f338f1a0..00000000000
--- a/app/assets/javascripts/issues_list/service_desk_helper.js
+++ /dev/null
@@ -1,111 +0,0 @@
-import { __, s__ } from '~/locale';
-
-/**
- * Generates empty state messages for Service Desk issues list.
- *
- * @param {emptyStateMeta} emptyStateMeta - Meta data used to generate empty state messages
- * @returns {Object} Object containing empty state messages generated using the meta data.
- */
-export function generateMessages(emptyStateMeta) {
- const {
- svgPath,
- serviceDeskHelpPage,
- serviceDeskAddress,
- editProjectPage,
- incomingEmailHelpPage,
- } = emptyStateMeta;
-
- const serviceDeskSupportedTitle = s__(
- 'ServiceDesk|Use Service Desk to connect with your users and offer customer support through email right inside GitLab',
- );
-
- const serviceDeskSupportedMessage = s__(
- 'ServiceDesk|Issues created from Service Desk emails will appear here. Each comment becomes part of the email conversation.',
- );
-
- const commonDescription = `
- <span>${serviceDeskSupportedMessage}</span>
- <a href="${serviceDeskHelpPage}">${__('Learn more.')}</a>`;
-
- return {
- serviceDeskEnabledAndCanEditProjectSettings: {
- title: serviceDeskSupportedTitle,
- svgPath,
- description: `<p>${s__('ServiceDesk|Your users can send emails to this address:')}
- <code>${serviceDeskAddress}</code>
- </p>
- ${commonDescription}`,
- },
- serviceDeskEnabledAndCannotEditProjectSettings: {
- title: serviceDeskSupportedTitle,
- svgPath,
- description: commonDescription,
- },
- serviceDeskDisabledAndCanEditProjectSettings: {
- title: serviceDeskSupportedTitle,
- svgPath,
- description: commonDescription,
- primaryLink: editProjectPage,
- primaryText: s__('ServiceDesk|Enable Service Desk'),
- },
- serviceDeskDisabledAndCannotEditProjectSettings: {
- title: serviceDeskSupportedTitle,
- svgPath,
- description: commonDescription,
- },
- serviceDeskIsNotSupported: {
- title: s__('ServiceDesk|Service Desk is not supported'),
- svgPath,
- description: s__(
- 'ServiceDesk|To enable Service Desk on this instance, an instance administrator must first set up incoming email.',
- ),
- primaryLink: incomingEmailHelpPage,
- primaryText: __('Learn more.'),
- },
- serviceDeskIsNotEnabled: {
- title: s__('ServiceDesk|Service Desk is not enabled'),
- svgPath,
- description: s__(
- 'ServiceDesk|For help setting up the Service Desk for your instance, please contact an administrator.',
- ),
- },
- };
-}
-
-/**
- * Returns the attributes used for gl-empty-state in the Service Desk issues list.
- *
- * @param {Object} emptyStateMeta - Meta data used to generate empty state messages
- * @returns {Object}
- */
-export function emptyStateHelper(emptyStateMeta) {
- const messages = generateMessages(emptyStateMeta);
-
- const { isServiceDeskSupported, canEditProjectSettings, isServiceDeskEnabled } = emptyStateMeta;
-
- if (isServiceDeskSupported) {
- if (isServiceDeskEnabled && canEditProjectSettings) {
- return messages.serviceDeskEnabledAndCanEditProjectSettings;
- }
-
- if (isServiceDeskEnabled && !canEditProjectSettings) {
- return messages.serviceDeskEnabledAndCannotEditProjectSettings;
- }
-
- // !isServiceDeskEnabled && canEditProjectSettings
- if (canEditProjectSettings) {
- return messages.serviceDeskDisabledAndCanEditProjectSettings;
- }
-
- // !isServiceDeskEnabled && !canEditProjectSettings
- return messages.serviceDeskDisabledAndCannotEditProjectSettings;
- }
-
- // !serviceDeskSupported && canEditProjectSettings
- if (canEditProjectSettings) {
- return messages.serviceDeskIsNotSupported;
- }
-
- // !serviceDeskSupported && !canEditProjectSettings
- return messages.serviceDeskIsNotEnabled;
-}
diff --git a/app/assets/javascripts/issues_list/utils.js b/app/assets/javascripts/issues_list/utils.js
deleted file mode 100644
index 99946e4e851..00000000000
--- a/app/assets/javascripts/issues_list/utils.js
+++ /dev/null
@@ -1,261 +0,0 @@
-import {
- API_PARAM,
- BLOCKING_ISSUES_ASC,
- BLOCKING_ISSUES_DESC,
- CREATED_ASC,
- CREATED_DESC,
- defaultPageSizeParams,
- DUE_DATE_ASC,
- DUE_DATE_DESC,
- DUE_DATE_VALUES,
- filters,
- LABEL_PRIORITY_ASC,
- LABEL_PRIORITY_DESC,
- largePageSizeParams,
- MILESTONE_DUE_ASC,
- MILESTONE_DUE_DESC,
- NORMAL_FILTER,
- POPULARITY_ASC,
- POPULARITY_DESC,
- PRIORITY_ASC,
- PRIORITY_DESC,
- RELATIVE_POSITION_ASC,
- SPECIAL_FILTER,
- SPECIAL_FILTER_VALUES,
- TITLE_ASC,
- TITLE_DESC,
- TOKEN_TYPE_ASSIGNEE,
- TOKEN_TYPE_CONFIDENTIAL,
- TOKEN_TYPE_ITERATION,
- TOKEN_TYPE_MILESTONE,
- TOKEN_TYPE_RELEASE,
- TOKEN_TYPE_TYPE,
- UPDATED_ASC,
- UPDATED_DESC,
- URL_PARAM,
- urlSortParams,
- WEIGHT_ASC,
- WEIGHT_DESC,
-} from '~/issues_list/constants';
-import { isPositiveInteger } from '~/lib/utils/number_utils';
-import { __ } from '~/locale';
-import {
- FILTERED_SEARCH_TERM,
- OPERATOR_IS_NOT,
-} from '~/vue_shared/components/filtered_search_bar/constants';
-
-export const getInitialPageParams = (sortKey) =>
- sortKey === RELATIVE_POSITION_ASC ? largePageSizeParams : defaultPageSizeParams;
-
-export const getSortKey = (sort) =>
- Object.keys(urlSortParams).find((key) => urlSortParams[key] === sort);
-
-export const getDueDateValue = (value) => (DUE_DATE_VALUES.includes(value) ? value : undefined);
-
-export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature) => {
- const sortOptions = [
- {
- id: 1,
- title: __('Priority'),
- sortDirection: {
- ascending: PRIORITY_ASC,
- descending: PRIORITY_DESC,
- },
- },
- {
- id: 2,
- title: __('Created date'),
- sortDirection: {
- ascending: CREATED_ASC,
- descending: CREATED_DESC,
- },
- },
- {
- id: 3,
- title: __('Last updated'),
- sortDirection: {
- ascending: UPDATED_ASC,
- descending: UPDATED_DESC,
- },
- },
- {
- id: 4,
- title: __('Milestone due date'),
- sortDirection: {
- ascending: MILESTONE_DUE_ASC,
- descending: MILESTONE_DUE_DESC,
- },
- },
- {
- id: 5,
- title: __('Due date'),
- sortDirection: {
- ascending: DUE_DATE_ASC,
- descending: DUE_DATE_DESC,
- },
- },
- {
- id: 6,
- title: __('Popularity'),
- sortDirection: {
- ascending: POPULARITY_ASC,
- descending: POPULARITY_DESC,
- },
- },
- {
- id: 7,
- title: __('Label priority'),
- sortDirection: {
- ascending: LABEL_PRIORITY_ASC,
- descending: LABEL_PRIORITY_DESC,
- },
- },
- {
- id: 8,
- title: __('Manual'),
- sortDirection: {
- ascending: RELATIVE_POSITION_ASC,
- descending: RELATIVE_POSITION_ASC,
- },
- },
- {
- id: 9,
- title: __('Title'),
- sortDirection: {
- ascending: TITLE_ASC,
- descending: TITLE_DESC,
- },
- },
- ];
-
- if (hasIssueWeightsFeature) {
- sortOptions.push({
- id: sortOptions.length + 1,
- title: __('Weight'),
- sortDirection: {
- ascending: WEIGHT_ASC,
- descending: WEIGHT_DESC,
- },
- });
- }
-
- if (hasBlockedIssuesFeature) {
- sortOptions.push({
- id: sortOptions.length + 1,
- title: __('Blocking'),
- sortDirection: {
- ascending: BLOCKING_ISSUES_ASC,
- descending: BLOCKING_ISSUES_DESC,
- },
- });
- }
-
- return sortOptions;
-};
-
-const tokenTypes = Object.keys(filters);
-
-const getUrlParams = (tokenType) =>
- Object.values(filters[tokenType][URL_PARAM]).flatMap((filterObj) => Object.values(filterObj));
-
-const urlParamKeys = tokenTypes.flatMap(getUrlParams);
-
-const getTokenTypeFromUrlParamKey = (urlParamKey) =>
- tokenTypes.find((tokenType) => getUrlParams(tokenType).includes(urlParamKey));
-
-const getOperatorFromUrlParamKey = (tokenType, urlParamKey) =>
- Object.entries(filters[tokenType][URL_PARAM]).find(([, filterObj]) =>
- Object.values(filterObj).includes(urlParamKey),
- )[0];
-
-const convertToFilteredTokens = (locationSearch) =>
- Array.from(new URLSearchParams(locationSearch).entries())
- .filter(([key]) => urlParamKeys.includes(key))
- .map(([key, data]) => {
- const type = getTokenTypeFromUrlParamKey(key);
- const operator = getOperatorFromUrlParamKey(type, key);
- return {
- type,
- value: { data, operator },
- };
- });
-
-const convertToFilteredSearchTerms = (locationSearch) =>
- new URLSearchParams(locationSearch)
- .get('search')
- ?.split(' ')
- .map((word) => ({
- type: FILTERED_SEARCH_TERM,
- value: {
- data: word,
- },
- })) || [];
-
-export const getFilterTokens = (locationSearch) => {
- if (!locationSearch) {
- return [];
- }
- const filterTokens = convertToFilteredTokens(locationSearch);
- const searchTokens = convertToFilteredSearchTerms(locationSearch);
- return filterTokens.concat(searchTokens);
-};
-
-const getFilterType = (data, tokenType = '') =>
- SPECIAL_FILTER_VALUES.includes(data) ||
- (tokenType === TOKEN_TYPE_ASSIGNEE && isPositiveInteger(data))
- ? SPECIAL_FILTER
- : NORMAL_FILTER;
-
-const wildcardTokens = [TOKEN_TYPE_ITERATION, TOKEN_TYPE_MILESTONE, TOKEN_TYPE_RELEASE];
-
-const isWildcardValue = (tokenType, value) =>
- wildcardTokens.includes(tokenType) && SPECIAL_FILTER_VALUES.includes(value);
-
-const requiresUpperCaseValue = (tokenType, value) =>
- tokenType === TOKEN_TYPE_TYPE || isWildcardValue(tokenType, value);
-
-const formatData = (token) => {
- if (requiresUpperCaseValue(token.type, token.value.data)) {
- return token.value.data.toUpperCase();
- }
- if (token.type === TOKEN_TYPE_CONFIDENTIAL) {
- return token.value.data === 'yes';
- }
- return token.value.data;
-};
-
-export const convertToApiParams = (filterTokens) => {
- const params = {};
- const not = {};
-
- filterTokens
- .filter((token) => token.type !== FILTERED_SEARCH_TERM)
- .forEach((token) => {
- const filterType = getFilterType(token.value.data, token.type);
- const field = filters[token.type][API_PARAM][filterType];
- const obj = token.value.operator === OPERATOR_IS_NOT ? not : params;
- const data = formatData(token);
- Object.assign(obj, {
- [field]: obj[field] ? [obj[field], data].flat() : data,
- });
- });
-
- return Object.keys(not).length ? Object.assign(params, { not }) : params;
-};
-
-export const convertToUrlParams = (filterTokens) =>
- filterTokens
- .filter((token) => token.type !== FILTERED_SEARCH_TERM)
- .reduce((acc, token) => {
- const filterType = getFilterType(token.value.data, token.type);
- const param = filters[token.type][URL_PARAM][token.value.operator]?.[filterType];
- return Object.assign(acc, {
- [param]: acc[param] ? [acc[param], token.value.data].flat() : token.value.data,
- });
- }, {});
-
-export const convertToSearchQuery = (filterTokens) =>
- filterTokens
- .filter((token) => token.type === FILTERED_SEARCH_TERM && token.value.data)
- .map((token) => token.value.data)
- .join(' ');
diff --git a/app/assets/javascripts/jira_import/utils/constants.js b/app/assets/javascripts/jira_import/utils/constants.js
index 178159be009..4230f85e443 100644
--- a/app/assets/javascripts/jira_import/utils/constants.js
+++ b/app/assets/javascripts/jira_import/utils/constants.js
@@ -1,5 +1,7 @@
import { __ } from '~/locale';
+export const JIRA_IMPORT_SUCCESS_ALERT_HIDE_MAP_KEY = 'jira-import-success-alert-hide-map';
+
export const debounceWait = 500;
export const dropdownLabel = __(
diff --git a/app/assets/javascripts/jira_import/utils/jira_import_utils.js b/app/assets/javascripts/jira_import/utils/jira_import_utils.js
index 4e3b5b2fbde..bd83dd4d219 100644
--- a/app/assets/javascripts/jira_import/utils/jira_import_utils.js
+++ b/app/assets/javascripts/jira_import/utils/jira_import_utils.js
@@ -1,5 +1,5 @@
import { last } from 'lodash';
-import { JIRA_IMPORT_SUCCESS_ALERT_HIDE_MAP_KEY } from '~/issues_list/constants';
+import { JIRA_IMPORT_SUCCESS_ALERT_HIDE_MAP_KEY } from './constants';
export const IMPORT_STATE = {
FAILED: 'failed',
diff --git a/app/assets/javascripts/jobs/bridge/app.vue b/app/assets/javascripts/jobs/bridge/app.vue
index 67c22712776..c639e49083b 100644
--- a/app/assets/javascripts/jobs/bridge/app.vue
+++ b/app/assets/javascripts/jobs/bridge/app.vue
@@ -1,20 +1,118 @@
<script>
+import { GlLoadingIcon } from '@gitlab/ui';
+import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+import { __, sprintf } from '~/locale';
+import CiHeader from '~/vue_shared/components/header_ci_component.vue';
+import getPipelineQuery from './graphql/queries/pipeline.query.graphql';
import BridgeEmptyState from './components/empty_state.vue';
import BridgeSidebar from './components/sidebar.vue';
+import { SIDEBAR_COLLAPSE_BREAKPOINTS } from './components/constants';
export default {
name: 'BridgePageApp',
components: {
BridgeEmptyState,
BridgeSidebar,
+ CiHeader,
+ GlLoadingIcon,
+ },
+ inject: ['buildId', 'projectFullPath', 'pipelineIid'],
+ apollo: {
+ pipeline: {
+ query: getPipelineQuery,
+ variables() {
+ return {
+ fullPath: this.projectFullPath,
+ iid: this.pipelineIid,
+ };
+ },
+ update(data) {
+ if (!data?.project?.pipeline) {
+ return null;
+ }
+
+ const { pipeline } = data.project;
+ const stages = pipeline?.stages.edges.map((edge) => edge.node) || [];
+ const jobs = stages.map((stage) => stage.jobs.nodes).flat();
+
+ return {
+ ...pipeline,
+ commit: {
+ ...pipeline.commit,
+ commit_path: pipeline.commit.webPath,
+ short_id: pipeline.commit.shortId,
+ },
+ id: getIdFromGraphQLId(pipeline.id),
+ jobs,
+ stages,
+ };
+ },
+ },
+ },
+ data() {
+ return {
+ isSidebarExpanded: true,
+ pipeline: {},
+ };
+ },
+ computed: {
+ bridgeJob() {
+ return (
+ this.pipeline.jobs?.filter(
+ (job) => getIdFromGraphQLId(job.id) === Number(this.buildId),
+ )[0] || {}
+ );
+ },
+ bridgeName() {
+ return sprintf(__('Job %{jobName}'), { jobName: this.bridgeJob.name });
+ },
+ isPipelineLoading() {
+ return this.$apollo.queries.pipeline.loading;
+ },
+ },
+ created() {
+ window.addEventListener('resize', this.onResize);
+ },
+ mounted() {
+ this.onResize();
+ },
+ methods: {
+ toggleSidebar() {
+ this.isSidebarExpanded = !this.isSidebarExpanded;
+ },
+ onResize() {
+ const breakpoint = bp.getBreakpointSize();
+ if (SIDEBAR_COLLAPSE_BREAKPOINTS.includes(breakpoint)) {
+ this.isSidebarExpanded = false;
+ } else if (!this.isSidebarExpanded) {
+ this.isSidebarExpanded = true;
+ }
+ },
},
};
</script>
<template>
<div>
- <!-- TODO: get job details and show CI header -->
- <!-- TODO: add downstream pipeline path -->
- <bridge-empty-state downstream-pipeline-path="#" />
- <bridge-sidebar />
+ <gl-loading-icon v-if="isPipelineLoading" size="lg" class="gl-mt-4" />
+ <div v-else>
+ <ci-header
+ class="gl-border-b-1 gl-border-b-solid gl-border-b-gray-100"
+ :status="bridgeJob.detailedStatus"
+ :time="bridgeJob.createdAt"
+ :user="pipeline.user"
+ :has-sidebar-button="true"
+ :item-name="bridgeName"
+ @clickedSidebarButton="toggleSidebar"
+ />
+ <bridge-empty-state :downstream-pipeline-path="bridgeJob.downstreamPipeline.path" />
+ <bridge-sidebar
+ v-if="isSidebarExpanded"
+ :bridge-job="bridgeJob"
+ :commit="pipeline.commit"
+ :is-sidebar-expanded="isSidebarExpanded"
+ @toggleSidebar="toggleSidebar"
+ />
+ </div>
</div>
</template>
diff --git a/app/assets/javascripts/jobs/bridge/components/sidebar.vue b/app/assets/javascripts/jobs/bridge/components/sidebar.vue
index 68b767408f0..3ba07cf55d1 100644
--- a/app/assets/javascripts/jobs/bridge/components/sidebar.vue
+++ b/app/assets/javascripts/jobs/bridge/components/sidebar.vue
@@ -1,14 +1,13 @@
<script>
import { GlButton, GlDropdown, GlDropdownItem } from '@gitlab/ui';
-import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import { __ } from '~/locale';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
import { JOB_SIDEBAR } from '../../constants';
-import { SIDEBAR_COLLAPSE_BREAKPOINTS } from './constants';
+import CommitBlock from '../../components/commit_block.vue';
export default {
styles: {
- top: '75px',
width: '290px',
},
name: 'BridgeSidebar',
@@ -18,40 +17,47 @@ export default {
retryTriggerJob: __('Retry the trigger job'),
retryDownstreamPipeline: __('Retry the downstream pipeline'),
},
- borderTopClass: ['gl-border-t-solid', 'gl-border-t-1', 'gl-border-t-gray-100'],
+ sectionClass: ['gl-border-t-solid', 'gl-border-t-1', 'gl-border-t-gray-100', 'gl-py-5'],
components: {
+ CommitBlock,
GlButton,
GlDropdown,
GlDropdownItem,
TooltipOnTruncate,
},
- inject: {
- buildName: {
- type: String,
- default: '',
+ mixins: [glFeatureFlagsMixin()],
+ props: {
+ bridgeJob: {
+ type: Object,
+ required: true,
+ },
+ commit: {
+ type: Object,
+ required: true,
},
},
data() {
return {
- isSidebarExpanded: true,
+ topPosition: 0,
};
},
- created() {
- window.addEventListener('resize', this.onResize);
+ computed: {
+ rootStyle() {
+ return { ...this.$options.styles, top: `${this.topPosition}px` };
+ },
},
mounted() {
- this.onResize();
+ this.setTopPosition();
},
methods: {
- toggleSidebar() {
- this.isSidebarExpanded = !this.isSidebarExpanded;
+ onSidebarButtonClick() {
+ this.$emit('toggleSidebar');
},
- onResize() {
- const breakpoint = bp.getBreakpointSize();
- if (SIDEBAR_COLLAPSE_BREAKPOINTS.includes(breakpoint)) {
- this.isSidebarExpanded = false;
- } else if (!this.isSidebarExpanded) {
- this.isSidebarExpanded = true;
+ setTopPosition() {
+ const navbarEl = document.querySelector('.js-navbar');
+
+ if (navbarEl) {
+ this.topPosition = navbarEl.getBoundingClientRect().bottom;
}
},
},
@@ -60,19 +66,19 @@ export default {
<template>
<aside
class="gl-fixed gl-right-0 gl-px-5 gl-bg-gray-10 gl-h-full gl-border-l-solid gl-border-1 gl-border-gray-100 gl-z-index-200 gl-overflow-hidden"
- :style="this.$options.styles"
- :class="{
- 'gl-display-none': !isSidebarExpanded,
- }"
+ :style="rootStyle"
>
<div class="gl-py-5 gl-display-flex gl-align-items-center">
- <tooltip-on-truncate :title="buildName" truncate-target="child"
+ <tooltip-on-truncate :title="bridgeJob.name" truncate-target="child"
><h4 class="gl-mb-0 gl-mr-2 gl-text-truncate">
- {{ buildName }}
+ {{ bridgeJob.name }}
</h4>
</tooltip-on-truncate>
<!-- TODO: implement retry actions -->
- <div class="gl-flex-grow-1 gl-flex-shrink-0 gl-text-right">
+ <div
+ v-if="glFeatures.triggerJobRetryAction"
+ class="gl-flex-grow-1 gl-flex-shrink-0 gl-text-right"
+ >
<gl-dropdown
:text="$options.i18n.retryButton"
category="primary"
@@ -90,9 +96,10 @@ export default {
category="tertiary"
class="gl-md-display-none gl-ml-2"
icon="chevron-double-lg-right"
- @click="toggleSidebar"
+ @click="onSidebarButtonClick"
/>
</div>
- <!-- TODO: get job details and show commit block, stage dropdown, jobs list -->
+ <commit-block :commit="commit" :class="$options.sectionClass" />
+ <!-- TODO: show stage dropdown, jobs list -->
</aside>
</template>
diff --git a/app/assets/javascripts/jobs/bridge/graphql/queries/pipeline.query.graphql b/app/assets/javascripts/jobs/bridge/graphql/queries/pipeline.query.graphql
new file mode 100644
index 00000000000..338ca9f16c7
--- /dev/null
+++ b/app/assets/javascripts/jobs/bridge/graphql/queries/pipeline.query.graphql
@@ -0,0 +1,70 @@
+query getPipelineData($fullPath: ID!, $iid: ID!) {
+ project(fullPath: $fullPath) {
+ id
+ pipeline(iid: $iid) {
+ id
+ iid
+ path
+ sha
+ ref
+ refPath
+ commit {
+ id
+ shortId
+ title
+ webPath
+ }
+ detailedStatus {
+ id
+ icon
+ group
+ }
+ stages {
+ edges {
+ node {
+ id
+ name
+ jobs {
+ nodes {
+ id
+ createdAt
+ name
+ scheduledAt
+ startedAt
+ status
+ triggered
+ detailedStatus {
+ id
+ detailsPath
+ icon
+ group
+ text
+ tooltip
+ }
+ downstreamPipeline {
+ id
+ path
+ }
+ stage {
+ id
+ name
+ }
+ }
+ }
+ }
+ }
+ }
+ user {
+ id
+ avatarUrl
+ name
+ username
+ webPath
+ webUrl
+ status {
+ message
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/jobs/components/job_log_controllers.vue b/app/assets/javascripts/jobs/components/job_log_controllers.vue
index 97141a27a5e..8e35fd91481 100644
--- a/app/assets/javascripts/jobs/components/job_log_controllers.vue
+++ b/app/assets/javascripts/jobs/components/job_log_controllers.vue
@@ -107,6 +107,7 @@ export default {
: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"
/>
diff --git a/app/assets/javascripts/jobs/components/sidebar_job_details_container.vue b/app/assets/javascripts/jobs/components/sidebar_job_details_container.vue
index 5451cd21c14..5428f657252 100644
--- a/app/assets/javascripts/jobs/components/sidebar_job_details_container.vue
+++ b/app/assets/javascripts/jobs/components/sidebar_job_details_container.vue
@@ -1,5 +1,6 @@
<script>
import { mapState } from 'vuex';
+import { GlBadge } from '@gitlab/ui';
import { helpPagePath } from '~/helpers/help_page_helper';
import { timeIntervalInWords } from '~/lib/utils/datetime_utility';
import { __, sprintf } from '~/locale';
@@ -10,6 +11,7 @@ export default {
name: 'JobSidebarDetailsContainer',
components: {
DetailRow,
+ GlBadge,
},
mixins: [timeagoMixin],
computed: {
@@ -100,12 +102,7 @@ export default {
<p v-if="hasTags" class="build-detail-row" data-testid="job-tags">
<span class="font-weight-bold">{{ __('Tags:') }}</span>
- <span
- v-for="(tag, i) in job.tags"
- :key="i"
- class="badge badge-pill badge-primary gl-badge sm"
- >{{ tag }}</span
- >
+ <gl-badge v-for="(tag, i) in job.tags" :key="i" variant="info">{{ tag }}</gl-badge>
</p>
</div>
</template>
diff --git a/app/assets/javascripts/jobs/index.js b/app/assets/javascripts/jobs/index.js
index e078a6c2319..6e958ea1842 100644
--- a/app/assets/javascripts/jobs/index.js
+++ b/app/assets/javascripts/jobs/index.js
@@ -54,7 +54,13 @@ const initializeJobPage = (element) => {
};
const initializeBridgePage = (el) => {
- const { buildName, emptyStateIllustrationPath } = el.dataset;
+ const {
+ buildId,
+ downstreamPipelinePath,
+ emptyStateIllustrationPath,
+ pipelineIid,
+ projectFullPath,
+ } = el.dataset;
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
@@ -65,8 +71,11 @@ const initializeBridgePage = (el) => {
el,
apolloProvider,
provide: {
- buildName,
+ buildId,
+ downstreamPipelinePath,
emptyStateIllustrationPath,
+ pipelineIid,
+ projectFullPath,
},
render(h) {
return h(BridgeApp);
diff --git a/app/assets/javascripts/labels/components/delete_label_modal.vue b/app/assets/javascripts/labels/components/delete_label_modal.vue
index 1ff0938d086..2be404de1e1 100644
--- a/app/assets/javascripts/labels/components/delete_label_modal.vue
+++ b/app/assets/javascripts/labels/components/delete_label_modal.vue
@@ -56,6 +56,7 @@ export default {
</gl-sprintf>
</template>
<gl-sprintf
+ v-if="subjectName"
:message="
__(
`%{strongStart}${labelName}%{strongEnd} will be permanently deleted from ${subjectName}. This cannot be undone.`,
@@ -66,6 +67,18 @@ export default {
<strong>{{ content }}</strong>
</template>
</gl-sprintf>
+ <gl-sprintf
+ v-else
+ :message="
+ __(
+ `%{strongStart}${labelName}%{strongEnd} will be permanently deleted. This cannot be undone.`,
+ )
+ "
+ >
+ <template #strong="{ content }">
+ <strong>{{ content }}</strong>
+ </template>
+ </gl-sprintf>
<template #modal-footer>
<gl-button category="secondary" @click="closeModal">{{ __('Cancel') }}</gl-button>
<gl-button
diff --git a/app/assets/javascripts/labels/create_label_dropdown.js b/app/assets/javascripts/labels/create_label_dropdown.js
index 8c166158a44..033ca9dd3ea 100644
--- a/app/assets/javascripts/labels/create_label_dropdown.js
+++ b/app/assets/javascripts/labels/create_label_dropdown.js
@@ -16,6 +16,7 @@ export default class CreateLabelDropdown {
this.$colorPreview = $('.js-dropdown-label-color-preview', this.$el);
this.$addList = $('.js-add-list', this.$el);
this.$newLabelError = $('.js-label-error', this.$el);
+ this.$newLabelErrorContent = $('.gl-alert-content', this.$newLabelError);
this.$newLabelCreateButton = $('.js-new-label-btn', this.$el);
this.$colorSuggestions = $('.suggest-colors-dropdown a', this.$el);
@@ -119,7 +120,8 @@ export default class CreateLabelDropdown {
.join('<br/>');
}
- this.$newLabelError.html(errors).show();
+ this.$newLabelErrorContent.html(errors);
+ this.$newLabelError.show();
} else {
const addNewList = this.$addList.is(':checked');
this.$dropdownBack.trigger('click');
diff --git a/app/assets/javascripts/labels/index.js b/app/assets/javascripts/labels/index.js
index 22a9c0a89c0..e87ad8d9a06 100644
--- a/app/assets/javascripts/labels/index.js
+++ b/app/assets/javascripts/labels/index.js
@@ -26,7 +26,7 @@ export function initLabels() {
if ($('.prioritized-labels').length) {
new LabelManager(); // eslint-disable-line no-new
}
- $('.label-subscription').each((i, el) => {
+ $('.js-label-subscription').each((i, el) => {
const $el = $(el);
if ($el.find('.dropdown-group-label').length) {
diff --git a/app/assets/javascripts/lib/mermaid.js b/app/assets/javascripts/lib/mermaid.js
new file mode 100644
index 00000000000..d621c9ddf9e
--- /dev/null
+++ b/app/assets/javascripts/lib/mermaid.js
@@ -0,0 +1,61 @@
+import mermaid from 'mermaid';
+import { getParameterByName } from '~/lib/utils/url_utility';
+
+const setIframeRenderedSize = (h, w) => {
+ const { origin } = window.location;
+ window.parent.postMessage({ h, w }, origin);
+};
+
+const drawDiagram = (source) => {
+ const element = document.getElementById('app');
+ const insertSvg = (svgCode) => {
+ element.innerHTML = svgCode;
+
+ const height = parseInt(element.firstElementChild.getAttribute('height'), 10);
+ const width = parseInt(element.firstElementChild.style.maxWidth, 10);
+ setIframeRenderedSize(height, width);
+ };
+ mermaid.mermaidAPI.render('mermaid', source, insertSvg);
+};
+
+const darkModeEnabled = () => getParameterByName('darkMode') === 'true';
+
+const initMermaid = () => {
+ let theme = 'neutral';
+
+ if (darkModeEnabled()) {
+ theme = 'dark';
+ }
+
+ mermaid.initialize({
+ // mermaid core options
+ mermaid: {
+ startOnLoad: false,
+ },
+ // mermaidAPI options
+ theme,
+ flowchart: {
+ useMaxWidth: true,
+ htmlLabels: true,
+ },
+ secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize', 'htmlLabels'],
+ securityLevel: 'strict',
+ });
+};
+
+const addListener = () => {
+ window.addEventListener(
+ 'message',
+ (event) => {
+ if (event.origin !== window.location.origin) {
+ return;
+ }
+ drawDiagram(event.data);
+ },
+ false,
+ );
+};
+
+addListener();
+initMermaid();
+export default {};
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js
index 7235b38848c..eff00dff7a7 100644
--- a/app/assets/javascripts/lib/utils/common_utils.js
+++ b/app/assets/javascripts/lib/utils/common_utils.js
@@ -181,6 +181,7 @@ export const contentTop = () => {
},
() => getOuterHeight('.merge-request-tabs'),
() => getOuterHeight('.js-diff-files-changed'),
+ () => getOuterHeight('.issue-sticky-header.gl-fixed'),
({ desktop }) => {
const diffsTabIsActive = window.mrTabs?.currentAction === 'diffs';
let size;
@@ -746,3 +747,12 @@ export const isLoggedIn = () => Boolean(window.gon?.current_user_id);
*/
export const convertArrayOfObjectsToCamelCase = (array) =>
array.map((o) => convertObjectPropsToCamelCase(o));
+
+export const getFirstPropertyValue = (data) => {
+ if (!data) return null;
+
+ const [key] = Object.keys(data);
+ if (!key) return null;
+
+ return data[key];
+};
diff --git a/app/assets/javascripts/lib/utils/constants.js b/app/assets/javascripts/lib/utils/constants.js
index a108b02bcbf..36c6545164e 100644
--- a/app/assets/javascripts/lib/utils/constants.js
+++ b/app/assets/javascripts/lib/utils/constants.js
@@ -17,7 +17,6 @@ export const BV_HIDE_MODAL = 'bv::hide::modal';
export const BV_HIDE_TOOLTIP = 'bv::hide::tooltip';
export const BV_DROPDOWN_SHOW = 'bv::dropdown::show';
export const BV_DROPDOWN_HIDE = 'bv::dropdown::hide';
-export const BV_COLLAPSE_STATE = 'bv::collapse::state';
export const DEFAULT_TH_CLASSES =
'gl-bg-transparent! gl-border-b-solid! gl-border-b-gray-100! gl-p-5! gl-border-b-1!';
diff --git a/app/assets/javascripts/lib/utils/resize_observer.js b/app/assets/javascripts/lib/utils/resize_observer.js
new file mode 100644
index 00000000000..e72c6fe1679
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/resize_observer.js
@@ -0,0 +1,58 @@
+import { contentTop } from './common_utils';
+
+const interactionEvents = ['mousedown', 'touchstart', 'keydown', 'wheel'];
+
+export function createResizeObserver() {
+ return new ResizeObserver((entries) => {
+ entries.forEach((entry) => {
+ entry.target.dispatchEvent(new CustomEvent(`ResizeUpdate`, { detail: { entry } }));
+ });
+ });
+}
+
+// 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
+export function scrollToTargetOnResize({
+ target = window.location.hash,
+ container = '#content-body',
+} = {}) {
+ if (!target) return null;
+
+ const ro = createResizeObserver();
+ const containerEl = document.querySelector(container);
+ let interactionListenersAdded = false;
+
+ function keepTargetAtTop() {
+ const anchorEl = document.querySelector(target);
+
+ if (!anchorEl) return;
+
+ const anchorTop = anchorEl.getBoundingClientRect().top + window.scrollY;
+ const top = anchorTop - contentTop();
+ document.documentElement.scrollTo({
+ top,
+ });
+
+ if (!interactionListenersAdded) {
+ interactionEvents.forEach((event) =>
+ // eslint-disable-next-line no-use-before-define
+ document.addEventListener(event, removeListeners),
+ );
+ interactionListenersAdded = true;
+ }
+ }
+
+ function removeListeners() {
+ interactionEvents.forEach((event) => document.removeEventListener(event, removeListeners));
+
+ ro.unobserve(containerEl);
+ containerEl.removeEventListener('ResizeUpdate', keepTargetAtTop);
+ }
+
+ containerEl.addEventListener('ResizeUpdate', keepTargetAtTop);
+
+ ro.observe(containerEl);
+ return ro;
+}
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index e221a54d9c6..376134afef0 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -101,6 +101,21 @@ function deferredInitialisation() {
initFeatureHighlight();
initCopyCodeButton();
+ const helpToggle = document.querySelector('.header-help-dropdown-toggle');
+ if (helpToggle) {
+ helpToggle.addEventListener(
+ 'click',
+ () => {
+ import(/* webpackChunkName: 'versionCheck' */ './gitlab_version_check')
+ .then(({ default: initGitlabVersionCheck }) => {
+ initGitlabVersionCheck();
+ })
+ .catch(() => {});
+ },
+ { once: true },
+ );
+ }
+
const search = document.querySelector('#search');
if (search) {
search.addEventListener(
diff --git a/app/assets/javascripts/members/components/table/members_table.vue b/app/assets/javascripts/members/components/table/members_table.vue
index de733ae75df..e09d16cf680 100644
--- a/app/assets/javascripts/members/components/table/members_table.vue
+++ b/app/assets/javascripts/members/components/table/members_table.vue
@@ -6,6 +6,7 @@ import { canOverride, canRemove, canResend, canUpdate } from 'ee_else_ce/members
import { mergeUrlParams } from '~/lib/utils/url_utility';
import initUserPopovers from '~/user_popovers';
import {
+ FIELD_KEY_ACTIONS,
FIELDS,
ACTIVE_TAB_QUERY_PARAM_NAME,
TAB_QUERY_PARAM_VALUES,
@@ -63,17 +64,10 @@ export default {
return state[this.namespace].pagination;
},
}),
- filteredFields() {
+ filteredAndModifiedFields() {
return FIELDS.filter(
(field) => this.tableFields.includes(field.key) && this.showField(field),
- ).map((field) => {
- const tdClassFunction = this[field.tdClassFunction];
-
- return {
- ...field,
- ...(tdClassFunction && { tdClass: tdClassFunction }),
- };
- });
+ ).map(this.modifyFieldDefinition);
},
userIsLoggedIn() {
return this.currentUserId !== null;
@@ -100,20 +94,29 @@ export default {
);
},
showField(field) {
- if (!Object.prototype.hasOwnProperty.call(field, 'showFunction')) {
- return true;
- }
+ switch (field.key) {
+ case FIELD_KEY_ACTIONS:
+ if (!this.userIsLoggedIn) {
+ return false;
+ }
- return this[field.showFunction]();
+ return this.members.some((member) => this.hasActionButtons(member));
+ default:
+ return true;
+ }
},
- showActionsField() {
- if (!this.userIsLoggedIn) {
- return false;
+ modifyFieldDefinition(field) {
+ switch (field.key) {
+ case FIELD_KEY_ACTIONS:
+ return {
+ ...field,
+ tdClass: this.actionsFieldTdClass,
+ };
+ default:
+ return field;
}
-
- return this.members.some((member) => this.hasActionButtons(member));
},
- tdClassActions(value, key, member) {
+ actionsFieldTdClass(value, key, member) {
if (this.hasActionButtons(member)) {
return 'col-actions';
}
@@ -219,7 +222,7 @@ export default {
data-testid="members-table"
head-variant="white"
stacked="lg"
- :fields="filteredFields"
+ :fields="filteredAndModifiedFields"
:items="members"
primary-key="id"
thead-class="border-bottom"
diff --git a/app/assets/javascripts/members/constants.js b/app/assets/javascripts/members/constants.js
index f5ca881ab0d..62241eaed04 100644
--- a/app/assets/javascripts/members/constants.js
+++ b/app/assets/javascripts/members/constants.js
@@ -1,8 +1,18 @@
import { __ } from '~/locale';
+export const FIELD_KEY_ACCOUNT = 'account';
+export const FIELD_KEY_SOURCE = 'source';
+export const FIELD_KEY_GRANTED = 'granted';
+export const FIELD_KEY_INVITED = 'invited';
+export const FIELD_KEY_REQUESTED = 'requested';
+export const FIELD_KEY_MAX_ROLE = 'maxRole';
+export const FIELD_KEY_EXPIRATION = 'expiration';
+export const FIELD_KEY_LAST_SIGN_IN = 'lastSignIn';
+export const FIELD_KEY_ACTIONS = 'actions';
+
export const FIELDS = [
{
- key: 'account',
+ key: FIELD_KEY_ACCOUNT,
label: __('Account'),
sort: {
asc: 'name_asc',
@@ -10,13 +20,13 @@ export const FIELDS = [
},
},
{
- key: 'source',
+ key: FIELD_KEY_SOURCE,
label: __('Source'),
thClass: 'col-meta',
tdClass: 'col-meta',
},
{
- key: 'granted',
+ key: FIELD_KEY_GRANTED,
label: __('Access granted'),
thClass: 'col-meta',
tdClass: 'col-meta',
@@ -26,19 +36,19 @@ export const FIELDS = [
},
},
{
- key: 'invited',
+ key: FIELD_KEY_INVITED,
label: __('Invited'),
thClass: 'col-meta',
tdClass: 'col-meta',
},
{
- key: 'requested',
+ key: FIELD_KEY_REQUESTED,
label: __('Requested'),
thClass: 'col-meta',
tdClass: 'col-meta',
},
{
- key: 'maxRole',
+ key: FIELD_KEY_MAX_ROLE,
label: __('Max role'),
thClass: 'col-max-role',
tdClass: 'col-max-role',
@@ -48,13 +58,13 @@ export const FIELDS = [
},
},
{
- key: 'expiration',
+ key: FIELD_KEY_EXPIRATION,
label: __('Expiration'),
thClass: 'col-expiration',
tdClass: 'col-expiration',
},
{
- key: 'lastSignIn',
+ key: FIELD_KEY_LAST_SIGN_IN,
label: __('Last sign-in'),
sort: {
asc: 'recent_sign_in',
@@ -62,10 +72,8 @@ export const FIELDS = [
},
},
{
- key: 'actions',
+ key: FIELD_KEY_ACTIONS,
thClass: 'col-actions',
- showFunction: 'showActionsField',
- tdClassFunction: 'tdClassActions',
},
];
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 d988ad8d8ca..29c181f04fb 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
@@ -143,6 +143,7 @@ export default {
</template>
<template #right-actions>
<gl-dropdown
+ v-if="!deleteButtonDisabled"
icon="ellipsis_v"
text="More actions"
:text-sr-only="true"
@@ -150,11 +151,7 @@ export default {
no-caret
right
>
- <gl-dropdown-item
- variant="danger"
- :disabled="deleteButtonDisabled"
- @click="$emit('delete')"
- >
+ <gl-dropdown-item variant="danger" @click="$emit('delete')">
{{ __('Delete image repository') }}
</gl-dropdown-item>
</gl-dropdown>
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/empty_state.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/empty_state.vue
deleted file mode 100644
index a16d95a6b30..00000000000
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/empty_state.vue
+++ /dev/null
@@ -1,44 +0,0 @@
-<script>
-import { GlEmptyState } from '@gitlab/ui';
-import {
- NO_TAGS_TITLE,
- NO_TAGS_MESSAGE,
- MISSING_OR_DELETED_IMAGE_TITLE,
- MISSING_OR_DELETED_IMAGE_MESSAGE,
-} from '../../constants/index';
-
-export default {
- components: {
- GlEmptyState,
- },
- props: {
- noContainersImage: {
- type: String,
- required: false,
- default: '',
- },
- isEmptyImage: {
- type: Boolean,
- default: false,
- required: false,
- },
- },
- computed: {
- title() {
- return this.isEmptyImage ? MISSING_OR_DELETED_IMAGE_TITLE : NO_TAGS_TITLE;
- },
- description() {
- return this.isEmptyImage ? MISSING_OR_DELETED_IMAGE_MESSAGE : NO_TAGS_MESSAGE;
- },
- },
-};
-</script>
-
-<template>
- <gl-empty-state
- :title="title"
- :svg-path="noContainersImage"
- :description="description"
- class="gl-mx-auto gl-my-0"
- />
-</template>
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue
index 2d32295b537..4fda4058711 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue
@@ -1,28 +1,38 @@
<script>
+import { GlEmptyState } from '@gitlab/ui';
import createFlash from '~/flash';
import { n__ } from '~/locale';
import { joinPaths } from '~/lib/utils/url_utility';
import RegistryList from '~/packages_and_registries/shared/components/registry_list.vue';
+
+import PersistedSearch from '~/packages_and_registries/shared/components/persisted_search.vue';
+import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants';
import {
REMOVE_TAGS_BUTTON_TITLE,
TAGS_LIST_TITLE,
GRAPHQL_PAGE_SIZE,
FETCH_IMAGES_LIST_ERROR_MESSAGE,
+ NAME_SORT_FIELD,
+ NO_TAGS_TITLE,
+ NO_TAGS_MESSAGE,
+ NO_TAGS_MATCHING_FILTERS_TITLE,
+ NO_TAGS_MATCHING_FILTERS_DESCRIPTION,
} from '../../constants/index';
import getContainerRepositoryTagsQuery from '../../graphql/queries/get_container_repository_tags.query.graphql';
-import EmptyState from './empty_state.vue';
import TagsListRow from './tags_list_row.vue';
import TagsLoader from './tags_loader.vue';
export default {
name: 'TagsList',
components: {
+ GlEmptyState,
TagsListRow,
- EmptyState,
TagsLoader,
RegistryList,
+ PersistedSearch,
},
inject: ['config'],
+
props: {
id: {
type: [Number, String],
@@ -44,6 +54,7 @@ export default {
required: false,
},
},
+ searchConfig: { NAME_SORT_FIELD },
i18n: {
REMOVE_TAGS_BUTTON_TITLE,
TAGS_LIST_TITLE,
@@ -51,6 +62,9 @@ export default {
apollo: {
containerRepository: {
query: getContainerRepositoryTagsQuery,
+ skip() {
+ return !this.sort;
+ },
variables() {
return this.queryVariables;
},
@@ -62,6 +76,8 @@ export default {
data() {
return {
containerRepository: {},
+ filters: {},
+ sort: null,
};
},
computed: {
@@ -78,6 +94,8 @@ export default {
return {
id: joinPaths(this.config.gidPrefix, `${this.id}`),
first: GRAPHQL_PAGE_SIZE,
+ name: this.filters?.name,
+ sort: this.sort,
};
},
showMultiDeleteButton() {
@@ -87,7 +105,16 @@ export default {
return this.tags.length === 0;
},
isLoading() {
- return this.isImageLoading || this.$apollo.queries.containerRepository.loading;
+ return this.isImageLoading || this.$apollo.queries.containerRepository.loading || !this.sort;
+ },
+ hasFilters() {
+ return this.filters?.name;
+ },
+ emptyStateTitle() {
+ return this.hasFilters ? NO_TAGS_MATCHING_FILTERS_TITLE : NO_TAGS_TITLE;
+ },
+ emptyStateDescription() {
+ return this.hasFilters ? NO_TAGS_MATCHING_FILTERS_DESCRIPTION : NO_TAGS_MESSAGE;
},
},
methods: {
@@ -114,15 +141,47 @@ export default {
},
});
},
+ handleSearchUpdate({ sort, filters }) {
+ this.sort = sort;
+
+ const parsed = {
+ name: '',
+ };
+
+ // This takes in account the fact that we will be adding more filters types
+ // this is why is an object and not an array or a simple string
+ this.filters = filters.reduce((acc, filter) => {
+ if (filter.type === FILTERED_SEARCH_TERM) {
+ return {
+ ...acc,
+ name: `${acc.name} ${filter.value.data}`.trim(),
+ };
+ }
+ return acc;
+ }, parsed);
+ },
},
};
</script>
<template>
<div>
+ <persisted-search
+ class="gl-mb-5"
+ :sortable-fields="[$options.searchConfig.NAME_SORT_FIELD]"
+ :default-order="$options.searchConfig.NAME_SORT_FIELD.orderBy"
+ default-sort="asc"
+ @update="handleSearchUpdate"
+ />
<tags-loader v-if="isLoading" />
<template v-else>
- <empty-state v-if="hasNoTags" :no-containers-image="config.noContainersImage" />
+ <gl-empty-state
+ v-if="hasNoTags"
+ :title="emptyStateTitle"
+ :svg-path="config.noContainersImage"
+ :description="emptyStateDescription"
+ class="gl-mx-auto gl-my-0"
+ />
<template v-else>
<registry-list
:title="listTitle"
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row.vue
index 0556fd298aa..15d92ab0ef7 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row.vue
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row.vue
@@ -107,11 +107,8 @@ export default {
isInvalidTag() {
return !this.tag.digest;
},
- isCheckboxDisabled() {
- return this.isInvalidTag || this.disabled;
- },
isDeleteDisabled() {
- return this.isInvalidTag || this.disabled || !this.tag.canDelete;
+ return this.disabled || !this.tag.canDelete;
},
},
};
@@ -122,7 +119,7 @@ export default {
<template #left-action>
<gl-form-checkbox
v-if="tag.canDelete"
- :disabled="isCheckboxDisabled"
+ :disabled="disabled"
class="gl-m-0"
:checked="selected"
@change="$emit('select')"
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/registry_breadcrumb.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/registry_breadcrumb.vue
deleted file mode 100644
index e77eda31596..00000000000
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/registry_breadcrumb.vue
+++ /dev/null
@@ -1,51 +0,0 @@
-<script>
-// We are using gl-breadcrumb only at the last child of the handwritten breadcrumb
-// until this gitlab-ui issue is resolved: https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1079
-//
-// See the CSS workaround in app/assets/stylesheets/pages/registry.scss when this file is changed.
-import { GlBreadcrumb, GlIcon } from '@gitlab/ui';
-
-export default {
- components: {
- GlBreadcrumb,
- GlIcon,
- },
- computed: {
- rootRoute() {
- return this.$router.options.routes.find((r) => r.meta.root);
- },
- detailsRoute() {
- return this.$router.options.routes.find((r) => r.name === 'details');
- },
- isRootRoute() {
- return this.$route.name === this.rootRoute.name;
- },
- isLoaded() {
- return this.isRootRoute || this.$store?.state.imageDetails?.name;
- },
- allCrumbs() {
- const crumbs = [
- {
- text: this.rootRoute.meta.nameGenerator(),
- to: this.rootRoute.path,
- },
- ];
- if (!this.isRootRoute) {
- crumbs.push({
- text: this.detailsRoute.meta.nameGenerator(),
- href: this.detailsRoute.meta.path,
- });
- }
- return crumbs;
- },
- },
-};
-</script>
-
-<template>
- <gl-breadcrumb :key="isLoaded" :items="allCrumbs">
- <template #separator>
- <gl-icon name="angle-right" :size="8" />
- </template>
- </gl-breadcrumb>
-</template>
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/common.js b/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/common.js
index f7beec2c935..17adaec7a7d 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/common.js
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/common.js
@@ -2,3 +2,5 @@ import { s__, __ } from '~/locale';
export const ROOT_IMAGE_TEXT = s__('ContainerRegistry|Root image');
export const MORE_ACTIONS_TEXT = __('More actions');
+
+export const NAME_SORT_FIELD = { orderBy: 'NAME', label: __('Name') };
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 19e1a75fb2f..8b8769a884d 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
@@ -116,6 +116,13 @@ export const ROOT_IMAGE_TOOLTIP = s__(
'ContainerRegistry|Image repository with no name located at the project URL.',
);
+export const NO_TAGS_MATCHING_FILTERS_TITLE = s__(
+ 'ContainerRegistry|The filter returned no results',
+);
+export const NO_TAGS_MATCHING_FILTERS_DESCRIPTION = s__(
+ 'ContainerRegistry|Please try different search criteria',
+);
+
// Parameters
export const DEFAULT_PAGE = 1;
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/list.js b/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/list.js
index d21a154d1b8..7fa950ccfd0 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/list.js
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/list.js
@@ -1,4 +1,5 @@
import { s__, __ } from '~/locale';
+import { NAME_SORT_FIELD } from './common';
// Translations strings
@@ -49,5 +50,5 @@ export const GRAPHQL_PAGE_SIZE = 10;
export const SORT_FIELDS = [
{ orderBy: 'UPDATED', label: __('Updated') },
{ orderBy: 'CREATED', label: __('Created') },
- { orderBy: 'NAME', label: __('Name') },
+ NAME_SORT_FIELD,
];
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags.query.graphql b/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags.query.graphql
index 502382010f9..d753d33a02c 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags.query.graphql
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags.query.graphql
@@ -6,11 +6,13 @@ query getContainerRepositoryTags(
$last: Int
$after: String
$before: String
+ $name: String
+ $sort: ContainerRepositoryTagSort
) {
containerRepository(id: $id) {
id
tagsCount
- tags(after: $after, before: $before, first: $first, last: $last) {
+ tags(after: $after, before: $before, first: $first, last: $last, name: $name, sort: $sort) {
nodes {
digest
location
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/index.js b/app/assets/javascripts/packages_and_registries/container_registry/explorer/index.js
index 246a6768593..ca5bd8d6964 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/index.js
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/index.js
@@ -3,7 +3,8 @@ import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
import PerformancePlugin from '~/performance/vue_performance_plugin';
import Translate from '~/vue_shared/translate';
-import RegistryBreadcrumb from './components/registry_breadcrumb.vue';
+import RegistryBreadcrumb from '~/packages_and_registries/shared/components/registry_breadcrumb.vue';
+import { renderBreadcrumb } from '~/packages_and_registries/shared/utils';
import { apolloProvider } from './graphql/index';
import RegistryExplorer from './pages/index.vue';
import createRouter from './router';
@@ -84,38 +85,8 @@ export default () => {
},
});
- const attachBreadcrumb = () => {
- const breadCrumbEls = document.querySelectorAll('nav .js-breadcrumbs-list li');
- const breadCrumbEl = breadCrumbEls[breadCrumbEls.length - 1];
- const crumbs = [breadCrumbEl.querySelector('h2')];
- const nestedBreadcrumbEl = document.createElement('div');
- breadCrumbEl.replaceChild(nestedBreadcrumbEl, breadCrumbEl.querySelector('h2'));
- return new Vue({
- el: nestedBreadcrumbEl,
- router,
- apolloProvider,
- components: {
- RegistryBreadcrumb,
- },
- render(createElement) {
- // FIXME(@tnir): this is a workaround until the MR gets merged:
- // https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48115
- const parentEl = breadCrumbEl.parentElement.parentElement;
- if (parentEl) {
- parentEl.classList.remove('breadcrumbs-container');
- parentEl.classList.add('gl-display-flex');
- parentEl.classList.add('w-100');
- }
- // End of FIXME(@tnir)
- return createElement('registry-breadcrumb', {
- class: breadCrumbEl.className,
- props: {
- crumbs,
- },
- });
- },
- });
+ return {
+ attachBreadcrumb: renderBreadcrumb(router, apolloProvider, RegistryBreadcrumb),
+ attachMainComponent,
};
-
- return { attachBreadcrumb, attachMainComponent };
};
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 bc6e3091f0e..bb687ffdb89 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
@@ -1,5 +1,5 @@
<script>
-import { GlResizeObserverDirective } from '@gitlab/ui';
+import { GlResizeObserverDirective, GlEmptyState } from '@gitlab/ui';
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
@@ -9,7 +9,6 @@ import DeleteImage from '../components/delete_image.vue';
import DeleteAlert from '../components/details_page/delete_alert.vue';
import DeleteModal from '../components/details_page/delete_modal.vue';
import DetailsHeader from '../components/details_page/details_header.vue';
-import EmptyState from '../components/details_page/empty_state.vue';
import PartialCleanupAlert from '../components/details_page/partial_cleanup_alert.vue';
import StatusAlert from '../components/details_page/status_alert.vue';
import TagsList from '../components/details_page/tags_list.vue';
@@ -26,6 +25,8 @@ import {
MISSING_OR_DELETED_IMAGE_BREADCRUMB,
ROOT_IMAGE_TEXT,
GRAPHQL_PAGE_SIZE,
+ MISSING_OR_DELETED_IMAGE_TITLE,
+ MISSING_OR_DELETED_IMAGE_MESSAGE,
} from '../constants/index';
import deleteContainerRepositoryTagsMutation from '../graphql/mutations/delete_container_repository_tags.mutation.graphql';
import getContainerRepositoryDetailsQuery from '../graphql/queries/get_container_repository_details.query.graphql';
@@ -34,13 +35,13 @@ import getContainerRepositoryTagsQuery from '../graphql/queries/get_container_re
export default {
name: 'RegistryDetailsPage',
components: {
+ GlEmptyState,
DeleteAlert,
PartialCleanupAlert,
DetailsHeader,
DeleteModal,
TagsList,
TagsLoader,
- EmptyState,
StatusAlert,
DeleteImage,
},
@@ -49,6 +50,10 @@ export default {
},
mixins: [Tracking.mixin()],
inject: ['breadCrumbState', 'config'],
+ i18n: {
+ MISSING_OR_DELETED_IMAGE_TITLE,
+ MISSING_OR_DELETED_IMAGE_MESSAGE,
+ },
apollo: {
containerRepository: {
query: getContainerRepositoryDetailsQuery,
@@ -230,6 +235,12 @@ export default {
@cancel="track('cancel_delete')"
/>
</template>
- <empty-state v-else is-empty-image :no-containers-image="config.noContainersImage" />
+ <gl-empty-state
+ v-else
+ :title="$options.i18n.MISSING_OR_DELETED_IMAGE_TITLE"
+ :description="$options.i18n.MISSING_OR_DELETED_IMAGE_MESSAGE"
+ :svg-path="config.noContainersImage"
+ class="gl-mx-auto gl-my-0"
+ />
</div>
</template>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue
deleted file mode 100644
index d49c1be5202..00000000000
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue
+++ /dev/null
@@ -1,347 +0,0 @@
-<script>
-import {
- GlBadge,
- GlButton,
- GlModal,
- GlModalDirective,
- GlTooltipDirective,
- GlEmptyState,
- GlTab,
- GlTabs,
- GlSprintf,
-} from '@gitlab/ui';
-import createFlash from '~/flash';
-import { convertToGraphQLId } from '~/graphql_shared/utils';
-import { numberToHumanSize } from '~/lib/utils/number_utils';
-import { objectToQuery } from '~/lib/utils/url_utility';
-import { s__, __ } from '~/locale';
-import { packageTypeToTrackCategory } from '~/packages_and_registries/package_registry/utils';
-import AdditionalMetadata from '~/packages_and_registries/package_registry/components/details/additional_metadata.vue';
-import DependencyRow from '~/packages_and_registries/package_registry/components/details/dependency_row.vue';
-import InstallationCommands from '~/packages_and_registries/package_registry/components/details/installation_commands.vue';
-import PackageFiles from '~/packages_and_registries/package_registry/components/details/package_files.vue';
-import PackageHistory from '~/packages_and_registries/package_registry/components/details/package_history.vue';
-import PackageTitle from '~/packages_and_registries/package_registry/components/details/package_title.vue';
-import VersionRow from '~/packages_and_registries/package_registry/components/details/version_row.vue';
-import DeletePackage from '~/packages_and_registries/package_registry/components/functional/delete_package.vue';
-import {
- PACKAGE_TYPE_NUGET,
- PACKAGE_TYPE_COMPOSER,
- DELETE_PACKAGE_TRACKING_ACTION,
- REQUEST_DELETE_PACKAGE_TRACKING_ACTION,
- CANCEL_DELETE_PACKAGE_TRACKING_ACTION,
- PULL_PACKAGE_TRACKING_ACTION,
- DELETE_PACKAGE_FILE_TRACKING_ACTION,
- REQUEST_DELETE_PACKAGE_FILE_TRACKING_ACTION,
- CANCEL_DELETE_PACKAGE_FILE_TRACKING_ACTION,
- SHOW_DELETE_SUCCESS_ALERT,
- FETCH_PACKAGE_DETAILS_ERROR_MESSAGE,
- DELETE_PACKAGE_FILE_ERROR_MESSAGE,
- DELETE_PACKAGE_FILE_SUCCESS_MESSAGE,
-} from '~/packages_and_registries/package_registry/constants';
-
-import destroyPackageFileMutation from '~/packages_and_registries/package_registry/graphql/mutations/destroy_package_file.mutation.graphql';
-import getPackageDetails from '~/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql';
-import Tracking from '~/tracking';
-
-export default {
- name: 'PackagesApp',
- components: {
- GlBadge,
- GlButton,
- GlEmptyState,
- GlModal,
- GlTab,
- GlTabs,
- GlSprintf,
- PackageTitle,
- VersionRow,
- DependencyRow,
- PackageHistory,
- AdditionalMetadata,
- InstallationCommands,
- PackageFiles,
- DeletePackage,
- },
- directives: {
- GlTooltip: GlTooltipDirective,
- GlModal: GlModalDirective,
- },
- mixins: [Tracking.mixin()],
- inject: [
- 'packageId',
- 'projectName',
- 'canDelete',
- 'svgPath',
- 'npmPath',
- 'npmHelpPath',
- 'projectListUrl',
- 'groupListUrl',
- ],
- trackingActions: {
- DELETE_PACKAGE_TRACKING_ACTION,
- REQUEST_DELETE_PACKAGE_TRACKING_ACTION,
- CANCEL_DELETE_PACKAGE_TRACKING_ACTION,
- PULL_PACKAGE_TRACKING_ACTION,
- DELETE_PACKAGE_FILE_TRACKING_ACTION,
- REQUEST_DELETE_PACKAGE_FILE_TRACKING_ACTION,
- CANCEL_DELETE_PACKAGE_FILE_TRACKING_ACTION,
- },
- data() {
- return {
- fileToDelete: null,
- packageEntity: {},
- };
- },
- apollo: {
- packageEntity: {
- query: getPackageDetails,
- variables() {
- return this.queryVariables;
- },
- update(data) {
- return data.package;
- },
- error(error) {
- createFlash({
- message: FETCH_PACKAGE_DETAILS_ERROR_MESSAGE,
- captureError: true,
- error,
- });
- },
- },
- },
- computed: {
- queryVariables() {
- return {
- id: convertToGraphQLId('Packages::Package', this.packageId),
- };
- },
- packageFiles() {
- return this.packageEntity?.packageFiles?.nodes;
- },
- isLoading() {
- return this.$apollo.queries.packageEntity.loading;
- },
- isValidPackage() {
- return this.isLoading || Boolean(this.packageEntity?.name);
- },
- tracking() {
- return {
- category: packageTypeToTrackCategory(this.packageEntity.packageType),
- };
- },
- hasVersions() {
- return this.packageEntity.versions?.nodes?.length > 0;
- },
- packageDependencies() {
- return this.packageEntity.dependencyLinks?.nodes || [];
- },
- showDependencies() {
- return this.packageEntity.packageType === PACKAGE_TYPE_NUGET;
- },
- showFiles() {
- return this.packageEntity?.packageType !== PACKAGE_TYPE_COMPOSER;
- },
- },
- methods: {
- formatSize(size) {
- return numberToHumanSize(size);
- },
- navigateToListWithSuccessModal() {
- const returnTo =
- !this.groupListUrl || document.referrer.includes(this.projectName)
- ? this.projectListUrl
- : this.groupListUrl; // to avoid security issue url are supplied from backend
-
- const modalQuery = objectToQuery({ [SHOW_DELETE_SUCCESS_ALERT]: true });
-
- window.location.replace(`${returnTo}?${modalQuery}`);
- },
- async deletePackageFile(id) {
- try {
- const { data } = await this.$apollo.mutate({
- mutation: destroyPackageFileMutation,
- variables: {
- id,
- },
- awaitRefetchQueries: true,
- refetchQueries: [
- {
- query: getPackageDetails,
- variables: this.queryVariables,
- },
- ],
- });
- if (data?.destroyPackageFile?.errors[0]) {
- throw data.destroyPackageFile.errors[0];
- }
- createFlash({
- message: DELETE_PACKAGE_FILE_SUCCESS_MESSAGE,
- type: 'success',
- });
- } catch (error) {
- createFlash({
- message: DELETE_PACKAGE_FILE_ERROR_MESSAGE,
- type: 'warning',
- captureError: true,
- error,
- });
- }
- },
- handleFileDelete(file) {
- this.track(REQUEST_DELETE_PACKAGE_FILE_TRACKING_ACTION);
- this.fileToDelete = { ...file };
- this.$refs.deleteFileModal.show();
- },
- confirmFileDelete() {
- this.track(DELETE_PACKAGE_FILE_TRACKING_ACTION);
- this.deletePackageFile(this.fileToDelete.id);
- this.fileToDelete = null;
- },
- },
- i18n: {
- deleteModalTitle: s__(`PackageRegistry|Delete Package Version`),
- deleteModalContent: s__(
- `PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?`,
- ),
- deleteFileModalTitle: s__(`PackageRegistry|Delete Package File`),
- deleteFileModalContent: s__(
- `PackageRegistry|You are about to delete %{filename}. This is a destructive action that may render your package unusable. Are you sure?`,
- ),
- },
- modal: {
- packageDeletePrimaryAction: {
- text: __('Delete'),
- attributes: [
- { variant: 'danger' },
- { category: 'primary' },
- { 'data-qa-selector': 'delete_modal_button' },
- ],
- },
- fileDeletePrimaryAction: {
- text: __('Delete'),
- attributes: [{ variant: 'danger' }, { category: 'primary' }],
- },
- cancelAction: {
- text: __('Cancel'),
- },
- },
-};
-</script>
-
-<template>
- <gl-empty-state
- v-if="!isValidPackage"
- :title="s__('PackageRegistry|Unable to load package')"
- :description="s__('PackageRegistry|There was a problem fetching the details for this package.')"
- :svg-path="svgPath"
- />
- <div v-else-if="!isLoading" class="packages-app">
- <package-title :package-entity="packageEntity">
- <template #delete-button>
- <gl-button
- v-if="canDelete"
- v-gl-modal="'delete-modal'"
- variant="danger"
- category="primary"
- data-qa-selector="delete_button"
- data-testid="delete-package"
- >
- {{ __('Delete') }}
- </gl-button>
- </template>
- </package-title>
-
- <gl-tabs>
- <gl-tab :title="__('Detail')">
- <div v-if="!isLoading" data-qa-selector="package_information_content">
- <package-history :package-entity="packageEntity" :project-name="projectName" />
-
- <installation-commands :package-entity="packageEntity" />
-
- <additional-metadata :package-entity="packageEntity" />
- </div>
-
- <package-files
- v-if="showFiles"
- :package-files="packageFiles"
- @download-file="track($options.trackingActions.PULL_PACKAGE)"
- @delete-file="handleFileDelete"
- />
- </gl-tab>
-
- <gl-tab v-if="showDependencies">
- <template #title>
- <span>{{ __('Dependencies') }}</span>
- <gl-badge size="sm">{{ packageDependencies.length }}</gl-badge>
- </template>
-
- <template v-if="packageDependencies.length > 0">
- <dependency-row v-for="dep in packageDependencies" :key="dep.id" :dependency-link="dep" />
- </template>
-
- <p v-else class="gl-mt-3" data-testid="no-dependencies-message">
- {{ s__('PackageRegistry|This NuGet package has no dependencies.') }}
- </p>
- </gl-tab>
-
- <gl-tab :title="__('Other versions')" title-item-class="js-versions-tab">
- <template v-if="hasVersions">
- <version-row v-for="v in packageEntity.versions.nodes" :key="v.id" :package-entity="v" />
- </template>
-
- <p v-else class="gl-mt-3" data-testid="no-versions-message">
- {{ s__('PackageRegistry|There are no other versions of this package.') }}
- </p>
- </gl-tab>
- </gl-tabs>
-
- <delete-package
- @start="track($options.trackingActions.DELETE_PACKAGE_TRACKING_ACTION)"
- @end="navigateToListWithSuccessModal"
- >
- <template #default="{ deletePackage }">
- <gl-modal
- ref="deleteModal"
- size="sm"
- modal-id="delete-modal"
- data-testid="delete-modal"
- :action-primary="$options.modal.packageDeletePrimaryAction"
- :action-cancel="$options.modal.cancelAction"
- @primary="deletePackage(packageEntity)"
- @canceled="track($options.trackingActions.CANCEL_DELETE_PACKAGE)"
- >
- <template #modal-title>{{ $options.i18n.deleteModalTitle }}</template>
- <gl-sprintf :message="$options.i18n.deleteModalContent">
- <template #version>
- <strong>{{ packageEntity.version }}</strong>
- </template>
-
- <template #name>
- <strong>{{ packageEntity.name }}</strong>
- </template>
- </gl-sprintf>
- </gl-modal>
- </template>
- </delete-package>
-
- <gl-modal
- ref="deleteFileModal"
- size="sm"
- modal-id="delete-file-modal"
- :action-primary="$options.modal.fileDeletePrimaryAction"
- :action-cancel="$options.modal.cancelAction"
- data-testid="delete-file-modal"
- @primary="confirmFileDelete"
- @canceled="track($options.trackingActions.CANCEL_DELETE_PACKAGE_FILE)"
- >
- <template #modal-title>{{ $options.i18n.deleteFileModalTitle }}</template>
- <gl-sprintf v-if="fileToDelete" :message="$options.i18n.deleteFileModalContent">
- <template #filename>
- <strong>{{ fileToDelete.file_name }}</strong>
- </template>
- </gl-sprintf>
- </gl-modal>
- </div>
-</template>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/composer_installation.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/composer_installation.vue
index cc629ae394c..a482c29bf50 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/composer_installation.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/composer_installation.vue
@@ -6,6 +6,7 @@ import {
TRACKING_ACTION_COPY_COMPOSER_REGISTRY_INCLUDE_COMMAND,
TRACKING_ACTION_COPY_COMPOSER_PACKAGE_INCLUDE_COMMAND,
TRACKING_LABEL_CODE_INSTRUCTION,
+ COMPOSER_HELP_PATH,
} from '~/packages_and_registries/package_registry/constants';
import CodeInstruction from '~/vue_shared/components/registry/code_instruction.vue';
@@ -17,7 +18,7 @@ export default {
GlLink,
GlSprintf,
},
- inject: ['composerHelpPath', 'composerConfigRepositoryName', 'composerPath', 'groupListUrl'],
+ inject: ['groupListUrl'],
props: {
packageEntity: {
type: Object,
@@ -27,7 +28,7 @@ export default {
computed: {
composerRegistryInclude() {
// eslint-disable-next-line @gitlab/require-i18n-strings
- return `composer config repositories.${this.composerConfigRepositoryName} '{"type": "composer", "url": "${this.composerPath}"}'`;
+ return `composer config repositories.${this.packageEntity.composerConfigRepositoryUrl} '{"type": "composer", "url": "${this.packageEntity.composerUrl}"}'`;
},
composerPackageInclude() {
// eslint-disable-next-line @gitlab/require-i18n-strings
@@ -51,6 +52,9 @@ export default {
TRACKING_ACTION_COPY_COMPOSER_PACKAGE_INCLUDE_COMMAND,
TRACKING_LABEL_CODE_INSTRUCTION,
},
+ links: {
+ COMPOSER_HELP_PATH,
+ },
installOptions: [{ value: 'composer', label: s__('PackageRegistry|Show Composer commands') }],
};
</script>
@@ -79,7 +83,7 @@ export default {
<span data-testid="help-text">
<gl-sprintf :message="$options.i18n.infoLine">
<template #link="{ content }">
- <gl-link :href="composerHelpPath" target="_blank">{{ content }}</gl-link>
+ <gl-link :href="$options.links.COMPOSER_HELP_PATH" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</span>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/conan_installation.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/conan_installation.vue
index 99e27c9d44a..ba0a3fcf5a1 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/conan_installation.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/conan_installation.vue
@@ -6,6 +6,7 @@ import {
TRACKING_ACTION_COPY_CONAN_COMMAND,
TRACKING_ACTION_COPY_CONAN_SETUP_COMMAND,
TRACKING_LABEL_CODE_INSTRUCTION,
+ CONAN_HELP_PATH,
} from '~/packages_and_registries/package_registry/constants';
import CodeInstruction from '~/vue_shared/components/registry/code_instruction.vue';
@@ -17,7 +18,6 @@ export default {
GlLink,
GlSprintf,
},
- inject: ['conanHelpPath', 'conanPath'],
props: {
packageEntity: {
type: Object,
@@ -31,7 +31,7 @@ export default {
},
conanSetupCommand() {
// eslint-disable-next-line @gitlab/require-i18n-strings
- return `conan remote add gitlab ${this.conanPath}`;
+ return `conan remote add gitlab ${this.packageEntity.conanUrl}`;
},
},
i18n: {
@@ -44,7 +44,7 @@ export default {
TRACKING_ACTION_COPY_CONAN_SETUP_COMMAND,
TRACKING_LABEL_CODE_INSTRUCTION,
},
-
+ links: { CONAN_HELP_PATH },
installOptions: [{ value: 'conan', label: s__('PackageRegistry|Show Conan commands') }],
};
</script>
@@ -72,7 +72,7 @@ export default {
/>
<gl-sprintf :message="$options.i18n.helpText">
<template #link="{ content }">
- <gl-link :href="conanHelpPath" target="_blank">{{ content }}</gl-link>
+ <gl-link :href="$options.links.CONAN_HELP_PATH" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</div>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/maven_installation.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/maven_installation.vue
index 2070f0bbca0..4510c7a7322 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/maven_installation.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/maven_installation.vue
@@ -12,6 +12,7 @@ import {
TRACKING_ACTION_COPY_KOTLIN_ADD_TO_SOURCE_COMMAND,
TRACKING_LABEL_CODE_INSTRUCTION,
TRACKING_LABEL_MAVEN_INSTALLATION,
+ MAVEN_HELP_PATH,
} from '~/packages_and_registries/package_registry/constants';
import CodeInstruction from '~/vue_shared/components/registry/code_instruction.vue';
@@ -23,7 +24,6 @@ export default {
GlLink,
GlSprintf,
},
- inject: ['mavenHelpPath', 'mavenPath'],
props: {
packageEntity: {
type: Object,
@@ -36,6 +36,9 @@ export default {
};
},
computed: {
+ mavenUrl() {
+ return this.packageEntity.mavenUrl;
+ },
appGroup() {
return this.packageEntity.metadata.appGroup;
},
@@ -61,19 +64,19 @@ export default {
return `<repositories>
<repository>
<id>gitlab-maven</id>
- <url>${this.mavenPath}</url>
+ <url>${this.mavenUrl}</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>gitlab-maven</id>
- <url>${this.mavenPath}</url>
+ <url>${this.mavenUrl}</url>
</repository>
<snapshotRepository>
<id>gitlab-maven</id>
- <url>${this.mavenPath}</url>
+ <url>${this.mavenUrl}</url>
</snapshotRepository>
</distributionManagement>`;
},
@@ -86,7 +89,7 @@ export default {
gradleGroovyAddSourceCommand() {
// eslint-disable-next-line @gitlab/require-i18n-strings
return `maven {
- url '${this.mavenPath}'
+ url '${this.mavenUrl}'
}`;
},
@@ -95,7 +98,7 @@ export default {
},
gradleKotlinAddSourceCommand() {
- return `maven("${this.mavenPath}")`;
+ return `maven("${this.mavenUrl}")`;
},
showMaven() {
return this.instructionType === 'maven';
@@ -126,7 +129,7 @@ export default {
TRACKING_LABEL_CODE_INSTRUCTION,
TRACKING_LABEL_MAVEN_INSTALLATION,
},
-
+ links: { MAVEN_HELP_PATH },
installOptions: [
{ value: 'maven', label: s__('PackageRegistry|Maven XML') },
{ value: 'groovy', label: s__('PackageRegistry|Gradle Groovy DSL') },
@@ -185,7 +188,7 @@ export default {
/>
<gl-sprintf :message="$options.i18n.helpText">
<template #link="{ content }">
- <gl-link :href="mavenHelpPath" target="_blank">{{ content }}</gl-link>
+ <gl-link :href="$options.links.MAVEN_HELP_PATH" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</template>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/npm_installation.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/npm_installation.vue
index 2448324549e..7479f748a56 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/npm_installation.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/npm_installation.vue
@@ -13,6 +13,7 @@ import {
YARN_PACKAGE_MANAGER,
PROJECT_PACKAGE_ENDPOINT_TYPE,
INSTANCE_PACKAGE_ENDPOINT_TYPE,
+ NPM_HELP_PATH,
} from '~/packages_and_registries/package_registry/constants';
import CodeInstruction from '~/vue_shared/components/registry/code_instruction.vue';
@@ -25,7 +26,7 @@ export default {
GlSprintf,
GlFormRadioGroup,
},
- inject: ['npmHelpPath', 'npmPath', 'npmProjectPath'],
+ inject: ['npmInstanceUrl'],
props: {
packageEntity: {
type: Object,
@@ -65,7 +66,9 @@ export default {
npmSetupCommand(type, endpointType) {
const scope = this.packageEntity.name.substring(0, this.packageEntity.name.indexOf('/'));
const npmPathForEndpoint =
- endpointType === INSTANCE_PACKAGE_ENDPOINT_TYPE ? this.npmPath : this.npmProjectPath;
+ endpointType === INSTANCE_PACKAGE_ENDPOINT_TYPE
+ ? this.npmInstanceUrl
+ : this.packageEntity.npmUrl;
if (type === NPM_PACKAGE_MANAGER) {
return `echo ${scope}:registry=${npmPathForEndpoint}/ >> .npmrc`;
@@ -89,6 +92,7 @@ export default {
'PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more.',
),
},
+ links: { NPM_HELP_PATH },
installOptions: [
{ value: NPM_PACKAGE_MANAGER, label: s__('PackageRegistry|Show NPM commands') },
{ value: YARN_PACKAGE_MANAGER, label: s__('PackageRegistry|Show Yarn commands') },
@@ -150,7 +154,7 @@ export default {
<gl-sprintf :message="$options.i18n.helpText">
<template #link="{ content }">
- <gl-link :href="npmHelpPath" target="_blank">{{ content }}</gl-link>
+ <gl-link :href="$options.links.NPM_HELP_PATH" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</div>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/nuget_installation.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/nuget_installation.vue
index 2e9991b7be5..b2007df142c 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/nuget_installation.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/nuget_installation.vue
@@ -6,6 +6,7 @@ import {
TRACKING_ACTION_COPY_NUGET_INSTALL_COMMAND,
TRACKING_ACTION_COPY_NUGET_SETUP_COMMAND,
TRACKING_LABEL_CODE_INSTRUCTION,
+ NUGET_HELP_PATH,
} from '~/packages_and_registries/package_registry/constants';
import CodeInstruction from '~/vue_shared/components/registry/code_instruction.vue';
@@ -17,7 +18,6 @@ export default {
GlLink,
GlSprintf,
},
- inject: ['nugetHelpPath', 'nugetPath'],
props: {
packageEntity: {
type: Object,
@@ -29,7 +29,7 @@ export default {
return `nuget install ${this.packageEntity.name} -Source "GitLab"`;
},
nugetSetupCommand() {
- return `nuget source Add -Name "GitLab" -Source "${this.nugetPath}" -UserName <your_username> -Password <your_token>`;
+ return `nuget source Add -Name "GitLab" -Source "${this.packageEntity.nugetUrl}" -UserName <your_username> -Password <your_token>`;
},
},
tracking: {
@@ -42,6 +42,7 @@ export default {
'PackageRegistry|For more information on the NuGet registry, %{linkStart}see the documentation%{linkEnd}.',
),
},
+ links: { NUGET_HELP_PATH },
installOptions: [{ value: 'nuget', label: s__('PackageRegistry|Show Nuget commands') }],
};
</script>
@@ -68,7 +69,7 @@ export default {
/>
<gl-sprintf :message="$options.i18n.helpText">
<template #link="{ content }">
- <gl-link :href="nugetHelpPath" target="_blank">{{ content }}</gl-link>
+ <gl-link :href="$options.links.NUGET_HELP_PATH" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</div>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue
index bf7fe6fb91b..3724e371e01 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue
@@ -22,8 +22,12 @@ export default {
FileSha,
},
mixins: [Tracking.mixin()],
- inject: ['canDelete'],
props: {
+ canDelete: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
packageFiles: {
type: Array,
required: false,
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/pypi_installation.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/pypi_installation.vue
index 669adab9df6..a126d30f1ec 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/pypi_installation.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/pypi_installation.vue
@@ -7,6 +7,7 @@ import {
TRACKING_ACTION_COPY_PIP_INSTALL_COMMAND,
TRACKING_ACTION_COPY_PYPI_SETUP_COMMAND,
TRACKING_LABEL_CODE_INSTRUCTION,
+ PYPI_HELP_PATH,
} from '~/packages_and_registries/package_registry/constants';
import CodeInstruction from '~/vue_shared/components/registry/code_instruction.vue';
@@ -18,7 +19,6 @@ export default {
GlLink,
GlSprintf,
},
- inject: ['pypiHelpPath', 'pypiPath', 'pypiSetupPath'],
props: {
packageEntity: {
type: Object,
@@ -28,11 +28,11 @@ export default {
computed: {
pypiPipCommand() {
// eslint-disable-next-line @gitlab/require-i18n-strings
- return `pip install ${this.packageEntity.name} --extra-index-url ${this.pypiPath}`;
+ return `pip install ${this.packageEntity.name} --extra-index-url ${this.packageEntity.pypiUrl}`;
},
pypiSetupCommand() {
return `[gitlab]
-repository = ${this.pypiSetupPath}
+repository = ${this.packageEntity.pypiSetupUrl}
username = __token__
password = <your personal access token>`;
},
@@ -50,6 +50,7 @@ password = <your personal access token>`;
'PackageRegistry|For more information on the PyPi registry, %{linkStart}see the documentation%{linkEnd}.',
),
},
+ links: { PYPI_HELP_PATH },
installOptions: [{ value: 'pypi', label: s__('PackageRegistry|Show PyPi commands') }],
};
</script>
@@ -86,7 +87,7 @@ password = <your personal access token>`;
/>
<gl-sprintf :message="$options.i18n.helpText">
<template #link="{ content }">
- <gl-link :href="pypiHelpPath" target="_blank">{{ content }}</gl-link>
+ <gl-link :href="$options.links.PYPI_HELP_PATH" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</div>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_list_row.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_list_row.vue
index 6fd96c0654f..6222c2e73d7 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_list_row.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/list/package_list_row.vue
@@ -1,5 +1,5 @@
<script>
-import { GlButton, GlLink, GlSprintf, GlTooltipDirective, GlTruncate } from '@gitlab/ui';
+import { GlButton, GlSprintf, GlTooltipDirective, GlTruncate } from '@gitlab/ui';
import { s__, __ } from '~/locale';
import ListItem from '~/vue_shared/components/registry/list_item.vue';
import {
@@ -18,7 +18,6 @@ export default {
name: 'PackageListRow',
components: {
GlButton,
- GlLink,
GlSprintf,
GlTruncate,
PackageTags,
@@ -42,9 +41,8 @@ export default {
packageType() {
return getPackageTypeLabel(this.packageEntity.packageType);
},
- packageLink() {
- const { project, id } = this.packageEntity;
- return `${project?.webUrl}/-/packages/${getIdFromGraphQLId(id)}`;
+ packageId() {
+ return getIdFromGraphQLId(this.packageEntity.id);
},
pipeline() {
return this.packageEntity?.pipelines?.nodes[0];
@@ -61,6 +59,9 @@ export default {
disabledRow() {
return this.packageEntity.status && this.packageEntity.status !== PACKAGE_DEFAULT_STATUS;
},
+ routerLinkEvent() {
+ return this.disabledRow ? '' : 'click';
+ },
},
i18n: {
erroredPackageText: s__('PackageRegistry|Invalid Package: failed metadata extraction'),
@@ -73,14 +74,15 @@ export default {
<list-item data-qa-selector="package_row" :disabled="disabledRow">
<template #left-primary>
<div class="gl-display-flex gl-align-items-center gl-mr-3 gl-min-w-0">
- <gl-link
- :href="packageLink"
+ <router-link
class="gl-text-body gl-min-w-0"
+ data-testid="details-link"
data-qa-selector="package_link"
- :disabled="disabledRow"
+ :event="routerLinkEvent"
+ :to="{ name: 'details', params: { id: packageId } }"
>
<gl-truncate :text="packageEntity.name" />
- </gl-link>
+ </router-link>
<gl-button
v-if="showWarningIcon"
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/constants.js b/app/assets/javascripts/packages_and_registries/package_registry/constants.js
index ab6541e4264..c4d331fa384 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/constants.js
+++ b/app/assets/javascripts/packages_and_registries/package_registry/constants.js
@@ -74,6 +74,7 @@ export const FETCH_PACKAGE_DETAILS_ERROR_MESSAGE = s__(
);
export const DELETE_PACKAGE_SUCCESS_MESSAGE = s__('PackageRegistry|Package deleted successfully');
+export const PACKAGE_REGISTRY_TITLE = __('Package Registry');
export const PACKAGE_ERROR_STATUS = 'ERROR';
export const PACKAGE_DEFAULT_STATUS = 'DEFAULT';
@@ -142,3 +143,9 @@ export const PACKAGE_TYPES = [
export const EMPTY_LIST_HELP_URL = helpPagePath('user/packages/package_registry/index');
export const PACKAGE_HELP_URL = helpPagePath('user/packages/index');
+export const NPM_HELP_PATH = helpPagePath('user/packages/npm_registry/index');
+export const MAVEN_HELP_PATH = helpPagePath('user/packages/maven_repository/index');
+export const CONAN_HELP_PATH = helpPagePath('user/packages/conan_repository/index');
+export const NUGET_HELP_PATH = helpPagePath('user/packages/nuget_repository/index');
+export const PYPI_HELP_PATH = helpPagePath('user/packages/pypi_repository/index');
+export const COMPOSER_HELP_PATH = helpPagePath('user/packages/composer_repository/index');
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql b/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql
index 08ea0938a59..c45cbe56e00 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql
+++ b/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql
@@ -7,9 +7,19 @@ query getPackageDetails($id: ID!) {
createdAt
updatedAt
status
+ canDestroy
+ npmUrl
+ mavenUrl
+ conanUrl
+ nugetUrl
+ pypiUrl
+ pypiSetupUrl
+ composerUrl
+ composerConfigRepositoryUrl
project {
id
path
+ name
}
tags(first: 10) {
nodes {
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/index.js b/app/assets/javascripts/packages_and_registries/package_registry/index.js
index 7ec931ff9a0..6680e612985 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/index.js
+++ b/app/assets/javascripts/packages_and_registries/package_registry/index.js
@@ -2,29 +2,59 @@ import Vue from 'vue';
import Translate from '~/vue_shared/translate';
import { apolloProvider } from '~/packages_and_registries/package_registry/graphql/index';
import PackageRegistry from '~/packages_and_registries/package_registry/pages/index.vue';
+import RegistryBreadcrumb from '~/packages_and_registries/shared/components/registry_breadcrumb.vue';
+import { renderBreadcrumb } from '~/packages_and_registries/shared/utils';
import createRouter from './router';
Vue.use(Translate);
export default () => {
const el = document.getElementById('js-vue-packages-list');
- const { endpoint, resourceId, fullPath, pageType, emptyListIllustration } = el.dataset;
- const router = createRouter(endpoint);
+ const {
+ endpoint,
+ resourceId,
+ fullPath,
+ pageType,
+ emptyListIllustration,
+ npmInstanceUrl,
+ projectListUrl,
+ groupListUrl,
+ } = el.dataset;
const isGroupPage = pageType === 'groups';
- return new Vue({
- el,
- router,
- apolloProvider,
- provide: {
- resourceId,
- fullPath,
- emptyListIllustration,
- isGroupPage,
- },
- render(createElement) {
- return createElement(PackageRegistry);
+ // This is a mini state to help the breadcrumb have the correct name in the details page
+ const breadCrumbState = Vue.observable({
+ name: '',
+ updateName(value) {
+ this.name = value;
},
});
+
+ const router = createRouter(endpoint, breadCrumbState);
+
+ const attachMainComponent = () =>
+ new Vue({
+ el,
+ router,
+ apolloProvider,
+ provide: {
+ resourceId,
+ fullPath,
+ emptyListIllustration,
+ isGroupPage,
+ npmInstanceUrl,
+ projectListUrl,
+ groupListUrl,
+ breadCrumbState,
+ },
+ render(createElement) {
+ return createElement(PackageRegistry);
+ },
+ });
+
+ return {
+ attachBreadcrumb: renderBreadcrumb(router, apolloProvider, RegistryBreadcrumb),
+ attachMainComponent,
+ };
};
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/pages/details.js b/app/assets/javascripts/packages_and_registries/package_registry/pages/details.js
deleted file mode 100644
index d94bbd21035..00000000000
--- a/app/assets/javascripts/packages_and_registries/package_registry/pages/details.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import Vue from 'vue';
-import { parseBoolean } from '~/lib/utils/common_utils';
-import PackagesApp from '~/packages_and_registries/package_registry/components/details/app.vue';
-import { apolloProvider } from '~/packages_and_registries/package_registry/graphql/index';
-import Translate from '~/vue_shared/translate';
-
-Vue.use(Translate);
-
-export default () => {
- const el = document.getElementById('js-vue-packages-detail-new');
- if (!el) {
- return null;
- }
-
- const { canDelete, ...datasetOptions } = el.dataset;
- return new Vue({
- el,
- apolloProvider,
- provide: {
- canDelete: parseBoolean(canDelete),
- ...datasetOptions,
- },
- render(createElement) {
- return createElement(PackagesApp);
- },
- });
-};
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue b/app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue
new file mode 100644
index 00000000000..162b420a784
--- /dev/null
+++ b/app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue
@@ -0,0 +1,350 @@
+<script>
+import {
+ GlBadge,
+ GlButton,
+ GlModal,
+ GlModalDirective,
+ GlTooltipDirective,
+ GlEmptyState,
+ GlTab,
+ GlTabs,
+ GlSprintf,
+} from '@gitlab/ui';
+import createFlash from '~/flash';
+import { convertToGraphQLId } from '~/graphql_shared/utils';
+import { numberToHumanSize } from '~/lib/utils/number_utils';
+import { objectToQuery } from '~/lib/utils/url_utility';
+import { s__, __ } from '~/locale';
+import { packageTypeToTrackCategory } from '~/packages_and_registries/package_registry/utils';
+import AdditionalMetadata from '~/packages_and_registries/package_registry/components/details/additional_metadata.vue';
+import DependencyRow from '~/packages_and_registries/package_registry/components/details/dependency_row.vue';
+import InstallationCommands from '~/packages_and_registries/package_registry/components/details/installation_commands.vue';
+import PackageFiles from '~/packages_and_registries/package_registry/components/details/package_files.vue';
+import PackageHistory from '~/packages_and_registries/package_registry/components/details/package_history.vue';
+import PackageTitle from '~/packages_and_registries/package_registry/components/details/package_title.vue';
+import VersionRow from '~/packages_and_registries/package_registry/components/details/version_row.vue';
+import DeletePackage from '~/packages_and_registries/package_registry/components/functional/delete_package.vue';
+import {
+ PACKAGE_TYPE_NUGET,
+ PACKAGE_TYPE_COMPOSER,
+ DELETE_PACKAGE_TRACKING_ACTION,
+ REQUEST_DELETE_PACKAGE_TRACKING_ACTION,
+ CANCEL_DELETE_PACKAGE_TRACKING_ACTION,
+ PULL_PACKAGE_TRACKING_ACTION,
+ DELETE_PACKAGE_FILE_TRACKING_ACTION,
+ REQUEST_DELETE_PACKAGE_FILE_TRACKING_ACTION,
+ CANCEL_DELETE_PACKAGE_FILE_TRACKING_ACTION,
+ SHOW_DELETE_SUCCESS_ALERT,
+ FETCH_PACKAGE_DETAILS_ERROR_MESSAGE,
+ DELETE_PACKAGE_FILE_ERROR_MESSAGE,
+ DELETE_PACKAGE_FILE_SUCCESS_MESSAGE,
+} from '~/packages_and_registries/package_registry/constants';
+
+import destroyPackageFileMutation from '~/packages_and_registries/package_registry/graphql/mutations/destroy_package_file.mutation.graphql';
+import getPackageDetails from '~/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql';
+import Tracking from '~/tracking';
+
+export default {
+ name: 'PackagesApp',
+ components: {
+ GlBadge,
+ GlButton,
+ GlEmptyState,
+ GlModal,
+ GlTab,
+ GlTabs,
+ GlSprintf,
+ PackageTitle,
+ VersionRow,
+ DependencyRow,
+ PackageHistory,
+ AdditionalMetadata,
+ InstallationCommands,
+ PackageFiles,
+ DeletePackage,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ GlModal: GlModalDirective,
+ },
+ mixins: [Tracking.mixin()],
+ inject: ['emptyListIllustration', 'projectListUrl', 'groupListUrl', 'breadCrumbState'],
+ trackingActions: {
+ DELETE_PACKAGE_TRACKING_ACTION,
+ REQUEST_DELETE_PACKAGE_TRACKING_ACTION,
+ CANCEL_DELETE_PACKAGE_TRACKING_ACTION,
+ PULL_PACKAGE_TRACKING_ACTION,
+ DELETE_PACKAGE_FILE_TRACKING_ACTION,
+ REQUEST_DELETE_PACKAGE_FILE_TRACKING_ACTION,
+ CANCEL_DELETE_PACKAGE_FILE_TRACKING_ACTION,
+ },
+ data() {
+ return {
+ fileToDelete: null,
+ packageEntity: {},
+ };
+ },
+ apollo: {
+ packageEntity: {
+ query: getPackageDetails,
+ variables() {
+ return this.queryVariables;
+ },
+ update(data) {
+ return data.package || {};
+ },
+ error(error) {
+ createFlash({
+ message: FETCH_PACKAGE_DETAILS_ERROR_MESSAGE,
+ captureError: true,
+ error,
+ });
+ },
+ result() {
+ this.breadCrumbState.updateName(
+ `${this.packageEntity?.name} v ${this.packageEntity?.version}`,
+ );
+ },
+ },
+ },
+ computed: {
+ projectName() {
+ return this.packageEntity.project?.name;
+ },
+ packageId() {
+ return this.$route.params.id;
+ },
+ queryVariables() {
+ return {
+ id: convertToGraphQLId('Packages::Package', this.packageId),
+ };
+ },
+ packageFiles() {
+ return this.packageEntity.packageFiles?.nodes;
+ },
+ isLoading() {
+ return this.$apollo.queries.packageEntity.loading;
+ },
+ isValidPackage() {
+ return this.isLoading || Boolean(this.packageEntity.name);
+ },
+ tracking() {
+ return {
+ category: packageTypeToTrackCategory(this.packageEntity.packageType),
+ };
+ },
+ hasVersions() {
+ return this.packageEntity.versions?.nodes?.length > 0;
+ },
+ packageDependencies() {
+ return this.packageEntity.dependencyLinks?.nodes || [];
+ },
+ showDependencies() {
+ return this.packageEntity.packageType === PACKAGE_TYPE_NUGET;
+ },
+ showFiles() {
+ return this.packageEntity.packageType !== PACKAGE_TYPE_COMPOSER;
+ },
+ },
+ methods: {
+ formatSize(size) {
+ return numberToHumanSize(size);
+ },
+ navigateToListWithSuccessModal() {
+ const returnTo =
+ !this.groupListUrl || document.referrer.includes(this.projectName)
+ ? this.projectListUrl
+ : this.groupListUrl; // to avoid security issue url are supplied from backend
+
+ const modalQuery = objectToQuery({ [SHOW_DELETE_SUCCESS_ALERT]: true });
+
+ window.location.replace(`${returnTo}?${modalQuery}`);
+ },
+ async deletePackageFile(id) {
+ try {
+ const { data } = await this.$apollo.mutate({
+ mutation: destroyPackageFileMutation,
+ variables: {
+ id,
+ },
+ awaitRefetchQueries: true,
+ refetchQueries: [
+ {
+ query: getPackageDetails,
+ variables: this.queryVariables,
+ },
+ ],
+ });
+ if (data?.destroyPackageFile?.errors[0]) {
+ throw data.destroyPackageFile.errors[0];
+ }
+ createFlash({
+ message: DELETE_PACKAGE_FILE_SUCCESS_MESSAGE,
+ type: 'success',
+ });
+ } catch (error) {
+ createFlash({
+ message: DELETE_PACKAGE_FILE_ERROR_MESSAGE,
+ type: 'warning',
+ captureError: true,
+ error,
+ });
+ }
+ },
+ handleFileDelete(file) {
+ this.track(REQUEST_DELETE_PACKAGE_FILE_TRACKING_ACTION);
+ this.fileToDelete = { ...file };
+ this.$refs.deleteFileModal.show();
+ },
+ confirmFileDelete() {
+ this.track(DELETE_PACKAGE_FILE_TRACKING_ACTION);
+ this.deletePackageFile(this.fileToDelete.id);
+ this.fileToDelete = null;
+ },
+ },
+ i18n: {
+ deleteModalTitle: s__(`PackageRegistry|Delete Package Version`),
+ deleteModalContent: s__(
+ `PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?`,
+ ),
+ deleteFileModalTitle: s__(`PackageRegistry|Delete Package File`),
+ deleteFileModalContent: s__(
+ `PackageRegistry|You are about to delete %{filename}. This is a destructive action that may render your package unusable. Are you sure?`,
+ ),
+ },
+ modal: {
+ packageDeletePrimaryAction: {
+ text: __('Delete'),
+ attributes: [
+ { variant: 'danger' },
+ { category: 'primary' },
+ { 'data-qa-selector': 'delete_modal_button' },
+ ],
+ },
+ fileDeletePrimaryAction: {
+ text: __('Delete'),
+ attributes: [{ variant: 'danger' }, { category: 'primary' }],
+ },
+ cancelAction: {
+ text: __('Cancel'),
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-empty-state
+ v-if="!isValidPackage"
+ :title="s__('PackageRegistry|Unable to load package')"
+ :description="s__('PackageRegistry|There was a problem fetching the details for this package.')"
+ :svg-path="emptyListIllustration"
+ />
+ <div v-else-if="!isLoading" class="packages-app">
+ <package-title :package-entity="packageEntity">
+ <template #delete-button>
+ <gl-button
+ v-if="packageEntity.canDestroy"
+ v-gl-modal="'delete-modal'"
+ variant="danger"
+ category="primary"
+ data-qa-selector="delete_button"
+ data-testid="delete-package"
+ >
+ {{ __('Delete') }}
+ </gl-button>
+ </template>
+ </package-title>
+
+ <gl-tabs>
+ <gl-tab :title="__('Detail')">
+ <div v-if="!isLoading" data-qa-selector="package_information_content">
+ <package-history :package-entity="packageEntity" :project-name="projectName" />
+
+ <installation-commands :package-entity="packageEntity" />
+
+ <additional-metadata :package-entity="packageEntity" />
+ </div>
+
+ <package-files
+ v-if="showFiles"
+ :can-delete="packageEntity.canDestroy"
+ :package-files="packageFiles"
+ @download-file="track($options.trackingActions.PULL_PACKAGE)"
+ @delete-file="handleFileDelete"
+ />
+ </gl-tab>
+
+ <gl-tab v-if="showDependencies">
+ <template #title>
+ <span>{{ __('Dependencies') }}</span>
+ <gl-badge size="sm">{{ packageDependencies.length }}</gl-badge>
+ </template>
+
+ <template v-if="packageDependencies.length > 0">
+ <dependency-row v-for="dep in packageDependencies" :key="dep.id" :dependency-link="dep" />
+ </template>
+
+ <p v-else class="gl-mt-3" data-testid="no-dependencies-message">
+ {{ s__('PackageRegistry|This NuGet package has no dependencies.') }}
+ </p>
+ </gl-tab>
+
+ <gl-tab :title="__('Other versions')" title-item-class="js-versions-tab">
+ <template v-if="hasVersions">
+ <version-row v-for="v in packageEntity.versions.nodes" :key="v.id" :package-entity="v" />
+ </template>
+
+ <p v-else class="gl-mt-3" data-testid="no-versions-message">
+ {{ s__('PackageRegistry|There are no other versions of this package.') }}
+ </p>
+ </gl-tab>
+ </gl-tabs>
+
+ <delete-package
+ @start="track($options.trackingActions.DELETE_PACKAGE_TRACKING_ACTION)"
+ @end="navigateToListWithSuccessModal"
+ >
+ <template #default="{ deletePackage }">
+ <gl-modal
+ ref="deleteModal"
+ size="sm"
+ modal-id="delete-modal"
+ data-testid="delete-modal"
+ :action-primary="$options.modal.packageDeletePrimaryAction"
+ :action-cancel="$options.modal.cancelAction"
+ @primary="deletePackage(packageEntity)"
+ @canceled="track($options.trackingActions.CANCEL_DELETE_PACKAGE)"
+ >
+ <template #modal-title>{{ $options.i18n.deleteModalTitle }}</template>
+ <gl-sprintf :message="$options.i18n.deleteModalContent">
+ <template #version>
+ <strong>{{ packageEntity.version }}</strong>
+ </template>
+
+ <template #name>
+ <strong>{{ packageEntity.name }}</strong>
+ </template>
+ </gl-sprintf>
+ </gl-modal>
+ </template>
+ </delete-package>
+
+ <gl-modal
+ ref="deleteFileModal"
+ size="sm"
+ modal-id="delete-file-modal"
+ :action-primary="$options.modal.fileDeletePrimaryAction"
+ :action-cancel="$options.modal.cancelAction"
+ data-testid="delete-file-modal"
+ @primary="confirmFileDelete"
+ @canceled="track($options.trackingActions.CANCEL_DELETE_PACKAGE_FILE)"
+ >
+ <template #modal-title>{{ $options.i18n.deleteFileModalTitle }}</template>
+ <gl-sprintf v-if="fileToDelete" :message="$options.i18n.deleteFileModalContent">
+ <template #filename>
+ <strong>{{ fileToDelete.file_name }}</strong>
+ </template>
+ </gl-sprintf>
+ </gl-modal>
+ </div>
+</template>
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/router.js b/app/assets/javascripts/packages_and_registries/package_registry/router.js
index ea5b740e879..c5ef4f70dd9 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/router.js
+++ b/app/assets/javascripts/packages_and_registries/package_registry/router.js
@@ -1,10 +1,12 @@
import Vue from 'vue';
import VueRouter from 'vue-router';
import List from '~/packages_and_registries/package_registry/pages/list.vue';
+import Details from '~/packages_and_registries/package_registry/pages/details.vue';
+import { PACKAGE_REGISTRY_TITLE } from '~/packages_and_registries/package_registry/constants';
Vue.use(VueRouter);
-export default function createRouter(base) {
+export default function createRouter(base, breadCrumbState) {
const router = new VueRouter({
base,
mode: 'history',
@@ -13,9 +15,25 @@ export default function createRouter(base) {
name: 'list',
path: '/',
component: List,
+ meta: {
+ nameGenerator: () => PACKAGE_REGISTRY_TITLE,
+ root: true,
+ },
+ },
+ {
+ name: 'details',
+ path: '/:id',
+ component: Details,
+ meta: {
+ nameGenerator: () => breadCrumbState.name,
+ },
},
],
});
+ router.afterEach(() => {
+ breadCrumbState.updateName('');
+ });
+
return router;
}
diff --git a/app/assets/javascripts/packages_and_registries/shared/components/persisted_search.vue b/app/assets/javascripts/packages_and_registries/shared/components/persisted_search.vue
new file mode 100644
index 00000000000..9b2de1a1b84
--- /dev/null
+++ b/app/assets/javascripts/packages_and_registries/shared/components/persisted_search.vue
@@ -0,0 +1,80 @@
+<script>
+import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue';
+import UrlSync from '~/vue_shared/components/url_sync.vue';
+import { extractFilterAndSorting, getQueryParams } from '~/packages_and_registries/shared/utils';
+
+export default {
+ components: { RegistrySearch, UrlSync },
+ props: {
+ sortableFields: {
+ type: Array,
+ required: true,
+ },
+ defaultOrder: {
+ type: String,
+ required: true,
+ },
+ defaultSort: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ filters: [],
+ sorting: {
+ orderBy: this.defaultOrder,
+ sort: this.defaultSort,
+ },
+ mountRegistrySearch: false,
+ };
+ },
+ computed: {
+ parsedSorting() {
+ const cleanOrderBy = this.sorting?.orderBy.replace('_at', '');
+ return `${cleanOrderBy}_${this.sorting?.sort}`.toUpperCase();
+ },
+ },
+ mounted() {
+ const queryParams = getQueryParams(window.document.location.search);
+ const { sorting, filters } = extractFilterAndSorting(queryParams);
+ this.updateSorting(sorting);
+ this.updateFilters(filters);
+ this.mountRegistrySearch = true;
+ this.emitUpdate();
+ },
+ methods: {
+ updateFilters(newValue) {
+ this.filters = newValue;
+ },
+ updateSorting(newValue) {
+ this.sorting = { ...this.sorting, ...newValue };
+ },
+ updateSortingAndEmitUpdate(newValue) {
+ this.updateSorting(newValue);
+ this.emitUpdate();
+ },
+ emitUpdate() {
+ this.$emit('update', { sort: this.parsedSorting, filters: this.filters });
+ },
+ },
+};
+</script>
+
+<template>
+ <url-sync>
+ <template #default="{ updateQuery }">
+ <registry-search
+ v-if="mountRegistrySearch"
+ :filter="filters"
+ :sorting="sorting"
+ :tokens="$options.tokens"
+ :sortable-fields="sortableFields"
+ @sorting:changed="updateSortingAndEmitUpdate"
+ @filter:changed="updateFilters"
+ @filter:submit="emitUpdate"
+ @query:changed="updateQuery"
+ />
+ </template>
+ </url-sync>
+</template>
diff --git a/app/assets/javascripts/packages_and_registries/shared/components/registry_breadcrumb.vue b/app/assets/javascripts/packages_and_registries/shared/components/registry_breadcrumb.vue
new file mode 100644
index 00000000000..a1e3c06812c
--- /dev/null
+++ b/app/assets/javascripts/packages_and_registries/shared/components/registry_breadcrumb.vue
@@ -0,0 +1,56 @@
+<script>
+// We are using gl-breadcrumb only at the last child of the handwritten breadcrumb
+// until this gitlab-ui issue is resolved: https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1079
+//
+// See the CSS workaround in app/assets/stylesheets/pages/registry.scss when this file is changed.
+import { GlBreadcrumb, GlIcon } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlBreadcrumb,
+ GlIcon,
+ },
+ computed: {
+ rootRoute() {
+ return this.$router.options.routes.find((r) => r.meta.root);
+ },
+ detailsRoute() {
+ return this.$router.options.routes.find((r) => r.name === 'details');
+ },
+ isRootRoute() {
+ return this.$route.name === this.rootRoute.name;
+ },
+ detailsRouteName() {
+ return this.detailsRoute.meta.nameGenerator();
+ },
+ isLoaded() {
+ return this.isRootRoute || this.detailsRouteName;
+ },
+ allCrumbs() {
+ const crumbs = [
+ {
+ text: this.rootRoute.meta.nameGenerator(),
+ to: this.rootRoute.path,
+ },
+ ];
+ if (!this.isRootRoute) {
+ crumbs.push({
+ text: this.detailsRouteName,
+ href: this.detailsRoute.meta.path,
+ });
+ }
+ return crumbs;
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-breadcrumb :key="isLoaded" :items="allCrumbs">
+ <template #separator>
+ <span class="gl-mx-n5">
+ <gl-icon name="angle-right" :size="8" />
+ </span>
+ </template>
+ </gl-breadcrumb>
+</template>
diff --git a/app/assets/javascripts/packages_and_registries/shared/utils.js b/app/assets/javascripts/packages_and_registries/shared/utils.js
index cf18f655e79..7e963cd0b08 100644
--- a/app/assets/javascripts/packages_and_registries/shared/utils.js
+++ b/app/assets/javascripts/packages_and_registries/shared/utils.js
@@ -1,3 +1,4 @@
+import Vue from 'vue';
import { queryToObject } from '~/lib/utils/url_utility';
import { FILTERED_SEARCH_TERM } from './constants';
@@ -38,3 +39,37 @@ export const getCommitLink = ({ project_path: projectPath, pipeline = {} }, isGr
return `../commit/${pipeline.sha}`;
};
+
+export const renderBreadcrumb = (router, apolloProvider, RegistryBreadcrumb) => () => {
+ const breadCrumbEls = document.querySelectorAll('nav .js-breadcrumbs-list li');
+ const breadCrumbEl = breadCrumbEls[breadCrumbEls.length - 1];
+ const lastCrumb = breadCrumbEl.children[0];
+ const crumbs = [lastCrumb];
+ const nestedBreadcrumbEl = document.createElement('div');
+ breadCrumbEl.replaceChild(nestedBreadcrumbEl, lastCrumb);
+ return new Vue({
+ el: nestedBreadcrumbEl,
+ router,
+ apolloProvider,
+ components: {
+ RegistryBreadcrumb,
+ },
+ render(createElement) {
+ // FIXME(@tnir): this is a workaround until the MR gets merged:
+ // https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48115
+ const parentEl = breadCrumbEl.parentElement.parentElement;
+ if (parentEl) {
+ parentEl.classList.remove('breadcrumbs-container');
+ parentEl.classList.add('gl-display-flex');
+ parentEl.classList.add('w-100');
+ }
+ // End of FIXME(@tnir)
+ return createElement('registry-breadcrumb', {
+ class: breadCrumbEl.className,
+ props: {
+ crumbs,
+ },
+ });
+ },
+ });
+};
diff --git a/app/assets/javascripts/pages/admin/integrations/edit/index.js b/app/assets/javascripts/pages/admin/integrations/edit/index.js
index 8485b460261..c354ed1c142 100644
--- a/app/assets/javascripts/pages/admin/integrations/edit/index.js
+++ b/app/assets/javascripts/pages/admin/integrations/edit/index.js
@@ -1,7 +1,7 @@
import initIntegrationSettingsForm from '~/integrations/edit';
import PrometheusMetrics from '~/prometheus_metrics/prometheus_metrics';
-initIntegrationSettingsForm('.js-integration-settings-form');
+initIntegrationSettingsForm();
const prometheusSettingsSelector = '.js-prometheus-metrics-monitoring';
const prometheusSettingsWrapper = document.querySelector(prometheusSettingsSelector);
diff --git a/app/assets/javascripts/pages/admin/labels/edit/index.js b/app/assets/javascripts/pages/admin/labels/edit/index.js
index a3b9c43388a..a5eee2857df 100644
--- a/app/assets/javascripts/pages/admin/labels/edit/index.js
+++ b/app/assets/javascripts/pages/admin/labels/edit/index.js
@@ -1,3 +1,5 @@
import Labels from '~/labels/labels';
+import { initDeleteLabelModal } from '~/labels';
new Labels(); // eslint-disable-line no-new
+initDeleteLabelModal();
diff --git a/app/assets/javascripts/pages/admin/runners/edit/index.js b/app/assets/javascripts/pages/admin/runners/edit/index.js
new file mode 100644
index 00000000000..ddf135a2732
--- /dev/null
+++ b/app/assets/javascripts/pages/admin/runners/edit/index.js
@@ -0,0 +1,3 @@
+import { initAdminRunnerEdit } from '~/runner/admin_runner_edit';
+
+initAdminRunnerEdit();
diff --git a/app/assets/javascripts/pages/admin/runners/show/index.js b/app/assets/javascripts/pages/admin/runners/show/index.js
deleted file mode 100644
index d1853772fda..00000000000
--- a/app/assets/javascripts/pages/admin/runners/show/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import { initRunnerDetail } from '~/runner/runner_details';
-
-initRunnerDetail();
diff --git a/app/assets/javascripts/pages/dashboard/todos/index/todos.js b/app/assets/javascripts/pages/dashboard/todos/index/todos.js
index a1e7eb5d3de..cabb1b24ae6 100644
--- a/app/assets/javascripts/pages/dashboard/todos/index/todos.js
+++ b/app/assets/javascripts/pages/dashboard/todos/index/todos.js
@@ -172,8 +172,12 @@ export default class Todos {
updateBadges(data) {
$(document).trigger('todo:toggle', data.count);
- document.querySelector('.js-todos-pending .badge').innerHTML = addDelimiter(data.count);
- document.querySelector('.js-todos-done .badge').innerHTML = addDelimiter(data.done_count);
+ document.querySelector('.js-todos-pending .js-todos-badge').innerHTML = addDelimiter(
+ data.count,
+ );
+ document.querySelector('.js-todos-done .js-todos-badge').innerHTML = addDelimiter(
+ data.done_count,
+ );
}
goToTodoUrl(e) {
diff --git a/app/assets/javascripts/pages/explore/groups/index.js b/app/assets/javascripts/pages/explore/groups/index.js
index 808fcce46df..05078191e5c 100644
--- a/app/assets/javascripts/pages/explore/groups/index.js
+++ b/app/assets/javascripts/pages/explore/groups/index.js
@@ -1,6 +1,6 @@
-import GroupsList from '~/groups_list';
-import Landing from '~/landing';
-import initGroupsList from '../../../groups';
+import initGroupsList from '~/groups';
+import GroupsList from '~/groups/groups_list';
+import Landing from '~/groups/landing';
function exploreGroups() {
new GroupsList(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/groups/edit/index.js b/app/assets/javascripts/pages/groups/edit/index.js
index 604da77f60c..f6155b2ab2f 100644
--- a/app/assets/javascripts/pages/groups/edit/index.js
+++ b/app/assets/javascripts/pages/groups/edit/index.js
@@ -1,20 +1,18 @@
import { GROUP_BADGE } from '~/badges/constants';
-import initConfirmDangerModal from '~/confirm_danger_modal';
import dirtySubmitFactory from '~/dirty_submit/dirty_submit_factory';
import initFilePickers from '~/file_pickers';
import TransferDropdown from '~/groups/transfer_dropdown';
+import setupTransferEdit from '~/groups/transfer_edit';
import groupsSelect from '~/groups_select';
import { initCascadingSettingsLockPopovers } from '~/namespaces/cascading_settings';
import mountBadgeSettings from '~/pages/shared/mount_badge_settings';
import projectSelect from '~/project_select';
import initSearchSettings from '~/search_settings';
import initSettingsPanels from '~/settings_panels';
-import setupTransferEdit from '~/transfer_edit';
import initConfirmDanger from '~/init_confirm_danger';
document.addEventListener('DOMContentLoaded', () => {
initFilePickers();
- initConfirmDangerModal();
initConfirmDanger();
initSettingsPanels();
dirtySubmitFactory(
diff --git a/app/assets/javascripts/pages/groups/issues/index.js b/app/assets/javascripts/pages/groups/issues/index.js
index 966d55e5587..725c38defc3 100644
--- a/app/assets/javascripts/pages/groups/issues/index.js
+++ b/app/assets/javascripts/pages/groups/issues/index.js
@@ -1,6 +1,6 @@
import IssuableFilteredSearchTokenKeys from 'ee_else_ce/filtered_search/issuable_filtered_search_token_keys';
-import issuableInitBulkUpdateSidebar from '~/issuable/bulk_update_sidebar/issuable_init_bulk_update_sidebar';
-import { mountIssuablesListApp, mountIssuesListApp } from '~/issues_list';
+import { initBulkUpdateSidebar } from '~/issuable/bulk_update_sidebar';
+import { mountIssuesListApp } from '~/issues/list';
import initManualOrdering from '~/issues/manual_ordering';
import { FILTERED_SEARCH } from '~/filtered_search/constants';
import initFilteredSearch from '~/pages/search/init_filtered_search';
@@ -13,7 +13,7 @@ if (gon.features?.vueIssuesList) {
IssuableFilteredSearchTokenKeys.addExtraTokensForIssues();
IssuableFilteredSearchTokenKeys.removeTokensForKeys('release');
- issuableInitBulkUpdateSidebar.init(ISSUE_BULK_UPDATE_PREFIX);
+ initBulkUpdateSidebar(ISSUE_BULK_UPDATE_PREFIX);
initFilteredSearch({
page: FILTERED_SEARCH.ISSUES,
@@ -23,8 +23,4 @@ if (gon.features?.vueIssuesList) {
});
projectSelect();
initManualOrdering();
-
- if (gon.features?.vueIssuablesList) {
- mountIssuablesListApp();
- }
}
diff --git a/app/assets/javascripts/pages/groups/labels/edit/index.js b/app/assets/javascripts/pages/groups/labels/edit/index.js
index e4e377f62fc..c032321d039 100644
--- a/app/assets/javascripts/pages/groups/labels/edit/index.js
+++ b/app/assets/javascripts/pages/groups/labels/edit/index.js
@@ -1,4 +1,6 @@
import Labels from 'ee_else_ce/labels/labels';
+import { initDeleteLabelModal } from '~/labels';
// eslint-disable-next-line no-new
new Labels();
+initDeleteLabelModal();
diff --git a/app/assets/javascripts/pages/groups/merge_requests/index.js b/app/assets/javascripts/pages/groups/merge_requests/index.js
index cb38ee1c6e0..de28f027126 100644
--- a/app/assets/javascripts/pages/groups/merge_requests/index.js
+++ b/app/assets/javascripts/pages/groups/merge_requests/index.js
@@ -1,6 +1,6 @@
import addExtraTokensForMergeRequests from 'ee_else_ce/filtered_search/add_extra_tokens_for_merge_requests';
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
-import issuableInitBulkUpdateSidebar from '~/issuable/bulk_update_sidebar/issuable_init_bulk_update_sidebar';
+import { initBulkUpdateSidebar } from '~/issuable/bulk_update_sidebar';
import { FILTERED_SEARCH } from '~/filtered_search/constants';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import projectSelect from '~/project_select';
@@ -8,7 +8,7 @@ import projectSelect from '~/project_select';
const ISSUABLE_BULK_UPDATE_PREFIX = 'merge_request_';
addExtraTokensForMergeRequests(IssuableFilteredSearchTokenKeys);
-issuableInitBulkUpdateSidebar.init(ISSUABLE_BULK_UPDATE_PREFIX);
+initBulkUpdateSidebar(ISSUABLE_BULK_UPDATE_PREFIX);
initFilteredSearch({
page: FILTERED_SEARCH.MERGE_REQUESTS,
diff --git a/app/assets/javascripts/pages/groups/new/index.js b/app/assets/javascripts/pages/groups/new/index.js
index 7b0418e1ad5..702b152d25a 100644
--- a/app/assets/javascripts/pages/groups/new/index.js
+++ b/app/assets/javascripts/pages/groups/new/index.js
@@ -15,7 +15,7 @@ initFilePickers();
new Group(); // eslint-disable-line no-new
function initNewGroupCreation(el) {
- const { hasErrors } = el.dataset;
+ const { hasErrors, verificationRequired, verificationFormUrl, subscriptionsUrl } = el.dataset;
const props = {
hasErrors: parseBoolean(hasErrors),
@@ -23,6 +23,11 @@ function initNewGroupCreation(el) {
return new Vue({
el,
+ provide: {
+ verificationRequired: parseBoolean(verificationRequired),
+ verificationFormUrl,
+ subscriptionsUrl,
+ },
render(h) {
return h(NewGroupCreationApp, { props });
},
diff --git a/app/assets/javascripts/pages/groups/packages/index.js b/app/assets/javascripts/pages/groups/packages/index.js
new file mode 100644
index 00000000000..cbe08565cfa
--- /dev/null
+++ b/app/assets/javascripts/pages/groups/packages/index.js
@@ -0,0 +1,8 @@
+import packageApp from '~/packages_and_registries/package_registry/index';
+
+const app = packageApp();
+
+if (app) {
+ app.attachBreadcrumb();
+ app.attachMainComponent();
+}
diff --git a/app/assets/javascripts/pages/groups/packages/index/index.js b/app/assets/javascripts/pages/groups/packages/index/index.js
deleted file mode 100644
index 174973a9fad..00000000000
--- a/app/assets/javascripts/pages/groups/packages/index/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import packageApp from '~/packages_and_registries/package_registry/index';
-
-packageApp();
diff --git a/app/assets/javascripts/pages/groups/settings/access_tokens/index.js b/app/assets/javascripts/pages/groups/settings/access_tokens/index.js
new file mode 100644
index 00000000000..dc1bb88bf4b
--- /dev/null
+++ b/app/assets/javascripts/pages/groups/settings/access_tokens/index.js
@@ -0,0 +1,3 @@
+import { initExpiresAtField } from '~/access_tokens';
+
+initExpiresAtField();
diff --git a/app/assets/javascripts/pages/groups/settings/integrations/edit/index.js b/app/assets/javascripts/pages/groups/settings/integrations/edit/index.js
index 8485b460261..c354ed1c142 100644
--- a/app/assets/javascripts/pages/groups/settings/integrations/edit/index.js
+++ b/app/assets/javascripts/pages/groups/settings/integrations/edit/index.js
@@ -1,7 +1,7 @@
import initIntegrationSettingsForm from '~/integrations/edit';
import PrometheusMetrics from '~/prometheus_metrics/prometheus_metrics';
-initIntegrationSettingsForm('.js-integration-settings-form');
+initIntegrationSettingsForm();
const prometheusSettingsSelector = '.js-prometheus-metrics-monitoring';
const prometheusSettingsWrapper = document.querySelector(prometheusSettingsSelector);
diff --git a/app/assets/javascripts/pages/help/index/index.js b/app/assets/javascripts/pages/help/index/index.js
index 736add8dca3..a8e67c57307 100644
--- a/app/assets/javascripts/pages/help/index/index.js
+++ b/app/assets/javascripts/pages/help/index/index.js
@@ -1,6 +1,5 @@
-import $ from 'jquery';
import docs from '~/docs/docs_bundle';
-import VersionCheckImage from '~/version_check_image';
+import initGitlabVersionCheck from '~/gitlab_version_check';
docs();
-VersionCheckImage.bindErrorEvent($('img.js-version-status-badge'));
+initGitlabVersionCheck();
diff --git a/app/assets/javascripts/pages/profiles/keys/index.js b/app/assets/javascripts/pages/profiles/keys/index.js
index 1b291d9509d..6b12604c76b 100644
--- a/app/assets/javascripts/pages/profiles/keys/index.js
+++ b/app/assets/javascripts/pages/profiles/keys/index.js
@@ -7,11 +7,13 @@ function initSshKeyValidation() {
const input = document.querySelector('.js-add-ssh-key-validation-input');
if (!input) return;
+ const supportedAlgorithms = JSON.parse(input.dataset.supportedAlgorithms);
const warning = document.querySelector('.js-add-ssh-key-validation-warning');
const originalSubmit = input.form.querySelector('.js-add-ssh-key-validation-original-submit');
const confirmSubmit = warning.querySelector('.js-add-ssh-key-validation-confirm-submit');
const addSshKeyValidation = new AddSshKeyValidation(
+ supportedAlgorithms,
input,
warning,
originalSubmit,
diff --git a/app/assets/javascripts/pages/projects/blob/show/index.js b/app/assets/javascripts/pages/projects/blob/show/index.js
index b365e039191..2fc9a111405 100644
--- a/app/assets/javascripts/pages/projects/blob/show/index.js
+++ b/app/assets/javascripts/pages/projects/blob/show/index.js
@@ -1,5 +1,6 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
+import VueRouter from 'vue-router';
import TableOfContents from '~/blob/components/table_contents.vue';
import PipelineTourSuccessModal from '~/blob/pipeline_tour_success_modal.vue';
import { BlobViewer, initAuxiliaryViewer } from '~/blob/viewer/index';
@@ -12,11 +13,14 @@ import BlobContentViewer from '~/repository/components/blob_content_viewer.vue';
import '~/sourcegraph/load';
Vue.use(VueApollo);
+Vue.use(VueRouter);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
});
+const router = new VueRouter({ mode: 'history' });
+
const viewBlobEl = document.querySelector('#js-view-blob-app');
if (viewBlobEl) {
@@ -25,6 +29,7 @@ if (viewBlobEl) {
// eslint-disable-next-line no-new
new Vue({
el: viewBlobEl,
+ router,
apolloProvider,
provide: {
targetBranch,
@@ -41,6 +46,7 @@ if (viewBlobEl) {
});
initAuxiliaryViewer();
+ initBlob();
} else {
new BlobViewer(); // eslint-disable-line no-new
initBlob();
diff --git a/app/assets/javascripts/pages/projects/branches/index/index.js b/app/assets/javascripts/pages/projects/branches/index/index.js
index 97dc76908af..d279c4cbb08 100644
--- a/app/assets/javascripts/pages/projects/branches/index/index.js
+++ b/app/assets/javascripts/pages/projects/branches/index/index.js
@@ -1,13 +1,11 @@
import initDeprecatedRemoveRowBehavior from '~/behaviors/deprecated_remove_row_behavior';
import AjaxLoadingSpinner from '~/branches/ajax_loading_spinner';
import BranchSortDropdown from '~/branches/branch_sort_dropdown';
-import DeleteModal from '~/branches/branches_delete_modal';
import initDiverganceGraph from '~/branches/divergence_graph';
import initDeleteBranchButton from '~/branches/init_delete_branch_button';
import initDeleteBranchModal from '~/branches/init_delete_branch_modal';
AjaxLoadingSpinner.init();
-new DeleteModal(); // eslint-disable-line no-new
const { divergingCountsEndpoint, defaultBranch } = document.querySelector(
'.js-branch-list',
diff --git a/app/assets/javascripts/pages/projects/edit/index.js b/app/assets/javascripts/pages/projects/edit/index.js
index 100ca5b36d9..c0eb2a8fd77 100644
--- a/app/assets/javascripts/pages/projects/edit/index.js
+++ b/app/assets/javascripts/pages/projects/edit/index.js
@@ -1,5 +1,4 @@
import { PROJECT_BADGE } from '~/badges/constants';
-import initLegacyConfirmDangerModal from '~/confirm_danger_modal';
import initConfirmDanger from '~/init_confirm_danger';
import dirtySubmitFactory from '~/dirty_submit/dirty_submit_factory';
import initFilePickers from '~/file_pickers';
@@ -15,7 +14,6 @@ import initProjectPermissionsSettings from '../shared/permissions';
import initProjectLoadingSpinner from '../shared/save_project_loader';
initFilePickers();
-initLegacyConfirmDangerModal();
initConfirmDanger();
initSettingsPanels();
initProjectDeleteButton();
diff --git a/app/assets/javascripts/pages/projects/find_file/show/index.js b/app/assets/javascripts/pages/projects/find_file/show/index.js
index a8225167c6b..f47888f0cb8 100644
--- a/app/assets/javascripts/pages/projects/find_file/show/index.js
+++ b/app/assets/javascripts/pages/projects/find_file/show/index.js
@@ -1,6 +1,6 @@
import $ from 'jquery';
import ShortcutsFindFile from '~/behaviors/shortcuts/shortcuts_find_file';
-import ProjectFindFile from '~/project_find_file';
+import ProjectFindFile from '~/projects/project_find_file';
const findElement = document.querySelector('.js-file-finder');
const projectFindFile = new ProjectFindFile($('.file-finder-holder'), {
diff --git a/app/assets/javascripts/pages/projects/imports/show/index.js b/app/assets/javascripts/pages/projects/imports/show/index.js
index 8397826f8eb..21d07e04ddc 100644
--- a/app/assets/javascripts/pages/projects/imports/show/index.js
+++ b/app/assets/javascripts/pages/projects/imports/show/index.js
@@ -1,3 +1,3 @@
-import ProjectImport from '~/project_import';
+import ProjectImport from '~/projects/project_import';
new ProjectImport(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/projects/incidents/show/index.js b/app/assets/javascripts/pages/projects/incidents/show/index.js
index 4633eaef8f9..5a8cfcf8462 100644
--- a/app/assets/javascripts/pages/projects/incidents/show/index.js
+++ b/app/assets/javascripts/pages/projects/incidents/show/index.js
@@ -1,6 +1,6 @@
+import { initShow } from '~/issues';
import initRelatedIssues from '~/related_issues';
import initSidebarBundle from '~/sidebar/sidebar_bundle';
-import initShow from '~/issues/show';
initShow();
initSidebarBundle();
diff --git a/app/assets/javascripts/pages/projects/init_blob.js b/app/assets/javascripts/pages/projects/init_blob.js
index 06aba866ccf..7db34816cfe 100644
--- a/app/assets/javascripts/pages/projects/init_blob.js
+++ b/app/assets/javascripts/pages/projects/init_blob.js
@@ -2,8 +2,8 @@ import ShortcutsBlob from '~/behaviors/shortcuts/shortcuts_blob';
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import BlobForkSuggestion from '~/blob/blob_fork_suggestion';
import BlobLinePermalinkUpdater from '~/blob/blob_line_permalink_updater';
+import LineHighlighter from '~/blob/line_highlighter';
import initBlobBundle from '~/blob_edit/blob_bundle';
-import LineHighlighter from '~/line_highlighter';
export default () => {
new LineHighlighter(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/projects/issues/edit/index.js b/app/assets/javascripts/pages/projects/issues/edit/index.js
index aa00d1f58bd..06dcd2c2d94 100644
--- a/app/assets/javascripts/pages/projects/issues/edit/index.js
+++ b/app/assets/javascripts/pages/projects/issues/edit/index.js
@@ -1,3 +1,3 @@
-import initForm from 'ee_else_ce/issues/form';
+import { initForm } from 'ee_else_ce/issues';
initForm();
diff --git a/app/assets/javascripts/pages/projects/issues/index/index.js b/app/assets/javascripts/pages/projects/issues/index/index.js
index e937713044c..44b1d5277d1 100644
--- a/app/assets/javascripts/pages/projects/issues/index/index.js
+++ b/app/assets/javascripts/pages/projects/issues/index/index.js
@@ -1,8 +1,8 @@
import IssuableFilteredSearchTokenKeys from 'ee_else_ce/filtered_search/issuable_filtered_search_token_keys';
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import { initCsvImportExportButtons, initIssuableByEmail } from '~/issuable';
-import issuableInitBulkUpdateSidebar from '~/issuable/bulk_update_sidebar/issuable_init_bulk_update_sidebar';
-import { mountIssuablesListApp, mountIssuesListApp, mountJiraIssuesListApp } from '~/issues_list';
+import { initBulkUpdateSidebar, initIssueStatusSelect } from '~/issuable/bulk_update_sidebar';
+import { mountIssuesListApp, mountJiraIssuesListApp } from '~/issues/list';
import initManualOrdering from '~/issues/manual_ordering';
import { FILTERED_SEARCH } from '~/filtered_search/constants';
import { ISSUABLE_INDEX } from '~/issuable/constants';
@@ -20,16 +20,13 @@ if (gon.features?.vueIssuesList) {
useDefaultState: true,
});
- issuableInitBulkUpdateSidebar.init(ISSUABLE_INDEX.ISSUE);
+ initBulkUpdateSidebar(ISSUABLE_INDEX.ISSUE);
+ initIssueStatusSelect();
new UsersSelect(); // eslint-disable-line no-new
initCsvImportExportButtons();
initIssuableByEmail();
initManualOrdering();
-
- if (gon.features?.vueIssuablesList) {
- mountIssuablesListApp();
- }
}
new ShortcutsNavigation(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/projects/issues/new/index.js b/app/assets/javascripts/pages/projects/issues/new/index.js
index aa00d1f58bd..06dcd2c2d94 100644
--- a/app/assets/javascripts/pages/projects/issues/new/index.js
+++ b/app/assets/javascripts/pages/projects/issues/new/index.js
@@ -1,3 +1,3 @@
-import initForm from 'ee_else_ce/issues/form';
+import { initForm } from 'ee_else_ce/issues';
initForm();
diff --git a/app/assets/javascripts/pages/projects/issues/service_desk/index.js b/app/assets/javascripts/pages/projects/issues/service_desk/index.js
index 69639d17f8a..7dd128fedb9 100644
--- a/app/assets/javascripts/pages/projects/issues/service_desk/index.js
+++ b/app/assets/javascripts/pages/projects/issues/service_desk/index.js
@@ -1,8 +1,3 @@
-import { mountIssuablesListApp } from '~/issues_list';
-import { initFilteredSearchServiceDesk } from '~/issues/init_filtered_search_service_desk';
+import { initFilteredSearchServiceDesk } from '~/issues';
initFilteredSearchServiceDesk();
-
-if (gon.features?.vueIssuablesList) {
- mountIssuablesListApp();
-}
diff --git a/app/assets/javascripts/pages/projects/issues/show/index.js b/app/assets/javascripts/pages/projects/issues/show/index.js
index d0b1942f2a4..46a34c025b6 100644
--- a/app/assets/javascripts/pages/projects/issues/show/index.js
+++ b/app/assets/javascripts/pages/projects/issues/show/index.js
@@ -1,7 +1,7 @@
+import { initShow } from '~/issues';
import { store } from '~/notes/stores';
import initRelatedIssues from '~/related_issues';
import initSidebarBundle from '~/sidebar/sidebar_bundle';
-import initShow from '~/issues/show';
initShow();
initSidebarBundle(store);
diff --git a/app/assets/javascripts/pages/projects/labels/edit/index.js b/app/assets/javascripts/pages/projects/labels/edit/index.js
index c4d7af39767..cb554e3d4da 100644
--- a/app/assets/javascripts/pages/projects/labels/edit/index.js
+++ b/app/assets/javascripts/pages/projects/labels/edit/index.js
@@ -1,3 +1,5 @@
import Labels from 'ee_else_ce/labels/labels';
+import { initDeleteLabelModal } from '~/labels';
new Labels(); // eslint-disable-line no-new
+initDeleteLabelModal();
diff --git a/app/assets/javascripts/pages/projects/merge_requests/index/index.js b/app/assets/javascripts/pages/projects/merge_requests/index/index.js
index acd1731a700..e284e7b2c5e 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/index/index.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/index/index.js
@@ -2,13 +2,14 @@ import addExtraTokensForMergeRequests from 'ee_else_ce/filtered_search/add_extra
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
import { initCsvImportExportButtons, initIssuableByEmail } from '~/issuable';
-import issuableInitBulkUpdateSidebar from '~/issuable/bulk_update_sidebar/issuable_init_bulk_update_sidebar';
+import { initBulkUpdateSidebar, initIssueStatusSelect } from '~/issuable/bulk_update_sidebar';
import { FILTERED_SEARCH } from '~/filtered_search/constants';
import { ISSUABLE_INDEX } from '~/issuable/constants';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import UsersSelect from '~/users_select';
-issuableInitBulkUpdateSidebar.init(ISSUABLE_INDEX.MERGE_REQUEST);
+initBulkUpdateSidebar(ISSUABLE_INDEX.MERGE_REQUEST);
+initIssueStatusSelect();
addExtraTokensForMergeRequests(IssuableFilteredSearchTokenKeys);
IssuableFilteredSearchTokenKeys.removeTokensForKeys('iteration');
diff --git a/app/assets/javascripts/pages/projects/new/index.js b/app/assets/javascripts/pages/projects/new/index.js
index d89b4d0e0a3..5d830872ed9 100644
--- a/app/assets/javascripts/pages/projects/new/index.js
+++ b/app/assets/javascripts/pages/projects/new/index.js
@@ -1,5 +1,5 @@
import { initNewProjectCreation, initNewProjectUrlSelect } from '~/projects/new';
-import initProjectVisibilitySelector from '~/project_visibility';
+import initProjectVisibilitySelector from '~/projects/project_visibility';
import initProjectNew from '~/projects/project_new';
initProjectVisibilitySelector();
diff --git a/app/assets/javascripts/pages/projects/packages/packages/index.js b/app/assets/javascripts/pages/projects/packages/packages/index.js
new file mode 100644
index 00000000000..cbe08565cfa
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/packages/packages/index.js
@@ -0,0 +1,8 @@
+import packageApp from '~/packages_and_registries/package_registry/index';
+
+const app = packageApp();
+
+if (app) {
+ app.attachBreadcrumb();
+ app.attachMainComponent();
+}
diff --git a/app/assets/javascripts/pages/projects/packages/packages/index/index.js b/app/assets/javascripts/pages/projects/packages/packages/index/index.js
deleted file mode 100644
index 174973a9fad..00000000000
--- a/app/assets/javascripts/pages/projects/packages/packages/index/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import packageApp from '~/packages_and_registries/package_registry/index';
-
-packageApp();
diff --git a/app/assets/javascripts/pages/projects/packages/packages/show/index.js b/app/assets/javascripts/pages/projects/packages/packages/show/index.js
deleted file mode 100644
index 2dee87985cb..00000000000
--- a/app/assets/javascripts/pages/projects/packages/packages/show/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import initPackageDetails from '~/packages_and_registries/package_registry/pages/details';
-
-initPackageDetails();
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js
index e92b9b30fa4..277d2e0d30a 100644
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js
+++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js
@@ -1,6 +1,6 @@
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
-const defaultTimezone = { name: 'UTC', offset: 0 };
+const defaultTimezone = { identifier: 'Etc/UTC', name: 'UTC', offset: 0 };
const defaults = {
$inputEl: null,
$dropdownEl: null,
@@ -70,7 +70,7 @@ export default class TimezoneDropdown {
setDropdownValue(timezone) {
this.$dropdownToggle.text(this.displayFormat(timezone));
- this.$input.val(timezone.name);
+ this.$input.val(timezone.identifier);
}
handleDropdownChange({ selectedObj, e }) {
diff --git a/app/assets/javascripts/pages/projects/services/edit/index.js b/app/assets/javascripts/pages/projects/services/edit/index.js
index a2b18d86240..2048d3dfc37 100644
--- a/app/assets/javascripts/pages/projects/services/edit/index.js
+++ b/app/assets/javascripts/pages/projects/services/edit/index.js
@@ -2,7 +2,7 @@ import initIntegrationSettingsForm from '~/integrations/edit';
import PrometheusAlerts from '~/prometheus_alerts';
import CustomMetrics from '~/prometheus_metrics/custom_metrics';
-initIntegrationSettingsForm('.js-integration-settings-form');
+initIntegrationSettingsForm();
const prometheusSettingsSelector = '.js-prometheus-metrics-monitoring';
const prometheusSettingsWrapper = document.querySelector(prometheusSettingsSelector);
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
index 384ee1f5034..d5e00f54e91 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
+++ b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
@@ -1,6 +1,6 @@
<script>
-import { GlIcon, GlSprintf, GlLink, GlFormCheckbox, GlToggle } from '@gitlab/ui';
-
+import { GlButton, GlIcon, GlSprintf, GlLink, GlFormCheckbox, GlToggle } from '@gitlab/ui';
+import ConfirmDanger from '~/vue_shared/components/confirm_danger/confirm_danger.vue';
import settingsMixin from 'ee_else_ce/pages/projects/shared/permissions/mixins/settings_pannel_mixin';
import { __, s__ } from '~/locale';
import {
@@ -41,16 +41,19 @@ export default {
pucWarningHelpText: s__(
'ProjectSettings|Highlight the usage of hidden unicode characters. These have innocent uses for right-to-left languages, but can also be used in potential exploits.',
),
+ confirmButtonText: __('Save changes'),
},
components: {
projectFeatureSetting,
projectSettingRow,
+ GlButton,
GlIcon,
GlSprintf,
GlLink,
GlFormCheckbox,
GlToggle,
+ ConfirmDanger,
},
mixins: [settingsMixin],
@@ -163,6 +166,15 @@ export default {
required: false,
default: '',
},
+ confirmationPhrase: {
+ type: String,
+ required: true,
+ },
+ showVisibilityConfirmModal: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
const defaults = {
@@ -274,6 +286,12 @@ export default {
cveIdRequestIsDisabled() {
return this.visibilityLevel !== visibilityOptions.PUBLIC;
},
+ isVisibilityReduced() {
+ return (
+ this.showVisibilityConfirmModal &&
+ this.visibilityLevel < this.currentSettings.visibilityLevel
+ );
+ },
},
watch: {
@@ -774,5 +792,23 @@ export default {
<template #help>{{ $options.i18n.pucWarningHelpText }}</template>
</gl-form-checkbox>
</project-setting-row>
+ <confirm-danger
+ v-if="isVisibilityReduced"
+ button-variant="confirm"
+ :disabled="false"
+ :phrase="confirmationPhrase"
+ :button-text="$options.i18n.confirmButtonText"
+ data-testid="project-features-save-button"
+ @confirm="$emit('confirm')"
+ />
+ <gl-button
+ v-else
+ type="submit"
+ variant="confirm"
+ data-testid="project-features-save-button"
+ data-qa-selector="visibility_features_permissions_save_button"
+ >
+ {{ $options.i18n.confirmButtonText }}
+ </gl-button>
</div>
</template>
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/index.js b/app/assets/javascripts/pages/projects/shared/permissions/index.js
index d7bae44e96e..de8b1cc400e 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/index.js
+++ b/app/assets/javascripts/pages/projects/shared/permissions/index.js
@@ -1,4 +1,5 @@
import Vue from 'vue';
+import { parseBoolean } from '~/lib/utils/common_utils';
import settingsPanel from './components/settings_panel.vue';
export default function initProjectPermissionsSettings() {
@@ -6,8 +7,36 @@ export default function initProjectPermissionsSettings() {
const componentPropsEl = document.querySelector('.js-project-permissions-form-data');
const componentProps = JSON.parse(componentPropsEl.innerHTML);
+ const {
+ targetFormId,
+ additionalInformation,
+ confirmDangerMessage,
+ confirmButtonText,
+ showVisibilityConfirmModal,
+ htmlConfirmationMessage,
+ phrase: confirmationPhrase,
+ } = mountPoint.dataset;
+
return new Vue({
el: mountPoint,
- render: (createElement) => createElement(settingsPanel, { props: { ...componentProps } }),
+ provide: {
+ additionalInformation,
+ confirmDangerMessage,
+ confirmButtonText,
+ htmlConfirmationMessage: parseBoolean(htmlConfirmationMessage),
+ },
+ render: (createElement) =>
+ createElement(settingsPanel, {
+ props: {
+ ...componentProps,
+ confirmationPhrase,
+ showVisibilityConfirmModal: parseBoolean(showVisibilityConfirmModal),
+ },
+ on: {
+ confirm: () => {
+ if (targetFormId) document.getElementById(targetFormId)?.submit();
+ },
+ },
+ }),
});
}
diff --git a/app/assets/javascripts/pages/projects/show/index.js b/app/assets/javascripts/pages/projects/show/index.js
index 31d69a731fe..71c6773c176 100644
--- a/app/assets/javascripts/pages/projects/show/index.js
+++ b/app/assets/javascripts/pages/projects/show/index.js
@@ -1,16 +1,16 @@
import initTree from 'ee_else_ce/repository';
import Activities from '~/activities';
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
-import { BlobViewer } from '~/blob/viewer/index';
+import { BlobViewer } from '~/blob/viewer';
import { initUploadForm } from '~/blob_edit/blob_bundle';
import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
import leaveByUrl from '~/namespaces/leave_by_url';
import initVueNotificationsDropdown from '~/notifications';
+import Star from '~/projects/star';
import { initUploadFileTrigger } from '~/projects/upload_file';
import initReadMore from '~/read_more';
import UserCallout from '~/user_callout';
-import Star from '../../../star';
initReadMore();
new Star(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/registrations/new/index.js b/app/assets/javascripts/pages/registrations/new/index.js
index ae605edeaf0..8bbe81a9ed5 100644
--- a/app/assets/javascripts/pages/registrations/new/index.js
+++ b/app/assets/javascripts/pages/registrations/new/index.js
@@ -1,3 +1,5 @@
+import { trackNewRegistrations } from '~/google_tag_manager';
+
import NoEmojiValidator from '~/emoji/no_emoji_validator';
import LengthValidator from '~/pages/sessions/new/length_validator';
import UsernameValidator from '~/pages/sessions/new/username_validator';
@@ -5,3 +7,5 @@ import UsernameValidator from '~/pages/sessions/new/username_validator';
new UsernameValidator(); // eslint-disable-line no-new
new LengthValidator(); // eslint-disable-line no-new
new NoEmojiValidator(); // eslint-disable-line no-new
+
+trackNewRegistrations();
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 b29e9455755..c28de88554a 100644
--- a/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue
+++ b/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue
@@ -596,7 +596,9 @@ export default {
:disabled="disableSubmitButton"
>{{ submitButtonText }}</gl-button
>
- <gl-button :href="cancelFormPath" class="float-right">{{ $options.i18n.cancel }}</gl-button>
+ <gl-button data-testid="wiki-cancel-button" :href="cancelFormPath" class="float-right">{{
+ $options.i18n.cancel
+ }}</gl-button>
</div>
</gl-form>
</template>
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 9f82d4a5395..ca78f194a82 100644
--- a/app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue
+++ b/app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue
@@ -142,6 +142,7 @@ export default {
class="js-no-auto-disable"
category="primary"
variant="confirm"
+ data-qa-selector="commit_changes_button"
:disabled="submitDisabled"
:loading="isSaving"
>
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 92fa411d5af..bfbf24c6b13 100644
--- a/app/assets/javascripts/pipeline_editor/components/editor/text_editor.vue
+++ b/app/assets/javascripts/pipeline_editor/components/editor/text_editor.vue
@@ -15,12 +15,10 @@ export default {
onCiConfigUpdate(content) {
this.$emit('updateCiConfig', content);
},
- registerCiSchema() {
+ registerCiSchema({ detail: { instance } }) {
if (this.glFeatures.schemaLinting) {
- const editorInstance = this.$refs.editor.getEditor();
-
- editorInstance.use({ definition: CiSchemaExtension });
- editorInstance.registerCiSchema();
+ instance.use({ definition: CiSchemaExtension });
+ instance.registerCiSchema();
}
},
},
@@ -33,7 +31,7 @@ export default {
ref="editor"
:file-name="ciConfigPath"
v-bind="$attrs"
- @[$options.readyEvent]="registerCiSchema"
+ @[$options.readyEvent]="registerCiSchema($event)"
@input="onCiConfigUpdate"
v-on="$listeners"
/>
diff --git a/app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue b/app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue
index 16ad648afca..72b492a5877 100644
--- a/app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue
+++ b/app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue
@@ -153,7 +153,9 @@ export default {
<span class="gl-font-weight-bold">
<gl-sprintf :message="$options.i18n.pipelineInfo">
<template #id="{ content }">
- <span data-testid="pipeline-id"> {{ content }}{{ pipelineId }} </span>
+ <span data-testid="pipeline-id" data-qa-selector="pipeline_id_content">
+ {{ content }}{{ pipelineId }}
+ </span>
</template>
<template #status>{{ status.text }}</template>
<template #commit>
diff --git a/app/assets/javascripts/pipeline_editor/components/header/validation_segment.vue b/app/assets/javascripts/pipeline_editor/components/header/validation_segment.vue
index 833d784f940..23f1592cac1 100644
--- a/app/assets/javascripts/pipeline_editor/components/header/validation_segment.vue
+++ b/app/assets/javascripts/pipeline_editor/components/header/validation_segment.vue
@@ -5,6 +5,7 @@ import getAppStatus from '~/pipeline_editor/graphql/queries/client/app_status.qu
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
import {
EDITOR_APP_STATUS_EMPTY,
+ EDITOR_APP_STATUS_LINT_UNAVAILABLE,
EDITOR_APP_STATUS_LOADING,
EDITOR_APP_STATUS_VALID,
} from '../../constants';
@@ -17,6 +18,7 @@ export const i18n = {
loading: s__('Pipelines|Validating GitLab CI configuration…'),
invalid: s__('Pipelines|This GitLab CI configuration is invalid.'),
invalidWithReason: s__('Pipelines|This GitLab CI configuration is invalid: %{reason}.'),
+ unavailableValidation: s__('Pipelines|Configuration validation currently not available.'),
valid: s__('Pipelines|This GitLab CI configuration is valid.'),
};
@@ -29,6 +31,9 @@ export default {
TooltipOnTruncate,
},
inject: {
+ lintUnavailableHelpPagePath: {
+ default: '',
+ },
ymlHelpPagePath: {
default: '',
},
@@ -49,9 +54,15 @@ export default {
},
},
computed: {
+ helpPath() {
+ return this.isLintUnavailable ? this.lintUnavailableHelpPagePath : this.ymlHelpPagePath;
+ },
isEmpty() {
return this.appStatus === EDITOR_APP_STATUS_EMPTY;
},
+ isLintUnavailable() {
+ return this.appStatus === EDITOR_APP_STATUS_LINT_UNAVAILABLE;
+ },
isLoading() {
return this.appStatus === EDITOR_APP_STATUS_LOADING;
},
@@ -62,6 +73,8 @@ export default {
switch (this.appStatus) {
case EDITOR_APP_STATUS_EMPTY:
return 'check';
+ case EDITOR_APP_STATUS_LINT_UNAVAILABLE:
+ return 'time-out';
case EDITOR_APP_STATUS_VALID:
return 'check';
default:
@@ -74,6 +87,8 @@ export default {
switch (this.appStatus) {
case EDITOR_APP_STATUS_EMPTY:
return this.$options.i18n.empty;
+ case EDITOR_APP_STATUS_LINT_UNAVAILABLE:
+ return this.$options.i18n.unavailableValidation;
case EDITOR_APP_STATUS_VALID:
return this.$options.i18n.valid;
default:
@@ -96,10 +111,13 @@ export default {
<span v-else class="gl-display-inline-flex gl-white-space-nowrap gl-max-w-full">
<tooltip-on-truncate :title="message" class="gl-text-truncate">
- <gl-icon :name="icon" /> <span data-testid="validationMsg">{{ message }}</span>
+ <gl-icon :name="icon" />
+ <span data-qa-selector="validation_message_content" data-testid="validationMsg">
+ {{ message }}
+ </span>
</tooltip-on-truncate>
<span v-if="!isEmpty" class="gl-flex-shrink-0 gl-pl-2">
- <gl-link data-testid="learnMoreLink" :href="ymlHelpPagePath">
+ <gl-link data-testid="learnMoreLink" :href="helpPath">
{{ $options.i18n.learnMore }}
</gl-link>
</span>
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 3f50a1225d8..c75b1d4bb11 100644
--- a/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue
+++ b/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue
@@ -11,6 +11,7 @@ import {
EDITOR_APP_STATUS_INVALID,
EDITOR_APP_STATUS_LOADING,
EDITOR_APP_STATUS_VALID,
+ EDITOR_APP_STATUS_LINT_UNAVAILABLE,
LINT_TAB,
MERGED_TAB,
TAB_QUERY_PARAM,
@@ -106,6 +107,9 @@ export default {
isInvalid() {
return this.appStatus === EDITOR_APP_STATUS_INVALID;
},
+ isLintUnavailable() {
+ return this.appStatus === EDITOR_APP_STATUS_LINT_UNAVAILABLE;
+ },
isValid() {
return this.appStatus === EDITOR_APP_STATUS_VALID;
},
@@ -142,6 +146,7 @@ export default {
<template>
<gl-tabs
class="file-editor gl-mb-3"
+ data-qa-selector="file_editor_container"
:query-param-name="$options.query.TAB_QUERY_PARAM"
sync-active-tab-with-query-params
>
@@ -166,6 +171,7 @@ export default {
:empty-message="$options.i18n.empty.visualization"
:is-empty="isEmpty"
:is-invalid="isInvalid"
+ :is-unavailable="isLintUnavailable"
:keep-component-mounted="false"
:title="$options.i18n.tabGraph"
lazy
@@ -179,6 +185,7 @@ export default {
class="gl-mb-3"
:empty-message="$options.i18n.empty.lint"
:is-empty="isEmpty"
+ :is-unavailable="isLintUnavailable"
:title="$options.i18n.tabLint"
data-testid="lint-tab"
@click="setCurrentTab($options.tabConstants.LINT_TAB)"
@@ -192,6 +199,7 @@ export default {
:keep-component-mounted="false"
:is-empty="isEmpty"
:is-invalid="isInvalid"
+ :is-unavailable="isLintUnavailable"
:title="$options.i18n.tabMergedYaml"
lazy
data-testid="merged-tab"
diff --git a/app/assets/javascripts/pipeline_editor/components/ui/editor_tab.vue b/app/assets/javascripts/pipeline_editor/components/ui/editor_tab.vue
index 7c032441a04..673599da085 100644
--- a/app/assets/javascripts/pipeline_editor/components/ui/editor_tab.vue
+++ b/app/assets/javascripts/pipeline_editor/components/ui/editor_tab.vue
@@ -42,6 +42,9 @@ import { __, s__ } from '~/locale';
export default {
i18n: {
invalid: __('Your CI/CD configuration syntax is invalid. View Lint tab for more details.'),
+ unavailable: __(
+ "We're experiencing difficulties and this tab content is currently unavailable.",
+ ),
},
components: {
GlAlert,
@@ -66,14 +69,14 @@ export default {
isEmpty: {
type: Boolean,
required: false,
- default: null,
+ default: false,
},
isInvalid: {
type: Boolean,
required: false,
- default: null,
+ default: false,
},
- lazy: {
+ isUnavailable: {
type: Boolean,
required: false,
default: false,
@@ -83,6 +86,11 @@ export default {
required: false,
default: true,
},
+ lazy: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
return {
@@ -109,6 +117,9 @@ export default {
<template>
<gl-tab :lazy="isLazy" v-bind="$attrs" v-on="$listeners">
<gl-alert v-if="isEmpty" variant="tip">{{ emptyMessage }}</gl-alert>
+ <gl-alert v-else-if="isUnavailable" variant="danger" :dismissible="false">
+ {{ $options.i18n.unavailable }}</gl-alert
+ >
<gl-alert v-else-if="isInvalid" variant="danger">{{ $options.i18n.invalid }}</gl-alert>
<template v-else>
<slot v-for="slot in slots" :name="slot"></slot>
diff --git a/app/assets/javascripts/pipeline_editor/constants.js b/app/assets/javascripts/pipeline_editor/constants.js
index a2eaeeef286..bc79b0742e7 100644
--- a/app/assets/javascripts/pipeline_editor/constants.js
+++ b/app/assets/javascripts/pipeline_editor/constants.js
@@ -6,12 +6,14 @@ export const CI_CONFIG_STATUS_VALID = 'VALID';
// represent the global state of the pipeline editor app.
export const EDITOR_APP_STATUS_EMPTY = 'EMPTY';
export const EDITOR_APP_STATUS_INVALID = CI_CONFIG_STATUS_INVALID;
+export const EDITOR_APP_STATUS_LINT_UNAVAILABLE = 'LINT_DOWN';
export const EDITOR_APP_STATUS_LOADING = 'LOADING';
export const EDITOR_APP_STATUS_VALID = CI_CONFIG_STATUS_VALID;
export const EDITOR_APP_VALID_STATUSES = [
EDITOR_APP_STATUS_EMPTY,
EDITOR_APP_STATUS_INVALID,
+ EDITOR_APP_STATUS_LINT_UNAVAILABLE,
EDITOR_APP_STATUS_LOADING,
EDITOR_APP_STATUS_VALID,
];
diff --git a/app/assets/javascripts/pipeline_editor/index.js b/app/assets/javascripts/pipeline_editor/index.js
index ee93e327b76..04f91cb3d1e 100644
--- a/app/assets/javascripts/pipeline_editor/index.js
+++ b/app/assets/javascripts/pipeline_editor/index.js
@@ -37,6 +37,7 @@ export const initPipelineEditor = (selector = '#js-pipeline-editor') => {
emptyStateIllustrationPath,
helpPaths,
lintHelpPagePath,
+ lintUnavailableHelpPagePath,
needsHelpPagePath,
newMergeRequestPath,
pipelinePagePath,
@@ -124,6 +125,7 @@ export const initPipelineEditor = (selector = '#js-pipeline-editor') => {
emptyStateIllustrationPath,
helpPaths,
lintHelpPagePath,
+ lintUnavailableHelpPagePath,
needsHelpPagePath,
newMergeRequestPath,
pipelinePagePath,
diff --git a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
index e397054f06a..90f48195c5e 100644
--- a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
+++ b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
@@ -12,8 +12,9 @@ import PipelineEditorMessages from './components/ui/pipeline_editor_messages.vue
import {
COMMIT_SHA_POLL_INTERVAL,
EDITOR_APP_STATUS_EMPTY,
- EDITOR_APP_VALID_STATUSES,
EDITOR_APP_STATUS_LOADING,
+ EDITOR_APP_STATUS_LINT_UNAVAILABLE,
+ EDITOR_APP_VALID_STATUSES,
LOAD_FAILURE_UNKNOWN,
STARTER_TEMPLATE_NAME,
} from './constants';
@@ -51,6 +52,7 @@ export default {
failureReasons: [],
initialCiFileContent: '',
isFetchingCommitSha: false,
+ isLintUnavailable: false,
isNewCiConfigFile: false,
lastCommittedContent: '',
shouldSkipStartScreen: false,
@@ -147,10 +149,19 @@ export default {
return { ...ciConfig, stages };
},
result({ data }) {
- this.setAppStatus(data?.ciConfig?.status);
+ if (data?.ciConfig?.status) {
+ this.setAppStatus(data.ciConfig.status);
+ if (this.isLintUnavailable) {
+ this.isLintUnavailable = false;
+ }
+ }
},
- error(err) {
- this.reportFailure(LOAD_FAILURE_UNKNOWN, [String(err)]);
+ error() {
+ // We are not using `reportFailure` here because we don't
+ // need to bring attention to the linter being down. We let
+ // the user work on their file and if they look at their
+ // lint status, they will notice that the service is down
+ this.isLintUnavailable = true;
},
watchLoading(isLoading) {
if (isLoading) {
@@ -247,6 +258,13 @@ export default {
this.setAppStatus(EDITOR_APP_STATUS_EMPTY);
}
},
+ isLintUnavailable(flag) {
+ if (flag) {
+ // We cannot set this status directly in the `error`
+ // hook otherwise we get an infinite loop caused by apollo.
+ this.setAppStatus(EDITOR_APP_STATUS_LINT_UNAVAILABLE);
+ }
+ },
},
mounted() {
this.loadTemplateFromURL();
@@ -269,14 +287,10 @@ export default {
await this.$apollo.queries.initialCiFileContent.refetch();
},
reportFailure(type, reasons = []) {
- const isCurrentFailure = this.failureType === type && this.failureReasons[0] === reasons[0];
-
- if (!isCurrentFailure) {
- this.showFailure = true;
- this.failureType = type;
- this.failureReasons = reasons;
- window.scrollTo({ top: 0, behavior: 'smooth' });
- }
+ this.showFailure = true;
+ this.failureType = type;
+ this.failureReasons = reasons;
+ window.scrollTo({ top: 0, behavior: 'smooth' });
},
reportSuccess(type) {
window.scrollTo({ top: 0, behavior: 'smooth' });
@@ -289,7 +303,10 @@ export default {
},
setAppStatus(appStatus) {
if (EDITOR_APP_VALID_STATUSES.includes(appStatus)) {
- this.$apollo.mutate({ mutation: updateAppStatus, variables: { appStatus } });
+ this.$apollo.mutate({
+ mutation: updateAppStatus,
+ variables: { appStatus },
+ });
}
},
setNewEmptyCiConfigFile() {
diff --git a/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue b/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue
index 8e8f31a4acc..96680080f0c 100644
--- a/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue
+++ b/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue
@@ -90,7 +90,7 @@ export default {
</script>
<template>
- <div class="gl-pr-9 gl-transition-medium gl-w-full">
+ <div class="gl-pr-10 gl-transition-medium gl-w-full">
<gl-modal
v-if="showSwitchBranchModal"
visible
diff --git a/app/assets/javascripts/pipelines/components/header_component.vue b/app/assets/javascripts/pipelines/components/header_component.vue
index 4db6a3c9fd8..8088858f381 100644
--- a/app/assets/javascripts/pipelines/components/header_component.vue
+++ b/app/assets/javascripts/pipelines/components/header_component.vue
@@ -212,7 +212,9 @@ export default {
</script>
<template>
<div class="js-pipeline-header-container">
- <gl-alert v-if="hasError" :variant="failure.variant">{{ failure.text }}</gl-alert>
+ <gl-alert v-if="hasError" :variant="failure.variant" :dismissible="false">{{
+ failure.text
+ }}</gl-alert>
<ci-header
v-if="shouldRenderContent"
:status="pipeline.detailedStatus"
diff --git a/app/assets/javascripts/pipelines/components/jobs/jobs_app.vue b/app/assets/javascripts/pipelines/components/jobs/jobs_app.vue
index ffac8206b58..e11073aee33 100644
--- a/app/assets/javascripts/pipelines/components/jobs/jobs_app.vue
+++ b/app/assets/javascripts/pipelines/components/jobs/jobs_app.vue
@@ -112,7 +112,7 @@ export default {
</gl-skeleton-loader>
</div>
- <jobs-table v-else :jobs="jobs" :table-fields="$options.fields" />
+ <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" />
diff --git a/app/assets/javascripts/pipelines/components/parsing_utils.js b/app/assets/javascripts/pipelines/components/parsing_utils.js
index fa7330ce890..cae4e11c13f 100644
--- a/app/assets/javascripts/pipelines/components/parsing_utils.js
+++ b/app/assets/javascripts/pipelines/components/parsing_utils.js
@@ -1,5 +1,6 @@
import { memoize } from 'lodash';
import { createNodeDict } from '../utils';
+import { EXPLICIT_NEEDS_PROPERTY, NEEDS_PROPERTY } from '../constants';
import { createSankey } from './dag/drawing_utils';
/*
@@ -15,12 +16,14 @@ const deduplicate = (item, itemIndex, arr) => {
return foundIdx === itemIndex;
};
-export const makeLinksFromNodes = (nodes, nodeDict) => {
+export const makeLinksFromNodes = (nodes, nodeDict, { needsKey = NEEDS_PROPERTY } = {}) => {
const constantLinkValue = 10; // all links are the same weight
return nodes
.map(({ jobs, name: groupName }) =>
- jobs.map(({ needs = [] }) =>
- needs.reduce((acc, needed) => {
+ jobs.map((job) => {
+ const needs = job[needsKey] || [];
+
+ return needs.reduce((acc, needed) => {
// It's possible that we have an optional job, which
// is being needed by another job. In that scenario,
// the needed job doesn't exist, so we don't want to
@@ -34,8 +37,8 @@ export const makeLinksFromNodes = (nodes, nodeDict) => {
}
return acc;
- }, []),
- ),
+ }, []);
+ }),
)
.flat(2);
};
@@ -76,9 +79,9 @@ export const filterByAncestors = (links, nodeDict) =>
return !allAncestors.includes(source);
});
-export const parseData = (nodes) => {
- const nodeDict = createNodeDict(nodes);
- const allLinks = makeLinksFromNodes(nodes, nodeDict);
+export const parseData = (nodes, { needsKey = NEEDS_PROPERTY } = {}) => {
+ const nodeDict = createNodeDict(nodes, { needsKey });
+ const allLinks = makeLinksFromNodes(nodes, nodeDict, { needsKey });
const filteredLinks = allLinks.filter(deduplicate);
const links = filterByAncestors(filteredLinks, nodeDict);
@@ -123,7 +126,8 @@ export const removeOrphanNodes = (sankeyfiedNodes) => {
export const listByLayers = ({ stages }) => {
const arrayOfJobs = stages.flatMap(({ groups }) => groups);
const parsedData = parseData(arrayOfJobs);
- const dataWithLayers = createSankey()(parsedData);
+ const explicitParsedData = parseData(arrayOfJobs, { needsKey: EXPLICIT_NEEDS_PROPERTY });
+ const dataWithLayers = createSankey()(explicitParsedData);
const pipelineLayers = dataWithLayers.nodes.reduce((acc, { layer, name }) => {
/* sort groups by layer */
diff --git a/app/assets/javascripts/pipelines/components/pipeline_graph/pipeline_graph.vue b/app/assets/javascripts/pipelines/components/pipeline_graph/pipeline_graph.vue
index 64210576b29..8daf85e2b2e 100644
--- a/app/assets/javascripts/pipelines/components/pipeline_graph/pipeline_graph.vue
+++ b/app/assets/javascripts/pipelines/components/pipeline_graph/pipeline_graph.vue
@@ -132,6 +132,7 @@ export default {
:ref="$options.CONTAINER_REF"
class="gl-bg-gray-10 gl-overflow-auto"
data-testid="graph-container"
+ data-qa-selector="pipeline_graph_container"
>
<links-layer
:pipeline-data="pipelineStages"
@@ -147,7 +148,10 @@ export default {
:key="`${stage.name}-${index}`"
class="gl-flex-direction-column"
>
- <div class="gl-display-flex gl-align-items-center gl-w-full gl-px-9 gl-py-4 gl-mb-5">
+ <div
+ class="gl-display-flex gl-align-items-center gl-w-full gl-px-9 gl-py-4 gl-mb-5"
+ data-qa-selector="stage_container"
+ >
<stage-name :stage-name="stage.name" />
</div>
<div :class="$options.jobWrapperClasses">
@@ -158,6 +162,7 @@ export default {
:pipeline-id="$options.PIPELINE_ID"
:is-hovered="highlightedJob === group.name"
:is-faded-out="isFadedOut(group.name)"
+ data-qa-selector="job_container"
@on-mouse-enter="setHoveredJob"
@on-mouse-leave="removeHoveredJob"
/>
diff --git a/app/assets/javascripts/pipelines/components/unwrapping_utils.js b/app/assets/javascripts/pipelines/components/unwrapping_utils.js
index 2d24beb8323..d42a11c3aba 100644
--- a/app/assets/javascripts/pipelines/components/unwrapping_utils.js
+++ b/app/assets/javascripts/pipelines/components/unwrapping_utils.js
@@ -1,4 +1,5 @@
import { reportToSentry } from '../utils';
+import { EXPLICIT_NEEDS_PROPERTY, NEEDS_PROPERTY } from '../constants';
const unwrapGroups = (stages) => {
return stages.map((stage, idx) => {
@@ -27,12 +28,16 @@ const unwrapNodesWithName = (jobArray, prop, field = 'name') => {
}
return jobArray.map((job) => {
- return { ...job, [prop]: job[prop].nodes.map((item) => item[field] || '') };
+ if (job[prop]) {
+ return { ...job, [prop]: job[prop].nodes.map((item) => item[field] || '') };
+ }
+ return job;
});
};
const unwrapJobWithNeeds = (denodedJobArray) => {
- return unwrapNodesWithName(denodedJobArray, 'needs');
+ const explicitNeedsUnwrapped = unwrapNodesWithName(denodedJobArray, EXPLICIT_NEEDS_PROPERTY);
+ return unwrapNodesWithName(explicitNeedsUnwrapped, NEEDS_PROPERTY);
};
const unwrapStagesWithNeedsAndLookup = (denodedStages) => {
diff --git a/app/assets/javascripts/pipelines/constants.js b/app/assets/javascripts/pipelines/constants.js
index d123f7a203c..410fc7b82cd 100644
--- a/app/assets/javascripts/pipelines/constants.js
+++ b/app/assets/javascripts/pipelines/constants.js
@@ -7,6 +7,8 @@ export const ANY_TRIGGER_AUTHOR = 'Any';
export const SUPPORTED_FILTER_PARAMETERS = ['username', 'ref', 'status', 'source'];
export const FILTER_TAG_IDENTIFIER = 'tag';
export const SCHEDULE_ORIGIN = 'schedule';
+export const NEEDS_PROPERTY = 'needs';
+export const EXPLICIT_NEEDS_PROPERTY = 'previousStageJobsOrNeeds';
export const TestStatus = {
FAILED: 'failed',
diff --git a/app/assets/javascripts/pipelines/graphql/fragmentTypes.json b/app/assets/javascripts/pipelines/graphql/fragmentTypes.json
new file mode 100644
index 00000000000..4601b74b5c1
--- /dev/null
+++ b/app/assets/javascripts/pipelines/graphql/fragmentTypes.json
@@ -0,0 +1 @@
+{"__schema":{"types":[{"kind":"UNION","name":"JobNeedUnion","possibleTypes":[{"name":"CiBuildNeed"},{"name":"CiJob"}]}]}} \ No newline at end of file
diff --git a/app/assets/javascripts/pipelines/pipeline_shared_client.js b/app/assets/javascripts/pipelines/pipeline_shared_client.js
index c3be487caae..84276588d6a 100644
--- a/app/assets/javascripts/pipelines/pipeline_shared_client.js
+++ b/app/assets/javascripts/pipelines/pipeline_shared_client.js
@@ -1,10 +1,19 @@
import VueApollo from 'vue-apollo';
+import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import createDefaultClient from '~/lib/graphql';
+import introspectionQueryResultData from './graphql/fragmentTypes.json';
+
+export const fragmentMatcher = new IntrospectionFragmentMatcher({
+ introspectionQueryResultData,
+});
export const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
{},
{
+ cacheConfig: {
+ fragmentMatcher,
+ },
useGet: true,
},
),
diff --git a/app/assets/javascripts/pipelines/utils.js b/app/assets/javascripts/pipelines/utils.js
index e28eb74fb1b..f6e1c8b7412 100644
--- a/app/assets/javascripts/pipelines/utils.js
+++ b/app/assets/javascripts/pipelines/utils.js
@@ -1,6 +1,6 @@
import * as Sentry from '@sentry/browser';
import { pickBy } from 'lodash';
-import { SUPPORTED_FILTER_PARAMETERS } from './constants';
+import { SUPPORTED_FILTER_PARAMETERS, NEEDS_PROPERTY } from './constants';
/*
The following functions are the main engine in transforming the data as
@@ -35,11 +35,11 @@ import { SUPPORTED_FILTER_PARAMETERS } from './constants';
10 -> value (constant)
*/
-export const createNodeDict = (nodes) => {
+export const createNodeDict = (nodes, { needsKey = NEEDS_PROPERTY } = {}) => {
return nodes.reduce((acc, node) => {
const newNode = {
...node,
- needs: node.jobs.map((job) => job.needs || []).flat(),
+ needs: node.jobs.map((job) => job[needsKey] || []).flat(),
};
if (node.size > 1) {
diff --git a/app/assets/javascripts/profile/add_ssh_key_validation.js b/app/assets/javascripts/profile/add_ssh_key_validation.js
index 5c78de7ffb0..628dd159db8 100644
--- a/app/assets/javascripts/profile/add_ssh_key_validation.js
+++ b/app/assets/javascripts/profile/add_ssh_key_validation.js
@@ -1,8 +1,17 @@
export default class AddSshKeyValidation {
- constructor(inputElement, warningElement, originalSubmitElement, confirmSubmitElement) {
+ constructor(
+ supportedAlgorithms,
+ inputElement,
+ warningElement,
+ originalSubmitElement,
+ confirmSubmitElement,
+ ) {
this.inputElement = inputElement;
this.form = inputElement.form;
+ this.supportedAlgorithms = supportedAlgorithms;
+ this.publicKeyRegExp = new RegExp(`^(${this.supportedAlgorithms.join('|')})`);
+
this.warningElement = warningElement;
this.originalSubmitElement = originalSubmitElement;
@@ -23,7 +32,7 @@ export default class AddSshKeyValidation {
}
submit(event) {
- this.isValid = AddSshKeyValidation.isPublicKey(this.inputElement.value);
+ this.isValid = this.isPublicKey(this.inputElement.value);
if (this.isValid) return true;
@@ -37,7 +46,7 @@ export default class AddSshKeyValidation {
this.originalSubmitElement.classList.toggle('hide', isVisible);
}
- static isPublicKey(value) {
- return /^(ssh|ecdsa-sha2)-/.test(value);
+ isPublicKey(value) {
+ return this.publicKeyRegExp.test(value);
}
}
diff --git a/app/assets/javascripts/project_import.js b/app/assets/javascripts/project_import.js
deleted file mode 100644
index a51a2a2242f..00000000000
--- a/app/assets/javascripts/project_import.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import { visitUrl } from './lib/utils/url_utility';
-
-export default function projectImport() {
- setTimeout(() => {
- visitUrl(window.location.href);
- }, 5000);
-}
diff --git a/app/assets/javascripts/project_select_combo_button.js b/app/assets/javascripts/project_select_combo_button.js
index fd45d643ecc..09dbf2cee04 100644
--- a/app/assets/javascripts/project_select_combo_button.js
+++ b/app/assets/javascripts/project_select_combo_button.js
@@ -1,11 +1,12 @@
import $ from 'jquery';
+import { sprintf, __ } from '~/locale';
import AccessorUtilities from './lib/utils/accessor';
import { loadCSSFile } from './lib/utils/css_utils';
export default class ProjectSelectComboButton {
constructor(select) {
this.projectSelectInput = $(select);
- this.newItemBtn = $('.new-project-item-link');
+ this.newItemBtn = $('.js-new-project-item-link');
this.resourceType = this.newItemBtn.data('type');
this.resourceLabel = this.newItemBtn.data('label');
this.formattedText = this.deriveTextVariants();
@@ -80,9 +81,18 @@ export default class ProjectSelectComboButton {
setNewItemBtnAttributes(project) {
if (project) {
this.newItemBtn.attr('href', project.url);
- this.newItemBtn.text(`${this.formattedText.defaultTextPrefix} in ${project.name}`);
+ this.newItemBtn.text(
+ sprintf(__('New %{type} in %{project}'), {
+ type: this.resourceLabel,
+ project: project.name,
+ }),
+ );
} else {
- this.newItemBtn.text(`Select project to create ${this.formattedText.presetTextSuffix}`);
+ this.newItemBtn.text(
+ sprintf(__('Select project to create %{type}'), {
+ type: this.formattedText.presetTextSuffix,
+ }),
+ );
}
}
@@ -99,15 +109,12 @@ export default class ProjectSelectComboButton {
}
deriveTextVariants() {
- const defaultTextPrefix = this.resourceLabel;
-
// the trailing slice call depluralizes each of these strings (e.g. new-issues -> new-issue)
const localStorageItemType = `new-${this.resourceType.split('_').join('-').slice(0, -1)}`;
const presetTextSuffix = this.resourceType.split('_').join(' ').slice(0, -1);
return {
localStorageItemType, // new-issue / new-merge-request
- defaultTextPrefix, // New issue / New merge request
presetTextSuffix, // issue / merge request
};
}
diff --git a/app/assets/javascripts/project_visibility.js b/app/assets/javascripts/project_visibility.js
deleted file mode 100644
index 1b57a69d464..00000000000
--- a/app/assets/javascripts/project_visibility.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import $ from 'jquery';
-import eventHub from '~/projects/new/event_hub';
-
-// Values are from lib/gitlab/visibility_level.rb
-const visibilityLevel = {
- private: 0,
- internal: 10,
- public: 20,
-};
-
-function setVisibilityOptions({ name, visibility, showPath, editPath }) {
- document.querySelectorAll('.visibility-level-setting .form-check').forEach((option) => {
- // Don't change anything if the option is restricted by admin
- if (option.classList.contains('restricted')) {
- return;
- }
-
- const optionInput = option.querySelector('input[type=radio]');
- const optionValue = optionInput ? parseInt(optionInput.value, 10) : 0;
-
- if (visibilityLevel[visibility] < optionValue) {
- option.classList.add('disabled');
- optionInput.disabled = true;
- const reason = option.querySelector('.option-disabled-reason');
- if (reason) {
- const optionTitle = option.querySelector('.option-title');
- const optionName = optionTitle ? optionTitle.innerText.toLowerCase() : '';
- reason.innerHTML = `This project cannot be ${optionName} because the visibility of
- <a href="${showPath}">${name}</a> is ${visibility}. To make this project
- ${optionName}, you must first <a href="${editPath}">change the visibility</a>
- of the parent group.`;
- }
- } else {
- option.classList.remove('disabled');
- optionInput.disabled = false;
- }
- });
-}
-
-function handleSelect2DropdownChange(namespaceSelector) {
- if (!namespaceSelector || !('selectedIndex' in namespaceSelector)) {
- return;
- }
- const selectedNamespace = namespaceSelector.options[namespaceSelector.selectedIndex];
- setVisibilityOptions(selectedNamespace.dataset);
-}
-
-export default function initProjectVisibilitySelector() {
- eventHub.$on('update-visibility', setVisibilityOptions);
-
- const namespaceSelector = document.querySelector('select.js-select-namespace');
- if (namespaceSelector) {
- $('.select2.js-select-namespace').on('change', () =>
- handleSelect2DropdownChange(namespaceSelector),
- );
- handleSelect2DropdownChange(namespaceSelector);
- }
-}
diff --git a/app/assets/javascripts/project_find_file.js b/app/assets/javascripts/projects/project_find_file.js
index d295c06928f..d295c06928f 100644
--- a/app/assets/javascripts/project_find_file.js
+++ b/app/assets/javascripts/projects/project_find_file.js
diff --git a/app/assets/javascripts/projects/project_import.js b/app/assets/javascripts/projects/project_import.js
new file mode 100644
index 00000000000..27a218f1f52
--- /dev/null
+++ b/app/assets/javascripts/projects/project_import.js
@@ -0,0 +1,7 @@
+import { visitUrl } from '~/lib/utils/url_utility';
+
+export default function projectImport() {
+ setTimeout(() => {
+ visitUrl(window.location.href);
+ }, 5000);
+}
diff --git a/app/assets/javascripts/projects/project_visibility.js b/app/assets/javascripts/projects/project_visibility.js
new file mode 100644
index 00000000000..c962554c9f4
--- /dev/null
+++ b/app/assets/javascripts/projects/project_visibility.js
@@ -0,0 +1,71 @@
+import $ from 'jquery';
+import { escape } from 'lodash';
+import { __, sprintf } from '~/locale';
+import eventHub from '~/projects/new/event_hub';
+
+// Values are from lib/gitlab/visibility_level.rb
+const visibilityLevel = {
+ private: 0,
+ internal: 10,
+ public: 20,
+};
+
+function setVisibilityOptions({ name, visibility, showPath, editPath }) {
+ document.querySelectorAll('.visibility-level-setting .form-check').forEach((option) => {
+ // Don't change anything if the option is restricted by admin
+ if (option.classList.contains('restricted')) {
+ return;
+ }
+
+ const optionInput = option.querySelector('input[type=radio]');
+ const optionValue = optionInput ? parseInt(optionInput.value, 10) : 0;
+
+ if (visibilityLevel[visibility] < optionValue) {
+ option.classList.add('disabled');
+ optionInput.disabled = true;
+ const reason = option.querySelector('.option-disabled-reason');
+ if (reason) {
+ const optionTitle = option.querySelector('.option-title');
+ const optionName = optionTitle ? optionTitle.innerText.toLowerCase() : '';
+ reason.innerHTML = sprintf(
+ __(
+ '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.',
+ ),
+ {
+ visibilityLevel: optionName,
+ name: escape(name),
+ visibility,
+ openShowLink: `<a href="${showPath}">`,
+ closeShowLink: '</a>',
+ openEditLink: `<a href="${editPath}">`,
+ closeEditLink: '</a>',
+ },
+ false,
+ );
+ }
+ } else {
+ option.classList.remove('disabled');
+ optionInput.disabled = false;
+ }
+ });
+}
+
+function handleSelect2DropdownChange(namespaceSelector) {
+ if (!namespaceSelector || !('selectedIndex' in namespaceSelector)) {
+ return;
+ }
+ const selectedNamespace = namespaceSelector.options[namespaceSelector.selectedIndex];
+ setVisibilityOptions(selectedNamespace.dataset);
+}
+
+export default function initProjectVisibilitySelector() {
+ eventHub.$on('update-visibility', setVisibilityOptions);
+
+ const namespaceSelector = document.querySelector('select.js-select-namespace');
+ if (namespaceSelector) {
+ $('.select2.js-select-namespace').on('change', () =>
+ handleSelect2DropdownChange(namespaceSelector),
+ );
+ handleSelect2DropdownChange(namespaceSelector);
+ }
+}
diff --git a/app/assets/javascripts/projects/star.js b/app/assets/javascripts/projects/star.js
new file mode 100644
index 00000000000..578e22ca25d
--- /dev/null
+++ b/app/assets/javascripts/projects/star.js
@@ -0,0 +1,38 @@
+import $ from 'jquery';
+import createFlash from '~/flash';
+import axios from '~/lib/utils/axios_utils';
+import { spriteIcon } from '~/lib/utils/common_utils';
+import { __, s__ } from '~/locale';
+
+export default class Star {
+ constructor(container = '.project-home-panel') {
+ $(`${container} .toggle-star`).on('click', function toggleStarClickCallback() {
+ const $this = $(this);
+ const $starSpan = $this.find('span');
+ const $starIcon = $this.find('svg');
+ const iconClasses = $starIcon.attr('class').split(' ');
+
+ axios
+ .post($this.data('endpoint'))
+ .then(({ data }) => {
+ const isStarred = $starSpan.hasClass('starred');
+ $this.parent().find('.count').text(data.star_count);
+
+ if (isStarred) {
+ $starSpan.removeClass('starred').text(s__('StarProject|Star'));
+ $starIcon.remove();
+ $this.prepend(spriteIcon('star-o', iconClasses));
+ } else {
+ $starSpan.addClass('starred').text(__('Unstar'));
+ $starIcon.remove();
+ $this.prepend(spriteIcon('star', iconClasses));
+ }
+ })
+ .catch(() =>
+ createFlash({
+ message: __('Star toggle failed. Try again later.'),
+ }),
+ );
+ });
+ }
+}
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 58138655241..8b39851405e 100644
--- a/app/assets/javascripts/related_issues/components/related_issues_list.vue
+++ b/app/assets/javascripts/related_issues/components/related_issues_list.vue
@@ -110,7 +110,7 @@ export default {
v-for="issue in relatedIssues"
:key="issue.id"
:class="{
- 'user-can-drag': canReorder,
+ 'gl-cursor-grab': canReorder,
'sortable-row': canReorder,
'card card-slim': canReorder,
}"
diff --git a/app/assets/javascripts/repository/components/blob_button_group.vue b/app/assets/javascripts/repository/components/blob_button_group.vue
index 6f540bf8ece..857795c71b0 100644
--- a/app/assets/javascripts/repository/components/blob_button_group.vue
+++ b/app/assets/javascripts/repository/components/blob_button_group.vue
@@ -1,5 +1,5 @@
<script>
-import { GlButtonGroup, GlButton, GlModalDirective } from '@gitlab/ui';
+import { GlButtonGroup, GlButton } from '@gitlab/ui';
import { uniqueId } from 'lodash';
import { sprintf, __ } from '~/locale';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
@@ -20,9 +20,6 @@ export default {
DeleteBlobModal,
LockButton: () => import('ee_component/repository/components/lock_button.vue'),
},
- directives: {
- GlModal: GlModalDirective,
- },
mixins: [getRefMixin, glFeatureFlagMixin()],
inject: {
targetBranch: {
@@ -73,6 +70,10 @@ export default {
type: Boolean,
required: true,
},
+ showForkSuggestion: {
+ type: Boolean,
+ required: true,
+ },
},
computed: {
replaceModalId() {
@@ -91,6 +92,16 @@ export default {
return this.canLock ? 'lock_button' : 'disabled_lock_button';
},
},
+ methods: {
+ showModal(modalId) {
+ if (this.showForkSuggestion) {
+ this.$emit('fork');
+ return;
+ }
+
+ this.$refs[modalId].show();
+ },
+ },
};
</script>
@@ -107,14 +118,15 @@ export default {
data-testid="lock"
:data-qa-selector="lockBtnQASelector"
/>
- <gl-button v-gl-modal="replaceModalId" data-testid="replace">
+ <gl-button data-testid="replace" @click="showModal(replaceModalId)">
{{ $options.i18n.replace }}
</gl-button>
- <gl-button v-gl-modal="deleteModalId" data-testid="delete">
+ <gl-button data-testid="delete" @click="showModal(deleteModalId)">
{{ $options.i18n.delete }}
</gl-button>
</gl-button-group>
<upload-blob-modal
+ :ref="replaceModalId"
:modal-id="replaceModalId"
:modal-title="replaceModalTitle"
:commit-message="replaceModalTitle"
@@ -126,6 +138,7 @@ export default {
:primary-btn-text="$options.i18n.replacePrimaryBtnText"
/>
<delete-blob-modal
+ :ref="deleteModalId"
:modal-id="deleteModalId"
:modal-title="deleteModalTitle"
:delete-path="deletePath"
diff --git a/app/assets/javascripts/repository/components/blob_content_viewer.vue b/app/assets/javascripts/repository/components/blob_content_viewer.vue
index f3fa4526999..9368d7e6058 100644
--- a/app/assets/javascripts/repository/components/blob_content_viewer.vue
+++ b/app/assets/javascripts/repository/components/blob_content_viewer.vue
@@ -105,8 +105,10 @@ export default {
forkAndEditPath: '',
ideForkAndEditPath: '',
storedExternally: false,
+ externalStorage: '',
canModifyBlob: false,
canCurrentUserPushToBranch: false,
+ archived: false,
rawPath: '',
externalStorageUrl: '',
replacePath: '',
@@ -166,7 +168,7 @@ export default {
return pushCode && downloadCode;
},
pathLockedByUser() {
- const pathLock = this.project.pathLocks.nodes.find((node) => node.path === this.path);
+ const pathLock = this.project?.pathLocks?.nodes.find((node) => node.path === this.path);
return pathLock ? pathLock.user : null;
},
@@ -249,6 +251,7 @@ export default {
>
<template #actions>
<blob-edit
+ v-if="!blobInfo.archived"
:show-edit-button="!isBinaryFileType"
:edit-path="blobInfo.editBlobPath"
:web-ide-path="blobInfo.ideEditPath"
@@ -268,7 +271,7 @@ export default {
</gl-button>
<blob-button-group
- v-if="isLoggedIn"
+ v-if="isLoggedIn && !blobInfo.archived"
:path="path"
:name="blobInfo.name"
:replace-path="blobInfo.replacePath"
@@ -279,6 +282,8 @@ export default {
:project-path="projectPath"
:is-locked="Boolean(pathLockedByUser)"
:can-lock="canLock"
+ :show-fork-suggestion="showForkSuggestion"
+ @fork="setForkTarget('ide')"
/>
</template>
</blob-header>
@@ -289,6 +294,7 @@ export default {
/>
<blob-content
v-if="!blobViewer"
+ class="js-syntax-highlight"
:rich-viewer="legacyRichViewer"
:blob="blobInfo"
:content="legacySimpleViewer"
diff --git a/app/assets/javascripts/repository/components/blob_controls.vue b/app/assets/javascripts/repository/components/blob_controls.vue
new file mode 100644
index 00000000000..3223ed92fe2
--- /dev/null
+++ b/app/assets/javascripts/repository/components/blob_controls.vue
@@ -0,0 +1,119 @@
+<script>
+import { GlButton } from '@gitlab/ui';
+import { __ } from '~/locale';
+import createFlash from '~/flash';
+import getRefMixin from '~/repository/mixins/get_ref';
+import initSourcegraph from '~/sourcegraph';
+import { updateElementsVisibility } from '../utils/dom';
+import blobControlsQuery from '../queries/blob_controls.query.graphql';
+
+export default {
+ i18n: {
+ findFile: __('Find file'),
+ blame: __('Blame'),
+ history: __('History'),
+ permalink: __('Permalink'),
+ errorMessage: __('An error occurred while loading the blob controls.'),
+ },
+ buttonClassList: 'gl-sm-w-auto gl-w-full gl-sm-mt-0 gl-mt-3',
+ components: {
+ GlButton,
+ },
+ mixins: [getRefMixin],
+ apollo: {
+ project: {
+ query: blobControlsQuery,
+ variables() {
+ return {
+ projectPath: this.projectPath,
+ filePath: this.filePath,
+ ref: this.ref,
+ };
+ },
+ skip() {
+ return !this.filePath;
+ },
+ error() {
+ createFlash({ message: this.$options.i18n.errorMessage });
+ },
+ },
+ },
+ props: {
+ projectPath: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ project: {
+ repository: {
+ blobs: {
+ nodes: [
+ {
+ findFilePath: null,
+ blamePath: null,
+ historyPath: null,
+ permalinkPath: null,
+ storedExternally: null,
+ externalStorage: null,
+ },
+ ],
+ },
+ },
+ },
+ };
+ },
+ computed: {
+ filePath() {
+ return this.$route.params.path;
+ },
+ showBlobControls() {
+ return this.filePath && this.$route.name === 'blobPathDecoded';
+ },
+ blobInfo() {
+ return this.project?.repository?.blobs?.nodes[0] || {};
+ },
+ showBlameButton() {
+ return !this.blobInfo.storedExternally && this.blobInfo.externalStorage !== 'lfs';
+ },
+ },
+ watch: {
+ showBlobControls(shouldShow) {
+ updateElementsVisibility('.tree-controls', !shouldShow);
+ },
+ blobInfo() {
+ initSourcegraph();
+ },
+ },
+};
+</script>
+
+<template>
+ <div v-if="showBlobControls">
+ <gl-button data-testid="find" :href="blobInfo.findFilePath" :class="$options.buttonClassList">
+ {{ $options.i18n.findFile }}
+ </gl-button>
+ <gl-button
+ v-if="showBlameButton"
+ data-testid="blame"
+ :href="blobInfo.blamePath"
+ :class="$options.buttonClassList"
+ >
+ {{ $options.i18n.blame }}
+ </gl-button>
+
+ <gl-button data-testid="history" :href="blobInfo.historyPath" :class="$options.buttonClassList">
+ {{ $options.i18n.history }}
+ </gl-button>
+
+ <gl-button
+ data-testid="permalink"
+ :href="blobInfo.permalinkPath"
+ :class="$options.buttonClassList"
+ class="js-data-file-blob-permalink-url"
+ >
+ {{ $options.i18n.permalink }}
+ </gl-button>
+ </div>
+</template>
diff --git a/app/assets/javascripts/repository/components/blob_edit.vue b/app/assets/javascripts/repository/components/blob_edit.vue
index fd377ba1b81..69e2bd563c9 100644
--- a/app/assets/javascripts/repository/components/blob_edit.vue
+++ b/app/assets/javascripts/repository/components/blob_edit.vue
@@ -50,6 +50,7 @@ export default {
:web-ide-url="webIdePath"
:needs-to-fork="needsToFork"
:is-blob="true"
+ disable-fork-modal
@edit="onEdit"
/>
<div v-else>
diff --git a/app/assets/javascripts/repository/components/delete_blob_modal.vue b/app/assets/javascripts/repository/components/delete_blob_modal.vue
index 0d3dc06c2c8..f3c9aea36f1 100644
--- a/app/assets/javascripts/repository/components/delete_blob_modal.vue
+++ b/app/assets/javascripts/repository/components/delete_blob_modal.vue
@@ -146,6 +146,9 @@ export default {
/* eslint-enable dot-notation */
},
methods: {
+ show() {
+ this.$refs[this.modalId].show();
+ },
submitForm(e) {
e.preventDefault(); // Prevent modal from closing
this.form.showValidation = true;
@@ -164,6 +167,7 @@ export default {
<template>
<gl-modal
+ :ref="modalId"
v-bind="$attrs"
data-testid="modal-delete"
:modal-id="modalId"
diff --git a/app/assets/javascripts/repository/components/fork_suggestion.vue b/app/assets/javascripts/repository/components/fork_suggestion.vue
index c266bea319b..471f1dad2e3 100644
--- a/app/assets/javascripts/repository/components/fork_suggestion.vue
+++ b/app/assets/javascripts/repository/components/fork_suggestion.vue
@@ -32,6 +32,7 @@ export default {
class="gl-mr-3"
category="secondary"
variant="confirm"
+ data-method="post"
:href="forkPath"
data-testid="fork"
>
diff --git a/app/assets/javascripts/repository/components/preview/index.vue b/app/assets/javascripts/repository/components/preview/index.vue
index c6e461b10e0..dc5a031c9f3 100644
--- a/app/assets/javascripts/repository/components/preview/index.vue
+++ b/app/assets/javascripts/repository/components/preview/index.vue
@@ -47,6 +47,9 @@ export default {
}
},
},
+ safeHtmlConfig: {
+ ADD_TAGS: ['copy-code'],
+ },
};
</script>
@@ -62,7 +65,11 @@ export default {
</div>
<div class="blob-viewer" data-qa-selector="blob_viewer_content" itemprop="about">
<gl-loading-icon v-if="loading > 0" size="md" color="dark" class="my-4 mx-auto" />
- <div v-else-if="readme" ref="readme" v-safe-html="readme.html"></div>
+ <div
+ v-else-if="readme"
+ ref="readme"
+ v-safe-html:[$options.safeHtmlConfig]="readme.html"
+ ></div>
</div>
</article>
</template>
diff --git a/app/assets/javascripts/repository/components/upload_blob_modal.vue b/app/assets/javascripts/repository/components/upload_blob_modal.vue
index b56c9ce5247..7fcaf772aac 100644
--- a/app/assets/javascripts/repository/components/upload_blob_modal.vue
+++ b/app/assets/javascripts/repository/components/upload_blob_modal.vue
@@ -136,6 +136,9 @@ export default {
},
},
methods: {
+ show() {
+ this.$refs[this.modalId].show();
+ },
setFile(file) {
this.file = file;
@@ -206,6 +209,7 @@ export default {
<template>
<gl-form>
<gl-modal
+ :ref="modalId"
:modal-id="modalId"
:title="modalTitle"
:action-primary="primaryOptions"
diff --git a/app/assets/javascripts/repository/index.js b/app/assets/javascripts/repository/index.js
index 197b19387cf..120c32caefd 100644
--- a/app/assets/javascripts/repository/index.js
+++ b/app/assets/javascripts/repository/index.js
@@ -9,6 +9,7 @@ import App from './components/app.vue';
import Breadcrumbs from './components/breadcrumbs.vue';
import DirectoryDownloadLinks from './components/directory_download_links.vue';
import LastCommit from './components/last_commit.vue';
+import BlobControls from './components/blob_controls.vue';
import apolloProvider from './graphql';
import commitsQuery from './queries/commits.query.graphql';
import projectPathQuery from './queries/project_path.query.graphql';
@@ -71,8 +72,26 @@ export default function setupVueRepositoryList() {
},
});
+ const initBlobControlsApp = () =>
+ new Vue({
+ el: document.getElementById('js-blob-controls'),
+ router,
+ apolloProvider,
+ render(h) {
+ return h(BlobControls, {
+ props: {
+ projectPath,
+ },
+ });
+ },
+ });
+
initLastCommitApp();
+ if (gon.features.refactorBlobViewer) {
+ initBlobControlsApp();
+ }
+
router.afterEach(({ params: { path } }) => {
setTitle(path, ref, fullName);
});
@@ -144,7 +163,7 @@ export default function setupVueRepositoryList() {
}`,
// Ideally passing this class to `props` should work
// But it doesn't work here. :(
- class: 'btn btn-default btn-md gl-button ml-sm-0',
+ class: 'btn btn-default btn-md gl-button',
},
},
[__('History')],
diff --git a/app/assets/javascripts/repository/queries/blob_controls.query.graphql b/app/assets/javascripts/repository/queries/blob_controls.query.graphql
new file mode 100644
index 00000000000..fc1cf5f254b
--- /dev/null
+++ b/app/assets/javascripts/repository/queries/blob_controls.query.graphql
@@ -0,0 +1,18 @@
+query getBlobControls($projectPath: ID!, $filePath: String!, $ref: String!) {
+ project(fullPath: $projectPath) {
+ id
+ repository {
+ blobs(paths: [$filePath], ref: $ref) {
+ nodes {
+ id
+ findFilePath
+ blamePath
+ historyPath
+ permalinkPath
+ storedExternally
+ externalStorage
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/repository/queries/blob_info.query.graphql b/app/assets/javascripts/repository/queries/blob_info.query.graphql
index 45d1ba80917..ae20a0f0bc4 100644
--- a/app/assets/javascripts/repository/queries/blob_info.query.graphql
+++ b/app/assets/javascripts/repository/queries/blob_info.query.graphql
@@ -1,22 +1,14 @@
+#import "ee_else_ce/repository/queries/path_locks.fragment.graphql"
+
query getBlobInfo($projectPath: ID!, $filePath: String!, $ref: String!) {
project(fullPath: $projectPath) {
- id
userPermissions {
pushCode
downloadCode
createMergeRequestIn
forkProject
}
- pathLocks {
- nodes {
- id
- path
- user {
- id
- username
- }
- }
- }
+ ...ProjectPathLocksFragment
repository {
empty
blobs(paths: [$filePath], ref: $ref) {
@@ -35,7 +27,9 @@ query getBlobInfo($projectPath: ID!, $filePath: String!, $ref: String!) {
ideForkAndEditPath
canModifyBlob
canCurrentUserPushToBranch
+ archived
storedExternally
+ externalStorage
rawPath
replacePath
pipelineEditorPath
diff --git a/app/assets/javascripts/repository/queries/path_locks.fragment.graphql b/app/assets/javascripts/repository/queries/path_locks.fragment.graphql
new file mode 100644
index 00000000000..868a513362d
--- /dev/null
+++ b/app/assets/javascripts/repository/queries/path_locks.fragment.graphql
@@ -0,0 +1,3 @@
+fragment ProjectPathLocksFragment on Project {
+ id
+}
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
new file mode 100644
index 00000000000..4d2ca9b0c58
--- /dev/null
+++ b/app/assets/javascripts/runner/admin_runner_edit/admin_runner_edit_app.vue
@@ -0,0 +1,58 @@
+<script>
+import { createAlert } from '~/flash';
+import { TYPE_CI_RUNNER } from '~/graphql_shared/constants';
+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 { captureException } from '../sentry_utils';
+
+export default {
+ name: 'AdminRunnerEditApp',
+ components: {
+ RunnerHeader,
+ RunnerUpdateForm,
+ },
+ props: {
+ runnerId: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ runner: null,
+ };
+ },
+ apollo: {
+ runner: {
+ query: getRunnerQuery,
+ variables() {
+ return {
+ id: convertToGraphQLId(TYPE_CI_RUNNER, this.runnerId),
+ };
+ },
+ error(error) {
+ createAlert({ message: I18N_FETCH_ERROR });
+
+ this.reportToSentry(error);
+ },
+ },
+ },
+ errorCaptured(error) {
+ this.reportToSentry(error);
+ },
+ methods: {
+ reportToSentry(error) {
+ captureException({ error, component: this.$options.name });
+ },
+ },
+};
+</script>
+<template>
+ <div>
+ <runner-header v-if="runner" :runner="runner" />
+ <runner-update-form :runner="runner" class="gl-my-5" />
+ </div>
+</template>
diff --git a/app/assets/javascripts/runner/admin_runner_edit/index.js b/app/assets/javascripts/runner/admin_runner_edit/index.js
new file mode 100644
index 00000000000..adb420f9963
--- /dev/null
+++ b/app/assets/javascripts/runner/admin_runner_edit/index.js
@@ -0,0 +1,32 @@
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import createDefaultClient from '~/lib/graphql';
+import AdminRunnerEditApp from './admin_runner_edit_app.vue';
+
+Vue.use(VueApollo);
+
+export const initAdminRunnerEdit = (selector = '#js-admin-runner-edit') => {
+ const el = document.querySelector(selector);
+
+ if (!el) {
+ return null;
+ }
+
+ const { runnerId } = el.dataset;
+
+ const apolloProvider = new VueApollo({
+ defaultClient: createDefaultClient(),
+ });
+
+ return new Vue({
+ el,
+ apolloProvider,
+ render(h) {
+ return h(AdminRunnerEditApp, {
+ props: {
+ 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 f8220553db6..bb2bac531a7 100644
--- a/app/assets/javascripts/runner/admin_runners/admin_runners_app.vue
+++ b/app/assets/javascripts/runner/admin_runners/admin_runners_app.vue
@@ -1,14 +1,15 @@
<script>
import { GlBadge, GlLink } from '@gitlab/ui';
-import createFlash from '~/flash';
+import { createAlert } from '~/flash';
import { fetchPolicies } from '~/lib/graphql';
import { updateHistory } from '~/lib/utils/url_utility';
+import { formatNumber } from '~/locale';
import RegistrationDropdown from '../components/registration/registration_dropdown.vue';
import RunnerFilteredSearchBar from '../components/runner_filtered_search_bar.vue';
import RunnerList from '../components/runner_list.vue';
import RunnerName from '../components/runner_name.vue';
-import RunnerOnlineStat from '../components/stat/runner_online_stat.vue';
+import RunnerStats from '../components/stat/runner_stats.vue';
import RunnerPagination from '../components/runner_pagination.vue';
import RunnerTypeTabs from '../components/runner_type_tabs.vue';
@@ -19,9 +20,13 @@ import {
INSTANCE_TYPE,
GROUP_TYPE,
PROJECT_TYPE,
+ STATUS_ONLINE,
+ STATUS_OFFLINE,
+ 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 {
fromUrlQueryToSearch,
fromSearchToUrl,
@@ -29,6 +34,17 @@ import {
} from '../runner_search_utils';
import { captureException } from '../sentry_utils';
+const runnersCountSmartQuery = {
+ query: getRunnersCountQuery,
+ fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
+ update(data) {
+ return data?.runners?.count;
+ },
+ error(error) {
+ this.reportToSentry(error);
+ },
+};
+
export default {
name: 'AdminRunnersApp',
components: {
@@ -38,7 +54,7 @@ export default {
RunnerFilteredSearchBar,
RunnerList,
RunnerName,
- RunnerOnlineStat,
+ RunnerStats,
RunnerPagination,
RunnerTypeTabs,
},
@@ -47,26 +63,6 @@ export default {
type: String,
required: true,
},
- activeRunnersCount: {
- type: String,
- required: true,
- },
- allRunnersCount: {
- type: String,
- required: true,
- },
- instanceRunnersCount: {
- type: String,
- required: true,
- },
- groupRunnersCount: {
- type: String,
- required: true,
- },
- projectRunnersCount: {
- type: String,
- required: true,
- },
},
data() {
return {
@@ -95,16 +91,78 @@ export default {
};
},
error(error) {
- createFlash({ message: I18N_FETCH_ERROR });
+ createAlert({ message: I18N_FETCH_ERROR });
this.reportToSentry(error);
},
},
+ allRunnersCount: {
+ ...runnersCountSmartQuery,
+ variables() {
+ return this.countVariables;
+ },
+ },
+ instanceRunnersCount: {
+ ...runnersCountSmartQuery,
+ variables() {
+ return {
+ ...this.countVariables,
+ type: INSTANCE_TYPE,
+ };
+ },
+ },
+ groupRunnersCount: {
+ ...runnersCountSmartQuery,
+ variables() {
+ return {
+ ...this.countVariables,
+ type: GROUP_TYPE,
+ };
+ },
+ },
+ projectRunnersCount: {
+ ...runnersCountSmartQuery,
+ variables() {
+ return {
+ ...this.countVariables,
+ type: PROJECT_TYPE,
+ };
+ },
+ },
+ onlineRunnersTotal: {
+ ...runnersCountSmartQuery,
+ variables() {
+ return {
+ status: STATUS_ONLINE,
+ };
+ },
+ },
+ offlineRunnersTotal: {
+ ...runnersCountSmartQuery,
+ variables() {
+ return {
+ status: STATUS_OFFLINE,
+ };
+ },
+ },
+ staleRunnersTotal: {
+ ...runnersCountSmartQuery,
+ variables() {
+ return {
+ status: STATUS_STALE,
+ };
+ },
+ },
},
computed: {
variables() {
return fromSearchToVariables(this.search);
},
+ countVariables() {
+ // Exclude pagination variables, leave only filters variables
+ const { sort, before, last, after, first, ...countVariables } = this.variables;
+ return countVariables;
+ },
runnersLoading() {
return this.$apollo.queries.runners.loading;
},
@@ -125,7 +183,7 @@ export default {
search: {
deep: true,
handler() {
- // TODO Implement back button reponse using onpopstate
+ // TODO Implement back button response using onpopstate
updateHistory({
url: fromSearchToUrl(this.search),
title: document.title,
@@ -138,18 +196,27 @@ export default {
},
methods: {
tabCount({ runnerType }) {
+ let count;
switch (runnerType) {
case null:
- return this.allRunnersCount;
+ count = this.allRunnersCount;
+ break;
case INSTANCE_TYPE:
- return this.instanceRunnersCount;
+ count = this.instanceRunnersCount;
+ break;
case GROUP_TYPE:
- return this.groupRunnersCount;
+ count = this.groupRunnersCount;
+ break;
case PROJECT_TYPE:
- return this.projectRunnersCount;
+ count = this.projectRunnersCount;
+ break;
default:
return null;
}
+ if (typeof count === 'number') {
+ return formatNumber(count);
+ }
+ return '';
},
reportToSentry(error) {
captureException({ error, component: this.$options.name });
@@ -161,7 +228,11 @@ export default {
</script>
<template>
<div>
- <runner-online-stat class="gl-py-6 gl-px-5" :value="activeRunnersCount" />
+ <runner-stats
+ :online-runners-count="onlineRunnersTotal"
+ :offline-runners-count="offlineRunnersTotal"
+ :stale-runners-count="staleRunnersTotal"
+ />
<div
class="gl-display-flex gl-align-items-center gl-flex-direction-column-reverse gl-md-flex-direction-row gl-mt-3 gl-md-mt-0"
diff --git a/app/assets/javascripts/runner/admin_runners/index.js b/app/assets/javascripts/runner/admin_runners/index.js
index 62da6cbfa2b..3b8a8fe9cd1 100644
--- a/app/assets/javascripts/runner/admin_runners/index.js
+++ b/app/assets/javascripts/runner/admin_runners/index.js
@@ -2,6 +2,8 @@ import { GlToast } from '@gitlab/ui';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
+import { visitUrl } from '~/lib/utils/url_utility';
+import { updateOutdatedUrl } from '~/runner/runner_search_utils';
import AdminRunnersApp from './admin_runners_app.vue';
Vue.use(GlToast);
@@ -14,18 +16,16 @@ export const initAdminRunners = (selector = '#js-admin-runners') => {
return null;
}
- // TODO `activeRunnersCount` should be implemented using a GraphQL API
- // https://gitlab.com/gitlab-org/gitlab/-/issues/333806
- const {
- runnerInstallHelpPage,
- registrationToken,
+ // Redirect outdated URLs
+ const updatedUrlQuery = updateOutdatedUrl();
+ if (updatedUrlQuery) {
+ visitUrl(updatedUrlQuery);
- activeRunnersCount,
- allRunnersCount,
- instanceRunnersCount,
- groupRunnersCount,
- projectRunnersCount,
- } = el.dataset;
+ // Prevent mounting the rest of the app, redirecting now.
+ return null;
+ }
+
+ const { runnerInstallHelpPage, registrationToken } = el.dataset;
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
@@ -41,14 +41,6 @@ export const initAdminRunners = (selector = '#js-admin-runners') => {
return h(AdminRunnersApp, {
props: {
registrationToken,
-
- // All runner counts are returned as formatted
- // strings, we do not use `parseInt`.
- activeRunnersCount,
- allRunnersCount,
- instanceRunnersCount,
- groupRunnersCount,
- projectRunnersCount,
},
});
},
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 33f7a67aba4..0934508c87f 100644
--- a/app/assets/javascripts/runner/components/cells/runner_actions_cell.vue
+++ b/app/assets/javascripts/runner/components/cells/runner_actions_cell.vue
@@ -1,6 +1,6 @@
<script>
import { GlButton, GlButtonGroup, GlModalDirective, GlTooltipDirective } from '@gitlab/ui';
-import createFlash from '~/flash';
+import { createAlert } from '~/flash';
import { __, s__, sprintf } from '~/locale';
import runnerDeleteMutation from '~/runner/graphql/runner_delete.mutation.graphql';
import runnerActionsUpdateMutation from '~/runner/graphql/runner_actions_update.mutation.graphql';
@@ -69,6 +69,12 @@ export default {
runnerDeleteModalId() {
return `delete-runner-modal-${this.runnerId}`;
},
+ canUpdate() {
+ return this.runner.userPermissions?.updateRunner;
+ },
+ canDelete() {
+ return this.runner.userPermissions?.deleteRunner;
+ },
},
methods: {
async onToggleActive() {
@@ -133,7 +139,7 @@ export default {
onError(error) {
const { message } = error;
- createFlash({ message });
+ createAlert({ message });
this.reportToSentry(error);
},
@@ -156,14 +162,15 @@ export default {
See https://gitlab.com/gitlab-org/gitlab/-/issues/334802
-->
<gl-button
- v-if="runner.adminUrl"
+ v-if="canUpdate && runner.editAdminUrl"
v-gl-tooltip.hover.viewport="$options.I18N_EDIT"
- :href="runner.adminUrl"
+ :href="runner.editAdminUrl"
:aria-label="$options.I18N_EDIT"
icon="pencil"
data-testid="edit-runner"
/>
<gl-button
+ v-if="canUpdate"
v-gl-tooltip.hover.viewport="toggleActiveTitle"
:aria-label="toggleActiveTitle"
:icon="toggleActiveIcon"
@@ -172,6 +179,7 @@ export default {
@click="onToggleActive"
/>
<gl-button
+ v-if="canDelete"
v-gl-tooltip.hover.viewport="deleteTitle"
v-gl-modal="runnerDeleteModalId"
:aria-label="deleteTitle"
@@ -182,6 +190,7 @@ export default {
/>
<runner-delete-modal
+ v-if="canDelete"
:ref="runnerDeleteModalId"
:modal-id="runnerDeleteModalId"
:runner-name="runnerName"
diff --git a/app/assets/javascripts/runner/components/cells/runner_status_cell.vue b/app/assets/javascripts/runner/components/cells/runner_status_cell.vue
index 473cd7e9794..93f86ae2a2c 100644
--- a/app/assets/javascripts/runner/components/cells/runner_status_cell.vue
+++ b/app/assets/javascripts/runner/components/cells/runner_status_cell.vue
@@ -28,7 +28,15 @@ export default {
<template>
<div>
- <runner-status-badge :runner="runner" size="sm" />
- <runner-paused-badge v-if="paused" size="sm" />
+ <runner-status-badge
+ :runner="runner"
+ size="sm"
+ class="gl-display-inline-block gl-max-w-full gl-text-truncate"
+ />
+ <runner-paused-badge
+ v-if="paused"
+ size="sm"
+ class="gl-display-inline-block gl-max-w-full gl-text-truncate"
+ />
</div>
</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 3bb15bff8d8..0e259807f98 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
@@ -1,6 +1,6 @@
<script>
-import { GlDropdownItem, GlLoadingIcon } from '@gitlab/ui';
-import createFlash from '~/flash';
+import { GlDropdownItem, GlLoadingIcon, GlModal, GlModalDirective } from '@gitlab/ui';
+import { createAlert } from '~/flash';
import { TYPE_GROUP, TYPE_PROJECT } from '~/graphql_shared/constants';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { __, s__ } from '~/locale';
@@ -10,9 +10,17 @@ import { INSTANCE_TYPE, GROUP_TYPE, PROJECT_TYPE } from '../../constants';
export default {
name: 'RunnerRegistrationTokenReset',
+ i18n: {
+ modalTitle: __('Reset registration token'),
+ modalCopy: __('Are you sure you want to reset the registration token?'),
+ },
components: {
GlDropdownItem,
GlLoadingIcon,
+ GlModal,
+ },
+ directives: {
+ GlModal: GlModalDirective,
},
inject: {
groupId: {
@@ -22,6 +30,7 @@ export default {
default: null,
},
},
+ modalID: 'token-reset-modal',
props: {
type: {
type: String,
@@ -59,14 +68,10 @@ export default {
},
},
methods: {
+ handleModalPrimary() {
+ this.resetToken();
+ },
async resetToken() {
- // TODO Replace confirmation with gl-modal
- // See: https://gitlab.com/gitlab-org/gitlab/-/issues/333810
- // eslint-disable-next-line no-alert
- if (!window.confirm(__('Are you sure you want to reset the registration token?'))) {
- return;
- }
-
this.loading = true;
try {
const {
@@ -91,7 +96,7 @@ export default {
},
onError(error) {
const { message } = error;
- createFlash({ message });
+ createAlert({ message });
this.reportToSentry(error);
},
@@ -106,8 +111,15 @@ export default {
};
</script>
<template>
- <gl-dropdown-item @click.capture.native.stop="resetToken">
+ <gl-dropdown-item v-gl-modal="$options.modalID">
{{ __('Reset registration token') }}
+ <gl-modal
+ :modal-id="$options.modalID"
+ :title="$options.i18n.modalTitle"
+ @primary="handleModalPrimary"
+ >
+ <p>{{ $options.i18n.modalCopy }}</p>
+ </gl-modal>
<gl-loading-icon v-if="loading" inline />
</gl-dropdown-item>
</template>
diff --git a/app/assets/javascripts/runner/components/runner_header.vue b/app/assets/javascripts/runner/components/runner_header.vue
new file mode 100644
index 00000000000..09f58df7bd0
--- /dev/null
+++ b/app/assets/javascripts/runner/components/runner_header.vue
@@ -0,0 +1,52 @@
+<script>
+import { GlSprintf } from '@gitlab/ui';
+import { sprintf } from '~/locale';
+import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+import { I18N_DETAILS_TITLE } from '../constants';
+import RunnerTypeBadge from './runner_type_badge.vue';
+import RunnerStatusBadge from './runner_status_badge.vue';
+
+export default {
+ components: {
+ GlSprintf,
+ TimeAgo,
+ RunnerTypeBadge,
+ RunnerStatusBadge,
+ },
+ props: {
+ runner: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ paused() {
+ return !this.runner.active;
+ },
+ heading() {
+ const id = getIdFromGraphQLId(this.runner.id);
+ return sprintf(I18N_DETAILS_TITLE, { runner_id: id });
+ },
+ },
+};
+</script>
+<template>
+ <div class="gl-py-5 gl-border-b-1 gl-border-b-solid gl-border-b-gray-100">
+ <runner-status-badge :runner="runner" />
+ <runner-type-badge v-if="runner" :type="runner.runnerType" />
+ <template v-if="runner.createdAt">
+ <gl-sprintf :message="__('%{runner} created %{timeago}')">
+ <template #runner>
+ <strong>{{ heading }}</strong>
+ </template>
+ <template #timeago>
+ <time-ago :time="runner.createdAt" />
+ </template>
+ </gl-sprintf>
+ </template>
+ <template v-else>
+ <strong>{{ heading }}</strong>
+ </template>
+ </div>
+</template>
diff --git a/app/assets/javascripts/runner/components/runner_status_badge.vue b/app/assets/javascripts/runner/components/runner_status_badge.vue
index 0823876a187..6d0445ecb7a 100644
--- a/app/assets/javascripts/runner/components/runner_status_badge.vue
+++ b/app/assets/javascripts/runner/components/runner_status_badge.vue
@@ -4,11 +4,10 @@ import { __, s__, sprintf } from '~/locale';
import { getTimeago } from '~/lib/utils/datetime_utility';
import {
I18N_ONLINE_RUNNER_TIMEAGO_DESCRIPTION,
- I18N_NOT_CONNECTED_RUNNER_DESCRIPTION,
+ I18N_NEVER_CONTACTED_RUNNER_DESCRIPTION,
I18N_OFFLINE_RUNNER_TIMEAGO_DESCRIPTION,
I18N_STALE_RUNNER_DESCRIPTION,
STATUS_ONLINE,
- STATUS_NOT_CONNECTED,
STATUS_NEVER_CONTACTED,
STATUS_OFFLINE,
STATUS_STALE,
@@ -45,12 +44,11 @@ export default {
timeAgo: this.contactedAtTimeAgo,
}),
};
- case STATUS_NOT_CONNECTED:
case STATUS_NEVER_CONTACTED:
return {
variant: 'muted',
- label: s__('Runners|not connected'),
- tooltip: I18N_NOT_CONNECTED_RUNNER_DESCRIPTION,
+ label: s__('Runners|never contacted'),
+ tooltip: I18N_NEVER_CONTACTED_RUNNER_DESCRIPTION,
};
case STATUS_OFFLINE:
return {
diff --git a/app/assets/javascripts/runner/components/runner_type_alert.vue b/app/assets/javascripts/runner/components/runner_type_alert.vue
deleted file mode 100644
index 1400875a1d6..00000000000
--- a/app/assets/javascripts/runner/components/runner_type_alert.vue
+++ /dev/null
@@ -1,54 +0,0 @@
-<script>
-import { GlAlert, GlLink } from '@gitlab/ui';
-import { helpPagePath } from '~/helpers/help_page_helper';
-import { s__ } from '~/locale';
-import { INSTANCE_TYPE, GROUP_TYPE, PROJECT_TYPE } from '../constants';
-
-const ALERT_DATA = {
- [INSTANCE_TYPE]: {
- message: s__(
- 'Runners|This runner is available to all groups and projects in your GitLab instance.',
- ),
- anchor: 'shared-runners',
- },
- [GROUP_TYPE]: {
- message: s__('Runners|This runner is available to all projects and subgroups in a group.'),
- anchor: 'group-runners',
- },
- [PROJECT_TYPE]: {
- message: s__('Runners|This runner is associated with one or more projects.'),
- anchor: 'specific-runners',
- },
-};
-
-export default {
- components: {
- GlAlert,
- GlLink,
- },
- props: {
- type: {
- type: String,
- required: false,
- default: null,
- validator(type) {
- return Boolean(ALERT_DATA[type]);
- },
- },
- },
- computed: {
- alert() {
- return ALERT_DATA[this.type];
- },
- helpHref() {
- return helpPagePath('ci/runners/runners_scope', { anchor: this.alert.anchor });
- },
- },
-};
-</script>
-<template>
- <gl-alert v-if="alert" variant="info" :dismissible="false">
- {{ alert.message }}
- <gl-link :href="helpHref">{{ __('Learn more.') }}</gl-link>
- </gl-alert>
-</template>
diff --git a/app/assets/javascripts/runner/components/runner_update_form.vue b/app/assets/javascripts/runner/components/runner_update_form.vue
index 9a6fc07f6dd..e3deb94236e 100644
--- a/app/assets/javascripts/runner/components/runner_update_form.vue
+++ b/app/assets/javascripts/runner/components/runner_update_form.vue
@@ -10,8 +10,8 @@ import {
import {
modelToUpdateMutationVariables,
runnerToModel,
-} from 'ee_else_ce/runner/runner_details/runner_update_form_utils';
-import createFlash, { FLASH_TYPES } from '~/flash';
+} from 'ee_else_ce/runner/runner_update_form_utils';
+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';
@@ -75,14 +75,14 @@ export default {
if (errors?.length) {
// Validation errors need not be thrown
- createFlash({ message: errors[0] });
+ createAlert({ message: errors[0] });
return;
}
this.onSuccess();
} catch (error) {
const { message } = error;
- createFlash({ message });
+ createAlert({ message });
this.reportToSentry(error);
} finally {
@@ -90,7 +90,7 @@ export default {
}
},
onSuccess() {
- createFlash({ message: __('Changes saved.'), type: FLASH_TYPES.SUCCESS });
+ createAlert({ message: __('Changes saved.'), variant: VARIANT_SUCCESS });
this.model = runnerToModel(this.runner);
},
reportToSentry(error) {
diff --git a/app/assets/javascripts/runner/components/search_tokens/status_token_config.js b/app/assets/javascripts/runner/components/search_tokens/status_token_config.js
index 4b356fa47ed..79038eb8228 100644
--- a/app/assets/javascripts/runner/components/search_tokens/status_token_config.js
+++ b/app/assets/javascripts/runner/components/search_tokens/status_token_config.js
@@ -6,7 +6,7 @@ import {
STATUS_PAUSED,
STATUS_ONLINE,
STATUS_OFFLINE,
- STATUS_NOT_CONNECTED,
+ STATUS_NEVER_CONTACTED,
STATUS_STALE,
PARAM_KEY_STATUS,
} from '../../constants';
@@ -16,7 +16,7 @@ const options = [
{ value: STATUS_PAUSED, title: s__('Runners|Paused') },
{ value: STATUS_ONLINE, title: s__('Runners|Online') },
{ value: STATUS_OFFLINE, title: s__('Runners|Offline') },
- { value: STATUS_NOT_CONNECTED, title: s__('Runners|Not connected') },
+ { value: STATUS_NEVER_CONTACTED, title: s__('Runners|Never contacted') },
{ value: STATUS_STALE, title: s__('Runners|Stale') },
];
diff --git a/app/assets/javascripts/runner/components/search_tokens/tag_token.vue b/app/assets/javascripts/runner/components/search_tokens/tag_token.vue
index 7461308ab91..59230bb809e 100644
--- a/app/assets/javascripts/runner/components/search_tokens/tag_token.vue
+++ b/app/assets/javascripts/runner/components/search_tokens/tag_token.vue
@@ -1,6 +1,6 @@
<script>
import { GlFilteredSearchSuggestion, GlToken } from '@gitlab/ui';
-import createFlash from '~/flash';
+import { createAlert } from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { s__ } from '~/locale';
@@ -50,7 +50,7 @@ export default {
try {
this.tags = await this.getTagsOptions(searchTerm);
} catch {
- createFlash({
+ createAlert({
message: s__('Runners|Something went wrong while fetching the tags suggestions'),
});
} finally {
diff --git a/app/assets/javascripts/runner/components/stat/runner_online_stat.vue b/app/assets/javascripts/runner/components/stat/runner_online_stat.vue
deleted file mode 100644
index b92b9badef0..00000000000
--- a/app/assets/javascripts/runner/components/stat/runner_online_stat.vue
+++ /dev/null
@@ -1,17 +0,0 @@
-<script>
-import { GlSingleStat } from '@gitlab/ui/dist/charts';
-
-export default {
- components: {
- GlSingleStat,
- },
-};
-</script>
-<template>
- <gl-single-stat
- v-bind="$attrs"
- variant="success"
- :title="s__('Runners|Online Runners')"
- :meta-text="s__('Runners|online')"
- />
-</template>
diff --git a/app/assets/javascripts/runner/components/stat/runner_stats.vue b/app/assets/javascripts/runner/components/stat/runner_stats.vue
new file mode 100644
index 00000000000..d3693ee593e
--- /dev/null
+++ b/app/assets/javascripts/runner/components/stat/runner_stats.vue
@@ -0,0 +1,49 @@
+<script>
+import { STATUS_ONLINE, STATUS_OFFLINE, STATUS_STALE } from '../../constants';
+import RunnerStatusStat from './runner_status_stat.vue';
+
+export default {
+ components: {
+ RunnerStatusStat,
+ },
+ props: {
+ onlineRunnersCount: {
+ type: Number,
+ required: false,
+ default: null,
+ },
+ offlineRunnersCount: {
+ type: Number,
+ required: false,
+ default: null,
+ },
+ staleRunnersCount: {
+ type: Number,
+ required: false,
+ default: null,
+ },
+ },
+ STATUS_ONLINE,
+ STATUS_OFFLINE,
+ STATUS_STALE,
+};
+</script>
+<template>
+ <div class="gl-display-flex gl-py-6">
+ <runner-status-stat
+ class="gl-px-5"
+ :status="$options.STATUS_ONLINE"
+ :value="onlineRunnersCount"
+ />
+ <runner-status-stat
+ class="gl-px-5"
+ :status="$options.STATUS_OFFLINE"
+ :value="offlineRunnersCount"
+ />
+ <runner-status-stat
+ class="gl-px-5"
+ :status="$options.STATUS_STALE"
+ :value="staleRunnersCount"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/runner/components/stat/runner_status_stat.vue b/app/assets/javascripts/runner/components/stat/runner_status_stat.vue
new file mode 100644
index 00000000000..b77bbe15541
--- /dev/null
+++ b/app/assets/javascripts/runner/components/stat/runner_status_stat.vue
@@ -0,0 +1,65 @@
+<script>
+import { GlSingleStat } from '@gitlab/ui/dist/charts';
+import { s__, formatNumber } from '~/locale';
+import { STATUS_ONLINE, STATUS_OFFLINE, STATUS_STALE } from '../../constants';
+
+export default {
+ components: {
+ GlSingleStat,
+ },
+ props: {
+ value: {
+ type: Number,
+ required: false,
+ default: null,
+ },
+ status: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ formattedValue() {
+ if (typeof this.value === 'number') {
+ return formatNumber(this.value);
+ }
+ return '-';
+ },
+ stat() {
+ switch (this.status) {
+ case STATUS_ONLINE:
+ return {
+ variant: 'success',
+ title: s__('Runners|Online runners'),
+ metaText: s__('Runners|online'),
+ };
+ case STATUS_OFFLINE:
+ return {
+ variant: 'muted',
+ title: s__('Runners|Offline runners'),
+ metaText: s__('Runners|offline'),
+ };
+ case STATUS_STALE:
+ return {
+ variant: 'warning',
+ title: s__('Runners|Stale runners'),
+ metaText: s__('Runners|stale'),
+ };
+ default:
+ return {
+ title: s__('Runners|Runners'),
+ };
+ }
+ },
+ },
+};
+</script>
+<template>
+ <gl-single-stat
+ v-if="stat"
+ :value="formattedValue"
+ :variant="stat.variant"
+ :title="stat.title"
+ :meta-text="stat.metaText"
+ />
+</template>
diff --git a/app/assets/javascripts/runner/constants.js b/app/assets/javascripts/runner/constants.js
index 355f3054917..ce8019ffaa0 100644
--- a/app/assets/javascripts/runner/constants.js
+++ b/app/assets/javascripts/runner/constants.js
@@ -18,8 +18,8 @@ export const I18N_PROJECT_RUNNER_DESCRIPTION = s__('Runners|Associated with one
export const I18N_ONLINE_RUNNER_TIMEAGO_DESCRIPTION = s__(
'Runners|Runner is online; last contact was %{timeAgo}',
);
-export const I18N_NOT_CONNECTED_RUNNER_DESCRIPTION = s__(
- 'Runners|This runner has never connected to this instance',
+export const I18N_NEVER_CONTACTED_RUNNER_DESCRIPTION = s__(
+ 'Runners|This runner has never contacted this instance',
);
export const I18N_OFFLINE_RUNNER_TIMEAGO_DESCRIPTION = s__(
'Runners|No recent contact from this runner; last contact was %{timeAgo}',
@@ -60,7 +60,6 @@ export const STATUS_ACTIVE = 'ACTIVE';
export const STATUS_PAUSED = 'PAUSED';
export const STATUS_ONLINE = 'ONLINE';
-export const STATUS_NOT_CONNECTED = 'NOT_CONNECTED';
export const STATUS_NEVER_CONTACTED = 'NEVER_CONTACTED';
export const STATUS_OFFLINE = 'OFFLINE';
export const STATUS_STALE = 'STALE';
diff --git a/app/assets/javascripts/runner/graphql/get_group_runners.query.graphql b/app/assets/javascripts/runner/graphql/get_group_runners.query.graphql
index 6da9e276f74..f7bcd683718 100644
--- a/app/assets/javascripts/runner/graphql/get_group_runners.query.graphql
+++ b/app/assets/javascripts/runner/graphql/get_group_runners.query.graphql
@@ -13,7 +13,7 @@ query getGroupRunners(
$sort: CiRunnerSort
) {
group(fullPath: $groupFullPath) {
- id
+ id # Apollo required
runners(
membership: DESCENDANTS
before: $before
diff --git a/app/assets/javascripts/runner/graphql/get_group_runners_count.query.graphql b/app/assets/javascripts/runner/graphql/get_group_runners_count.query.graphql
new file mode 100644
index 00000000000..554eb09e372
--- /dev/null
+++ b/app/assets/javascripts/runner/graphql/get_group_runners_count.query.graphql
@@ -0,0 +1,20 @@
+query getGroupRunnersCount(
+ $groupFullPath: ID!
+ $status: CiRunnerStatus
+ $type: CiRunnerType
+ $tagList: [String!]
+ $search: String
+) {
+ group(fullPath: $groupFullPath) {
+ id # Apollo required
+ runners(
+ membership: DESCENDANTS
+ status: $status
+ type: $type
+ tagList: $tagList
+ search: $search
+ ) {
+ count
+ }
+ }
+}
diff --git a/app/assets/javascripts/runner/graphql/get_runners.query.graphql b/app/assets/javascripts/runner/graphql/get_runners.query.graphql
index 51a91b9eb96..05df399fa6a 100644
--- a/app/assets/javascripts/runner/graphql/get_runners.query.graphql
+++ b/app/assets/javascripts/runner/graphql/get_runners.query.graphql
@@ -26,6 +26,7 @@ query getRunners(
nodes {
...RunnerNode
adminUrl
+ editAdminUrl
}
pageInfo {
...PageInfo
diff --git a/app/assets/javascripts/runner/graphql/get_runners_count.query.graphql b/app/assets/javascripts/runner/graphql/get_runners_count.query.graphql
new file mode 100644
index 00000000000..181a4495cae
--- /dev/null
+++ b/app/assets/javascripts/runner/graphql/get_runners_count.query.graphql
@@ -0,0 +1,10 @@
+query getRunnersCount(
+ $status: CiRunnerStatus
+ $type: CiRunnerType
+ $tagList: [String!]
+ $search: String
+) {
+ runners(status: $status, type: $type, tagList: $tagList, search: $search) {
+ count
+ }
+}
diff --git a/app/assets/javascripts/runner/graphql/runner_details_shared.fragment.graphql b/app/assets/javascripts/runner/graphql/runner_details_shared.fragment.graphql
index 8c50cba7de3..8e968343b9b 100644
--- a/app/assets/javascripts/runner/graphql/runner_details_shared.fragment.graphql
+++ b/app/assets/javascripts/runner/graphql/runner_details_shared.fragment.graphql
@@ -9,4 +9,6 @@ fragment RunnerDetailsShared on CiRunner {
description
maximumTimeout
tagList
+ createdAt
+ status(legacyMode: null)
}
diff --git a/app/assets/javascripts/runner/graphql/runner_node.fragment.graphql b/app/assets/javascripts/runner/graphql/runner_node.fragment.graphql
index 169f6ffd2ea..4a771d779dc 100644
--- a/app/assets/javascripts/runner/graphql/runner_node.fragment.graphql
+++ b/app/assets/javascripts/runner/graphql/runner_node.fragment.graphql
@@ -12,4 +12,8 @@ fragment RunnerNode on CiRunner {
tagList
contactedAt
status(legacyMode: null)
+ userPermissions {
+ updateRunner
+ deleteRunner
+ }
}
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 a58a53a6a0d..3a7b58e3dc9 100644
--- a/app/assets/javascripts/runner/group_runners/group_runners_app.vue
+++ b/app/assets/javascripts/runner/group_runners/group_runners_app.vue
@@ -1,6 +1,6 @@
<script>
import { GlLink } from '@gitlab/ui';
-import createFlash from '~/flash';
+import { createAlert } from '~/flash';
import { fetchPolicies } from '~/lib/graphql';
import { updateHistory } from '~/lib/utils/url_utility';
import { formatNumber, sprintf, s__ } from '~/locale';
@@ -9,7 +9,7 @@ import RegistrationDropdown from '../components/registration/registration_dropdo
import RunnerFilteredSearchBar from '../components/runner_filtered_search_bar.vue';
import RunnerList from '../components/runner_list.vue';
import RunnerName from '../components/runner_name.vue';
-import RunnerOnlineStat from '../components/stat/runner_online_stat.vue';
+import RunnerStats from '../components/stat/runner_stats.vue';
import RunnerPagination from '../components/runner_pagination.vue';
import RunnerTypeTabs from '../components/runner_type_tabs.vue';
@@ -19,8 +19,12 @@ import {
GROUP_FILTERED_SEARCH_NAMESPACE,
GROUP_TYPE,
GROUP_RUNNER_COUNT_LIMIT,
+ STATUS_ONLINE,
+ STATUS_OFFLINE,
+ STATUS_STALE,
} from '../constants';
import getGroupRunnersQuery from '../graphql/get_group_runners.query.graphql';
+import getGroupRunnersCountQuery from '../graphql/get_group_runners_count.query.graphql';
import {
fromUrlQueryToSearch,
fromSearchToUrl,
@@ -28,6 +32,17 @@ import {
} from '../runner_search_utils';
import { captureException } from '../sentry_utils';
+const runnersCountSmartQuery = {
+ query: getGroupRunnersCountQuery,
+ fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
+ update(data) {
+ return data?.group?.runners?.count;
+ },
+ error(error) {
+ this.reportToSentry(error);
+ },
+};
+
export default {
name: 'GroupRunnersApp',
components: {
@@ -36,7 +51,7 @@ export default {
RunnerFilteredSearchBar,
RunnerList,
RunnerName,
- RunnerOnlineStat,
+ RunnerStats,
RunnerPagination,
RunnerTypeTabs,
},
@@ -84,11 +99,38 @@ export default {
};
},
error(error) {
- createFlash({ message: I18N_FETCH_ERROR });
+ createAlert({ message: I18N_FETCH_ERROR });
this.reportToSentry(error);
},
},
+ onlineRunnersTotal: {
+ ...runnersCountSmartQuery,
+ variables() {
+ return {
+ groupFullPath: this.groupFullPath,
+ status: STATUS_ONLINE,
+ };
+ },
+ },
+ offlineRunnersTotal: {
+ ...runnersCountSmartQuery,
+ variables() {
+ return {
+ groupFullPath: this.groupFullPath,
+ status: STATUS_OFFLINE,
+ };
+ },
+ },
+ staleRunnersTotal: {
+ ...runnersCountSmartQuery,
+ variables() {
+ return {
+ groupFullPath: this.groupFullPath,
+ status: STATUS_STALE,
+ };
+ },
+ },
},
computed: {
variables() {
@@ -147,7 +189,11 @@ export default {
<template>
<div>
- <runner-online-stat class="gl-py-6 gl-px-5" :value="groupRunnersCount" />
+ <runner-stats
+ :online-runners-count="onlineRunnersTotal"
+ :offline-runners-count="offlineRunnersTotal"
+ :stale-runners-count="staleRunnersTotal"
+ />
<div class="gl-display-flex gl-align-items-center">
<runner-type-tabs
diff --git a/app/assets/javascripts/runner/runner_details/index.js b/app/assets/javascripts/runner/runner_details/index.js
deleted file mode 100644
index db8f239a3c3..00000000000
--- a/app/assets/javascripts/runner/runner_details/index.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import Vue from 'vue';
-import VueApollo from 'vue-apollo';
-import createDefaultClient from '~/lib/graphql';
-import RunnerDetailsApp from './runner_details_app.vue';
-
-Vue.use(VueApollo);
-
-export const initRunnerDetail = (selector = '#js-runner-details') => {
- const el = document.querySelector(selector);
-
- if (!el) {
- return null;
- }
-
- const { runnerId } = el.dataset;
-
- const apolloProvider = new VueApollo({
- defaultClient: createDefaultClient(),
- });
-
- return new Vue({
- el,
- apolloProvider,
- render(h) {
- return h(RunnerDetailsApp, {
- props: {
- runnerId,
- },
- });
- },
- });
-};
diff --git a/app/assets/javascripts/runner/runner_details/runner_details_app.vue b/app/assets/javascripts/runner/runner_details/runner_details_app.vue
deleted file mode 100644
index 6557a7834e7..00000000000
--- a/app/assets/javascripts/runner/runner_details/runner_details_app.vue
+++ /dev/null
@@ -1,71 +0,0 @@
-<script>
-import createFlash from '~/flash';
-import { TYPE_CI_RUNNER } from '~/graphql_shared/constants';
-import { convertToGraphQLId } from '~/graphql_shared/utils';
-import { sprintf } from '~/locale';
-import RunnerTypeAlert from '../components/runner_type_alert.vue';
-import RunnerTypeBadge from '../components/runner_type_badge.vue';
-import RunnerUpdateForm from '../components/runner_update_form.vue';
-import { I18N_DETAILS_TITLE, I18N_FETCH_ERROR } from '../constants';
-import getRunnerQuery from '../graphql/get_runner.query.graphql';
-import { captureException } from '../sentry_utils';
-
-export default {
- name: 'RunnerDetailsApp',
- components: {
- RunnerTypeAlert,
- RunnerTypeBadge,
- RunnerUpdateForm,
- },
- props: {
- runnerId: {
- type: String,
- required: true,
- },
- },
- data() {
- return {
- runner: null,
- };
- },
- apollo: {
- runner: {
- query: getRunnerQuery,
- variables() {
- return {
- id: convertToGraphQLId(TYPE_CI_RUNNER, this.runnerId),
- };
- },
- error(error) {
- createFlash({ message: I18N_FETCH_ERROR });
-
- this.reportToSentry(error);
- },
- },
- },
- computed: {
- pageTitle() {
- return sprintf(I18N_DETAILS_TITLE, { runner_id: this.runnerId });
- },
- },
- errorCaptured(error) {
- this.reportToSentry(error);
- },
- methods: {
- reportToSentry(error) {
- captureException({ error, component: this.$options.name });
- },
- },
-};
-</script>
-<template>
- <div>
- <h2 class="page-title">
- {{ pageTitle }} <runner-type-badge v-if="runner" :type="runner.runnerType" />
- </h2>
-
- <runner-type-alert v-if="runner" :type="runner.runnerType" />
-
- <runner-update-form :runner="runner" class="gl-my-5" />
- </div>
-</template>
diff --git a/app/assets/javascripts/runner/runner_search_utils.js b/app/assets/javascripts/runner/runner_search_utils.js
index b88023720e8..c80a73948b8 100644
--- a/app/assets/javascripts/runner/runner_search_utils.js
+++ b/app/assets/javascripts/runner/runner_search_utils.js
@@ -16,6 +16,7 @@ import {
PARAM_KEY_BEFORE,
DEFAULT_SORT,
RUNNER_PAGE_SIZE,
+ STATUS_NEVER_CONTACTED,
} from './constants';
/**
@@ -79,6 +80,33 @@ const getPaginationFromParams = (params) => {
};
};
+// Outdated URL parameters
+const STATUS_NOT_CONNECTED = 'NOT_CONNECTED';
+
+/**
+ * Returns an updated URL for old (or deprecated) admin runner URLs.
+ *
+ * Use for redirecting users to currently used URLs.
+ *
+ * @param {String?} URL
+ * @returns Updated URL if outdated, `null` otherwise
+ */
+export const updateOutdatedUrl = (url = window.location.href) => {
+ const urlObj = new URL(url);
+ const query = urlObj.search;
+
+ const params = queryToObject(query, { gatherArrays: true });
+
+ const runnerType = params[PARAM_KEY_STATUS]?.[0] || null;
+ if (runnerType === STATUS_NOT_CONNECTED) {
+ const updatedParams = {
+ [PARAM_KEY_STATUS]: [STATUS_NEVER_CONTACTED],
+ };
+ return setUrlParams(updatedParams, url, false, true, true);
+ }
+ return null;
+};
+
/**
* Takes a URL query and transforms it into a "search" object
* @param {String?} query
diff --git a/app/assets/javascripts/runner/runner_details/runner_update_form_utils.js b/app/assets/javascripts/runner/runner_update_form_utils.js
index 3b519fa7d71..3b519fa7d71 100644
--- a/app/assets/javascripts/runner/runner_details/runner_update_form_utils.js
+++ b/app/assets/javascripts/runner/runner_update_form_utils.js
diff --git a/app/assets/javascripts/security_configuration/components/app.vue b/app/assets/javascripts/security_configuration/components/app.vue
index 75d2b324623..d228f77f27d 100644
--- a/app/assets/javascripts/security_configuration/components/app.vue
+++ b/app/assets/javascripts/security_configuration/components/app.vue
@@ -27,6 +27,9 @@ export const i18n = {
securityConfiguration: __('Security Configuration'),
vulnerabilityManagement: s__('SecurityConfiguration|Vulnerability Management'),
securityTraining: s__('SecurityConfiguration|Security training'),
+ securityTrainingDescription: s__(
+ 'SecurityConfiguration|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.',
+ ),
};
export default {
@@ -160,8 +163,12 @@ export default {
</template>
</user-callout-dismisser>
- <gl-tabs content-class="gl-pt-0">
- <gl-tab data-testid="security-testing-tab" :title="$options.i18n.securityTesting">
+ <gl-tabs content-class="gl-pt-0" sync-active-tab-with-query-params lazy>
+ <gl-tab
+ data-testid="security-testing-tab"
+ :title="$options.i18n.securityTesting"
+ query-param-value="security-testing"
+ >
<auto-dev-ops-enabled-alert
v-if="shouldShowAutoDevopsEnabledAlert"
class="gl-mt-3"
@@ -185,9 +192,12 @@ export default {
{{ $options.i18n.description }}
</p>
<p v-if="canViewCiHistory">
- <gl-link data-testid="security-view-history-link" :href="gitlabCiHistoryPath">{{
- $options.i18n.configurationHistory
- }}</gl-link>
+ <gl-link
+ data-testid="security-view-history-link"
+ data-qa-selector="security_configuration_history_link"
+ :href="gitlabCiHistoryPath"
+ >{{ $options.i18n.configurationHistory }}</gl-link
+ >
</p>
</template>
@@ -203,7 +213,11 @@ export default {
</template>
</section-layout>
</gl-tab>
- <gl-tab data-testid="compliance-testing-tab" :title="$options.i18n.compliance">
+ <gl-tab
+ data-testid="compliance-testing-tab"
+ :title="$options.i18n.compliance"
+ query-param-value="compliance-testing"
+ >
<section-layout :heading="$options.i18n.compliance">
<template #description>
<p>
@@ -241,8 +255,14 @@ export default {
v-if="glFeatures.secureVulnerabilityTraining"
data-testid="vulnerability-management-tab"
:title="$options.i18n.vulnerabilityManagement"
+ query-param-value="vulnerability-management"
>
<section-layout :heading="$options.i18n.securityTraining">
+ <template #description>
+ <p>
+ {{ $options.i18n.securityTrainingDescription }}
+ </p>
+ </template>
<template #features>
<training-provider-list />
</template>
diff --git a/app/assets/javascripts/security_configuration/components/auto_dev_ops_alert.vue b/app/assets/javascripts/security_configuration/components/auto_dev_ops_alert.vue
index ce6a1b4888b..315f676e659 100644
--- a/app/assets/javascripts/security_configuration/components/auto_dev_ops_alert.vue
+++ b/app/assets/javascripts/security_configuration/components/auto_dev_ops_alert.vue
@@ -28,6 +28,7 @@ export default {
variant="info"
:primary-button-link="autoDevopsPath"
:primary-button-text="$options.i18n.primaryButtonText"
+ data-qa-selector="autodevops_container"
@dismiss="dismissMethod"
>
<gl-sprintf :message="$options.i18n.body">
diff --git a/app/assets/javascripts/security_configuration/components/constants.js b/app/assets/javascripts/security_configuration/components/constants.js
index dd8ba72ad1f..034dba29196 100644
--- a/app/assets/javascripts/security_configuration/components/constants.js
+++ b/app/assets/javascripts/security_configuration/components/constants.js
@@ -254,7 +254,7 @@ export const securityFeatures = [
helpPath: COVERAGE_FUZZING_HELP_PATH,
configurationHelpPath: COVERAGE_FUZZING_CONFIG_HELP_PATH,
type: REPORT_TYPE_COVERAGE_FUZZING,
- secondary: gon?.features?.corpusManagement
+ secondary: gon?.features?.corpusManagementUi
? {
type: REPORT_TYPE_CORPUS_MANAGEMENT,
name: CORPUS_MANAGEMENT_NAME,
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 509377a63e8..ca4596e16b3 100644
--- a/app/assets/javascripts/security_configuration/components/training_provider_list.vue
+++ b/app/assets/javascripts/security_configuration/components/training_provider_list.vue
@@ -1,21 +1,39 @@
<script>
-import { GlCard, GlToggle, GlLink, GlSkeletonLoader } from '@gitlab/ui';
+import { GlAlert, GlCard, GlToggle, GlLink, GlSkeletonLoader } from '@gitlab/ui';
+import { __ } from '~/locale';
import securityTrainingProvidersQuery from '../graphql/security_training_providers.query.graphql';
+import configureSecurityTrainingProvidersMutation from '../graphql/configure_security_training_providers.mutation.graphql';
+
+const i18n = {
+ providerQueryErrorMessage: __(
+ 'Could not fetch training providers. Please refresh the page, or try again later.',
+ ),
+ configMutationErrorMessage: __(
+ 'Could not save configuration. Please refresh the page, or try again later.',
+ ),
+};
export default {
components: {
+ GlAlert,
GlCard,
GlToggle,
GlLink,
GlSkeletonLoader,
},
+ inject: ['projectPath'],
apollo: {
securityTrainingProviders: {
query: securityTrainingProvidersQuery,
+ error() {
+ this.errorMessage = this.$options.i18n.providerQueryErrorMessage;
+ },
},
},
data() {
return {
+ errorMessage: '',
+ toggleLoading: false,
securityTrainingProviders: [],
};
},
@@ -24,38 +42,92 @@ export default {
return this.$apollo.queries.securityTrainingProviders.loading;
},
},
+ methods: {
+ toggleProvider(selectedProviderId) {
+ const toggledProviders = this.securityTrainingProviders.map((provider) => ({
+ ...provider,
+ ...(provider.id === selectedProviderId && { isEnabled: !provider.isEnabled }),
+ }));
+
+ const enabledProviderIds = toggledProviders
+ .filter(({ isEnabled }) => isEnabled)
+ .map(({ id }) => id);
+
+ this.storeEnabledProviders(toggledProviders, enabledProviderIds);
+ },
+ async storeEnabledProviders(toggledProviders, enabledProviderIds) {
+ this.toggleLoading = true;
+
+ try {
+ const {
+ data: {
+ configureSecurityTrainingProviders: { errors = [] },
+ },
+ } = await this.$apollo.mutate({
+ mutation: configureSecurityTrainingProvidersMutation,
+ variables: {
+ input: {
+ enabledProviders: enabledProviderIds,
+ fullPath: this.projectPath,
+ },
+ },
+ });
+
+ if (errors.length > 0) {
+ // throwing an error here means we can handle scenarios within the `catch` block below
+ throw new Error();
+ }
+ } catch {
+ this.errorMessage = this.$options.i18n.configMutationErrorMessage;
+ } finally {
+ this.toggleLoading = false;
+ }
+ },
+ },
+ i18n,
};
</script>
<template>
- <div
- v-if="isLoading"
- class="gl-bg-white gl-py-6 gl-rounded-base gl-border-1 gl-border-solid gl-border-gray-100"
- >
- <gl-skeleton-loader :width="350" :height="44">
- <rect width="200" height="8" x="10" y="0" rx="4" />
- <rect width="300" height="8" x="10" y="15" rx="4" />
- <rect width="100" height="8" x="10" y="35" rx="4" />
- </gl-skeleton-loader>
- </div>
- <ul v-else class="gl-list-style-none gl-m-0 gl-p-0">
- <li
- v-for="{ id, isEnabled, name, description, url } in securityTrainingProviders"
- :key="id"
- class="gl-mb-6"
+ <div>
+ <gl-alert v-if="errorMessage" variant="danger" :dismissible="false" class="gl-mb-6">
+ {{ errorMessage }}
+ </gl-alert>
+ <div
+ v-if="isLoading"
+ class="gl-bg-white gl-py-6 gl-rounded-base gl-border-1 gl-border-solid gl-border-gray-100"
>
- <gl-card>
- <div class="gl-display-flex">
- <gl-toggle :value="isEnabled" :label="__('Training mode')" label-position="hidden" />
- <div class="gl-ml-5">
- <h3 class="gl-font-lg gl-m-0 gl-mb-2">{{ name }}</h3>
- <p>
- {{ description }}
- <gl-link :href="url" target="_blank">{{ __('Learn more.') }}</gl-link>
- </p>
+ <gl-skeleton-loader :width="350" :height="44">
+ <rect width="200" height="8" x="10" y="0" rx="4" />
+ <rect width="300" height="8" x="10" y="15" rx="4" />
+ <rect width="100" height="8" x="10" y="35" rx="4" />
+ </gl-skeleton-loader>
+ </div>
+ <ul v-else class="gl-list-style-none gl-m-0 gl-p-0">
+ <li
+ v-for="{ id, isEnabled, name, description, url } in securityTrainingProviders"
+ :key="id"
+ class="gl-mb-6"
+ >
+ <gl-card>
+ <div class="gl-display-flex">
+ <gl-toggle
+ :value="isEnabled"
+ :label="__('Training mode')"
+ label-position="hidden"
+ :is-loading="toggleLoading"
+ @change="toggleProvider(id)"
+ />
+ <div class="gl-ml-5">
+ <h3 class="gl-font-lg gl-m-0 gl-mb-2">{{ name }}</h3>
+ <p>
+ {{ description }}
+ <gl-link :href="url" target="_blank">{{ __('Learn more.') }}</gl-link>
+ </p>
+ </div>
</div>
- </div>
- </gl-card>
- </li>
- </ul>
+ </gl-card>
+ </li>
+ </ul>
+ </div>
</template>
diff --git a/app/assets/javascripts/security_configuration/graphql/configure_security_training_providers.mutation.graphql b/app/assets/javascripts/security_configuration/graphql/configure_security_training_providers.mutation.graphql
new file mode 100644
index 00000000000..660e0fadafb
--- /dev/null
+++ b/app/assets/javascripts/security_configuration/graphql/configure_security_training_providers.mutation.graphql
@@ -0,0 +1,9 @@
+mutation configureSecurityTrainingProviders($input: configureSecurityTrainingProvidersInput!) {
+ configureSecurityTrainingProviders(input: $input) @client {
+ errors
+ securityTrainingProviders {
+ id
+ isEnabled
+ }
+ }
+}
diff --git a/app/assets/javascripts/security_configuration/index.js b/app/assets/javascripts/security_configuration/index.js
index c86ff1a58f2..24c0585e077 100644
--- a/app/assets/javascripts/security_configuration/index.js
+++ b/app/assets/javascripts/security_configuration/index.js
@@ -2,38 +2,10 @@ import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import { parseBooleanDataAttributes } from '~/lib/utils/dom_utils';
-import { __ } from '~/locale';
import SecurityConfigurationApp from './components/app.vue';
import { securityFeatures, complianceFeatures } from './components/constants';
import { augmentFeatures } from './utils';
-
-// Note: this is behind a feature flag and only a placeholder
-// until the actual GraphQL fields have been added
-// https://gitlab.com/gitlab-org/gi tlab/-/issues/346480
-export const tempResolvers = {
- Query: {
- securityTrainingProviders() {
- return [
- {
- __typename: 'SecurityTrainingProvider',
- id: 101,
- name: __('Kontra'),
- description: __('Interactive developer security education.'),
- url: 'https://application.security/',
- isEnabled: false,
- },
- {
- __typename: 'SecurityTrainingProvider',
- id: 102,
- name: __('SecureCodeWarrior'),
- description: __('Security training with guide and learning pathways.'),
- url: 'https://www.securecodewarrior.com/',
- isEnabled: true,
- },
- ];
- },
- },
-};
+import tempResolvers from './resolver';
export const initSecurityConfiguration = (el) => {
if (!el) {
diff --git a/app/assets/javascripts/security_configuration/resolver.js b/app/assets/javascripts/security_configuration/resolver.js
new file mode 100644
index 00000000000..93175d4a3d1
--- /dev/null
+++ b/app/assets/javascripts/security_configuration/resolver.js
@@ -0,0 +1,56 @@
+import produce from 'immer';
+import { __ } from '~/locale';
+import securityTrainingProvidersQuery from './graphql/security_training_providers.query.graphql';
+
+// Note: this is behind a feature flag and only a placeholder
+// until the actual GraphQL fields have been added
+// https://gitlab.com/gitlab-org/gi tlab/-/issues/346480
+export default {
+ Query: {
+ securityTrainingProviders() {
+ return [
+ {
+ __typename: 'SecurityTrainingProvider',
+ id: 101,
+ name: __('Kontra'),
+ description: __('Interactive developer security education.'),
+ url: 'https://application.security/',
+ isEnabled: false,
+ },
+ {
+ __typename: 'SecurityTrainingProvider',
+ id: 102,
+ name: __('SecureCodeWarrior'),
+ description: __('Security training with guide and learning pathways.'),
+ url: 'https://www.securecodewarrior.com/',
+ isEnabled: true,
+ },
+ ];
+ },
+ },
+
+ Mutation: {
+ configureSecurityTrainingProviders: (
+ _,
+ { input: { enabledProviders, primaryProvider } },
+ { cache },
+ ) => {
+ const sourceData = cache.readQuery({
+ query: securityTrainingProvidersQuery,
+ });
+
+ const data = produce(sourceData.securityTrainingProviders, (draftData) => {
+ /* eslint-disable no-param-reassign */
+ draftData.forEach((provider) => {
+ provider.isPrimary = provider.id === primaryProvider;
+ provider.isEnabled =
+ provider.id === primaryProvider || enabledProviders.includes(provider.id);
+ });
+ });
+ return {
+ __typename: 'configureSecurityTrainingProvidersPayload',
+ securityTrainingProviders: data,
+ };
+ },
+ },
+};
diff --git a/app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue b/app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue
index e41f3aa5c9d..a746642c191 100644
--- a/app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue
+++ b/app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue
@@ -267,6 +267,8 @@ export default {
v-if="glFeatures.improvedEmojiPicker"
dropdown-class="gl-h-full"
toggle-class="btn emoji-menu-toggle-button gl-px-4! gl-rounded-top-right-none! gl-rounded-bottom-right-none!"
+ boundary="viewport"
+ :right="false"
@click="setEmoji"
>
<template #button-content>
diff --git a/app/assets/javascripts/sidebar/components/crm_contacts/crm_contacts.vue b/app/assets/javascripts/sidebar/components/crm_contacts/crm_contacts.vue
index 6d4da104952..950647f1cb2 100644
--- a/app/assets/javascripts/sidebar/components/crm_contacts/crm_contacts.vue
+++ b/app/assets/javascripts/sidebar/components/crm_contacts/crm_contacts.vue
@@ -1,5 +1,5 @@
<script>
-import { GlIcon, GlPopover, GlTooltipDirective } from '@gitlab/ui';
+import { GlIcon, GlLink, GlPopover, GlTooltipDirective } from '@gitlab/ui';
import { __, n__, sprintf } from '~/locale';
import createFlash from '~/flash';
import { convertToGraphQLId } from '~/graphql_shared/utils';
@@ -10,6 +10,7 @@ import issueCrmContactsSubscription from './queries/issue_crm_contacts.subscript
export default {
components: {
GlIcon,
+ GlLink,
GlPopover,
},
directives: {
@@ -85,9 +86,6 @@ export default {
);
},
},
- i18n: {
- help: __('Work in progress- click here to find out more'),
- },
};
</script>
@@ -97,11 +95,10 @@ export default {
<gl-icon name="users" />
<span> {{ contactCount }} </span>
</div>
- <div
- v-gl-tooltip.left.viewport="$options.i18n.help"
- class="hide-collapsed help-button float-right"
- >
- <a href="https://gitlab.com/gitlab-org/gitlab/-/issues/2256"><gl-icon name="question-o" /></a>
+ <div class="hide-collapsed help-button gl-float-right">
+ <gl-link href="https://docs.gitlab.com/ee/user/crm/" target="_blank"
+ ><gl-icon name="question-o"
+ /></gl-link>
</div>
<div class="title hide-collapsed gl-mb-2 gl-line-height-20">
{{ contactsLabel }}
diff --git a/app/assets/javascripts/sidebar/mount_sidebar.js b/app/assets/javascripts/sidebar/mount_sidebar.js
index cbe40d0bfbe..6363422259e 100644
--- a/app/assets/javascripts/sidebar/mount_sidebar.js
+++ b/app/assets/javascripts/sidebar/mount_sidebar.js
@@ -26,6 +26,7 @@ import trackShowInviteMemberLink from '~/sidebar/track_invite_members';
import { DropdownVariant } from '~/vue_shared/components/sidebar/labels_select_vue/constants';
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 Translate from '../vue_shared/translate';
import SidebarAssignees from './components/assignees/sidebar_assignees.vue';
import CopyEmailToClipboard from './components/copy_email_to_clipboard.vue';
@@ -600,6 +601,12 @@ export function mountSidebar(mediator, store) {
mountTimeTrackingComponent();
mountSeverityComponent();
+
+ if (window.gon?.features?.mrAttentionRequests) {
+ eventHub.$on('removeCurrentUserAttentionRequested', () =>
+ mediator.removeCurrentUserAttentionRequested(),
+ );
+ }
}
export { getSidebarOptions };
diff --git a/app/assets/javascripts/sidebar/sidebar_mediator.js b/app/assets/javascripts/sidebar/sidebar_mediator.js
index a49ddac8c89..25468d4a697 100644
--- a/app/assets/javascripts/sidebar/sidebar_mediator.js
+++ b/app/assets/javascripts/sidebar/sidebar_mediator.js
@@ -30,7 +30,7 @@ export default class SidebarMediator {
this.store.addAssignee(this.store.currentUser);
}
- saveAssignees(field) {
+ async saveAssignees(field) {
const selected = this.store.assignees.map((u) => u.id);
// If there are no ids, that means we have to unassign (which is id = 0)
@@ -38,10 +38,22 @@ export default class SidebarMediator {
const assignees = selected.length === 0 ? [0] : selected;
const data = { assignee_ids: assignees };
- return this.service.update(field, data);
+ try {
+ const res = await this.service.update(field, data);
+
+ this.store.overwrite('assignees', res.data.assignees);
+
+ if (res.data.reviewers) {
+ this.store.overwrite('reviewers', res.data.reviewers);
+ }
+
+ return Promise.resolve(res);
+ } catch (e) {
+ return Promise.reject(e);
+ }
}
- saveReviewers(field) {
+ async saveReviewers(field) {
const selected = this.store.reviewers.map((u) => u.id);
// If there are no ids, that means we have to unassign (which is id = 0)
@@ -49,7 +61,16 @@ export default class SidebarMediator {
const reviewers = selected.length === 0 ? [0] : selected;
const data = { reviewer_ids: reviewers };
- return this.service.update(field, data);
+ try {
+ const res = await this.service.update(field, data);
+
+ this.store.overwrite('reviewers', res.data.reviewers);
+ this.store.overwrite('assignees', res.data.assignees);
+
+ return Promise.resolve(res);
+ } catch (e) {
+ return Promise.reject();
+ }
}
requestReview({ userId, callback }) {
@@ -63,6 +84,19 @@ export default class SidebarMediator {
.catch(() => callback(userId, false));
}
+ removeCurrentUserAttentionRequested() {
+ const currentUserId = gon.current_user_id;
+
+ const currentUserReviewer = this.store.findReviewer({ id: currentUserId });
+ const currentUserAssignee = this.store.findAssignee({ id: currentUserId });
+
+ if (currentUserReviewer?.attention_requested || currentUserAssignee?.attention_requested) {
+ // Update current users attention_requested state
+ this.store.updateReviewer(currentUserId, 'attention_requested');
+ this.store.updateAssignee(currentUserId, 'attention_requested');
+ }
+ }
+
async toggleAttentionRequested(type, { user, callback }) {
try {
const isReviewer = type === 'reviewer';
@@ -82,15 +116,7 @@ export default class SidebarMediator {
const currentUserId = gon.current_user_id;
if (currentUserId !== user.id) {
- const currentUserReviewerOrAssignee = isReviewer
- ? this.store.findReviewer({ id: currentUserId })
- : this.store.findAssignee({ id: currentUserId });
-
- if (currentUserReviewerOrAssignee?.attention_requested) {
- // Update current users attention_requested state
- this.store.updateReviewer(currentUserId, 'attention_requested');
- this.store.updateAssignee(currentUserId, 'attention_requested');
- }
+ this.removeCurrentUserAttentionRequested();
}
toast(sprintf(__('Requested attention from @%{username}'), { username: user.username }));
diff --git a/app/assets/javascripts/sidebar/stores/sidebar_store.js b/app/assets/javascripts/sidebar/stores/sidebar_store.js
index 5376791469e..2caa6f4f0a0 100644
--- a/app/assets/javascripts/sidebar/stores/sidebar_store.js
+++ b/app/assets/javascripts/sidebar/stores/sidebar_store.js
@@ -98,6 +98,10 @@ export default class SidebarStore {
}
}
+ overwrite(key, newData) {
+ this[key] = newData;
+ }
+
findAssignee(findAssignee) {
return this.assignees.find(({ id }) => id === findAssignee.id);
}
diff --git a/app/assets/javascripts/star.js b/app/assets/javascripts/star.js
deleted file mode 100644
index 7cba445d9b1..00000000000
--- a/app/assets/javascripts/star.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import $ from 'jquery';
-import createFlash from './flash';
-import axios from './lib/utils/axios_utils';
-import { spriteIcon } from './lib/utils/common_utils';
-import { __, s__ } from './locale';
-
-export default class Star {
- constructor(container = '.project-home-panel') {
- $(`${container} .toggle-star`).on('click', function toggleStarClickCallback() {
- const $this = $(this);
- const $starSpan = $this.find('span');
- const $starIcon = $this.find('svg');
- const iconClasses = $starIcon.attr('class').split(' ');
-
- axios
- .post($this.data('endpoint'))
- .then(({ data }) => {
- const isStarred = $starSpan.hasClass('starred');
- $this.parent().find('.count').text(data.star_count);
-
- if (isStarred) {
- $starSpan.removeClass('starred').text(s__('StarProject|Star'));
- $starIcon.remove();
- $this.prepend(spriteIcon('star-o', iconClasses));
- } else {
- $starSpan.addClass('starred').text(__('Unstar'));
- $starIcon.remove();
- $this.prepend(spriteIcon('star', iconClasses));
- }
- })
- .catch(() =>
- createFlash({
- message: __('Star toggle failed. Try again later.'),
- }),
- );
- });
- }
-}
diff --git a/app/assets/javascripts/tracking/index.js b/app/assets/javascripts/tracking/index.js
index 7e99ecb4f4e..d60eb37a9a2 100644
--- a/app/assets/javascripts/tracking/index.js
+++ b/app/assets/javascripts/tracking/index.js
@@ -46,7 +46,10 @@ export function initDefaultTrackers() {
// must be after enableActivityTracking
const standardContext = getStandardContext();
const experimentContexts = getAllExperimentContexts();
- window.snowplow('trackPageView', null, [standardContext, ...experimentContexts]);
+ // To not expose personal identifying information, the page title is hardcoded as `GitLab`
+ // See: https://gitlab.com/gitlab-org/gitlab/-/issues/345243
+ window.snowplow('trackPageView', 'GitLab', [standardContext, ...experimentContexts]);
+ window.snowplow('setDocumentTitle', 'GitLab');
if (window.snowplowOptions.formTracking) {
Tracking.enableFormTracking(opts.formTrackingConfig);
diff --git a/app/assets/javascripts/tree.js b/app/assets/javascripts/tree.js
deleted file mode 100644
index 58bff370fa5..00000000000
--- a/app/assets/javascripts/tree.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/* eslint-disable func-names, consistent-return, one-var, class-methods-use-this */
-
-import $ from 'jquery';
-import { visitUrl } from './lib/utils/url_utility';
-
-export default class TreeView {
- constructor() {
- this.initKeyNav();
- // Code browser tree slider
- // Make the entire tree-item row clickable, but not if clicking another link (like a commit message)
- $('.tree-content-holder .tree-item').on('click', function (e) {
- const $clickedEl = $(e.target);
- const path = $('.tree-item-file-name a', this).attr('href');
- if (!$clickedEl.is('a') && !$clickedEl.is('.str-truncated')) {
- if (e.metaKey || e.which === 2) {
- e.preventDefault();
- return window.open(path, '_blank');
- }
- return visitUrl(path);
- }
- });
- // Show the "Loading commit data" for only the first element
- $('span.log_loading').first().removeClass('hide');
- }
-
- initKeyNav() {
- const li = $('tr.tree-item');
- let liSelected = null;
- return $('body').keydown((e) => {
- let next, path;
- if ($('input:focus').length > 0 && (e.which === 38 || e.which === 40)) {
- return false;
- }
- if (e.which === 40) {
- if (liSelected) {
- next = liSelected.next();
- if (next.length > 0) {
- liSelected.removeClass('selected');
- liSelected = next.addClass('selected');
- }
- } else {
- liSelected = li.eq(0).addClass('selected');
- }
- return $(liSelected).focus();
- } else if (e.which === 38) {
- if (liSelected) {
- next = liSelected.prev();
- if (next.length > 0) {
- liSelected.removeClass('selected');
- liSelected = next.addClass('selected');
- }
- } else {
- liSelected = li.last().addClass('selected');
- }
- return $(liSelected).focus();
- } else if (e.which === 13) {
- path = $('.tree-item.selected .tree-item-file-name a').attr('href');
- if (path) {
- return visitUrl(path);
- }
- }
- });
- }
-}
diff --git a/app/assets/javascripts/version_check_image.js b/app/assets/javascripts/version_check_image.js
deleted file mode 100644
index 4e00e0f11f7..00000000000
--- a/app/assets/javascripts/version_check_image.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default class VersionCheckImage {
- static bindErrorEvent(imageElement) {
- // eslint-disable-next-line @gitlab/no-global-event-off
- imageElement.off('error').on('error', () => imageElement.hide());
- }
-}
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue b/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue
index 386ba2e2d77..24cefd63ce3 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue
@@ -3,6 +3,7 @@ import { GlButton } from '@gitlab/ui';
import createFlash from '~/flash';
import { BV_SHOW_MODAL } from '~/lib/utils/constants';
import { s__ } from '~/locale';
+import sidebarEventHub from '~/sidebar/event_hub';
import eventHub from '../../event_hub';
import approvalsMixin from '../../mixins/approvals';
import MrWidgetContainer from '../mr_widget_container.vue';
@@ -172,6 +173,7 @@ export default {
this.mr.setApprovals(data);
eventHub.$emit('MRWidgetUpdateRequested');
eventHub.$emit('ApprovalUpdated');
+ sidebarEventHub.$emit('removeCurrentUserAttentionRequested');
this.$emit('updated');
})
.catch(errFn)
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/actions.vue b/app/assets/javascripts/vue_merge_request_widget/components/extensions/actions.vue
index 33a83aef057..d878a1fa2e0 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/actions.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/actions.vue
@@ -70,6 +70,7 @@ export default {
variant="confirm"
size="small"
class="gl-display-none gl-md-display-block gl-float-left"
+ data-testid="extension-actions-button"
@click="onClickAction(btn)"
>
{{ btn.text }}
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 549cf64fb08..7322958e6df 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
@@ -13,6 +13,7 @@ import * as Sentry from '@sentry/browser';
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';
@@ -132,19 +133,50 @@ export default {
this.triggerRedisTracking();
},
+ initExtensionPolling() {
+ const poll = new Poll({
+ resource: {
+ fetchData: () => this.fetchCollapsedData(this.$props),
+ },
+ method: 'fetchData',
+ successCallback: (data) => {
+ if (Object.keys(data).length > 0) {
+ poll.stop();
+ this.setCollapsedData(data);
+ }
+ },
+ errorCallback: (e) => {
+ poll.stop();
+
+ this.setCollapsedError(e);
+ },
+ });
+
+ poll.makeRequest();
+ },
loadCollapsedData() {
this.loadingState = LOADING_STATES.collapsedLoading;
- this.fetchCollapsedData(this.$props)
- .then((data) => {
- this.collapsedData = data;
- this.loadingState = null;
- })
- .catch((e) => {
- this.loadingState = LOADING_STATES.collapsedError;
+ if (this.$options.enablePolling) {
+ this.initExtensionPolling();
+ } else {
+ this.fetchCollapsedData(this.$props)
+ .then((data) => {
+ this.setCollapsedData(data);
+ })
+ .catch((e) => {
+ this.setCollapsedError(e);
+ });
+ }
+ },
+ setCollapsedData(data) {
+ this.collapsedData = data;
+ this.loadingState = null;
+ },
+ setCollapsedError(e) {
+ this.loadingState = LOADING_STATES.collapsedError;
- Sentry.captureException(e);
- });
+ Sentry.captureException(e);
},
loadAllData() {
if (this.hasFullData) return;
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js b/app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js
index ec6e6ed2620..8438f3492b2 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js
@@ -13,6 +13,7 @@ export const registerExtension = (extension) => {
props: extension.props,
i18n: extension.i18n,
expandEvent: extension.expandEvent,
+ enablePolling: extension.enablePolling,
computed: {
...Object.keys(extension.computed).reduce(
(acc, computedKey) => ({
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
index 235a200b747..8cdaa3316ee 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
@@ -119,6 +119,8 @@ export default {
:show-gitpod-button="mr.showGitpodButton"
:gitpod-url="mr.gitpodUrl"
:gitpod-enabled="mr.gitpodEnabled"
+ :user-preferences-gitpod-path="mr.userPreferencesGitpodPath"
+ :user-profile-enable-gitpod-path="mr.userProfileEnableGitpodPath"
:gitpod-text="$options.i18n.gitpodText"
class="gl-display-none gl-md-display-inline-block gl-mr-3"
data-placement="bottom"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue
index 677c50ed930..2e3a02b1712 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue
@@ -1,5 +1,6 @@
<script>
import { GlButton, GlLoadingIcon } from '@gitlab/ui';
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import ciIcon from '../../vue_shared/components/ci_icon.vue';
export default {
@@ -8,6 +9,7 @@ export default {
GlButton,
GlLoadingIcon,
},
+ mixins: [glFeatureFlagMixin()],
props: {
status: {
type: String,
@@ -42,7 +44,7 @@ export default {
</div>
<gl-button
- v-if="showDisabledButton"
+ v-if="!glFeatures.restructuredMrWidget && showDisabledButton"
category="primary"
variant="success"
data-testid="disabled-merge-button"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/merge_checks_failed.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/merge_checks_failed.vue
index ce572f8b0bf..701ef89304c 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/merge_checks_failed.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/merge_checks_failed.vue
@@ -1,20 +1,16 @@
<script>
-import { GlButton } from '@gitlab/ui';
import { s__ } from '~/locale';
-import notesEventHub from '~/notes/event_hub';
import StatusIcon from '../mr_widget_status_icon.vue';
export default {
i18n: {
- pipelineFailed: s__(
- 'mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure.',
- ),
approvalNeeded: s__('mrWidget|Merge blocked: this merge request must be approved.'),
- unresolvedDiscussions: s__('mrWidget|Merge blocked: all threads must be resolved.'),
+ blockingMergeRequests: s__(
+ 'mrWidget|Merge blocked: you can only merge after the above items are resolved.',
+ ),
},
components: {
StatusIcon,
- GlButton,
},
props: {
mr: {
@@ -24,22 +20,15 @@ export default {
},
computed: {
failedText() {
- if (this.mr.isPipelineFailed) {
- return this.$options.i18n.pipelineFailed;
- } else if (this.mr.approvals && !this.mr.isApproved) {
+ if (this.mr.approvals && !this.mr.isApproved) {
return this.$options.i18n.approvalNeeded;
- } else if (this.mr.hasMergeableDiscussionsState) {
- return this.$options.i18n.unresolvedDiscussions;
+ } else if (this.mr.blockingMergeRequests?.total_count > 0) {
+ return this.$options.i18n.blockingMergeRequests;
}
return null;
},
},
- methods: {
- jumpToFirstUnresolvedDiscussion() {
- notesEventHub.$emit('jumpToFirstUnresolvedDiscussion');
- },
- },
};
</script>
@@ -48,28 +37,6 @@ export default {
<status-icon status="warning" />
<p class="media-body gl-m-0! gl-font-weight-bold gl-text-black-normal!">
{{ failedText }}
- <template v-if="failedText == $options.i18n.unresolvedDiscussions">
- <gl-button
- class="gl-ml-3"
- size="small"
- variant="confirm"
- data-testid="jumpToUnresolved"
- @click="jumpToFirstUnresolvedDiscussion"
- >
- {{ s__('mrWidget|Jump to first unresolved thread') }}
- </gl-button>
- <gl-button
- v-if="mr.createIssueToResolveDiscussionsPath"
- :href="mr.createIssueToResolveDiscussionsPath"
- class="gl-ml-3"
- size="small"
- variant="confirm"
- category="secondary"
- data-testid="resolveIssue"
- >
- {{ s__('mrWidget|Create issue to resolve all threads') }}
- </gl-button>
- </template>
</p>
</div>
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.vue
index 13b1e49f44e..071920856a8 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.vue
@@ -1,25 +1,22 @@
<script>
-import { GlButton } from '@gitlab/ui';
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import statusIcon from '../mr_widget_status_icon.vue';
export default {
name: 'MRWidgetArchived',
components: {
- GlButton,
statusIcon,
},
+ mixins: [glFeatureFlagMixin()],
};
</script>
<template>
<div class="mr-widget-body media">
<div class="space-children">
- <status-icon status="warning" />
- <gl-button category="secondary" variant="success" :disabled="true">
- {{ s__('mrWidget|Merge') }}
- </gl-button>
+ <status-icon status="warning" show-disabled-button />
</div>
<div class="media-body">
- <span class="bold">
+ <span :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" class="bold">
{{ s__('mrWidget|Merge unavailable: merge requests are read-only on archived projects.') }}
</span>
</div>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.vue
index 10b93d7849f..fd42fa0421f 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.vue
@@ -12,9 +12,11 @@ export default {
</script>
<template>
<div class="mr-widget-body media">
- <status-icon :show-disabled-button="!glFeatures.restructuredMrWidget" status="loading" />
+ <status-icon :show-disabled-button="true" status="loading" />
<div class="media-body space-children">
- <span class="bold"> {{ s__('mrWidget|Checking if merge request can be merged…') }} </span>
+ <span :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" class="bold">
+ {{ s__('mrWidget|Checking if merge request can be merged…') }}
+ </span>
</div>
</div>
</template>
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 7a002d41ac0..a2c9cfe53cc 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
@@ -109,14 +109,18 @@ export default {
</gl-skeleton-loader>
</div>
<div v-else class="media-body space-children gl-display-flex gl-align-items-center">
- <span v-if="shouldBeRebased" class="bold">
+ <span
+ v-if="shouldBeRebased"
+ :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }"
+ class="bold"
+ >
{{
s__(`mrWidget|Merge blocked: fast-forward merge is not possible.
To merge this request, first rebase locally.`)
}}
</span>
<template v-else>
- <span class="bold">
+ <span :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" class="bold">
{{ s__('mrWidget|Merge blocked: merge conflicts must be resolved.') }}
<span v-if="!canMerge">
{{
@@ -129,6 +133,7 @@ export default {
<gl-button
v-if="showResolveButton"
:href="mr.conflictResolutionPath"
+ :size="glFeatures.restructuredMrWidget ? 'small' : 'medium'"
data-testid="resolve-conflicts-button"
>
{{ s__('mrWidget|Resolve conflicts') }}
@@ -136,6 +141,7 @@ export default {
<gl-button
v-if="canMerge"
v-gl-modal-directive="'modal-merge-info'"
+ :size="glFeatures.restructuredMrWidget ? 'small' : 'medium'"
data-testid="merge-locally-button"
>
{{ s__('mrWidget|Merge locally') }}
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue
index f91350d4a82..5b03eda2eac 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue
@@ -74,10 +74,21 @@ export default {
<status-icon :show-disabled-button="true" status="warning" />
<div class="media-body space-children">
- <span class="bold js-branch-text">
+ <span
+ :class="{
+ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget,
+ }"
+ class="bold js-branch-text"
+ >
<span class="capitalize" data-testid="missingBranchName"> {{ missingBranchName }} </span>
{{ s__('mrWidget|branch does not exist.') }} {{ missingBranchNameMessage }}
- <gl-icon v-gl-tooltip :title="message" :aria-label="message" name="question-o" />
+ <gl-icon
+ v-gl-tooltip
+ :title="message"
+ :aria-label="message"
+ name="question-o"
+ class="gl-text-blue-600 gl-cursor-pointer"
+ />
</span>
</div>
</div>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.vue
index 68ffca9cd68..34c5a2ff2c8 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.vue
@@ -1,4 +1,5 @@
<script>
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import StatusIcon from '../mr_widget_status_icon.vue';
export default {
@@ -6,13 +7,14 @@ export default {
components: {
StatusIcon,
},
+ mixins: [glFeatureFlagMixin()],
};
</script>
<template>
<div class="mr-widget-body media">
<status-icon :show-disabled-button="true" status="warning" />
<div class="media-body space-children">
- <span class="bold">
+ <span :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" class="bold">
{{
s__(
`mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue.`,
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 01e8303f513..bb0fb410d3e 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,11 +3,13 @@ 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',
@@ -25,8 +27,9 @@ export default {
},
components: {
statusIcon,
- GlButton,
GlSkeletonLoader,
+ ActionsButton,
+ GlButton,
},
mixins: [glFeatureFlagMixin(), mergeRequestQueryVariablesMixin],
props: {
@@ -44,12 +47,16 @@ export default {
state: {},
isMakingRequest: false,
rebasingError: null,
+ selectedRebaseAction: REBASE_BUTTON_KEY,
};
},
computed: {
isLoading() {
return this.glFeatures.mergeRequestWidgetGraphql && this.$apollo.queries.state.loading;
},
+ showRebaseWithoutCi() {
+ return this.glFeatures?.rebaseWithoutCiUi;
+ },
rebaseInProgress() {
if (this.glFeatures.mergeRequestWidgetGraphql) {
return this.state.rebaseInProgress;
@@ -86,14 +93,36 @@ 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() {
+ rebase({ skipCi = false } = {}) {
this.isMakingRequest = true;
this.rebasingError = null;
this.service
- .rebase()
+ .rebase({ skipCi })
.then(() => {
simplePoll(this.checkRebaseStatus);
})
@@ -109,6 +138,9 @@ export default {
}
});
},
+ selectRebaseAction(key) {
+ this.selectedRebaseAction = key;
+ },
checkRebaseStatus(continuePolling, stopPolling) {
this.service
.poll()
@@ -152,12 +184,14 @@ export default {
<div class="rebase-state-find-class-convention media media-body space-children">
<span
v-if="rebaseInProgress || isMakingRequest"
+ :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }"
class="gl-font-weight-bold"
data-testid="rebase-message"
>{{ __('Rebase in progress') }}</span
>
<span
v-if="!rebaseInProgress && !canPushToSourceBranch"
+ :class="{ 'gl-text-body!': glFeatures.restructuredMrWidget }"
class="gl-font-weight-bold gl-ml-0!"
data-testid="rebase-message"
>{{ fastForwardMergeText }}</span
@@ -167,15 +201,26 @@ export default {
class="accept-merge-holder clearfix js-toggle-container accept-action media space-children"
>
<gl-button
+ v-if="!glFeatures.restructuredMrWidget && !showRebaseWithoutCi"
:loading="isMakingRequest"
variant="confirm"
data-qa-selector="mr_rebase_button"
+ data-testid="standard-rebase-button"
@click="rebase"
>
{{ __('Rebase') }}
</gl-button>
+ <actions-button
+ v-if="!glFeatures.restructuredMrWidget && showRebaseWithoutCi"
+ :actions="actions"
+ :selected-key="selectedRebaseAction"
+ variant="confirm"
+ category="primary"
+ @select="selectRebaseAction"
+ />
<span
v-if="!rebasingError"
+ :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }"
class="gl-font-weight-bold"
data-testid="rebase-message"
data-qa-selector="no_fast_forward_message_content"
@@ -186,6 +231,17 @@ export default {
<span v-else class="gl-font-weight-bold danger" data-testid="rebase-message">{{
rebasingError
}}</span>
+ <gl-button
+ v-if="glFeatures.restructuredMrWidget"
+ :loading="isMakingRequest"
+ variant="confirm"
+ size="small"
+ data-qa-selector="mr_rebase_button"
+ class="gl-ml-3!"
+ @click="rebase"
+ >
+ {{ __('Rebase') }}
+ </gl-button>
</div>
</div>
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue
index 2d704d3b07a..e43319d42ca 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue
@@ -62,8 +62,8 @@ export default {
<gl-button
v-if="mr.newBlobPath"
:href="mr.newBlobPath"
- category="secondary"
- variant="success"
+ category="primary"
+ variant="confirm"
data-testid="createFileButton"
@click="onClickNewFile"
>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/pipeline_failed.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/pipeline_failed.vue
index b5d2f91c637..d88dad2e086 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/pipeline_failed.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/pipeline_failed.vue
@@ -1,6 +1,7 @@
<script>
import { GlLink, GlSprintf } from '@gitlab/ui';
import { helpPagePath } from '~/helpers/help_page_helper';
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { s__ } from '~/locale';
import statusIcon from '../mr_widget_status_icon.vue';
@@ -11,6 +12,7 @@ export default {
GlSprintf,
statusIcon,
},
+ mixins: [glFeatureFlagMixin()],
computed: {
troubleshootingDocsPath() {
return helpPagePath('ci/troubleshooting', { anchor: 'merge-request-status-messages' });
@@ -28,7 +30,7 @@ export default {
<div class="mr-widget-body media">
<status-icon :show-disabled-button="true" status="warning" />
<div class="media-body space-children">
- <span class="bold">
+ <span :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" class="bold">
<gl-sprintf :message="$options.i18n.failedMessage">
<template #link="{ content }">
<gl-link :href="troubleshootingDocsPath" target="_blank">
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 8830128b7d6..06ce312bd4c 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
@@ -529,7 +529,7 @@ export default {
<template>
<div
:class="{
- 'gl-border-t-1 gl-border-t-solid gl-border-gray-100 gl-bg-gray-10 gl-pl-7':
+ 'gl-border-t-1 gl-border-t-solid gl-border-gray-100 gl-bg-gray-10 gl-pl-7 gl-rounded-bottom-left-base gl-rounded-bottom-right-base':
glFeatures.restructuredMrWidget,
}"
>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/sha_mismatch.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/sha_mismatch.vue
index 7eeba8d8f89..b1fbe150fcf 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/sha_mismatch.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/sha_mismatch.vue
@@ -1,5 +1,6 @@
<script>
import { GlButton } from '@gitlab/ui';
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { I18N_SHA_MISMATCH } from '../../i18n';
import statusIcon from '../mr_widget_status_icon.vue';
@@ -12,6 +13,7 @@ export default {
i18n: {
I18N_SHA_MISMATCH,
},
+ mixins: [glFeatureFlagMixin()],
props: {
mr: {
type: Object,
@@ -25,7 +27,11 @@ export default {
<div class="mr-widget-body media">
<status-icon :show-disabled-button="false" status="warning" />
<div class="media-body">
- <span class="gl-font-weight-bold" data-qa-selector="head_mismatch_content">
+ <span
+ :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }"
+ class="gl-font-weight-bold"
+ data-qa-selector="head_mismatch_content"
+ >
{{ $options.i18n.I18N_SHA_MISMATCH.warningMessage }}
</span>
<gl-button
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue
index 69e4df0ca11..8cf6383c26a 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue
@@ -1,5 +1,6 @@
<script>
import { GlButton } from '@gitlab/ui';
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import notesEventHub from '~/notes/event_hub';
import statusIcon from '../mr_widget_status_icon.vue';
@@ -9,6 +10,7 @@ export default {
statusIcon,
GlButton,
},
+ mixins: [glFeatureFlagMixin()],
props: {
mr: {
type: Object,
@@ -25,16 +27,24 @@ export default {
<template>
<div class="mr-widget-body media gl-flex-wrap">
- <status-icon :show-disabled-button="true" status="warning" />
+ <status-icon show-disabled-button status="warning" />
<div class="media-body">
- <span class="gl-ml-3 gl-font-weight-bold gl-display-block gl-w-100">{{
- s__('mrWidget|Merge blocked: all threads must be resolved.')
- }}</span>
+ <span
+ :class="{
+ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget,
+ 'gl-display-block': !glFeatures.restructuredMrWidget,
+ }"
+ class="gl-ml-3 gl-font-weight-bold gl-w-100"
+ >
+ {{ s__('mrWidget|Merge blocked: all threads must be resolved.') }}
+ </span>
<gl-button
data-testid="jump-to-first"
class="gl-ml-3"
size="small"
- icon="comment-next"
+ :icon="glFeatures.restructuredMrWidget ? undefined : 'comment-next'"
+ :variant="glFeatures.restructuredMrWidget && 'confirm'"
+ :category="glFeatures.restructuredMrWidget && 'secondary'"
@click="jumpToFirstUnresolvedDiscussion"
>
{{ s__('mrWidget|Jump to first unresolved thread') }}
@@ -44,7 +54,7 @@ export default {
:href="mr.createIssueToResolveDiscussionsPath"
class="js-create-issue gl-ml-3"
size="small"
- icon="issue-new"
+ :icon="glFeatures.restructuredMrWidget ? undefined : 'issue-new'"
>
{{ s__('mrWidget|Create issue to resolve all threads') }}
</gl-button>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue
index ba831a33b73..e0e19094c40 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue
@@ -166,7 +166,10 @@ export default {
<status-icon :show-disabled-button="canUpdate" status="warning" />
<div class="media-body">
<div class="float-left">
- <span class="gl-font-weight-bold">
+ <span
+ :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }"
+ class="gl-font-weight-bold"
+ >
{{
__("Merge blocked: merge request must be marked as ready. It's still marked as draft.")
}}
diff --git a/app/assets/javascripts/vue_merge_request_widget/constants.js b/app/assets/javascripts/vue_merge_request_widget/constants.js
index 2edccce7f4e..32effb91043 100644
--- a/app/assets/javascripts/vue_merge_request_widget/constants.js
+++ b/app/assets/javascripts/vue_merge_request_widget/constants.js
@@ -162,3 +162,6 @@ 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/terraform/index.js b/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js
new file mode 100644
index 00000000000..a564acada02
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js
@@ -0,0 +1,173 @@
+import { __, n__, s__, sprintf } from '~/locale';
+import axios from '~/lib/utils/axios_utils';
+import { EXTENSION_ICONS } from '../../constants';
+
+export default {
+ name: 'WidgetTerraform',
+ enablePolling: true,
+ i18n: {
+ label: s__('Terraform|Terraform reports'),
+ loading: s__('Terraform|Loading Terraform reports...'),
+ error: s__('Terraform|Failed to load Terraform reports'),
+ reportGenerated: s__('Terraform|A Terraform report was generated in your pipelines.'),
+ namedReportGenerated: s__(
+ 'Terraform|The job %{strong_start}%{name}%{strong_end} generated a report.',
+ ),
+ reportChanges: s__(
+ 'Terraform|Reported Resource Changes: %{addNum} to add, %{changeNum} to change, %{deleteNum} to delete',
+ ),
+ reportFailed: s__('Terraform|A Terraform report failed to generate.'),
+ namedReportFailed: s__(
+ 'Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report.',
+ ),
+ reportErrored: s__('Terraform|Generating the report caused an error.'),
+ fullLog: __('Full log'),
+ },
+ expandEvent: 'i_testing_terraform_widget_total',
+ props: ['terraformReportsPath'],
+ computed: {
+ // Extension computed props
+ statusIcon() {
+ return EXTENSION_ICONS.warning;
+ },
+ },
+ methods: {
+ // Extension methods
+ summary({ valid = [], invalid = [] }) {
+ let title;
+ let subtitle = '';
+
+ const validText = sprintf(
+ n__(
+ 'Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines',
+ 'Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines',
+ valid.length,
+ ),
+ {
+ number: valid.length,
+ },
+ false,
+ );
+
+ const invalidText = sprintf(
+ n__(
+ 'Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate',
+ 'Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate',
+ invalid.length,
+ ),
+ {
+ number: invalid.length,
+ },
+ false,
+ );
+
+ if (valid.length) {
+ title = validText;
+ if (invalid.length) {
+ subtitle = sprintf(`<br>%{small_start}${invalidText}%{small_end}`);
+ }
+ } else {
+ title = invalidText;
+ }
+
+ return `${title}${subtitle}`;
+ },
+ fetchCollapsedData() {
+ return Promise.resolve(this.fetchPlans().then(this.prepareReports));
+ },
+ fetchFullData() {
+ const { valid, invalid } = this.collapsedData;
+ return Promise.resolve([...valid, ...invalid]);
+ },
+ // Custom methods
+ fetchPlans() {
+ return axios
+ .get(this.terraformReportsPath)
+ .then(({ data }) => {
+ return Object.keys(data).map((key) => {
+ return data[key];
+ });
+ })
+ .catch(() => {
+ const invalidData = { tf_report_error: 'api_error' };
+ return [invalidData];
+ });
+ },
+ createReportRow(report, iconName) {
+ const addNum = Number(report.create);
+ const changeNum = Number(report.update);
+ const deleteNum = Number(report.delete);
+ const validPlanValues = addNum + changeNum + deleteNum >= 0;
+
+ const actions = [];
+
+ let title;
+ let subtitle;
+
+ if (report.job_path) {
+ const action = {
+ href: report.job_path,
+ text: this.$options.i18n.fullLog,
+ target: '_blank',
+ };
+ actions.push(action);
+ }
+
+ if (validPlanValues) {
+ if (report.job_name) {
+ title = sprintf(
+ this.$options.i18n.namedReportGenerated,
+ {
+ name: report.job_name,
+ },
+ false,
+ );
+ } else {
+ title = this.$options.i18n.reportGenerated;
+ }
+
+ subtitle = sprintf(`%{small_start}${this.$options.i18n.reportChanges}%{small_end}`, {
+ addNum,
+ changeNum,
+ deleteNum,
+ });
+ } else {
+ if (report.job_name) {
+ title = sprintf(
+ this.$options.i18n.namedReportFailed,
+ {
+ name: report.job_name,
+ },
+ false,
+ );
+ } else {
+ title = this.$options.i18n.reportFailed;
+ }
+
+ subtitle = sprintf(`%{small_start}${this.$options.i18n.reportErrored}%{small_end}`);
+ }
+
+ return {
+ text: `${title}
+ <br>
+ ${subtitle}`,
+ icon: { name: iconName },
+ actions,
+ };
+ },
+ prepareReports(reports) {
+ const valid = [];
+ const invalid = [];
+
+ reports.forEach((report) => {
+ if (report.tf_report_error) {
+ invalid.push(this.createReportRow(report, EXTENSION_ICONS.error));
+ } else {
+ valid.push(this.createReportRow(report, EXTENSION_ICONS.success));
+ }
+ });
+
+ return { valid, invalid };
+ },
+ },
+};
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 c98dc426224..83a07240403 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
@@ -1,6 +1,7 @@
<script>
import { GlSafeHtmlDirective } from '@gitlab/ui';
import { isEmpty } from 'lodash';
+import { registerExtension } from '~/vue_merge_request_widget/components/extensions';
import MrWidgetApprovals from 'ee_else_ce/vue_merge_request_widget/components/approvals/approvals.vue';
import MRWidgetService from 'ee_else_ce/vue_merge_request_widget/services/mr_widget_service';
import MRWidgetStore from 'ee_else_ce/vue_merge_request_widget/stores/mr_widget_store';
@@ -43,6 +44,7 @@ import { STATE_MACHINE, stateToComponentMap } from './constants';
import eventHub from './event_hub';
import mergeRequestQueryVariablesMixin from './mixins/merge_request_query_variables';
import getStateQuery from './queries/get_state.query.graphql';
+import terraformExtension from './extensions/terraform';
export default {
// False positive i18n lint: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/25
@@ -184,6 +186,9 @@ export default {
shouldRenderSecurityReport() {
return Boolean(this.mr.pipeline.id);
},
+ shouldRenderTerraformPlans() {
+ return Boolean(this.mr?.terraformReportsPath);
+ },
mergeError() {
let { mergeError } = this.mr;
@@ -230,6 +235,11 @@ export default {
this.initPostMergeDeploymentsPolling();
}
},
+ shouldRenderTerraformPlans(newVal) {
+ if (newVal) {
+ this.registerTerraformPlans();
+ }
+ },
},
mounted() {
MRWidgetService.fetchInitialData()
@@ -463,6 +473,11 @@ export default {
dismissSuggestPipelines() {
this.mr.isDismissedSuggestPipeline = true;
},
+ registerTerraformPlans() {
+ if (this.shouldRenderTerraformPlans && this.shouldShowExtension) {
+ registerExtension(terraformExtension);
+ }
+ },
},
};
</script>
@@ -542,7 +557,10 @@ export default {
:pipeline-path="mr.pipeline.path"
/>
- <terraform-plan v-if="mr.terraformReportsPath" :endpoint="mr.terraformReportsPath" />
+ <terraform-plan
+ v-if="mr.terraformReportsPath && !shouldShowExtension"
+ :endpoint="mr.terraformReportsPath"
+ />
<grouped-accessibility-reports-app
v-if="shouldShowAccessibilityReport"
diff --git a/app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js b/app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js
index 7dcb4881e7f..7b803b0fcbb 100644
--- a/app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js
+++ b/app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js
@@ -55,8 +55,9 @@ export default class MRWidgetService {
return axios.get(this.endpoints.mergeActionsContentPath);
}
- rebase() {
- return axios.post(this.endpoints.rebasePath);
+ rebase({ skipCi = false } = {}) {
+ const path = `${this.endpoints.rebasePath}?skip_ci=${Boolean(skipCi)}`;
+ return axios.post(path);
}
fetchApprovals() {
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 57af869a0ba..5378dabf638 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
@@ -222,6 +222,8 @@ export default class MergeRequestStore {
this.showGitpodButton = data.show_gitpod_button;
this.gitpodUrl = data.gitpod_url;
this.gitpodEnabled = data.gitpod_enabled;
+ this.userPreferencesGitpodPath = data.user_preferences_gitpod_path;
+ this.userProfileEnableGitpodPath = data.user_profile_enable_gitpod_path;
}
setState() {
@@ -357,15 +359,13 @@ export default class MergeRequestStore {
setApprovals(data) {
this.approvals = data;
this.isApproved = data.approved || false;
+
+ this.setState();
}
+ // eslint-disable-next-line class-methods-use-this
get hasMergeChecksFailed() {
- if (!window.gon?.features?.restructuredMrWidget) return false;
-
- return (
- this.hasMergeableDiscussionsState ||
- (this.onlyAllowMergeIfPipelineSucceeds && this.isPipelineFailed)
- );
+ return false;
}
// Because the state machine doesn't yet handle every state and transition,
diff --git a/app/assets/javascripts/vue_shared/components/actions_button.vue b/app/assets/javascripts/vue_shared/components/actions_button.vue
index bab13fe7c75..6db18afe51c 100644
--- a/app/assets/javascripts/vue_shared/components/actions_button.vue
+++ b/app/assets/javascripts/vue_shared/components/actions_button.vue
@@ -66,6 +66,7 @@ export default {
:variant="variant"
:category="category"
split
+ data-qa-selector="action_dropdown"
@click="handleClick(selectedAction, $event)"
>
<template #button-content>
@@ -79,6 +80,7 @@ export default {
:is-check-item="true"
:is-checked="action.key === selectedAction.key"
:secondary-text="action.secondaryText"
+ :data-qa-selector="`${action.key}_menu_item`"
:data-testid="`action_${action.key}`"
@click="handleItemClick(action)"
>
diff --git a/app/assets/javascripts/vue_shared/components/clipboard_button.vue b/app/assets/javascripts/vue_shared/components/clipboard_button.vue
index 400be3ef688..f907b64608c 100644
--- a/app/assets/javascripts/vue_shared/components/clipboard_button.vue
+++ b/app/assets/javascripts/vue_shared/components/clipboard_button.vue
@@ -13,9 +13,23 @@
* />
*/
import { GlButton, GlTooltipDirective } from '@gitlab/ui';
+import { uniqueId } from 'lodash';
+
+import { __ } from '~/locale';
+import {
+ CLIPBOARD_SUCCESS_EVENT,
+ CLIPBOARD_ERROR_EVENT,
+ I18N_ERROR_MESSAGE,
+} from '~/behaviors/copy_to_clipboard';
export default {
name: 'ClipboardButton',
+ i18n: {
+ copied: __('Copied'),
+ error: I18N_ERROR_MESSAGE,
+ },
+ CLIPBOARD_SUCCESS_EVENT,
+ CLIPBOARD_ERROR_EVENT,
directives: {
GlTooltip: GlTooltipDirective,
},
@@ -72,6 +86,13 @@ export default {
default: 'default',
},
},
+ data() {
+ return {
+ localTitle: this.title,
+ titleTimeout: null,
+ id: null,
+ };
+ },
computed: {
clipboardText() {
if (this.gfm !== null) {
@@ -79,25 +100,50 @@ export default {
}
return this.text;
},
+ tooltipDirectiveOptions() {
+ return {
+ placement: this.tooltipPlacement,
+ container: this.tooltipContainer,
+ boundary: this.tooltipBoundary,
+ };
+ },
+ },
+ created() {
+ this.id = uniqueId('clipboard-button-');
+ },
+ methods: {
+ updateTooltip(title) {
+ this.localTitle = title;
+ this.$root.$emit('bv::show::tooltip', this.id);
+
+ clearTimeout(this.titleTimeout);
+
+ this.titleTimeout = setTimeout(() => {
+ this.localTitle = this.title;
+ this.$root.$emit('bv::hide::tooltip', this.id);
+ }, 1000);
+ },
},
};
</script>
<template>
<gl-button
- v-gl-tooltip.hover.blur.viewport="{
- placement: tooltipPlacement,
- container: tooltipContainer,
- boundary: tooltipBoundary,
- }"
+ :id="id"
+ ref="copyButton"
+ v-gl-tooltip.hover.focus.click.viewport="tooltipDirectiveOptions"
:class="cssClass"
- :title="title"
+ :title="localTitle"
:data-clipboard-text="clipboardText"
+ data-clipboard-handle-tooltip="false"
:category="category"
:size="size"
icon="copy-to-clipboard"
- :aria-label="__('Copy this value')"
:variant="variant"
+ :aria-label="localTitle"
+ aria-live="polite"
+ @[$options.CLIPBOARD_SUCCESS_EVENT]="updateTooltip($options.i18n.copied)"
+ @[$options.CLIPBOARD_ERROR_EVENT]="updateTooltip($options.i18n.error)"
v-on="$listeners"
>
<slot></slot>
diff --git a/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger.vue b/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger.vue
index f93415ced45..e12e06a2454 100644
--- a/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger.vue
+++ b/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger.vue
@@ -36,6 +36,11 @@ export default {
required: false,
default: 'confirm-danger-button',
},
+ buttonVariant: {
+ type: String,
+ required: false,
+ default: 'danger',
+ },
},
modalId: CONFIRM_DANGER_MODAL_ID,
};
@@ -45,7 +50,7 @@ export default {
<gl-button
v-gl-modal="$options.modalId"
:class="buttonClass"
- variant="danger"
+ :variant="buttonVariant"
:disabled="disabled"
:data-testid="buttonTestid"
>{{ buttonText }}</gl-button
diff --git a/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.stories.js b/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.stories.js
index 18fa297da87..6629b293eb9 100644
--- a/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.stories.js
+++ b/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.stories.js
@@ -11,7 +11,9 @@ const Template = (args, { argTypes }) => ({
props: Object.keys(argTypes),
template: '<confirm-danger v-bind="$props" />',
provide: {
- confirmDangerMessage: 'You require more Vespene Gas',
+ additionalInformation: args.additionalInformation || null,
+ confirmDangerMessage: args.confirmDangerMessage || 'You require more Vespene Gas',
+ htmlConfirmationMessage: args.confirmDangerMessage || false,
},
});
@@ -26,3 +28,16 @@ Disabled.args = {
...Default.args,
disabled: true,
};
+
+export const AdditionalInformation = Template.bind({});
+AdditionalInformation.args = {
+ ...Default.args,
+ additionalInformation: 'This replaces the default warning information',
+};
+
+export const HtmlMessage = Template.bind({});
+HtmlMessage.args = {
+ ...Default.args,
+ confirmDangerMessage: 'You strongly require more <strong>Vespene Gas</strong>',
+ htmlConfirmationMessage: true,
+};
diff --git a/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.vue b/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.vue
index 5bbe44b20b3..88890b3332d 100644
--- a/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.vue
+++ b/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.vue
@@ -1,5 +1,12 @@
<script>
-import { GlAlert, GlModal, GlFormGroup, GlFormInput, GlSprintf } from '@gitlab/ui';
+import {
+ GlAlert,
+ GlModal,
+ GlFormGroup,
+ GlFormInput,
+ GlSafeHtmlDirective as SafeHtml,
+ GlSprintf,
+} from '@gitlab/ui';
import {
CONFIRM_DANGER_MODAL_BUTTON,
CONFIRM_DANGER_MODAL_TITLE,
@@ -17,13 +24,22 @@ export default {
GlFormInput,
GlSprintf,
},
+ directives: {
+ SafeHtml,
+ },
inject: {
+ htmlConfirmationMessage: {
+ default: false,
+ },
confirmDangerMessage: {
default: '',
},
confirmButtonText: {
default: CONFIRM_DANGER_MODAL_BUTTON,
},
+ additionalInformation: {
+ default: CONFIRM_DANGER_WARNING,
+ },
},
props: {
modalId: {
@@ -81,9 +97,12 @@ export default {
:dismissible="false"
class="gl-mb-4"
>
- {{ confirmDangerMessage }}
+ <span v-if="htmlConfirmationMessage" v-safe-html="confirmDangerMessage"></span>
+ <span v-else>
+ {{ confirmDangerMessage }}
+ </span>
</gl-alert>
- <p data-testid="confirm-danger-warning">{{ $options.i18n.CONFIRM_DANGER_WARNING }}</p>
+ <p data-testid="confirm-danger-warning">{{ additionalInformation }}</p>
<p data-testid="confirm-danger-phrase">
<gl-sprintf :message="$options.i18n.CONFIRM_DANGER_PHRASE_TEXT">
<template #phrase_code>
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue
index 7c1828f2294..5cdf7b6a3b2 100644
--- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue
@@ -332,7 +332,7 @@ export default {
v-if="showCheckbox"
class="gl-align-self-center"
:checked="checkboxChecked"
- @input="$emit('checked-input', $event)"
+ @change="$emit('checked-input', $event)"
>
<span class="gl-sr-only">{{ __('Select all') }}</span>
</gl-form-checkbox>
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/author_token.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/author_token.vue
index 06478a89721..b70317b2ec4 100644
--- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/author_token.vue
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/author_token.vue
@@ -4,7 +4,7 @@ import { compact } from 'lodash';
import createFlash from '~/flash';
import { __ } from '~/locale';
-import { DEFAULT_LABEL_ANY } from '../constants';
+import { DEFAULT_NONE_ANY } from '../constants';
import BaseToken from './base_token.vue';
@@ -36,7 +36,7 @@ export default {
},
computed: {
defaultAuthors() {
- return this.config.defaultAuthors || [DEFAULT_LABEL_ANY];
+ return this.config.defaultAuthors || DEFAULT_NONE_ANY;
},
preloadedAuthors() {
return this.config.preloadedAuthors || [];
diff --git a/app/assets/javascripts/vue_shared/components/gitlab_version_check.vue b/app/assets/javascripts/vue_shared/components/gitlab_version_check.vue
new file mode 100644
index 00000000000..acddf16bd27
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/gitlab_version_check.vue
@@ -0,0 +1,67 @@
+<script>
+import { GlBadge } from '@gitlab/ui';
+import { s__ } from '~/locale';
+import axios from '~/lib/utils/axios_utils';
+
+const STATUS_TYPES = {
+ SUCCESS: 'success',
+ WARNING: 'warning',
+ DANGER: 'danger',
+};
+
+export default {
+ name: 'GitlabVersionCheck',
+ components: {
+ GlBadge,
+ },
+ props: {
+ size: {
+ type: String,
+ required: false,
+ default: 'md',
+ },
+ },
+ data() {
+ return {
+ status: null,
+ };
+ },
+ computed: {
+ title() {
+ if (this.status === STATUS_TYPES.SUCCESS) {
+ return s__('VersionCheck|Up to date');
+ } else if (this.status === STATUS_TYPES.WARNING) {
+ return s__('VersionCheck|Update available');
+ } else if (this.status === STATUS_TYPES.DANGER) {
+ return s__('VersionCheck|Update ASAP');
+ }
+
+ return null;
+ },
+ },
+ created() {
+ this.checkGitlabVersion();
+ },
+ methods: {
+ checkGitlabVersion() {
+ axios
+ .get('/admin/version_check.json')
+ .then((res) => {
+ if (res.data) {
+ this.status = res.data.severity;
+ }
+ })
+ .catch(() => {
+ // Silently fail
+ this.status = null;
+ });
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-badge v-if="status" class="version-check-badge" :variant="status" :size="size">{{
+ title
+ }}</gl-badge>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/line_numbers.vue b/app/assets/javascripts/vue_shared/components/line_numbers.vue
index 7e17cca3dcc..11caf3be00a 100644
--- a/app/assets/javascripts/vue_shared/components/line_numbers.vue
+++ b/app/assets/javascripts/vue_shared/components/line_numbers.vue
@@ -12,31 +12,6 @@ export default {
required: true,
},
},
- data() {
- return {
- currentlyHighlightedLine: null,
- };
- },
- mounted() {
- this.scrollToLine();
- },
- methods: {
- scrollToLine(hash = window.location.hash) {
- const lineToHighlight = hash && this.$el.querySelector(hash);
-
- if (!lineToHighlight) {
- return;
- }
-
- if (this.currentlyHighlightedLine) {
- this.currentlyHighlightedLine.classList.remove('hll');
- }
-
- lineToHighlight.classList.add('hll');
- this.currentlyHighlightedLine = lineToHighlight;
- lineToHighlight.scrollIntoView({ behavior: 'smooth', block: 'center' });
- },
- },
};
</script>
<template>
@@ -45,10 +20,9 @@ export default {
v-for="line in lines"
:id="`L${line}`"
:key="line"
- class="diff-line-num"
- :href="`#L${line}`"
+ class="diff-line-num gl-shadow-none!"
+ :to="`#LC${line}`"
:data-line-number="line"
- @click="scrollToLine(`#L${line}`)"
>
<gl-icon :size="12" name="link" />
{{ line }}
diff --git a/app/assets/javascripts/vue_shared/components/markdown/apply_suggestion.vue b/app/assets/javascripts/vue_shared/components/markdown/apply_suggestion.vue
index ce7cbafb97d..709d3592828 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/apply_suggestion.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/apply_suggestion.vue
@@ -67,7 +67,7 @@ export default {
<gl-button
class="gl-w-auto! gl-mt-3 gl-text-center! gl-hover-text-white! gl-transition-medium! float-right"
category="primary"
- variant="success"
+ variant="confirm"
data-qa-selector="commit_with_custom_message_button"
@click="onApply"
>
diff --git a/app/assets/javascripts/vue_shared/components/markdown/field.vue b/app/assets/javascripts/vue_shared/components/markdown/field.vue
index 86f04c78ebe..5c86c928ce3 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/field.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/field.vue
@@ -2,7 +2,7 @@
import { GlIcon } from '@gitlab/ui';
import $ from 'jquery';
import '~/behaviors/markdown/render_gfm';
-import { unescape } from 'lodash';
+import { debounce, unescape } from 'lodash';
import createFlash from '~/flash';
import GLForm from '~/gl_form';
import axios from '~/lib/utils/axios_utils';
@@ -110,7 +110,7 @@ export default {
return {
markdownPreview: '',
referencedCommands: '',
- referencedUsers: '',
+ referencedUsers: [],
hasSuggestion: false,
markdownPreviewLoading: false,
previewMarkdown: false,
@@ -188,6 +188,24 @@ export default {
});
}
},
+
+ textareaValue: {
+ immediate: true,
+ handler(textareaValue, oldVal) {
+ const all = /@all([^\w._-]|$)/;
+ const hasAll = all.test(textareaValue);
+ const hadAll = all.test(oldVal);
+
+ const justAddedAll = !hadAll && hasAll;
+ const justRemovedAll = hadAll && !hasAll;
+
+ if (justAddedAll) {
+ this.debouncedFetchMarkdown();
+ } else if (justRemovedAll) {
+ this.referencedUsers = [];
+ }
+ },
+ },
},
mounted() {
// GLForm class handles all the toolbar buttons
@@ -222,9 +240,9 @@ export default {
if (this.textareaValue) {
this.markdownPreviewLoading = true;
this.markdownPreview = __('Loading…');
- axios
- .post(this.markdownPreviewPath, { text: this.textareaValue })
- .then((response) => this.renderMarkdown(response.data))
+
+ this.fetchMarkdown()
+ .then((data) => this.renderMarkdown(data))
.catch(() =>
createFlash({
message: __('Error loading markdown preview'),
@@ -239,17 +257,28 @@ export default {
this.previewMarkdown = false;
},
+ fetchMarkdown() {
+ return axios.post(this.markdownPreviewPath, { text: this.textareaValue }).then(({ data }) => {
+ const { references } = data;
+ if (references) {
+ this.referencedCommands = references.commands;
+ this.referencedUsers = references.users;
+ this.hasSuggestion = references.suggestions?.length > 0;
+ this.suggestions = references.suggestions;
+ }
+
+ return data;
+ });
+ },
+
+ debouncedFetchMarkdown: debounce(function debouncedFetchMarkdown() {
+ return this.fetchMarkdown();
+ }, 400),
+
renderMarkdown(data = {}) {
this.markdownPreviewLoading = false;
this.markdownPreview = data.body || __('Nothing to preview.');
- if (data.references) {
- this.referencedCommands = data.references.commands;
- this.referencedUsers = data.references.users;
- this.hasSuggestion = data.references.suggestions && data.references.suggestions.length;
- this.suggestions = data.references.suggestions;
- }
-
this.$nextTick()
.then(() => $(this.$refs['markdown-preview']).renderGFM())
.catch(() =>
@@ -326,18 +355,14 @@ export default {
v-html="markdownPreview /* eslint-disable-line vue/no-v-html */"
></div>
</template>
- <template v-if="previewMarkdown && !markdownPreviewLoading">
- <div
- v-if="referencedCommands"
- class="referenced-commands"
- v-html="referencedCommands /* eslint-disable-line vue/no-v-html */"
- ></div>
- <div v-if="shouldShowReferencedUsers" class="referenced-users">
- <gl-icon name="warning-solid" />
- <span
- v-html="addMultipleToDiscussionWarning /* eslint-disable-line vue/no-v-html */"
- ></span>
- </div>
- </template>
+ <div
+ v-if="referencedCommands && previewMarkdown && !markdownPreviewLoading"
+ class="referenced-commands"
+ v-html="referencedCommands /* eslint-disable-line vue/no-v-html */"
+ ></div>
+ <div v-if="shouldShowReferencedUsers" class="referenced-users">
+ <gl-icon name="warning-solid" />
+ <span v-html="addMultipleToDiscussionWarning /* eslint-disable-line vue/no-v-html */"></span>
+ </div>
</div>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/modal_copy_button.vue b/app/assets/javascripts/vue_shared/components/modal_copy_button.vue
index 38afd56bae6..d4f50e347cb 100644
--- a/app/assets/javascripts/vue_shared/components/modal_copy_button.vue
+++ b/app/assets/javascripts/vue_shared/components/modal_copy_button.vue
@@ -1,6 +1,6 @@
<script>
import { GlButton, GlTooltipDirective } from '@gitlab/ui';
-import Clipboard from 'clipboard';
+import ClipboardJS from 'clipboard';
import { uniqueId } from 'lodash';
import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants';
@@ -69,7 +69,7 @@ export default {
},
mounted() {
this.$nextTick(() => {
- this.clipboard = new Clipboard(this.$el, {
+ this.clipboard = new ClipboardJS(this.$el, {
container:
document.querySelector(`${this.modalDomId} div.modal-content`) ||
document.getElementById(this.container) ||
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue
index 13a6dd43207..0fa64a29b3a 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue
@@ -179,6 +179,9 @@ export default {
this.searchKey = '';
this.setFocus();
},
+ selectFirstItem() {
+ this.$refs.dropdownContentsView.selectFirstItem();
+ },
},
};
</script>
@@ -204,11 +207,13 @@ export default {
@toggleDropdownContentsCreateView="toggleDropdownContent"
@closeDropdown="$emit('closeDropdown')"
@input="debouncedSearchKeyUpdate"
+ @searchEnter="selectFirstItem"
/>
</template>
<template #default>
<component
:is="dropdownContentsView"
+ ref="dropdownContentsView"
v-model="localSelectedLabels"
:search-key="searchKey"
:allow-multiselect="allowMultiselect"
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue
index da626a21b14..b99083713a8 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue
@@ -1,5 +1,12 @@
<script>
-import { GlTooltipDirective, GlButton, GlFormInput, GlLink, GlLoadingIcon } from '@gitlab/ui';
+import {
+ GlAlert,
+ GlTooltipDirective,
+ GlButton,
+ GlFormInput,
+ GlLink,
+ GlLoadingIcon,
+} from '@gitlab/ui';
import produce from 'immer';
import createFlash from '~/flash';
import { __ } from '~/locale';
@@ -11,6 +18,7 @@ const errorMessage = __('Error creating label.');
export default {
components: {
+ GlAlert,
GlButton,
GlFormInput,
GlLink,
@@ -42,6 +50,7 @@ export default {
labelTitle: '',
selectedColor: '',
labelCreateInProgress: false,
+ error: undefined,
};
},
computed: {
@@ -111,13 +120,14 @@ export default {
) => this.updateLabelsInCache(store, label),
});
if (labelCreate.errors.length) {
- createFlash({ message: errorMessage });
+ [this.error] = labelCreate.errors;
+ } else {
+ this.$emit('hideCreateView');
}
} catch {
createFlash({ message: errorMessage });
}
this.labelCreateInProgress = false;
- this.$emit('hideCreateView');
},
},
};
@@ -126,6 +136,9 @@ export default {
<template>
<div class="labels-select-contents-create js-labels-create">
<div class="dropdown-input">
+ <gl-alert v-if="error" variant="danger" :dismissible="false" class="gl-mb-3">
+ {{ error }}
+ </gl-alert>
<gl-form-input
v-model.trim="labelTitle"
:placeholder="__('Name new label')"
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue
index e9a2d7747e2..ae179ef93c7 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue
@@ -84,6 +84,9 @@ export default {
showNoMatchingResultsMessage() {
return Boolean(this.searchKey) && this.visibleLabels.length === 0;
},
+ shouldHighlightFirstItem() {
+ return this.searchKey !== '' && this.visibleLabels.length > 0;
+ },
},
methods: {
isLabelSelected(label) {
@@ -128,6 +131,11 @@ export default {
onDropdownAppear() {
this.isVisible = true;
},
+ selectFirstItem() {
+ if (this.shouldHighlightFirstItem) {
+ this.handleLabelClick(this.visibleLabels[0]);
+ }
+ },
},
};
</script>
@@ -143,11 +151,13 @@ export default {
/>
<template v-else>
<gl-dropdown-item
- v-for="label in visibleLabels"
+ v-for="(label, index) in visibleLabels"
:key="label.id"
:is-checked="isLabelSelected(label)"
:is-check-centered="true"
:is-check-item="true"
+ :active="shouldHighlightFirstItem && index === 0"
+ active-class="is-focused"
data-testid="labels-list"
@click.native.capture.stop="handleLabelClick(label)"
>
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_header.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_header.vue
index 7a0f20b0c83..faad69732dd 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_header.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_header.vue
@@ -83,6 +83,7 @@ export default {
data-qa-selector="dropdown_input_field"
data-testid="dropdown-input-field"
@input="$emit('input', $event)"
+ @keydown.enter="$emit('searchEnter', $event)"
/>
</div>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/label_item.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/label_item.vue
index f27f0b4e34c..caeee2df7e5 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/label_item.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/label_item.vue
@@ -10,7 +10,7 @@ export default {
</script>
<template>
- <div>
+ <div class="gl-display-flex gl-align-items-center">
<span
class="dropdown-label-box gl-flex-shrink-0 gl-top-0 gl-mr-3"
:style="{ 'background-color': label.color }"
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue
index 3adda69b892..f53b75df4eb 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue
@@ -289,6 +289,7 @@ export default {
'is-standalone': isDropdownVariantStandalone(variant),
'is-embedded': isDropdownVariantEmbedded(variant),
}"
+ data-testid="sidebar-labels"
data-qa-selector="labels_block"
>
<template v-if="isDropdownVariantSidebar(variant)">
diff --git a/app/assets/javascripts/vue_shared/components/source_editor.vue b/app/assets/javascripts/vue_shared/components/source_editor.vue
index 8a0fef36079..011cad4267c 100644
--- a/app/assets/javascripts/vue_shared/components/source_editor.vue
+++ b/app/assets/javascripts/vue_shared/components/source_editor.vue
@@ -97,7 +97,7 @@ export default {
ref="editor"
data-editor-loading
data-qa-selector="source_editor_container"
- @[$options.readyEvent]="$emit($options.readyEvent)"
+ @[$options.readyEvent]="$emit($options.readyEvent, $event)"
>
<pre class="editor-loading-content">{{ value }}</pre>
</div>
diff --git a/app/assets/javascripts/vue_shared/components/source_viewer.vue b/app/assets/javascripts/vue_shared/components/source_viewer.vue
index 8f0d051543f..99895926653 100644
--- a/app/assets/javascripts/vue_shared/components/source_viewer.vue
+++ b/app/assets/javascripts/vue_shared/components/source_viewer.vue
@@ -1,6 +1,9 @@
<script>
import { GlSafeHtmlDirective } from '@gitlab/ui';
import LineNumbers from '~/vue_shared/components/line_numbers.vue';
+import { sanitize } from '~/lib/dompurify';
+
+const LINE_SELECT_CLASS_NAME = 'hll';
export default {
components: {
@@ -46,7 +49,15 @@ export default {
}
}
- return highlightedContent;
+ return this.wrapLines(highlightedContent);
+ },
+ },
+ watch: {
+ highlightedContent() {
+ this.$nextTick(() => this.selectLine());
+ },
+ $route() {
+ this.selectLine();
},
},
async mounted() {
@@ -73,16 +84,40 @@ export default {
return languageDefinition;
},
+ wrapLines(content) {
+ return (
+ content &&
+ content
+ .split('\n')
+ .map((line, i) => `<span id="LC${i + 1}" class="line">${line}</span>`)
+ .join('\r\n')
+ );
+ },
+ selectLine() {
+ const hash = sanitize(this.$route.hash);
+ const lineToSelect = hash && this.$el.querySelector(hash);
+
+ if (!lineToSelect) {
+ return;
+ }
+
+ if (this.$options.currentlySelectedLine) {
+ this.$options.currentlySelectedLine.classList.remove(LINE_SELECT_CLASS_NAME);
+ }
+
+ lineToSelect.classList.add(LINE_SELECT_CLASS_NAME);
+ this.$options.currentlySelectedLine = lineToSelect;
+ lineToSelect.scrollIntoView({ behavior: 'smooth', block: 'center' });
+ },
},
userColorScheme: window.gon.user_color_scheme,
+ currentlySelectedLine: null,
};
</script>
<template>
- <div class="file-content code" :class="$options.userColorScheme">
+ <div class="file-content code js-syntax-highlight" :class="$options.userColorScheme">
<line-numbers :lines="lineNumbers" />
- <pre
- class="code gl-pl-3!"
- ><code v-safe-html="highlightedContent" class="gl-white-space-pre-wrap!"></code>
+ <pre class="code"><code v-safe-html="highlightedContent"></code>
</pre>
</div>
</template>
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 6da2d39a95a..f02cd5c4e2e 100644
--- a/app/assets/javascripts/vue_shared/components/web_ide_link.vue
+++ b/app/assets/javascripts/vue_shared/components/web_ide_link.vue
@@ -1,6 +1,7 @@
<script>
import $ from 'jquery';
-import { __ } from '~/locale';
+import { GlModal, GlSprintf, GlLink } from '@gitlab/ui';
+import { s__, __ } from '~/locale';
import ActionsButton from '~/vue_shared/components/actions_button.vue';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
@@ -12,6 +13,19 @@ export default {
components: {
ActionsButton,
LocalStorageSync,
+ GlModal,
+ GlSprintf,
+ GlLink,
+ },
+ i18n: {
+ modal: {
+ title: __('Enable Gitpod?'),
+ content: s__(
+ 'Gitpod|To use Gitpod you must first enable the feature in the integrations section of your %{linkStart}user preferences%{linkEnd}.',
+ ),
+ actionCancelText: __('Cancel'),
+ actionPrimaryText: __('Enable Gitpod'),
+ },
},
props: {
isFork: {
@@ -49,6 +63,16 @@ export default {
required: false,
default: false,
},
+ userPreferencesGitpodPath: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ userProfileEnableGitpodPath: {
+ type: String,
+ required: false,
+ default: '',
+ },
editUrl: {
type: String,
required: false,
@@ -74,10 +98,16 @@ export default {
required: false,
default: '',
},
+ disableForkModal: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
return {
selection: KEY_WEB_IDE,
+ showEnableGitpodModal: false,
};
},
computed: {
@@ -93,8 +123,12 @@ export default {
? {
href: '#modal-confirm-fork-edit',
handle: () => {
- this.$emit('edit', 'simple');
- this.showModal('#modal-confirm-fork-edit');
+ if (this.disableForkModal) {
+ this.$emit('edit', 'simple');
+ return;
+ }
+
+ this.showJQueryModal('#modal-confirm-fork-edit');
},
}
: { href: this.editUrl };
@@ -132,8 +166,12 @@ export default {
? {
href: '#modal-confirm-fork-webide',
handle: () => {
- this.$emit('edit', 'ide');
- this.showModal('#modal-confirm-fork-webide');
+ if (this.disableForkModal) {
+ this.$emit('edit', 'ide');
+ return;
+ }
+
+ this.showJQueryModal('#modal-confirm-fork-webide');
},
}
: { href: this.webIdeUrl };
@@ -154,14 +192,23 @@ export default {
gitpodActionText() {
return this.gitpodText || __('Gitpod');
},
+ computedShowGitpodButton() {
+ return (
+ this.showGitpodButton && this.userPreferencesGitpodPath && this.userProfileEnableGitpodPath
+ );
+ },
gitpodAction() {
- if (!this.showGitpodButton) {
+ if (!this.computedShowGitpodButton) {
return null;
}
const handleOptions = this.gitpodEnabled
? { href: this.gitpodUrl }
- : { href: '#modal-enable-gitpod', handle: () => this.showModal('#modal-enable-gitpod') };
+ : {
+ handle: () => {
+ this.showModal('showEnableGitpodModal');
+ },
+ };
const secondaryText = __('Launch a ready-to-code development environment for your project.');
@@ -176,14 +223,36 @@ export default {
...handleOptions,
};
},
+ enableGitpodModalProps() {
+ return {
+ 'modal-id': 'enable-gitpod-modal',
+ size: 'sm',
+ title: this.$options.i18n.modal.title,
+ 'action-cancel': {
+ text: this.$options.i18n.modal.actionCancelText,
+ },
+ 'action-primary': {
+ text: this.$options.i18n.modal.actionPrimaryText,
+ attributes: {
+ variant: 'confirm',
+ category: 'primary',
+ href: this.userProfileEnableGitpodPath,
+ 'data-method': 'put',
+ },
+ },
+ };
+ },
},
methods: {
select(key) {
this.selection = key;
},
- showModal(id) {
+ showJQueryModal(id) {
$(id).modal('show');
},
+ showModal(dataKey) {
+ this[dataKey] = true;
+ },
},
};
</script>
@@ -202,5 +271,16 @@ export default {
:value="selection"
@input="select"
/>
+ <gl-modal
+ v-if="computedShowGitpodButton && !gitpodEnabled"
+ v-model="showEnableGitpodModal"
+ v-bind="enableGitpodModalProps"
+ >
+ <gl-sprintf :message="$options.i18n.modal.content">
+ <template #link="{ content }">
+ <gl-link :href="userPreferencesGitpodPath">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </gl-modal>
</div>
</template>
diff --git a/app/assets/javascripts/vue_shared/issuable/list/components/issuable_bulk_edit_sidebar.vue b/app/assets/javascripts/vue_shared/issuable/list/components/issuable_bulk_edit_sidebar.vue
index 5ca9e50d854..bcc889495bd 100644
--- a/app/assets/javascripts/vue_shared/issuable/list/components/issuable_bulk_edit_sidebar.vue
+++ b/app/assets/javascripts/vue_shared/issuable/list/components/issuable_bulk_edit_sidebar.vue
@@ -13,6 +13,7 @@ export default {
if (layoutPageEl) {
layoutPageEl.classList.toggle('right-sidebar-expanded', value);
layoutPageEl.classList.toggle('right-sidebar-collapsed', !value);
+ layoutPageEl.classList.toggle('issuable-bulk-update-sidebar', !value);
}
},
},
diff --git a/app/assets/javascripts/vue_shared/issuable/list/components/issuable_item.vue b/app/assets/javascripts/vue_shared/issuable/list/components/issuable_item.vue
index 0bb0e0d9fb0..af0235bfc69 100644
--- a/app/assets/javascripts/vue_shared/issuable/list/components/issuable_item.vue
+++ b/app/assets/javascripts/vue_shared/issuable/list/components/issuable_item.vue
@@ -193,7 +193,13 @@ export default {
:title="__('This issue is hidden because its author has been banned')"
:aria-label="__('Hidden')"
/>
- <gl-link class="issue-title-text" dir="auto" :href="webUrl" v-bind="issuableTitleProps">
+ <gl-link
+ class="issue-title-text"
+ dir="auto"
+ :href="webUrl"
+ data-qa-selector="issuable_title_link"
+ v-bind="issuableTitleProps"
+ >
{{ issuable.title }}
<gl-icon v-if="isIssuableUrlExternal" name="external-link" class="gl-ml-2" />
</gl-link>
diff --git a/app/assets/javascripts/vue_shared/issuable/list/components/issuable_tabs.vue b/app/assets/javascripts/vue_shared/issuable/list/components/issuable_tabs.vue
index 3ff87ba3c4f..9bf54e98cc4 100644
--- a/app/assets/javascripts/vue_shared/issuable/list/components/issuable_tabs.vue
+++ b/app/assets/javascripts/vue_shared/issuable/list/components/issuable_tabs.vue
@@ -1,5 +1,6 @@
<script>
import { GlTabs, GlTab, GlBadge } from '@gitlab/ui';
+import { formatNumber } from '~/locale';
export default {
components: {
@@ -29,6 +30,9 @@ export default {
isTabCountNumeric(tab) {
return Number.isInteger(this.tabCounts[tab.name]);
},
+ formatNumber(count) {
+ return formatNumber(count);
+ },
},
};
</script>
@@ -55,7 +59,7 @@ export default {
size="sm"
class="gl-tab-counter-badge"
>
- {{ tabCounts[tab.name] }}
+ {{ formatNumber(tabCounts[tab.name]) }}
</gl-badge>
</template>
</gl-tab>
diff --git a/app/assets/javascripts/vue_shared/issuable/list/constants.js b/app/assets/javascripts/vue_shared/issuable/list/constants.js
index 773ad0f8e93..c6dce6a51c2 100644
--- a/app/assets/javascripts/vue_shared/issuable/list/constants.js
+++ b/app/assets/javascripts/vue_shared/issuable/list/constants.js
@@ -38,7 +38,7 @@ export const AvailableSortOptions = [
},
{
id: 2,
- title: __('Last updated'),
+ title: __('Updated date'),
sortDirection: {
descending: 'updated_desc',
ascending: 'updated_asc',
diff --git a/app/assets/javascripts/vue_shared/issuable/show/constants.js b/app/assets/javascripts/vue_shared/issuable/show/constants.js
deleted file mode 100644
index 346f45c7d90..00000000000
--- a/app/assets/javascripts/vue_shared/issuable/show/constants.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export const IssuableType = {
- Issue: 'issue',
- Incident: 'incident',
- TestCase: 'test_case',
-};
diff --git a/app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue b/app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue
index 114f60c96ee..f67e590e2ce 100644
--- a/app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue
+++ b/app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue
@@ -10,10 +10,17 @@ export default {
GlIcon,
WelcomePage,
LegacyContainer,
+ CreditCardVerification: () =>
+ import('ee_component/pages/groups/new/components/credit_card_verification.vue'),
},
directives: {
SafeHtml,
},
+ inject: {
+ verificationRequired: {
+ default: false,
+ },
+ },
props: {
title: {
type: String,
@@ -41,6 +48,7 @@ export default {
data() {
return {
activePanelName: null,
+ verificationCompleted: false,
};
},
@@ -67,6 +75,10 @@ export default {
{ text: this.activePanel.title, href: `#${this.activePanel.name}` },
];
},
+
+ shouldVerify() {
+ return this.verificationRequired && !this.verificationCompleted;
+ },
},
created() {
@@ -93,12 +105,16 @@ export default {
localStorage.setItem(this.persistenceKey, this.activePanelName);
}
},
+ onVerified() {
+ this.verificationCompleted = true;
+ },
},
};
</script>
<template>
- <welcome-page v-if="!activePanelName" :panels="panels" :title="title">
+ <credit-card-verification v-if="shouldVerify" @verified="onVerified" />
+ <welcome-page v-else-if="!activePanelName" :panels="panels" :title="title">
<template #footer>
<slot name="welcome-footer"> </slot>
</template>
diff --git a/app/assets/javascripts/work_items/components/item_title.vue b/app/assets/javascripts/work_items/components/item_title.vue
index 5e9e50a94f0..79840cc4f0f 100644
--- a/app/assets/javascripts/work_items/components/item_title.vue
+++ b/app/assets/javascripts/work_items/components/item_title.vue
@@ -2,7 +2,10 @@
import { escape } from 'lodash';
import { __ } from '~/locale';
+import { WI_TITLE_TRACK_LABEL } from '../constants';
+
export default {
+ WI_TITLE_TRACK_LABEL,
props: {
initialTitle: {
type: String,
@@ -56,6 +59,7 @@ export default {
role="textbox"
:aria-label="__('Title')"
:data-placeholder="placeholder"
+ :data-track-label="$options.WI_TITLE_TRACK_LABEL"
:contenteditable="!disabled"
class="gl-pseudo-placeholder"
@blur="handleBlur"
diff --git a/app/assets/javascripts/work_items/constants.js b/app/assets/javascripts/work_items/constants.js
index b39f68abf74..995c02a2c5b 100644
--- a/app/assets/javascripts/work_items/constants.js
+++ b/app/assets/javascripts/work_items/constants.js
@@ -1,3 +1,5 @@
export const widgetTypes = {
title: 'TITLE',
};
+
+export const WI_TITLE_TRACK_LABEL = 'item_title';
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 479274baf3a..4262e169655 100644
--- a/app/assets/javascripts/work_items/pages/work_item_root.vue
+++ b/app/assets/javascripts/work_items/pages/work_item_root.vue
@@ -1,16 +1,21 @@
<script>
import { GlAlert } from '@gitlab/ui';
+import Tracking from '~/tracking';
import workItemQuery from '../graphql/work_item.query.graphql';
import updateWorkItemMutation from '../graphql/update_work_item.mutation.graphql';
-import { widgetTypes } from '../constants';
+import { widgetTypes, WI_TITLE_TRACK_LABEL } from '../constants';
import ItemTitle from '../components/item_title.vue';
+const trackingMixin = Tracking.mixin();
+
export default {
+ titleUpdatedEvent: 'updated_title',
components: {
ItemTitle,
GlAlert,
},
+ mixins: [trackingMixin],
props: {
id: {
type: String,
@@ -34,6 +39,14 @@ export default {
},
},
computed: {
+ tracking() {
+ return {
+ category: 'workItems:show',
+ action: 'updated_title',
+ label: WI_TITLE_TRACK_LABEL,
+ property: '[type_work_item]',
+ };
+ },
titleWidgetData() {
return this.workItem?.widgets?.nodes?.find((widget) => widget.type === widgetTypes.title);
},
@@ -50,6 +63,7 @@ export default {
},
},
});
+ this.track();
} catch {
this.error = true;
}
diff --git a/app/assets/stylesheets/_page_specific_files.scss b/app/assets/stylesheets/_page_specific_files.scss
index 8f3b5b3b7cc..ff2b82d1806 100644
--- a/app/assets/stylesheets/_page_specific_files.scss
+++ b/app/assets/stylesheets/_page_specific_files.scss
@@ -28,7 +28,6 @@
@import './pages/service_desk';
@import './pages/settings';
@import './pages/settings_ci_cd';
-@import './pages/sherlock';
@import './pages/storage_quota';
@import './pages/tree';
@import './pages/users';
diff --git a/app/assets/stylesheets/components/whats_new.scss b/app/assets/stylesheets/components/whats_new.scss
index 4437b5b673d..98a7ea5792b 100644
--- a/app/assets/stylesheets/components/whats_new.scss
+++ b/app/assets/stylesheets/components/whats_new.scss
@@ -36,15 +36,15 @@
}
.with-performance-bar .whats-new-drawer {
- margin-top: $performance-bar-height + $header-height;
+ margin-top: calc(#{$performance-bar-height} + #{$header-height});
}
.with-system-header .whats-new-drawer {
- margin-top: $system-header-height + $header-height;
+ margin-top: calc(#{$system-header-height} + #{$header-height});
}
.with-performance-bar.with-system-header .whats-new-drawer {
- margin-top: $performance-bar-height + $system-header-height + $header-height;
+ margin-top: calc(#{$performance-bar-height} + #{$system-header-height} + #{$header-height});
}
.gl-badge.whats-new-item-badge {
diff --git a/app/assets/stylesheets/framework/contextual_sidebar.scss b/app/assets/stylesheets/framework/contextual_sidebar.scss
index 345c180d164..2a3ed29258a 100644
--- a/app/assets/stylesheets/framework/contextual_sidebar.scss
+++ b/app/assets/stylesheets/framework/contextual_sidebar.scss
@@ -357,7 +357,9 @@
}
> li {
- .badge.badge-pill {
+ // 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;
@@ -370,7 +372,9 @@
display: block;
}
- .badge.badge-pill {
+ // 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/diffs.scss b/app/assets/stylesheets/framework/diffs.scss
index 23dc16b7e7f..ffacac07517 100644
--- a/app/assets/stylesheets/framework/diffs.scss
+++ b/app/assets/stylesheets/framework/diffs.scss
@@ -34,7 +34,7 @@
@media (min-width: map-get($grid-breakpoints, md)) {
// The `+11` is to ensure the file header border shows when scrolled -
// the bottom of the compare-versions header and the top of the file header
- $mr-file-header-top: $mr-version-controls-height + $header-height + $mr-tabs-height + 11;
+ $mr-file-header-top: calc(#{$mr-version-controls-height} + #{$header-height} + #{$mr-tabs-height} + 11px);
position: -webkit-sticky;
position: sticky;
@@ -42,11 +42,11 @@
z-index: 120;
.with-system-header & {
- top: $mr-file-header-top + $system-header-height;
+ top: calc(#{$mr-file-header-top} + #{$system-header-height});
}
.with-system-header.with-performance-bar & {
- top: $mr-file-header-top + $system-header-height + $performance-bar-height;
+ top: calc(#{$mr-file-header-top} + #{$system-header-height} + #{$performance-bar-height});
}
&::before {
@@ -61,22 +61,22 @@
}
.with-performance-bar & {
- top: $mr-file-header-top + $performance-bar-height;
+ top: calc(#{$mr-file-header-top} + #{$performance-bar-height});
}
&.is-commit {
- top: $header-height + $commit-stat-summary-height;
+ top: calc(#{$header-height} + #{$commit-stat-summary-height});
.with-performance-bar & {
- top: $header-height + $commit-stat-summary-height + $performance-bar-height;
+ top: calc(#{$header-height} + #{$commit-stat-summary-height} + #{$performance-bar-height});
}
}
&.is-compare {
- top: $header-height + $compare-branches-sticky-header-height;
+ top: calc(#{$header-height} + #{$compare-branches-sticky-header-height});
.with-performance-bar & {
- top: $performance-bar-height + $header-height + $compare-branches-sticky-header-height;
+ top: calc(#{$performance-bar-height} + #{$header-height} + #{$compare-branches-sticky-header-height});
}
}
}
@@ -99,17 +99,17 @@
.with-performance-bar &.conflict .file-title,
.with-performance-bar &.conflict .file-title-flex-parent {
- top: $header-height + $performance-bar-height;
+ top: calc(#{$header-height} + #{$performance-bar-height});
}
.with-system-header &.conflict .file-title,
.with-system-header &.conflict .file-title-flex-parent {
- top: $header-height + $system-header-height;
+ top: calc(#{$header-height} + #{$system-header-height});
}
.with-system-header.with-performance-bar &.conflict .file-title,
.with-system-header.with-performance-bar &.conflict .file-title-flex-parent {
- top: $header-height + $performance-bar-height + $system-header-height;
+ top: calc(#{$header-height} + #{$performance-bar-height} + #{$system-header-height});
}
}
@@ -825,7 +825,7 @@ table.code {
top: $header-height;
.with-performance-bar & {
- top: $header-height + $performance-bar-height;
+ top: calc(#{$header-height} + #{$performance-bar-height});
}
}
}
@@ -839,12 +839,12 @@ table.code {
@include media-breakpoint-up(sm) {
@include gl-sticky;
- top: $header-height + $mr-tabs-height;
+ top: calc(#{$header-height} + #{$mr-tabs-height});
@include gl-bg-white;
z-index: 200;
.with-performance-bar & {
- top: $header-height + $mr-tabs-height + $performance-bar-height;
+ top: calc(#{$header-height} + #{$mr-tabs-height} + #{$performance-bar-height});
}
&.is-stuck {
diff --git a/app/assets/stylesheets/framework/emojis.scss b/app/assets/stylesheets/framework/emojis.scss
index 1ddde3d2ed6..a31910e3090 100644
--- a/app/assets/stylesheets/framework/emojis.scss
+++ b/app/assets/stylesheets/framework/emojis.scss
@@ -43,6 +43,10 @@ gl-emoji {
border-bottom-color: transparent;
}
+.emoji-picker-category-active {
+ border-bottom-color: var(--gl-theme-accent, $theme-indigo-500);
+}
+
.emoji-picker .gl-new-dropdown-inner > :last-child {
padding-bottom: 0;
}
diff --git a/app/assets/stylesheets/framework/flash.scss b/app/assets/stylesheets/framework/flash.scss
index 30a1c8af414..b51daf0e4dc 100644
--- a/app/assets/stylesheets/framework/flash.scss
+++ b/app/assets/stylesheets/framework/flash.scss
@@ -75,6 +75,10 @@ $notification-box-shadow-color: rgba(0, 0, 0, 0.25);
.flash-action {
display: inline-block;
}
+
+ .gl-alert {
+ @include gl-my-4;
+ }
}
@include media-breakpoint-down(sm) {
diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss
index 44b099fc873..68535badd78 100644
--- a/app/assets/stylesheets/framework/header.scss
+++ b/app/assets/stylesheets/framework/header.scss
@@ -150,7 +150,7 @@ $top-nav-hover-bg: var(--indigo-900-alpha-008, $indigo-900-alpha-008) !important
}
li {
- .badge.badge-pill:not(.merge-request-badge) {
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge) {
box-shadow: none;
font-weight: $gl-font-weight-bold;
}
@@ -417,7 +417,7 @@ $top-nav-hover-bg: var(--indigo-900-alpha-008, $indigo-900-alpha-008) !important
.title-container,
.navbar-nav {
- .badge.badge-pill:not(.merge-request-badge) {
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge) {
position: inherit;
font-weight: $gl-font-weight-normal;
margin-left: -6px;
diff --git a/app/assets/stylesheets/framework/layout.scss b/app/assets/stylesheets/framework/layout.scss
index f79dc38f2f7..fb05f8575ef 100644
--- a/app/assets/stylesheets/framework/layout.scss
+++ b/app/assets/stylesheets/framework/layout.scss
@@ -140,7 +140,7 @@ body {
}
.with-performance-bar .layout-page {
- margin-top: $header-height + $performance-bar-height;
+ margin-top: calc(#{$header-height} + #{$performance-bar-height});
}
.fullscreen-layout {
@@ -201,3 +201,9 @@ body {
padding-right: 0;
}
}
+
+@include media-breakpoint-up(sm) {
+ .logged-out-marketing-header-candidate {
+ --header-height: 72px;
+ }
+}
diff --git a/app/assets/stylesheets/framework/mixins.scss b/app/assets/stylesheets/framework/mixins.scss
index 33f7aa4dba1..1e51bf3d974 100644
--- a/app/assets/stylesheets/framework/mixins.scss
+++ b/app/assets/stylesheets/framework/mixins.scss
@@ -276,7 +276,7 @@
top: $header-height;
.with-performance-bar & {
- top: $header-height + $performance-bar-height;
+ top: calc(#{$header-height} + #{$performance-bar-height});
}
}
@@ -419,6 +419,30 @@
height: $gl-font-size * $code-line-height * 0.9;
}
+@mixin email-code-block {
+ .code.language-email {
+ font-family: inherit;
+ font-size: inherit;
+
+ code {
+ white-space: pre-wrap;
+ font-family: inherit;
+
+ // Rouge `Name.Tag` and `Operator` token (email header key + ':')
+ .nt,
+ .o {
+ color: inherit;
+ font-weight: bold;
+ }
+
+ // Rouge `Name.Attribute` token (email header value)
+ .na {
+ color: inherit;
+ }
+ }
+ }
+}
+
@mixin avatar-counter($border-radius: 1em) {
background-color: $gray-darkest;
color: $white;
diff --git a/app/assets/stylesheets/framework/secondary_navigation_elements.scss b/app/assets/stylesheets/framework/secondary_navigation_elements.scss
index 685f1f413e6..563075b911c 100644
--- a/app/assets/stylesheets/framework/secondary_navigation_elements.scss
+++ b/app/assets/stylesheets/framework/secondary_navigation_elements.scss
@@ -40,9 +40,11 @@
a.active {
color: $black;
font-weight: $gl-font-weight-bold;
+ border-bottom: 2px solid var(--gl-theme-accent, $theme-indigo-500);
.badge.badge-pill {
color: $black;
+ font-weight: $gl-font-weight-bold;
}
}
@@ -126,14 +128,6 @@
input {
display: inline-block;
position: relative;
-
- &:not[type='checkbox'] {
- /* Medium devices (desktops, 992px and up) */
- @include media-breakpoint-up(md) { width: 200px; }
-
- /* Large devices (large desktops, 1200px and up) */
- @include media-breakpoint-up(lg) { width: 250px; }
- }
}
@include media-breakpoint-up(md) {
diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss
index 6c7fc25f2d9..e77971d5280 100644
--- a/app/assets/stylesheets/framework/sidebar.scss
+++ b/app/assets/stylesheets/framework/sidebar.scss
@@ -81,7 +81,7 @@
}
.with-performance-bar .right-sidebar.affix {
- top: $header-height + $performance-bar-height;
+ top: calc(#{$header-height} + #{$performance-bar-height});
}
@mixin maintain-sidebar-dimensions {
diff --git a/app/assets/stylesheets/framework/system_messages.scss b/app/assets/stylesheets/framework/system_messages.scss
index 1cb34bea069..89585fd96ae 100644
--- a/app/assets/stylesheets/framework/system_messages.scss
+++ b/app/assets/stylesheets/framework/system_messages.scss
@@ -49,11 +49,11 @@
// right sidebar eg: MR page
.nav-sidebar,
.right-sidebar {
- top: $system-header-height + $header-height;
+ top: calc(#{$system-header-height} + #{$header-height});
}
.content-wrapper-margin {
- margin-top: $system-header-height + $header-height;
+ margin-top: calc(#{$system-header-height} + #{$header-height});
}
// Performance Bar
@@ -66,14 +66,14 @@
}
.layout-page {
- margin-top: $header-height + $performance-bar-height + $system-header-height;
+ margin-top: calc(#{$header-height} + #{$performance-bar-height} + #{$system-header-height});
}
// left sidebar eg: project page
// right sidebar eg: MR page
.nav-sidebar,
.right-sidebar {
- top: $header-height + $performance-bar-height + $system-header-height;
+ top: calc(#{$header-height} + #{$performance-bar-height} + #{$system-header-height});
}
}
}
@@ -97,7 +97,7 @@
.boards-list,
.board-swimlanes {
- height: calc(100vh - #{$header-height + $breadcrumb-min-height + $performance-bar-height + $system-footer-height + $gl-padding-32});
+ height: calc(100vh - (#{$header-height} + #{$breadcrumb-min-height} + #{$performance-bar-height} + #{$system-footer-height} + #{$gl-padding-32}));
}
}
diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss
index 16ff4b81f95..51c41c46f61 100644
--- a/app/assets/stylesheets/framework/typography.scss
+++ b/app/assets/stylesheets/framework/typography.scss
@@ -365,10 +365,17 @@
padding: 0;
margin: 0 0 16px;
+ // Lists embedded in other lists can be "loose" or "tight"
+ // Remove bottom margin for all lists (default for tight lists)
ul,
ol {
margin-bottom: 0;
}
+
+ // Loose lists need bottom margin added back
+ p ~ ol,
+ p ~ ul {
+ margin-bottom: 16px; }
}
ul:dir(rtl),
@@ -420,12 +427,12 @@
list-style-type: none;
position: relative;
min-height: 22px;
- padding-left: 28px;
- margin-left: 0 !important;
+ padding-inline-start: 28px;
+ margin-inline-start: 0 !important;
> input.task-list-item-checkbox {
position: absolute;
- left: 8px;
+ inset-inline-start: 8px;
top: 5px;
}
}
@@ -590,6 +597,8 @@
.text-justify {
text-align: justify !important;
}
+
+ @include email-code-block;
}
/**
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index 026aeeb1e8e..21add43ad3f 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -433,7 +433,7 @@ $browser-scrollbar-size: 10px;
/*
* Misc
*/
-$header-height: 40px;
+$header-height: var(--header-height, 40px);
$header-zindex: 1000;
$zindex-dropdown-menu: 300;
$suggestion-header-height: 46px;
@@ -610,6 +610,14 @@ $pagination-disabled-color: #cdcdcd;
*/
$status-icon-size: 22px;
+
+/*
+* Social Icons
+*/
+$twitter: #1d9bf0;
+$skype: #0078d7;
+$linkedin: #2867b2;
+
/*
* Award emoji
*/
@@ -667,18 +675,18 @@ $issue-boards-filter-height: 68px;
$issue-boards-filter-height-md: 110px;
$issue-boards-filter-height-sm: 299px;
$issue-boards-breadcrumbs-height-xs: 63px;
-$issue-board-list-difference-xs: $header-height + $issue-boards-breadcrumbs-height-xs;
-$issue-board-list-difference-sm: $header-height + $breadcrumb-min-height;
-$issue-board-list-difference-md: $issue-board-list-difference-sm + $issue-boards-filter-height-md;
-$issue-board-list-difference-lg: $issue-board-list-difference-sm + $issue-boards-filter-height;
+$issue-board-list-difference-xs: calc(#{$header-height} + #{$issue-boards-breadcrumbs-height-xs});
+$issue-board-list-difference-sm: calc(#{$header-height} + #{$breadcrumb-min-height});
+$issue-board-list-difference-md: calc(#{$issue-board-list-difference-sm} + #{$issue-boards-filter-height-md});
+$issue-board-list-difference-lg: calc(#{$issue-board-list-difference-sm} + #{$issue-boards-filter-height});
/*
The following heights are used in environment_logs.scss and are used for calculation of the log viewer height.
*/
$environment-logs-breadcrumbs-height: 63px;
$environment-logs-breadcrumbs-height-md: $breadcrumb-min-height;
-$environment-logs-difference-xs-up: $header-height + $environment-logs-breadcrumbs-height;
-$environment-logs-difference-md-up: $header-height + $environment-logs-breadcrumbs-height-md;
+$environment-logs-difference-xs-up: calc(#{$header-height} + #{$environment-logs-breadcrumbs-height});
+$environment-logs-difference-md-up: calc(#{$header-height} + #{$environment-logs-breadcrumbs-height-md});
/*
* Avatar
@@ -867,21 +875,12 @@ $image-comment-cursor-left-offset: 12;
$image-comment-cursor-top-offset: 12;
/*
-Add GitLab Slack Application
-*/
-$add-to-slack-popup-max-width: 400px;
-$add-to-slack-gif-max-width: 850px;
-$add-to-slack-well-max-width: 750px;
-$add-to-slack-logo-size: 100px;
-
-/*
Security & Compliance Carousel
*/
$security-and-compliance-carousel-image-carousel-width: 1000px;
$security-and-compliance-carousel-image-discover-button-width: 45%;
$security-and-compliance-carousel-image-discover-buttons-max-width: 280px;
$security-and-compliance-carousel-image-discover-footer-max-width: 500px;
-$security-and-compliance-carousel-image-discover-feedback-width: 30%;
$security-and-compliance-carousel-image-discover-text-carousel-max-width: 650px;
$security-and-compliance-carousel-image-discover-text-carousel-caption-height: 100%;
$security-and-compliance-carousel-image-discover-text-carousel-caption-max-width: 500px;
diff --git a/app/assets/stylesheets/framework/variables_overrides.scss b/app/assets/stylesheets/framework/variables_overrides.scss
index acfda718e77..ea81863e094 100644
--- a/app/assets/stylesheets/framework/variables_overrides.scss
+++ b/app/assets/stylesheets/framework/variables_overrides.scss
@@ -5,7 +5,7 @@
$secondary: $gray-light;
$input-disabled-bg: $gray-light;
-$input-border-color: $gray-100;
+$input-border-color: $gray-400;
$input-color: $gl-text-color;
$input-font-size: $gl-font-size;
$font-family-sans-serif: $regular-font;
diff --git a/app/assets/stylesheets/framework/wells.scss b/app/assets/stylesheets/framework/wells.scss
index d550a1faa18..b796f04750b 100644
--- a/app/assets/stylesheets/framework/wells.scss
+++ b/app/assets/stylesheets/framework/wells.scss
@@ -65,33 +65,6 @@
display: inline;
}
- .branch-link {
- margin-bottom: 2px;
- }
-
- .limit-box {
- cursor: pointer;
- display: inline-flex;
- align-items: center;
- background-color: $red-100;
- border-radius: $border-radius-default;
- text-align: center;
-
- &:hover {
- background-color: $red-200;
- }
-
- .limit-icon {
- margin: 0 4px;
- }
-
- .limit-message {
- line-height: 16px;
- margin-right: 8px;
- font-size: 12px;
- }
- }
-
svg {
vertical-align: text-top;
}
diff --git a/app/assets/stylesheets/highlight/white_base.scss b/app/assets/stylesheets/highlight/white_base.scss
index c0f8475323a..80052f4a4d5 100644
--- a/app/assets/stylesheets/highlight/white_base.scss
+++ b/app/assets/stylesheets/highlight/white_base.scss
@@ -255,18 +255,23 @@ span.highlight_word {
.hll { background-color: $white-hll-bg; }
-.c { color: $white-c;
+.c,
+.hljs-comment { color: $white-c;
font-style: italic; }
.err { color: $white-err;
background-color: $white-err-bg; }
-.k { font-weight: $gl-font-weight-bold; }
+
+.k,
+.hljs-variable.language_,
+.hljs-built_in { font-weight: $gl-font-weight-bold; }
.o { font-weight: $gl-font-weight-bold; }
.cm { color: $white-cm;
font-style: italic; }
-.cp { color: $white-cp;
+.cp,
+.hljs-meta { color: $white-cp;
font-weight: $gl-font-weight-bold; }
.c1 { color: $white-c1;
@@ -310,20 +315,34 @@ span.highlight_word {
font-weight: $gl-font-weight-bold; }
.gt { color: $white-gt; }
.kc { font-weight: $gl-font-weight-bold; }
-.kd { font-weight: $gl-font-weight-bold; }
+
+.kd,
+.hljs-keyword { font-weight: $gl-font-weight-bold; }
.kn { font-weight: $gl-font-weight-bold; }
.kp { font-weight: $gl-font-weight-bold; }
.kr { font-weight: $gl-font-weight-bold; }
-.kt { color: $white-kt;
+.kt,
+.hljs-type { color: $white-kt;
font-weight: $gl-font-weight-bold; }
.m { color: $white-m; }
.s { color: $white-s; }
-.n { color: $white-n; }
-.na { color: $white-na; }
-.nb { color: $white-nb; }
-.nc { color: $white-nc;
+.n,
+.hljs-built_in { color: $white-n; }
+
+.na,
+.hljs-attr,
+.hljs-property,
+.hljs-title.function_ { color: $white-na; }
+
+.nb,
+.hljs-title.class_,
+.hljs-literal { color: $white-nb; }
+
+.nc,
+.hljs-title.class_,
+.hljs-built_in { color: $white-nc;
font-weight: $gl-font-weight-bold; }
.no { color: $white-no; }
.ni { color: $white-ni; }
@@ -331,7 +350,9 @@ span.highlight_word {
.ne { color: $white-ne;
font-weight: $gl-font-weight-bold; }
-.nf { color: $white-nf;
+.nf,
+.hljs-title,
+.hljs-title.function_ { color: $white-nf;
font-weight: $gl-font-weight-bold; }
.nn { color: $white-nn; }
.nt { color: $white-nt; }
@@ -340,7 +361,9 @@ span.highlight_word {
.w { color: $white-w; }
.mf { color: $white-mf; }
.mh { color: $white-mh; }
-.mi { color: $white-mi; }
+
+.mi,
+.hljs-number { color: $white-mi; }
.mo { color: $white-mo; }
.sb { color: $white-sb; }
.sc { color: $white-sc; }
@@ -351,7 +374,9 @@ span.highlight_word {
.si { color: $white-si; }
.sx { color: $white-sx; }
.sr { color: $white-sr; }
-.s1 { color: $white-s1; }
+
+.s1,
+.hljs-string { color: $white-s1; }
.ss { color: $white-ss; }
.bp { color: $white-bp; }
.vc { color: $white-vc; }
diff --git a/app/assets/stylesheets/notify.scss b/app/assets/stylesheets/notify.scss
index d281f62c370..feb4ea77e58 100644
--- a/app/assets/stylesheets/notify.scss
+++ b/app/assets/stylesheets/notify.scss
@@ -1,3 +1,4 @@
+@import 'framework/mixins';
@import 'framework/variables';
img {
@@ -38,3 +39,14 @@ pre.commit-message {
.gl-label-text-dark {
color: $gl-text-color;
}
+
+.content {
+ .markdown-code-block pre.code {
+ padding: $gl-padding-8 $input-horizontal-padding;
+ margin: 0 0 $gl-padding-8;
+ border: 1px solid $gray-100;
+ border-radius: $border-radius-small;
+ }
+
+ @include email-code-block;
+}
diff --git a/app/assets/stylesheets/page_bundles/boards.scss b/app/assets/stylesheets/page_bundles/boards.scss
index d4c59a6ab0c..f91ca489bdf 100644
--- a/app/assets/stylesheets/page_bundles/boards.scss
+++ b/app/assets/stylesheets/page_bundles/boards.scss
@@ -1,9 +1,5 @@
@import 'mixins_and_variables_and_functions';
-.user-can-drag {
- cursor: grab;
-}
-
.is-ghost {
opacity: 0.3;
pointer-events: none;
diff --git a/app/assets/stylesheets/page_bundles/build.scss b/app/assets/stylesheets/page_bundles/build.scss
index ed62e055427..d55d6b27576 100644
--- a/app/assets/stylesheets/page_bundles/build.scss
+++ b/app/assets/stylesheets/page_bundles/build.scss
@@ -13,7 +13,7 @@
border: 1px solid var(--border-color, $border-color);
.with-performance-bar & {
- top: $header-height + $performance-bar-height;
+ top: calc(#{$header-height} + #{$performance-bar-height});
}
}
@@ -21,10 +21,10 @@
@include build-log-top-bar(50px);
&.has-archived-block {
- top: $header-height + 28px;
+ top: calc(#{$header-height} + 28px);
.with-performance-bar & {
- top: $header-height + $performance-bar-height + 28px;
+ top: calc(#{$header-height} + #{$performance-bar-height} + 28px);
}
}
diff --git a/app/assets/stylesheets/page_bundles/cycle_analytics.scss b/app/assets/stylesheets/page_bundles/cycle_analytics.scss
deleted file mode 100644
index 5d42ece32c9..00000000000
--- a/app/assets/stylesheets/page_bundles/cycle_analytics.scss
+++ /dev/null
@@ -1,6 +0,0 @@
-@import 'mixins_and_variables_and_functions';
-
-.cycle-analytics {
- margin: 24px auto 0;
- position: relative;
-}
diff --git a/app/assets/stylesheets/page_bundles/import.scss b/app/assets/stylesheets/page_bundles/import.scss
index 79468ce62ce..b7a4d9564fe 100644
--- a/app/assets/stylesheets/page_bundles/import.scss
+++ b/app/assets/stylesheets/page_bundles/import.scss
@@ -41,7 +41,7 @@ $import-bar-height: $gl-spacing-scale-11;
z-index: 3;
html.with-performance-bar & {
- top: $header-height + $performance-bar-height;
+ top: calc(#{$header-height} + #{$performance-bar-height});
}
}
diff --git a/app/assets/stylesheets/page_bundles/issues_list.scss b/app/assets/stylesheets/page_bundles/issues_list.scss
index 8a958bdf0c5..41515a98e0a 100644
--- a/app/assets/stylesheets/page_bundles/issues_list.scss
+++ b/app/assets/stylesheets/page_bundles/issues_list.scss
@@ -35,10 +35,6 @@
}
}
-.user-can-drag {
- cursor: grab;
-}
-
.is-ghost {
opacity: 0.3;
pointer-events: none;
diff --git a/app/assets/stylesheets/page_bundles/members.scss b/app/assets/stylesheets/page_bundles/members.scss
index 62dd3dcb9c0..8d2c0a8ca22 100644
--- a/app/assets/stylesheets/page_bundles/members.scss
+++ b/app/assets/stylesheets/page_bundles/members.scss
@@ -22,10 +22,6 @@
}
}
-.members-ldap {
- align-self: center;
-}
-
.card {
.card-header {
.badge.badge-pill {
diff --git a/app/assets/stylesheets/page_bundles/merge_requests.scss b/app/assets/stylesheets/page_bundles/merge_requests.scss
index 02113fe8b58..37ab2e2be2b 100644
--- a/app/assets/stylesheets/page_bundles/merge_requests.scss
+++ b/app/assets/stylesheets/page_bundles/merge_requests.scss
@@ -36,7 +36,7 @@
// If they don't match, the file tree and the diff files stick
// to the top at different heights, which is a bad-looking defect
$diff-file-header-top: 11px;
- $top-pos: $header-height + $mr-tabs-height + $mr-version-controls-height + $diff-file-header-top;
+ $top-pos: calc(#{$header-height} + #{$mr-tabs-height} + #{$mr-version-controls-height} + #{$diff-file-header-top});
position: -webkit-sticky;
position: sticky;
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index 8600a4059d8..cdef843c9b4 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -514,7 +514,7 @@
}
.with-performance-bar .right-sidebar {
- top: $header-height + $performance-bar-height;
+ top: calc(#{$header-height} + #{$performance-bar-height});
}
.sidebar-move-issue-confirmation-button {
diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss
index 880231f5644..d77c8a40a79 100644
--- a/app/assets/stylesheets/pages/issues.scss
+++ b/app/assets/stylesheets/pages/issues.scss
@@ -256,7 +256,7 @@ ul.related-merge-requests > li gl-emoji {
}
.with-performance-bar .issue-sticky-header {
- top: $header-height + $performance-bar-height;
+ top: calc(#{$header-height} + #{$performance-bar-height});
}
@include media-breakpoint-up(md) {
diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss
index c7b4dd660d0..82216b8d5c5 100644
--- a/app/assets/stylesheets/pages/labels.scss
+++ b/app/assets/stylesheets/pages/labels.scss
@@ -68,13 +68,6 @@
color: $white;
}
-.dropdown-labels-error {
- padding: 5px 10px;
- margin-bottom: 10px;
- background-color: $red-500;
- color: $white;
-}
-
.manage-labels-list {
padding: 0;
margin-bottom: 0;
@@ -114,9 +107,8 @@
display: none;
}
-.label-subscribe-button {
- width: 105px;
- font-weight: 200;
+.label-subscription {
+ width: 109px;
}
.labels-container {
diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss
index 71ddbf175e9..fffea301a4f 100644
--- a/app/assets/stylesheets/pages/login.scss
+++ b/app/assets/stylesheets/pages/login.scss
@@ -10,6 +10,8 @@
.flash-container {
margin-bottom: $gl-padding;
+ position: relative;
+ top: 8px;
}
.brand-holder {
@@ -203,7 +205,7 @@
&.with-system-header {
.login-page-broadcast {
- margin-top: $system-header-height + $header-height;
+ margin-top: calc(#{$system-header-height} + #{$header-height});
}
}
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index a4b8e912614..10026e290e8 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -689,14 +689,14 @@ $tabs-holder-z-index: 250;
@include media-breakpoint-up(md) {
position: -webkit-sticky;
position: sticky;
- top: $header-height + $mr-tabs-height;
+ top: calc(#{$header-height} + #{$mr-tabs-height});
.with-system-header & {
- top: $header-height + $mr-tabs-height + $system-header-height;
+ top: calc(#{$header-height} + #{$mr-tabs-height} + #{$system-header-height});
}
.with-system-header.with-performance-bar & {
- top: $header-height + $mr-tabs-height + $system-header-height + $performance-bar-height;
+ top: calc(#{$header-height} + #{$mr-tabs-height} + #{$system-header-height} + #{$performance-bar-height});
}
.mr-version-menus-container {
@@ -704,7 +704,7 @@ $tabs-holder-z-index: 250;
}
.with-performance-bar & {
- top: $header-height + $performance-bar-height + $mr-tabs-height;
+ top: calc(#{$header-height} + #{$performance-bar-height} + #{$mr-tabs-height});
}
}
}
@@ -717,11 +717,11 @@ $tabs-holder-z-index: 250;
border-bottom: 1px solid $border-color;
.with-system-header & {
- top: $header-height + $system-header-height;
+ top: calc(#{$header-height} + #{$system-header-height});
}
.with-system-header.with-performance-bar & {
- top: $header-height + $system-header-height + $performance-bar-height;
+ top: calc(#{$header-height} + #{$system-header-height} + #{$performance-bar-height});
}
@include media-breakpoint-up(sm) {
@@ -752,7 +752,7 @@ $tabs-holder-z-index: 250;
.with-performance-bar {
.merge-request-tabs-holder,
.epic-tabs-holder {
- top: $header-height + $performance-bar-height;
+ top: calc(#{$header-height} + #{$performance-bar-height});
}
}
@@ -957,10 +957,10 @@ $tabs-holder-z-index: 250;
.mr-compare {
.diff-file .file-title-flex-parent {
- top: $header-height + $mr-tabs-height + 36px;
+ top: calc(#{$header-height} + #{$mr-tabs-height} + 36px);
.with-performance-bar & {
- top: $performance-bar-height + $header-height + $mr-tabs-height + 36px;
+ top: calc(#{$performance-bar-height} + #{$header-height} + #{$mr-tabs-height} + 36px);
}
}
}
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index 04da75b586f..d8c3851748d 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -368,7 +368,7 @@ $system-note-svg-size: 16px;
border-radius: 0;
@media (min-width: map-get($grid-breakpoints, md)) {
- top: $mr-tabs-height + $header-height;
+ top: calc(#{$mr-tabs-height} + #{$header-height});
.with-performance-bar & {
top: 123px;
diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss
index a7ed7172f5f..f76a8030e5b 100644
--- a/app/assets/stylesheets/pages/profile.scss
+++ b/app/assets/stylesheets/pages/profile.scss
@@ -363,23 +363,22 @@ table.u2f-registrations {
color: $gl-text-color-secondary;
}
-.gitlab-slack-gif {
- width: 100%;
- max-width: $add-to-slack-gif-max-width;
+.gitlab-slack-body {
+ max-width: 420px;
}
-.gitlab-slack-well {
- background-color: $white;
- box-shadow: none;
- max-width: $add-to-slack-well-max-width;
+.gitlab-slack-slack-logo {
+ transform: scale(200%); // Slack logo SVG is scaled down 50% and has empty space around it
}
-.gitlab-slack-logo {
- width: $add-to-slack-logo-size;
- height: $add-to-slack-logo-size;
+.skype-icon {
+ color: $skype;
}
-.gitlab-slack-popup {
- width: 100%;
- max-width: $add-to-slack-popup-max-width;
+.linkedin-icon {
+ color: $linkedin;
+}
+
+.twitter-icon {
+ color: $twitter;
}
diff --git a/app/assets/stylesheets/pages/settings.scss b/app/assets/stylesheets/pages/settings.scss
index 37e272cfff7..633051918a4 100644
--- a/app/assets/stylesheets/pages/settings.scss
+++ b/app/assets/stylesheets/pages/settings.scss
@@ -293,10 +293,8 @@
}
}
-.modal-doorkeepr-auth {
- .modal-body {
- padding: $gl-padding;
- }
+.doorkeeper-authorize {
+ max-width: px-to-rem(500px);
}
.created-deploy-token-container {
@@ -316,12 +314,6 @@
}
}
-.mirror-error-badge {
- background-color: $red-400;
- border-radius: $border-radius-default;
- color: $white;
-}
-
.push-pull-table {
margin-top: 1em;
}
diff --git a/app/assets/stylesheets/pages/sherlock.scss b/app/assets/stylesheets/pages/sherlock.scss
deleted file mode 100644
index 55b0b5295af..00000000000
--- a/app/assets/stylesheets/pages/sherlock.scss
+++ /dev/null
@@ -1,31 +0,0 @@
-table .sherlock-code {
- max-width: 700px;
-}
-
-.sherlock-code {
- pre {
- word-wrap: normal;
-
- code {
- white-space: pre;
- }
- }
-}
-
-.sherlock-line-samples-table {
- thead th,
- tbody td {
- font-size: 13px !important;
- text-align: right;
- padding: 0 10px !important;
- }
-
- .slow {
- color: $red-500;
- font-weight: $gl-font-weight-bold;
- }
-}
-
-.sherlock-file-sample pre {
- padding-top: 28px !important;
-}
diff --git a/app/assets/stylesheets/pages/users.scss b/app/assets/stylesheets/pages/users.scss
index 917d16a9c53..3dcc17df61a 100644
--- a/app/assets/stylesheets/pages/users.scss
+++ b/app/assets/stylesheets/pages/users.scss
@@ -1,7 +1,3 @@
-.user-sort-dropdown {
- margin-left: $gl-padding-8;
-}
-
.user-search-form {
position: relative;
diff --git a/app/assets/stylesheets/performance_bar.scss b/app/assets/stylesheets/performance_bar.scss
index f2874e67796..5024b082b99 100644
--- a/app/assets/stylesheets/performance_bar.scss
+++ b/app/assets/stylesheets/performance_bar.scss
@@ -129,5 +129,5 @@
}
html.with-performance-bar .nav-sidebar {
- top: $header-height + $performance-bar-height;
+ top: calc(#{$header-height} + #{$performance-bar-height});
}
diff --git a/app/assets/stylesheets/startup/startup-dark.scss b/app/assets/stylesheets/startup/startup-dark.scss
index c9ff8205142..c72de0e6f29 100644
--- a/app/assets/stylesheets/startup/startup-dark.scss
+++ b/app/assets/stylesheets/startup/startup-dark.scss
@@ -140,7 +140,7 @@ h1 {
color: #fafafa;
background-color: #333;
background-clip: padding-box;
- border: 1px solid #404040;
+ border: 1px solid #868686;
border-radius: 0.25rem;
}
@media (prefers-reduced-motion: reduce) {
@@ -314,6 +314,10 @@ h1 {
padding-left: 0.6em;
border-radius: 10rem;
}
+.badge-info {
+ color: #fff;
+ background-color: #428fdc;
+}
.bg-transparent {
background-color: transparent !important;
}
@@ -372,6 +376,24 @@ h1 {
padding-left: 0.5rem;
padding-right: 0.5rem;
}
+.gl-badge.sm {
+ padding-top: 0;
+ padding-bottom: 0;
+}
+.gl-badge.badge-info {
+ background-color: #064787;
+ color: #9dc7f1;
+}
+a.gl-badge.badge-info.active,
+a.gl-badge.badge-info:active {
+ color: #e9f3fc;
+ background-color: #0b5cad;
+}
+a.gl-badge.badge-info:active {
+ box-shadow: inset 0 0 0 1px rgba(51, 51, 51, 0.8),
+ 0 0 0 1px rgba(51, 51, 51, 0.4), 0 0 0 4px rgba(66, 143, 220, 0.48);
+ outline: none;
+}
.gl-button .gl-badge {
top: 0;
}
@@ -704,7 +726,7 @@ input {
padding: 0 16px;
z-index: 1000;
margin-bottom: 0;
- min-height: 40px;
+ min-height: var(--header-height, 40px);
border: 0;
position: fixed;
top: 0;
@@ -729,7 +751,7 @@ input {
display: flex;
justify-content: space-between;
position: relative;
- min-height: 40px;
+ min-height: var(--header-height, 40px);
padding-left: 0;
}
.navbar-gitlab .header-content .title-container {
@@ -815,7 +837,7 @@ input {
.container-fluid
.navbar-nav
li
- .badge.badge-pill:not(.merge-request-badge) {
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge) {
box-shadow: none;
font-weight: 600;
}
@@ -898,8 +920,10 @@ input {
line-height: 18px;
margin: 4px 0 4px 2px;
}
-.title-container .badge.badge-pill:not(.merge-request-badge),
-.navbar-nav .badge.badge-pill:not(.merge-request-badge) {
+.title-container
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge),
+.navbar-nav
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge) {
position: inherit;
font-weight: 400;
margin-left: -6px;
@@ -910,17 +934,22 @@ input {
border-radius: 7px;
box-shadow: 0 1px 0 rgba(76, 78, 84, 0.2);
}
-.title-container .badge.badge-pill:not(.merge-request-badge).green-badge,
-.navbar-nav .badge.badge-pill:not(.merge-request-badge).green-badge {
+.title-container
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge).green-badge,
+.navbar-nav
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge).green-badge {
background-color: var(--green-400, #108548);
}
.title-container
- .badge.badge-pill:not(.merge-request-badge).merge-requests-count,
-.navbar-nav .badge.badge-pill:not(.merge-request-badge).merge-requests-count {
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge).merge-requests-count,
+.navbar-nav
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge).merge-requests-count {
background-color: var(--orange-400, #ab6100);
}
-.title-container .badge.badge-pill:not(.merge-request-badge).todos-count,
-.navbar-nav .badge.badge-pill:not(.merge-request-badge).todos-count {
+.title-container
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge).todos-count,
+.navbar-nav
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge).todos-count {
background-color: var(--blue-400, #1f75cb);
}
.title-container .canary-badge .badge,
@@ -1030,7 +1059,7 @@ input {
left: 0;
z-index: 600;
width: 220px;
- top: 40px;
+ top: var(--header-height, 40px);
background-color: #303030;
transform: translate3d(0, 0, 0);
}
@@ -1367,7 +1396,7 @@ 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 {
+.sidebar-top-level-items > li .badge.badge-pill:not(.gl-badge) {
border-radius: 0.5rem;
padding-top: 0.125rem;
padding-bottom: 0.125rem;
@@ -1381,7 +1410,7 @@ input {
.sidebar-sub-level-items:not(.is-fly-out-only) {
display: block;
}
-.sidebar-top-level-items > li.active .badge.badge-pill {
+.sidebar-top-level-items > li.active .badge.badge-pill:not(.gl-badge) {
font-weight: 400;
color: #9dc7f1;
}
@@ -1766,6 +1795,9 @@ body.gl-dark {
.nav-sidebar li.active:not(.fly-out-top-item) > a:not(.has-sub-items) {
background-color: var(--indigo-900-alpha-008);
}
+body.gl-dark {
+ --gl-theme-accent: #868686;
+}
body.gl-dark .navbar-gitlab {
background-color: #fafafa;
}
@@ -1838,7 +1870,7 @@ body.gl-dark .header-search input::placeholder {
color: rgba(250, 250, 250, 0.8);
}
body.gl-dark .header-search input:active::placeholder {
- color: #fafafa;
+ color: #868686;
}
body.gl-dark .search form {
background-color: rgba(250, 250, 250, 0.2);
diff --git a/app/assets/stylesheets/startup/startup-general.scss b/app/assets/stylesheets/startup/startup-general.scss
index a57202515ad..2f79c86cdc6 100644
--- a/app/assets/stylesheets/startup/startup-general.scss
+++ b/app/assets/stylesheets/startup/startup-general.scss
@@ -121,7 +121,7 @@ h1 {
color: #303030;
background-color: #fff;
background-clip: padding-box;
- border: 1px solid #dbdbdb;
+ border: 1px solid #868686;
border-radius: 0.25rem;
}
@media (prefers-reduced-motion: reduce) {
@@ -295,6 +295,10 @@ h1 {
padding-left: 0.6em;
border-radius: 10rem;
}
+.badge-info {
+ color: #fff;
+ background-color: #1f75cb;
+}
.bg-transparent {
background-color: transparent !important;
}
@@ -353,6 +357,24 @@ h1 {
padding-left: 0.5rem;
padding-right: 0.5rem;
}
+.gl-badge.sm {
+ padding-top: 0;
+ padding-bottom: 0;
+}
+.gl-badge.badge-info {
+ background-color: #cbe2f9;
+ color: #0b5cad;
+}
+a.gl-badge.badge-info.active,
+a.gl-badge.badge-info:active {
+ color: #033464;
+ background-color: #9dc7f1;
+}
+a.gl-badge.badge-info:active {
+ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.8),
+ 0 0 0 1px rgba(255, 255, 255, 0.4), 0 0 0 4px rgba(31, 117, 203, 0.48);
+ outline: none;
+}
.gl-button .gl-badge {
top: 0;
}
@@ -685,7 +707,7 @@ input {
padding: 0 16px;
z-index: 1000;
margin-bottom: 0;
- min-height: 40px;
+ min-height: var(--header-height, 40px);
border: 0;
position: fixed;
top: 0;
@@ -710,7 +732,7 @@ input {
display: flex;
justify-content: space-between;
position: relative;
- min-height: 40px;
+ min-height: var(--header-height, 40px);
padding-left: 0;
}
.navbar-gitlab .header-content .title-container {
@@ -796,7 +818,7 @@ input {
.container-fluid
.navbar-nav
li
- .badge.badge-pill:not(.merge-request-badge) {
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge) {
box-shadow: none;
font-weight: 600;
}
@@ -879,8 +901,10 @@ input {
line-height: 18px;
margin: 4px 0 4px 2px;
}
-.title-container .badge.badge-pill:not(.merge-request-badge),
-.navbar-nav .badge.badge-pill:not(.merge-request-badge) {
+.title-container
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge),
+.navbar-nav
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge) {
position: inherit;
font-weight: 400;
margin-left: -6px;
@@ -891,17 +915,22 @@ input {
border-radius: 7px;
box-shadow: 0 1px 0 rgba(76, 78, 84, 0.2);
}
-.title-container .badge.badge-pill:not(.merge-request-badge).green-badge,
-.navbar-nav .badge.badge-pill:not(.merge-request-badge).green-badge {
+.title-container
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge).green-badge,
+.navbar-nav
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge).green-badge {
background-color: var(--green-400, #2da160);
}
.title-container
- .badge.badge-pill:not(.merge-request-badge).merge-requests-count,
-.navbar-nav .badge.badge-pill:not(.merge-request-badge).merge-requests-count {
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge).merge-requests-count,
+.navbar-nav
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge).merge-requests-count {
background-color: var(--orange-400, #c17d10);
}
-.title-container .badge.badge-pill:not(.merge-request-badge).todos-count,
-.navbar-nav .badge.badge-pill:not(.merge-request-badge).todos-count {
+.title-container
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge).todos-count,
+.navbar-nav
+ .badge.badge-pill:not(.merge-request-badge):not(.version-check-badge).todos-count {
background-color: var(--blue-400, #428fdc);
}
.title-container .canary-badge .badge,
@@ -1011,7 +1040,7 @@ input {
left: 0;
z-index: 600;
width: 220px;
- top: 40px;
+ top: var(--header-height, 40px);
background-color: #f0f0f0;
transform: translate3d(0, 0, 0);
}
@@ -1348,7 +1377,7 @@ 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 {
+.sidebar-top-level-items > li .badge.badge-pill:not(.gl-badge) {
border-radius: 0.5rem;
padding-top: 0.125rem;
padding-bottom: 0.125rem;
@@ -1362,7 +1391,7 @@ input {
.sidebar-sub-level-items:not(.is-fly-out-only) {
display: block;
}
-.sidebar-top-level-items > li.active .badge.badge-pill {
+.sidebar-top-level-items > li.active .badge.badge-pill:not(.gl-badge) {
font-weight: 400;
color: #0b5cad;
}
diff --git a/app/assets/stylesheets/startup/startup-signin.scss b/app/assets/stylesheets/startup/startup-signin.scss
index 3daeeb30082..3ed257caf60 100644
--- a/app/assets/stylesheets/startup/startup-signin.scss
+++ b/app/assets/stylesheets/startup/startup-signin.scss
@@ -189,7 +189,7 @@ hr {
color: #303030;
background-color: #fff;
background-clip: padding-box;
- border: 1px solid #dbdbdb;
+ border: 1px solid #868686;
border-radius: 0.25rem;
}
@media (prefers-reduced-motion: reduce) {
@@ -419,7 +419,7 @@ body.navless {
}
}
.navless-container {
- margin-top: 40px;
+ margin-top: var(--header-height, 40px);
padding-top: 32px;
}
.btn {
@@ -506,7 +506,7 @@ label.label-bold {
}
.navbar-empty {
justify-content: center;
- height: 40px;
+ height: var(--header-height, 40px);
background: #fff;
border-bottom: 1px solid #dbdbdb;
}
@@ -548,6 +548,8 @@ svg {
}
.login-page .flash-container {
margin-bottom: 16px;
+ position: relative;
+ top: 8px;
}
.login-page .brand-holder {
font-size: 18px;
@@ -770,6 +772,9 @@ svg {
.gl-mt-2 {
margin-top: 0.25rem;
}
+.gl-mt-5 {
+ margin-top: 1rem;
+}
.gl-mb-3 {
margin-bottom: 0.5rem;
}
diff --git a/app/assets/stylesheets/themes/theme_helper.scss b/app/assets/stylesheets/themes/theme_helper.scss
index e119af716a6..ec0928fc3d4 100644
--- a/app/assets/stylesheets/themes/theme_helper.scss
+++ b/app/assets/stylesheets/themes/theme_helper.scss
@@ -4,12 +4,16 @@
*/
@mixin gitlab-theme(
$search-and-nav-links,
- $active-tab-border,
+ $accent,
$border-and-box-shadow,
$sidebar-text,
$nav-svg-color,
$color-alternate
) {
+ // Set custom properties
+
+ --gl-theme-accent: #{$accent};
+
// Header
.navbar-gitlab {
@@ -163,7 +167,7 @@
&:focus,
&:active {
&::placeholder {
- color: $search-and-nav-links;
+ color: $gray-400;
}
}
}
@@ -219,22 +223,6 @@
}
}
- .nav-links li {
- &.active a,
- &.md-header-tab.active button,
- a.active {
- border-bottom: 2px solid $active-tab-border;
-
- .badge.badge-pill {
- font-weight: $gl-font-weight-bold;
- }
- }
- }
-
- .emoji-picker-category-active {
- border-bottom-color: $active-tab-border;
- }
-
.branch-header-title {
color: $border-and-box-shadow;
}
diff --git a/app/assets/stylesheets/utilities.scss b/app/assets/stylesheets/utilities.scss
index 2623de80fe9..0e7e52129b4 100644
--- a/app/assets/stylesheets/utilities.scss
+++ b/app/assets/stylesheets/utilities.scss
@@ -58,6 +58,13 @@
}
}
+.gl-first-child-ml-sm-0 > a:first-child,
+.gl-first-child-ml-sm-0 > button:first-child {
+ @include media-breakpoint-up(sm) {
+ @include gl-ml-0;
+ }
+}
+
.mh-50vh { max-height: 50vh; }
.min-width-0 {
@@ -240,16 +247,6 @@ $gl-line-height-42: px-to-rem(42px);
max-width: 50%;
}
-// Will be moved to @gitlab/ui by https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1465
-.gl-popover {
- .popover-header {
- .gl-button.close {
- margin-top: -$gl-spacing-scale-3;
- margin-right: -$gl-spacing-scale-4;
- }
- }
-}
-
// Will be moved to @gitlab/ui by https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1490
.gl-w-grid-size-28 {
width: $grid-size * 28;
@@ -307,3 +304,8 @@ $gl-line-height-42: px-to-rem(42px);
width: 25%;
}
}
+
+// Will be moved to @gitlab/ui by https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/2600
+.gl-pr-10 {
+ padding-right: $gl-spacing-scale-10;
+}
diff --git a/app/controllers/admin/runner_projects_controller.rb b/app/controllers/admin/runner_projects_controller.rb
index fdf681de9ef..598c536d652 100644
--- a/app/controllers/admin/runner_projects_controller.rb
+++ b/app/controllers/admin/runner_projects_controller.rb
@@ -9,9 +9,9 @@ class Admin::RunnerProjectsController < Admin::ApplicationController
@runner = Ci::Runner.find(params[:runner_project][:runner_id])
if @runner.assign_to(@project, current_user)
- redirect_to admin_runner_path(@runner), notice: s_('Runners|Runner assigned to project.')
+ redirect_to edit_admin_runner_url(@runner), notice: s_('Runners|Runner assigned to project.')
else
- redirect_to admin_runner_path(@runner), alert: 'Failed adding runner to project'
+ redirect_to edit_admin_runner_url(@runner), alert: 'Failed adding runner to project'
end
end
@@ -20,7 +20,7 @@ class Admin::RunnerProjectsController < Admin::ApplicationController
runner = rp.runner
rp.destroy
- redirect_to admin_runner_path(runner), status: :found, notice: s_('Runners|Runner unassigned from project.')
+ redirect_to edit_admin_runner_url(runner), status: :found, notice: s_('Runners|Runner unassigned from project.')
end
private
diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb
index 9312651b8bf..16657612050 100644
--- a/app/controllers/admin/runners_controller.rb
+++ b/app/controllers/admin/runners_controller.rb
@@ -11,13 +11,21 @@ class Admin::RunnersController < Admin::ApplicationController
end
def show
+ # We will show runner details in a read-only view in
+ # future iterations. For now, this route will have a
+ # redirect until this new view is developed. See more:
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/347856
+ redirect_to edit_admin_runner_path(runner) unless Feature.enabled?(:runner_read_only_admin_view, default_enabled: :yaml)
+ end
+
+ def edit
assign_builds_and_projects
end
def update
if Ci::UpdateRunnerService.new(@runner).update(runner_params)
respond_to do |format|
- format.html { redirect_to admin_runner_path(@runner) }
+ format.html { redirect_to edit_admin_runner_path(@runner) }
end
else
assign_builds_and_projects
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index cdfb3a32f4c..b40e2affcee 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -158,7 +158,7 @@ class Admin::UsersController < Admin::ApplicationController
end
def confirm
- if update_user { |user| user.confirm }
+ if update_user { |user| user.force_confirm }
redirect_back_or_admin_user(notice: _("Successfully confirmed"))
else
redirect_back_or_admin_user(alert: _("Error occurred. User was not confirmed"))
diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb
index c32a7f10aa4..ee5caf63703 100644
--- a/app/controllers/autocomplete_controller.rb
+++ b/app/controllers/autocomplete_controller.rb
@@ -2,6 +2,7 @@
class AutocompleteController < ApplicationController
skip_before_action :authenticate_user!, only: [:users, :award_emojis, :merge_request_target_branches]
+ before_action :check_email_search_rate_limit!, only: [:users]
feature_category :users, [:users, :user]
feature_category :projects, [:projects]
@@ -71,6 +72,12 @@ 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/concerns/access_tokens_actions.rb b/app/controllers/concerns/access_tokens_actions.rb
new file mode 100644
index 00000000000..451841c43bb
--- /dev/null
+++ b/app/controllers/concerns/access_tokens_actions.rb
@@ -0,0 +1,83 @@
+# frozen_string_literal: true
+
+module AccessTokensActions
+ extend ActiveSupport::Concern
+
+ included do
+ before_action -> { check_permission(:read_resource_access_tokens) }, only: [:index]
+ before_action -> { check_permission(:destroy_resource_access_tokens) }, only: [:revoke]
+ before_action -> { check_permission(:create_resource_access_tokens) }, only: [:create]
+ end
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def index
+ @resource_access_token = PersonalAccessToken.new
+ set_index_vars
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def create
+ token_response = ResourceAccessTokens::CreateService.new(current_user, resource, create_params).execute
+
+ if token_response.success?
+ @resource_access_token = token_response.payload[:access_token]
+ PersonalAccessToken.redis_store!(key_identity, @resource_access_token.token)
+
+ redirect_to resource_access_tokens_path, notice: _("Your new access token has been created.")
+ else
+ redirect_to resource_access_tokens_path, alert: _("Failed to create new access token: %{token_response_message}") % { token_response_message: token_response.message }
+ end
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def revoke
+ @resource_access_token = finder.find(params[:id])
+ revoked_response = ResourceAccessTokens::RevokeService.new(current_user, resource, @resource_access_token).execute
+
+ if revoked_response.success?
+ flash[:notice] = _("Revoked access token %{access_token_name}!") % { access_token_name: @resource_access_token.name }
+ else
+ flash[:alert] = _("Could not revoke access token %{access_token_name}.") % { access_token_name: @resource_access_token.name }
+ end
+
+ redirect_to resource_access_tokens_path
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ private
+
+ def check_permission(action)
+ render_404 unless can?(current_user, action, resource)
+ end
+
+ def create_params
+ params.require(:resource_access_token).permit(:name, :expires_at, :access_level, scopes: [])
+ end
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def set_index_vars
+ # Loading resource members so that we can fetch access level of the bot
+ # user in the resource without multiple queries.
+ resource.members.load
+
+ @scopes = Gitlab::Auth.resource_bot_scopes
+ @active_resource_access_tokens = finder(state: 'active').execute.preload_users
+ @inactive_resource_access_tokens = finder(state: 'inactive', sort: 'expires_at_asc').execute.preload_users
+ @new_resource_access_token = PersonalAccessToken.redis_getdel(key_identity)
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ def finder(options = {})
+ PersonalAccessTokensFinder.new({ user: bot_users, impersonation: false }.merge(options))
+ end
+
+ def bot_users
+ resource.bots
+ end
+
+ def key_identity
+ "#{current_user.id}:#{resource.id}"
+ end
+end
diff --git a/app/controllers/concerns/check_rate_limit.rb b/app/controllers/concerns/check_rate_limit.rb
index 5ccdf843525..0eaf74fd3a9 100644
--- a/app/controllers/concerns/check_rate_limit.rb
+++ b/app/controllers/concerns/check_rate_limit.rb
@@ -8,6 +8,7 @@
# See lib/api/helpers/rate_limiter.rb for API version
module CheckRateLimit
def check_rate_limit!(key, scope:, redirect_back: false, **options)
+ return if bypass_header_set?
return unless rate_limiter.throttled?(key, scope: scope, **options)
rate_limiter.log_request(request, "#{key}_request_limit".to_sym, current_user)
@@ -28,4 +29,8 @@ module CheckRateLimit
def rate_limiter
::Gitlab::ApplicationRateLimiter
end
+
+ def bypass_header_set?
+ ::Gitlab::Throttle.bypass_header.present? && request.get_header(Gitlab::Throttle.bypass_header) == '1'
+ end
end
diff --git a/app/controllers/concerns/integrations/actions.rb b/app/controllers/concerns/integrations/actions.rb
index 1f788860c8f..f6e98c25b72 100644
--- a/app/controllers/concerns/integrations/actions.rb
+++ b/app/controllers/concerns/integrations/actions.rb
@@ -8,6 +8,9 @@ module Integrations::Actions
include IntegrationsHelper
before_action :integration, only: [:edit, :update, :overrides, :test]
+ before_action do
+ push_frontend_feature_flag(:vue_integration_form, current_user, default_enabled: :yaml)
+ end
urgency :low, [:test]
end
diff --git a/app/controllers/concerns/integrations/params.rb b/app/controllers/concerns/integrations/params.rb
index 201fb1dc83f..945540d1f8c 100644
--- a/app/controllers/concerns/integrations/params.rb
+++ b/app/controllers/concerns/integrations/params.rb
@@ -11,6 +11,7 @@ module Integrations
:api_key,
:api_token,
:api_url,
+ :archive_trace_events,
:bamboo_url,
:branches_to_be_notified,
:labels_to_be_notified,
diff --git a/app/controllers/concerns/sessionless_authentication.rb b/app/controllers/concerns/sessionless_authentication.rb
index c6d926c8a8d..1f17f9f4e1b 100644
--- a/app/controllers/concerns/sessionless_authentication.rb
+++ b/app/controllers/concerns/sessionless_authentication.rb
@@ -20,7 +20,7 @@ module SessionlessAuthentication
end
def sessionless_sign_in(user)
- if can?(user, :log_in) && !user.password_expired_if_applicable?
+ if user.can_log_in_with_non_expired_password?
# Notice we are passing store false, so the user is not
# actually stored in the session and a token is needed
# for every request. If you want the token to work as a
diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb
index f48d03869a4..689ca32f6d9 100644
--- a/app/controllers/graphql_controller.rb
+++ b/app/controllers/graphql_controller.rb
@@ -44,6 +44,13 @@ class GraphqlController < ApplicationController
# The default feature category is overridden to read from request
feature_category :not_owned
+ # We don't know what the query is going to be, so we can't set a high urgency
+ # See https://gitlab.com/groups/gitlab-org/-/epics/5841 for the work that will
+ # allow us to specify an urgency per query.
+ # Currently, all queries have a default urgency. And this is measured in the `graphql_queries`
+ # SLI. But queries could be multiplexed, so the total duration could be longer.
+ urgency :low, [:execute]
+
def execute
result = multiplex? ? execute_multiplex : execute_query
render json: result
diff --git a/app/controllers/groups/application_controller.rb b/app/controllers/groups/application_controller.rb
index ab67a007bd9..f9c875b80b2 100644
--- a/app/controllers/groups/application_controller.rb
+++ b/app/controllers/groups/application_controller.rb
@@ -37,6 +37,18 @@ class Groups::ApplicationController < ApplicationController
end
end
+ def authorize_admin_group_runners!
+ unless can?(current_user, :admin_group_runners, group)
+ render_404
+ end
+ end
+
+ def authorize_read_group_runners!
+ unless can?(current_user, :read_group_runners, group)
+ render_404
+ end
+ end
+
def authorize_create_deploy_token!
unless can?(current_user, :create_deploy_token, group)
render_404
diff --git a/app/controllers/groups/boards_controller.rb b/app/controllers/groups/boards_controller.rb
index 3fbcb2fd7aa..6de77450a46 100644
--- a/app/controllers/groups/boards_controller.rb
+++ b/app/controllers/groups/boards_controller.rb
@@ -9,7 +9,6 @@ class Groups::BoardsController < Groups::ApplicationController
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(:swimlanes_buffered_rendering, group, default_enabled: :yaml)
push_frontend_feature_flag(:iteration_cadences, group, default_enabled: :yaml)
experiment(:prominent_create_board_btn, subject: current_user) do |e|
e.use { }
diff --git a/app/controllers/groups/dependency_proxy_for_containers_controller.rb b/app/controllers/groups/dependency_proxy_for_containers_controller.rb
index 171314b5f26..00839583ecc 100644
--- a/app/controllers/groups/dependency_proxy_for_containers_controller.rb
+++ b/app/controllers/groups/dependency_proxy_for_containers_controller.rb
@@ -33,17 +33,15 @@ class Groups::DependencyProxyForContainersController < ::Groups::DependencyProxy
end
def blob
- return blob_via_workhorse if Feature.enabled?(:dependency_proxy_workhorse, group, default_enabled: :yaml)
-
- result = DependencyProxy::FindOrCreateBlobService
- .new(group, image, token, params[:sha]).execute
+ blob = @group.dependency_proxy_blobs.find_by_file_name(blob_file_name)
- if result[:status] == :success
- event_name = tracking_event_name(object_type: :blob, from_cache: result[:from_cache])
+ if blob.present?
+ event_name = tracking_event_name(object_type: :blob, from_cache: true)
track_package_event(event_name, :dependency_proxy, namespace: group, user: auth_user)
- send_upload(result[:blob].file)
+
+ send_upload(blob.file)
else
- head result[:http_status]
+ send_dependency(token_header, DependencyProxy::Registry.blob_url(image, params[:sha]), blob_file_name)
end
end
@@ -99,19 +97,6 @@ class Groups::DependencyProxyForContainersController < ::Groups::DependencyProxy
private
- def blob_via_workhorse
- blob = @group.dependency_proxy_blobs.find_by_file_name(blob_file_name)
-
- if blob.present?
- event_name = tracking_event_name(object_type: :blob, from_cache: true)
- track_package_event(event_name, :dependency_proxy, namespace: group, user: auth_user)
-
- send_upload(blob.file)
- else
- send_dependency(token_header, DependencyProxy::Registry.blob_url(image, params[:sha]), blob_file_name)
- end
- end
-
def send_manifest(manifest, from_cache:)
response.headers[DependencyProxy::Manifest::DIGEST_HEADER] = manifest.digest
response.headers['Content-Length'] = manifest.size
@@ -160,8 +145,7 @@ class Groups::DependencyProxyForContainersController < ::Groups::DependencyProxy
end
def dependency_proxy
- @dependency_proxy ||=
- group.dependency_proxy_setting || group.create_dependency_proxy_setting
+ @dependency_proxy ||= group.dependency_proxy_setting
end
def ensure_group
diff --git a/app/controllers/groups/packages_controller.rb b/app/controllers/groups/packages_controller.rb
index 47f1816cc4c..1f3d80260ed 100644
--- a/app/controllers/groups/packages_controller.rb
+++ b/app/controllers/groups/packages_controller.rb
@@ -6,6 +6,11 @@ module Groups
feature_category :package_registry
+ # The show action renders index to allow frontend routing to work on page refresh
+ def show
+ render :index
+ end
+
private
def verify_packages_enabled!
diff --git a/app/controllers/groups/runners_controller.rb b/app/controllers/groups/runners_controller.rb
index 5c21c7b023c..f602d02a165 100644
--- a/app/controllers/groups/runners_controller.rb
+++ b/app/controllers/groups/runners_controller.rb
@@ -1,9 +1,8 @@
# frozen_string_literal: true
class Groups::RunnersController < Groups::ApplicationController
- # TODO Proper policies, such as `read_group_runners, should be implemented per
- # https://gitlab.com/gitlab-org/gitlab/-/issues/334802
- before_action :authorize_admin_group!
+ before_action :authorize_read_group_runners!, only: [:index, :show]
+ before_action :authorize_admin_group_runners!, only: [:edit, :update, :destroy, :pause, :resume]
before_action :runner_list_group_view_vue_ui_enabled, only: [:index]
before_action :runner, only: [:edit, :update, :destroy, :pause, :resume, :show]
@@ -17,7 +16,7 @@ class Groups::RunnersController < Groups::ApplicationController
end
def runner_list_group_view_vue_ui_enabled
- return render_404 unless Feature.enabled?(:runner_list_group_view_vue_ui, group, default_enabled: :yaml)
+ render_404 unless Feature.enabled?(:runner_list_group_view_vue_ui, group, default_enabled: :yaml)
end
def show
diff --git a/app/controllers/groups/settings/access_tokens_controller.rb b/app/controllers/groups/settings/access_tokens_controller.rb
new file mode 100644
index 00000000000..b9ab2e008cc
--- /dev/null
+++ b/app/controllers/groups/settings/access_tokens_controller.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Groups
+ module Settings
+ class AccessTokensController < Groups::ApplicationController
+ include AccessTokensActions
+
+ layout 'group_settings'
+ feature_category :authentication_and_authorization
+
+ alias_method :resource, :group
+
+ def resource_access_tokens_path
+ group_settings_access_tokens_path
+ end
+ end
+ end
+end
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 62336c7eede..4acbb0482f3 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -32,7 +32,6 @@ class GroupsController < Groups::ApplicationController
before_action :user_actions, only: [:show]
before_action do
- push_frontend_feature_flag(:vue_issuables_list, @group)
push_frontend_feature_flag(:vue_issues_list, @group, default_enabled: :yaml)
push_frontend_feature_flag(:iteration_cadences, @group, default_enabled: :yaml)
end
@@ -276,7 +275,8 @@ class GroupsController < Groups::ApplicationController
:resource_access_token_creation_allowed,
:prevent_sharing_groups_outside_hierarchy,
:setup_for_company,
- :jobs_to_be_done
+ :jobs_to_be_done,
+ :crm_enabled
]
end
diff --git a/app/controllers/import/gitlab_controller.rb b/app/controllers/import/gitlab_controller.rb
index 662b02010ba..fa9517c3545 100644
--- a/app/controllers/import/gitlab_controller.rb
+++ b/app/controllers/import/gitlab_controller.rb
@@ -41,7 +41,7 @@ class Import::GitlabController < Import::BaseController
override :importable_repos
def importable_repos
- client.projects(starting_page: 1, page_limit: MAX_PROJECT_PAGES, per_page: PER_PAGE_PROJECTS)
+ client.projects(starting_page: 1, page_limit: MAX_PROJECT_PAGES, per_page: PER_PAGE_PROJECTS).to_a
end
override :incompatible_repos
diff --git a/app/controllers/oauth/token_info_controller.rb b/app/controllers/oauth/token_info_controller.rb
index e37f8992d92..789356f4410 100644
--- a/app/controllers/oauth/token_info_controller.rb
+++ b/app/controllers/oauth/token_info_controller.rb
@@ -13,7 +13,7 @@ class Oauth::TokenInfoController < Doorkeeper::TokenInfoController
'expires_in_seconds' => token_json[:expires_in]
), status: :ok
else
- error = Doorkeeper::OAuth::ErrorResponse.new(name: :invalid_request)
+ error = Doorkeeper::OAuth::InvalidTokenResponse.new
response.headers.merge!(error.headers)
render json: error.body, status: error.status
end
diff --git a/app/controllers/profiles/emails_controller.rb b/app/controllers/profiles/emails_controller.rb
index be2cb270a19..7a88162f469 100644
--- a/app/controllers/profiles/emails_controller.rb
+++ b/app/controllers/profiles/emails_controller.rb
@@ -52,3 +52,5 @@ class Profiles::EmailsController < Profiles::ApplicationController
@email = current_user.emails.find(params[:id])
end
end
+
+Profiles::EmailsController.prepend_mod
diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb
index e6b80f90dca..46738651960 100644
--- a/app/controllers/profiles_controller.rb
+++ b/app/controllers/profiles_controller.rb
@@ -6,6 +6,9 @@ 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)
+ end
skip_before_action :require_email, only: [:show, :update]
before_action do
push_frontend_feature_flag(:webauthn, default_enabled: :yaml)
diff --git a/app/controllers/projects/analytics/cycle_analytics/stages_controller.rb b/app/controllers/projects/analytics/cycle_analytics/stages_controller.rb
index 2f9d70fede1..7b38c069a60 100644
--- a/app/controllers/projects/analytics/cycle_analytics/stages_controller.rb
+++ b/app/controllers/projects/analytics/cycle_analytics/stages_controller.rb
@@ -11,6 +11,8 @@ class Projects::Analytics::CycleAnalytics::StagesController < Projects::Applicat
before_action :authorize_read_cycle_analytics!
before_action :only_default_value_stream_is_allowed!
+ urgency :low
+
private
override :parent
diff --git a/app/controllers/projects/analytics/cycle_analytics/summary_controller.rb b/app/controllers/projects/analytics/cycle_analytics/summary_controller.rb
index bf8742bf6e8..69327feeb02 100644
--- a/app/controllers/projects/analytics/cycle_analytics/summary_controller.rb
+++ b/app/controllers/projects/analytics/cycle_analytics/summary_controller.rb
@@ -9,6 +9,8 @@ class Projects::Analytics::CycleAnalytics::SummaryController < Projects::Applica
before_action :authorize_read_cycle_analytics!
+ urgency :low
+
def show
render json: project_level.summary
end
diff --git a/app/controllers/projects/boards_controller.rb b/app/controllers/projects/boards_controller.rb
index 81ad6243efe..adaa47b48cb 100644
--- a/app/controllers/projects/boards_controller.rb
+++ b/app/controllers/projects/boards_controller.rb
@@ -7,8 +7,7 @@ class Projects::BoardsController < Projects::ApplicationController
before_action :check_issues_available!
before_action :assign_endpoint_vars
before_action do
- push_frontend_feature_flag(:swimlanes_buffered_rendering, project, default_enabled: :yaml)
- push_frontend_feature_flag(:issue_boards_filtered_search, project, default_enabled: :yaml)
+ 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/google_cloud/base_controller.rb b/app/controllers/projects/google_cloud/base_controller.rb
index aff305ab7d6..f4a773a62f6 100644
--- a/app/controllers/projects/google_cloud/base_controller.rb
+++ b/app/controllers/projects/google_cloud/base_controller.rb
@@ -23,4 +23,39 @@ class Projects::GoogleCloud::BaseController < Projects::ApplicationController
def feature_flag_enabled!
access_denied! unless Feature.enabled?(:incubation_5mp_google_cloud, project)
end
+
+ def validate_gcp_token!
+ is_token_valid = GoogleApi::CloudPlatform::Client.new(token_in_session, nil)
+ .validate_token(expires_at_in_session)
+
+ return if is_token_valid
+
+ return_url = project_google_cloud_index_path(project)
+ state = generate_session_key_redirect(request.url, return_url)
+ @authorize_url = GoogleApi::CloudPlatform::Client.new(nil,
+ callback_google_api_auth_url,
+ state: state).authorize_url
+ redirect_to @authorize_url
+ end
+
+ def generate_session_key_redirect(uri, error_uri)
+ GoogleApi::CloudPlatform::Client.new_session_key_for_redirect_uri do |key|
+ session[key] = uri
+ session[:error_uri] = error_uri
+ end
+ end
+
+ def token_in_session
+ session[GoogleApi::CloudPlatform::Client.session_key_for_token]
+ end
+
+ def expires_at_in_session
+ 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)
+ @js_data = { screen: 'gcp_error', error: error.to_s }.to_json
+ render status: :unauthorized, template: 'projects/google_cloud/errors/gcp_error'
+ end
end
diff --git a/app/controllers/projects/google_cloud/deployments_controller.rb b/app/controllers/projects/google_cloud/deployments_controller.rb
new file mode 100644
index 00000000000..4e7fd73e378
--- /dev/null
+++ b/app/controllers/projects/google_cloud/deployments_controller.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class Projects::GoogleCloud::DeploymentsController < Projects::GoogleCloud::BaseController
+ before_action :validate_gcp_token!
+
+ def cloud_run
+ render json: "Placeholder"
+ end
+
+ def cloud_storage
+ render json: "Placeholder"
+ 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 a69a744154c..b5f2b658235 100644
--- a/app/controllers/projects/google_cloud/service_accounts_controller.rb
+++ b/app/controllers/projects/google_cloud/service_accounts_controller.rb
@@ -24,62 +24,16 @@ class Projects::GoogleCloud::ServiceAccountsController < Projects::GoogleCloud::
end
def create
- google_api_client = GoogleApi::CloudPlatform::Client.new(token_in_session, nil)
- service_accounts_service = GoogleCloud::ServiceAccountsService.new(project)
- gcp_project = params[:gcp_project]
- environment = params[:environment]
- generated_name = "GitLab :: #{@project.name} :: #{environment}"
- generated_desc = "GitLab generated service account for project '#{@project.name}' and environment '#{environment}'"
-
- service_account = google_api_client.create_service_account(gcp_project, generated_name, generated_desc)
- service_account_key = google_api_client.create_service_account_key(gcp_project, service_account.unique_id)
-
- service_accounts_service.add_for_project(
- environment,
- service_account.project_id,
- service_account.to_json,
- service_account_key.to_json
- )
-
- redirect_to project_google_cloud_index_path(project), notice: _('Service account generated successfully')
+ response = GoogleCloud::CreateServiceAccountsService.new(
+ project,
+ current_user,
+ google_oauth2_token: token_in_session,
+ gcp_project_id: params[:gcp_project],
+ environment_name: params[:environment]
+ ).execute
+
+ 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)
end
-
- private
-
- def validate_gcp_token!
- is_token_valid = GoogleApi::CloudPlatform::Client.new(token_in_session, nil)
- .validate_token(expires_at_in_session)
-
- return if is_token_valid
-
- return_url = project_google_cloud_index_path(project)
- state = generate_session_key_redirect(request.url, return_url)
- @authorize_url = GoogleApi::CloudPlatform::Client.new(nil,
- callback_google_api_auth_url,
- state: state).authorize_url
- redirect_to @authorize_url
- end
-
- def generate_session_key_redirect(uri, error_uri)
- GoogleApi::CloudPlatform::Client.new_session_key_for_redirect_uri do |key|
- session[key] = uri
- session[:error_uri] = error_uri
- end
- end
-
- def token_in_session
- session[GoogleApi::CloudPlatform::Client.session_key_for_token]
- end
-
- def expires_at_in_session
- 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)
- @js_data = { screen: 'gcp_error', error: error.to_s }.to_json
- render status: :unauthorized, template: 'projects/google_cloud/errors/gcp_error'
- end
end
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index fc67cd98d15..785fbdaa611 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -43,7 +43,6 @@ class Projects::IssuesController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:tribute_autocomplete, @project)
- push_frontend_feature_flag(:vue_issuables_list, project)
push_frontend_feature_flag(:improved_emoji_picker, project, default_enabled: :yaml)
push_frontend_feature_flag(:vue_issues_list, project&.group, default_enabled: :yaml)
push_frontend_feature_flag(:iteration_cadences, project&.group, default_enabled: :yaml)
@@ -54,6 +53,7 @@ class Projects::IssuesController < Projects::ApplicationController
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)
end
around_action :allow_gitaly_ref_name_caching, only: [:discussions]
@@ -291,10 +291,12 @@ class Projects::IssuesController < Projects::ApplicationController
end
def issue_params
- params.require(:issue).permit(
+ all_params = params.require(:issue).permit(
*issue_params_attributes,
sentry_issue_attributes: [:sentry_issue_identifier]
)
+
+ clean_params(all_params)
end
def issue_params_attributes
@@ -348,6 +350,13 @@ class Projects::IssuesController < Projects::ApplicationController
private
+ def clean_params(all_params)
+ issue_type = all_params[:issue_type].to_s
+ all_params.delete(:issue_type) unless WorkItems::Type.allowed_types_for_issues.include?(issue_type)
+
+ all_params
+ end
+
def finder_options
options = super
diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb
index fa7c62c34dd..bfc2fe6432d 100644
--- a/app/controllers/projects/jobs_controller.rb
+++ b/app/controllers/projects/jobs_controller.rb
@@ -19,6 +19,7 @@ class Projects::JobsController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:infinitely_collapsible_sections, @project, default_enabled: :yaml)
+ push_frontend_feature_flag(:trigger_job_retry_action, @project, default_enabled: :yaml)
end
layout 'project'
diff --git a/app/controllers/projects/mattermosts_controller.rb b/app/controllers/projects/mattermosts_controller.rb
index ebba20b285a..c4f4913a620 100644
--- a/app/controllers/projects/mattermosts_controller.rb
+++ b/app/controllers/projects/mattermosts_controller.rb
@@ -20,7 +20,7 @@ class Projects::MattermostsController < Projects::ApplicationController
if result
flash[:notice] = 'This service is now configured'
- redirect_to edit_project_service_path(@project, integration)
+ redirect_to edit_project_integration_path(@project, integration)
else
flash[:alert] = message || 'Failed to configure service'
redirect_to new_project_mattermost_path(@project)
diff --git a/app/controllers/projects/merge_requests/creations_controller.rb b/app/controllers/projects/merge_requests/creations_controller.rb
index beb179f584b..88337242fcd 100644
--- a/app/controllers/projects/merge_requests/creations_controller.rb
+++ b/app/controllers/projects/merge_requests/creations_controller.rb
@@ -56,9 +56,7 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
@diff_notes_disabled = true
- @environment = @merge_request.environments_for(current_user, latest: true).last
-
- render json: { html: view_to_html_string('projects/merge_requests/creations/_diffs', diffs: @diffs, environment: @environment) }
+ render json: { html: view_to_html_string('projects/merge_requests/creations/_diffs', diffs: @diffs) }
end
def diff_for_path
diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb
index 32ca7d779d2..9bc9c19157a 100644
--- a/app/controllers/projects/merge_requests/diffs_controller.rb
+++ b/app/controllers/projects/merge_requests/diffs_controller.rb
@@ -35,13 +35,11 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
diffs = @compare.diffs_in_batch(params[:page], params[:per_page], diff_options: diff_options_hash)
unfoldable_positions = @merge_request.note_positions_for_paths(diffs.diff_file_paths, current_user).unfoldable
- environment = @merge_request.environments_for(current_user, latest: true).last
diffs.unfold_diff_files(unfoldable_positions)
diffs.write_cache
options = {
- environment: environment,
merge_request: @merge_request,
commit: commit,
diff_view: diff_view,
@@ -54,7 +52,6 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
# NOTE: Any variables that would affect the resulting json needs to be added to the cache_context to avoid stale cache issues.
cache_context = [
current_user&.cache_key,
- environment&.cache_key,
unfoldable_positions.map(&:to_h),
diff_view,
params[:w],
@@ -98,7 +95,6 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
# Deprecated: https://gitlab.com/gitlab-org/gitlab/issues/37735
def render_diffs
diffs = @compare.diffs(diff_options)
- @environment = @merge_request.environments_for(current_user, latest: true).last
diffs.unfold_diff_files(note_positions.unfoldable)
diffs.write_cache
@@ -175,7 +171,6 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
def additional_attributes
{
- environment: @environment,
merge_request: @merge_request,
merge_request_diff: @merge_request_diff,
merge_request_diffs: @merge_request_diffs,
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 7133233f083..f936aeb0084 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -42,17 +42,14 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:restructured_mr_widget, project, default_enabled: :yaml)
push_frontend_feature_flag(:mr_changes_fluid_layout, project, default_enabled: :yaml)
push_frontend_feature_flag(:mr_attention_requests, 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)
# 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)
push_frontend_feature_flag(:diff_searching_usage_data, @project, default_enabled: :yaml)
end
- before_action do
- push_frontend_feature_flag(:show_relevant_approval_rule_approvers, @project, default_enabled: :yaml)
- end
-
around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :discussions]
after_action :log_merge_request_show, only: [:show]
@@ -66,7 +63,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
feature_category :code_testing, [:test_reports, :coverage_reports]
feature_category :code_quality, [:codequality_reports, :codequality_mr_diff_reports]
- feature_category :accessibility_testing, [:accessibility_reports]
+ feature_category :code_testing, [:accessibility_reports]
feature_category :infrastructure_as_code, [:terraform_reports]
feature_category :continuous_integration, [:pipeline_status, :pipelines, :exposed_artifacts]
diff --git a/app/controllers/projects/packages/infrastructure_registry_controller.rb b/app/controllers/projects/packages/infrastructure_registry_controller.rb
index 4506a83634a..c02a0a56e03 100644
--- a/app/controllers/projects/packages/infrastructure_registry_controller.rb
+++ b/app/controllers/projects/packages/infrastructure_registry_controller.rb
@@ -9,7 +9,11 @@ module Projects
def show
@package = project.packages.find(params[:id])
- @package_files = @package.package_files.recent
+ @package_files = if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml)
+ @package.installable_package_files.recent
+ else
+ @package.package_files.recent
+ end
end
end
end
diff --git a/app/controllers/projects/packages/packages_controller.rb b/app/controllers/projects/packages/packages_controller.rb
index 5de71466c10..969922266fa 100644
--- a/app/controllers/projects/packages/packages_controller.rb
+++ b/app/controllers/projects/packages/packages_controller.rb
@@ -7,8 +7,9 @@ module Projects
feature_category :package_registry
+ # The show action renders index to allow frontend routing to work on page refresh
def show
- @package = project.packages.find(params[:id])
+ render :index
end
end
end
diff --git a/app/controllers/projects/prometheus/metrics_controller.rb b/app/controllers/projects/prometheus/metrics_controller.rb
index f3a3d22244c..e61d357ce4e 100644
--- a/app/controllers/projects/prometheus/metrics_controller.rb
+++ b/app/controllers/projects/prometheus/metrics_controller.rb
@@ -66,7 +66,7 @@ module Projects
)
if @metric.persisted?
- redirect_to edit_project_service_path(project, ::Integrations::Prometheus),
+ redirect_to edit_project_integration_path(project, ::Integrations::Prometheus),
notice: _('Metric was successfully added.')
else
render 'new'
@@ -77,7 +77,7 @@ module Projects
@metric = update_metrics_service(prometheus_metric).execute
if @metric.persisted?
- redirect_to edit_project_service_path(project, ::Integrations::Prometheus),
+ redirect_to edit_project_integration_path(project, ::Integrations::Prometheus),
notice: _('Metric was successfully updated.')
else
render 'edit'
@@ -93,7 +93,7 @@ module Projects
respond_to do |format|
format.html do
- redirect_to edit_project_service_path(project, ::Integrations::Prometheus), status: :see_other
+ redirect_to edit_project_integration_path(project, ::Integrations::Prometheus), status: :see_other
end
format.json do
head :ok
diff --git a/app/controllers/projects/security/configuration_controller.rb b/app/controllers/projects/security/configuration_controller.rb
index 444f4783a19..14f765814e6 100644
--- a/app/controllers/projects/security/configuration_controller.rb
+++ b/app/controllers/projects/security/configuration_controller.rb
@@ -9,6 +9,37 @@ module Projects
def show
render_403 unless can?(current_user, :read_security_configuration, project)
+
+ respond_to do |format|
+ format.html
+ format.json do
+ render status: :ok, json: configuration.to_h
+ end
+ end
+ end
+
+ private
+
+ def configuration
+ if unify_configuration_enabled?
+ configuration_presenter
+ else
+ {}
+ end
+ end
+
+ def configuration_presenter
+ ::Projects::Security::ConfigurationPresenter.new(project,
+ **presenter_attributes,
+ current_user: current_user)
+ end
+
+ def presenter_attributes
+ {}
+ end
+
+ def unify_configuration_enabled?
+ Feature.enabled?(:unify_security_configuration, project, default_enabled: :yaml)
end
end
end
diff --git a/app/controllers/projects/service_hook_logs_controller.rb b/app/controllers/projects/service_hook_logs_controller.rb
index 88de0b7ba0d..7b037c60321 100644
--- a/app/controllers/projects/service_hook_logs_controller.rb
+++ b/app/controllers/projects/service_hook_logs_controller.rb
@@ -7,13 +7,13 @@ class Projects::ServiceHookLogsController < Projects::HookLogsController
def retry
execute_hook
- redirect_to edit_project_service_path(@project, @integration)
+ redirect_to edit_project_integration_path(@project, @integration)
end
private
def integration
- @integration ||= @project.find_or_initialize_integration(params[:service_id])
+ @integration ||= @project.find_or_initialize_integration(params[:integration_id])
end
override :hook
diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb
index 9464826701d..9896f75c099 100644
--- a/app/controllers/projects/services_controller.rb
+++ b/app/controllers/projects/services_controller.rb
@@ -12,6 +12,9 @@ class Projects::ServicesController < Projects::ApplicationController
before_action :web_hook_logs, only: [:edit, :update]
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(:vue_integration_form, current_user, default_enabled: :yaml)
+ end
respond_to :html
@@ -66,7 +69,7 @@ class Projects::ServicesController < Projects::ApplicationController
private
def redirect_path
- safe_redirect_path(params[:redirect_to]).presence || edit_project_service_path(project, integration)
+ safe_redirect_path(params[:redirect_to]).presence || edit_project_integration_path(project, integration)
end
def service_test_response
@@ -119,7 +122,7 @@ class Projects::ServicesController < Projects::ApplicationController
end
def redirect_deprecated_prometheus_integration
- redirect_to edit_project_service_path(project, integration) if integration.is_a?(::Integrations::Prometheus) && Feature.enabled?(:settings_operations_prometheus_service, project)
+ redirect_to edit_project_integration_path(project, integration) if integration.is_a?(::Integrations::Prometheus) && Feature.enabled?(:settings_operations_prometheus_service, project)
end
def set_deprecation_notice_for_prometheus_integration
diff --git a/app/controllers/projects/settings/access_tokens_controller.rb b/app/controllers/projects/settings/access_tokens_controller.rb
index 1ecede4c7a2..32916831ecd 100644
--- a/app/controllers/projects/settings/access_tokens_controller.rb
+++ b/app/controllers/projects/settings/access_tokens_controller.rb
@@ -3,77 +3,15 @@
module Projects
module Settings
class AccessTokensController < Projects::ApplicationController
- include ProjectsHelper
+ include AccessTokensActions
layout 'project_settings'
- before_action -> { check_permission(:read_resource_access_tokens) }, only: [:index]
- before_action -> { check_permission(:destroy_resource_access_tokens) }, only: [:revoke]
- before_action -> { check_permission(:create_resource_access_tokens) }, only: [:create]
-
feature_category :authentication_and_authorization
- def index
- @project_access_token = PersonalAccessToken.new
- set_index_vars
- end
-
- def create
- token_response = ResourceAccessTokens::CreateService.new(current_user, @project, create_params).execute
-
- if token_response.success?
- @project_access_token = token_response.payload[:access_token]
- PersonalAccessToken.redis_store!(key_identity, @project_access_token.token)
-
- redirect_to namespace_project_settings_access_tokens_path, notice: _("Your new project access token has been created.")
- else
- redirect_to namespace_project_settings_access_tokens_path, alert: _("Failed to create new project access token: %{token_response_message}") % { token_response_message: token_response.message }
- end
- end
-
- def revoke
- @project_access_token = finder.find(params[:id])
- revoked_response = ResourceAccessTokens::RevokeService.new(current_user, @project, @project_access_token).execute
-
- if revoked_response.success?
- flash[:notice] = _("Revoked project access token %{project_access_token_name}!") % { project_access_token_name: @project_access_token.name }
- else
- flash[:alert] = _("Could not revoke project access token %{project_access_token_name}.") % { project_access_token_name: @project_access_token.name }
- end
-
- redirect_to namespace_project_settings_access_tokens_path
- end
-
- private
-
- def check_permission(action)
- render_404 unless can?(current_user, action, @project)
- end
-
- def create_params
- params.require(:project_access_token).permit(:name, :expires_at, :access_level, scopes: [])
- end
-
- def set_index_vars
- # Loading project members so that we can fetch access level of the bot
- # user in the project without multiple queries.
- @project.project_members.load
-
- @scopes = Gitlab::Auth.resource_bot_scopes
- @active_project_access_tokens = finder(state: 'active').execute.preload_users
- @inactive_project_access_tokens = finder(state: 'inactive', sort: 'expires_at_asc').execute.preload_users
- @new_project_access_token = PersonalAccessToken.redis_getdel(key_identity)
- end
-
- def finder(options = {})
- PersonalAccessTokensFinder.new({ user: bot_users, impersonation: false }.merge(options))
- end
-
- def bot_users
- @project.bots
- end
+ alias_method :resource, :project
- def key_identity
- "#{current_user.id}:#{@project.id}"
+ def resource_access_tokens_path
+ namespace_project_settings_access_tokens_path
end
end
end
diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb
index ef6c10d43cd..c71134e0547 100644
--- a/app/controllers/projects/settings/ci_cd_controller.rb
+++ b/app/controllers/projects/settings/ci_cd_controller.rb
@@ -26,9 +26,13 @@ module Projects
).to_json
end
- # @assignable_runners is using ci_owned_runners
- ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336436') do
+ if current_user.ci_owned_runners_cross_joins_fix_enabled?
render
+ else
+ # @assignable_runners is using ci_owned_runners
+ ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336436') do
+ render
+ end
end
end
diff --git a/app/controllers/projects/settings/repository_controller.rb b/app/controllers/projects/settings/repository_controller.rb
index cc419bab687..d750bd201e2 100644
--- a/app/controllers/projects/settings/repository_controller.rb
+++ b/app/controllers/projects/settings/repository_controller.rb
@@ -81,8 +81,7 @@ module Projects
@protected_branch = @project.protected_branches.new
@protected_tag = @project.protected_tags.new
- @protected_branches_count = @protected_branches.reduce(0) { |sum, branch| sum + branch.matching(@project.repository.branches).size }
- @protected_tags_count = @protected_tags.reduce(0) { |sum, tag| sum + tag.matching(@project.repository.tags).size }
+ @protected_tags_count = @protected_tags.reduce(0) { |sum, tag| sum + tag.matching(@project.repository.tag_names).size }
load_gon_index
end
diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb
index 660ebcc30d3..4f905a2d565 100644
--- a/app/controllers/projects/tree_controller.rb
+++ b/app/controllers/projects/tree_controller.rb
@@ -6,6 +6,7 @@ class Projects::TreeController < Projects::ApplicationController
include CreatesCommit
include ActionView::Helpers::SanitizeHelper
include RedirectsForMissingPathOnTree
+ include SourcegraphDecorator
around_action :allow_gitaly_ref_name_caching, only: [:show]
@@ -19,6 +20,9 @@ class Projects::TreeController < Projects::ApplicationController
push_frontend_feature_flag(:lazy_load_commits, @project, default_enabled: :yaml)
push_frontend_feature_flag(:new_dir_modal, @project, default_enabled: :yaml)
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 04dde5ef7b2..64abcd7cc33 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -9,6 +9,7 @@ class ProjectsController < Projects::ApplicationController
include RecordUserLastActivity
include ImportUrlParams
include FiltersEvents
+ include SourcegraphDecorator
prepend_before_action(only: [:show]) { authenticate_sessionless_user!(:rss) }
@@ -39,6 +40,7 @@ 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)
end
layout :determine_layout
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index ed3facd72c5..c1765d367d1 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -13,6 +13,13 @@ class RegistrationsController < Devise::RegistrationsController
before_action :ensure_destroy_prerequisites_met, only: [:destroy]
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)
+ end
+
+ before_action only: [:new] do
+ push_frontend_feature_flag(:gitlab_gtm_datalayer, type: :ops)
+ end
feature_category :authentication_and_authorization
diff --git a/app/controllers/repositories/lfs_api_controller.rb b/app/controllers/repositories/lfs_api_controller.rb
index d93d88c9e64..2b0aa67326e 100644
--- a/app/controllers/repositories/lfs_api_controller.rb
+++ b/app/controllers/repositories/lfs_api_controller.rb
@@ -155,7 +155,7 @@ module Repositories
end
def should_auto_link?
- return false unless Feature.enabled?(:lfs_auto_link_fork_source, project)
+ return false unless Feature.enabled?(:lfs_auto_link_fork_source, project, default_enabled: :yaml)
return false unless project.forked?
# Sanity check in case for some reason the user doesn't have access to the parent
diff --git a/app/controllers/sandbox_controller.rb b/app/controllers/sandbox_controller.rb
new file mode 100644
index 00000000000..a87c2b38e60
--- /dev/null
+++ b/app/controllers/sandbox_controller.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class SandboxController < ApplicationController # rubocop:disable Gitlab/NamespacedClass
+ skip_before_action :authenticate_user!
+
+ feature_category :not_owned
+
+ def mermaid
+ render layout: false
+ end
+end
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index 99a6dfa811e..d58ed252a36 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -17,6 +17,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]
rescue_from ActiveRecord::QueryCanceled, with: :render_timeout
@@ -142,6 +143,7 @@ class SearchController < ApplicationController
payload[:metadata]['meta.search.filters.confidential'] = params[:confidential]
payload[:metadata]['meta.search.filters.state'] = params[:state]
payload[:metadata]['meta.search.force_search_results'] = params[:force_search_results]
+ payload[:metadata]['meta.search.project_ids'] = params[:project_ids]
if search_service.abuse_detected?
payload[:metadata]['abuse.confidence'] = Gitlab::Abuse.confidence(:certain)
@@ -198,6 +200,12 @@ 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/sherlock/application_controller.rb b/app/controllers/sherlock/application_controller.rb
deleted file mode 100644
index c048254d348..00000000000
--- a/app/controllers/sherlock/application_controller.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-module Sherlock
- class ApplicationController < ::ApplicationController
- before_action :find_transaction
-
- def find_transaction
- if params[:transaction_id]
- @transaction = Gitlab::Sherlock.collection
- .find_transaction(params[:transaction_id])
- end
- end
- end
-end
diff --git a/app/controllers/sherlock/file_samples_controller.rb b/app/controllers/sherlock/file_samples_controller.rb
deleted file mode 100644
index 900446bb75a..00000000000
--- a/app/controllers/sherlock/file_samples_controller.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-module Sherlock
- class FileSamplesController < Sherlock::ApplicationController
- def show
- @file_sample = @transaction.find_file_sample(params[:id])
- end
- end
-end
diff --git a/app/controllers/sherlock/queries_controller.rb b/app/controllers/sherlock/queries_controller.rb
deleted file mode 100644
index 49a25c682b5..00000000000
--- a/app/controllers/sherlock/queries_controller.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-module Sherlock
- class QueriesController < Sherlock::ApplicationController
- def show
- @query = @transaction.find_query(params[:id])
- end
- end
-end
diff --git a/app/controllers/sherlock/transactions_controller.rb b/app/controllers/sherlock/transactions_controller.rb
deleted file mode 100644
index 8d1847507cc..00000000000
--- a/app/controllers/sherlock/transactions_controller.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-module Sherlock
- class TransactionsController < Sherlock::ApplicationController
- def index
- @transactions = Gitlab::Sherlock.collection.newest_first
- end
-
- def show
- @transaction = Gitlab::Sherlock.collection.find_transaction(params[:id])
-
- render_404 unless @transaction
- end
-
- def destroy_all
- Gitlab::Sherlock.collection.clear
-
- redirect_back_or_default(options: { status: :found })
- end
- end
-end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 26f56307862..8710eebf210 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -23,6 +23,9 @@ class UsersController < ApplicationController
before_action :user, except: [:exists]
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)
+ end
feature_category :users
diff --git a/app/events/ci/pipeline_created_event.rb b/app/events/ci/pipeline_created_event.rb
new file mode 100644
index 00000000000..8b971b63cea
--- /dev/null
+++ b/app/events/ci/pipeline_created_event.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module Ci
+ class PipelineCreatedEvent < ::Gitlab::EventStore::Event
+ def schema
+ {
+ 'type' => 'object',
+ 'properties' => {
+ 'pipeline_id' => { 'type' => 'integer' }
+ }
+ }
+ end
+ end
+end
diff --git a/app/experiments/change_continuous_onboarding_link_urls_experiment.rb b/app/experiments/change_continuous_onboarding_link_urls_experiment.rb
deleted file mode 100644
index 680cb8eadd8..00000000000
--- a/app/experiments/change_continuous_onboarding_link_urls_experiment.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class ChangeContinuousOnboardingLinkUrlsExperiment < ApplicationExperiment # rubocop:disable Gitlab/NamespacedClass
- attr_writer :namespace
-
- def track(action, **event_args)
- super(action, **event_args.merge(namespace: @namespace))
- end
-end
diff --git a/app/experiments/new_project_sast_enabled_experiment.rb b/app/experiments/new_project_sast_enabled_experiment.rb
index b7b4552f0cc..a779b8ec633 100644
--- a/app/experiments/new_project_sast_enabled_experiment.rb
+++ b/app/experiments/new_project_sast_enabled_experiment.rb
@@ -15,4 +15,7 @@ class NewProjectSastEnabledExperiment < ApplicationExperiment # rubocop:disable
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
new file mode 100644
index 00000000000..1cadac7e7d4
--- /dev/null
+++ b/app/experiments/require_verification_for_namespace_creation_experiment.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class RequireVerificationForNamespaceCreationExperiment < ApplicationExperiment # rubocop:disable Gitlab/NamespacedClass
+ def control_behavior
+ false
+ end
+
+ def candidate_behavior
+ true
+ end
+
+ def candidate?
+ run
+ end
+
+ def record_conversion(namespace)
+ return unless should_track?
+
+ Experiment.by_name(name).record_conversion_event_for_subject(subject, namespace_id: namespace.id)
+ end
+
+ private
+
+ def subject
+ context.value[:user]
+ end
+end
diff --git a/app/experiments/templates/new_project_readme_content/readme_advanced.md.tt b/app/experiments/templates/new_project_readme_content/readme_advanced.md.tt
index 7592c7c6ab7..9b950ff49e4 100644
--- a/app/experiments/templates/new_project_readme_content/readme_advanced.md.tt
+++ b/app/experiments/templates/new_project_readme_content/readme_advanced.md.tt
@@ -47,7 +47,7 @@ Use the built-in continuous integration in GitLab.
# Editing this README
-When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](<%= redirect("https://www.makeareadme.com/") %>) for this template.
+When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com) for this template.
## Suggestions for a good README
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
diff --git a/app/finders/ci/runners_finder.rb b/app/finders/ci/runners_finder.rb
index 5d597f94f72..3ebf6bd1562 100644
--- a/app/finders/ci/runners_finder.rb
+++ b/app/finders/ci/runners_finder.rb
@@ -47,15 +47,19 @@ module Ci
end
def group_runners
- raise Gitlab::Access::AccessDeniedError unless can?(@current_user, :admin_group, @group)
+ raise Gitlab::Access::AccessDeniedError unless can?(@current_user, :read_group_runners, @group)
@runners = case @params[:membership]
when :direct
Ci::Runner.belonging_to_group(@group.id)
when :descendants, nil
- # Getting all runners from the group itself and all its descendant groups/projects
- descendant_projects = Project.for_group_and_its_subgroups(@group)
- Ci::Runner.belonging_to_group_or_project(@group.self_and_descendants, descendant_projects)
+ if ::Feature.enabled?(:ci_find_runners_by_ci_mirrors, @group, default_enabled: :yaml)
+ Ci::Runner.belonging_to_group_or_project_descendants(@group.id)
+ else
+ # Getting all runners from the group itself and all its descendant groups/projects
+ descendant_projects = Project.for_group_and_its_subgroups(@group)
+ Ci::Runner.legacy_belonging_to_group_or_project(@group.self_and_descendants, descendant_projects)
+ end
else
raise ArgumentError, 'Invalid membership filter'
end
diff --git a/app/finders/environments/environments_by_deployments_finder.rb b/app/finders/environments/environments_by_deployments_finder.rb
index 2716c80ea6e..1a0d5ff0d5e 100644
--- a/app/finders/environments/environments_by_deployments_finder.rb
+++ b/app/finders/environments/environments_by_deployments_finder.rb
@@ -14,8 +14,7 @@ module Environments
def execute
deployments =
if ref
- deployments_query = params[:with_tags] ? 'ref = :ref OR tag IS TRUE' : 'ref = :ref'
- Deployment.where(deployments_query, ref: ref.to_s)
+ Deployment.where(ref: ref.to_s)
elsif commit
Deployment.where(sha: commit.sha)
else
diff --git a/app/finders/fork_targets_finder.rb b/app/finders/fork_targets_finder.rb
index 3a79b216853..0b5dfb16572 100644
--- a/app/finders/fork_targets_finder.rb
+++ b/app/finders/fork_targets_finder.rb
@@ -8,9 +8,9 @@ class ForkTargetsFinder
# rubocop: disable CodeReuse/ActiveRecord
def execute(options = {})
- return ::Namespace.where(id: user.manageable_namespaces).sort_by_type unless options[:only_groups]
+ return ::Namespace.where(id: user.forkable_namespaces).sort_by_type unless options[:only_groups]
- ::Group.where(id: user.manageable_groups)
+ ::Group.where(id: user.manageable_groups(include_groups_with_developer_maintainer_access: true))
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/finders/group_descendants_finder.rb b/app/finders/group_descendants_finder.rb
index 7974710e67b..3d9b6e94cc6 100644
--- a/app/finders/group_descendants_finder.rb
+++ b/app/finders/group_descendants_finder.rb
@@ -87,13 +87,7 @@ class GroupDescendantsFinder
visible_to_user = visible_to_user.or(authorized_to_user)
end
- group_to_query = if Feature.enabled?(:linear_group_descendants_finder, current_user, default_enabled: :yaml)
- parent_group
- else
- hierarchy_for_parent
- end
-
- group_to_query.descendants.where(visible_to_user)
+ parent_group.descendants.where(visible_to_user)
# rubocop: enable CodeReuse/Finder
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -159,13 +153,7 @@ class GroupDescendantsFinder
# rubocop: disable CodeReuse/ActiveRecord
def projects_matching_filter
# rubocop: disable CodeReuse/Finder
- objects_in_hierarchy = if Feature.enabled?(:linear_group_descendants_finder, current_user, default_enabled: :yaml)
- parent_group.self_and_descendants.as_ids
- else
- hierarchy_for_parent.base_and_descendants.select(:id)
- end
-
- projects_nested_in_group = Project.where(namespace_id: objects_in_hierarchy)
+ projects_nested_in_group = Project.where(namespace_id: parent_group.self_and_descendants.as_ids)
params_with_search = params.merge(search: params[:filter])
ProjectsFinder.new(params: params_with_search,
diff --git a/app/finders/group_members_finder.rb b/app/finders/group_members_finder.rb
index 75623d33ef5..fff17098c7b 100644
--- a/app/finders/group_members_finder.rb
+++ b/app/finders/group_members_finder.rb
@@ -1,14 +1,15 @@
# frozen_string_literal: true
class GroupMembersFinder < UnionFinder
- RELATIONS = %i(direct inherited descendants).freeze
+ RELATIONS = %i(direct inherited descendants shared_from_groups).freeze
DEFAULT_RELATIONS = %i(direct inherited).freeze
INVALID_RELATION_TYPE_ERROR_MSG = "is not a valid relation type. Valid relation types are #{RELATIONS.join(', ')}."
RELATIONS_DESCRIPTIONS = {
direct: 'Members in the group itself',
inherited: "Members in the group's ancestor groups",
- descendants: "Members in the group's subgroups"
+ descendants: "Members in the group's subgroups",
+ shared_from_groups: "Invited group's members"
}.freeze
include CreatedAtFilter
@@ -28,11 +29,7 @@ class GroupMembersFinder < UnionFinder
end
def execute(include_relations: DEFAULT_RELATIONS)
- return filter_members(group_members_list) if include_relations == [:direct]
-
groups = groups_by_relations(include_relations)
- return GroupMember.none unless groups
-
members = all_group_members(groups).distinct_on_user_with_max_access_level
filter_members(members)
@@ -45,22 +42,14 @@ class GroupMembersFinder < UnionFinder
def groups_by_relations(include_relations)
check_relation_arguments!(include_relations)
- case include_relations.sort
- when [:inherited]
- group.ancestors
- when [:descendants]
- group.descendants
- when [:direct, :inherited]
- group.self_and_ancestors
- when [:descendants, :direct]
- group.self_and_descendants
- when [:descendants, :inherited]
- find_union([group.ancestors, group.descendants], Group)
- when [:descendants, :direct, :inherited]
- group.self_and_hierarchy
- else
- nil
- end
+ related_groups = []
+
+ related_groups << Group.by_id(group.id) if include_relations&.include?(:direct)
+ related_groups << group.ancestors if include_relations&.include?(:inherited)
+ related_groups << group.descendants if include_relations&.include?(:descendants)
+ related_groups << group.shared_with_groups.public_or_visible_to_user(user) if include_relations&.include?(:shared_from_groups)
+
+ find_union(related_groups, Group)
end
def filter_members(members)
diff --git a/app/finders/groups/user_groups_finder.rb b/app/finders/groups/user_groups_finder.rb
index 5946e3a8933..f4aed413867 100644
--- a/app/finders/groups/user_groups_finder.rb
+++ b/app/finders/groups/user_groups_finder.rb
@@ -53,8 +53,7 @@ module Groups
end
def permission_scope_create_projects?
- params[:permission_scope] == :create_projects &&
- Feature.enabled?(:paginatable_namespace_drop_down_for_project_creation, current_user, default_enabled: :yaml)
+ params[:permission_scope] == :create_projects
end
end
end
diff --git a/app/finders/groups_finder.rb b/app/finders/groups_finder.rb
index 7e3cdd79a4c..7cb3e7a5d7f 100644
--- a/app/finders/groups_finder.rb
+++ b/app/finders/groups_finder.rb
@@ -54,7 +54,7 @@ class GroupsFinder < UnionFinder
groups = []
if current_user
- if Feature.enabled?(:use_traversal_ids_groups_finder, default_enabled: :yaml)
+ if Feature.enabled?(:use_traversal_ids_groups_finder, current_user, default_enabled: :yaml)
groups << current_user.authorized_groups.self_and_ancestors
groups << current_user.groups.self_and_descendants
else
@@ -81,7 +81,7 @@ class GroupsFinder < UnionFinder
.groups
.where('members.access_level >= ?', params[:min_access_level])
- if Feature.enabled?(:use_traversal_ids_groups_finder, default_enabled: :yaml)
+ if Feature.enabled?(:use_traversal_ids_groups_finder, current_user, default_enabled: :yaml)
groups.self_and_descendants
else
Gitlab::ObjectHierarchy
diff --git a/app/finders/issues_finder.rb b/app/finders/issues_finder.rb
index 21a19aa22a1..de750b49c6a 100644
--- a/app/finders/issues_finder.rb
+++ b/app/finders/issues_finder.rb
@@ -27,7 +27,7 @@
# updated_after: datetime
# updated_before: datetime
# confidential: boolean
-# issue_types: array of strings (one of WorkItem::Type.base_types)
+# issue_types: array of strings (one of WorkItems::Type.base_types)
#
class IssuesFinder < IssuableFinder
CONFIDENTIAL_ACCESS_LEVEL = Gitlab::Access::REPORTER
@@ -124,13 +124,13 @@ class IssuesFinder < IssuableFinder
def by_issue_types(items)
issue_type_params = Array(params[:issue_types]).map(&:to_s)
return items if issue_type_params.blank?
- return Issue.none unless (WorkItem::Type.base_types.keys & issue_type_params).sort == issue_type_params.sort
+ return Issue.none unless (WorkItems::Type.base_types.keys & issue_type_params).sort == issue_type_params.sort
items.with_issue_type(params[:issue_types])
end
def by_negated_issue_types(items)
- issue_type_params = Array(not_params[:issue_types]).map(&:to_s) & WorkItem::Type.base_types.keys
+ issue_type_params = Array(not_params[:issue_types]).map(&:to_s) & WorkItems::Type.base_types.keys
return items if issue_type_params.blank?
items.without_issue_type(issue_type_params)
diff --git a/app/finders/merge_requests_finder.rb b/app/finders/merge_requests_finder.rb
index ba709d3bdfc..81e4ab7014d 100644
--- a/app/finders/merge_requests_finder.rb
+++ b/app/finders/merge_requests_finder.rb
@@ -140,14 +140,13 @@ class MergeRequestsFinder < IssuableFinder
# rubocop: disable CodeReuse/ActiveRecord
def by_draft(items)
- draft_param = params[:draft] || params[:wip]
+ draft_param = Gitlab::Utils.to_boolean(params.fetch(:draft) { params.fetch(:wip, nil) })
+ return items if draft_param.nil?
- if draft_param == 'yes'
+ if draft_param
items.where(wip_match(items.arel_table))
- elsif draft_param == 'no'
- items.where.not(wip_match(items.arel_table))
else
- items
+ items.where.not(wip_match(items.arel_table))
end
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/finders/packages/package_file_finder.rb b/app/finders/packages/package_file_finder.rb
index 792ffa0591b..55dc4be2001 100644
--- a/app/finders/packages/package_file_finder.rb
+++ b/app/finders/packages/package_file_finder.rb
@@ -19,7 +19,11 @@ class Packages::PackageFileFinder
private
def package_files
- files = package.package_files
+ files = if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml)
+ package.installable_package_files
+ else
+ package.package_files
+ end
by_file_name(files)
end
diff --git a/app/finders/projects/members/effective_access_level_finder.rb b/app/finders/projects/members/effective_access_level_finder.rb
index d238679f2fb..4538fc4c855 100644
--- a/app/finders/projects/members/effective_access_level_finder.rb
+++ b/app/finders/projects/members/effective_access_level_finder.rb
@@ -27,13 +27,9 @@ module Projects
attr_reader :project
def generate_from_statement(user_ids_and_access_levels)
- "(VALUES #{generate_values_expression(user_ids_and_access_levels)}) members (user_id, access_level)"
- end
+ values_list = Arel::Nodes::ValuesList.new(user_ids_and_access_levels).to_sql
- def generate_values_expression(user_ids_and_access_levels)
- user_ids_and_access_levels.map do |user_id, access_level|
- "(#{user_id}, #{access_level})"
- end.join(",")
+ "(#{values_list}) members (user_id, access_level)"
end
def no_members?
diff --git a/app/finders/user_group_notification_settings_finder.rb b/app/finders/user_group_notification_settings_finder.rb
index c2af581dd14..c6a1a6b36d1 100644
--- a/app/finders/user_group_notification_settings_finder.rb
+++ b/app/finders/user_group_notification_settings_finder.rb
@@ -7,15 +7,7 @@ class UserGroupNotificationSettingsFinder
end
def execute
- # rubocop: disable CodeReuse/ActiveRecord
- selected_groups = Group.where(id: groups.select(:id))
- groups_with_ancestors = if Feature.enabled?(:linear_user_group_notification_settings_finder_ancestors_scopes, user, default_enabled: :yaml)
- selected_groups.self_and_ancestors
- else
- Gitlab::ObjectHierarchy.new(selected_groups).base_and_ancestors
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
+ groups_with_ancestors = groups.self_and_ancestors
@loaded_groups_with_ancestors = groups_with_ancestors.index_by(&:id)
@loaded_notification_settings = user.notification_settings_for_groups(groups_with_ancestors).preload_source_route.index_by(&:source_id)
diff --git a/app/finders/user_recent_events_finder.rb b/app/finders/user_recent_events_finder.rb
index 596a413782e..96120d9412f 100644
--- a/app/finders/user_recent_events_finder.rb
+++ b/app/finders/user_recent_events_finder.rb
@@ -47,6 +47,24 @@ class UserRecentEventsFinder
end
# rubocop: disable CodeReuse/ActiveRecord
+ def execute_optimized_multi(users)
+ Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder.new(
+ scope: Event.reorder(id: :desc),
+ array_scope: User.select(:id).where(id: users),
+ # Event model has a default scope { reorder(nil) }
+ # When a relation is rordered and used as a target when merging scope,
+ # its order takes a precedence and _overwrites_ the original scope's order.
+ # Thus we have to explicitly provide `reorder` for array_mapping_scope here.
+ array_mapping_scope: -> (author_id_expression) { Event.where(Event.arel_table[:author_id].eq(author_id_expression)).reorder(id: :desc) },
+ finder_query: -> (id_expression) { Event.where(Event.arel_table[:id].eq(id_expression)) }
+ )
+ .execute
+ .limit(limit)
+ .offset(params[:offset] || 0)
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ # rubocop: disable CodeReuse/ActiveRecord
def execute_multi
users = []
@target_user.each do |user|
@@ -55,7 +73,11 @@ class UserRecentEventsFinder
return Event.none if users.empty?
- event_filter.apply_filter(Event.where(author: users).limit_recent(limit, params[:offset] || 0))
+ if event_filter.filter == EventFilter::ALL
+ execute_optimized_multi(users)
+ else
+ event_filter.apply_filter(Event.where(author: users).limit_recent(limit, params[:offset] || 0))
+ end
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/graphql/mutations/clusters/agent_tokens/revoke.rb b/app/graphql/mutations/clusters/agent_tokens/revoke.rb
new file mode 100644
index 00000000000..ca570792296
--- /dev/null
+++ b/app/graphql/mutations/clusters/agent_tokens/revoke.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Clusters
+ module AgentTokens
+ class Revoke < BaseMutation
+ graphql_name 'ClusterAgentTokenRevoke'
+
+ authorize :admin_cluster
+
+ TokenID = ::Types::GlobalIDType[::Clusters::AgentToken]
+
+ argument :id, TokenID,
+ required: true,
+ description: 'Global ID of the agent token that will be revoked.'
+
+ def resolve(id:)
+ token = authorized_find!(id: id)
+ token.update(status: token.class.statuses[:revoked])
+
+ { errors: errors_on_object(token) }
+ 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 = TokenID.coerce_isolated_input(id)
+ GitlabSchema.find_by_gid(id)
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/issues/set_crm_contacts.rb b/app/graphql/mutations/issues/set_crm_contacts.rb
index 4e49a45d52a..62990fc67f1 100644
--- a/app/graphql/mutations/issues/set_crm_contacts.rb
+++ b/app/graphql/mutations/issues/set_crm_contacts.rb
@@ -18,7 +18,8 @@ module Mutations
def resolve(project_path:, iid:, contact_ids:, operation_mode: Types::MutationOperationModeEnum.enum[:replace])
issue = authorized_find!(project_path: project_path, iid: iid)
project = issue.project
- raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature disabled' unless Feature.enabled?(:customer_relations, project.group, default_enabled: :yaml)
+
+ raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature disabled' unless feature_enabled?(project)
contact_ids = contact_ids.compact.map do |contact_id|
raise Gitlab::Graphql::Errors::ArgumentError, "Contact #{contact_id} is invalid." unless contact_id.respond_to?(:model_id)
@@ -43,6 +44,12 @@ module Mutations
errors: response.errors
}
end
+
+ private
+
+ def feature_enabled?(project)
+ Feature.enabled?(:customer_relations, project.group, default_enabled: :yaml) && project.group&.crm_enabled?
+ end
end
end
end
diff --git a/app/graphql/mutations/issues/set_escalation_status.rb b/app/graphql/mutations/issues/set_escalation_status.rb
new file mode 100644
index 00000000000..6073b73277b
--- /dev/null
+++ b/app/graphql/mutations/issues/set_escalation_status.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Issues
+ class SetEscalationStatus < Base
+ graphql_name 'IssueSetEscalationStatus'
+
+ argument :status, Types::IncidentManagement::EscalationStatusEnum,
+ required: true,
+ description: 'Set the escalation status.'
+
+ def resolve(project_path:, iid:, status:)
+ issue = authorized_find!(project_path: project_path, iid: iid)
+ project = issue.project
+
+ authorize_escalation_status!(project)
+ check_feature_availability!(project, issue)
+
+ ::Issues::UpdateService.new(
+ project: project,
+ current_user: current_user,
+ params: { escalation_status: { status: status } }
+ ).execute(issue)
+
+ {
+ issue: issue,
+ errors: errors_on_object(issue)
+ }
+ end
+
+ private
+
+ def authorize_escalation_status!(project)
+ return if Ability.allowed?(current_user, :update_escalation_status, project)
+
+ raise_resource_not_available_error!
+ end
+
+ def check_feature_availability!(project, issue)
+ return if Feature.enabled?(:incident_escalations, project) && issue.supports_escalation?
+
+ raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature unavailable for provided issue'
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/work_items/create.rb b/app/graphql/mutations/work_items/create.rb
new file mode 100644
index 00000000000..88b8cefd8d2
--- /dev/null
+++ b/app/graphql/mutations/work_items/create.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+module Mutations
+ module WorkItems
+ class Create < BaseMutation
+ include Mutations::SpamProtection
+ include FindsProject
+
+ graphql_name 'WorkItemCreate'
+
+ authorize :create_work_item
+
+ argument :description, GraphQL::Types::String,
+ required: false,
+ description: copy_field_description(Types::WorkItemType, :description)
+ argument :project_path, GraphQL::Types::ID,
+ required: true,
+ description: 'Full path of the project the work item is associated with.'
+ argument :title, GraphQL::Types::String,
+ required: true,
+ description: copy_field_description(Types::WorkItemType, :title)
+ argument :work_item_type_id, ::Types::GlobalIDType[::WorkItems::Type],
+ required: true,
+ description: 'Global ID of a work item type.'
+
+ field :work_item, Types::WorkItemType,
+ null: true,
+ description: 'Created work item.'
+
+ def resolve(project_path:, **attributes)
+ project = authorized_find!(project_path)
+ params = global_id_compatibility_params(attributes).merge(author_id: current_user.id)
+
+ spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
+ work_item = ::WorkItems::CreateService.new(project: project, current_user: current_user, params: params, spam_params: spam_params).execute
+
+ check_spam_action_response!(work_item)
+
+ {
+ work_item: work_item.valid? ? work_item : nil,
+ errors: errors_on_object(work_item)
+ }
+ end
+
+ private
+
+ def global_id_compatibility_params(params)
+ # TODO: remove this line when the compatibility layer is removed
+ # See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
+ params[:work_item_type_id] = ::Types::GlobalIDType[::WorkItems::Type].coerce_isolated_input(params[:work_item_type_id]) if params[:work_item_type_id]
+ params[:work_item_type_id] = params[:work_item_type_id]&.model_id
+
+ params
+ end
+ end
+ end
+end
diff --git a/app/graphql/queries/pipelines/get_pipeline_details.query.graphql b/app/graphql/queries/pipelines/get_pipeline_details.query.graphql
index dd5c9e07488..5dece2f81cc 100644
--- a/app/graphql/queries/pipelines/get_pipeline_details.query.graphql
+++ b/app/graphql/queries/pipelines/get_pipeline_details.query.graphql
@@ -1,3 +1,18 @@
+fragment CiNeeds on JobNeedUnion {
+ ...CiBuildNeedFields
+ ...CiJobNeedFields
+}
+
+fragment CiBuildNeedFields on CiBuildNeed {
+ id
+ name
+}
+
+fragment CiJobNeedFields on CiJob {
+ id
+ name
+}
+
fragment LinkedPipelineData on Pipeline {
__typename
id
@@ -91,6 +106,12 @@ query getPipelineDetails($projectPath: ID!, $iid: ID!) {
name
}
}
+ previousStageJobsOrNeeds {
+ __typename
+ nodes {
+ ...CiNeeds
+ }
+ }
status: detailedStatus {
__typename
id
diff --git a/app/graphql/resolvers/base_issues_resolver.rb b/app/graphql/resolvers/base_issues_resolver.rb
index 3983a3697cb..3e7509b4068 100644
--- a/app/graphql/resolvers/base_issues_resolver.rb
+++ b/app/graphql/resolvers/base_issues_resolver.rb
@@ -48,7 +48,8 @@ module Resolvers
labels: [:labels],
assignees: [:assignees],
timelogs: [:timelogs],
- customer_relations_contacts: { customer_relations_contacts: [:group] }
+ customer_relations_contacts: { customer_relations_contacts: [:group] },
+ escalation_status: [:incident_management_issuable_escalation_status]
}
end
diff --git a/app/graphql/resolvers/ci/config_resolver.rb b/app/graphql/resolvers/ci/config_resolver.rb
index 2d74392a84c..387185b5171 100644
--- a/app/graphql/resolvers/ci/config_resolver.rb
+++ b/app/graphql/resolvers/ci/config_resolver.rb
@@ -47,11 +47,13 @@ module Resolvers
{
status: :valid,
errors: [],
+ warnings: result.warnings,
stages: make_stages(result.jobs)
}
else
{
status: :invalid,
+ warnings: result.warnings,
errors: result.errors
}
end
diff --git a/app/graphql/resolvers/clusters/agent_tokens_resolver.rb b/app/graphql/resolvers/clusters/agent_tokens_resolver.rb
index 5ae19700fd5..8208fa56485 100644
--- a/app/graphql/resolvers/clusters/agent_tokens_resolver.rb
+++ b/app/graphql/resolvers/clusters/agent_tokens_resolver.rb
@@ -9,10 +9,17 @@ module Resolvers
delegate :project, to: :agent
+ argument :status, Types::Clusters::AgentTokenStatusEnum,
+ required: false,
+ description: 'Status of the token.'
+
def resolve(**args)
return ::Clusters::AgentToken.none unless can_read_agent_tokens?
- agent.last_used_agent_tokens
+ tokens = agent.last_used_agent_tokens
+ tokens = tokens.with_status(args[:status]) if args[:status].present?
+
+ tokens
end
private
diff --git a/app/graphql/resolvers/concerns/resolves_pipelines.rb b/app/graphql/resolvers/concerns/resolves_pipelines.rb
index 1c01e5e0250..42c4c22a938 100644
--- a/app/graphql/resolvers/concerns/resolves_pipelines.rb
+++ b/app/graphql/resolvers/concerns/resolves_pipelines.rb
@@ -24,7 +24,7 @@ module ResolvesPipelines
argument :source,
GraphQL::Types::String,
required: false,
- description: "Filter pipelines by their source. Will be ignored if `dast_view_scans` feature flag is disabled."
+ description: "Filter pipelines by their source."
end
class_methods do
@@ -38,8 +38,6 @@ module ResolvesPipelines
end
def resolve_pipelines(project, params = {})
- params.delete(:source) unless Feature.enabled?(:dast_view_scans, project, default_enabled: :yaml)
-
Ci::PipelinesFinder.new(project, context[:current_user], params).execute
end
end
diff --git a/app/graphql/resolvers/design_management/version/designs_at_version_resolver.rb b/app/graphql/resolvers/design_management/version/designs_at_version_resolver.rb
index 254f1efa0a5..97cc7554ba8 100644
--- a/app/graphql/resolvers/design_management/version/designs_at_version_resolver.rb
+++ b/app/graphql/resolvers/design_management/version/designs_at_version_resolver.rb
@@ -13,13 +13,13 @@ module Resolvers
DesignID = ::Types::GlobalIDType[::DesignManagement::Design]
- argument :ids, [DesignID],
- required: false,
- description: 'Filters designs by their ID.'
argument :filenames,
[GraphQL::Types::String],
required: false,
description: 'Filters designs by their filename.'
+ argument :ids, [DesignID],
+ required: false,
+ description: 'Filters designs by their ID.'
def self.single
::Resolvers::DesignManagement::Version::DesignAtVersionResolver
diff --git a/app/graphql/resolvers/design_management/version_in_collection_resolver.rb b/app/graphql/resolvers/design_management/version_in_collection_resolver.rb
index 80db15755d3..2682ce6b3b1 100644
--- a/app/graphql/resolvers/design_management/version_in_collection_resolver.rb
+++ b/app/graphql/resolvers/design_management/version_in_collection_resolver.rb
@@ -15,13 +15,13 @@ module Resolvers
VersionID = ::Types::GlobalIDType[::DesignManagement::Version]
- argument :sha, GraphQL::Types::String,
- required: false,
- description: "SHA256 of a specific version."
argument :id, VersionID,
as: :version_id,
required: false,
description: 'Global ID of the version.'
+ argument :sha, GraphQL::Types::String,
+ required: false,
+ description: "SHA256 of a specific version."
def resolve(version_id: nil, sha: nil)
# TODO: remove this line when the compatibility layer is removed
diff --git a/app/graphql/resolvers/group_milestones_resolver.rb b/app/graphql/resolvers/group_milestones_resolver.rb
index 44192b6f4bf..319ff9f68c4 100644
--- a/app/graphql/resolvers/group_milestones_resolver.rb
+++ b/app/graphql/resolvers/group_milestones_resolver.rb
@@ -2,12 +2,12 @@
module Resolvers
class GroupMilestonesResolver < MilestonesResolver
- argument :include_descendants, GraphQL::Types::Boolean,
- required: false,
- description: 'Include milestones from all subgroups and subprojects.'
argument :include_ancestors, GraphQL::Types::Boolean,
required: false,
description: 'Include milestones from all parent groups.'
+ argument :include_descendants, GraphQL::Types::Boolean,
+ required: false,
+ description: 'Include milestones from all subgroups and subprojects.'
type Types::MilestoneType.connection_type, null: true
diff --git a/app/graphql/resolvers/merge_requests_resolver.rb b/app/graphql/resolvers/merge_requests_resolver.rb
index bd7f1f0774e..6dbcbe0e04d 100644
--- a/app/graphql/resolvers/merge_requests_resolver.rb
+++ b/app/graphql/resolvers/merge_requests_resolver.rb
@@ -51,6 +51,10 @@ module Resolvers
required: false,
description: 'Merge request state. If provided, all resolved merge requests will have this state.'
+ argument :draft, GraphQL::Types::Boolean,
+ required: false,
+ description: 'Limit result to draft merge requests.'
+
argument :labels, [GraphQL::Types::String],
required: false,
as: :label_name,
diff --git a/app/graphql/resolvers/users/groups_resolver.rb b/app/graphql/resolvers/users/groups_resolver.rb
index eafb56d8f4c..d8492a8fcf9 100644
--- a/app/graphql/resolvers/users/groups_resolver.rb
+++ b/app/graphql/resolvers/users/groups_resolver.rb
@@ -23,10 +23,6 @@ module Resolvers
Preloaders::GroupPolicyPreloader.new(nodes, current_user).execute
end
- def ready?(**args)
- Feature.enabled?(:paginatable_namespace_drop_down_for_project_creation, current_user, default_enabled: :yaml)
- end
-
private
def resolve_groups(**args)
diff --git a/app/graphql/resolvers/work_items/types_resolver.rb b/app/graphql/resolvers/work_items/types_resolver.rb
new file mode 100644
index 00000000000..b7a32e13423
--- /dev/null
+++ b/app/graphql/resolvers/work_items/types_resolver.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module WorkItems
+ class TypesResolver < BaseResolver
+ type Types::WorkItems::TypeType.connection_type, null: true
+
+ def resolve
+ # 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
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/ci/config/config_type.rb b/app/graphql/types/ci/config/config_type.rb
index 6ac21968bd4..de355c8eacf 100644
--- a/app/graphql/types/ci/config/config_type.rb
+++ b/app/graphql/types/ci/config/config_type.rb
@@ -15,6 +15,8 @@ module Types
description: 'Stages of the pipeline.'
field :status, Types::Ci::Config::StatusEnum, null: true,
description: 'Status of linting, can be either valid or invalid.'
+ field :warnings, [GraphQL::Types::String], null: true,
+ description: 'Linting warnings.'
end
end
end
diff --git a/app/graphql/types/ci/job_type.rb b/app/graphql/types/ci/job_type.rb
index 928ca2f597d..1320b96907e 100644
--- a/app/graphql/types/ci/job_type.rb
+++ b/app/graphql/types/ci/job_type.rb
@@ -50,6 +50,8 @@ 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,
@@ -89,6 +91,10 @@ module Types
Gitlab::Graphql::Loaders::BatchModelLoader.new(::Ci::Pipeline, object.pipeline_id).find
end
+ def downstream_pipeline
+ object.downstream_pipeline if object.respond_to?(:downstream_pipeline)
+ end
+
def tags
object.tags.map(&:name) if object.is_a?(::Ci::Build)
end
diff --git a/app/graphql/types/ci/pipeline_message_type.rb b/app/graphql/types/ci/pipeline_message_type.rb
new file mode 100644
index 00000000000..7edea1901a1
--- /dev/null
+++ b/app/graphql/types/ci/pipeline_message_type.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ # rubocop: disable Graphql/AuthorizeTypes
+ class PipelineMessageType < BaseObject
+ graphql_name 'PipelineMessage'
+
+ field :id, GraphQL::Types::ID, null: false,
+ description: 'ID of the pipeline message.'
+
+ field :content, GraphQL::Types::String, null: false,
+ description: 'Content of the pipeline message.'
+ end
+ end
+end
diff --git a/app/graphql/types/ci/pipeline_type.rb b/app/graphql/types/ci/pipeline_type.rb
index c8ac31bce4d..537b8e42ad1 100644
--- a/app/graphql/types/ci/pipeline_type.rb
+++ b/app/graphql/types/ci/pipeline_type.rb
@@ -18,8 +18,14 @@ module Types
field :iid, GraphQL::Types::String, null: false,
description: 'Internal ID of the pipeline.'
- field :sha, GraphQL::Types::String, null: false,
- description: "SHA of the pipeline's commit."
+ field :sha, GraphQL::Types::String, null: true,
+ method: :sha,
+ description: "SHA of the pipeline's commit." do
+ argument :format,
+ type: Types::ShaFormatEnum,
+ required: false,
+ description: 'Format of the SHA.'
+ end
field :before_sha, GraphQL::Types::String, null: true,
description: 'Base SHA of the source branch.'
@@ -162,6 +168,13 @@ module Types
field :ref, GraphQL::Types::String, null: true,
description: 'Reference to the branch from which the pipeline was triggered.'
+ field :ref_path, GraphQL::Types::String, null: true,
+ description: 'Reference path to the branch from which the pipeline was triggered.',
+ method: :source_ref_path
+
+ field :warning_messages, [Types::Ci::PipelineMessageType], null: true,
+ description: 'Pipeline warning messages.'
+
def detailed_status
object.detailed_status(current_user)
end
@@ -189,6 +202,12 @@ module Types
end.take # rubocop: disable CodeReuse/ActiveRecord
end
+ def sha(format: Types::ShaFormatEnum.enum[:long])
+ return pipeline.short_sha if format == Types::ShaFormatEnum.enum[:short]
+
+ pipeline.sha
+ end
+
alias_method :pipeline, :object
end
end
diff --git a/app/graphql/types/ci/runner_type.rb b/app/graphql/types/ci/runner_type.rb
index d37cca0927f..4fe65734911 100644
--- a/app/graphql/types/ci/runner_type.rb
+++ b/app/graphql/types/ci/runner_type.rb
@@ -4,6 +4,7 @@ module Types
module Ci
class RunnerType < BaseObject
edge_type_class(RunnerWebUrlEdge)
+ connection_type_class(Types::CountableConnectionType)
graphql_name 'CiRunner'
authorize :read_runner
present_using ::Ci::RunnerPresenter
@@ -18,8 +19,10 @@ module Types
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: 'Last contact from the runner.',
+ description: 'Timestamp of last contact from this runner.',
method: :contacted_at
field :maximum_timeout, GraphQL::Types::Int, null: true,
description: 'Maximum timeout (in seconds) for jobs processed by the runner.'
@@ -54,6 +57,12 @@ module Types
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 :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,
+ description: 'Executor last advertised by the runner.',
+ method: :executor_name,
+ feature_flag: :graphql_ci_runner_executor
def job_count
# We limit to 1 above the JOB_COUNT_LIMIT to indicate that more items exist after JOB_COUNT_LIMIT
@@ -64,6 +73,10 @@ module Types
Gitlab::Routing.url_helpers.admin_runner_url(runner) if can_admin_runners?
end
+ def edit_admin_url
+ Gitlab::Routing.url_helpers.edit_admin_runner_url(runner) if can_admin_runners?
+ end
+
# rubocop: disable CodeReuse/ActiveRecord
def project_count
BatchLoader::GraphQL.for(runner.id).batch(key: :runner_project_count) do |ids, loader, args|
diff --git a/app/graphql/types/clusters/agent_token_status_enum.rb b/app/graphql/types/clusters/agent_token_status_enum.rb
new file mode 100644
index 00000000000..c00a64d21c1
--- /dev/null
+++ b/app/graphql/types/clusters/agent_token_status_enum.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module Types
+ module Clusters
+ class AgentTokenStatusEnum < BaseEnum
+ graphql_name 'AgentTokenStatus'
+ description 'Agent token statuses'
+
+ ::Clusters::AgentToken.statuses.keys.each do |status|
+ value status.upcase, value: status, description: "#{status.titleize} agent token."
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/clusters/agent_token_type.rb b/app/graphql/types/clusters/agent_token_type.rb
index 94c5fc46a5d..96fdb5f05c8 100644
--- a/app/graphql/types/clusters/agent_token_type.rb
+++ b/app/graphql/types/clusters/agent_token_type.rb
@@ -44,6 +44,11 @@ module Types
null: true,
description: 'Name given to the token.'
+ field :status,
+ Types::Clusters::AgentTokenStatusEnum,
+ null: true,
+ description: 'Current status of the token.'
+
def cluster_agent
Gitlab::Graphql::Loaders::BatchModelLoader.new(::Clusters::Agent, object.agent_id).find
end
diff --git a/app/graphql/types/commit_type.rb b/app/graphql/types/commit_type.rb
index 7d141bd6daa..2584e15ff0b 100644
--- a/app/graphql/types/commit_type.rb
+++ b/app/graphql/types/commit_type.rb
@@ -39,6 +39,8 @@ module Types
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.'
diff --git a/app/graphql/types/deprecated_mutations.rb b/app/graphql/types/deprecated_mutations.rb
index 49bad56b6f9..70d5fc31cd1 100644
--- a/app/graphql/types/deprecated_mutations.rb
+++ b/app/graphql/types/deprecated_mutations.rb
@@ -5,7 +5,8 @@ module Types
extend ActiveSupport::Concern
prepended do
- # placeholder for any FOSS mutations to be deprecated
+ mount_mutation Mutations::Clusters::AgentTokens::Delete,
+ deprecated: { reason: 'Tokens must be revoked with ClusterAgentTokenRevoke', milestone: '14.7' }
end
end
end
diff --git a/app/graphql/types/group_type.rb b/app/graphql/types/group_type.rb
index 4a20d84f2ab..e02650fd285 100644
--- a/app/graphql/types/group_type.rb
+++ b/app/graphql/types/group_type.rb
@@ -210,6 +210,11 @@ module Types
null: true,
description: "Find contacts of this group."
+ 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
+
def avatar_url
object.avatar_url(only_path: false)
end
diff --git a/app/graphql/types/incident_management/escalation_status_enum.rb b/app/graphql/types/incident_management/escalation_status_enum.rb
new file mode 100644
index 00000000000..bc462f03148
--- /dev/null
+++ b/app/graphql/types/incident_management/escalation_status_enum.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module Types
+ module IncidentManagement
+ class EscalationStatusEnum < BaseEnum
+ graphql_name 'IssueEscalationStatus'
+ description 'Issue escalation status values'
+
+ ::IncidentManagement::IssuableEscalationStatus.status_names.each do |status|
+ value status.to_s.upcase, value: status, description: "#{::IncidentManagement::IssuableEscalationStatus::STATUS_DESCRIPTIONS[status]}."
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/issue_type.rb b/app/graphql/types/issue_type.rb
index 498569f11ca..46fe91feae4 100644
--- a/app/graphql/types/issue_type.rb
+++ b/app/graphql/types/issue_type.rb
@@ -140,6 +140,9 @@ module Types
field :customer_relations_contacts, Types::CustomerRelations::ContactType.connection_type, null: true,
description: 'Customer relations contacts of the issue.'
+ field :escalation_status, Types::IncidentManagement::EscalationStatusEnum, null: true,
+ description: 'Escalation status of the issue.'
+
def author
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find
end
@@ -167,6 +170,12 @@ module Types
def hidden?
object.hidden? if Feature.enabled?(:ban_user_feature_flag)
end
+
+ def escalation_status
+ return unless Feature.enabled?(:incident_escalations, object.project) && object.supports_escalation?
+
+ object.escalation_status&.status_name
+ end
end
end
diff --git a/app/graphql/types/issue_type_enum.rb b/app/graphql/types/issue_type_enum.rb
index 0cfba6bbbd0..b18c8b90e96 100644
--- a/app/graphql/types/issue_type_enum.rb
+++ b/app/graphql/types/issue_type_enum.rb
@@ -5,7 +5,7 @@ module Types
graphql_name 'IssueType'
description 'Issue type'
- ::WorkItem::Type.allowed_types_for_issues.each do |issue_type|
+ ::WorkItems::Type.allowed_types_for_issues.each do |issue_type|
value issue_type.upcase, value: issue_type, description: "#{issue_type.titleize} issue type"
end
end
diff --git a/app/graphql/types/merge_request_type.rb b/app/graphql/types/merge_request_type.rb
index 0672ec6f0f8..ea05671c79c 100644
--- a/app/graphql/types/merge_request_type.rb
+++ b/app/graphql/types/merge_request_type.rb
@@ -189,6 +189,8 @@ module Types
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 :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,
@@ -196,7 +198,7 @@ module Types
field :auto_merge_strategy, GraphQL::Types::String, null: true,
description: 'Selected auto merge strategy.'
field :merge_user, Types::UserType, null: true,
- description: 'User who merged this merge request.'
+ description: 'User who merged this merge request or set it to merge when pipeline succeeds.'
field :timelogs, Types::TimelogType.connection_type, null: false,
description: 'Timelogs on the merge request.'
@@ -249,16 +251,28 @@ module Types
!!object.discussion_locked
end
+ def default_merge_commit_message
+ object.default_merge_commit_message(include_description: false, user: current_user)
+ end
+
def default_merge_commit_message_with_description
object.default_merge_commit_message(include_description: true)
end
+ def default_squash_commit_message
+ object.default_squash_commit_message(user: current_user)
+ end
+
def available_auto_merge_strategies
AutoMergeService.new(object.project, current_user).available_strategies(object)
end
+ def commits
+ object.commits.commits
+ end
+
def commits_without_merge_commits
- object.recent_commits.without_merge_commits
+ object.commits.without_merge_commits
end
def security_auto_fix
@@ -268,6 +282,10 @@ module Types
def reviewers
object.reviewers
end
+
+ def merge_user
+ object.metrics&.merged_by || object.merge_user
+ end
end
end
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index e8a952e9c61..c350f4dd922 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -35,7 +35,7 @@ module Types
mount_mutation Mutations::Clusters::Agents::Create
mount_mutation Mutations::Clusters::Agents::Delete
mount_mutation Mutations::Clusters::AgentTokens::Create
- mount_mutation Mutations::Clusters::AgentTokens::Delete
+ mount_mutation Mutations::Clusters::AgentTokens::Revoke
mount_mutation Mutations::Commits::Create, calls_gitaly: true
mount_mutation Mutations::CustomEmoji::Create, feature_flag: :custom_emoji
mount_mutation Mutations::CustomEmoji::Destroy, feature_flag: :custom_emoji
@@ -55,6 +55,7 @@ module Types
mount_mutation Mutations::Issues::SetDueDate
mount_mutation Mutations::Issues::SetSeverity
mount_mutation Mutations::Issues::SetSubscription
+ mount_mutation Mutations::Issues::SetEscalationStatus
mount_mutation Mutations::Issues::Update
mount_mutation Mutations::Issues::Move
mount_mutation Mutations::Labels::Create
@@ -123,6 +124,7 @@ module Types
mount_mutation Mutations::Packages::Destroy
mount_mutation Mutations::Packages::DestroyFile
mount_mutation Mutations::Echo
+ mount_mutation Mutations::WorkItems::Create, feature_flag: :work_items
end
end
diff --git a/app/graphql/types/packages/package_details_type.rb b/app/graphql/types/packages/package_details_type.rb
index 5ac80860fe2..1d2cf9649d8 100644
--- a/app/graphql/types/packages/package_details_type.rb
+++ b/app/graphql/types/packages/package_details_type.rb
@@ -3,6 +3,8 @@
module Types
module Packages
class PackageDetailsType < PackageType
+ include ::PackagesHelper
+
graphql_name 'PackageDetailsType'
description 'Represents a package details in the Package Registry. Note that this type is in beta and susceptible to changes'
authorize :read_package
@@ -21,9 +23,58 @@ module Types
description: 'Pipelines that built the package.',
deprecated: { reason: 'Due to scalability concerns, this field is going to be removed', milestone: '14.6' }
+ field :composer_config_repository_url, GraphQL::Types::String, null: true, description: 'Url of the Composer setup endpoint.'
+ field :composer_url, GraphQL::Types::String, null: true, description: 'Url of the Composer endpoint.'
+ field :conan_url, GraphQL::Types::String, null: true, description: 'Url of the Conan project endpoint.'
+ field :maven_url, GraphQL::Types::String, null: true, description: 'Url of the Maven project endpoint.'
+ field :npm_url, GraphQL::Types::String, null: true, description: 'Url of the NPM project endpoint.'
+ field :nuget_url, GraphQL::Types::String, null: true, description: 'Url of the Nuget project endpoint.'
+ field :pypi_setup_url, GraphQL::Types::String, null: true, description: 'Url of the PyPi project setup endpoint.'
+ field :pypi_url, GraphQL::Types::String, null: true, description: 'Url of the PyPi project endpoint.'
+
def versions
object.versions
end
+
+ def package_files
+ if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml)
+ object.installable_package_files
+ else
+ object.package_files
+ end
+ end
+
+ def composer_config_repository_url
+ composer_config_repository_name(object.project.group&.id)
+ end
+
+ def composer_url
+ composer_registry_url(object.project.group&.id)
+ end
+
+ def conan_url
+ package_registry_project_url(object.project.id, :conan)
+ end
+
+ def maven_url
+ package_registry_project_url(object.project.id, :maven)
+ end
+
+ def npm_url
+ package_registry_project_url(object.project.id, :npm)
+ end
+
+ def nuget_url
+ nuget_package_registry_url(object.project.id)
+ end
+
+ def pypi_setup_url
+ package_registry_project_url(object.project.id, :pypi)
+ end
+
+ def pypi_url
+ pypi_registry_url(object.project.id)
+ end
end
end
end
diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index 3d2ee47a499..f4067552f55 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -27,7 +27,6 @@ module Types
field :description, GraphQL::Types::String, null: true,
description: 'Short description of the project.'
- markdown_field :description_html, null: true
field :tag_list, GraphQL::Types::String, null: true,
deprecated: { reason: 'Use `topics`', milestone: '13.12' },
@@ -75,21 +74,6 @@ module Types
field :avatar_url, GraphQL::Types::String, null: true, calls_gitaly: true,
description: 'URL to avatar image file of the project.'
- {
- issues: "Issues are",
- merge_requests: "Merge Requests are",
- wiki: 'Wikis are',
- snippets: 'Snippets are',
- container_registry: 'Container Registry is'
- }.each do |feature, name_string|
- field "#{feature}_enabled", GraphQL::Types::Boolean, null: true,
- description: "Indicates if #{name_string} enabled for the current user"
-
- define_method "#{feature}_enabled" do
- object.feature_available?(feature, context[:current_user])
- end
- end
-
field :jobs_enabled, GraphQL::Types::Boolean, null: true,
description: 'Indicates if CI/CD pipeline jobs are enabled for the current user.'
@@ -391,6 +375,17 @@ module Types
null: true,
description: 'Template used to create squash commit message in merge requests.'
+ field :labels,
+ Types::LabelType.connection_type,
+ null: true,
+ description: 'Labels available on this project.',
+ resolver: Resolvers::LabelsResolver
+
+ 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
+
def label(title:)
BatchLoader::GraphQL.for(title).batch(key: project) do |titles, loader, args|
LabelsFinder
@@ -400,11 +395,22 @@ module Types
end
end
- field :labels,
- Types::LabelType.connection_type,
- null: true,
- description: 'Labels available on this project.',
- resolver: Resolvers::LabelsResolver
+ {
+ issues: "Issues are",
+ merge_requests: "Merge Requests are",
+ wiki: 'Wikis are',
+ snippets: 'Snippets are',
+ container_registry: 'Container Registry is'
+ }.each do |feature, name_string|
+ field "#{feature}_enabled", GraphQL::Types::Boolean, null: true,
+ description: "Indicates if #{name_string} enabled for the current user"
+
+ define_method "#{feature}_enabled" do
+ object.feature_available?(feature, context[:current_user])
+ end
+ end
+
+ markdown_field :description_html, null: true
def avatar_url
object.avatar_url(only_path: false)
diff --git a/app/graphql/types/projects/topic_type.rb b/app/graphql/types/projects/topic_type.rb
index 79ab69e794b..c579f2f2b9d 100644
--- a/app/graphql/types/projects/topic_type.rb
+++ b/app/graphql/types/projects/topic_type.rb
@@ -14,11 +14,12 @@ module Types
field :description, GraphQL::Types::String, null: true,
description: 'Description of the topic.'
- markdown_field :description_html, null: true
field :avatar_url, GraphQL::Types::String, null: true,
description: 'URL to avatar image file of the topic.'
+ markdown_field :description_html, null: true
+
def avatar_url
object.avatar_url(only_path: false)
end
diff --git a/app/graphql/types/release_type.rb b/app/graphql/types/release_type.rb
index fcc9ec49252..fbc3779ea9b 100644
--- a/app/graphql/types/release_type.rb
+++ b/app/graphql/types/release_type.rb
@@ -20,7 +20,6 @@ module Types
authorize: :download_code
field :description, GraphQL::Types::String, null: true,
description: 'Description (also known as "release notes") of the release.'
- markdown_field :description_html, null: true
field :name, GraphQL::Types::String, null: true,
description: 'Name of the release.'
field :created_at, Types::TimeType, null: true,
@@ -42,14 +41,16 @@ module Types
field :author, Types::UserType, null: true,
description: 'User that created the release.'
- def author
- Gitlab::Graphql::Loaders::BatchModelLoader.new(User, release.author_id).find
- end
-
field :commit, Types::CommitType, null: true,
complexity: 10, calls_gitaly: true,
description: 'Commit associated with the release.'
+ markdown_field :description_html, null: true
+
+ def author
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(User, release.author_id).find
+ end
+
def commit
return if release.sha.nil?
diff --git a/app/graphql/types/repository/blob_type.rb b/app/graphql/types/repository/blob_type.rb
index 3265c14bdca..28339093172 100644
--- a/app/graphql/types/repository/blob_type.rb
+++ b/app/graphql/types/repository/blob_type.rb
@@ -56,6 +56,9 @@ module Types
field :stored_externally, GraphQL::Types::Boolean, null: true, method: :stored_externally?,
description: "Whether the blob's content is stored externally (for instance, in LFS)."
+ field :external_storage, GraphQL::Types::String, null: true, method: :external_storage,
+ description: "External storage being used, if enabled (for instance, 'LFS')."
+
field :edit_blob_path, GraphQL::Types::String, null: true,
description: 'Web path to edit the blob in the old-style editor.'
@@ -71,6 +74,19 @@ module Types
field :pipeline_editor_path, GraphQL::Types::String, null: true,
description: 'Web path to edit .gitlab-ci.yml file.'
+ field :find_file_path, GraphQL::Types::String, null: true,
+ description: 'Web path to find file.'
+
+ field :blame_path, GraphQL::Types::String, null: true,
+ description: 'Web path to blob blame page.'
+
+ field :history_path, GraphQL::Types::String, null: true,
+ description: 'Web path to blob history page.'
+
+ field :permalink_path, GraphQL::Types::String, null: true,
+ description: 'Web path to blob permalink.',
+ calls_gitaly: true
+
field :code_owners, [Types::UserType], null: true,
description: 'List of code owners for the blob.',
calls_gitaly: true
@@ -98,6 +114,9 @@ module Types
field :can_current_user_push_to_branch, GraphQL::Types::Boolean, null: true, method: :can_current_user_push_to_branch?,
description: 'Whether the current user can push to the branch.'
+ field :archived, GraphQL::Types::Boolean, null: true, method: :archived?,
+ description: 'Whether the current project is archived.'
+
def raw_text_blob
object.data unless object.binary?
end
diff --git a/app/graphql/types/sha_format_enum.rb b/app/graphql/types/sha_format_enum.rb
new file mode 100644
index 00000000000..2e0e5bb85f3
--- /dev/null
+++ b/app/graphql/types/sha_format_enum.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Types
+ class ShaFormatEnum < BaseEnum
+ graphql_name 'ShaFormat'
+ description 'How to format SHA strings.'
+
+ FORMATS_DESCRIPTION = {
+ short: 'Abbreviated format. Short SHAs are typically eight characters long.',
+ long: 'Unabbreviated format.'
+ }.freeze
+
+ FORMATS_DESCRIPTION.each do |format, description|
+ value format.to_s.upcase,
+ description: description,
+ value: format.to_s
+ end
+ end
+end
diff --git a/app/graphql/types/user_interface.rb b/app/graphql/types/user_interface.rb
index 7cc201b6df4..6bb4cb29cdd 100644
--- a/app/graphql/types/user_interface.rb
+++ b/app/graphql/types/user_interface.rb
@@ -64,8 +64,7 @@ module Types
description: 'Group memberships of the user.'
field :groups,
resolver: Resolvers::Users::GroupsResolver,
- description: 'Groups where the user has access. Will always return `null` if ' \
- '`paginatable_namespace_drop_down_for_project_creation` feature flag is disabled.'
+ description: 'Groups where the user has access.'
field :group_count,
resolver: Resolvers::Users::GroupCountResolver,
description: 'Group count for the user.'
diff --git a/app/graphql/types/work_item_type.rb b/app/graphql/types/work_item_type.rb
new file mode 100644
index 00000000000..486c1e52987
--- /dev/null
+++ b/app/graphql/types/work_item_type.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Types
+ class WorkItemType < BaseObject
+ graphql_name 'WorkItem'
+
+ authorize :read_issue
+
+ field :description, GraphQL::Types::String, null: true,
+ description: 'Description of the work item.'
+ field :id, Types::GlobalIDType[::WorkItem], null: false,
+ description: 'Global ID of the work item.'
+ field :iid, GraphQL::Types::ID, null: false,
+ description: 'Internal ID of the work item.'
+ field :title, GraphQL::Types::String, null: false,
+ description: 'Title of the work item.'
+ field :work_item_type, Types::WorkItems::TypeType, null: false,
+ description: 'Type assigned to the work item.'
+
+ markdown_field :title_html, null: true
+ markdown_field :description_html, null: true
+ end
+end
diff --git a/app/graphql/types/work_items/type_type.rb b/app/graphql/types/work_items/type_type.rb
new file mode 100644
index 00000000000..f31bd7ee9ba
--- /dev/null
+++ b/app/graphql/types/work_items/type_type.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Types
+ module WorkItems
+ class TypeType < BaseObject
+ graphql_name 'WorkItemType'
+
+ authorize :read_work_item_type
+
+ field :icon_name, GraphQL::Types::String, null: true,
+ description: 'Icon name of the work item type.'
+ field :id, Types::GlobalIDType[::WorkItems::Type], null: false,
+ description: 'Global ID of the work item type.'
+ field :name, GraphQL::Types::String, null: false,
+ description: 'Name of the work item type.'
+ end
+ end
+end
diff --git a/app/helpers/admin/background_migrations_helper.rb b/app/helpers/admin/background_migrations_helper.rb
index 698d81cc8a2..6516ea27b2c 100644
--- a/app/helpers/admin/background_migrations_helper.rb
+++ b/app/helpers/admin/background_migrations_helper.rb
@@ -2,15 +2,15 @@
module Admin
module BackgroundMigrationsHelper
- def batched_migration_status_badge_class_name(migration)
- class_names = {
- 'active' => 'badge-info',
- 'paused' => 'badge-warning',
- 'failed' => 'badge-danger',
- 'finished' => 'badge-success'
+ def batched_migration_status_badge_variant(migration)
+ variants = {
+ 'active' => :info,
+ 'paused' => :warning,
+ 'failed' => :danger,
+ 'finished' => :success
}
- class_names[migration.status]
+ variants[migration.status]
end
# The extra logic here is needed because total_tuple_count is just
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 02a87979f40..e88d1832480 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -285,6 +285,7 @@ module ApplicationHelper
class_names << 'environment-logs-page' if current_controller?(:logs)
class_names << 'with-performance-bar' if performance_bar_enabled?
class_names << system_message_class
+ class_names << marketing_header_experiment_class
class_names
end
@@ -420,6 +421,18 @@ module ApplicationHelper
def appearance
::Appearance.current
end
+
+ def marketing_header_experiment_class
+ return if current_user
+
+ experiment(:logged_out_marketing_header, actor: nil) do |e|
+ html_class = 'logged-out-marketing-header-candidate'
+ e.candidate { html_class }
+ e.try(:trial_focused) { html_class }
+ e.control {}
+ e.run
+ end
+ end
end
ApplicationHelper.prepend_mod
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index b8ee71daeee..7541247b19f 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -144,36 +144,39 @@ module ApplicationSettingsHelper
end
def external_authorization_description
- _("If enabled, access to projects will be validated on an external service"\
+ s_("ExternalAuthorization|Access to projects is validated on an external service"\
" using their classification label.")
end
def external_authorization_timeout_help_text
- _("Time in seconds GitLab will wait for a response from the external "\
- "service. When the service does not respond in time, access will be "\
- "denied.")
+ s_("ExternalAuthorization|Period GitLab waits for a response from the external "\
+ "service. If there is no response, access is denied. Default: 0.5 seconds.")
end
def external_authorization_url_help_text
- _("When leaving the URL blank, classification labels can still be "\
- "specified without disabling cross project features or performing "\
- "external authorization checks.")
+ s_("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.")
end
def external_authorization_client_certificate_help_text
- _("The X509 Certificate to use when mutual TLS is required to communicate "\
- "with the external authorization service. If left blank, the server "\
- "certificate is still validated when accessing over HTTPS.")
+ s_("ExternalAuthorization|Certificate used to authenticate with the external authorization service. "\
+ "If blank, the server certificate is validated when accessing over HTTPS.")
end
def external_authorization_client_key_help_text
- _("The private key to use when a client certificate is provided. This value "\
- "is encrypted at rest.")
+ s_("ExternalAuthorization|Private key of client authentication certificate. "\
+ "Encrypted when stored.")
end
def external_authorization_client_pass_help_text
- _("The passphrase required to decrypt the private key. This is optional "\
- "and the value is encrypted at rest.")
+ s_("ExternalAuthorization|Passphrase required to decrypt the private key. "\
+ "Encrypted when stored.")
+ end
+
+ def external_authorization_client_url_help_text
+ s_("ExternalAuthorization|Classification label to use when requesting authorization if no specific "\
+ " label is defined on the project.")
end
def sidekiq_job_limiter_mode_help_text
@@ -401,6 +404,12 @@ module ApplicationSettingsHelper
:rate_limiting_response_text,
:container_registry_expiration_policies_worker_capacity,
:container_registry_cleanup_tags_service_max_list_size,
+ :container_registry_import_max_tags_count,
+ :container_registry_import_max_retries,
+ :container_registry_import_start_max_retries,
+ :container_registry_import_max_step_duration,
+ :container_registry_import_target_plan,
+ :container_registry_import_created_before,
:keep_latest_artifact,
:whats_new_variant,
:user_deactivation_emails_enabled,
@@ -411,7 +420,8 @@ module ApplicationSettingsHelper
:sidekiq_job_limiter_mode,
:sidekiq_job_limiter_compression_threshold_bytes,
:sidekiq_job_limiter_limit_bytes,
- :suggest_pipeline_enabled
+ :suggest_pipeline_enabled,
+ :user_email_lookup_limit
].tap do |settings|
settings << :deactivate_dormant_users unless Gitlab.com?
end
@@ -486,6 +496,10 @@ module ApplicationSettingsHelper
def pending_user_count
User.blocked_pending_approval.count
end
+
+ def registration_features_can_be_prompted?
+ !Gitlab::CurrentSettings.usage_ping_enabled?
+ end
end
ApplicationSettingsHelper.prepend_mod_with('ApplicationSettingsHelper')
diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb
index c1a74382d46..fb2fa547447 100644
--- a/app/helpers/auth_helper.rb
+++ b/app/helpers/auth_helper.rb
@@ -3,6 +3,7 @@
module AuthHelper
PROVIDERS_WITH_ICONS = %w(
atlassian_oauth2
+ auth0
authentiq
azure_activedirectory_v2
azure_oauth2
@@ -12,8 +13,10 @@ module AuthHelper
github
gitlab
google_oauth2
+ jwt
openid_connect
salesforce
+ shibboleth
twitter
).freeze
LDAP_PROVIDER = /\Aldap/.freeze
@@ -177,15 +180,13 @@ module AuthHelper
def google_tag_manager_enabled?
return false unless Gitlab.dev_env_or_com?
- has_config_key = if Feature.enabled?(:gtm_nonce, type: :ops)
- extra_config.has_key?('google_tag_manager_nonce_id') &&
- extra_config.google_tag_manager_nonce_id.present?
- else
- extra_config.has_key?('google_tag_manager_id') &&
- extra_config.google_tag_manager_id.present?
- end
-
- has_config_key && !current_user
+ if Feature.enabled?(:gtm_nonce, type: :ops)
+ extra_config.has_key?('google_tag_manager_nonce_id') &&
+ extra_config.google_tag_manager_nonce_id.present?
+ else
+ extra_config.has_key?('google_tag_manager_id') &&
+ extra_config.google_tag_manager_id.present?
+ end
end
def google_tag_manager_id
diff --git a/app/helpers/button_helper.rb b/app/helpers/button_helper.rb
index eb30ffc0093..4ec95dc8bd7 100644
--- a/app/helpers/button_helper.rb
+++ b/app/helpers/button_helper.rb
@@ -50,7 +50,7 @@ module ButtonHelper
data: data,
type: :button,
title: title,
- aria: { label: title },
+ aria: { label: title, live: 'polite' },
itemprop: item_prop
}
diff --git a/app/helpers/ci/jobs_helper.rb b/app/helpers/ci/jobs_helper.rb
index c7f40decae8..c0dca66bac8 100644
--- a/app/helpers/ci/jobs_helper.rb
+++ b/app/helpers/ci/jobs_helper.rb
@@ -19,10 +19,12 @@ module Ci
}
end
- def bridge_data(build)
+ def bridge_data(build, project)
{
- "build_name" => build.name,
- "empty-state-illustration-path" => image_path('illustrations/job-trigger-md.svg')
+ "build_id" => build.id,
+ "empty-state-illustration-path" => image_path('illustrations/job-trigger-md.svg'),
+ "pipeline_iid" => build.pipeline.iid,
+ "project_full_path" => project.full_path
}
end
diff --git a/app/helpers/ci/pipeline_editor_helper.rb b/app/helpers/ci/pipeline_editor_helper.rb
index 9bbc326a750..bb7226da74e 100644
--- a/app/helpers/ci/pipeline_editor_helper.rb
+++ b/app/helpers/ci/pipeline_editor_helper.rb
@@ -20,6 +20,7 @@ module Ci
"empty-state-illustration-path" => image_path('illustrations/empty-state/empty-dag-md.svg'),
"initial-branch-name" => initial_branch,
"lint-help-page-path" => help_page_path('ci/lint', anchor: 'validate-basic-logic-and-syntax'),
+ "lint-unavailable-help-page-path" => help_page_path('ci/pipeline_editor/index', anchor: 'configuration-validation-currently-not-available'),
"needs-help-page-path" => help_page_path('ci/yaml/index', anchor: 'needs'),
"new-merge-request-path" => namespace_project_new_merge_request_path,
"pipeline_etag" => latest_commit ? graphql_etag_pipeline_sha_path(commit_sha) : '',
diff --git a/app/helpers/ci/runners_helper.rb b/app/helpers/ci/runners_helper.rb
index 8f219656b71..f84b42209da 100644
--- a/app/helpers/ci/runners_helper.rb
+++ b/app/helpers/ci/runners_helper.rb
@@ -24,7 +24,7 @@ module Ci
span_class = 'gl-text-gray-600'
end
when :not_connected, :never_contacted
- title = s_("Runners|New runner, has not connected yet")
+ title = s_("Runners|New runner, has not contacted yet")
icon = 'warning-solid'
when :offline
title = s_("Runners|Runner is offline, last contact was %{runner_contact} ago") % { runner_contact: time_ago_in_words(runner.contacted_at) }
@@ -65,14 +65,7 @@ module Ci
# Runner install help page is external, located at
# https://gitlab.com/gitlab-org/gitlab-runner
runner_install_help_page: 'https://docs.gitlab.com/runner/install/',
- registration_token: Gitlab::CurrentSettings.runners_registration_token,
-
- # All runner counts are returned as formatted strings
- active_runners_count: Ci::Runner.online.count.to_s,
- all_runners_count: limited_counter_with_delimiter(Ci::Runner),
- instance_runners_count: limited_counter_with_delimiter(Ci::Runner.instance_type),
- group_runners_count: limited_counter_with_delimiter(Ci::Runner.group_type),
- project_runners_count: limited_counter_with_delimiter(Ci::Runner.project_type)
+ registration_token: Gitlab::CurrentSettings.runners_registration_token
}
end
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index ee5f4bb364a..43e727ac483 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -27,10 +27,12 @@ module CommitsHelper
end
def commit_to_html(commit, ref, project)
- render 'projects/commits/commit.html',
- commit: commit,
- ref: ref,
- project: project
+ render partial: 'projects/commits/commit', formats: :html,
+ locals: {
+ commit: commit,
+ ref: ref,
+ project: project
+ }
end
# Breadcrumb links for a Project and, if applicable, a tree path
@@ -73,9 +75,7 @@ module CommitsHelper
# Returns a link formatted as a commit branch link
def commit_branch_link(url, text)
- link_to(url, class: 'badge badge-gray ref-name branch-link') do
- sprite_icon('branch', size: 12, css_class: 'fork-svg') + "#{text}"
- end
+ gl_badge_tag(text, { variant: :info, icon: 'branch' }, { href: url, class: 'gl-font-monospace gl-mb-1' })
end
# Returns the sorted alphabetically links to branches, separated by a comma
@@ -87,9 +87,7 @@ module CommitsHelper
# Returns a link formatted as a commit tag link
def commit_tag_link(url, text)
- link_to(url, class: 'badge badge-gray ref-name') do
- sprite_icon('tag', size: 12, css_class: 'gl-mr-2 vertical-align-middle') + "#{text}"
- end
+ gl_badge_tag(text, { variant: :info, icon: 'tag' }, { href: url, class: 'gl-font-monospace' })
end
# Returns the sorted links to tags, separated by a comma
diff --git a/app/helpers/custom_metrics_helper.rb b/app/helpers/custom_metrics_helper.rb
index 9fbfe377c61..5442120008a 100644
--- a/app/helpers/custom_metrics_helper.rb
+++ b/app/helpers/custom_metrics_helper.rb
@@ -5,7 +5,7 @@ module CustomMetricsHelper
{
'custom-metrics-path' => url_for([project, metric]),
'metric-persisted' => metric.persisted?.to_s,
- 'edit-project-service-path' => edit_project_service_path(project, ::Integrations::Prometheus),
+ 'edit-project-service-path' => edit_project_integration_path(project, ::Integrations::Prometheus),
'validate-query-path' => validate_query_project_prometheus_metrics_path(project),
'title' => metric.title.to_s,
'query' => metric.query.to_s,
diff --git a/app/helpers/environment_helper.rb b/app/helpers/environment_helper.rb
index f57bb600527..1f0bf46097d 100644
--- a/app/helpers/environment_helper.rb
+++ b/app/helpers/environment_helper.rb
@@ -54,6 +54,8 @@ module EnvironmentHelper
s_('Deployment|canceled')
when 'skipped'
s_('Deployment|skipped')
+ when 'blocked'
+ s_('Deployment|blocked')
end
klass = "ci-status ci-#{status.dasherize}"
diff --git a/app/helpers/environments_helper.rb b/app/helpers/environments_helper.rb
index cde45e7bc0f..1894aba7dc0 100644
--- a/app/helpers/environments_helper.rb
+++ b/app/helpers/environments_helper.rb
@@ -59,7 +59,7 @@ module EnvironmentsHelper
return {} unless project
{
- 'settings_path' => edit_project_service_path(project, 'prometheus'),
+ 'settings_path' => edit_project_integration_path(project, 'prometheus'),
'clusters_path' => project_clusters_path(project),
'dashboards_endpoint' => project_performance_monitoring_dashboards_path(project, format: :json),
'default_branch' => project.default_branch,
diff --git a/app/helpers/groups/crm_settings_helper.rb b/app/helpers/groups/crm_settings_helper.rb
new file mode 100644
index 00000000000..ab47ec40b13
--- /dev/null
+++ b/app/helpers/groups/crm_settings_helper.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module Groups
+ module CrmSettingsHelper
+ def crm_feature_flag_enabled?(group)
+ Feature.enabled?(:customer_relations, group)
+ end
+ end
+end
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index 9ba7d004d6c..7296560a450 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -134,6 +134,16 @@ module GroupsHelper
@group_projects_sort || @sort || params[:sort] || sort_value_recently_created
end
+ def verification_for_group_creation_data
+ # overridden in EE
+ {}
+ end
+
+ def require_verification_for_group_creation_enabled?
+ # overridden in EE
+ false
+ end
+
private
def group_title_link(group, hidable: false, show_avatar: false, for_dropdown: false)
diff --git a/app/helpers/hooks_helper.rb b/app/helpers/hooks_helper.rb
index c1dfd2b2cda..1e50033e0e0 100644
--- a/app/helpers/hooks_helper.rb
+++ b/app/helpers/hooks_helper.rb
@@ -39,7 +39,7 @@ module HooksHelper
def hook_log_path(hook, hook_log)
case hook
- when ProjectHook
+ when ProjectHook, ServiceHook
hook_log.present.details_path
when SystemHook
admin_hook_hook_log_path(hook, hook_log)
diff --git a/app/helpers/integrations_helper.rb b/app/helpers/integrations_helper.rb
index c5e767c6f64..230f80e20a5 100644
--- a/app/helpers/integrations_helper.rb
+++ b/app/helpers/integrations_helper.rb
@@ -29,7 +29,7 @@ module IntegrationsHelper
def scoped_integration_path(integration, project: nil, group: nil)
if project.present?
- project_service_path(project, integration)
+ project_integration_path(project, integration)
elsif group.present?
group_settings_integration_path(group, integration)
else
@@ -39,7 +39,7 @@ module IntegrationsHelper
def scoped_edit_integration_path(integration, project: nil, group: nil)
if project.present?
- edit_project_service_path(project, integration)
+ edit_project_integration_path(project, integration)
elsif group.present?
edit_group_settings_integration_path(group, integration)
else
@@ -53,7 +53,7 @@ module IntegrationsHelper
def scoped_test_integration_path(integration, project: nil, group: nil)
if project.present?
- test_project_service_path(project, integration)
+ test_project_integration_path(project, integration)
elsif group.present?
test_group_settings_integration_path(group, integration)
else
@@ -90,7 +90,9 @@ module IntegrationsHelper
cancel_path: scoped_integrations_path(project: project, group: group),
can_test: integration.testable?.to_s,
test_path: scoped_test_integration_path(integration, project: project, group: group),
- reset_path: scoped_reset_integration_path(integration, group: group)
+ reset_path: scoped_reset_integration_path(integration, group: group),
+ form_path: scoped_integration_path(integration, project: project, group: group),
+ redirect_to: request.referer
}
if integration.is_a?(Integrations::Jira)
@@ -101,8 +103,9 @@ module IntegrationsHelper
form_data
end
- def integration_overrides_data(integration)
+ def integration_overrides_data(integration, project: nil, group: nil)
{
+ edit_path: scoped_edit_integration_path(integration, project: project, group: group),
overrides_path: scoped_overrides_integration_path(integration, format: :json)
}
end
@@ -225,6 +228,10 @@ module IntegrationsHelper
name: integration.to_param
}
end
+
+ def vue_integration_form_enabled?
+ Feature.enabled?(:vue_integration_form, current_user, default_enabled: :yaml)
+ end
end
IntegrationsHelper.prepend_mod_with('IntegrationsHelper')
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index cddf740a0e6..5aa2aca37f3 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -7,7 +7,7 @@ module IssuesHelper
classes = ["issue"]
classes << "closed" if issue.closed?
classes << "today" if issue.new?
- classes << "user-can-drag" if @sort == 'relative_position'
+ classes << "gl-cursor-grab" if @sort == 'relative_position'
classes.join(' ')
end
@@ -51,7 +51,7 @@ module IssuesHelper
end
def work_item_type_icon(issue_type)
- if WorkItem::Type.base_types.include?(issue_type)
+ if WorkItems::Type.base_types.include?(issue_type)
"issue-type-#{issue_type.to_s.dasherize}"
else
'issue-type-issue'
@@ -168,21 +168,6 @@ module IssuesHelper
issue.moved_from.project.service_desk_enabled? && !issue.project.service_desk_enabled?
end
- def use_startup_call?
- request.query_parameters.empty? && @sort == 'created_date'
- end
-
- def startup_call_params
- {
- state: 'opened',
- with_labels_details: 'true',
- page: 1,
- per_page: 20,
- order_by: 'created_at',
- sort: 'desc'
- }
- 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" } }
if issuable.incident?
diff --git a/app/helpers/learn_gitlab_helper.rb b/app/helpers/learn_gitlab_helper.rb
index 7f8f6d77ff4..6330b8fc829 100644
--- a/app/helpers/learn_gitlab_helper.rb
+++ b/app/helpers/learn_gitlab_helper.rb
@@ -27,8 +27,12 @@ module LearnGitlabHelper
urls_to_use = nil
- experiment(:change_continuous_onboarding_link_urls) do |e|
- e.namespace = project.namespace
+ experiment(
+ :change_continuous_onboarding_link_urls,
+ namespace: project.namespace,
+ actor: current_user,
+ sticky_to: project.namespace
+ ) do |e|
e.use { urls_to_use = action_urls }
e.try { urls_to_use = new_action_urls(project) }
end
diff --git a/app/helpers/namespaces_helper.rb b/app/helpers/namespaces_helper.rb
index 6acec417a75..64b58d28fc9 100644
--- a/app/helpers/namespaces_helper.rb
+++ b/app/helpers/namespaces_helper.rb
@@ -49,13 +49,6 @@ module NamespacesHelper
end
end
- def namespaces_options_with_developer_maintainer_access(options = {})
- selected = options.delete(:selected) || :current_user
- options[:groups] = current_user.manageable_groups_with_routes(include_groups_with_developer_maintainer_access: true)
-
- namespaces_options(selected, **options)
- end
-
def cascading_namespace_settings_popover_data(attribute, group, settings_path_helper)
locked_by_ancestor = group.namespace_settings.public_send("#{attribute}_locked_by_ancestor?") # rubocop:disable GitlabSecurity/PublicSend
diff --git a/app/helpers/nav/top_nav_helper.rb b/app/helpers/nav/top_nav_helper.rb
index ecef2d38e54..24102a90a3b 100644
--- a/app/helpers/nav/top_nav_helper.rb
+++ b/app/helpers/nav/top_nav_helper.rb
@@ -123,7 +123,7 @@ module Nav
if dashboard_nav_link?(:milestones)
builder.add_primary_menu_item_with_shortcut(
id: 'milestones',
- title: 'Milestones',
+ title: _('Milestones'),
href: dashboard_milestones_path,
active: active_nav_link?(controller: 'dashboard/milestones'),
icon: 'clock',
@@ -144,7 +144,7 @@ module Nav
if dashboard_nav_link?(:activity)
builder.add_primary_menu_item_with_shortcut(
id: 'activity',
- title: 'Activity',
+ title: _('Activity'),
href: activity_dashboard_path,
active: active_nav_link?(path: 'dashboard#activity'),
icon: 'history',
@@ -189,15 +189,6 @@ module Nav
end
end
# rubocop: enable Cop/UserAdmin
-
- if Gitlab::Sherlock.enabled?
- builder.add_secondary_menu_item(
- id: 'sherlock',
- title: _('Sherlock Transactions'),
- icon: 'admin',
- href: sherlock_transactions_path
- )
- end
end
def projects_menu_item_attrs
@@ -212,7 +203,7 @@ module Nav
def groups_menu_item_attrs
{
id: 'groups',
- title: 'Groups',
+ title: _('Groups'),
icon: 'group',
shortcut_class: 'dashboard-shortcuts-groups'
}
diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb
index 9a6630ec3cb..1c4d294baa7 100644
--- a/app/helpers/nav_helper.rb
+++ b/app/helpers/nav_helper.rb
@@ -46,10 +46,6 @@ module NavHelper
class_names
end
- def has_extra_nav_icons?
- Gitlab::Sherlock.enabled? || current_user.admin?
- end
-
def page_has_markdown?
current_path?('merge_requests#show') ||
current_path?('projects/merge_requests/conflicts#show') ||
diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb
index 2dadaa0be0a..1afdb7a0ab9 100644
--- a/app/helpers/notes_helper.rb
+++ b/app/helpers/notes_helper.rb
@@ -48,7 +48,7 @@ module NotesHelper
data[:note_type] = LegacyDiffNote.name
else
data[:note_type] = DiffNote.name
- data[:position] = position.to_json
+ data[:position] = Gitlab::Json.dump(position)
end
data
diff --git a/app/helpers/packages_helper.rb b/app/helpers/packages_helper.rb
index 66f80e7eeb8..402a363349f 100644
--- a/app/helpers/packages_helper.rb
+++ b/app/helpers/packages_helper.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
module PackagesHelper
+ include ::API::Helpers::RelatedResourcesHelpers
+
def package_sort_path(options = {})
"#{request.path}?#{options.to_param}"
end
@@ -53,30 +55,4 @@ module PackagesHelper
project.container_expiration_policy.nil? &&
project.container_repositories.exists?
end
-
- def package_details_data(project, package)
- {
- package_id: package.id,
- can_delete: can?(current_user, :destroy_package, project).to_s,
- svg_path: image_path('illustrations/no-packages.svg'),
- npm_path: package_registry_instance_url(:npm),
- npm_project_path: package_registry_project_url(project.id, :npm),
- npm_help_path: help_page_path('user/packages/npm_registry/index'),
- maven_path: package_registry_project_url(project.id, :maven),
- maven_help_path: help_page_path('user/packages/maven_repository/index'),
- conan_path: package_registry_project_url(project.id, :conan),
- conan_help_path: help_page_path('user/packages/conan_repository/index'),
- nuget_path: nuget_package_registry_url(project.id),
- nuget_help_path: help_page_path('user/packages/nuget_repository/index'),
- pypi_path: pypi_registry_url(project.id),
- pypi_setup_path: package_registry_project_url(project.id, :pypi),
- pypi_help_path: help_page_path('user/packages/pypi_repository/index'),
- composer_path: composer_registry_url(project&.group&.id),
- composer_help_path: help_page_path('user/packages/composer_repository/index'),
- project_name: project.name,
- project_list_url: project_packages_path(project),
- group_list_url: project.group ? group_packages_path(project.group) : '',
- composer_config_repository_name: composer_config_repository_name(project.group&.id)
- }
- end
end
diff --git a/app/helpers/page_layout_helper.rb b/app/helpers/page_layout_helper.rb
index 2729951d685..fb74a52fcda 100644
--- a/app/helpers/page_layout_helper.rb
+++ b/app/helpers/page_layout_helper.rb
@@ -125,7 +125,7 @@ module PageLayoutHelper
end
def fluid_layout
- current_user && current_user.layout == "fluid"
+ @force_fluid_layout == true || (current_user && current_user.layout == "fluid")
end
def blank_container(enabled = false)
diff --git a/app/helpers/preferences_helper.rb b/app/helpers/preferences_helper.rb
index 76f2ee0981b..17450e5b26b 100644
--- a/app/helpers/preferences_helper.rb
+++ b/app/helpers/preferences_helper.rb
@@ -4,8 +4,8 @@
module PreferencesHelper
def layout_choices
[
- ['Fixed', :fixed],
- ['Fluid', :fluid]
+ [s_('Layout|Fixed'), :fixed],
+ [s_('Layout|Fluid'), :fluid]
]
end
@@ -40,9 +40,9 @@ module PreferencesHelper
def project_view_choices
[
- ['Files and Readme (default)', :files],
- ['Activity', :activity],
- ['Readme', :readme]
+ [s_('ProjectView|Files and Readme (default)'), :files],
+ [s_('ProjectView|Activity'), :activity],
+ [s_('ProjectView|Readme'), :readme]
]
end
diff --git a/app/helpers/projects/cluster_agents_helper.rb b/app/helpers/projects/cluster_agents_helper.rb
index aeeab250c7a..e3027759d65 100644
--- a/app/helpers/projects/cluster_agents_helper.rb
+++ b/app/helpers/projects/cluster_agents_helper.rb
@@ -3,9 +3,10 @@
module Projects::ClusterAgentsHelper
def js_cluster_agent_details_data(agent_name, project)
{
+ activity_empty_state_image: image_path('illustrations/empty-state/empty-state-agents.svg'),
agent_name: agent_name,
- project_path: project.full_path,
- activity_empty_state_image: image_path('illustrations/empty-state/empty-state-agents.svg')
+ empty_state_svg_path: image_path('illustrations/operations-dashboard_empty.svg'),
+ project_path: project.full_path
}
end
end
diff --git a/app/helpers/projects/issues/service_desk_helper.rb b/app/helpers/projects/issues/service_desk_helper.rb
deleted file mode 100644
index 0f87e5ed837..00000000000
--- a/app/helpers/projects/issues/service_desk_helper.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# frozen_string_literal: true
-
-module Projects::Issues::ServiceDeskHelper
- def service_desk_meta(project)
- empty_state_meta = {
- is_service_desk_supported: Gitlab::ServiceDesk.supported?,
- is_service_desk_enabled: project.service_desk_enabled?,
- can_edit_project_settings: can?(current_user, :admin_project, project)
- }
-
- if Gitlab::ServiceDesk.supported?
- empty_state_meta.merge(supported_meta(project))
- else
- empty_state_meta.merge(unsupported_meta(project))
- end
- end
-
- private
-
- def supported_meta(project)
- {
- service_desk_address: project.service_desk_address,
- service_desk_help_page: help_page_path('user/project/service_desk'),
- edit_project_page: edit_project_path(project),
- svg_path: image_path('illustrations/service_desk_empty.svg')
- }
- end
-
- def unsupported_meta(project)
- {
- incoming_email_help_page: help_page_path('administration/incoming_email', anchor: 'set-it-up'),
- svg_path: image_path('illustrations/service-desk-setup.svg')
- }
- end
-end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 827d2cb7164..084c962d34c 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -660,6 +660,31 @@ module ProjectsHelper
project.unlink_forks_upon_visibility_decrease_enabled? && project.visibility_level > Gitlab::VisibilityLevel::PRIVATE && project.forks_count > 0
end
+ def confirm_reduce_visibility_message(project)
+ strong_start = "<strong>".html_safe
+ strong_end = "</strong>".html_safe
+ message = _("You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}.")
+
+ if project.group
+ message = _("You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end} in %{strong_start}%{group_name}%{strong_end}.")
+ end
+
+ html_escape(message) % { strong_start: strong_start, strong_end: strong_end, project_name: project.name, group_name: project.group ? project.group.name : nil }
+ end
+
+ def visibility_confirm_modal_data(project, target_form_id = nil)
+ {
+ target_form_id: target_form_id,
+ button_testid: 'reduce-project-visibility-button',
+ confirm_button_text: _('Reduce project visibility'),
+ confirm_danger_message: confirm_reduce_visibility_message(project),
+ phrase: project.full_path,
+ additional_information: _('Note: current forks will keep their visibility level.'),
+ html_confirmation_message: true.to_s,
+ show_visibility_confirm_modal: show_visibility_confirm_modal?(project).to_s
+ }
+ end
+
def build_project_breadcrumb_link(project)
project_name = simple_sanitize(project.name)
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index aedb7df9e4f..6efede8d565 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -141,7 +141,7 @@ module SearchHelper
}
},
{
- title: _('Last updated'),
+ title: _('Updated date'),
sortable: true,
sortParam: {
asc: 'updated_asc',
@@ -336,7 +336,7 @@ module SearchHelper
link_to search_path(search_params) do
concat label
concat ' '
- concat content_tag(:span, count, class: ['badge badge-pill gl-badge badge-muted sm', badge_class], data: badge_data)
+ concat gl_badge_tag(count, { size: :sm }, { class: badge_class, data: badge_data })
end
end
end
diff --git a/app/helpers/snippets_helper.rb b/app/helpers/snippets_helper.rb
index e9ef9146529..ca90d1e13c1 100644
--- a/app/helpers/snippets_helper.rb
+++ b/app/helpers/snippets_helper.rb
@@ -26,11 +26,8 @@ module SnippetsHelper
return unless attrs = snippet_badge_attributes(snippet)
icon_name, text = attrs
- tag.span(class: %w[badge badge-gray]) do
- concat(sprite_icon(icon_name, size: 14, css_class: 'gl-vertical-align-middle'))
- concat(' ')
- concat(text)
- end
+
+ gl_badge_tag(text, icon: icon_name)
end
def snippet_badge_attributes(snippet)
diff --git a/app/helpers/sorting_titles_values_helper.rb b/app/helpers/sorting_titles_values_helper.rb
index 75ba6e8a153..4dfa7689110 100644
--- a/app/helpers/sorting_titles_values_helper.rb
+++ b/app/helpers/sorting_titles_values_helper.rb
@@ -59,7 +59,7 @@ module SortingTitlesValuesHelper
end
def sort_title_latest_activity
- s_('SortOptions|Last updated')
+ _('Updated date')
end
def sort_title_milestone
@@ -127,7 +127,7 @@ module SortingTitlesValuesHelper
end
def sort_title_recently_updated
- s_('SortOptions|Last updated')
+ _('Updated date')
end
def sort_title_start_date_later
diff --git a/app/helpers/ssh_keys_helper.rb b/app/helpers/ssh_keys_helper.rb
index f5a9bea482b..17a9fd6146d 100644
--- a/app/helpers/ssh_keys_helper.rb
+++ b/app/helpers/ssh_keys_helper.rb
@@ -18,4 +18,14 @@ module SshKeysHelper
container: 'body'
}
end
+
+ def ssh_key_allowed_algorithms
+ allowed_algorithms = Gitlab::CurrentSettings.allowed_key_types.flat_map do |ssh_key_type_name|
+ Gitlab::SSHPublicKey.supported_algorithms_for_name(ssh_key_type_name)
+ end
+
+ quoted_allowed_algorithms = allowed_algorithms.map { |name| "'#{name}'" }
+
+ Gitlab::Utils.to_exclusive_sentence(quoted_allowed_algorithms)
+ end
end
diff --git a/app/helpers/tracking_helper.rb b/app/helpers/tracking_helper.rb
index 3f53bd535b2..1beb88548c5 100644
--- a/app/helpers/tracking_helper.rb
+++ b/app/helpers/tracking_helper.rb
@@ -13,6 +13,10 @@ module TrackingHelper
}
end
+ def tracking_attrs_data(label, action, property)
+ tracking_attrs(label, action, property).fetch(:data, {})
+ end
+
private
def tracking_enabled?
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index d089b540282..4437f309a9c 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -191,7 +191,10 @@ module TreeHelper
web_ide_url: web_ide_url,
edit_url: edit_url(options),
- gitpod_url: gitpod_url
+
+ gitpod_url: gitpod_url,
+ user_preferences_gitpod_path: profile_preferences_path(anchor: 'user_gitpod_enabled'),
+ user_profile_enable_gitpod_path: profile_path(user: { gitpod_enabled: true })
}
end
diff --git a/app/helpers/version_check_helper.rb b/app/helpers/version_check_helper.rb
index 7875b9e4a28..48548ae9e6a 100644
--- a/app/helpers/version_check_helper.rb
+++ b/app/helpers/version_check_helper.rb
@@ -1,12 +1,11 @@
# frozen_string_literal: true
module VersionCheckHelper
- def version_status_badge
- return unless Rails.env.production?
- return unless Gitlab::CurrentSettings.version_check_enabled
- return if User.single_user&.requires_usage_stats_consent?
+ def show_version_check?
+ return false unless Gitlab::CurrentSettings.version_check_enabled
+ return false if User.single_user&.requires_usage_stats_consent?
- image_tag VersionCheck.image_url, class: 'js-version-status-badge'
+ current_user&.can_read_all_resources?
end
def link_to_version
diff --git a/app/helpers/webpack_helper.rb b/app/helpers/webpack_helper.rb
index 0d27e07f172..64900714327 100644
--- a/app/helpers/webpack_helper.rb
+++ b/app/helpers/webpack_helper.rb
@@ -25,6 +25,10 @@ module WebpackHelper
else
preload_link_tag(path, options)
end
+ rescue Gitlab::Webpack::Manifest::AssetMissingError
+ # In development/test, incremental compilation may be enabled, meaning not
+ # all chunks may be available/split out
+ raise unless Gitlab.dev_or_test_env?
end
def webpack_controller_bundle_tags
diff --git a/app/mailers/previews/notify_preview.rb b/app/mailers/previews/notify_preview.rb
index 13b24e099c9..8e30eeee73f 100644
--- a/app/mailers/previews/notify_preview.rb
+++ b/app/mailers/previews/notify_preview.rb
@@ -246,7 +246,7 @@ class NotifyPreview < ActionMailer::Preview
def cleanup
email = nil
- ActiveRecord::Base.transaction do # rubocop: disable Database/MultipleDatabases
+ ApplicationRecord.transaction do
email = yield
raise ActiveRecord::Rollback
end
diff --git a/app/models/active_session.rb b/app/models/active_session.rb
index 0094d98fb73..9f634e70ff4 100644
--- a/app/models/active_session.rb
+++ b/app/models/active_session.rb
@@ -21,7 +21,6 @@
#
class ActiveSession
include ActiveModel::Model
- include ::Gitlab::Redis::SessionsStoreHelper
SESSION_BATCH_SIZE = 200
ALLOWED_NUMBER_OF_ACTIVE_SESSIONS = 100
@@ -66,7 +65,7 @@ class ActiveSession
end
def self.set(user, request)
- redis_store_class.with do |redis|
+ Gitlab::Redis::Sessions.with do |redis|
session_private_id = request.session.id.private_id
client = DeviceDetector.new(request.user_agent)
timestamp = Time.current
@@ -107,7 +106,7 @@ class ActiveSession
end
def self.list(user)
- redis_store_class.with do |redis|
+ Gitlab::Redis::Sessions.with do |redis|
cleaned_up_lookup_entries(redis, user).map do |raw_session|
load_raw_session(raw_session)
end
@@ -115,7 +114,7 @@ class ActiveSession
end
def self.cleanup(user)
- redis_store_class.with do |redis|
+ Gitlab::Redis::Sessions.with do |redis|
clean_up_old_sessions(redis, user)
cleaned_up_lookup_entries(redis, user)
end
@@ -138,7 +137,7 @@ class ActiveSession
def self.destroy_session(user, session_id)
return unless session_id
- redis_store_class.with do |redis|
+ Gitlab::Redis::Sessions.with do |redis|
destroy_sessions(redis, user, [session_id].compact)
end
end
@@ -147,7 +146,7 @@ class ActiveSession
sessions = not_impersonated(user)
sessions.reject! { |session| session.current?(current_rack_session) } if current_rack_session
- redis_store_class.with do |redis|
+ Gitlab::Redis::Sessions.with do |redis|
session_ids = sessions.flat_map(&:ids)
destroy_sessions(redis, user, session_ids) if session_ids.any?
end
@@ -182,7 +181,7 @@ class ActiveSession
#
# Returns an array of strings
def self.session_ids_for_user(user_id)
- redis_store_class.with do |redis|
+ Gitlab::Redis::Sessions.with do |redis|
redis.smembers(lookup_key_name(user_id))
end
end
@@ -195,7 +194,7 @@ class ActiveSession
def self.sessions_from_ids(session_ids)
return [] if session_ids.empty?
- redis_store_class.with do |redis|
+ Gitlab::Redis::Sessions.with do |redis|
session_keys = rack_session_keys(session_ids)
session_keys.each_slice(SESSION_BATCH_SIZE).flat_map do |session_keys_batch|
diff --git a/app/models/alert_management/alert.rb b/app/models/alert_management/alert.rb
index f40d0cd2fa4..a53fa39c58f 100644
--- a/app/models/alert_management/alert.rb
+++ b/app/models/alert_management/alert.rb
@@ -78,7 +78,6 @@ module AlertManagement
scope :for_environment, -> (environment) { where(environment: environment) }
scope :for_assignee_username, -> (assignee_username) { joins(:assignees).merge(User.by_username(assignee_username)) }
scope :search, -> (query) { fuzzy_search(query, [:title, :description, :monitoring_tool, :service]) }
- scope :open, -> { with_status(open_statuses) }
scope :not_resolved, -> { without_status(:resolved) }
scope :with_prometheus_alert, -> { includes(:prometheus_alert) }
scope :with_threat_monitoring_alerts, -> { where(domain: :threat_monitoring ) }
@@ -143,18 +142,6 @@ module AlertManagement
reference.to_i > 0 && reference.to_i <= Gitlab::Database::MAX_INT_VALUE
end
- def self.open_statuses
- [:triggered, :acknowledged]
- end
-
- def self.open_status?(status)
- open_statuses.include?(status)
- end
-
- def open?
- self.class.open_status?(status_name)
- end
-
def prometheus?
monitoring_tool == Gitlab::AlertManagement::Payload::MONITORING_TOOLS[:prometheus]
end
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index 65472615f42..b69c0199c70 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -9,6 +9,7 @@ class ApplicationSetting < ApplicationRecord
include Sanitizable
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'
INSTANCE_REVIEW_MIN_USERS = 50
GRAFANA_URL_ERROR_MESSAGE = 'Please check your Grafana URL setting in ' \
@@ -21,7 +22,7 @@ class ApplicationSetting < ApplicationRecord
add_authentication_token_field :runners_registration_token, encrypted: -> { Feature.enabled?(:application_settings_tokens_optional_encryption) ? :optional : :required }
add_authentication_token_field :health_check_access_token
- add_authentication_token_field :static_objects_external_storage_auth_token, encrypted: :optional
+ add_authentication_token_field :static_objects_external_storage_auth_token, encrypted: :required
belongs_to :self_monitoring_project, class_name: "Project", foreign_key: 'instance_administration_project_id'
belongs_to :push_rule
@@ -77,6 +78,10 @@ class ApplicationSetting < ApplicationRecord
chronic_duration_attr_writer :archive_builds_in_human_readable, :archive_builds_in_seconds
+ chronic_duration_attr :runner_token_expiration_interval_human_readable, :runner_token_expiration_interval
+ chronic_duration_attr :group_runner_token_expiration_interval_human_readable, :group_runner_token_expiration_interval
+ chronic_duration_attr :project_runner_token_expiration_interval_human_readable, :project_runner_token_expiration_interval
+
validates :grafana_url,
system_hook_url: {
blocked_message: "is blocked: %{exception_message}. " + GRAFANA_URL_ERROR_MESSAGE
@@ -352,18 +357,28 @@ class ApplicationSetting < ApplicationRecord
validates :hashed_storage_enabled, inclusion: { in: [true], message: _("Hashed storage can't be disabled anymore for new projects") }
validates :container_registry_delete_tags_service_timeout,
+ :container_registry_cleanup_tags_service_max_list_size,
+ :container_registry_expiration_policies_worker_capacity,
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
- validates :container_registry_cleanup_tags_service_max_list_size,
+ validates :container_registry_import_max_tags_count,
+ :container_registry_import_max_retries,
+ :container_registry_import_start_max_retries,
+ :container_registry_import_max_step_duration,
+ allow_nil: false,
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
- validates :container_registry_expiration_policies_worker_capacity,
- numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+ validates :container_registry_import_target_plan, presence: true
+ validates :container_registry_import_created_before, presence: true
validates :dependency_proxy_ttl_group_policy_worker_capacity,
allow_nil: false,
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+ validates :packages_cleanup_package_file_worker_capacity,
+ allow_nil: false,
+ numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+
validates :invisible_captcha_enabled,
inclusion: { in: [true, false], message: _('must be a boolean value') }
@@ -500,6 +515,9 @@ class ApplicationSetting < ApplicationRecord
validates :notes_create_limit,
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+ validates :user_email_lookup_limit,
+ 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
diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb
index 5e20aac3b92..25198178f69 100644
--- a/app/models/application_setting_implementation.rb
+++ b/app/models/application_setting_implementation.rb
@@ -14,7 +14,7 @@ module ApplicationSettingImplementation
# Setting a key restriction to `-1` means that all keys of this type are
# forbidden.
FORBIDDEN_KEY_VALUE = KeyRestrictionValidator::FORBIDDEN
- SUPPORTED_KEY_TYPES = %i[rsa dsa ecdsa ed25519].freeze
+ SUPPORTED_KEY_TYPES = Gitlab::SSHPublicKey.supported_types
VALID_RUNNER_REGISTRAR_TYPES = %w(project group).freeze
DEFAULT_PROTECTED_PATHS = [
@@ -217,12 +217,19 @@ module ApplicationSettingImplementation
wiki_page_max_content_bytes: 50.megabytes,
container_registry_delete_tags_service_timeout: 250,
container_registry_expiration_policies_worker_capacity: 0,
+ container_registry_import_max_tags_count: 100,
+ container_registry_import_max_retries: 3,
+ container_registry_import_start_max_retries: 50,
+ container_registry_import_max_step_duration: 5.minutes,
+ container_registry_import_target_plan: 'free',
+ container_registry_import_created_before: '2022-01-23 00:00:00',
kroki_enabled: false,
kroki_url: nil,
kroki_formats: { blockdiag: false, bpmn: false, excalidraw: false },
rate_limiting_response_text: nil,
whats_new_variant: 0,
- user_deactivation_emails_enabled: true
+ user_deactivation_emails_enabled: true,
+ user_email_lookup_limit: 60
}
end
diff --git a/app/models/audit_event.rb b/app/models/audit_event.rb
index 1a8bd05c42c..35c4e08730e 100644
--- a/app/models/audit_event.rb
+++ b/app/models/audit_event.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
class AuditEvent < ApplicationRecord
+ include AfterCommitQueue
include CreatedAtFilterable
include BulkInsertSafe
include EachBatch
diff --git a/app/models/bulk_imports/file_transfer/project_config.rb b/app/models/bulk_imports/file_transfer/project_config.rb
index fdfb0dd0186..38884df9fcf 100644
--- a/app/models/bulk_imports/file_transfer/project_config.rb
+++ b/app/models/bulk_imports/file_transfer/project_config.rb
@@ -8,6 +8,8 @@ module BulkImports
group_members
).freeze
+ LFS_OBJECTS_RELATION = 'lfs_objects'
+
def import_export_yaml
::Gitlab::ImportExport.config_file
end
@@ -15,6 +17,10 @@ module BulkImports
def skipped_relations
SKIPPED_RELATIONS
end
+
+ def file_relations
+ [UPLOADS_RELATION, LFS_OBJECTS_RELATION]
+ end
end
end
end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 428e440afba..c4d1a2c740b 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -268,6 +268,10 @@ module Ci
!build.any_unmet_prerequisites? # If false is returned, it stops the transition
end
+ before_transition on: :enqueue do |build|
+ !build.waiting_for_deployment_approval? # If false is returned, it stops the transition
+ end
+
after_transition created: :scheduled do |build|
build.run_after_commit do
Ci::BuildScheduleWorker.perform_at(build.scheduled_at, build.id)
@@ -393,6 +397,10 @@ module Ci
auto_retry.allowed?
end
+ def auto_retry_expected?
+ failed? && auto_retry_allowed?
+ end
+
def detailed_status(current_user)
Gitlab::Ci::Status::Build::Factory
.new(self.present, current_user)
@@ -416,6 +424,10 @@ module Ci
true
end
+ def save_tags
+ super unless Thread.current['ci_bulk_insert_tags']
+ end
+
def archived?
return true if degenerated?
@@ -424,7 +436,11 @@ module Ci
end
def playable?
- action? && !archived? && (manual? || scheduled? || retryable?)
+ action? && !archived? && (manual? || scheduled? || retryable?) && !waiting_for_deployment_approval?
+ end
+
+ def waiting_for_deployment_approval?
+ manual? && starts_environment? && deployment&.blocked?
end
def schedulable?
@@ -751,9 +767,7 @@ module Ci
def any_runners_available?
cache_for_available_runners do
- ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/339937') do
- project.active_runners.exists?
- end
+ project.active_runners.exists?
end
end
@@ -1021,7 +1035,15 @@ module Ci
transaction do
update_columns(status: :failed, failure_reason: :data_integrity_failure)
all_queuing_entries.delete_all
+ all_runtime_metadata.delete_all
end
+
+ Gitlab::AppLogger.info(
+ message: 'Build doomed',
+ class: self.class.name,
+ build_id: id,
+ pipeline_id: pipeline_id,
+ project_id: project_id)
end
def degradation_threshold
@@ -1051,10 +1073,7 @@ module Ci
end
def drop_with_exit_code!(failure_reason, exit_code)
- transaction do
- conditionally_allow_failure!(exit_code)
- drop!(failure_reason)
- end
+ drop!(::Gitlab::Ci::Build::Status::Reason.new(self, failure_reason, exit_code))
end
def exit_codes_defined?
@@ -1065,6 +1084,10 @@ module Ci
::Ci::PendingBuild.upsert_from_build!(self)
end
+ def create_runtime_metadata!
+ ::Ci::RunningBuild.upsert_shared_runner_build!(self)
+ end
+
##
# We can have only one queuing entry or running build tracking entry,
# because there is a unique index on `build_id` in each table, but we need
@@ -1093,6 +1116,13 @@ module Ci
end
end
+ def allowed_to_fail_with_code?(exit_code)
+ options
+ .dig(:allow_failure_criteria, :exit_codes)
+ .to_a
+ .include?(exit_code)
+ end
+
protected
def run_status_commit_hooks!
@@ -1174,27 +1204,15 @@ module Ci
break variables unless Feature.enabled?(:ci_job_jwt, project, default_enabled: true)
jwt = Gitlab::Ci::Jwt.for_build(self)
+ jwt_v2 = Gitlab::Ci::JwtV2.for_build(self)
variables.append(key: 'CI_JOB_JWT', value: jwt, public: false, masked: true)
+ variables.append(key: 'CI_JOB_JWT_V1', value: jwt, public: false, masked: true)
+ variables.append(key: 'CI_JOB_JWT_V2', value: jwt_v2, public: false, masked: true)
rescue OpenSSL::PKey::RSAError, Gitlab::Ci::Jwt::NoSigningKeyError => e
Gitlab::ErrorTracking.track_exception(e)
end
end
- def conditionally_allow_failure!(exit_code)
- return unless exit_code
-
- if allowed_to_fail_with_code?(exit_code)
- update_columns(allow_failure: true)
- end
- end
-
- def allowed_to_fail_with_code?(exit_code)
- options
- .dig(:allow_failure_criteria, :exit_codes)
- .to_a
- .include?(exit_code)
- end
-
def cache_for_online_runners(&block)
Rails.cache.fetch(
['has-online-runners', id],
diff --git a/app/models/ci/job_artifact.rb b/app/models/ci/job_artifact.rb
index e6dd62fab34..3426c4d5248 100644
--- a/app/models/ci/job_artifact.rb
+++ b/app/models/ci/job_artifact.rb
@@ -181,9 +181,7 @@ module Ci
end
scope :erasable, -> do
- types = self.file_types.reject { |file_type| NON_ERASABLE_FILE_TYPES.include?(file_type) }.values
-
- where(file_type: types)
+ where(file_type: self.erasable_file_types)
end
scope :downloadable, -> { where(file_type: DOWNLOADABLE_TYPES) }
@@ -263,6 +261,10 @@ module Ci
[file_type]
end
+ def self.erasable_file_types
+ self.file_types.keys - NON_ERASABLE_FILE_TYPES
+ end
+
def self.total_size
self.sum(:size)
end
@@ -271,10 +273,6 @@ module Ci
self.where(project: project).sum(:size)
end
- def self.distinct_job_ids
- distinct.pluck(:job_id)
- end
-
##
# FastDestroyAll concerns
# rubocop: disable CodeReuse/ServiceClass
@@ -350,9 +348,7 @@ module Ci
def store_after_commit?
strong_memoize(:store_after_commit) do
- trace? &&
- JobArtifactUploader.direct_upload_enabled? &&
- Feature.enabled?(:ci_store_trace_outside_transaction, project, default_enabled: :yaml)
+ trace? && JobArtifactUploader.direct_upload_enabled?
end
end
diff --git a/app/models/ci/namespace_mirror.rb b/app/models/ci/namespace_mirror.rb
index 8a4be3139e8..ce3faf3546b 100644
--- a/app/models/ci/namespace_mirror.rb
+++ b/app/models/ci/namespace_mirror.rb
@@ -10,6 +10,12 @@ module Ci
where('traversal_ids @> ARRAY[?]::int[]', id)
end
+ scope :contains_any_of_namespaces, -> (ids) do
+ where('traversal_ids && ARRAY[?]::int[]', ids)
+ end
+
+ scope :by_namespace_id, -> (namespace_id) { where(namespace_id: namespace_id) }
+
class << self
def sync!(event)
namespace = event.namespace
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index a90bd739741..00d331df4c3 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -69,6 +69,7 @@ module Ci
has_many :builds, foreign_key: :commit_id, inverse_of: :pipeline
has_many :generic_commit_statuses, foreign_key: :commit_id, inverse_of: :pipeline, class_name: 'GenericCommitStatus'
has_many :job_artifacts, through: :builds
+ has_many :build_trace_chunks, class_name: 'Ci::BuildTraceChunk', through: :builds, source: :trace_chunks
has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id # rubocop:disable Cop/ActiveRecordDependent
has_many :variables, class_name: 'Ci::PipelineVariable'
has_many :deployments, through: :builds
@@ -130,6 +131,7 @@ module Ci
after_create :keep_around_commits, unless: :importing?
use_fast_destroy :job_artifacts
+ use_fast_destroy :build_trace_chunks
# We use `Enums::Ci::Pipeline.sources` here so that EE can more easily extend
# this `Hash` with new values.
@@ -242,11 +244,7 @@ module Ci
::JiraConnect::SyncBuildsWorker.perform_async(pipeline.id, seq_id)
end
- if Feature.enabled?(:expire_job_and_pipeline_cache_synchronously, pipeline.project, default_enabled: :yaml)
- Ci::ExpirePipelineCacheService.new.execute(pipeline) # rubocop: disable CodeReuse/ServiceClass
- else
- ExpirePipelineCacheWorker.perform_async(pipeline.id)
- end
+ Ci::ExpirePipelineCacheService.new.execute(pipeline) # rubocop: disable CodeReuse/ServiceClass
end
end
@@ -466,6 +464,14 @@ module Ci
statuses.count(:id)
end
+ def tags_count
+ ActsAsTaggableOn::Tagging.where(taggable: builds).count
+ end
+
+ def distinct_tags_count
+ ActsAsTaggableOn::Tagging.where(taggable: builds).count('distinct(tag_id)')
+ end
+
def stages_names
statuses.order(:stage_idx).distinct
.pluck(:stage, :stage_idx).map(&:first)
@@ -1284,6 +1290,12 @@ module Ci
end
end
+ def use_variables_builder_definitions?
+ strong_memoize(:use_variables_builder_definitions) do
+ ::Feature.enabled?(:ci_use_variables_builder_definitions, project, default_enabled: :yaml)
+ end
+ end
+
private
def add_message(severity, content)
diff --git a/app/models/ci/project_mirror.rb b/app/models/ci/project_mirror.rb
index d6aaa3f50c1..9000d1791a6 100644
--- a/app/models/ci/project_mirror.rb
+++ b/app/models/ci/project_mirror.rb
@@ -6,6 +6,9 @@ module Ci
class ProjectMirror < ApplicationRecord
belongs_to :project
+ scope :by_namespace_id, -> (namespace_id) { where(namespace_id: namespace_id) }
+ scope :by_project_id, -> (project_id) { where(project_id: project_id) }
+
class << self
def sync!(event)
upsert({ project_id: event.project_id, namespace_id: event.project.namespace_id },
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index a80fd02080f..809c245d2b9 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -95,7 +95,33 @@ module Ci
joins(:runner_projects).where(ci_runner_projects: { project_id: project_id })
}
- scope :belonging_to_group, -> (group_id, include_ancestors: false) {
+ scope :belonging_to_group, -> (group_id) {
+ joins(:runner_namespaces)
+ .where(ci_runner_namespaces: { namespace_id: group_id })
+ }
+
+ scope :belonging_to_group_or_project_descendants, -> (group_id) {
+ group_ids = Ci::NamespaceMirror.contains_namespace(group_id).select(:namespace_id)
+ project_ids = Ci::ProjectMirror.by_namespace_id(group_ids).select(:project_id)
+
+ group_runners = joins(:runner_namespaces).where(ci_runner_namespaces: { namespace_id: group_ids })
+ project_runners = joins(:runner_projects).where(ci_runner_projects: { project_id: project_ids })
+
+ union_sql = ::Gitlab::SQL::Union.new([group_runners, project_runners]).to_sql
+
+ from("(#{union_sql}) #{table_name}")
+ }
+
+ scope :belonging_to_group_and_ancestors, -> (group_id) {
+ group_self_and_ancestors_ids = ::Group.find_by(id: group_id)&.self_and_ancestor_ids
+
+ joins(:runner_namespaces)
+ .where(ci_runner_namespaces: { namespace_id: group_self_and_ancestors_ids })
+ }
+
+ # deprecated
+ # split this into: belonging_to_group & belonging_to_group_and_ancestors
+ scope :legacy_belonging_to_group, -> (group_id, include_ancestors: false) {
groups = ::Group.where(id: group_id)
groups = groups.self_and_ancestors if include_ancestors
@@ -104,7 +130,8 @@ module Ci
.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336433')
}
- scope :belonging_to_group_or_project, -> (group_id, project_id) {
+ # deprecated
+ scope :legacy_belonging_to_group_or_project, -> (group_id, project_id) {
groups = ::Group.where(id: group_id)
group_runners = joins(:runner_namespaces).where(ci_runner_namespaces: { namespace_id: groups })
@@ -117,11 +144,11 @@ module Ci
}
scope :belonging_to_parent_group_of_project, -> (project_id) {
+ raise ArgumentError, "only 1 project_id allowed for performance reasons" unless project_id.is_a?(Integer)
+
project_groups = ::Group.joins(:projects).where(projects: { id: project_id })
- joins(:groups)
- .where(namespaces: { id: project_groups.self_and_ancestors.as_ids })
- .allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336433')
+ belonging_to_group(project_groups.self_and_ancestors.pluck(:id))
}
scope :owned_or_instance_wide, -> (project_id) do
@@ -132,7 +159,7 @@ module Ci
instance_type
],
remove_duplicates: false
- ).allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336433')
+ )
end
scope :assignable_for, ->(project) do
@@ -183,6 +210,8 @@ module Ci
validates :config, json_schema: { filename: 'ci_runner_config' }
+ validates :maintainer_note, length: { maximum: 255 }
+
# Searches for runners matching the given query.
#
# This method uses ILIKE on PostgreSQL for the description field and performs a full match on tokens.
@@ -233,18 +262,16 @@ module Ci
Arel.sql("(#{arel_tag_names_array.to_sql})")
]
- ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/339621') do
- group(*unique_params).pluck('array_agg(ci_runners.id)', *unique_params).map do |values|
- Gitlab::Ci::Matching::RunnerMatcher.new({
- runner_ids: values[0],
- runner_type: values[1],
- public_projects_minutes_cost_factor: values[2],
- private_projects_minutes_cost_factor: values[3],
- run_untagged: values[4],
- access_level: values[5],
- tag_list: values[6]
- })
- end
+ group(*unique_params).pluck('array_agg(ci_runners.id)', *unique_params).map do |values|
+ Gitlab::Ci::Matching::RunnerMatcher.new({
+ runner_ids: values[0],
+ runner_type: values[1],
+ public_projects_minutes_cost_factor: values[2],
+ private_projects_minutes_cost_factor: values[3],
+ run_untagged: values[4],
+ access_level: values[5],
+ tag_list: values[6]
+ })
end
end
@@ -441,6 +468,7 @@ module Ci
private
EXECUTOR_NAME_TO_TYPES = {
+ 'unknown' => :unknown,
'custom' => :custom,
'shell' => :shell,
'docker' => :docker,
@@ -454,6 +482,8 @@ module Ci
'kubernetes' => :kubernetes
}.freeze
+ EXECUTOR_TYPE_TO_NAMES = EXECUTOR_NAME_TO_TYPES.invert.freeze
+
def cleanup_runner_queue
Gitlab::Redis::SharedState.with do |redis|
redis.del(runner_queue_key)
diff --git a/app/models/ci/secure_file.rb b/app/models/ci/secure_file.rb
new file mode 100644
index 00000000000..56f632b6232
--- /dev/null
+++ b/app/models/ci/secure_file.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Ci
+ class SecureFile < Ci::ApplicationRecord
+ include FileStoreMounter
+
+ FILE_SIZE_LIMIT = 5.megabytes.freeze
+ CHECKSUM_ALGORITHM = 'sha256'
+
+ belongs_to :project, optional: false
+
+ validates :file, presence: true, file_size: { maximum: FILE_SIZE_LIMIT }
+ validates :checksum, :file_store, :name, :permissions, :project_id, presence: true
+
+ before_validation :assign_checksum
+
+ enum permissions: { read_only: 0, read_write: 1, execute: 2 }
+
+ default_value_for(:file_store) { Ci::SecureFileUploader.default_store }
+
+ mount_file_store_uploader Ci::SecureFileUploader
+
+ def checksum_algorithm
+ CHECKSUM_ALGORITHM
+ end
+
+ private
+
+ def assign_checksum
+ self.checksum = file.checksum if file.present? && file_changed?
+ end
+ end
+end
diff --git a/app/models/clusters/agent.rb b/app/models/clusters/agent.rb
index 98490a13351..79fc2b58237 100644
--- a/app/models/clusters/agent.rb
+++ b/app/models/clusters/agent.rb
@@ -5,6 +5,7 @@ module Clusters
self.table_name = 'cluster_agents'
INACTIVE_AFTER = 1.hour.freeze
+ ACTIVITY_EVENT_LIMIT = 200
belongs_to :created_by_user, class_name: 'User', optional: true
belongs_to :project, class_name: '::Project' # Otherwise, it will load ::Clusters::Project
@@ -36,8 +37,15 @@ module Clusters
requested_project == project
end
- def active?
- agent_tokens.where("last_used_at > ?", INACTIVE_AFTER.ago).exists?
+ def connected?
+ agent_tokens.active.where("last_used_at > ?", INACTIVE_AFTER.ago).exists?
+ end
+
+ def activity_event_deletion_cutoff
+ # Order is defined by the association
+ activity_events
+ .offset(ACTIVITY_EVENT_LIMIT - 1)
+ .pick(:recorded_at)
end
end
end
diff --git a/app/models/clusters/agent_token.rb b/app/models/clusters/agent_token.rb
index 87dba50cd69..691d628524f 100644
--- a/app/models/clusters/agent_token.rb
+++ b/app/models/clusters/agent_token.rb
@@ -10,9 +10,6 @@ module Clusters
self.table_name = 'cluster_agent_tokens'
- # The `UPDATE_USED_COLUMN_EVERY` defines how often the token DB entry can be updated
- UPDATE_USED_COLUMN_EVERY = (40.minutes..55.minutes).freeze
-
belongs_to :agent, class_name: 'Clusters::Agent', optional: false
belongs_to :created_by_user, class_name: 'User', optional: true
@@ -22,40 +19,11 @@ module Clusters
validates :name, presence: true, length: { maximum: 255 }
scope :order_last_used_at_desc, -> { order(::Gitlab::Database.nulls_last_order('last_used_at', 'DESC')) }
+ scope :with_status, -> (status) { where(status: status) }
- def track_usage
- track_values = { last_used_at: Time.current.utc }
-
- cache_attributes(track_values)
-
- if can_update_track_values?
- log_activity_event!(track_values[:last_used_at]) unless agent.active?
-
- # Use update_column so updated_at is skipped
- update_columns(track_values)
- end
- end
-
- private
-
- def can_update_track_values?
- # Use a random threshold to prevent beating DB updates.
- last_used_at_max_age = Random.rand(UPDATE_USED_COLUMN_EVERY)
-
- real_last_used_at = read_attribute(:last_used_at)
-
- # Handle too many updates from high token traffic
- real_last_used_at.nil? ||
- (Time.current - real_last_used_at) >= last_used_at_max_age
- end
-
- def log_activity_event!(recorded_at)
- agent.activity_events.create!(
- kind: :agent_connected,
- level: :info,
- recorded_at: recorded_at,
- agent_token: self
- )
- end
+ enum status: {
+ active: 0,
+ revoked: 1
+ }
end
end
diff --git a/app/models/clusters/agents/activity_event.rb b/app/models/clusters/agents/activity_event.rb
index 5d9c885c923..ec2bbfde339 100644
--- a/app/models/clusters/agents/activity_event.rb
+++ b/app/models/clusters/agents/activity_event.rb
@@ -3,6 +3,7 @@
module Clusters
module Agents
class ActivityEvent < ApplicationRecord
+ include EachBatch
include NullifyIfBlank
self.table_name = 'agent_activity_events'
@@ -12,6 +13,7 @@ module Clusters
belongs_to :agent_token, class_name: 'Clusters::AgentToken'
scope :in_timeline_order, -> { order(recorded_at: :desc, id: :desc) }
+ scope :recorded_before, -> (cutoff) { where('recorded_at < ?', cutoff) }
validates :recorded_at, :kind, :level, presence: true
diff --git a/app/models/clusters/applications/runner.rb b/app/models/clusters/applications/runner.rb
index b57a24dead0..33cd5de3518 100644
--- a/app/models/clusters/applications/runner.rb
+++ b/app/models/clusters/applications/runner.rb
@@ -3,7 +3,7 @@
module Clusters
module Applications
class Runner < ApplicationRecord
- VERSION = '0.35.0'
+ VERSION = '0.36.0'
self.table_name = 'clusters_applications_runners'
@@ -41,7 +41,7 @@ module Clusters
end
def prepare_uninstall
- runner&.update!(active: false)
+ # No op, see https://gitlab.com/gitlab-org/gitlab/-/issues/350180.
end
def post_uninstall
diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index d6a2f62ca9b..21e2e21e9b3 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -170,8 +170,11 @@ class CommitStatus < Ci::ApplicationRecord
end
before_transition any => :failed do |commit_status, transition|
- failure_reason = transition.args.first
- commit_status.failure_reason = CommitStatus.failure_reasons[failure_reason]
+ reason = ::Gitlab::Ci::Build::Status::Reason
+ .fabricate(commit_status, transition.args.first)
+
+ commit_status.failure_reason = reason.failure_reason_enum
+ commit_status.allow_failure = true if reason.force_allow_failure?
end
before_transition [:skipped, :manual] => :created do |commit_status, transition|
@@ -191,11 +194,7 @@ class CommitStatus < Ci::ApplicationRecord
commit_status.run_after_commit do
PipelineProcessWorker.perform_async(pipeline_id) unless transition_options[:skip_pipeline_processing]
- if Feature.enabled?(:expire_job_and_pipeline_cache_synchronously, project, default_enabled: :yaml)
- expire_etag_cache!
- else
- ExpireJobCacheWorker.perform_async(id)
- end
+ expire_etag_cache!
end
end
@@ -221,8 +220,8 @@ class CommitStatus < Ci::ApplicationRecord
false
end
- def self.bulk_insert_tags!(statuses, tag_list_by_build)
- Gitlab::Ci::Tags::BulkInsert.new(statuses, tag_list_by_build).insert!
+ def self.bulk_insert_tags!(statuses)
+ Gitlab::Ci::Tags::BulkInsert.new(statuses).insert!
end
def locking_enabled?
diff --git a/app/models/concerns/ci/contextable.rb b/app/models/concerns/ci/contextable.rb
index 12ddbc2cc40..ed3b422251f 100644
--- a/app/models/concerns/ci/contextable.rb
+++ b/app/models/concerns/ci/contextable.rb
@@ -13,6 +13,8 @@ module Ci
track_duration do
variables = pipeline.variables_builder.scoped_variables(self, environment: environment, dependencies: dependencies)
+ next variables if pipeline.use_variables_builder_definitions?
+
variables.concat(project.predefined_variables)
variables.concat(pipeline.predefined_variables)
variables.concat(runner.predefined_variables) if runnable? && runner
@@ -60,49 +62,27 @@ module Ci
end
def user_variables
- Gitlab::Ci::Variables::Collection.new.tap do |variables|
- break variables if user.blank?
-
- variables.append(key: 'GITLAB_USER_ID', value: user.id.to_s)
- variables.append(key: 'GITLAB_USER_EMAIL', value: user.email)
- variables.append(key: 'GITLAB_USER_LOGIN', value: user.username)
- variables.append(key: 'GITLAB_USER_NAME', value: user.name)
- end
+ pipeline.variables_builder.user_variables(user)
end
def kubernetes_variables
- ::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
- template = ::Ci::GenerateKubeconfigService.new(self).execute
-
- if template.valid?
- collection.append(key: 'KUBECONFIG', value: template.to_yaml, public: false, file: true)
- end
- end
+ pipeline.variables_builder.kubernetes_variables(self)
end
def deployment_variables(environment:)
- return [] unless environment
-
- project.deployment_variables(
- environment: environment,
- kubernetes_namespace: expanded_kubernetes_namespace
- )
+ pipeline.variables_builder.deployment_variables(job: self, environment: environment)
end
def secret_instance_variables
- project.ci_instance_variables_for(ref: git_ref)
+ pipeline.variables_builder.secret_instance_variables(ref: git_ref)
end
def secret_group_variables(environment: expanded_environment_name)
- return [] unless project.group
-
- project.group.ci_variables_for(git_ref, project, environment: environment)
+ pipeline.variables_builder.secret_group_variables(environment: environment, ref: git_ref)
end
def secret_project_variables(environment: expanded_environment_name)
- project.ci_variables_for(ref: git_ref, environment: environment)
+ pipeline.variables_builder.secret_project_variables(environment: environment, ref: git_ref)
end
end
end
diff --git a/app/models/concerns/ci/metadatable.rb b/app/models/concerns/ci/metadatable.rb
index 611b27c722b..aa9669ee208 100644
--- a/app/models/concerns/ci/metadatable.rb
+++ b/app/models/concerns/ci/metadatable.rb
@@ -18,13 +18,19 @@ module Ci
delegate :timeout, to: :metadata, prefix: true, allow_nil: true
delegate :interruptible, to: :metadata, prefix: false, allow_nil: true
- delegate :has_exposed_artifacts?, to: :metadata, prefix: false, allow_nil: true
delegate :environment_auto_stop_in, to: :metadata, prefix: false, allow_nil: true
delegate :set_cancel_gracefully, to: :metadata, prefix: false, allow_nil: false
- delegate :cancel_gracefully?, to: :metadata, prefix: false, allow_nil: false
before_create :ensure_metadata
end
+ def has_exposed_artifacts?
+ !!metadata&.has_exposed_artifacts?
+ end
+
+ def cancel_gracefully?
+ !!metadata&.cancel_gracefully?
+ end
+
def ensure_metadata
metadata || build_metadata(project: project)
end
diff --git a/app/models/concerns/forced_email_confirmation.rb b/app/models/concerns/forced_email_confirmation.rb
new file mode 100644
index 00000000000..649400184e5
--- /dev/null
+++ b/app/models/concerns/forced_email_confirmation.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module ForcedEmailConfirmation
+ extend ActiveSupport::Concern
+
+ included do
+ attr_accessor :skip_confirmation_period_expiry_check
+ end
+
+ def force_confirm(args = {})
+ self.skip_confirmation_period_expiry_check = true
+ confirm(args)
+ ensure
+ self.skip_confirmation_period_expiry_check = nil
+ end
+
+ protected
+
+ # Override, from Devise::Models::Confirmable
+ # Link: https://github.com/heartcombo/devise/blob/main/lib/devise/models/confirmable.rb
+ def confirmation_period_expired?
+ return false if skip_confirmation_period_expiry_check
+
+ super
+ end
+end
diff --git a/app/models/concerns/has_wiki.rb b/app/models/concerns/has_wiki.rb
index df7bbe4dc08..89bcabafb84 100644
--- a/app/models/concerns/has_wiki.rb
+++ b/app/models/concerns/has_wiki.rb
@@ -17,7 +17,7 @@ module HasWiki
def wiki
strong_memoize(:wiki) do
- Wiki.for_container(self, self.default_owner)
+ Wiki.for_container(self, self.first_owner)
end
end
diff --git a/app/models/concerns/import_state/sidekiq_job_tracker.rb b/app/models/concerns/import_state/sidekiq_job_tracker.rb
index 340bf4279bc..b7d0ed0f51b 100644
--- a/app/models/concerns/import_state/sidekiq_job_tracker.rb
+++ b/app/models/concerns/import_state/sidekiq_job_tracker.rb
@@ -15,7 +15,7 @@ module ImportState
def refresh_jid_expiration
return unless jid
- Gitlab::SidekiqStatus.set(jid, Gitlab::Import::StuckImportJob::IMPORT_JOBS_EXPIRATION, value: 2)
+ Gitlab::SidekiqStatus.set(jid, Gitlab::Import::StuckImportJob::IMPORT_JOBS_EXPIRATION)
end
def self.jid_by(project_id:, status:)
diff --git a/app/models/concerns/incident_management/escalatable.rb b/app/models/concerns/incident_management/escalatable.rb
index 81eef50603a..a9e4a066e0e 100644
--- a/app/models/concerns/incident_management/escalatable.rb
+++ b/app/models/concerns/incident_management/escalatable.rb
@@ -27,6 +27,8 @@ module IncidentManagement
ignored: 'No action will be taken'
}.freeze
+ OPEN_STATUSES = [:triggered, :acknowledged].freeze
+
included do
validates :status, presence: true
@@ -34,6 +36,7 @@ module IncidentManagement
# Descending sort order sorts statuses: Triggered > Acknowledged > Resolved > Ignored
# https://gitlab.com/gitlab-org/gitlab/-/issues/221242#what-is-the-expected-correct-behavior
scope :order_status, -> (sort_order) { order(status: sort_order == :asc ? :desc : :asc) }
+ scope :open, -> { with_status(OPEN_STATUSES) }
state_machine :status, initial: :triggered do
state :triggered, value: STATUSES[:triggered]
@@ -89,6 +92,10 @@ module IncidentManagement
@status_names ||= state_machine_statuses.keys
end
+ def open_status?(status)
+ OPEN_STATUSES.include?(status)
+ end
+
private
def state_machine_statuses
@@ -99,6 +106,10 @@ module IncidentManagement
def status_event_for(status)
self.class.state_machines[:status].events.transitions_for(self, to: status.to_s.to_sym).first&.event
end
+
+ def open?
+ self.class.open_status?(status_name)
+ end
end
end
end
diff --git a/app/models/concerns/packages/debian/distribution.rb b/app/models/concerns/packages/debian/distribution.rb
index ff52769fce8..2d46889ce6a 100644
--- a/app/models/concerns/packages/debian/distribution.rb
+++ b/app/models/concerns/packages/debian/distribution.rb
@@ -96,6 +96,15 @@ module Packages
architectures.pluck(:name).sort
end
+ def package_files
+ if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml)
+ ::Packages::PackageFile.installable
+ .for_package_ids(packages.select(:id))
+ else
+ ::Packages::PackageFile.for_package_ids(packages.select(:id))
+ end
+ end
+
private
def unique_codename_and_suite
diff --git a/app/models/concerns/packages/destructible.rb b/app/models/concerns/packages/destructible.rb
new file mode 100644
index 00000000000..a3b7d8580c1
--- /dev/null
+++ b/app/models/concerns/packages/destructible.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Packages
+ module Destructible
+ extend ActiveSupport::Concern
+
+ class_methods do
+ def next_pending_destruction(order_by: nil)
+ set = pending_destruction.limit(1).lock('FOR UPDATE SKIP LOCKED')
+ set = set.order(order_by) if order_by
+ set.take
+ end
+ end
+ end
+end
diff --git a/app/models/concerns/packages/installable.rb b/app/models/concerns/packages/installable.rb
new file mode 100644
index 00000000000..e9303e55412
--- /dev/null
+++ b/app/models/concerns/packages/installable.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Packages
+ # This module requires a status column.
+ # It also requires a constant INSTALLABLE_STATUSES. This should be
+ # an array that defines which values of the status column are
+ # considered as installable.
+ module Installable
+ extend ActiveSupport::Concern
+
+ included do
+ scope :with_status, ->(status) { where(status: status) }
+ scope :installable, -> { with_status(const_get(:INSTALLABLE_STATUSES, false)) }
+ end
+ end
+end
diff --git a/app/models/concerns/participable.rb b/app/models/concerns/participable.rb
index 1663aa6c886..20743ebcb52 100644
--- a/app/models/concerns/participable.rb
+++ b/app/models/concerns/participable.rb
@@ -64,8 +64,6 @@ module Participable
#
# Returns an Array of User instances.
def visible_participants(user)
- return participants(user) unless Feature.enabled?(:verify_participants_access, project, default_enabled: :yaml)
-
filter_by_ability(raw_participants(user, verify_access: true))
end
diff --git a/app/models/concerns/routable.rb b/app/models/concerns/routable.rb
index f382b3624ed..2cf95ac0dae 100644
--- a/app/models/concerns/routable.rb
+++ b/app/models/concerns/routable.rb
@@ -190,5 +190,10 @@ module Routable
route || build_route(source: self)
route.path = build_full_path
route.name = build_full_name
+ route.namespace = if is_a?(Namespace)
+ self
+ elsif is_a?(Project)
+ self.project_namespace
+ end
end
end
diff --git a/app/models/concerns/runner_token_expiration_interval.rb b/app/models/concerns/runner_token_expiration_interval.rb
new file mode 100644
index 00000000000..f84e69e7b7d
--- /dev/null
+++ b/app/models/concerns/runner_token_expiration_interval.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module RunnerTokenExpirationInterval
+ extend ActiveSupport::Concern
+
+ def enforced_runner_token_expiration_interval_human_readable
+ interval = enforced_runner_token_expiration_interval
+ ChronicDuration.output(interval, format: :short) if interval
+ end
+
+ def effective_runner_token_expiration_interval
+ [
+ enforced_runner_token_expiration_interval,
+ runner_token_expiration_interval&.seconds
+ ].compact.min
+ end
+
+ def effective_runner_token_expiration_interval_human_readable
+ interval = effective_runner_token_expiration_interval
+ ChronicDuration.output(interval, format: :short) if interval
+ end
+end
diff --git a/app/models/concerns/ttl_expirable.rb b/app/models/concerns/ttl_expirable.rb
index 6d89521255c..1c2147beedd 100644
--- a/app/models/concerns/ttl_expirable.rb
+++ b/app/models/concerns/ttl_expirable.rb
@@ -7,16 +7,10 @@ module TtlExpirable
validates :status, presence: true
default_value_for :read_at, Time.zone.now
- enum status: { default: 0, expired: 1, processing: 2, error: 3 }
+ enum status: { default: 0, pending_destruction: 1, processing: 2, error: 3 }
scope :read_before, ->(number_of_days) { where("read_at <= ?", Time.zone.now - number_of_days.days) }
scope :active, -> { where(status: :default) }
-
- scope :lock_next_by, ->(sort) do
- order(sort)
- .limit(1)
- .lock('FOR UPDATE SKIP LOCKED')
- end
end
def read!
diff --git a/app/models/container_repository.rb b/app/models/container_repository.rb
index c914819f79d..b03d946fc47 100644
--- a/app/models/container_repository.rb
+++ b/app/models/container_repository.rb
@@ -13,9 +13,15 @@ class ContainerRepository < ApplicationRecord
validates :name, length: { minimum: 0, allow_nil: false }
validates :name, uniqueness: { scope: :project_id }
+ validates :migration_state, presence: true
+
+ validates :migration_retries_count, presence: true,
+ numericality: { greater_than_or_equal_to: 0 },
+ allow_nil: false
enum status: { delete_scheduled: 0, delete_failed: 1 }
enum expiration_policy_cleanup_status: { cleanup_unscheduled: 0, cleanup_scheduled: 1, cleanup_unfinished: 2, cleanup_ongoing: 3 }
+ enum migration_skipped_reason: { not_in_plan: 0, too_many_retries: 1, too_many_tags: 2, root_namespace_in_deny_list: 3 }
delegate :client, to: :registry
diff --git a/app/models/customer_relations/contact.rb b/app/models/customer_relations/contact.rb
index d8669f1f4c2..168f1c48a6c 100644
--- a/app/models/customer_relations/contact.rb
+++ b/app/models/customer_relations/contact.rb
@@ -24,11 +24,12 @@ class CustomerRelations::Contact < ApplicationRecord
validates :email, length: { maximum: 255 }
validates :description, length: { maximum: 1024 }
validate :validate_email_format
+ validate :unique_email_for_group_hierarchy
- def self.find_ids_by_emails(group_id, emails)
+ 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_id, email: emails)
+ where(group_id: group.self_and_ancestor_ids, email: emails)
.pluck(:id)
end
@@ -39,4 +40,14 @@ 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
+
+ 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
+ end
end
diff --git a/app/models/customer_relations/issue_contact.rb b/app/models/customer_relations/issue_contact.rb
index 78f662b6a58..89dac6bad22 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
+ validate :contact_belongs_to_issue_group_or_ancestor
def self.find_contact_ids_by_emails(issue_id, emails)
raise ArgumentError, "Cannot lookup more than #{MAX_PLUCK} emails" if emails.length > MAX_PLUCK
@@ -18,11 +18,11 @@ class CustomerRelations::IssueContact < ApplicationRecord
private
- def contact_belongs_to_issue_group
+ def contact_belongs_to_issue_group_or_ancestor
return unless contact&.group_id
return unless issue&.project&.namespace_id
- return if contact.group_id == issue.project.namespace_id
+ return if issue.project.group&.self_and_ancestor_ids&.include?(contact.group_id)
- errors.add(:base, _('The contact does not belong to the same group as the issue'))
+ errors.add(:base, _('The contact does not belong to the issue group or an ancestor'))
end
end
diff --git a/app/models/dependency_proxy/blob.rb b/app/models/dependency_proxy/blob.rb
index bd5c022e692..e4018ab4770 100644
--- a/app/models/dependency_proxy/blob.rb
+++ b/app/models/dependency_proxy/blob.rb
@@ -3,6 +3,7 @@
class DependencyProxy::Blob < ApplicationRecord
include FileStoreMounter
include TtlExpirable
+ include Packages::Destructible
include EachBatch
belongs_to :group
diff --git a/app/models/dependency_proxy/manifest.rb b/app/models/dependency_proxy/manifest.rb
index 64f484942ef..fe887c99e81 100644
--- a/app/models/dependency_proxy/manifest.rb
+++ b/app/models/dependency_proxy/manifest.rb
@@ -3,6 +3,7 @@
class DependencyProxy::Manifest < ApplicationRecord
include FileStoreMounter
include TtlExpirable
+ include Packages::Destructible
include EachBatch
belongs_to :group
diff --git a/app/models/deployment.rb b/app/models/deployment.rb
index 4c60ce57f49..2f04d99f9f6 100644
--- a/app/models/deployment.rb
+++ b/app/models/deployment.rb
@@ -8,6 +8,7 @@ class Deployment < ApplicationRecord
include Importable
include Gitlab::Utils::StrongMemoize
include FastDestroyAll
+ include FromUnion
StatusUpdateError = Class.new(StandardError)
StatusSyncError = Class.new(StandardError)
@@ -69,6 +70,10 @@ class Deployment < ApplicationRecord
transition created: :blocked
end
+ event :unblock do
+ transition blocked: :created
+ end
+
event :succeed do
transition any - [:success] => :success
end
@@ -107,10 +112,7 @@ class Deployment < ApplicationRecord
deployment.run_after_commit do
Deployments::UpdateEnvironmentWorker.perform_async(id)
Deployments::LinkMergeRequestWorker.perform_async(id)
-
- if ::Feature.enabled?(:deployments_archive, deployment.project, default_enabled: :yaml)
- Deployments::ArchiveInProjectWorker.perform_async(deployment.project_id)
- end
+ Deployments::ArchiveInProjectWorker.perform_async(deployment.project_id)
end
end
diff --git a/app/models/email.rb b/app/models/email.rb
index 676e79406e9..3896dfd5d22 100644
--- a/app/models/email.rb
+++ b/app/models/email.rb
@@ -6,8 +6,8 @@ class Email < ApplicationRecord
belongs_to :user, optional: false
- validates :email, presence: true, uniqueness: true
- validate :validate_email_format
+ validates :email, presence: true, uniqueness: true, devise_email: true
+
validate :unique_email, if: ->(email) { email.email_changed? }
scope :confirmed, -> { where.not(confirmed_at: nil) }
@@ -19,6 +19,7 @@ class Email < ApplicationRecord
# This module adds async behaviour to Devise emails
# and should be added after Devise modules are initialized.
include AsyncDeviseEmail
+ include ForcedEmailConfirmation
self.reconfirmable = false # currently email can't be changed, no need to reconfirm
@@ -32,10 +33,6 @@ class Email < ApplicationRecord
self.errors.add(:email, 'has already been taken') if primary_email_of_another_user?
end
- def validate_email_format
- self.errors.add(:email, I18n.t(:invalid, scope: 'valid_email.validations.email')) unless ValidateEmail.valid?(self.email)
- end
-
# once email is confirmed, update the gpg signatures
def update_invalid_gpg_signatures
user.update_invalid_gpg_signatures if confirmed?
diff --git a/app/models/experiment.rb b/app/models/experiment.rb
index cd0814c476a..2300ec2996d 100644
--- a/app/models/experiment.rb
+++ b/app/models/experiment.rb
@@ -7,7 +7,7 @@ class Experiment < ApplicationRecord
validates :name, presence: true, uniqueness: true, length: { maximum: 255 }
def self.add_user(name, group_type, user, context = {})
- find_or_create_by!(name: name).record_user_and_group(user, group_type, context)
+ by_name(name).record_user_and_group(user, group_type, context)
end
def self.add_group(name, variant:, group:)
@@ -15,11 +15,15 @@ class Experiment < ApplicationRecord
end
def self.add_subject(name, variant:, subject:)
- find_or_create_by!(name: name).record_subject_and_variant!(subject, variant)
+ by_name(name).record_subject_and_variant!(subject, variant)
end
def self.record_conversion_event(name, user, context = {})
- find_or_create_by!(name: name).record_conversion_event_for_user(user, context)
+ by_name(name).record_conversion_event_for_user(user, context)
+ end
+
+ def self.by_name(name)
+ find_or_create_by!(name: name)
end
# Create or update the recorded experiment_user row for the user in this experiment.
@@ -41,6 +45,16 @@ class Experiment < ApplicationRecord
experiment_user.update!(converted_at: Time.current, context: merged_context(experiment_user, context))
end
+ def record_conversion_event_for_subject(subject, context = {})
+ raise 'Incompatible subject provided!' unless ExperimentSubject.valid_subject?(subject)
+
+ attr_name = subject.class.table_name.singularize.to_sym
+ experiment_subject = experiment_subjects.find_by(attr_name => subject)
+ return unless experiment_subject
+
+ experiment_subject.update!(converted_at: Time.current, context: merged_context(experiment_subject, context))
+ end
+
def record_subject_and_variant!(subject, variant)
raise 'Incompatible subject provided!' unless ExperimentSubject.valid_subject?(subject)
@@ -57,7 +71,7 @@ class Experiment < ApplicationRecord
private
- def merged_context(experiment_user, new_context)
- experiment_user.context.deep_merge(new_context.deep_stringify_keys)
+ def merged_context(experiment_subject, new_context)
+ experiment_subject.context.deep_merge(new_context.deep_stringify_keys)
end
end
diff --git a/app/models/external_pull_request.rb b/app/models/external_pull_request.rb
index 3fc166203e7..4654f7e2341 100644
--- a/app/models/external_pull_request.rb
+++ b/app/models/external_pull_request.rb
@@ -11,7 +11,7 @@
# When the mirror is updated and changes are pushed to branches we check
# if there are open pull requests for the source and target branch.
# If so, we create pipelines for external pull requests.
-class ExternalPullRequest < ApplicationRecord
+class ExternalPullRequest < Ci::ApplicationRecord
include Gitlab::Utils::StrongMemoize
include ShaAttribute
@@ -40,6 +40,9 @@ class ExternalPullRequest < ApplicationRecord
scope :by_source_branch, ->(branch) { where(source_branch: branch) }
scope :by_source_repository, -> (repository) { where(source_repository: repository) }
+ # Needed to override Ci::ApplicationRecord as this does not have ci_ table prefix
+ self.table_name = 'external_pull_requests'
+
def self.create_or_update_from_params(params)
find_params = params.slice(:project_id, :source_branch, :target_branch)
diff --git a/app/models/group.rb b/app/models/group.rb
index f51782785f9..53da70f47e5 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -17,6 +17,8 @@ class Group < Namespace
include GroupAPICompatibility
include EachBatch
include BulkMemberAccessLoad
+ include ChronicDurationAttribute
+ include RunnerTokenExpirationInterval
def self.sti_name
'Group'
@@ -91,6 +93,11 @@ class Group < Namespace
has_many :group_callouts, class_name: 'Users::GroupCallout', foreign_key: :group_id
delegate :prevent_sharing_groups_outside_hierarchy, :new_user_signups_cap, :setup_for_company, :jobs_to_be_done, to: :namespace_settings
+ delegate :runner_token_expiration_interval, :runner_token_expiration_interval=, :runner_token_expiration_interval_human_readable, :runner_token_expiration_interval_human_readable=, to: :namespace_settings, allow_nil: true
+ delegate :subgroup_runner_token_expiration_interval, :subgroup_runner_token_expiration_interval=, :subgroup_runner_token_expiration_interval_human_readable, :subgroup_runner_token_expiration_interval_human_readable=, to: :namespace_settings, allow_nil: true
+ delegate :project_runner_token_expiration_interval, :project_runner_token_expiration_interval=, :project_runner_token_expiration_interval_human_readable, :project_runner_token_expiration_interval_human_readable=, to: :namespace_settings, allow_nil: true
+
+ has_one :crm_settings, class_name: 'Group::CrmSettings', inverse_of: :group
accepts_nested_attributes_for :variables, allow_destroy: true
@@ -121,6 +128,8 @@ class Group < Namespace
scope :by_id, ->(groups) { where(id: groups) }
+ scope :by_ids_or_paths, -> (ids, paths) { by_id(ids).or(where(path: paths)) }
+
scope :for_authorized_group_members, -> (user_ids) do
joins(:group_members)
.where(members: { user_id: user_ids })
@@ -212,6 +221,10 @@ class Group < Namespace
Set.new(group_ids)
end
+ def get_ids_by_ids_or_paths(ids, paths)
+ by_ids_or_paths(ids, paths).pluck(:id)
+ end
+
private
def public_to_user_arel(user)
@@ -619,7 +632,7 @@ class Group < Namespace
end
end
- def group_member(user)
+ def member(user)
if group_members.loaded?
group_members.find { |gm| gm.user_id == user.id }
else
@@ -631,6 +644,10 @@ class Group < Namespace
GroupMember.where(source_id: self_and_ancestors_ids, user_id: user.id).order(:access_level).last
end
+ def bots
+ users.project_bot
+ end
+
def related_group_ids
[id,
*ancestors.pluck(:id),
@@ -713,8 +730,8 @@ class Group < Namespace
end
end
- def default_owner
- owners.first || parent&.default_owner || owner
+ def first_owner
+ owners.first || parent&.first_owner || owner
end
def default_branch_name
@@ -764,6 +781,29 @@ class Group < Namespace
super || build_dependency_proxy_image_ttl_policy
end
+ def dependency_proxy_setting
+ super || build_dependency_proxy_setting
+ end
+
+ def crm_enabled?
+ crm_settings&.enabled?
+ end
+
+ def shared_with_group_links_visible_to_user(user)
+ shared_with_group_links.preload_shared_with_groups.filter { |link| Ability.allowed?(user, :read_group, link.shared_with_group) }
+ end
+
+ def enforced_runner_token_expiration_interval
+ all_parent_groups = Gitlab::ObjectHierarchy.new(Group.where(id: id)).ancestors
+ all_group_settings = NamespaceSetting.where(namespace_id: all_parent_groups)
+ group_interval = all_group_settings.where.not(subgroup_runner_token_expiration_interval: nil).minimum(:subgroup_runner_token_expiration_interval)&.seconds
+
+ [
+ Gitlab::CurrentSettings.group_runner_token_expiration_interval&.seconds,
+ group_interval
+ ].compact.min
+ end
+
private
def max_member_access(user_ids)
diff --git a/app/models/group/crm_settings.rb b/app/models/group/crm_settings.rb
new file mode 100644
index 00000000000..30fbe6ae07f
--- /dev/null
+++ b/app/models/group/crm_settings.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class Group::CrmSettings < ApplicationRecord
+ self.primary_key = :group_id
+ self.table_name = 'group_crm_settings'
+
+ belongs_to :group, -> { where(type: Group.sti_name) }, foreign_key: 'group_id'
+
+ validates :group, presence: true
+end
diff --git a/app/models/group_group_link.rb b/app/models/group_group_link.rb
index fdc54ba33ab..c4c3fc390e1 100644
--- a/app/models/group_group_link.rb
+++ b/app/models/group_group_link.rb
@@ -14,7 +14,7 @@ class GroupGroupLink < ApplicationRecord
presence: true
scope :non_guests, -> { where('group_access > ?', Gitlab::Access::GUEST) }
- scope :public_or_visible_to_user, ->(group, user) { where(shared_group: group, shared_with_group: Group.public_or_visible_to_user(user)) } # rubocop:disable Cop/GroupPublicOrVisibleToUser
+ scope :preload_shared_with_groups, -> { preload(:shared_with_group) }
def self.access_options
Gitlab::Access.options_with_owner
diff --git a/app/models/hooks/project_hook.rb b/app/models/hooks/project_hook.rb
index 16b95d2a2b9..9f45160d3a8 100644
--- a/app/models/hooks/project_hook.rb
+++ b/app/models/hooks/project_hook.rb
@@ -41,6 +41,11 @@ class ProjectHook < WebHook
super.merge(project: project)
end
+ override :parent
+ def parent
+ project
+ end
+
private
override :web_hooks_disable_failed?
diff --git a/app/models/hooks/service_hook.rb b/app/models/hooks/service_hook.rb
index 1a466b333a5..80e167b350b 100644
--- a/app/models/hooks/service_hook.rb
+++ b/app/models/hooks/service_hook.rb
@@ -2,6 +2,7 @@
class ServiceHook < WebHook
include Presentable
+ extend ::Gitlab::Utils::Override
belongs_to :integration, foreign_key: :service_id
validates :integration, presence: true
@@ -9,4 +10,7 @@ class ServiceHook < WebHook
def execute(data, hook_name = 'service_hook')
super(data, hook_name)
end
+
+ override :parent
+ delegate :parent, to: :integration
end
diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb
index e8a55abfc8f..3320c13e87b 100644
--- a/app/models/hooks/web_hook.rb
+++ b/app/models/hooks/web_hook.rb
@@ -122,6 +122,11 @@ class WebHook < ApplicationRecord
nil
end
+ # Returns the associated Project or Group for the WebHook if one exists.
+ # Overridden by inheriting classes.
+ def parent
+ end
+
# Custom attributes to be included in the worker context.
def application_context
{ related_class: type }
diff --git a/app/models/instance_configuration.rb b/app/models/instance_configuration.rb
index bbddc18103a..dc025e576ed 100644
--- a/app/models/instance_configuration.rb
+++ b/app/models/instance_configuration.rb
@@ -117,7 +117,8 @@ class InstanceConfiguration
group_export: application_setting_limit_per_minute(:group_export_limit),
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)
+ raw_blob: application_setting_limit_per_minute(:raw_blob_request_limit),
+ user_email_lookup: application_setting_limit_per_minute(:user_email_lookup_limit)
}
end
diff --git a/app/models/integration.rb b/app/models/integration.rb
index 29d96650a81..89b34932e20 100644
--- a/app/models/integration.rb
+++ b/app/models/integration.rb
@@ -92,6 +92,7 @@ class Integration < ApplicationRecord
scope :note_hooks, -> { where(note_events: true, active: true) }
scope :confidential_note_hooks, -> { where(confidential_note_events: true, active: true) }
scope :job_hooks, -> { where(job_events: true, active: true) }
+ scope :archive_trace_hooks, -> { where(archive_trace_events: true, active: true) }
scope :pipeline_hooks, -> { where(pipeline_events: true, active: true) }
scope :wiki_page_hooks, -> { where(wiki_page_events: true, active: true) }
scope :deployment_hooks, -> { where(deployment_events: true, active: true) }
diff --git a/app/models/integrations/base_chat_notification.rb b/app/models/integrations/base_chat_notification.rb
index ca72de47d30..d0d54a92021 100644
--- a/app/models/integrations/base_chat_notification.rb
+++ b/app/models/integrations/base_chat_notification.rb
@@ -204,7 +204,7 @@ module Integrations
when "wiki_page"
Integrations::ChatMessage::WikiPageMessage.new(data)
when "deployment"
- Integrations::ChatMessage::DeploymentMessage.new(data)
+ Integrations::ChatMessage::DeploymentMessage.new(data) if notify_for_ref?(data)
end
end
@@ -241,7 +241,11 @@ module Integrations
def notify_for_ref?(data)
return true if data[:object_kind] == 'tag_push'
- return true if data.dig(:object_attributes, :tag)
+ 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
+ return true if Gitlab::Git.tag_ref?(ref) # Skip protected branch check because it doesn't support tags
notify_for_branch?(data)
end
diff --git a/app/models/integrations/datadog.rb b/app/models/integrations/datadog.rb
index 72e0ca22ac2..b86f0aaa7ef 100644
--- a/app/models/integrations/datadog.rb
+++ b/app/models/integrations/datadog.rb
@@ -2,7 +2,6 @@
module Integrations
class Datadog < Integration
- include ActionView::Helpers::UrlHelper
include HasWebHook
extend Gitlab::Utils::Override
@@ -34,12 +33,21 @@ module Integrations
SUPPORTED_EVENTS
end
+ def supported_events
+ events = super
+
+ return events + ['archive_trace'] if Feature.enabled?(:datadog_integration_logs_collection, parent)
+
+ events
+ end
+
def self.default_test_event
'pipeline'
end
def configurable_events
[] # do not allow to opt out of required hooks
+ # archive_trace is opt-in but we handle it with a more detailed field below
end
def title
@@ -51,7 +59,11 @@ module Integrations
end
def help
- docs_link = link_to s_('DatadogIntegration|How do I set up this integration?'), Rails.application.routes.url_helpers.help_page_url('integration/datadog'), target: '_blank', rel: 'noopener noreferrer'
+ docs_link = ActionController::Base.helpers.link_to(
+ s_('DatadogIntegration|How do I set up this integration?'),
+ Rails.application.routes.url_helpers.help_page_url('integration/datadog'),
+ target: '_blank', rel: 'noopener noreferrer'
+ )
s_('DatadogIntegration|Send CI/CD pipeline information to Datadog to monitor for job failures and troubleshoot performance issues. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
@@ -60,7 +72,7 @@ module Integrations
end
def fields
- [
+ f = [
{
type: 'text',
name: 'datadog_site',
@@ -93,7 +105,21 @@ module Integrations
linkClose: '</a>'.html_safe
},
required: true
- },
+ }
+ ]
+
+ if Feature.enabled?(:datadog_integration_logs_collection, parent)
+ f.append({
+ type: 'checkbox',
+ name: 'archive_trace_events',
+ title: s_('Logs'),
+ checkbox_label: s_('Enable logs collection'),
+ help: s_('When enabled, job logs are collected by Datadog and displayed along with pipeline execution traces.'),
+ required: false
+ })
+ end
+
+ f += [
{
type: 'text',
name: 'datadog_service',
@@ -116,6 +142,8 @@ module Integrations
}
}
]
+
+ f
end
override :hook_url
@@ -136,8 +164,7 @@ module Integrations
object_kind = 'job' if object_kind == 'build'
return unless supported_events.include?(object_kind)
- data = data.with_retried_builds if data.respond_to?(:with_retried_builds)
-
+ data = hook_data(data, object_kind)
execute_web_hook!(data, "#{object_kind} hook")
end
@@ -158,5 +185,13 @@ module Integrations
# US3 needs to keep a prefix but other datacenters cannot have the listed "app" prefix
datadog_site.delete_prefix("app.")
end
+
+ def hook_data(data, object_kind)
+ if object_kind == 'pipeline' && data.respond_to?(:with_retried_builds)
+ return data.with_retried_builds
+ end
+
+ data
+ end
end
end
diff --git a/app/models/integrations/jira.rb b/app/models/integrations/jira.rb
index d46299de1be..816f5cbe177 100644
--- a/app/models/integrations/jira.rb
+++ b/app/models/integrations/jira.rb
@@ -303,11 +303,7 @@ module Integrations
private
def branch_name(commit)
- if Feature.enabled?(:jira_use_first_ref_by_oid, project, default_enabled: :yaml)
- commit.first_ref_by_oid(project.repository)
- else
- commit.ref_names(project.repository).first
- end
+ commit.first_ref_by_oid(project.repository)
end
def server_info
diff --git a/app/models/internal_id.rb b/app/models/internal_id.rb
index 10d24ab50b2..b502d5e354d 100644
--- a/app/models/internal_id.rb
+++ b/app/models/internal_id.rb
@@ -57,7 +57,7 @@ class InternalId < ApplicationRecord
self.internal_id_transactions_total.increment(
operation: operation,
usage: usage.to_s,
- in_transaction: ActiveRecord::Base.connection.transaction_open?.to_s # rubocop: disable Database/MultipleDatabases
+ in_transaction: InternalId.connection.transaction_open?.to_s
)
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 537e16e5cc3..4f2773f4147 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -48,7 +48,7 @@ class Issue < ApplicationRecord
belongs_to :duplicated_to, class_name: 'Issue'
belongs_to :closed_by, class_name: 'User'
belongs_to :iteration, foreign_key: 'sprint_id'
- belongs_to :work_item_type, class_name: 'WorkItem::Type', inverse_of: :work_items
+ belongs_to :work_item_type, class_name: 'WorkItems::Type', inverse_of: :work_items
belongs_to :moved_to, class_name: 'Issue'
has_one :moved_from, class_name: 'Issue', foreign_key: :moved_to_id
@@ -85,13 +85,16 @@ class Issue < ApplicationRecord
has_many :issue_customer_relations_contacts, class_name: 'CustomerRelations::IssueContact', inverse_of: :issue
has_many :customer_relations_contacts, through: :issue_customer_relations_contacts, source: :contact, class_name: 'CustomerRelations::Contact', inverse_of: :issues
+ alias_attribute :escalation_status, :incident_management_issuable_escalation_status
+
accepts_nested_attributes_for :issuable_severity, update_only: true
accepts_nested_attributes_for :sentry_issue
+ accepts_nested_attributes_for :incident_management_issuable_escalation_status, update_only: true
validates :project, presence: true
validates :issue_type, presence: true
- enum issue_type: WorkItem::Type.base_types
+ enum issue_type: WorkItems::Type.base_types
alias_method :issuing_parent, :project
@@ -230,8 +233,6 @@ class Issue < ApplicationRecord
end
def next_object_by_relative_position(ignoring: nil, order: :asc)
- return super unless Feature.enabled?(:optimized_issue_neighbor_queries, project, default_enabled: :yaml)
-
array_mapping_scope = -> (id_expression) do
relation = Issue.where(Issue.arel_table[:project_id].eq(id_expression))
@@ -600,6 +601,11 @@ class Issue < ApplicationRecord
author&.banned?
end
+ # Necessary until all issues are backfilled and we add a NOT NULL constraint on the DB
+ def work_item_type
+ super || WorkItems::Type.default_by_type(issue_type)
+ end
+
private
def spammable_attribute_changed?
diff --git a/app/models/key.rb b/app/models/key.rb
index a478434538c..933c939fdf5 100644
--- a/app/models/key.rb
+++ b/app/models/key.rb
@@ -22,7 +22,7 @@ class Key < ApplicationRecord
validates :key,
presence: true,
length: { maximum: 5000 },
- format: { with: /\A(ssh|ecdsa)-.*\Z/ }
+ format: { with: /\A(#{Gitlab::SSHPublicKey.supported_algorithms.join('|')})/ }
validates :fingerprint,
uniqueness: true,
diff --git a/app/models/label.rb b/app/models/label.rb
index a46d6bc5c0f..0ebbb5b9bd3 100644
--- a/app/models/label.rb
+++ b/app/models/label.rb
@@ -260,7 +260,7 @@ class Label < ApplicationRecord
attributes
end
- def present(attributes)
+ def present(attributes = {})
super(**attributes.merge(presenter_class: ::LabelPresenter))
end
diff --git a/app/models/loose_foreign_keys/deleted_record.rb b/app/models/loose_foreign_keys/deleted_record.rb
index 0fbdd2d8a5b..db82d5bbf29 100644
--- a/app/models/loose_foreign_keys/deleted_record.rb
+++ b/app/models/loose_foreign_keys/deleted_record.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class LooseForeignKeys::DeletedRecord < ApplicationRecord
+class LooseForeignKeys::DeletedRecord < Gitlab::Database::SharedModel
PARTITION_DURATION = 1.day
include PartitionedTable
diff --git a/app/models/loose_foreign_keys/modification_tracker.rb b/app/models/loose_foreign_keys/modification_tracker.rb
index 6eb04608cd9..72a596d2114 100644
--- a/app/models/loose_foreign_keys/modification_tracker.rb
+++ b/app/models/loose_foreign_keys/modification_tracker.rb
@@ -4,7 +4,7 @@ module LooseForeignKeys
class ModificationTracker
MAX_DELETES = 100_000
MAX_UPDATES = 50_000
- MAX_RUNTIME = 3.minutes
+ MAX_RUNTIME = 30.seconds # must be less than the scheduling frequency of the LooseForeignKeys::CleanupWorker cron worker
delegate :monotonic_time, to: :'Gitlab::Metrics::System'
diff --git a/app/models/member.rb b/app/models/member.rb
index 90fb281abf4..6c0503dca3f 100644
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -18,11 +18,15 @@ class Member < ApplicationRecord
AVATAR_SIZE = 40
ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT = 10
+ STATE_ACTIVE = 0
+ STATE_AWAITING = 1
+
attr_accessor :raw_invite_token
belongs_to :created_by, class_name: "User"
belongs_to :user
belongs_to :source, polymorphic: true # rubocop:disable Cop/PolymorphicAssociations
+ belongs_to :member_namespace, inverse_of: :namespace_members, foreign_key: 'member_namespace_id', class_name: 'Namespace'
has_one :member_task
delegate :name, :username, :email, :last_activity_on, to: :user, prefix: true
@@ -231,14 +235,7 @@ class Member < ApplicationRecord
end
def left_join_users
- users = User.arel_table
- members = Member.arel_table
-
- member_users = members.join(users, Arel::Nodes::OuterJoin)
- .on(members[:user_id].eq(users[:id]))
- .join_sources
-
- joins(member_users)
+ left_outer_joins(:user)
end
def access_for_user_ids(user_ids)
diff --git a/app/models/members/group_member.rb b/app/models/members/group_member.rb
index 1ad4cb6d368..a8a4fbedc41 100644
--- a/app/models/members/group_member.rb
+++ b/app/models/members/group_member.rb
@@ -18,7 +18,7 @@ class GroupMember < Member
default_scope { where(source_type: SOURCE_TYPE) } # rubocop:disable Cop/DefaultScope
- scope :of_groups, ->(groups) { where(source_id: groups.select(:id)) }
+ scope :of_groups, ->(groups) { where(source_id: groups&.select(:id)) }
scope :of_ldap_type, -> { where(ldap: true) }
scope :count_users_by_group_id, -> { group(:source_id).count }
scope :with_user, -> (user) { where(user: user) }
diff --git a/app/models/members/project_namespace_member.rb b/app/models/members/project_namespace_member.rb
new file mode 100644
index 00000000000..0e0c52ee3ca
--- /dev/null
+++ b/app/models/members/project_namespace_member.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+# TODO: https://gitlab.com/groups/gitlab-org/-/epics/7054
+# This file is a part of the Consolidate Group and Project member management epic,
+# and will be developed further as we progress through that epic.
+class ProjectNamespaceMember < ProjectMember # rubocop:disable Gitlab/NamespacedClass
+end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index f88aee38d67..cf36e72a565 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -1315,9 +1315,9 @@ class MergeRequest < ApplicationRecord
self.target_project.repository.branch_exists?(self.target_branch)
end
- def default_merge_commit_message(include_description: false)
+ def default_merge_commit_message(include_description: false, user: nil)
if self.target_project.merge_commit_template.present? && !include_description
- return ::Gitlab::MergeRequests::CommitMessageGenerator.new(merge_request: self).merge_message
+ return ::Gitlab::MergeRequests::CommitMessageGenerator.new(merge_request: self, current_user: user).merge_message
end
closes_issues_references = visible_closing_issues_for.map do |issue|
@@ -1339,9 +1339,9 @@ class MergeRequest < ApplicationRecord
message.join("\n\n")
end
- def default_squash_commit_message
+ def default_squash_commit_message(user: nil)
if self.target_project.squash_commit_template.present?
- return ::Gitlab::MergeRequests::CommitMessageGenerator.new(merge_request: self).squash_message
+ return ::Gitlab::MergeRequests::CommitMessageGenerator.new(merge_request: self, current_user: user).squash_message
end
title
@@ -1395,20 +1395,6 @@ class MergeRequest < ApplicationRecord
actual_head_pipeline.success?
end
- def environments_for(current_user, latest: false)
- return [] unless diff_head_commit
-
- envs = Environments::EnvironmentsByDeploymentsFinder.new(target_project, current_user,
- ref: target_branch, commit: diff_head_commit, with_tags: true, find_latest: latest).execute
-
- if source_project
- envs.concat Environments::EnvironmentsByDeploymentsFinder.new(source_project, current_user,
- ref: source_branch, commit: diff_head_commit, find_latest: latest).execute
- end
-
- envs.uniq
- end
-
##
# This method is for looking for active environments which created via pipelines for merge requests.
# Since deployments run on a merge request ref (e.g. `refs/merge-requests/:iid/head`),
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 4b1cf2fa217..0dc20e0016c 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -43,6 +43,8 @@ class Namespace < ApplicationRecord
has_many :projects, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
has_many :project_statistics
has_one :namespace_settings, inverse_of: :namespace, class_name: 'NamespaceSetting', autosave: true
+ has_one :namespace_route, foreign_key: :namespace_id, autosave: false, inverse_of: :namespace, class_name: 'Route'
+ has_many :namespace_members, foreign_key: :member_namespace_id, inverse_of: :member_namespace, class_name: 'Member'
has_many :runner_namespaces, inverse_of: :namespace, class_name: 'Ci::RunnerNamespace'
has_many :runners, through: :runner_namespaces, source: :runner, class_name: 'Ci::Runner'
@@ -299,6 +301,10 @@ class Namespace < ApplicationRecord
user_namespace?
end
+ def first_owner
+ owner
+ end
+
def find_fork_of(project)
return unless project.fork_network
diff --git a/app/models/namespace_setting.rb b/app/models/namespace_setting.rb
index 170b29e9e21..ef917c8a22e 100644
--- a/app/models/namespace_setting.rb
+++ b/app/models/namespace_setting.rb
@@ -3,6 +3,7 @@
class NamespaceSetting < ApplicationRecord
include CascadingNamespaceSettingAttribute
include Sanitizable
+ include ChronicDurationAttribute
cascading_attr :delayed_project_removal
@@ -12,17 +13,19 @@ class NamespaceSetting < ApplicationRecord
validate :allow_mfa_for_group
validate :allow_resource_access_token_creation_for_group
- before_save :set_prevent_sharing_groups_outside_hierarchy, if: -> { user_cap_enabled? }
- after_save :disable_project_sharing!, if: -> { user_cap_enabled? }
-
before_validation :normalize_default_branch_name
enum jobs_to_be_done: { basics: 0, move_repository: 1, code_storage: 2, exploring: 3, ci: 4, other: 5 }, _suffix: true
+ chronic_duration_attr :runner_token_expiration_interval_human_readable, :runner_token_expiration_interval
+ chronic_duration_attr :subgroup_runner_token_expiration_interval_human_readable, :subgroup_runner_token_expiration_interval
+ chronic_duration_attr :project_runner_token_expiration_interval_human_readable, :project_runner_token_expiration_interval
+
NAMESPACE_SETTINGS_PARAMS = [:default_branch_name, :delayed_project_removal,
:lock_delayed_project_removal, :resource_access_token_creation_allowed,
:prevent_sharing_groups_outside_hierarchy, :new_user_signups_cap,
- :setup_for_company, :jobs_to_be_done].freeze
+ :setup_for_company, :jobs_to_be_done, :runner_token_expiration_interval,
+ :subgroup_runner_token_expiration_interval, :project_runner_token_expiration_interval].freeze
self.primary_key = :namespace_id
@@ -59,18 +62,6 @@ class NamespaceSetting < ApplicationRecord
errors.add(:resource_access_token_creation_allowed, _('is not allowed since the group is not top-level group.'))
end
end
-
- def set_prevent_sharing_groups_outside_hierarchy
- self.prevent_sharing_groups_outside_hierarchy = true
- end
-
- def disable_project_sharing!
- namespace.update_attribute(:share_with_group_lock, true)
- end
-
- def user_cap_enabled?
- new_user_signups_cap.present? && namespace.root?
- end
end
NamespaceSetting.prepend_mod_with('NamespaceSetting')
diff --git a/app/models/namespaces/traversal/linear.rb b/app/models/namespaces/traversal/linear.rb
index 5a5f2a5d063..757a0e40eb3 100644
--- a/app/models/namespaces/traversal/linear.rb
+++ b/app/models/namespaces/traversal/linear.rb
@@ -57,6 +57,13 @@ module Namespaces
traversal_ids.present?
end
+ def use_traversal_ids_for_self_and_hierarchy?
+ return false unless use_traversal_ids?
+ return false unless Feature.enabled?(:use_traversal_ids_for_self_and_hierarchy, root_ancestor, default_enabled: :yaml)
+
+ traversal_ids.present?
+ end
+
def use_traversal_ids_for_ancestors?
return false unless use_traversal_ids?
return false unless Feature.enabled?(:use_traversal_ids_for_ancestors, root_ancestor, default_enabled: :yaml)
@@ -107,6 +114,12 @@ module Namespaces
self_and_descendants.where.not(id: id)
end
+ def self_and_hierarchy
+ return super unless use_traversal_ids_for_self_and_hierarchy?
+
+ self_and_descendants.or(ancestors)
+ end
+
def ancestors(hierarchy_order: nil)
return super unless use_traversal_ids_for_ancestors?
diff --git a/app/models/namespaces/traversal/linear_scopes.rb b/app/models/namespaces/traversal/linear_scopes.rb
index 0dfb7320461..9f0f49e729c 100644
--- a/app/models/namespaces/traversal/linear_scopes.rb
+++ b/app/models/namespaces/traversal/linear_scopes.rb
@@ -22,19 +22,28 @@ module Namespaces
unscoped.where(id: root_ids)
end
- def self_and_ancestors(include_self: true, hierarchy_order: nil)
+ def self_and_ancestors(include_self: true, upto: nil, hierarchy_order: nil)
return super unless use_traversal_ids_for_ancestor_scopes?
+ ancestors_cte, base_cte = ancestor_ctes
+ namespaces = Arel::Table.new(:namespaces)
+
records = unscoped
- .where(id: select('unnest(traversal_ids)'))
+ .with(base_cte.to_arel, ancestors_cte.to_arel)
+ .distinct
+ .from([ancestors_cte.table, namespaces])
+ .where(namespaces[:id].eq(ancestors_cte.table[:ancestor_id]))
.order_by_depth(hierarchy_order)
- .normal_select
- if include_self
- records
- else
- records.where.not(id: all.as_ids)
+ unless include_self
+ records = records.where(ancestors_cte.table[:base_id].not_eq(ancestors_cte.table[:ancestor_id]))
+ end
+
+ if upto
+ records = records.where.not(id: unscoped.where(id: upto).select('unnest(traversal_ids)'))
end
+
+ records
end
def self_and_ancestor_ids(include_self: true)
@@ -150,6 +159,20 @@ module Namespaces
records.where('namespaces.id <> base.id')
end
end
+
+ def ancestor_ctes
+ base_scope = all.select('namespaces.id', 'namespaces.traversal_ids')
+ base_cte = Gitlab::SQL::CTE.new(:base_ancestors_cte, base_scope)
+
+ # We have to alias id with 'AS' to avoid ambiguous column references by calling methods.
+ ancestors_scope = unscoped
+ .unscope(where: [:type])
+ .select('id as base_id', 'unnest(traversal_ids) as ancestor_id')
+ .from(base_cte.table)
+ ancestors_cte = Gitlab::SQL::CTE.new(:ancestors_cte, ancestors_scope)
+
+ [ancestors_cte, base_cte]
+ end
end
end
end
diff --git a/app/models/namespaces/traversal/recursive_scopes.rb b/app/models/namespaces/traversal/recursive_scopes.rb
index 925d9b8bb0c..583c53f8221 100644
--- a/app/models/namespaces/traversal/recursive_scopes.rb
+++ b/app/models/namespaces/traversal/recursive_scopes.rb
@@ -17,8 +17,8 @@ module Namespaces
.where(namespaces: { parent_id: nil })
end
- def self_and_ancestors(include_self: true, hierarchy_order: nil)
- records = Gitlab::ObjectHierarchy.new(all).base_and_ancestors(hierarchy_order: hierarchy_order)
+ def self_and_ancestors(include_self: true, upto: nil, hierarchy_order: nil)
+ records = Gitlab::ObjectHierarchy.new(all).base_and_ancestors(upto: upto, hierarchy_order: hierarchy_order)
if include_self
records
diff --git a/app/models/onboarding_progress.rb b/app/models/onboarding_progress.rb
index c12309d1852..58b7848f7e2 100644
--- a/app/models/onboarding_progress.rb
+++ b/app/models/onboarding_progress.rb
@@ -20,7 +20,14 @@ class OnboardingProgress < ApplicationRecord
:issue_created,
:issue_auto_closed,
:repository_imported,
- :repository_mirrored
+ :repository_mirrored,
+ :secure_dependency_scanning_run,
+ :secure_container_scanning_run,
+ :secure_dast_run,
+ :secure_secret_detection_run,
+ :secure_coverage_fuzzing_run,
+ :secure_api_fuzzing_run,
+ :secure_cluster_image_scanning_run
].freeze
scope :incomplete_actions, -> (actions) do
@@ -52,12 +59,19 @@ class OnboardingProgress < ApplicationRecord
where(namespace: namespace).any?
end
- def register(namespace, action)
- return unless root_namespace?(namespace) && ACTIONS.include?(action)
+ def register(namespace, actions)
+ actions = Array(actions)
+ return unless root_namespace?(namespace) && actions.difference(ACTIONS).empty?
- action_column = column_name(action)
- onboarding_progress = find_by(namespace: namespace, action_column => nil)
- onboarding_progress&.update!(action_column => Time.current)
+ onboarding_progress = find_by(namespace: namespace)
+ return unless onboarding_progress
+
+ now = Time.current
+ nil_actions = actions.select { |action| onboarding_progress[column_name(action)].nil? }
+ return if nil_actions.empty?
+
+ updates = nil_actions.inject({}) { |sum, action| sum.merge!({ column_name(action) => now }) }
+ onboarding_progress.update!(updates)
end
def completed?(namespace, action)
diff --git a/app/models/packages/debian/group_distribution.rb b/app/models/packages/debian/group_distribution.rb
index 50c1ec9f163..01938f4a2ec 100644
--- a/app/models/packages/debian/group_distribution.rb
+++ b/app/models/packages/debian/group_distribution.rb
@@ -12,8 +12,4 @@ class Packages::Debian::GroupDistribution < ApplicationRecord
.for_projects(group.all_projects.public_only)
.with_debian_codename(codename)
end
-
- def package_files
- ::Packages::PackageFile.for_package_ids(packages.select(:id))
- end
end
diff --git a/app/models/packages/debian/project_distribution.rb b/app/models/packages/debian/project_distribution.rb
index 5ac60d789b3..73777e3b9d8 100644
--- a/app/models/packages/debian/project_distribution.rb
+++ b/app/models/packages/debian/project_distribution.rb
@@ -9,5 +9,4 @@ class Packages::Debian::ProjectDistribution < ApplicationRecord
has_many :publications, class_name: 'Packages::Debian::Publication', inverse_of: :distribution, foreign_key: :distribution_id
has_many :packages, class_name: 'Packages::Package', through: :publications
- has_many :package_files, class_name: 'Packages::PackageFile', through: :packages
end
diff --git a/app/models/packages/package.rb b/app/models/packages/package.rb
index 962a1057a22..52dd0aba43b 100644
--- a/app/models/packages/package.rb
+++ b/app/models/packages/package.rb
@@ -5,9 +5,10 @@ class Packages::Package < ApplicationRecord
include Gitlab::SQL::Pattern
include UsageStatistics
include Gitlab::Utils::StrongMemoize
+ include Packages::Installable
DISPLAYABLE_STATUSES = [:default, :error].freeze
- INSTALLABLE_STATUSES = [:default].freeze
+ INSTALLABLE_STATUSES = [:default, :hidden].freeze
enum package_type: {
maven: 1,
@@ -31,6 +32,9 @@ class Packages::Package < ApplicationRecord
# package_files must be destroyed by ruby code in order to properly remove carrierwave uploads and update project statistics
has_many :package_files, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
+ # TODO: put the installable default scope on the :package_files association once the dependent: :destroy is removed
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/349191
+ has_many :installable_package_files, -> { installable }, class_name: 'Packages::PackageFile', inverse_of: :package
has_many :dependency_links, inverse_of: :package, class_name: 'Packages::DependencyLink'
has_many :tags, inverse_of: :package, class_name: 'Packages::Tag'
has_one :conan_metadatum, inverse_of: :package, class_name: 'Packages::Conan::Metadatum'
@@ -100,9 +104,7 @@ class Packages::Package < ApplicationRecord
scope :without_version_like, -> (version) { where.not(arel_table[:version].matches(version)) }
scope :with_package_type, ->(package_type) { where(package_type: package_type) }
scope :without_package_type, ->(package_type) { where.not(package_type: package_type) }
- scope :with_status, ->(status) { where(status: status) }
scope :displayable, -> { with_status(DISPLAYABLE_STATUSES) }
- scope :installable, -> { with_status(INSTALLABLE_STATUSES) }
scope :including_project_route, -> { includes(project: { namespace: :route }) }
scope :including_tags, -> { includes(:tags) }
scope :including_dependency_links, -> { includes(dependency_links: :dependency) }
@@ -131,7 +133,7 @@ class Packages::Package < ApplicationRecord
scope :without_nuget_temporary_name, -> { where.not(name: Packages::Nuget::TEMPORARY_PACKAGE_NAME) }
scope :has_version, -> { where.not(version: nil) }
- scope :preload_files, -> { preload(:package_files) }
+ scope :preload_files, -> { Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml) ? preload(:installable_package_files) : preload(:package_files) }
scope :preload_pipelines, -> { preload(pipelines: :user) }
scope :last_of_each_version, -> { where(id: all.select('MAX(id) AS id').group(:version)) }
scope :limit_recent, ->(limit) { order_created_desc.limit(limit) }
diff --git a/app/models/packages/package_file.rb b/app/models/packages/package_file.rb
index 87c9f56cc41..072ff4a3a5f 100644
--- a/app/models/packages/package_file.rb
+++ b/app/models/packages/package_file.rb
@@ -2,12 +2,18 @@
class Packages::PackageFile < ApplicationRecord
include UpdateProjectStatistics
include FileStoreMounter
+ include Packages::Installable
+ include Packages::Destructible
+
+ INSTALLABLE_STATUSES = [:default].freeze
delegate :project, :project_id, to: :package
delegate :conan_file_type, to: :conan_file_metadatum
delegate :file_type, :dsc?, :component, :architecture, :fields, to: :debian_file_metadatum, prefix: :debian
delegate :channel, :metadata, to: :helm_file_metadatum, prefix: :helm
+ enum status: { default: 0, pending_destruction: 1, processing: 2, error: 3 }
+
belongs_to :package
# used to move the linked file within object storage
@@ -48,9 +54,12 @@ class Packages::PackageFile < ApplicationRecord
end
scope :for_helm_with_channel, ->(project, channel) do
- joins(:package).merge(project.packages.helm.installable)
- .joins(:helm_file_metadatum)
- .where(packages_helm_file_metadata: { channel: channel })
+ result = joins(:package)
+ .merge(project.packages.helm.installable)
+ .joins(:helm_file_metadatum)
+ .where(packages_helm_file_metadata: { channel: channel })
+ result = result.installable if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml)
+ result
end
scope :with_conan_file_type, ->(file_type) do
@@ -94,14 +103,19 @@ class Packages::PackageFile < ApplicationRecord
skip_callback :commit, :after, :remove_previously_stored_file, if: :execute_move_in_object_storage?
after_commit :move_in_object_storage, if: :execute_move_in_object_storage?
- # Returns the most recent package files for *each* of the given packages.
+ # Returns the most recent installable package file for *each* of the given packages.
# The order is not guaranteed.
def self.most_recent_for(packages, extra_join: nil, extra_where: nil)
cte_name = :packages_cte
cte = Gitlab::SQL::CTE.new(cte_name, packages.select(:id))
- package_files = ::Packages::PackageFile.limit_recent(1)
- .where(arel_table[:package_id].eq(Arel.sql("#{cte_name}.id")))
+ package_files = if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml)
+ ::Packages::PackageFile.installable.limit_recent(1)
+ .where(arel_table[:package_id].eq(Arel.sql("#{cte_name}.id")))
+ else
+ ::Packages::PackageFile.limit_recent(1)
+ .where(arel_table[:package_id].eq(Arel.sql("#{cte_name}.id")))
+ end
package_files = package_files.joins(extra_join) if extra_join
package_files = package_files.where(extra_where) if extra_where
diff --git a/app/models/pages_domain.rb b/app/models/pages_domain.rb
index 0c5a155d48a..c21027455b1 100644
--- a/app/models/pages_domain.rb
+++ b/app/models/pages_domain.rb
@@ -46,9 +46,6 @@ class PagesDomain < ApplicationRecord
algorithm: 'aes-256-cbc'
after_initialize :set_verification_code
- after_create :update_daemon
- after_update :update_daemon, if: :saved_change_to_pages_config?
- after_destroy :update_daemon
scope :for_project, ->(project) { where(project: project) }
@@ -233,32 +230,6 @@ class PagesDomain < ApplicationRecord
self.verification_code = SecureRandom.hex(16)
end
- # rubocop: disable CodeReuse/ServiceClass
- def update_daemon
- return if usage_serverless?
- return unless pages_deployed?
-
- run_after_commit { PagesUpdateConfigurationWorker.perform_async(project_id) }
- end
- # rubocop: enable CodeReuse/ServiceClass
-
- def saved_change_to_pages_config?
- saved_change_to_project_id? ||
- saved_change_to_domain? ||
- saved_change_to_certificate? ||
- saved_change_to_key? ||
- became_enabled? ||
- became_disabled?
- end
-
- def became_enabled?
- enabled_until.present? && !enabled_until_before_last_save.present?
- end
-
- def became_disabled?
- !enabled_until.present? && enabled_until_before_last_save.present?
- end
-
def validate_matching_key
unless has_matching_key?
self.errors.add(:key, "doesn't match the certificate")
diff --git a/app/models/preloaders/environments/deployment_preloader.rb b/app/models/preloaders/environments/deployment_preloader.rb
new file mode 100644
index 00000000000..fcf892698bb
--- /dev/null
+++ b/app/models/preloaders/environments/deployment_preloader.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module Preloaders
+ module Environments
+ # This class is to batch-load deployments of multiple environments.
+ # The deployments to batch-load are fetched using UNION of N selects in a single query instead of default scoping with `IN (environment_id1, environment_id2 ...)`.
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/345672#note_761852224 for more details.
+ class DeploymentPreloader
+ attr_reader :environments
+
+ def initialize(environments)
+ @environments = environments
+ end
+
+ def execute_with_union(association_name, association_attributes)
+ load_deployment_association(association_name, association_attributes)
+ end
+
+ private
+
+ 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
+
+ deployments = Deployment
+ .from("(#{union_sql}) #{::Deployment.table_name}")
+ .preload(association_attributes)
+
+ deployments_by_environment_id = deployments.index_by(&:environment_id)
+
+ environments.each do |environment|
+ environment.association(association_name).target = deployments_by_environment_id[environment.id]
+ environment.association(association_name).loaded!
+ end
+ end
+ end
+ end
+end
diff --git a/app/models/project.rb b/app/models/project.rb
index a751e8adeb0..f2b3db684ae 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -37,6 +37,7 @@ class Project < ApplicationRecord
include EachBatch
include GitlabRoutingHelper
include BulkMemberAccessLoad
+ include RunnerTokenExpirationInterval
extend Gitlab::Cache::RequestCache
extend Gitlab::Utils::Override
@@ -340,6 +341,7 @@ class Project < ApplicationRecord
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 :environments
has_many :environments_for_dashboard, -> { from(with_rank.unfoldered.available, :environments).where('rank <= 3') }, class_name: 'Environment'
has_many :deployments
@@ -436,6 +438,7 @@ class Project < ApplicationRecord
prefix: :import, to: :import_state, allow_nil: true
delegate :squash_always?, :squash_never?, :squash_enabled_by_default?, :squash_readonly?, to: :project_setting
delegate :squash_option, :squash_option=, to: :project_setting
+ delegate :mr_default_target_self, :mr_default_target_self=, to: :project_setting
delegate :previous_default_branch, :previous_default_branch=, to: :project_setting
delegate :no_import?, to: :import_state, allow_nil: true
delegate :name, to: :owner, allow_nil: true, prefix: true
@@ -452,7 +455,8 @@ class Project < ApplicationRecord
delegate :job_token_scope_enabled, :job_token_scope_enabled=, to: :ci_cd_settings, prefix: :ci, allow_nil: true
delegate :keep_latest_artifact, :keep_latest_artifact=, to: :ci_cd_settings, allow_nil: true
delegate :restrict_user_defined_variables, :restrict_user_defined_variables=, to: :ci_cd_settings, allow_nil: true
- delegate :actual_limits, :actual_plan_name, to: :namespace, allow_nil: true
+ delegate :runner_token_expiration_interval, :runner_token_expiration_interval=, :runner_token_expiration_interval_human_readable, :runner_token_expiration_interval_human_readable=, to: :ci_cd_settings, allow_nil: true
+ delegate :actual_limits, :actual_plan_name, :actual_plan, to: :namespace, allow_nil: true
delegate :allow_merge_on_skipped_pipeline, :allow_merge_on_skipped_pipeline?,
:allow_merge_on_skipped_pipeline=, :has_confluence?, :has_shimo?,
to: :project_setting
@@ -983,7 +987,7 @@ class Project < ApplicationRecord
end
def context_commits_enabled?
- Feature.enabled?(:context_commits, default_enabled: true)
+ Feature.enabled?(:context_commits, self, default_enabled: :yaml)
end
# LFS and hashed repository storage are required for using Design Management.
@@ -1512,11 +1516,11 @@ class Project < ApplicationRecord
group || namespace.try(:owner)
end
- def default_owner
+ def first_owner
obj = owner
- if obj.respond_to?(:default_owner)
- obj.default_owner
+ if obj.respond_to?(:first_owner)
+ obj.first_owner
else
obj
end
@@ -1660,7 +1664,7 @@ class Project < ApplicationRecord
attrs
end
- def project_member(user)
+ def member(user)
if project_members.loaded?
project_members.find { |member| member.user_id == user.id }
else
@@ -1773,17 +1777,12 @@ class Project < ApplicationRecord
def all_runners
Ci::Runner.from_union([runners, group_runners, shared_runners])
- .allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/339937')
end
def all_available_runners
Ci::Runner.from_union([runners, group_runners, available_shared_runners])
- .allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/339937')
end
- # Once issue 339937 is fixed, please search for all mentioned of
- # https://gitlab.com/gitlab-org/gitlab/-/issues/339937,
- # and remove the allow_cross_joins_across_databases.
def active_runners
strong_memoize(:active_runners) do
all_available_runners.active
@@ -1791,9 +1790,7 @@ class Project < ApplicationRecord
end
def any_online_runners?(&block)
- ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/339937') do
- online_runners_with_tags.any?(&block)
- end
+ online_runners_with_tags.any?(&block)
end
def valid_runners_token?(token)
@@ -2702,6 +2699,10 @@ class Project < ApplicationRecord
ci_cd_settings.keep_latest_artifact?
end
+ def runner_token_expiration_interval
+ ci_cd_settings&.runner_token_expiration_interval
+ end
+
def group_runners_enabled?
return false unless ci_cd_settings
@@ -2733,6 +2734,17 @@ class Project < ApplicationRecord
end
end
+ def enforced_runner_token_expiration_interval
+ all_parent_groups = Gitlab::ObjectHierarchy.new(Group.where(id: group)).base_and_ancestors
+ all_group_settings = NamespaceSetting.where(namespace_id: all_parent_groups)
+ group_interval = all_group_settings.where.not(project_runner_token_expiration_interval: nil).minimum(:project_runner_token_expiration_interval)&.seconds
+
+ [
+ Gitlab::CurrentSettings.project_runner_token_expiration_interval&.seconds,
+ group_interval
+ ].compact.min
+ end
+
private
# overridden in EE
diff --git a/app/models/project_ci_cd_setting.rb b/app/models/project_ci_cd_setting.rb
index c0c2ea42d46..28a493cae33 100644
--- a/app/models/project_ci_cd_setting.rb
+++ b/app/models/project_ci_cd_setting.rb
@@ -1,9 +1,11 @@
# frozen_string_literal: true
class ProjectCiCdSetting < ApplicationRecord
+ include ChronicDurationAttribute
+
belongs_to :project, inverse_of: :ci_cd_settings
- DEFAULT_GIT_DEPTH = 50
+ DEFAULT_GIT_DEPTH = 20
before_create :set_default_git_depth
@@ -17,6 +19,8 @@ class ProjectCiCdSetting < ApplicationRecord
default_value_for :forward_deployment_enabled, true
+ chronic_duration_attr :runner_token_expiration_interval_human_readable, :runner_token_expiration_interval
+
def forward_deployment_enabled?
super && ::Feature.enabled?(:forward_deployment_enabled, project, default_enabled: true)
end
diff --git a/app/models/project_setting.rb b/app/models/project_setting.rb
index fc834286876..4e37174e604 100644
--- a/app/models/project_setting.rb
+++ b/app/models/project_setting.rb
@@ -22,6 +22,16 @@ class ProjectSetting < ApplicationRecord
def squash_readonly?
%w[always never].include?(squash_option)
end
+
+ validate :validates_mr_default_target_self
+
+ private
+
+ def validates_mr_default_target_self
+ if mr_default_target_self_changed? && !project.forked?
+ errors.add :mr_default_target_self, _('This setting is allowed for forked projects only')
+ end
+ end
end
ProjectSetting.prepend_mod
diff --git a/app/models/protectable_dropdown.rb b/app/models/protectable_dropdown.rb
index e1336be9528..855876f2ec9 100644
--- a/app/models/protectable_dropdown.rb
+++ b/app/models/protectable_dropdown.rb
@@ -2,6 +2,10 @@
class ProtectableDropdown
REF_TYPES = %i[branches tags].freeze
+ REF_NAME_METHODS = {
+ branches: :branch_names,
+ tags: :tag_names
+ }.freeze
def initialize(project, ref_type)
raise ArgumentError, "invalid ref type `#{ref_type}`" unless ref_type.in?(REF_TYPES)
@@ -23,12 +27,12 @@ class ProtectableDropdown
private
- def refs
- @project.repository.public_send(@ref_type) # rubocop:disable GitlabSecurity/PublicSend
+ def ref_names
+ @project.repository.public_send(ref_name_method) # rubocop:disable GitlabSecurity/PublicSend
end
- def ref_names
- refs.map(&:name)
+ def ref_name_method
+ REF_NAME_METHODS[@ref_type]
end
def protections
diff --git a/app/models/ref_matcher.rb b/app/models/ref_matcher.rb
index fa7d2c0f06c..46f4ce0ecc7 100644
--- a/app/models/ref_matcher.rb
+++ b/app/models/ref_matcher.rb
@@ -5,10 +5,10 @@ class RefMatcher
@ref_name_or_pattern = ref_name_or_pattern
end
- # Returns all branches/tags (among the given list of refs [`Gitlab::Git::Branch`])
+ # Returns all branches/tags (among the given list of refs [`Gitlab::Git::Branch`] or their names [`String`])
# that match the current protected ref.
def matching(refs)
- refs.select { |ref| matches?(ref.name) }
+ refs.select { |ref| ref.is_a?(String) ? matches?(ref) : matches?(ref.name) }
end
# Checks if the protected ref matches the given ref name.
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 645cc9773bd..be8e530c650 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -191,7 +191,7 @@ class Repository
end
def find_tag(name)
- if @tags.blank? && Feature.enabled?(:find_tag_via_gitaly, project, default_enabled: :yaml)
+ if @tags.blank?
raw_repository.find_tag(name)
else
tags.find { |tag| tag.name == name }
diff --git a/app/models/route.rb b/app/models/route.rb
index fcc8459d6e5..12b2d5c5bb2 100644
--- a/app/models/route.rb
+++ b/app/models/route.rb
@@ -5,6 +5,7 @@ class Route < ApplicationRecord
include Gitlab::SQL::Pattern
belongs_to :source, polymorphic: true, inverse_of: :route # rubocop:disable Cop/PolymorphicAssociations
+ belongs_to :namespace, inverse_of: :namespace_route
validates :source, presence: true
validates :path,
diff --git a/app/models/user.rb b/app/models/user.rb
index a39da30220a..a587723053f 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -48,7 +48,7 @@ class User < ApplicationRecord
add_authentication_token_field :incoming_email_token, token_generator: -> { SecureRandom.hex.to_i(16).to_s(36) }
add_authentication_token_field :feed_token
- add_authentication_token_field :static_object_token
+ add_authentication_token_field :static_object_token, encrypted: :optional
default_value_for :admin, false
default_value_for(:external) { Gitlab::CurrentSettings.user_default_external }
@@ -81,6 +81,7 @@ class User < ApplicationRecord
# This module adds async behaviour to Devise emails
# and should be added after Devise modules are initialized.
include AsyncDeviseEmail
+ include ForcedEmailConfirmation
MINIMUM_INACTIVE_DAYS = 90
@@ -250,7 +251,7 @@ class User < ApplicationRecord
validate :notification_email_verified, if: :notification_email_changed?
validate :public_email_verified, if: :public_email_changed?
validate :commit_email_verified, if: :commit_email_changed?
- validate :signup_email_valid?, on: :create, if: ->(user) { !user.created_by_id }
+ validate :email_allowed_by_restrictions?, if: ->(user) { user.new_record? ? !user.created_by_id : user.email_changed? }
validate :check_username_format, if: :username_changed?
validates :theme_id, allow_nil: true, inclusion: { in: Gitlab::Themes.valid_ids,
@@ -330,6 +331,7 @@ class User < ApplicationRecord
delegate :pronouns, :pronouns=, to: :user_detail, allow_nil: true
delegate :pronunciation, :pronunciation=, to: :user_detail, allow_nil: true
delegate :registration_objective, :registration_objective=, to: :user_detail, allow_nil: true
+ delegate :requires_credit_card_verification, :requires_credit_card_verification=, to: :user_detail, allow_nil: true
accepts_nested_attributes_for :user_preference, update_only: true
accepts_nested_attributes_for :user_detail, update_only: true
@@ -465,7 +467,7 @@ class User < ApplicationRecord
scope :dormant, -> { with_state(:active).human_or_service_user.where('last_activity_on <= ?', MINIMUM_INACTIVE_DAYS.day.ago.to_date) }
scope :with_no_activity, -> { with_state(:active).human_or_service_user.where(last_activity_on: nil) }
scope :by_provider_and_extern_uid, ->(provider, extern_uid) { joins(:identities).merge(Identity.with_extern_uid(provider, extern_uid)) }
- scope :get_ids_by_username, -> (username) { where(username: username).pluck(:id) }
+ scope :by_ids_or_usernames, -> (ids, usernames) { where(username: usernames).or(where(id: ids)) }
strip_attributes! :name
@@ -536,27 +538,15 @@ class User < ApplicationRecord
end
def self.with_two_factor
- with_u2f_registrations = <<-SQL
- EXISTS (
- SELECT *
- FROM u2f_registrations AS u2f
- WHERE u2f.user_id = users.id
- ) OR users.otp_required_for_login = ?
- OR
- EXISTS (
- SELECT *
- FROM webauthn_registrations AS webauthn
- WHERE webauthn.user_id = users.id
- )
- SQL
-
- where(with_u2f_registrations, true)
+ where(otp_required_for_login: true)
+ .or(where_exists(U2fRegistration.where(U2fRegistration.arel_table[:user_id].eq(arel_table[:id]))))
+ .or(where_exists(WebauthnRegistration.where(WebauthnRegistration.arel_table[:user_id].eq(arel_table[:id]))))
end
def self.without_two_factor
- joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id
- LEFT OUTER JOIN webauthn_registrations AS webauthn ON webauthn.user_id = users.id")
- .where("u2f.id IS NULL AND webauthn.id IS NULL AND users.otp_required_for_login = ?", false)
+ where
+ .missing(:u2f_registrations, :webauthn_registrations)
+ .where(otp_required_for_login: false)
end
#
@@ -720,13 +710,19 @@ class User < ApplicationRecord
.take(1) # at most 1 record as there is a unique constraint
where(
- fuzzy_arel_match(:name, query)
- .or(fuzzy_arel_match(:username, query))
+ fuzzy_arel_match(:name, query, use_minimum_char_limit: user_search_minimum_char_limit)
+ .or(fuzzy_arel_match(:username, query, use_minimum_char_limit: user_search_minimum_char_limit))
.or(arel_table[:email].eq(query))
.or(arel_table[:id].eq(matched_by_email_user_id))
)
end
+ # This method is overridden in JiHu.
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/348509
+ def user_search_minimum_char_limit
+ true
+ end
+
def by_login(login)
return unless login
@@ -841,6 +837,10 @@ class User < ApplicationRecord
def single_user
User.non_internal.first if single_user?
end
+
+ def get_ids_by_ids_or_usernames(ids, usernames)
+ by_ids_or_usernames(ids, usernames).pluck(:id)
+ end
end
#
@@ -1337,7 +1337,7 @@ class User < ApplicationRecord
def can_leave_project?(project)
project.namespace != namespace &&
- project.project_member(self)
+ project.member(self)
end
def full_website_url
@@ -1536,8 +1536,8 @@ class User < ApplicationRecord
end
end
- def manageable_namespaces
- @manageable_namespaces ||= [namespace] + manageable_groups
+ def forkable_namespaces
+ @forkable_namespaces ||= [namespace] + manageable_groups(include_groups_with_developer_maintainer_access: true)
end
def manageable_groups(include_groups_with_developer_maintainer_access: false)
@@ -1606,23 +1606,32 @@ class User < ApplicationRecord
def ci_owned_runners
@ci_owned_runners ||= begin
- project_runners = Ci::RunnerProject
- .where(project: authorized_projects(Gitlab::Access::MAINTAINER))
- .joins(:runner)
- .select('ci_runners.*')
-
- group_runners = Ci::RunnerNamespace
- .where(namespace_id: owned_groups.self_and_descendant_ids)
- .joins(:runner)
- .select('ci_runners.*')
-
- Ci::Runner.from_union([project_runners, group_runners]).allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336436')
+ if ci_owned_runners_cross_joins_fix_enabled?
+ Ci::Runner
+ .from_union([ci_owned_project_runners_from_project_members,
+ ci_owned_project_runners_from_group_members,
+ ci_owned_group_runners])
+ else
+ Ci::Runner
+ .from_union([ci_legacy_owned_project_runners, ci_legacy_owned_group_runners])
+ .allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336436')
+ end
end
end
def owns_runner?(runner)
- ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336436') do
+ if ci_owned_runners_cross_joins_fix_enabled?
ci_owned_runners.exists?(runner.id)
+ else
+ ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336436') do
+ ci_owned_runners.exists?(runner.id)
+ end
+ end
+ end
+
+ def ci_owned_runners_cross_joins_fix_enabled?
+ strong_memoize(:ci_owned_runners_cross_joins_fix_enabled) do
+ Feature.enabled?(:ci_owned_runners_cross_joins_fix, self, default_enabled: :yaml)
end
end
@@ -1902,6 +1911,10 @@ class User < ApplicationRecord
true
end
+ def can_log_in_with_non_expired_password?
+ can?(:log_in) && !password_expired_if_applicable?
+ end
+
def can_be_deactivated?
active? && no_recent_activity? && !internal?
end
@@ -1980,18 +1993,22 @@ class User < ApplicationRecord
ci_job_token_scope.present?
end
- # override from Devise::Confirmable
+ # 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)
+ 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?
- email_to_confirm.confirm(*args)
+ 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
@@ -2142,14 +2159,14 @@ class User < ApplicationRecord
end
end
- def signup_email_valid?
+ def email_allowed_by_restrictions?
error = validate_admin_signup_restrictions(email)
errors.add(:email, error) if error
end
def signup_email_invalid_message
- _('is not allowed for sign-up.')
+ self.new_record? ? _('is not allowed for sign-up.') : _('is not allowed.')
end
def check_username_format
@@ -2192,6 +2209,50 @@ class User < ApplicationRecord
::Gitlab::Auth::Ldap::Access.allowed?(self)
end
+
+ def ci_legacy_owned_project_runners
+ Ci::RunnerProject
+ .select('ci_runners.*')
+ .joins(:runner)
+ .where(project: authorized_projects(Gitlab::Access::MAINTAINER))
+ end
+
+ def ci_legacy_owned_group_runners
+ Ci::RunnerNamespace
+ .select('ci_runners.*')
+ .joins(:runner)
+ .where(namespace_id: owned_groups.self_and_descendant_ids)
+ end
+
+ def ci_owned_project_runners_from_project_members
+ Ci::RunnerProject
+ .select('ci_runners.*')
+ .joins(:runner)
+ .where(project: project_members.where('access_level >= ?', Gitlab::Access::MAINTAINER).pluck(:source_id))
+ end
+
+ def ci_owned_project_runners_from_group_members
+ Ci::RunnerProject
+ .select('ci_runners.*')
+ .joins(:runner)
+ .joins('JOIN ci_project_mirrors ON ci_project_mirrors.project_id = ci_runner_projects.project_id')
+ .joins('JOIN ci_namespace_mirrors ON ci_namespace_mirrors.namespace_id = ci_project_mirrors.namespace_id')
+ .merge(ci_namespace_mirrors_for_group_members(Gitlab::Access::MAINTAINER))
+ end
+
+ def ci_owned_group_runners
+ Ci::RunnerNamespace
+ .select('ci_runners.*')
+ .joins(:runner)
+ .joins('JOIN ci_namespace_mirrors ON ci_namespace_mirrors.namespace_id = ci_runner_namespaces.namespace_id')
+ .merge(ci_namespace_mirrors_for_group_members(Gitlab::Access::OWNER))
+ end
+
+ def ci_namespace_mirrors_for_group_members(level)
+ Ci::NamespaceMirror.contains_any_of_namespaces(
+ group_members.where('access_level >= ?', level).pluck(:source_id)
+ )
+ end
end
User.prepend_mod_with('User')
diff --git a/app/models/users/callout.rb b/app/models/users/callout.rb
index 9ce0beed3b3..8394192c5ae 100644
--- a/app/models/users/callout.rb
+++ b/app/models/users/callout.rb
@@ -40,7 +40,8 @@ module Users
profile_personal_access_token_expiry: 37, # EE-only
terraform_notification_dismissed: 38,
security_newsletter_callout: 39,
- verification_reminder: 40 # EE-only
+ verification_reminder: 40, # EE-only
+ ci_deprecation_warning_for_types_keyword: 41
}
validates :feature_name,
diff --git a/app/models/work_item.rb b/app/models/work_item.rb
new file mode 100644
index 00000000000..02f52f04c85
--- /dev/null
+++ b/app/models/work_item.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+
+class WorkItem < Issue
+ self.table_name = 'issues'
+ self.inheritance_column = :_type_disabled
+end
diff --git a/app/models/work_item/type.rb b/app/models/work_item/type.rb
deleted file mode 100644
index 3acb9c0011c..00000000000
--- a/app/models/work_item/type.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-# frozen_string_literal: true
-
-# Note: initial thinking behind `icon_name` is for it to do triple duty:
-# 1. one of our svg icon names, such as `external-link` or a new one `bug`
-# 2. if it's an absolute url, then url to a user uploaded icon/image
-# 3. an emoji, with the format of `:smile:`
-class WorkItem::Type < ApplicationRecord
- self.table_name = 'work_item_types'
-
- include CacheMarkdownField
-
- # Base types need to exist on the DB on app startup
- # This constant is used by the DB seeder
- BASE_TYPES = {
- issue: { name: 'Issue', icon_name: 'issue-type-issue', enum_value: 0 },
- incident: { name: 'Incident', icon_name: 'issue-type-incident', enum_value: 1 },
- test_case: { name: 'Test Case', icon_name: 'issue-type-test-case', enum_value: 2 }, ## EE-only
- requirement: { name: 'Requirement', icon_name: 'issue-type-requirements', enum_value: 3 }, ## EE-only
- task: { name: 'Task', icon_name: 'issue-type-task', enum_value: 4 }
- }.freeze
-
- cache_markdown_field :description, pipeline: :single_line
-
- enum base_type: BASE_TYPES.transform_values { |value| value[:enum_value] }
-
- belongs_to :namespace, optional: true
- has_many :work_items, class_name: 'Issue', foreign_key: :work_item_type_id, inverse_of: :work_item_type
-
- before_validation :strip_whitespace
-
- # TODO: review validation rules
- # https://gitlab.com/gitlab-org/gitlab/-/issues/336919
- validates :name, presence: true
- validates :name, uniqueness: { case_sensitive: false, scope: [:namespace_id] }
- validates :name, length: { maximum: 255 }
- validates :icon_name, length: { maximum: 255 }
-
- def self.default_by_type(type)
- find_by(namespace_id: nil, base_type: type)
- end
-
- def self.default_issue_type
- default_by_type(:issue)
- end
-
- def self.allowed_types_for_issues
- base_types.keys.excluding('task')
- end
-
- private
-
- def strip_whitespace
- name&.strip!
- end
-end
diff --git a/app/models/work_items/type.rb b/app/models/work_items/type.rb
new file mode 100644
index 00000000000..494c4f5abe4
--- /dev/null
+++ b/app/models/work_items/type.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+# Note: initial thinking behind `icon_name` is for it to do triple duty:
+# 1. one of our svg icon names, such as `external-link` or a new one `bug`
+# 2. if it's an absolute url, then url to a user uploaded icon/image
+# 3. an emoji, with the format of `:smile:`
+module WorkItems
+ class Type < ApplicationRecord
+ self.table_name = 'work_item_types'
+
+ include CacheMarkdownField
+
+ # Base types need to exist on the DB on app startup
+ # This constant is used by the DB seeder
+ BASE_TYPES = {
+ issue: { name: 'Issue', icon_name: 'issue-type-issue', enum_value: 0 },
+ incident: { name: 'Incident', icon_name: 'issue-type-incident', enum_value: 1 },
+ test_case: { name: 'Test Case', icon_name: 'issue-type-test-case', enum_value: 2 }, ## EE-only
+ requirement: { name: 'Requirement', icon_name: 'issue-type-requirements', enum_value: 3 }, ## EE-only
+ task: { name: 'Task', icon_name: 'issue-type-task', enum_value: 4 }
+ }.freeze
+
+ cache_markdown_field :description, pipeline: :single_line
+
+ enum base_type: BASE_TYPES.transform_values { |value| value[:enum_value] }
+
+ belongs_to :namespace, optional: true
+ has_many :work_items, class_name: 'Issue', foreign_key: :work_item_type_id, inverse_of: :work_item_type
+
+ before_validation :strip_whitespace
+
+ # TODO: review validation rules
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/336919
+ validates :name, presence: true
+ validates :name, uniqueness: { case_sensitive: false, scope: [:namespace_id] }
+ validates :name, length: { maximum: 255 }
+ validates :icon_name, length: { maximum: 255 }
+
+ scope :default, -> { where(namespace: nil) }
+ scope :order_by_name_asc, -> { order('LOWER(name)') }
+
+ def self.default_by_type(type)
+ find_by(namespace_id: nil, base_type: type)
+ end
+
+ def self.default_issue_type
+ default_by_type(:issue)
+ end
+
+ def self.allowed_types_for_issues
+ base_types.keys.excluding('task')
+ end
+
+ def default?
+ namespace.blank?
+ end
+
+ private
+
+ def strip_whitespace
+ name&.strip!
+ end
+ end
+end
diff --git a/app/policies/global_policy.rb b/app/policies/global_policy.rb
index c3b4b163cb4..2a2ddf29899 100644
--- a/app/policies/global_policy.rb
+++ b/app/policies/global_policy.rb
@@ -9,7 +9,7 @@ class GlobalPolicy < BasePolicy
with_options scope: :user, score: 0
condition(:access_locked) { @user&.access_locked? }
- condition(:can_create_fork, scope: :user) { @user && @user.manageable_namespaces.any? { |namespace| @user.can?(:create_projects, namespace) } }
+ condition(:can_create_fork, scope: :user) { @user && @user.forkable_namespaces.any? { |namespace| @user.can?(:create_projects, namespace) } }
condition(:required_terms_not_accepted, scope: :user, score: 0) do
@user&.required_terms_not_accepted?
diff --git a/app/policies/group_member_policy.rb b/app/policies/group_member_policy.rb
index f7a7286aba7..a394b63fc8e 100644
--- a/app/policies/group_member_policy.rb
+++ b/app/policies/group_member_policy.rb
@@ -5,6 +5,7 @@ class GroupMemberPolicy < BasePolicy
with_scope :subject
condition(:last_owner) { @subject.group.member_last_owner?(@subject) || @subject.group.member_last_blocked_owner?(@subject) }
+ condition(:project_bot) { @subject.user&.project_bot? && @subject.group.member?(@subject.user) }
desc "Membership is users' own"
with_score 0
@@ -20,11 +21,13 @@ class GroupMemberPolicy < BasePolicy
prevent :destroy_group_member
end
- rule { can?(:admin_group_member) }.policy do
+ rule { ~project_bot & can?(:admin_group_member) }.policy do
enable :update_group_member
enable :destroy_group_member
end
+ rule { project_bot & can?(:admin_group_member) }.enable :destroy_project_bot_member
+
rule { is_target_user }.policy do
enable :destroy_group_member
end
diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb
index 5c4990ffd9b..fee47fe0ae9 100644
--- a/app/policies/group_policy.rb
+++ b/app/policies/group_policy.rb
@@ -23,6 +23,9 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
condition(:parent_share_with_group_locked, scope: :subject) { @subject.parent&.share_with_group_lock? }
condition(:can_change_parent_share_with_group_lock) { can?(:change_share_with_group_lock, @subject.parent) }
+ desc "User is a project bot"
+ condition(:project_bot) { user.project_bot? && access_level >= GroupMember::GUEST }
+
condition(:has_projects) do
group_projects_for(user: @user, group: @subject).any?
end
@@ -75,7 +78,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
with_scope :subject
condition(:has_project_with_service_desk_enabled) { @subject.has_project_with_service_desk_enabled? }
- condition(:crm_enabled, score: 0, scope: :subject) { Feature.enabled?(:customer_relations, @subject) }
+ 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
@@ -120,8 +123,6 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
enable :read_group_member
enable :read_custom_emoji
enable :read_counts
- enable :read_crm_organization
- enable :read_crm_contact
end
rule { ~public_group & ~has_access }.prevent :read_counts
@@ -156,13 +157,14 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
enable :read_prometheus
enable :read_package
enable :read_package_settings
+ enable :read_crm_organization
+ enable :read_crm_contact
end
rule { maintainer }.policy do
enable :destroy_package
enable :create_projects
enable :admin_pipeline
- enable :admin_group_runners
enable :admin_build
enable :read_cluster
enable :add_cluster
@@ -180,6 +182,10 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
enable :admin_group_member
enable :change_visibility_level
+ enable :read_group_runners
+ enable :admin_group_runners
+ enable :register_group_runners
+
enable :set_note_created_at
enable :set_emails_disabled
enable :change_prevent_sharing_groups_outside_hierarchy
@@ -205,10 +211,6 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
enable :read_nested_project_resources
end
- rule { can?(:admin_group_runners) }.policy do
- enable :register_group_runners
- end
-
rule { owner }.enable :create_subgroup
rule { maintainer & maintainer_can_create_group }.enable :create_subgroup
@@ -250,6 +252,8 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
enable :admin_dependency_proxy
end
+ rule { project_bot }.enable :project_bot_access
+
rule { can?(:admin_group) & resource_access_token_feature_available }.policy do
enable :read_resource_access_tokens
enable :destroy_resource_access_tokens
@@ -260,6 +264,10 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
enable :create_resource_access_tokens
end
+ rule { can?(:project_bot_access) }.policy do
+ prevent :create_resource_access_tokens
+ end
+
rule { support_bot & has_project_with_service_desk_enabled }.policy do
enable :read_label
end
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index b3aa49a00ae..55f43cd9f7b 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -258,6 +258,11 @@ class ProjectPolicy < BasePolicy
rule { can?(:reporter_access) & can?(:create_issue) }.enable :create_incident
+ rule { can?(:guest_access) & can?(:create_issue) }.policy do
+ enable :create_task
+ enable :create_work_item
+ end
+
# 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
@@ -399,6 +404,7 @@ class ProjectPolicy < BasePolicy
enable :destroy_feature_flag
enable :admin_feature_flag
enable :admin_feature_flags_user_lists
+ enable :update_escalation_status
end
rule { can?(:developer_access) & user_confirmed? }.policy do
diff --git a/app/policies/work_items/type_policy.rb b/app/policies/work_items/type_policy.rb
new file mode 100644
index 00000000000..c9b3321146a
--- /dev/null
+++ b/app/policies/work_items/type_policy.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module WorkItems
+ class TypePolicy < BasePolicy
+ condition(:is_default_type) { @subject.default? }
+
+ rule { is_default_type }.enable :read_work_item_type
+ end
+end
diff --git a/app/presenters/blob_presenter.rb b/app/presenters/blob_presenter.rb
index 3bd92ebc942..2577fcaf303 100644
--- a/app/presenters/blob_presenter.rb
+++ b/app/presenters/blob_presenter.rb
@@ -63,6 +63,22 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
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 find_file_path
+ url_helpers.project_find_file_path(project, ref_qualified_path)
+ end
+
+ def blame_path
+ url_helpers.project_blame_path(project, ref_qualified_path)
+ end
+
+ def history_path
+ url_helpers.project_commits_path(project, ref_qualified_path)
+ end
+
+ def permalink_path
+ url_helpers.project_blob_path(project, File.join(project.repository.commit.sha, blob.path))
+ end
+
# Will be overridden in EE
def code_owners
[]
@@ -86,6 +102,10 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
user_access(project).can_push_to_branch?(blob.commit_id)
end
+ def archived?
+ project.archived
+ end
+
def ide_edit_path
super(project, blob.commit_id, blob.path)
end
diff --git a/app/presenters/ci/runner_presenter.rb b/app/presenters/ci/runner_presenter.rb
index ad889d444f8..ffd826fab64 100644
--- a/app/presenters/ci/runner_presenter.rb
+++ b/app/presenters/ci/runner_presenter.rb
@@ -11,5 +11,9 @@ module Ci
delegator_override :locked
alias_method :locked, :locked?
+
+ def executor_name
+ Ci::Runner::EXECUTOR_TYPE_TO_NAMES[executor_type&.to_sym]
+ end
end
end
diff --git a/app/presenters/label_presenter.rb b/app/presenters/label_presenter.rb
index fafade2828f..8d604f9a0f6 100644
--- a/app/presenters/label_presenter.rb
+++ b/app/presenters/label_presenter.rb
@@ -2,7 +2,7 @@
class LabelPresenter < Gitlab::View::Presenter::Delegated
presents ::Label, as: :label
- delegate :name, :full_name, to: :label_subject, prefix: :subject
+ delegate :name, :full_name, to: :label_subject, prefix: :subject, allow_nil: true
delegator_override :subject # TODO: Fix `Gitlab::View::Presenter::Delegated#subject` not to override `Label#subject`.
@@ -10,6 +10,7 @@ class LabelPresenter < Gitlab::View::Presenter::Delegated
case label
when GroupLabel then edit_group_label_path(label.group, label)
when ProjectLabel then edit_project_label_path(label.project, label)
+ else edit_admin_label_path(label)
end
end
@@ -17,6 +18,7 @@ class LabelPresenter < Gitlab::View::Presenter::Delegated
case label
when GroupLabel then group_label_path(label.group, label)
when ProjectLabel then project_label_path(label.project, label)
+ else admin_label_path(label)
end
end
@@ -43,7 +45,7 @@ class LabelPresenter < Gitlab::View::Presenter::Delegated
end
def label_subject
- @label_subject ||= label.subject
+ @label_subject ||= label.subject if label.respond_to?(:subject)
end
private
diff --git a/app/presenters/packages/conan/package_presenter.rb b/app/presenters/packages/conan/package_presenter.rb
index df770777ad1..57636922676 100644
--- a/app/presenters/packages/conan/package_presenter.rb
+++ b/app/presenters/packages/conan/package_presenter.rb
@@ -80,7 +80,13 @@ module Packages
def package_files
return unless @package
- @package_files ||= @package.package_files.preload_conan_file_metadata
+ strong_memoize(:package_files) do
+ if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml)
+ @package.installable_package_files.preload_conan_file_metadata
+ else
+ @package.package_files.preload_conan_file_metadata
+ end
+ end
end
def matching_reference?(package_file)
diff --git a/app/presenters/packages/detail/package_presenter.rb b/app/presenters/packages/detail/package_presenter.rb
index 59e50b96ab2..c257edcadfb 100644
--- a/app/presenters/packages/detail/package_presenter.rb
+++ b/app/presenters/packages/detail/package_presenter.rb
@@ -15,7 +15,7 @@ module Packages
id: @package.id,
created_at: @package.created_at,
name: name,
- package_files: @package.package_files.map { |pf| build_package_file_view(pf) },
+ package_files: package_file_views,
package_type: @package.package_type,
status: @package.status,
project_id: @package.project_id,
@@ -38,6 +38,16 @@ module Packages
private
+ def package_file_views
+ package_files = if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml)
+ @package.installable_package_files
+ else
+ @package.package_files
+ end
+
+ package_files.map { |pf| build_package_file_view(pf) }
+ end
+
def build_package_file_view(package_file)
file_view = {
created_at: package_file.created_at,
diff --git a/app/presenters/packages/npm/package_presenter.rb b/app/presenters/packages/npm/package_presenter.rb
index c30dfa6196b..1f94187204f 100644
--- a/app/presenters/packages/npm/package_presenter.rb
+++ b/app/presenters/packages/npm/package_presenter.rb
@@ -26,7 +26,11 @@ module Packages
.preload_npm_metadatum
batched_packages.each do |package|
- package_file = package.package_files.last
+ package_file = if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml)
+ package.installable_package_files.last
+ else
+ package.package_files.last
+ end
next unless package_file
diff --git a/app/presenters/packages/nuget/presenter_helpers.rb b/app/presenters/packages/nuget/presenter_helpers.rb
index 09bf1e009a6..cd3e123033c 100644
--- a/app/presenters/packages/nuget/presenter_helpers.rb
+++ b/app/presenters/packages/nuget/presenter_helpers.rb
@@ -27,12 +27,19 @@ module Packages
end
def archive_url_for(package)
+ package_files = if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml)
+ package.installable_package_files
+ else
+ package.package_files
+ end
+
+ package_filename = package_files.with_format(NUGET_PACKAGE_FORMAT).last&.file_name
path = api_v4_projects_packages_nuget_download_package_name_package_version_package_filename_path(
{
id: package.project_id,
package_name: package.name,
package_version: package.version,
- package_filename: package.package_files.with_format(NUGET_PACKAGE_FORMAT).last&.file_name
+ package_filename: package_filename
},
true
)
diff --git a/app/presenters/packages/pypi/package_presenter.rb b/app/presenters/packages/pypi/package_presenter.rb
index 7997c1b9b79..33854e4d2fc 100644
--- a/app/presenters/packages/pypi/package_presenter.rb
+++ b/app/presenters/packages/pypi/package_presenter.rb
@@ -36,7 +36,13 @@ module Packages
refs = []
@packages.map do |package|
- package.package_files.each do |file|
+ package_files = if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml)
+ package.installable_package_files
+ else
+ package.package_files
+ end
+
+ package_files.each do |file|
url = build_pypi_package_path(file)
refs << package_link(url, package.pypi_metadatum.required_python, file.file_name)
diff --git a/app/presenters/project_presenter.rb b/app/presenters/project_presenter.rb
index ec66f9bdd4f..64cd54953e2 100644
--- a/app/presenters/project_presenter.rb
+++ b/app/presenters/project_presenter.rb
@@ -364,7 +364,7 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
if clusters.empty?
AnchorData.new(false,
statistic_icon + _('Add Kubernetes cluster'),
- new_project_cluster_path(project))
+ project_clusters_path(project))
else
cluster_link = clusters.count == 1 ? project_cluster_path(project, clusters.first) : project_clusters_path(project)
diff --git a/app/presenters/service_hook_presenter.rb b/app/presenters/service_hook_presenter.rb
index 91911eb3dff..f2a06358918 100644
--- a/app/presenters/service_hook_presenter.rb
+++ b/app/presenters/service_hook_presenter.rb
@@ -4,10 +4,10 @@ class ServiceHookPresenter < Gitlab::View::Presenter::Delegated
presents ::ServiceHook, as: :service_hook
def logs_details_path(log)
- project_service_hook_log_path(integration.project, integration, log)
+ project_integration_hook_log_path(integration.project, integration, log)
end
def logs_retry_path(log)
- retry_project_service_hook_log_path(integration.project, integration, log)
+ retry_project_integration_hook_log_path(integration.project, integration, log)
end
end
diff --git a/app/serializers/analytics_build_entity.rb b/app/serializers/analytics_build_entity.rb
index 99663c8d5eb..169df94ad7b 100644
--- a/app/serializers/analytics_build_entity.rb
+++ b/app/serializers/analytics_build_entity.rb
@@ -9,6 +9,13 @@ class AnalyticsBuildEntity < Grape::Entity
expose :ref, as: :branch
expose :short_sha
expose :author, using: UserEntity
+ expose :project_path do |build|
+ build.project.path
+ end
+
+ expose :namespace_full_path do |build|
+ build.project.namespace.full_path
+ end
expose :started_at, as: :date do |build|
interval_in_words(build[:started_at])
diff --git a/app/serializers/analytics_issue_entity.rb b/app/serializers/analytics_issue_entity.rb
index 307ce14a921..a0d6d120a48 100644
--- a/app/serializers/analytics_issue_entity.rb
+++ b/app/serializers/analytics_issue_entity.rb
@@ -6,6 +6,13 @@ class AnalyticsIssueEntity < Grape::Entity
expose :title
expose :author, using: UserEntity
+ expose :project_path do |object|
+ object[:project_path]
+ end
+
+ expose :namespace_full_path do |object|
+ object[:namespace_path]
+ end
expose :iid do |object|
object[:iid].to_s
diff --git a/app/serializers/environment_serializer.rb b/app/serializers/environment_serializer.rb
index 2fb1ad52135..11445f93609 100644
--- a/app/serializers/environment_serializer.rb
+++ b/app/serializers/environment_serializer.rb
@@ -52,7 +52,17 @@ class EnvironmentSerializer < BaseSerializer
end
def batch_load(resource)
- resource = resource.preload(environment_associations)
+ if ::Feature.enabled?(:custom_preloader_for_deployments, default_enabled: :yaml)
+ resource = resource.preload(environment_associations.except(:last_deployment, :upcoming_deployment))
+
+ Preloaders::Environments::DeploymentPreloader.new(resource)
+ .execute_with_union(:last_deployment, deployment_associations)
+
+ Preloaders::Environments::DeploymentPreloader.new(resource)
+ .execute_with_union(:upcoming_deployment, deployment_associations)
+ else
+ resource = resource.preload(environment_associations)
+ end
resource.all.to_a.tap do |environments|
environments.each do |environment|
diff --git a/app/serializers/group_child_entity.rb b/app/serializers/group_child_entity.rb
index 0ca6e7b40d9..c469dbdd6b8 100644
--- a/app/serializers/group_child_entity.rb
+++ b/app/serializers/group_child_entity.rb
@@ -33,6 +33,8 @@ class GroupChildEntity < Grape::Entity
end
# Project only attributes
+ expose :last_activity_at, if: lambda { |instance| project? }
+
expose :star_count, :archived,
if: lambda { |_instance, _options| project? }
diff --git a/app/serializers/merge_request_poll_cached_widget_entity.rb b/app/serializers/merge_request_poll_cached_widget_entity.rb
index 8b0f3c8eb74..5bf02c93c99 100644
--- a/app/serializers/merge_request_poll_cached_widget_entity.rb
+++ b/app/serializers/merge_request_poll_cached_widget_entity.rb
@@ -17,7 +17,6 @@ class MergeRequestPollCachedWidgetEntity < IssuableEntity
expose :target_project_id
expose :squash
expose :rebase_in_progress?, as: :rebase_in_progress
- expose :default_squash_commit_message
expose :commits_count
expose :merge_ongoing?, as: :merge_ongoing
expose :work_in_progress?, as: :work_in_progress
@@ -27,6 +26,10 @@ class MergeRequestPollCachedWidgetEntity < IssuableEntity
expose :source_branch_exists?, as: :source_branch_exists
expose :branch_missing?, as: :branch_missing
+ expose :default_squash_commit_message do |merge_request|
+ merge_request.default_squash_commit_message(user: request.current_user)
+ end
+
expose :commits_without_merge_commits, using: MergeRequestWidgetCommitEntity do |merge_request|
merge_request.recent_commits.without_merge_commits
end
diff --git a/app/serializers/merge_request_poll_widget_entity.rb b/app/serializers/merge_request_poll_widget_entity.rb
index 074bd2d18d7..f68477e82c9 100644
--- a/app/serializers/merge_request_poll_widget_entity.rb
+++ b/app/serializers/merge_request_poll_widget_entity.rb
@@ -19,7 +19,9 @@ class MergeRequestPollWidgetEntity < Grape::Entity
# User entities
expose :merge_user, using: UserEntity
- expose :default_merge_commit_message
+ expose :default_merge_commit_message do |merge_request, options|
+ merge_request.default_merge_commit_message(include_description: false, user: current_user)
+ end
expose :mergeable do |merge_request, options|
next merge_request.mergeable? if Feature.disabled?(:check_mergeability_async_in_widget, merge_request.project, default_enabled: :yaml)
diff --git a/app/serializers/merge_request_sidebar_basic_entity.rb b/app/serializers/merge_request_sidebar_basic_entity.rb
index 3c911bbe4c8..a0832655563 100644
--- a/app/serializers/merge_request_sidebar_basic_entity.rb
+++ b/app/serializers/merge_request_sidebar_basic_entity.rb
@@ -5,5 +5,9 @@ class MergeRequestSidebarBasicEntity < IssuableSidebarBasicEntity
expose :can_merge do |merge_request|
merge_request.can_be_merged_by?(current_user)
end
+
+ expose :can_update_merge_request do |merge_request|
+ current_user.can?(:update_merge_request, merge_request)
+ end
end
end
diff --git a/app/services/alert_management/alerts/update_service.rb b/app/services/alert_management/alerts/update_service.rb
index 089715a42fb..7a9bcf2a52d 100644
--- a/app/services/alert_management/alerts/update_service.rb
+++ b/app/services/alert_management/alerts/update_service.rb
@@ -2,7 +2,7 @@
module AlertManagement
module Alerts
- class UpdateService
+ class UpdateService < ::BaseProjectService
include Gitlab::Utils::StrongMemoize
# @param alert [AlertManagement::Alert]
@@ -10,10 +10,10 @@ module AlertManagement
# @param params [Hash] Attributes of the alert
def initialize(alert, current_user, params)
@alert = alert
- @current_user = current_user
- @params = params
@param_errors = []
@status = params.delete(:status)
+
+ super(project: alert.project, current_user: current_user, params: params)
end
def execute
@@ -36,7 +36,7 @@ module AlertManagement
private
- attr_reader :alert, :current_user, :params, :param_errors, :status
+ attr_reader :alert, :param_errors, :status
def allowed?
current_user&.can?(:update_alert_management_alert, alert)
@@ -109,7 +109,7 @@ module AlertManagement
end
def add_assignee_system_note(old_assignees)
- SystemNoteService.change_issuable_assignees(alert, alert.project, current_user, old_assignees)
+ SystemNoteService.change_issuable_assignees(alert, project, current_user, old_assignees)
end
# ------ Status-related behavior -------
@@ -129,6 +129,7 @@ module AlertManagement
def handle_status_change
add_status_change_system_note
resolve_todos if alert.resolved?
+ sync_to_incident if should_sync_to_incident?
end
def add_status_change_system_note
@@ -139,6 +140,22 @@ module AlertManagement
todo_service.resolve_todos_for_target(alert, current_user)
end
+ def sync_to_incident
+ ::Issues::UpdateService.new(
+ project: project,
+ current_user: current_user,
+ params: { escalation_status: { status: status } }
+ ).execute(alert.issue)
+ end
+
+ def should_sync_to_incident?
+ Feature.enabled?(:incident_escalations, project) &&
+ alert.issue &&
+ alert.issue.supports_escalation? &&
+ alert.issue.escalation_status &&
+ alert.issue.escalation_status.status != alert.status
+ end
+
def filter_duplicate
# Only need to check if changing to an open status
return unless params[:status_event] && AlertManagement::Alert.open_status?(status)
@@ -154,7 +171,7 @@ module AlertManagement
def open_alerts
strong_memoize(:open_alerts) do
- AlertManagement::Alert.for_fingerprint(alert.project, alert.fingerprint).open
+ AlertManagement::Alert.for_fingerprint(project, alert.fingerprint).open
end
end
@@ -166,7 +183,7 @@ module AlertManagement
def open_alert_url_params
open_alert = open_alerts.first
- alert_path = Gitlab::Routing.url_helpers.details_project_alert_management_path(alert.project, open_alert)
+ alert_path = Gitlab::Routing.url_helpers.details_project_alert_management_path(project, open_alert)
{
link_start: '<a href="%{url}">'.html_safe % { url: alert_path },
diff --git a/app/services/audit_event_service.rb b/app/services/audit_event_service.rb
index 1426bf25a00..f2b1d89161c 100644
--- a/app/services/audit_event_service.rb
+++ b/app/services/audit_event_service.rb
@@ -141,7 +141,7 @@ class AuditEventService
event.save! if should_save_database?(@save_type)
stream_event_to_external_destinations(event) if should_save_stream?(@save_type)
rescue StandardError => e
- Gitlab::ErrorTracking.track_exception(e, audit_event_type: event.class.to_s)
+ Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e, audit_event_type: event.class.to_s)
end
end
diff --git a/app/services/auth/container_registry_authentication_service.rb b/app/services/auth/container_registry_authentication_service.rb
index ea4723c9e28..a92a2c8aef5 100644
--- a/app/services/auth/container_registry_authentication_service.rb
+++ b/app/services/auth/container_registry_authentication_service.rb
@@ -124,7 +124,8 @@ module Auth
type: type,
name: path.to_s,
actions: authorized_actions,
- migration_eligible: self.class.migration_eligible(project: requested_project)
+ migration_eligible: self.class.migration_eligible(project: requested_project),
+ cdn_redirect: cdn_redirect
}.compact
end
@@ -145,6 +146,16 @@ module Auth
# 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
+
+ # This is used to determine whether blob download requests using a given JWT token should be redirected to Google
+ # Cloud CDN or not. The intent is to enable a percentage of time rollout for this new feature on the Container
+ # Registry side. See https://gitlab.com/gitlab-org/gitlab/-/issues/349417 for more details.
+ def cdn_redirect
+ Feature.enabled?(:container_registry_cdn_redirect) || nil
end
##
diff --git a/app/services/auto_merge/base_service.rb b/app/services/auto_merge/base_service.rb
index da80211f9bb..4ed4368d3b7 100644
--- a/app/services/auto_merge/base_service.rb
+++ b/app/services/auto_merge/base_service.rb
@@ -6,7 +6,7 @@ module AutoMerge
include MergeRequests::AssignsMergeParams
def execute(merge_request)
- ActiveRecord::Base.transaction do # rubocop: disable Database/MultipleDatabases
+ ApplicationRecord.transaction do
register_auto_merge_parameters!(merge_request)
yield if block_given?
end
@@ -29,7 +29,7 @@ module AutoMerge
end
def cancel(merge_request)
- ActiveRecord::Base.transaction do # rubocop: disable Database/MultipleDatabases
+ ApplicationRecord.transaction do
clear_auto_merge_parameters!(merge_request)
yield if block_given?
end
@@ -41,7 +41,7 @@ module AutoMerge
end
def abort(merge_request, reason)
- ActiveRecord::Base.transaction do # rubocop: disable Database/MultipleDatabases
+ ApplicationRecord.transaction do
clear_auto_merge_parameters!(merge_request)
yield if block_given?
end
diff --git a/app/services/bulk_imports/archive_extraction_service.rb b/app/services/bulk_imports/archive_extraction_service.rb
index 9fc828b8e34..caa40d98a76 100644
--- a/app/services/bulk_imports/archive_extraction_service.rb
+++ b/app/services/bulk_imports/archive_extraction_service.rb
@@ -28,8 +28,8 @@ module BulkImports
end
def execute
- validate_filepath
validate_tmpdir
+ validate_filepath
validate_symlink
extract_archive
@@ -46,7 +46,7 @@ module BulkImports
end
def validate_tmpdir
- raise(BulkImports::Error, 'Invalid target directory') unless File.expand_path(tmpdir).start_with?(Dir.tmpdir)
+ Gitlab::Utils.check_allowed_absolute_path!(tmpdir, [Dir.tmpdir])
end
def validate_symlink
diff --git a/app/services/bulk_imports/file_decompression_service.rb b/app/services/bulk_imports/file_decompression_service.rb
index fe9017377ec..b76746b199f 100644
--- a/app/services/bulk_imports/file_decompression_service.rb
+++ b/app/services/bulk_imports/file_decompression_service.rb
@@ -1,21 +1,26 @@
# frozen_string_literal: true
+# File Decompression Service allows gzipped files decompression into tmp directory.
+#
+# @param tmpdir [String] Temp directory to store downloaded file to. Must be located under `Dir.tmpdir`.
+# @param filename [String] Name of the file to decompress.
module BulkImports
class FileDecompressionService
include Gitlab::ImportExport::CommandLineUtil
ServiceError = Class.new(StandardError)
- def initialize(dir:, filename:)
- @dir = dir
+ def initialize(tmpdir:, filename:)
+ @tmpdir = tmpdir
@filename = filename
- @filepath = File.join(@dir, @filename)
+ @filepath = File.join(@tmpdir, @filename)
@decompressed_filename = File.basename(@filename, '.gz')
- @decompressed_filepath = File.join(@dir, @decompressed_filename)
+ @decompressed_filepath = File.join(@tmpdir, @decompressed_filename)
end
def execute
- validate_dir
+ validate_tmpdir
+ validate_filepath
validate_decompressed_file_size if Feature.enabled?(:validate_import_decompressed_archive_size, default_enabled: :yaml)
validate_symlink(filepath)
@@ -33,10 +38,14 @@ module BulkImports
private
- attr_reader :dir, :filename, :filepath, :decompressed_filename, :decompressed_filepath
+ attr_reader :tmpdir, :filename, :filepath, :decompressed_filename, :decompressed_filepath
- def validate_dir
- raise(ServiceError, 'Invalid target directory') unless dir.start_with?(Dir.tmpdir)
+ def validate_filepath
+ Gitlab::Utils.check_path_traversal!(filepath)
+ end
+
+ def validate_tmpdir
+ Gitlab::Utils.check_allowed_absolute_path!(tmpdir, [Dir.tmpdir])
end
def validate_decompressed_file_size
@@ -48,7 +57,7 @@ module BulkImports
end
def decompress_file
- gunzip(dir: dir, filename: filename)
+ gunzip(dir: tmpdir, filename: filename)
end
def size_validator
diff --git a/app/services/bulk_imports/file_download_service.rb b/app/services/bulk_imports/file_download_service.rb
index d08dc72e30b..8d6ba54cd50 100644
--- a/app/services/bulk_imports/file_download_service.rb
+++ b/app/services/bulk_imports/file_download_service.rb
@@ -1,6 +1,13 @@
# frozen_string_literal: true
-# Downloads a remote file. If no filename is given, it'll use the remote filename
+# File Download Service allows remote file download into tmp directory.
+#
+# @param configuration [BulkImports::Configuration] Config object containing url and access token
+# @param relative_url [String] Relative URL to download the file from
+# @param tmpdir [String] Temp directory to store downloaded file to. Must be located under `Dir.tmpdir`.
+# @param file_size_limit [Integer] Maximum allowed file size
+# @param allowed_content_types [Array<String>] Allowed file content types
+# @param filename [String] Name of the file to download, if known. Use remote filename if none given.
module BulkImports
class FileDownloadService
ServiceError = Class.new(StandardError)
@@ -13,20 +20,21 @@ module BulkImports
def initialize(
configuration:,
relative_url:,
- dir:,
+ tmpdir:,
file_size_limit: DEFAULT_FILE_SIZE_LIMIT,
allowed_content_types: DEFAULT_ALLOWED_CONTENT_TYPES,
filename: nil)
@configuration = configuration
@relative_url = relative_url
@filename = filename
- @dir = dir
+ @tmpdir = tmpdir
@file_size_limit = file_size_limit
@allowed_content_types = allowed_content_types
end
def execute
- validate_dir
+ validate_tmpdir
+ validate_filepath
validate_url
validate_content_type
validate_content_length
@@ -40,7 +48,7 @@ module BulkImports
private
- attr_reader :configuration, :relative_url, :dir, :file_size_limit, :allowed_content_types
+ attr_reader :configuration, :relative_url, :tmpdir, :file_size_limit, :allowed_content_types
def download_file
File.open(filepath, 'wb') do |file|
@@ -76,8 +84,12 @@ module BulkImports
@headers ||= http_client.head(relative_url).headers
end
- def validate_dir
- raise(ServiceError, 'Invalid target directory') unless dir.start_with?(Dir.tmpdir)
+ def validate_filepath
+ Gitlab::Utils.check_path_traversal!(filepath)
+ end
+
+ def validate_tmpdir
+ Gitlab::Utils.check_allowed_absolute_path!(tmpdir, [Dir.tmpdir])
end
def validate_symlink
@@ -119,7 +131,7 @@ module BulkImports
end
def filepath
- @filepath ||= File.join(@dir, filename)
+ @filepath ||= File.join(@tmpdir, filename)
end
def filename
diff --git a/app/services/bulk_imports/file_export_service.rb b/app/services/bulk_imports/file_export_service.rb
index a7e0f998666..a9d06d84277 100644
--- a/app/services/bulk_imports/file_export_service.rb
+++ b/app/services/bulk_imports/file_export_service.rb
@@ -26,8 +26,10 @@ module BulkImports
def export_service
case relation
- when FileTransfer::ProjectConfig::UPLOADS_RELATION
+ when FileTransfer::BaseConfig::UPLOADS_RELATION
UploadsExportService.new(portable, export_path)
+ when FileTransfer::ProjectConfig::LFS_OBJECTS_RELATION
+ LfsObjectsExportService.new(portable, export_path)
else
raise BulkImports::Error, 'Unsupported relation export type'
end
diff --git a/app/services/bulk_imports/lfs_objects_export_service.rb b/app/services/bulk_imports/lfs_objects_export_service.rb
new file mode 100644
index 00000000000..fa606e4e5a3
--- /dev/null
+++ b/app/services/bulk_imports/lfs_objects_export_service.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+module BulkImports
+ class LfsObjectsExportService
+ include Gitlab::ImportExport::CommandLineUtil
+
+ BATCH_SIZE = 100
+
+ def initialize(portable, export_path)
+ @portable = portable
+ @export_path = export_path
+ @lfs_json = {}
+ end
+
+ def execute
+ portable.lfs_objects.find_in_batches(batch_size: BATCH_SIZE) do |batch| # rubocop: disable CodeReuse/ActiveRecord
+ batch.each do |lfs_object|
+ save_lfs_object(lfs_object)
+ end
+
+ append_lfs_json_for_batch(batch)
+ end
+
+ write_lfs_json
+ end
+
+ private
+
+ attr_reader :portable, :export_path, :lfs_json
+
+ def save_lfs_object(lfs_object)
+ destination_filepath = File.join(export_path, lfs_object.oid)
+
+ if lfs_object.local_store?
+ copy_files(lfs_object.file.path, destination_filepath)
+ else
+ download(lfs_object.file.url, destination_filepath)
+ end
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def append_lfs_json_for_batch(lfs_objects_batch)
+ lfs_objects_projects = LfsObjectsProject
+ .select('lfs_objects.oid, array_agg(distinct lfs_objects_projects.repository_type) as repository_types')
+ .joins(:lfs_object)
+ .where(project: portable, lfs_object: lfs_objects_batch)
+ .group('lfs_objects.oid')
+
+ lfs_objects_projects.each do |group|
+ oid = group.oid
+
+ lfs_json[oid] ||= []
+ lfs_json[oid] += group.repository_types
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def write_lfs_json
+ filepath = File.join(export_path, "#{BulkImports::FileTransfer::ProjectConfig::LFS_OBJECTS_RELATION}.json")
+
+ File.write(filepath, lfs_json.to_json)
+ end
+ end
+end
diff --git a/app/services/ci/archive_trace_service.rb b/app/services/ci/archive_trace_service.rb
index 17cac38ace2..7b1d2207460 100644
--- a/app/services/ci/archive_trace_service.rb
+++ b/app/services/ci/archive_trace_service.rb
@@ -27,6 +27,10 @@ module Ci
job.trace.archive!
job.remove_pending_state!
+ if Feature.enabled?(:datadog_integration_logs_collection, job.project) && job.job_artifacts_trace.present?
+ job.project.execute_integrations(Gitlab::DataBuilder::ArchiveTrace.build(job), :archive_trace_hooks)
+ end
+
# TODO: Remove this logging once we confirmed new live trace architecture is functional.
# See https://gitlab.com/gitlab-com/gl-infra/infrastructure/issues/4667.
unless job.has_archived_trace?
diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb
index c1f35afba40..d53e136effb 100644
--- a/app/services/ci/create_pipeline_service.rb
+++ b/app/services/ci/create_pipeline_service.rb
@@ -95,7 +95,10 @@ module Ci
.build!
if pipeline.persisted?
- schedule_head_pipeline_update
+ Gitlab::EventStore.publish(
+ Ci::PipelineCreatedEvent.new(data: { pipeline_id: pipeline.id })
+ )
+
create_namespace_onboarding_action
else
# If pipeline is not persisted, try to recover IID
@@ -134,12 +137,6 @@ module Ci
commit.try(:id)
end
- def schedule_head_pipeline_update
- pipeline.all_merge_requests.opened.each do |merge_request|
- UpdateHeadPipelineForMergeRequestWorker.perform_async(merge_request.id)
- end
- end
-
def create_namespace_onboarding_action
Namespaces::OnboardingPipelineCreatedWorker.perform_async(project.namespace_id)
end
diff --git a/app/services/ci/destroy_pipeline_service.rb b/app/services/ci/destroy_pipeline_service.rb
index 6fbde5d291c..d85e52e1312 100644
--- a/app/services/ci/destroy_pipeline_service.rb
+++ b/app/services/ci/destroy_pipeline_service.rb
@@ -9,12 +9,12 @@ module Ci
pipeline.cancel_running if pipeline.cancelable?
- # Ci::Pipeline#destroy triggers `use_fast_destroy :job_artifacts` and
- # ci_builds has ON DELETE CASCADE to ci_pipelines. The pipeline, the builds,
- # job and pipeline artifacts all get destroyed here.
- ::Gitlab::Database::QueryAnalyzers::PreventCrossDatabaseModification.allow_cross_database_modification_within_transaction(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/345664') do
- pipeline.reset.destroy!
- end
+ # The pipeline, the builds, job and pipeline artifacts all get destroyed here.
+ # Ci::Pipeline#destroy triggers fast destroy on job_artifacts and
+ # build_trace_chunks to remove the records and data stored in object storage.
+ # ci_builds records are deleted using ON DELETE CASCADE from ci_pipelines
+ #
+ pipeline.reset.destroy!
ServiceResponse.success(message: 'Pipeline not found')
rescue ActiveRecord::RecordNotFound
diff --git a/app/services/ci/job_artifacts/delete_project_artifacts_service.rb b/app/services/ci/job_artifacts/delete_project_artifacts_service.rb
new file mode 100644
index 00000000000..61394573748
--- /dev/null
+++ b/app/services/ci/job_artifacts/delete_project_artifacts_service.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Ci
+ module JobArtifacts
+ class DeleteProjectArtifactsService < BaseProjectService
+ def execute
+ ExpireProjectBuildArtifactsWorker.perform_async(project.id)
+ end
+ end
+ end
+end
diff --git a/app/services/ci/job_artifacts/destroy_all_expired_service.rb b/app/services/ci/job_artifacts/destroy_all_expired_service.rb
index 7fa56677a0c..c089567ec14 100644
--- a/app/services/ci/job_artifacts/destroy_all_expired_service.rb
+++ b/app/services/ci/job_artifacts/destroy_all_expired_service.rb
@@ -8,13 +8,15 @@ module Ci
BATCH_SIZE = 100
LOOP_TIMEOUT = 5.minutes
- LOOP_LIMIT = 1000
+ SMALL_LOOP_LIMIT = 100
+ LARGE_LOOP_LIMIT = 500
EXCLUSIVE_LOCK_KEY = 'expired_job_artifacts:destroy:lock'
LOCK_TIMEOUT = 6.minutes
def initialize
@removed_artifacts_count = 0
@start_at = Time.current
+ @loop_limit = ::Feature.enabled?(:ci_artifact_fast_removal_large_loop_limit, default_enabled: :yaml) ? LARGE_LOOP_LIMIT : SMALL_LOOP_LIMIT
end
##
@@ -24,6 +26,8 @@ module Ci
# preventing multiple `ExpireBuildArtifactsWorker` CRON jobs run concurrently,
# which is scheduled every 7 minutes.
def execute
+ return 0 unless ::Feature.enabled?(:ci_destroy_all_expired_service, default_enabled: :yaml)
+
in_lock(EXCLUSIVE_LOCK_KEY, ttl: LOCK_TIMEOUT, retries: 1) do
if ::Feature.enabled?(:ci_destroy_unlocked_job_artifacts)
destroy_unlocked_job_artifacts
@@ -38,34 +42,13 @@ module Ci
private
def destroy_unlocked_job_artifacts
- loop_until(timeout: LOOP_TIMEOUT, limit: LOOP_LIMIT) do
+ loop_until(timeout: LOOP_TIMEOUT, limit: @loop_limit) do
artifacts = Ci::JobArtifact.expired_before(@start_at).artifact_unlocked.limit(BATCH_SIZE)
service_response = destroy_batch(artifacts)
@removed_artifacts_count += service_response[:destroyed_artifacts_count]
-
- update_locked_status_on_unknown_artifacts if service_response[:destroyed_artifacts_count] == 0
-
- # Return a truthy value here to prevent exiting #loop_until
- @removed_artifacts_count
end
end
- def update_locked_status_on_unknown_artifacts
- build_ids = Ci::JobArtifact.expired_before(@start_at).artifact_unknown.limit(BATCH_SIZE).distinct_job_ids
-
- return unless build_ids.present?
-
- locked_pipeline_build_ids = ::Ci::Build.with_pipeline_locked_artifacts.id_in(build_ids).pluck_primary_key
- unlocked_pipeline_build_ids = build_ids - locked_pipeline_build_ids
-
- update_unknown_artifacts(locked_pipeline_build_ids, Ci::JobArtifact.lockeds[:artifacts_locked])
- update_unknown_artifacts(unlocked_pipeline_build_ids, Ci::JobArtifact.lockeds[:unlocked])
- end
-
- def update_unknown_artifacts(build_ids, locked_value)
- Ci::JobArtifact.for_job_ids(build_ids).update_all(locked: locked_value) if build_ids.any?
- end
-
def destroy_job_artifacts_with_slow_iteration
Ci::JobArtifact.expired_before(@start_at).each_batch(of: BATCH_SIZE, column: :expire_at, order: :desc) do |relation, index|
# For performance reasons, join with ci_pipelines after the batch is queried.
@@ -76,7 +59,7 @@ module Ci
@removed_artifacts_count += service_response[:destroyed_artifacts_count]
break if loop_timeout?
- break if index >= LOOP_LIMIT
+ break if index >= @loop_limit
end
end
diff --git a/app/services/ci/job_artifacts/expire_project_build_artifacts_service.rb b/app/services/ci/job_artifacts/expire_project_build_artifacts_service.rb
new file mode 100644
index 00000000000..836b1d39736
--- /dev/null
+++ b/app/services/ci/job_artifacts/expire_project_build_artifacts_service.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module Ci
+ module JobArtifacts
+ class ExpireProjectBuildArtifactsService
+ BATCH_SIZE = 1000
+
+ def initialize(project_id, expiry_time)
+ @project_id = project_id
+ @expiry_time = expiry_time
+ end
+
+ # rubocop:disable CodeReuse/ActiveRecord
+ def execute
+ scope = Ci::JobArtifact.for_project(project_id).order(:id)
+ file_type_values = Ci::JobArtifact.erasable_file_types.map { |file_type| [Ci::JobArtifact.file_types[file_type]] }
+ from_sql = Arel::Nodes::Grouping.new(Arel::Nodes::ValuesList.new(file_type_values)).as('file_types (file_type)').to_sql
+ array_scope = Ci::JobArtifact.from(from_sql).select(:file_type)
+ array_mapping_scope = -> (file_type_expression) { Ci::JobArtifact.where(Ci::JobArtifact.arel_table[:file_type].eq(file_type_expression)) }
+
+ Gitlab::Pagination::Keyset::Iterator
+ .new(scope: scope, in_operator_optimization_options: { array_scope: array_scope, array_mapping_scope: array_mapping_scope })
+ .each_batch(of: BATCH_SIZE) do |batch|
+ ids = batch.reselect!(:id).to_a.map(&:id)
+ Ci::JobArtifact.unlocked.where(id: ids).update_all(locked: Ci::JobArtifact.lockeds[:unlocked], expire_at: expiry_time)
+ end
+ end
+ # rubocop:enable CodeReuse/ActiveRecord
+
+ private
+
+ attr_reader :project_id, :expiry_time
+ end
+ end
+end
diff --git a/app/services/ci/pipeline_processing/atomic_processing_service.rb b/app/services/ci/pipeline_processing/atomic_processing_service.rb
index d8ce063ffb4..508d9c3f2e1 100644
--- a/app/services/ci/pipeline_processing/atomic_processing_service.rb
+++ b/app/services/ci/pipeline_processing/atomic_processing_service.rb
@@ -36,9 +36,7 @@ module Ci
update_pipeline!
update_statuses_processed!
- if Feature.enabled?(:expire_job_and_pipeline_cache_synchronously, pipeline.project, default_enabled: :yaml)
- Ci::ExpirePipelineCacheService.new.execute(pipeline)
- end
+ Ci::ExpirePipelineCacheService.new.execute(pipeline)
true
end
diff --git a/app/services/ci/pipelines/add_job_service.rb b/app/services/ci/pipelines/add_job_service.rb
index 703bb22fb5d..fc852bc3edd 100644
--- a/app/services/ci/pipelines/add_job_service.rb
+++ b/app/services/ci/pipelines/add_job_service.rb
@@ -39,6 +39,12 @@ module Ci
job.pipeline = pipeline
job.project = pipeline.project
job.ref = pipeline.ref
+
+ # update metadata since it might have been lazily initialised before this call
+ # metadata is present on `Ci::Processable`
+ if job.respond_to?(:metadata) && job.metadata
+ job.metadata.project = pipeline.project
+ end
end
end
end
diff --git a/app/services/ci/play_build_service.rb b/app/services/ci/play_build_service.rb
index e2673c763f3..2d6b6aeee14 100644
--- a/app/services/ci/play_build_service.rb
+++ b/app/services/ci/play_build_service.rb
@@ -14,7 +14,10 @@ module Ci
AfterRequeueJobService.new(project, current_user).execute(build)
end
else
- Ci::Build.retry(build, current_user)
+ # Retrying in Ci::PlayBuildService is a legacy process that should be removed.
+ # Instead, callers should explicitly execute Ci::RetryBuildService.
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/347493.
+ build.retryable? ? Ci::Build.retry(build, current_user) : build
end
end
diff --git a/app/services/ci/process_build_service.rb b/app/services/ci/process_build_service.rb
index 5271c0fe93d..e6ec65fcc91 100644
--- a/app/services/ci/process_build_service.rb
+++ b/app/services/ci/process_build_service.rb
@@ -4,14 +4,7 @@ module Ci
class ProcessBuildService < BaseService
def execute(build, current_status)
if valid_statuses_for_build(build).include?(current_status)
- if build.schedulable?
- build.schedule
- elsif build.action?
- build.actionize
- else
- enqueue(build)
- end
-
+ process(build)
true
else
build.skip
@@ -21,6 +14,16 @@ module Ci
private
+ def process(build)
+ if build.schedulable?
+ build.schedule
+ elsif build.action?
+ build.actionize
+ else
+ enqueue(build)
+ end
+ end
+
def enqueue(build)
build.enqueue
end
diff --git a/app/services/ci/process_sync_events_service.rb b/app/services/ci/process_sync_events_service.rb
index 6be8c41dc6a..11ce6e8eeaf 100644
--- a/app/services/ci/process_sync_events_service.rb
+++ b/app/services/ci/process_sync_events_service.rb
@@ -28,18 +28,16 @@ module Ci
return if events.empty?
- first = events.first
- last_processed = nil
+ processed_events = []
begin
events.each do |event|
@sync_class.sync!(event)
- last_processed = event
+ processed_events << event
end
ensure
- # remove events till the one that was last succesfully processed
- @sync_event_class.id_in(first.id..last_processed.id).delete_all if last_processed
+ @sync_event_class.id_in(processed_events).delete_all
end
end
diff --git a/app/services/ci/register_runner_service.rb b/app/services/ci/register_runner_service.rb
new file mode 100644
index 00000000000..0a2027e33ce
--- /dev/null
+++ b/app/services/ci/register_runner_service.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Ci
+ class RegisterRunnerService
+ def execute(registration_token, attributes)
+ runner_type_attrs = check_token_and_extract_attrs(registration_token)
+
+ return unless runner_type_attrs
+
+ ::Ci::Runner.create(attributes.merge(runner_type_attrs))
+ end
+
+ private
+
+ def check_token_and_extract_attrs(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, projects: [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, groups: [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
+ end
+end
diff --git a/app/services/ci/retry_build_service.rb b/app/services/ci/retry_build_service.rb
index 89fe4ff9f60..7e5d5373648 100644
--- a/app/services/ci/retry_build_service.rb
+++ b/app/services/ci/retry_build_service.rb
@@ -25,10 +25,6 @@ module Ci
Gitlab::OptimisticLocking.retry_lock(new_build, name: 'retry_build', &:enqueue)
AfterRequeueJobService.new(project, current_user).execute(build)
-
- ::MergeRequests::AddTodoWhenBuildFailsService
- .new(project: project, current_user: current_user)
- .close(new_build)
end
end
@@ -42,16 +38,25 @@ module Ci
check_access!(build)
new_build = clone_build(build)
+
+ new_build.run_after_commit do
+ ::MergeRequests::AddTodoWhenBuildFailsService
+ .new(project: project)
+ .close(new_build)
+ end
+
+ if create_deployment_in_separate_transaction?
+ new_build.run_after_commit do |new_build|
+ ::Deployments::CreateForBuildService.new.execute(new_build)
+ end
+ end
+
::Ci::Pipelines::AddJobService.new(build.pipeline).execute!(new_build) do |job|
BulkInsertableAssociations.with_bulk_insert do
job.save!
end
end
- if create_deployment_in_separate_transaction?
- clone_deployment!(new_build, build)
- end
-
build.reset # refresh the data to get new values of `retried` and `processed`.
new_build
@@ -95,20 +100,6 @@ module Ci
.deployment_attributes_for(new_build, old_build.persisted_environment)
end
- def clone_deployment!(new_build, old_build)
- return unless old_build.deployment.present?
-
- # We should clone the previous deployment attributes instead of initializing
- # new object with `Seed::Deployment`.
- # See https://gitlab.com/gitlab-org/gitlab/-/issues/347206
- deployment = ::Gitlab::Ci::Pipeline::Seed::Deployment
- .new(new_build, old_build.persisted_environment).to_resource
-
- return unless deployment
-
- new_build.create_deployment!(deployment.attributes)
- end
-
def create_deployment_in_separate_transaction?
strong_memoize(:create_deployment_in_separate_transaction) do
::Feature.enabled?(:create_deployment_in_separate_transaction, project, default_enabled: :yaml)
diff --git a/app/services/ci/stuck_builds/drop_helpers.rb b/app/services/ci/stuck_builds/drop_helpers.rb
index f79b805c23d..048b52c6e13 100644
--- a/app/services/ci/stuck_builds/drop_helpers.rb
+++ b/app/services/ci/stuck_builds/drop_helpers.rb
@@ -34,7 +34,7 @@ module Ci
# rubocop: enable CodeReuse/ActiveRecord
def drop_build(type, build, reason)
- Gitlab::AppLogger.info "#{self.class}: Dropping #{type} build #{build.id} for runner #{build.runner_id} (status: #{build.status}, failure_reason: #{reason})"
+ log_dropping_message(type, build, reason)
Gitlab::OptimisticLocking.retry_lock(build, 3, name: 'stuck_ci_jobs_worker_drop_build') do |b|
b.drop(reason)
end
@@ -53,6 +53,16 @@ module Ci
project_id: build.project_id
)
end
+
+ def log_dropping_message(type, build, reason)
+ Gitlab::AppLogger.info(class: self.class.name,
+ message: "Dropping #{type} build",
+ build_stuck_type: type,
+ build_id: build.id,
+ runner_id: build.runner_id,
+ build_status: build.status,
+ build_failure_reason: reason)
+ end
end
end
end
diff --git a/app/services/ci/update_build_queue_service.rb b/app/services/ci/update_build_queue_service.rb
index 146239bb7e5..2e38969c7a9 100644
--- a/app/services/ci/update_build_queue_service.rb
+++ b/app/services/ci/update_build_queue_service.rb
@@ -99,17 +99,15 @@ module Ci
private
def tick_for(build, runners)
- ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/339937') do
- runners = runners.with_recent_runner_queue
- runners = runners.with_tags if Feature.enabled?(:ci_preload_runner_tags, default_enabled: :yaml)
+ runners = runners.with_recent_runner_queue
+ runners = runners.with_tags if Feature.enabled?(:ci_preload_runner_tags, default_enabled: :yaml)
- metrics.observe_active_runners(-> { runners.to_a.size })
+ metrics.observe_active_runners(-> { runners.to_a.size })
- runners.each do |runner|
- metrics.increment_runner_tick(runner)
+ runners.each do |runner|
+ metrics.increment_runner_tick(runner)
- runner.pick_build!(build)
- end
+ runner.pick_build!(build)
end
end
diff --git a/app/services/clusters/agent_tokens/create_service.rb b/app/services/clusters/agent_tokens/create_service.rb
index 5b8a0e46a6c..2539ffdc5ba 100644
--- a/app/services/clusters/agent_tokens/create_service.rb
+++ b/app/services/clusters/agent_tokens/create_service.rb
@@ -30,13 +30,14 @@ module Clusters
end
def log_activity_event!(token)
- token.agent.activity_events.create!(
+ Clusters::Agents::CreateActivityEventService.new(
+ token.agent,
kind: :token_created,
level: :info,
recorded_at: token.created_at,
user: current_user,
agent_token: token
- )
+ ).execute
end
end
end
diff --git a/app/services/clusters/agent_tokens/track_usage_service.rb b/app/services/clusters/agent_tokens/track_usage_service.rb
new file mode 100644
index 00000000000..fdc79ac0f8b
--- /dev/null
+++ b/app/services/clusters/agent_tokens/track_usage_service.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module Clusters
+ module AgentTokens
+ class TrackUsageService
+ # The `UPDATE_USED_COLUMN_EVERY` defines how often the token DB entry can be updated
+ UPDATE_USED_COLUMN_EVERY = (40.minutes..55.minutes).freeze
+
+ delegate :agent, to: :token
+
+ def initialize(token)
+ @token = token
+ end
+
+ def execute
+ track_values = { last_used_at: Time.current.utc }
+
+ token.cache_attributes(track_values)
+
+ if can_update_track_values?
+ log_activity_event!(track_values[:last_used_at]) unless agent.connected?
+
+ # Use update_column so updated_at is skipped
+ token.update_columns(track_values)
+ end
+ end
+
+ private
+
+ attr_reader :token
+
+ def can_update_track_values?
+ # Use a random threshold to prevent beating DB updates.
+ last_used_at_max_age = Random.rand(UPDATE_USED_COLUMN_EVERY)
+
+ real_last_used_at = token.read_attribute(:last_used_at)
+
+ # Handle too many updates from high token traffic
+ real_last_used_at.nil? ||
+ (Time.current - real_last_used_at) >= last_used_at_max_age
+ end
+
+ def log_activity_event!(recorded_at)
+ Clusters::Agents::CreateActivityEventService.new(
+ agent,
+ kind: :agent_connected,
+ level: :info,
+ recorded_at: recorded_at,
+ agent_token: token
+ ).execute
+ end
+ end
+ end
+end
diff --git a/app/services/clusters/agents/create_activity_event_service.rb b/app/services/clusters/agents/create_activity_event_service.rb
new file mode 100644
index 00000000000..886dddf1a52
--- /dev/null
+++ b/app/services/clusters/agents/create_activity_event_service.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Clusters
+ module Agents
+ class CreateActivityEventService
+ def initialize(agent, **params)
+ @agent = agent
+ @params = params
+ end
+
+ def execute
+ agent.activity_events.create!(params)
+
+ DeleteExpiredEventsWorker.perform_at(schedule_cleanup_at, agent.id)
+
+ ServiceResponse.success
+ end
+
+ private
+
+ attr_reader :agent, :params
+
+ def schedule_cleanup_at
+ 1.hour.from_now.change(min: agent.id % 60)
+ end
+ end
+ end
+end
diff --git a/app/services/clusters/agents/delete_expired_events_service.rb b/app/services/clusters/agents/delete_expired_events_service.rb
new file mode 100644
index 00000000000..a0c0291c1fb
--- /dev/null
+++ b/app/services/clusters/agents/delete_expired_events_service.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Clusters
+ module Agents
+ class DeleteExpiredEventsService
+ def initialize(agent)
+ @agent = agent
+ end
+
+ def execute
+ agent.activity_events
+ .recorded_before(remove_events_before)
+ .each_batch { |batch| batch.delete_all }
+ end
+
+ private
+
+ attr_reader :agent
+
+ def remove_events_before
+ agent.activity_event_deletion_cutoff
+ end
+ end
+ end
+end
diff --git a/app/services/concerns/issues/issue_type_helpers.rb b/app/services/concerns/issues/issue_type_helpers.rb
index 44c20d20ff1..e6ac08a567d 100644
--- a/app/services/concerns/issues/issue_type_helpers.rb
+++ b/app/services/concerns/issues/issue_type_helpers.rb
@@ -5,7 +5,7 @@ module Issues
# @param object [Issue, Project]
# @param issue_type [String, Symbol]
def create_issue_type_allowed?(object, issue_type)
- WorkItem::Type.base_types.key?(issue_type.to_s) &&
+ WorkItems::Type.base_types.key?(issue_type.to_s) &&
can?(current_user, :"create_#{issue_type}", object)
end
end
diff --git a/app/services/dependency_proxy/download_blob_service.rb b/app/services/dependency_proxy/download_blob_service.rb
deleted file mode 100644
index b3548c8a126..00000000000
--- a/app/services/dependency_proxy/download_blob_service.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-# frozen_string_literal: true
-
-module DependencyProxy
- class DownloadBlobService < DependencyProxy::BaseService
- def initialize(image, blob_sha, token)
- @image = image
- @blob_sha = blob_sha
- @token = token
- @temp_file = Tempfile.new
- end
-
- def execute
- File.open(@temp_file.path, "wb") do |file|
- Gitlab::HTTP.get(blob_url, headers: auth_headers, stream_body: true) do |fragment|
- if [301, 302, 307].include?(fragment.code)
- # do nothing
- elsif fragment.code == 200
- file.write(fragment)
- else
- raise DownloadError.new('Non-success response code on downloading blob fragment', fragment.code)
- end
- end
- end
-
- success(file: @temp_file)
- rescue DownloadError => exception
- error(exception.message, exception.http_status)
- rescue Timeout::Error => exception
- error(exception.message, 599)
- end
-
- private
-
- def blob_url
- registry.blob_url(@image, @blob_sha)
- end
- end
-end
diff --git a/app/services/dependency_proxy/find_or_create_blob_service.rb b/app/services/dependency_proxy/find_or_create_blob_service.rb
deleted file mode 100644
index 1b43263a3ba..00000000000
--- a/app/services/dependency_proxy/find_or_create_blob_service.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# frozen_string_literal: true
-
-module DependencyProxy
- class FindOrCreateBlobService < DependencyProxy::BaseService
- def initialize(group, image, token, blob_sha)
- @group = group
- @image = image
- @token = token
- @blob_sha = blob_sha
- end
-
- def execute
- from_cache = true
- file_name = @blob_sha.sub('sha256:', '') + '.gz'
- blob = @group.dependency_proxy_blobs.active.find_or_build(file_name)
-
- unless blob.persisted?
- from_cache = false
- result = DependencyProxy::DownloadBlobService
- .new(@image, @blob_sha, @token).execute
-
- if result[:status] == :error
- log_failure(result)
-
- return error('Failed to download the blob', result[:http_status])
- end
-
- blob.file = result[:file]
- blob.size = result[:file].size
- blob.save!
- end
-
- blob.read! if from_cache
- success(blob: blob, from_cache: from_cache)
- end
-
- private
-
- def log_failure(result)
- log_error(
- "Dependency proxy: Failed to download the blob." \
- "Blob sha: #{@blob_sha}." \
- "Error message: #{result[:message][0, 100]}" \
- "HTTP status: #{result[:http_status]}"
- )
- end
- end
-end
diff --git a/app/services/deployments/archive_in_project_service.rb b/app/services/deployments/archive_in_project_service.rb
index a593721f390..d80ed637cd8 100644
--- a/app/services/deployments/archive_in_project_service.rb
+++ b/app/services/deployments/archive_in_project_service.rb
@@ -7,10 +7,6 @@ module Deployments
BATCH_SIZE = 100
def execute
- unless ::Feature.enabled?(:deployments_archive, project, default_enabled: :yaml)
- return error('Feature flag is not enabled')
- end
-
deployments = Deployment.archivables_in(project, limit: BATCH_SIZE)
return success(result: :empty) if deployments.empty?
diff --git a/app/services/deployments/create_for_build_service.rb b/app/services/deployments/create_for_build_service.rb
new file mode 100644
index 00000000000..b3e2d2edb59
--- /dev/null
+++ b/app/services/deployments/create_for_build_service.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Deployments
+ # This class creates a deployment record for a build (a pipeline job).
+ class CreateForBuildService
+ DeploymentCreationError = Class.new(StandardError)
+
+ def execute(build)
+ return unless build.instance_of?(::Ci::Build) && build.persisted_environment.present?
+
+ # TODO: Move all buisness logic in `Seed::Deployment` to this class after
+ # `create_deployment_in_separate_transaction` feature flag has been removed.
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/348778
+ deployment = ::Gitlab::Ci::Pipeline::Seed::Deployment
+ .new(build, build.persisted_environment).to_resource
+
+ return unless deployment
+
+ build.create_deployment!(deployment.attributes)
+ rescue ActiveRecord::RecordInvalid => e
+ Gitlab::ErrorTracking.track_and_raise_for_dev_exception(
+ DeploymentCreationError.new(e.message), build_id: build.id)
+ end
+ end
+end
diff --git a/app/services/deployments/update_environment_service.rb b/app/services/deployments/update_environment_service.rb
index 83c37257297..19b950044d0 100644
--- a/app/services/deployments/update_environment_service.rb
+++ b/app/services/deployments/update_environment_service.rb
@@ -26,7 +26,7 @@ module Deployments
end
def update_environment(deployment)
- ActiveRecord::Base.transaction do # rubocop: disable Database/MultipleDatabases
+ ApplicationRecord.transaction do
# Renew attributes at update
renew_external_url
renew_auto_stop_in
diff --git a/app/services/design_management/copy_design_collection/copy_service.rb b/app/services/design_management/copy_design_collection/copy_service.rb
index 5e557e9ea53..886077191ab 100644
--- a/app/services/design_management/copy_design_collection/copy_service.rb
+++ b/app/services/design_management/copy_design_collection/copy_service.rb
@@ -16,7 +16,7 @@ module DesignManagement
@temporary_branch = "CopyDesignCollectionService_#{SecureRandom.hex}"
# The user who triggered the copy may not have permissions to push
# to the design repository.
- @git_user = @target_project.default_owner
+ @git_user = @target_project.first_owner
@designs = DesignManagement::Design.unscoped.where(issue: issue).order(:id).load
@versions = DesignManagement::Version.unscoped.where(issue: issue).order(:id).includes(:designs).load
diff --git a/app/services/emails/confirm_service.rb b/app/services/emails/confirm_service.rb
index 38204e011dd..4ceff4e3cfa 100644
--- a/app/services/emails/confirm_service.rb
+++ b/app/services/emails/confirm_service.rb
@@ -7,3 +7,5 @@ module Emails
end
end
end
+
+Emails::ConfirmService.prepend_mod
diff --git a/app/services/error_tracking/collect_error_service.rb b/app/services/error_tracking/collect_error_service.rb
index 304e3898ee5..50508c9810a 100644
--- a/app/services/error_tracking/collect_error_service.rb
+++ b/app/services/error_tracking/collect_error_service.rb
@@ -2,6 +2,8 @@
module ErrorTracking
class CollectErrorService < ::BaseService
+ include Gitlab::Utils::StrongMemoize
+
def execute
# Error is a way to group events based on common data like name or cause
# of exception. We need to keep a sane balance here between taking too little
@@ -43,16 +45,29 @@ module ErrorTracking
end
def exception
- event['exception']['values'].first
+ strong_memoize(:exception) do
+ # Find the first exception that has a stacktrace since the first
+ # exception may not provide adequate context (e.g. in the Go SDK).
+ entries = event['exception']['values']
+ entries.find { |x| x.key?('stacktrace') } || entries.first
+ end
+ end
+
+ def stacktrace_frames
+ strong_memoize(:stacktrace_frames) do
+ exception.dig('stacktrace', 'frames')
+ end
end
def actor
return event['transaction'] if event['transaction']
- # Some SDK do not have transaction attribute.
+ # Some SDKs do not have a transaction attribute.
# So we build it by combining function name and module name from
# the last item in stacktrace.
- last_line = exception.dig('stacktrace', 'frames').last
+ return unless stacktrace_frames.present?
+
+ last_line = stacktrace_frames.last
"#{last_line['function']}(#{last_line['module']})"
end
diff --git a/app/services/events/destroy_service.rb b/app/services/events/destroy_service.rb
index fdb718f0fcb..3a0a7b339bf 100644
--- a/app/services/events/destroy_service.rb
+++ b/app/services/events/destroy_service.rb
@@ -2,20 +2,29 @@
module Events
class DestroyService
+ BATCH_SIZE = 50
+
def initialize(project)
@project = project
end
def execute
- project.events.all.delete_all
+ loop do
+ count = delete_events_in_batches
+ break if count < BATCH_SIZE
+ end
ServiceResponse.success(message: 'Events were deleted.')
- rescue StandardError
- ServiceResponse.error(message: 'Failed to remove events.')
+ rescue StandardError => e
+ ServiceResponse.error(message: e.message)
end
private
attr_reader :project
+
+ def delete_events_in_batches
+ project.events.limit(BATCH_SIZE).delete_all
+ end
end
end
diff --git a/app/services/google_cloud/create_service_accounts_service.rb b/app/services/google_cloud/create_service_accounts_service.rb
new file mode 100644
index 00000000000..fa025e8f672
--- /dev/null
+++ b/app/services/google_cloud/create_service_accounts_service.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+module GoogleCloud
+ class CreateServiceAccountsService < :: BaseService
+ def execute
+ service_account = google_api_client.create_service_account(gcp_project_id, service_account_name, service_account_desc)
+ service_account_key = google_api_client.create_service_account_key(gcp_project_id, service_account.unique_id)
+
+ service_accounts_service.add_for_project(
+ environment_name,
+ service_account.project_id,
+ service_account.to_json,
+ service_account_key.to_json,
+ environment_protected?
+ )
+
+ ServiceResponse.success(message: _('Service account generated successfully'), payload: {
+ service_account: service_account,
+ service_account_key: service_account_key
+ })
+ end
+
+ private
+
+ def google_oauth2_token
+ @params[:google_oauth2_token]
+ end
+
+ def gcp_project_id
+ @params[:gcp_project_id]
+ end
+
+ def environment_name
+ @params[:environment_name]
+ end
+
+ def google_api_client
+ GoogleApi::CloudPlatform::Client.new(google_oauth2_token, nil)
+ end
+
+ def service_accounts_service
+ GoogleCloud::ServiceAccountsService.new(project)
+ end
+
+ def service_account_name
+ "GitLab :: #{project.name} :: #{environment_name}"
+ end
+
+ def service_account_desc
+ "GitLab generated service account for project '#{project.name}' and environment '#{environment_name}'"
+ end
+
+ # Overriden in EE
+ def environment_protected?
+ false
+ end
+ end
+end
+
+GoogleCloud::CreateServiceAccountsService.prepend_mod
diff --git a/app/services/google_cloud/service_accounts_service.rb b/app/services/google_cloud/service_accounts_service.rb
index a512b27493d..3014daf08e2 100644
--- a/app/services/google_cloud/service_accounts_service.rb
+++ b/app/services/google_cloud/service_accounts_service.rb
@@ -27,39 +27,42 @@ module GoogleCloud
end
end
- def add_for_project(environment, gcp_project_id, service_account, service_account_key)
+ def add_for_project(environment, gcp_project_id, service_account, service_account_key, is_protected)
project_var_create_or_replace(
environment,
'GCP_PROJECT_ID',
- gcp_project_id
+ gcp_project_id,
+ is_protected
)
project_var_create_or_replace(
environment,
'GCP_SERVICE_ACCOUNT',
- service_account
+ service_account,
+ is_protected
)
project_var_create_or_replace(
environment,
'GCP_SERVICE_ACCOUNT_KEY',
- service_account_key
+ service_account_key,
+ is_protected
)
end
private
def group_vars_by_environment
- filtered_vars = @project.variables.filter { |variable| GCP_KEYS.include? variable.key }
+ filtered_vars = project.variables.filter { |variable| GCP_KEYS.include? variable.key }
filtered_vars.each_with_object({}) do |variable, grouped|
grouped[variable.environment_scope] ||= {}
grouped[variable.environment_scope][variable.key] = variable.value
end
end
- def project_var_create_or_replace(environment_scope, key, value)
+ 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 = ::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: true)
+ project.variables.create!(key: key, value: value, environment_scope: environment_scope, protected: is_protected)
end
end
end
diff --git a/app/services/groups/update_service.rb b/app/services/groups/update_service.rb
index 2d6334251ad..b3b0397eac3 100644
--- a/app/services/groups/update_service.rb
+++ b/app/services/groups/update_service.rb
@@ -107,6 +107,7 @@ module Groups
def handle_changes
handle_settings_update
+ handle_crm_settings_update unless params[:crm_enabled].nil?
end
def handle_settings_update
@@ -116,6 +117,15 @@ module Groups
::NamespaceSettings::UpdateService.new(current_user, group, settings_params).execute
end
+ def handle_crm_settings_update
+ crm_enabled = params.delete(:crm_enabled)
+ return if group.crm_enabled? == crm_enabled
+
+ crm_settings = group.crm_settings || group.build_crm_settings
+ crm_settings.enabled = crm_enabled
+ crm_settings.save
+ end
+
def allowed_settings_params
SETTINGS_PARAMS
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
index bbfdaf692f9..edb9dc8ad91 100644
--- 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
@@ -4,7 +4,10 @@ module Import
module GitlabProjects
class CreateProjectFromRemoteFileService < CreateProjectFromUploadedFileService
FILE_SIZE_LIMIT = 10.gigabytes
- ALLOWED_CONTENT_TYPES = ['application/gzip'].freeze
+ 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
@@ -44,17 +47,27 @@ module Import
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(',')
+ 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
@@ -64,6 +77,10 @@ module Import
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?
diff --git a/app/services/import/validate_remote_git_endpoint_service.rb b/app/services/import/validate_remote_git_endpoint_service.rb
index afccb5373a9..1b8fa45e979 100644
--- a/app/services/import/validate_remote_git_endpoint_service.rb
+++ b/app/services/import/validate_remote_git_endpoint_service.rb
@@ -23,6 +23,8 @@ module Import
return ServiceResponse.error(message: "#{@params[:url]} is not a valid URL") unless uri
+ return ServiceResponse.success if uri.scheme == 'git'
+
uri.fragment = nil
url = Gitlab::Utils.append_path(uri.to_s, "/info/refs?service=#{GIT_SERVICE_NAME}")
diff --git a/app/services/incident_management/issuable_escalation_statuses/after_update_service.rb b/app/services/incident_management/issuable_escalation_statuses/after_update_service.rb
new file mode 100644
index 00000000000..a7a99f88b32
--- /dev/null
+++ b/app/services/incident_management/issuable_escalation_statuses/after_update_service.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module IncidentManagement
+ module IssuableEscalationStatuses
+ class AfterUpdateService < ::BaseProjectService
+ def initialize(issuable, current_user)
+ @issuable = issuable
+ @escalation_status = issuable.escalation_status
+ @alert = issuable.alert_management_alert
+
+ super(project: issuable.project, current_user: current_user)
+ end
+
+ def execute
+ after_update
+
+ ServiceResponse.success(payload: { escalation_status: escalation_status })
+ end
+
+ private
+
+ attr_reader :issuable, :escalation_status, :alert
+
+ def after_update
+ sync_to_alert
+ end
+
+ def sync_to_alert
+ return unless alert
+ return if alert.status == escalation_status.status
+
+ ::AlertManagement::Alerts::UpdateService.new(
+ alert,
+ current_user,
+ status: escalation_status.status_name
+ ).execute
+ end
+ end
+ end
+end
+
+::IncidentManagement::IssuableEscalationStatuses::AfterUpdateService.prepend_mod
diff --git a/app/services/incident_management/issuable_escalation_statuses/prepare_update_service.rb b/app/services/incident_management/issuable_escalation_statuses/prepare_update_service.rb
new file mode 100644
index 00000000000..1a660e1a163
--- /dev/null
+++ b/app/services/incident_management/issuable_escalation_statuses/prepare_update_service.rb
@@ -0,0 +1,99 @@
+# frozen_string_literal: true
+
+module IncidentManagement
+ module IssuableEscalationStatuses
+ class PrepareUpdateService
+ include Gitlab::Utils::StrongMemoize
+
+ SUPPORTED_PARAMS = %i[status].freeze
+
+ InvalidParamError = Class.new(StandardError)
+
+ def initialize(issuable, current_user, params)
+ @issuable = issuable
+ @current_user = current_user
+ @params = params.dup || {}
+ @project = issuable.project
+ end
+
+ def execute
+ return availability_error unless available?
+
+ filter_unsupported_params
+ filter_attributes
+ filter_redundant_params
+
+ ServiceResponse.success(payload: { escalation_status: params })
+ rescue InvalidParamError
+ invalid_param_error
+ end
+
+ private
+
+ attr_reader :issuable, :current_user, :params, :project
+
+ def available?
+ Feature.enabled?(:incident_escalations, project) &&
+ user_has_permissions? &&
+ issuable.supports_escalation? &&
+ escalation_status.present?
+ end
+
+ def user_has_permissions?
+ current_user&.can?(:update_escalation_status, issuable)
+ end
+
+ def escalation_status
+ strong_memoize(:escalation_status) do
+ issuable.escalation_status
+ end
+ end
+
+ def filter_unsupported_params
+ params.slice!(*supported_params)
+ end
+
+ def supported_params
+ SUPPORTED_PARAMS
+ end
+
+ def filter_attributes
+ filter_status
+ end
+
+ def filter_status
+ status = params.delete(:status)
+ return unless status
+
+ status_event = escalation_status.status_event_for(status)
+ raise InvalidParamError unless status_event
+
+ params[:status_event] = status_event
+ end
+
+ def filter_redundant_params
+ params.delete_if do |key, value|
+ current_params.key?(key) && current_params[key] == value
+ end
+ end
+
+ def current_params
+ strong_memoize(:current_params) do
+ {
+ status_event: escalation_status.status_event_for(escalation_status.status_name)
+ }
+ end
+ end
+
+ def availability_error
+ ServiceResponse.error(message: 'Escalation status updates are not available for this issue, user, or project.')
+ end
+
+ def invalid_param_error
+ ServiceResponse.error(message: 'Invalid value was provided for a parameter.')
+ end
+ end
+ end
+end
+
+::IncidentManagement::IssuableEscalationStatuses::PrepareUpdateService.prepend_mod
diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb
index 1d1d9b6bec7..ecf10cf97a8 100644
--- a/app/services/issuable_base_service.rb
+++ b/app/services/issuable_base_service.rb
@@ -63,6 +63,7 @@ class IssuableBaseService < ::BaseProjectService
filter_milestone
filter_labels
filter_severity(issuable)
+ filter_escalation_status(issuable)
end
def filter_assignees(issuable)
@@ -152,6 +153,18 @@ class IssuableBaseService < ::BaseProjectService
params[:issuable_severity_attributes] = { severity: severity }
end
+ def filter_escalation_status(issuable)
+ result = ::IncidentManagement::IssuableEscalationStatuses::PrepareUpdateService.new(
+ issuable,
+ current_user,
+ params.delete(:escalation_status)
+ ).execute
+
+ return unless result.success? && result.payload.present?
+
+ params[:incident_management_issuable_escalation_status_attributes] = result[:escalation_status]
+ end
+
def process_label_ids(attributes, existing_label_ids: nil, extra_label_ids: [])
label_ids = attributes.delete(:label_ids)
add_label_ids = attributes.delete(:add_label_ids)
@@ -471,6 +484,7 @@ 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?
associations
end
diff --git a/app/services/issues/base_service.rb b/app/services/issues/base_service.rb
index 577f7dd1e3a..37d667d4be8 100644
--- a/app/services/issues/base_service.rb
+++ b/app/services/issues/base_service.rb
@@ -36,8 +36,8 @@ module Issues
private
def find_work_item_type_id(issue_type)
- work_item_type = WorkItem::Type.default_by_type(issue_type)
- work_item_type ||= WorkItem::Type.default_issue_type
+ work_item_type = WorkItems::Type.default_by_type(issue_type)
+ work_item_type ||= WorkItems::Type.default_issue_type
work_item_type.id
end
@@ -46,7 +46,6 @@ module Issues
super
params.delete(:issue_type) unless create_issue_type_allowed?(issue, params[:issue_type])
- filter_incident_label(issue) if params[:issue_type]
moved_issue = params.delete(:moved_issue)
@@ -89,37 +88,6 @@ module Issues
Milestones::IssuesCountService.new(milestone).delete_cache
end
-
- # @param issue [Issue]
- def filter_incident_label(issue)
- return unless add_incident_label?(issue) || remove_incident_label?(issue)
-
- label = ::IncidentManagement::CreateIncidentLabelService
- .new(project, current_user)
- .execute
- .payload[:label]
-
- # These(add_label_ids, remove_label_ids) are being added ahead of time
- # to be consumed by #process_label_ids, this allows system notes
- # to be applied correctly alongside the label updates.
- if add_incident_label?(issue)
- params[:add_label_ids] ||= []
- params[:add_label_ids] << label.id
- else
- params[:remove_label_ids] ||= []
- params[:remove_label_ids] << label.id
- end
- end
-
- # @param issue [Issue]
- def add_incident_label?(issue)
- issue.incident?
- end
-
- # @param _issue [Issue, nil]
- def remove_incident_label?(_issue)
- false
- end
end
end
diff --git a/app/services/issues/build_service.rb b/app/services/issues/build_service.rb
index 8fd844c4886..1ebf9bb6ba2 100644
--- a/app/services/issues/build_service.rb
+++ b/app/services/issues/build_service.rb
@@ -7,7 +7,7 @@ module Issues
def execute
filter_resolve_discussion_params
- @issue = project.issues.new(issue_params).tap do |issue|
+ @issue = model_klass.new(issue_params.merge(project: project)).tap do |issue|
ensure_milestone_available(issue)
end
end
@@ -62,16 +62,25 @@ module Issues
def issue_params
@issue_params ||= build_issue_params
- # If :issue_type is nil then params[:issue_type] was either nil
- # or not permitted. Either way, the :issue_type will default
- # to the column default of `issue`. And that means we need to
- # ensure the work_item_type_id is set
- @issue_params[:work_item_type_id] = get_work_item_type_id(@issue_params[:issue_type])
+ if @issue_params[:work_item_type].present?
+ @issue_params[:issue_type] = @issue_params[:work_item_type].base_type
+ else
+ # If :issue_type is nil then params[:issue_type] was either nil
+ # or not permitted. Either way, the :issue_type will default
+ # to the column default of `issue`. And that means we need to
+ # ensure the work_item_type_id is set
+ @issue_params[:work_item_type_id] = get_work_item_type_id(@issue_params[:issue_type])
+ end
+
@issue_params
end
private
+ def model_klass
+ ::Issue
+ end
+
def allowed_issue_params
allowed_params = [
:title,
@@ -79,8 +88,11 @@ module Issues
:confidential
]
+ params[:work_item_type] = WorkItems::Type.find_by(id: params[:work_item_type_id]) if params[:work_item_type_id].present? # rubocop: disable CodeReuse/ActiveRecord
+
allowed_params << :milestone_id if can?(current_user, :admin_issue, project)
allowed_params << :issue_type if create_issue_type_allowed?(project, params[:issue_type])
+ allowed_params << :work_item_type if create_issue_type_allowed?(project, params[:work_item_type]&.base_type)
params.slice(*allowed_params)
end
diff --git a/app/services/issues/create_service.rb b/app/services/issues/create_service.rb
index 79b59eee5e1..e29bcf4a453 100644
--- a/app/services/issues/create_service.rb
+++ b/app/services/issues/create_service.rb
@@ -12,13 +12,14 @@ module Issues
# spam_checking is likely to be necessary. However, if there is not a request available in scope
# in the caller (for example, an issue 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:)
+ def initialize(project:, current_user: nil, params: {}, spam_params:, build_service: nil)
super(project: project, current_user: current_user, params: params)
@spam_params = spam_params
+ @build_service = build_service || BuildService.new(project: project, current_user: current_user, params: params)
end
def execute(skip_system_notes: false)
- @issue = BuildService.new(project: project, current_user: current_user, params: params).execute
+ @issue = @build_service.execute
filter_resolve_discussion_params
diff --git a/app/services/issues/set_crm_contacts_service.rb b/app/services/issues/set_crm_contacts_service.rb
index c435ab81b4d..947d46f0809 100644
--- a/app/services/issues/set_crm_contacts_service.rb
+++ b/app/services/issues/set_crm_contacts_service.rb
@@ -48,7 +48,7 @@ module Issues
end
def add_by_email
- contact_ids = ::CustomerRelations::Contact.find_ids_by_emails(project_group.id, params[:add_emails])
+ contact_ids = ::CustomerRelations::Contact.find_ids_by_emails(project_group, params[: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 824a609dfb9..aecb22453b7 100644
--- a/app/services/issues/update_service.rb
+++ b/app/services/issues/update_service.rb
@@ -53,6 +53,7 @@ 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)
@@ -69,6 +70,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_issue_type_change(issue)
end
@@ -208,6 +210,13 @@ 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
+
+ ::IncidentManagement::IssuableEscalationStatuses::AfterUpdateService.new(issue, current_user).execute
+ end
+
# rubocop: disable CodeReuse/ActiveRecord
def issuable_for_positioning(id, board_group_id = nil)
return unless id
@@ -227,16 +236,6 @@ module Issues
SystemNoteService.change_issue_confidentiality(issue, issue.project, current_user)
end
- override :add_incident_label?
- def add_incident_label?(issue)
- issue.issue_type != params[:issue_type] && !issue.incident?
- end
-
- override :remove_incident_label?
- def remove_incident_label?(issue)
- issue.issue_type != params[:issue_type] && issue.incident?
- end
-
def handle_issue_type_change(issue)
return unless issue.previous_changes.include?('issue_type')
@@ -245,6 +244,8 @@ module Issues
def do_handle_issue_type_change(issue)
SystemNoteService.change_issue_type(issue, current_user)
+
+ ::IncidentManagement::IssuableEscalationStatuses::CreateService.new(issue).execute if issue.supports_escalation?
end
end
end
diff --git a/app/services/labels/transfer_service.rb b/app/services/labels/transfer_service.rb
index 19d419609a5..67163cb8122 100644
--- a/app/services/labels/transfer_service.rb
+++ b/app/services/labels/transfer_service.rb
@@ -50,32 +50,17 @@ module Labels
# rubocop: disable CodeReuse/ActiveRecord
def group_labels_applied_to_issues
- @labels_applied_to_issues ||= if use_optimized_group_labels_query?
- Label.joins(:issues)
- .joins("INNER JOIN namespaces on namespaces.id = labels.group_id AND namespaces.type = 'Group'" )
- .where(issues: { project_id: project.id }).reorder(nil)
- else
- Label.joins(:issues).where(
- issues: { project_id: project.id },
- labels: { group_id: old_group.self_and_ancestors }
- )
- end
+ @labels_applied_to_issues ||= Label.joins(:issues)
+ .joins("INNER JOIN namespaces on namespaces.id = labels.group_id AND namespaces.type = 'Group'" )
+ .where(issues: { project_id: project.id }).reorder(nil)
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def group_labels_applied_to_merge_requests
- @labels_applied_to_mrs ||= if use_optimized_group_labels_query?
- Label.joins(:merge_requests)
- .joins("INNER JOIN namespaces on namespaces.id = labels.group_id AND namespaces.type = 'Group'" )
- .where(merge_requests: { target_project_id: project.id }).reorder(nil)
- else
- Label.joins(:merge_requests)
- .where(
- merge_requests: { target_project_id: project.id },
- labels: { group_id: old_group.self_and_ancestors }
- )
- end
+ @labels_applied_to_mrs ||= Label.joins(:merge_requests)
+ .joins("INNER JOIN namespaces on namespaces.id = labels.group_id AND namespaces.type = 'Group'" )
+ .where(merge_requests: { target_project_id: project.id }).reorder(nil)
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -99,9 +84,5 @@ module Labels
.update_all(label_id: new_label_id)
end
# rubocop: enable CodeReuse/ActiveRecord
-
- def use_optimized_group_labels_query?
- Feature.enabled?(:use_optimized_group_labels_query, project.root_namespace, default_enabled: :yaml)
- end
end
end
diff --git a/app/services/loose_foreign_keys/process_deleted_records_service.rb b/app/services/loose_foreign_keys/process_deleted_records_service.rb
index 025829aa774..2826bdb4c3c 100644
--- a/app/services/loose_foreign_keys/process_deleted_records_service.rb
+++ b/app/services/loose_foreign_keys/process_deleted_records_service.rb
@@ -10,7 +10,6 @@ module LooseForeignKeys
def execute
modification_tracker = ModificationTracker.new
-
tracked_tables.cycle do |table|
records = load_batch_for_table(table)
diff --git a/app/services/merge_requests/add_todo_when_build_fails_service.rb b/app/services/merge_requests/add_todo_when_build_fails_service.rb
index d3ef892875b..47cd19e9d8d 100644
--- a/app/services/merge_requests/add_todo_when_build_fails_service.rb
+++ b/app/services/merge_requests/add_todo_when_build_fails_service.rb
@@ -16,9 +16,7 @@ module MergeRequests
# build is retried
#
def close(commit_status)
- pipeline_merge_requests(commit_status.pipeline) do |merge_request|
- todo_service.merge_request_build_retried(merge_request)
- end
+ close_all(commit_status.pipeline)
end
def close_all(pipeline)
diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb
index d744881549a..b0d0c32abd1 100644
--- a/app/services/merge_requests/base_service.rb
+++ b/app/services/merge_requests/base_service.rb
@@ -59,7 +59,9 @@ module MergeRequests
merge_request_activity_counter.track_users_review_requested(users: new_reviewers)
merge_request_activity_counter.track_reviewers_changed_action(user: current_user)
- remove_attention_requested(merge_request, current_user)
+ unless new_reviewers.include?(current_user)
+ remove_attention_requested(merge_request, current_user)
+ end
end
def cleanup_environments(merge_request)
diff --git a/app/services/merge_requests/handle_assignees_change_service.rb b/app/services/merge_requests/handle_assignees_change_service.rb
index 1d9f7ab59f4..97be9fe8d9f 100644
--- a/app/services/merge_requests/handle_assignees_change_service.rb
+++ b/app/services/merge_requests/handle_assignees_change_service.rb
@@ -23,7 +23,9 @@ module MergeRequests
execute_assignees_hooks(merge_request, old_assignees) if options[:execute_hooks]
- remove_attention_requested(merge_request, current_user)
+ unless new_assignees.include?(current_user)
+ remove_attention_requested(merge_request, current_user)
+ end
end
private
diff --git a/app/services/merge_requests/merge_base_service.rb b/app/services/merge_requests/merge_base_service.rb
index 3b9d3bccacf..3e630d40b3d 100644
--- a/app/services/merge_requests/merge_base_service.rb
+++ b/app/services/merge_requests/merge_base_service.rb
@@ -56,7 +56,7 @@ module MergeRequests
def commit_message
params[:commit_message] ||
- merge_request.default_merge_commit_message
+ merge_request.default_merge_commit_message(user: current_user)
end
def squash_sha!
diff --git a/app/services/merge_requests/remove_approval_service.rb b/app/services/merge_requests/remove_approval_service.rb
index 872e7e0c89c..198a21884b8 100644
--- a/app/services/merge_requests/remove_approval_service.rb
+++ b/app/services/merge_requests/remove_approval_service.rb
@@ -17,6 +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)
end
success
diff --git a/app/services/merge_requests/squash_service.rb b/app/services/merge_requests/squash_service.rb
index 90cf4af7e41..69b9740c2a5 100644
--- a/app/services/merge_requests/squash_service.rb
+++ b/app/services/merge_requests/squash_service.rb
@@ -39,7 +39,7 @@ module MergeRequests
end
def message
- params[:squash_commit_message].presence || merge_request.default_squash_commit_message
+ params[:squash_commit_message].presence || merge_request.default_squash_commit_message(user: current_user)
end
end
end
diff --git a/app/services/packages/maven/metadata/sync_service.rb b/app/services/packages/maven/metadata/sync_service.rb
index 48e157d4930..4f35db36fb0 100644
--- a/app/services/packages/maven/metadata/sync_service.rb
+++ b/app/services/packages/maven/metadata/sync_service.rb
@@ -93,10 +93,15 @@ module Packages
def metadata_package_file_for(package)
return unless package
- package.package_files
- .with_file_name(Metadata.filename)
- .recent
- .first
+ package_files = if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml)
+ package.installable_package_files
+ else
+ package.package_files
+ end
+
+ package_files.with_file_name(Metadata.filename)
+ .recent
+ .first
end
def versionless_package_named(name)
diff --git a/app/services/packages/terraform_module/create_package_service.rb b/app/services/packages/terraform_module/create_package_service.rb
index 03f749edfa8..d1bc79089a3 100644
--- a/app/services/packages/terraform_module/create_package_service.rb
+++ b/app/services/packages/terraform_module/create_package_service.rb
@@ -7,7 +7,7 @@ module Packages
def execute
return error('Version is empty.', 400) if params[:module_version].blank?
- return error('Package already exists.', 403) if current_package_exists_elsewhere?
+ return error('Access Denied', 403) if current_package_exists_elsewhere?
return error('Package version already exists.', 403) if current_package_version_exists?
return error('File is too large.', 400) if file_size_exceeded?
diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb
index aef92b8adee..5c4a0e947de 100644
--- a/app/services/projects/destroy_service.rb
+++ b/app/services/projects/destroy_service.rb
@@ -41,6 +41,8 @@ module Projects
true
rescue StandardError => error
+ context = Gitlab::ApplicationContext.current.merge(project_id: project.id)
+ Gitlab::ErrorTracking.track_exception(error, **context)
attempt_rollback(project, error.message)
false
rescue Exception => error # rubocop:disable Lint/RescueException
@@ -80,8 +82,14 @@ module Projects
end
def remove_events
+ log_info("Attempting to destroy events from #{project.full_path} (#{project.id})")
+
response = ::Events::DestroyService.new(project).execute
+ if response.error?
+ log_error("Event deletion failed on #{project.full_path} with the following message: #{response.message}")
+ end
+
response.success?
end
diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb
index 74b7d18f401..3e8d6563709 100644
--- a/app/services/projects/fork_service.rb
+++ b/app/services/projects/fork_service.rb
@@ -69,6 +69,8 @@ module Projects
new_params[:avatar] = @project.avatar
end
+ new_params[:mr_default_target_self] = target_mr_default_target_self unless target_mr_default_target_self.nil?
+
new_params.merge!(@project.object_pool_params)
new_params
@@ -127,5 +129,9 @@ module Projects
Gitlab::VisibilityLevel.closest_allowed_level(target_level)
end
+
+ def target_mr_default_target_self
+ @target_mr_default_target_self ||= params[:mr_default_target_self]
+ end
end
end
diff --git a/app/services/projects/overwrite_project_service.rb b/app/services/projects/overwrite_project_service.rb
index 2612001eb95..c58fba33b2a 100644
--- a/app/services/projects/overwrite_project_service.rb
+++ b/app/services/projects/overwrite_project_service.rb
@@ -11,7 +11,9 @@ module Projects
move_before_destroy_relationships(source_project)
# Reset is required in order to get the proper
# uncached fork network method calls value.
- destroy_old_project(source_project.reset)
+ ::Gitlab::Database::QueryAnalyzers::PreventCrossDatabaseModification.allow_cross_database_modification_within_transaction(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/340256') do
+ destroy_old_project(source_project.reset)
+ end
rename_project(source_project.name, source_project.path)
@project
diff --git a/app/services/projects/prometheus/alerts/notify_service.rb b/app/services/projects/prometheus/alerts/notify_service.rb
index 56f65718d24..bc517ee3d6f 100644
--- a/app/services/projects/prometheus/alerts/notify_service.rb
+++ b/app/services/projects/prometheus/alerts/notify_service.rb
@@ -18,6 +18,14 @@ module Projects
SUPPORTED_VERSION = '4'
+ # If feature flag :prometheus_notify_max_alerts is enabled truncate
+ # alerts to 100 and process only them.
+ # If feature flag is disabled process any amount of alerts.
+ #
+ # This is to mitigate incident:
+ # https://gitlab.com/gitlab-com/gl-infra/production/-/issues/6086
+ PROCESS_MAX_ALERTS = 100
+
def initialize(project, payload)
@project = project
@payload = payload
@@ -28,6 +36,8 @@ module Projects
return unprocessable_entity unless self.class.processable?(payload)
return unauthorized unless valid_alert_manager_token?(token, integration)
+ truncate_alerts! if max_alerts_exceeded?
+
alert_responses = process_prometheus_alerts
alert_response(alert_responses)
@@ -49,12 +59,23 @@ module Projects
Gitlab::Utils::DeepSize.new(payload).valid?
end
- def firings
- @firings ||= alerts_by_status('firing')
+ def max_alerts_exceeded?
+ return false unless Feature.enabled?(:prometheus_notify_max_alerts, project, type: :ops)
+
+ alerts.size > PROCESS_MAX_ALERTS
end
- def alerts_by_status(status)
- alerts.select { |alert| alert['status'] == status }
+ def truncate_alerts!
+ Gitlab::AppLogger.warn(
+ message: 'Prometheus payload exceeded maximum amount of alerts. Truncating alerts.',
+ project_id: project.id,
+ alerts: {
+ total: alerts.size,
+ max: PROCESS_MAX_ALERTS
+ }
+ )
+
+ payload['alerts'] = alerts.first(PROCESS_MAX_ALERTS)
end
def alerts
@@ -137,7 +158,7 @@ module Projects
end
def alert_response(alert_responses)
- alerts = alert_responses.map { |resp| resp.payload[:alert] }.compact
+ alerts = alert_responses.flat_map { |resp| resp.payload[:alerts] }.compact
success(alerts)
end
diff --git a/app/services/projects/update_pages_configuration_service.rb b/app/services/projects/update_pages_configuration_service.rb
deleted file mode 100644
index 4272e1dc8b6..00000000000
--- a/app/services/projects/update_pages_configuration_service.rb
+++ /dev/null
@@ -1,109 +0,0 @@
-# frozen_string_literal: true
-
-module Projects
- class UpdatePagesConfigurationService < BaseService
- include Gitlab::Utils::StrongMemoize
-
- attr_reader :project
-
- def initialize(project)
- @project = project
- end
-
- def execute
- return success unless ::Settings.pages.local_store.enabled
-
- # If the pages were never deployed, we can't write out the config, as the
- # directory would not exist.
- # https://gitlab.com/gitlab-org/gitlab/-/issues/235139
- return success unless project.pages_deployed?
-
- unless file_equals?(pages_config_file, pages_config_json)
- update_file(pages_config_file, pages_config_json)
- reload_daemon
- end
-
- success
- end
-
- private
-
- def pages_config_json
- strong_memoize(:pages_config_json) do
- pages_config.to_json
- end
- end
-
- def pages_config
- {
- domains: pages_domains_config,
- https_only: project.pages_https_only?,
- id: project.project_id,
- access_control: !project.public_pages?
- }
- end
-
- def pages_domains_config
- enabled_pages_domains.map do |domain|
- {
- domain: domain.domain,
- certificate: domain.certificate,
- key: domain.key,
- https_only: project.pages_https_only? && domain.https?,
- id: project.project_id,
- access_control: !project.public_pages?
- }
- end
- end
-
- def enabled_pages_domains
- if Gitlab::CurrentSettings.pages_domain_verification_enabled?
- project.pages_domains.enabled
- else
- project.pages_domains
- end
- end
-
- def reload_daemon
- # GitLab Pages daemon constantly watches for modification time of `pages.path`
- # It reloads configuration when `pages.path` is modified
- update_file(pages_update_file, SecureRandom.hex(64))
- end
-
- def pages_path
- @pages_path ||= project.pages_path
- end
-
- def pages_config_file
- File.join(pages_path, 'config.json')
- end
-
- def pages_update_file
- File.join(::Settings.pages.path, '.update')
- end
-
- def update_file(file, data)
- temp_file = "#{file}.#{SecureRandom.hex(16)}"
- File.open(temp_file, 'w') do |f|
- f.write(data)
- end
- FileUtils.move(temp_file, file, force: true)
- ensure
- # In case if the updating fails
- FileUtils.remove(temp_file, force: true)
- end
-
- def file_equals?(file, data)
- existing_data = read_file(file)
- data == existing_data.to_s
- end
-
- def read_file(file)
- File.open(file, 'r') do |f|
- f.read
- end
- rescue StandardError
- nil
- end
- end
-end
diff --git a/app/services/projects/update_remote_mirror_service.rb b/app/services/projects/update_remote_mirror_service.rb
index 898125c181c..f3ea0967a99 100644
--- a/app/services/projects/update_remote_mirror_service.rb
+++ b/app/services/projects/update_remote_mirror_service.rb
@@ -41,18 +41,49 @@ module Projects
remote_mirror.update_start!
# LFS objects must be sent first, or the push has dangling pointers
- send_lfs_objects!(remote_mirror)
+ lfs_status = send_lfs_objects!(remote_mirror)
response = remote_mirror.update_repository
+ failed, failure_message = failure_status(lfs_status, response, remote_mirror)
+
+ # When the issue https://gitlab.com/gitlab-org/gitlab/-/issues/349262 is closed,
+ # we can move this block within failure_status.
+ if failed
+ remote_mirror.mark_as_failed!(failure_message)
+ else
+ remote_mirror.update_finish!
+ end
+ end
+
+ def failure_status(lfs_status, response, remote_mirror)
+ message = ''
+ failed = false
+ lfs_sync_failed = false
+
+ if lfs_status&.dig(:status) == :error
+ lfs_sync_failed = true
+ message += "Error synchronizing LFS files:"
+ message += "\n\n#{lfs_status[:message]}\n\n"
+
+ failed = Feature.enabled?(:remote_mirror_fail_on_lfs, project, default_enabled: :yaml)
+ end
if response.divergent_refs.any?
- message = "Some refs have diverged and have not been updated on the remote:"
+ message += "Some refs have diverged and have not been updated on the remote:"
message += "\n\n#{response.divergent_refs.join("\n")}"
+ failed = true
+ end
- remote_mirror.mark_as_failed!(message)
- else
- remote_mirror.update_finish!
+ if message.present?
+ Gitlab::AppJsonLogger.info(message: "Error synching remote mirror",
+ project_id: project.id,
+ project_path: project.full_path,
+ remote_mirror_id: remote_mirror.id,
+ lfs_sync_failed: lfs_sync_failed,
+ divergent_ref_list: response.divergent_refs)
end
+
+ [failed, message]
end
def send_lfs_objects!(remote_mirror)
diff --git a/app/services/projects/update_service.rb b/app/services/projects/update_service.rb
index b34ecf06e52..fb810af3e6b 100644
--- a/app/services/projects/update_service.rb
+++ b/app/services/projects/update_service.rb
@@ -104,7 +104,6 @@ module Projects
system_hook_service.execute_hooks_for(project, :update)
end
- update_pages_config if changing_pages_related_config?
update_pending_builds if runners_settings_toggled?
end
@@ -112,10 +111,6 @@ module Projects
AfterRenameService.new(project, path_before: project.path_before_last_save, full_path_before: project.full_path_before_last_save)
end
- def changing_pages_related_config?
- changing_pages_https_only? || changing_pages_access_level?
- end
-
def update_failed!
model_errors = project.errors.full_messages.to_sentence
error_message = model_errors.presence || s_('UpdateProject|Project could not be updated!')
@@ -143,10 +138,6 @@ module Projects
params.dig(:project_feature_attributes, :wiki_access_level).to_i > ProjectFeature::DISABLED
end
- def changing_pages_access_level?
- params.dig(:project_feature_attributes, :pages_access_level)
- end
-
def ensure_wiki_exists
return if project.create_wiki
@@ -154,16 +145,6 @@ module Projects
Gitlab::Metrics.counter(:wiki_can_not_be_created_total, 'Counts the times we failed to create a wiki').increment
end
- def update_pages_config
- return unless project.pages_deployed?
-
- PagesUpdateConfigurationWorker.perform_async(project.id)
- end
-
- def changing_pages_https_only?
- project.previous_changes.include?(:pages_https_only)
- end
-
def changing_repository_storage?
new_repository_storage = params[:repository_storage]
diff --git a/app/services/resource_access_tokens/create_service.rb b/app/services/resource_access_tokens/create_service.rb
index e0371e5d80f..28ea1ac8296 100644
--- a/app/services/resource_access_tokens/create_service.rb
+++ b/app/services/resource_access_tokens/create_service.rb
@@ -63,7 +63,7 @@ module ResourceAccessTokens
name: params[:name] || "#{resource.name.to_s.humanize} bot",
email: generate_email,
username: generate_username,
- user_type: "#{resource_type}_bot".to_sym,
+ user_type: :project_bot,
skip_confirmation: true # Bot users should always have their emails confirmed.
}
end
@@ -75,7 +75,8 @@ module ResourceAccessTokens
end
def generate_email
- email_pattern = "#{resource_type}#{resource.id}_bot%s@example.com"
+ # Default emaildomain need to be reworked. See gitlab-org/gitlab#260305
+ email_pattern = "#{resource_type}#{resource.id}_bot%s@noreply.#{Gitlab.config.gitlab.host}"
uniquify.string(-> (n) { Kernel.sprintf(email_pattern, n) }) do |s|
User.find_by_email(s)
diff --git a/app/services/resource_access_tokens/revoke_service.rb b/app/services/resource_access_tokens/revoke_service.rb
index 9543ea4b68d..2aaf4cc31d2 100644
--- a/app/services/resource_access_tokens/revoke_service.rb
+++ b/app/services/resource_access_tokens/revoke_service.rb
@@ -43,13 +43,9 @@ module ResourceAccessTokens
def find_member
strong_memoize(:member) do
- if resource.is_a?(Project)
- resource.project_member(bot_user)
- elsif resource.is_a?(Group)
- resource.group_member(bot_user)
- else
- false
- end
+ next false unless resource.is_a?(Project) || resource.is_a?(Group)
+
+ resource.member(bot_user)
end
end
diff --git a/app/services/search_service.rb b/app/services/search_service.rb
index 171d52c328d..28e487aa24d 100644
--- a/app/services/search_service.rb
+++ b/app/services/search_service.rb
@@ -7,6 +7,8 @@ class SearchService
DEFAULT_PER_PAGE = Gitlab::SearchResults::DEFAULT_PER_PAGE
MAX_PER_PAGE = 200
+ attr_reader :params
+
def initialize(current_user, params = {})
@current_user = current_user
@params = Gitlab::Search::Params.new(params, detect_abuse: prevent_abusive_searches?)
@@ -159,7 +161,7 @@ class SearchService
end
end
- attr_reader :current_user, :params
+ attr_reader :current_user
end
SearchService.prepend_mod_with('SearchService')
diff --git a/app/services/users/upsert_credit_card_validation_service.rb b/app/services/users/upsert_credit_card_validation_service.rb
index 61cf598f178..7190c82bea3 100644
--- a/app/services/users/upsert_credit_card_validation_service.rb
+++ b/app/services/users/upsert_credit_card_validation_service.rb
@@ -2,8 +2,9 @@
module Users
class UpsertCreditCardValidationService < BaseService
- def initialize(params)
+ def initialize(params, user)
@params = params.to_h.with_indifferent_access
+ @current_user = user
end
def execute
@@ -18,6 +19,8 @@ module Users
::Users::CreditCardValidation.upsert(@params)
+ ::Users::UpdateService.new(current_user, user: current_user, requires_credit_card_verification: false).execute!
+
ServiceResponse.success(message: 'CreditCardValidation was set')
rescue ActiveRecord::InvalidForeignKey, ActiveRecord::NotNullViolation => e
ServiceResponse.error(message: "Could not set CreditCardValidation: #{e.message}")
diff --git a/app/services/web_hook_service.rb b/app/services/web_hook_service.rb
index 79bdf34392f..33e34ec41e2 100644
--- a/app/services/web_hook_service.rb
+++ b/app/services/web_hook_service.rb
@@ -26,7 +26,6 @@ class WebHookService
end
REQUEST_BODY_SIZE_LIMIT = 25.megabytes
- GITLAB_EVENT_HEADER = 'X-Gitlab-Event'
attr_accessor :hook, :data, :hook_name, :request_options
attr_reader :uniqueness_token
@@ -50,6 +49,10 @@ class WebHookService
def execute
return { status: :error, message: 'Hook disabled' } unless hook.executable?
+ log_recursion_limit if recursion_blocked?
+
+ Gitlab::WebHooks::RecursionDetection.register!(hook)
+
start_time = Gitlab::Metrics::System.monotonic_time
response = if parsed_url.userinfo.blank?
@@ -95,6 +98,10 @@ class WebHookService
Gitlab::ApplicationContext.with_context(hook.application_context) do
break log_rate_limit if rate_limited?
+ log_recursion_limit if recursion_blocked?
+
+ data[:_gitlab_recursion_detection_request_uuid] = Gitlab::WebHooks::RecursionDetection::UUID.instance.request_uuid
+
WebHookWorker.perform_async(hook.id, data, hook_name)
end
end
@@ -108,7 +115,7 @@ class WebHookService
def make_request(url, basic_auth = false)
Gitlab::HTTP.post(url,
body: Gitlab::Json::LimitedEncoder.encode(data, limit: REQUEST_BODY_SIZE_LIMIT),
- headers: build_headers(hook_name),
+ headers: build_headers,
verify: hook.enable_ssl_verification,
basic_auth: basic_auth,
**request_options)
@@ -129,7 +136,7 @@ class WebHookService
trigger: trigger,
url: url,
execution_duration: execution_duration,
- request_headers: build_headers(hook_name),
+ request_headers: build_headers,
request_data: request_data,
response_headers: format_response_headers(response),
response_body: safe_response_body(response),
@@ -151,15 +158,16 @@ class WebHookService
end
end
- def build_headers(hook_name)
+ def build_headers
@headers ||= begin
- {
+ headers = {
'Content-Type' => 'application/json',
'User-Agent' => "GitLab/#{Gitlab::VERSION}",
- GITLAB_EVENT_HEADER => self.class.hook_to_event(hook_name)
- }.tap do |hash|
- hash['X-Gitlab-Token'] = Gitlab::Utils.remove_line_breaks(hook.token) if hook.token.present?
- end
+ Gitlab::WebHooks::GITLAB_EVENT_HEADER => self.class.hook_to_event(hook_name)
+ }
+
+ headers['X-Gitlab-Token'] = Gitlab::Utils.remove_line_breaks(hook.token) if hook.token.present?
+ headers.merge!(Gitlab::WebHooks::RecursionDetection.header(hook))
end
end
@@ -186,6 +194,10 @@ class WebHookService
)
end
+ def recursion_blocked?
+ Gitlab::WebHooks::RecursionDetection.block?(hook)
+ end
+
def rate_limit
@rate_limit ||= hook.rate_limit
end
@@ -199,4 +211,15 @@ class WebHookService
**Gitlab::ApplicationContext.current
)
end
+
+ def log_recursion_limit
+ Gitlab::AuthLogger.error(
+ message: 'Webhook recursion detected and will be blocked in future',
+ hook_id: hook.id,
+ hook_type: hook.type,
+ hook_name: hook_name,
+ recursion_detection: ::Gitlab::WebHooks::RecursionDetection.to_log(hook),
+ **Gitlab::ApplicationContext.current
+ )
+ end
end
diff --git a/app/services/work_items/build_service.rb b/app/services/work_items/build_service.rb
new file mode 100644
index 00000000000..15a26f81d7c
--- /dev/null
+++ b/app/services/work_items/build_service.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module WorkItems
+ class BuildService < ::Issues::BuildService
+ private
+
+ def model_klass
+ ::WorkItem
+ end
+ end
+end
diff --git a/app/services/work_items/create_service.rb b/app/services/work_items/create_service.rb
new file mode 100644
index 00000000000..49f7b89158b
--- /dev/null
+++ b/app/services/work_items/create_service.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module WorkItems
+ class CreateService
+ def initialize(project:, current_user: nil, params: {}, spam_params:)
+ @create_service = ::Issues::CreateService.new(
+ project: project,
+ current_user: current_user,
+ params: params,
+ spam_params: spam_params,
+ build_service: ::WorkItems::BuildService.new(project: project, current_user: current_user, params: params)
+ )
+ end
+
+ def execute
+ @create_service.execute
+ end
+ end
+end
diff --git a/app/uploaders/ci/secure_file_uploader.rb b/app/uploaders/ci/secure_file_uploader.rb
new file mode 100644
index 00000000000..514d88dd177
--- /dev/null
+++ b/app/uploaders/ci/secure_file_uploader.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+module Ci
+ class SecureFileUploader < GitlabUploader
+ include ObjectStorage::Concern
+
+ storage_options Gitlab.config.ci_secure_files
+
+ # Use Lockbox to encrypt/decrypt the stored file (registers CarrierWave callbacks)
+ encrypt(key: :key)
+
+ def key
+ OpenSSL::HMAC.digest('SHA256', Gitlab::Application.secrets.db_key_base, model.project_id.to_s)
+ end
+
+ def checksum
+ @checksum ||= Digest::SHA256.hexdigest(model.file.read)
+ end
+
+ def store_dir
+ dynamic_segment
+ end
+
+ private
+
+ def dynamic_segment
+ Gitlab::HashedPath.new('secure_files', model.id, root_hash: model.project_id)
+ end
+
+ class << self
+ # direct upload is disabled since the file
+ # must always be encrypted
+ def direct_upload_enabled?
+ false
+ end
+
+ def background_upload_enabled?
+ false
+ end
+
+ def default_store
+ object_store_enabled? ? ObjectStorage::Store::REMOTE : ObjectStorage::Store::LOCAL
+ end
+ end
+ end
+end
diff --git a/app/validators/json_schemas/error_tracking_event_payload.json b/app/validators/json_schemas/error_tracking_event_payload.json
index 1497a05a68f..d1728609315 100644
--- a/app/validators/json_schemas/error_tracking_event_payload.json
+++ b/app/validators/json_schemas/error_tracking_event_payload.json
@@ -13,57 +13,72 @@
"type": "object"
},
"exception": {
- "type": "object",
- "required": ["values"],
- "properties": {
- "values": {
+ "oneOf": [
+ {
"type": "array",
"items": {
- "type": "object",
- "required": [],
- "properties": {
- "type": {
- "type": "string"
- },
- "value": {
- "type": "string"
- },
- "stacktrace": {
+ "$ref": "#/definitions/exception"
+ }
+ },
+ {
+ "type": "object",
+ "required": ["values"],
+ "properties": {
+ "values": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/exception"
+ }
+ }
+ }
+ }
+ ]
+ }
+ },
+ "definitions": {
+ "exception": {
+ "type": "object",
+ "required": [],
+ "properties": {
+ "type": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string"
+ },
+ "stacktrace": {
+ "type": "object",
+ "required": [],
+ "properties": {
+ "frames": {
+ "type": "array",
+ "items": {
"type": "object",
"required": [],
"properties": {
- "frames": {
- "type": "array",
- "items": {
- "type": "object",
- "required": [],
- "properties": {
- "abs_path": {
- "type": "string"
- },
- "function": {
- "type": "string"
- },
- "lineno": {
- "type": "number"
- },
- "in_app": {
- "type": "boolean"
- },
- "filename": {
- "type": "string"
- },
- "pre_context": {
- "type": "array"
- },
- "context_line": {
- "type": ["string", "null"]
- },
- "post_context": {
- "type": "array"
- }
- }
- }
+ "abs_path": {
+ "type": "string"
+ },
+ "function": {
+ "type": "string"
+ },
+ "lineno": {
+ "type": "number"
+ },
+ "in_app": {
+ "type": "boolean"
+ },
+ "filename": {
+ "type": "string"
+ },
+ "pre_context": {
+ "type": "array"
+ },
+ "context_line": {
+ "type": ["string", "null"]
+ },
+ "post_context": {
+ "type": "array"
}
}
}
diff --git a/app/views/admin/application_settings/_account_and_limit.html.haml b/app/views/admin/application_settings/_account_and_limit.html.haml
index 65882491575..e46a88b2217 100644
--- a/app/views/admin/application_settings/_account_and_limit.html.haml
+++ b/app/views/admin/application_settings/_account_and_limit.html.haml
@@ -52,8 +52,7 @@
= f.text_field :user_default_internal_regex, placeholder: _('Regex pattern'), class: 'form-control gl-form-input gl-mt-2'
.help-block
= _('Specify an email address regex pattern to identify default internal users.')
- = link_to _('Learn more'), help_page_path('user/permissions', anchor: 'setting-new-users-to-external'),
- target: '_blank'
+ = link_to _('Learn more'), help_page_path('user/permissions', anchor: 'setting-new-users-to-external'), target: '_blank', rel: 'noopener noreferrer'
- unless Gitlab.com?
.form-group
= f.label :deactivate_dormant_users, _('Dormant users'), class: 'label-bold'
@@ -63,7 +62,7 @@
= _('Deactivate dormant users after 90 days of inactivity')
.help-block
= _('Users can reactivate their account by signing in.')
- = link_to _('Learn more'), help_page_path('user/admin_area/moderate_users', anchor: 'automatically-deactivate-dormant-users'), target: '_blank'
+ = link_to _('Learn more'), help_page_path('user/admin_area/moderate_users', anchor: 'automatically-deactivate-dormant-users'), target: '_blank', rel: 'noopener noreferrer'
.form-group
= f.label :personal_access_token_prefix, _('Personal Access Token prefix'), class: 'label-light'
= f.text_field :personal_access_token_prefix, placeholder: _('Maximum 20 characters'), class: 'form-control gl-form-input'
diff --git a/app/views/admin/application_settings/_ci_cd.html.haml b/app/views/admin/application_settings/_ci_cd.html.haml
index 8026ec4702b..41698f9720b 100644
--- a/app/views/admin/application_settings/_ci_cd.html.haml
+++ b/app/views/admin/application_settings/_ci_cd.html.haml
@@ -9,13 +9,13 @@
= s_('CICD|Default to Auto DevOps pipeline for all projects')
.form-text.text-muted
= s_('CICD|The Auto DevOps pipeline runs by default in all projects with no CI/CD configuration file.')
- = link_to _('What is Auto DevOps?'), help_page_path('topics/autodevops/index.md'), target: '_blank'
+ = link_to _('What is Auto DevOps?'), help_page_path('topics/autodevops/index.md'), target: '_blank', rel: 'noopener noreferrer'
.form-group
= f.label :auto_devops_domain, s_('AdminSettings|Auto DevOps domain'), class: 'label-bold'
= f.text_field :auto_devops_domain, class: 'form-control gl-form-input', placeholder: 'example.com'
.form-text.text-muted
= s_("AdminSettings|The default domain to use for Auto Review Apps and Auto Deploy stages in all projects.")
- = link_to _('Learn more.'), help_page_path('topics/autodevops/stages.md', anchor: 'auto-review-apps'), target: '_blank'
+ = link_to _('Learn more.'), help_page_path('topics/autodevops/stages.md', anchor: 'auto-review-apps'), target: '_blank', rel: 'noopener noreferrer'
.form-group
.form-check
@@ -68,7 +68,7 @@
= f.text_field :default_ci_config_path, class: 'form-control gl-form-input', placeholder: '.gitlab-ci.yml'
%p.form-text.text-muted
= _("The default CI/CD configuration file and path for new projects.").html_safe
- = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'specify-a-custom-cicd-configuration-file'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'specify-a-custom-cicd-configuration-file'), target: '_blank', rel: 'noopener noreferrer'
.form-group
.form-check
= f.check_box :suggest_pipeline_enabled, class: 'form-check-input'
diff --git a/app/views/admin/application_settings/_email.html.haml b/app/views/admin/application_settings/_email.html.haml
index 073c0bf619d..0ab462a3fa8 100644
--- a/app/views/admin/application_settings/_email.html.haml
+++ b/app/views/admin/application_settings/_email.html.haml
@@ -20,7 +20,7 @@
= f.label :commit_email_hostname, _('Custom hostname (for private commit emails)'), class: 'label-bold'
= f.text_field :commit_email_hostname, class: 'form-control gl-form-input'
.form-text.text-muted
- - commit_email_hostname_docs_link = link_to _('Learn more'), help_page_path('user/admin_area/settings/email.md', anchor: 'custom-hostname-for-private-commit-emails'), target: '_blank'
+ - commit_email_hostname_docs_link = link_to _('Learn more'), help_page_path('user/admin_area/settings/email.md', anchor: 'custom-hostname-for-private-commit-emails'), target: '_blank', rel: 'noopener noreferrer'
= _("Hostname used in private commit emails. %{learn_more}").html_safe % { learn_more: commit_email_hostname_docs_link }
= render_if_exists 'admin/application_settings/email_additional_text_setting', form: f
diff --git a/app/views/admin/application_settings/_external_authorization_service_form.html.haml b/app/views/admin/application_settings/_external_authorization_service_form.html.haml
index 23484eaec32..4fb10d48540 100644
--- a/app/views/admin/application_settings/_external_authorization_service_form.html.haml
+++ b/app/views/admin/application_settings/_external_authorization_service_form.html.haml
@@ -1,11 +1,12 @@
%section.settings.as-external-auth.no-animate#js-external-auth-settings{ class: ('expanded' if expanded) }
.settings-header
%h4
- = _('External authentication')
+ = s_('ExternalAuthorization|External authorization')
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? 'Collapse' : 'Expand'
%p
- = _('External Classification Policy Authorization')
+ = s_('ExternalAuthorization|External classification policy authorization.')
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/external_authorization'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-external-auth-settings'), html: { class: 'fieldset-form', id: 'external-auth-settings' } do |f|
@@ -16,35 +17,37 @@
.form-check
= f.check_box :external_authorization_service_enabled, class: 'form-check-input'
= f.label :external_authorization_service_enabled, class: 'form-check-label' do
- = _('Enable classification control using an external service')
+ = s_('ExternalAuthorization|Enable classification control using an external service')
%span.form-text.text-muted
= external_authorization_description
- = link_to sprite_icon('question-o'), help_page_path('user/admin_area/settings/external_authorization')
.form-group
- = f.label :external_authorization_service_url, _('Service URL'), class: 'label-bold'
+ = f.label :external_authorization_service_url, s_('ExternalAuthorization|Service URL'), class: 'label-bold'
= f.text_field :external_authorization_service_url, class: 'form-control gl-form-input'
%span.form-text.text-muted
= external_authorization_url_help_text
.form-group
- = f.label :external_authorization_service_timeout, _('External authorization request timeout'), class: 'label-bold'
+ = f.label :external_authorization_service_timeout, s_('ExternalAuthorization|External authorization request timeout (seconds)'), class: 'label-bold'
= f.number_field :external_authorization_service_timeout, class: 'form-control gl-form-input', min: 0.001, max: 10, step: 0.001
%span.form-text.text-muted
= external_authorization_timeout_help_text
- = f.label :external_auth_client_cert, _('Client authentication certificate'), class: 'label-bold'
+ .form-group
+ = f.label :external_auth_client_cert, s_('ExternalAuthorization|Client authorization certificate'), class: 'label-bold'
= f.text_area :external_auth_client_cert, class: 'form-control gl-form-input'
%span.form-text.text-muted
= external_authorization_client_certificate_help_text
.form-group
- = f.label :external_auth_client_key, _('Client authentication key'), class: 'label-bold'
+ = f.label :external_auth_client_key, s_('ExternalAuthorization|Client authorization key'), class: 'label-bold'
= f.text_area :external_auth_client_key, class: 'form-control gl-form-input'
%span.form-text.text-muted
= external_authorization_client_key_help_text
.form-group
- = f.label :external_auth_client_key_pass, _('Client authentication key password'), class: 'label-bold'
+ = f.label :external_auth_client_key_pass, s_('ExternalAuthorization|Client authorization key password (optional)'), class: 'label-bold'
= f.password_field :external_auth_client_key_pass, class: 'form-control gl-form-input'
%span.form-text.text-muted
= external_authorization_client_pass_help_text
.form-group
- = f.label :external_authorization_service_default_label, _('Default classification label'), class: 'label-bold'
+ = f.label :external_authorization_service_default_label, s_('ExternalAuthorization|Default classification label'), class: 'label-bold'
= f.text_field :external_authorization_service_default_label, class: 'form-control gl-form-input'
+ %span.form-text.text-muted
+ = external_authorization_client_url_help_text
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_floc.html.haml b/app/views/admin/application_settings/_floc.html.haml
index 52833b5cfc2..66259926064 100644
--- a/app/views/admin/application_settings/_floc.html.haml
+++ b/app/views/admin/application_settings/_floc.html.haml
@@ -8,7 +8,7 @@
= expanded ? _('Collapse') : _('Expand')
%p
= s_('FloC|Configure whether you want to participate in FloC.').html_safe
- = link_to sprite_icon('question-o'), 'https://github.com/WICG/floc', target: '_blank', class: 'has-tooltip', title: _('More information')
+ = link_to sprite_icon('question-o'), 'https://github.com/WICG/floc', target: '_blank', rel: 'noopener noreferrer', class: 'has-tooltip', title: _('More information')
.settings-content
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-floc-settings'), html: { class: 'fieldset-form', id: 'floc-settings' } do |f|
diff --git a/app/views/admin/application_settings/_localization.html.haml b/app/views/admin/application_settings/_localization.html.haml
index 5c8f3379fce..d0bb6a78ed6 100644
--- a/app/views/admin/application_settings/_localization.html.haml
+++ b/app/views/admin/application_settings/_localization.html.haml
@@ -7,7 +7,7 @@
= f.select :first_day_of_week, first_day_of_week_choices, {}, class: 'form-control'
.form-text.text-muted
= _('Default first day of the week in calendars and date pickers.')
- = link_to _('Learn more.'), help_page_path('user/admin_area/settings/index.md', anchor: 'default-first-day-of-the-week'), target: '_blank'
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/index.md', anchor: 'default-first-day-of-the-week'), target: '_blank', rel: 'noopener noreferrer'
.form-group
= f.label :time_tracking, _('Time tracking'), class: 'label-bold'
@@ -17,7 +17,7 @@
= _('Limit display of time tracking units to hours.')
.form-text.text-muted
= _('Display time tracking in issues in total hours only.')
- = link_to _('What is time tracking?'), help_page_path('user/project/time_tracking.md'), target: '_blank'
+ = link_to _('What is time tracking?'), help_page_path('user/project/time_tracking.md'), target: '_blank', rel: 'noopener noreferrer'
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_outbound.html.haml b/app/views/admin/application_settings/_outbound.html.haml
index 142a3fbfbd0..9a31fdd7fdf 100644
--- a/app/views/admin/application_settings/_outbound.html.haml
+++ b/app/views/admin/application_settings/_outbound.html.haml
@@ -6,25 +6,26 @@
.form-check
= f.check_box :allow_local_requests_from_web_hooks_and_services, class: 'form-check-input', data: { qa_selector: 'allow_requests_from_services_checkbox' }
= f.label :allow_local_requests_from_web_hooks_and_services, class: 'form-check-label' do
- = _('Allow requests to the local network from web hooks and services')
+ = s_('OutboundRequests|Allow requests to the local network from web hooks and services')
.form-check
= f.check_box :allow_local_requests_from_system_hooks, class: 'form-check-input'
= f.label :allow_local_requests_from_system_hooks, class: 'form-check-label' do
- = _('Allow requests to the local network from system hooks')
+ = s_('OutboundRequests|Allow requests to the local network from system hooks')
.form-group
= f.label :outbound_local_requests_allowlist_raw, class: 'label-bold' do
- = _('Local IP addresses and domain names that hooks and services may access.')
- = f.text_area :outbound_local_requests_allowlist_raw, placeholder: "example.com, 192.168.1.1", class: 'form-control gl-form-input', rows: 8
+ = s_('OutboundRequests|Local IP addresses and domain names that hooks and services may access')
+ = f.text_area :outbound_local_requests_allowlist_raw, placeholder: "example.com, 192.168.1.1, xn--itlab-j1a.com", class: 'form-control gl-form-input', rows: 8
%span.form-text.text-muted
- = _('Requests to these domain(s)/address(es) on the local network will be allowed when local requests from hooks and services are not allowed. IP ranges such as 1:0:0:0:0:0:0:0/124 or 127.0.0.0/28 are supported. Domain wildcards are not supported currently. Use comma, semicolon, or newline to separate multiple entries. The allowlist can hold a maximum of 1000 entries. Domains should use IDNA encoding. Ex: example.com, 192.168.1.1, 127.0.0.0/28, xn--itlab-j1a.com.')
+ = s_('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.')
+ = link_to _('Learn more.'), help_page_path('security/webhooks.md', anchor: 'allowlist-for-local-requests'), target: '_blank', rel: 'noopener noreferrer'
.form-group
.form-check
= f.check_box :dns_rebinding_protection_enabled, class: 'form-check-input'
= f.label :dns_rebinding_protection_enabled, class: 'form-check-label' do
- = _('Enforce DNS rebinding attack protection')
+ = s_('OutboundRequests|Enforce DNS rebinding attack protection')
%span.form-text.text-muted
- = _('Resolves IP addresses once and uses them to submit requests')
+ = s_('OutboundRequests|Resolve IP addresses once and uses them to submit requests.')
= f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/admin/application_settings/_prometheus.html.haml b/app/views/admin/application_settings/_prometheus.html.haml
index 59690fdee8b..08befa59952 100644
--- a/app/views/admin/application_settings/_prometheus.html.haml
+++ b/app/views/admin/application_settings/_prometheus.html.haml
@@ -9,7 +9,7 @@
= _("Enable health and performance metrics endpoint")
.form-text.text-muted
= _('Enable a Prometheus endpoint that exposes health and performance statistics. The Health Check menu item appears in the Monitoring section of the Admin Area. Restart required.')
- = link_to _('Learn More.'), help_page_path('administration/monitoring/prometheus/gitlab_metrics.md'), target: '_blank'
+ = link_to _('Learn More.'), help_page_path('administration/monitoring/prometheus/gitlab_metrics.md'), target: '_blank', rel: 'noopener noreferrer'
- unless Gitlab::Metrics.metrics_folder_present?
.form-text.text-muted
%strong.cred= _("WARNING:")
diff --git a/app/views/admin/application_settings/_registry.html.haml b/app/views/admin/application_settings/_registry.html.haml
index 78d4e8c8cc3..b55c2f05300 100644
--- a/app/views/admin/application_settings/_registry.html.haml
+++ b/app/views/admin/application_settings/_registry.html.haml
@@ -10,10 +10,10 @@
= f.check_box :container_expiration_policies_enable_historic_entries, class: 'form-check-input'
= f.label :container_expiration_policies_enable_historic_entries, class: 'form-check-label' do
= _("Enable container expiration and retention policies for projects created earlier than GitLab 12.7.")
- = link_to sprite_icon('question-o'), help_page_path('user/packages/container_registry/index', anchor: 'cleanup-policy')
+ = link_to sprite_icon('question-o'), help_page_path('user/packages/container_registry/reduce_container_registry_storage', anchor: 'cleanup-policy')
.form-text.text-muted
= _("Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project.")
- = link_to sprite_icon('question-o'), help_page_path('user/packages/container_registry/index', anchor: 'use-with-external-container-registries')
+ = link_to sprite_icon('question-o'), help_page_path('user/packages/container_registry/reduce_container_registry_storage', anchor: 'use-with-external-container-registries')
- if container_registry_expiration_policies_throttling?
.form-group
= f.label :container_registry_delete_tags_service_timeout, _('Cleanup policy maximum processing time (seconds)'), class: 'label-bold'
diff --git a/app/views/admin/application_settings/_runner_registrars_form.html.haml b/app/views/admin/application_settings/_runner_registrars_form.html.haml
index b7ab896533b..08b3d173d20 100644
--- a/app/views/admin/application_settings/_runner_registrars_form.html.haml
+++ b/app/views/admin/application_settings/_runner_registrars_form.html.haml
@@ -11,6 +11,6 @@
= s_("Runners|Members of the %{type} can register runners") % { type: type }
%span.form-text.gl-text-gray-600
= _('If no options are selected, only administrators can register runners.')
- = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'runner-registration'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'prevent-users-from-registering-runners'), target: '_blank', rel: 'noopener noreferrer'
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_sourcegraph.html.haml b/app/views/admin/application_settings/_sourcegraph.html.haml
index d87ded09a2b..b92cf7b156a 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'
+ = link_to s_('SourcegraphAdmin|More information'), help_page_path('integration/sourcegraph.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
diff --git a/app/views/admin/application_settings/_spam.html.haml b/app/views/admin/application_settings/_spam.html.haml
index 53ca4d4aa79..27113fddb27 100644
--- a/app/views/admin/application_settings/_spam.html.haml
+++ b/app/views/admin/application_settings/_spam.html.haml
@@ -27,7 +27,7 @@
= f.text_field :recaptcha_site_key, class: 'form-control gl-form-input'
.form-text.text-muted
= _("Generate site and private keys at")
- %a{ href: 'http://www.google.com/recaptcha', target: 'blank' } http://www.google.com/recaptcha
+ %a{ href: 'http://www.google.com/recaptcha', target: 'blank', rel: 'noopener noreferrer' } http://www.google.com/recaptcha
.form-group
= f.label :recaptcha_private_key, _('reCAPTCHA private key'), class: 'label-bold'
@@ -65,7 +65,7 @@
= f.text_field :akismet_api_key, class: 'form-control gl-form-input'
.form-text.text-muted
Generate API key at
- %a{ href: 'http://www.akismet.com', target: 'blank' } http://www.akismet.com
+ %a{ href: 'http://www.akismet.com', target: 'blank', rel: 'noopener noreferrer' } http://www.akismet.com
%h5
= _('IP address restrictions')
diff --git a/app/views/admin/application_settings/_third_party_offers.html.haml b/app/views/admin/application_settings/_third_party_offers.html.haml
index 9a34400092e..231c45ec46c 100644
--- a/app/views/admin/application_settings/_third_party_offers.html.haml
+++ b/app/views/admin/application_settings/_third_party_offers.html.haml
@@ -2,11 +2,11 @@
%section.settings.as-third-party-offers.no-animate#js-third-party-offers-settings{ class: ('expanded' if expanded) }
.settings-header
%h4
- = _('Third-party offers')
+ = _('Customer experience improvement and third-party offers')
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p
- = _('Control whether to display third-party offers in GitLab.')
+ = _('Control whether to display customer experience improvement content and third-party offers in GitLab.')
.settings-content
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-third-party-offers-settings'), html: { class: 'fieldset-form', id: 'third-party-offers-settings' } do |f|
= form_errors(@application_setting) if expanded
@@ -15,6 +15,6 @@
.form-group
.form-check
= f.check_box :hide_third_party_offers, class: 'form-check-input'
- = f.label :hide_third_party_offers, _('Do not display offers from third parties'), class: 'form-check-label'
+ = f.label :hide_third_party_offers, _('Do not display content for customer experience improvement and offers from third parties'), class: 'form-check-label'
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/appearances/_form.html.haml b/app/views/admin/application_settings/appearances/_form.html.haml
index 3bd16e4c344..0f7f0109a54 100644
--- a/app/views/admin/application_settings/appearances/_form.html.haml
+++ b/app/views/admin/application_settings/appearances/_form.html.haml
@@ -20,7 +20,7 @@
%hr
= f.hidden_field :header_logo_cache
= f.file_field :header_logo, class: "", accept: 'image/*'
- .hint
+ .form-text.text-muted
= _('Maximum file size is 1MB. Pages are optimized for a 28px tall header logo')
%hr
.row
@@ -39,7 +39,7 @@
%hr
= f.hidden_field :favicon_cache
= f.file_field :favicon, class: '', accept: 'image/*'
- .hint
+ .form-text.text-muted
= _("Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_whitelist}.") % { favicon_extension_whitelist: favicon_extension_whitelist }
%br
= _("Images with incorrect dimensions are not resized automatically, and may result in unexpected behavior.")
@@ -58,7 +58,7 @@
.form-group
= f.label :description, class: 'col-form-label label-bold'
= f.text_area :description, class: "form-control gl-form-input", rows: 10
- .hint
+ .form-text.text-muted
= parsed_with_gfm
.form-group
= f.label :logo, class: 'col-form-label label-bold pt-0'
@@ -71,7 +71,7 @@
%hr
= f.hidden_field :logo_cache
= f.file_field :logo, class: "", accept: 'image/*'
- .hint
+ .form-text.text-muted
= _('Maximum file size is 1MB. Pages are optimized for a 640x360 px logo.')
%hr
@@ -84,7 +84,7 @@
= f.label :new_project_guidelines, class: 'col-form-label label-bold'
%p
= f.text_area :new_project_guidelines, class: "form-control gl-form-input", rows: 10
- .hint
+ .form-text.text-muted
= parsed_with_gfm
%hr
@@ -97,7 +97,7 @@
= f.label :profile_image_guidelines, class: 'col-form-label label-bold'
%p
= f.text_area :profile_image_guidelines, class: "form-control gl-form-input", rows: 10
- .hint
+ .form-text.text-muted
= parsed_with_gfm
.gl-mt-3.gl-mb-3
diff --git a/app/views/admin/application_settings/appearances/_system_header_footer_form.html.haml b/app/views/admin/application_settings/appearances/_system_header_footer_form.html.haml
index 4571d34a497..1ce79e61ac6 100644
--- a/app/views/admin/application_settings/appearances/_system_header_footer_form.html.haml
+++ b/app/views/admin/application_settings/appearances/_system_header_footer_form.html.haml
@@ -19,7 +19,7 @@
= form.label :email_header_and_footer_enabled, class: 'label-bold' do
= _('Enable header and footer in emails')
- .hint
+ .form-text.text-muted
= _('Add header and footer to emails. Please note that color settings will only be applied within the application interface')
.form-group.js-toggle-colors-container
diff --git a/app/views/admin/application_settings/general.html.haml b/app/views/admin/application_settings/general.html.haml
index 53ba626760b..9eef4bc2a37 100644
--- a/app/views/admin/application_settings/general.html.haml
+++ b/app/views/admin/application_settings/general.html.haml
@@ -118,3 +118,4 @@
= render 'admin/application_settings/snowplow'
= render 'admin/application_settings/eks'
= render 'admin/application_settings/floc'
+= render_if_exists 'admin/application_settings/license_file'
diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml
index 61a2f97764f..242d0c364f4 100644
--- a/app/views/admin/application_settings/network.html.haml
+++ b/app/views/admin/application_settings/network.html.haml
@@ -75,11 +75,13 @@
%section.settings.as-outbound.no-animate#js-outbound-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'outbound_requests_content' } }
.settings-header
%h4
- = _('Outbound requests')
+ = s_('OutboundRequests|Outbound requests')
+
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Allow requests to the local network from hooks and services.')
+ = s_('OutboundRequests|Allow requests to the local network from hooks and services.')
+ = link_to _('Learn more.'), help_page_path('security/webhooks.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'outbound'
diff --git a/app/views/admin/background_migrations/_migration.html.haml b/app/views/admin/background_migrations/_migration.html.haml
index 4a7c0083bc7..b6077bc54d6 100644
--- a/app/views/admin/background_migrations/_migration.html.haml
+++ b/app/views/admin/background_migrations/_migration.html.haml
@@ -7,7 +7,7 @@
- else
= _('Unknown')
%td{ role: 'cell', data: { label: _('Status') } }
- %span.badge.badge-pill.gl-badge.sm{ class: batched_migration_status_badge_class_name(migration) }= migration.status.humanize
+ = gl_badge_tag migration.status.humanize, { size: :sm, variant: batched_migration_status_badge_variant(migration) }
%td{ role: 'cell', data: { label: _('Action') } }
- if migration.active?
= button_to pause_admin_background_migration_path(migration),
diff --git a/app/views/admin/background_migrations/index.html.haml b/app/views/admin/background_migrations/index.html.haml
index 9ccbdfb5f20..13ac511f1b4 100644
--- a/app/views/admin/background_migrations/index.html.haml
+++ b/app/views/admin/background_migrations/index.html.haml
@@ -8,18 +8,15 @@
%li.nav-item{ role: 'presentation' }
%a.nav-link.gl-tab-nav-item{ href: admin_background_migrations_path, class: (active_tab_classes if @current_tab == 'queued'), role: 'tab' }
= _('Queued')
- %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm
- = limited_counter_with_delimiter(@relations_by_tab['queued'])
+ = gl_tab_counter_badge limited_counter_with_delimiter(@relations_by_tab['queued'])
%li.nav-item{ role: 'presentation' }
%a.nav-link.gl-tab-nav-item{ href: admin_background_migrations_path(tab: 'failed'), class: (active_tab_classes if @current_tab == 'failed'), role: 'tab' }
= _('Failed')
- %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm
- = limited_counter_with_delimiter(@relations_by_tab['failed'])
+ = gl_tab_counter_badge limited_counter_with_delimiter(@relations_by_tab['failed'])
%li.nav-item{ role: 'presentation' }
%a.nav-link.gl-tab-nav-item{ href: admin_background_migrations_path(tab: 'finished'), class: (active_tab_classes if @current_tab == 'finished'), role: 'tab' }
= _('Finished')
- %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm
- = limited_counter_with_delimiter(@relations_by_tab['finished'])
+ = gl_tab_counter_badge limited_counter_with_delimiter(@relations_by_tab['finished'])
.tab-content.gl-tab-content
.tab-pane.active{ role: 'tabpanel' }
diff --git a/app/views/admin/cohorts/_cohorts_table.html.haml b/app/views/admin/cohorts/_cohorts_table.html.haml
index a92cfb5851a..4e2292a9f67 100644
--- a/app/views/admin/cohorts/_cohorts_table.html.haml
+++ b/app/views/admin/cohorts/_cohorts_table.html.haml
@@ -2,7 +2,7 @@
.bs-callout.clearfix
%p
= s_("Cohorts|User cohorts are shown for the last %{months_included} months. Only users with activity are counted in the 'New users' column; inactive users are counted separately.") % { months_included: @cohorts[:months_included] }
- = link_to sprite_icon('question-o'), help_page_path('user/admin_area/user_cohorts', anchor: 'cohorts'), title: 'About this feature', target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('user/admin_area/user_cohorts', anchor: 'cohorts'), title: 'About this feature', target: '_blank', rel: 'noopener noreferrer'
.table-holder.d-xl-table
%table.table
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
index 801b903395a..85b6ebfc63a 100644
--- a/app/views/admin/dashboard/index.html.haml
+++ b/app/views/admin/dashboard/index.html.haml
@@ -118,9 +118,9 @@
.gl-card-body
%h4
= s_('AdminArea|Components')
- - if Gitlab::CurrentSettings.version_check_enabled
+ - if show_version_check?
.float-right
- = version_status_badge
+ .js-gitlab-version-check{ data: { "size": "lg" } }
= link_to(sprite_icon('question'), "https://gitlab.com/gitlab-org/gitlab/-/blob/master/CHANGELOG.md", class: 'gl-ml-2', target: '_blank', rel: 'noopener noreferrer')
%p
= link_to _('GitLab'), general_admin_application_settings_path
diff --git a/app/views/admin/deploy_keys/index.html.haml b/app/views/admin/deploy_keys/index.html.haml
index ba4abdc02e4..de2a737faa1 100644
--- a/app/views/admin/deploy_keys/index.html.haml
+++ b/app/views/admin/deploy_keys/index.html.haml
@@ -1,44 +1,3 @@
- page_title _('Deploy Keys')
-- if Feature.enabled?(:admin_deploy_keys_vue, default_enabled: :yaml)
- #js-admin-deploy-keys-table{ data: admin_deploy_keys_data }
-- else
- - if @deploy_keys.any?
- %h3.page-title.deploy-keys-title
- = _('Public deploy keys (%{deploy_keys_count})') % { deploy_keys_count: @deploy_keys.load.size }
- = link_to _('New deploy key'), new_admin_deploy_key_path, class: 'float-right btn gl-button btn-confirm btn-md gl-button'
- %table.table.b-table.gl-table.b-table-stacked-lg{ data: { testid: 'deploy-keys-list' } }
- %thead
- %tr
- %th= _('Title')
- %th= _('Fingerprint')
- %th= _('Projects with write access')
- %th= _('Created')
- %th.gl-lg-w-1px.gl-white-space-nowrap
- %span.gl-sr-only
- = _('Actions')
- %tbody
- - @deploy_keys.each do |deploy_key|
- %tr
- %td{ data: { label: _('Title') } }
- %div
- = deploy_key.title
- %td{ data: { label: _('Fingerprint') } }
- %div
- %code= deploy_key.fingerprint
- %td{ data: { label: _('Projects with write access') } }
- %div
- - deploy_key.projects_with_write_access.each do |project|
- = link_to project.full_name, admin_project_path(project), class: 'gl-display-block'
- %td{ data: { label: _('Created') } }
- %div
- = time_ago_with_tooltip(deploy_key.created_at)
- %td.gl-lg-w-1px.gl-white-space-nowrap{ data: { label: _('Actions') } }
- %div
- = link_to edit_admin_deploy_key_path(deploy_key), class: 'btn btn-default btn-md gl-button btn-icon gl-mr-3', aria: { label: _('Edit deploy key') } do
- = sprite_icon('pencil', css_class: 'gl-button-icon')
- = link_to admin_deploy_key_path(deploy_key), data: { confirm: _('Are you sure?') }, method: :delete, class: 'btn btn-danger btn-md gl-button btn-icon', aria: { label: _('Remove deploy key') } do
- = sprite_icon('remove', css_class: 'gl-button-icon')
-
- - else
- = render 'shared/empty_states/deploy_keys'
+#js-admin-deploy-keys-table{ data: admin_deploy_keys_data }
diff --git a/app/views/admin/groups/_group.html.haml b/app/views/admin/groups/_group.html.haml
index bbc65850794..0c2280a2f63 100644
--- a/app/views/admin/groups/_group.html.haml
+++ b/app/views/admin/groups/_group.html.haml
@@ -15,8 +15,7 @@
= markdown_field(group, :description)
.stats.gl-text-gray-500.gl-flex-shrink-0.gl-display-none.gl-sm-display-flex
- %span.badge.badge-muted.badge-pill.gl-badge.sm
- = storage_counter(group.storage_size)
+ = gl_badge_tag storage_counter(group.storage_size), size: :sm
= render_if_exists 'admin/namespace_plan_badge', namespace: group, css_class: 'gl-ml-5 gl-mr-0'
= render_if_exists 'admin/groups/marked_for_deletion_badge', group: group, css_class: 'gl-ml-5'
diff --git a/app/views/admin/labels/_form.html.haml b/app/views/admin/labels/_form.html.haml
deleted file mode 100644
index abf380474e4..00000000000
--- a/app/views/admin/labels/_form.html.haml
+++ /dev/null
@@ -1,31 +0,0 @@
-= form_for [:admin, @label], html: { class: 'label-form js-requires-input' } do |f|
- = form_errors(@label)
-
- .form-group.row
- .col-sm-2.col-form-label
- = f.label :title
- .col-sm-10
- = f.text_field :title, class: "form-control gl-form-input", required: true
- .form-group.row
- .col-sm-2.col-form-label
- = f.label :description
- .col-sm-10
- = f.text_field :description, class: "form-control gl-form-input js-quick-submit"
- .form-group.row
- .col-sm-2.col-form-label
- = f.label :color, _("Background color")
- .col-sm-10
- .input-group
- .input-group-prepend
- .input-group-text.label-color-preview &nbsp;
- = f.text_field :color, class: "form-control gl-form-input"
- .form-text.text-muted
- = _('Choose any color.')
- %br
- = _("Or you can choose one of the suggested colors below")
-
- = render_suggested_colors
-
- .form-actions
- = f.submit _('Save'), class: 'btn gl-button btn-confirm js-save-button'
- = link_to _("Cancel"), admin_labels_path, class: 'btn gl-button btn-default btn-cancel'
diff --git a/app/views/admin/labels/edit.html.haml b/app/views/admin/labels/edit.html.haml
index 652ed095d00..44dd2b6a646 100644
--- a/app/views/admin/labels/edit.html.haml
+++ b/app/views/admin/labels/edit.html.haml
@@ -4,4 +4,4 @@
%h3.page-title
= _('Edit Label')
%hr
-= render 'form'
+= render 'shared/labels/form', url: admin_label_path(@label), back_path: admin_labels_path
diff --git a/app/views/admin/labels/new.html.haml b/app/views/admin/labels/new.html.haml
index 20103fb8a29..5166bdb4d20 100644
--- a/app/views/admin/labels/new.html.haml
+++ b/app/views/admin/labels/new.html.haml
@@ -2,4 +2,4 @@
%h3.page-title
= _('New Label')
%hr
-= render 'form'
+= render 'shared/labels/form', url: admin_labels_path, back_path: admin_labels_path
diff --git a/app/views/admin/runners/edit.html.haml b/app/views/admin/runners/edit.html.haml
new file mode 100644
index 00000000000..0257983016c
--- /dev/null
+++ b/app/views/admin/runners/edit.html.haml
@@ -0,0 +1,99 @@
+- add_page_specific_style 'page_bundles/ci_status'
+
+- runner_name = "##{@runner.id} (#{@runner.short_sha})"
+- if Feature.enabled?(:runner_read_only_admin_view)
+ - breadcrumb_title _('Edit')
+ - page_title _('Edit'), runner_name
+ - add_to_breadcrumbs _('Runners'), admin_runners_path
+ - add_to_breadcrumbs runner_name, admin_runner_path(@runner)
+- else
+ - breadcrumb_title runner_name
+ - page_title runner_name
+
+#js-admin-runner-edit{ data: {runner_id: @runner.id} }
+
+.row
+ .col-md-6
+ %h4= _('Restrict projects for this runner')
+ - if @runner.runner_projects.any?
+ %table.table{ data: { testid: 'assigned-projects' } }
+ %thead
+ %tr
+ %th= _('Assigned projects')
+ - @runner.runner_projects.each do |runner_project|
+ - project = runner_project.project
+ - 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'
+
+ %table.table{ data: { testid: 'unassigned-projects' } }
+ %thead
+ %tr
+ %th= _('Project')
+ %th
+
+ %tr
+ %td
+ = form_tag edit_admin_runner_path(@runner), id: 'runner-projects-search', class: 'form-inline', method: :get do
+ .input-group
+ = search_field_tag :search, params[:search], class: 'form-control gl-form-input', spellcheck: false
+ .input-group-append
+ = submit_tag _('Search'), class: 'gl-button btn btn-default'
+
+ %td
+ - @projects.each do |project|
+ %tr
+ %td
+ = project.full_name
+ %td
+ .float-right
+ = form_for project.runner_projects.new, url: admin_namespace_project_runner_projects_path(project.namespace, project), method: :post do |f|
+ = f.hidden_field :runner_id, value: @runner.id
+ = f.submit _('Enable'), aria: { label: s_('Runners|Change to project runner') }, class: 'gl-button btn btn-sm', data: { confirm: (s_('Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?') if @runner.instance_type?), confirm_btn_variant: 'danger' }
+ = paginate_without_count @projects
+
+ .col-md-6
+ %h4= _('Recent jobs served by this runner')
+ %table.table.ci-table.runner-builds
+ %thead
+ %tr
+ %th= _('Job')
+ %th= _('Status')
+ %th= _('Project')
+ %th= _('Commit')
+ %th= _('Finished at')
+
+ - @builds.each do |build|
+ - project = build.project
+ %tr.build
+ %td.id
+ - if project
+ = link_to project_job_path(project, build) do
+ %strong ##{build.id}
+ - else
+ %strong ##{build.id}
+
+ %td.status
+ = render 'ci/status/badge', status: build.detailed_status(current_user)
+
+ %td.status
+ - if project
+ = project.full_name
+
+ %td.build-link
+ - if project
+ = link_to pipeline_path(build.pipeline) do
+ %strong= build.pipeline.short_sha
+
+ %td.timestamp
+ - if build.finished_at
+ %span= time_ago_with_tooltip build.finished_at
diff --git a/app/views/admin/runners/show.html.haml b/app/views/admin/runners/show.html.haml
index 808b2bb4f8e..7b4390ae463 100644
--- a/app/views/admin/runners/show.html.haml
+++ b/app/views/admin/runners/show.html.haml
@@ -1,93 +1,8 @@
- add_page_specific_style 'page_bundles/ci_status'
-- breadcrumb_title @runner.short_sha
-- page_title "##{@runner.id} (#{@runner.short_sha})"
+- title = "##{@runner.id} (#{@runner.short_sha})"
+- breadcrumb_title title
+- page_title title
- add_to_breadcrumbs _('Runners'), admin_runners_path
-#js-runner-details{ data: {runner_id: @runner.id} }
-
-.row
- .col-md-6
- %h4= _('Restrict projects for this runner')
- - if @runner.runner_projects.any?
- %table.table{ data: { testid: 'assigned-projects' } }
- %thead
- %tr
- %th= _('Assigned projects')
- - @runner.runner_projects.each do |runner_project|
- - project = runner_project.project
- - 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'
-
- %table.table{ data: { testid: 'unassigned-projects' } }
- %thead
- %tr
- %th= _('Project')
- %th
-
- %tr
- %td
- = form_tag admin_runner_path(@runner), id: 'runner-projects-search', class: 'form-inline', method: :get do
- .input-group
- = search_field_tag :search, params[:search], class: 'form-control gl-form-input', spellcheck: false
- .input-group-append
- = submit_tag _('Search'), class: 'gl-button btn btn-default'
-
- %td
- - @projects.each do |project|
- %tr
- %td
- = project.full_name
- %td
- .float-right
- = form_for project.runner_projects.new, url: admin_namespace_project_runner_projects_path(project.namespace, project), method: :post do |f|
- = f.hidden_field :runner_id, value: @runner.id
- = f.submit _('Enable'), class: 'gl-button btn btn-sm', data: { confirm: (s_('Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?') if @runner.instance_type?) }
- = paginate_without_count @projects
-
- .col-md-6
- %h4= _('Recent jobs served by this runner')
- %table.table.ci-table.runner-builds
- %thead
- %tr
- %th= _('Job')
- %th= _('Status')
- %th= _('Project')
- %th= _('Commit')
- %th= _('Finished at')
-
- - @builds.each do |build|
- - project = build.project
- %tr.build
- %td.id
- - if project
- = link_to project_job_path(project, build) do
- %strong ##{build.id}
- - else
- %strong ##{build.id}
-
- %td.status
- = render 'ci/status/badge', status: build.detailed_status(current_user)
-
- %td.status
- - if project
- = project.full_name
-
- %td.build-link
- - if project
- = link_to pipeline_path(build.pipeline) do
- %strong= build.pipeline.short_sha
-
- %td.timestamp
- - if build.finished_at
- %span= time_ago_with_tooltip build.finished_at
+-# Empty view in development behind feature flag runner_read_only_admin_view
diff --git a/app/views/admin/users/_head.html.haml b/app/views/admin/users/_head.html.haml
index bafb2085589..ca14d898d79 100644
--- a/app/views/admin/users/_head.html.haml
+++ b/app/views/admin/users/_head.html.haml
@@ -3,23 +3,26 @@
%h3.page-title.gl-m-0
= @user.name
- if @user.blocked_pending_approval?
- %span.cred
+ %span.gl-text-red-500
= s_('AdminUsers|(Pending approval)')
- elsif @user.banned?
- %span.cred
+ %span.gl-text-red-500
= s_('AdminUsers|(Banned)')
- elsif @user.blocked?
- %span.cred
+ %span.gl-text-red-500
= s_('AdminUsers|(Blocked)')
- if @user.internal?
- %span.cred
+ %span.gl-text-red-500
= s_('AdminUsers|(Internal)')
- if @user.admin
- %span.cred
+ %span.gl-text-red-500
= s_('AdminUsers|(Admin)')
- if @user.deactivated?
- %span.cred
+ %span.gl-text-red-500
= s_('AdminUsers|(Deactivated)')
+ - if @user.access_locked?
+ %span.gl-text-red-500
+ = s_('AdminUsers|(Locked)')
= render_if_exists 'admin/users/auditor_user_badge'
= render_if_exists 'admin/users/gma_user_badge'
diff --git a/app/views/admin/users/_users.html.haml b/app/views/admin/users/_users.html.haml
index e62e4cfa192..5edd5403d49 100644
--- a/app/views/admin/users/_users.html.haml
+++ b/app/views/admin/users/_users.html.haml
@@ -1,3 +1,11 @@
+- if registration_features_can_be_prompted?
+ = render 'shared/global_alert',
+ variant: :tip,
+ alert_class: 'gl-my-5',
+ dismissible: false do
+ .gl-alert-body
+ = render 'shared/registration_features_discovery_message', feature_title: s_('RegistrationFeatures|send emails to users')
+
.top-area.scrolling-tabs-container.inner-page-scroll-tabs
.fade-left
= sprite_icon('chevron-lg-left', size: 12)
@@ -51,7 +59,7 @@
= hidden_field_tag :sort, @sort
= sprite_icon('search', css_class: 'search-icon')
= button_tag s_('AdminUsers|Search users') if Rails.env.test?
- .dropdown.user-sort-dropdown
+ .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' })
diff --git a/app/views/admin/users/projects.html.haml b/app/views/admin/users/projects.html.haml
index b47ed38f65f..f51ac40df4f 100644
--- a/app/views/admin/users/projects.html.haml
+++ b/app/views/admin/users/projects.html.haml
@@ -5,7 +5,7 @@
- if @user.groups.any?
.card
- .card-header= _('Group projects')
+ .card-header= _('Groups')
%ul.hover-list
- @user.group_members.includes(:source).each do |group_member| # rubocop: disable CodeReuse/ActiveRecord
- group = group_member.group
diff --git a/app/views/ci/runner/_how_to_setup_runner.html.haml b/app/views/ci/runner/_how_to_setup_runner.html.haml
index 24048a8b328..c872ee481ad 100644
--- a/app/views/ci/runner/_how_to_setup_runner.html.haml
+++ b/app/views/ci/runner/_how_to_setup_runner.html.haml
@@ -1,4 +1,4 @@
-- link = link_to _("Install GitLab Runner and ensure it's running."), 'https://docs.gitlab.com/runner/install/', target: '_blank'
+- link = link_to _("Install GitLab Runner and ensure it's running."), 'https://docs.gitlab.com/runner/install/', target: '_blank', rel: 'noopener noreferrer'
.gl-mb-3
%h5= _("Set up a %{type} Runner for a project") % { type: type }
%ol
diff --git a/app/views/clusters/clusters/_advanced_settings.html.haml b/app/views/clusters/clusters/_advanced_settings.html.haml
index c84b3a923ca..59c8fe04b09 100644
--- a/app/views/clusters/clusters/_advanced_settings.html.haml
+++ b/app/views/clusters/clusters/_advanced_settings.html.haml
@@ -23,7 +23,7 @@
placeholder: _('Select project'), idAttribute: 'id', data: { order_by: 'last_activity_at', idattribute: 'id', simple_filter: true, allow_clear: true, include_groups: false, include_projects_in_subgroups: true, group_id: group_id, user_id: user_id }, value: @cluster.management_project_id)
.text-muted
= html_escape(s_('ClusterIntegration|A cluster management project can be used to run deployment jobs with Kubernetes %{code_open}cluster-admin%{code_close} privileges.')) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
- = link_to _('More information'), help_page_path('user/clusters/management_project.md'), target: '_blank'
+ = link_to _('More information'), help_page_path('user/clusters/management_project.md'), target: '_blank', rel: 'noopener noreferrer'
= field.submit _('Save changes'), class: 'btn gl-button btn-confirm'
.sub-section.form-group
diff --git a/app/views/clusters/clusters/_integrations.html.haml b/app/views/clusters/clusters/_integrations.html.haml
index f136091dad5..c670dafb947 100644
--- a/app/views/clusters/clusters/_integrations.html.haml
+++ b/app/views/clusters/clusters/_integrations.html.haml
@@ -1,7 +1,7 @@
.settings.expanded.border-0.m-0
%p
= s_('ClusterIntegration|Integrations allow you to use applications installed in your cluster as part of your GitLab workflow.')
- = link_to _('Learn more'), help_page_path('user/clusters/integrations.md'), target: '_blank'
+ = link_to _('Learn more'), help_page_path('user/clusters/integrations.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content#integrations-settings-section
- if can?(current_user, :admin_cluster, @cluster)
.sub-section.form-group
diff --git a/app/views/clusters/clusters/_namespace.html.haml b/app/views/clusters/clusters/_namespace.html.haml
index 6412972e195..cedece5ad93 100644
--- a/app/views/clusters/clusters/_namespace.html.haml
+++ b/app/views/clusters/clusters/_namespace.html.haml
@@ -1,6 +1,6 @@
- managed_namespace_help_text = s_('ClusterIntegration|Set a prefix for your namespaces. If not set, defaults to your project path. If modified, existing environments will use their current namespaces until the cluster cache is cleared.')
- non_managed_namespace_help_text = s_('ClusterIntegration|The namespace associated with your project. This will be used for deploy boards, logs, and Web terminals.')
-- managed_namespace_help_link = link_to _('More information'), help_page_path('user/project/clusters/gitlab_managed_clusters.md'), target: '_blank'
+- managed_namespace_help_link = link_to _('More information'), help_page_path('user/project/clusters/gitlab_managed_clusters.md'), target: '_blank', rel: 'noopener noreferrer'
.js-namespace-prefixed
= platform_field.text_field :namespace,
diff --git a/app/views/clusters/clusters/_provider_details_form.html.haml b/app/views/clusters/clusters/_provider_details_form.html.haml
index fe3d1998234..11277a83e3a 100644
--- a/app/views/clusters/clusters/_provider_details_form.html.haml
+++ b/app/views/clusters/clusters/_provider_details_form.html.haml
@@ -43,13 +43,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'
+ = link_to _('More information'), 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'
+ = link_to _('More information'), help_page_path('user/project/clusters/deploy_to_cluster.md', anchor: 'custom-namespace'), target: '_blank', rel: 'noopener noreferrer'
- if cluster.allow_user_defined_namespace?
= render('clusters/clusters/namespace', platform_field: platform_field, field: field)
diff --git a/app/views/clusters/clusters/gcp/_form.html.haml b/app/views/clusters/clusters/gcp/_form.html.haml
index 173456926a5..c8105fd1152 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'
+ = link_to _('More information'), 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'
+ = link_to _('More information'), 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'
+ = link_to _('More information'), 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/show.html.haml b/app/views/clusters/clusters/show.html.haml
index a6efe597f0c..bf654999f2f 100644
--- a/app/views/clusters/clusters/show.html.haml
+++ b/app/views/clusters/clusters/show.html.haml
@@ -36,7 +36,7 @@
= sprite_icon('close', css_class: 'gl-icon')
.gl-alert-body
= s_('ClusterApplicationsRemoved|One-click application management was removed in GitLab 14.0. Your applications are still installed in your cluster, and integrations continue working.')
- = link_to _('More information.'), help_page_path("user/clusters/applications"), target: '_blank'
+ = link_to _('More information.'), help_page_path("user/clusters/applications"), target: '_blank', rel: 'noopener noreferrer'
- if cluster_created?(@cluster)
.js-toggle-container
diff --git a/app/views/clusters/clusters/user/_form.html.haml b/app/views/clusters/clusters/user/_form.html.haml
index e9b84952c15..29af79cee5f 100644
--- a/app/views/clusters/clusters/user/_form.html.haml
+++ b/app/views/clusters/clusters/user/_form.html.haml
@@ -1,7 +1,7 @@
- more_info_link = link_to _('More information'), help_page_path('user/project/clusters/add_remove_clusters.md',
- anchor: 'add-existing-cluster'), target: '_blank'
+ 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',
- anchor: 'access-controls'), target: '_blank'
+ anchor: 'access-controls'), target: '_blank', rel: 'noopener noreferrer'
- api_url_help_text = s_('ClusterIntegration|The URL used to access the Kubernetes API.')
- ca_cert_help_text = s_('ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster.')
@@ -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'
+ = link_to _('More information'), 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'
+ = link_to _('More information'), 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/issues.html.haml b/app/views/dashboard/issues.html.haml
index 5a7eb46771b..f0216253dad 100644
--- a/app/views/dashboard/issues.html.haml
+++ b/app/views/dashboard/issues.html.haml
@@ -11,7 +11,7 @@
- if current_user
.page-title-controls
- = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", with_feature_enabled: 'issues', type: :issues
+ = render 'shared/new_project_item_select', path: 'issues/new', label: _("issue"), with_feature_enabled: 'issues', type: :issues
.top-area
= render 'shared/issuable/nav', type: :issues, display_count: !@no_filters_set
diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml
index ae557b73620..90fb09ed909 100644
--- a/app/views/dashboard/merge_requests.html.haml
+++ b/app/views/dashboard/merge_requests.html.haml
@@ -9,7 +9,7 @@
- if current_user
.page-title-controls.ml-0.mb-3.ml-sm-auto.mb-sm-0
- = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request", with_feature_enabled: 'merge_requests', type: :merge_requests
+ = render 'shared/new_project_item_select', path: 'merge_requests/new', label: _("merge request"), with_feature_enabled: 'merge_requests', type: :merge_requests
.top-area
= render 'shared/issuable/nav', type: :merge_requests, display_count: !@no_filters_set
diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml
index aa54a1e589e..f6dc62e1d44 100644
--- a/app/views/dashboard/todos/index.html.haml
+++ b/app/views/dashboard/todos/index.html.haml
@@ -6,26 +6,26 @@
- add_page_specific_style 'page_bundles/todos'
.page-title-holder.d-flex.align-items-center
- %h1.page-title= _('To-Do List')
+ %h1.page-title= _("To-Do List")
- if current_user.todos.any?
.top-area
= gl_tabs_nav({ class: 'gl-flex-grow-1 gl-border-0' }) do
= gl_tab_link_to todos_filter_path(state: 'pending'), item_active: params[:state].blank? || params[:state] == 'pending', class: "js-todos-pending" do
= _("To Do")
- = gl_tab_counter_badge number_with_delimiter(todos_pending_count)
+ = gl_tab_counter_badge(number_with_delimiter(todos_pending_count), { class: 'js-todos-badge' })
= gl_tab_link_to todos_filter_path(state: 'done'), item_active: params[:state] == 'done', class: "js-todos-done" do
= _("Done")
- = gl_tab_counter_badge number_with_delimiter(todos_done_count)
+ = gl_tab_counter_badge(number_with_delimiter(todos_done_count), { class: 'js-todos-badge' })
.nav-controls
- 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
- Mark all as done
+ = 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
- Undo mark all as done
+ = s_("Todos|Undo mark all as done")
%span.gl-spinner.ml-1
.todos-filters
@@ -35,28 +35,23 @@
.filter-item.gl-m-2
- if params[:group_id].present?
= hidden_field_tag(:group_id, params[:group_id])
- = dropdown_tag(group_dropdown_label(params[:group_id], 'Group'), options: { toggle_class: 'js-group-search js-filter-submit gl-xs-w-full!', title: 'Filter by group', filter: true, filterInput: 'input#group-search', dropdown_class: 'dropdown-menu-selectable dropdown-menu-group js-filter-submit',
- placeholder: 'Search groups', data: { default_label: 'Group', display: 'static' } })
+ = dropdown_tag(group_dropdown_label(params[:group_id], _("Group")), options: { toggle_class: 'js-group-search js-filter-submit gl-xs-w-full!', title: s_("Todos|Filter by group"), filter: true, filterInput: 'input#group-search', dropdown_class: 'dropdown-menu-selectable dropdown-menu-group js-filter-submit', placeholder: _("Search groups"), data: { default_label: _("Group"), display: 'static' } })
.filter-item.gl-m-2
- if params[:project_id].present?
= hidden_field_tag(:project_id, params[:project_id])
- = dropdown_tag(project_dropdown_label(params[:project_id], 'Project'), options: { toggle_class: 'js-project-search js-filter-submit gl-xs-w-full!', title: 'Filter by project', filter: true, filterInput: 'input#project-search', dropdown_class: 'dropdown-menu-selectable dropdown-menu-project js-filter-submit',
- placeholder: 'Search projects', data: { default_label: 'Project', display: 'static' } })
+ = dropdown_tag(project_dropdown_label(params[:project_id], _("Project")), options: { toggle_class: 'js-project-search js-filter-submit gl-xs-w-full!', title: s_("Todos|Filter by project"), filter: true, filterInput: 'input#project-search', dropdown_class: 'dropdown-menu-selectable dropdown-menu-project js-filter-submit', placeholder: _("Search projects"), data: { default_label: _("Project"), display: 'static' } })
.filter-item.gl-m-2
- if params[:author_id].present?
= hidden_field_tag(:author_id, params[:author_id])
- = dropdown_tag(user_dropdown_label(params[:author_id], 'Author'), options: { toggle_class: 'js-user-search js-filter-submit js-author-search gl-xs-w-full!', title: 'Filter by author', filter: true, filterInput: 'input#author-search', dropdown_class: 'dropdown-menu-user dropdown-menu-selectable dropdown-menu-author js-filter-submit',
- placeholder: 'Search authors', data: { any_user: 'Any Author', first_user: (current_user.username if current_user), project_id: (@project.id if @project), selected: params[:author_id], field_name: 'author_id', default_label: 'Author', todo_filter: true, todo_state_filter: params[:state] || 'pending' } })
+ = dropdown_tag(user_dropdown_label(params[:author_id], _("Author")), options: { toggle_class: 'js-user-search js-filter-submit js-author-search gl-xs-w-full!', title: s_("Todos|Filter by author"), filter: true, filterInput: 'input#author-search', dropdown_class: 'dropdown-menu-user dropdown-menu-selectable dropdown-menu-author js-filter-submit', placeholder: _("Search authors"), data: { any_user: _("Any Author"), first_user: (current_user.username if current_user), project_id: (@project.id if @project), selected: params[:author_id], field_name: 'author_id', default_label: _("Author"), todo_filter: true, todo_state_filter: params[:state] || 'pending' } })
.filter-item.gl-m-2
- if params[:type].present?
= hidden_field_tag(:type, params[:type])
- = dropdown_tag(todo_types_dropdown_label(params[:type], 'Type'), options: { toggle_class: 'js-type-search js-filter-submit gl-xs-w-full!', dropdown_class: 'dropdown-menu-selectable dropdown-menu-type js-filter-submit',
- data: { data: todo_types_options, default_label: 'Type' } })
+ = dropdown_tag(todo_types_dropdown_label(params[:type], _("Type")), options: { toggle_class: 'js-type-search js-filter-submit gl-xs-w-full!', dropdown_class: 'dropdown-menu-selectable dropdown-menu-type js-filter-submit', data: { data: todo_types_options, default_label: _("Type") } })
.filter-item.actions-filter.gl-m-2
- if params[:action_id].present?
= hidden_field_tag(:action_id, params[:action_id])
- = dropdown_tag(todo_actions_dropdown_label(params[:action_id], 'Action'), options: { toggle_class: 'js-action-search js-filter-submit gl-xs-w-full!', dropdown_class: 'dropdown-menu-selectable dropdown-menu-action js-filter-submit',
- data: { data: todo_actions_options, default_label: 'Action' } })
+ = dropdown_tag(todo_actions_dropdown_label(params[:action_id], _("Action")), options: { toggle_class: 'js-action-search js-filter-submit gl-xs-w-full!', dropdown_class: 'dropdown-menu-selectable dropdown-menu-action js-filter-submit', data: { data: todo_actions_options, default_label: _("Action") } })
.filter-item.sort-filter.gl-mt-3.gl-sm-mt-0.gl-mb-0.gl-sm-mb-0
.dropdown
%button.dropdown-menu-toggle.dropdown-menu-toggle-sort{ type: 'button', class: 'gl-xs-w-full!', 'data-toggle' => 'dropdown' }
@@ -85,40 +80,30 @@
.js-nothing-here-container.empty-state.hidden
.svg-content
= image_tag 'illustrations/todos_all_done.svg'
- .text-content
- %h4.text-center
- You're all done!
+ .text-content.gl-text-center
+ %h4
+ = s_("Todos|You're all done!")
- elsif current_user.todos.any?
.col.todos-all-done.empty-state
.svg-content.svg-250
= image_tag 'illustrations/todos_all_done.svg'
- .text-content
+ .text-content.gl-text-center
- if todos_filter_empty?
- %h4.text-center
+ %h4
= Gitlab.config.gitlab.no_todos_messages.sample
%p
- Are you looking for things to do? Take a look at
- = succeed "," do
- %strong
- = link_to "open issues", issues_dashboard_path
- contribute to
- %strong
- = link_to "a merge request\,", merge_requests_dashboard_path
- or mention someone in a comment to automatically assign them a new to-do item.
+ = (s_("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.") % { strongStart: '<strong>', strongEnd: '</strong>', openIssuesLinkStart: "<a href=\"#{issues_dashboard_path}\">", openIssuesLinkEnd: '</a>', mergeRequestLinkStart: "<a href=\"#{merge_requests_dashboard_path}\">", mergeRequestLinkEnd: '</a>' }).html_safe
- else
- %h4.text-center
- Nothing is on your to-do list. Nice work!
+ %h4
+ = s_("Todos|Nothing is on your to-do list. Nice work!")
- else
.col.empty-state
.svg-content
= image_tag 'illustrations/todos_empty.svg'
- .text-content
- %h4.text-center
- Your To-Do List shows what to work on next
+ .text-content.gl-text-center
+ %h4
+ = s_("Todos|Your To-Do List shows what to work on next")
%p
- When an issue or merge request is assigned to you, or when you receive a
- %strong
- @mention
- in a comment, this automatically triggers a new item in your To-Do List.
+ = (s_("Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List.") % { strongStart: '<strong>', strongEnd: '</strong>' }).html_safe
%p
- It's how you always know what to work on next.
+ = s_("Todos|It's how you always know what to work on next.")
diff --git a/app/views/devise/confirmations/almost_there.haml b/app/views/devise/confirmations/almost_there.haml
index 892ef730884..1d46a43e5bd 100644
--- a/app/views/devise/confirmations/almost_there.haml
+++ b/app/views/devise/confirmations/almost_there.haml
@@ -2,7 +2,9 @@
- request_link_start = '<a href="%{new_user_confirmation_path}">'.html_safe % { new_user_confirmation_path: new_user_confirmation_path }
- request_link_end = '</a>'.html_safe
- content_for :page_specific_javascripts do
+ = render "layouts/google_tag_manager_head"
= render "layouts/one_trust"
+= render "layouts/google_tag_manager_body"
.well-confirmation.gl-text-center.gl-mb-6
%h1.gl-mt-0
diff --git a/app/views/devise/shared/_signup_box.html.haml b/app/views/devise/shared/_signup_box.html.haml
index 15143684b8b..982171b9e34 100644
--- a/app/views/devise/shared/_signup_box.html.haml
+++ b/app/views/devise/shared/_signup_box.html.haml
@@ -62,7 +62,7 @@
%div
- if show_recaptcha_sign_up?
= recaptcha_tags nonce: content_security_policy_nonce
- .submit-container
+ .submit-container.gl-mt-5
= f.submit button_text, class: 'btn gl-button btn-confirm gl-display-block gl-w-full', data: { qa_selector: 'new_user_register_button' }
= render 'devise/shared/terms_of_service_notice', button_text: button_text
- if show_omniauth_providers && omniauth_providers_placement == :bottom
diff --git a/app/views/devise/shared/_signup_omniauth_provider_list.haml b/app/views/devise/shared/_signup_omniauth_provider_list.haml
index c24e8770f05..6688308cd71 100644
--- a/app/views/devise/shared/_signup_omniauth_provider_list.haml
+++ b/app/views/devise/shared/_signup_omniauth_provider_list.haml
@@ -2,7 +2,7 @@
= _("Create an account using:")
.gl-display-flex.gl-justify-content-between.gl-flex-wrap
- providers.each do |provider|
- = link_to omniauth_authorize_path(:user, provider), method: :post, class: "btn gl-button btn-default gl-w-full gl-mb-3 js-oauth-login #{qa_class_for_provider(provider)}", id: "oauth-login-#{provider}" do
+ = link_to omniauth_authorize_path(:user, provider), method: :post, class: "btn gl-button btn-default gl-w-full gl-mb-3 js-oauth-login #{qa_class_for_provider(provider)}", data: { provider: provider }, id: "oauth-login-#{provider}" do
- if provider_has_icon?(provider)
= provider_image_tag(provider)
%span.gl-button-text
diff --git a/app/views/doorkeeper/authorizations/new.html.haml b/app/views/doorkeeper/authorizations/new.html.haml
index f0e7a96f69f..bc69da5775f 100644
--- a/app/views/doorkeeper/authorizations/new.html.haml
+++ b/app/views/doorkeeper/authorizations/new.html.haml
@@ -1,14 +1,14 @@
%main{ :role => "main" }
- .modal-dialog.modal-doorkeepr-auth
- .modal-content.gl-shadow-none
- .modal-header
- %h3.page-title
+ .doorkeeper-authorize.gl-mx-auto.gl-mt-6
+ .gl-border-gray-200.gl-border-1.gl-border-solid.gl-rounded-base
+ .gl-p-5.gl-border-b-gray-200.gl-border-b-1.gl-border-b-solid
+ %h4.gl-m-0
- link_to_client = link_to(@pre_auth.client.name, @pre_auth.redirect_uri, target: '_blank', rel: 'noopener noreferrer')
= _("Authorize %{link_to_client} to use your account?").html_safe % { link_to_client: link_to_client }
- .modal-body
+ .gl-p-5
- if current_user.admin?
- .text-warning
+ .gl-text-orange-500
%p
= sprite_icon('warning-solid')
= html_escape(_('You are an admin, which means granting access to %{client_name} will allow them to interact with GitLab as an admin as well. Proceed with caution.')) % { client_name: tag.strong(@pre_auth.client.name) }
@@ -27,25 +27,25 @@
- @pre_auth.scopes.each do |scope|
%li
%strong= t scope, scope: [:doorkeeper, :scopes]
- .text-secondary= t scope, scope: [:doorkeeper, :scope_desc]
- .form-actions.text-right
- = form_tag oauth_authorization_path, method: :delete, class: 'inline' do
- = hidden_field_tag :client_id, @pre_auth.client.uid
- = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri
- = hidden_field_tag :state, @pre_auth.state
- = hidden_field_tag :response_type, @pre_auth.response_type
- = hidden_field_tag :scope, @pre_auth.scope
- = hidden_field_tag :nonce, @pre_auth.nonce
- = hidden_field_tag :code_challenge, @pre_auth.code_challenge
- = hidden_field_tag :code_challenge_method, @pre_auth.code_challenge_method
- = submit_tag _("Deny"), class: "gl-button btn btn-danger"
- = form_tag oauth_authorization_path, method: :post, class: 'inline' do
- = hidden_field_tag :client_id, @pre_auth.client.uid
- = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri
- = hidden_field_tag :state, @pre_auth.state
- = hidden_field_tag :response_type, @pre_auth.response_type
- = hidden_field_tag :scope, @pre_auth.scope
- = hidden_field_tag :nonce, @pre_auth.nonce
- = hidden_field_tag :code_challenge, @pre_auth.code_challenge
- = hidden_field_tag :code_challenge_method, @pre_auth.code_challenge_method
- = submit_tag _("Authorize"), class: "gl-button btn btn-confirm gl-ml-3", data: { qa_selector: 'authorization_button' }
+ .gl-text-gray-500= t scope, scope: [:doorkeeper, :scope_desc]
+ .gl-p-5.gl-bg-gray-10.gl-border-t-gray-200.gl-border-t-1.gl-border-t-solid.gl-rounded-bottom-right-base.gl-rounded-bottom-left-base.gl-text-right
+ = form_tag oauth_authorization_path, method: :delete, class: 'inline' do
+ = hidden_field_tag :client_id, @pre_auth.client.uid
+ = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri
+ = hidden_field_tag :state, @pre_auth.state
+ = hidden_field_tag :response_type, @pre_auth.response_type
+ = hidden_field_tag :scope, @pre_auth.scope
+ = hidden_field_tag :nonce, @pre_auth.nonce
+ = hidden_field_tag :code_challenge, @pre_auth.code_challenge
+ = hidden_field_tag :code_challenge_method, @pre_auth.code_challenge_method
+ = submit_tag _("Deny"), class: "btn btn-default gl-button"
+ = form_tag oauth_authorization_path, method: :post, class: 'inline' do
+ = hidden_field_tag :client_id, @pre_auth.client.uid
+ = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri
+ = hidden_field_tag :state, @pre_auth.state
+ = hidden_field_tag :response_type, @pre_auth.response_type
+ = hidden_field_tag :scope, @pre_auth.scope
+ = hidden_field_tag :nonce, @pre_auth.nonce
+ = hidden_field_tag :code_challenge, @pre_auth.code_challenge
+ = hidden_field_tag :code_challenge_method, @pre_auth.code_challenge_method
+ = submit_tag _("Authorize"), class: "btn btn-danger gl-button gl-ml-3", data: { qa_selector: 'authorization_button' }
diff --git a/app/views/graphiql/rails/editors/show.html.erb b/app/views/graphiql/rails/editors/show.html.erb
deleted file mode 100644
index b8f82ae8323..00000000000
--- a/app/views/graphiql/rails/editors/show.html.erb
+++ /dev/null
@@ -1,99 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>GraphiQL</title>
- <%= stylesheet_link_tag("graphiql/rails/application") %>
- <%# TODO: This file was included to fix a CSP failure. Please remove when https://github.com/rmosolgo/graphiql-rails/pull/71 will be released %>
- <%= javascript_include_tag("graphiql/rails/application", nonce: true) %>
- </head>
- <body>
- <div id="graphiql-container">
- Loading...
- </div>
- <%= javascript_tag nonce: true do -%>
- var parameters = {};
-
- <% if GraphiQL::Rails.config.query_params %>
- // Parse the search string to get url parameters.
- var search = window.location.search;
- search.substr(1).split('&').forEach(function (entry) {
- var eq = entry.indexOf('=');
- if (eq >= 0) {
- parameters[decodeURIComponent(entry.slice(0, eq))] =
- decodeURIComponent(entry.slice(eq + 1));
- }
- });
- // if variables was provided, try to format it.
- if (parameters.variables) {
- try {
- parameters.variables =
- JSON.stringify(JSON.parse(parameters.variables), null, 2);
- } catch (e) {
- // Do nothing, we want to display the invalid JSON as a string, rather
- // than present an error.
- }
- }
- // When the query and variables string is edited, update the URL bar so
- // that it can be easily shared
- function onEditQuery(newQuery) {
- parameters.query = newQuery;
- updateURL();
- }
- function onEditVariables(newVariables) {
- parameters.variables = newVariables;
- updateURL();
- }
- function updateURL() {
- var newSearch = '?' + Object.keys(parameters).map(function (key) {
- return encodeURIComponent(key) + '=' +
- encodeURIComponent(parameters[key]);
- }).join('&');
- history.replaceState(null, null, newSearch);
- }
- <% end %>
-
- // Defines a GraphQL fetcher using the fetch API.
- var graphQLEndpoint = "<%= graphql_endpoint_path %>";
- function graphQLFetcher(graphQLParams) {
- return fetch(graphQLEndpoint, {
- method: 'post',
- headers: <%= raw JSON.pretty_generate(GraphiQL::Rails.config.resolve_headers(self)) %>,
- body: JSON.stringify(graphQLParams),
- credentials: 'include',
- }).then(function(response) {
- return response.text();
- }).then(function(text) {
- try {
- return JSON.parse(text);
- } catch(error) {
- return {
- "message": "The server responded with invalid JSON, this is probably a server-side error",
- "response": text,
- };
- }
- })
- }
-
- <% if GraphiQL::Rails.config.initial_query %>
- var defaultQuery = "<%= GraphiQL::Rails.config.initial_query.gsub("\n", '\n').gsub('"', '\"').html_safe %>";
- <% else %>
- var defaultQuery = undefined
- <% end %>
-
- // Render <GraphiQL /> into the body.
- ReactDOM.render(
- React.createElement(GraphiQL, {
- fetcher: graphQLFetcher,
- defaultQuery: defaultQuery,
- <% if GraphiQL::Rails.config.query_params %>
- query: parameters.query,
- variables: parameters.variables,
- onEditQuery: onEditQuery,
- onEditVariables: onEditVariables
- <% end %>
- }),
- document.getElementById("graphiql-container")
- );
- <% end -%>
- </body>
-</html>
diff --git a/app/views/groups/_home_panel.html.haml b/app/views/groups/_home_panel.html.haml
index e530d9c60b6..e5d67831c71 100644
--- a/app/views/groups/_home_panel.html.haml
+++ b/app/views/groups/_home_panel.html.haml
@@ -9,17 +9,18 @@
= group_icon(@group, class: 'avatar avatar-tile s64', width: 64, height: 64, itemprop: 'logo')
.d-flex.flex-column.flex-wrap.align-items-baseline
.d-inline-flex.align-items-baseline
- %h1.home-panel-title.gl-mt-3.gl-mb-2.gl-ml-3{ itemprop: 'name' }
+ %h1.home-panel-title.gl-mt-3.gl-mb-2{ itemprop: 'name' }
= @group.name
%span.visibility-icon.text-secondary.gl-ml-2.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@group) }
= visibility_level_icon(@group.visibility_level, options: {class: 'icon'})
- .home-panel-metadata.text-secondary.gl-font-base.gl-font-weight-normal.gl-line-height-normal
+ .home-panel-metadata.text-secondary.gl-font-base.gl-font-weight-normal.gl-line-height-normal{ data: { qa_selector: 'group_id_content' }, itemprop: 'identifier' }
- if can?(current_user, :read_group, @group)
- - button_class = "btn gl-button btn-sm btn-tertiary btn-default-tertiary home-panel-metadata"
- - button_text = s_('GroupPage|Group ID: %{group_id}') % { group_id: @group.id }
- = clipboard_button(title: s_('GroupPage|Copy group ID'), text: @group.id, hide_button_icon: true, button_text: button_text, class: button_class, qa_selector: 'group_id_content', itemprop: 'identifier')
+ %span.gl-display-inline-block.gl-vertical-align-middle
+ = s_("GroupPage|Group ID: %{group_id}") % { group_id: @group.id }
+ - button_class = "btn gl-button btn-sm btn-tertiary btn-default-tertiary home-panel-metadata"
+ = clipboard_button(title: s_('GroupPage|Copy group ID'), text: @group.id, class: button_class)
- if current_user
- %span.gl-ml-3
+ %span.gl-ml-3.gl-mb-3
= render 'shared/members/access_request_links', source: @group
.home-panel-buttons.col-md-12.col-lg-6
diff --git a/app/views/groups/_new_group_fields.html.haml b/app/views/groups/_new_group_fields.html.haml
index 8ee7c91a938..fe2ee62d9be 100644
--- a/app/views/groups/_new_group_fields.html.haml
+++ b/app/views/groups/_new_group_fields.html.haml
@@ -7,14 +7,15 @@
= _('Visibility level')
%p
= _('Who will be able to see this group?')
- = link_to _('View the documentation'), help_page_path("public_access/public_access"), target: '_blank'
+ = link_to _('View the documentation'), help_page_path("public_access/public_access"), target: '_blank', rel: 'noopener noreferrer'
= render 'shared/visibility_level', f: f, visibility_level: default_group_visibility, can_change_visibility_level: true, form_model: @group, with_label: false
- if Gitlab.config.mattermost.enabled
.row
= render 'create_chat_team', f: f
-= render 'personalize', f: f
+- unless Gitlab::CurrentSettings.current_application_settings.hide_third_party_offers?
+ = render 'personalize', f: f
.row.js-invite-members-section
.col-sm-4
diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml
index 420771257c9..f3494149087 100644
--- a/app/views/groups/edit.html.haml
+++ b/app/views/groups/edit.html.haml
@@ -20,11 +20,11 @@
%section.settings.gs-permissions.no-animate#js-permissions-settings{ class: ('expanded' if expanded), data: { qa_selector: 'permission_lfs_2fa_content' } }
.settings-header
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only{ role: 'button' }
- = _('Permissions, LFS, 2FA')
+ = _('Permissions and group features')
%button.btn.gl-button.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p
- = _('Configure advanced permissions, Large File Storage, and two-factor authentication settings.')
+ = _('Configure advanced permissions, Large File Storage, two-factor authentication, and customer relations settings.')
.settings-content
= render 'groups/settings/permissions'
@@ -60,4 +60,3 @@
= render_if_exists 'shared/groups/max_pages_size_setting'
-= render 'shared/confirm_modal', phrase: @group.path
diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml
index 0c6776a6038..a9258a4e0d0 100644
--- a/app/views/groups/issues.html.haml
+++ b/app/views/groups/issues.html.haml
@@ -18,21 +18,11 @@
- if @can_bulk_update
= render_if_exists 'shared/issuable/bulk_update_button', type: :issues
- = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", type: :issues, with_feature_enabled: 'issues', with_shared: false, include_projects_in_subgroups: true
+ = render 'shared/new_project_item_select', path: 'issues/new', label: _("issue"), type: :issues, with_feature_enabled: 'issues', with_shared: false, include_projects_in_subgroups: true
= render 'shared/issuable/search_bar', type: :issues
- if @can_bulk_update
= render_if_exists 'shared/issuable/group_bulk_update_sidebar', group: @group, type: :issues
- - if Feature.enabled?(:vue_issuables_list, @group) && @issues.to_a.any?
- - if use_startup_call?
- - add_page_startup_api_call(api_v4_groups_issues_path(id: @group.id, params: startup_call_params))
- .js-issuables-list{ data: { endpoint: expose_url(api_v4_groups_issues_path(id: @group.id)),
- 'can-bulk-edit': @can_bulk_update.to_json,
- 'empty-state-meta': { svg_path: image_path('illustrations/issues.svg') },
- 'sort-key': @sort,
- type: 'issues',
- 'scoped-labels-available': scoped_labels_available?(@group).to_json } }
- - else
- = render 'shared/issues', project_select_button: true
+ = render 'shared/issues', project_select_button: true
diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml
index ad916e3aeec..011c76e5ae7 100644
--- a/app/views/groups/merge_requests.html.haml
+++ b/app/views/groups/merge_requests.html.haml
@@ -12,7 +12,7 @@
- if @can_bulk_update
= render_if_exists 'shared/issuable/bulk_update_button', type: :merge_requests
- = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request", type: :merge_requests, with_feature_enabled: 'merge_requests', with_shared: false, include_projects_in_subgroups: true
+ = render 'shared/new_project_item_select', path: 'merge_requests/new', label: _("merge request"), type: :merge_requests, with_feature_enabled: 'merge_requests', with_shared: false, include_projects_in_subgroups: true
= render 'shared/issuable/search_bar', type: :merge_requests
diff --git a/app/views/groups/new.html.haml b/app/views/groups/new.html.haml
index e55af71022e..750030601b7 100644
--- a/app/views/groups/new.html.haml
+++ b/app/views/groups/new.html.haml
@@ -6,7 +6,7 @@
.group-edit-container.gl-mt-5
- .js-new-group-creation{ data: { has_errors: @group.errors.any?.to_s } }
+ .js-new-group-creation{ data: { has_errors: @group.errors.any?.to_s }.merge(verification_for_group_creation_data) }
.row{ 'v-cloak': true }
#create-group-pane.tab-pane
diff --git a/app/views/groups/packages/index.html.haml b/app/views/groups/packages/index.html.haml
index d56a806f082..1c0627779ec 100644
--- a/app/views/groups/packages/index.html.haml
+++ b/app/views/groups/packages/index.html.haml
@@ -7,4 +7,7 @@
full_path: @group.full_path,
endpoint: group_packages_path(@group),
page_type: 'groups',
- empty_list_illustration: image_path('illustrations/no-packages.svg'), } }
+ empty_list_illustration: image_path('illustrations/no-packages.svg'),
+ npm_instance_url: package_registry_instance_url(:npm),
+ project_list_url: '',
+ group_list_url: group_packages_path(@group) } }
diff --git a/app/views/groups/runners/_group_runners.html.haml b/app/views/groups/runners/_group_runners.html.haml
index e7cfc87ac88..876642474cd 100644
--- a/app/views/groups/runners/_group_runners.html.haml
+++ b/app/views/groups/runners/_group_runners.html.haml
@@ -25,5 +25,5 @@
%br
- else
= _('Please contact an admin to register runners.')
- = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'runner-registration'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'prevent-users-from-registering-runners'), target: '_blank', rel: 'noopener noreferrer'
diff --git a/app/views/groups/runners/_runner.html.haml b/app/views/groups/runners/_runner.html.haml
index a76701ea5d2..78ce5b3e110 100644
--- a/app/views/groups/runners/_runner.html.haml
+++ b/app/views/groups/runners/_runner.html.haml
@@ -3,17 +3,13 @@
.table-mobile-header{ role: 'rowheader' }= _('Type')
.table-mobile-content
- if runner.group_type?
- %span.badge.badge-pill.gl-badge.sm.badge-success
- = s_('Runners|group')
+ = gl_badge_tag s_('Runners|group'), variant: :success, size: :sm
- else
- %span.badge.badge-pill.gl-badge.sm.badge-info
- = s_('Runners|specific')
+ = gl_badge_tag s_('Runners|specific'), variant: :info, size: :sm
- if runner.locked?
- %span.badge.badge-pill.gl-badge.sm.badge-warning
- = s_('Runners|locked')
+ = gl_badge_tag s_('Runners|locked'), variant: :warning, size: :sm
- unless runner.active?
- %span.badge.badge-pill.gl-badge.sm.badge-danger
- = s_('Runners|paused')
+ = gl_badge_tag s_('Runners|paused'), variant: :danger, size: :sm
.table-section.section-30
.table-mobile-header{ role: 'rowheader' }= s_('Runners|Runner')
@@ -50,8 +46,7 @@
.table-mobile-header{ role: 'rowheader' }= _('Tags')
.table-mobile-content
- runner.tags.map(&:name).sort.each do |tag|
- %span.badge.badge-primary.str-truncated.has-tooltip{ title: tag }
- = tag
+ = gl_badge_tag tag, { variant: :info }, { class: 'str-truncated has-tooltip', title: tag }
.table-section.section-10
.table-mobile-header{ role: 'rowheader' }= _('Last contact')
@@ -81,5 +76,5 @@
= sprite_icon('close', css_class: 'gl-icon')
- else
.btn-group
- = link_to group_runner_path(@group, runner), method: :delete, class: 'gl-button btn btn-danger btn-icon has-tooltip', title: _('Remove'), ref: 'tooltip', aria: { label: _('Remove') }, data: { placement: 'top', container: 'body', confirm: _('Are you sure?') } do
+ = link_to group_runner_path(@group, runner), method: :delete, class: 'gl-button btn btn-danger btn-icon has-tooltip', title: _('Remove'), ref: 'tooltip', aria: { label: _('Remove') }, data: { placement: 'top', container: 'body', confirm: _('Are you sure?'), confirm_btn_variant: "danger" } do
= sprite_icon('close', css_class: 'gl-icon')
diff --git a/app/views/groups/settings/_ip_restriction_registration_features_cta.html.haml b/app/views/groups/settings/_ip_restriction_registration_features_cta.html.haml
new file mode 100644
index 00000000000..3067220ea8f
--- /dev/null
+++ b/app/views/groups/settings/_ip_restriction_registration_features_cta.html.haml
@@ -0,0 +1,8 @@
+- return unless registration_features_can_be_prompted?
+
+.form-group
+ = f.label :disabled_ip_restriction_ranges, class: 'label-bold' do
+ = _('Allow access to the following IP addresses')
+ = f.text_field :disabled_ip_restriction_ranges, value: '', class: 'form-control', disabled: true
+ %span.form-text.text-muted
+ = render 'shared/registration_features_discovery_message'
diff --git a/app/views/groups/settings/_permissions.html.haml b/app/views/groups/settings/_permissions.html.haml
index eb38aa43881..d4b74665398 100644
--- a/app/views/groups/settings/_permissions.html.haml
+++ b/app/views/groups/settings/_permissions.html.haml
@@ -29,8 +29,9 @@
checkbox_options: { checked: @group.mentions_disabled? },
help_text: s_('GroupSettings|Prevents group members from being notified if the group is mentioned.')
- = render 'groups/settings/project_access_token_creation', f: f, group: @group
+ = render 'groups/settings/resource_access_token_creation', f: f, group: @group
= render_if_exists 'groups/settings/delayed_project_removal', f: f, group: @group
+ = render 'groups/settings/ip_restriction_registration_features_cta', f: f
= 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
@@ -41,4 +42,13 @@
= render 'groups/settings/two_factor_auth', f: f, group: @group
= 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)
+ %h5= _('Customer relations')
+ .form-group.gl-mb-3
+ = f.gitlab_ui_checkbox_component :crm_enabled,
+ s_('GroupSettings|Enable customer relations'),
+ checkbox_options: { checked: @group.crm_enabled? },
+ help_text: s_('GroupSettings|Allows creating organizations and contacts and associating them with issues.')
+
= f.submit _('Save changes'), class: 'btn gl-button btn-confirm gl-mt-3 js-dirty-submit', data: { qa_selector: 'save_permissions_changes_button' }
diff --git a/app/views/groups/settings/_project_access_token_creation.html.haml b/app/views/groups/settings/_project_access_token_creation.html.haml
deleted file mode 100644
index 948b25390ba..00000000000
--- a/app/views/groups/settings/_project_access_token_creation.html.haml
+++ /dev/null
@@ -1,9 +0,0 @@
-- return unless render_setting_to_allow_project_access_token_creation?(group)
-
-.form-group.gl-mb-3
- - project_access_tokens_link = help_page_path('user/project/settings/project_access_tokens')
- - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: project_access_tokens_link }
- = f.gitlab_ui_checkbox_component :resource_access_token_creation_allowed,
- s_('GroupSettings|Allow project access token creation'),
- checkbox_options: { checked: group.namespace_settings.resource_access_token_creation_allowed?, data: { qa_selector: 'resource_access_token_creation_allowed_checkbox' } },
- help_text: s_('GroupSettings|Users can create %{link_start}project access tokens%{link_end} for projects in this group.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
diff --git a/app/views/groups/settings/_resource_access_token_creation.html.haml b/app/views/groups/settings/_resource_access_token_creation.html.haml
new file mode 100644
index 00000000000..160f8ae1e07
--- /dev/null
+++ b/app/views/groups/settings/_resource_access_token_creation.html.haml
@@ -0,0 +1,11 @@
+- return unless render_setting_to_allow_project_access_token_creation?(group)
+
+.form-group.gl-mb-3
+ - project_access_tokens_link = help_page_path('user/project/settings/project_access_tokens')
+ - group_access_tokens_link = help_page_path('user/group/settings/group_access_tokens')
+ - link_start_project = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: project_access_tokens_link }
+ - link_start_group = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: group_access_tokens_link }
+ = f.gitlab_ui_checkbox_component :resource_access_token_creation_allowed,
+ s_('GroupSettings|Allow project and group access token creation'),
+ checkbox_options: { checked: group.namespace_settings.resource_access_token_creation_allowed?, data: { qa_selector: 'resource_access_token_creation_allowed_checkbox' } },
+ help_text: s_('GroupSettings|Users can create %{link_start_project}project access tokens%{link_end} and %{link_start_group}group access tokens%{link_end} in this group.').html_safe % { link_start_project: link_start_project, link_start_group: link_start_group, link_end: '</a>'.html_safe }
diff --git a/app/views/groups/settings/access_tokens/index.html.haml b/app/views/groups/settings/access_tokens/index.html.haml
new file mode 100644
index 00000000000..16ea96f0b08
--- /dev/null
+++ b/app/views/groups/settings/access_tokens/index.html.haml
@@ -0,0 +1,50 @@
+- breadcrumb_title s_('AccessTokens|Access Tokens')
+- page_title _('Group Access Tokens')
+- type = _('group access token')
+- type_plural = _('group access tokens')
+- @content_class = 'limit-container-width' unless fluid_layout
+
+.row.gl-mt-3
+ .col-lg-4
+ %h4.gl-mt-0
+ = page_title
+ %p
+ - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/group/settings/group_access_tokens') }
+ - if current_user.can?(:create_resource_access_tokens, @group)
+ = _('Generate group access tokens scoped to this group for your applications that need access to the GitLab API.')
+ %p
+ = _('You can also use group access tokens with Git to authenticate over HTTP(S). %{link_start}Learn more.%{link_end}').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
+ - else
+ = _('Group access token creation is disabled in this group. You can still use and manage existing tokens. %{link_start}Learn more.%{link_end}').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
+ %p
+ - root_group = @group.root_ancestor
+ - if current_user.can?(:admin_group, root_group)
+ - group_settings_link = edit_group_path(root_group)
+ - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: group_settings_link }
+ = _('You can enable group access token creation in %{link_start}group settings%{link_end}.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
+
+ .col-lg-8
+ - if @new_resource_access_token
+ = render 'shared/access_tokens/created_container',
+ type: type,
+ new_token_value: @new_resource_access_token
+
+ - if current_user.can?(:create_resource_access_tokens, @group)
+ = render 'shared/access_tokens/form',
+ type: type,
+ path: group_settings_access_tokens_path(@group),
+ resource: @group,
+ token: @resource_access_token,
+ scopes: @scopes,
+ access_levels: GroupMember.access_level_roles,
+ default_access_level: Gitlab::Access::MAINTAINER,
+ prefix: :resource_access_token,
+ help_path: help_page_path('user/group/settings/group_access_tokens', anchor: 'scopes-for-a-group-access-token')
+
+ = render 'shared/access_tokens/table',
+ active_tokens: @active_resource_access_tokens,
+ resource: @group,
+ type: type,
+ type_plural: type_plural,
+ revoke_route_helper: ->(token) { revoke_group_settings_access_token_path(id: token) },
+ no_active_tokens_message: _('This group has no active access tokens.')
diff --git a/app/views/groups/settings/ci_cd/_auto_devops_form.html.haml b/app/views/groups/settings/ci_cd/_auto_devops_form.html.haml
index 32da444d058..12c0f15aff5 100644
--- a/app/views/groups/settings/ci_cd/_auto_devops_form.html.haml
+++ b/app/views/groups/settings/ci_cd/_auto_devops_form.html.haml
@@ -11,5 +11,6 @@
= gl_badge_tag badge_for_auto_devops_scope(group), variant: :info
.form-text.text-muted
= s_('GroupSettings|The Auto DevOps pipeline runs if no alternative CI configuration file is found.')
- = link_to _('Learn more.'), help_page_path('topics/autodevops/index.md'), target: '_blank'
+ = link_to _('Learn more.'), help_page_path('topics/autodevops/index.md'), target: '_blank', rel: 'noopener noreferrer'
+
= f.submit _('Save changes'), class: 'btn gl-button btn-confirm gl-mt-5'
diff --git a/app/views/help/index.html.haml b/app/views/help/index.html.haml
index f81afd0a82e..3992cb527ed 100644
--- a/app/views/help/index.html.haml
+++ b/app/views/help/index.html.haml
@@ -4,12 +4,15 @@
= markdown_field(Gitlab::CurrentSettings.current_application_settings, :help_page_text)
%hr
-%h1
- = default_brand_title
- - if user_signed_in?
- %span= link_to_version
- = version_status_badge
- %hr
+.gl-display-flex.gl-align-items-flex-end
+ %h1.gl-mt-5.gl-mb-3
+ = default_brand_title
+ - if user_signed_in?
+ %span= link_to_version
+ - if show_version_check?
+ %span.gl-mt-5.gl-mb-3.gl-ml-3
+ .js-gitlab-version-check{ data: { "size": "lg" } }
+%hr
- unless Gitlab::CurrentSettings.help_page_hide_commercial_content?
%p.slead
diff --git a/app/views/layouts/_init_auto_complete.html.haml b/app/views/layouts/_init_auto_complete.html.haml
index 509f5be8097..46d84d9f883 100644
--- a/app/views/layouts/_init_auto_complete.html.haml
+++ b/app/views/layouts/_init_auto_complete.html.haml
@@ -1,5 +1,5 @@
- object = @target_project || @project || @group
-- noteable_type = @noteable.class if @noteable.present?
+- noteable_type = @noteable_type || @noteable&.class
- datasources = autocomplete_data_sources(object, noteable_type)
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index 69b8518ef33..d0a06c7d5bf 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -19,8 +19,18 @@
%span.gl-badge.gl-bg-green-500.gl-text-white.gl-rounded-pill.gl-font-weight-bold.gl-py-1
= _('Next')
- .gl-display-none.gl-sm-display-block
- = render "layouts/nav/top_nav"
+ - if current_user
+ .gl-display-none.gl-sm-display-block
+ = render "layouts/nav/top_nav"
+ - else
+ - experiment(:logged_out_marketing_header, actor: nil) do |e|
+ - e.candidate do
+ = render 'layouts/header/marketing_links'
+ - e.try(:trial_focused) do
+ = render 'layouts/header/marketing_links'
+ - e.control do
+ .gl-display-none.gl-sm-display-block
+ = render "layouts/nav/top_nav"
.navbar-collapse.collapse
%ul.nav.navbar-nav
@@ -38,7 +48,7 @@
'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: _('Search or jump to...'), class: 'form-control gl-form-input gl-search-box-by-type-input', id: 'search', autocomplete: 'off' }
+ %input{ type: "text", placeholder: s_('GlobalSearch|Search GitLab'), class: 'form-control gl-form-input gl-search-box-by-type-input', id: 'search', autocomplete: 'off' }
- else
= render 'layouts/search'
%li.nav-item{ class: 'd-none d-sm-inline-block d-lg-none' }
@@ -104,6 +114,15 @@
= sprite_icon('chevron-down', css_class: 'caret-down')
.dropdown-menu.dropdown-menu-right
= render 'layouts/header/help_dropdown'
+ - unless current_user
+ - experiment(:logged_out_marketing_header, actor: nil) do |e|
+ - e.candidate do
+ %li.nav-item.gl-display-none.gl-sm-display-block
+ = render "layouts/nav/top_nav"
+ - e.try(:trial_focused) do
+ %li.nav-item.gl-display-none.gl-sm-display-block
+ = render "layouts/nav/top_nav"
+ - e.control {}
- if header_link?(:user_dropdown)
%li.nav-item.header-user.js-nav-user-dropdown.dropdown{ data: { track_label: "profile_dropdown", track_action: "click_dropdown", track_value: "", qa_selector: 'user_menu' }, class: ('mr-0' if has_impersonation_link) }
= link_to current_user, class: user_dropdown_class, data: { toggle: "dropdown" } do
@@ -117,10 +136,23 @@
= link_to admin_impersonation_path, class: 'nav-link impersonation-btn', method: :delete, title: _('Stop impersonation'), aria: { label: _('Stop impersonation') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body', qa_selector: 'stop_impersonation_link' } do
= sprite_icon('incognito', size: 18)
- if header_link?(:sign_in)
- %li.nav-item
- %div
- - sign_in_text = allow_signup? ? _('Sign in / Register') : _('Sign in')
- = link_to sign_in_text, new_session_path(:user, redirect_to_referer: 'yes'), class: 'gl-button btn btn-default btn-sign-in'
+ - experiment(:logged_out_marketing_header, actor: nil) do |e|
+ - e.candidate do
+ %li.nav-item.gl-display-none.gl-sm-display-block
+ = link_to _('Sign up now'), new_user_registration_path, class: 'gl-button btn btn-default btn-sign-in'
+ %li.nav-item.gl-display-none.gl-sm-display-block
+ = link_to _('Login'), new_session_path(:user, redirect_to_referer: 'yes')
+ = render 'layouts/header/sign_in_register_button', class: 'gl-sm-display-none'
+ - e.try(:trial_focused) do
+ %li.nav-item.gl-display-none.gl-sm-display-block
+ = link_to _('Get a free trial'), 'https://about.gitlab.com/free-trial/', class: 'gl-button btn btn-default btn-sign-in'
+ %li.nav-item.gl-display-none.gl-sm-display-block
+ = link_to _('Sign up'), new_user_registration_path
+ %li.nav-item.gl-display-none.gl-sm-display-block
+ = link_to _('Login'), new_session_path(:user, redirect_to_referer: 'yes')
+ = render 'layouts/header/sign_in_register_button', class: 'gl-sm-display-none'
+ - e.control do
+ = render 'layouts/header/sign_in_register_button'
%button.navbar-toggler.d-block.d-sm-none{ type: 'button', class: 'gl-border-none!', data: { testid: 'top-nav-responsive-toggle', qa_selector: 'mobile_navbar_button' } }
%span.sr-only= _('Toggle navigation')
diff --git a/app/views/layouts/header/_gitlab_version.html.haml b/app/views/layouts/header/_gitlab_version.html.haml
new file mode 100644
index 00000000000..125fbaa084c
--- /dev/null
+++ b/app/views/layouts/header/_gitlab_version.html.haml
@@ -0,0 +1,11 @@
+- return unless show_version_check?
+
+.gl-display-flex.gl-flex-direction-column.gl-px-4.gl-py-3
+ %span
+ = s_("VersionCheck|Your GitLab Version")
+ = emoji_icon('rocket')
+ %span
+ %span.gl-font-sm.gl-text-gray-500
+ #{Gitlab.version_info.major}.#{Gitlab.version_info.minor}
+ %span.gl-ml-2
+ .js-gitlab-version-check{ data: { "size": "sm" } }
diff --git a/app/views/layouts/header/_help_dropdown.html.haml b/app/views/layouts/header/_help_dropdown.html.haml
index e2c7781da54..738bca2f2cc 100644
--- a/app/views/layouts/header/_help_dropdown.html.haml
+++ b/app/views/layouts/header/_help_dropdown.html.haml
@@ -1,5 +1,6 @@
%ul
- if current_user_menu?(:help)
+ = render 'layouts/header/gitlab_version'
= render 'layouts/header/whats_new_dropdown_item'
%li
= link_to _("Help"), help_path
diff --git a/app/views/layouts/header/_marketing_links.html.haml b/app/views/layouts/header/_marketing_links.html.haml
new file mode 100644
index 00000000000..24069de394d
--- /dev/null
+++ b/app/views/layouts/header/_marketing_links.html.haml
@@ -0,0 +1,34 @@
+%ul.nav.navbar-sub-nav.gl-display-none.gl-lg-display-flex.gl-align-items-center
+ %li.dropdown.gl-mr-3
+ %button{ type: "button", data: { toggle: "dropdown" } }
+ = s_('LoggedOutMarketingHeader|About GitLab')
+ = sprite_icon('chevron-down', css_class: 'caret-down')
+ .dropdown-menu
+ %ul
+ %li
+ = link_to 'https://about.gitlab.com/stages-devops-lifecycle/' do
+ = s_('LoggedOutMarketingHeader|GitLab: the DevOps platform')
+ %li
+ = link_to explore_root_path do
+ = s_('LoggedOutMarketingHeader|Explore GitLab')
+ %li
+ = link_to 'https://about.gitlab.com/install/' do
+ = s_('LoggedOutMarketingHeader|Install GitLab')
+ %li
+ = link_to 'https://about.gitlab.com/is-it-any-good/' do
+ = s_('LoggedOutMarketingHeader|How GitLab compares')
+ %li
+ = link_to 'https://about.gitlab.com/get-started/' do
+ = s_('LoggedOutMarketingHeader|Get started')
+ %li
+ = link_to 'https://docs.gitlab.com/' do
+ = s_('LoggedOutMarketingHeader|GitLab docs')
+ %li
+ = link_to 'https://about.gitlab.com/learn/' do
+ = s_('LoggedOutMarketingHeader|GitLab Learn')
+ %li.gl-mr-3
+ = link_to 'https://about.gitlab.com/pricing/' do
+ = s_('LoggedOutMarketingHeader|Pricing')
+ %li.gl-mr-3
+ = link_to 'https://about.gitlab.com/sales/' do
+ = s_('LoggedOutMarketingHeader|Talk to an expert')
diff --git a/app/views/layouts/header/_sign_in_register_button.html.haml b/app/views/layouts/header/_sign_in_register_button.html.haml
new file mode 100644
index 00000000000..992e8785251
--- /dev/null
+++ b/app/views/layouts/header/_sign_in_register_button.html.haml
@@ -0,0 +1,6 @@
+- top_class = local_assigns.fetch(:class, nil)
+
+%li.nav-item{ class: top_class }
+ %div
+ - sign_in_text = allow_signup? ? _('Sign in / Register') : _('Sign in')
+ = link_to sign_in_text, new_session_path(:user, redirect_to_referer: 'yes'), class: 'gl-button btn btn-default btn-sign-in'
diff --git a/app/views/notify/_note_email.html.haml b/app/views/notify/_note_email.html.haml
index ae9c8554e73..ad0c873bf56 100644
--- a/app/views/notify/_note_email.html.haml
+++ b/app/views/notify/_note_email.html.haml
@@ -26,12 +26,10 @@
= stylesheet_link_tag 'mailers/highlighted_diff_email'
%table
- = render partial: "projects/diffs/line",
+ = render partial: "projects/diffs/email_line",
collection: discussion.truncated_diff_lines(diff_limit: diff_limit),
as: :line,
- locals: { diff_file: discussion.diff_file,
- plain: true,
- email: true }
+ locals: { diff_file: discussion.diff_file }
%div{ 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/repository_push_email.html.haml b/app/views/notify/repository_push_email.html.haml
index 5c5520f4cb8..93806e6de8e 100644
--- a/app/views/notify/repository_push_email.html.haml
+++ b/app/views/notify/repository_push_email.html.haml
@@ -74,7 +74,7 @@
- blob = diff_file.blob
- if blob && blob.readable_text?
%table.code.white
- = render partial: "projects/diffs/line", collection: diff_file.highlighted_diff_lines, as: :line, locals: { diff_file: diff_file, plain: true, email: true }
+ = render partial: "projects/diffs/email_line", collection: diff_file.highlighted_diff_lines, as: :line, locals: { diff_file: diff_file }
- else
No preview for this file type
%br
diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml
index 809dc3320ff..97056db6b74 100644
--- a/app/views/profiles/accounts/show.html.haml
+++ b/app/views/profiles/accounts/show.html.haml
@@ -55,7 +55,7 @@
%p
= s_('Profiles|Changing your username can have unintended side effects.')
= succeed '.' do
- = link_to s_('Profiles|Learn more'), help_page_path('user/profile/index', anchor: 'change-your-username'), target: '_blank'
+ = link_to s_('Profiles|Learn more'), help_page_path('user/profile/index', anchor: 'change-your-username'), target: '_blank', rel: 'noopener noreferrer'
.col-lg-8
- data = { initial_username: current_user.username, root_url: root_url, action_url: update_username_profile_path(format: :json) }
#update-username{ data: data }
diff --git a/app/views/profiles/chat_names/_chat_name.html.haml b/app/views/profiles/chat_names/_chat_name.html.haml
index 24c25bc1ab2..3206fca6bcd 100644
--- a/app/views/profiles/chat_names/_chat_name.html.haml
+++ b/app/views/profiles/chat_names/_chat_name.html.haml
@@ -10,7 +10,7 @@
%td
%strong
- if can?(current_user, :admin_project, project)
- = link_to integration.title, edit_project_service_path(project, integration)
+ = link_to integration.title, edit_project_integration_path(project, integration)
- else
= integration.title
%td
diff --git a/app/views/profiles/chat_names/index.html.haml b/app/views/profiles/chat_names/index.html.haml
index 782850afcda..54c34228800 100644
--- a/app/views/profiles/chat_names/index.html.haml
+++ b/app/views/profiles/chat_names/index.html.haml
@@ -9,7 +9,8 @@
= _('You can see your chat accounts.')
.col-lg-8
- %h5.gl-mt-0 Active chat names (#{@chat_names.size})
+ %h5.gl-mt-0
+ = sprintf(_('Active chat names (%{count})'), { count: @chat_names.size })
- if @chat_names.present?
.table-responsive
diff --git a/app/views/profiles/emails/index.html.haml b/app/views/profiles/emails/index.html.haml
index 0cfe65994da..fef55f5d384 100644
--- a/app/views/profiles/emails/index.html.haml
+++ b/app/views/profiles/emails/index.html.haml
@@ -37,23 +37,23 @@
%li
= render partial: 'shared/email_with_badge', locals: { email: @primary_email, verified: current_user.confirmed? }
%span.float-right
- %span.badge.badge-muted.badge-pill.gl-badge.badge-success= s_('Profiles|Primary email')
+ = gl_badge_tag s_('Profiles|Primary email'), variant: :success
- if @primary_email === current_user.commit_email_or_default
- %span.badge.badge-muted.badge-pill.gl-badge.badge-info= s_('Profiles|Commit email')
+ = gl_badge_tag s_('Profiles|Commit email'), variant: :info
- if @primary_email === current_user.public_email
- %span.badge.badge-muted.badge-pill.gl-badge.badge-info= s_('Profiles|Public email')
+ = gl_badge_tag s_('Profiles|Public email'), variant: :info
- if @primary_email === current_user.notification_email_or_default
- %span.badge.badge-muted.badge-pill.gl-badge.badge-info= s_('Profiles|Default notification email')
+ = gl_badge_tag s_('Profiles|Default notification email'), variant: :info
- @emails.reject(&:user_primary_email?).each do |email|
%li{ data: { qa_selector: 'email_row_content' } }
= render partial: 'shared/email_with_badge', locals: { email: email.email, verified: email.confirmed? }
%span.float-right
- if email.email === current_user.commit_email_or_default
- %span.badge.badge-muted.badge-pill.gl-badge.badge-info= s_('Profiles|Commit email')
+ = gl_badge_tag s_('Profiles|Commit email'), variant: :info
- if email.email === current_user.public_email
- %span.badge.badge-muted.badge-pill.gl-badge.badge-info= s_('Profiles|Public email')
+ = gl_badge_tag s_('Profiles|Public email'), variant: :info
- if email.email === current_user.notification_email_or_default
- %span.badge.badge-muted.badge-pill.gl-badge.badge-info= s_('Profiles|Notification email')
+ = gl_badge_tag s_('Profiles|Notification email'), variant: :info
- unless email.confirmed?
- confirm_title = "#{email.confirmation_sent_at ? _('Resend confirmation email') : _('Send confirmation email')}"
= link_to confirm_title, resend_confirmation_instructions_profile_email_path(email), method: :put, class: 'gl-button btn btn-sm btn-warning gl-ml-3'
diff --git a/app/views/profiles/gpg_keys/index.html.haml b/app/views/profiles/gpg_keys/index.html.haml
index bf9c77cb3ec..91af6953ee1 100644
--- a/app/views/profiles/gpg_keys/index.html.haml
+++ b/app/views/profiles/gpg_keys/index.html.haml
@@ -12,7 +12,7 @@
= _('Add a GPG key')
%p.profile-settings-content
- help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/repository/gpg_signed_commits/index.md') }
- = _('Before you can add a GPG key you need to %{help_link_start}Generate it.%{help_link_end}'.html_safe) % {help_link_start: help_link_start, help_link_end: '</a>'.html_safe }
+ = _('Add a GPG key for secure access to GitLab. %{help_link_start}Learn more.%{help_link_end}').html_safe % {help_link_start: help_link_start, help_link_end: '</a>'.html_safe }
= render 'form'
%hr
%h5
diff --git a/app/views/profiles/keys/_form.html.haml b/app/views/profiles/keys/_form.html.haml
index 2b3109225a8..bebbe49a485 100644
--- a/app/views/profiles/keys/_form.html.haml
+++ b/app/views/profiles/keys/_form.html.haml
@@ -5,8 +5,8 @@
.form-group
= f.label :key, s_('Profiles|Key'), class: 'label-bold'
- %p= _("Paste your public SSH key, which is usually contained in the file '~/.ssh/id_ed25519.pub' or '~/.ssh/id_rsa.pub' and begins with 'ssh-ed25519' or 'ssh-rsa'. Do not paste your private SSH key, as that can compromise your identity.")
- = f.text_area :key, class: "form-control gl-form-input js-add-ssh-key-validation-input qa-key-public-key-field", rows: 8, required: true, placeholder: s_('Profiles|Typically starts with "ssh-ed25519 …" or "ssh-rsa …"')
+ = f.text_area :key, class: "form-control gl-form-input js-add-ssh-key-validation-input qa-key-public-key-field", rows: 8, required: true, data: { supported_algorithms: Gitlab::SSHPublicKey.supported_algorithms }
+ %p.form-text.text-muted= s_('Profiles|Begins with %{ssh_key_algorithms}.') % { ssh_key_algorithms: ssh_key_allowed_algorithms }
.form-row
.col.form-group
= f.label :title, _('Title'), class: 'label-bold'
diff --git a/app/views/profiles/keys/index.html.haml b/app/views/profiles/keys/index.html.haml
index 584bd44e386..7d4c3b6115f 100644
--- a/app/views/profiles/keys/index.html.haml
+++ b/app/views/profiles/keys/index.html.haml
@@ -11,11 +11,8 @@
%h5.gl-mt-0
= _('Add an SSH key')
%p.profile-settings-content
- - generate_link_url = help_page_path("ssh/index", anchor: 'generate-an-ssh-key-pair')
- - existing_link_url = help_page_path("ssh/index", anchor: 'see-if-you-have-an-existing-ssh-key-pair')
- - generate_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: generate_link_url }
- - existing_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: existing_link_url }
- = _('To add an SSH key you need to %{generate_link_start}generate one%{link_end} or use an %{existing_link_start}existing key%{link_end}.').html_safe % { generate_link_start: generate_link_start, existing_link_start: existing_link_start, link_end: '</a>'.html_safe }
+ - help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('ssh/index.md') }
+ = _('Add an SSH key for secure access to GitLab. %{help_link_start}Learn more.%{help_link_end}').html_safe % {help_link_start: help_link_start, help_link_end: '</a>'.html_safe }
= render 'form'
%hr
%h5
diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml
index a8275576327..887d07f7a20 100644
--- a/app/views/profiles/personal_access_tokens/index.html.haml
+++ b/app/views/profiles/personal_access_tokens/index.html.haml
@@ -32,64 +32,5 @@
type_plural: type_plural,
active_tokens: @active_personal_access_tokens,
revoke_route_helper: ->(token) { revoke_profile_personal_access_token_path(token) }
-- if Feature.enabled?(:hide_access_tokens, default_enabled: :yaml)
- #js-tokens-app{ data: { tokens_data: tokens_app_data } }
-- else
- - unless Gitlab::CurrentSettings.disable_feed_token
- .col-lg-12
- %hr
- .row.gl-mt-3.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0
- = s_('AccessTokens|Feed token')
- %p
- = s_('AccessTokens|Your feed token authenticates you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar. It is visible in those feed URLs.')
- %p
- = s_('AccessTokens|It cannot be used to access any other data.')
- .col-lg-8.feed-token-reset
- = label_tag :feed_token, s_('AccessTokens|Feed token'), class: 'label-bold'
- = text_field_tag :feed_token, current_user.feed_token, class: 'form-control gl-form-input js-select-on-focus', readonly: true
- %p.form-text.text-muted
- - reset_link = link_to s_('AccessTokens|reset this token'), [:reset, :feed_token, :profile], method: :put, data: { confirm: s_('AccessTokens|Are you sure? Any RSS or calendar URLs currently in use will stop working.'), testid: :reset_feed_token_link }
- - reset_message = s_('AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}.') % { link_reset_it: reset_link }
- = reset_message.html_safe
- - if incoming_email_token_enabled?
- .col-lg-12
- %hr
- .row.gl-mt-3.js-search-settings-section
- .col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0
- = s_('AccessTokens|Incoming email token')
- %p
- = s_('AccessTokens|Your incoming email token authenticates you when you create a new issue by email, and is included in your personal project-specific email addresses.')
- %p
- = s_('AccessTokens|It cannot be used to access any other data.')
- .col-lg-8.incoming-email-token-reset
- = label_tag :incoming_email_token, s_('AccessTokens|Incoming email token'), class: 'label-bold'
- = text_field_tag :incoming_email_token, current_user.incoming_email_token, class: 'form-control gl-form-input js-select-on-focus', readonly: true
- %p.form-text.text-muted
- - reset_link = link_to s_('AccessTokens|reset this token'), [:reset, :incoming_email_token, :profile], method: :put, data: { confirm: s_('AccessTokens|Are you sure? Any issue email addresses currently in use will stop working.'), testid: :reset_email_token_link }
- - reset_message = s_('AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}.') % { link_reset_it: reset_link }
- = reset_message.html_safe
-
- - if static_objects_external_storage_enabled?
- .col-lg-12
- %hr
- .row.gl-mt-3.js-search-settings-section
- .col-lg-4
- %h4.gl-mt-0
- = s_('AccessTokens|Static object token')
- %p
- = s_('AccessTokens|Your static object token authenticates you when repository static objects (such as archives or blobs) are served from an external storage.')
- %p
- = s_('AccessTokens|It cannot be used to access any other data.')
- .col-lg-8
- = label_tag :static_object_token, s_('AccessTokens|Static object token'), class: "label-bold"
- = text_field_tag :static_object_token, current_user.static_object_token, class: 'form-control gl-form-input', readonly: true, onclick: 'this.select()'
- %p.form-text.text-muted
- - reset_link = url_for [:reset, :static_object_token, :profile]
- - reset_link_start = '<a data-confirm="%{confirm}" rel="nofollow" data-method="put" href="%{url}">'.html_safe % { confirm: s_('AccessTokens|Are you sure?'), url: reset_link }
- - reset_link_end = '</a>'.html_safe
- - reset_message = s_('AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}.') % { reset_link_start: reset_link_start, reset_link_end: reset_link_end }
- = reset_message.html_safe
+#js-tokens-app{ data: { tokens_data: tokens_app_data } }
diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml
index e52a345bd86..48be2001c9c 100644
--- a/app/views/profiles/preferences/show.html.haml
+++ b/app/views/profiles/preferences/show.html.haml
@@ -2,7 +2,7 @@
- @content_class = "limit-container-width" unless fluid_layout
- user_theme_id = Gitlab::Themes.for_user(@user).id
- user_fields = { theme: user_theme_id, gitpod_enabled: @user.gitpod_enabled, sourcegraph_enabled: @user.sourcegraph_enabled }.to_json
-- @themes = Gitlab::Themes::THEMES.to_json
+- @themes = Gitlab::Themes::available_themes.to_json
- data_attributes = { themes: @themes, integration_views: integration_views.to_json, user_fields: user_fields, body_classes: Gitlab::Themes.body_classes, profile_preferences_path: profile_preferences_path }
- Gitlab::Themes.each do |theme|
@@ -33,7 +33,7 @@
%p
= s_('Preferences|This setting allows you to customize the appearance of the syntax.')
= succeed '.' do
- = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'syntax-highlighting-theme'), target: '_blank'
+ = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'syntax-highlighting-theme'), target: '_blank', rel: 'noopener noreferrer'
.col-lg-8.syntax-theme
- Gitlab::ColorSchemes.each do |scheme|
= label_tag do
@@ -51,7 +51,7 @@
%p
= s_('Preferences|This setting allows you to customize the behavior of the system layout and default views.')
= succeed '.' do
- = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'behavior'), target: '_blank'
+ = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'behavior'), target: '_blank', rel: 'noopener noreferrer'
.col-lg-8
.form-group
= f.label :layout, class: 'label-bold' do
@@ -94,8 +94,7 @@
= s_('Preferences|Surround text selection when typing quotes or brackets')
.form-text.text-muted
- supported_characters = %w(" ' ` \( [ { < * _).map {|char| "<code>#{char}</code>" }.join(', ')
- - msg = "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}."
- = s_(msg).html_safe
+ = sprintf(s_( "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}."), { supported_characters: supported_characters }).html_safe
.form-group
= f.label :tab_width, s_('Preferences|Tab width'), class: 'label-bold'
@@ -116,7 +115,7 @@
%p
= _('Customize language and region related settings.')
= succeed '.' do
- = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'localization'), target: '_blank'
+ = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'localization'), target: '_blank', rel: 'noopener noreferrer'
.col-lg-8
.form-group
= f.label :preferred_language, class: 'label-bold' do
@@ -137,7 +136,7 @@
%p
= s_('Preferences|Configure how dates and times display for you.')
= succeed '.' do
- = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'time-preferences'), target: '_blank'
+ = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'time-preferences'), target: '_blank', rel: 'noopener noreferrer'
.col-lg-8
.form-group.form-check
= f.check_box :time_display_relative, class: 'form-check-input'
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index f3993ad8c33..531e72b7cc2 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -97,19 +97,19 @@
= render 'profiles/name', form: f, user: @user
= f.text_field :id, class: 'gl-form-input', readonly: true, label: s_('Profiles|User ID'), wrapper: { class: 'col-md-3' }
- = f.text_field :pronouns, class: 'input-md gl-form-input', help: s_("Profiles|Enter your pronouns to let people know how to refer to you")
- = f.text_field :pronunciation, class: 'input-md gl-form-input', help: s_("Profiles|Enter how your name is pronounced to help people address you correctly")
+ = f.text_field :pronouns, label: s_('Profiles|Pronouns'), class: 'input-md gl-form-input', help: s_("Profiles|Enter your pronouns to let people know how to refer to you")
+ = f.text_field :pronunciation, label: s_('Profiles|Pronunciation'), class: 'input-md gl-form-input', help: s_("Profiles|Enter how your name is pronounced to help people address you correctly")
= render_if_exists 'profiles/extra_settings', form: f
= render_if_exists 'profiles/email_settings', form: f
= f.text_field :skype, class: 'input-md gl-form-input', placeholder: s_("Profiles|username")
= f.text_field :linkedin, class: 'input-md gl-form-input', help: s_("Profiles|Your LinkedIn profile name from linkedin.com/in/profilename")
= f.text_field :twitter, class: 'input-md gl-form-input', placeholder: s_("Profiles|@username")
- = f.text_field :website_url, class: 'input-lg gl-form-input', placeholder: s_("Profiles|https://website.com")
+ = f.text_field :website_url, label: s_('Profiles|Website url'), class: 'input-lg gl-form-input', placeholder: s_("Profiles|https://website.com")
- if @user.read_only_attribute?(:location)
= f.text_field :location, class: 'gl-form-input', readonly: true, help: s_("Profiles|Your location was automatically set based on your %{provider_label} account") % { provider_label: attribute_provider_label(:location) }
- else
= f.text_field :location, label: s_('Profiles|Location'), class: 'input-lg gl-form-input', placeholder: s_("Profiles|City, country")
- = f.text_field :job_title, class: 'input-md gl-form-input'
+ = f.text_field :job_title, label: s_('Profiles|Job title'), class: 'input-md gl-form-input'
= f.text_field :organization, label: s_('Profiles|Organization'), class: 'input-md gl-form-input', help: s_("Profiles|Who you represent or work for")
= f.text_area :bio, class: 'gl-form-input', label: s_('Profiles|Bio'), rows: 4, maxlength: 250, help: s_("Profiles|Tell us about yourself in fewer than 250 characters")
%hr
@@ -142,10 +142,10 @@
%img.modal-profile-crop-image{ alt: s_("Profiles|Avatar cropper") }
.crop-controls
.btn-group
- %button.btn.gl-button.btn-confirm{ data: { method: 'zoom', option: '-0.1' } }
+ %button.btn.gl-button.btn-default{ data: { method: 'zoom', option: '-0.1' } }
%span
= sprite_icon('search-minus')
- %button.btn.gl-button.btn-confirm{ data: { method: 'zoom', option: '0.1' } }
+ %button.btn.gl-button.btn-default{ data: { method: 'zoom', option: '0.1' } }
%span
= sprite_icon('search-plus')
.modal-footer
diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml
index 1f2c16324fb..7e8daea5651 100644
--- a/app/views/projects/_home_panel.html.haml
+++ b/app/views/projects/_home_panel.html.haml
@@ -10,18 +10,19 @@
= project_icon(@project, alt: @project.name, class: 'avatar avatar-tile s64', width: 64, height: 64, itemprop: 'image')
.d-flex.flex-column.flex-wrap.align-items-baseline
.d-inline-flex.align-items-baseline
- %h1.home-panel-title.gl-mt-3.gl-mb-2.gl-font-size-h1.gl-line-height-24.gl-font-weight-bold.gl-ml-3{ data: { qa_selector: 'project_name_content' }, itemprop: 'name' }
+ %h1.home-panel-title.gl-mt-3.gl-mb-2.gl-font-size-h1.gl-line-height-24.gl-font-weight-bold{ data: { qa_selector: 'project_name_content' }, itemprop: 'name' }
= @project.name
%span.visibility-icon.text-secondary.gl-ml-2.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@project) }
= visibility_level_icon(@project.visibility_level, options: { class: 'icon' })
= render_if_exists 'compliance_management/compliance_framework/compliance_framework_badge', project: @project
- .home-panel-metadata.text-secondary.gl-font-base.gl-font-weight-normal.gl-line-height-normal
+ .home-panel-metadata.text-secondary.gl-font-base.gl-font-weight-normal.gl-line-height-normal{ data: { qa_selector: 'project_id_content' }, itemprop: 'identifier' }
- if can?(current_user, :read_project, @project)
- - button_class = "btn gl-button btn-sm btn-tertiary btn-default-tertiary home-panel-metadata"
- - button_text = s_('ProjectPage|Project ID: %{project_id}') % { project_id: @project.id }
- = clipboard_button(title: s_('ProjectPage|Copy project ID'), text: @project.id, hide_button_icon: true, button_text: button_text, class: button_class, qa_selector: 'project_id_content', itemprop: 'identifier')
+ %span.gl-display-inline-block.gl-vertical-align-middle
+ = s_('ProjectPage|Project ID: %{project_id}') % { project_id: @project.id }
+ - button_class = "btn gl-button btn-sm btn-tertiary btn-default-tertiary home-panel-metadata"
+ = clipboard_button(title: s_('ProjectPage|Copy project ID'), text: @project.id, class: button_class)
- if current_user
- %span.gl-display-inline-block.gl-vertical-align-middle.gl-ml-3
+ %span.gl-ml-3.gl-mb-3
= render 'shared/members/access_request_links', source: @project
.gl-mt-3.gl-pl-3.gl-w-full
diff --git a/app/views/projects/_import_project_pane.html.haml b/app/views/projects/_import_project_pane.html.haml
index 81d9726fcdc..63f09a065df 100644
--- a/app/views/projects/_import_project_pane.html.haml
+++ b/app/views/projects/_import_project_pane.html.haml
@@ -8,22 +8,22 @@
.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', **tracking_attrs(track_label, 'click_button', 'gitlab_export') do
+ = 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
.gl-button-icon
= sprite_icon('tanuki')
= _("GitLab export")
- if github_import_enabled?
%div
- = link_to new_import_github_path, class: 'gl-button btn-default btn js-import-github', **tracking_attrs(track_label, 'click_button', 'github') do
+ = link_to new_import_github_path, class: 'gl-button btn-default btn js-import-github js-import-project-btn', data: { platform: 'github', **tracking_attrs_data(track_label, 'click_button', 'github') } do
.gl-button-icon
= sprite_icon('github')
GitHub
- if bitbucket_import_enabled?
%div
- = link_to status_import_bitbucket_path, class: "gl-button btn-default btn import_bitbucket #{'how_to_import_link' unless bitbucket_import_configured?}",
- **tracking_attrs(track_label, 'click_button', 'bitbucket_cloud') do
+ = link_to status_import_bitbucket_path, class: "gl-button btn-default btn import_bitbucket js-import-project-btn #{'how_to_import_link' unless bitbucket_import_configured?}",
+ data: { platform: 'bitbucket_cloud', **tracking_attrs_data(track_label, 'click_button', 'bitbucket_cloud') } do
.gl-button-icon
= sprite_icon('bitbucket')
Bitbucket Cloud
@@ -31,15 +31,14 @@
= render 'projects/bitbucket_import_modal'
- if bitbucket_server_import_enabled?
%div
- = link_to status_import_bitbucket_server_path, class: "gl-button btn-default btn import_bitbucket", **tracking_attrs(track_label, 'click_button', 'bitbucket_server') do
+ = link_to status_import_bitbucket_server_path, class: "gl-button btn-default btn import_bitbucket js-import-project-btn", data: { platform: 'bitbucket_server', **tracking_attrs_data(track_label, 'click_button', 'bitbucket_server') } do
.gl-button-icon
= sprite_icon('bitbucket')
Bitbucket Server
%div
- if gitlab_import_enabled?
%div
- = link_to status_import_gitlab_path, class: "gl-button btn-default btn import_gitlab #{'how_to_import_link' unless gitlab_import_configured?}",
- **tracking_attrs(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 #{'how_to_import_link' unless gitlab_import_configured?}", data: { platform: 'gitlab_com', **tracking_attrs_data(track_label, 'click_button', 'gitlab_com') } do
.gl-button-icon
= sprite_icon('tanuki')
= _("GitLab.com")
@@ -48,35 +47,35 @@
- if fogbugz_import_enabled?
%div
- = link_to new_import_fogbugz_path, class: 'gl-button btn-default btn import_fogbugz', **tracking_attrs(track_label, 'click_button', 'fogbugz') do
+ = link_to new_import_fogbugz_path, class: 'gl-button btn-default btn import_fogbugz js-import-project-btn', data: { platform: 'fogbugz', **tracking_attrs_data(track_label, 'click_button', 'fogbugz') } do
.gl-button-icon
= sprite_icon('bug')
FogBugz
- if gitea_import_enabled?
%div
- = link_to new_import_gitea_path, class: 'gl-button btn-default btn import_gitea', **tracking_attrs(track_label, 'click_button', 'gitea') do
+ = link_to new_import_gitea_path, class: 'gl-button btn-default btn import_gitea js-import-project-btn', data: { platform: 'gitea', **tracking_attrs_data(track_label, 'click_button', 'gitea') } do
.gl-button-icon
= custom_icon('gitea_logo')
Gitea
- if git_import_enabled?
%div
- %button.gl-button.btn-default.btn.btn-svg.js-toggle-button.js-import-git-toggle-button{ type: "button", data: { toggle_open_class: 'active' }, **tracking_attrs(track_label, 'click_button', 'repo_url') }
+ %button.gl-button.btn-default.btn.btn-svg.js-toggle-button.js-import-git-toggle-button.js-import-project-btn{ type: "button", data: { platform: 'repo_url', toggle_open_class: 'active', **tracking_attrs_data(track_label, 'click_button', 'repo_url') } }
.gl-button-icon
= sprite_icon('link', css_class: 'gl-icon')
= _('Repo by URL')
- if manifest_import_enabled?
%div
- = link_to new_import_manifest_path, class: 'gl-button btn-default btn import_manifest', **tracking_attrs(track_label, 'click_button', 'manifest_file') do
+ = link_to new_import_manifest_path, class: 'gl-button btn-default btn import_manifest js-import-project-btn', data: { platform: 'manifest_file', **tracking_attrs_data(track_label, 'click_button', 'manifest_file') } do
.gl-button-icon
= sprite_icon('doc-text')
Manifest file
- if phabricator_import_enabled?
%div
- = link_to new_import_phabricator_path, class: 'gl-button btn-default btn import_phabricator', data: { track_label: "#{track_label}", track_action: "click_button", track_property: "phabricator" } do
+ = link_to new_import_phabricator_path, class: 'gl-button btn-default btn import_phabricator js-import-project-btn', data: { platform: 'phabricator', track_label: "#{track_label}", track_action: "click_button", track_property: "phabricator" } do
.gl-button-icon
= custom_icon('issues')
= _("Phabricator Tasks")
diff --git a/app/views/projects/_merge_request_merge_checks_settings.html.haml b/app/views/projects/_merge_request_merge_checks_settings.html.haml
index fbc58283cbf..6b25c5ddaef 100644
--- a/app/views/projects/_merge_request_merge_checks_settings.html.haml
+++ b/app/views/projects/_merge_request_merge_checks_settings.html.haml
@@ -8,7 +8,7 @@
= form.label :only_allow_merge_if_pipeline_succeeds, class: 'form-check-label' do
= s_('ProjectSettings|Pipelines must succeed')
.text-secondary
- - configuring_pipelines_for_merge_requests_help_link_url = help_page_path('ci/pipelines/merge_request_pipelines.md', anchor: 'configure-pipelines-for-merge-requests')
+ - configuring_pipelines_for_merge_requests_help_link_url = help_page_path('ci/pipelines/merge_request_pipelines.md', anchor: 'prerequisites')
- configuring_pipelines_for_merge_requests_help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: configuring_pipelines_for_merge_requests_help_link_url }
= s_('ProjectSettings|To enable this feature, configure pipelines. %{link_start}How to configure pipelines for merge requests?%{link_end}').html_safe % { link_start: configuring_pipelines_for_merge_requests_help_link_start, link_end: '</a>'.html_safe }
.form-check.mb-2
diff --git a/app/views/projects/_merge_request_merge_commit_template.html.haml b/app/views/projects/_merge_request_merge_commit_template.html.haml
index 869d2d5d9ec..1c023ae6ceb 100644
--- a/app/views/projects/_merge_request_merge_commit_template.html.haml
+++ b/app/views/projects/_merge_request_merge_commit_template.html.haml
@@ -3,15 +3,12 @@
.form-group
%b= s_('ProjectSettings|Merge commit message template')
%p.text-secondary
- - configure_the_merge_commit_message_help_link_url = help_page_path('user/project/merge_requests/commit_templates.md')
- - configure_the_merge_commit_message_help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: configure_the_merge_commit_message_help_link_url }
- = s_('ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}').html_safe % { link_start: configure_the_merge_commit_message_help_link_start, link_end: '</a>'.html_safe }
+ = s_('ProjectSettings|The commit message used when merging, if the merge method creates a merge commit.')
.mb-2
- default_merge_commit_template = "Merge branch '%{source_branch}' into '%{target_branch}'\n\n%{title}\n\n%{issues}\n\nSee merge request %{reference}"
= form.text_area :merge_commit_template, class: 'form-control gl-form-input', rows: 8, maxlength: 500, placeholder: default_merge_commit_template
%p.form-text.text-muted
= s_('ProjectSettings|Maximum 500 characters.')
- = s_('ProjectSettings|Supported variables:')
- - Gitlab::MergeRequests::CommitMessageGenerator::PLACEHOLDERS.keys.each do |placeholder|
- %code
- = "%{#{placeholder}}".html_safe
+ - configure_the_merge_commit_message_help_link_url = help_page_path('user/project/merge_requests/commit_templates.md')
+ - configure_the_merge_commit_message_help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: configure_the_merge_commit_message_help_link_url }
+ = s_('ProjectSettings|%{link_start}What variables can I use?%{link_end}').html_safe % { link_start: configure_the_merge_commit_message_help_link_start, link_end: '</a>'.html_safe }
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 2d18285ba80..b0e3bda2b4f 100644
--- a/app/views/projects/_merge_request_merge_method_settings.html.haml
+++ b/app/views/projects/_merge_request_merge_method_settings.html.haml
@@ -31,3 +31,6 @@
= s_('ProjectSettings|Fast-forward merges only.')
%br
= s_('ProjectSettings|When there is a merge conflict, the user is given the option to rebase.')
+ %div
+ = s_('ProjectSettings|If merge trains are enabled, merging is only possible if the branch can be rebased without conflicts.')
+ = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/merge_trains.md', anchor: 'enable-merge-trains'), target: '_blank', rel: 'noopener noreferrer'
diff --git a/app/views/projects/_merge_request_merge_suggestions_settings.html.haml b/app/views/projects/_merge_request_merge_suggestions_settings.html.haml
index 6e3c366da82..9ed21593203 100644
--- a/app/views/projects/_merge_request_merge_suggestions_settings.html.haml
+++ b/app/views/projects/_merge_request_merge_suggestions_settings.html.haml
@@ -3,13 +3,10 @@
.form-group
%b= s_('ProjectSettings|Merge suggestions')
%p.text-secondary
- - configure_the_commit_message_for_applied_suggestions_help_link_url = help_page_path('user/project/merge_requests/reviews/suggestions.md', anchor: 'configure-the-commit-message-for-applied-suggestions')
- - configure_the_commit_message_for_applied_suggestions_help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: configure_the_commit_message_for_applied_suggestions_help_link_url }
- = s_('ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}').html_safe % { link_start: configure_the_commit_message_for_applied_suggestions_help_link_start, link_end: '</a>'.html_safe }
+ = s_('ProjectSettings|The commit message used when applying merge request suggestions.')
.mb-2
= form.text_field :suggestion_commit_message, class: 'form-control mb-2', placeholder: Gitlab::Suggestions::CommitMessage::DEFAULT_SUGGESTION_COMMIT_MESSAGE
%p.form-text.text-muted
- = s_('ProjectSettings|Supported variables:')
- - Gitlab::Suggestions::CommitMessage::PLACEHOLDERS.keys.each do |placeholder|
- %code
- = "%{#{placeholder}}".html_safe
+ - configure_the_commit_message_for_applied_suggestions_help_link_url = help_page_path('user/project/merge_requests/reviews/suggestions.md', anchor: 'configure-the-commit-message-for-applied-suggestions')
+ - configure_the_commit_message_for_applied_suggestions_help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: configure_the_commit_message_for_applied_suggestions_help_link_url }
+ = s_('ProjectSettings|%{link_start}What variables can I use?%{link_end}').html_safe % { link_start: configure_the_commit_message_for_applied_suggestions_help_link_start, link_end: '</a>'.html_safe }
diff --git a/app/views/projects/_merge_request_squash_commit_template.html.haml b/app/views/projects/_merge_request_squash_commit_template.html.haml
index 81e4bbed166..be1d78154c6 100644
--- a/app/views/projects/_merge_request_squash_commit_template.html.haml
+++ b/app/views/projects/_merge_request_squash_commit_template.html.haml
@@ -3,14 +3,11 @@
.form-group
%b= s_('ProjectSettings|Squash commit message template')
%p.text-secondary
- - configure_the_squash_commit_message_help_link_url = help_page_path('user/project/merge_requests/commit_templates.md')
- - configure_the_squash_commit_message_help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: configure_the_squash_commit_message_help_link_url }
- = s_('ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}').html_safe % { link_start: configure_the_squash_commit_message_help_link_start, link_end: '</a>'.html_safe }
+ = s_('ProjectSettings|The commit message used when squashing commits.')
.mb-2
= form.text_area :squash_commit_template, class: 'form-control gl-form-input', rows: 8, maxlength: 500, placeholder: '%{title}'
%p.form-text.text-muted
= s_('ProjectSettings|Maximum 500 characters.')
- = s_('ProjectSettings|Supported variables:')
- - Gitlab::MergeRequests::CommitMessageGenerator::PLACEHOLDERS.keys.each do |placeholder|
- %code
- = "%{#{placeholder}}".html_safe
+ - configure_the_squash_commit_message_help_link_url = help_page_path('user/project/merge_requests/commit_templates.md')
+ - configure_the_squash_commit_message_help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: configure_the_squash_commit_message_help_link_url }
+ = s_('ProjectSettings|%{link_start}What variables can I use?%{link_end}').html_safe % { link_start: configure_the_squash_commit_message_help_link_start, link_end: '</a>'.html_safe }
diff --git a/app/views/projects/_merge_request_squash_options_settings.html.haml b/app/views/projects/_merge_request_squash_options_settings.html.haml
index 61ffd4814f1..bf3000f2b5e 100644
--- a/app/views/projects/_merge_request_squash_options_settings.html.haml
+++ b/app/views/projects/_merge_request_squash_options_settings.html.haml
@@ -5,9 +5,7 @@
%b= s_('ProjectSettings|Squash commits when merging')
%p.text-secondary
= s_('ProjectSettings|Set the default behavior of this option in merge requests. Changes to this are also applied to existing merge requests.')
- = link_to "What is squashing?",
- help_page_path('user/project/merge_requests/squash_and_merge.md'),
- target: '_blank'
+ = link_to "What is squashing?", help_page_path('user/project/merge_requests/squash_and_merge.md'), target: '_blank', rel: 'noopener noreferrer'
.form-check.gl-mb-2
= settings.radio_button :squash_option, :never, class: "form-check-input"
diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml
index 6fc78003df4..0b5da84e4e3 100644
--- a/app/views/projects/_new_project_fields.html.haml
+++ b/app/views/projects/_new_project_fields.html.haml
@@ -15,23 +15,12 @@
.input-group.gl-flex-nowrap
- if current_user.can_select_namespace?
- namespace_id = namespace_id_from(params)
- - if Feature.enabled?(:paginatable_namespace_drop_down_for_project_creation, current_user, default_enabled: :yaml)
- .js-vue-new-project-url-select{ data: { namespace_full_path: GroupFinder.new(current_user).execute(id: namespace_id)&.full_path,
- namespace_id: namespace_id,
- root_url: root_url,
- track_label: track_label,
- user_namespace_full_path: current_user.namespace.full_path,
- user_namespace_id: current_user.namespace.id } }
- - else
- .input-group-prepend.flex-shrink-0.has-tooltip{ title: root_url }
- .input-group-text
- = root_url
- = f.select(:namespace_id,
- namespaces_options_with_developer_maintainer_access(selected: namespace_id,
- display_path: true,
- extra_group: namespace_id),
- {},
- { class: 'select2 js-select-namespace qa-project-namespace-select block-truncated', data: { track_label: "#{track_label}", track_action: "activate_form_input", track_property: "project_path", track_value: "", qa_selector: "select_namespace_dropdown" }})
+ .js-vue-new-project-url-select{ data: { namespace_full_path: GroupFinder.new(current_user).execute(id: namespace_id)&.full_path,
+ namespace_id: namespace_id,
+ root_url: root_url,
+ track_label: track_label,
+ user_namespace_full_path: current_user.namespace.full_path,
+ user_namespace_id: current_user.namespace.id } }
- else
.input-group-prepend.static-namespace.flex-shrink-0.has-tooltip{ title: user_url(current_user.username) + '/' }
.input-group-text.border-0
@@ -98,7 +87,7 @@
= check_box_tag 'project[initialize_with_sast]', '1', true, class: 'form-check-input', data: { qa_selector: 'initialize_with_sast_checkbox', track_experiment: e.name, track_label: track_label, track_action: 'activate_form_input', track_property: 'init_with_sast' }
= label_tag 'project[initialize_with_sast]', class: 'form-check-label' do
= s_('ProjectsNew|Enable Static Application Security Testing (SAST)')
- %span.badge.badge-info.badge-pill.gl-badge.sm= _('Free')
+ = gl_badge_tag _('Free'), variant: :info, size: :sm
.form-text.text-muted
= s_('ProjectsNew|Analyze your source code for known security vulnerabilities.')
= link_to _('Learn more.'), help_page_path('user/application_security/sast/index'), target: '_blank', rel: 'noopener noreferrer', data: { track_action: 'followed', track_experiment: e.name }
@@ -108,7 +97,7 @@
= check_box_tag 'project[initialize_with_sast]', '1', false, class: 'form-check-input', data: { qa_selector: 'initialize_with_sast_checkbox', track_experiment: e.name, track_label: track_label, track_action: 'activate_form_input', track_property: 'init_with_sast' }
= label_tag 'project[initialize_with_sast]', class: 'form-check-label' do
= s_('ProjectsNew|Enable Static Application Security Testing (SAST)')
- %span.badge.badge-info.badge-pill.gl-badge.sm= _('Free')
+ = gl_badge_tag _('Free'), variant: :info, size: :sm
.form-text.text-muted
= s_('ProjectsNew|Analyze your source code for known security vulnerabilities.')
= link_to _('Learn more.'), help_page_path('user/application_security/sast/index'), target: '_blank', rel: 'noopener noreferrer', data: { track_action: 'followed', track_experiment: e.name }
diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml
index be6efa310b9..f5e61c010cc 100644
--- a/app/views/projects/branches/_branch.html.haml
+++ b/app/views/projects/branches/_branch.html.haml
@@ -8,14 +8,11 @@
= link_to project_tree_path(@project, branch.name), class: 'item-title str-truncated-100 ref-name gl-ml-3 qa-branch-name' do
= branch.name
- if branch.name == @repository.root_ref
- %span.badge.gl-badge.sm.badge-pill.badge-primary.gl-ml-2 default
+ = gl_badge_tag s_('DefaultBranchLabel|default'), { variant: :info, size: :sm }, { class: 'gl-ml-2' }
- elsif merged
- %span.badge.gl-badge.sm.badge-pill.badge-info.has-tooltip.gl-ml-2{ title: s_('Branches|Merged into %{default_branch}') % { default_branch: @repository.root_ref } }
- = s_('Branches|merged')
-
+ = gl_badge_tag s_('Branches|merged'), { variant: :info, size: :sm }, { class: 'gl-ml-2', title: s_('Branches|Merged into %{default_branch}') % { default_branch: @repository.root_ref }, data: { toggle: 'tooltip', container: 'body' } }
- if protected_branch?(@project, branch)
- %span.badge.gl-badge.sm.badge-pill.badge-success.gl-ml-2
- = s_('Branches|protected')
+ = gl_badge_tag s_('Branches|protected'), { variant: :success, size: :sm }, { class: 'gl-ml-2' }
= render_if_exists 'projects/branches/diverged_from_upstream', branch: branch
@@ -48,38 +45,4 @@
= render 'projects/buttons/download', project: @project, ref: branch.name, pipeline: @refs_pipelines[branch.name], class: 'gl-vertical-align-top'
- - if Feature.enabled?(:delete_branch_confirmation_modals, @project, default_enabled: :yaml)
- = render 'projects/branches/delete_branch_modal_button', project: @project, branch: branch, merged: merged
-
- - elsif can?(current_user, :push_code, @project)
- - if branch.name == @project.repository.root_ref
- - delete_default_branch_tooltip = s_('Branches|The default branch cannot be deleted')
- %span.gl-display-inline-block.has-tooltip{ title: delete_default_branch_tooltip }
- %button{ class: 'gl-button btn btn-default btn-icon disabled', disabled: true, 'aria-label' => delete_default_branch_tooltip }
- = sprite_icon('remove', css_class: 'gl-button-icon gl-icon')
- - elsif protected_branch?(@project, branch)
- - if can?(current_user, :push_to_delete_protected_branch, @project)
- - delete_protected_branch_tooltip = s_('Branches|Delete protected branch')
- %button{ class: 'gl-button btn btn-default btn-icon has-tooltip',
- title: delete_protected_branch_tooltip,
- 'aria-label' => delete_protected_branch_tooltip,
- data: { toggle: 'modal',
- target: '#modal-delete-branch',
- delete_path: project_branch_path(@project, branch.name),
- branch_name: branch.name,
- is_merged: ('true' if merged) } }
- = sprite_icon('remove', css_class: 'gl-button-icon gl-icon')
- - else
- - delete_protected_branch_disabled_tooltip = s_('Branches|Only a project maintainer or owner can delete a protected branch')
- %span.has-tooltip{ title: delete_protected_branch_disabled_tooltip }
- %button{ class: 'gl-button btn btn-default btn-icon disabled', disabled: true, 'aria-label' => delete_protected_branch_disabled_tooltip, data: { testid: 'remove-protected-branch' } }
- = sprite_icon('remove', css_class: 'gl-button-icon gl-icon')
- - else
- = link_to project_branch_path(@project, branch.name),
- class: 'gl-button btn btn-default btn-icon js-remove-row qa-remove-btn js-ajax-loading-spinner has-tooltip',
- title: s_('Branches|Delete branch'),
- method: :delete,
- data: { confirm: s_("Branches|Deleting the '%{branch_name}' branch cannot be undone. Are you sure?") % { branch_name: branch.name } },
- remote: true,
- 'aria-label' => s_('Branches|Delete branch') do
- = sprite_icon('remove', css_class: 'gl-button-icon gl-icon')
+ = render 'projects/branches/delete_branch_modal_button', project: @project, branch: branch, merged: merged
diff --git a/app/views/projects/branches/_delete_protected_modal.html.haml b/app/views/projects/branches/_delete_protected_modal.html.haml
deleted file mode 100644
index 2b45b4eddcc..00000000000
--- a/app/views/projects/branches/_delete_protected_modal.html.haml
+++ /dev/null
@@ -1,42 +0,0 @@
-#modal-delete-branch.modal{ tabindex: -1 }
- .modal-dialog
- .modal-content
- .modal-header
- %h3.page-title
- - title_branch_name = capture do
- %span.js-branch-name.ref-name>[branch name]
- = s_("Branches|Delete protected branch '%{branch_name}'?").html_safe % { branch_name: title_branch_name }
- %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') }
- %span{ "aria-hidden": "true" } &times;
-
- .modal-body
- %p
- - branch_name = capture do
- %strong.js-branch-name.ref-name>[branch name]
- = s_('Branches|You’re about to permanently delete the protected branch %{branch_name}.').html_safe % { branch_name: branch_name }
- %p.js-not-merged
- - default_branch = capture do
- %span.ref-name= @repository.root_ref
- = s_('Branches|This branch hasn’t been merged into %{default_branch}.').html_safe % { default_branch: default_branch }
- = s_('Branches|To avoid data loss, consider merging this branch before deleting it.')
- %p
- - delete_protected_branch = capture do
- %strong
- = s_('Branches|Delete protected branch')
- = s_('Branches|Once you confirm and press %{delete_protected_branch}, it cannot be undone or recovered.').html_safe % { delete_protected_branch: delete_protected_branch }
- %p
- - branch_name_confirmation = capture do
- %kbd.js-branch-name [branch name]
- %strong
- = s_('Branches|To confirm, type %{branch_name_confirmation}:').html_safe % { branch_name_confirmation: branch_name_confirmation }
-
- .form-group
- = text_field_tag 'delete_branch_input', '', class: 'form-control js-delete-branch-input'
-
- .modal-footer
- %button.gl-button.btn.btn-default{ data: { dismiss: 'modal' } } Cancel
- = link_to s_('Branches|Delete protected branch'), '',
- class: "gl-button btn btn-danger js-delete-branch",
- title: s_('Branches|Delete branch'),
- method: :delete,
- 'aria-label' => s_('Branches|Delete branch')
diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml
index 1c543d47ecf..2121d15643c 100644
--- a/app/views/projects/branches/index.html.haml
+++ b/app/views/projects/branches/index.html.haml
@@ -50,7 +50,5 @@
.nothing-here-block
= s_('Branches|No branches to show')
-- if Feature.enabled?(:delete_branch_confirmation_modals, @project, default_enabled: :yaml) && can?(current_user, :push_code, @project)
+- if can?(current_user, :push_code, @project)
.js-delete-branch-modal
-- elsif can?(current_user, :push_code, @project)
- = render 'projects/branches/delete_protected_modal'
diff --git a/app/views/projects/buttons/_fork.html.haml b/app/views/projects/buttons/_fork.html.haml
index 3cec7fd9eb8..c57b6dbe28c 100644
--- a/app/views/projects/buttons/_fork.html.haml
+++ b/app/views/projects/buttons/_fork.html.haml
@@ -1,7 +1,7 @@
- unless @project.empty_repo?
- if current_user
.count-badge.btn-group
- - if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
+ - if current_user.already_forked?(@project) && current_user.forkable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: s_('ProjectOverview|Go to your fork'), class: 'gl-button btn btn-default btn-sm has-tooltip fork-btn' do
= sprite_icon('fork', css_class: 'icon')
%span= s_('ProjectOverview|Fork')
diff --git a/app/views/projects/ci/pipeline_editor/show.html.haml b/app/views/projects/ci/pipeline_editor/show.html.haml
index ce6f7553ab4..c4757ea9c26 100644
--- a/app/views/projects/ci/pipeline_editor/show.html.haml
+++ b/app/views/projects/ci/pipeline_editor/show.html.haml
@@ -1,3 +1,4 @@
+- @force_fluid_layout = true
- add_page_specific_style 'page_bundles/pipelines'
- page_title s_('Pipelines|Pipeline Editor')
diff --git a/app/views/projects/commit/_limit_exceeded_message.html.haml b/app/views/projects/commit/_limit_exceeded_message.html.haml
index 236418ecd0e..444e7d209f1 100644
--- a/app/views/projects/commit/_limit_exceeded_message.html.haml
+++ b/app/views/projects/commit/_limit_exceeded_message.html.haml
@@ -1,8 +1,5 @@
-.has-tooltip{ class: "limit-box limit-box-#{objects} gl-ml-2", data: { title: _('Project has too many %{label_for_message} to search') % { label_for_message: label_for_message } } }
- .limit-icon
- - if objects == :branch
- = sprite_icon('fork', size: 12)
- - else
- = sprite_icon('tag')
- .limit-message
- %span= _('%{label_for_message} unavailable') % { label_for_message: label_for_message.capitalize }
+- icon = objects == :branch ? 'fork' : 'tag'
+- text = _('%{label_for_message} unavailable') % { label_for_message: label_for_message.capitalize }
+- tooltip_title = _('Project has too many %{label_for_message} to search') % { label_for_message: label_for_message }
+
+= gl_badge_tag(text, { variant: :danger, icon: icon }, { class: 'has-tooltip gl-ml-2', data: { title: tooltip_title } })
diff --git a/app/views/projects/commit/branches.html.haml b/app/views/projects/commit/branches.html.haml
index 0b8e5105bc0..d08ace98408 100644
--- a/app/views/projects/commit/branches.html.haml
+++ b/app/views/projects/commit/branches.html.haml
@@ -6,8 +6,9 @@
- if @branches.any? || @tags.any? || @tags_limit_exceeded
%span
- = link_to "#", class: "js-details-expand badge badge-gray ref-name" do
- = sprite_icon('ellipsis_h', size: 12, css_class: 'vertical-align-middle')
+ = gl_badge_tag(_("Expand"),
+ { variant: :info, icon: 'ellipsis_h', icon_only: true },
+ { href: '#', class: 'js-details-expand gl-font-monospace' })
%span.js-details-content.hide
= commit_branches_links(@project, @branches)
- if @tags_limit_exceeded
diff --git a/app/views/projects/default_branch/_show.html.haml b/app/views/projects/default_branch/_show.html.haml
index e5f911d6f8b..f9d3af7aa36 100644
--- a/app/views/projects/default_branch/_show.html.haml
+++ b/app/views/projects/default_branch/_show.html.haml
@@ -26,6 +26,6 @@
%strong= _("Auto-close referenced issues on default branch")
.form-text.text-muted
= _("When merge requests and commits in the default branch close, any issues they reference also close.")
- = link_to sprite_icon('question-o'), help_page_path('user/project/issues/managing_issues.md', anchor: 'closing-issues-automatically'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('user/project/issues/managing_issues.md', anchor: 'closing-issues-automatically'), target: '_blank', rel: 'noopener noreferrer'
= f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/projects/deployments/_deployment.html.haml b/app/views/projects/deployments/_deployment.html.haml
index f18574c3ad5..504bbf3a304 100644
--- a/app/views/projects/deployments/_deployment.html.haml
+++ b/app/views/projects/deployments/_deployment.html.haml
@@ -27,8 +27,7 @@
= link_to deployment_path(deployment), class: 'build-link' do
#{deployment.deployable.name} (##{deployment.deployable.id})
- else
- .badge.badge-info.gl-cursor-help{ title: s_('Deployment|This deployment was created using the API') }
- = s_('Deployment|API')
+ = gl_badge_tag s_('Deployment|API'), { variant: :info }, { class: 'gl-cursor-help', data: { toggle: 'tooltip' }, title: s_('Deployment|This deployment was created using the API') }
.table-section.section-10{ role: 'gridcell' }
.table-mobile-header{ role: 'rowheader' }= _("Created")
diff --git a/app/views/projects/diffs/_email_line.html.haml b/app/views/projects/diffs/_email_line.html.haml
new file mode 100644
index 00000000000..dfff143196c
--- /dev/null
+++ b/app/views/projects/diffs/_email_line.html.haml
@@ -0,0 +1,21 @@
+-# This template is used when rendering diffs in email notifications
+-# Called inside: app/views/notify/repository_push_email.html.haml
+-# app/views/notify/_note_email.html.haml
+
+%tr.line_holder{ class: line.type }
+ - case line.type
+ - when 'match'
+ = diff_match_line line.old_pos, line.new_pos, text: line.text
+ - when 'old-nonewline', 'new-nonewline'
+ %td.old_line.diff-line-num
+ %td.new_line.diff-line-num
+ %td.line_content.match= line.text
+ - else
+ %td.old_line.diff-line-num{ class: line.type, data: { linenumber: line.old_pos } }
+ = diff_link_number(line.type, "new", line.old_pos)
+
+ %td.new_line.diff-line-num{ class: line.type, data: { linenumber: line.new_pos } }
+ = diff_link_number(line.type, "old", line.new_pos)
+
+ %td.line_content{ class: line.type }<
+ %pre= line.rich_text
diff --git a/app/views/projects/diffs/_file_header.html.haml b/app/views/projects/diffs/_file_header.html.haml
index d1792826522..afca27c5430 100644
--- a/app/views/projects/diffs/_file_header.html.haml
+++ b/app/views/projects/diffs/_file_header.html.haml
@@ -36,5 +36,5 @@
#{diff_file.a_mode} → #{diff_file.b_mode}
- if diff_file.stored_externally? && diff_file.external_storage == :lfs
- %span.badge.label-lfs.gl-mr-2 LFS
+ = gl_badge_tag(_('LFS'), variant: :neutral)
diff --git a/app/views/projects/diffs/_line.html.haml b/app/views/projects/diffs/_line.html.haml
index de7f9eba158..330e2f564c9 100644
--- a/app/views/projects/diffs/_line.html.haml
+++ b/app/views/projects/diffs/_line.html.haml
@@ -1,3 +1,5 @@
+-# This file is deprecated in favour of inline rendering:
+-# https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57237
- plain = local_assigns.fetch(:plain, false)
- discussions = local_assigns.fetch(:discussions, nil)
- line_code = diff_file.line_code(line)
diff --git a/app/views/projects/diffs/_text_file.html.haml b/app/views/projects/diffs/_text_file.html.haml
index bf946b0ce73..6e7e0244721 100644
--- a/app/views/projects/diffs/_text_file.html.haml
+++ b/app/views/projects/diffs/_text_file.html.haml
@@ -4,10 +4,38 @@
%a.show-suppressed-diff.cursor-pointer.js-show-suppressed-diff= _("Changes suppressed. Click to show.")
%table.text-file.diff-wrap-lines.code.code-commit.js-syntax-highlight.commit-diff{ data: diff_view_data, class: too_big ? 'hide' : '' }
- = render partial: "projects/diffs/line",
- collection: diff_file.highlighted_diff_lines,
- as: :line,
- locals: { diff_file: diff_file, discussions: @grouped_diff_discussions }
+ - if Feature.enabled?(:inline_haml_diff_line_rendering, @project, default_enabled: :yaml)
+ - diff_file.highlighted_diff_lines.each do |line|
+ - line_code = diff_file.line_code(line)
+
+ %tr.line_holder{ class: line.type, id: line_code }
+ - case line.type
+ - when 'match'
+ = diff_match_line line.old_pos, line.new_pos, text: line.text
+ - when 'old-nonewline', 'new-nonewline'
+ %td.old_line.diff-line-num
+ %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", data: { linenumber: line.old_pos } }
+ = 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 } }
+ %a{ href: "##{line_code}", data: { linenumber: diff_link_number(line.type, "old", line.new_pos) } }
+
+ %td.line_content{ class: line.type }<
+ = diff_line_content(line.rich_text)
+
+ - if line.discussable? && @grouped_diff_discussions.present? && @grouped_diff_discussions[line_code]
+ - line_discussions = @grouped_diff_discussions[line_code]
+ = render "discussions/diff_discussion", discussions: line_discussions, expanded: line_discussions.any?(&:expanded?)
+
+ - else
+ = render partial: "projects/diffs/line",
+ collection: diff_file.highlighted_diff_lines,
+ as: :line,
+ locals: { diff_file: diff_file, discussions: @grouped_diff_discussions }
- if !diff_file.new_file? && !diff_file.deleted_file? && diff_file.highlighted_diff_lines.any?
- last_line = diff_file.highlighted_diff_lines.last
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index 6421aef14cf..aa9a3ea61f7 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -2,6 +2,7 @@
- page_title _("General")
- @content_class = "limit-container-width" unless fluid_layout
- expanded = expanded_by_default?
+- reduce_visibility_form_id = 'reduce-visibility-form'
%section.settings.general-settings.no-animate.expanded#js-general-settings
.settings-header
@@ -17,13 +18,10 @@
%p= _('Choose visibility level, enable/disable project features and their permissions, disable email notifications, and show default award emoji.')
.settings-content
- = form_for @project, html: { multipart: true, class: "sharing-permissions-form" }, authenticity_token: true do |f|
+ = form_for @project, html: { multipart: true, class: "sharing-permissions-form", id: reduce_visibility_form_id }, authenticity_token: true do |f|
%input{ name: 'update_section', type: 'hidden', value: 'js-shared-permissions' }
%template.js-project-permissions-form-data{ type: "application/json" }= project_permissions_panel_data(@project).to_json.html_safe
- .js-project-permissions-form
- - if show_visibility_confirm_modal?(@project)
- = render "visibility_modal"
- = f.submit _('Save changes'), class: "btn gl-button btn-confirm #{('js-legacy-confirm-danger' if show_visibility_confirm_modal?(@project))}", data: { qa_selector: 'visibility_features_permissions_save_button', check_field_name: ("project[visibility_level]" if show_visibility_confirm_modal?(@project)), check_compare_value: @project.visibility_level }
+ .js-project-permissions-form{ data: visibility_confirm_modal_data(@project, reduce_visibility_form_id) }
%section.rspec-merge-request-settings.settings.merge-requests-feature.no-animate#js-merge-request-settings{ class: [('expanded' if expanded), ('hidden' if @project.project_feature.send(:merge_requests_access_level) == 0)], data: { qa_selector: 'merge_request_settings_content' } }
.settings-header
@@ -111,5 +109,3 @@
.gl-spinner.gl-spinner-md.align-text-bottom
= _('Saving project.')
%p= _('Please wait a moment, this page will automatically refresh when ready.')
-
-= render 'shared/confirm_modal', phrase: @project.path
diff --git a/app/views/projects/forks/index.html.haml b/app/views/projects/forks/index.html.haml
index d6f421e8ad6..5330c3aa6d6 100644
--- a/app/views/projects/forks/index.html.haml
+++ b/app/views/projects/forks/index.html.haml
@@ -25,7 +25,7 @@
= forks_sort_direction_button(sort_value)
- if current_user && can?(current_user, :fork_project, @project)
- - if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
+ - if current_user.already_forked?(@project) && current_user.forkable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: _('Go to your fork'), class: 'btn gl-button btn-confirm gl-md-ml-3' do
= sprite_icon('fork', size: 12)
%span= _('Fork')
diff --git a/app/views/projects/import/jira/show.html.haml b/app/views/projects/import/jira/show.html.haml
index 29296ce23c9..1feae7baa02 100644
--- a/app/views/projects/import/jira/show.html.haml
+++ b/app/views/projects/import/jira/show.html.haml
@@ -1,6 +1,6 @@
.js-jira-import-root{ data: { project_path: @project.full_path,
issues_path: project_issues_path(@project),
- jira_integration_path: edit_project_service_path(@project, :jira),
+ jira_integration_path: edit_project_integration_path(@project, :jira),
is_jira_configured: @project.jira_integration&.configured?.to_s,
in_progress_illustration: image_path('illustrations/export-import.svg'),
project_id: @project.id,
diff --git a/app/views/projects/issues/_by_email_description.html.haml b/app/views/projects/issues/_by_email_description.html.haml
index 0ff852352e1..aeed5fb69c9 100644
--- a/app/views/projects/issues/_by_email_description.html.haml
+++ b/app/views/projects/issues/_by_email_description.html.haml
@@ -1,6 +1,6 @@
The subject will be used as the title of the new issue, and the message will be the description.
-= link_to 'Quick actions', help_page_path('user/project/quick_actions'), target: '_blank'
+= link_to 'Quick actions', help_page_path('user/project/quick_actions'), target: '_blank', rel: 'noopener noreferrer'
and styling with
-= link_to 'Markdown', help_page_path('user/markdown'), target: '_blank'
+= link_to 'Markdown', help_page_path('user/markdown'), target: '_blank', rel: 'noopener noreferrer'
are supported.
diff --git a/app/views/projects/issues/_design_management.html.haml b/app/views/projects/issues/_design_management.html.haml
index a2ff9620c0c..c5ce0549816 100644
--- a/app/views/projects/issues/_design_management.html.haml
+++ b/app/views/projects/issues/_design_management.html.haml
@@ -8,7 +8,11 @@
- if @project.design_management_enabled?
- add_page_startup_graphql_call('design_management/get_design_list', { fullPath: @project.full_path, iid: @issue.iid.to_s, atVersion: nil })
- add_page_startup_graphql_call('design_management/design_permissions', { fullPath: @project.full_path, iid: @issue.iid.to_s })
- .js-design-management{ data: { project_path: @project.full_path, issue_iid: @issue.iid, issue_path: project_issue_path(@project, @issue) } }
+ .js-design-management{ data: { project_path: @project.full_path,
+ issue_iid: @issue.iid,
+ issue_path: project_issue_path(@project, @issue),
+ register_path: new_user_registration_path(redirect_to_referer: 'yes'),
+ sign_in_path: new_session_path(:user, redirect_to_referer: 'yes') } }
- else
.gl-border-solid.gl-border-1.gl-border-gray-100.gl-rounded-base.gl-mt-5.gl-p-3.gl-text-center
= enable_lfs_message
diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml
index 2dc21685057..4c96875ce42 100644
--- a/app/views/projects/issues/_issue.html.haml
+++ b/app/views/projects/issues/_issue.html.haml
@@ -1,4 +1,3 @@
--# DANGER: Any changes to this file need to be reflected in issuables_list/components/issuable.vue!
%li{ id: dom_id(issue), class: issue_css_classes(issue), url: issue_path(issue), data: { labels: issue.label_ids, id: issue.id, qa_selector: 'issue_container', qa_issue_title: issue.title } }
.issuable-info-container
- if @can_bulk_update
diff --git a/app/views/projects/issues/_issues.html.haml b/app/views/projects/issues/_issues.html.haml
index 1ab51df6d24..09b0b7a4d9b 100644
--- a/app/views/projects/issues/_issues.html.haml
+++ b/app/views/projects/issues/_issues.html.haml
@@ -1,25 +1,10 @@
-- is_project_overview = local_assigns.fetch(:is_project_overview, false)
= render 'shared/alerts/positioning_disabled' if @sort == 'relative_position'
-- if Feature.enabled?(:vue_issuables_list, @project) && !is_project_overview
- - data_endpoint = local_assigns.fetch(:data_endpoint, expose_path(api_v4_projects_issues_path(id: @project.id)))
- - default_empty_state_meta = { create_issue_path: new_project_issue_path(@project), svg_path: image_path('illustrations/issues.svg') }
- - data_empty_state_meta = local_assigns.fetch(:data_empty_state_meta, default_empty_state_meta)
- - type = local_assigns.fetch(:type, 'issues')
- - if type == 'issues' && use_startup_call?
- - add_page_startup_api_call(api_v4_projects_issues_path(id: @project.id, params: startup_call_params))
- .js-issuables-list{ data: { endpoint: data_endpoint,
- 'empty-state-meta': data_empty_state_meta.to_json,
- 'can-bulk-edit': @can_bulk_update.to_json,
- 'sort-key': @sort,
- type: type,
- 'scoped-labels-available': scoped_labels_available?(@project).to_json } }
-- else
- - empty_state_path = local_assigns.fetch(:empty_state_path, 'shared/empty_states/issues')
- %ul.content-list.issues-list.issuable-list{ class: issue_manual_ordering_class }
- = render partial: "projects/issues/issue", collection: @issues
- - if @issues.blank?
- = render empty_state_path
+%ul.content-list.issues-list.issuable-list{ class: issue_manual_ordering_class }
+ = render partial: "projects/issues/issue", collection: @issues
+ - if @issues.blank?
+ - empty_state_path = local_assigns.fetch(:empty_state_path, 'shared/empty_states/issues')
+ = render empty_state_path
- - if @issues.present?
- = paginate_collection @issues, total_pages: @total_pages
+- if @issues.present?
+ = paginate_collection @issues, total_pages: @total_pages
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 afeb2a23ea2..3e0b80700fe 100644
--- a/app/views/projects/issues/_service_desk_empty_state.html.haml
+++ b/app/views/projects/issues/_service_desk_empty_state.html.haml
@@ -27,7 +27,11 @@
.svg-content
= render 'shared/empty_states/icons/service_desk_setup.svg'
.text-content
- %h4= s_('ServiceDesk|Service Desk is enabled but not yet active')
- %p
- = s_("ServiceDesk|To activate Service Desk on this instance, an instance administrator must first set up incoming email.")
- = link_to _('Learn more.'), help_page_path('administration/incoming_email', anchor: 'set-it-up')
+ - if can_edit_project_settings
+ %h4= s_('ServiceDesk|Service Desk is not supported')
+ %p
+ = s_("ServiceDesk|To enable Service Desk on this instance, an instance administrator must first set up incoming email.")
+ = link_to _('Learn more.'), help_page_path('administration/incoming_email', anchor: 'set-it-up')
+ - else
+ %h4= s_('ServiceDesk|Service Desk is not enabled')
+ %p= s_("ServiceDesk|For help setting up the Service Desk for your instance, please contact an administrator.")
diff --git a/app/views/projects/issues/service_desk.html.haml b/app/views/projects/issues/service_desk.html.haml
index b0d8791c566..fb5880f633a 100644
--- a/app/views/projects/issues/service_desk.html.haml
+++ b/app/views/projects/issues/service_desk.html.haml
@@ -7,9 +7,7 @@
- support_bot_attrs = { service_desk_enabled: @project.service_desk_enabled?, **UserSerializer.new.represent(User.support_bot) }.to_json
-- data_endpoint = "#{expose_path(api_v4_projects_issues_path(id: @project.id))}?author_username=#{User.support_bot.username}"
-
-%div{ class: "js-service-desk-issues service-desk-issues", data: { support_bot: support_bot_attrs, service_desk_meta: service_desk_meta(@project) } }
+.js-service-desk-issues.service-desk-issues{ data: { support_bot: support_bot_attrs } }
.top-area
= render 'shared/issuable/nav', type: :issues
.nav-controls.d-block.d-sm-none
@@ -20,12 +18,5 @@
- if Gitlab::ServiceDesk.supported?
= render 'service_desk_info_content'
- -# TODO Remove empty_state_path once vue_issuables_list FF is removed.
- -# https://gitlab.com/gitlab-org/gitlab/-/issues/235652
- -# `empty_state_path` is used to render the empty state in the HAML version of issuables list.
.issues-holder
- = render 'projects/issues/issues',
- empty_state_path: 'service_desk_empty_state',
- data_endpoint: data_endpoint,
- data_empty_state_meta: service_desk_meta(@project),
- type: 'service_desk'
+ = render 'projects/issues/issues', empty_state_path: 'service_desk_empty_state'
diff --git a/app/views/projects/jobs/show.html.haml b/app/views/projects/jobs/show.html.haml
index 7af825b2819..fedc1291a92 100644
--- a/app/views/projects/jobs/show.html.haml
+++ b/app/views/projects/jobs/show.html.haml
@@ -10,4 +10,4 @@
- if @build.is_a? ::Ci::Build
#js-job-page{ data: jobs_data }
- else
- #js-bridge-page{ data: bridge_data(@build) }
+ #js-bridge-page{ data: bridge_data(@build, @project) }
diff --git a/app/views/projects/mattermosts/_no_teams.html.haml b/app/views/projects/mattermosts/_no_teams.html.haml
index adef11f315a..1efec0c017c 100644
--- a/app/views/projects/mattermosts/_no_teams.html.haml
+++ b/app/views/projects/mattermosts/_no_teams.html.haml
@@ -15,4 +15,4 @@
and try again.
%hr
.clearfix
- = link_to 'Go back', edit_project_service_path(@project, @integration), class: 'gl-button btn btn-lg float-right'
+ = link_to 'Go back', edit_project_integration_path(@project, @integration), class: 'gl-button btn btn-lg float-right'
diff --git a/app/views/projects/mattermosts/_team_selection.html.haml b/app/views/projects/mattermosts/_team_selection.html.haml
index 4832880eefc..d52d980c364 100644
--- a/app/views/projects/mattermosts/_team_selection.html.haml
+++ b/app/views/projects/mattermosts/_team_selection.html.haml
@@ -42,5 +42,5 @@
%hr
.clearfix
.float-right
- = link_to _('Cancel'), edit_project_service_path(@project, @integration), class: 'gl-button btn btn-lg'
+ = link_to _('Cancel'), edit_project_integration_path(@project, @integration), class: 'gl-button btn btn-lg'
= f.submit 'Install', class: 'gl-button btn btn-success btn-lg'
diff --git a/app/views/projects/merge_requests/_widget.html.haml b/app/views/projects/merge_requests/_widget.html.haml
index 0c8af873095..4e69dad2e12 100644
--- a/app/views/projects/merge_requests/_widget.html.haml
+++ b/app/views/projects/merge_requests/_widget.html.haml
@@ -1,24 +1,25 @@
-= cache_if(Feature.enabled?(:cached_mr_widget, @merge_request.project), [@merge_request.project, @merge_request, current_user], expires_in: 10.minutes) do
- - artifacts_endpoint_placeholder = ':pipeline_artifacts_id'
+- artifacts_endpoint_placeholder = ':pipeline_artifacts_id'
- = javascript_tag do
- :plain
- window.gl = window.gl || {};
- window.gl.mrWidgetData = #{serialize_issuable(@merge_request, serializer: 'widget', issues_links: true)}
+= javascript_tag do
+ :plain
+ window.gl = window.gl || {};
+ window.gl.mrWidgetData = #{serialize_issuable(@merge_request, serializer: 'widget', issues_links: true)}
- window.gl.mrWidgetData.artifacts_endpoint = '#{downloadable_artifacts_project_pipeline_path(@project, artifacts_endpoint_placeholder, format: :json)}';
- window.gl.mrWidgetData.artifacts_endpoint_placeholder = '#{artifacts_endpoint_placeholder}';
- window.gl.mrWidgetData.squash_before_merge_help_path = '#{help_page_path("user/project/merge_requests/squash_and_merge")}';
- window.gl.mrWidgetData.ci_troubleshooting_docs_path = '#{help_page_path('ci/troubleshooting.md')}';
- window.gl.mrWidgetData.mr_troubleshooting_docs_path = '#{help_page_path('user/project/merge_requests/reviews/index.md', anchor: 'troubleshooting')}';
- window.gl.mrWidgetData.pipeline_must_succeed_docs_path = '#{help_page_path('user/project/merge_requests/merge_when_pipeline_succeeds.md', anchor: 'only-allow-merge-requests-to-be-merged-if-the-pipeline-succeeds')}';
- window.gl.mrWidgetData.security_approvals_help_page_path = '#{help_page_path('user/application_security/index.md', anchor: 'security-approvals-in-merge-requests')}';
- window.gl.mrWidgetData.license_compliance_docs_path = '#{help_page_path('user/compliance/license_compliance/index.md', anchor: 'policies')}';
- window.gl.mrWidgetData.eligible_approvers_docs_path = '#{help_page_path('user/project/merge_requests/approvals/rules.md', anchor: 'eligible-approvers')}';
- window.gl.mrWidgetData.approvals_help_path = '#{help_page_path("user/project/merge_requests/approvals/index.md")}';
- window.gl.mrWidgetData.pipelines_empty_svg_path = '#{image_path('illustrations/pipelines_empty.svg')}';
- window.gl.mrWidgetData.codequality_help_path = '#{help_page_path("user/project/merge_requests/code_quality", anchor: "code-quality-reports")}';
- window.gl.mrWidgetData.false_positive_doc_url = '#{help_page_path('user/application_security/vulnerabilities/index')}';
- window.gl.mrWidgetData.can_view_false_positive = '#{@merge_request.project.licensed_feature_available?(:sast_fp_reduction).to_s}';
+ window.gl.mrWidgetData.artifacts_endpoint = '#{downloadable_artifacts_project_pipeline_path(@project, artifacts_endpoint_placeholder, format: :json)}';
+ window.gl.mrWidgetData.artifacts_endpoint_placeholder = '#{artifacts_endpoint_placeholder}';
+ window.gl.mrWidgetData.squash_before_merge_help_path = '#{help_page_path("user/project/merge_requests/squash_and_merge")}';
+ window.gl.mrWidgetData.ci_troubleshooting_docs_path = '#{help_page_path('ci/troubleshooting.md')}';
+ window.gl.mrWidgetData.mr_troubleshooting_docs_path = '#{help_page_path('user/project/merge_requests/reviews/index.md', anchor: 'troubleshooting')}';
+ window.gl.mrWidgetData.pipeline_must_succeed_docs_path = '#{help_page_path('user/project/merge_requests/merge_when_pipeline_succeeds.md', anchor: 'only-allow-merge-requests-to-be-merged-if-the-pipeline-succeeds')}';
+ window.gl.mrWidgetData.security_approvals_help_page_path = '#{help_page_path('user/application_security/index.md', anchor: 'security-approvals-in-merge-requests')}';
+ window.gl.mrWidgetData.license_compliance_docs_path = '#{help_page_path('user/compliance/license_compliance/index.md', anchor: 'policies')}';
+ window.gl.mrWidgetData.eligible_approvers_docs_path = '#{help_page_path('user/project/merge_requests/approvals/rules.md', anchor: 'eligible-approvers')}';
+ window.gl.mrWidgetData.approvals_help_path = '#{help_page_path("user/project/merge_requests/approvals/index.md")}';
+ window.gl.mrWidgetData.pipelines_empty_svg_path = '#{image_path('illustrations/pipelines_empty.svg')}';
+ window.gl.mrWidgetData.codequality_help_path = '#{help_page_path("user/project/merge_requests/code_quality", anchor: "code-quality-reports")}';
+ window.gl.mrWidgetData.false_positive_doc_url = '#{help_page_path('user/application_security/vulnerabilities/index')}';
+ window.gl.mrWidgetData.can_view_false_positive = '#{@merge_request.project.licensed_feature_available?(:sast_fp_reduction).to_s}';
+ window.gl.mrWidgetData.user_preferences_gitpod_path = '#{profile_preferences_path(anchor: 'user_gitpod_enabled')}';
+ window.gl.mrWidgetData.user_profile_enable_gitpod_path = '#{profile_path(user: { gitpod_enabled: true })}';
- #js-vue-mr-widget.mr-widget
+#js-vue-mr-widget.mr-widget
diff --git a/app/views/projects/merge_requests/invalid.html.haml b/app/views/projects/merge_requests/invalid.html.haml
index eb8de425f61..28fd0b83824 100644
--- a/app/views/projects/merge_requests/invalid.html.haml
+++ b/app/views/projects/merge_requests/invalid.html.haml
@@ -1,11 +1,8 @@
- page_title "#{@merge_request.title} (#{@merge_request.to_reference}", _("Merge requests")
-- badge_start = '<span class="badge badge-pill gl-badge sm badge-info">'.html_safe
-- badge_end = '</span>'.html_safe
-
- err_fork_project_removed = s_("MergeRequest|Can't show this merge request because the fork project was deleted.")
-- err_source_branch = s_("MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch.")
-- err_target_branch = s_("MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch.")
+- err_source_branch = s_("MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch.")
+- err_target_branch = s_("MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch.")
- err_internal = s_("MergeRequest|Can't show this merge request because of an internal error. Contact your administrator.")
.merge-request
@@ -20,8 +17,8 @@
- if @merge_request.for_fork? && !@merge_request.source_project
= err_fork_project_removed
- elsif !@merge_request.source_branch_exists?
- = err_source_branch.html_safe % { badge_start: badge_start, badge_end: badge_end, source_branch: @merge_request.source_branch, project_path: @merge_request.source_project_path }
+ = 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 % { badge_start: badge_start, badge_end: badge_end, target_branch: @merge_request.target_branch, project_path: @merge_request.source_project_path }
+ = 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 eb1c9712c52..a0e78b7570a 100644
--- a/app/views/projects/merge_requests/show.html.haml
+++ b/app/views/projects/merge_requests/show.html.haml
@@ -97,6 +97,4 @@
#js-review-bar
= render 'projects/invite_members_modal', project: @project
-- if Gitlab::CurrentSettings.gitpod_enabled && !current_user&.gitpod_enabled
- = render 'shared/gitpod/enable_gitpod_modal'
= render 'shared/web_ide_path'
diff --git a/app/views/projects/mirrors/_authentication_method.html.haml b/app/views/projects/mirrors/_authentication_method.html.haml
index 5f31ec4087e..e9e3645d7f2 100644
--- a/app/views/projects/mirrors/_authentication_method.html.haml
+++ b/app/views/projects/mirrors/_authentication_method.html.haml
@@ -6,7 +6,7 @@
.select-wrapper
= f.select :auth_method,
options_for_select(auth_options, mirror.auth_method),
- {}, { class: "form-control gl-form-input select-control js-mirror-auth-type qa-authentication-method" }
+ {}, { class: "form-control gl-form-select select-control js-mirror-auth-type qa-authentication-method" }
= sprite_icon('chevron-down', css_class: "gl-icon gl-absolute gl-top-3 gl-right-3 gl-text-gray-200")
= f.hidden_field :auth_method, value: "password", class: "js-hidden-mirror-auth-type"
diff --git a/app/views/projects/mirrors/_mirror_repos.html.haml b/app/views/projects/mirrors/_mirror_repos.html.haml
index d253ab8e32b..b2fa735f76f 100644
--- a/app/views/projects/mirrors/_mirror_repos.html.haml
+++ b/app/views/projects/mirrors/_mirror_repos.html.haml
@@ -69,7 +69,7 @@
- if mirror.disabled?
= render 'projects/mirrors/disabled_mirror_badge'
- if mirror.last_error.present?
- .badge.mirror-error-badge{ data: { toggle: 'tooltip', html: 'true', qa_selector: 'mirror_error_badge' }, title: html_escape(mirror.last_error.try(:strip)) }= _('Error')
+ = gl_badge_tag _('Error'), { variant: :danger }, { data: { toggle: 'tooltip', html: 'true', qa_selector: 'mirror_error_badge' }, title: html_escape(mirror.last_error.try(:strip)) }
%td.gl-display-flex
- if mirror_settings_enabled
%button.js-delete-mirror.qa-delete-mirror.rspec-delete-mirror.btn.btn-icon.gl-button.btn-danger.gl-mr-3{ type: 'button', data: { mirror_id: mirror.id, toggle: 'tooltip', container: 'body' }, title: _('Remove') }= sprite_icon('remove')
diff --git a/app/views/projects/mirrors/_mirror_repos_form.html.haml b/app/views/projects/mirrors/_mirror_repos_form.html.haml
index dca01ebbe90..34b7c75debf 100644
--- a/app/views/projects/mirrors/_mirror_repos_form.html.haml
+++ b/app/views/projects/mirrors/_mirror_repos_form.html.haml
@@ -1,7 +1,7 @@
.form-group
= label_tag :mirror_direction, _('Mirror direction'), class: 'label-light'
.select-wrapper
- = select_tag :mirror_direction, options_for_select([[_('Push'), 'push']]), class: 'form-control gl-form-input select-control js-mirror-direction qa-mirror-direction', disabled: true
+ = select_tag :mirror_direction, options_for_select([[_('Push'), 'push']]), class: 'form-control gl-form-select select-control js-mirror-direction qa-mirror-direction', disabled: true
= sprite_icon('chevron-down', css_class: "gl-icon gl-absolute gl-top-3 gl-right-3 gl-text-gray-200")
= render partial: "projects/mirrors/mirror_repos_push", locals: { f: f }
diff --git a/app/views/projects/packages/packages/index.html.haml b/app/views/projects/packages/packages/index.html.haml
index c67b06218e2..4ab16f25dd2 100644
--- a/app/views/projects/packages/packages/index.html.haml
+++ b/app/views/projects/packages/packages/index.html.haml
@@ -7,4 +7,7 @@
full_path: @project.full_path,
endpoint: project_packages_path(@project),
page_type: 'projects',
- empty_list_illustration: image_path('illustrations/no-packages.svg'), } }
+ empty_list_illustration: image_path('illustrations/no-packages.svg'),
+ npm_instance_url: package_registry_instance_url(:npm),
+ project_list_url: project_packages_path(@project),
+ group_list_url: '' } }
diff --git a/app/views/projects/packages/packages/show.html.haml b/app/views/projects/packages/packages/show.html.haml
deleted file mode 100644
index ebdc9e654f6..00000000000
--- a/app/views/projects/packages/packages/show.html.haml
+++ /dev/null
@@ -1,9 +0,0 @@
-- add_to_breadcrumbs _("Package Registry"), project_packages_path(@project)
-- add_to_breadcrumbs @package.name, project_packages_path(@project)
-- breadcrumb_title @package.version
-- page_title _("Package Registry")
-- @content_class = "limit-container-width" unless fluid_layout
-
-.row
- .col-12
- #js-vue-packages-detail-new{ data: package_details_data(@project, @package) }
diff --git a/app/views/projects/pages/_list.html.haml b/app/views/projects/pages/_list.html.haml
index 40352e79175..4e9c77564da 100644
--- a/app/views/projects/pages/_list.html.haml
+++ b/app/views/projects/pages/_list.html.haml
@@ -15,11 +15,9 @@
= external_link(domain.url, domain.url)
- if domain.certificate
%div
- %span.badge.badge-gray
- = s_('GitLabPages|Certificate: %{subject}') % { subject: domain.pages_domain.subject }
+ = gl_badge_tag(s_('GitLabPages|Certificate: %{subject}') % { subject: domain.pages_domain.subject })
- if domain.expired?
- %span.badge.badge-danger
- = s_('GitLabPages|Expired')
+ = gl_badge_tag s_('GitLabPages|Expired'), variant: :danger
%div
= link_to s_('GitLabPages|Edit'), project_pages_domain_path(@project, domain), class: "btn gl-button btn-sm btn-grouped btn-confirm btn-inverted"
= link_to s_('GitLabPages|Remove'), project_pages_domain_path(@project, domain), data: { confirm: s_('GitLabPages|Are you sure?')}, method: :delete, class: "btn gl-button btn-danger btn-sm btn-grouped"
diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml
index 0bfdee088b4..13a77dbf2fd 100644
--- a/app/views/projects/pipelines/_info.html.haml
+++ b/app/views/projects/pipelines/_info.html.haml
@@ -22,41 +22,25 @@
.icon-container
= sprite_icon('flag')
- if @pipeline.child?
- %span.js-pipeline-child.badge.badge-pill.gl-badge.sm.badge-primary.has-tooltip{ title: s_("Pipelines|This is a child pipeline within the parent pipeline") }
- = s_('Pipelines|Child pipeline')
- = surround '(', ')' do
- = link_to s_('Pipelines|parent'), pipeline_path(@pipeline.triggered_by_pipeline), class: 'text-white text-underline'
+ - text = sprintf(s_('Pipelines|Child pipeline (%{link_start}parent%{link_end})'), { link_start: "<a href='#{pipeline_path(@pipeline.triggered_by_pipeline)}' class='text-underline'>", link_end: "</a>"}).html_safe
+ = gl_badge_tag text, { variant: :info, size: :sm }, { class: 'js-pipeline-child has-tooltip', title: s_("Pipelines|This is a child pipeline within the parent pipeline") }
- if @pipeline.latest?
- %span.js-pipeline-url-latest.badge.badge-pill.gl-badge.sm.badge-success.has-tooltip{ title: _("Latest pipeline for the most recent commit on this branch") }
- 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?
- %span.js-pipeline-url-train.badge.badge-pill.gl-badge.sm.badge-info.has-tooltip{ title: _("This is a merge train pipeline") }
- train
+ = gl_badge_tag s_('Pipelines|train'), { variant: :info, size: :sm }, { class: 'js-pipeline-url-train has-tooltip', title: _("This is a merge train pipeline") }
- if @pipeline.has_yaml_errors?
- %span.js-pipeline-url-yaml.badge.badge-pill.gl-badge.sm.badge-danger.has-tooltip{ title: @pipeline.yaml_errors }
- yaml invalid
+ = 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?
- %span.js-pipeline-url-failure.badge.badge-pill.gl-badge.sm.badge-danger.has-tooltip{ title: @pipeline.failure_reason }
- error
+ = gl_badge_tag s_('Pipelines|error'), { variant: :danger, size: :sm }, { class: 'js-pipeline-url-failure has-tooltip', title: @pipeline.failure_reason }
- if @pipeline.auto_devops_source?
- popover_title_text = html_escape(_('This pipeline makes use of a predefined CI/CD configuration enabled by %{b_open}Auto DevOps.%{b_close}')) % { b_open: '<b>'.html_safe, b_close: '</b>'.html_safe }
- popover_content_url = help_page_path('topics/autodevops/index.md')
- popover_content_text = _('Learn more about Auto DevOps')
- %a.js-pipeline-url-autodevops.badge.badge-pill.gl-badge.sm.badge-info.autodevops-badge{ 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>",
- } }
- 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?
- %span.js-pipeline-url-mergerequest.badge.badge-pill.gl-badge.sm.badge-info.has-tooltip{ title: _('Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results.') }
- detached
+ = gl_badge_tag s_('Pipelines|detached'), { variant: :info, size: :sm }, { class: 'js-pipeline-url-mergerequest has-tooltip', title: _('Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results.') }
- if @pipeline.stuck?
- %span.js-pipeline-url-stuck.badge.badge-pill.gl-badge.sm.badge-warning
- stuck
+ = gl_badge_tag s_('Pipelines|stuck'), { variant: :warning, size: :sm }, { class: 'js-pipeline-url-stuck has-tooltip' }
.well-segment.branch-info
.icon-container.commit-icon
diff --git a/app/views/projects/pipelines/show.html.haml b/app/views/projects/pipelines/show.html.haml
index ac5d34bfd44..d654d0e04d7 100644
--- a/app/views/projects/pipelines/show.html.haml
+++ b/app/views/projects/pipelines/show.html.haml
@@ -1,3 +1,4 @@
+- @force_fluid_layout = true
- add_to_breadcrumbs _('Pipelines'), project_pipelines_path(@project)
- breadcrumb_title "##{@pipeline.id}"
- page_title _('Pipeline')
diff --git a/app/views/projects/prometheus/metrics/edit.html.haml b/app/views/projects/prometheus/metrics/edit.html.haml
index d308824571e..146bf6b6853 100644
--- a/app/views/projects/prometheus/metrics/edit.html.haml
+++ b/app/views/projects/prometheus/metrics/edit.html.haml
@@ -1,6 +1,6 @@
- add_to_breadcrumbs _("Settings"), edit_project_path(@project)
- add_to_breadcrumbs _("Integrations"), project_settings_integrations_path(@project)
-- add_to_breadcrumbs "Prometheus", edit_project_service_path(@project, ::Integrations::Prometheus)
+- add_to_breadcrumbs "Prometheus", edit_project_integration_path(@project, ::Integrations::Prometheus)
- breadcrumb_title s_('Metrics|Edit metric')
- page_title @metric.title, s_('Metrics|Edit metric')
= render 'form', project: @project, metric: @metric
diff --git a/app/views/projects/prometheus/metrics/new.html.haml b/app/views/projects/prometheus/metrics/new.html.haml
index 8415ec9ee41..ad8463d1804 100644
--- a/app/views/projects/prometheus/metrics/new.html.haml
+++ b/app/views/projects/prometheus/metrics/new.html.haml
@@ -1,6 +1,6 @@
- add_to_breadcrumbs _("Settings"), edit_project_path(@project)
- add_to_breadcrumbs _("Integrations"), project_settings_integrations_path(@project)
-- add_to_breadcrumbs "Prometheus", edit_project_service_path(@project, ::Integrations::Prometheus)
+- add_to_breadcrumbs "Prometheus", edit_project_integration_path(@project, ::Integrations::Prometheus)
- breadcrumb_title s_('Metrics|New metric')
- page_title s_('Metrics|New metric')
= render 'form', project: @project, metric: @metric
diff --git a/app/views/projects/protected_branches/shared/_branches_list.html.haml b/app/views/projects/protected_branches/shared/_branches_list.html.haml
index b13117960dd..5964f2bfeda 100644
--- a/app/views/projects/protected_branches/shared/_branches_list.html.haml
+++ b/app/views/projects/protected_branches/shared/_branches_list.html.haml
@@ -1,7 +1,7 @@
.protected-branches-list.js-protected-branches-list.qa-protected-branches-list
- if @protected_branches.empty?
.card-header.bg-white
- = s_("ProtectedBranch|Protected branch (%{protected_branches_count})") % { protected_branches_count: @protected_branches_count }
+ = s_("ProtectedBranch|Protected branch (%{protected_branches_count})") % { protected_branches_count: 0 }
%p.settings-message.text-center
= s_("ProtectedBranch|There are currently no protected branches, protect a branch with the form above.")
- else
diff --git a/app/views/projects/protected_branches/shared/_protected_branch.html.haml b/app/views/projects/protected_branches/shared/_protected_branch.html.haml
index 02ec778b97c..f3bb2a66a4c 100644
--- a/app/views/projects/protected_branches/shared/_protected_branch.html.haml
+++ b/app/views/projects/protected_branches/shared/_protected_branch.html.haml
@@ -5,11 +5,11 @@
%span.ref-name= protected_branch.name
- if @project.root_ref?(protected_branch.name)
- %span.badge.gl-badge.badge-pill.badge-info.d-inline default
+ = gl_badge_tag s_('ProtectedBranch|default'), variant: :info
%div
- if protected_branch.wildcard?
- - matching_branches = protected_branch.matching(repository.branches)
+ - matching_branches = protected_branch.matching(repository.branch_names)
= link_to pluralize(matching_branches.count, "matching branch"), namespace_project_protected_branch_path(@project.namespace, @project, protected_branch)
- elsif !protected_branch.commit
%span.text-muted Branch was deleted.
@@ -20,4 +20,4 @@
- if can_admin_project
%td
- = link_to 'Unprotect', [@project, protected_branch, { update_section: 'js-protected-branches-settings' }], disabled: local_assigns[:disabled], data: { confirm: 'Branch will be writable for developers. Are you sure?' }, method: :delete, class: "btn gl-button btn-warning"
+ = link_to s_('ProtectedBranch|Unprotect'), [@project, protected_branch, { update_section: 'js-protected-branches-settings' }], disabled: local_assigns[:disabled], data: { confirm: s_('ProtectedBranch|Branch will be writable for developers. Are you sure?') }, method: :delete, class: "btn gl-button btn-warning"
diff --git a/app/views/projects/protected_tags/shared/_protected_tag.html.haml b/app/views/projects/protected_tags/shared/_protected_tag.html.haml
index 70357f39e44..b312a09aadd 100644
--- a/app/views/projects/protected_tags/shared/_protected_tag.html.haml
+++ b/app/views/projects/protected_tags/shared/_protected_tag.html.haml
@@ -6,7 +6,7 @@
= gl_badge_tag s_('ProtectedTags|default'), variant: :info, class: 'gl-ml-2'
%td
- if protected_tag.wildcard?
- - matching_tags = protected_tag.matching(repository.tags)
+ - matching_tags = protected_tag.matching(repository.tag_names)
= link_to pluralize(matching_tags.count, "matching tag"), project_protected_tag_path(@project, protected_tag)
- else
- if commit = protected_tag.commit
diff --git a/app/views/projects/protected_tags/shared/_tags_list.html.haml b/app/views/projects/protected_tags/shared/_tags_list.html.haml
index f3cf4013898..5f3ea281278 100644
--- a/app/views/projects/protected_tags/shared/_tags_list.html.haml
+++ b/app/views/projects/protected_tags/shared/_tags_list.html.haml
@@ -1,7 +1,7 @@
.protected-tags-list.js-protected-tags-list
- if @protected_tags.empty?
.card-header
- Protected tags (#{@protected_tags_count})
+ Protected tags (0)
%p.settings-message.text-center
No tags are protected.
- else
diff --git a/app/views/projects/registry/repositories/index.html.haml b/app/views/projects/registry/repositories/index.html.haml
index 03927cd3bfa..3efe1fd2e82 100644
--- a/app/views/projects/registry/repositories/index.html.haml
+++ b/app/views/projects/registry/repositories/index.html.haml
@@ -12,7 +12,7 @@
"containers_error_image" => image_path('illustrations/docker-error-state.svg'),
"repository_url" => escape_once(@project.container_registry_url),
"registry_host_url_with_port" => escape_once(registry_config.host_port),
- "expiration_policy_help_page_path" => help_page_path('user/packages/container_registry/index.md', anchor: 'cleanup-policy'),
+ "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'),
"project_path": @project.full_path,
diff --git a/app/views/projects/runners/_group_runners.html.haml b/app/views/projects/runners/_group_runners.html.haml
index 183e747afdd..c25fd7a7587 100644
--- a/app/views/projects/runners/_group_runners.html.haml
+++ b/app/views/projects/runners/_group_runners.html.haml
@@ -29,9 +29,9 @@
- 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)
- = _('Group maintainers can register group runners in the %{link}').html_safe % { link: group_link }
+ = _('Group owners can register group runners in the %{link}').html_safe % { link: group_link }
- else
- = _('Ask your group maintainer to set up a group runner.')
+ = _('Ask your group owner to set up a group runner.')
- else
%h4.underlined-title
diff --git a/app/views/projects/runners/_specific_runners.html.haml b/app/views/projects/runners/_specific_runners.html.haml
index 5e999b7afb3..1357846876e 100644
--- a/app/views/projects/runners/_specific_runners.html.haml
+++ b/app/views/projects/runners/_specific_runners.html.haml
@@ -17,7 +17,7 @@
group_path: '' }
- else
= _('Please contact an admin to register runners.')
- = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'runner-registration'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'prevent-users-from-registering-runners'), target: '_blank', rel: 'noopener noreferrer'
%hr
diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml
index dbc204ff9bf..419dd827e49 100644
--- a/app/views/projects/services/_form.html.haml
+++ b/app/views/projects/services/_form.html.haml
@@ -6,9 +6,12 @@
- if integration.operating?
= sprite_icon('check', css_class: 'gl-text-green-500')
-= form_for(integration, as: :service, url: scoped_integration_path(integration, project: @project, group: @group), method: :put, html: { class: 'gl-show-field-errors integration-settings-form js-integration-settings-form', data: { 'test-url' => test_project_service_path(@project, integration) } }) do |form|
- = render 'shared/service_settings', form: form, integration: integration
- %input{ id: 'services_redirect_to', type: 'hidden', name: 'redirect_to', value: request.referer }
+- if vue_integration_form_enabled?
+ = render 'shared/integration_settings', integration: integration
+- else
+ = form_for(integration, as: :service, url: scoped_integration_path(integration, project: @project, group: @group), method: :put, html: { class: 'gl-show-field-errors integration-settings-form js-integration-settings-form', data: { 'test-url' => test_project_integration_path(@project, integration), testid: 'integration-form' } }) do |form|
+ = render 'shared/integration_settings', form: form, integration: integration
+ %input{ id: 'services_redirect_to', type: 'hidden', name: 'redirect_to', value: request.referer }
- if lookup_context.template_exists?('show', "projects/services/#{integration.to_param}", true)
%hr
diff --git a/app/views/projects/settings/access_tokens/index.html.haml b/app/views/projects/settings/access_tokens/index.html.haml
index 4e946050881..e4b027fcc44 100644
--- a/app/views/projects/settings/access_tokens/index.html.haml
+++ b/app/views/projects/settings/access_tokens/index.html.haml
@@ -5,7 +5,7 @@
- @content_class = 'limit-container-width' unless fluid_layout
.row.gl-mt-3
- .col-lg-4.profile-settings-sidebar
+ .col-lg-4
%h4.gl-mt-0
= page_title
%p
@@ -24,26 +24,26 @@
= _('You can enable project access token creation in %{link_start}group settings%{link_end}.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
.col-lg-8
- - if @new_project_access_token
+ - if @new_resource_access_token
= render 'shared/access_tokens/created_container',
type: type,
- new_token_value: @new_project_access_token
+ new_token_value: @new_resource_access_token
- if current_user.can?(:create_resource_access_tokens, @project)
= render 'shared/access_tokens/form',
type: type,
path: project_settings_access_tokens_path(@project),
- project: @project,
- token: @project_access_token,
+ resource: @project,
+ token: @resource_access_token,
scopes: @scopes,
access_levels: ProjectMember.access_level_roles,
default_access_level: Gitlab::Access::MAINTAINER,
- prefix: :project_access_token,
+ prefix: :resource_access_token,
help_path: help_page_path('user/project/settings/project_access_tokens', anchor: 'scopes-for-a-project-access-token')
= render 'shared/access_tokens/table',
- active_tokens: @active_project_access_tokens,
- project: @project,
+ active_tokens: @active_resource_access_tokens,
+ resource: @project,
type: type,
type_plural: type_plural,
revoke_route_helper: ->(token) { revoke_namespace_project_settings_access_token_path(id: token) },
diff --git a/app/views/projects/settings/ci_cd/_autodevops_form.html.haml b/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
index e200635ba82..43d34173af6 100644
--- a/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
@@ -26,7 +26,7 @@
= gl_badge_tag badge_for_auto_devops_scope(@project), { variant: :info }, { class: 'js-instance-default-badge'}
.form-text.text-muted
= s_('CICD|The Auto DevOps pipeline runs if no alternative CI configuration file is found.')
- = link_to _('Learn more.'), help_page_path('topics/autodevops/index.md'), target: '_blank'
+ = link_to _('Learn more.'), help_page_path('topics/autodevops/index.md'), target: '_blank', rel: 'noopener noreferrer'
.card-footer.js-extra-settings{ class: auto_devops_enabled || 'hidden' }
- if @project.all_clusters.empty?
%p.settings-message.text-center
@@ -40,18 +40,18 @@
= form.radio_button :deploy_strategy, 'continuous', class: 'form-check-input'
= form.label :deploy_strategy_continuous, class: 'form-check-label' do
= s_('CICD|Continuous deployment to production')
- = link_to sprite_icon('question-o'), help_page_path('topics/autodevops/stages.md', anchor: 'auto-deploy'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('topics/autodevops/stages.md', anchor: 'auto-deploy'), target: '_blank', rel: 'noopener noreferrer'
.form-check
= form.radio_button :deploy_strategy, 'timed_incremental', class: 'form-check-input'
= form.label :deploy_strategy_timed_incremental, class: 'form-check-label' do
= s_('CICD|Continuous deployment to production using timed incremental rollout')
- = link_to sprite_icon('question-o'), help_page_path('topics/autodevops/customize.md', anchor: 'timed-incremental-rollout-to-production'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('topics/autodevops/customize.md', anchor: 'timed-incremental-rollout-to-production'), target: '_blank', rel: 'noopener noreferrer'
.form-check
= form.radio_button :deploy_strategy, 'manual', class: 'form-check-input'
= form.label :deploy_strategy_manual, class: 'form-check-label' do
= s_('CICD|Automatic deployment to staging, manual deployment to production')
- = link_to sprite_icon('question-o'), help_page_path('topics/autodevops/customize.md', anchor: 'incremental-rollout-to-production'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('topics/autodevops/customize.md', anchor: 'incremental-rollout-to-production'), target: '_blank', rel: 'noopener noreferrer'
= f.submit _('Save changes'), class: "btn gl-button btn-confirm gl-mt-5", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/projects/settings/ci_cd/_form.html.haml b/app/views/projects/settings/ci_cd/_form.html.haml
index a91c12d01ad..d3cdfc4f7c9 100644
--- a/app/views/projects/settings/ci_cd/_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_form.html.haml
@@ -10,7 +10,7 @@
%strong= _("Public pipelines")
.form-text.text-muted
= _("Allow public access to pipelines and job details, including output logs and artifacts.")
- = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'change-which-users-can-view-your-pipelines'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'change-which-users-can-view-your-pipelines'), target: '_blank', rel: 'noopener noreferrer'
.form-group
.form-check
@@ -19,7 +19,7 @@
%strong= _("Auto-cancel redundant pipelines")
.form-text.text-muted
= _("New pipelines cause older pending or running pipelines on the same branch to be cancelled.")
- = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'auto-cancel-redundant-pipelines'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'auto-cancel-redundant-pipelines'), target: '_blank', rel: 'noopener noreferrer'
.form-group
.form-check
@@ -29,14 +29,14 @@
%strong= _("Skip outdated deployment jobs")
.form-text.text-muted
= _("When a deployment job is successful, skip older deployment jobs that are still pending.")
- = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'skip-outdated-deployment-jobs'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'skip-outdated-deployment-jobs'), target: '_blank', rel: 'noopener noreferrer'
.form-group
= f.label :ci_config_path, _('CI/CD configuration file'), class: 'label-bold'
= f.text_field :ci_config_path, class: 'form-control', placeholder: '.gitlab-ci.yml'
%p.form-text.text-muted
= html_escape(_("The name of the CI/CD configuration file. A path relative to the root directory is optional (for example %{code_open}my/path/.myfile.yml%{code_close}).")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
- = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'specify-a-custom-cicd-configuration-file'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'specify-a-custom-cicd-configuration-file'), target: '_blank', rel: 'noopener noreferrer'
%hr
.form-group
@@ -44,7 +44,7 @@
= _("Git strategy")
%p
= _("Choose which Git strategy to use when fetching the project.")
- = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'choose-the-default-git-strategy'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'choose-the-default-git-strategy'), target: '_blank', rel: 'noopener noreferrer'
.form-check
= f.radio_button :build_allow_git_fetch, 'false', { class: 'form-check-input' }
= f.label :build_allow_git_fetch_false, class: 'form-check-label' do
@@ -66,7 +66,7 @@
= form.number_field :default_git_depth, { class: 'form-control gl-form-input', min: 0, max: 1000 }
%p.form-text.text-muted
= html_escape(_('The number of changes to fetch from GitLab when cloning a repository. Lower values can speed up pipeline execution. Set to %{code_open}0%{code_close} or blank to fetch all branches and tags for each job')) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
- = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'limit-the-number-of-changes-fetched-during-clone'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'limit-the-number-of-changes-fetched-during-clone'), target: '_blank', rel: 'noopener noreferrer'
%hr
.form-group
@@ -74,7 +74,7 @@
= f.text_field :build_timeout_human_readable, class: 'form-control gl-form-input'
%p.form-text.text-muted
= html_escape(_('Jobs fail if they run longer than the timeout time. Input value is in seconds by default. Human readable input is also accepted, for example %{code_open}1 hour%{code_close}.')) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
- = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'set-a-limit-for-how-long-jobs-can-run'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'set-a-limit-for-how-long-jobs-can-run'), target: '_blank', rel: 'noopener noreferrer'
- if can?(current_user, :update_max_artifacts_size, @project)
.form-group
@@ -82,7 +82,7 @@
= f.number_field :max_artifacts_size, class: 'form-control gl-form-input'
%p.form-text.text-muted
= _("The maximum file size in megabytes for individual job artifacts.")
- = link_to sprite_icon('question-o'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'maximum-artifacts-size'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'maximum-artifacts-size'), target: '_blank', rel: 'noopener noreferrer'
.form-group
= f.label :build_coverage_regex, _("Test coverage parsing"), class: 'label-bold'
@@ -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'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'add-test-coverage-results-to-a-merge-request'), 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 626ddc20431..07910899aa0 100644
--- a/app/views/projects/settings/packages_and_registries/show.html.haml
+++ b/app/views/projects/settings/packages_and_registries/show.html.haml
@@ -10,6 +10,6 @@
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,
- help_page_path: help_page_path('user/packages/container_registry/index', anchor: 'cleanup-policy'),
+ 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/index', anchor: 'regex-pattern-examples') } }
+ 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/starrers/index.html.haml b/app/views/projects/starrers/index.html.haml
index 7c8314c157d..618c4c249a1 100644
--- a/app/views/projects/starrers/index.html.haml
+++ b/app/views/projects/starrers/index.html.haml
@@ -12,7 +12,7 @@
= search_field_tag :search, params[:search], { placeholder: _('Search'), class: 'form-control', spellcheck: false }
%button.user-search-btn{ type: "submit", "aria-label" => _("Submit search") }
= sprite_icon('search')
- .dropdown.inline.user-sort-dropdown
+ .dropdown.inline.gl-ml-3
= dropdown_toggle(starrers_sort_options_hash[@sort], { toggle: 'dropdown' })
%ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable
%li.dropdown-header
diff --git a/app/views/projects/tree/_tree_header.html.haml b/app/views/projects/tree/_tree_header.html.haml
index 60cc043f813..202c0f22420 100644
--- a/app/views/projects/tree/_tree_header.html.haml
+++ b/app/views/projects/tree/_tree_header.html.haml
@@ -4,8 +4,9 @@
#js-repo-breadcrumb{ data: breadcrumb_data_attributes }
+#js-blob-controls
.tree-controls
- .d-block.d-sm-flex.flex-wrap.align-items-start.gl-children-ml-sm-3<
+ .d-block.d-sm-flex.flex-wrap.align-items-start.gl-children-ml-sm-3.gl-first-child-ml-sm-0<
= render_if_exists 'projects/tree/lock_link'
#js-tree-history-link{ data: { history_link: project_commits_path(@project, @ref) } }
diff --git a/app/views/projects/triggers/_index.html.haml b/app/views/projects/triggers/_index.html.haml
index 85ecfe7a982..8b3d0ef17a4 100644
--- a/app/views/projects/triggers/_index.html.haml
+++ b/app/views/projects/triggers/_index.html.haml
@@ -45,6 +45,7 @@
%pre
:plain
curl -X POST \
+ --fail \
-F token=TOKEN \
-F ref=REF_NAME \
#{builds_trigger_url(@project.id)}
@@ -54,7 +55,7 @@
%pre
:plain
script:
- - "curl -X POST -F token=TOKEN -F ref=REF_NAME #{builds_trigger_url(@project.id)}"
+ - "curl -X POST --fail -F token=TOKEN -F ref=REF_NAME #{builds_trigger_url(@project.id)}"
%h5.gl-mt-3
= _('Use webhook')
@@ -73,6 +74,7 @@
%pre
:plain
curl -X POST \
+ --fail \
-F token=TOKEN \
-F "ref=REF_NAME" \
-F "variables[RUN_NIGHTLY_BUILD]=true" \
diff --git a/app/views/registrations/welcome/show.html.haml b/app/views/registrations/welcome/show.html.haml
index 65a1ffa3e46..ca2f225a2d8 100644
--- a/app/views/registrations/welcome/show.html.haml
+++ b/app/views/registrations/welcome/show.html.haml
@@ -2,6 +2,10 @@
- page_title _('Your profile')
- add_page_specific_style 'page_bundles/signup'
- gitlab_experience_text = _('To personalize your GitLab experience, we\'d like to know a bit more about you')
+- content_for :page_specific_javascripts do
+ = render "layouts/google_tag_manager_head"
+ = render "layouts/one_trust"
+= render "layouts/google_tag_manager_body"
.row.gl-flex-grow-1
.d-flex.gl-flex-direction-column.gl-align-items-center.gl-w-full.gl-px-5.gl-pb-5
@@ -18,7 +22,7 @@
.row
.form-group.col-sm-12
= f.label :role, _('Role'), class: 'label-bold'
- = f.select :role, ::User.roles.keys.map { |role| [role.titleize, role] }, {}, class: 'form-control js-user-role-dropdown', autofocus: true
+ = f.select :role, ::User.roles.keys.map { |role| [role.titleize, role] }, { include_blank: _('Select a role') }, class: 'form-control js-user-role-dropdown', autofocus: true, required: true, data: { qa_selector: 'role_dropdown' }
- if Feature.enabled?(:user_other_role_details)
.row
.form-group.col-sm-12.js-other-role-group.hidden
diff --git a/app/views/sandbox/mermaid.html.erb b/app/views/sandbox/mermaid.html.erb
new file mode 100644
index 00000000000..2d2391c8866
--- /dev/null
+++ b/app/views/sandbox/mermaid.html.erb
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <%= webpack_bundle_tag("sandboxed_mermaid") %>
+ </head>
+ <body>
+ <div id="app"></div>
+ </body>
+</html>
diff --git a/app/views/shared/_confirm_modal.html.haml b/app/views/shared/_confirm_modal.html.haml
deleted file mode 100644
index 4cb3f6d1739..00000000000
--- a/app/views/shared/_confirm_modal.html.haml
+++ /dev/null
@@ -1,21 +0,0 @@
-#modal-confirm-danger.modal.qa-confirm-modal{ tabindex: -1 }
- .modal-dialog
- .modal-content
- .modal-header
- %h3.page-title= _('Confirmation required')
- %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') }
- %span{ "aria-hidden": "true" } &times;
-
- .modal-body
- %p.text-danger.js-confirm-text
-
- %p
- %span.js-warning-text= _('This action can lead to data loss. To prevent accidental actions we ask you to confirm your intention.')
- %br
- - phrase_code = '<code class="js-legacy-confirm-danger-match">%{phrase_name}</code>'.html_safe % { phrase_name: phrase }
- = _('Please type %{phrase_code} to proceed or close this modal to cancel.').html_safe % { phrase_code: phrase_code }
-
- .form-group
- = text_field_tag 'confirm_name_input', '', class: 'form-control js-legacy-confirm-danger-input qa-confirm-input'
- .form-actions
- = submit_tag _('Confirm'), class: "gl-button btn btn-danger js-legacy-confirm-danger-submit qa-confirm-button"
diff --git a/app/views/shared/_integration_settings.html.haml b/app/views/shared/_integration_settings.html.haml
new file mode 100644
index 00000000000..93606ca0aba
--- /dev/null
+++ b/app/views/shared/_integration_settings.html.haml
@@ -0,0 +1,14 @@
+= form_errors(integration)
+
+%div{ data: { testid: "integration-settings-form" } }
+ - if @default_integration
+ .js-vue-default-integration-settings{ data: integration_form_data(@default_integration, group: @group, project: @project) }
+ .js-vue-integration-settings{ data: integration_form_data(integration, group: @group, project: @project) }
+ .js-integration-help-html.gl-display-none
+ -# All content below will be repositioned in Vue
+ - if lookup_context.template_exists?('help', "projects/services/#{integration.to_param}", true)
+ = render "projects/services/#{integration.to_param}/help", integration: integration
+ - elsif integration.help.present?
+ .info-well
+ .well-segment
+ = markdown integration.help
diff --git a/app/views/shared/_label.html.haml b/app/views/shared/_label.html.haml
index e4ef0a52eba..9428813f6b0 100644
--- a/app/views/shared/_label.html.haml
+++ b/app/views/shared/_label.html.haml
@@ -10,18 +10,18 @@
= render "shared/label_row", label: label, force_priority: force_priority
%ul.label-actions-list
- if can?(current_user, :admin_label, @project)
- %li.inline.js-toggle-priority{ data: { url: remove_priority_project_label_path(@project, label),
+ %li.gl-display-inline-block.js-toggle-priority.gl-ml-3{ data: { url: remove_priority_project_label_path(@project, label),
dom_id: dom_id(label), type: label.type } }
- %button.add-priority.btn.gl-button.btn-default-tertiary.btn-sm.has-tooltip.gl-ml-3{ title: _('Prioritize'), type: 'button', data: { placement: 'bottom' }, aria_label: _('Prioritize label') }
+ %button.add-priority.btn.gl-button.btn-default-tertiary.btn-sm.has-tooltip{ title: _('Prioritize'), type: 'button', data: { placement: 'bottom' }, aria_label: _('Prioritize label') }
= sprite_icon('star-o')
- %button.remove-priority.btn.gl-button.btn-default-tertiary.btn-sm.has-tooltip.gl-ml-3{ title: _('Remove priority'), type: 'button', data: { placement: 'bottom' }, aria_label: _('Deprioritize label') }
+ %button.remove-priority.btn.gl-button.btn-default-tertiary.btn-sm.has-tooltip{ title: _('Remove priority'), type: 'button', data: { placement: 'bottom' }, aria_label: _('Deprioritize label') }
= sprite_icon('star')
- if can?(current_user, :admin_label, label)
- %li.inline
+ %li.gl-display-inline-block
= link_to label.edit_path, class: 'btn gl-button btn-default-tertiary btn-sm edit has-tooltip', title: _('Edit'), data: { placement: 'bottom' }, aria_label: _('Edit') do
= sprite_icon('pencil')
- if can?(current_user, :admin_label, label)
- %li.inline
+ %li.gl-display-inline-block
.dropdown
%button{ type: 'button', class: 'btn gl-button btn-default-tertiary btn-sm js-label-options-dropdown', data: { toggle: 'dropdown' }, aria_label: _('Label actions dropdown') }
= sprite_icon('ellipsis_v')
@@ -41,23 +41,23 @@
%button.text-danger.js-delete-label-modal-button{ type: 'button', data: { label_name: label.name, subject_name: label.subject_name, destroy_path: label.destroy_path } }
= _('Delete')
- if current_user
- %li.inline.label-subscription
+ %li.gl-display-inline-block.label-subscription.js-label-subscription.gl-ml-3
- if label.can_subscribe_to_label_in_different_levels?
- %button.js-unsubscribe-button.gl-button.label-subscribe-button.btn.btn-default.gl-ml-3{ class: ('hidden' if status.unsubscribed?), data: { url: toggle_subscription_path, toggle: 'tooltip' }, title: tooltip_title }
- %span= _('Unsubscribe')
+ %button.js-unsubscribe-button.gl-button.btn.btn-default.gl-w-full{ class: ('hidden' if status.unsubscribed?), data: { url: toggle_subscription_path, toggle: 'tooltip' }, title: tooltip_title }
+ %span.gl-button-text= _('Unsubscribe')
.dropdown.dropdown-group-label{ class: ('hidden' unless status.unsubscribed?) }
- %button.gl-button.label-subscribe-button.btn.btn-default.gl-ml-3{ data: { toggle: 'dropdown' } }
- %span
+ %button.gl-button.btn.btn-default.gl-w-full{ data: { toggle: 'dropdown' } }
+ %span.gl-button-text
= _('Subscribe')
= sprite_icon('chevron-down')
.dropdown-menu.dropdown-open-left
%ul
%li
- %button.js-subscribe-button.label-subscribe-button.gl-button.btn.btn-default{ class: ('hidden' unless status.unsubscribed?), data: { status: status, url: toggle_subscription_project_label_path(@project, label) } }
- %span= _('Subscribe at project level')
+ %button.js-subscribe-button{ class: ('hidden' unless status.unsubscribed?), data: { status: status, url: toggle_subscription_project_label_path(@project, label) } }
+ %span.gl-button-text= _('Subscribe at project level')
%li
- %button.js-subscribe-button.js-group-level.label-subscribe-button.gl-button.btn.btn-default{ class: ('hidden' unless status.unsubscribed?), data: { status: status, url: toggle_subscription_group_label_path(label.group, label) } }
- %span= _('Subscribe at group level')
+ %button.js-subscribe-button.js-group-level{ class: ('hidden' unless status.unsubscribed?), data: { status: status, url: toggle_subscription_group_label_path(label.group, label) } }
+ %span.gl-button-text= _('Subscribe at group level')
- else
- %button.gl-button.js-subscribe-button.label-subscribe-button.btn.btn-default.gl-ml-3{ data: { status: status, url: toggle_subscription_path, toggle: 'tooltip' }, title: tooltip_title }
- %span= label_subscription_toggle_button_text(label, @project)
+ %button.gl-button.js-subscribe-button.btn.btn-default.gl-w-full{ data: { status: status, url: toggle_subscription_path, toggle: 'tooltip' }, title: tooltip_title }
+ %span.gl-button-text= label_subscription_toggle_button_text(label, @project)
diff --git a/app/views/shared/_new_project_item_select.html.haml b/app/views/shared/_new_project_item_select.html.haml
index d5f4add2796..08003346d09 100644
--- a/app/views/shared/_new_project_item_select.html.haml
+++ b/app/views/shared/_new_project_item_select.html.haml
@@ -1,6 +1,6 @@
- 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.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!" }
+ %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')
= 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') }
diff --git a/app/views/shared/_old_visibility_level.html.haml b/app/views/shared/_old_visibility_level.html.haml
index 8a9cc7ab8a2..104c722ee65 100644
--- a/app/views/shared/_old_visibility_level.html.haml
+++ b/app/views/shared/_old_visibility_level.html.haml
@@ -1,6 +1,6 @@
.form-group.row
.col-sm-2.col-form-label
= _('Visibility level')
- = link_to sprite_icon('question-o'), help_page_path('public_access/public_access'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('public_access/public_access'), target: '_blank', rel: 'noopener noreferrer'
.col-sm-10
= render 'shared/visibility_level', f: f, visibility_level: visibility_level, can_change_visibility_level: can_change_visibility_level, form_model: form_model, with_label: with_label
diff --git a/app/views/shared/_registration_features_discovery_message.html.haml b/app/views/shared/_registration_features_discovery_message.html.haml
index 8bcd826d8c0..8a16d36b836 100644
--- a/app/views/shared/_registration_features_discovery_message.html.haml
+++ b/app/views/shared/_registration_features_discovery_message.html.haml
@@ -1,9 +1,9 @@
-- license = local_assigns.fetch(:license)
+- feature_title = local_assigns.fetch(:feature_title, s_('RegistrationFeatures|use this feature'))
- registration_features_docs_path = help_page_path('development/service_ping/index.md', anchor: 'registration-features-program')
- service_ping_settings_path = metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings')
%div
- %span= s_('RegistrationFeatures|Want to use this feature for free?')
- - if license.present?
+ %span= sprintf(s_('RegistrationFeatures|Want to %{feature_title} for free?'), { feature_title: feature_title })
+ - if Gitlab.ee?
= link_to s_('RegistrationFeatures|Enable Service Ping and register for this feature.'), service_ping_settings_path
- = sprintf(s_('RegistrationFeatures|Read more about the %{linkStart}Registration Features Program%{linkEnd}.') , { linkStart: "<a href=\"#{registration_features_docs_path}\" target=\"_blank\">", linkEnd: "</a>", }).html_safe
+ = sprintf(s_('RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}.') , { linkStart: "<a href=\"#{registration_features_docs_path}\" target=\"_blank\">", label: s_('RegistrationFeatures|Registration Features Program'), linkEnd: "</a>" }).html_safe
diff --git a/app/views/shared/_service_settings.html.haml b/app/views/shared/_service_settings.html.haml
deleted file mode 100644
index adacaeadfab..00000000000
--- a/app/views/shared/_service_settings.html.haml
+++ /dev/null
@@ -1,14 +0,0 @@
-= form_errors(integration)
-
-.service-settings
- - if @default_integration
- .js-vue-default-integration-settings{ data: integration_form_data(@default_integration, group: @group, project: @project) }
- .js-vue-integration-settings{ data: integration_form_data(integration, group: @group, project: @project) }
- .js-integration-help-html.gl-display-none
- -# All content below will be repositioned in Vue
- - if lookup_context.template_exists?('help', "projects/services/#{integration.to_param}", true)
- = render "projects/services/#{integration.to_param}/help", integration: integration
- - elsif integration.help.present?
- .info-well
- .well-segment
- = markdown integration.help
diff --git a/app/views/shared/_web_ide_button.html.haml b/app/views/shared/_web_ide_button.html.haml
index f9c6afcbc32..82af52cdd59 100644
--- a/app/views/shared/_web_ide_button.html.haml
+++ b/app/views/shared/_web_ide_button.html.haml
@@ -6,5 +6,3 @@
= render 'shared/confirm_fork_modal', fork_path: fork_and_edit_path(@project, @ref, @path), type: 'edit'
- if show_web_ide_button?
= render 'shared/confirm_fork_modal', fork_path: ide_fork_and_edit_path(@project, @ref, @path), type: 'webide'
-- if show_gitpod_button?
- = render 'shared/gitpod/enable_gitpod_modal'
diff --git a/app/views/shared/access_tokens/_form.html.haml b/app/views/shared/access_tokens/_form.html.haml
index 6435475a9a3..a52b7236137 100644
--- a/app/views/shared/access_tokens/_form.html.haml
+++ b/app/views/shared/access_tokens/_form.html.haml
@@ -1,7 +1,7 @@
- title = local_assigns.fetch(:title, _('Add a %{type}') % { type: type })
- prefix = local_assigns.fetch(:prefix, :personal_access_token)
- help_path = local_assigns.fetch(:help_path)
-- project = local_assigns.fetch(:project, false)
+- resource = local_assigns.fetch(:resource, false)
- access_levels = local_assigns.fetch(:access_levels, false)
- default_access_level = local_assigns.fetch(:default_access_level, false)
@@ -32,12 +32,12 @@
.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' }
- - if project
+ - if resource
.row
.form-group.col-md-6
= label_tag :access_level, _("Select a role"), class: "label-bold"
.select-wrapper
- = select_tag :"#{prefix}[access_level]", options_for_select(access_levels, default_access_level), class: "form-control project-access-select select-control", data: { qa_selector: 'access_token_access_level' }
+ = select_tag :"#{prefix}[access_level]", options_for_select(access_levels, default_access_level), class: "form-control select-control", data: { qa_selector: 'access_token_access_level' }
= sprite_icon('chevron-down', css_class: "gl-icon gl-absolute gl-top-3 gl-right-3 gl-text-gray-200")
.form-group
@@ -45,7 +45,7 @@
= s_('Tokens|Select scopes')
%p.text-secondary#select_scope_help_text
= s_('Tokens|Scopes set the permission levels granted to the token.')
- = link_to "Learn more.", help_path, target: '_blank'
+ = link_to _("Learn more."), help_path, target: '_blank', rel: 'noopener noreferrer'
= render 'shared/tokens/scopes_form', prefix: prefix, token: token, scopes: scopes
- if prefix == :personal_access_token && Feature.enabled?(:personal_access_tokens_scoped_to_projects, current_user)
diff --git a/app/views/shared/access_tokens/_table.html.haml b/app/views/shared/access_tokens/_table.html.haml
index c096044e439..aa579b4a672 100644
--- a/app/views/shared/access_tokens/_table.html.haml
+++ b/app/views/shared/access_tokens/_table.html.haml
@@ -1,7 +1,7 @@
- no_active_tokens_message = local_assigns.fetch(:no_active_tokens_message, _('This user has no active %{type}.') % { type: type_plural })
- impersonation = local_assigns.fetch(:impersonation, false)
-- project = local_assigns.fetch(:project, false)
-- personal = !impersonation && !project
+- resource = local_assigns.fetch(:resource, false)
+- personal = !impersonation && !resource
%hr
@@ -28,9 +28,9 @@
%th= s_('AccessTokens|Created')
%th
= _('Last Used')
- = link_to sprite_icon('question-o'), help_page_path('user/profile/personal_access_tokens.md', anchor: 'view-the-last-time-a-token-was-used'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('user/profile/personal_access_tokens.md', anchor: 'view-the-last-time-a-token-was-used'), target: '_blank', rel: 'noopener noreferrer'
%th= _('Expires')
- - if project
+ - if resource
%th= _('Role')
%th
%tbody
@@ -54,8 +54,8 @@
= time_ago_with_tooltip(token.expires_at)
- else
%span.token-never-expires-label= _('Never')
- - if project
- %td= project.project_member(token.user).human_access
+ - if resource
+ %td= resource.member(token.user).human_access
%td= link_to _('Revoke'), revoke_route_helper.call(token), method: :put, class: "gl-button btn btn-danger btn-sm float-right qa-revoke-button #{'btn-danger-secondary' unless token.expires?}", data: { confirm: _('Are you sure you want to revoke this %{type}? This action cannot be undone.') % { type: type } }
- else
.settings-message.text-center
diff --git a/app/views/shared/empty_states/_deploy_keys.html.haml b/app/views/shared/empty_states/_deploy_keys.html.haml
deleted file mode 100644
index 6c615de9c56..00000000000
--- a/app/views/shared/empty_states/_deploy_keys.html.haml
+++ /dev/null
@@ -1,9 +0,0 @@
-.empty-state.gl-display-flex.gl-flex-direction-column.gl-flex-wrap.gl-text-center
- .gl-flex-grow-0.gl-flex-shrink-0
- .svg-250.svg-content
- = image_tag 'illustrations/empty-state/empty-deploy-keys-lg.svg'
- .gl-flex-grow-0.gl-flex-shrink-0
- .text-content.gl-mx-auto.gl-my-0.gl-p-5
- %h4.h4= _('Deploy Keys')
- %p= _('Deploy keys grant read/write access to all repositories in your instance')
- = link_to _('New deploy key'), new_admin_deploy_key_path, class: 'gl-button btn btn-confirm btn-md'
diff --git a/app/views/shared/empty_states/_issues.html.haml b/app/views/shared/empty_states/_issues.html.haml
index 9842457a2eb..6b571794625 100644
--- a/app/views/shared/empty_states/_issues.html.haml
+++ b/app/views/shared/empty_states/_issues.html.haml
@@ -42,7 +42,7 @@
- if has_button
.text-center
- if project_select_button
- = render 'shared/new_project_item_select', path: 'issues/new', label: _('New issue'), type: :issues, with_feature_enabled: 'issues'
+ = render 'shared/new_project_item_select', path: 'issues/new', label: _('issue'), type: :issues, with_feature_enabled: 'issues'
- elsif show_new_issue_link?(@project)
= link_to _('New issue'), button_path, class: 'gl-button btn btn-confirm', id: 'new_issue_link'
diff --git a/app/views/shared/empty_states/_merge_requests.html.haml b/app/views/shared/empty_states/_merge_requests.html.haml
index 72db4d4c846..d0c4fb2432c 100644
--- a/app/views/shared/empty_states/_merge_requests.html.haml
+++ b/app/views/shared/empty_states/_merge_requests.html.haml
@@ -40,6 +40,6 @@
- if has_button
.text-center
- if project_select_button
- = render 'shared/new_project_item_select', path: 'merge_requests/new', label: _('New merge request'), type: :merge_requests, with_feature_enabled: 'merge_requests'
+ = render 'shared/new_project_item_select', path: 'merge_requests/new', label: _('merge request'), type: :merge_requests, with_feature_enabled: 'merge_requests'
- else
= link_to _('New merge request'), button_path, class: 'gl-button btn btn-confirm', title: _('New merge request'), id: 'new_merge_request_link'
diff --git a/app/views/shared/empty_states/_wikis.html.haml b/app/views/shared/empty_states/_wikis.html.haml
index 917ef666e85..c3120774826 100644
--- a/app/views/shared/empty_states/_wikis.html.haml
+++ b/app/views/shared/empty_states/_wikis.html.haml
@@ -13,7 +13,7 @@
= create_link
- if show_enable_confluence_integration?(@wiki.container)
= link_to s_('WikiEmpty|Enable the Confluence Wiki integration'),
- edit_project_service_path(@project, :confluence),
+ edit_project_integration_path(@project, :confluence),
class: 'btn gl-button', title: s_('WikiEmpty|Enable the Confluence Wiki integration')
- elsif @project && can?(current_user, :read_issue, @project)
diff --git a/app/views/shared/gitpod/_enable_gitpod_modal.html.haml b/app/views/shared/gitpod/_enable_gitpod_modal.html.haml
deleted file mode 100644
index 6a8ff98a09e..00000000000
--- a/app/views/shared/gitpod/_enable_gitpod_modal.html.haml
+++ /dev/null
@@ -1,12 +0,0 @@
-#modal-enable-gitpod.modal.qa-enable-gitpod-modal
- .modal-dialog
- .modal-content
- .modal-header
- %h3.page-title= _('Enable Gitpod?')
- %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') }
- %span{ "aria-hidden": "true" } &times;
- .modal-body.p-3
- %p= (_("To use Gitpod you must first enable the feature in the integrations section of your %{user_prefs}.") % { user_prefs: link_to(_('user preferences'), profile_preferences_path(anchor: 'gitpod')) }).html_safe
- .modal-footer
- = link_to _('Cancel'), '#', class: "gl-button btn btn-default btn-cancel", "data-dismiss" => "modal"
- = link_to _('Enable Gitpod'), profile_path(user: { gitpod_enabled: true}), class: 'gl-button btn btn-confirm', method: :put
diff --git a/app/views/shared/hook_logs/_content.html.haml b/app/views/shared/hook_logs/_content.html.haml
index ab6875a09f7..d358340814c 100644
--- a/app/views/shared/hook_logs/_content.html.haml
+++ b/app/views/shared/hook_logs/_content.html.haml
@@ -2,8 +2,7 @@
%h4
POST
= hook_log.url
- %span.badge.gl-badge.badge-pill.badge-muted.sm.gl-ml-3
- = hook_log.trigger.singularize.titleize
+ = gl_badge_tag hook_log.trigger.singularize.titleize, { size: :sm }, { class: 'gl-ml-3' }
%p
= _('Completed in %{duration_seconds} seconds (%{relative_time})').html_safe % { duration_seconds: number_with_precision(hook_log.execution_duration, precision: 2), relative_time: time_ago_with_tooltip(hook_log.created_at) }
diff --git a/app/views/shared/hook_logs/_recent_deliveries_table.html.haml b/app/views/shared/hook_logs/_recent_deliveries_table.html.haml
index 31ef8560781..3c91c2f6ab4 100644
--- a/app/views/shared/hook_logs/_recent_deliveries_table.html.haml
+++ b/app/views/shared/hook_logs/_recent_deliveries_table.html.haml
@@ -13,8 +13,7 @@
%td
= render partial: 'shared/hook_logs/status_label', locals: { hook_log: hook_log }
%td.d-none.d-sm-table-cell
- %span.badge.badge-pill.gl-badge.badge-muted.sm
- = hook_log.trigger.singularize.titleize
+ = gl_badge_tag hook_log.trigger.singularize.titleize, { size: :sm }
%td
#{number_with_precision(hook_log.execution_duration, precision: 2)} sec
%td
diff --git a/app/views/shared/hook_logs/_status_label.html.haml b/app/views/shared/hook_logs/_status_label.html.haml
index b930074303c..6f82dc280f3 100644
--- a/app/views/shared/hook_logs/_status_label.html.haml
+++ b/app/views/shared/hook_logs/_status_label.html.haml
@@ -1,3 +1,4 @@
-- label_status = hook_log.success? ? 'badge-success' : 'badge-danger'
-%span{ class: "badge badge-pill gl-badge sm #{label_status}" }
- = hook_log.internal_error? ? _('Error') : hook_log.response_status
+- badge_variant = hook_log.success? ? :success : :danger
+- badge_text = hook_log.internal_error? ? _('Error') : hook_log.response_status
+
+= gl_badge_tag badge_text, { variant: badge_variant, size: :sm }
diff --git a/app/views/shared/integrations/_form.html.haml b/app/views/shared/integrations/_form.html.haml
index 89c127408e1..e2457bc0632 100644
--- a/app/views/shared/integrations/_form.html.haml
+++ b/app/views/shared/integrations/_form.html.haml
@@ -1,4 +1,4 @@
- integration = local_assigns.fetch(:integration)
-= form_for integration, as: :service, url: scoped_integration_path(integration, group: @group), method: :put, html: { class: 'gl-show-field-errors integration-settings-form js-integration-settings-form', data: { 'test-url' => scoped_test_integration_path(integration, group: @group) } } do |form|
- = render 'shared/service_settings', form: form, integration: integration
+= form_for integration, as: :service, url: scoped_integration_path(integration, group: @group), method: :put, html: { class: 'gl-show-field-errors integration-settings-form js-integration-settings-form', data: { 'test-url' => scoped_test_integration_path(integration, group: @group), testid: 'integration-form' } } do |form|
+ = render 'shared/integration_settings', form: form, integration: integration
diff --git a/app/views/shared/integrations/edit.html.haml b/app/views/shared/integrations/edit.html.haml
index acb0c7ee52e..4ceaedc2a69 100644
--- a/app/views/shared/integrations/edit.html.haml
+++ b/app/views/shared/integrations/edit.html.haml
@@ -7,4 +7,7 @@
= @integration.title
= render 'shared/integrations/tabs', integration: @integration, active_tab: 'edit' do
- = render 'shared/integrations/form', integration: @integration
+ - if vue_integration_form_enabled?
+ = render 'shared/integration_settings', integration: @integration
+ - else
+ = render 'shared/integrations/form', integration: @integration
diff --git a/app/views/shared/integrations/overrides.html.haml b/app/views/shared/integrations/overrides.html.haml
index b8585fdef1f..4619675cfef 100644
--- a/app/views/shared/integrations/overrides.html.haml
+++ b/app/views/shared/integrations/overrides.html.haml
@@ -6,5 +6,4 @@
%h3.page-title
= @integration.title
-= render 'shared/integrations/tabs', integration: @integration, active_tab: 'overrides' do
- .js-vue-integration-overrides{ data: integration_overrides_data(@integration) }
+.js-vue-integration-overrides{ data: integration_overrides_data(@integration, project: @project, group: @group) }
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index 4024c5b77f6..16301789b65 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -64,9 +64,9 @@
for this project.
- if issuable.new_record?
- = form.submit "#{_('Create')} #{issuable.class.model_name.human.downcase}", class: 'gl-button btn btn-confirm gl-mr-2', data: { qa_selector: 'issuable_create_button' }
+ = form.submit "#{_('Create')} #{issuable.class.model_name.human.downcase}", class: 'gl-button btn btn-confirm gl-mr-2', data: { qa_selector: 'issuable_create_button', track_experiment: 'promote_mr_approvals_in_free', track_action: 'click_button', track_label: 'submit_mr', track_value: 0 }
- else
- = form.submit _('Save changes'), class: 'gl-button btn btn-confirm gl-mr-2'
+ = form.submit _('Save changes'), class: 'gl-button btn btn-confirm gl-mr-2', data: { track_experiment: 'promote_mr_approvals_in_free', track_action: 'click_button', track_label: 'submit_mr', track_value: 0 }
- if issuable.new_record?
= link_to _('Cancel'), polymorphic_path([@project, issuable.class]), class: 'btn gl-button btn-default'
diff --git a/app/views/shared/issuable/_label_page_create.html.haml b/app/views/shared/issuable/_label_page_create.html.haml
index cf7e6cf8365..84cdf129cb2 100644
--- a/app/views/shared/issuable/_label_page_create.html.haml
+++ b/app/views/shared/issuable/_label_page_create.html.haml
@@ -6,7 +6,10 @@
.dropdown-page-two.dropdown-new-label
= dropdown_title(create_label_title(subject), options: { back: true, close: show_close })
= dropdown_content do
- .dropdown-labels-error.js-label-error
+ .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
%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 e097852216c..3975748ba57 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -5,6 +5,11 @@
- 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)
- elsif board
@@ -26,7 +31,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, board&.resource_parent) && board
+ - elsif Feature.enabled?(:issue_boards_filtered_search, ff_resource) && 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/form/_merge_params.html.haml b/app/views/shared/issuable/form/_merge_params.html.haml
index 7233e671caa..76feb4d1613 100644
--- a/app/views/shared/issuable/form/_merge_params.html.haml
+++ b/app/views/shared/issuable/form/_merge_params.html.haml
@@ -25,7 +25,7 @@
= check_box_tag 'merge_request[squash]', '1', issuable_squash_option?(issuable, project), class: 'form-check-input'
= label_tag 'merge_request[squash]', class: 'form-check-label' do
Squash commits when merge request is accepted.
- = link_to sprite_icon('question-o'), help_page_path('user/project/merge_requests/squash_and_merge'), target: '_blank'
+ = link_to sprite_icon('question-o'), help_page_path('user/project/merge_requests/squash_and_merge'), target: '_blank', rel: 'noopener noreferrer'
- if project.squash_always?
.gl-text-gray-400
= _('Required in this project.')
diff --git a/app/views/shared/labels/_form.html.haml b/app/views/shared/labels/_form.html.haml
index 6f65dbe4811..29f6dc02749 100644
--- a/app/views/shared/labels/_form.html.haml
+++ b/app/views/shared/labels/_form.html.haml
@@ -5,30 +5,35 @@
.col-sm-2.col-form-label
= f.label :title
.col-sm-10
- = f.text_field :title, class: "form-control js-label-title qa-label-title", required: true, autofocus: true
+ = f.text_field :title, class: "gl-form-input form-control js-label-title qa-label-title", required: true, autofocus: true
= render_if_exists 'shared/labels/create_label_help_text'
.form-group.row
.col-sm-2.col-form-label
= f.label :description
.col-sm-10
- = f.text_field :description, class: "form-control js-quick-submit qa-label-description"
+ = f.text_field :description, class: "gl-form-input form-control js-quick-submit qa-label-description"
.form-group.row
.col-sm-2.col-form-label
- = f.label :color, "Background color"
+ = f.label :color, _("Background color")
.col-sm-10
.input-group
.input-group-prepend
.input-group-text.label-color-preview &nbsp;
- = f.text_field :color, class: "form-control qa-label-color"
+ = f.text_field :color, class: "gl-form-input form-control qa-label-color"
.form-text.text-muted
- Choose any color.
+ = _('Choose any color.')
%br
- Or you can choose one of the suggested colors below
+ = _("Or you can choose one of the suggested colors below")
= render_suggested_colors
- .form-actions
+ .gl-display-flex.gl-justify-content-space-between.gl-p-5.gl-bg-gray-10.gl-border-t-solid.gl-border-t-gray-100.gl-border-t-1
+ %div
+ - if @label.persisted?
+ = f.submit _('Save changes'), class: 'btn gl-button btn-confirm js-save-button'
+ - else
+ = f.submit _('Create label'), class: 'btn gl-button btn-confirm js-save-button qa-label-create-button'
+ = link_to _('Cancel'), back_path, class: 'btn gl-button btn-default btn-cancel'
- if @label.persisted?
- = f.submit _('Save changes'), class: 'btn gl-button btn-confirm js-save-button'
- - else
- = f.submit 'Create label', class: 'btn gl-button btn-confirm js-save-button qa-label-create-button'
- = link_to _('Cancel'), back_path, class: 'btn gl-button btn-default btn-cancel'
+ - presented_label = @label.present
+ %button.btn.btn-danger.gl-button.btn-danger-secondary.js-delete-label-modal-button{ type: 'button', data: { label_name: presented_label.name, subject_name: presented_label.subject_name, destroy_path: presented_label.destroy_path } }
+ %span.gl-button-text= _('Delete')
diff --git a/app/views/shared/members/_badge.html.haml b/app/views/shared/members/_badge.html.haml
index 5f925ff0cad..e7bd055fe5d 100644
--- a/app/views/shared/members/_badge.html.haml
+++ b/app/views/shared/members/_badge.html.haml
@@ -1,4 +1,4 @@
-- type ||= 'info'
+- variant ||= :info
%span.px-1.py-1
- %span{ class: "badge badge-pill gl-badge sm badge-#{type}" }= yield
+ = gl_badge_tag yield, variant: variant, size: :sm
diff --git a/app/views/shared/members/_blocked_badge.html.haml b/app/views/shared/members/_blocked_badge.html.haml
index 95335ebe74d..6795128279f 100644
--- a/app/views/shared/members/_blocked_badge.html.haml
+++ b/app/views/shared/members/_blocked_badge.html.haml
@@ -1,3 +1,3 @@
- if user.blocked?
- = render 'shared/members/badge', type: 'danger' do
+ = render 'shared/members/badge', variant: :danger do
= _("Blocked")
diff --git a/app/views/shared/members/_its_you_badge.html.haml b/app/views/shared/members/_its_you_badge.html.haml
index b53ffd8032d..4442e57f86e 100644
--- a/app/views/shared/members/_its_you_badge.html.haml
+++ b/app/views/shared/members/_its_you_badge.html.haml
@@ -1,3 +1,3 @@
- if user == current_user
- = render 'shared/members/badge', type: 'success' do
+ = render 'shared/members/badge', variant: :success do
= _("It's you")
diff --git a/app/views/shared/members/_two_factor_auth_badge.html.haml b/app/views/shared/members/_two_factor_auth_badge.html.haml
index 34850c135d6..f1cb7a5bd85 100644
--- a/app/views/shared/members/_two_factor_auth_badge.html.haml
+++ b/app/views/shared/members/_two_factor_auth_badge.html.haml
@@ -1,3 +1,3 @@
- if user.two_factor_enabled?
- = render 'shared/members/badge', type: 'info' do
+ = render 'shared/members/badge', variant: :info do
= _("2FA")
diff --git a/app/views/shared/nav/_sidebar_menu.html.haml b/app/views/shared/nav/_sidebar_menu.html.haml
index 4c4ceb9ea70..bc0648c14e0 100644
--- a/app/views/shared/nav/_sidebar_menu.html.haml
+++ b/app/views/shared/nav/_sidebar_menu.html.haml
@@ -13,7 +13,7 @@
%span.nav-item-name{ **sidebar_menu.title_html_options }
= sidebar_menu.title
- if sidebar_menu.has_pill?
- %span.badge.badge-pill.count{ **sidebar_menu.pill_html_options }
+ = gl_badge_tag({ variant: :info, size: :sm }, { class: "count #{sidebar_menu.pill_html_options[:class]}" }) do
= number_with_delimiter(sidebar_menu.pill_count)
= render partial: 'shared/nav/sidebar_submenu', locals: { sidebar_menu: sidebar_menu }
diff --git a/app/views/shared/notes/_hints.html.haml b/app/views/shared/notes/_hints.html.haml
index 6231f817704..6c8b2a9e5bb 100644
--- a/app/views/shared/notes/_hints.html.haml
+++ b/app/views/shared/notes/_hints.html.haml
@@ -2,10 +2,10 @@
- supports_file_upload = local_assigns.fetch(:supports_file_upload, true)
.comment-toolbar.clearfix
.toolbar-text
- = link_to _('Markdown'), help_page_path('user/markdown'), target: '_blank'
+ = link_to _('Markdown'), help_page_path('user/markdown'), target: '_blank', rel: 'noopener noreferrer'
- if supports_quick_actions
and
- = link_to _('quick actions'), help_page_path('user/project/quick_actions'), target: '_blank'
+ = link_to _('quick actions'), help_page_path('user/project/quick_actions'), target: '_blank', rel: 'noopener noreferrer'
are
- else
is
diff --git a/app/views/shared/runners/_shared_runners_description.html.haml b/app/views/shared/runners/_shared_runners_description.html.haml
index e2b57a7fd73..2779901ca0c 100644
--- a/app/views/shared/runners/_shared_runners_description.html.haml
+++ b/app/views/shared/runners/_shared_runners_description.html.haml
@@ -1,5 +1,5 @@
-# "MaxBuilds" is a runner configuration keyword so it must not be translated.
-- link = link_to 'MaxBuilds', 'https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnersmachine-section', target: '_blank'
+- link = link_to 'MaxBuilds', 'https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnersmachine-section', target: '_blank', rel: 'noopener noreferrer'
%h4
= _('Shared runners')
diff --git a/app/views/shared/web_hooks/_form.html.haml b/app/views/shared/web_hooks/_form.html.haml
index 18912bf149f..5650f08b2a9 100644
--- a/app/views/shared/web_hooks/_form.html.haml
+++ b/app/views/shared/web_hooks/_form.html.haml
@@ -4,12 +4,14 @@
= form.label :url, s_('Webhooks|URL'), class: 'label-bold'
= form.text_field :url, class: 'form-control gl-form-input', placeholder: 'http://example.com/trigger-ci.json'
%p.form-text.text-muted
- = s_('Webhooks|URL must be percent-encoded if neccessary.')
+ = s_('Webhooks|URL must be percent-encoded if it contains one or more special characters.')
.form-group
= form.label :token, s_('Webhooks|Secret token'), class: 'label-bold'
= form.text_field :token, class: 'form-control gl-form-input', placeholder: ''
%p.form-text.text-muted
- = s_('Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header.')
+ - code_start = '<code>'.html_safe
+ - code_end = '</code>'.html_safe
+ = s_('Webhooks|Used to validate received payloads. Sent with the request in the %{code_start}X-Gitlab-Token HTTP%{code_end} header.').html_safe % { code_start: code_start, code_end: code_end }
.form-group
= form.label :url, s_('Webhooks|Trigger'), class: 'label-bold'
%ul.list-unstyled.gl-ml-6
@@ -19,37 +21,37 @@
%strong= s_('Webhooks|Push events')
= form.text_field :push_events_branch_filter, class: 'form-control gl-form-input', placeholder: 'Branch name or wildcard pattern to trigger on (leave blank for all)'
%p.text-muted.gl-ml-1
- = s_('Webhooks|URL is triggered by a push to the repository')
+ = s_('Webhooks|Push to the repository.')
%li
= form.check_box :tag_push_events, class: 'form-check-input'
= form.label :tag_push_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Tag push events')
%p.text-muted.gl-ml-1
- = s_('Webhooks|URL is triggered when a new tag is pushed to the repository')
+ = s_('Webhooks|A new tag is pushed to the repository.')
%li
= form.check_box :note_events, class: 'form-check-input'
= form.label :note_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Comments')
%p.text-muted.gl-ml-1
- = s_('Webhooks|URL is triggered when someone adds a comment')
+ = s_('Webhooks|A comment is added to an issue.')
%li
= form.check_box :confidential_note_events, class: 'form-check-input'
= form.label :confidential_note_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Confidential comments')
%p.text-muted.gl-ml-1
- = s_('Webhooks|URL is triggered when someone adds a comment on a confidential issue')
+ = s_('Webhooks|A comment is added to a confidential issue.')
%li
= form.check_box :issues_events, class: 'form-check-input'
= form.label :issues_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Issues events')
%p.text-muted.gl-ml-1
- = s_('Webhooks|URL is triggered when an issue is created, updated, closed, or reopened')
+ = s_('Webhooks|An issue is created, updated, closed, or reopened.')
%li
= form.check_box :confidential_issues_events, class: 'form-check-input'
= form.label :confidential_issues_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Confidential issues events')
%p.text-muted.gl-ml-1
- = s_('Webhooks|URL is triggered when a confidential issue is created, updated, closed, or reopened')
+ = s_('Webhooks|A confidential issue is created, updated, closed, or reopened.')
- if @group
= render_if_exists 'groups/hooks/member_events', form: form
= render_if_exists 'groups/hooks/subgroup_events', form: form
@@ -58,43 +60,43 @@
= form.label :merge_requests_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Merge request events')
%p.text-muted.gl-ml-1
- = s_('Webhooks|URL is triggered when a merge request is created, updated, or merged')
+ = s_('Webhooks|A merge request is created, updated, or merged.')
%li
= form.check_box :job_events, class: 'form-check-input'
= form.label :job_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Job events')
%p.text-muted.gl-ml-1
- = s_('Webhooks|URL is triggered when the job status changes')
+ = s_("Webhooks|A job's status changes.")
%li
= form.check_box :pipeline_events, class: 'form-check-input'
= form.label :pipeline_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Pipeline events')
%p.text-muted.gl-ml-1
- = s_('Webhooks|URL is triggered when the pipeline status changes')
+ = s_("Webhooks|A pipeline's status changes.")
%li
= form.check_box :wiki_page_events, class: 'form-check-input'
= form.label :wiki_page_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Wiki page events')
%p.text-muted.gl-ml-1
- = s_('Webhooks|URL is triggered when a wiki page is created or updated')
+ = s_('Webhooks|A wiki page is created or updated.')
%li
= form.check_box :deployment_events, class: 'form-check-input'
= form.label :deployment_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Deployment events')
%p.text-muted.gl-ml-1
- = s_('Webhooks|URL is triggered when a deployment starts, finishes, fails, or is canceled')
+ = s_('Webhooks|A deployment starts, finishes, fails, or is canceled.')
%li
= form.check_box :feature_flag_events, class: 'form-check-input'
= form.label :feature_flag_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Feature flag events')
%p.text-muted.gl-ml-1
- = s_('Webhooks|URL is triggered when a feature flag is turned on or off')
+ = s_('Webhooks|A feature flag is turned on or off.')
%li
= form.check_box :releases_events, class: 'form-check-input'
= form.label :releases_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Releases events')
%p.text-muted.gl-ml-1
- = s_('Webhooks|URL is triggered when a release is created or updated')
+ = s_('Webhooks|A release is created or updated.')
.form-group
= form.label :enable_ssl_verification, s_('Webhooks|SSL verification'), class: 'label-bold checkbox'
.form-check
diff --git a/app/views/shared/web_hooks/_hook.html.haml b/app/views/shared/web_hooks/_hook.html.haml
index 45baa7e2184..c5a03ef4dc1 100644
--- a/app/views/shared/web_hooks/_hook.html.haml
+++ b/app/views/shared/web_hooks/_hook.html.haml
@@ -1,22 +1,23 @@
+- sslStatus = hook.enable_ssl_verification ? _('enabled') : _('disabled')
+- sslBadgeText = _('SSL Verification:') + ' ' + sslStatus
+
%li
.row
.col-md-8.col-lg-7
%strong.light-header
= hook.url
- if hook.rate_limited?
- %span.gl-badge.badge-danger.badge-pill.sm= _('Disabled')
+ = gl_badge_tag(_('Disabled'), variant: :danger, size: :sm)
- elsif hook.permanently_disabled?
- %span.gl-badge.badge-danger.badge-pill.sm= s_('Webhooks|Failed to connect')
+ = gl_badge_tag(s_('Webhooks|Failed to connect'), variant: :danger, size: :sm)
- elsif hook.temporarily_disabled?
- %span.gl-badge.badge-warning.badge-pill.sm= s_('Webhooks|Fails to connect')
+ = gl_badge_tag(s_('Webhooks|Fails to connect'), variant: :warning, size: :sm)
%div
- hook.class.triggers.each_value do |trigger|
- if hook.public_send(trigger)
- %span.gl-badge.badge-muted.badge-pill.sm.gl-mt-2.deploy-project-label= trigger.to_s.titleize
- %span.gl-badge.badge-muted.badge-pill.sm.gl-mt-2
- = _('SSL Verification:')
- = hook.enable_ssl_verification ? _('enabled') : _('disabled')
+ = gl_badge_tag(trigger.to_s.titleize, size: :sm)
+ = gl_badge_tag(sslBadgeText, size: :sm)
.col-md-4.col-lg-5.text-right-md.gl-mt-2
%span>= render 'shared/web_hooks/test_button', hook: hook, button_class: 'btn-sm btn-default gl-mr-3'
diff --git a/app/views/shared/web_hooks/_index.html.haml b/app/views/shared/web_hooks/_index.html.haml
index f1eef5d7f0f..5d07b0f95ab 100644
--- a/app/views/shared/web_hooks/_index.html.haml
+++ b/app/views/shared/web_hooks/_index.html.haml
@@ -11,4 +11,4 @@
= render 'shared/web_hooks/hook', hook: hook
- else
%p.text-center.gl-mt-3.gl-mb-3
- = _('No webhooks found, add one in the form above.')
+ = _('No webhooks enabled. Select trigger events above.')
diff --git a/app/views/sherlock/file_samples/show.html.haml b/app/views/sherlock/file_samples/show.html.haml
deleted file mode 100644
index b7e6f883667..00000000000
--- a/app/views/sherlock/file_samples/show.html.haml
+++ /dev/null
@@ -1,55 +0,0 @@
-- page_title t('sherlock.title'), t('sherlock.transaction'),
- t('sherlock.file_sample')
-
-- header_title t('sherlock.title'), sherlock_transactions_path
-
-.row-content-block
- .float-right
- = link_to(sherlock_transaction_path(@transaction), class: 'btn gl-button') do
- = sprite_icon('arrow-left')
- = t('sherlock.transaction')
- .oneline
- = t('sherlock.file_sample')
- = @file_sample.id
-
-.gl-mt-3
- %p
- %span.light
- #{t('sherlock.time')}:
- %strong
- = @file_sample.duration.round(2)
- = t('sherlock.milliseconds')
- %p
- %span.light
- #{t('sherlock.events')}:
- %strong
- = @file_sample.events
-
-%article.file-holder
- .js-file-title.file-title
- = sprite_icon("doc-text")
- %strong
- = @file_sample.file
- .code.file-content.js-syntax-highlight
- .line-numbers
- %table.sherlock-line-samples-table.gl-mb-0
- %thead
- %tr
- %th= t('sherlock.line_capitalized')
- %th= t('sherlock.events')
- %th= t('sherlock.time')
- %th= t('sherlock.percent')
- %tbody
- - @file_sample.line_samples.each_with_index do |sample, index|
- %tr{ class: sample.majority_of?(@file_sample.duration) ? 'slow' : '' }
- %td= index + 1
- %td= sample.events
- %td
- = sample.duration.round(2)
- = t('sherlock.milliseconds')
- %td
- = sample.percentage_of(@file_sample.duration).round
- = t('sherlock.percent')
-
- .sherlock-file-sample
- = highlight(@file_sample.file, @file_sample.source)
diff --git a/app/views/sherlock/queries/_backtrace.html.haml b/app/views/sherlock/queries/_backtrace.html.haml
deleted file mode 100644
index 425113ba325..00000000000
--- a/app/views/sherlock/queries/_backtrace.html.haml
+++ /dev/null
@@ -1,31 +0,0 @@
-.gl-mt-3
- .card
- .card-header
- %strong
- = t('sherlock.application_backtrace')
- %ul.content-list
- - @query.application_backtrace.each do |location|
- %li
- %strong
- - if defined?(BetterErrors)
- = link_to(location.path, BetterErrors.editor.url(location.path, location.line))
- - else
- = location.path
- %small.light
- = t('sherlock.line')
- = location.line
-
- .card
- .card-header
- %strong
- = t('sherlock.full_backtrace')
- %ul.content-list
- - @query.backtrace.each do |location|
- %li
- - if location.application?
- %strong= location.path
- - else
- = location.path
- %small.light
- = t('sherlock.line')
- = location.line
diff --git a/app/views/sherlock/queries/_general.html.haml b/app/views/sherlock/queries/_general.html.haml
deleted file mode 100644
index a16314213c4..00000000000
--- a/app/views/sherlock/queries/_general.html.haml
+++ /dev/null
@@ -1,54 +0,0 @@
-.gl-mt-3
- .card
- .card-header
- %strong
- = t('sherlock.general')
- %ul.content-list
- %li
- %span.light
- #{t('sherlock.time')}:
- %strong
- = @query.duration.round(4)
- = t('sherlock.milliseconds')
- %li
- - frame = @query.last_application_frame
- %span.light
- #{t('sherlock.origin')}:
- %strong
- - if defined?(BetterErrors)
- = link_to(frame.path, BetterErrors.editor.url(frame.path, frame.line))
- - else
- = frame.path
- %small.light
- = t('sherlock.line')
- = frame.line
-
- .card
- .card-header
- .float-right
- %button.js-clipboard-trigger.gl-button.btn.btn-default.btn-sm{ title: t('sherlock.copy_to_clipboard'), type: :button }
- = sprite_icon('copy-to-clipboard')
- %pre.hidden
- = @query.formatted_query
- %strong
- = t('sherlock.query')
- %ul.content-list
- %li
- .code.js-syntax-highlight.sherlock-code
- :preserve
- #{highlight("#{@query.id}.sql", @query.formatted_query, language: 'sql')}
-
- .card
- .card-header
- .float-right
- %button.js-clipboard-trigger.gl-button.btn.btn-default.btn-sm{ title: t('sherlock.copy_to_clipboard'), type: :button }
- = sprite_icon('copy-to-clipboard')
- %pre.hidden
- = @query.explain
- %strong
- = t('sherlock.query_plan')
- %ul.content-list
- %li
- .code.js-syntax-highlight.sherlock-code
- %pre
- %code= @query.explain
diff --git a/app/views/sherlock/queries/show.html.haml b/app/views/sherlock/queries/show.html.haml
deleted file mode 100644
index eea13d105d8..00000000000
--- a/app/views/sherlock/queries/show.html.haml
+++ /dev/null
@@ -1,26 +0,0 @@
-- page_title t('sherlock.title'), t('sherlock.transaction'), t('sherlock.query')
-- header_title t('sherlock.title'), sherlock_transactions_path
-
-%ul.nav-links.nav.nav-tabs
- %li.active
- %a{ href: "#tab-general", data: { toggle: "tab" } }
- = t('sherlock.general')
- %li
- %a{ href: "#tab-backtrace", data: { toggle: "tab" } }
- = t('sherlock.backtrace')
-
-.row-content-block
- .float-right
- = link_to(sherlock_transaction_path(@transaction), class: 'btn gl-button btn-default') do
- = sprite_icon('arrow-left')
- = t('sherlock.transaction')
- .oneline
- = t('sherlock.query')
- = @query.id
-
-.tab-content
- .tab-pane.active#tab-general
- = render(partial: 'general')
-
- .tab-pane#tab-backtrace
- = render(partial: 'backtrace')
diff --git a/app/views/sherlock/transactions/_file_samples.html.haml b/app/views/sherlock/transactions/_file_samples.html.haml
deleted file mode 100644
index 110eb42f9ea..00000000000
--- a/app/views/sherlock/transactions/_file_samples.html.haml
+++ /dev/null
@@ -1,24 +0,0 @@
-- if @transaction.file_samples.empty?
- .nothing-here-block
- = t('sherlock.no_file_samples')
-- else
- .table-holder
- %table.table
- %thead
- %tr
- %th= t('sherlock.time_inclusive')
- %th= t('sherlock.count')
- %th= t('sherlock.path')
- %th
- %tbody
- - @transaction.sorted_file_samples.each do |sample|
- %tr
- %td
- = sample.duration.round(2)
- = t('sherlock.milliseconds')
- %td= @transaction.view_counts.fetch(sample.file, 1)
- %td= sample.relative_path
- %td
- = link_to(t('sherlock.view'),
- sherlock_transaction_file_sample_path(@transaction, sample),
- class: 'gl-button btn btn-sm')
diff --git a/app/views/sherlock/transactions/_general.html.haml b/app/views/sherlock/transactions/_general.html.haml
deleted file mode 100644
index 7cf6f27e1af..00000000000
--- a/app/views/sherlock/transactions/_general.html.haml
+++ /dev/null
@@ -1,38 +0,0 @@
-.gl-mt-3
- .card
- .card-header
- %strong
- = t('sherlock.general')
- %ul.content-list
- %li
- %span.light
- #{t('sherlock.id')}:
- %strong
- = @transaction.id
- %li
- %span.light
- #{t('sherlock.type')}:
- %strong
- = @transaction.type
- %li
- %span.light
- #{t('sherlock.path')}:
- %strong
- = @transaction.path
- %li
- %span.light
- #{t('sherlock.time')}:
- %strong
- = @transaction.duration.round(2)
- = t('sherlock.seconds')
- %li
- %span.light
- #{t('sherlock.query_time')}
- %strong
- = @transaction.query_duration.round(2)
- = t('sherlock.seconds')
- %li
- %span.light
- #{t('sherlock.finished_at')}:
- %strong
- = time_ago_with_tooltip @transaction.finished_at
diff --git a/app/views/sherlock/transactions/_queries.html.haml b/app/views/sherlock/transactions/_queries.html.haml
deleted file mode 100644
index afe23d61bcd..00000000000
--- a/app/views/sherlock/transactions/_queries.html.haml
+++ /dev/null
@@ -1,24 +0,0 @@
-- if @transaction.queries.empty?
- .nothing-here-block
- = t('sherlock.no_queries')
-- else
- .table-holder
- %table.table#sherlock-queries
- %thead
- %tr
- %th= t('sherlock.time')
- %th= t('sherlock.query')
- %th
- %tbody
- - @transaction.sorted_queries.each do |query|
- %tr
- %td
- = query.duration.round(2)
- = t('sherlock.milliseconds')
- %td
- .code.js-syntax-highlight.sherlock-code
- = highlight("#{query.id}.sql", query.formatted_query, language: 'sql')
- %td
- = link_to(t('sherlock.view'),
- sherlock_transaction_query_path(@transaction, query),
- class: 'gl-button btn btn-sm')
diff --git a/app/views/sherlock/transactions/index.html.haml b/app/views/sherlock/transactions/index.html.haml
deleted file mode 100644
index a2be6cae1e0..00000000000
--- a/app/views/sherlock/transactions/index.html.haml
+++ /dev/null
@@ -1,41 +0,0 @@
-- page_title t('sherlock.title')
-- header_title t('sherlock.title'), sherlock_transactions_path
-
-.row-content-block
- .float-right
- = link_to(destroy_all_sherlock_transactions_path,
- class: 'gl-button btn btn-danger',
- method: :delete) do
- = sprite_icon('remove')
- = t('sherlock.delete_all_transactions')
- .oneline= t('sherlock.introduction')
-
-- if @transactions.empty?
- .nothing-here-block= t('sherlock.no_transactions')
-- else
- .table-holder
- %table.table
- %thead
- %tr
- %th= t('sherlock.type')
- %th= t('sherlock.path')
- %th= t('sherlock.time')
- %th= t('sherlock.queries')
- %th= t('sherlock.finished_at')
- %th
- %tbody
- - @transactions.each do |trans|
- %tr
- %td= trans.type
- %td
- %span{ title: trans.path }
- = truncate(trans.path, length: 70)
- %td
- = trans.duration.round(2)
- = t('sherlock.seconds')
- %td= trans.queries.length
- %td
- = time_ago_with_tooltip trans.finished_at
- %td
- = link_to(sherlock_transaction_path(trans), class: 'gl-button btn btn-sm') do
- = t('sherlock.view')
diff --git a/app/views/sherlock/transactions/show.html.haml b/app/views/sherlock/transactions/show.html.haml
deleted file mode 100644
index 162b14f01e1..00000000000
--- a/app/views/sherlock/transactions/show.html.haml
+++ /dev/null
@@ -1,36 +0,0 @@
-- page_title t('sherlock.title'), t('sherlock.transaction')
-- header_title t('sherlock.title'), sherlock_transactions_path
-
-%ul.nav-links.nav.nav-tabs
- %li.active
- %a{ href: "#tab-general", data: { toggle: "tab" } }
- = t('sherlock.general')
- %li
- %a{ href: "#tab-queries", data: { toggle: "tab" } }
- = t('sherlock.queries')
- %span.badge.badge-pill
- #{@transaction.queries.length}
- %li
- %a{ href: "#tab-file-samples", data: { toggle: "tab" } }
- = t('sherlock.file_samples')
- %span.badge.badge-pill
- #{@transaction.file_samples.length}
-
-.row-content-block
- .float-right
- = link_to(sherlock_transactions_path, class: 'gl-button btn') do
- = sprite_icon('arrow-left', css_class: 'gl-mr-3')
- = t('sherlock.all_transactions')
- .oneline
- = t('sherlock.transaction')
- = @transaction.id
-
-.tab-content
- .tab-pane.active#tab-general
- = render(partial: 'general')
-
- .tab-pane#tab-queries
- = render(partial: 'queries')
-
- .tab-pane#tab-file-samples
- = render(partial: 'file_samples')
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index ca276519758..d5a1f3884c9 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -98,15 +98,15 @@
- unless @user.skype.blank?
= render 'middle_dot_divider' do
= link_to "skype:#{@user.skype}", class: 'gl-hover-text-decoration-none', title: "Skype" do
- = sprite_icon('skype')
+ = sprite_icon('skype', css_class: 'skype-icon')
- unless @user.linkedin.blank?
= render 'middle_dot_divider' do
= link_to linkedin_url(@user), class: 'gl-hover-text-decoration-none', title: "LinkedIn", target: '_blank', rel: 'noopener noreferrer nofollow' do
- = sprite_icon('linkedin')
+ = sprite_icon('linkedin', css_class: 'linkedin-icon')
- unless @user.twitter.blank?
= render 'middle_dot_divider', breakpoint: 'sm' do
= link_to twitter_url(@user), class: 'gl-hover-text-decoration-none', title: "Twitter", target: '_blank', rel: 'noopener noreferrer nofollow' do
- = sprite_icon('twitter')
+ = sprite_icon('twitter', css_class: 'twitter-icon')
- unless @user.website_url.blank?
= render 'middle_dot_divider', stacking: true do
- if Feature.enabled?(:security_auto_fix) && @user.bot?
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index f2961d825a0..14fa6599073 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -129,6 +129,15 @@
:weight: 2
:idempotent:
:tags: []
+- :name: cluster_agent:clusters_agents_delete_expired_events
+ :worker_name: Clusters::Agents::DeleteExpiredEventsWorker
+ :feature_category: :kubernetes_management
+ :has_external_dependencies:
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: container_repository:cleanup_container_repository
:worker_name: CleanupContainerRepositoryWorker
:feature_category: :container_registry
@@ -435,6 +444,15 @@
:weight: 1
:idempotent:
:tags: []
+- :name: cronjob:packages_cleanup_package_registry
+ :worker_name: Packages::CleanupPackageRegistryWorker
+ :feature_category: :package_registry
+ :has_external_dependencies:
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: cronjob:packages_composer_cache_cleanup
:worker_name: Packages::Composer::CacheCleanupWorker
:feature_category: :package_registry
@@ -1357,6 +1375,15 @@
:weight: 1
:idempotent:
:tags: []
+- :name: package_cleanup:packages_cleanup_package_file
+ :worker_name: Packages::CleanupPackageFileWorker
+ :feature_category: :package_registry
+ :has_external_dependencies:
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: package_repositories:packages_debian_generate_distribution
:worker_name: Packages::Debian::GenerateDistributionWorker
:feature_category: :package_registry
@@ -1539,7 +1566,7 @@
:tags: []
- :name: pipeline_creation:ci_external_pull_requests_create_pipeline
:worker_name: Ci::ExternalPullRequests::CreatePipelineWorker
- :feature_category: :pipeline_authoring
+ :feature_category: :continuous_integration
:has_external_dependencies:
:urgency: :high
:resource_boundary: :cpu
@@ -1987,6 +2014,15 @@
:weight: 1
:idempotent: true
:tags: []
+- :name: ci_job_artifacts_expire_project_build_artifacts
+ :worker_name: Ci::JobArtifacts::ExpireProjectBuildArtifactsWorker
+ :feature_category: :build_artifacts
+ :has_external_dependencies:
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: create_commit_signature
:worker_name: CreateCommitSignatureWorker
:feature_category: :source_code_management
@@ -2420,6 +2456,15 @@
:weight: 1
:idempotent: true
:tags: []
+- :name: merge_requests_update_head_pipeline
+ :worker_name: MergeRequests::UpdateHeadPipelineWorker
+ :feature_category: :code_review
+ :has_external_dependencies:
+ :urgency: :high
+ :resource_boundary: :cpu
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: metrics_dashboard_prune_old_annotations
:worker_name: Metrics::Dashboard::PruneOldAnnotationsWorker
:feature_category: :metrics
@@ -2909,7 +2954,7 @@
:tags: []
- :name: update_external_pull_requests
:worker_name: UpdateExternalPullRequestsWorker
- :feature_category: :source_code_management
+ :feature_category: :continuous_integration
:has_external_dependencies:
:urgency: :low
:resource_boundary: :unknown
diff --git a/app/workers/ci/build_finished_worker.rb b/app/workers/ci/build_finished_worker.rb
index aa12bdb009e..56cfaa7e674 100644
--- a/app/workers/ci/build_finished_worker.rb
+++ b/app/workers/ci/build_finished_worker.rb
@@ -40,7 +40,7 @@ module Ci
BuildHooksWorker.perform_async(build.id)
ChatNotificationWorker.perform_async(build.id) if build.pipeline.chat?
- if build.failed?
+ if build.failed? && !build.auto_retry_expected?
::Ci::MergeRequests::AddTodoWhenBuildFailsWorker.perform_async(build.id)
end
diff --git a/app/workers/ci/external_pull_requests/create_pipeline_worker.rb b/app/workers/ci/external_pull_requests/create_pipeline_worker.rb
index 211ea1f2990..334ff099ea2 100644
--- a/app/workers/ci/external_pull_requests/create_pipeline_worker.rb
+++ b/app/workers/ci/external_pull_requests/create_pipeline_worker.rb
@@ -7,7 +7,7 @@ module Ci
data_consistency :always
queue_namespace :pipeline_creation
- feature_category :pipeline_authoring
+ feature_category :continuous_integration
urgency :high
worker_resource_boundary :cpu
diff --git a/app/workers/ci/job_artifacts/expire_project_build_artifacts_worker.rb b/app/workers/ci/job_artifacts/expire_project_build_artifacts_worker.rb
new file mode 100644
index 00000000000..299b9bbe3d3
--- /dev/null
+++ b/app/workers/ci/job_artifacts/expire_project_build_artifacts_worker.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module Ci
+ module JobArtifacts
+ class ExpireProjectBuildArtifactsWorker
+ include ApplicationWorker
+
+ data_consistency :always
+
+ feature_category :build_artifacts
+ idempotent!
+
+ def perform(project_id)
+ return unless Project.id_in(project_id).exists?
+
+ ExpireProjectBuildArtifactsService.new(project_id, Time.current).execute
+ end
+ end
+ end
+end
diff --git a/app/workers/clusters/agents/delete_expired_events_worker.rb b/app/workers/clusters/agents/delete_expired_events_worker.rb
new file mode 100644
index 00000000000..3414365a243
--- /dev/null
+++ b/app/workers/clusters/agents/delete_expired_events_worker.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Clusters
+ module Agents
+ class DeleteExpiredEventsWorker
+ include ApplicationWorker
+ include ClusterAgentQueue
+
+ deduplicate :until_executed, including_scheduled: true
+ idempotent!
+
+ data_consistency :always
+
+ def perform(agent_id)
+ if agent = Clusters::Agent.find_by_id(agent_id)
+ Clusters::Agents::DeleteExpiredEventsService.new(agent).execute
+ end
+ end
+ end
+ end
+end
diff --git a/app/workers/concerns/application_worker.rb b/app/workers/concerns/application_worker.rb
index d0b09c15289..83261d9e42e 100644
--- a/app/workers/concerns/application_worker.rb
+++ b/app/workers/concerns/application_worker.rb
@@ -189,12 +189,8 @@ module ApplicationWorker
schedule_at = bulk_schedule_at
end
- if Feature.enabled?(:sidekiq_push_bulk_in_batches)
- in_safe_limit_batches(args_list, schedule_at) do |args_batch, schedule_at_for_batch|
- Sidekiq::Client.push_bulk('class' => self, 'args' => args_batch, 'at' => schedule_at_for_batch)
- end
- else
- Sidekiq::Client.push_bulk('class' => self, 'args' => args_list, 'at' => schedule_at)
+ in_safe_limit_batches(args_list, schedule_at) do |args_batch, schedule_at_for_batch|
+ Sidekiq::Client.push_bulk('class' => self, 'args' => args_batch, 'at' => schedule_at_for_batch)
end
end
@@ -207,12 +203,8 @@ module ApplicationWorker
private
def do_push_bulk(args_list)
- if Feature.enabled?(:sidekiq_push_bulk_in_batches)
- in_safe_limit_batches(args_list) do |args_batch, _|
- Sidekiq::Client.push_bulk('class' => self, 'args' => args_batch)
- end
- else
- Sidekiq::Client.push_bulk('class' => self, 'args' => args_list)
+ in_safe_limit_batches(args_list) do |args_batch, _|
+ Sidekiq::Client.push_bulk('class' => self, 'args' => args_batch)
end
end
diff --git a/app/workers/concerns/cluster_agent_queue.rb b/app/workers/concerns/cluster_agent_queue.rb
new file mode 100644
index 00000000000..68de7cca135
--- /dev/null
+++ b/app/workers/concerns/cluster_agent_queue.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+module ClusterAgentQueue
+ extend ActiveSupport::Concern
+
+ included do
+ queue_namespace :cluster_agent
+ feature_category :kubernetes_management
+ end
+end
diff --git a/app/workers/concerns/dependency_proxy/cleanup_worker.rb b/app/workers/concerns/dependency_proxy/cleanup_worker.rb
deleted file mode 100644
index b668634f233..00000000000
--- a/app/workers/concerns/dependency_proxy/cleanup_worker.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-# frozen_string_literal: true
-
-module DependencyProxy
- module CleanupWorker
- extend ActiveSupport::Concern
- include Gitlab::Utils::StrongMemoize
-
- def perform_work
- return unless artifact
-
- log_metadata(artifact)
-
- artifact.destroy!
- rescue StandardError
- artifact&.error!
- end
-
- def max_running_jobs
- ::Gitlab::CurrentSettings.dependency_proxy_ttl_group_policy_worker_capacity
- end
-
- def remaining_work_count
- expired_artifacts.limit(max_running_jobs + 1).count
- end
-
- private
-
- def model
- raise NotImplementedError
- end
-
- def log_metadata
- raise NotImplementedError
- end
-
- def log_cleanup_item
- raise NotImplementedError
- end
-
- def artifact
- strong_memoize(:artifact) do
- model.transaction do
- to_delete = next_item
-
- if to_delete
- to_delete.processing!
- log_cleanup_item(to_delete)
- end
-
- to_delete
- end
- end
- end
-
- def expired_artifacts
- model.expired
- end
-
- def next_item
- expired_artifacts.lock_next_by(:updated_at).first
- end
- end
-end
diff --git a/app/workers/concerns/dependency_proxy/expireable.rb b/app/workers/concerns/dependency_proxy/expireable.rb
index 9650ac85c6c..7e37db36bef 100644
--- a/app/workers/concerns/dependency_proxy/expireable.rb
+++ b/app/workers/concerns/dependency_proxy/expireable.rb
@@ -10,7 +10,7 @@ module DependencyProxy
def expire_artifacts(collection)
collection.each_batch(of: UPDATE_BATCH_SIZE) do |batch|
- batch.update_all(status: :expired)
+ batch.update_all(status: :pending_destruction)
end
end
end
diff --git a/app/workers/concerns/packages/cleanup_artifact_worker.rb b/app/workers/concerns/packages/cleanup_artifact_worker.rb
new file mode 100644
index 00000000000..db6c7330ea3
--- /dev/null
+++ b/app/workers/concerns/packages/cleanup_artifact_worker.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+module Packages
+ module CleanupArtifactWorker
+ extend ActiveSupport::Concern
+ include LimitedCapacity::Worker
+ include Gitlab::Utils::StrongMemoize
+
+ def perform_work
+ return unless artifact
+
+ log_metadata(artifact)
+
+ artifact.destroy!
+ rescue StandardError
+ artifact&.error!
+ end
+
+ def remaining_work_count
+ artifacts_pending_destruction.limit(max_running_jobs + 1).count
+ end
+
+ private
+
+ def model
+ raise NotImplementedError
+ end
+
+ def log_metadata
+ raise NotImplementedError
+ end
+
+ def log_cleanup_item
+ raise NotImplementedError
+ end
+
+ def artifact
+ strong_memoize(:artifact) do
+ model.transaction do
+ to_delete = next_item
+
+ if to_delete
+ to_delete.processing!
+ log_cleanup_item(to_delete)
+ end
+
+ to_delete
+ end
+ end
+ end
+
+ def artifacts_pending_destruction
+ model.pending_destruction
+ end
+
+ def next_item
+ model.next_pending_destruction(order_by: :updated_at)
+ end
+ end
+end
diff --git a/app/workers/dependency_proxy/cleanup_blob_worker.rb b/app/workers/dependency_proxy/cleanup_blob_worker.rb
index 054bc5854a3..eab536cd191 100644
--- a/app/workers/dependency_proxy/cleanup_blob_worker.rb
+++ b/app/workers/dependency_proxy/cleanup_blob_worker.rb
@@ -3,9 +3,8 @@
module DependencyProxy
class CleanupBlobWorker
include ApplicationWorker
- include LimitedCapacity::Worker
+ include ::Packages::CleanupArtifactWorker
include Gitlab::Utils::StrongMemoize
- include DependencyProxy::CleanupWorker
data_consistency :always
@@ -17,6 +16,10 @@ module DependencyProxy
worker_resource_boundary :unknown
idempotent!
+ def max_running_jobs
+ ::Gitlab::CurrentSettings.dependency_proxy_ttl_group_policy_worker_capacity
+ end
+
private
def model
diff --git a/app/workers/dependency_proxy/cleanup_dependency_proxy_worker.rb b/app/workers/dependency_proxy/cleanup_dependency_proxy_worker.rb
index d77c782267a..6a958d6e9d7 100644
--- a/app/workers/dependency_proxy/cleanup_dependency_proxy_worker.rb
+++ b/app/workers/dependency_proxy/cleanup_dependency_proxy_worker.rb
@@ -11,8 +11,8 @@ module DependencyProxy
feature_category :dependency_proxy
def perform
- enqueue_blob_cleanup_job if DependencyProxy::Blob.expired.any?
- enqueue_manifest_cleanup_job if DependencyProxy::Manifest.expired.any?
+ enqueue_blob_cleanup_job if DependencyProxy::Blob.pending_destruction.any?
+ enqueue_manifest_cleanup_job if DependencyProxy::Manifest.pending_destruction.any?
end
private
diff --git a/app/workers/dependency_proxy/cleanup_manifest_worker.rb b/app/workers/dependency_proxy/cleanup_manifest_worker.rb
index 1186efa2034..4445ee32e6d 100644
--- a/app/workers/dependency_proxy/cleanup_manifest_worker.rb
+++ b/app/workers/dependency_proxy/cleanup_manifest_worker.rb
@@ -3,9 +3,8 @@
module DependencyProxy
class CleanupManifestWorker
include ApplicationWorker
- include LimitedCapacity::Worker
+ include ::Packages::CleanupArtifactWorker
include Gitlab::Utils::StrongMemoize
- include DependencyProxy::CleanupWorker
data_consistency :always
@@ -17,6 +16,10 @@ module DependencyProxy
worker_resource_boundary :unknown
idempotent!
+ def max_running_jobs
+ ::Gitlab::CurrentSettings.dependency_proxy_ttl_group_policy_worker_capacity
+ end
+
private
def model
diff --git a/app/workers/dependency_proxy/image_ttl_group_policy_worker.rb b/app/workers/dependency_proxy/image_ttl_group_policy_worker.rb
index 3de2364fc71..89099ab6398 100644
--- a/app/workers/dependency_proxy/image_ttl_group_policy_worker.rb
+++ b/app/workers/dependency_proxy/image_ttl_group_policy_worker.rb
@@ -26,8 +26,8 @@ module DependencyProxy
def log_counts
use_replica_if_available do
- expired_blob_count = DependencyProxy::Blob.expired.count
- expired_manifest_count = DependencyProxy::Manifest.expired.count
+ expired_blob_count = DependencyProxy::Blob.pending_destruction.count
+ expired_manifest_count = DependencyProxy::Manifest.pending_destruction.count
processing_blob_count = DependencyProxy::Blob.processing.count
processing_manifest_count = DependencyProxy::Manifest.processing.count
error_blob_count = DependencyProxy::Blob.error.count
diff --git a/app/workers/email_receiver_worker.rb b/app/workers/email_receiver_worker.rb
index 321d492f0f3..54689df4d7b 100644
--- a/app/workers/email_receiver_worker.rb
+++ b/app/workers/email_receiver_worker.rb
@@ -90,37 +90,6 @@ class EmailReceiverWorker # rubocop:disable Scalability/IdempotentWorker
def handle_failure(error)
return unless raw.present?
- can_retry = false
- reason =
- case error
- when Gitlab::Email::UnknownIncomingEmail
- s_("EmailError|We couldn't figure out what the email is for. Please create your issue or comment through the web interface.")
- when Gitlab::Email::SentNotificationNotFoundError
- s_("EmailError|We couldn't figure out what the email is in reply to. Please create your comment through the web interface.")
- when Gitlab::Email::ProjectNotFound
- s_("EmailError|We couldn't find the project. Please check if there's any typo.")
- when Gitlab::Email::EmptyEmailError
- can_retry = true
- s_("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.")
- when Gitlab::Email::UserNotFoundError
- s_("EmailError|We couldn't figure out what user corresponds to the email. Please create your comment through the web interface.")
- when Gitlab::Email::UserBlockedError
- s_("EmailError|Your account has been blocked. If you believe this is in error, contact a staff member.")
- when Gitlab::Email::UserNotAuthorizedError
- s_("EmailError|You are not allowed to perform this action. If you believe this is in error, contact a staff member.")
- when Gitlab::Email::NoteableNotFoundError
- s_("EmailError|The thread you are replying to no longer exists, perhaps it was deleted? If you believe this is in error, contact a staff member.")
- when Gitlab::Email::InvalidAttachment
- error.message
- when Gitlab::Email::InvalidRecordError
- can_retry = true
- error.message
- end
-
- if reason
- receiver.mail.body = nil
-
- EmailRejectionMailer.rejection(reason, receiver.mail.encoded, can_retry).deliver_later
- end
+ Gitlab::Email::FailureHandler.handle(receiver, error)
end
end
diff --git a/app/workers/expire_build_artifacts_worker.rb b/app/workers/expire_build_artifacts_worker.rb
index 295703cc1c3..9edff55b838 100644
--- a/app/workers/expire_build_artifacts_worker.rb
+++ b/app/workers/expire_build_artifacts_worker.rb
@@ -13,8 +13,8 @@ class ExpireBuildArtifactsWorker # rubocop:disable Scalability/IdempotentWorker
feature_category :build_artifacts
def perform
- service = Ci::JobArtifacts::DestroyAllExpiredService.new
- artifacts_count = service.execute
+ artifacts_count = Ci::JobArtifacts::DestroyAllExpiredService.new.execute
+
log_extra_metadata_on_done(:destroyed_job_artifacts_count, artifacts_count)
end
end
diff --git a/app/workers/loose_foreign_keys/cleanup_worker.rb b/app/workers/loose_foreign_keys/cleanup_worker.rb
index b4565dbf624..c3492fed77b 100644
--- a/app/workers/loose_foreign_keys/cleanup_worker.rb
+++ b/app/workers/loose_foreign_keys/cleanup_worker.rb
@@ -6,6 +6,7 @@ module LooseForeignKeys
include Gitlab::ExclusiveLeaseHelpers
include CronjobQueue # rubocop: disable Scalability/CronWorkerContext
+ sidekiq_options retry: false
feature_category :sharding
data_consistency :always
idempotent!
@@ -13,13 +14,30 @@ module LooseForeignKeys
def perform
return if Feature.disabled?(:loose_foreign_key_cleanup, default_enabled: :yaml)
- ttl = ModificationTracker::MAX_RUNTIME + 1.minute
- in_lock(self.class.name.underscore, ttl: ttl, retries: 0) do
- # TODO: Iterate over the connections
- # https://gitlab.com/gitlab-org/gitlab/-/issues/341513
- stats = ProcessDeletedRecordsService.new(connection: ApplicationRecord.connection).execute
+ in_lock(self.class.name.underscore, ttl: ModificationTracker::MAX_RUNTIME, retries: 0) do
+ stats = {}
+
+ connection_name, base_model = current_connection_name_and_base_model
+
+ Gitlab::Database::SharedModel.using_connection(base_model.connection) do
+ stats = ProcessDeletedRecordsService.new(connection: base_model.connection).execute
+ stats[:connection] = connection_name
+ end
+
log_extra_metadata_on_done(:stats, stats)
end
end
+
+ private
+
+ # Rotate the databases every minute
+ #
+ # If one DB is configured: every minute use the configured DB
+ # If two DBs are configured (Main, CI): minute 1 -> Main, minute 2 -> CI
+ def current_connection_name_and_base_model
+ minutes_since_epoch = Time.current.to_i / 60
+ connections_with_name = Gitlab::Database.database_base_models.to_a # this will never be empty
+ connections_with_name[minutes_since_epoch % connections_with_name.count]
+ end
end
end
diff --git a/app/workers/merge_requests/update_head_pipeline_worker.rb b/app/workers/merge_requests/update_head_pipeline_worker.rb
new file mode 100644
index 00000000000..c8dc9d1f7c8
--- /dev/null
+++ b/app/workers/merge_requests/update_head_pipeline_worker.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module MergeRequests
+ class UpdateHeadPipelineWorker
+ include ApplicationWorker
+ include Gitlab::EventStore::Subscriber
+
+ feature_category :code_review
+ urgency :high
+ worker_resource_boundary :cpu
+ data_consistency :always
+
+ idempotent!
+
+ def handle_event(event)
+ Ci::Pipeline.find_by_id(event.data[:pipeline_id]).try do |pipeline|
+ pipeline.all_merge_requests.opened.each do |merge_request|
+ UpdateHeadPipelineForMergeRequestWorker.perform_async(merge_request.id)
+ end
+ end
+ end
+ end
+end
diff --git a/app/workers/metrics/dashboard/sync_dashboards_worker.rb b/app/workers/metrics/dashboard/sync_dashboards_worker.rb
index fe8694582c4..63ca27d9c44 100644
--- a/app/workers/metrics/dashboard/sync_dashboards_worker.rb
+++ b/app/workers/metrics/dashboard/sync_dashboards_worker.rb
@@ -18,7 +18,7 @@ module Metrics
dashboard_paths = ::Gitlab::Metrics::Dashboard::RepoDashboardFinder.list_dashboards(project)
dashboard_paths.each do |dashboard_path|
- ::Gitlab::Metrics::Dashboard::Importer.new(dashboard_path, project).execute!
+ ::Gitlab::Metrics::Dashboard::Importer.new(dashboard_path, project).execute
end
end
end
diff --git a/app/workers/packages/cleanup_package_file_worker.rb b/app/workers/packages/cleanup_package_file_worker.rb
new file mode 100644
index 00000000000..cb2b2a12c5e
--- /dev/null
+++ b/app/workers/packages/cleanup_package_file_worker.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+module Packages
+ class CleanupPackageFileWorker
+ include ApplicationWorker
+ include ::Packages::CleanupArtifactWorker
+ include Gitlab::Utils::StrongMemoize
+
+ data_consistency :always
+ queue_namespace :package_cleanup
+ feature_category :package_registry
+ urgency :low
+ worker_resource_boundary :unknown
+ idempotent!
+
+ def max_running_jobs
+ ::Gitlab::CurrentSettings.packages_cleanup_package_file_worker_capacity
+ end
+
+ private
+
+ def model
+ Packages::PackageFile
+ end
+
+ def next_item
+ model.next_pending_destruction
+ end
+
+ def log_metadata(package_file)
+ log_extra_metadata_on_done(:package_file_id, package_file.id)
+ log_extra_metadata_on_done(:package_id, package_file.package_id)
+ end
+
+ def log_cleanup_item(package_file)
+ logger.info(
+ structured_payload(
+ package_id: package_file.package_id,
+ package_file_id: package_file.id
+ )
+ )
+ end
+ end
+end
diff --git a/app/workers/packages/cleanup_package_registry_worker.rb b/app/workers/packages/cleanup_package_registry_worker.rb
new file mode 100644
index 00000000000..a849e055b64
--- /dev/null
+++ b/app/workers/packages/cleanup_package_registry_worker.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module Packages
+ class CleanupPackageRegistryWorker
+ include ApplicationWorker
+ include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
+
+ data_consistency :always
+ idempotent!
+
+ feature_category :package_registry
+
+ def perform
+ enqueue_package_file_cleanup_job if Packages::PackageFile.pending_destruction.exists?
+
+ log_counts
+ end
+
+ private
+
+ def enqueue_package_file_cleanup_job
+ Packages::CleanupPackageFileWorker.perform_with_capacity
+ end
+
+ def log_counts
+ use_replica_if_available do
+ pending_destruction_package_files_count = Packages::PackageFile.pending_destruction.count
+ processing_package_files_count = Packages::PackageFile.processing.count
+ error_package_files_count = Packages::PackageFile.error.count
+
+ log_extra_metadata_on_done(:pending_destruction_package_files_count, pending_destruction_package_files_count)
+ log_extra_metadata_on_done(:processing_package_files_count, processing_package_files_count)
+ log_extra_metadata_on_done(:error_package_files_count, error_package_files_count)
+ end
+ end
+
+ def use_replica_if_available(&block)
+ ::Gitlab::Database::LoadBalancing::Session.current.use_replicas_for_read_queries(&block)
+ end
+ end
+end
diff --git a/app/workers/pages_update_configuration_worker.rb b/app/workers/pages_update_configuration_worker.rb
index 3dfd82ed517..9c58b40e098 100644
--- a/app/workers/pages_update_configuration_worker.rb
+++ b/app/workers/pages_update_configuration_worker.rb
@@ -1,25 +1,17 @@
# frozen_string_literal: true
+# TODO: remove this in 14.7 https://gitlab.com/gitlab-org/gitlab/-/issues/348582
class PagesUpdateConfigurationWorker
include ApplicationWorker
data_consistency :always
- sidekiq_options retry: 3
+ sidekiq_options retry: 1
idempotent!
feature_category :pages
- def self.perform_async(*args)
- return unless ::Settings.pages.local_store.enabled
-
- super(*args)
- end
-
- def perform(project_id)
- project = Project.find_by_id(project_id)
- return unless project
-
- Projects::UpdatePagesConfigurationService.new(project).execute
+ def perform(_project_id)
+ # Do nothing
end
end
diff --git a/app/workers/pages_worker.rb b/app/workers/pages_worker.rb
index cceafbc7d2d..3aff4b42629 100644
--- a/app/workers/pages_worker.rb
+++ b/app/workers/pages_worker.rb
@@ -16,14 +16,7 @@ class PagesWorker # rubocop:disable Scalability/IdempotentWorker
def deploy(build_id)
build = Ci::Build.find_by_id(build_id)
- update_contents = Projects::UpdatePagesService.new(build.project, build).execute
- if update_contents[:status] == :success
- Projects::UpdatePagesConfigurationService.new(build.project).execute
- end
- end
- def remove(namespace_path, project_path)
- full_path = File.join(Settings.pages.path, namespace_path, project_path)
- FileUtils.rm_r(full_path, force: true)
+ Projects::UpdatePagesService.new(build.project, build).execute
end
end
diff --git a/app/workers/update_external_pull_requests_worker.rb b/app/workers/update_external_pull_requests_worker.rb
index 2a319a7f6f9..4b3cda6b8f3 100644
--- a/app/workers/update_external_pull_requests_worker.rb
+++ b/app/workers/update_external_pull_requests_worker.rb
@@ -7,7 +7,7 @@ class UpdateExternalPullRequestsWorker # rubocop:disable Scalability/IdempotentW
sidekiq_options retry: 3
- feature_category :source_code_management
+ feature_category :continuous_integration
weight 3
loggable_arguments 2
diff --git a/app/workers/update_head_pipeline_for_merge_request_worker.rb b/app/workers/update_head_pipeline_for_merge_request_worker.rb
index 61fe278e016..3a2447b2108 100644
--- a/app/workers/update_head_pipeline_for_merge_request_worker.rb
+++ b/app/workers/update_head_pipeline_for_merge_request_worker.rb
@@ -8,8 +8,10 @@ class UpdateHeadPipelineForMergeRequestWorker
sidekiq_options retry: 3
include PipelineQueue
+ # NOTE: this worker belongs to :code_review since there is no CI logic.
queue_namespace :pipeline_processing
feature_category :continuous_integration
+
urgency :high
worker_resource_boundary :cpu
diff --git a/app/workers/web_hook_worker.rb b/app/workers/web_hook_worker.rb
index 5b4567dde29..952ac94d5e6 100644
--- a/app/workers/web_hook_worker.rb
+++ b/app/workers/web_hook_worker.rb
@@ -13,11 +13,21 @@ class WebHookWorker
worker_has_external_dependencies!
- def perform(hook_id, data, hook_name)
+ # Webhook recursion detection properties are 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
data = data.with_indifferent_access
+
+ # 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.
+ recursion_detection_uuid = data.delete(:_gitlab_recursion_detection_request_uuid)
+ Gitlab::WebHooks::RecursionDetection.set_request_uuid(recursion_detection_uuid)
+
WebHookService.new(hook, data, hook_name, jid).execute
end
end
diff --git a/config/application.rb b/config/application.rb
index f64e5c998eb..68b68c1c886 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -68,6 +68,9 @@ module Gitlab
require_dependency Rails.root.join('lib/gitlab/middleware/rack_multipart_tempfile_factory')
require_dependency Rails.root.join('lib/gitlab/runtime')
require_dependency Rails.root.join('lib/gitlab/patch/legacy_database_config')
+ require_dependency Rails.root.join('lib/gitlab/exceptions_app')
+
+ config.exceptions_app = Gitlab::ExceptionsApp.new(Rails.public_path)
# To be removed in 15.0
# This preload is needed to convert legacy `database.yml`
diff --git a/config/environments/production.rb b/config/environments/production.rb
index f8964479e60..b56aadb8b11 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -36,7 +36,9 @@ Rails.application.configure do
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
- # See everything in the log (default is :info)
+ # Include generic and useful information about system operation, but avoid logging too much
+ # information to avoid inadvertent exposure of personally identifiable information (PII).
+ # Note: This configuration does not affect the log level of `Gitlab::Logger` and its subclasses.
config.log_level = :info
# Suppress 'Rendered template ...' messages in the log
diff --git a/config/feature_categories.yml b/config/feature_categories.yml
index edc6541db8c..00b213d307b 100644
--- a/config/feature_categories.yml
+++ b/config/feature_categories.yml
@@ -7,7 +7,6 @@
# PLEASE DO NOT EDIT THIS FILE MANUALLY.
#
---
-- accessibility_testing
- advanced_deployments
- api_security
- attack_emulation
@@ -104,6 +103,8 @@
- review_apps
- runbooks
- runner
+- runner_fleet
+- runner_saas
- scalability
- secret_detection
- secrets_management
@@ -121,7 +122,6 @@
- synthetic_monitoring
- team_planning
- tracing
-- usability_testing
- usage_ping
- users
- utilization
diff --git a/config/feature_flags/development/admin_deploy_keys_vue.yml b/config/feature_flags/development/admin_deploy_keys_vue.yml
deleted file mode 100644
index 21e1b501d7a..00000000000
--- a/config/feature_flags/development/admin_deploy_keys_vue.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: admin_deploy_keys_vue
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73580
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/344855
-milestone: '14.5'
-type: development
-group: group::access
-default_enabled: true
diff --git a/config/feature_flags/development/bulk_expire_project_artifacts.yml b/config/feature_flags/development/bulk_expire_project_artifacts.yml
new file mode 100644
index 00000000000..609f87847fa
--- /dev/null
+++ b/config/feature_flags/development/bulk_expire_project_artifacts.yml
@@ -0,0 +1,8 @@
+---
+name: bulk_expire_project_artifacts
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75488
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/347405
+milestone: '14.6'
+type: development
+group: group::testing
+default_enabled: true
diff --git a/config/feature_flags/development/cached_mr_widget.yml b/config/feature_flags/development/cached_mr_widget.yml
deleted file mode 100644
index 0a73eafe57e..00000000000
--- a/config/feature_flags/development/cached_mr_widget.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: cached_mr_widget
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61584
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/330803
-milestone: '13.12'
-type: development
-group: group::code review
-default_enabled: false
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
new file mode 100644
index 00000000000..0b81a06c593
--- /dev/null
+++ b/config/feature_flags/development/chat_notification_deployment_protected_branch_filter.yml
@@ -0,0 +1,8 @@
+---
+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_archived_build_trace_checksum.yml b/config/feature_flags/development/ci_archived_build_trace_checksum.yml
deleted file mode 100644
index 95e641e0efa..00000000000
--- a/config/feature_flags/development/ci_archived_build_trace_checksum.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: ci_archived_build_trace_checksum
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70072
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340737
-milestone: '14.4'
-type: development
-group: group::pipeline execution
-default_enabled: false
diff --git a/config/feature_flags/development/ci_artifact_fast_removal_large_loop_limit.yml b/config/feature_flags/development/ci_artifact_fast_removal_large_loop_limit.yml
new file mode 100644
index 00000000000..bfb036bcc00
--- /dev/null
+++ b/config/feature_flags/development/ci_artifact_fast_removal_large_loop_limit.yml
@@ -0,0 +1,8 @@
+---
+name: ci_artifact_fast_removal_large_loop_limit
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76504
+rollout_issue_url:
+milestone: '14.6'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/ci_decompose_for_namespace_monthly_usage_query.yml b/config/feature_flags/development/ci_decompose_for_namespace_monthly_usage_query.yml
new file mode 100644
index 00000000000..7b90c3e19b2
--- /dev/null
+++ b/config/feature_flags/development/ci_decompose_for_namespace_monthly_usage_query.yml
@@ -0,0 +1,8 @@
+---
+name: ci_decompose_for_namespace_monthly_usage_query
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77952
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350146
+milestone: '14.7'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/ci_destroy_all_expired_service.yml b/config/feature_flags/development/ci_destroy_all_expired_service.yml
new file mode 100644
index 00000000000..34c94529f99
--- /dev/null
+++ b/config/feature_flags/development/ci_destroy_all_expired_service.yml
@@ -0,0 +1,8 @@
+---
+name: ci_destroy_all_expired_service
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76504
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348786
+milestone: '14.6'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/ci_find_runners_by_ci_mirrors.yml b/config/feature_flags/development/ci_find_runners_by_ci_mirrors.yml
new file mode 100644
index 00000000000..337e6b11408
--- /dev/null
+++ b/config/feature_flags/development/ci_find_runners_by_ci_mirrors.yml
@@ -0,0 +1,8 @@
+---
+name: ci_find_runners_by_ci_mirrors
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74900
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/347226
+milestone: '14.7'
+type: development
+group: group::runner
+default_enabled: false
diff --git a/config/feature_flags/development/ci_owned_runners_cross_joins_fix.yml b/config/feature_flags/development/ci_owned_runners_cross_joins_fix.yml
new file mode 100644
index 00000000000..aacb188ba35
--- /dev/null
+++ b/config/feature_flags/development/ci_owned_runners_cross_joins_fix.yml
@@ -0,0 +1,8 @@
+---
+name: ci_owned_runners_cross_joins_fix
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78216
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350322
+milestone: '14.8'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/ci_retry_downstream_pipeline.yml b/config/feature_flags/development/ci_retry_downstream_pipeline.yml
index 0eac0330188..69a2821c86e 100644
--- a/config/feature_flags/development/ci_retry_downstream_pipeline.yml
+++ b/config/feature_flags/development/ci_retry_downstream_pipeline.yml
@@ -2,7 +2,7 @@
name: ci_retry_downstream_pipeline
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76115
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/347424
-milestone: '14.16'
+milestone: '14.6'
type: development
group: group::pipeline authoring
default_enabled: false
diff --git a/config/feature_flags/development/ci_skip_legacy_extra_minutes_recalculation.yml b/config/feature_flags/development/ci_skip_legacy_extra_minutes_recalculation.yml
new file mode 100644
index 00000000000..2b10b124c54
--- /dev/null
+++ b/config/feature_flags/development/ci_skip_legacy_extra_minutes_recalculation.yml
@@ -0,0 +1,8 @@
+---
+name: ci_skip_legacy_extra_minutes_recalculation
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78476
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/341730
+milestone: '14.8'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/ci_skip_require_credit_card_for_addon_ci_minutes.yml b/config/feature_flags/development/ci_skip_require_credit_card_for_addon_ci_minutes.yml
new file mode 100644
index 00000000000..e9c355bd119
--- /dev/null
+++ b/config/feature_flags/development/ci_skip_require_credit_card_for_addon_ci_minutes.yml
@@ -0,0 +1,8 @@
+---
+name: ci_skip_require_credit_card_for_addon_ci_minutes
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77829
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/349841
+milestone: '14.7'
+type: development
+group: group::fulfillment
+default_enabled: false
diff --git a/config/feature_flags/development/ci_store_trace_outside_transaction.yml b/config/feature_flags/development/ci_store_trace_outside_transaction.yml
deleted file mode 100644
index 1be425c6bbf..00000000000
--- a/config/feature_flags/development/ci_store_trace_outside_transaction.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: ci_store_trace_outside_transaction
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66203
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/336280
-milestone: '14.5'
-type: development
-group: group::pipeline execution
-default_enabled: true
diff --git a/config/feature_flags/development/ci_use_variables_builder_definitions.yml b/config/feature_flags/development/ci_use_variables_builder_definitions.yml
new file mode 100644
index 00000000000..c01e4e9958e
--- /dev/null
+++ b/config/feature_flags/development/ci_use_variables_builder_definitions.yml
@@ -0,0 +1,8 @@
+---
+name: ci_use_variables_builder_definitions
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75254
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/349049
+milestone: '14.7'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/container_registry_cdn_redirect.yml b/config/feature_flags/development/container_registry_cdn_redirect.yml
new file mode 100644
index 00000000000..5cc2bf7a342
--- /dev/null
+++ b/config/feature_flags/development/container_registry_cdn_redirect.yml
@@ -0,0 +1,8 @@
+---
+name: container_registry_cdn_redirect
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77705
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/349717
+milestone: '14.7'
+type: development
+group: group::package
+default_enabled: false
diff --git a/config/feature_flags/development/create_deployment_in_separate_transaction.yml b/config/feature_flags/development/create_deployment_in_separate_transaction.yml
index 7d07a932966..96cda772beb 100644
--- a/config/feature_flags/development/create_deployment_in_separate_transaction.yml
+++ b/config/feature_flags/development/create_deployment_in_separate_transaction.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346879
milestone: '14.6'
type: development
group: group::release
-default_enabled: false
+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
index 3fbf929ca2e..0d6ea8b2784 100644
--- a/config/feature_flags/development/create_project_namespace_on_project_create.yml
+++ b/config/feature_flags/development/create_project_namespace_on_project_create.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/344954
milestone: '14.5'
type: development
group: group::workspace
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/custom_preloader_for_deployments.yml b/config/feature_flags/development/custom_preloader_for_deployments.yml
new file mode 100644
index 00000000000..f8abcb4ba4a
--- /dev/null
+++ b/config/feature_flags/development/custom_preloader_for_deployments.yml
@@ -0,0 +1,8 @@
+---
+name: custom_preloader_for_deployments
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75767
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348289
+milestone: '14.7'
+type: development
+group: group::release
+default_enabled: false
diff --git a/config/feature_flags/development/dast_api_scanner.yml b/config/feature_flags/development/dast_api_scanner.yml
new file mode 100644
index 00000000000..8299004fecb
--- /dev/null
+++ b/config/feature_flags/development/dast_api_scanner.yml
@@ -0,0 +1,8 @@
+---
+name: dast_api_scanner
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73564
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/345837
+milestone: '14.7'
+type: development
+group: group::dynamic analysis
+default_enabled: false
diff --git a/config/feature_flags/development/dast_view_scans.yml b/config/feature_flags/development/dast_view_scans.yml
deleted file mode 100644
index 736fcb01091..00000000000
--- a/config/feature_flags/development/dast_view_scans.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: dast_view_scans
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69571
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340388
-milestone: '14.3'
-type: development
-group: group::dynamic analysis
-default_enabled: true
diff --git a/config/feature_flags/development/datadog_integration_logs_collection.yml b/config/feature_flags/development/datadog_integration_logs_collection.yml
new file mode 100644
index 00000000000..5bd155eece9
--- /dev/null
+++ b/config/feature_flags/development/datadog_integration_logs_collection.yml
@@ -0,0 +1,8 @@
+---
+name: datadog_integration_logs_collection
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74725
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346339
+milestone: '14.8'
+type: development
+group: group::integrations
+default_enabled: false
diff --git a/config/feature_flags/development/delete_branch_confirmation_modals.yml b/config/feature_flags/development/delete_branch_confirmation_modals.yml
deleted file mode 100644
index 9959d8fe8e2..00000000000
--- a/config/feature_flags/development/delete_branch_confirmation_modals.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: delete_branch_confirmation_modals
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56782
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/329052
-milestone: '14.3'
-type: development
-group: group::expansion
-default_enabled: true
diff --git a/config/feature_flags/development/dependency_proxy_workhorse.yml b/config/feature_flags/development/dependency_proxy_workhorse.yml
deleted file mode 100644
index a14f38fa001..00000000000
--- a/config/feature_flags/development/dependency_proxy_workhorse.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: dependency_proxy_workhorse
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68157
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339639
-milestone: '14.3'
-type: development
-group: group::source code
-default_enabled: true
diff --git a/config/feature_flags/development/deployments_archive.yml b/config/feature_flags/development/deployments_archive.yml
deleted file mode 100644
index 8129d6d4af8..00000000000
--- a/config/feature_flags/development/deployments_archive.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: deployments_archive
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73628
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/345027
-milestone: '14.5'
-type: development
-group: group::release
-default_enabled: true
diff --git a/config/feature_flags/development/expire_job_and_pipeline_cache_synchronously.yml b/config/feature_flags/development/expire_job_and_pipeline_cache_synchronously.yml
deleted file mode 100644
index dda23cb641a..00000000000
--- a/config/feature_flags/development/expire_job_and_pipeline_cache_synchronously.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: expire_job_and_pipeline_cache_synchronously
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75611
-rollout_issue_url: https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1380
-milestone: '14.6'
-type: development
-group: group::project management
-default_enabled: false
diff --git a/config/feature_flags/development/find_tag_via_gitaly.yml b/config/feature_flags/development/find_tag_via_gitaly.yml
deleted file mode 100644
index 43cbdb3993f..00000000000
--- a/config/feature_flags/development/find_tag_via_gitaly.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: find_tag_via_gitaly
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70181
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340899
-milestone: '14.3'
-type: development
-group: group::source code
-default_enabled: true
diff --git a/config/feature_flags/development/fix_comment_scroll.yml b/config/feature_flags/development/fix_comment_scroll.yml
new file mode 100644
index 00000000000..706cd816288
--- /dev/null
+++ b/config/feature_flags/development/fix_comment_scroll.yml
@@ -0,0 +1,8 @@
+---
+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/github_importer_use_diff_note_with_suggestions.yml b/config/feature_flags/development/github_importer_use_diff_note_with_suggestions.yml
index c106d5131ff..c7f8d9f4943 100644
--- a/config/feature_flags/development/github_importer_use_diff_note_with_suggestions.yml
+++ b/config/feature_flags/development/github_importer_use_diff_note_with_suggestions.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/344309
milestone: '14.5'
type: development
group: group::import
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/graphql_ci_runner_executor.yml b/config/feature_flags/development/graphql_ci_runner_executor.yml
new file mode 100644
index 00000000000..f58482b32d8
--- /dev/null
+++ b/config/feature_flags/development/graphql_ci_runner_executor.yml
@@ -0,0 +1,8 @@
+---
+name: graphql_ci_runner_executor
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76534
+rollout_issue_url:
+milestone: '14.7'
+type: development
+group: group::runner
+default_enabled: false
diff --git a/config/feature_flags/development/hide_access_tokens.yml b/config/feature_flags/development/hide_access_tokens.yml
deleted file mode 100644
index 1607780a0d0..00000000000
--- a/config/feature_flags/development/hide_access_tokens.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: hide_access_tokens
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76280
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/347490
-milestone: '14.6'
-type: development
-group: group::access
-default_enabled: true
diff --git a/config/feature_flags/development/import_redis_increment_by.yml b/config/feature_flags/development/import_redis_increment_by.yml
index bc2e5f97860..9932c8e868e 100644
--- a/config/feature_flags/development/import_redis_increment_by.yml
+++ b/config/feature_flags/development/import_redis_increment_by.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/336226
milestone: '14.1'
type: development
group: group::import
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/improved_container_scan_matching.yml b/config/feature_flags/development/improved_container_scan_matching.yml
deleted file mode 100644
index 81a486831cc..00000000000
--- a/config/feature_flags/development/improved_container_scan_matching.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: improved_container_scan_matching
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73486
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/344534
-milestone: '14.6'
-type: development
-group: group::container security
-default_enabled: true
diff --git a/config/feature_flags/development/inline_haml_diff_line_rendering.yml b/config/feature_flags/development/inline_haml_diff_line_rendering.yml
new file mode 100644
index 00000000000..a5e1f010c16
--- /dev/null
+++ b/config/feature_flags/development/inline_haml_diff_line_rendering.yml
@@ -0,0 +1,8 @@
+---
+name: inline_haml_diff_line_rendering
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57237
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/330582
+milestone: '14.7'
+type: development
+group: group::source code
+default_enabled: false
diff --git a/config/feature_flags/development/jira_use_first_ref_by_oid.yml b/config/feature_flags/development/jira_use_first_ref_by_oid.yml
deleted file mode 100644
index 88db6c1ab4c..00000000000
--- a/config/feature_flags/development/jira_use_first_ref_by_oid.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: jira_use_first_ref_by_oid
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72739
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343585
-milestone: '14.5'
-type: development
-group: group::integrations
-default_enabled: true
diff --git a/config/feature_flags/development/lfs_auto_link_fork_source.yml b/config/feature_flags/development/lfs_auto_link_fork_source.yml
index 022bcdd3128..e14daa6b30b 100644
--- a/config/feature_flags/development/lfs_auto_link_fork_source.yml
+++ b/config/feature_flags/development/lfs_auto_link_fork_source.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348243
milestone: '14.6'
type: development
group: group::source code
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/lfs_link_existing_object.yml b/config/feature_flags/development/lfs_link_existing_object.yml
index b8a0b810209..9388e7de8b5 100644
--- a/config/feature_flags/development/lfs_link_existing_object.yml
+++ b/config/feature_flags/development/lfs_link_existing_object.yml
@@ -2,6 +2,7 @@
name: lfs_link_existing_object
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41770
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/249246
+milestone: '13.4'
group: group::source code
type: development
default_enabled: false
diff --git a/config/feature_flags/development/linear_group_descendants_finder.yml b/config/feature_flags/development/linear_group_descendants_finder.yml
deleted file mode 100644
index 12f09c25c85..00000000000
--- a/config/feature_flags/development/linear_group_descendants_finder.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: linear_group_descendants_finder
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68954
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339440
-milestone: '14.6'
-type: development
-group: group::access
-default_enabled: false
diff --git a/config/feature_flags/development/linear_mirrors_worker_roots.yml b/config/feature_flags/development/linear_mirrors_worker_roots.yml
new file mode 100644
index 00000000000..5595cea6504
--- /dev/null
+++ b/config/feature_flags/development/linear_mirrors_worker_roots.yml
@@ -0,0 +1,8 @@
+---
+name: linear_mirrors_worker_roots
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76735
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348415
+milestone: '14.7'
+type: development
+group: group::authentication and authorization
+default_enabled: false
diff --git a/config/feature_flags/development/linear_user_group_notification_settings_finder_ancestors_scopes.yml b/config/feature_flags/development/linear_user_group_notification_settings_finder_ancestors_scopes.yml
deleted file mode 100644
index b54b82d00a0..00000000000
--- a/config/feature_flags/development/linear_user_group_notification_settings_finder_ancestors_scopes.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: linear_user_group_notification_settings_finder_ancestors_scopes
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74606
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/345792
-milestone: '14.6'
-type: development
-group: group::access
-default_enabled: false
diff --git a/config/feature_flags/development/log_implicit_sidekiq_status_calls.yml b/config/feature_flags/development/log_implicit_sidekiq_status_calls.yml
deleted file mode 100644
index 1aeb768b3dd..00000000000
--- a/config/feature_flags/development/log_implicit_sidekiq_status_calls.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: log_implicit_sidekiq_status_calls
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74815
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343964
-milestone: '14.6'
-type: development
-group: group::scalability
-default_enabled: false
diff --git a/config/feature_flags/development/log_import_export_relation_creation.yml b/config/feature_flags/development/log_import_export_relation_creation.yml
deleted file mode 100644
index 04d1b1e5d4f..00000000000
--- a/config/feature_flags/development/log_import_export_relation_creation.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: log_import_export_relation_creation
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27605
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/282245
-milestone: '12.10'
-type: development
-group: group::import
-default_enabled: false
diff --git a/config/feature_flags/development/loose_index_scan_for_distinct_values.yml b/config/feature_flags/development/loose_index_scan_for_distinct_values.yml
deleted file mode 100644
index 84f693d9247..00000000000
--- a/config/feature_flags/development/loose_index_scan_for_distinct_values.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: loose_index_scan_for_distinct_values
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55985
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/324210
-milestone: '13.10'
-type: development
-group: group::optimize
-default_enabled: false
diff --git a/config/feature_flags/development/migrate_vulnerability_finding_uuids.yml b/config/feature_flags/development/migrate_vulnerability_finding_uuids.yml
new file mode 100644
index 00000000000..dc168ba5374
--- /dev/null
+++ b/config/feature_flags/development/migrate_vulnerability_finding_uuids.yml
@@ -0,0 +1,8 @@
+---
+name: migrate_vulnerability_finding_uuids
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75546
+rollout_issue_url:
+milestone: '14.7'
+type: development
+group: group::threat insights
+default_enabled: true
diff --git a/config/feature_flags/development/multiple_gpg_signatures.yml b/config/feature_flags/development/multiple_gpg_signatures.yml
deleted file mode 100644
index 433309aea58..00000000000
--- a/config/feature_flags/development/multiple_gpg_signatures.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: multiple_gpg_signatures
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74095
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/345261
-milestone: '14.5'
-type: development
-group: group::source code
-default_enabled: true
diff --git a/config/feature_flags/development/operational_vulnerabilities.yml b/config/feature_flags/development/operational_vulnerabilities.yml
deleted file mode 100644
index ac92892592b..00000000000
--- a/config/feature_flags/development/operational_vulnerabilities.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: operational_vulnerabilities
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70732
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/341423
-milestone: '14.4'
-type: development
-group: group::container security
-default_enabled: true
diff --git a/config/feature_flags/development/optimize_merge_request_parser.yml b/config/feature_flags/development/optimize_merge_request_parser.yml
deleted file mode 100644
index 9e65f5412c4..00000000000
--- a/config/feature_flags/development/optimize_merge_request_parser.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: optimize_merge_request_parser
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62490/
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/331893
-milestone: '14.0'
-type: development
-group: group::source code
-default_enabled: false
diff --git a/config/feature_flags/development/optimized_issue_neighbor_queries.yml b/config/feature_flags/development/optimized_issue_neighbor_queries.yml
deleted file mode 100644
index db333dace72..00000000000
--- a/config/feature_flags/development/optimized_issue_neighbor_queries.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: optimized_issue_neighbor_queries
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76073
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/345921
-milestone: '14.6'
-type: development
-group: group::project management
-default_enabled: false
diff --git a/config/feature_flags/development/packages_installable_package_files.yml b/config/feature_flags/development/packages_installable_package_files.yml
new file mode 100644
index 00000000000..ed0091f41e2
--- /dev/null
+++ b/config/feature_flags/development/packages_installable_package_files.yml
@@ -0,0 +1,8 @@
+---
+name: packages_installable_package_files
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76767
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348677
+milestone: '14.6'
+type: development
+group: group::package
+default_enabled: true
diff --git a/config/feature_flags/development/paginatable_namespace_drop_down_for_project_creation.yml b/config/feature_flags/development/paginatable_namespace_drop_down_for_project_creation.yml
deleted file mode 100644
index f0f60d4d0b7..00000000000
--- a/config/feature_flags/development/paginatable_namespace_drop_down_for_project_creation.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: paginatable_namespace_drop_down_for_project_creation
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66112
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338930
-milestone: '14.3'
-type: development
-group: group::project management
-default_enabled: true
diff --git a/config/feature_flags/development/permitted_attributes_for_import_export.yml b/config/feature_flags/development/permitted_attributes_for_import_export.yml
deleted file mode 100644
index da5168b6ab8..00000000000
--- a/config/feature_flags/development/permitted_attributes_for_import_export.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: permitted_attributes_for_import_export
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70168
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340789
-milestone: '14.4'
-type: development
-group: group::import
-default_enabled: true
diff --git a/config/feature_flags/development/rate_limit_gitlab_shell.yml b/config/feature_flags/development/rate_limit_gitlab_shell.yml
new file mode 100644
index 00000000000..ceb9e86b01c
--- /dev/null
+++ b/config/feature_flags/development/rate_limit_gitlab_shell.yml
@@ -0,0 +1,8 @@
+---
+name: rate_limit_gitlab_shell
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78373
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350465
+milestone: '14.7'
+type: development
+group: group::source code
+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
new file mode 100644
index 00000000000..e72e3d605e3
--- /dev/null
+++ b/config/feature_flags/development/rate_limit_profile_update_username.yml
@@ -0,0 +1,8 @@
+---
+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
new file mode 100644
index 00000000000..d5523b7541b
--- /dev/null
+++ b/config/feature_flags/development/rate_limit_user_by_id_endpoint.yml
@@ -0,0 +1,8 @@
+---
+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
new file mode 100644
index 00000000000..af1957e54c8
--- /dev/null
+++ b/config/feature_flags/development/rate_limit_user_sign_up_endpoint.yml
@@ -0,0 +1,8 @@
+---
+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
new file mode 100644
index 00000000000..5a82dc96943
--- /dev/null
+++ b/config/feature_flags/development/rate_limit_username_exists_endpoint.yml
@@ -0,0 +1,8 @@
+---
+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/rebase_without_ci_ui.yml b/config/feature_flags/development/rebase_without_ci_ui.yml
new file mode 100644
index 00000000000..b05711ced29
--- /dev/null
+++ b/config/feature_flags/development/rebase_without_ci_ui.yml
@@ -0,0 +1,8 @@
+---
+name: rebase_without_ci_ui
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78194
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350262
+milestone: '14.7'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/remote_mirror_fail_on_lfs.yml b/config/feature_flags/development/remote_mirror_fail_on_lfs.yml
new file mode 100644
index 00000000000..4bbaa92a5b0
--- /dev/null
+++ b/config/feature_flags/development/remote_mirror_fail_on_lfs.yml
@@ -0,0 +1,8 @@
+---
+name: remote_mirror_fail_on_lfs
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77339
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/349262
+milestone: '14.7'
+type: development
+group: group::source code
+default_enabled: false
diff --git a/config/feature_flags/development/runner_read_only_admin_view.yml b/config/feature_flags/development/runner_read_only_admin_view.yml
new file mode 100644
index 00000000000..8053c31df6a
--- /dev/null
+++ b/config/feature_flags/development/runner_read_only_admin_view.yml
@@ -0,0 +1,8 @@
+---
+name: runner_read_only_admin_view
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77682
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350164
+milestone: '14.7'
+type: development
+group: group::runner
+default_enabled: false
diff --git a/config/feature_flags/development/sandboxed_mermaid.yml b/config/feature_flags/development/sandboxed_mermaid.yml
new file mode 100644
index 00000000000..434cd4055d8
--- /dev/null
+++ b/config/feature_flags/development/sandboxed_mermaid.yml
@@ -0,0 +1,8 @@
+---
+name: sandboxed_mermaid
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74414
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/349755
+milestone: '14.7'
+type: development
+group: group::analyzer frontend
+default_enabled: true
diff --git a/config/feature_flags/development/scim_token_vue.yml b/config/feature_flags/development/scim_token_vue.yml
deleted file mode 100644
index 8cc82bafd66..00000000000
--- a/config/feature_flags/development/scim_token_vue.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: scim_token_vue
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74743
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/347270
-milestone: '14.6'
-type: development
-group: group::access
-default_enabled: true
diff --git a/config/feature_flags/development/show_relevant_approval_rule_approvers.yml b/config/feature_flags/development/show_relevant_approval_rule_approvers.yml
deleted file mode 100644
index 233f6916896..00000000000
--- a/config/feature_flags/development/show_relevant_approval_rule_approvers.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: show_relevant_approval_rule_approvers
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60339
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/329153
-milestone: '13.12'
-type: development
-group: group::source code
-default_enabled: true
diff --git a/config/feature_flags/development/sidekiq_push_bulk_in_batches.yml b/config/feature_flags/development/sidekiq_push_bulk_in_batches.yml
deleted file mode 100644
index ea4c5253856..00000000000
--- a/config/feature_flags/development/sidekiq_push_bulk_in_batches.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: sidekiq_push_bulk_in_batches
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72263
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343740
-milestone: '14.5'
-type: development
-group: group::access
-default_enabled: false
diff --git a/config/feature_flags/development/sourcegraph.yml b/config/feature_flags/development/sourcegraph.yml
index 12170aec869..f9aa76f6c7c 100644
--- a/config/feature_flags/development/sourcegraph.yml
+++ b/config/feature_flags/development/sourcegraph.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/292199
milestone: '12.5'
type: development
group: group::editor
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/swimlanes_buffered_rendering.yml b/config/feature_flags/development/swimlanes_buffered_rendering.yml
deleted file mode 100644
index 30da5383406..00000000000
--- a/config/feature_flags/development/swimlanes_buffered_rendering.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: swimlanes_buffered_rendering
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56614
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/324994
-milestone: '13.11'
-type: development
-group: group::product planning
-default_enabled: false \ No newline at end of file
diff --git a/config/feature_flags/development/track_geo_proxy_events.yml b/config/feature_flags/development/track_geo_proxy_events.yml
new file mode 100644
index 00000000000..29e8d771adf
--- /dev/null
+++ b/config/feature_flags/development/track_geo_proxy_events.yml
@@ -0,0 +1,8 @@
+---
+name: track_geo_proxy_events
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76587
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348414
+milestone: '14.7'
+type: development
+group: group::geo
+default_enabled: true
diff --git a/config/feature_flags/development/trigger_job_retry_action.yml b/config/feature_flags/development/trigger_job_retry_action.yml
new file mode 100644
index 00000000000..79a8593fd05
--- /dev/null
+++ b/config/feature_flags/development/trigger_job_retry_action.yml
@@ -0,0 +1,8 @@
+---
+name: trigger_job_retry_action
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77951
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/349966
+milestone: '14.7'
+type: development
+group: group::pipeline authoring
+default_enabled: false
diff --git a/config/feature_flags/development/unify_security_configuration.yml b/config/feature_flags/development/unify_security_configuration.yml
new file mode 100644
index 00000000000..bbc4489ec82
--- /dev/null
+++ b/config/feature_flags/development/unify_security_configuration.yml
@@ -0,0 +1,8 @@
+---
+name: unify_security_configuration
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76866
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350177
+milestone: '14.7'
+type: development
+group: group::composition analysis
+default_enabled: false
diff --git a/config/feature_flags/development/use_cmark_renderer.yml b/config/feature_flags/development/use_cmark_renderer.yml
deleted file mode 100644
index 5e4ea534590..00000000000
--- a/config/feature_flags/development/use_cmark_renderer.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: use_cmark_renderer
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61792
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/345744
-milestone: '14.6'
-type: development
-group: group::project management
-default_enabled: true
diff --git a/config/feature_flags/development/use_optimized_group_labels_query.yml b/config/feature_flags/development/use_optimized_group_labels_query.yml
deleted file mode 100644
index 82cecb5f337..00000000000
--- a/config/feature_flags/development/use_optimized_group_labels_query.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: use_optimized_group_labels_query
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73501
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/344957
-milestone: '14.5'
-type: development
-group: group::workspace
-default_enabled: true
diff --git a/config/feature_flags/development/use_primary_and_secondary_stores_for_sessions.yml b/config/feature_flags/development/use_primary_and_secondary_stores_for_sessions.yml
deleted file mode 100644
index 2204472c0a6..00000000000
--- a/config/feature_flags/development/use_primary_and_secondary_stores_for_sessions.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: use_primary_and_secondary_stores_for_sessions
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73660
-rollout_issue_url: https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1429
-milestone: '14.6'
-type: development
-group: group::memory
-default_enabled: false
diff --git a/config/feature_flags/development/use_primary_store_as_default_for_sessions.yml b/config/feature_flags/development/use_primary_store_as_default_for_sessions.yml
deleted file mode 100644
index ac130ab7761..00000000000
--- a/config/feature_flags/development/use_primary_store_as_default_for_sessions.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: use_primary_store_as_default_for_sessions
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75258
-rollout_issue_url:
-milestone: '14.6'
-type: development
-group: group::memory
-default_enabled: false
diff --git a/config/feature_flags/development/use_traversal_ids.yml b/config/feature_flags/development/use_traversal_ids.yml
index e9fd2d03737..ab3a2eaf733 100644
--- a/config/feature_flags/development/use_traversal_ids.yml
+++ b/config/feature_flags/development/use_traversal_ids.yml
@@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56296
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/321948
milestone: '13.11'
type: development
-group: group::access
+group: group::workspace
default_enabled: false
diff --git a/config/feature_flags/development/use_traversal_ids_for_ancestor_scopes.yml b/config/feature_flags/development/use_traversal_ids_for_ancestor_scopes.yml
index 7f398fc5f0b..e2619ef5231 100644
--- a/config/feature_flags/development/use_traversal_ids_for_ancestor_scopes.yml
+++ b/config/feature_flags/development/use_traversal_ids_for_ancestor_scopes.yml
@@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67652
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340159
milestone: '14.3'
type: development
-group: group::access
+group: group::workspace
default_enabled: false
diff --git a/config/feature_flags/development/use_traversal_ids_for_ancestors.yml b/config/feature_flags/development/use_traversal_ids_for_ancestors.yml
index ae5f154a6bc..4a89aac140d 100644
--- a/config/feature_flags/development/use_traversal_ids_for_ancestors.yml
+++ b/config/feature_flags/development/use_traversal_ids_for_ancestors.yml
@@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57137
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/334952
milestone: '13.12'
type: development
-group: group::access
+group: group::workspace
default_enabled: false
diff --git a/config/feature_flags/development/use_traversal_ids_for_ancestors_upto.yml b/config/feature_flags/development/use_traversal_ids_for_ancestors_upto.yml
index 4fe7ca695c3..9da967f87ea 100644
--- a/config/feature_flags/development/use_traversal_ids_for_ancestors_upto.yml
+++ b/config/feature_flags/development/use_traversal_ids_for_ancestors_upto.yml
@@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72662
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343619
milestone: '14.6'
type: development
-group: group::access
+group: group::workspace
default_enabled: false
diff --git a/config/feature_flags/development/use_traversal_ids_for_root_ancestor.yml b/config/feature_flags/development/use_traversal_ids_for_root_ancestor.yml
index be02645720e..74ae139b68a 100644
--- a/config/feature_flags/development/use_traversal_ids_for_root_ancestor.yml
+++ b/config/feature_flags/development/use_traversal_ids_for_root_ancestor.yml
@@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61163
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/331907
milestone: '14.0'
type: development
-group: group::access
+group: group::workspace
default_enabled: false
diff --git a/config/feature_flags/development/use_traversal_ids_for_self_and_hierarchy.yml b/config/feature_flags/development/use_traversal_ids_for_self_and_hierarchy.yml
new file mode 100644
index 00000000000..06bddc2aa1c
--- /dev/null
+++ b/config/feature_flags/development/use_traversal_ids_for_self_and_hierarchy.yml
@@ -0,0 +1,8 @@
+---
+name: use_traversal_ids_for_self_and_hierarchy
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76814
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348527
+milestone: '14.7'
+type: development
+group: group::workspace
+default_enabled: false
diff --git a/config/feature_flags/development/use_traversal_ids_groups_finder.yml b/config/feature_flags/development/use_traversal_ids_groups_finder.yml
index b0550fe62d9..2f35ede7e87 100644
--- a/config/feature_flags/development/use_traversal_ids_groups_finder.yml
+++ b/config/feature_flags/development/use_traversal_ids_groups_finder.yml
@@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67650
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/345666
milestone: '14.6'
type: development
-group: group::access
+group: group::workspace
default_enabled: false
diff --git a/config/feature_flags/development/use_typhoeus_elasticsearch_adapter.yml b/config/feature_flags/development/use_typhoeus_elasticsearch_adapter.yml
new file mode 100644
index 00000000000..ac762395cd2
--- /dev/null
+++ b/config/feature_flags/development/use_typhoeus_elasticsearch_adapter.yml
@@ -0,0 +1,8 @@
+---
+name: use_typhoeus_elasticsearch_adapter
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76879
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348607
+milestone: '14.7'
+type: development
+group: group::global search
+default_enabled: false
diff --git a/config/feature_flags/development/verify_participants_access.yml b/config/feature_flags/development/verify_participants_access.yml
deleted file mode 100644
index 8857003fd47..00000000000
--- a/config/feature_flags/development/verify_participants_access.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: verify_participants_access
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74906
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/347407
-milestone: '14.6'
-type: development
-group: group::source code
-default_enabled: false
diff --git a/config/feature_flags/development/vue_epics_list.yml b/config/feature_flags/development/vue_epics_list.yml
deleted file mode 100644
index 22e2a53aeee..00000000000
--- a/config/feature_flags/development/vue_epics_list.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: vue_epics_list
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46769
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/276189
-milestone: '13.9'
-type: development
-group: group::product planning
-default_enabled: false
diff --git a/config/feature_flags/development/vue_integration_form.yml b/config/feature_flags/development/vue_integration_form.yml
new file mode 100644
index 00000000000..a11c42b8d4a
--- /dev/null
+++ b/config/feature_flags/development/vue_integration_form.yml
@@ -0,0 +1,8 @@
+---
+name: vue_integration_form
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77934
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350444
+milestone: '14.7'
+type: development
+group: group::integrations
+default_enabled: false
diff --git a/config/feature_flags/development/vue_issuables_list.yml b/config/feature_flags/development/vue_issuables_list.yml
deleted file mode 100644
index 75ef82999ca..00000000000
--- a/config/feature_flags/development/vue_issuables_list.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: vue_issuables_list
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/15091
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/208093
-milestone: '12.5'
-type: development
-group: group::project management
-default_enabled: false
diff --git a/config/feature_flags/development/vulnerability_finding_replace_metadata.yml b/config/feature_flags/development/vulnerability_finding_replace_metadata.yml
index f7b3cb67c38..2774547668f 100644
--- a/config/feature_flags/development/vulnerability_finding_replace_metadata.yml
+++ b/config/feature_flags/development/vulnerability_finding_replace_metadata.yml
@@ -2,6 +2,7 @@
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 \ No newline at end of file
+default_enabled: false
diff --git a/config/feature_flags/development/vulnerability_location_image_filter.yml b/config/feature_flags/development/vulnerability_location_image_filter.yml
deleted file mode 100644
index 1bbc8e43d57..00000000000
--- a/config/feature_flags/development/vulnerability_location_image_filter.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: vulnerability_location_image_filter
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69867
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340915
-milestone: '14.4'
-type: development
-group: group::container security
-default_enabled: true
diff --git a/config/feature_flags/development/wiki_switch_between_content_editor_raw_markdown.yml b/config/feature_flags/development/wiki_switch_between_content_editor_raw_markdown.yml
index f499263acec..dbdf2d616d2 100644
--- a/config/feature_flags/development/wiki_switch_between_content_editor_raw_markdown.yml
+++ b/config/feature_flags/development/wiki_switch_between_content_editor_raw_markdown.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/345398
milestone: '14.6'
type: development
group: group::editor
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/experiment/logged_out_marketing_header.yml b/config/feature_flags/experiment/logged_out_marketing_header.yml
new file mode 100644
index 00000000000..8bc09d59b16
--- /dev/null
+++ b/config/feature_flags/experiment/logged_out_marketing_header.yml
@@ -0,0 +1,8 @@
+---
+name: logged_out_marketing_header
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76076
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348525
+milestone: '14.7'
+type: experiment
+group: group::activation
+default_enabled: false
diff --git a/config/feature_flags/experiment/pql_three_cta_test.yml b/config/feature_flags/experiment/pql_three_cta_test.yml
new file mode 100644
index 00000000000..33ffcadb5c0
--- /dev/null
+++ b/config/feature_flags/experiment/pql_three_cta_test.yml
@@ -0,0 +1,8 @@
+---
+name: pql_three_cta_test
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74054
+rollout_issue_url:
+milestone: '14.7'
+type: experiment
+group: group::conversion
+default_enabled: false
diff --git a/config/feature_flags/experiment/require_verification_for_group_creation.yml b/config/feature_flags/experiment/require_verification_for_group_creation.yml
new file mode 100644
index 00000000000..767d5f55bce
--- /dev/null
+++ b/config/feature_flags/experiment/require_verification_for_group_creation.yml
@@ -0,0 +1,8 @@
+---
+name: require_verification_for_group_creation
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77569
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/349857
+milestone: '14.7'
+type: experiment
+group: group::activation
+default_enabled: false
diff --git a/config/feature_flags/experiment/require_verification_for_namespace_creation.yml b/config/feature_flags/experiment/require_verification_for_namespace_creation.yml
new file mode 100644
index 00000000000..5772d3217b8
--- /dev/null
+++ b/config/feature_flags/experiment/require_verification_for_namespace_creation.yml
@@ -0,0 +1,8 @@
+---
+name: require_verification_for_namespace_creation
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77315
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350251
+milestone: '14.8'
+type: experiment
+group: group::activation
+default_enabled: false
diff --git a/config/feature_flags/ops/ci_unsafe_regexp_logger.yml b/config/feature_flags/ops/ci_unsafe_regexp_logger.yml
new file mode 100644
index 00000000000..00dbab724f8
--- /dev/null
+++ b/config/feature_flags/ops/ci_unsafe_regexp_logger.yml
@@ -0,0 +1,8 @@
+---
+name: ci_unsafe_regexp_logger
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78458
+rollout_issue_url:
+milestone: '14.8'
+type: ops
+group: group::pipeline authoring
+default_enabled: true
diff --git a/config/feature_flags/ops/gitlab_gtm_datalayer.yml b/config/feature_flags/ops/gitlab_gtm_datalayer.yml
new file mode 100644
index 00000000000..f41506ce114
--- /dev/null
+++ b/config/feature_flags/ops/gitlab_gtm_datalayer.yml
@@ -0,0 +1,8 @@
+---
+name: gitlab_gtm_datalayer
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76305
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348932
+milestone: '14.6'
+type: ops
+group: group::buyer experience
+default_enabled: false
diff --git a/config/feature_flags/ops/prometheus_notify_max_alerts.yml b/config/feature_flags/ops/prometheus_notify_max_alerts.yml
new file mode 100644
index 00000000000..2861299d9bf
--- /dev/null
+++ b/config/feature_flags/ops/prometheus_notify_max_alerts.yml
@@ -0,0 +1,8 @@
+---
+name: prometheus_notify_max_alerts
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77168
+rollout_issue_url: https://gitlab.com/gitlab-com/gl-infra/production/-/issues/6086
+milestone: '14.7'
+type: ops
+group: group::monitor
+default_enabled: false
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 05eab1a9b43..f5755591da7 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -9,6 +9,8 @@
# If you change this file in a merge request, please also create #
# a MR on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests. #
# For more details see https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/gitlab.yml.md #
+# Be sure to create a MR against the GDK configuration #
+# file (https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/support/templates/gitlab/config/gitlab.yml.erb) too. #
########################################################################
#
#
@@ -228,6 +230,10 @@ 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.
+ # Default is '.gitlab_mailroom_secret' relative to Rails.root (i.e. root of the GitLab app).
+ # secret_file: /home/git/gitlab/.gitlab_mailroom_secret
+
## Consolidated object store config
## This will only take effect if the object_store sections are not defined
## within the types (e.g. artifacts, lfs, etc.).
@@ -1421,6 +1427,18 @@ test:
aws_secret_access_key: AWS_SECRET_ACCESS_KEY
region: us-east-1
+ ci_secure_files:
+ enabled: true
+ storage_path: tmp/tests/ci_secure_files
+ object_store:
+ enabled: false
+ remote_directory: ci_secure_files
+ connection:
+ provider: AWS # Only AWS supported at the moment
+ aws_access_key_id: AWS_ACCESS_KEY_ID
+ aws_secret_access_key: AWS_SECRET_ACCESS_KEY
+ region: us-east-1
+
gitlab:
host: localhost
port: 80
diff --git a/config/helpers/patched_crypto.js b/config/helpers/patched_crypto.js
new file mode 100644
index 00000000000..235242195b1
--- /dev/null
+++ b/config/helpers/patched_crypto.js
@@ -0,0 +1,22 @@
+/**
+ * Webpack 4 uses md4 internally because it is fast.
+ * Some loaders also use md5 directly.
+ * It is not available systems with FIPS enabled node.
+ *
+ * This is a hack to monkey patch the crypto function to use
+ * another algorithm if md4 or md5 is expected.
+ *
+ * https://github.com/webpack/webpack/issues/13572#issuecomment-923736472
+ *
+ * This hack can be removed once we upgrade to webpack v5 as
+ * it includes native support for configuring hash options:
+ * https://github.com/webpack/webpack/pull/14306
+ */
+const crypto = require('crypto');
+
+const cryptoHashOriginal = crypto.createHash;
+
+crypto.createHash = (algorithm) =>
+ cryptoHashOriginal(['md4', 'md5'].includes(algorithm) ? 'sha256' : algorithm);
+
+module.exports = crypto;
diff --git a/config/helpers/vendor_dll_hash.js b/config/helpers/vendor_dll_hash.js
index 9b99b4c4ae9..5d7feb35d36 100644
--- a/config/helpers/vendor_dll_hash.js
+++ b/config/helpers/vendor_dll_hash.js
@@ -1,6 +1,6 @@
-const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
+const crypto = require('./patched_crypto');
const CACHE_PATHS = [
'./config/webpack.config.js',
@@ -11,7 +11,7 @@ const CACHE_PATHS = [
const resolvePath = (file) => path.resolve(__dirname, '../..', file);
const readFile = (file) => fs.readFileSync(file);
-const fileHash = (buffer) => crypto.createHash('md5').update(buffer).digest('hex');
+const fileHash = (buffer) => crypto.createHash('sha256').update(buffer).digest('hex');
module.exports = () => {
const fileBuffers = CACHE_PATHS.map(resolvePath).map(readFile);
diff --git a/config/initializers/0_inject_enterprise_edition_module.rb b/config/initializers/0_inject_enterprise_edition_module.rb
index 41d1043af38..1951940a2a1 100644
--- a/config/initializers/0_inject_enterprise_edition_module.rb
+++ b/config/initializers/0_inject_enterprise_edition_module.rb
@@ -46,7 +46,7 @@ module InjectEnterpriseEditionModule
end
def each_extension_for(constant_name, namespace)
- Gitlab.extensions.each do |extension_name|
+ GitlabEdition.extensions.each do |extension_name|
extension_namespace =
const_get_maybe_false(namespace, extension_name.upcase)
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index 2587347719a..8244f570a18 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -247,6 +247,14 @@ Settings.gitlab_ci['builds_path'] = Settings.absolute(Settings.gitlab_
Settings.gitlab_ci['url'] ||= Settings.__send__(:build_gitlab_ci_url)
#
+# CI Secure Files
+#
+Settings['ci_secure_files'] ||= Settingslogic.new({})
+Settings.ci_secure_files['enabled'] = true if Settings.ci_secure_files['enabled'].nil?
+Settings.ci_secure_files['storage_path'] = Settings.absolute(Settings.ci_secure_files['storage_path'] || File.join(Settings.shared['path'], "ci_secure_files"))
+Settings.ci_secure_files['object_store'] = ObjectStoreSettings.legacy_parse(Settings.ci_secure_files['object_store'])
+
+#
# Reply by email
#
Settings['incoming_email'] ||= Settingslogic.new({})
@@ -537,6 +545,10 @@ Settings.cron_jobs['image_ttl_group_policy_worker']['job_class'] = 'DependencyPr
Settings.cron_jobs['cleanup_dependency_proxy_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['cleanup_dependency_proxy_worker']['cron'] ||= '20 3,15 * * *'
Settings.cron_jobs['cleanup_dependency_proxy_worker']['job_class'] = 'DependencyProxy::CleanupDependencyProxyWorker'
+Settings.cron_jobs['cleanup_package_registry_worker'] ||= Settingslogic.new({})
+Settings.cron_jobs['cleanup_package_registry_worker']['cron'] ||= '20 0,12 * * *'
+Settings.cron_jobs['cleanup_package_registry_worker']['job_class'] = 'Packages::CleanupPackageRegistryWorker'
+
Settings.cron_jobs['x509_issuer_crl_check_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['x509_issuer_crl_check_worker']['cron'] ||= '30 1 * * *'
Settings.cron_jobs['x509_issuer_crl_check_worker']['job_class'] = 'X509IssuerCrlCheckWorker'
@@ -723,7 +735,7 @@ Gitlab.ee do
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'
Settings.cron_jobs['loose_foreign_keys_cleanup_worker'] ||= Settingslogic.new({})
- Settings.cron_jobs['loose_foreign_keys_cleanup_worker']['cron'] ||= '*/5 * * * *'
+ Settings.cron_jobs['loose_foreign_keys_cleanup_worker']['cron'] ||= '*/1 * * * *'
Settings.cron_jobs['loose_foreign_keys_cleanup_worker']['job_class'] = 'LooseForeignKeys::CleanupWorker'
end
diff --git a/config/initializers/7_prometheus_metrics.rb b/config/initializers/7_prometheus_metrics.rb
index 8ef11b83131..15757c05bd0 100644
--- a/config/initializers/7_prometheus_metrics.rb
+++ b/config/initializers/7_prometheus_metrics.rb
@@ -70,17 +70,17 @@ if !Rails.env.test? && Gitlab::Metrics.prometheus_metrics_enabled?
Gitlab::Cluster::LifecycleEvents.on_worker_start do
defined?(::Prometheus::Client.reinitialize_on_pid_change) && ::Prometheus::Client.reinitialize_on_pid_change
-
- Gitlab::Metrics::Samplers::RubySampler.initialize_instance.start
- Gitlab::Metrics::Samplers::DatabaseSampler.initialize_instance.start
- Gitlab::Metrics::Samplers::ThreadsSampler.initialize_instance.start
+ 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.start
+ Gitlab::Metrics::Samplers::ActionCableSampler.instance(logger: logger).start
end
if Gitlab.ee? && Gitlab::Runtime.sidekiq?
- Gitlab::Metrics::Samplers::GlobalSearchSampler.instance.start
+ Gitlab::Metrics::Samplers::GlobalSearchSampler.instance(logger: logger).start
end
Gitlab::Ci::Parsers.instrument!
diff --git a/config/initializers/active_record_lifecycle.rb b/config/initializers/active_record_lifecycle.rb
index 8d4b6d61abe..92cc1d81617 100644
--- a/config/initializers/active_record_lifecycle.rb
+++ b/config/initializers/active_record_lifecycle.rb
@@ -5,7 +5,7 @@
if defined?(ActiveRecord::Base) && !Gitlab::Runtime.sidekiq?
Gitlab::Cluster::LifecycleEvents.on_worker_start do
ActiveSupport.on_load(:active_record) do
- ActiveRecord::Base.establish_connection
+ ActiveRecord::Base.establish_connection # rubocop: disable Database/EstablishConnection
Gitlab::AppLogger.debug("ActiveRecord connection established")
end
diff --git a/config/initializers/active_record_transaction_observer.rb b/config/initializers/active_record_transaction_observer.rb
index a1d4b13344e..b90b3a39ac1 100644
--- a/config/initializers/active_record_transaction_observer.rb
+++ b/config/initializers/active_record_transaction_observer.rb
@@ -1,18 +1,9 @@
# frozen_string_literal: true
-def feature_flags_available?
- # When the DBMS is not available, an exception (e.g. PG::ConnectionBad) is raised
- active_db_connection = ActiveRecord::Base.connection.active? rescue false
-
- active_db_connection && Feature::FlipperFeature.table_exists?
-rescue ActiveRecord::NoDatabaseError
- false
-end
-
return unless Gitlab.com? || Gitlab.dev_or_test_env?
Gitlab::Application.configure do
- if feature_flags_available? && ::Feature.enabled?(:active_record_transactions_tracking, type: :ops, default_enabled: :yaml)
+ if Feature.feature_flags_available? && ::Feature.enabled?(:active_record_transactions_tracking, type: :ops, default_enabled: :yaml)
Gitlab::Database::Transaction::Observer.register!
end
end
diff --git a/config/initializers/database_config.rb b/config/initializers/database_config.rb
index a3172fae027..050ab1d9b3e 100644
--- a/config/initializers/database_config.rb
+++ b/config/initializers/database_config.rb
@@ -13,6 +13,6 @@ Gitlab.ee do
# The Geo::TrackingBase model does not yet use connects_to. So,
# this will not properly support geo: from config/databse.yml
# file yet. This is ACK of the current state and will be fixed.
- Geo::TrackingBase.establish_connection(Gitlab::Database.geo_db_config_with_default_pool_size)
+ Geo::TrackingBase.establish_connection(Gitlab::Database.geo_db_config_with_default_pool_size) # rubocop: disable Database/EstablishConnection
end
end
diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb
index bb2e01a30f1..a7754667320 100644
--- a/config/initializers/session_store.rb
+++ b/config/initializers/session_store.rb
@@ -19,15 +19,7 @@ cookie_key = if Rails.env.development?
"_gitlab_session"
end
-store = if Gitlab::Utils.to_boolean(ENV['GITLAB_USE_REDIS_SESSIONS_STORE'], default: true)
- Gitlab::Redis::Sessions.store(
- namespace: Gitlab::Redis::Sessions::SESSION_NAMESPACE
- )
- else
- Gitlab::Redis::SharedState.store(
- namespace: Gitlab::Redis::Sessions::SESSION_NAMESPACE
- )
- end
+store = Gitlab::Redis::Sessions.store(namespace: Gitlab::Redis::Sessions::SESSION_NAMESPACE)
Gitlab::Application.config.session_store(
:redis_store, # Using the cookie_store would enable session replay attacks.
diff --git a/config/initializers/sherlock.rb b/config/initializers/sherlock.rb
deleted file mode 100644
index ba33ffa13c5..00000000000
--- a/config/initializers/sherlock.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-if Gitlab::Sherlock.enabled?
- Rails.application.configure do |config|
- config.middleware.use(Gitlab::Sherlock::Middleware)
- end
-end
diff --git a/config/initializers/webhook_recursion_detection.rb b/config/initializers/webhook_recursion_detection.rb
new file mode 100644
index 00000000000..b345c005bac
--- /dev/null
+++ b/config/initializers/webhook_recursion_detection.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+Rails.application.configure do |config|
+ config.middleware.insert_after RequestStore::Middleware, Gitlab::Middleware::WebhookRecursionDetection
+end
diff --git a/config/initializers/wikicloth_disable_lua_patch.rb b/config/initializers/wikicloth_disable_lua_patch.rb
new file mode 100644
index 00000000000..67d41b4327d
--- /dev/null
+++ b/config/initializers/wikicloth_disable_lua_patch.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require 'wikicloth'
+require 'wikicloth/extensions/lua'
+
+# Adds patch to disable lua support to eliminate vulnerability to injection attack.
+#
+# The maintainers are not releasing new versions, so we need to patch it here.
+#
+# If they ever do release a version which contains a fix for this, then we can remove this file.
+#
+# See: https://gitlab.com/gitlab-org/gitlab/-/issues/345892#note_751107320
+
+# Guard to ensure we remember to delete this patch if they ever release a new version of wikicloth
+# which disables Lua by default or otherwise eliminates all vulnerabilities mentioned in
+# https://gitlab.com/gitlab-org/gitlab/-/issues/345892, including the possibility of an HTML/JS
+# injection attack as mentioned in https://gitlab.com/gitlab-org/gitlab/-/issues/345892#note_751981608
+unless Gem::Version.new(WikiCloth::VERSION) == Gem::Version.new('0.8.1')
+ raise 'New version of WikiCloth detected, please either update the version for this check, ' \
+ 'or remove this patch if no longer needed'
+end
+
+module WikiCloth
+ class LuaExtension < Extension
+ protected
+
+ def init_lua
+ @options[:disable_lua] = true
+ end
+ end
+end
diff --git a/config/initializers/wikicloth_patch.rb b/config/initializers/wikicloth_redos_patch.rb
index 13180180c32..13180180c32 100644
--- a/config/initializers/wikicloth_patch.rb
+++ b/config/initializers/wikicloth_redos_patch.rb
diff --git a/config/locales/sherlock.en.yml b/config/locales/sherlock.en.yml
deleted file mode 100644
index 963e1d6295a..00000000000
--- a/config/locales/sherlock.en.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-en:
- sherlock:
- title: Sherlock
- delete_all_transactions: Delete All Transactions
- introduction: >
- Below is a list of all transactions recorded by Sherlock. Requests to
- Sherlock's own routes are ignored.
- no_transactions: No transactions to show
- no_queries: No queries to show
- no_file_samples: No file samples to show
- all_transactions: All Transactions
- transaction: Transaction
- query: Query
- file_sample: File Sample
- type: Type
- path: Path
- time: Time
- queries: Queries
- finished_at: Finished at
- ago: ago
- view: View
- seconds: seconds
- milliseconds: ms
- general: General
- id: ID
- time_inclusive: Time (inclusive)
- backtrace: Backtrace
- application_backtrace: Application Backtrace
- full_backtrace: Full Backtrace
- origin: Origin
- line: line
- line_capitalized: Line
- copy_to_clipboard: Copy
- query_plan: Query Plan
- events: Events
- percent: '%'
- count: Count
- query_time: Query Time
diff --git a/config/mail_room.yml b/config/mail_room.yml
index 895438dcc4e..669925c2390 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 |config|
+ Gitlab::MailRoom.enabled_configs.each do |_key, config|
%>
-
:host: <%= config[:host].to_json %>
diff --git a/config/metrics/counts_28d/20210216175109_suggestions.yml b/config/metrics/counts_28d/20210216175109_suggestions.yml
index fcccc350252..27288e43eee 100644
--- a/config/metrics/counts_28d/20210216175109_suggestions.yml
+++ b/config/metrics/counts_28d/20210216175109_suggestions.yml
@@ -8,7 +8,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: active
+status: removed
time_frame: 28d
data_source: database
distribution:
@@ -20,3 +20,4 @@ tier:
- ultimate
performance_indicator_type: []
milestone: "<13.9"
+milestone_removed: '14.7'
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 976ffa0444a..d27548980b0 100644
--- a/config/metrics/counts_28d/20210216175550_ci_pipeline_config_repository.yml
+++ b/config/metrics/counts_28d/20210216175550_ci_pipeline_config_repository.yml
@@ -1,7 +1,7 @@
---
data_category: operational
key_path: usage_activity_by_stage_monthly.verify.ci_pipeline_config_repository
-description: Total Monthly Pipelines from templates in repository
+description: Monthly count of unique users creating pipelines from CI files in the repository
product_section: ops
product_stage: verify
product_group: group::pipeline execution
diff --git a/config/metrics/counts_28d/20210216183640_gitlab.yml b/config/metrics/counts_28d/20210216183640_gitlab.yml
index 6b074612937..9fc8a81d95f 100644
--- a/config/metrics/counts_28d/20210216183640_gitlab.yml
+++ b/config/metrics/counts_28d/20210216183640_gitlab.yml
@@ -1,13 +1,13 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.manage.bulk_imports.gitlab
-description: DEPRECATED - Count of projects imported using bulk imports
+description: REMOVED - Count of projects imported using bulk imports
product_section: dev
product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: database
distribution:
diff --git a/config/metrics/counts_28d/20210216183712_total.yml b/config/metrics/counts_28d/20210216183712_total.yml
index 6df82786097..7d20907a88c 100644
--- a/config/metrics/counts_28d/20210216183712_total.yml
+++ b/config/metrics/counts_28d/20210216183712_total.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: database
distribution:
diff --git a/config/metrics/counts_28d/20210216183714_gitlab_project.yml b/config/metrics/counts_28d/20210216183714_gitlab_project.yml
index 65b7f08ee9b..11397036533 100644
--- a/config/metrics/counts_28d/20210216183714_gitlab_project.yml
+++ b/config/metrics/counts_28d/20210216183714_gitlab_project.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: database
distribution:
diff --git a/config/metrics/counts_28d/20210216183716_gitlab.yml b/config/metrics/counts_28d/20210216183716_gitlab.yml
index 78113f063ca..1f7a233360a 100644
--- a/config/metrics/counts_28d/20210216183716_gitlab.yml
+++ b/config/metrics/counts_28d/20210216183716_gitlab.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: database
distribution:
diff --git a/config/metrics/counts_28d/20210216183718_github.yml b/config/metrics/counts_28d/20210216183718_github.yml
index caa2602d5fa..d3686ee5f13 100644
--- a/config/metrics/counts_28d/20210216183718_github.yml
+++ b/config/metrics/counts_28d/20210216183718_github.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: database
distribution:
diff --git a/config/metrics/counts_28d/20210216183720_bitbucket.yml b/config/metrics/counts_28d/20210216183720_bitbucket.yml
index c9e54883e3f..281ddbc4179 100644
--- a/config/metrics/counts_28d/20210216183720_bitbucket.yml
+++ b/config/metrics/counts_28d/20210216183720_bitbucket.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: database
distribution:
diff --git a/config/metrics/counts_28d/20210216183722_bitbucket_server.yml b/config/metrics/counts_28d/20210216183722_bitbucket_server.yml
index 7b81f7bf2dd..bdff1803a6a 100644
--- a/config/metrics/counts_28d/20210216183722_bitbucket_server.yml
+++ b/config/metrics/counts_28d/20210216183722_bitbucket_server.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: database
distribution:
diff --git a/config/metrics/counts_28d/20210216183724_gitea.yml b/config/metrics/counts_28d/20210216183724_gitea.yml
index 9a8c27cae3f..eecbd276e0c 100644
--- a/config/metrics/counts_28d/20210216183724_gitea.yml
+++ b/config/metrics/counts_28d/20210216183724_gitea.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: database
distribution:
diff --git a/config/metrics/counts_28d/20210216183726_git.yml b/config/metrics/counts_28d/20210216183726_git.yml
index b044fd6f493..e9b7a0d5e76 100644
--- a/config/metrics/counts_28d/20210216183726_git.yml
+++ b/config/metrics/counts_28d/20210216183726_git.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: database
distribution:
diff --git a/config/metrics/counts_28d/20210216183728_manifest.yml b/config/metrics/counts_28d/20210216183728_manifest.yml
index 56d47b288f3..8cf5bb94cef 100644
--- a/config/metrics/counts_28d/20210216183728_manifest.yml
+++ b/config/metrics/counts_28d/20210216183728_manifest.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: database
distribution:
diff --git a/config/metrics/counts_28d/20210216183730_jira.yml b/config/metrics/counts_28d/20210216183730_jira.yml
index 1a51229d107..094e46ba7f6 100644
--- a/config/metrics/counts_28d/20210216183730_jira.yml
+++ b/config/metrics/counts_28d/20210216183730_jira.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: database
distribution:
diff --git a/config/metrics/counts_28d/20210216183731_fogbugz.yml b/config/metrics/counts_28d/20210216183731_fogbugz.yml
index 53cfec950c2..678d57b894e 100644
--- a/config/metrics/counts_28d/20210216183731_fogbugz.yml
+++ b/config/metrics/counts_28d/20210216183731_fogbugz.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: database
distribution:
diff --git a/config/metrics/counts_28d/20210216183733_phabricator.yml b/config/metrics/counts_28d/20210216183733_phabricator.yml
index 07b95a6066c..0f3b9cc46ee 100644
--- a/config/metrics/counts_28d/20210216183733_phabricator.yml
+++ b/config/metrics/counts_28d/20210216183733_phabricator.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: database
distribution:
diff --git a/config/metrics/counts_28d/20210216183735_csv.yml b/config/metrics/counts_28d/20210216183735_csv.yml
index afdafb3c507..e81cc094832 100644
--- a/config/metrics/counts_28d/20210216183735_csv.yml
+++ b/config/metrics/counts_28d/20210216183735_csv.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: database
distribution:
diff --git a/config/metrics/counts_28d/20210216183737_groups_imported.yml b/config/metrics/counts_28d/20210216183737_groups_imported.yml
index 0de2e16e661..3c62a859573 100644
--- a/config/metrics/counts_28d/20210216183737_groups_imported.yml
+++ b/config/metrics/counts_28d/20210216183737_groups_imported.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: database
distribution:
diff --git a/config/metrics/counts_28d/20210216184814_i_package_container_deploy_token_monthly.yml b/config/metrics/counts_28d/20210216184814_i_package_container_deploy_token_monthly.yml
index dc08e248c4f..3ddc5ee355a 100644
--- a/config/metrics/counts_28d/20210216184814_i_package_container_deploy_token_monthly.yml
+++ b/config/metrics/counts_28d/20210216184814_i_package_container_deploy_token_monthly.yml
@@ -8,7 +8,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
diff --git a/config/metrics/counts_28d/20210216184818_i_package_debian_deploy_token_monthly.yml b/config/metrics/counts_28d/20210216184818_i_package_debian_deploy_token_monthly.yml
index edb282fd1a1..3de1fc2c0e8 100644
--- a/config/metrics/counts_28d/20210216184818_i_package_debian_deploy_token_monthly.yml
+++ b/config/metrics/counts_28d/20210216184818_i_package_debian_deploy_token_monthly.yml
@@ -8,7 +8,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
diff --git a/config/metrics/counts_28d/20210216184826_i_package_golang_deploy_token_monthly.yml b/config/metrics/counts_28d/20210216184826_i_package_golang_deploy_token_monthly.yml
index 1e3247a7109..c11dead0b06 100644
--- a/config/metrics/counts_28d/20210216184826_i_package_golang_deploy_token_monthly.yml
+++ b/config/metrics/counts_28d/20210216184826_i_package_golang_deploy_token_monthly.yml
@@ -8,7 +8,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
diff --git a/config/metrics/counts_28d/20210216184846_i_package_tag_deploy_token_monthly.yml b/config/metrics/counts_28d/20210216184846_i_package_tag_deploy_token_monthly.yml
index d465a6aff4b..bb6dd458ca6 100644
--- a/config/metrics/counts_28d/20210216184846_i_package_tag_deploy_token_monthly.yml
+++ b/config/metrics/counts_28d/20210216184846_i_package_tag_deploy_token_monthly.yml
@@ -8,7 +8,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
diff --git a/config/metrics/counts_28d/20210216184902_i_package_container_user_monthly.yml b/config/metrics/counts_28d/20210216184902_i_package_container_user_monthly.yml
index 50df5df1b25..0e018dcd1a2 100644
--- a/config/metrics/counts_28d/20210216184902_i_package_container_user_monthly.yml
+++ b/config/metrics/counts_28d/20210216184902_i_package_container_user_monthly.yml
@@ -8,7 +8,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
diff --git a/config/metrics/counts_28d/20210216184906_i_package_debian_user_monthly.yml b/config/metrics/counts_28d/20210216184906_i_package_debian_user_monthly.yml
index cb716aae070..03e9ec5f665 100644
--- a/config/metrics/counts_28d/20210216184906_i_package_debian_user_monthly.yml
+++ b/config/metrics/counts_28d/20210216184906_i_package_debian_user_monthly.yml
@@ -8,7 +8,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
diff --git a/config/metrics/counts_28d/20210216184913_i_package_golang_user_monthly.yml b/config/metrics/counts_28d/20210216184913_i_package_golang_user_monthly.yml
index c1fcfd38e63..5f135e00214 100644
--- a/config/metrics/counts_28d/20210216184913_i_package_golang_user_monthly.yml
+++ b/config/metrics/counts_28d/20210216184913_i_package_golang_user_monthly.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
diff --git a/config/metrics/counts_28d/20210216184933_i_package_tag_user_monthly.yml b/config/metrics/counts_28d/20210216184933_i_package_tag_user_monthly.yml
index f8d411c0348..4912d7fd40d 100644
--- a/config/metrics/counts_28d/20210216184933_i_package_tag_user_monthly.yml
+++ b/config/metrics/counts_28d/20210216184933_i_package_tag_user_monthly.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: deprecated
+status: removed
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
diff --git a/config/metrics/counts_28d/20211216083832_users_clicking_license_testing_visiting_external_website_monthly.yml b/config/metrics/counts_28d/20211216083832_users_clicking_license_testing_visiting_external_website_monthly.yml
new file mode 100644
index 00000000000..24f062f9a10
--- /dev/null
+++ b/config/metrics/counts_28d/20211216083832_users_clicking_license_testing_visiting_external_website_monthly.yml
@@ -0,0 +1,25 @@
+---
+data_category: optional
+key_path: redis_hll_counters.testing.users_clicking_license_testing_visiting_external_website_monthly
+description: Count of users clicking licence to visit external information website
+product_section: sec
+product_stage: secure
+product_group: group::static analysis
+product_category: dependency_scanning
+value_type: number
+status: active
+milestone: '14.7'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76917
+time_frame: 28d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - users_clicking_license_testing_visiting_external_website
+distribution:
+ - ce
+ - ee
+tier:
+ - free
+ - premium
+ - ultimate \ No newline at end of file
diff --git a/config/metrics/counts_7d/20210216184805_i_package_composer_deploy_token_weekly.yml b/config/metrics/counts_7d/20210216184805_i_package_composer_deploy_token_weekly.yml
index 627138b5082..4238901ee7f 100644
--- a/config/metrics/counts_7d/20210216184805_i_package_composer_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210216184805_i_package_composer_deploy_token_weekly.yml
@@ -8,7 +8,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: deprecated
+status: removed
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
diff --git a/config/metrics/counts_7d/20210216184812_i_package_container_deploy_token_weekly.yml b/config/metrics/counts_7d/20210216184812_i_package_container_deploy_token_weekly.yml
index 9fc146d3c86..5e724cef1b7 100644
--- a/config/metrics/counts_7d/20210216184812_i_package_container_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210216184812_i_package_container_deploy_token_weekly.yml
@@ -8,7 +8,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: deprecated
+status: removed
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
diff --git a/config/metrics/counts_7d/20210216184816_i_package_debian_deploy_token_weekly.yml b/config/metrics/counts_7d/20210216184816_i_package_debian_deploy_token_weekly.yml
index 40b86d27bca..6f190f6b4ec 100644
--- a/config/metrics/counts_7d/20210216184816_i_package_debian_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210216184816_i_package_debian_deploy_token_weekly.yml
@@ -8,7 +8,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: deprecated
+status: removed
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
diff --git a/config/metrics/counts_7d/20210216184824_i_package_golang_deploy_token_weekly.yml b/config/metrics/counts_7d/20210216184824_i_package_golang_deploy_token_weekly.yml
index 59b1aef3cb6..00103711910 100644
--- a/config/metrics/counts_7d/20210216184824_i_package_golang_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210216184824_i_package_golang_deploy_token_weekly.yml
@@ -8,7 +8,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: deprecated
+status: removed
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
diff --git a/config/metrics/counts_7d/20210216184844_i_package_tag_deploy_token_weekly.yml b/config/metrics/counts_7d/20210216184844_i_package_tag_deploy_token_weekly.yml
index e28f423b108..9b8ca1c5d7c 100644
--- a/config/metrics/counts_7d/20210216184844_i_package_tag_deploy_token_weekly.yml
+++ b/config/metrics/counts_7d/20210216184844_i_package_tag_deploy_token_weekly.yml
@@ -8,7 +8,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: deprecated
+status: removed
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
diff --git a/config/metrics/counts_7d/20210216184900_i_package_container_user_weekly.yml b/config/metrics/counts_7d/20210216184900_i_package_container_user_weekly.yml
index 313b9b9a68e..abd37cd02d6 100644
--- a/config/metrics/counts_7d/20210216184900_i_package_container_user_weekly.yml
+++ b/config/metrics/counts_7d/20210216184900_i_package_container_user_weekly.yml
@@ -8,7 +8,7 @@ product_stage: package
product_group: group::package
product_category: container registry
value_type: number
-status: deprecated
+status: removed
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
diff --git a/config/metrics/counts_7d/20210216184904_i_package_debian_user_weekly.yml b/config/metrics/counts_7d/20210216184904_i_package_debian_user_weekly.yml
index 2d61d3fa992..29aabf7a7fa 100644
--- a/config/metrics/counts_7d/20210216184904_i_package_debian_user_weekly.yml
+++ b/config/metrics/counts_7d/20210216184904_i_package_debian_user_weekly.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: deprecated
+status: removed
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
diff --git a/config/metrics/counts_7d/20210216184911_i_package_golang_user_weekly.yml b/config/metrics/counts_7d/20210216184911_i_package_golang_user_weekly.yml
index 1ccd4d89b5b..75437f7e174 100644
--- a/config/metrics/counts_7d/20210216184911_i_package_golang_user_weekly.yml
+++ b/config/metrics/counts_7d/20210216184911_i_package_golang_user_weekly.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: deprecated
+status: removed
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
diff --git a/config/metrics/counts_7d/20210216184931_i_package_tag_user_weekly.yml b/config/metrics/counts_7d/20210216184931_i_package_tag_user_weekly.yml
index 5169e2d5519..976ca5febe1 100644
--- a/config/metrics/counts_7d/20210216184931_i_package_tag_user_weekly.yml
+++ b/config/metrics/counts_7d/20210216184931_i_package_tag_user_weekly.yml
@@ -8,7 +8,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: deprecated
+status: removed
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
diff --git a/config/metrics/counts_7d/20211216084934_users_clicking_license_testing_visiting_external_website_weekly.yml b/config/metrics/counts_7d/20211216084934_users_clicking_license_testing_visiting_external_website_weekly.yml
new file mode 100644
index 00000000000..aaa5a4f2675
--- /dev/null
+++ b/config/metrics/counts_7d/20211216084934_users_clicking_license_testing_visiting_external_website_weekly.yml
@@ -0,0 +1,25 @@
+---
+data_category: optional
+key_path: redis_hll_counters.testing.users_clicking_license_testing_visiting_external_website_weekly
+description: Count of users clicking licence to visit external information website
+product_section: sec
+product_stage: secure
+product_group: group::static analysis
+product_category: dependency_scanning
+value_type: number
+status: active
+milestone: '14.7'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76917
+time_frame: 7d
+data_source: redis_hll
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - users_clicking_license_testing_visiting_external_website
+distribution:
+ - ce
+ - ee
+tier:
+ - free
+ - premium
+ - ultimate
diff --git a/config/metrics/counts_all/20210216175053_suggestions.yml b/config/metrics/counts_all/20210216175053_suggestions.yml
index f09a64efc0c..774f355b02c 100644
--- a/config/metrics/counts_all/20210216175053_suggestions.yml
+++ b/config/metrics/counts_all/20210216175053_suggestions.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: active
+status: removed
time_frame: all
data_source: database
distribution:
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
milestone: "<13.9"
+milestone_removed: '14.7'
diff --git a/config/metrics/counts_all/20210216175518_ci_pipeline_config_repository.yml b/config/metrics/counts_all/20210216175518_ci_pipeline_config_repository.yml
index cf850f26d42..2d904295d18 100644
--- a/config/metrics/counts_all/20210216175518_ci_pipeline_config_repository.yml
+++ b/config/metrics/counts_all/20210216175518_ci_pipeline_config_repository.yml
@@ -1,7 +1,7 @@
---
data_category: optional
key_path: counts.ci_pipeline_config_repository
-description: Total Pipelines from templates in repository
+description: Total Pipelines from CI files in repository
product_section: ops
product_stage: verify
product_group: group::pipeline execution
diff --git a/config/metrics/counts_all/20210216175533_ci_pipeline_config_repository.yml b/config/metrics/counts_all/20210216175533_ci_pipeline_config_repository.yml
index 269acb1105e..c28daf950dd 100644
--- a/config/metrics/counts_all/20210216175533_ci_pipeline_config_repository.yml
+++ b/config/metrics/counts_all/20210216175533_ci_pipeline_config_repository.yml
@@ -1,7 +1,7 @@
---
data_category: optional
key_path: usage_activity_by_stage.verify.ci_pipeline_config_repository
-description: Total Pipelines from templates in repository
+description: Total count of unique users creating pipelines from CI files in the repository
product_section: ops
product_stage: verify
product_group: group::pipeline execution
diff --git a/config/metrics/counts_all/20210216180634_gitlab.yml b/config/metrics/counts_all/20210216180634_gitlab.yml
index c157ae84873..491095d836e 100644
--- a/config/metrics/counts_all/20210216180634_gitlab.yml
+++ b/config/metrics/counts_all/20210216180634_gitlab.yml
@@ -8,7 +8,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: all
data_source: database
distribution:
diff --git a/config/metrics/counts_all/20210216180705_total.yml b/config/metrics/counts_all/20210216180705_total.yml
index 5d76fd3873b..a159fe43199 100644
--- a/config/metrics/counts_all/20210216180705_total.yml
+++ b/config/metrics/counts_all/20210216180705_total.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: all
data_source: database
distribution:
diff --git a/config/metrics/counts_all/20210216180707_gitlab_project.yml b/config/metrics/counts_all/20210216180707_gitlab_project.yml
index f0d513e80b3..3627fe7c13f 100644
--- a/config/metrics/counts_all/20210216180707_gitlab_project.yml
+++ b/config/metrics/counts_all/20210216180707_gitlab_project.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: all
data_source: database
distribution:
diff --git a/config/metrics/counts_all/20210216180709_gitlab.yml b/config/metrics/counts_all/20210216180709_gitlab.yml
index ea5e3b25775..97826963cef 100644
--- a/config/metrics/counts_all/20210216180709_gitlab.yml
+++ b/config/metrics/counts_all/20210216180709_gitlab.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: all
data_source: database
distribution:
diff --git a/config/metrics/counts_all/20210216180711_github.yml b/config/metrics/counts_all/20210216180711_github.yml
index cd3fd06d057..1df68631a35 100644
--- a/config/metrics/counts_all/20210216180711_github.yml
+++ b/config/metrics/counts_all/20210216180711_github.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: all
data_source: database
distribution:
diff --git a/config/metrics/counts_all/20210216180713_bitbucket.yml b/config/metrics/counts_all/20210216180713_bitbucket.yml
index d0eb23fc41a..c2ad8aeb57b 100644
--- a/config/metrics/counts_all/20210216180713_bitbucket.yml
+++ b/config/metrics/counts_all/20210216180713_bitbucket.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: all
data_source: database
distribution:
diff --git a/config/metrics/counts_all/20210216180715_bitbucket_server.yml b/config/metrics/counts_all/20210216180715_bitbucket_server.yml
index 9a3de0cb330..d588f1f48cf 100644
--- a/config/metrics/counts_all/20210216180715_bitbucket_server.yml
+++ b/config/metrics/counts_all/20210216180715_bitbucket_server.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: all
data_source: database
distribution:
diff --git a/config/metrics/counts_all/20210216180716_gitea.yml b/config/metrics/counts_all/20210216180716_gitea.yml
index b107b213a30..7e585cd6808 100644
--- a/config/metrics/counts_all/20210216180716_gitea.yml
+++ b/config/metrics/counts_all/20210216180716_gitea.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: all
data_source: database
distribution:
diff --git a/config/metrics/counts_all/20210216180718_git.yml b/config/metrics/counts_all/20210216180718_git.yml
index 0cd399a65ec..9e23899875a 100644
--- a/config/metrics/counts_all/20210216180718_git.yml
+++ b/config/metrics/counts_all/20210216180718_git.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: all
data_source: database
distribution:
diff --git a/config/metrics/counts_all/20210216180720_manifest.yml b/config/metrics/counts_all/20210216180720_manifest.yml
index b91ae015f6e..07a5e2ce282 100644
--- a/config/metrics/counts_all/20210216180720_manifest.yml
+++ b/config/metrics/counts_all/20210216180720_manifest.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: all
data_source: database
distribution:
diff --git a/config/metrics/counts_all/20210216180722_jira.yml b/config/metrics/counts_all/20210216180722_jira.yml
index 89ea9da081d..a069aa329a7 100644
--- a/config/metrics/counts_all/20210216180722_jira.yml
+++ b/config/metrics/counts_all/20210216180722_jira.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: all
data_source: database
distribution:
diff --git a/config/metrics/counts_all/20210216180724_fogbugz.yml b/config/metrics/counts_all/20210216180724_fogbugz.yml
index e9cb3159301..ff1abeef151 100644
--- a/config/metrics/counts_all/20210216180724_fogbugz.yml
+++ b/config/metrics/counts_all/20210216180724_fogbugz.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: all
data_source: database
distribution:
diff --git a/config/metrics/counts_all/20210216180726_phabricator.yml b/config/metrics/counts_all/20210216180726_phabricator.yml
index 933047aff58..e7de4c560bd 100644
--- a/config/metrics/counts_all/20210216180726_phabricator.yml
+++ b/config/metrics/counts_all/20210216180726_phabricator.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: all
data_source: database
distribution:
diff --git a/config/metrics/counts_all/20210216180727_csv.yml b/config/metrics/counts_all/20210216180727_csv.yml
index e6bc3eba973..a132f2e53c1 100644
--- a/config/metrics/counts_all/20210216180727_csv.yml
+++ b/config/metrics/counts_all/20210216180727_csv.yml
@@ -8,7 +8,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: all
data_source: database
distribution:
diff --git a/config/metrics/counts_all/20210216180729_groups_imported.yml b/config/metrics/counts_all/20210216180729_groups_imported.yml
index 32e968c76e2..5631a1315e6 100644
--- a/config/metrics/counts_all/20210216180729_groups_imported.yml
+++ b/config/metrics/counts_all/20210216180729_groups_imported.yml
@@ -7,7 +7,7 @@ product_stage: manage
product_group: group::import
product_category: importers
value_type: number
-status: deprecated
+status: removed
time_frame: all
data_source: database
distribution:
diff --git a/config/metrics/counts_all/20210216183017_package_events_i_package_tag_delete_package.yml b/config/metrics/counts_all/20210216183017_package_events_i_package_tag_delete_package.yml
index 580f06259a1..7f5dab5e1bc 100644
--- a/config/metrics/counts_all/20210216183017_package_events_i_package_tag_delete_package.yml
+++ b/config/metrics/counts_all/20210216183017_package_events_i_package_tag_delete_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: deprecated
+status: removed
time_frame: all
data_source: redis
distribution:
diff --git a/config/metrics/counts_all/20210216183019_package_events_i_package_tag_pull_package.yml b/config/metrics/counts_all/20210216183019_package_events_i_package_tag_pull_package.yml
index cb399d23ed1..6cf631953f6 100644
--- a/config/metrics/counts_all/20210216183019_package_events_i_package_tag_pull_package.yml
+++ b/config/metrics/counts_all/20210216183019_package_events_i_package_tag_pull_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: deprecated
+status: removed
time_frame: all
data_source: redis
distribution:
diff --git a/config/metrics/counts_all/20210216183021_package_events_i_package_tag_push_package.yml b/config/metrics/counts_all/20210216183021_package_events_i_package_tag_push_package.yml
index aa32883e6a5..dbd553d3ea1 100644
--- a/config/metrics/counts_all/20210216183021_package_events_i_package_tag_push_package.yml
+++ b/config/metrics/counts_all/20210216183021_package_events_i_package_tag_push_package.yml
@@ -7,7 +7,7 @@ product_stage: package
product_group: group::package
product_category: package registry
value_type: number
-status: deprecated
+status: removed
time_frame: all
data_source: redis
distribution:
diff --git a/config/metrics/schema.json b/config/metrics/schema.json
index d416c7b6d6e..09376e32ef0 100644
--- a/config/metrics/schema.json
+++ b/config/metrics/schema.json
@@ -30,7 +30,7 @@
},
"status": {
"type": ["string"],
- "enum": ["active", "deprecated", "removed", "broken"]
+ "enum": ["active", "removed", "broken"]
},
"milestone": {
"type": ["string"],
diff --git a/config/metrics/settings/20211201012652_flavor.yml b/config/metrics/settings/20211201012652_flavor.yml
new file mode 100644
index 00000000000..3a409424eef
--- /dev/null
+++ b/config/metrics/settings/20211201012652_flavor.yml
@@ -0,0 +1,24 @@
+---
+key_path: database.flavor
+description: What PostgreSQL flavor is being used. Possible values are
+ "Amazon Aurora PostgreSQL", "PostgreSQL on Amazon RDS", "Cloud SQL for PostgreSQL",
+ "Azure Database for PostgreSQL - Single Server", "Azure Database for PostgreSQL - Flexible Server",
+ or "null".
+product_section: enablement
+product_stage: enablement
+product_group: group::database
+product_category: database
+value_type: string
+status: active
+milestone: "14.6"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75587
+time_frame: none
+data_source: system
+data_category: optional
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/object_store_settings.rb b/config/object_store_settings.rb
index 8cbb3451a16..53fbfb088db 100644
--- a/config/object_store_settings.rb
+++ b/config/object_store_settings.rb
@@ -2,7 +2,7 @@
# Set default values for object_store settings
class ObjectStoreSettings
- SUPPORTED_TYPES = %w(artifacts external_diffs lfs uploads packages dependency_proxy terraform_state pages).freeze
+ SUPPORTED_TYPES = %w(artifacts external_diffs lfs uploads packages dependency_proxy terraform_state pages secure_files).freeze
ALLOWED_OBJECT_STORE_OVERRIDES = %w(bucket enabled proxy_download).freeze
# To ensure the one Workhorse credential matches the Rails config, we
diff --git a/config/routes.rb b/config/routes.rb
index b02c1380c7e..5d20d070c20 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -20,7 +20,6 @@ Rails.application.routes.draw do
get 'favicon.png', to: favicon_redirect
get 'favicon.ico', to: favicon_redirect
- draw :sherlock
draw :development
use_doorkeeper do
@@ -108,6 +107,9 @@ Rails.application.routes.draw do
get '/autocomplete/namespace_routes' => 'autocomplete#namespace_routes'
end
+ # sandbox
+ get '/sandbox/mermaid' => 'sandbox#mermaid'
+
get '/whats_new' => 'whats_new#index'
# '/-/health' implemented by BasicHealthCheck middleware
@@ -145,9 +147,6 @@ Rails.application.routes.draw do
get 'acme-challenge/' => 'acme_challenges#show'
- # UserCallouts
- resources :user_callouts, controller: 'users/callouts', only: [:create] # remove after 14.6 2021-12-22 to handle mixed deployments
-
scope :ide, as: :ide, format: false do
get '/', to: 'ide#index'
get '/project', to: 'ide#index'
diff --git a/config/routes/admin.rb b/config/routes/admin.rb
index 7f19f6b8427..ed1afc9efa3 100644
--- a/config/routes/admin.rb
+++ b/config/routes/admin.rb
@@ -159,7 +159,7 @@ namespace :admin do
resources :labels
- resources :runners, only: [:index, :show, :update, :destroy] do
+ resources :runners, only: [:index, :show, :edit, :update, :destroy] do
member do
post :resume
post :pause
diff --git a/config/routes/group.rb b/config/routes/group.rb
index da205163e6d..c313f7209fb 100644
--- a/config/routes/group.rb
+++ b/config/routes/group.rb
@@ -43,6 +43,12 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
post :create_deploy_token, path: 'deploy_token/create'
end
+ resources :access_tokens, only: [:index, :create] do
+ member do
+ put :revoke
+ end
+ end
+
resources :integrations, only: [:index, :edit, :update] do
member do
put :test
@@ -64,7 +70,7 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
post :toggle_subscription, on: :member
end
- resources :packages, only: [:index]
+ resources :packages, only: [:index, :show]
resources :milestones, constraints: { id: %r{[^/]+} } do
member do
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 5f1b35d67c0..702ef64a2ca 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -212,7 +212,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end
end
- resources :services, constraints: { id: %r{[^/]+} }, only: [:edit, :update] do
+ resources :integrations, controller: :services, constraints: { id: %r{[^/]+} }, only: [:edit, :update] do
member do
put :test
end
@@ -319,6 +319,9 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
namespace :google_cloud do
resources :service_accounts, only: [:index, :create]
+
+ get '/deployments/cloud_run', to: 'deployments#cloud_run'
+ get '/deployments/cloud_storage', to: 'deployments#cloud_storage'
end
resources :environments, except: [:destroy] do
diff --git a/config/routes/sherlock.rb b/config/routes/sherlock.rb
deleted file mode 100644
index a9be434dba7..00000000000
--- a/config/routes/sherlock.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-if Gitlab::Sherlock.enabled?
- namespace :sherlock do
- resources :transactions, only: [:index, :show] do
- resources :queries, only: [:show]
- resources :file_samples, only: [:show]
-
- collection do
- delete :destroy_all
- end
- end
- end
-end
diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml
index 49989e022fa..bf84527bc5f 100644
--- a/config/sidekiq_queues.yml
+++ b/config/sidekiq_queues.yml
@@ -73,8 +73,12 @@
- 1
- - ci_delete_objects
- 1
+- - ci_job_artifacts_expire_project_build_artifacts
+ - 1
- - ci_upstream_projects_subscriptions_cleanup
- 1
+- - cluster_agent
+ - 1
- - container_repository
- 1
- - create_commit_signature
@@ -207,6 +211,8 @@
- 1
- - incident_management_pending_escalations_issue_check
- 1
+- - incident_management_pending_escalations_issue_create
+ - 1
- - integrations_create_external_cross_reference
- 1
- - invalid_gpg_signature_update
@@ -255,6 +261,8 @@
- 1
- - merge_requests_sync_code_owner_approval_rules
- 1
+- - merge_requests_update_head_pipeline
+ - 1
- - metrics_dashboard_prune_old_annotations
- 1
- - metrics_dashboard_sync_dashboards
@@ -289,6 +297,8 @@
- 1
- - object_storage
- 1
+- - package_cleanup
+ - 1
- - package_repositories
- 1
- - packages_composer_cache_update
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 7eaa11d9346..912c2fe5c45 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -1,4 +1,6 @@
-const crypto = require('crypto');
+// eslint-disable-next-line import/order
+const crypto = require('./helpers/patched_crypto');
+
const fs = require('fs');
const path = require('path');
@@ -141,6 +143,7 @@ function generateEntries() {
sentry: './sentry/index.js',
performance_bar: './performance_bar/index.js',
jira_connect_app: './jira_connect/subscriptions/index.js',
+ sandboxed_mermaid: './lib/mermaid.js',
};
return Object.assign(manualEntries, incrementalCompiler.filterEntryPoints(autoEntries));
diff --git a/danger/datateam/Dangerfile b/danger/datateam/Dangerfile
index 263fd4aa8e3..ed2703f31e6 100644
--- a/danger/datateam/Dangerfile
+++ b/danger/datateam/Dangerfile
@@ -1,19 +1,3 @@
# frozen_string_literal: true
-DATA_WAREHOUSE_LABELS = [
- "Data Warehouse::Impact Check",
- "Data Warehouse::Impacted",
- "Data Warehouse::Not Impacted"
-].freeze
-
-CHANGED_SCHEMA_MESSAGE = <<~MSG
-Notification to the Data Team about changes to the db/structure.sql file, add label `Data Warehouse::Impact Check`.
-
-/label ~"Data Warehouse::Impact Check"
-
-MSG
-
-db_schema_updated = !git.modified_files.grep(%r{\Adb/structure\.sql}).empty?
-no_data_warehouse_labels = (gitlab.mr_labels & DATA_WAREHOUSE_LABELS).empty?
-
-markdown(CHANGED_SCHEMA_MESSAGE) if db_schema_updated && no_data_warehouse_labels
+markdown(datateam.build_message) if datateam.impacted?
diff --git a/danger/plugins/datateam.rb b/danger/plugins/datateam.rb
new file mode 100644
index 00000000000..110414a50e2
--- /dev/null
+++ b/danger/plugins/datateam.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require_relative '../../tooling/danger/datateam'
+
+module Danger
+ class Datateam < ::Danger::Plugin
+ include Tooling::Danger::Datateam
+ end
+end
diff --git a/data/deprecations/ runner-s3-authenticationtype-nonexplicit-config-deprecation.yml b/data/deprecations/ runner-s3-authenticationtype-nonexplicit-config-deprecation.yml
deleted file mode 100644
index c4c5f6258b4..00000000000
--- a/data/deprecations/ runner-s3-authenticationtype-nonexplicit-config-deprecation.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-- name: "Must explicitly assign `AuthenticationType` for `[runners.cache.s3]`"
- 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
- 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.
- stage: Verify
- tiers: [Core, Premium, Ultimate]
- issue_url: https://gitlab.com/gitlab-org/gitlab-runner/-/issues/28171
- documentation_url: https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnerscaches3-section
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 a1261154e8c..7e2d8338dfd 100644
--- a/data/deprecations/14-0-nfs-fot-git-repository-storage.yml
+++ b/data/deprecations/14-0-nfs-fot-git-repository-storage.yml
@@ -2,7 +2,8 @@
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" # the date of the milestone release 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.
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.
diff --git a/data/deprecations/14-2-deprecation-release-cli.yml b/data/deprecations/14-2-deprecation-release-cli.yml
new file mode 100644
index 00000000000..809d8eb1e8b
--- /dev/null
+++ b/data/deprecations/14-2-deprecation-release-cli.yml
@@ -0,0 +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
+ breaking_change: false
+ 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
diff --git a/data/deprecations/14-2-deprecation-task-runner.yml b/data/deprecations/14-2-deprecation-task-runner.yml
index 9f4d81ddd3a..8162b5c4d4e 100644
--- a/data/deprecations/14-2-deprecation-task-runner.yml
+++ b/data/deprecations/14-2-deprecation-task-runner.yml
@@ -3,6 +3,7 @@
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.
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).
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 e460abcb077..29e55337261 100644
--- a/data/deprecations/14-3-database-deprecate-legacy-database-conf.yml
+++ b/data/deprecations/14-3-database-deprecate-legacy-database-conf.yml
@@ -3,12 +3,13 @@
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
+ breaking_change: true
body: |
- The syntax of [GitLabs database](https://docs.gitlab.com/omnibus/settings/database.html)
- configuration located in `database.yml` is changing and the legacy format is deprecated. The legacy format
- supported using a single PostgreSQL adapter, whereas the new format is changing to support multiple databases. The `main:` database needs to be defined as a first configuration item.
-
- This deprecation mainly impacts users compiling GitLab from source because Omnibus will handle this configuration automatically.
+ The syntax of [GitLabs database](https://docs.gitlab.com/omnibus/settings/database.html)
+ configuration located in `database.yml` is changing and the legacy format is deprecated. The legacy format
+ supported using a single PostgreSQL adapter, whereas the new format is changing to support multiple databases. The `main:` database needs to be defined as a first configuration item.
+
+ This deprecation mainly impacts users compiling GitLab from source because Omnibus will handle this configuration automatically.
stage: Enablement
tiers: [Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338182
diff --git a/data/deprecations/14-3-deprecation-release-cli.yml b/data/deprecations/14-3-deprecation-release-cli.yml
deleted file mode 100644
index d04e97df380..00000000000
--- a/data/deprecations/14-3-deprecation-release-cli.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-- name: "Release CLI be 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
- 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
diff --git a/data/deprecations/14-3-deprecation_omniauth-kerberos_gem.yml b/data/deprecations/14-3-deprecation_omniauth-kerberos_gem.yml
new file mode 100644
index 00000000000..17c6cbc8e7a
--- /dev/null
+++ b/data/deprecations/14-3-deprecation_omniauth-kerberos_gem.yml
@@ -0,0 +1,17 @@
+- name: "OmniAuth Kerberos gem"
+ announcement_milestone: "14.3"
+ announcement_date: "2021-09-22"
+ removal_milestone: "15.0"
+ removal_date: "2022-05-22"
+ breaking_change: true
+ body: | # Do not modify this line, instead modify the lines below.
+ The `omniauth-kerberos` gem will be removed in our next major release, GitLab 15.0.
+
+ This gem has not been maintained and has very little usage. We therefore plan to remove support for this authentication method and recommend using the Kerberos [SPNEGO](https://en.wikipedia.org/wiki/SPNEGO) integration instead. You can follow the [upgrade instructions](https://docs.gitlab.com/ee/integration/kerberos.html#upgrading-from-password-based-to-ticket-based-kerberos-sign-ins) to upgrade from the `omniauth-kerberos` integration to the supported one.
+
+ Note that we are not deprecating the Kerberos SPNEGO integration, only the old password-based Kerberos integration.
+ stage: Manage
+ tiers: [Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337384
+ documentation_url: https://docs.gitlab.com/ee/integration/kerberos.html#upgrading-from-password-based-to-ticket-based-kerberos-sign-ins
+
diff --git a/data/deprecations/14-3-package-container-registry-api-group-update.yml b/data/deprecations/14-3-package-container-registry-api-group-update.yml
deleted file mode 100644
index de5d184888a..00000000000
--- a/data/deprecations/14-3-package-container-registry-api-group-update.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-- name: "Update to the Container Registry group-level API"
- announcement_milestone: "14.5" # 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" # 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.
- 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.
- stage: Package
- tiers: Free
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/336912
- documentation_url: https://docs.gitlab.com/ee/api/container_registry.html#within-a-group
- announcement_date: 2021-11-22
diff --git a/data/deprecations/14-3-repository-push-audit-events.yml b/data/deprecations/14-3-repository-push-audit-events.yml
index defa4576cde..72281be5e97 100644
--- a/data/deprecations/14-3-repository-push-audit-events.yml
+++ b/data/deprecations/14-3-repository-push-audit-events.yml
@@ -1,7 +1,9 @@
- 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
+ breaking_change: true
body: | # Do not modify this line, instead modify the lines below.
Audit events for [repository events](https://docs.gitlab.com/ee/administration/audit_events.html#repository-push) are now deprecated and will be removed in GitLab 15.0.
@@ -12,4 +14,3 @@
tiers: Premium
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337993
documentation_url: https://docs.gitlab.com/ee/administration/audit_events.html#repository-push
- announcement_date: "2021-09-22" # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69024
diff --git a/data/deprecations/14-3-serverless.yml b/data/deprecations/14-3-serverless.yml
new file mode 100644
index 00000000000..aac3cc9cd6a
--- /dev/null
+++ b/data/deprecations/14-3-serverless.yml
@@ -0,0 +1,14 @@
+- name: "GitLab Serverless"
+ announcement_milestone: "14.3"
+ announcement_date: "2021-09-22"
+ removal_milestone: "15.0"
+ removal_date: "2022-05-22"
+ breaking_change: true
+ body: |
+ [GitLab Serverless](https://docs.gitlab.com/ee/user/project/clusters/serverless/) is a feature set to support Knative-based serverless development with automatic deployments and monitoring.
+
+ We decided to remove the GitLab Serverless features as they never really resonated with our users. Besides, given the continuous development of Kubernetes and Knative, our current implementations do not even work with recent versions.
+ stage: Configure
+ tiers: [Core, Premium, Ultimate]
+ issue_url: "https://gitlab.com/groups/gitlab-org/configure/-/epics/6"
+ documentation_url: "https://docs.gitlab.com/ee/user/project/clusters/serverless/"
diff --git a/data/deprecations/14-5-certificate-based-integration-with-kubernetes.yml b/data/deprecations/14-5-certificate-based-integration-with-kubernetes.yml
index e93fa25facb..60664f785b2 100644
--- a/data/deprecations/14-5-certificate-based-integration-with-kubernetes.yml
+++ b/data/deprecations/14-5-certificate-based-integration-with-kubernetes.yml
@@ -3,6 +3,7 @@
announcement_date: "2021-11-15"
removal_milestone: "15.0"
removal_date: "2022-05-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 not yet planned and we will communicate
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 29b8fe0e70c..b33f2cc88f1 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
@@ -3,10 +3,10 @@
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
+ breaking_change: true
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
tiers: [Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/345347
-
diff --git a/data/deprecations/14-5-deprecate-defaultMergeCommitMessageWithDescription-graphql.yml b/data/deprecations/14-5-deprecate-defaultMergeCommitMessageWithDescription-graphql.yml
new file mode 100644
index 00000000000..6fb97cbc7f4
--- /dev/null
+++ b/data/deprecations/14-5-deprecate-defaultMergeCommitMessageWithDescription-graphql.yml
@@ -0,0 +1,15 @@
+- name: "Removal of `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.
+ 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
diff --git a/data/deprecations/14-5-deprecate-opensuse-15-2.yml b/data/deprecations/14-5-deprecate-opensuse-15-2.yml
index 7b776293dbb..f95a80e6eac 100644
--- a/data/deprecations/14-5-deprecate-opensuse-15-2.yml
+++ b/data/deprecations/14-5-deprecate-opensuse-15-2.yml
@@ -3,6 +3,7 @@
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.
Distribution support and security updates for openSUSE Leap 15.2 are [ending December 2021](https://en.opensuse.org/Lifetime#openSUSE_Leap).
diff --git a/data/deprecations/14-5-deprecate-sles-12sp2.yml b/data/deprecations/14-5-deprecate-sles-12sp2.yml
new file mode 100644
index 00000000000..61e989defd3
--- /dev/null
+++ b/data/deprecations/14-5-deprecate-sles-12sp2.yml
@@ -0,0 +1,8 @@
+- name: "Deprecate 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
+ breaking_change: true
+ 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
new file mode 100644
index 00000000000..78db5c0d414
--- /dev/null
+++ b/data/deprecations/14-5-deprecation-versions-packagetype.yml
@@ -0,0 +1,13 @@
+- name: "Deprecate `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
+ breaking_change: true
+ 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`.
+ stage: package
+ tiers: Free
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/327453
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 5706e826a9d..2c16aca5df6 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
@@ -3,9 +3,10 @@
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.
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]
diff --git a/data/deprecations/14-5-disable_strict_host_key_checking.yml b/data/deprecations/14-5-disable_strict_host_key_checking.yml
new file mode 100644
index 00000000000..a3a6a3bf223
--- /dev/null
+++ b/data/deprecations/14-5-disable_strict_host_key_checking.yml
@@ -0,0 +1,14 @@
+- name: "Known host required for GitLab Runner SSH executor"
+ 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"
+ breaking_change: true
+ 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.
+ stage: Verify
+ tiers: [Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab-runner/-/issues/28192
+ documentation_url: https://docs.gitlab.com/runner/executors/ssh.html#security
diff --git a/data/deprecations/14-5-geo-deprecate-promote-db.yml b/data/deprecations/14-5-geo-deprecate-promote-db.yml
index ba2aa7dc032..113ddc53165 100644
--- a/data/deprecations/14-5-geo-deprecate-promote-db.yml
+++ b/data/deprecations/14-5-geo-deprecate-promote-db.yml
@@ -1,19 +1,9 @@
-# This is a template for a feature deprecation
-# A deprecation typically occurs when a feature or capability is planned to be removed in a future release.
-# Deprecations should be announced at least two releases prior to removal. Any breaking changes should only be done in major releases.
-#
-# Below is an example of what a single entry should look like, it's required attributes,
-# and what types we expect those attribute values to be.
-#
-# For more information please refer to the handbook documentation here:
-# {{LINK TBD}}
-#
-# Please delete this line and above before submitting your merge request.
-
- name: "Removal of `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.
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"
@@ -22,4 +12,3 @@
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"
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 29301ed3c47..591ca6f6a87 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,19 +1,9 @@
-# This is a template for a feature deprecation
-# A deprecation typically occurs when a feature or capability is planned to be removed in a future release.
-# Deprecations should be announced at least two releases prior to removal. Any breaking changes should only be done in major releases.
-#
-# Below is an example of what a single entry should look like, it's required attributes,
-# and what types we expect those attribute values to be.
-#
-# For more information please refer to the handbook documentation here:
-# {{LINK TBD}}
-#
-# Please delete this line and above before submitting your merge request.
-
- name: "Removal of `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.
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"
@@ -22,4 +12,3 @@
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"
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
new file mode 100644
index 00000000000..951de288d90
--- /dev/null
+++ b/data/deprecations/14-5-package-container-registry-api-group-update.yml
@@ -0,0 +1,14 @@
+- name: "Update to the Container Registry group-level API"
+ 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
+ breaking_change: true
+ 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.
+ stage: Package
+ tiers: Free
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/336912
+ documentation_url: https://docs.gitlab.com/ee/api/container_registry.html#within-a-group
diff --git a/data/deprecations/14-5-remove-dependency-proxy-permissions-flag.yml b/data/deprecations/14-5-remove-dependency-proxy-permissions-flag.yml
new file mode 100644
index 00000000000..1e6a4e7d378
--- /dev/null
+++ b/data/deprecations/14-5-remove-dependency-proxy-permissions-flag.yml
@@ -0,0 +1,13 @@
+- name: "Remove the `: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.
+ 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.
+ stage: package
+ tiers: Free
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/276777
diff --git a/data/deprecations/14-5-remove-package-pipelines-api.yml b/data/deprecations/14-5-remove-package-pipelines-api.yml
new file mode 100644
index 00000000000..46ef1213da8
--- /dev/null
+++ b/data/deprecations/14-5-remove-package-pipelines-api.yml
@@ -0,0 +1,13 @@
+- 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.
+ 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.
+ stage: package
+ tiers: Free
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/289956
diff --git a/data/deprecations/14-5-remove-pipelines-from-version-field.yml b/data/deprecations/14-5-remove-pipelines-from-version-field.yml
new file mode 100644
index 00000000000..917442219e5
--- /dev/null
+++ b/data/deprecations/14-5-remove-pipelines-from-version-field.yml
@@ -0,0 +1,16 @@
+- name: "Remove the `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.
+ 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.
+
+ 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.
+ stage: package
+ tiers: Free
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/342882
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 5cf7b107354..dd2e6e7a6fb 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,7 +1,9 @@
- name: "REST API Runner will not contain `paused`"
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
+ breaking_change: true
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.
@@ -14,4 +16,3 @@
tiers: [Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/344648
documentation_url: https://docs.gitlab.com/ee/api/runners.html
- announcement_date: "2021-11-22"
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
new file mode 100644
index 00000000000..d957b79e450
--- /dev/null
+++ b/data/deprecations/14-5-runner-s3-authenticationtype-nonexplicit-config-deprecation.yml
@@ -0,0 +1,14 @@
+- name: "Must explicitly assign `AuthenticationType` for `[runners.cache.s3]`"
+ 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
+ breaking_change: true
+ 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.
+ stage: Verify
+ tiers: [Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab-runner/-/issues/28171
+ documentation_url: https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnerscaches3-section
diff --git a/data/deprecations/14-6-Enforce-validation-of-security-schemas.yml b/data/deprecations/14-6-Enforce-validation-of-security-schemas.yml
new file mode 100644
index 00000000000..42de723ee99
--- /dev/null
+++ b/data/deprecations/14-6-Enforce-validation-of-security-schemas.yml
@@ -0,0 +1,26 @@
+- 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.
+
+ Security tools that [integrate with GitLab by outputting security reports](https://docs.gitlab.com/ee/development/integrations/secure.html#report)
+ as pipeline job artifacts are affected. You must ensure that all output reports adhere to the correct
+ schema with a minimum version of 14.0.0. Reports with a lower version or that fail to validate
+ against the declared schema version will not be processed, and vulnerability
+ findings will not display in MRs, pipelines, or Vulnerability Reports.
+
+ To help with the transition, from GitLab 14.10, non-compliant reports will display a
+ [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
diff --git a/data/deprecations/14-6-container-scanning-schemas-below-14.yml b/data/deprecations/14-6-container-scanning-schemas-below-14.yml
new file mode 100644
index 00000000000..b79418d5765
--- /dev/null
+++ b/data/deprecations/14-6-container-scanning-schemas-below-14.yml
@@ -0,0 +1,23 @@
+- 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.
+
+ Third-party tools that [integrate with GitLab by outputting a container scanning security report](https://docs.gitlab.com/ee/development/integrations/secure.html#report)
+ as a pipeline job artifact are affected. You must ensure that all output reports adhere to the correct schema with a minimum version of 14.0.0. Reports with a lower version or that fail to validate against the declared schema version will not be processed, and vulnerability findings will not display in MRs, pipelines, or Vulnerability Reports.
+
+ To help with the transition, from GitLab 14.10, non-compliant reports will display a
+ [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
diff --git a/data/deprecations/14-6-coverage-fuzzing-schemas-below-14.yml b/data/deprecations/14-6-coverage-fuzzing-schemas-below-14.yml
new file mode 100644
index 00000000000..13babcc26ba
--- /dev/null
+++ b/data/deprecations/14-6-coverage-fuzzing-schemas-below-14.yml
@@ -0,0 +1,26 @@
+- 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.
+
+ Third-party tools that [integrate with GitLab by outputting a coverage guided fuzzing security report](https://docs.gitlab.com/ee/development/integrations/secure.html#report)
+ as a pipeline job artifact are affected. You must ensure that all output reports adhere to the correct
+ schema with a minimum version of 14.0.0. Any reports with a lower version or that fail to validate
+ against the declared schema version will not be processed, and vulnerability
+ findings will not display in MRs, pipelines, or Vulnerability Reports.
+
+ To help with the transition, from GitLab 14.10, non-compliant reports will display a
+ [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
diff --git a/data/deprecations/14-6-dast-schemas-below-14.yml b/data/deprecations/14-6-dast-schemas-below-14.yml
new file mode 100644
index 00000000000..afd27a1fa7a
--- /dev/null
+++ b/data/deprecations/14-6-dast-schemas-below-14.yml
@@ -0,0 +1,26 @@
+- 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.
+
+ Third-party tools that [integrate with GitLab by outputting a DAST security report](https://docs.gitlab.com/ee/development/integrations/secure.html#report)
+ as a pipeline job artifact are affected. You must ensure that all output reports adhere to the correct
+ schema with a minimum version of 14.0.0. Reports with a lower version or that fail to validate
+ against the declared schema version will not be processed, and vulnerability
+ findings will not display in MRs, pipelines, or Vulnerability Reports.
+
+ To help with the transition, from GitLab 14.10, non-compliant reports will cause a
+ [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
diff --git a/data/deprecations/14-6-dependency-scanning-schemas-below-14.yml b/data/deprecations/14-6-dependency-scanning-schemas-below-14.yml
new file mode 100644
index 00000000000..226cffc3afc
--- /dev/null
+++ b/data/deprecations/14-6-dependency-scanning-schemas-below-14.yml
@@ -0,0 +1,26 @@
+- 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.
+
+ Third-party tools that [integrate with GitLab by outputting a Dependency scanning security report](https://docs.gitlab.com/ee/development/integrations/secure.html#report)
+ as a pipeline job artifact are affected. You must ensure that all output reports adhere to the correct
+ schema with a minimum version of 14.0.0. Reports with a lower version or that fail to validate
+ against the declared schema version will not be processed, and vulnerability
+ findings will not display in MRs, pipelines, or Vulnerability Reports.
+
+ To help with the transition, from GitLab 14.10, non-compliant reports will cause a
+ [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
diff --git a/data/deprecations/14-6-deprecate-types.yml b/data/deprecations/14-6-deprecate-types.yml
index 5cbc07efa89..3e04ad1d6fe 100644
--- a/data/deprecations/14-6-deprecate-types.yml
+++ b/data/deprecations/14-6-deprecate-types.yml
@@ -3,8 +3,9 @@
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.
- 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 `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]
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 d75b668f111..55c74ddfabd 100644
--- a/data/deprecations/14-6-deprecation-license-compliance-api-terms.yml
+++ b/data/deprecations/14-6-deprecation-license-compliance-api-terms.yml
@@ -2,10 +2,11 @@
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.
- 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.
+ 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.
+ 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]
@@ -13,4 +14,4 @@
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
+ 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 23e59da21e4..8cf0ddc49f4 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
@@ -2,8 +2,9 @@
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.
- 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.
+ 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.
@@ -13,4 +14,4 @@
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
+ 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
new file mode 100644
index 00000000000..6570b1b8e81
--- /dev/null
+++ b/data/deprecations/14-6-job_char_limit.yml
@@ -0,0 +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
+ breaking_change: true
+ 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
diff --git a/data/deprecations/14-6-pipeline-fields-package-deprecation.yml b/data/deprecations/14-6-pipeline-fields-package-deprecation.yml
index b06bb4d16dc..b9140a84cdd 100644
--- a/data/deprecations/14-6-pipeline-fields-package-deprecation.yml
+++ b/data/deprecations/14-6-pipeline-fields-package-deprecation.yml
@@ -3,6 +3,7 @@
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.
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.
diff --git a/data/deprecations/14-6-remove-api-fuzzing-ci-configuration-create-mutation.yml b/data/deprecations/14-6-remove-api-fuzzing-ci-configuration-create-mutation.yml
index f2b22b047af..bdf7a64700b 100644
--- a/data/deprecations/14-6-remove-api-fuzzing-ci-configuration-create-mutation.yml
+++ b/data/deprecations/14-6-remove-api-fuzzing-ci-configuration-create-mutation.yml
@@ -2,6 +2,8 @@
announcement_milestone: "14.6"
announcement_date: "2021-12-22"
removal_milestone: "15.0"
+ removal_date: "2022-05-22"
+ breaking_change: true
body: |
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
@@ -10,4 +12,3 @@
tiers: Ultimate
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/333233
documentation_url: https://docs.gitlab.com/ee/user/application_security/api_fuzzing/#web-api-fuzzing-configuration-form
- removal_date: "2022-05-22"
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 5f7db1ac0e5..5654d3227eb 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
@@ -2,6 +2,7 @@
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.
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
new file mode 100644
index 00000000000..3cf6ed69354
--- /dev/null
+++ b/data/deprecations/14-6-runner_api_new_stale_status_breaking_change.yml
@@ -0,0 +1,14 @@
+- 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_date: "2021-12-22"
+ 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.
+ 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.
+ stage: Verify
+ tiers: [Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/347303
+ documentation_url: https://docs.gitlab.com/ee/api/runners.html#runners-api
diff --git a/data/deprecations/14-6-sast-schemas-below-14.yml b/data/deprecations/14-6-sast-schemas-below-14.yml
new file mode 100644
index 00000000000..02e112ec4b8
--- /dev/null
+++ b/data/deprecations/14-6-sast-schemas-below-14.yml
@@ -0,0 +1,26 @@
+- 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.
+
+ Third-party tools that [integrate with GitLab by outputting a SAST security report](https://docs.gitlab.com/ee/development/integrations/secure.html#report)
+ as a pipeline job artifact are affected. You must ensure that all output reports adhere to the correct
+ schema with a minimum version of 14.0.0. Reports with a lower version or that fail to validate
+ against the declared schema version will not be processed, and vulnerability
+ findings will not display in MRs, pipelines, or Vulnerability Reports.
+
+ To help with the transition, from GitLab 14.10, non-compliant reports will display a
+ [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
diff --git a/data/deprecations/14-6-secret-detection-schemas-below-14.yml b/data/deprecations/14-6-secret-detection-schemas-below-14.yml
new file mode 100644
index 00000000000..d366e08a8c0
--- /dev/null
+++ b/data/deprecations/14-6-secret-detection-schemas-below-14.yml
@@ -0,0 +1,26 @@
+- 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.
+
+ Third-party tools that [integrate with GitLab by outputting a Secret detection security report](https://docs.gitlab.com/ee/development/integrations/secure.html#report)
+ as a pipeline job artifact are affected. You must ensure that all output reports adhere to the correct
+ schema with a minimum version of 14.0.0. Reports with a lower version or that fail to validate
+ against the declared schema version will not be processed, and vulnerability
+ findings will not display in MRs, pipelines, or Vulnerability Reports.
+
+ To help with the transition, from GitLab 14.10, non-compliant reports will display a
+ [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
diff --git a/data/deprecations/14-7-deprecate-artifacts-keyword.yml b/data/deprecations/14-7-deprecate-artifacts-keyword.yml
new file mode 100644
index 00000000000..cbd1a6d41e5
--- /dev/null
+++ b/data/deprecations/14-7-deprecate-artifacts-keyword.yml
@@ -0,0 +1,16 @@
+- name: "Removal of `artifacts:report:cobertura` keyword"
+ announcement_milestone: "14.7"
+ announcement_date: "2022-01-22"
+ removal_milestone: "15.0"
+ removal_date: "2022-05-22"
+ breaking_change: false
+ body: |
+ Currently, test coverage visualizations in GitLab only support Cobertura reports. Starting 15.0, the
+ `artifacts:report:cobertura` keyword will be replaced by
+ [`artifacts:reports:coverage_report`](https://gitlab.com/gitlab-org/gitlab/-/issues/344533). Cobertura will be the
+ only supported report file in 15.0, but this is the first step towards GitLab supporting other report types.
+
+# The following items are not published on the docs page, but may be used in the future.
+ stage: Verify
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348980
+ documentation_url: https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportscobertura
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
new file mode 100644
index 00000000000..cf986341884
--- /dev/null
+++ b/data/deprecations/14-7-deprecate-godep-support-in-license-compliance.yml
@@ -0,0 +1,12 @@
+- 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
+ and will remove it in GitLab 15.0
+ documentation_url: "https://docs.gitlab.com/ee/user/compliance/license_compliance/#supported-languages-and-package-managers"
+ issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/327057"
diff --git a/data/deprecations/14-7-deprecate-merged_by-api-field.yml b/data/deprecations/14-7-deprecate-merged_by-api-field.yml
new file mode 100644
index 00000000000..31b2d9c9244
--- /dev/null
+++ b/data/deprecations/14-7-deprecate-merged_by-api-field.yml
@@ -0,0 +1,27 @@
+# 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: "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: false # 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
diff --git a/data/deprecations/14-7-deprecate-static-site-editor.yml b/data/deprecations/14-7-deprecate-static-site-editor.yml
new file mode 100644
index 00000000000..d8acfbf8ab3
--- /dev/null
+++ b/data/deprecations/14-7-deprecate-static-site-editor.yml
@@ -0,0 +1,14 @@
+- name: "Removal of 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
diff --git a/data/deprecations/14-7-pseudonymizer.yml b/data/deprecations/14-7-pseudonymizer.yml
new file mode 100644
index 00000000000..bd8cb215496
--- /dev/null
+++ b/data/deprecations/14-7-pseudonymizer.yml
@@ -0,0 +1,12 @@
+- 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.
+ It is now considered deprecated, and will be removed in GitLab 15.0.
+ documentation_url: "https://docs.gitlab.com/ee/administration/pseudonymizer.html"
+ issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/219952"
diff --git a/data/deprecations/14-7-sidekiq-metrics-health-check-donfig.yml b/data/deprecations/14-7-sidekiq-metrics-health-check-donfig.yml
new file mode 100644
index 00000000000..34c262b1539
--- /dev/null
+++ b/data/deprecations/14-7-sidekiq-metrics-health-check-donfig.yml
@@ -0,0 +1,30 @@
+- name: "Sidekiq metrics and health checks configuration"
+ announcement_milestone: "14.7"
+ announcement_date: "2021-01-22"
+ removal_milestone: "15.0"
+ removal_date: "2022-05-22"
+ breaking_change: true
+ 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.
+
+ We have updated Sidekiq to export [metrics and health checks from two separate processes](https://gitlab.com/groups/gitlab-org/-/epics/6409)
+ to improve stability and availability and prevent data loss in edge cases.
+ As those are two separate servers, a configuration change will be required in 15.0
+ to explicitly set separate ports for metrics and health-checks.
+ The newly introduced settings for `sidekiq['health_checks_*']`
+ should always be set in `gitlab.rb`.
+ For more information, check the documentation for [configuring Sidekiq](https://docs.gitlab.com/ee/administration/sidekiq.html).
+
+ These changes also require updates in either Prometheus to scrape the new endpoint or k8s health-checks to target the new
+ health-check port to work properly, otherwise either metrics or health-checks will disappear.
+
+ For the deprecation period those settings are optional
+ and GitLab will default the Sidekiq health-checks port to the same port as `sidekiq_exporter`
+ and only run one server (not changing the current behaviour).
+ Only if they are both set and a different port is provided, a separate metrics server will spin up
+ to serve the Sidekiq metrics, similar to the way Sidekiq will behave in 15.0.
+ stage: Enablement
+ tiers: [Free, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/347509
+ documentation_url: https://docs.gitlab.com/ee/administration/sidekiq.html
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
new file mode 100644
index 00000000000..cda67e53b8e
--- /dev/null
+++ b/data/deprecations/14-8-remove-support-for-fixup-in-commit-message-triggering-draft-status.yml
@@ -0,0 +1,15 @@
+- 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
+ 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.
+ documentation_url: "https://docs.gitlab.com/ee/user/project/merge_requests/drafts.html#mark-merge-requests-as-drafts"
+ issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/342937"
diff --git a/data/deprecations/15-0-deprecate-monitor-logging.yml b/data/deprecations/15-0-deprecate-monitor-logging.yml
new file mode 100644
index 00000000000..facb66e4ee8
--- /dev/null
+++ b/data/deprecations/15-0-deprecate-monitor-logging.yml
@@ -0,0 +1,16 @@
+- 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
+
diff --git a/data/deprecations/15-0-deprecate-monitor-metrics.yml b/data/deprecations/15-0-deprecate-monitor-metrics.yml
new file mode 100644
index 00000000000..0a28785105f
--- /dev/null
+++ b/data/deprecations/15-0-deprecate-monitor-metrics.yml
@@ -0,0 +1,17 @@
+- 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
+
diff --git a/data/deprecations/15-0-deprecate-monitor-tracing.yml b/data/deprecations/15-0-deprecate-monitor-tracing.yml
new file mode 100644
index 00000000000..126ada081f4
--- /dev/null
+++ b/data/deprecations/15-0-deprecate-monitor-tracing.yml
@@ -0,0 +1,16 @@
+- 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
+
diff --git a/data/deprecations/15-0-deprecate-sles-12sp2.yml b/data/deprecations/15-0-deprecate-sles-12sp2.yml
deleted file mode 100644
index a466d8b4100..00000000000
--- a/data/deprecations/15-0-deprecate-sles-12sp2.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-- name: "Deprecate 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
- 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/15-0-deprecation-versions-packagetype.yml b/data/deprecations/15-0-deprecation-versions-packagetype.yml
deleted file mode 100644
index e409e9be072..00000000000
--- a/data/deprecations/15-0-deprecation-versions-packagetype.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-- name: "Deprecate `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
- 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`.
- stage: package
- tiers: Free
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/327453
-
diff --git a/data/deprecations/15-0-remove-dependency-proxy-permissions-flag.yml b/data/deprecations/15-0-remove-dependency-proxy-permissions-flag.yml
deleted file mode 100644
index b7e317d148e..00000000000
--- a/data/deprecations/15-0-remove-dependency-proxy-permissions-flag.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-- name: "Remove the `: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
- 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.
- stage: package
- tiers: Free
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/276777
diff --git a/data/deprecations/15-0-remove-package-pipelines-api.yml b/data/deprecations/15-0-remove-package-pipelines-api.yml
deleted file mode 100644
index d26e291bb97..00000000000
--- a/data/deprecations/15-0-remove-package-pipelines-api.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-- 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
- 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.
- stage: package
- tiers: Free
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/289956
diff --git a/data/deprecations/15-0-remove-pipelines-from-version-field.yml b/data/deprecations/15-0-remove-pipelines-from-version-field.yml
deleted file mode 100644
index 88eafedf36b..00000000000
--- a/data/deprecations/15-0-remove-pipelines-from-version-field.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-- name: "Remove the `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
- 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.
- - The `pipelines` field of a specific `version`. This returns only the pipelines associated with that single package version.
-
- 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.
- stage: package
- tiers: Free
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/342882
diff --git a/data/deprecations/deprecate-defaultMergeCommitMessageWithDescription-graphql.yml b/data/deprecations/deprecate-defaultMergeCommitMessageWithDescription-graphql.yml
deleted file mode 100644
index 5da61172410..00000000000
--- a/data/deprecations/deprecate-defaultMergeCommitMessageWithDescription-graphql.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-- name: "Removal of `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
- 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
diff --git a/data/deprecations/deprecation_omniauth-kerberos_gem.yml b/data/deprecations/deprecation_omniauth-kerberos_gem.yml
deleted file mode 100644
index 903d64db717..00000000000
--- a/data/deprecations/deprecation_omniauth-kerberos_gem.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-- name: "OmniAuth Kerberos gem"
- announcement_milestone: "14.3"
- removal_milestone: "15.0"
- removal_date: "2022-05-22"
- body: | # Do not modify this line, instead modify the lines below.
- The `omniauth-kerberos` gem will be removed in our next major release, GitLab 15.0.
-
- This gem has not been maintained and has very little usage. We therefore plan to remove support for this authentication method and recommend using the Kerberos [SPNEGO](https://en.wikipedia.org/wiki/SPNEGO) integration instead. You can follow the [upgrade instructions](https://docs.gitlab.com/ee/integration/kerberos.html#upgrading-from-password-based-to-ticket-based-kerberos-sign-ins) to upgrade from the `omniauth-kerberos` integration to the supported one.
-
- Note that we are not deprecating the Kerberos SPNEGO integration, only the old password-based Kerberos integration.
- stage: Manage
- tiers: [Premium, Ultimate]
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337384
- documentation_url: https://docs.gitlab.com/ee/integration/kerberos.html#upgrading-from-password-based-to-ticket-based-kerberos-sign-ins
- announcement_date: "2021-09-22"
-
diff --git a/data/deprecations/disable_strict_host_key_checking.yml b/data/deprecations/disable_strict_host_key_checking.yml
deleted file mode 100644
index e7e5eb1fa9f..00000000000
--- a/data/deprecations/disable_strict_host_key_checking.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-- name: "Known host required for GitLab Runner SSH executor"
- 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"
- 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.
- stage: Verify
- tiers: [Core, Premium, Ultimate]
- issue_url: https://gitlab.com/gitlab-org/gitlab-runner/-/issues/28192
- documentation_url: https://docs.gitlab.com/runner/executors/ssh.html#security
diff --git a/data/deprecations/job_char_limit.yml b/data/deprecations/job_char_limit.yml
deleted file mode 100644
index 706e3a078eb..00000000000
--- a/data/deprecations/job_char_limit.yml
+++ /dev/null
@@ -1,26 +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: "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
- 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
- removal_date: "2022-05-22"
diff --git a/data/deprecations/runner_api_new_stale_status_breaking_change.yml b/data/deprecations/runner_api_new_stale_status_breaking_change.yml
deleted file mode 100644
index bb3098ff517..00000000000
--- a/data/deprecations/runner_api_new_stale_status_breaking_change.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-- 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_date: "2021-12-22"
- removal_milestone: "15.0" # the milestone when this feature is planned to be removed
- removal_date: "2022-05-22"
- 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.
- stage: Verify
- tiers: [Core, Premium, Ultimate]
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/347303
- documentation_url: https://docs.gitlab.com/ee/api/runners.html#runners-api
diff --git a/data/deprecations/serverless.yml b/data/deprecations/serverless.yml
deleted file mode 100644
index 3d280ff2f62..00000000000
--- a/data/deprecations/serverless.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-- name: "GitLab Serverless"
- announcement_milestone: "14.3"
- announcement_date: "2021-09-22"
- removal_milestone: "15.0"
- removal_date: "2022-05-22"
- body: |
- [GitLab Serverless](https://docs.gitlab.com/ee/user/project/clusters/serverless/) is a feature set to support Knative-based serverless development with automatic deployments and monitoring.
-
- We decided to remove the GitLab Serverless features as they never really resonated with our users. Besides, given the continuous development of Kubernetes and Knative, our current implementations do not even work with recent versions.
- stage: Configure
- tiers: [Core, Premium, Ultimate]
- issue_url: "https://gitlab.com/groups/gitlab-org/configure/-/epics/6"
- documentation_url: "https://docs.gitlab.com/ee/user/project/clusters/serverless/"
-
diff --git a/data/deprecations/templates/_deprecation_template.md.erb b/data/deprecations/templates/_deprecation_template.md.erb
index b0068c32ad9..70169ef5c5c 100644
--- a/data/deprecations/templates/_deprecation_template.md.erb
+++ b/data/deprecations/templates/_deprecation_template.md.erb
@@ -4,7 +4,7 @@ group: none
info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-development-guidelines"
---
-# Deprecated feature removal schedule
+# Deprecations by milestone
DISCLAIMER:
This page contains information related to upcoming products, features, and functionality.
@@ -38,13 +38,19 @@ For deprecation reviewers (Technical Writers only):
<% if milestones.any? -%>
<%- milestones.each do |milestone| %>
## <%= milestone %>
- <%- deprecations.select{|d| d["removal_milestone"] == milestone}.each do |deprecation| %>
+ <%- entries.select{|d| d["announcement_milestone"] == milestone}.each do |deprecation| %>
### <%= deprecation["name"]%>
+<% if deprecation["breaking_change"] -%>
-<%= deprecation["body"] -%>
+WARNING:
+This feature will be changed or removed in <%= deprecation["removal_milestone"]%>
+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.
-Announced: <%= deprecation["announcement_date"]%>
-Planned removal: <%= deprecation["removal_date"]%>
+<%= deprecation["body"] -%><% else %>
+<%= deprecation["body"] -%><% end %>
+**Planned removal milestone: <%= deprecation["removal_milestone"]%> (<%= deprecation["removal_date"]%>)**
<%- end -%>
<%- end -%>
<%- else -%>
diff --git a/data/deprecations/templates/example.yml b/data/deprecations/templates/example.yml
index 07e65af8277..3097db557b8 100644
--- a/data/deprecations/templates/example.yml
+++ b/data/deprecations/templates/example.yml
@@ -14,7 +14,8 @@
announcement_milestone: "XX.YY" # The milestone when this feature was first announced as deprecated.
announcement_date: "YYYY-MM-DD" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "XX.YY" # The milestone when this feature is planned to be removed
- removal_date: "YYYY-MM-DD" # 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.
+ removal_date: # 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: false # If this deprecation is a breaking change, set this value to true
body: | # Do not modify this line, instead modify the lines below.
<!-- START OF BODY COMMENT
diff --git a/data/removals/14_0/14_0-ds-deprecations.yml b/data/removals/14_0/14_0-ds-deprecations.yml
new file mode 100644
index 00000000000..c9eefe65c91
--- /dev/null
+++ b/data/removals/14_0/14_0-ds-deprecations.yml
@@ -0,0 +1,10 @@
+- name: "Deprecations for Dependency Scanning"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: nicoleschwartz
+ body: |
+ As mentioned in [13.9](https://about.gitlab.com/releases/2021/02/22/gitlab-13-9-released/#deprecations-for-dependency-scanning) and [this blog post](https://about.gitlab.com/blog/2021/02/08/composition-analysis-14-deprecations-and-removals/) several removals for Dependency Scanning take effect.
+
+ Previously, to exclude a DS analyzer, you needed to remove it from the default list of analyzers, and use that to set the `DS_DEFAULT_ANALYZERS` variable in your project’s CI template. We determined it should be easier to avoid running a particular analyzer without losing the benefit of newly added analyzers. As a result, we ask you to migrate from `DS_DEFAULT_ANALYZERS` to `DS_EXCLUDED_ANALYZERS` when it is available. Read about it in [issue #287691](https://gitlab.com/gitlab-org/gitlab/-/issues/287691).
+
+ Previously, to prevent the Gemnasium analyzers to fetch the advisory database at runtime, you needed to set the `GEMNASIUM_DB_UPDATE` variable. However, this is not documented properly, and its naming is inconsistent with the equivalent `BUNDLER_AUDIT_UPDATE_DISABLED` variable. As a result, we ask you to migrate from `GEMNASIUM_DB_UPDATE` to `GEMNASIUM_UPDATE_DISABLED` when it is available. Read about it in [issue #215483](https://gitlab.com/gitlab-org/gitlab/-/issues/215483).
diff --git a/data/removals/14_0/14_0-lc-deprecations.yml b/data/removals/14_0/14_0-lc-deprecations.yml
new file mode 100644
index 00000000000..8f59fdbb557
--- /dev/null
+++ b/data/removals/14_0/14_0-lc-deprecations.yml
@@ -0,0 +1,6 @@
+- name: "Removals for License Compliance"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: nicoleschwartz
+ body: |
+ In 13.0, we deprecated the License-Management CI template and renamed it License-Scanning. We have been providing backward compatibility by warning users of the old template to switch. Now in 14.0, we are completely removing the License-Management CI template. Read about it in [issue #216261](https://gitlab.com/gitlab-org/gitlab/-/issues/216261) or [this blog post](https://about.gitlab.com/blog/2021/02/08/composition-analysis-14-deprecations-and-removals/).
diff --git a/data/removals/14_0/change_default_branch_name_to_main.yml b/data/removals/14_0/change_default_branch_name_to_main.yml
new file mode 100644
index 00000000000..d2c0128daa5
--- /dev/null
+++ b/data/removals/14_0/change_default_branch_name_to_main.yml
@@ -0,0 +1,10 @@
+- name: "Default branch name for new repositories now `main`"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: sarahwaldner
+ body: |
+ Every Git repository has an initial branch, which is named `master` by default. It's the first branch to be created automatically when you create a new repository. Future [Git versions](https://lore.kernel.org/git/pull.656.v4.git.1593009996.gitgitgadget@gmail.com/) will change the default branch name in Git from `master` to `main`. In coordination with the Git project and the broader community, [GitLab has changed the default branch name](https://gitlab.com/gitlab-org/gitlab/-/issues/223789) for new projects on both our SaaS (GitLab.com) and self-managed offerings starting with GitLab 14.0. This will not affect existing projects.
+
+ GitLab has already introduced changes that allow you to change the default branch name both at the [instance level](https://docs.gitlab.com/ee/user/project/repository/branches/default.html#instance-level-custom-initial-branch-name) (for self-managed users) and at the [group level](https://docs.gitlab.com/ee/user/group/#use-a-custom-name-for-the-initial-branch) (for both SaaS and self-managed users). We encourage you to make use of these features to set default branch names on new projects.
+
+ For more information, check out our [blog post](https://about.gitlab.com/blog/2021/03/10/new-git-default-branch-name/).
diff --git a/data/removals/14_0/create-code-review-draft-wip.yml b/data/removals/14_0/create-code-review-draft-wip.yml
new file mode 100644
index 00000000000..addd6c400a6
--- /dev/null
+++ b/data/removals/14_0/create-code-review-draft-wip.yml
@@ -0,0 +1,6 @@
+- name: "WIP merge requests renamed 'draft merge requests'"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: phikai
+ body: |
+ The WIP (work in progress) status for merge requests signaled to reviewers that the merge request in question wasn't ready to merge. We've renamed the WIP feature to **Draft**, a more inclusive and self-explanatory term. **Draft** clearly communicates the merge request in question isn't ready for review, and makes no assumptions about the progress being made toward it. **Draft** also reduces the cognitive load for new users, non-English speakers, and anyone unfamiliar with the WIP acronym.
diff --git a/data/removals/14_0/create-code-review-w-parameter-removal.yml b/data/removals/14_0/create-code-review-w-parameter-removal.yml
new file mode 100644
index 00000000000..471df85b540
--- /dev/null
+++ b/data/removals/14_0/create-code-review-w-parameter-removal.yml
@@ -0,0 +1,6 @@
+- name: "Remove `?w=1` URL parameter to ignore whitespace changes"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: phikai
+ body: |
+ To create a consistent experience for users based on their preferences, support for toggling whitespace changes via URL parameter has been removed in GitLab 14.0.
diff --git a/data/removals/14_0/deprecate_ci_project_config_path_variable.yml b/data/removals/14_0/deprecate_ci_project_config_path_variable.yml
new file mode 100644
index 00000000000..c262a641bd1
--- /dev/null
+++ b/data/removals/14_0/deprecate_ci_project_config_path_variable.yml
@@ -0,0 +1,6 @@
+- name: "`CI_PROJECT_CONFIG_PATH` removed in GitLab 14.0"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: stkerr
+ body: |
+ GitLab 14.0 removes the `CI_PROJECT_CONFIG_PATH` pre-defined project variable in favor of `CI_CONFIG_PATH`, which is functionally the same. If you are using `CI_PROJECT_CONFIG_PATH` in your pipeline configurations, update them to use `CI_CONFIG_PATH` instead.
diff --git a/data/removals/14_0/deprecation_bump_terraform_template_version.yml b/data/removals/14_0/deprecation_bump_terraform_template_version.yml
new file mode 100644
index 00000000000..a2e4bad9913
--- /dev/null
+++ b/data/removals/14_0/deprecation_bump_terraform_template_version.yml
@@ -0,0 +1,18 @@
+- name: "New Terraform template version"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0" # example
+ issue_url: ""
+ reporter: nagyv-gitlab
+ body: |
+ As we continuously [develop GitLab's Terraform integrations](https://gitlab.com/gitlab-org/gitlab/-/issues/325312), to minimize customer disruption, we maintain two GitLab CI/CD templates for Terraform:
+
+ - The ["latest version" template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml), which is updated frequently between minor releases of GitLab (such as 13.10, 13.11, etc).
+ - The ["major version" template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml), which is updated only at major releases (such as 13.0, 14.0, etc).
+
+ 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).
+
+ 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/deprecation_manage_access_14_0.yml b/data/removals/14_0/deprecation_manage_access_14_0.yml
new file mode 100644
index 00000000000..bc82067821f
--- /dev/null
+++ b/data/removals/14_0/deprecation_manage_access_14_0.yml
@@ -0,0 +1,17 @@
+- name: Limit projects returned in `GET /groups/:id/`
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: ogolowisnki
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/257829
+ body: |
+ To improve performance, we are limiting the number of projects returned from the `GET /groups/:id/` API call to 100. A complete list of projects can still be retrieved with the `GET /groups/:id/projects` API call.
+
+- name: "GitLab OAuth implicit grant deprecation"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: ogolowinski
+ issue_url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/288516'
+ body: |
+ GitLab is deprecating the [OAuth 2 implicit grant flow](https://docs.gitlab.com/ee/api/oauth2.html#implicit-grant-flow) as it has been removed for [OAuth 2.1](https://oauth.net/2.1/).
+
+ Beginning in 14.0, new applications can't be created with the OAuth 2 implicit grant flow. Existing OAuth implicit grant flows are no longer supported in 14.4. Migrate your existing applications to other supported [OAuth2 flows](https://docs.gitlab.com/ee/api/oauth2.html#supported-oauth2-flows) before release 14.4.
diff --git a/data/removals/14_0/deprecation_update_cicd_templates_to_stop_using_hardcode_master.yml b/data/removals/14_0/deprecation_update_cicd_templates_to_stop_using_hardcode_master.yml
new file mode 100644
index 00000000000..97adc4bb050
--- /dev/null
+++ b/data/removals/14_0/deprecation_update_cicd_templates_to_stop_using_hardcode_master.yml
@@ -0,0 +1,6 @@
+- name: "Update CI/CD templates to stop using hardcoded `master`"
+ reporter: dhershkovitch
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ body: |
+ Our CI/CD templates have been updated to no longer use hard-coded references to a `master` branch. In 14.0, they all use a variable that points to your project's configured default branch instead. If your CI/CD pipeline relies on our built-in templates, verify that this change works with your current configuration. For example, if you have a `master` branch and a different default branch, the updates to the templates may cause changes to your pipeline behavior. For more information, [read the issue](https://gitlab.com/gitlab-org/gitlab/-/issues/324131).
diff --git a/data/removals/14_0/deuley_servicetemplates_removal.yml b/data/removals/14_0/deuley_servicetemplates_removal.yml
new file mode 100644
index 00000000000..94816bbee4a
--- /dev/null
+++ b/data/removals/14_0/deuley_servicetemplates_removal.yml
@@ -0,0 +1,8 @@
+- name: "Service Templates removed"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: deuley
+ body: |
+ Service Templates are [removed in GitLab 14.0](https://gitlab.com/groups/gitlab-org/-/epics/5672). They were used to apply identical settings to a large number of projects, but they only did so at the time of project creation.
+
+ While they solved part of the problem, _updating_ those values later proved to be a major pain point. [Project Integration Management](https://docs.gitlab.com/ee/user/admin_area/settings/project_integration_management.html) solves this problem by enabling you to create settings at the Group or Instance level, and projects within that namespace inheriting those settings.
diff --git a/data/removals/14_0/release_announce_deprecation_of_release_notes_api.yml b/data/removals/14_0/release_announce_deprecation_of_release_notes_api.yml
new file mode 100644
index 00000000000..066022dae87
--- /dev/null
+++ b/data/removals/14_0/release_announce_deprecation_of_release_notes_api.yml
@@ -0,0 +1,7 @@
+- name: "Removal of release description in the Tags API"
+ reporter: kbychu
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ issue_url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/300887'
+ body: |
+ GitLab 14.0 removes support for the release description in the Tags API. You can no longer add a release description when [creating a new tag](https://docs.gitlab.com/ee/api/tags.html#create-a-new-tag). You also can no longer [create](https://docs.gitlab.com/ee/api/tags.html#create-a-new-release) or [update](https://docs.gitlab.com/ee/api/tags.html#update-a-release) a release through the Tags API. Please migrate to use the [Releases API](https://docs.gitlab.com/ee/api/releases/#create-a-release) instead.
diff --git a/data/removals/14_0/release_deprecation_auto-deploy-image.yml b/data/removals/14_0/release_deprecation_auto-deploy-image.yml
new file mode 100644
index 00000000000..7a8f0e598c4
--- /dev/null
+++ b/data/removals/14_0/release_deprecation_auto-deploy-image.yml
@@ -0,0 +1,9 @@
+- name: "Update Auto Deploy template version"
+ reporter: kbychu
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ issue_url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/300862'
+ body: |
+ In GitLab 14.0, we will update the [Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/stages.html#auto-deploy) CI template to the latest version. This includes new features, bug fixes, and performance improvements with a dependency on the v2 [auto-deploy-image](https://gitlab.com/gitlab-org/cluster-integration/auto-deploy-image). Auto Deploy CI tempalte v1 will is deprecated going forward.
+
+ Since the v1 and v2 versions are not backward-compatible, your project might encounter an unexpected failure if you already have a deployed application. Follow the [upgrade guide](https://docs.gitlab.com/ee/topics/autodevops/upgrading_auto_deploy_dependencies.html#upgrade-guide) to upgrade your environments. You can also start using the latest template today by following the [early adoption guide](https://docs.gitlab.com/ee/topics/autodevops/upgrading_auto_deploy_dependencies.html#early-adopters).
diff --git a/data/removals/14_0/release_domainsource_configuration_for_gitlab_pages_deprecation.yml b/data/removals/14_0/release_domainsource_configuration_for_gitlab_pages_deprecation.yml
new file mode 100644
index 00000000000..694c168fb93
--- /dev/null
+++ b/data/removals/14_0/release_domainsource_configuration_for_gitlab_pages_deprecation.yml
@@ -0,0 +1,7 @@
+- name: "Remove disk source configuration for GitLab Pages"
+ reporter: kbychu
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ issue_url: 'https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5993'
+ body: |
+ GitLab Pages [API-based configuration](https://docs.gitlab.com/ee/administration/pages/#gitlab-api-based-configuration) has been available since GitLab 13.0. It replaces the unsupported `disk` source configuration removed in GitLab 14.0, which can no longer be chosen. You should stop using `disk` source configuration, and move to `gitlab` for an API-based configuration. To migrate away from the 'disk' source configuration, set `gitlab_pages['domain_config_source'] = "gitlab"` in your `/etc/gitlab/gitlab.rb` file. We recommend you migrate before updating to GitLab 14.0, to identify and troubleshoot any potential problems before upgrading.
diff --git a/data/removals/14_0/release_legacy_feature_flags_deprecation.yml b/data/removals/14_0/release_legacy_feature_flags_deprecation.yml
new file mode 100644
index 00000000000..aa62be7eb1d
--- /dev/null
+++ b/data/removals/14_0/release_legacy_feature_flags_deprecation.yml
@@ -0,0 +1,7 @@
+- name: "Legacy feature flags removed"
+ reporter: kbychu
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ issue_url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/254324'
+ body: |
+ Legacy feature flags became read-only in GitLab 13.4. GitLab 14.0 removes support for legacy feature flags, so you must migrate them to the [new version](https://docs.gitlab.com/ee/operations/feature_flags.html). You can do this by first taking a note (screenshot) of the legacy flag, then deleting the flag through the API or UI (you don't need to alter the code), and finally create a new Feature Flag with the same name as the legacy flag you deleted. Also, make sure the strategies and environments match the deleted flag. We created a [video tutorial](https://www.youtube.com/watch?v=CAJY2IGep7Y) to help with this migration.
diff --git a/data/removals/14_0/release_remove_redundant_keyvalue_pair_from_the_payload_of_dora.yml b/data/removals/14_0/release_remove_redundant_keyvalue_pair_from_the_payload_of_dora.yml
new file mode 100644
index 00000000000..48e79230297
--- /dev/null
+++ b/data/removals/14_0/release_remove_redundant_keyvalue_pair_from_the_payload_of_dora.yml
@@ -0,0 +1,7 @@
+- name: "Remove redundant timestamp field from DORA metrics API payload"
+ reporter: kbychu
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ issue_url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/325931'
+ body: |
+ The [deployment frequency project-level API](https://docs.gitlab.com/ee/api/dora4_project_analytics.html#list-project-deployment-frequencies) endpoint has been deprecated in favor of the [DORA 4 API](https://docs.gitlab.com/ee/api/dora/metrics.html), which consolidates all the metrics under one API with the specific metric as a required field. As a result, the timestamp field, which doesn't allow adding future extensions and causes performance issues, will be removed. With the old API, an example response would be `{ "2021-03-01": 3, "date": "2021-03-01", "value": 3 }`. The first key/value (`"2021-03-01": 3`) will be removed and replaced by the last two (`"date": "2021-03-01", "value": 3`).
diff --git a/data/removals/14_0/removal-geo-fdw-settings.yml b/data/removals/14_0/removal-geo-fdw-settings.yml
new file mode 100644
index 00000000000..c2066269cb8
--- /dev/null
+++ b/data/removals/14_0/removal-geo-fdw-settings.yml
@@ -0,0 +1,11 @@
+- name: "Geo Foreign Data Wrapper settings removed"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: fzimmer
+ body: |
+ As [announced in GitLab 13.3](https://about.gitlab.com/releases/2020/08/22/gitlab-13-3-released/#geo-foreign-data-wrapper-settings-deprecated), the following configuration settings in `/etc/gitlab/gitlab.rb` have been removed in 14.0:
+
+ - `geo_secondary['db_fdw']`
+ - `geo_postgresql['fdw_external_user']`
+ - `geo_postgresql['fdw_external_password']`
+ - `gitlab-_rails['geo_migrated_local_files_clean_up_worker_cron']`
diff --git a/data/removals/14_0/removal-graphql-fields.yml b/data/removals/14_0/removal-graphql-fields.yml
new file mode 100644
index 00000000000..24d2bb4a4eb
--- /dev/null
+++ b/data/removals/14_0/removal-graphql-fields.yml
@@ -0,0 +1,13 @@
+- name: "Deprecated GraphQL fields have been removed"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: gweaver
+ body: |
+ In accordance with our [GraphQL deprecation and removal process](https://docs.gitlab.com/ee/api/graphql/#deprecation-process), the following fields that were deprecated prior to 13.7 are [fully removed in 14.0](https://gitlab.com/gitlab-org/gitlab/-/issues/267966):
+
+ - `Mutations::Todos::MarkAllDone`, `Mutations::Todos::RestoreMany` - `:updated_ids`
+ - `Mutations::DastScannerProfiles::Create`, `Types::DastScannerProfileType` - `:global_id`
+ - `Types::SnippetType` - `:blob`
+ - `EE::Types::GroupType`, `EE::Types::QueryType` - `:vulnerabilities_count_by_day_and_severity`
+ - `DeprecatedMutations (concern**)` - `AddAwardEmoji`, `RemoveAwardEmoji`, `ToggleAwardEmoji`
+ - `EE::Types::DeprecatedMutations (concern***)` - `Mutations::Pipelines::RunDastScan`, `Mutations::Vulnerabilities::Dismiss`, `Mutations::Vulnerabilities::RevertToDetected`
diff --git a/data/removals/14_0/removal-legacy-storage.yml b/data/removals/14_0/removal-legacy-storage.yml
new file mode 100644
index 00000000000..677ec7b8512
--- /dev/null
+++ b/data/removals/14_0/removal-legacy-storage.yml
@@ -0,0 +1,6 @@
+- name: "Legacy storage removed"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: fzimmer
+ body: |
+ As [announced in GitLab 13.0](https://about.gitlab.com/releases/2020/05/22/gitlab-13-0-released/#planned-removal-of-legacy-storage-in-14.0), [legacy storage](https://docs.gitlab.com/ee/administration/repository_storage_types.html#legacy-storage) has been removed in GitLab 14.0.
diff --git a/data/removals/14_0/removal-protect-features.yml b/data/removals/14_0/removal-protect-features.yml
new file mode 100644
index 00000000000..8e50925f6db
--- /dev/null
+++ b/data/removals/14_0/removal-protect-features.yml
@@ -0,0 +1,13 @@
+- name: Container Scanning Engine Clair
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: sam.white
+ body: |
+ Clair, the default container scanning engine, was deprecated in GitLab 13.9 and is removed from GitLab 14.0 and replaced by Trivy. We advise customers who are customizing variables for their container scanning job to [follow these instructions](https://docs.gitlab.com/ee/user/application_security/container_scanning/#change-scanners) to ensure that their container scanning jobs continue to work.
+
+- name: Web Application Firewall (WAF)
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: sam.white
+ body: |
+ The Web Application Firewall (WAF) was deprecated in GitLab 13.6 and is removed from GitLab 14.0. The WAF had limitations inherent in the architectural design that made it difficult to meet the requirements traditionally expected of a WAF. By removing the WAF, GitLab is able to focus on improving other areas in the product where more value can be provided to users. Users who currently rely on the WAF can continue to use the free and open source [ModSecurity](https://github.com/SpiderLabs/ModSecurity) project, which is independent from GitLab. Additional details are available in the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/271276).
diff --git a/data/removals/14_0/removal-sidekiq_experimental_queue_selector.yml b/data/removals/14_0/removal-sidekiq_experimental_queue_selector.yml
new file mode 100644
index 00000000000..442c0e97cde
--- /dev/null
+++ b/data/removals/14_0/removal-sidekiq_experimental_queue_selector.yml
@@ -0,0 +1,10 @@
+- name: Sidekiq queue selector options no longer accept the 'experimental' prefix
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: smcgivern
+ body: |
+ 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-unicorn.yml b/data/removals/14_0/removal-unicorn.yml
new file mode 100644
index 00000000000..af0bed0f3ec
--- /dev/null
+++ b/data/removals/14_0/removal-unicorn.yml
@@ -0,0 +1,6 @@
+- name: "Unicorn removed in favor of Puma for GitLab self-managed"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: fzimmer
+ body: |
+ [Support for Unicorn](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/6078) has been removed in GitLab 14.0 in favor of Puma. [Puma has a multi-threaded architecture](https://docs.gitlab.com/ee/administration/operations/puma.html) which uses less memory than a multi-process application server like Unicorn. On GitLab.com, we saw a 40% reduction in memory consumption by using Puma.
diff --git a/data/removals/14_0/removal_ci_project_config_path.yml b/data/removals/14_0/removal_ci_project_config_path.yml
new file mode 100644
index 00000000000..8e90c83c7c4
--- /dev/null
+++ b/data/removals/14_0/removal_ci_project_config_path.yml
@@ -0,0 +1,11 @@
+- name: "`CI_PROJECT_CONFIG_PATH` variable has been removed"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: stkerr
+ body: |
+ The `CI_PROJECT_CONFIG_PATH` [predefined project variable](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html)
+ has been removed in favor of `CI_CONFIG_PATH`, which is functionally the same.
+
+ 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_helm2.yml b/data/removals/14_0/removal_enablement_helm2.yml
new file mode 100644
index 00000000000..323b22fd3b4
--- /dev/null
+++ b/data/removals/14_0/removal_enablement_helm2.yml
@@ -0,0 +1,8 @@
+- name: "Helm v2 support"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: joshlambert
+ body: |
+ Helm v2 was [officially deprecated](https://helm.sh/blog/helm-v2-deprecation-timeline/) in November of 2020, with the `stable` repository being [de-listed from the Helm Hub](https://about.gitlab.com/blog/2020/11/09/ensure-auto-devops-work-after-helm-stable-repo/) shortly thereafter. With the release of GitLab 14.0, which will include the 5.0 release of the [GitLab Helm chart](https://docs.gitlab.com/charts/), Helm v2 will no longer be supported.
+
+ Users of the chart should [upgrade to Helm v3](https://helm.sh/docs/topics/v2_v3_migration/) to deploy GitLab 14.0 and later.
diff --git a/data/removals/14_0/removal_enablement_opensuse_15_1.yml b/data/removals/14_0/removal_enablement_opensuse_15_1.yml
new file mode 100644
index 00000000000..cff442d7b92
--- /dev/null
+++ b/data/removals/14_0/removal_enablement_opensuse_15_1.yml
@@ -0,0 +1,6 @@
+- name: "OpenSUSE Leap 15.1"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: dorrino
+ body: |
+ Support for [OpenSUSE Leap 15.1 is being deprecated](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/5135). Support for 15.1 will be dropped in 14.0. We are now providing support for openSUSE Leap 15.2 packages.
diff --git a/data/removals/14_0/removal_enablement_pg11.yml b/data/removals/14_0/removal_enablement_pg11.yml
new file mode 100644
index 00000000000..c7b9f8b528b
--- /dev/null
+++ b/data/removals/14_0/removal_enablement_pg11.yml
@@ -0,0 +1,10 @@
+- name: "PostgreSQL 11 support"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: joshlambert
+ body: |
+ 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
new file mode 100644
index 00000000000..65457db8c68
--- /dev/null
+++ b/data/removals/14_0/removal_enablement_ubuntu_16.yml
@@ -0,0 +1,11 @@
+- name: "Ubuntu 16.04 support"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: joshlambert
+ body: |
+ 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_repost_static_analysis_notices.yml b/data/removals/14_0/removal_repost_static_analysis_notices.yml
new file mode 100644
index 00000000000..1105f21e3fd
--- /dev/null
+++ b/data/removals/14_0/removal_repost_static_analysis_notices.yml
@@ -0,0 +1,39 @@
+- name: "Migrate from `SAST_DEFAULT_ANALYZERS` to `SAST_EXCLUDED_ANALYZERS`"
+ reporter: tmccaslin
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ issue_url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/229974'
+ body: |
+ Until GitLab 13.9, if you wanted to avoid running one particular GitLab SAST analyzer, you needed to remove it from the [long string of analyzers in the `SAST.gitlab-ci.yml` file](https://gitlab.com/gitlab-org/gitlab/-/blob/390afc431e7ce1ac253b35beb39f19e49c746bff/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml#L12) and use that to set the [`SAST_DEFAULT_ANALYZERS`](https://docs.gitlab.com/ee/user/application_security/sast/#docker-images) variable in your project's CI file. If you did this, it would exclude you from future new analyzers because this string hard codes the list of analyzers to execute. We avoid this problem by inverting this variable's logic to exclude, rather than choose default analyzers.
+ Beginning with 13.9, [we migrated](https://gitlab.com/gitlab-org/gitlab/-/blob/14fed7a33bfdbd4663d8928e46002a5ef3e3282c/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml#L13) to `SAST_EXCLUDED_ANALYZERS` in our `SAST.gitlab-ci.yml` file. We encourage anyone who uses a [customized SAST configuration](https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings) in their project CI file to migrate to this new variable. If you have not overridden `SAST_DEFAULT_ANALYZERS`, no action is needed. The CI/CD variable `SAST_DEFAULT_ANALYZERS` has been removed in GitLab 14.0, which released on June 22, 2021.
+
+- name: "Remove `secret_detection_default_branch` job"
+ reporter: tmccaslin
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ issue_url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/297269'
+ body: |
+ To ensure Secret Detection was scanning both default branches and feature branches, we introduced two separate secret detection CI jobs (`secret_detection_default_branch` and `secret_detection`) in our managed [`Secret-Detection.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml) template. These two CI jobs created confusion and complexity in the CI rules logic. This deprecation moves the `rule` logic into the `script` section, which then determines how the `secret_detection` job is run (historic, on a branch, commits, etc).
+ If you override or maintain custom versions of `SAST.gitlab-ci.yml` or `Secret-Detection.gitlab-ci.yml`, you must update your CI templates. We strongly encourage [inheriting and overriding our managed CI templates](https://docs.gitlab.com/ee/user/application_security/secret_detection/#custom-settings-example) to future-proof your CI templates. GitLab 14.0 no longer supports the old `secret_detection_default_branch` job.
+
+- name: "Remove SAST analyzer `SAST_GOSEC_CONFIG` variable in favor of
+ custom rulesets"
+ reporter: tmccaslin
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ issue_url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/301215'
+ body: |
+ With the release of [SAST Custom Rulesets](https://docs.gitlab.com/ee/user/application_security/sast/#customize-rulesets) in GitLab 13.5 we allow greater flexibility in configuration options for our Go analyzer (GoSec). As a result we no longer plan to support our less flexible [`SAST_GOSEC_CONFIG`](https://docs.gitlab.com/ee/user/application_security/sast/#analyzer-settings) analyzer setting. This variable was deprecated in GitLab 13.10.
+ GitLab 14.0 removes the old `SAST_GOSEC_CONFIG variable`. If you use or override `SAST_GOSEC_CONFIG` in your CI file, update your SAST CI configuration or pin to an older version of the GoSec analyzer. We strongly encourage [inheriting and overriding our managed CI templates](https://docs.gitlab.com/ee/user/application_security/sast/#overriding-sast-jobs) to future-proof your CI templates.
+
+- name: "Removed Global `SAST_ANALYZER_IMAGE_TAG` in SAST CI template"
+ reporter: tmccaslin
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ issue_url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/301216'
+ body: |
+ With the maturity of GitLab Secure scanning tools, we've needed to add more granularity to our release process. Previously, GitLab shared a major version number for [all analyzers and tools](https://docs.gitlab.com/ee/user/application_security/sast/#supported-languages-and-frameworks). This requires all tools to share a major version, and prevents the use of [semantic version numbering](https://semver.org/). In GitLab 14.0, SAST removes the `SAST_ANALYZER_IMAGE_TAG` global variable in our [managed `SAST.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/SAST.gitlab-ci.yml) CI template, in favor of the analyzer job variable setting the `major.minor` tag in the SAST vendored template.
+
+ Each analyzer job now has a scoped `SAST_ANALYZER_IMAGE_TAG` variable, which will be actively managed by GitLab and set to the `major` tag for the respective analyzer. To pin to a specific version, [change the variable value to the specific version tag](https://docs.gitlab.com/ee/user/application_security/sast/#pinning-to-minor-image-version).
+ If you override or maintain custom versions of `SAST.gitlab-ci.yml`, update your CI templates to stop referencing the global `SAST_ANALYZER_IMAGE_TAG`, and move it to a scoped analyzer job tag. We strongly encourage [inheriting and overriding our managed CI templates](https://docs.gitlab.com/ee/user/application_security/sast/#overriding-sast-jobs) to future-proof your CI templates. This change allows you to more granularly control future analyzer updates with a pinned `major.minor` version.
+ This deprecation and removal changes our [previously announced plan](https://about.gitlab.com/releases/2021/02/22/gitlab-13-9-released/#pin-static-analysis-analyzers-and-tools-to-minor-versions) to pin the Static Analysis tools.
diff --git a/data/removals/14_0/removal_runner_25555.yml b/data/removals/14_0/removal_runner_25555.yml
new file mode 100644
index 00000000000..f317eaab846
--- /dev/null
+++ b/data/removals/14_0/removal_runner_25555.yml
@@ -0,0 +1,7 @@
+- name: "Remove off peak time mode configuration for Docker Machine autoscaling"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: deastman
+ 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/removal_runner_26036.yml b/data/removals/14_0/removal_runner_26036.yml
new file mode 100644
index 00000000000..564143fda82
--- /dev/null
+++ b/data/removals/14_0/removal_runner_26036.yml
@@ -0,0 +1,6 @@
+- name: "Remove Ubuntu 19.10 (Eoan Ermine) package"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: deastman
+ body: |
+ Ubuntu 19.10 (Eoan Ermine) reached end of life on Friday, July 17, 2020. In GitLab Runner 14.0, Ubuntu 19.10 (Eoan Ermine) is no longer available from our package distribution. Refer to [issue #26036](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/26036) for details.
diff --git a/data/removals/14_0/removal_runner_26419.yml b/data/removals/14_0/removal_runner_26419.yml
new file mode 100644
index 00000000000..8b0f3846c7a
--- /dev/null
+++ b/data/removals/14_0/removal_runner_26419.yml
@@ -0,0 +1,6 @@
+- name: "Make `pwsh` the default shell for newly-registered Windows Runners"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: deastman
+ body: |
+ In GitLab Runner 13.2, PowerShell Core support was added to the Shell executor. In 14.0, PowerShell Core, `pwsh` is now the default shell for newly-registered Windows runners. Windows `CMD` will still be available as a shell option for Windows runners. Refer to [issue #26419](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/26419) for details.
diff --git a/data/removals/14_0/removal_runner_4845.yml b/data/removals/14_0/removal_runner_4845.yml
new file mode 100644
index 00000000000..92e4e0172f2
--- /dev/null
+++ b/data/removals/14_0/removal_runner_4845.yml
@@ -0,0 +1,6 @@
+- name: "GitLab Runner installation to ignore the `skel` directory"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: deastman
+ body: |
+ In GitLab Runner 14.0, the installation process will ignore the `skel` directory by default when creating the user home directory. Refer to [issue #4845](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4845) for details.
diff --git a/data/removals/14_0/removal_runner_6413.yml b/data/removals/14_0/removal_runner_6413.yml
new file mode 100644
index 00000000000..f08b1091cca
--- /dev/null
+++ b/data/removals/14_0/removal_runner_6413.yml
@@ -0,0 +1,6 @@
+- name: "Remove `FF_SHELL_EXECUTOR_USE_LEGACY_PROCESS_KILL` feature flag"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: deastman
+ body: |
+ In [GitLab Runner 13.1](https://docs.gitlab.com/runner/executors/shell.html#gitlab-131-and-later), [issue #3376](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/3376), we introduced `sigterm` and then `sigkill` to a process in the Shell executor. We also introduced a new feature flag, `FF_SHELL_EXECUTOR_USE_LEGACY_PROCESS_KILL`, so you can use the previous process termination sequence. In GitLab Runner 14.0, [issue #6413](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/6413), the feature flag has been removed.
diff --git a/data/removals/14_0/removals-14-testing-team.yml b/data/removals/14_0/removals-14-testing-team.yml
new file mode 100644
index 00000000000..d76de564cdd
--- /dev/null
+++ b/data/removals/14_0/removals-14-testing-team.yml
@@ -0,0 +1,26 @@
+- name: "Default Browser Performance testing job renamed in GitLab 14.0"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: jheimbuck_gl
+ body: |
+ Browser Performance Testing has run in a job named `performance` by default. With the introduction of [Load Performance Testing](https://docs.gitlab.com/ee/user/project/merge_requests/load_performance_testing.html) in GitLab 13.2, this naming could be confusing. To make it clear which job is running [Browser Performance Testing](https://docs.gitlab.com/ee/user/project/merge_requests/browser_performance_testing.html), the default job name is changed from `performance` to `browser_performance` in the template in GitLab 14.0.
+
+ Relevant Issue: [Rename default Browser Performance Testing job](https://gitlab.com/gitlab-org/gitlab/-/issues/225914)
+- name: "Code Quality RuboCop support changed"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: jheimbuck_gl
+ body: |
+ By default, the Code Quality feature has not provided support for Ruby 2.6+ if you're using the Code Quality template. To better support the latest versions of Ruby, the default RuboCop version is updated to add support for Ruby 2.4 through 3.0. As a result, support for Ruby 2.1, 2.2, and 2.3 is removed. You can re-enable support for older versions by [customizing your configuration](https://docs.gitlab.com/ee/user/project/merge_requests/code_quality.html#rubocop-errors).
+
+ Relevant Issue: [Default `codeclimate-rubocop` engine does not support Ruby 2.6+](https://gitlab.com/gitlab-org/ci-cd/codequality/-/issues/28)
+- name: "Ruby version changed in `Ruby.gitlab-ci.yml`"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: jheimbuck_gl
+ body: |
+ By default, the `Ruby.gitlab-ci.yml` file has included Ruby 2.5.
+
+ To better support the latest versions of Ruby, the template is changed to use `ruby:latest`, which is currently 3.0. To better understand the changes in Ruby 3.0, please reference the [Ruby-lang.org release announcement](https://www.ruby-lang.org/en/news/2020/12/25/ruby-3-0-0-released/).
+
+ Relevant Issue: [Updates Ruby version 2.5 to 3.0](https://gitlab.com/gitlab-org/gitlab/-/issues/329160)
diff --git a/data/removals/14_0/removals_runner_26651.yml b/data/removals/14_0/removals_runner_26651.yml
new file mode 100644
index 00000000000..a22f8dfc9ac
--- /dev/null
+++ b/data/removals/14_0/removals_runner_26651.yml
@@ -0,0 +1,6 @@
+- name: "Remove `/usr/lib/gitlab-runner` symlink from package"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: deastman
+ body: |
+ In GitLab Runner 13.3, a symlink was added from `/user/lib/gitlab-runner/gitlab-runner` to `/usr/bin/gitlab-runner`. In 14.0, the symlink has been removed and the runner is now installed in `/usr/bin/gitlab-runner`. Refer to [issue #26651](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/26651) for details.
diff --git a/data/removals/14_0/removals_runner_26679.yml b/data/removals/14_0/removals_runner_26679.yml
new file mode 100644
index 00000000000..816bd8f37d5
--- /dev/null
+++ b/data/removals/14_0/removals_runner_26679.yml
@@ -0,0 +1,6 @@
+- name: "Remove `FF_RESET_HELPER_IMAGE_ENTRYPOINT` feature flag"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: deastman
+ body: |
+ In 14.0, we have deactivated the `FF_RESET_HELPER_IMAGE_ENTRYPOINT` feature flag. Refer to issue [#26679](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/26679) for details.
diff --git a/data/removals/14_0/removals_runner_26900.yml b/data/removals/14_0/removals_runner_26900.yml
new file mode 100644
index 00000000000..bdba368eee8
--- /dev/null
+++ b/data/removals/14_0/removals_runner_26900.yml
@@ -0,0 +1,6 @@
+- name: "Remove success and failure for finished build metric conversion"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: deastman
+ body: |
+ In GitLab Runner 13.5, we introduced `failed` and `success` states for a job. To support Prometheus rules, we chose to convert `success/failure` to `finished` for the metric. In 14.0, the conversion has now been removed. Refer to [issue #26900](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/26900) for details.
diff --git a/data/removals/14_0/removals_runner_27175.yml b/data/removals/14_0/removals_runner_27175.yml
new file mode 100644
index 00000000000..33629084073
--- /dev/null
+++ b/data/removals/14_0/removals_runner_27175.yml
@@ -0,0 +1,6 @@
+- name: "Remove `FF_USE_GO_CLOUD_WITH_CACHE_ARCHIVER` feature flag"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: deastman
+ body: |
+ GitLab Runner 14.0 removes the `FF_USE_GO_CLOUD_WITH_CACHE_ARCHIVER` feature flag. Refer to [issue #27175](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27175) for details.
diff --git a/data/removals/14_0/removals_runner_27218.yml b/data/removals/14_0/removals_runner_27218.yml
new file mode 100644
index 00000000000..fb1e27c3f91
--- /dev/null
+++ b/data/removals/14_0/removals_runner_27218.yml
@@ -0,0 +1,6 @@
+- name: "GitLab Runner helper image in GitLab.com Container Registry"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: deastman
+ body: |
+ In 14.0, we are now pulling the GitLab Runner [helper image](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#helper-image) from the GitLab Container Registry instead of Docker Hub. Refer to [issue #27218](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27218) for details.
diff --git a/data/removals/14_0/removals_runner_27551.yml b/data/removals/14_0/removals_runner_27551.yml
new file mode 100644
index 00000000000..6f4ee52749c
--- /dev/null
+++ b/data/removals/14_0/removals_runner_27551.yml
@@ -0,0 +1,6 @@
+- name: "Remove support for Windows Server 1903 image"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: deastman
+ body: |
+ In 14.0, we have removed Windows Server 1903. Microsoft ended support for this version on 2020-08-12. Refer to [issue #27551](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27551) for details.
diff --git a/data/removals/14_0/removals_runner_27899.yml b/data/removals/14_0/removals_runner_27899.yml
new file mode 100644
index 00000000000..226520abda4
--- /dev/null
+++ b/data/removals/14_0/removals_runner_27899.yml
@@ -0,0 +1,6 @@
+- name: "Remove support for Windows Server 1909 image"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: deastman
+ body: |
+ In 14.0, we have removed Windows Server 1909. Microsoft ended support for this version on 2021-05-11. Refer to [issue #27899](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27899) for details.
diff --git a/data/removals/14_0/remove-sql-elector.yml b/data/removals/14_0/remove-sql-elector.yml
new file mode 100644
index 00000000000..d35fac0786c
--- /dev/null
+++ b/data/removals/14_0/remove-sql-elector.yml
@@ -0,0 +1,9 @@
+- name: "Gitaly Cluster SQL primary elector has been removed"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: mjwood
+ body: |
+ Now that Praefect supports a [primary election strategy](https://docs.gitlab.com/ee/administration/gitaly/praefect.html#repository-specific-primary-nodes) for each repository, we have removed the `sql` election strategy.
+ The `per_repository` election strategy is the new default, which is automatically used if no election strategy was specified.
+
+ If you had configured the `sql` election strategy, you must follow the [migration instructions](https://docs.gitlab.com/ee/administration/gitaly/praefect.html#migrate-to-repository-specific-primary-gitaly-nodes) before upgrading to 14.0.
diff --git a/data/removals/14_0/remove_dast_env_variables.yml b/data/removals/14_0/remove_dast_env_variables.yml
new file mode 100644
index 00000000000..f2bbe748af5
--- /dev/null
+++ b/data/removals/14_0/remove_dast_env_variables.yml
@@ -0,0 +1,15 @@
+- name: "DAST environment variable renaming and removal"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: derekferguson
+ body: |
+ GitLab 13.8 renamed multiple environment variables to support their broader usage in different workflows. In GitLab 14.0, the old variables have been permanently removed and will no longer work. Any configurations using these variables must be updated to the new variable names. Any scans using these variables in GitLab 14.0 and later will fail to be configured correctly. These variables are:
+
+ - `DAST_AUTH_EXCLUDE_URLS` becomes `DAST_EXCLUDE_URLS`.
+ - `AUTH_EXCLUDE_URLS` becomes `DAST_EXCLUDE_URLS`.
+ - `AUTH_USERNAME` becomes `DAST_USERNAME`.
+ - `AUTH_PASSWORD` becomes `DAST_PASSWORD`.
+ - `AUTH_USERNAME_FIELD` becomes `DAST_USERNAME_FIELD`.
+ - `AUTH_PASSWORD_FIELD` becomes `DAST_PASSWORD_FIELD`.
+ - `DAST_ZAP_USE_AJAX_SPIDER` will now be `DAST_USE_AJAX_SPIDER`.
+ - `DAST_FULL_SCAN_DOMAIN_VALIDATION_REQUIRED` will be removed, since the feature is being removed.
diff --git a/data/removals/14_0/remove_dast_legacy_domain_validation.yml b/data/removals/14_0/remove_dast_legacy_domain_validation.yml
new file mode 100644
index 00000000000..61fb9002880
--- /dev/null
+++ b/data/removals/14_0/remove_dast_legacy_domain_validation.yml
@@ -0,0 +1,8 @@
+- name: "Remove legacy DAST domain validation"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: derekferguson
+ body: |
+ The legacy method of DAST Domain Validation for CI/CD scans was deprecated in GitLab 13.8, and is removed in GitLab 14.0. This method of domain validation only disallows scans if the `DAST_FULL_SCAN_DOMAIN_VALIDATION_REQUIRED` environment variable is set to `true` in the `gitlab-ci.yml` file, and a `Gitlab-DAST-Permission` header on the site is not set to `allow`. This two-step method required users to opt in to using the variable before they could opt out from using the header.
+
+ For more information, see the [removal issue](https://gitlab.com/gitlab-org/gitlab/-/issues/293595).
diff --git a/data/removals/14_0/remove_dast_legacy_report_fields.yml b/data/removals/14_0/remove_dast_legacy_report_fields.yml
new file mode 100644
index 00000000000..ec98b173a24
--- /dev/null
+++ b/data/removals/14_0/remove_dast_legacy_report_fields.yml
@@ -0,0 +1,8 @@
+- name: "Removal of legacy fields from DAST report"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: derekferguson
+ body: |
+ As a part of the migration to a common report format for all of the Secure scanners in GitLab, DAST is making changes to the DAST JSON report. Certain legacy fields were deprecated in 13.8 and have been completely removed in 14.0. These fields are `@generated`, `@version`, `site`, and `spider`. This should not affect any normal DAST operation, but does affect users who consume the JSON report in an automated way and use these fields. Anyone affected by these changes, and needs these fields for business reasons, is encouraged to open a new GitLab issue and explain the need.
+
+ For more information, see [the removal issue](https://gitlab.com/gitlab-org/gitlab/-/issues/33915).
diff --git a/data/removals/14_0/remove_dast_spider_host_reset.yml b/data/removals/14_0/remove_dast_spider_host_reset.yml
new file mode 100644
index 00000000000..de334618b88
--- /dev/null
+++ b/data/removals/14_0/remove_dast_spider_host_reset.yml
@@ -0,0 +1,6 @@
+- name: "Default DAST spider begins crawling at target URL"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: derekferguson
+ body: |
+ In GitLab 14.0, DAST has removed the current method of resetting the scan to the hostname when starting to spider. Prior to GitLab 14.0, the spider would not begin at the specified target path for the URL but would instead reset the URL to begin crawling at the host root. GitLab 14.0 changes the default for the new variable `DAST_SPIDER_START_AT_HOST` to `false` to better support users' intention of beginning spidering and scanning at the specified target URL, rather than the host root URL. This change has an added benefit: scans can take less time, if the specified path does not contain links to the entire site. This enables easier scanning of smaller sections of an application, rather than crawling the entire app during every scan.
diff --git a/data/removals/14_0/remove_dast_template_stages.yml b/data/removals/14_0/remove_dast_template_stages.yml
new file mode 100644
index 00000000000..0f72091735d
--- /dev/null
+++ b/data/removals/14_0/remove_dast_template_stages.yml
@@ -0,0 +1,6 @@
+- name: "Remove DAST default template stages"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: derekferguson
+ body: |
+ In GitLab 14.0, we've removed the stages defined in the current `DAST.gitlab-ci.yml` template to avoid the situation where the template overrides manual changes made by DAST users. We're making this change in response to customer issues where the stages in the template cause problems when used with customized DAST configurations. Because of this removal, `gitlab-ci.yml` configurations that do not specify a `dast` stage must be updated to include this stage.
diff --git a/data/removals/14_0/remove_optimize_api.yml b/data/removals/14_0/remove_optimize_api.yml
new file mode 100644
index 00000000000..5df120858c6
--- /dev/null
+++ b/data/removals/14_0/remove_optimize_api.yml
@@ -0,0 +1,6 @@
+- name: "Segments removed from DevOps Adoption API"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: ljlane
+ body: |
+ The first release of the DevOps Adoption report had a concept of **Segments**. Segments were [quickly removed from the report](https://gitlab.com/groups/gitlab-org/-/epics/5251) because they introduced an additional layer of complexity on top of **Groups** and **Projects**. Subsequent iterations of the DevOps Adoption report focus on comparing adoption across groups rather than segments. GitLab 14.0 removes all references to **Segments** [from the GraphQL API](https://gitlab.com/gitlab-org/gitlab/-/issues/324414) and replaces them with **Enabled groups**.
diff --git a/data/removals/14_0/remove_terraform_template.yml b/data/removals/14_0/remove_terraform_template.yml
new file mode 100644
index 00000000000..bc3b529f630
--- /dev/null
+++ b/data/removals/14_0/remove_terraform_template.yml
@@ -0,0 +1,9 @@
+- name: "Breaking changes to Terraform CI template"
+ reporter: nagyv-gitlab
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ issue_url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/328500'
+ body: |
+ GitLab 14.0 renews the Terraform CI template to the latest version. The new template is set up for the GitLab Managed Terraform state, with a dependency on the GitLab `terraform-images` image, to provide a good user experience around GitLab's Infrastructure-as-Code features.
+
+ The current stable and latest templates are not compatible, and the current latest template becomes the stable template beginning with GitLab 14.0, your Terraform pipeline might encounter an unexpected failure if you run a custom `init` job.
diff --git a/data/removals/14_0/verify-ci-removal-parametertrace.yml b/data/removals/14_0/verify-ci-removal-parametertrace.yml
new file mode 100644
index 00000000000..c37497c1a35
--- /dev/null
+++ b/data/removals/14_0/verify-ci-removal-parametertrace.yml
@@ -0,0 +1,8 @@
+- name: "Removal of deprecated `trace` parameter from `jobs` API endpoint"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: jreporter
+ 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_0/verify-ci-removalpipelineservice.yml b/data/removals/14_0/verify-ci-removalpipelineservice.yml
new file mode 100644
index 00000000000..f3583bd0498
--- /dev/null
+++ b/data/removals/14_0/verify-ci-removalpipelineservice.yml
@@ -0,0 +1,6 @@
+- name: "External Pipeline Validation Service Code Changes"
+ removal_date: "2021-06-22"
+ removal_milestone: "14.0"
+ reporter: jreporter
+ body: |
+ For self-managed instances using the experimental [external pipeline validation service](https://docs.gitlab.com/ee/administration/external_pipeline_validation.html), the range of error codes GitLab accepts will be reduced. Currently, pipelines are invalidated when the validation service returns a response code from `400` to `499`. In GitLab 14.0 and later, pipelines will be invalidated for the `406: Not Accepted` response code only.
diff --git a/data/removals/14_1/removal-memory-prometheus-options-source.yml b/data/removals/14_1/removal-memory-prometheus-options-source.yml
new file mode 100644
index 00000000000..afef081c348
--- /dev/null
+++ b/data/removals/14_1/removal-memory-prometheus-options-source.yml
@@ -0,0 +1,8 @@
+- name: "Remove support for `prometheus.listen_address` and `prometheus.enable`"
+ removal_date: July 22, 2021
+ removal_milestone: "14.1"
+ reporter: fzimmer
+ body: |
+ 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.
diff --git a/data/removals/14_1/removal-outdated-browser-support.yml b/data/removals/14_1/removal-outdated-browser-support.yml
new file mode 100644
index 00000000000..1019b8fe2f3
--- /dev/null
+++ b/data/removals/14_1/removal-outdated-browser-support.yml
@@ -0,0 +1,20 @@
+- name: "Remove support for older browsers"
+ removal_date: July 22, 2021
+ removal_milestone: "14.1"
+ reporter: leipert
+ body: |
+ 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.
diff --git a/data/removals/14_2/removal-verify-build-log.yml b/data/removals/14_2/removal-verify-build-log.yml
new file mode 100644
index 00000000000..6b4e37c7c6e
--- /dev/null
+++ b/data/removals/14_2/removal-verify-build-log.yml
@@ -0,0 +1,7 @@
+- name: "Max job log file size of 100 MB"
+ removal_date: August 22, 2021 # day the removal was released
+ removal_milestone: "14.2"
+ reporter: jreporter # GitLab username of the person reporting the removal
+ 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.
+ 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.
diff --git a/data/removals/14_3/removal-limit-tags-to-50.yml b/data/removals/14_3/removal-limit-tags-to-50.yml
new file mode 100644
index 00000000000..db624656e6e
--- /dev/null
+++ b/data/removals/14_3/removal-limit-tags-to-50.yml
@@ -0,0 +1,6 @@
+- name: "Introduced limit of 50 tags for jobs"
+ removal_date: September 22nd, 2021
+ removal_milestone: "14.3"
+ reporter: jreporter
+ body: |
+ 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.
diff --git a/data/removals/14_3/removal-verify-pe-pipelinefindername.yml b/data/removals/14_3/removal-verify-pe-pipelinefindername.yml
new file mode 100644
index 00000000000..979317f99df
--- /dev/null
+++ b/data/removals/14_3/removal-verify-pe-pipelinefindername.yml
@@ -0,0 +1,6 @@
+- name: "List project pipelines API endpoint removes `name` support in 14.3"
+ removal_date: September 22, 2021 # day the removal was released
+ removal_milestone: "14.3"
+ reporter: jreporter # GitLab username of the person reporting the removal
+ 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
new file mode 100644
index 00000000000..b1f98e47554
--- /dev/null
+++ b/data/removals/14_3/removal_legacy_storage_setting.yml
@@ -0,0 +1,8 @@
+- name: Use of legacy storage setting
+ removal_date: September 22nd, 2021 # day the removal was released
+ removal_milestone: "14.3"
+ reporter: dorrino # GitLab username of the person reporting the removal
+ 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/templates/_removal_template.md.erb b/data/removals/templates/_removal_template.md.erb
new file mode 100644
index 00000000000..e227c6aa6e6
--- /dev/null
+++ b/data/removals/templates/_removal_template.md.erb
@@ -0,0 +1,46 @@
+---
+stage: none
+group: none
+info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-development-guidelines"
+---
+
+# Removals by milestone
+
+<!-- vale off -->
+
+<!--
+DO NOT EDIT THIS PAGE DIRECTLY
+
+This page is automatically generated from the YAML files in `/data/removals` by the rake task
+located at `lib/tasks/gitlab/docs/compile_removals.rake`.
+
+For removal authors (usually Product Managers and Engineering Managers):
+
+- To add a removal, use the example.yml file in `/data/removals/templates` as a template.
+- For more information about authoring removals, check the the removal item guidance:
+ https://about.gitlab.com/handbook/marketing/blog/release-posts/#creating-a-removal-entry
+
+For removal reviewers (Technical Writers only):
+
+- To update the removal doc, run: `bin/rake gitlab:docs:compile_removals`
+- To verify the removals doc is up to date, run: `bin/rake gitlab:docs:check_removals`
+- For more information about updating the removal doc, see the removal doc update guidance:
+ https://about.gitlab.com/handbook/marketing/blog/release-posts/#update-the-removals-doc
+-->
+<% if milestones.any? -%>
+ <%- milestones.each do |milestone| %>
+## <%= milestone %>
+ <%- entries.select{|entry| entry["removal_milestone"] == milestone}.each do |removal| %>
+### <%= removal["name"]%>
+<% if removal["breaking_change"] -%>
+WARNING:
+This feature was changed or removed in <%= removal["removal_milestone"]%>
+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.
+
+<%= removal["body"] -%><% else %>
+<%= removal["body"] -%><% end %><%- end -%><%- end -%>
+<%- else -%>
+Features scheduled for removal will be listed here, sorted by GitLab milestone.
+<% end -%>
diff --git a/data/removals/templates/example.yml b/data/removals/templates/example.yml
new file mode 100644
index 00000000000..78cbec2be28
--- /dev/null
+++ b/data/removals/templates/example.yml
@@ -0,0 +1,32 @@
+# This is a template for a feature removal
+# Generally, a feature or configuration should be removed in a major release.
+# It should be announced at least 2 releases prior to being removed.
+#
+# Below is an example of a removal.
+#
+# For more information please refer to the handbook documentation here:
+# https://about.gitlab.com/handbook/marketing/blog/release-posts/#removals
+#
+# Please delete this line and above before submitting your merge request.
+
+- name: "Announcement headline" # The headline announcing the removal. i.e. "`CI_PROJECT_CONFIG_PATH` removed in Gitlab 14.0"
+ announcement_milestone: "XX.YY" # The milestone when this feature was deprecated.
+ announcement_date: "YYYY-MM-DD" # The date of the milestone release when this feature was deprecated. This should almost always be the 22nd of a month (YYYY-MM-DD), unless you did an out of band blog post.
+ removal_milestone: "XX.YY" # The milestone when this feature is being removed.
+ removal_date: "YYYY-MM-DD" # This should almost always be the 22nd of a month (YYYY-MM-DD), the date of the milestone release when this feature will be removed.
+ breaking_change: false # Change to true if this removal is a breaking change.
+ body: | # Do not modify this line, instead modify the lines below.
+ <!-- START OF BODY COMMENT
+
+ This area supports markdown. Delete this entire comment and replace it with your markdown content.
+
+ When ready, assign to your tech writer for review. When ready, they will run `bin/rake gitlab:docs:compile_removals` to update the removals doc, then merge.
+
+ END OF BODY COMMENT -->
+# 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/whats_new/202010230001_13_05.yml b/data/whats_new/202010230001_13_05.yml
index d7dc43d0294..9166d148b37 100644
--- a/data/whats_new/202010230001_13_05.yml
+++ b/data/whats_new/202010230001_13_05.yml
@@ -5,7 +5,7 @@
Despite this popularity, teams have struggled with the limitation that wikis were only available at the project level. Teams working on multiple projects needed to create separate wikis for each repository, leading to a fragmented experience.
- In Gitlab 13.5, we are so excited to bring you group wikis! With [680 upvotes](https://gitlab.com/gitlab-org/gitlab/-/issues/13195) this was the most upvoted feature in the entire GitLab backlog. While highly requested, making a large project-only feature like wikis available at the group level has been a non-trivial operation.
+ In GitLab 13.5, we are so excited to bring you group wikis! With [680 upvotes](https://gitlab.com/gitlab-org/gitlab/-/issues/13195) this was the most upvoted feature in the entire GitLab backlog. While highly requested, making a large project-only feature like wikis available at the group level has been a non-trivial operation.
We know a lot of folks have been looking forward to this feature and shared their input pre-release. We hope all of you will continue to weigh in now that group wikis are available and we’ve opened up a [dedicated issue](https://gitlab.com/gitlab-org/gitlab/-/issues/267593) for your feedback.
stage: Create
diff --git a/data/whats_new/2021102000001_14_04.yml b/data/whats_new/2021102000001_14_04.yml
index 6157b243cbc..146544f6f6b 100644
--- a/data/whats_new/2021102000001_14_04.yml
+++ b/data/whats_new/2021102000001_14_04.yml
@@ -48,7 +48,7 @@
release: 14.4
- title: Integrated error tracking inside GitLab without a Sentry instance
body: |
- Prior to GitLab 14.4, you could integrate with Sentry Error Tracking by supplying an endpoint for a Sentry backend (either self-deployed or in their cloud service). With Gitlab 14.4, you now have access to a Sentry-compatible backend built into your GitLab instance. This allows you to quickly instrument your apps so your errors show up directly in GitLab without the need for a separate Sentry instance.
+ Prior to GitLab 14.4, you could integrate with Sentry Error Tracking by supplying an endpoint for a Sentry backend (either self-deployed or in their cloud service). With GitLab 14.4, you now have access to a Sentry-compatible backend built into your GitLab instance. This allows you to quickly instrument your apps so your errors show up directly in GitLab without the need for a separate Sentry instance.
stage: Manage
self-managed: true
gitlab-com: true
diff --git a/data/whats_new/2021111800001_14_05.yml b/data/whats_new/2021111800001_14_05.yml
index 63b87c21ee0..c38d4cfa9fa 100644
--- a/data/whats_new/2021111800001_14_05.yml
+++ b/data/whats_new/2021111800001_14_05.yml
@@ -1,6 +1,6 @@
- title: Introducing Infrastructure as Code (IaC) security scanning
body: |
- With Gitlab 14.5 we're introducing security scanning for Infrastructure as Code (IaC) configuration files. Like all our SAST scanners, we've chosen to make this capability available for all customers for free to encourage secure coding practices with the rise of IaC. The initial version of this IaC security scanner supports configuration files for Terraform, Ansible, AWS CloudFormation, and Kubernetes and is based on the open-source [Keeping Infrastructure as Code Secure (KICS) project](https://kics.io/). This new IaC scanning capability joins our [existing Kubernetes manifest SAST scanner](https://docs.gitlab.com/ee/user/application_security/sast/#enabling-kubesec-analyzer).
+ With GitLab 14.5 we're introducing security scanning for Infrastructure as Code (IaC) configuration files. Like all our SAST scanners, we've chosen to make this capability available for all customers for free to encourage secure coding practices with the rise of IaC. The initial version of this IaC security scanner supports configuration files for Terraform, Ansible, AWS CloudFormation, and Kubernetes and is based on the open-source [Keeping Infrastructure as Code Secure (KICS) project](https://kics.io/). This new IaC scanning capability joins our [existing Kubernetes manifest SAST scanner](https://docs.gitlab.com/ee/user/application_security/sast/#enabling-kubesec-analyzer).
stage: Secure
self-managed: true
gitlab-com: true
diff --git a/db/fixtures/development/18_abuse_reports.rb b/db/fixtures/development/18_abuse_reports.rb
index 88d2f784852..b06beca35e9 100644
--- a/db/fixtures/development/18_abuse_reports.rb
+++ b/db/fixtures/development/18_abuse_reports.rb
@@ -11,7 +11,7 @@ module Db
name: FFaker::Name.name,
email: FFaker::Internet.email,
confirmed_at: DateTime.now,
- password: '12345678'
+ password: Gitlab::Password.test_default
)
::AbuseReport.create(reporter: ::User.take, user: reported_user, message: 'User sends spam')
diff --git a/db/fixtures/development/31_terraform_state.rb b/db/fixtures/development/31_terraform_state.rb
new file mode 100644
index 00000000000..76f9c270f72
--- /dev/null
+++ b/db/fixtures/development/31_terraform_state.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+TERRAFORM_FILE_VERSION = 1
+
+# Create sample terraform states in existing projects
+Gitlab::Seeder.quiet do
+ tfdata = {terraform_version: '0.14.1'}.to_json
+
+ Project.not_mass_generated.find_each do |project|
+ # Create as the project's creator
+ user = project.creator
+ # Set a build job source, if one exists for the project
+ build = project.builds.last
+
+ remote_state_handler = ::Terraform::RemoteStateHandler.new(project, user, name: project.path, lock_id: nil)
+
+ remote_state_handler.handle_with_lock do |state|
+ # Upload a file if a version does not already exist
+ state.update_file!(CarrierWaveStringFile.new(tfdata), version: TERRAFORM_FILE_VERSION, build: build) if state.latest_version.nil?
+ end
+
+ # rubocop:disable Rails/Output
+ print '.'
+ # rubocop:enable Rails/Output
+ end
+end
diff --git a/db/init_structure.sql b/db/init_structure.sql
index d3f576a7b89..913b495b6fd 100644
--- a/db/init_structure.sql
+++ b/db/init_structure.sql
@@ -10,6 +10,37 @@ CREATE EXTENSION IF NOT EXISTS btree_gist;
CREATE EXTENSION IF NOT EXISTS pg_trgm;
+CREATE FUNCTION set_has_external_issue_tracker() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$
+BEGIN
+UPDATE projects SET has_external_issue_tracker = (
+ EXISTS
+ (
+ SELECT 1
+ FROM services
+ WHERE project_id = COALESCE(NEW.project_id, OLD.project_id)
+ AND active = TRUE
+ AND category = 'issue_tracker'
+ )
+)
+WHERE projects.id = COALESCE(NEW.project_id, OLD.project_id);
+RETURN NULL;
+
+END
+$$;
+
+CREATE FUNCTION set_has_external_wiki() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$
+BEGIN
+UPDATE projects SET has_external_wiki = COALESCE(NEW.active, FALSE)
+WHERE projects.id = COALESCE(NEW.project_id, OLD.project_id);
+RETURN NULL;
+
+END
+$$;
+
CREATE FUNCTION table_sync_function_2be879775d() RETURNS trigger
LANGUAGE plpgsql
AS $$
@@ -63,24 +94,6 @@ $$;
COMMENT ON FUNCTION table_sync_function_2be879775d() IS 'Partitioning migration: table sync for audit_events table';
-CREATE TABLE audit_events (
- id bigint NOT NULL,
- author_id integer NOT NULL,
- entity_id integer NOT NULL,
- entity_type character varying NOT NULL,
- details text,
- ip_address inet,
- author_name text,
- target_details text,
- entity_path text,
- created_at timestamp without time zone NOT NULL,
- target_type text,
- target_id bigint,
- CONSTRAINT check_83ff8406e2 CHECK ((char_length(author_name) <= 255)),
- CONSTRAINT check_97a8c868e7 CHECK ((char_length(target_type) <= 255))
-)
-PARTITION BY RANGE (created_at);
-
CREATE TABLE product_analytics_events_experimental (
id bigint NOT NULL,
project_id integer NOT NULL,
@@ -8836,6 +8849,8 @@ CREATE TABLE alert_management_http_integrations (
encrypted_token_iv text NOT NULL,
endpoint_identifier text NOT NULL,
name text NOT NULL,
+ payload_example jsonb DEFAULT '{}'::jsonb NOT NULL,
+ payload_attribute_mapping jsonb DEFAULT '{}'::jsonb NOT NULL,
CONSTRAINT check_286943b636 CHECK ((char_length(encrypted_token_iv) <= 255)),
CONSTRAINT check_392143ccf4 CHECK ((char_length(name) <= 255)),
CONSTRAINT check_e270820180 CHECK ((char_length(endpoint_identifier) <= 255)),
@@ -8851,24 +8866,6 @@ CREATE SEQUENCE alert_management_http_integrations_id_seq
ALTER SEQUENCE alert_management_http_integrations_id_seq OWNED BY alert_management_http_integrations.id;
-CREATE TABLE alerts_service_data (
- id bigint NOT NULL,
- service_id integer NOT NULL,
- created_at timestamp with time zone NOT NULL,
- updated_at timestamp with time zone NOT NULL,
- encrypted_token character varying(255),
- encrypted_token_iv character varying(255)
-);
-
-CREATE SEQUENCE alerts_service_data_id_seq
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-ALTER SEQUENCE alerts_service_data_id_seq OWNED BY alerts_service_data.id;
-
CREATE TABLE allowed_email_domains (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
@@ -8974,10 +8971,11 @@ ALTER SEQUENCE analytics_devops_adoption_segment_selections_id_seq OWNED BY anal
CREATE TABLE analytics_devops_adoption_segments (
id bigint NOT NULL,
- name text NOT NULL,
+ name text,
last_recorded_at timestamp with time zone,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
+ namespace_id integer,
CONSTRAINT check_4be7a006fd CHECK ((char_length(name) <= 255))
);
@@ -9000,7 +8998,8 @@ 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 NOT NULL,
+ end_time timestamp with time zone NOT NULL
);
CREATE SEQUENCE analytics_devops_adoption_snapshots_id_seq
@@ -9216,7 +9215,6 @@ CREATE TABLE application_settings (
local_markdown_version integer DEFAULT 0 NOT NULL,
asset_proxy_enabled boolean DEFAULT false NOT NULL,
asset_proxy_url character varying,
- asset_proxy_whitelist text,
encrypted_asset_proxy_secret_key text,
encrypted_asset_proxy_secret_key_iv character varying,
lets_encrypt_notification_email character varying,
@@ -9327,7 +9325,7 @@ CREATE TABLE application_settings (
spam_check_endpoint_enabled boolean DEFAULT false NOT NULL,
elasticsearch_pause_indexing boolean DEFAULT false NOT NULL,
repository_storages_weighted jsonb DEFAULT '{}'::jsonb NOT NULL,
- max_import_size integer DEFAULT 50 NOT NULL,
+ max_import_size integer DEFAULT 0 NOT NULL,
enforce_pat_expiration boolean DEFAULT true NOT NULL,
compliance_frameworks smallint[] DEFAULT '{}'::smallint[] NOT NULL,
notify_on_unknown_sign_in boolean DEFAULT true NOT NULL,
@@ -9375,12 +9373,24 @@ CREATE TABLE application_settings (
personal_access_token_prefix text,
kroki_formats jsonb DEFAULT '{}'::jsonb NOT NULL,
disable_feed_token boolean DEFAULT false NOT NULL,
+ container_registry_cleanup_tags_service_max_list_size integer DEFAULT 200 NOT NULL,
+ invisible_captcha_enabled boolean DEFAULT false NOT NULL,
+ rate_limiting_response_text text,
+ keep_latest_artifact boolean DEFAULT true NOT NULL,
+ enforce_ssh_key_expiration boolean DEFAULT false NOT NULL,
+ git_two_factor_session_expiry integer DEFAULT 15 NOT NULL,
+ notes_create_limit integer DEFAULT 300 NOT NULL,
+ notes_create_limit_allowlist text[] DEFAULT '{}'::text[] NOT NULL,
+ in_product_marketing_emails_enabled boolean DEFAULT true NOT NULL,
+ asset_proxy_whitelist text,
+ CONSTRAINT app_settings_container_reg_cleanup_tags_max_list_size_positive CHECK ((container_registry_cleanup_tags_service_max_list_size >= 0)),
CONSTRAINT app_settings_registry_exp_policies_worker_capacity_positive CHECK ((container_registry_expiration_policies_worker_capacity >= 0)),
CONSTRAINT check_17d9558205 CHECK ((char_length(kroki_url) <= 1024)),
CONSTRAINT check_2dba05b802 CHECK ((char_length(gitpod_url) <= 255)),
CONSTRAINT check_51700b31b5 CHECK ((char_length(default_branch_name) <= 255)),
CONSTRAINT check_57123c9593 CHECK ((char_length(help_page_documentation_base_url) <= 255)),
CONSTRAINT check_718b4458ae CHECK ((char_length(personal_access_token_prefix) <= 20)),
+ CONSTRAINT check_7227fad848 CHECK ((char_length(rate_limiting_response_text) <= 255)),
CONSTRAINT check_85a39b68ff CHECK ((char_length(encrypted_ci_jwt_signing_key_iv) <= 255)),
CONSTRAINT check_9a719834eb CHECK ((char_length(secret_detection_token_revocation_url) <= 255)),
CONSTRAINT check_9c6c447a13 CHECK ((char_length(maintenance_mode_message) <= 255)),
@@ -9621,6 +9631,24 @@ CREATE SEQUENCE atlassian_identities_user_id_seq
ALTER SEQUENCE atlassian_identities_user_id_seq OWNED BY atlassian_identities.user_id;
+CREATE TABLE audit_events (
+ id bigint NOT NULL,
+ author_id integer NOT NULL,
+ entity_id integer NOT NULL,
+ entity_type character varying NOT NULL,
+ details text,
+ ip_address inet,
+ author_name text,
+ target_details text,
+ entity_path text,
+ created_at timestamp without time zone NOT NULL,
+ target_type text,
+ target_id bigint,
+ CONSTRAINT check_83ff8406e2 CHECK ((char_length(author_name) <= 255)),
+ CONSTRAINT check_97a8c868e7 CHECK ((char_length(target_type) <= 255))
+)
+PARTITION BY RANGE (created_at);
+
CREATE TABLE audit_events_archived (
id integer NOT NULL,
author_id integer NOT NULL,
@@ -9720,23 +9748,6 @@ CREATE SEQUENCE background_migration_jobs_id_seq
ALTER SEQUENCE background_migration_jobs_id_seq OWNED BY background_migration_jobs.id;
-CREATE TABLE backup_labels (
- id integer NOT NULL,
- title character varying,
- color character varying,
- project_id integer,
- created_at timestamp without time zone,
- updated_at timestamp without time zone,
- template boolean DEFAULT false,
- description character varying,
- description_html text,
- type character varying,
- group_id integer,
- cached_markdown_version integer,
- restore_action integer,
- new_title character varying
-);
-
CREATE TABLE badges (
id integer NOT NULL,
link_url character varying NOT NULL,
@@ -9759,6 +9770,64 @@ CREATE SEQUENCE badges_id_seq
ALTER SEQUENCE badges_id_seq OWNED BY badges.id;
+CREATE TABLE batched_background_migration_jobs (
+ id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ started_at timestamp with time zone,
+ finished_at timestamp with time zone,
+ batched_background_migration_id bigint NOT NULL,
+ min_value bigint NOT NULL,
+ max_value bigint NOT NULL,
+ batch_size integer NOT NULL,
+ sub_batch_size integer NOT NULL,
+ status smallint DEFAULT 0 NOT NULL,
+ attempts smallint DEFAULT 0 NOT NULL
+);
+
+CREATE SEQUENCE batched_background_migration_jobs_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE batched_background_migration_jobs_id_seq OWNED BY batched_background_migration_jobs.id;
+
+CREATE TABLE batched_background_migrations (
+ id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ min_value bigint DEFAULT 1 NOT NULL,
+ max_value bigint NOT NULL,
+ batch_size integer NOT NULL,
+ sub_batch_size integer NOT NULL,
+ "interval" smallint NOT NULL,
+ status smallint DEFAULT 0 NOT NULL,
+ job_class_name text NOT NULL,
+ batch_class_name text DEFAULT 'Gitlab::Database::BackgroundMigration::PrimaryKeyBatchingStrategy'::text NOT NULL,
+ table_name text NOT NULL,
+ column_name text NOT NULL,
+ job_arguments jsonb DEFAULT '"[]"'::jsonb NOT NULL,
+ CONSTRAINT check_5bb0382d6f CHECK ((char_length(column_name) <= 63)),
+ CONSTRAINT check_6b6a06254a CHECK ((char_length(table_name) <= 63)),
+ CONSTRAINT check_batch_size_in_range CHECK ((batch_size >= sub_batch_size)),
+ CONSTRAINT check_e6c75b1e29 CHECK ((char_length(job_class_name) <= 100)),
+ CONSTRAINT check_fe10674721 CHECK ((char_length(batch_class_name) <= 100)),
+ CONSTRAINT check_max_value_in_range CHECK ((max_value >= min_value)),
+ CONSTRAINT check_positive_min_value CHECK ((min_value > 0)),
+ CONSTRAINT check_positive_sub_batch_size CHECK ((sub_batch_size > 0))
+);
+
+CREATE SEQUENCE batched_background_migrations_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE batched_background_migrations_id_seq OWNED BY batched_background_migrations.id;
+
CREATE TABLE board_assignees (
id integer NOT NULL,
board_id integer NOT NULL,
@@ -9912,6 +9981,44 @@ CREATE SEQUENCE boards_epic_boards_id_seq
ALTER SEQUENCE boards_epic_boards_id_seq OWNED BY boards_epic_boards.id;
+CREATE TABLE boards_epic_list_user_preferences (
+ id bigint NOT NULL,
+ user_id bigint NOT NULL,
+ epic_list_id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ collapsed boolean DEFAULT false NOT NULL
+);
+
+CREATE SEQUENCE boards_epic_list_user_preferences_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE boards_epic_list_user_preferences_id_seq OWNED BY boards_epic_list_user_preferences.id;
+
+CREATE TABLE boards_epic_lists (
+ id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ epic_board_id bigint NOT NULL,
+ label_id bigint,
+ "position" integer,
+ list_type smallint DEFAULT 1 NOT NULL,
+ CONSTRAINT boards_epic_lists_position_constraint CHECK (((list_type <> 1) OR (("position" IS NOT NULL) AND ("position" >= 0))))
+);
+
+CREATE SEQUENCE boards_epic_lists_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE boards_epic_lists_id_seq OWNED BY boards_epic_lists.id;
+
CREATE TABLE boards_epic_user_preferences (
id bigint NOT NULL,
board_id bigint NOT NULL,
@@ -10022,8 +10129,10 @@ CREATE TABLE bulk_import_failures (
exception_class text NOT NULL,
exception_message text NOT NULL,
correlation_id_value text,
+ pipeline_step text,
CONSTRAINT check_053d65c7a4 CHECK ((char_length(pipeline_class) <= 255)),
CONSTRAINT check_6eca8f972e CHECK ((char_length(exception_message) <= 255)),
+ CONSTRAINT check_721a422375 CHECK ((char_length(pipeline_step) <= 255)),
CONSTRAINT check_c7dba8398e CHECK ((char_length(exception_class) <= 255)),
CONSTRAINT check_e787285882 CHECK ((char_length(correlation_id_value) <= 255))
);
@@ -10121,7 +10230,8 @@ CREATE TABLE ci_build_needs (
id integer NOT NULL,
build_id integer NOT NULL,
name text NOT NULL,
- artifacts boolean DEFAULT true NOT NULL
+ artifacts boolean DEFAULT true NOT NULL,
+ optional boolean DEFAULT false NOT NULL
);
CREATE SEQUENCE ci_build_needs_id_seq
@@ -10225,7 +10335,6 @@ CREATE TABLE ci_builds (
runner_id integer,
coverage double precision,
commit_id integer,
- commands text,
name character varying,
options text,
allow_failure boolean DEFAULT false NOT NULL,
@@ -10238,14 +10347,11 @@ CREATE TABLE ci_builds (
type character varying,
target_url character varying,
description character varying,
- artifacts_file text,
project_id integer,
- artifacts_metadata text,
erased_by_id integer,
erased_at timestamp without time zone,
artifacts_expire_at timestamp without time zone,
environment character varying,
- artifacts_size bigint,
"when" character varying,
yaml_variables text,
queued_at timestamp without time zone,
@@ -10255,8 +10361,6 @@ CREATE TABLE ci_builds (
auto_canceled_by_id integer,
retried boolean,
stage_id integer,
- artifacts_file_store integer,
- artifacts_metadata_store integer,
protected boolean,
failure_reason integer,
scheduled_at timestamp with time zone,
@@ -10328,7 +10432,8 @@ CREATE TABLE ci_daily_build_group_report_results (
ref_path text NOT NULL,
group_name text NOT NULL,
data jsonb NOT NULL,
- default_branch boolean DEFAULT false NOT NULL
+ default_branch boolean DEFAULT false NOT NULL,
+ group_id bigint
);
CREATE SEQUENCE ci_daily_build_group_report_results_id_seq
@@ -10392,7 +10497,8 @@ CREATE TABLE ci_group_variables (
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
masked boolean DEFAULT false NOT NULL,
- variable_type smallint DEFAULT 1 NOT NULL
+ variable_type smallint DEFAULT 1 NOT NULL,
+ environment_scope text DEFAULT '*'::text NOT NULL
);
CREATE SEQUENCE ci_group_variables_id_seq
@@ -10473,6 +10579,24 @@ CREATE SEQUENCE ci_job_variables_id_seq
ALTER SEQUENCE ci_job_variables_id_seq OWNED BY ci_job_variables.id;
+CREATE TABLE ci_namespace_monthly_usages (
+ id bigint NOT NULL,
+ namespace_id bigint NOT NULL,
+ date date NOT NULL,
+ additional_amount_available integer DEFAULT 0 NOT NULL,
+ amount_used numeric(18,2) DEFAULT 0.0 NOT NULL,
+ CONSTRAINT ci_namespace_monthly_usages_year_month_constraint CHECK ((date = date_trunc('month'::text, (date)::timestamp with time zone)))
+);
+
+CREATE SEQUENCE ci_namespace_monthly_usages_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE ci_namespace_monthly_usages_id_seq OWNED BY ci_namespace_monthly_usages.id;
+
CREATE TABLE ci_pipeline_artifacts (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
@@ -10673,6 +10797,23 @@ CREATE SEQUENCE ci_platform_metrics_id_seq
ALTER SEQUENCE ci_platform_metrics_id_seq OWNED BY ci_platform_metrics.id;
+CREATE TABLE ci_project_monthly_usages (
+ id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ date date NOT NULL,
+ amount_used numeric(18,2) DEFAULT 0.0 NOT NULL,
+ CONSTRAINT ci_project_monthly_usages_year_month_constraint CHECK ((date = date_trunc('month'::text, (date)::timestamp with time zone)))
+);
+
+CREATE SEQUENCE ci_project_monthly_usages_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE ci_project_monthly_usages_id_seq OWNED BY ci_project_monthly_usages.id;
+
CREATE TABLE ci_refs (
id bigint NOT NULL,
project_id bigint NOT NULL,
@@ -10766,7 +10907,6 @@ CREATE TABLE ci_runners (
description character varying,
contacted_at timestamp without time zone,
active boolean DEFAULT true NOT NULL,
- is_shared boolean DEFAULT false,
name character varying,
version character varying,
revision character varying,
@@ -10966,6 +11106,11 @@ CREATE TABLE cluster_agent_tokens (
updated_at timestamp with time zone NOT NULL,
agent_id bigint NOT NULL,
token_encrypted text NOT NULL,
+ created_by_user_id bigint,
+ description text,
+ name text,
+ CONSTRAINT check_2b79dbb315 CHECK ((char_length(name) <= 255)),
+ CONSTRAINT check_4e4ec5070a CHECK ((char_length(description) <= 1024)),
CONSTRAINT check_c60daed227 CHECK ((char_length(token_encrypted) <= 255))
);
@@ -10984,6 +11129,7 @@ CREATE TABLE cluster_agents (
updated_at timestamp with time zone NOT NULL,
project_id bigint NOT NULL,
name text NOT NULL,
+ created_by_user_id bigint,
CONSTRAINT check_3498369510 CHECK ((char_length(name) <= 255))
);
@@ -11134,7 +11280,7 @@ CREATE TABLE clusters (
cleanup_status smallint DEFAULT 1 NOT NULL,
cleanup_status_reason text,
management_project_id integer,
- helm_major_version integer DEFAULT 2 NOT NULL
+ helm_major_version integer DEFAULT 3 NOT NULL
);
CREATE TABLE clusters_applications_cert_managers (
@@ -11433,15 +11579,16 @@ ALTER SEQUENCE commit_user_mentions_id_seq OWNED BY commit_user_mentions.id;
CREATE TABLE compliance_management_frameworks (
id bigint NOT NULL,
- group_id bigint,
name text NOT NULL,
description text NOT NULL,
color text NOT NULL,
namespace_id integer NOT NULL,
regulated boolean DEFAULT true NOT NULL,
+ pipeline_configuration_full_path text,
CONSTRAINT check_08cd34b2c2 CHECK ((char_length(color) <= 10)),
CONSTRAINT check_1617e0b87e CHECK ((char_length(description) <= 255)),
- CONSTRAINT check_ab00bc2193 CHECK ((char_length(name) <= 255))
+ CONSTRAINT check_ab00bc2193 CHECK ((char_length(name) <= 255)),
+ CONSTRAINT check_e7a9972435 CHECK ((char_length(pipeline_configuration_full_path) <= 255))
);
CREATE SEQUENCE compliance_management_frameworks_id_seq
@@ -11475,7 +11622,8 @@ CREATE TABLE container_repositories (
updated_at timestamp without time zone NOT NULL,
status smallint,
expiration_policy_started_at timestamp with time zone,
- expiration_policy_cleanup_status smallint DEFAULT 0 NOT NULL
+ expiration_policy_cleanup_status smallint DEFAULT 0 NOT NULL,
+ expiration_policy_completed_at timestamp with time zone
);
CREATE SEQUENCE container_repositories_id_seq
@@ -11559,6 +11707,7 @@ CREATE TABLE custom_emoji (
name text NOT NULL,
file text NOT NULL,
external boolean DEFAULT true NOT NULL,
+ creator_id bigint NOT NULL,
CONSTRAINT check_8c586dd507 CHECK ((char_length(name) <= 36)),
CONSTRAINT check_dd5d60f1fb CHECK ((char_length(file) <= 255))
);
@@ -11572,6 +11721,32 @@ CREATE SEQUENCE custom_emoji_id_seq
ALTER SEQUENCE custom_emoji_id_seq OWNED BY custom_emoji.id;
+CREATE TABLE dast_profiles (
+ id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ dast_site_profile_id bigint NOT NULL,
+ dast_scanner_profile_id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ name text NOT NULL,
+ description text NOT NULL,
+ branch_name text,
+ CONSTRAINT check_5fcf73bf61 CHECK ((char_length(name) <= 255)),
+ CONSTRAINT check_6c9d775949 CHECK ((char_length(branch_name) <= 255)),
+ CONSTRAINT check_c34e505c24 CHECK ((char_length(description) <= 255))
+);
+
+COMMENT ON TABLE dast_profiles IS '{"owner":"group::dynamic analysis","description":"Profile used to run a DAST on-demand scan"}';
+
+CREATE SEQUENCE dast_profiles_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE dast_profiles_id_seq OWNED BY dast_profiles.id;
+
CREATE TABLE dast_scanner_profiles (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
@@ -11730,7 +11905,9 @@ CREATE TABLE dependency_proxy_manifests (
file_name text NOT NULL,
file text NOT NULL,
digest text NOT NULL,
+ content_type text,
CONSTRAINT check_079b293a7b CHECK ((char_length(file) <= 255)),
+ CONSTRAINT check_167a9a8a91 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_c579e3f586 CHECK ((char_length(file_name) <= 255)),
CONSTRAINT check_f5d9996bf1 CHECK ((char_length(digest) <= 255))
);
@@ -11947,6 +12124,25 @@ CREATE SEQUENCE diff_note_positions_id_seq
ALTER SEQUENCE diff_note_positions_id_seq OWNED BY diff_note_positions.id;
+CREATE TABLE dora_daily_metrics (
+ id bigint NOT NULL,
+ environment_id bigint NOT NULL,
+ date date NOT NULL,
+ deployment_frequency integer,
+ lead_time_for_changes_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))
+);
+
+CREATE SEQUENCE dora_daily_metrics_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE dora_daily_metrics_id_seq OWNED BY dora_daily_metrics.id;
+
CREATE TABLE draft_notes (
id bigint NOT NULL,
merge_request_id integer NOT NULL,
@@ -11969,6 +12165,32 @@ CREATE SEQUENCE draft_notes_id_seq
ALTER SEQUENCE draft_notes_id_seq OWNED BY draft_notes.id;
+CREATE TABLE elastic_reindexing_subtasks (
+ id bigint NOT NULL,
+ elastic_reindexing_task_id bigint NOT NULL,
+ alias_name text NOT NULL,
+ index_name_from text NOT NULL,
+ index_name_to text NOT NULL,
+ elastic_task text NOT NULL,
+ documents_count_target integer,
+ documents_count integer,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ CONSTRAINT check_4910adc798 CHECK ((char_length(elastic_task) <= 255)),
+ CONSTRAINT check_88f56216a4 CHECK ((char_length(alias_name) <= 255)),
+ CONSTRAINT check_a1fbd9faa9 CHECK ((char_length(index_name_from) <= 255)),
+ CONSTRAINT check_f456494bd8 CHECK ((char_length(index_name_to) <= 255))
+);
+
+CREATE SEQUENCE elastic_reindexing_subtasks_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE elastic_reindexing_subtasks_id_seq OWNED BY elastic_reindexing_subtasks.id;
+
CREATE TABLE elastic_reindexing_tasks (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
@@ -12040,7 +12262,9 @@ CREATE TABLE environments (
environment_type character varying,
state character varying DEFAULT 'available'::character varying NOT NULL,
slug character varying NOT NULL,
- auto_stop_at timestamp with time zone
+ auto_stop_at timestamp with time zone,
+ auto_delete_at timestamp with time zone,
+ tier smallint
);
CREATE SEQUENCE environments_id_seq
@@ -12203,6 +12427,8 @@ CREATE TABLE experiment_subjects (
variant smallint DEFAULT 0 NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
+ converted_at timestamp with time zone,
+ context jsonb DEFAULT '{}'::jsonb NOT NULL,
CONSTRAINT chk_has_one_subject CHECK ((num_nonnulls(user_id, group_id, project_id) = 1))
);
@@ -12250,6 +12476,41 @@ CREATE SEQUENCE experiments_id_seq
ALTER SEQUENCE experiments_id_seq OWNED BY experiments.id;
+CREATE TABLE external_approval_rules (
+ id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ external_url text NOT NULL,
+ name text NOT NULL,
+ CONSTRAINT check_1c64b53ea5 CHECK ((char_length(name) <= 255)),
+ CONSTRAINT check_b634ca168d CHECK ((char_length(external_url) <= 255))
+);
+
+CREATE SEQUENCE external_approval_rules_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE external_approval_rules_id_seq OWNED BY external_approval_rules.id;
+
+CREATE TABLE external_approval_rules_protected_branches (
+ id bigint NOT NULL,
+ external_approval_rule_id bigint NOT NULL,
+ protected_branch_id bigint NOT NULL
+);
+
+CREATE SEQUENCE external_approval_rules_protected_branches_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE external_approval_rules_protected_branches_id_seq OWNED BY external_approval_rules_protected_branches.id;
+
CREATE TABLE external_pull_requests (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
@@ -12990,6 +13251,34 @@ CREATE SEQUENCE group_import_states_group_id_seq
ALTER SEQUENCE group_import_states_group_id_seq OWNED BY group_import_states.group_id;
+CREATE TABLE group_merge_request_approval_settings (
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ group_id bigint NOT NULL,
+ allow_author_approval boolean DEFAULT false NOT NULL
+);
+
+CREATE TABLE group_repository_storage_moves (
+ id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ group_id bigint NOT NULL,
+ state smallint DEFAULT 1 NOT NULL,
+ source_storage_name text NOT NULL,
+ destination_storage_name text NOT NULL,
+ CONSTRAINT group_repository_storage_moves_destination_storage_name CHECK ((char_length(destination_storage_name) <= 255)),
+ CONSTRAINT group_repository_storage_moves_source_storage_name CHECK ((char_length(source_storage_name) <= 255))
+);
+
+CREATE SEQUENCE group_repository_storage_moves_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE group_repository_storage_moves_id_seq OWNED BY group_repository_storage_moves.id;
+
CREATE TABLE group_wiki_repositories (
shard_id bigint NOT NULL,
group_id bigint NOT NULL,
@@ -13085,7 +13374,8 @@ CREATE TABLE incident_management_oncall_participants (
oncall_rotation_id bigint NOT NULL,
user_id bigint NOT NULL,
color_palette smallint NOT NULL,
- color_weight smallint NOT NULL
+ color_weight smallint NOT NULL,
+ is_removed boolean DEFAULT false NOT NULL
);
CREATE SEQUENCE incident_management_oncall_participants_id_seq
@@ -13106,6 +13396,9 @@ CREATE TABLE incident_management_oncall_rotations (
length_unit smallint NOT NULL,
starts_at timestamp with time zone NOT NULL,
name text NOT NULL,
+ active_period_start time without time zone,
+ active_period_end time without time zone,
+ ends_at timestamp with time zone,
CONSTRAINT check_5209fb5d02 CHECK ((char_length(name) <= 200))
);
@@ -13442,6 +13735,30 @@ CREATE TABLE issues_self_managed_prometheus_alert_events (
updated_at timestamp with time zone NOT NULL
);
+CREATE TABLE iterations_cadences (
+ id bigint NOT NULL,
+ group_id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ start_date date NOT NULL,
+ last_run_date date,
+ duration_in_weeks integer,
+ iterations_in_advance integer,
+ active boolean DEFAULT true NOT NULL,
+ automatic boolean DEFAULT true NOT NULL,
+ title text NOT NULL,
+ CONSTRAINT check_fedff82d3b CHECK ((char_length(title) <= 255))
+);
+
+CREATE SEQUENCE iterations_cadences_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE iterations_cadences_id_seq OWNED BY iterations_cadences.id;
+
CREATE TABLE jira_connect_installations (
id bigint NOT NULL,
client_key character varying,
@@ -13525,6 +13842,15 @@ CREATE TABLE jira_tracker_data (
deployment_type smallint DEFAULT 0 NOT NULL,
vulnerabilities_issuetype text,
vulnerabilities_enabled boolean DEFAULT false NOT NULL,
+ encrypted_proxy_address text,
+ encrypted_proxy_address_iv text,
+ encrypted_proxy_port text,
+ encrypted_proxy_port_iv text,
+ encrypted_proxy_username text,
+ encrypted_proxy_username_iv text,
+ encrypted_proxy_password text,
+ encrypted_proxy_password_iv text,
+ jira_issue_transition_automatic boolean DEFAULT false NOT NULL,
CONSTRAINT check_0bf84b76e9 CHECK ((char_length(vulnerabilities_issuetype) <= 255)),
CONSTRAINT check_214cf6a48b CHECK ((char_length(project_key) <= 255))
);
@@ -13874,7 +14200,8 @@ CREATE TABLE merge_request_context_commits (
author_email text,
committer_name text,
committer_email text,
- message text
+ message text,
+ trailers jsonb DEFAULT '{}'::jsonb NOT NULL
);
CREATE SEQUENCE merge_request_context_commits_id_seq
@@ -13896,7 +14223,8 @@ CREATE TABLE merge_request_diff_commits (
author_email text,
committer_name text,
committer_email text,
- message text
+ message text,
+ trailers jsonb DEFAULT '{}'::jsonb NOT NULL
);
CREATE TABLE merge_request_diff_details (
@@ -13951,6 +14279,7 @@ CREATE TABLE merge_request_diffs (
stored_externally boolean,
files_count smallint,
sorted boolean DEFAULT false NOT NULL,
+ diff_type smallint DEFAULT 1 NOT NULL,
CONSTRAINT check_93ee616ac9 CHECK ((external_diff_store IS NOT NULL))
);
@@ -14005,7 +14334,8 @@ CREATE TABLE merge_request_reviewers (
id bigint NOT NULL,
user_id bigint NOT NULL,
merge_request_id bigint NOT NULL,
- created_at timestamp with time zone NOT NULL
+ created_at timestamp with time zone NOT NULL,
+ state smallint DEFAULT 0 NOT NULL
);
CREATE SEQUENCE merge_request_reviewers_id_seq
@@ -14069,7 +14399,7 @@ CREATE TABLE merge_requests (
merge_jid character varying,
discussion_locked boolean,
latest_merge_request_diff_id integer,
- allow_maintainer_to_push boolean,
+ allow_maintainer_to_push boolean DEFAULT true,
squash boolean DEFAULT false NOT NULL,
state_id smallint DEFAULT 1 NOT NULL,
approvals_before_merge integer,
@@ -14201,6 +14531,24 @@ CREATE SEQUENCE milestones_id_seq
ALTER SEQUENCE milestones_id_seq OWNED BY milestones.id;
+CREATE TABLE namespace_admin_notes (
+ id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ namespace_id bigint NOT NULL,
+ note text,
+ CONSTRAINT check_e9d2e71b5d CHECK ((char_length(note) <= 1000))
+);
+
+CREATE SEQUENCE namespace_admin_notes_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE namespace_admin_notes_id_seq OWNED BY namespace_admin_notes.id;
+
CREATE TABLE namespace_aggregation_schedules (
namespace_id integer NOT NULL
);
@@ -14222,22 +14570,13 @@ CREATE TABLE namespace_limits (
temporary_storage_increase_ends_on date
);
-CREATE TABLE namespace_onboarding_actions (
- id bigint NOT NULL,
+CREATE TABLE namespace_package_settings (
namespace_id bigint NOT NULL,
- created_at timestamp with time zone NOT NULL,
- action smallint NOT NULL
+ maven_duplicates_allowed boolean DEFAULT true NOT NULL,
+ maven_duplicate_exception_regex text DEFAULT ''::text NOT NULL,
+ CONSTRAINT check_d63274b2b6 CHECK ((char_length(maven_duplicate_exception_regex) <= 255))
);
-CREATE SEQUENCE namespace_onboarding_actions_id_seq
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-ALTER SEQUENCE namespace_onboarding_actions_id_seq OWNED BY namespace_onboarding_actions.id;
-
CREATE TABLE namespace_root_storage_statistics (
namespace_id integer NOT NULL,
updated_at timestamp with time zone NOT NULL,
@@ -14269,6 +14608,8 @@ CREATE TABLE namespace_settings (
prevent_forking_outside_group boolean DEFAULT false NOT NULL,
allow_mfa_for_subgroups boolean DEFAULT true NOT NULL,
default_branch_name text,
+ repository_read_only boolean DEFAULT false NOT NULL,
+ delayed_project_removal boolean DEFAULT false NOT NULL,
CONSTRAINT check_0ba93c78c7 CHECK ((char_length(default_branch_name) <= 255))
);
@@ -14276,7 +14617,9 @@ CREATE TABLE namespace_statistics (
id integer NOT NULL,
namespace_id integer NOT NULL,
shared_runners_seconds integer DEFAULT 0 NOT NULL,
- shared_runners_seconds_last_reset timestamp without time zone
+ shared_runners_seconds_last_reset timestamp without time zone,
+ storage_size bigint DEFAULT 0 NOT NULL,
+ wiki_size bigint DEFAULT 0 NOT NULL
);
CREATE SEQUENCE namespace_statistics_id_seq
@@ -14440,7 +14783,8 @@ CREATE TABLE notification_settings (
new_release boolean,
fixed_pipeline boolean,
moved_project boolean DEFAULT true NOT NULL,
- change_reviewer_merge_request boolean
+ change_reviewer_merge_request boolean,
+ merge_when_pipeline_succeeds boolean DEFAULT false NOT NULL
);
CREATE SEQUENCE notification_settings_id_seq
@@ -14542,6 +14886,37 @@ CREATE SEQUENCE oauth_openid_requests_id_seq
ALTER SEQUENCE oauth_openid_requests_id_seq OWNED BY oauth_openid_requests.id;
+CREATE TABLE onboarding_progresses (
+ id bigint NOT NULL,
+ namespace_id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ git_pull_at timestamp with time zone,
+ git_write_at timestamp with time zone,
+ merge_request_created_at timestamp with time zone,
+ pipeline_created_at timestamp with time zone,
+ user_added_at timestamp with time zone,
+ trial_started_at timestamp with time zone,
+ subscription_created_at timestamp with time zone,
+ required_mr_approvals_enabled_at timestamp with time zone,
+ code_owners_enabled_at timestamp with time zone,
+ scoped_label_created_at timestamp with time zone,
+ security_scan_enabled_at timestamp with time zone,
+ issue_auto_closed_at timestamp with time zone,
+ repository_imported_at timestamp with time zone,
+ repository_mirrored_at timestamp with time zone,
+ issue_created_at timestamp with time zone
+);
+
+CREATE SEQUENCE onboarding_progresses_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE onboarding_progresses_id_seq OWNED BY onboarding_progresses.id;
+
CREATE TABLE open_project_tracker_data (
id bigint NOT NULL,
service_id integer NOT NULL,
@@ -14716,6 +15091,27 @@ CREATE SEQUENCE packages_build_infos_id_seq
ALTER SEQUENCE packages_build_infos_id_seq OWNED BY packages_build_infos.id;
+CREATE TABLE packages_composer_cache_files (
+ id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ delete_at timestamp with time zone,
+ namespace_id integer,
+ file_store smallint DEFAULT 1 NOT NULL,
+ file text NOT NULL,
+ file_sha256 bytea NOT NULL,
+ CONSTRAINT check_84f5ba81f5 CHECK ((char_length(file) <= 255))
+);
+
+CREATE SEQUENCE packages_composer_cache_files_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE packages_composer_cache_files_id_seq OWNED BY packages_composer_cache_files.id;
+
CREATE TABLE packages_composer_metadata (
package_id bigint NOT NULL,
target_sha bytea NOT NULL,
@@ -15132,7 +15528,8 @@ CREATE TABLE packages_packages (
name character varying NOT NULL,
version character varying,
package_type smallint NOT NULL,
- creator_id integer
+ creator_id integer,
+ status smallint DEFAULT 0 NOT NULL
);
CREATE SEQUENCE packages_packages_id_seq
@@ -15151,6 +15548,58 @@ CREATE TABLE packages_pypi_metadata (
CONSTRAINT check_379019d5da CHECK ((char_length(required_python) <= 255))
);
+CREATE TABLE packages_rubygems_metadata (
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ package_id bigint NOT NULL,
+ authors text,
+ files text,
+ summary text,
+ description text,
+ email text,
+ homepage text,
+ licenses text,
+ metadata text,
+ author text,
+ bindir text,
+ cert_chain text,
+ executables text,
+ extensions text,
+ extra_rdoc_files text,
+ platform text,
+ post_install_message text,
+ rdoc_options text,
+ require_paths text,
+ required_ruby_version text,
+ required_rubygems_version text,
+ requirements text,
+ rubygems_version text,
+ signing_key text,
+ CONSTRAINT check_0154a18c82 CHECK ((char_length(description) <= 1024)),
+ CONSTRAINT check_22814c771b CHECK ((char_length(email) <= 255)),
+ CONSTRAINT check_242293030e CHECK ((char_length(extensions) <= 255)),
+ CONSTRAINT check_27619a7922 CHECK ((char_length(rubygems_version) <= 255)),
+ CONSTRAINT check_3d1b6f3a39 CHECK ((char_length(post_install_message) <= 255)),
+ CONSTRAINT check_545f7606f9 CHECK ((char_length(required_rubygems_version) <= 255)),
+ CONSTRAINT check_5988451714 CHECK ((char_length(executables) <= 255)),
+ CONSTRAINT check_5f9c84ea17 CHECK ((char_length(platform) <= 255)),
+ CONSTRAINT check_64f1cecf05 CHECK ((char_length(requirements) <= 255)),
+ CONSTRAINT check_6ac7043c50 CHECK ((char_length(extra_rdoc_files) <= 255)),
+ CONSTRAINT check_6ff3abe325 CHECK ((char_length(cert_chain) <= 255)),
+ CONSTRAINT check_7cb01436df CHECK ((char_length(licenses) <= 255)),
+ CONSTRAINT check_8be21d92e7 CHECK ((char_length(summary) <= 1024)),
+ CONSTRAINT check_946cb96acb CHECK ((char_length(homepage) <= 255)),
+ CONSTRAINT check_9824fc9efc CHECK ((char_length(bindir) <= 255)),
+ CONSTRAINT check_994b68eb64 CHECK ((char_length(authors) <= 255)),
+ CONSTRAINT check_9d42fa48ae CHECK ((char_length(signing_key) <= 255)),
+ CONSTRAINT check_b0f4f8c853 CHECK ((char_length(files) <= 255)),
+ CONSTRAINT check_b7b296b420 CHECK ((char_length(author) <= 255)),
+ CONSTRAINT check_bf16b21a47 CHECK ((char_length(rdoc_options) <= 255)),
+ CONSTRAINT check_ca641a3354 CHECK ((char_length(required_ruby_version) <= 255)),
+ CONSTRAINT check_ea02f4800f CHECK ((char_length(metadata) <= 30000)),
+ CONSTRAINT check_f76bad1a9a CHECK ((char_length(require_paths) <= 255))
+);
+
CREATE TABLE packages_tags (
id bigint NOT NULL,
package_id integer NOT NULL,
@@ -15175,10 +15624,11 @@ CREATE TABLE pages_deployments (
project_id bigint NOT NULL,
ci_build_id bigint,
file_store smallint NOT NULL,
- size integer NOT NULL,
file text NOT NULL,
file_count integer NOT NULL,
file_sha256 bytea NOT NULL,
+ size bigint,
+ CONSTRAINT check_5f9132a958 CHECK ((size IS NOT NULL)),
CONSTRAINT check_f0fe8032dd CHECK ((char_length(file) <= 255))
);
@@ -15366,7 +15816,8 @@ CREATE TABLE plan_limits (
ci_max_artifact_size_api_fuzzing integer DEFAULT 0 NOT NULL,
daily_invites integer DEFAULT 0 NOT NULL,
ci_pipeline_deployments integer DEFAULT 500 NOT NULL,
- pull_mirror_interval_seconds integer DEFAULT 300 NOT NULL
+ pull_mirror_interval_seconds integer DEFAULT 300 NOT NULL,
+ rubygems_max_file_size bigint DEFAULT '3221225472'::bigint NOT NULL
);
CREATE SEQUENCE plan_limits_id_seq
@@ -15595,6 +16046,7 @@ CREATE TABLE postgres_reindex_actions (
ondisk_size_bytes_end bigint,
state smallint DEFAULT 0 NOT NULL,
index_identifier text NOT NULL,
+ bloat_estimate_bytes_start bigint,
CONSTRAINT check_f12527622c CHECK ((char_length(index_identifier) <= 255))
);
@@ -15686,7 +16138,8 @@ CREATE TABLE project_ci_cd_settings (
forward_deployment_enabled boolean,
merge_trains_enabled boolean DEFAULT false,
auto_rollback_enabled boolean DEFAULT false NOT NULL,
- keep_latest_artifact boolean DEFAULT true NOT NULL
+ keep_latest_artifact boolean DEFAULT true NOT NULL,
+ restrict_user_defined_variables boolean DEFAULT false NOT NULL
);
CREATE SEQUENCE project_ci_cd_settings_id_seq
@@ -15817,7 +16270,9 @@ CREATE TABLE project_features (
metrics_dashboard_access_level integer,
analytics_access_level integer DEFAULT 20 NOT NULL,
requirements_access_level integer DEFAULT 20 NOT NULL,
- operations_access_level integer DEFAULT 20 NOT NULL
+ operations_access_level integer DEFAULT 20 NOT NULL,
+ security_and_compliance_access_level integer DEFAULT 10 NOT NULL,
+ container_registry_access_level integer DEFAULT 0 NOT NULL
);
CREATE SEQUENCE project_features_id_seq
@@ -16013,7 +16468,8 @@ CREATE TABLE project_settings (
squash_option smallint DEFAULT 3,
has_confluence boolean DEFAULT false NOT NULL,
cve_id_request_enabled boolean DEFAULT true NOT NULL,
- has_vulnerabilities boolean DEFAULT false NOT NULL
+ has_vulnerabilities boolean DEFAULT false NOT NULL,
+ prevent_merge_without_jira_issue boolean DEFAULT false NOT NULL
);
CREATE TABLE project_statistics (
@@ -16290,7 +16746,8 @@ CREATE TABLE protected_branches (
name character varying NOT NULL,
created_at timestamp without time zone,
updated_at timestamp without time zone,
- code_owner_approval_required boolean DEFAULT false NOT NULL
+ code_owner_approval_required boolean DEFAULT false NOT NULL,
+ allow_force_push boolean DEFAULT false NOT NULL
);
CREATE SEQUENCE protected_branches_id_seq
@@ -16429,7 +16886,8 @@ CREATE TABLE raw_usage_data (
updated_at timestamp with time zone NOT NULL,
recorded_at timestamp with time zone NOT NULL,
sent_at timestamp with time zone,
- payload jsonb NOT NULL
+ payload jsonb NOT NULL,
+ version_usage_data_id_value bigint
);
CREATE SEQUENCE raw_usage_data_id_seq
@@ -16842,6 +17300,25 @@ CREATE SEQUENCE security_findings_id_seq
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,
+ security_policy_management_project_id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT 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"}';
+
+CREATE SEQUENCE security_orchestration_policy_configurations_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE security_orchestration_policy_configurations_id_seq OWNED BY security_orchestration_policy_configurations.id;
+
CREATE TABLE security_scans (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
@@ -17196,6 +17673,7 @@ CREATE TABLE sprints (
description text,
description_html text,
state_enum smallint DEFAULT 1 NOT NULL,
+ iterations_cadence_id integer,
CONSTRAINT sprints_must_belong_to_project_or_group CHECK ((((project_id <> NULL::bigint) AND (group_id IS NULL)) OR ((group_id <> NULL::bigint) AND (project_id IS NULL)))),
CONSTRAINT sprints_title CHECK ((char_length(title) <= 255))
);
@@ -17406,7 +17884,7 @@ CREATE TABLE terraform_states (
locked_at timestamp with time zone,
locked_by_user_id bigint,
uuid character varying(32) NOT NULL,
- name character varying(255),
+ name character varying(255) NOT NULL,
versioning_enabled boolean DEFAULT true NOT NULL
);
@@ -17703,7 +18181,8 @@ CREATE TABLE user_preferences (
tab_width smallint,
experience_level smallint,
view_diffs_file_by_file boolean DEFAULT false NOT NULL,
- gitpod_enabled boolean DEFAULT false NOT NULL
+ gitpod_enabled boolean DEFAULT false NOT NULL,
+ markdown_surround_selection boolean DEFAULT true NOT NULL
);
CREATE SEQUENCE user_preferences_id_seq
@@ -17722,7 +18201,8 @@ CREATE TABLE user_statuses (
emoji character varying DEFAULT 'speech_balloon'::character varying NOT NULL,
message character varying(100),
message_html character varying,
- availability smallint DEFAULT 0 NOT NULL
+ availability smallint DEFAULT 0 NOT NULL,
+ clear_status_at timestamp with time zone
);
CREATE SEQUENCE user_statuses_user_id_seq
@@ -18018,7 +18498,8 @@ CREATE TABLE vulnerability_feedback (
comment_author_id integer,
comment text,
comment_timestamp timestamp with time zone,
- finding_uuid uuid
+ finding_uuid uuid,
+ dismissal_reason smallint
);
CREATE SEQUENCE vulnerability_feedback_id_seq
@@ -18036,7 +18517,7 @@ CREATE TABLE vulnerability_finding_fingerprints (
finding_id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
- algorithm_type integer NOT NULL,
+ algorithm_type smallint NOT NULL,
fingerprint_sha256 bytea NOT NULL
);
@@ -18201,7 +18682,16 @@ CREATE TABLE vulnerability_occurrences (
metadata_version character varying NOT NULL,
raw_metadata text NOT NULL,
vulnerability_id bigint,
- details jsonb DEFAULT '{}'::jsonb NOT NULL
+ details jsonb DEFAULT '{}'::jsonb NOT NULL,
+ description text,
+ message text,
+ solution text,
+ cve text,
+ location jsonb,
+ CONSTRAINT check_4a3a60f2ba CHECK ((char_length(solution) <= 7000)),
+ CONSTRAINT check_ade261da6b CHECK ((char_length(description) <= 15000)),
+ CONSTRAINT check_df6dd20219 CHECK ((char_length(message) <= 3000)),
+ CONSTRAINT check_f602da68dd CHECK ((char_length(cve) <= 48400))
);
CREATE SEQUENCE vulnerability_occurrences_id_seq
@@ -18352,7 +18842,8 @@ CREATE TABLE web_hooks (
deployment_events boolean DEFAULT false NOT NULL,
feature_flag_events boolean DEFAULT false NOT NULL,
releases_events boolean DEFAULT false NOT NULL,
- member_events boolean DEFAULT false NOT NULL
+ member_events boolean DEFAULT false NOT NULL,
+ subgroup_events boolean DEFAULT false NOT NULL
);
CREATE SEQUENCE web_hooks_id_seq
@@ -18512,8 +19003,6 @@ ALTER TABLE ONLY alert_management_alerts ALTER COLUMN id SET DEFAULT nextval('al
ALTER TABLE ONLY alert_management_http_integrations ALTER COLUMN id SET DEFAULT nextval('alert_management_http_integrations_id_seq'::regclass);
-ALTER TABLE ONLY alerts_service_data ALTER COLUMN id SET DEFAULT nextval('alerts_service_data_id_seq'::regclass);
-
ALTER TABLE ONLY allowed_email_domains ALTER COLUMN id SET DEFAULT nextval('allowed_email_domains_id_seq'::regclass);
ALTER TABLE ONLY analytics_cycle_analytics_group_stages ALTER COLUMN id SET DEFAULT nextval('analytics_cycle_analytics_group_stages_id_seq'::regclass);
@@ -18570,6 +19059,10 @@ ALTER TABLE ONLY background_migration_jobs ALTER COLUMN id SET DEFAULT nextval('
ALTER TABLE ONLY badges ALTER COLUMN id SET DEFAULT nextval('badges_id_seq'::regclass);
+ALTER TABLE ONLY batched_background_migration_jobs ALTER COLUMN id SET DEFAULT nextval('batched_background_migration_jobs_id_seq'::regclass);
+
+ALTER TABLE ONLY batched_background_migrations ALTER COLUMN id SET DEFAULT nextval('batched_background_migrations_id_seq'::regclass);
+
ALTER TABLE ONLY board_assignees ALTER COLUMN id SET DEFAULT nextval('board_assignees_id_seq'::regclass);
ALTER TABLE ONLY board_group_recent_visits ALTER COLUMN id SET DEFAULT nextval('board_group_recent_visits_id_seq'::regclass);
@@ -18588,6 +19081,10 @@ ALTER TABLE ONLY boards_epic_board_positions ALTER COLUMN id SET DEFAULT nextval
ALTER TABLE ONLY boards_epic_boards ALTER COLUMN id SET DEFAULT nextval('boards_epic_boards_id_seq'::regclass);
+ALTER TABLE ONLY boards_epic_list_user_preferences ALTER COLUMN id SET DEFAULT nextval('boards_epic_list_user_preferences_id_seq'::regclass);
+
+ALTER TABLE ONLY boards_epic_lists ALTER COLUMN id SET DEFAULT nextval('boards_epic_lists_id_seq'::regclass);
+
ALTER TABLE ONLY boards_epic_user_preferences ALTER COLUMN id SET DEFAULT nextval('boards_epic_user_preferences_id_seq'::regclass);
ALTER TABLE ONLY broadcast_messages ALTER COLUMN id SET DEFAULT nextval('broadcast_messages_id_seq'::regclass);
@@ -18636,6 +19133,8 @@ ALTER TABLE ONLY ci_job_artifacts ALTER COLUMN id SET DEFAULT nextval('ci_job_ar
ALTER TABLE ONLY ci_job_variables ALTER COLUMN id SET DEFAULT nextval('ci_job_variables_id_seq'::regclass);
+ALTER TABLE ONLY ci_namespace_monthly_usages ALTER COLUMN id SET DEFAULT nextval('ci_namespace_monthly_usages_id_seq'::regclass);
+
ALTER TABLE ONLY ci_pipeline_artifacts ALTER COLUMN id SET DEFAULT nextval('ci_pipeline_artifacts_id_seq'::regclass);
ALTER TABLE ONLY ci_pipeline_chat_data ALTER COLUMN id SET DEFAULT nextval('ci_pipeline_chat_data_id_seq'::regclass);
@@ -18654,6 +19153,8 @@ ALTER TABLE ONLY ci_pipelines_config ALTER COLUMN pipeline_id SET DEFAULT nextva
ALTER TABLE ONLY ci_platform_metrics ALTER COLUMN id SET DEFAULT nextval('ci_platform_metrics_id_seq'::regclass);
+ALTER TABLE ONLY ci_project_monthly_usages ALTER COLUMN id SET DEFAULT nextval('ci_project_monthly_usages_id_seq'::regclass);
+
ALTER TABLE ONLY ci_refs ALTER COLUMN id SET DEFAULT nextval('ci_refs_id_seq'::regclass);
ALTER TABLE ONLY ci_resource_groups ALTER COLUMN id SET DEFAULT nextval('ci_resource_groups_id_seq'::regclass);
@@ -18736,6 +19237,8 @@ ALTER TABLE ONLY csv_issue_imports ALTER COLUMN id SET DEFAULT nextval('csv_issu
ALTER TABLE ONLY custom_emoji ALTER COLUMN id SET DEFAULT nextval('custom_emoji_id_seq'::regclass);
+ALTER TABLE ONLY dast_profiles ALTER COLUMN id SET DEFAULT nextval('dast_profiles_id_seq'::regclass);
+
ALTER TABLE ONLY dast_scanner_profiles ALTER COLUMN id SET DEFAULT nextval('dast_scanner_profiles_id_seq'::regclass);
ALTER TABLE ONLY dast_site_profiles ALTER COLUMN id SET DEFAULT nextval('dast_site_profiles_id_seq'::regclass);
@@ -18770,8 +19273,12 @@ ALTER TABLE ONLY design_user_mentions ALTER COLUMN id SET DEFAULT nextval('desig
ALTER TABLE ONLY diff_note_positions ALTER COLUMN id SET DEFAULT nextval('diff_note_positions_id_seq'::regclass);
+ALTER TABLE ONLY dora_daily_metrics ALTER COLUMN id SET DEFAULT nextval('dora_daily_metrics_id_seq'::regclass);
+
ALTER TABLE ONLY draft_notes ALTER COLUMN id SET DEFAULT nextval('draft_notes_id_seq'::regclass);
+ALTER TABLE ONLY elastic_reindexing_subtasks ALTER COLUMN id SET DEFAULT nextval('elastic_reindexing_subtasks_id_seq'::regclass);
+
ALTER TABLE ONLY elastic_reindexing_tasks ALTER COLUMN id SET DEFAULT nextval('elastic_reindexing_tasks_id_seq'::regclass);
ALTER TABLE ONLY emails ALTER COLUMN id SET DEFAULT nextval('emails_id_seq'::regclass);
@@ -18796,6 +19303,10 @@ ALTER TABLE ONLY experiment_users ALTER COLUMN id SET DEFAULT nextval('experimen
ALTER TABLE ONLY experiments ALTER COLUMN id SET DEFAULT nextval('experiments_id_seq'::regclass);
+ALTER TABLE ONLY external_approval_rules ALTER COLUMN id SET DEFAULT nextval('external_approval_rules_id_seq'::regclass);
+
+ALTER TABLE ONLY external_approval_rules_protected_branches ALTER COLUMN id SET DEFAULT nextval('external_approval_rules_protected_branches_id_seq'::regclass);
+
ALTER TABLE ONLY external_pull_requests ALTER COLUMN id SET DEFAULT nextval('external_pull_requests_id_seq'::regclass);
ALTER TABLE ONLY feature_gates ALTER COLUMN id SET DEFAULT nextval('feature_gates_id_seq'::regclass);
@@ -18866,6 +19377,8 @@ ALTER TABLE ONLY group_group_links ALTER COLUMN id SET DEFAULT nextval('group_gr
ALTER TABLE ONLY group_import_states ALTER COLUMN group_id SET DEFAULT nextval('group_import_states_group_id_seq'::regclass);
+ALTER TABLE ONLY group_repository_storage_moves ALTER COLUMN id SET DEFAULT nextval('group_repository_storage_moves_id_seq'::regclass);
+
ALTER TABLE ONLY historical_data ALTER COLUMN id SET DEFAULT nextval('historical_data_id_seq'::regclass);
ALTER TABLE ONLY identities ALTER COLUMN id SET DEFAULT nextval('identities_id_seq'::regclass);
@@ -18908,6 +19421,8 @@ ALTER TABLE ONLY issue_user_mentions ALTER COLUMN id SET DEFAULT nextval('issue_
ALTER TABLE ONLY issues ALTER COLUMN id SET DEFAULT nextval('issues_id_seq'::regclass);
+ALTER TABLE ONLY iterations_cadences ALTER COLUMN id SET DEFAULT nextval('iterations_cadences_id_seq'::regclass);
+
ALTER TABLE ONLY jira_connect_installations ALTER COLUMN id SET DEFAULT nextval('jira_connect_installations_id_seq'::regclass);
ALTER TABLE ONLY jira_connect_subscriptions ALTER COLUMN id SET DEFAULT nextval('jira_connect_subscriptions_id_seq'::regclass);
@@ -18970,9 +19485,9 @@ ALTER TABLE ONLY metrics_users_starred_dashboards ALTER COLUMN id SET DEFAULT ne
ALTER TABLE ONLY milestones ALTER COLUMN id SET DEFAULT nextval('milestones_id_seq'::regclass);
-ALTER TABLE ONLY namespace_aggregation_schedules ALTER COLUMN namespace_id SET DEFAULT nextval('namespace_aggregation_schedules_namespace_id_seq'::regclass);
+ALTER TABLE ONLY namespace_admin_notes ALTER COLUMN id SET DEFAULT nextval('namespace_admin_notes_id_seq'::regclass);
-ALTER TABLE ONLY namespace_onboarding_actions ALTER COLUMN id SET DEFAULT nextval('namespace_onboarding_actions_id_seq'::regclass);
+ALTER TABLE ONLY namespace_aggregation_schedules ALTER COLUMN namespace_id SET DEFAULT nextval('namespace_aggregation_schedules_namespace_id_seq'::regclass);
ALTER TABLE ONLY namespace_root_storage_statistics ALTER COLUMN namespace_id SET DEFAULT nextval('namespace_root_storage_statistics_namespace_id_seq'::regclass);
@@ -18994,6 +19509,8 @@ ALTER TABLE ONLY oauth_applications ALTER COLUMN id SET DEFAULT nextval('oauth_a
ALTER TABLE ONLY oauth_openid_requests ALTER COLUMN id SET DEFAULT nextval('oauth_openid_requests_id_seq'::regclass);
+ALTER TABLE ONLY onboarding_progresses ALTER COLUMN id SET DEFAULT nextval('onboarding_progresses_id_seq'::regclass);
+
ALTER TABLE ONLY open_project_tracker_data ALTER COLUMN id SET DEFAULT nextval('open_project_tracker_data_id_seq'::regclass);
ALTER TABLE ONLY operations_feature_flag_scopes ALTER COLUMN id SET DEFAULT nextval('operations_feature_flag_scopes_id_seq'::regclass);
@@ -19014,6 +19531,8 @@ ALTER TABLE ONLY operations_user_lists ALTER COLUMN id SET DEFAULT nextval('oper
ALTER TABLE ONLY packages_build_infos ALTER COLUMN id SET DEFAULT nextval('packages_build_infos_id_seq'::regclass);
+ALTER TABLE ONLY packages_composer_cache_files ALTER COLUMN id SET DEFAULT nextval('packages_composer_cache_files_id_seq'::regclass);
+
ALTER TABLE ONLY packages_conan_file_metadata ALTER COLUMN id SET DEFAULT nextval('packages_conan_file_metadata_id_seq'::regclass);
ALTER TABLE ONLY packages_conan_metadata ALTER COLUMN id SET DEFAULT nextval('packages_conan_metadata_id_seq'::regclass);
@@ -19178,6 +19697,8 @@ ALTER TABLE ONLY scim_oauth_access_tokens ALTER COLUMN id SET DEFAULT nextval('s
ALTER TABLE ONLY security_findings ALTER COLUMN id SET DEFAULT nextval('security_findings_id_seq'::regclass);
+ALTER TABLE ONLY security_orchestration_policy_configurations ALTER COLUMN id SET DEFAULT nextval('security_orchestration_policy_configurations_id_seq'::regclass);
+
ALTER TABLE ONLY security_scans ALTER COLUMN id SET DEFAULT nextval('security_scans_id_seq'::regclass);
ALTER TABLE ONLY self_managed_prometheus_alert_events ALTER COLUMN id SET DEFAULT nextval('self_managed_prometheus_alert_events_id_seq'::regclass);
@@ -19528,9 +20049,6 @@ ALTER TABLE ONLY alert_management_alerts
ALTER TABLE ONLY alert_management_http_integrations
ADD CONSTRAINT alert_management_http_integrations_pkey PRIMARY KEY (id);
-ALTER TABLE ONLY alerts_service_data
- ADD CONSTRAINT alerts_service_data_pkey PRIMARY KEY (id);
-
ALTER TABLE ONLY allowed_email_domains
ADD CONSTRAINT allowed_email_domains_pkey PRIMARY KEY (id);
@@ -19624,12 +20142,15 @@ ALTER TABLE ONLY aws_roles
ALTER TABLE ONLY background_migration_jobs
ADD CONSTRAINT background_migration_jobs_pkey PRIMARY KEY (id);
-ALTER TABLE ONLY backup_labels
- ADD CONSTRAINT backup_labels_pkey PRIMARY KEY (id);
-
ALTER TABLE ONLY badges
ADD CONSTRAINT badges_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY batched_background_migration_jobs
+ ADD CONSTRAINT batched_background_migration_jobs_pkey PRIMARY KEY (id);
+
+ALTER TABLE ONLY batched_background_migrations
+ ADD CONSTRAINT batched_background_migrations_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY board_assignees
ADD CONSTRAINT board_assignees_pkey PRIMARY KEY (id);
@@ -19654,6 +20175,12 @@ ALTER TABLE ONLY boards_epic_board_positions
ALTER TABLE ONLY boards_epic_boards
ADD CONSTRAINT boards_epic_boards_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY boards_epic_list_user_preferences
+ ADD CONSTRAINT boards_epic_list_user_preferences_pkey PRIMARY KEY (id);
+
+ALTER TABLE ONLY boards_epic_lists
+ ADD CONSTRAINT boards_epic_lists_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY boards_epic_user_preferences
ADD CONSTRAINT boards_epic_user_preferences_pkey PRIMARY KEY (id);
@@ -19687,9 +20214,15 @@ ALTER TABLE ONLY chat_teams
ALTER TABLE vulnerability_scanners
ADD CONSTRAINT check_37608c9db5 CHECK ((char_length(vendor) <= 255)) NOT VALID;
+ALTER TABLE sprints
+ ADD CONSTRAINT check_ccd8a1eae0 CHECK ((start_date IS NOT NULL)) NOT VALID;
+
ALTER TABLE group_import_states
ADD CONSTRAINT check_cda75c7c3f CHECK ((user_id IS NOT NULL)) NOT VALID;
+ALTER TABLE sprints
+ ADD CONSTRAINT check_df3816aed7 CHECK ((due_date IS NOT NULL)) NOT VALID;
+
ALTER TABLE ONLY ci_build_needs
ADD CONSTRAINT ci_build_needs_pkey PRIMARY KEY (id);
@@ -19738,6 +20271,9 @@ ALTER TABLE ONLY ci_job_artifacts
ALTER TABLE ONLY ci_job_variables
ADD CONSTRAINT ci_job_variables_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY ci_namespace_monthly_usages
+ ADD CONSTRAINT ci_namespace_monthly_usages_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY ci_pipeline_artifacts
ADD CONSTRAINT ci_pipeline_artifacts_pkey PRIMARY KEY (id);
@@ -19765,6 +20301,9 @@ ALTER TABLE ONLY ci_pipelines
ALTER TABLE ONLY ci_platform_metrics
ADD CONSTRAINT ci_platform_metrics_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY ci_project_monthly_usages
+ ADD CONSTRAINT ci_project_monthly_usages_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY ci_refs
ADD CONSTRAINT ci_refs_pkey PRIMARY KEY (id);
@@ -19891,6 +20430,9 @@ ALTER TABLE ONLY csv_issue_imports
ALTER TABLE ONLY custom_emoji
ADD CONSTRAINT custom_emoji_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY dast_profiles
+ ADD CONSTRAINT dast_profiles_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY dast_scanner_profiles
ADD CONSTRAINT dast_scanner_profiles_pkey PRIMARY KEY (id);
@@ -19948,9 +20490,15 @@ ALTER TABLE ONLY design_user_mentions
ALTER TABLE ONLY diff_note_positions
ADD CONSTRAINT diff_note_positions_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY dora_daily_metrics
+ ADD CONSTRAINT dora_daily_metrics_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY draft_notes
ADD CONSTRAINT draft_notes_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY elastic_reindexing_subtasks
+ ADD CONSTRAINT elastic_reindexing_subtasks_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY elastic_reindexing_tasks
ADD CONSTRAINT elastic_reindexing_tasks_pkey PRIMARY KEY (id);
@@ -19993,6 +20541,12 @@ ALTER TABLE ONLY experiment_users
ALTER TABLE ONLY experiments
ADD CONSTRAINT experiments_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY external_approval_rules
+ ADD CONSTRAINT external_approval_rules_pkey PRIMARY KEY (id);
+
+ALTER TABLE ONLY external_approval_rules_protected_branches
+ ADD CONSTRAINT external_approval_rules_protected_branches_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY external_pull_requests
ADD CONSTRAINT external_pull_requests_pkey PRIMARY KEY (id);
@@ -20101,6 +20655,12 @@ ALTER TABLE ONLY group_group_links
ALTER TABLE ONLY group_import_states
ADD CONSTRAINT group_import_states_pkey PRIMARY KEY (group_id);
+ALTER TABLE ONLY group_merge_request_approval_settings
+ ADD CONSTRAINT group_merge_request_approval_settings_pkey PRIMARY KEY (group_id);
+
+ALTER TABLE ONLY group_repository_storage_moves
+ ADD CONSTRAINT group_repository_storage_moves_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY group_wiki_repositories
ADD CONSTRAINT group_wiki_repositories_pkey PRIMARY KEY (group_id);
@@ -20180,11 +20740,14 @@ ALTER TABLE ONLY issues_self_managed_prometheus_alert_events
ADD CONSTRAINT issues_self_managed_prometheus_alert_events_pkey PRIMARY KEY (issue_id, self_managed_prometheus_alert_event_id);
ALTER TABLE ONLY sprints
- ADD CONSTRAINT iteration_start_and_due_daterange_group_id_constraint EXCLUDE USING gist (group_id WITH =, daterange(start_date, due_date, '[]'::text) WITH &&) WHERE ((group_id IS NOT NULL));
+ ADD CONSTRAINT iteration_start_and_due_date_iterations_cadence_id_constraint EXCLUDE USING gist (iterations_cadence_id WITH =, daterange(start_date, due_date, '[]'::text) WITH &&) WHERE ((group_id IS NOT NULL));
ALTER TABLE ONLY sprints
ADD CONSTRAINT iteration_start_and_due_daterange_project_id_constraint EXCLUDE USING gist (project_id WITH =, daterange(start_date, due_date, '[]'::text) WITH &&) WHERE ((project_id IS NOT NULL));
+ALTER TABLE ONLY iterations_cadences
+ ADD CONSTRAINT iterations_cadences_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY jira_connect_installations
ADD CONSTRAINT jira_connect_installations_pkey PRIMARY KEY (id);
@@ -20290,14 +20853,17 @@ ALTER TABLE ONLY milestone_releases
ALTER TABLE ONLY milestones
ADD CONSTRAINT milestones_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY namespace_admin_notes
+ ADD CONSTRAINT namespace_admin_notes_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY namespace_aggregation_schedules
ADD CONSTRAINT namespace_aggregation_schedules_pkey PRIMARY KEY (namespace_id);
ALTER TABLE ONLY namespace_limits
ADD CONSTRAINT namespace_limits_pkey PRIMARY KEY (namespace_id);
-ALTER TABLE ONLY namespace_onboarding_actions
- ADD CONSTRAINT namespace_onboarding_actions_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY namespace_package_settings
+ ADD CONSTRAINT namespace_package_settings_pkey PRIMARY KEY (namespace_id);
ALTER TABLE ONLY namespace_root_storage_statistics
ADD CONSTRAINT namespace_root_storage_statistics_pkey PRIMARY KEY (namespace_id);
@@ -20332,6 +20898,9 @@ ALTER TABLE ONLY oauth_applications
ALTER TABLE ONLY oauth_openid_requests
ADD CONSTRAINT oauth_openid_requests_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY onboarding_progresses
+ ADD CONSTRAINT onboarding_progresses_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY open_project_tracker_data
ADD CONSTRAINT open_project_tracker_data_pkey PRIMARY KEY (id);
@@ -20362,6 +20931,9 @@ ALTER TABLE ONLY operations_user_lists
ALTER TABLE ONLY packages_build_infos
ADD CONSTRAINT packages_build_infos_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY packages_composer_cache_files
+ ADD CONSTRAINT packages_composer_cache_files_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY packages_composer_metadata
ADD CONSTRAINT packages_composer_metadata_pkey PRIMARY KEY (package_id);
@@ -20431,6 +21003,9 @@ ALTER TABLE ONLY packages_packages
ALTER TABLE ONLY packages_pypi_metadata
ADD CONSTRAINT packages_pypi_metadata_pkey PRIMARY KEY (package_id);
+ALTER TABLE ONLY packages_rubygems_metadata
+ ADD CONSTRAINT packages_rubygems_metadata_pkey PRIMARY KEY (package_id);
+
ALTER TABLE ONLY packages_tags
ADD CONSTRAINT packages_tags_pkey PRIMARY KEY (id);
@@ -20653,6 +21228,9 @@ ALTER TABLE ONLY scim_oauth_access_tokens
ALTER TABLE ONLY security_findings
ADD CONSTRAINT security_findings_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY security_orchestration_policy_configurations
+ ADD CONSTRAINT security_orchestration_policy_configurations_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY security_scans
ADD CONSTRAINT security_scans_pkey PRIMARY KEY (id);
@@ -21033,20 +21611,6 @@ CREATE UNIQUE INDEX any_approver_project_rule_type_unique_index ON approval_proj
CREATE INDEX approval_mr_rule_index_merge_request_id ON approval_merge_request_rules USING btree (merge_request_id);
-CREATE UNIQUE INDEX backup_labels_group_id_project_id_title_idx ON backup_labels USING btree (group_id, project_id, title);
-
-CREATE INDEX backup_labels_group_id_title_idx ON backup_labels USING btree (group_id, title) WHERE (project_id = NULL::integer);
-
-CREATE INDEX backup_labels_project_id_idx ON backup_labels USING btree (project_id);
-
-CREATE INDEX backup_labels_project_id_title_idx ON backup_labels USING btree (project_id, title) WHERE (group_id = NULL::integer);
-
-CREATE INDEX backup_labels_template_idx ON backup_labels USING btree (template) WHERE template;
-
-CREATE INDEX backup_labels_title_idx ON backup_labels USING btree (title);
-
-CREATE INDEX backup_labels_type_project_id_idx ON backup_labels USING btree (type, project_id);
-
CREATE UNIQUE INDEX bulk_import_trackers_uniq_relation_by_entity ON bulk_import_trackers USING btree (bulk_import_entity_id, relation);
CREATE INDEX ci_builds_gitlab_monitor_metrics ON ci_builds USING btree (status, created_at, project_id) WHERE ((type)::text = 'Ci::Build'::text);
@@ -21055,6 +21619,8 @@ CREATE INDEX code_owner_approval_required ON protected_branches USING btree (pro
CREATE INDEX commit_id_and_note_id_index ON commit_user_mentions USING btree (commit_id, note_id);
+CREATE INDEX composer_cache_files_index_on_deleted_at ON packages_composer_cache_files USING btree (delete_at, id);
+
CREATE UNIQUE INDEX design_management_designs_versions_uniqueness ON design_management_designs_versions USING btree (design_id, version_id);
CREATE INDEX design_user_mentions_on_design_id_and_note_id_index ON design_user_mentions USING btree (design_id, note_id);
@@ -21063,8 +21629,6 @@ CREATE UNIQUE INDEX epic_user_mentions_on_epic_id_and_note_id_index ON epic_user
CREATE UNIQUE INDEX epic_user_mentions_on_epic_id_index ON epic_user_mentions USING btree (epic_id) WHERE (note_id IS NULL);
-CREATE INDEX expired_artifacts_temp_index ON ci_job_artifacts USING btree (id, created_at) WHERE ((expire_at IS NULL) AND (created_at < '2020-06-22 02:00:00+02'::timestamp with time zone));
-
CREATE INDEX finding_links_on_vulnerability_occurrence_id ON vulnerability_finding_links USING btree (vulnerability_occurrence_id);
CREATE INDEX idx_audit_events_on_entity_id_desc_author_id_created_at ON audit_events_archived USING btree (entity_id, entity_type, id DESC, author_id, created_at);
@@ -21079,6 +21643,8 @@ CREATE INDEX idx_container_repositories_on_exp_cleanup_status_and_start_date ON
CREATE INDEX idx_deployment_clusters_on_cluster_id_and_kubernetes_namespace ON deployment_clusters USING btree (cluster_id, kubernetes_namespace);
+CREATE INDEX idx_eaprpb_external_approval_rule_id ON external_approval_rules_protected_branches USING btree (external_approval_rule_id);
+
CREATE UNIQUE INDEX idx_environment_merge_requests_unique_index ON deployment_merge_requests USING btree (environment_id, merge_request_id);
CREATE INDEX idx_geo_con_rep_updated_events_on_container_repository_id ON geo_container_repository_updated_events USING btree (container_repository_id);
@@ -21119,7 +21685,9 @@ CREATE INDEX idx_mr_cc_diff_files_on_mr_cc_id_and_sha ON merge_request_context_c
CREATE UNIQUE INDEX idx_on_compliance_management_frameworks_namespace_id_name ON compliance_management_frameworks USING btree (namespace_id, name);
-CREATE INDEX idx_on_issues_where_service_desk_reply_to_is_not_null ON issues USING btree (id) WHERE (service_desk_reply_to IS NOT NULL);
+CREATE UNIQUE INDEX idx_on_external_approval_rules_project_id_external_url ON external_approval_rules USING btree (project_id, external_url);
+
+CREATE UNIQUE INDEX idx_on_external_approval_rules_project_id_name ON external_approval_rules USING btree (project_id, name);
CREATE INDEX idx_packages_build_infos_on_package_id ON packages_build_infos USING btree (package_id);
@@ -21149,6 +21717,8 @@ CREATE INDEX idx_projects_id_created_at_disable_overriding_approvers_true ON pro
CREATE INDEX idx_projects_on_repository_storage_last_repository_updated_at ON projects USING btree (id, repository_storage, last_repository_updated_at);
+CREATE UNIQUE INDEX idx_protected_branch_id_external_approval_rule_id ON external_approval_rules_protected_branches USING btree (protected_branch_id, external_approval_rule_id);
+
CREATE INDEX idx_repository_states_on_last_repository_verification_ran_at ON project_repository_states USING btree (project_id, last_repository_verification_ran_at) WHERE ((repository_verification_checksum IS NOT NULL) AND (last_repository_verification_failure IS NULL));
CREATE INDEX idx_repository_states_on_last_wiki_verification_ran_at ON project_repository_states USING btree (project_id, last_wiki_verification_ran_at) WHERE ((wiki_verification_checksum IS NOT NULL) AND (last_wiki_verification_failure IS NULL));
@@ -21201,8 +21771,6 @@ CREATE UNIQUE INDEX index_alert_user_mentions_on_alert_id_and_note_id ON alert_m
CREATE UNIQUE INDEX index_alert_user_mentions_on_note_id ON alert_management_alert_user_mentions USING btree (note_id) WHERE (note_id IS NOT NULL);
-CREATE INDEX index_alerts_service_data_on_service_id ON alerts_service_data USING btree (service_id);
-
CREATE INDEX index_allowed_email_domains_on_group_id ON allowed_email_domains USING btree (group_id);
CREATE INDEX index_analytics_ca_group_stages_on_end_event_label_id ON analytics_cycle_analytics_group_stages USING btree (end_event_label_id);
@@ -21229,7 +21797,7 @@ CREATE INDEX index_analytics_ca_project_stages_on_start_event_label_id ON analyt
CREATE INDEX index_analytics_cycle_analytics_group_stages_custom_only ON analytics_cycle_analytics_group_stages USING btree (id) WHERE (custom = true);
-CREATE UNIQUE INDEX index_analytics_devops_adoption_segments_on_name ON analytics_devops_adoption_segments USING btree (name);
+CREATE UNIQUE INDEX index_analytics_devops_adoption_segments_on_namespace_id ON analytics_devops_adoption_segments USING btree (namespace_id);
CREATE INDEX index_application_settings_on_custom_project_templates_group_id ON application_settings USING btree (custom_project_templates_group_id);
@@ -21323,6 +21891,10 @@ CREATE INDEX index_badges_on_group_id ON badges USING btree (group_id);
CREATE INDEX index_badges_on_project_id ON badges USING btree (project_id);
+CREATE INDEX index_batched_jobs_by_batched_migration_id_and_id ON batched_background_migration_jobs USING btree (batched_background_migration_id, id);
+
+CREATE INDEX index_batched_migrations_on_job_table_and_column_name ON batched_background_migrations USING btree (job_class_name, table_name, column_name);
+
CREATE INDEX index_board_assignees_on_assignee_id ON board_assignees USING btree (assignee_id);
CREATE UNIQUE INDEX index_board_assignees_on_board_id_and_assignee_id ON board_assignees USING btree (board_id, assignee_id);
@@ -21361,8 +21933,18 @@ CREATE UNIQUE INDEX index_boards_epic_board_positions_on_epic_board_id_and_epic_
CREATE INDEX index_boards_epic_board_positions_on_epic_id ON boards_epic_board_positions USING btree (epic_id);
+CREATE INDEX index_boards_epic_board_positions_on_scoped_relative_position ON boards_epic_board_positions USING btree (epic_board_id, epic_id, relative_position);
+
CREATE INDEX index_boards_epic_boards_on_group_id ON boards_epic_boards USING btree (group_id);
+CREATE INDEX index_boards_epic_list_user_preferences_on_epic_list_id ON boards_epic_list_user_preferences USING btree (epic_list_id);
+
+CREATE INDEX index_boards_epic_lists_on_epic_board_id ON boards_epic_lists USING btree (epic_board_id);
+
+CREATE UNIQUE INDEX index_boards_epic_lists_on_epic_board_id_and_label_id ON boards_epic_lists USING btree (epic_board_id, label_id) WHERE (list_type = 1);
+
+CREATE INDEX index_boards_epic_lists_on_label_id ON boards_epic_lists USING btree (label_id);
+
CREATE INDEX index_boards_epic_user_preferences_on_board_id ON boards_epic_user_preferences USING btree (board_id);
CREATE UNIQUE INDEX index_boards_epic_user_preferences_on_board_user_epic_unique ON boards_epic_user_preferences USING btree (board_id, user_id, epic_id);
@@ -21421,12 +22003,10 @@ CREATE UNIQUE INDEX index_ci_builds_metadata_on_build_id ON ci_builds_metadata U
CREATE INDEX index_ci_builds_metadata_on_build_id_and_has_exposed_artifacts ON ci_builds_metadata USING btree (build_id) WHERE (has_exposed_artifacts IS TRUE);
-CREATE INDEX index_ci_builds_metadata_on_build_id_and_interruptible ON ci_builds_metadata USING btree (build_id) WHERE (interruptible = true);
+CREATE INDEX index_ci_builds_metadata_on_build_id_and_id_and_interruptible ON ci_builds_metadata USING btree (build_id) INCLUDE (id) WHERE (interruptible = true);
CREATE INDEX index_ci_builds_metadata_on_project_id ON ci_builds_metadata USING btree (project_id);
-CREATE INDEX index_ci_builds_on_artifacts_expire_at ON ci_builds USING btree (artifacts_expire_at) WHERE (artifacts_file <> ''::text);
-
CREATE INDEX index_ci_builds_on_auto_canceled_by_id ON ci_builds USING btree (auto_canceled_by_id);
CREATE INDEX index_ci_builds_on_commit_id_and_stage_idx_and_created_at ON ci_builds USING btree (commit_id, stage_idx, created_at);
@@ -21471,6 +22051,8 @@ CREATE INDEX index_ci_builds_project_id_and_status_for_live_jobs_partial2 ON ci_
CREATE UNIQUE INDEX index_ci_builds_runner_session_on_build_id ON ci_builds_runner_session USING btree (build_id);
+CREATE INDEX index_ci_daily_build_group_report_results_on_group_id ON ci_daily_build_group_report_results USING btree (group_id);
+
CREATE INDEX index_ci_daily_build_group_report_results_on_last_pipeline_id ON ci_daily_build_group_report_results USING btree (last_pipeline_id);
CREATE INDEX index_ci_daily_build_group_report_results_on_project_and_date ON ci_daily_build_group_report_results USING btree (project_id, date DESC) WHERE ((default_branch = true) AND ((data -> 'coverage'::text) IS NOT NULL));
@@ -21479,7 +22061,7 @@ CREATE INDEX index_ci_deleted_objects_on_pick_up_at ON ci_deleted_objects USING
CREATE INDEX index_ci_freeze_periods_on_project_id ON ci_freeze_periods USING btree (project_id);
-CREATE UNIQUE INDEX index_ci_group_variables_on_group_id_and_key ON ci_group_variables USING btree (group_id, key);
+CREATE UNIQUE INDEX index_ci_group_variables_on_group_id_and_key_and_environment ON ci_group_variables USING btree (group_id, key, environment_scope);
CREATE UNIQUE INDEX index_ci_instance_variables_on_key ON ci_instance_variables USING btree (key);
@@ -21501,6 +22083,8 @@ CREATE INDEX index_ci_job_variables_on_job_id ON ci_job_variables USING btree (j
CREATE UNIQUE INDEX index_ci_job_variables_on_key_and_job_id ON ci_job_variables USING btree (key, job_id);
+CREATE UNIQUE INDEX index_ci_namespace_monthly_usages_on_namespace_id_and_date ON ci_namespace_monthly_usages USING btree (namespace_id, date);
+
CREATE INDEX index_ci_pipeline_artifacts_on_expire_at ON ci_pipeline_artifacts USING btree (expire_at);
CREATE INDEX index_ci_pipeline_artifacts_on_pipeline_id ON ci_pipeline_artifacts USING btree (pipeline_id);
@@ -21537,7 +22121,7 @@ CREATE INDEX index_ci_pipelines_on_external_pull_request_id ON ci_pipelines USIN
CREATE INDEX index_ci_pipelines_on_merge_request_id ON ci_pipelines USING btree (merge_request_id) WHERE (merge_request_id IS NOT NULL);
-CREATE INDEX index_ci_pipelines_on_pipeline_schedule_id ON ci_pipelines USING btree (pipeline_schedule_id);
+CREATE INDEX index_ci_pipelines_on_pipeline_schedule_id_and_id ON ci_pipelines USING btree (pipeline_schedule_id, id);
CREATE INDEX index_ci_pipelines_on_project_id_and_id_desc ON ci_pipelines USING btree (project_id, id DESC);
@@ -21565,6 +22149,8 @@ CREATE INDEX index_ci_pipelines_on_user_id_and_created_at_and_config_source ON c
CREATE INDEX index_ci_pipelines_on_user_id_and_created_at_and_source ON ci_pipelines USING btree (user_id, created_at, source);
+CREATE UNIQUE INDEX index_ci_project_monthly_usages_on_project_id_and_date ON ci_project_monthly_usages USING btree (project_id, date);
+
CREATE UNIQUE INDEX index_ci_refs_on_project_id_and_ref_path ON ci_refs USING btree (project_id, ref_path);
CREATE UNIQUE INDEX index_ci_resource_groups_on_project_id_and_key ON ci_resource_groups USING btree (project_id, key);
@@ -21583,8 +22169,6 @@ CREATE INDEX index_ci_runner_projects_on_runner_id ON ci_runner_projects USING b
CREATE INDEX index_ci_runners_on_contacted_at ON ci_runners USING btree (contacted_at);
-CREATE INDEX index_ci_runners_on_is_shared ON ci_runners USING btree (is_shared);
-
CREATE INDEX index_ci_runners_on_locked ON ci_runners USING btree (locked);
CREATE INDEX index_ci_runners_on_runner_type ON ci_runners USING btree (runner_type);
@@ -21637,8 +22221,12 @@ CREATE UNIQUE INDEX index_ci_variables_on_project_id_and_key_and_environment_sco
CREATE INDEX index_cluster_agent_tokens_on_agent_id ON cluster_agent_tokens USING btree (agent_id);
+CREATE INDEX index_cluster_agent_tokens_on_created_by_user_id ON cluster_agent_tokens USING btree (created_by_user_id);
+
CREATE UNIQUE INDEX index_cluster_agent_tokens_on_token_encrypted ON cluster_agent_tokens USING btree (token_encrypted);
+CREATE INDEX index_cluster_agents_on_created_by_user_id ON cluster_agents USING btree (created_by_user_id);
+
CREATE UNIQUE INDEX index_cluster_agents_on_project_id_and_name ON cluster_agents USING btree (project_id, name);
CREATE UNIQUE INDEX index_cluster_groups_on_cluster_id_and_group_id ON cluster_groups USING btree (cluster_id, group_id);
@@ -21705,6 +22293,8 @@ CREATE INDEX index_clusters_on_user_id ON clusters USING btree (user_id);
CREATE UNIQUE INDEX index_commit_user_mentions_on_note_id ON commit_user_mentions USING btree (note_id);
+CREATE INDEX index_composer_cache_files_where_namespace_id_is_null ON packages_composer_cache_files USING btree (id) WHERE (namespace_id IS NULL);
+
CREATE INDEX index_container_expiration_policies_on_next_run_at_and_enabled ON container_expiration_policies USING btree (next_run_at, enabled);
CREATE INDEX index_container_repositories_on_project_id ON container_repositories USING btree (project_id);
@@ -21721,10 +22311,18 @@ CREATE INDEX index_csv_issue_imports_on_project_id ON csv_issue_imports USING bt
CREATE INDEX index_csv_issue_imports_on_user_id ON csv_issue_imports USING btree (user_id);
+CREATE INDEX index_custom_emoji_on_creator_id ON custom_emoji USING btree (creator_id);
+
CREATE UNIQUE INDEX index_custom_emoji_on_namespace_id_and_name ON custom_emoji USING btree (namespace_id, name);
CREATE UNIQUE INDEX index_daily_build_group_report_results_unique_columns ON ci_daily_build_group_report_results USING btree (project_id, ref_path, date, group_name);
+CREATE INDEX index_dast_profiles_on_dast_scanner_profile_id ON dast_profiles USING btree (dast_scanner_profile_id);
+
+CREATE INDEX index_dast_profiles_on_dast_site_profile_id ON dast_profiles USING btree (dast_site_profile_id);
+
+CREATE UNIQUE INDEX index_dast_profiles_on_project_id_and_name ON dast_profiles USING btree (project_id, name);
+
CREATE UNIQUE INDEX index_dast_scanner_profiles_on_project_id_and_name ON dast_scanner_profiles USING btree (project_id, name);
CREATE INDEX index_dast_site_profiles_on_dast_site_id ON dast_site_profiles USING btree (dast_site_id);
@@ -21827,12 +22425,16 @@ CREATE UNIQUE INDEX index_design_user_mentions_on_note_id ON design_user_mention
CREATE UNIQUE INDEX index_diff_note_positions_on_note_id_and_diff_type ON diff_note_positions USING btree (note_id, diff_type);
+CREATE UNIQUE INDEX index_dora_daily_metrics_on_environment_id_and_date ON dora_daily_metrics USING btree (environment_id, date);
+
CREATE INDEX index_draft_notes_on_author_id ON draft_notes USING btree (author_id);
CREATE INDEX index_draft_notes_on_discussion_id ON draft_notes USING btree (discussion_id);
CREATE INDEX index_draft_notes_on_merge_request_id ON draft_notes USING btree (merge_request_id);
+CREATE INDEX index_elastic_reindexing_subtasks_on_elastic_reindexing_task_id ON elastic_reindexing_subtasks USING btree (elastic_reindexing_task_id);
+
CREATE UNIQUE INDEX index_elastic_reindexing_tasks_on_in_progress ON elastic_reindexing_tasks USING btree (in_progress) WHERE in_progress;
CREATE INDEX index_elastic_reindexing_tasks_on_state ON elastic_reindexing_tasks USING btree (state);
@@ -21857,8 +22459,12 @@ CREATE INDEX index_environments_on_project_id_state_environment_type ON environm
CREATE INDEX index_environments_on_state_and_auto_stop_at ON environments USING btree (state, auto_stop_at) WHERE ((auto_stop_at IS NOT NULL) AND ((state)::text = 'available'::text));
+CREATE UNIQUE INDEX index_epic_board_list_preferences_on_user_and_list ON boards_epic_list_user_preferences USING btree (user_id, epic_list_id);
+
CREATE INDEX index_epic_issues_on_epic_id ON epic_issues USING btree (epic_id);
+CREATE INDEX index_epic_issues_on_epic_id_and_issue_id ON epic_issues USING btree (epic_id, issue_id);
+
CREATE UNIQUE INDEX index_epic_issues_on_issue_id ON epic_issues USING btree (issue_id);
CREATE INDEX index_epic_metrics ON epic_metrics USING btree (epic_id);
@@ -22091,6 +22697,8 @@ CREATE INDEX index_group_import_states_on_group_id ON group_import_states USING
CREATE INDEX index_group_import_states_on_user_id ON group_import_states USING btree (user_id) WHERE (user_id IS NOT NULL);
+CREATE INDEX index_group_repository_storage_moves_on_group_id ON group_repository_storage_moves USING btree (group_id);
+
CREATE UNIQUE INDEX index_group_stages_on_group_id_group_value_stream_id_and_name ON analytics_cycle_analytics_group_stages USING btree (group_id, group_value_stream_id, name);
CREATE UNIQUE INDEX index_group_wiki_repositories_on_disk_path ON group_wiki_repositories USING btree (disk_path);
@@ -22121,12 +22729,12 @@ CREATE INDEX index_import_failures_on_project_id_not_null ON import_failures USI
CREATE INDEX index_imported_projects_on_import_type_creator_id_created_at ON projects USING btree (import_type, creator_id, created_at) WHERE (import_type IS NOT NULL);
-CREATE INDEX index_inc_mgmnt_oncall_participants_on_oncall_rotation_id ON incident_management_oncall_participants USING btree (oncall_rotation_id);
-
CREATE INDEX index_inc_mgmnt_oncall_participants_on_oncall_user_id ON incident_management_oncall_participants USING btree (user_id);
CREATE UNIQUE INDEX index_inc_mgmnt_oncall_participants_on_user_id_and_rotation_id ON incident_management_oncall_participants USING btree (user_id, oncall_rotation_id);
+CREATE INDEX index_inc_mgmnt_oncall_pcpnt_on_oncall_rotation_id_is_removed ON incident_management_oncall_participants USING btree (oncall_rotation_id, is_removed);
+
CREATE UNIQUE INDEX index_inc_mgmnt_oncall_rotations_on_oncall_schedule_id_and_id ON incident_management_oncall_rotations USING btree (oncall_schedule_id, id);
CREATE UNIQUE INDEX index_inc_mgmnt_oncall_rotations_on_oncall_schedule_id_and_name ON incident_management_oncall_rotations USING btree (oncall_schedule_id, name);
@@ -22135,8 +22743,6 @@ CREATE INDEX index_incident_management_oncall_schedules_on_project_id ON inciden
CREATE INDEX index_incident_management_oncall_shifts_on_participant_id ON incident_management_oncall_shifts USING btree (participant_id);
-CREATE INDEX index_incident_management_oncall_shifts_on_rotation_id ON incident_management_oncall_shifts USING btree (rotation_id);
-
CREATE UNIQUE INDEX index_index_statuses_on_project_id ON index_statuses USING btree (project_id);
CREATE INDEX index_insights_on_namespace_id ON insights USING btree (namespace_id);
@@ -22169,8 +22775,6 @@ CREATE UNIQUE INDEX index_issue_links_on_source_id_and_target_id ON issue_links
CREATE INDEX index_issue_links_on_target_id ON issue_links USING btree (target_id);
-CREATE INDEX index_issue_metrics ON issue_metrics USING btree (issue_id);
-
CREATE INDEX index_issue_metrics_on_issue_id_and_timestamps ON issue_metrics USING btree (issue_id, first_mentioned_in_commit_at, first_associated_with_milestone_at, first_added_to_board_at);
CREATE INDEX index_issue_on_project_id_state_id_and_blocking_issues_count ON issues USING btree (project_id, state_id, blocking_issues_count);
@@ -22219,6 +22823,8 @@ CREATE INDEX index_issues_on_updated_at ON issues USING btree (updated_at);
CREATE INDEX index_issues_on_updated_by_id ON issues USING btree (updated_by_id) WHERE (updated_by_id IS NOT NULL);
+CREATE INDEX index_iterations_cadences_on_group_id ON iterations_cadences USING btree (group_id);
+
CREATE UNIQUE INDEX index_jira_connect_installations_on_client_key ON jira_connect_installations USING btree (client_key);
CREATE INDEX index_jira_connect_subscriptions_on_namespace_id ON jira_connect_subscriptions USING btree (namespace_id);
@@ -22257,8 +22863,6 @@ CREATE UNIQUE INDEX index_labels_on_group_id_and_project_id_and_title ON labels
CREATE UNIQUE INDEX index_labels_on_group_id_and_title_unique ON labels USING btree (group_id, title) WHERE (project_id IS NULL);
-CREATE INDEX index_labels_on_group_id_and_title_with_null_project_id ON labels USING btree (group_id, title) WHERE (project_id IS NULL);
-
CREATE INDEX index_labels_on_project_id ON labels USING btree (project_id);
CREATE UNIQUE INDEX index_labels_on_project_id_and_title_unique ON labels USING btree (project_id, title) WHERE (group_id IS NULL);
@@ -22337,6 +22941,8 @@ CREATE INDEX index_merge_request_diffs_on_external_diff_store ON merge_request_d
CREATE INDEX index_merge_request_diffs_on_merge_request_id_and_id ON merge_request_diffs USING btree (merge_request_id, id);
+CREATE UNIQUE INDEX index_merge_request_diffs_on_unique_merge_request_id ON merge_request_diffs USING btree (merge_request_id) WHERE (diff_type = 2);
+
CREATE INDEX index_merge_request_metrics_on_first_deployed_to_production_at ON merge_request_metrics USING btree (first_deployed_to_production_at);
CREATE INDEX index_merge_request_metrics_on_latest_closed_at ON merge_request_metrics USING btree (latest_closed_at) WHERE (latest_closed_at IS NOT NULL);
@@ -22397,6 +23003,8 @@ CREATE INDEX index_merge_requests_on_target_project_id_and_iid_and_state_id ON m
CREATE INDEX index_merge_requests_on_target_project_id_and_iid_jira_title ON merge_requests USING btree (target_project_id, iid) WHERE ((title)::text ~ '[A-Z][A-Z_0-9]+-\d+'::text);
+CREATE INDEX index_merge_requests_on_target_project_id_and_squash_commit_sha ON merge_requests USING btree (target_project_id, squash_commit_sha);
+
CREATE INDEX index_merge_requests_on_target_project_id_and_target_branch ON merge_requests USING btree (target_project_id, target_branch) WHERE ((state_id = 1) AND (merge_when_pipeline_succeeds = true));
CREATE INDEX index_merge_requests_on_target_project_id_iid_jira_description ON merge_requests USING btree (target_project_id, iid) WHERE (description ~ '[A-Z][A-Z_0-9]+-\d+'::text);
@@ -22449,9 +23057,9 @@ CREATE INDEX index_mr_metrics_on_target_project_id_merged_at_nulls_last ON merge
CREATE INDEX index_mr_metrics_on_target_project_id_merged_at_time_to_merge ON merge_request_metrics USING btree (target_project_id, merged_at, created_at) WHERE (merged_at > created_at);
-CREATE UNIQUE INDEX index_namespace_aggregation_schedules_on_namespace_id ON namespace_aggregation_schedules USING btree (namespace_id);
+CREATE INDEX index_namespace_admin_notes_on_namespace_id ON namespace_admin_notes USING btree (namespace_id);
-CREATE INDEX index_namespace_onboarding_actions_on_namespace_id ON namespace_onboarding_actions USING btree (namespace_id);
+CREATE UNIQUE INDEX index_namespace_aggregation_schedules_on_namespace_id ON namespace_aggregation_schedules USING btree (namespace_id);
CREATE UNIQUE INDEX index_namespace_root_storage_statistics_on_namespace_id ON namespace_root_storage_statistics USING btree (namespace_id);
@@ -22549,6 +23157,10 @@ CREATE UNIQUE INDEX index_on_instance_statistics_recorded_at_and_identifier ON a
CREATE INDEX index_on_label_links_all_columns ON label_links USING btree (target_id, label_id, target_type);
+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';
+
CREATE INDEX index_on_namespaces_lower_name ON namespaces USING btree (lower((name)::text));
CREATE INDEX index_on_namespaces_lower_path ON namespaces USING btree (lower((path)::text));
@@ -22563,6 +23175,8 @@ CREATE UNIQUE INDEX index_on_segment_selections_project_id_segment_id ON analyti
CREATE INDEX index_on_segment_selections_segment_id ON analytics_devops_adoption_segment_selections USING btree (segment_id);
+CREATE INDEX index_on_snapshots_segment_id_end_time ON analytics_devops_adoption_snapshots USING btree (segment_id, end_time);
+
CREATE INDEX index_on_snapshots_segment_id_recorded_at ON analytics_devops_adoption_snapshots USING btree (segment_id, recorded_at);
CREATE INDEX index_on_users_lower_email ON users USING btree (lower((email)::text));
@@ -22571,6 +23185,18 @@ CREATE INDEX index_on_users_lower_username ON users USING btree (lower((username
CREATE INDEX index_on_users_name_lower ON users USING btree (lower((name)::text));
+CREATE INDEX index_onboarding_progresses_for_create_track ON onboarding_progresses USING btree (created_at) WHERE (git_write_at IS NULL);
+
+CREATE INDEX index_onboarding_progresses_for_team_track ON onboarding_progresses USING btree (GREATEST(git_write_at, pipeline_created_at, trial_started_at)) WHERE ((git_write_at IS NOT NULL) AND (pipeline_created_at IS NOT NULL) AND (trial_started_at IS NOT NULL) AND (user_added_at IS NULL));
+
+CREATE INDEX index_onboarding_progresses_for_trial_track ON onboarding_progresses USING btree (GREATEST(git_write_at, pipeline_created_at)) WHERE ((git_write_at IS NOT NULL) AND (pipeline_created_at IS NOT NULL) AND (trial_started_at IS NULL));
+
+CREATE INDEX index_onboarding_progresses_for_verify_track ON onboarding_progresses USING btree (git_write_at) WHERE ((git_write_at IS NOT NULL) AND (pipeline_created_at IS NULL));
+
+CREATE UNIQUE INDEX index_onboarding_progresses_on_namespace_id ON onboarding_progresses USING btree (namespace_id);
+
+CREATE INDEX index_oncall_shifts_on_rotation_id_and_starts_at_and_ends_at ON incident_management_oncall_shifts USING btree (rotation_id, starts_at, ends_at);
+
CREATE INDEX index_open_project_tracker_data_on_service_id ON open_project_tracker_data USING btree (service_id);
CREATE INDEX index_operations_feature_flags_issues_on_issue_id ON operations_feature_flags_issues USING btree (issue_id);
@@ -22595,6 +23221,8 @@ CREATE UNIQUE INDEX index_ops_strategies_user_lists_on_strategy_id_and_user_list
CREATE INDEX index_packages_build_infos_on_pipeline_id ON packages_build_infos USING btree (pipeline_id);
+CREATE UNIQUE INDEX index_packages_composer_cache_namespace_and_sha ON packages_composer_cache_files USING btree (namespace_id, file_sha256);
+
CREATE UNIQUE INDEX index_packages_composer_metadata_on_package_id_and_target_sha ON packages_composer_metadata USING btree (package_id, target_sha);
CREATE UNIQUE INDEX index_packages_conan_file_metadata_on_package_file_id ON packages_conan_file_metadata USING btree (package_file_id);
@@ -22629,6 +23257,8 @@ CREATE INDEX index_packages_nuget_dl_metadata_on_dependency_link_id ON packages_
CREATE UNIQUE INDEX index_packages_on_project_id_name_version_unique_when_generic ON packages_packages USING btree (project_id, name, version) WHERE (package_type = 7);
+CREATE UNIQUE INDEX index_packages_on_project_id_name_version_unique_when_golang ON packages_packages USING btree (project_id, name, version) WHERE (package_type = 8);
+
CREATE INDEX index_packages_package_file_build_infos_on_package_file_id ON packages_package_file_build_infos USING btree (package_file_id);
CREATE INDEX index_packages_package_file_build_infos_on_pipeline_id ON packages_package_file_build_infos USING btree (pipeline_id);
@@ -22649,6 +23279,8 @@ CREATE INDEX index_packages_packages_on_project_id_and_created_at ON packages_pa
CREATE INDEX index_packages_packages_on_project_id_and_package_type ON packages_packages USING btree (project_id, package_type);
+CREATE INDEX index_packages_packages_on_project_id_and_status ON packages_packages USING btree (project_id, status);
+
CREATE INDEX index_packages_packages_on_project_id_and_version ON packages_packages USING btree (project_id, version);
CREATE INDEX index_packages_project_id_name_partial_for_nuget ON packages_packages USING btree (project_id, name) WHERE (((name)::text <> 'NuGet.Temporary.Package'::text) AND (version IS NOT NULL) AND (package_type = 4));
@@ -23101,7 +23733,7 @@ CREATE INDEX index_security_findings_on_scanner_id ON security_findings USING bt
CREATE INDEX index_security_findings_on_severity ON security_findings USING btree (severity);
-CREATE UNIQUE INDEX index_security_findings_on_uuid ON security_findings USING btree (uuid);
+CREATE UNIQUE INDEX index_security_findings_on_uuid_and_scan_id ON security_findings USING btree (uuid, scan_id);
CREATE INDEX index_security_scans_on_date_created_at_and_id ON security_scans USING btree (date(timezone('UTC'::text, created_at)), id);
@@ -23123,7 +23755,7 @@ CREATE INDEX index_service_desk_enabled_projects_on_id_creator_id_created_at ON
CREATE INDEX index_services_on_inherit_from_id ON services USING btree (inherit_from_id);
-CREATE INDEX index_services_on_project_id_and_type ON services USING btree (project_id, type);
+CREATE UNIQUE INDEX index_services_on_project_id_and_type_unique ON services USING btree (project_id, type);
CREATE INDEX index_services_on_template ON services USING btree (template);
@@ -23187,6 +23819,12 @@ 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 UNIQUE INDEX index_sop_configs_on_security_policy_management_project_id ON security_orchestration_policy_configurations USING btree (security_policy_management_project_id);
+
+CREATE INDEX index_sprints_iterations_cadence_id ON sprints USING btree (iterations_cadence_id);
+
CREATE INDEX index_sprints_on_description_trigram ON sprints USING gin (description gin_trgm_ops);
CREATE INDEX index_sprints_on_due_date ON sprints USING btree (due_date);
@@ -23291,6 +23929,8 @@ CREATE INDEX index_u2f_registrations_on_key_handle ON u2f_registrations USING bt
CREATE INDEX index_u2f_registrations_on_user_id ON u2f_registrations USING btree (user_id);
+CREATE UNIQUE INDEX index_unique_issue_metrics_issue_id ON issue_metrics USING btree (issue_id);
+
CREATE INDEX index_uploads_on_checksum ON uploads USING btree (checksum);
CREATE INDEX index_uploads_on_model_id_and_model_type ON uploads USING btree (model_id, model_type);
@@ -23329,6 +23969,8 @@ CREATE INDEX index_user_preferences_on_gitpod_enabled ON user_preferences USING
CREATE UNIQUE INDEX index_user_preferences_on_user_id ON user_preferences USING btree (user_id);
+CREATE INDEX index_user_statuses_on_clear_status_at_not_null ON user_statuses USING btree (clear_status_at) WHERE (clear_status_at IS NOT NULL);
+
CREATE INDEX index_user_statuses_on_user_id ON user_statuses USING btree (user_id);
CREATE UNIQUE INDEX index_user_synced_attributes_metadata_on_user_id ON user_synced_attributes_metadata USING btree (user_id);
@@ -23577,17 +24219,17 @@ CREATE INDEX temporary_index_vulnerabilities_on_id ON vulnerabilities USING btre
CREATE UNIQUE INDEX term_agreements_unique_index ON term_agreements USING btree (user_id, term_id);
-CREATE INDEX tmp_build_stage_position_index ON ci_builds USING btree (stage_id, stage_idx) WHERE (stage_idx IS NOT NULL);
-
CREATE INDEX tmp_idx_deduplicate_vulnerability_occurrences ON vulnerability_occurrences USING btree (project_id, report_type, location_fingerprint, primary_identifier_id, id);
+CREATE INDEX tmp_idx_on_namespaces_delayed_project_removal ON namespaces USING btree (id) WHERE (delayed_project_removal = true);
+
CREATE INDEX tmp_index_ci_builds_lock_version ON ci_builds USING btree (id) WHERE (lock_version IS NULL);
CREATE INDEX tmp_index_ci_pipelines_lock_version ON ci_pipelines USING btree (id) WHERE (lock_version IS NULL);
CREATE INDEX tmp_index_ci_stages_lock_version ON ci_stages USING btree (id) WHERE (lock_version IS NULL);
-CREATE INDEX tmp_index_for_email_unconfirmation_migration ON emails USING btree (id) WHERE (confirmed_at IS NOT NULL);
+CREATE INDEX tmp_index_on_security_findings_scan_id ON security_findings USING btree (scan_id) WHERE (uuid IS NULL);
CREATE INDEX tmp_index_on_vulnerabilities_non_dismissed ON vulnerabilities USING btree (id) WHERE (state <> 2);
@@ -23873,6 +24515,18 @@ ALTER INDEX product_analytics_events_experimental_pkey ATTACH PARTITION gitlab_p
CREATE TRIGGER table_sync_trigger_ee39a25f9d AFTER INSERT OR DELETE OR UPDATE ON audit_events FOR EACH ROW EXECUTE FUNCTION table_sync_function_2be879775d();
+CREATE TRIGGER trigger_has_external_issue_tracker_on_delete AFTER DELETE ON services FOR EACH ROW WHEN ((((old.category)::text = 'issue_tracker'::text) AND (old.active = true) AND (old.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_issue_tracker();
+
+CREATE TRIGGER trigger_has_external_issue_tracker_on_insert AFTER INSERT ON services FOR EACH ROW WHEN ((((new.category)::text = 'issue_tracker'::text) AND (new.active = true) AND (new.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_issue_tracker();
+
+CREATE TRIGGER trigger_has_external_issue_tracker_on_update AFTER UPDATE ON services FOR EACH ROW WHEN ((((new.category)::text = 'issue_tracker'::text) AND (old.active <> new.active) AND (new.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_issue_tracker();
+
+CREATE TRIGGER trigger_has_external_wiki_on_delete AFTER DELETE ON services FOR EACH ROW WHEN ((((old.type)::text = 'ExternalWikiService'::text) AND (old.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_wiki();
+
+CREATE TRIGGER trigger_has_external_wiki_on_insert AFTER INSERT ON services FOR EACH ROW WHEN (((new.active = true) AND ((new.type)::text = 'ExternalWikiService'::text) AND (new.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_wiki();
+
+CREATE TRIGGER trigger_has_external_wiki_on_update AFTER UPDATE ON services FOR EACH ROW WHEN ((((new.type)::text = 'ExternalWikiService'::text) AND (old.active <> new.active) AND (new.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_wiki();
+
ALTER TABLE ONLY chat_names
ADD CONSTRAINT fk_00797a2bf9 FOREIGN KEY (service_id) REFERENCES services(id) ON DELETE CASCADE;
@@ -24014,6 +24668,9 @@ ALTER TABLE ONLY namespaces
ALTER TABLE ONLY epics
ADD CONSTRAINT fk_3654b61b03 FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE CASCADE;
+ALTER TABLE ONLY sprints
+ ADD CONSTRAINT fk_365d1db505 FOREIGN KEY (iterations_cadence_id) REFERENCES iterations_cadences(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY push_event_payloads
ADD CONSTRAINT fk_36c74129da FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE;
@@ -24119,6 +24776,9 @@ ALTER TABLE ONLY vulnerabilities
ALTER TABLE ONLY index_statuses
ADD CONSTRAINT fk_74b2492545 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY cluster_agent_tokens
+ ADD CONSTRAINT fk_75008f3553 FOREIGN KEY (created_by_user_id) REFERENCES users(id) ON DELETE SET NULL;
+
ALTER TABLE ONLY vulnerabilities
ADD CONSTRAINT fk_76bc5f5455 FOREIGN KEY (resolved_by_id) REFERENCES users(id) ON DELETE SET NULL;
@@ -24149,9 +24809,6 @@ ALTER TABLE ONLY vulnerabilities
ALTER TABLE ONLY labels
ADD CONSTRAINT fk_7de4989a69 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-ALTER TABLE ONLY backup_labels
- ADD CONSTRAINT fk_7de4989a69 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY merge_requests
ADD CONSTRAINT fk_7e85395a64 FOREIGN KEY (sprint_id) REFERENCES sprints(id) ON DELETE CASCADE;
@@ -24224,6 +24881,9 @@ ALTER TABLE ONLY milestones
ALTER TABLE ONLY vulnerabilities
ADD CONSTRAINT fk_959d40ad0a FOREIGN KEY (confirmed_by_id) REFERENCES users(id) ON DELETE SET NULL;
+ALTER TABLE ONLY boards_epic_list_user_preferences
+ ADD CONSTRAINT fk_95eac55851 FOREIGN KEY (epic_list_id) REFERENCES boards_epic_lists(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY application_settings
ADD CONSTRAINT fk_964370041d FOREIGN KEY (usage_stats_set_by_user_id) REFERENCES users(id) ON DELETE SET NULL;
@@ -24290,6 +24950,9 @@ ALTER TABLE ONLY merge_requests
ALTER TABLE ONLY epics
ADD CONSTRAINT fk_aa5798e761 FOREIGN KEY (closed_by_id) REFERENCES users(id) ON DELETE SET NULL;
+ALTER TABLE ONLY dast_profiles
+ ADD CONSTRAINT fk_aa76ef30e9 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY alert_management_alerts
ADD CONSTRAINT fk_aad61aedca FOREIGN KEY (environment_id) REFERENCES environments(id) ON DELETE SET NULL;
@@ -24380,6 +25043,12 @@ ALTER TABLE ONLY issues
ALTER TABLE ONLY issue_links
ADD CONSTRAINT fk_c900194ff2 FOREIGN KEY (source_id) REFERENCES issues(id) ON DELETE CASCADE;
+ALTER TABLE ONLY external_approval_rules_protected_branches
+ ADD CONSTRAINT fk_c9a037a926 FOREIGN KEY (external_approval_rule_id) REFERENCES external_approval_rules(id) ON DELETE CASCADE;
+
+ALTER TABLE ONLY external_approval_rules_protected_branches
+ ADD CONSTRAINT fk_ca2ffb55e6 FOREIGN KEY (protected_branch_id) REFERENCES protected_branches(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY experiment_subjects
ADD CONSTRAINT fk_ccc28f8ceb FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -24389,6 +25058,9 @@ ALTER TABLE ONLY todos
ALTER TABLE ONLY geo_event_log
ADD CONSTRAINT fk_cff7185ad2 FOREIGN KEY (reset_checksum_event_id) REFERENCES geo_reset_checksum_events(id) ON DELETE CASCADE;
+ALTER TABLE ONLY custom_emoji
+ ADD CONSTRAINT fk_custom_emoji_creator_id FOREIGN KEY (creator_id) REFERENCES users(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY bulk_import_entities
ADD CONSTRAINT fk_d06d023c30 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -24521,6 +25193,15 @@ ALTER TABLE ONLY ci_pipeline_variables
ALTER TABLE ONLY design_management_designs_versions
ADD CONSTRAINT fk_f4d25ba00c FOREIGN KEY (version_id) REFERENCES design_management_versions(id) ON DELETE CASCADE;
+ALTER TABLE ONLY analytics_devops_adoption_segments
+ ADD CONSTRAINT fk_f5aa768998 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
+ALTER TABLE ONLY boards_epic_list_user_preferences
+ ADD CONSTRAINT fk_f5f2fe5c1f FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
+
+ALTER TABLE ONLY cluster_agents
+ ADD CONSTRAINT fk_f7d43dee13 FOREIGN KEY (created_by_user_id) REFERENCES users(id) ON DELETE SET NULL;
+
ALTER TABLE ONLY protected_tag_create_access_levels
ADD CONSTRAINT fk_f7dfda8c51 FOREIGN KEY (protected_tag_id) REFERENCES protected_tags(id) ON DELETE CASCADE;
@@ -24533,6 +25214,9 @@ ALTER TABLE ONLY system_note_metadata
ALTER TABLE ONLY vulnerability_remediations
ADD CONSTRAINT fk_fc61a535a0 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY ci_daily_build_group_report_results
+ ADD CONSTRAINT fk_fd1858fefd FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY merge_requests
ADD CONSTRAINT fk_fd82eae0b9 FOREIGN KEY (head_pipeline_id) REFERENCES ci_pipelines(id) ON DELETE SET NULL;
@@ -24605,6 +25289,9 @@ ALTER TABLE ONLY user_interacted_projects
ALTER TABLE ONLY trending_projects
ADD CONSTRAINT fk_rails_09feecd872 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY security_orchestration_policy_configurations
+ ADD CONSTRAINT fk_rails_0a22dcd52d FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY project_deploy_tokens
ADD CONSTRAINT fk_rails_0aca134388 FOREIGN KEY (deploy_token_id) REFERENCES deploy_tokens(id) ON DELETE CASCADE;
@@ -24632,6 +25319,9 @@ ALTER TABLE ONLY user_synced_attributes_metadata
ALTER TABLE ONLY project_authorizations
ADD CONSTRAINT fk_rails_0f84bb11f3 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY boards_epic_lists
+ ADD CONSTRAINT fk_rails_0f9c7f646f FOREIGN KEY (epic_board_id) REFERENCES boards_epic_boards(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY issue_email_participants
ADD CONSTRAINT fk_rails_0fdfd8b811 FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE;
@@ -24740,6 +25430,12 @@ ALTER TABLE ONLY boards_epic_board_positions
ALTER TABLE ONLY geo_repository_created_events
ADD CONSTRAINT fk_rails_1f49e46a61 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY dora_daily_metrics
+ ADD CONSTRAINT fk_rails_1fd07aff6f FOREIGN KEY (environment_id) REFERENCES environments(id) ON DELETE CASCADE;
+
+ALTER TABLE ONLY boards_epic_lists
+ ADD CONSTRAINT fk_rails_1fe6b54909 FOREIGN KEY (label_id) REFERENCES labels(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY approval_merge_request_rules_groups
ADD CONSTRAINT fk_rails_2020a7124a FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
@@ -24761,6 +25457,9 @@ ALTER TABLE ONLY service_desk_settings
ALTER TABLE ONLY saml_group_links
ADD CONSTRAINT fk_rails_22e312c530 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+ALTER TABLE ONLY dast_profiles
+ ADD CONSTRAINT fk_rails_23cae5abe1 FOREIGN KEY (dast_scanner_profile_id) REFERENCES dast_scanner_profiles(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY group_custom_attributes
ADD CONSTRAINT fk_rails_246e0db83a FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
@@ -24815,6 +25514,9 @@ ALTER TABLE ONLY packages_debian_group_component_files
ALTER TABLE ONLY boards_epic_board_labels
ADD CONSTRAINT fk_rails_2bedeb8799 FOREIGN KEY (label_id) REFERENCES labels(id) ON DELETE CASCADE;
+ALTER TABLE ONLY onboarding_progresses
+ ADD CONSTRAINT fk_rails_2ccfd420cc FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY protected_branch_unprotect_access_levels
ADD CONSTRAINT fk_rails_2d2aba21ef FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
@@ -24869,6 +25571,9 @@ ALTER TABLE ONLY merge_request_blocks
ALTER TABLE ONLY merge_request_reviewers
ADD CONSTRAINT fk_rails_3704a66140 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
+ALTER TABLE ONLY group_merge_request_approval_settings
+ ADD CONSTRAINT fk_rails_37b6b4cdba FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY analytics_cycle_analytics_project_stages
ADD CONSTRAINT fk_rails_3829e49b66 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -24932,12 +25637,18 @@ ALTER TABLE ONLY epic_issues
ALTER TABLE ONLY ci_refs
ADD CONSTRAINT fk_rails_4249db8cc3 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY security_orchestration_policy_configurations
+ ADD CONSTRAINT fk_rails_42ed6c25ec FOREIGN KEY (security_policy_management_project_id) REFERENCES projects(id) ON DELETE RESTRICT;
+
ALTER TABLE ONLY ci_resources
ADD CONSTRAINT fk_rails_430336af2d FOREIGN KEY (resource_group_id) REFERENCES ci_resource_groups(id) ON DELETE CASCADE;
ALTER TABLE ONLY clusters_applications_fluentd
ADD CONSTRAINT fk_rails_4319b1dcd2 FOREIGN KEY (cluster_id) REFERENCES clusters(id) ON DELETE CASCADE;
+ALTER TABLE ONLY batched_background_migration_jobs
+ ADD CONSTRAINT fk_rails_432153b86d FOREIGN KEY (batched_background_migration_id) REFERENCES batched_background_migrations(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY operations_strategies_user_lists
ADD CONSTRAINT fk_rails_43241e8d29 FOREIGN KEY (strategy_id) REFERENCES operations_strategies(id) ON DELETE CASCADE;
@@ -24953,9 +25664,6 @@ ALTER TABLE ONLY merge_request_assignees
ALTER TABLE ONLY packages_dependency_links
ADD CONSTRAINT fk_rails_4437bf4070 FOREIGN KEY (dependency_id) REFERENCES packages_dependencies(id) ON DELETE CASCADE;
-ALTER TABLE ONLY namespace_onboarding_actions
- ADD CONSTRAINT fk_rails_4504f6875a FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY project_auto_devops
ADD CONSTRAINT fk_rails_45436b12b2 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -25028,6 +25736,9 @@ ALTER TABLE ONLY resource_iteration_events
ALTER TABLE ONLY status_page_settings
ADD CONSTRAINT fk_rails_506e5ba391 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY ci_project_monthly_usages
+ ADD CONSTRAINT fk_rails_508bcd4aa6 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY project_repository_storage_moves
ADD CONSTRAINT fk_rails_5106dbd44a FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -25172,6 +25883,9 @@ ALTER TABLE ONLY approval_merge_request_rules_approved_approvers
ALTER TABLE ONLY operations_feature_flags_clients
ADD CONSTRAINT fk_rails_6650ed902c FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY namespace_admin_notes
+ ADD CONSTRAINT fk_rails_666166ea7b FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY web_hook_logs
ADD CONSTRAINT fk_rails_666826e111 FOREIGN KEY (web_hook_id) REFERENCES web_hooks(id) ON DELETE CASCADE;
@@ -25412,12 +26126,18 @@ ALTER TABLE ONLY scim_identities
ALTER TABLE ONLY packages_debian_project_distributions
ADD CONSTRAINT fk_rails_94b95e1f84 FOREIGN KEY (creator_id) REFERENCES users(id) ON DELETE SET NULL;
+ALTER TABLE ONLY packages_rubygems_metadata
+ ADD CONSTRAINT fk_rails_95a3f5ce78 FOREIGN KEY (package_id) REFERENCES packages_packages(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY packages_pypi_metadata
ADD CONSTRAINT fk_rails_9698717cdd FOREIGN KEY (package_id) REFERENCES packages_packages(id) ON DELETE CASCADE;
ALTER TABLE ONLY packages_dependency_links
ADD CONSTRAINT fk_rails_96ef1c00d3 FOREIGN KEY (package_id) REFERENCES packages_packages(id) ON DELETE CASCADE;
+ALTER TABLE ONLY group_repository_storage_moves
+ ADD CONSTRAINT fk_rails_982bb5daf1 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY resource_label_events
ADD CONSTRAINT fk_rails_9851a00031 FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
@@ -25583,8 +26303,8 @@ ALTER TABLE ONLY namespace_aggregation_schedules
ALTER TABLE ONLY approval_project_rules_protected_branches
ADD CONSTRAINT fk_rails_b7567b031b FOREIGN KEY (protected_branch_id) REFERENCES protected_branches(id) ON DELETE CASCADE;
-ALTER TABLE ONLY alerts_service_data
- ADD CONSTRAINT fk_rails_b93215a42c FOREIGN KEY (service_id) REFERENCES services(id) ON DELETE CASCADE;
+ALTER TABLE ONLY packages_composer_cache_files
+ ADD CONSTRAINT fk_rails_b82cea43a0 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE SET NULL;
ALTER TABLE ONLY merge_trains
ADD CONSTRAINT fk_rails_b9d67af01d FOREIGN KEY (target_project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -25637,9 +26357,6 @@ ALTER TABLE ONLY serverless_domain_cluster
ALTER TABLE ONLY labels
ADD CONSTRAINT fk_rails_c1ac5161d8 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
-ALTER TABLE ONLY backup_labels
- ADD CONSTRAINT fk_rails_c1ac5161d8 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY project_feature_usages
ADD CONSTRAINT fk_rails_c22a50024b FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -25823,6 +26540,9 @@ ALTER TABLE ONLY merge_request_metrics
ALTER TABLE ONLY draft_notes
ADD CONSTRAINT fk_rails_e753681674 FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
+ALTER TABLE ONLY namespace_package_settings
+ ADD CONSTRAINT fk_rails_e773444769 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY dast_site_tokens
ADD CONSTRAINT fk_rails_e84f721a8e FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -25850,6 +26570,12 @@ ALTER TABLE ONLY alert_management_alert_user_mentions
ALTER TABLE ONLY snippet_statistics
ADD CONSTRAINT fk_rails_ebc283ccf1 FOREIGN KEY (snippet_id) REFERENCES snippets(id) ON DELETE CASCADE;
+ALTER TABLE ONLY iterations_cadences
+ ADD CONSTRAINT fk_rails_ece400c55a FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
+ALTER TABLE ONLY dast_profiles
+ ADD CONSTRAINT fk_rails_ed1e66fbbf FOREIGN KEY (dast_site_profile_id) REFERENCES dast_site_profiles(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY project_security_settings
ADD CONSTRAINT fk_rails_ed4abe1338 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -25883,6 +26609,9 @@ ALTER TABLE ONLY requirements
ALTER TABLE ONLY snippet_repositories
ADD CONSTRAINT fk_rails_f21f899728 FOREIGN KEY (shard_id) REFERENCES shards(id) ON DELETE RESTRICT;
+ALTER TABLE ONLY elastic_reindexing_subtasks
+ ADD CONSTRAINT fk_rails_f2cc190164 FOREIGN KEY (elastic_reindexing_task_id) REFERENCES elastic_reindexing_tasks(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY ci_pipeline_chat_data
ADD CONSTRAINT fk_rails_f300456b63 FOREIGN KEY (chat_name_id) REFERENCES chat_names(id) ON DELETE CASCADE;
@@ -25946,6 +26675,9 @@ ALTER TABLE ONLY ci_job_variables
ALTER TABLE ONLY packages_nuget_metadata
ADD CONSTRAINT fk_rails_fc0c19f5b4 FOREIGN KEY (package_id) REFERENCES packages_packages(id) ON DELETE CASCADE;
+ALTER TABLE ONLY external_approval_rules
+ ADD CONSTRAINT fk_rails_fd4f9ac573 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY experiment_users
ADD CONSTRAINT fk_rails_fd805f771a FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
diff --git a/db/migrate/20201211145950_add_bloat_estimate_to_reindex_action.rb b/db/migrate/20201211145950_add_bloat_estimate_to_reindex_action.rb
deleted file mode 100644
index 894cee92284..00000000000
--- a/db/migrate/20201211145950_add_bloat_estimate_to_reindex_action.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddBloatEstimateToReindexAction < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :postgres_reindex_actions, :bloat_estimate_bytes_start, :bigint
- end
-end
diff --git a/db/migrate/20201214000000_change_mr_allow_maintainer_to_push_default.rb b/db/migrate/20201214000000_change_mr_allow_maintainer_to_push_default.rb
deleted file mode 100644
index 47eec16807b..00000000000
--- a/db/migrate/20201214000000_change_mr_allow_maintainer_to_push_default.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class ChangeMrAllowMaintainerToPushDefault < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- change_column_default :merge_requests, :allow_maintainer_to_push, from: nil, to: true
- end
- end
-
- def down
- with_lock_retries do
- change_column_default :merge_requests, :allow_maintainer_to_push, from: true, to: nil
- end
- end
-end
diff --git a/db/migrate/20201214032220_add_has_external_wiki_trigger.rb b/db/migrate/20201214032220_add_has_external_wiki_trigger.rb
deleted file mode 100644
index c77b887d509..00000000000
--- a/db/migrate/20201214032220_add_has_external_wiki_trigger.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-# frozen_string_literal: true
-
-class AddHasExternalWikiTrigger < ActiveRecord::Migration[6.0]
- include Gitlab::Database::SchemaHelpers
-
- DOWNTIME = false
- FUNCTION_NAME = 'set_has_external_wiki'
- TRIGGER_ON_INSERT_NAME = 'trigger_has_external_wiki_on_insert'
- TRIGGER_ON_UPDATE_NAME = 'trigger_has_external_wiki_on_update'
- TRIGGER_ON_DELETE_NAME = 'trigger_has_external_wiki_on_delete'
-
- def up
- create_trigger_function(FUNCTION_NAME, replace: true) do
- <<~SQL
- UPDATE projects SET has_external_wiki = COALESCE(NEW.active, FALSE)
- WHERE projects.id = COALESCE(NEW.project_id, OLD.project_id);
- RETURN NULL;
- SQL
- end
-
- execute(<<~SQL)
- CREATE TRIGGER #{TRIGGER_ON_INSERT_NAME}
- AFTER INSERT ON services
- FOR EACH ROW
- WHEN (NEW.active = TRUE AND NEW.type = 'ExternalWikiService' AND NEW.project_id IS NOT NULL)
- EXECUTE FUNCTION #{FUNCTION_NAME}();
- SQL
-
- execute(<<~SQL)
- CREATE TRIGGER #{TRIGGER_ON_UPDATE_NAME}
- AFTER UPDATE ON services
- FOR EACH ROW
- WHEN (NEW.type = 'ExternalWikiService' AND OLD.active != NEW.active AND NEW.project_id IS NOT NULL)
- EXECUTE FUNCTION #{FUNCTION_NAME}();
- SQL
-
- execute(<<~SQL)
- CREATE TRIGGER #{TRIGGER_ON_DELETE_NAME}
- AFTER DELETE ON services
- FOR EACH ROW
- WHEN (OLD.type = 'ExternalWikiService' AND OLD.project_id IS NOT NULL)
- EXECUTE FUNCTION #{FUNCTION_NAME}();
- SQL
- end
-
- def down
- drop_trigger(:services, TRIGGER_ON_INSERT_NAME)
- drop_trigger(:services, TRIGGER_ON_UPDATE_NAME)
- drop_trigger(:services, TRIGGER_ON_DELETE_NAME)
- drop_function(FUNCTION_NAME)
- end
-end
diff --git a/db/migrate/20201214084105_add_expiration_policy_completed_at_to_container_repositories.rb b/db/migrate/20201214084105_add_expiration_policy_completed_at_to_container_repositories.rb
deleted file mode 100644
index 9e1f21068c2..00000000000
--- a/db/migrate/20201214084105_add_expiration_policy_completed_at_to_container_repositories.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-class AddExpirationPolicyCompletedAtToContainerRepositories < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def up
- add_column(:container_repositories, :expiration_policy_completed_at, :datetime_with_timezone)
- end
-
- def down
- remove_column(:container_repositories, :expiration_policy_completed_at)
- end
-end
diff --git a/db/migrate/20201214111858_add_container_registry_cleanup_tags_service_max_list_size_to_application_settings.rb b/db/migrate/20201214111858_add_container_registry_cleanup_tags_service_max_list_size_to_application_settings.rb
deleted file mode 100644
index 312220914c1..00000000000
--- a/db/migrate/20201214111858_add_container_registry_cleanup_tags_service_max_list_size_to_application_settings.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-class AddContainerRegistryCleanupTagsServiceMaxListSizeToApplicationSettings < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- add_column(:application_settings, :container_registry_cleanup_tags_service_max_list_size, :integer, default: 200, null: false)
- end
-end
diff --git a/db/migrate/20201214112752_add_app_settings_container_reg_cleanup_tags_service_max_list_size_constraint.rb b/db/migrate/20201214112752_add_app_settings_container_reg_cleanup_tags_service_max_list_size_constraint.rb
deleted file mode 100644
index 935dd641b4c..00000000000
--- a/db/migrate/20201214112752_add_app_settings_container_reg_cleanup_tags_service_max_list_size_constraint.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddAppSettingsContainerRegCleanupTagsServiceMaxListSizeConstraint < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- CONSTRAINT_NAME = 'app_settings_container_reg_cleanup_tags_max_list_size_positive'
-
- disable_ddl_transaction!
-
- def up
- add_check_constraint :application_settings, 'container_registry_cleanup_tags_service_max_list_size >= 0', CONSTRAINT_NAME
- end
-
- def down
- remove_check_constraint :application_settings, CONSTRAINT_NAME
- end
-end
diff --git a/db/migrate/20201214113729_add_custom_mapping_columns_to_http_integrations.rb b/db/migrate/20201214113729_add_custom_mapping_columns_to_http_integrations.rb
deleted file mode 100644
index dbad28280ac..00000000000
--- a/db/migrate/20201214113729_add_custom_mapping_columns_to_http_integrations.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-# frozen_string_literal: true
-
-class AddCustomMappingColumnsToHttpIntegrations < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :alert_management_http_integrations, :payload_example, :jsonb, null: false, default: {}
- add_column :alert_management_http_integrations, :payload_attribute_mapping, :jsonb, null: false, default: {}
- end
-end
diff --git a/db/migrate/20201214184020_add_epic_board_list.rb b/db/migrate/20201214184020_add_epic_board_list.rb
deleted file mode 100644
index 9c4e3280754..00000000000
--- a/db/migrate/20201214184020_add_epic_board_list.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# frozen_string_literal: true
-
-class AddEpicBoardList < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- unless table_exists?(:boards_epic_lists)
- with_lock_retries do
- create_table :boards_epic_lists do |t|
- t.timestamps_with_timezone
- t.references :epic_board, index: true, foreign_key: { to_table: :boards_epic_boards, on_delete: :cascade }, null: false
- t.references :label, index: true, foreign_key: { on_delete: :cascade }
- t.integer :position
- t.integer :list_type, default: 1, limit: 2, null: false
-
- t.index [:epic_board_id, :label_id], unique: true, where: 'list_type = 1', name: 'index_boards_epic_lists_on_epic_board_id_and_label_id'
- end
- end
- end
-
- add_check_constraint :boards_epic_lists, '(list_type <> 1) OR ("position" IS NOT NULL AND "position" >= 0)', 'boards_epic_lists_position_constraint'
- end
-
- def down
- with_lock_retries do
- drop_table :boards_epic_lists
- end
- end
-end
diff --git a/db/migrate/20201215084652_delete_mock_deployment_service_records.rb b/db/migrate/20201215084652_delete_mock_deployment_service_records.rb
deleted file mode 100644
index 6c601a5e852..00000000000
--- a/db/migrate/20201215084652_delete_mock_deployment_service_records.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-class DeleteMockDeploymentServiceRecords < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def up
- if Rails.env.development?
- execute("DELETE FROM services WHERE type = 'MockDeploymentService'")
- end
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/migrate/20201215132151_change_unique_index_on_security_findings.rb b/db/migrate/20201215132151_change_unique_index_on_security_findings.rb
deleted file mode 100644
index fe474ef3991..00000000000
--- a/db/migrate/20201215132151_change_unique_index_on_security_findings.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-class ChangeUniqueIndexOnSecurityFindings < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- OLD_INDEX_NAME = 'index_security_findings_on_uuid'
- NEW_INDEX_NAME = 'index_security_findings_on_uuid_and_scan_id'
-
- disable_ddl_transaction!
-
- class SecurityFinding < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'security_findings'
- end
-
- def up
- add_concurrent_index :security_findings, [:uuid, :scan_id], unique: true, name: NEW_INDEX_NAME
-
- remove_concurrent_index_by_name :security_findings, OLD_INDEX_NAME
- end
-
- def down
- # It is very unlikely that we rollback this migration but just in case if we have to,
- # we have to clear the table because there can be multiple records with the same UUID
- # which would break the creation of unique index on the `uuid` column.
- # We choose clearing the table because just removing the duplicated records would
- # cause data inconsistencies.
- SecurityFinding.each_batch(of: 10000) { |relation| relation.delete_all }
-
- add_concurrent_index :security_findings, :uuid, unique: true, name: OLD_INDEX_NAME
-
- remove_concurrent_index_by_name :security_findings, NEW_INDEX_NAME
- end
-end
diff --git a/db/migrate/20201215205404_create_namespace_package_settings.rb b/db/migrate/20201215205404_create_namespace_package_settings.rb
deleted file mode 100644
index d74b99597ce..00000000000
--- a/db/migrate/20201215205404_create_namespace_package_settings.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-class CreateNamespacePackageSettings < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- with_lock_retries do
- create_table :namespace_package_settings, if_not_exists: true, id: false do |t|
- t.references :namespace, primary_key: true, index: false, default: nil, foreign_key: { to_table: :namespaces, on_delete: :cascade }, type: :bigint
- t.boolean :maven_duplicates_allowed, null: false, default: true
- t.text :maven_duplicate_exception_regex, null: false, default: ''
- end
- end
-
- add_text_limit :namespace_package_settings, :maven_duplicate_exception_regex, 255
- end
-
- def down
- drop_table :namespace_package_settings
- end
-end
diff --git a/db/migrate/20201216151616_add_squash_commit_sha_index.rb b/db/migrate/20201216151616_add_squash_commit_sha_index.rb
deleted file mode 100644
index ac6d3fda2d2..00000000000
--- a/db/migrate/20201216151616_add_squash_commit_sha_index.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-class AddSquashCommitShaIndex < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- INDEX_NAME = "index_merge_requests_on_target_project_id_and_squash_commit_sha"
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :merge_requests,
- [:target_project_id, :squash_commit_sha],
- name: INDEX_NAME
- end
-
- def down
- remove_concurrent_index :merge_requests,
- [:target_project_id, :squash_commit_sha],
- name: INDEX_NAME
- end
-end
diff --git a/db/migrate/20201216154457_add_devops_adoption_snapshot_range_end.rb b/db/migrate/20201216154457_add_devops_adoption_snapshot_range_end.rb
deleted file mode 100644
index ada1bd9b346..00000000000
--- a/db/migrate/20201216154457_add_devops_adoption_snapshot_range_end.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-class AddDevopsAdoptionSnapshotRangeEnd < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- add_column :analytics_devops_adoption_snapshots, :end_time, :datetime_with_timezone
- end
-end
diff --git a/db/migrate/20201217070530_add_group_merge_request_approval_settings.rb b/db/migrate/20201217070530_add_group_merge_request_approval_settings.rb
deleted file mode 100644
index dba9e6e440f..00000000000
--- a/db/migrate/20201217070530_add_group_merge_request_approval_settings.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-class AddGroupMergeRequestApprovalSettings < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- create_table :group_merge_request_approval_settings, id: false do |t|
- t.timestamps_with_timezone null: false
- t.references :group, references: :namespaces, primary_key: true, default: nil, index: false,
- foreign_key: { to_table: :namespaces, on_delete: :cascade }
- t.boolean :allow_author_approval, null: false, default: false
- end
- end
- end
-
- def down
- with_lock_retries do
- drop_table :group_merge_request_approval_settings
- end
- end
-end
diff --git a/db/migrate/20201217111448_change_pages_deployment_size_to_bigint.rb b/db/migrate/20201217111448_change_pages_deployment_size_to_bigint.rb
deleted file mode 100644
index 75420166b87..00000000000
--- a/db/migrate/20201217111448_change_pages_deployment_size_to_bigint.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class ChangePagesDeploymentSizeToBigint < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- change_column_type_concurrently :pages_deployments, :size, :bigint
- end
-
- def down
- undo_change_column_type_concurrently :pages_deployments, :size
- end
-end
diff --git a/db/migrate/20201217132603_create_elastic_reindexing_subtasks.rb b/db/migrate/20201217132603_create_elastic_reindexing_subtasks.rb
deleted file mode 100644
index db084b885c2..00000000000
--- a/db/migrate/20201217132603_create_elastic_reindexing_subtasks.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-# frozen_string_literal: true
-
-class CreateElasticReindexingSubtasks < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- class ReindexingTask < ActiveRecord::Base
- self.table_name = 'elastic_reindexing_tasks'
- end
-
- class ReindexingSubtask < ActiveRecord::Base
- self.table_name = 'elastic_reindexing_subtasks'
- end
-
- def up
- unless table_exists?(:elastic_reindexing_subtasks)
- create_table :elastic_reindexing_subtasks do |t|
- t.references :elastic_reindexing_task, foreign_key: { on_delete: :cascade }, null: false
- t.text :alias_name, null: false
- t.text :index_name_from, null: false
- t.text :index_name_to, null: false
- t.text :elastic_task, null: false
- t.integer :documents_count_target
- t.integer :documents_count
- t.timestamps_with_timezone null: false
- end
- end
-
- add_text_limit :elastic_reindexing_subtasks, :index_name_from, 255
- add_text_limit :elastic_reindexing_subtasks, :index_name_to, 255
- add_text_limit :elastic_reindexing_subtasks, :elastic_task, 255
- add_text_limit :elastic_reindexing_subtasks, :alias_name, 255
-
- ReindexingTask.find_each do |task|
- next if task.index_name_from.blank? || task.index_name_to.blank? || task.elastic_task.blank?
- next if ReindexingSubtask.where(elastic_reindexing_task_id: task.id).exists?
-
- ReindexingSubtask.create(
- elastic_reindexing_task_id: task.id,
- documents_count_target: task.documents_count_target,
- documents_count: task.documents_count,
- alias_name: 'gitlab-production',
- index_name_from: task.index_name_from,
- index_name_to: task.index_name_to,
- elastic_task: task.elastic_task
- )
- end
- end
-
- def down
- drop_table :elastic_reindexing_subtasks
- end
-end
diff --git a/db/migrate/20201218194311_create_admin_notes.rb b/db/migrate/20201218194311_create_admin_notes.rb
deleted file mode 100644
index 32f5818cdfb..00000000000
--- a/db/migrate/20201218194311_create_admin_notes.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-class CreateAdminNotes < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- create_table_with_constraints :namespace_admin_notes do |t|
- t.timestamps_with_timezone
- t.references :namespace, null: false, foreign_key: { on_delete: :cascade }
- t.text :note
-
- t.text_limit :note, 1000
- end
- end
-
- def down
- drop_table :namespace_admin_notes
- end
-end
diff --git a/db/migrate/20201221124036_add_devops_snapshot_index.rb b/db/migrate/20201221124036_add_devops_snapshot_index.rb
deleted file mode 100644
index 85001e9abcf..00000000000
--- a/db/migrate/20201221124036_add_devops_snapshot_index.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddDevopsSnapshotIndex < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- INDEX_NAME = 'index_on_snapshots_segment_id_end_time'
-
- def up
- add_concurrent_index :analytics_devops_adoption_snapshots, [:segment_id, :end_time], name: INDEX_NAME
- end
-
- def down
- remove_concurrent_index_by_name :analytics_devops_adoption_snapshots, INDEX_NAME
- end
-end
diff --git a/db/migrate/20201221213415_change_clusters_helm_major_version_default_to_3.rb b/db/migrate/20201221213415_change_clusters_helm_major_version_default_to_3.rb
deleted file mode 100644
index baec0da208b..00000000000
--- a/db/migrate/20201221213415_change_clusters_helm_major_version_default_to_3.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class ChangeClustersHelmMajorVersionDefaultTo3 < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- change_column_default(:clusters, :helm_major_version, from: 2, to: 3)
- end
-end
diff --git a/db/migrate/20201221225303_add_service_desk_reply_to_is_not_null_index_on_issues.rb b/db/migrate/20201221225303_add_service_desk_reply_to_is_not_null_index_on_issues.rb
deleted file mode 100644
index 7643fc107aa..00000000000
--- a/db/migrate/20201221225303_add_service_desk_reply_to_is_not_null_index_on_issues.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-class AddServiceDeskReplyToIsNotNullIndexOnIssues < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- # no-op, the migration's version number was lowered to be executed earlier than db/post_migrate/20201128210234_schedule_populate_issue_email_participants.rb
- #
- # The new migration is located here: db/migrate/20201128210000_add_service_desk_reply_to_is_not_null_index_on_issues_fix.rb
- end
-end
diff --git a/db/migrate/20201222151823_update_trusted_apps_to_confidential.rb b/db/migrate/20201222151823_update_trusted_apps_to_confidential.rb
deleted file mode 100644
index bcb94c65125..00000000000
--- a/db/migrate/20201222151823_update_trusted_apps_to_confidential.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-class UpdateTrustedAppsToConfidential < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- INDEX_NAME = 'tmp_index_oauth_applications_on_id_where_trusted'
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :oauth_applications, :id, where: 'trusted = true', name: INDEX_NAME
-
- execute('UPDATE oauth_applications SET confidential = true WHERE trusted = true')
- end
-
- def down
- # We won't be able to tell which trusted applications weren't confidential before the migration
- # and setting all trusted applications are not confidential would introduce security issues
-
- remove_concurrent_index_by_name :oauth_applications, INDEX_NAME
- end
-end
diff --git a/db/migrate/20201223114050_add_restrict_user_defined_variables_to_project_settings.rb b/db/migrate/20201223114050_add_restrict_user_defined_variables_to_project_settings.rb
deleted file mode 100644
index d04c6981bf9..00000000000
--- a/db/migrate/20201223114050_add_restrict_user_defined_variables_to_project_settings.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddRestrictUserDefinedVariablesToProjectSettings < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- add_column :project_ci_cd_settings, :restrict_user_defined_variables, :boolean, default: false, null: false
- end
- end
-
- def down
- with_lock_retries do
- remove_column :project_ci_cd_settings, :restrict_user_defined_variables
- end
- end
-end
diff --git a/db/migrate/20201224144948_migrate_coverage_report_worker.rb b/db/migrate/20201224144948_migrate_coverage_report_worker.rb
deleted file mode 100644
index 8580a15c256..00000000000
--- a/db/migrate/20201224144948_migrate_coverage_report_worker.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-class MigrateCoverageReportWorker < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- sidekiq_queue_migrate 'ci_pipelines_create_artifact', to: 'ci_pipeline_artifacts_coverage_report' # rubocop:disable Migration/SidekiqQueueMigrate
- end
-
- def down
- sidekiq_queue_migrate 'ci_pipeline_artifacts_coverage_report', to: 'ci_pipelines_create_artifact' # rubocop:disable Migration/SidekiqQueueMigrate
- end
-end
diff --git a/db/migrate/20201228110136_create_iterations_cadence.rb b/db/migrate/20201228110136_create_iterations_cadence.rb
deleted file mode 100644
index 95601ab4b29..00000000000
--- a/db/migrate/20201228110136_create_iterations_cadence.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-class CreateIterationsCadence < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- create_table_with_constraints :iterations_cadences do |t|
- t.references :group, null: false, foreign_key: { to_table: :namespaces, on_delete: :cascade }
- t.timestamps_with_timezone null: false
- t.date :start_date, null: false
- t.date :last_run_date
- t.integer :duration_in_weeks
- t.integer :iterations_in_advance
- t.boolean :active, default: true, null: false
- t.boolean :automatic, default: true, null: false
- t.text :title, null: false
-
- t.text_limit :title, 255
- end
- end
-
- def down
- drop_table :iterations_cadences if table_exists?(:iterations_cadences)
- end
-end
diff --git a/db/migrate/20201228110238_add_iterations_cadence_to_sprints.rb b/db/migrate/20201228110238_add_iterations_cadence_to_sprints.rb
deleted file mode 100644
index 9d9026a265b..00000000000
--- a/db/migrate/20201228110238_add_iterations_cadence_to_sprints.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-class AddIterationsCadenceToSprints < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- INDEX_NAME = 'index_sprints_iterations_cadence_id'
-
- def up
- add_column :sprints, :iterations_cadence_id, :integer unless column_exists?(:sprints, :iterations_cadence_id)
-
- add_concurrent_index :sprints, :iterations_cadence_id, name: INDEX_NAME
- add_concurrent_foreign_key :sprints, :iterations_cadences, column: :iterations_cadence_id, on_delete: :cascade
- end
-
- def down
- remove_column :sprints, :iterations_cadence_id if column_exists?(:sprints, :iterations_cadence_id)
- end
-end
diff --git a/db/migrate/20201228184500_add_dismissal_reason_into_vulnerability_feedback_table.rb b/db/migrate/20201228184500_add_dismissal_reason_into_vulnerability_feedback_table.rb
deleted file mode 100644
index 92484aced4e..00000000000
--- a/db/migrate/20201228184500_add_dismissal_reason_into_vulnerability_feedback_table.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: true
-
-class AddDismissalReasonIntoVulnerabilityFeedbackTable < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def up
- add_column :vulnerability_feedback, :dismissal_reason, :smallint
- end
-
- def down
- remove_column :vulnerability_feedback, :dismissal_reason
- end
-end
diff --git a/db/migrate/20201229105948_add_invisible_captcha_enabled_to_settings.rb b/db/migrate/20201229105948_add_invisible_captcha_enabled_to_settings.rb
deleted file mode 100644
index 025fcba0729..00000000000
--- a/db/migrate/20201229105948_add_invisible_captcha_enabled_to_settings.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddInvisibleCaptchaEnabledToSettings < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :application_settings, :invisible_captcha_enabled, :boolean, null: false, default: false
- end
-end
diff --git a/db/migrate/20201230161206_add_rate_limiting_response_text_to_application_settings.rb b/db/migrate/20201230161206_add_rate_limiting_response_text_to_application_settings.rb
deleted file mode 100644
index 647455f5f88..00000000000
--- a/db/migrate/20201230161206_add_rate_limiting_response_text_to_application_settings.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-class AddRateLimitingResponseTextToApplicationSettings < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- # rubocop:disable Migration/AddLimitToTextColumns
- # limit is added in 20210101110640_set_limit_for_rate_limiting_response_text
- def change
- add_column :application_settings, :rate_limiting_response_text, :text
- end
- # rubocop:enable Migration/AddLimitToTextColumns
-end
diff --git a/db/migrate/20201230180202_create_onboarding_progress.rb b/db/migrate/20201230180202_create_onboarding_progress.rb
deleted file mode 100644
index b9fe64eb19d..00000000000
--- a/db/migrate/20201230180202_create_onboarding_progress.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-class CreateOnboardingProgress < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- create_table :onboarding_progresses do |t|
- t.references :namespace, null: false, index: { unique: true }, foreign_key: { on_delete: :cascade }
- t.timestamps_with_timezone null: false
- t.datetime_with_timezone :git_pull_at
- t.datetime_with_timezone :git_write_at
- t.datetime_with_timezone :merge_request_created_at
- t.datetime_with_timezone :pipeline_created_at
- t.datetime_with_timezone :user_added_at
- t.datetime_with_timezone :trial_started_at
- t.datetime_with_timezone :subscription_created_at
- t.datetime_with_timezone :required_mr_approvals_enabled_at
- t.datetime_with_timezone :code_owners_enabled_at
- t.datetime_with_timezone :scoped_label_created_at
- t.datetime_with_timezone :security_scan_enabled_at
- t.datetime_with_timezone :issue_auto_closed_at
- t.datetime_with_timezone :repository_imported_at
- t.datetime_with_timezone :repository_mirrored_at
- end
- end
- end
-
- def down
- with_lock_retries do
- drop_table :onboarding_progresses
- end
- end
-end
diff --git a/db/migrate/20210101110640_set_limit_for_rate_limiting_response_text.rb b/db/migrate/20210101110640_set_limit_for_rate_limiting_response_text.rb
deleted file mode 100644
index b72f2ae7d70..00000000000
--- a/db/migrate/20210101110640_set_limit_for_rate_limiting_response_text.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-class SetLimitForRateLimitingResponseText < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_text_limit :application_settings, :rate_limiting_response_text, 255
- end
-
- def down
- remove_text_limit :application_settings, :rate_limiting_response_text
- end
-end
diff --git a/db/migrate/20210102164121_drop_temporary_index_on_ci_builds.rb b/db/migrate/20210102164121_drop_temporary_index_on_ci_builds.rb
deleted file mode 100644
index 9c99414792e..00000000000
--- a/db/migrate/20210102164121_drop_temporary_index_on_ci_builds.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class DropTemporaryIndexOnCiBuilds < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- INDEX = 'tmp_build_stage_position_index'
-
- def up
- remove_concurrent_index_by_name :ci_builds, INDEX
- end
-
- def down
- add_concurrent_index :ci_builds, [:stage_id, :stage_idx], where: 'stage_idx IS NOT NULL', name: INDEX
- end
-end
diff --git a/db/migrate/20210104163218_add_epic_board_position_index.rb b/db/migrate/20210104163218_add_epic_board_position_index.rb
deleted file mode 100644
index 32c829f0288..00000000000
--- a/db/migrate/20210104163218_add_epic_board_position_index.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class AddEpicBoardPositionIndex < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- INDEX_NAME = 'index_boards_epic_board_positions_on_scoped_relative_position'
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :boards_epic_board_positions, [:epic_board_id, :epic_id, :relative_position], name: INDEX_NAME
- end
-
- def down
- remove_concurrent_index_by_name :boards_epic_board_positions, INDEX_NAME
- end
-end
diff --git a/db/migrate/20210105052034_rename_asset_proxy_whitelist_on_application_settings.rb b/db/migrate/20210105052034_rename_asset_proxy_whitelist_on_application_settings.rb
deleted file mode 100644
index cdfbd368070..00000000000
--- a/db/migrate/20210105052034_rename_asset_proxy_whitelist_on_application_settings.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-class RenameAssetProxyWhitelistOnApplicationSettings < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers::V2
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- rename_column_concurrently :application_settings,
- :asset_proxy_whitelist,
- :asset_proxy_allowlist
- end
-
- def down
- undo_rename_column_concurrently :application_settings,
- :asset_proxy_whitelist,
- :asset_proxy_allowlist
- end
-end
diff --git a/db/migrate/20210105153342_add_entity_columns_to_vulnerability_occurrences.rb b/db/migrate/20210105153342_add_entity_columns_to_vulnerability_occurrences.rb
deleted file mode 100644
index 3b5ffff7645..00000000000
--- a/db/migrate/20210105153342_add_entity_columns_to_vulnerability_occurrences.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-class AddEntityColumnsToVulnerabilityOccurrences < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- # rubocop:disable Migration/AddLimitToTextColumns
- # limit is added in 20200501000002_add_text_limit_to_sprints_extended_title
- def change
- add_column :vulnerability_occurrences, :description, :text
- add_column :vulnerability_occurrences, :message, :text
- add_column :vulnerability_occurrences, :solution, :text
- add_column :vulnerability_occurrences, :cve, :text
- add_column :vulnerability_occurrences, :location, :jsonb
- end
- # rubocop:enable Migration/AddLimitToTextColumns
-end
diff --git a/db/migrate/20210105154321_add_text_limit_to_vulnerability_occurrences_entity_columns.rb b/db/migrate/20210105154321_add_text_limit_to_vulnerability_occurrences_entity_columns.rb
deleted file mode 100644
index c2e138303d8..00000000000
--- a/db/migrate/20210105154321_add_text_limit_to_vulnerability_occurrences_entity_columns.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-class AddTextLimitToVulnerabilityOccurrencesEntityColumns < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_text_limit :vulnerability_occurrences, :description, 15000
- add_text_limit :vulnerability_occurrences, :message, 3000
- add_text_limit :vulnerability_occurrences, :solution, 7000
- add_text_limit :vulnerability_occurrences, :cve, 48400
- end
-
- def down
- remove_text_limit :vulnerability_occurrences, :description
- remove_text_limit :vulnerability_occurrences, :message
- remove_text_limit :vulnerability_occurrences, :solution
- remove_text_limit :vulnerability_occurrences, :cve
- end
-end
diff --git a/db/migrate/20210106061254_add_unique_index_for_golang_packages.rb b/db/migrate/20210106061254_add_unique_index_for_golang_packages.rb
deleted file mode 100644
index 44237699fda..00000000000
--- a/db/migrate/20210106061254_add_unique_index_for_golang_packages.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-class AddUniqueIndexForGolangPackages < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- INDEX_NAME = 'index_packages_on_project_id_name_version_unique_when_golang'
- PACKAGE_TYPE_GOLANG = 8
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :packages_packages, [:project_id, :name, :version], unique: true, where: "package_type = #{PACKAGE_TYPE_GOLANG}", name: INDEX_NAME
- end
-
- def down
- remove_concurrent_index_by_name(:packages_packages, INDEX_NAME)
- end
-end
diff --git a/db/migrate/20210106153021_drop_tmp_index_on_emails.rb b/db/migrate/20210106153021_drop_tmp_index_on_emails.rb
deleted file mode 100644
index 94b4a5437af..00000000000
--- a/db/migrate/20210106153021_drop_tmp_index_on_emails.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-class DropTmpIndexOnEmails < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- EMAIL_INDEX_NAME = 'tmp_index_for_email_unconfirmation_migration'
-
- disable_ddl_transaction!
-
- def up
- Gitlab::BackgroundMigration.steal('WrongfullyConfirmedEmailUnconfirmer')
-
- remove_concurrent_index_by_name(:emails, EMAIL_INDEX_NAME)
- end
-
- def down
- add_concurrent_index(:emails, :id, where: 'confirmed_at IS NOT NULL', name: EMAIL_INDEX_NAME)
- end
-end
diff --git a/db/migrate/20210106155209_add_merge_request_diff_commit_trailers.rb b/db/migrate/20210106155209_add_merge_request_diff_commit_trailers.rb
deleted file mode 100644
index 906efa58bcd..00000000000
--- a/db/migrate/20210106155209_add_merge_request_diff_commit_trailers.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# 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 AddMergeRequestDiffCommitTrailers < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- add_column :merge_request_diff_commits, :trailers, :jsonb, default: {}, null: false
- end
- end
-
- def down
- with_lock_retries do
- remove_column :merge_request_diff_commits, :trailers
- end
- end
-end
diff --git a/db/migrate/20210106191305_rename_indexes_on_git_lab_com.rb b/db/migrate/20210106191305_rename_indexes_on_git_lab_com.rb
deleted file mode 100644
index 5238192e1d1..00000000000
--- a/db/migrate/20210106191305_rename_indexes_on_git_lab_com.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-# frozen_string_literal: true
-
-# This migration aligns an existing database schema with what we actually expect
-# and fixes inconsistencies with index names and similar issues.
-#
-# This is intended for GitLab.com, but can be run on any instance.
-class RenameIndexesOnGitLabCom < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- rename_index_if_exists :ldap_group_links, 'ldap_groups_pkey', 'ldap_group_links_pkey'
-
- # Removes unique constraint, add unique index instead
- replace_unique_constraint_with_index :emails, :email, 'emails_email_key', 'index_emails_on_email'
- replace_unique_constraint_with_index :users, :confirmation_token, 'users_confirmation_token_key', 'index_users_on_confirmation_token'
- replace_unique_constraint_with_index :users, :reset_password_token, 'users_reset_password_token_key', 'index_users_on_reset_password_token'
- replace_unique_constraint_with_index :users, :email, 'users_email_key', 'index_users_on_email'
-
- upgrade_to_primary_key(:schema_migrations, :version, 'schema_migrations_version_key', 'schema_migrations_pkey')
- end
-
- def down
- # no-op
- end
-
- private
-
- def replace_unique_constraint_with_index(table, columns, old_name, new_name)
- return unless index_exists_by_name?(table, old_name)
-
- add_concurrent_index table, columns, unique: true, name: new_name
- execute "ALTER TABLE #{quote_table_name(table)} DROP CONSTRAINT #{quote_table_name(old_name)}"
- end
-
- def rename_index_if_exists(table, old_name, new_name)
- return unless index_exists_by_name?(table, old_name)
- return if index_exists_by_name?(table, new_name)
-
- with_lock_retries do
- rename_index table, old_name, new_name
- end
- end
-
- def upgrade_to_primary_key(table, column, old_name, new_name)
- return unless index_exists_by_name?(table, old_name)
- return if index_exists_by_name?(table, new_name)
-
- return if primary_key(table)
-
- execute "ALTER TABLE #{quote_table_name(table)} ADD CONSTRAINT #{new_name} PRIMARY KEY (#{column})"
- execute "ALTER TABLE #{quote_table_name(table)} DROP CONSTRAINT #{old_name}"
- end
-end
diff --git a/db/migrate/20210106225424_add_keep_latest_artifacts_to_application_settings.rb b/db/migrate/20210106225424_add_keep_latest_artifacts_to_application_settings.rb
deleted file mode 100644
index 884159ddedb..00000000000
--- a/db/migrate/20210106225424_add_keep_latest_artifacts_to_application_settings.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-class AddKeepLatestArtifactsToApplicationSettings < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- # This is named keep_latest_artifact for consistency with the project level setting but
- # turning it on keeps all (multiple) artifacts on the latest pipeline per ref
- add_column :application_settings, :keep_latest_artifact, :boolean, default: true, null: false
- end
-end
diff --git a/db/migrate/20210107105306_add_diff_type_to_merge_request_diffs.rb b/db/migrate/20210107105306_add_diff_type_to_merge_request_diffs.rb
deleted file mode 100644
index 0b9b5e93054..00000000000
--- a/db/migrate/20210107105306_add_diff_type_to_merge_request_diffs.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# frozen_string_literal: true
-
-class AddDiffTypeToMergeRequestDiffs < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- UNIQUE_INDEX_NAME = 'index_merge_request_diffs_on_unique_merge_request_id'
-
- def up
- unless column_exists?(:merge_request_diffs, :diff_type)
- with_lock_retries do
- add_column :merge_request_diffs, :diff_type, :integer, null: false, limit: 2, default: 1
- end
- end
-
- add_concurrent_index :merge_request_diffs, :merge_request_id, unique: true, where: 'diff_type = 2', name: UNIQUE_INDEX_NAME
- end
-
- def down
- remove_concurrent_index_by_name(:merge_request_diffs, UNIQUE_INDEX_NAME)
-
- if column_exists?(:merge_request_diffs, :diff_type)
- with_lock_retries do
- remove_column :merge_request_diffs, :diff_type
- end
- end
- end
-end
diff --git a/db/migrate/20210107154615_add_merge_request_context_commit_trailers.rb b/db/migrate/20210107154615_add_merge_request_context_commit_trailers.rb
deleted file mode 100644
index e7bd7c2ea56..00000000000
--- a/db/migrate/20210107154615_add_merge_request_context_commit_trailers.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# 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 AddMergeRequestContextCommitTrailers < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :merge_request_context_commits, :trailers, :jsonb, default: {}, null: false
- end
-end
diff --git a/db/migrate/20210108161039_update_max_import_size_default.rb b/db/migrate/20210108161039_update_max_import_size_default.rb
deleted file mode 100644
index 5f0591b2766..00000000000
--- a/db/migrate/20210108161039_update_max_import_size_default.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class UpdateMaxImportSizeDefault < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- change_column_default(:application_settings, :max_import_size, from: 50, to: 0)
- end
-end
diff --git a/db/migrate/20210111051045_create_dast_profiles.rb b/db/migrate/20210111051045_create_dast_profiles.rb
deleted file mode 100644
index f2667e1222e..00000000000
--- a/db/migrate/20210111051045_create_dast_profiles.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# frozen_string_literal: true
-
-class CreateDastProfiles < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- table_comment = { owner: 'group::dynamic analysis', description: 'Profile used to run a DAST on-demand scan' }
-
- create_table_with_constraints :dast_profiles, comment: table_comment.to_json do |t| # rubocop:disable Migration/AddLimitToTextColumns
- t.references :project, null: false, foreign_key: false, index: false
- t.references :dast_site_profile, null: false, foreign_key: { on_delete: :cascade }
- t.references :dast_scanner_profile, null: false, foreign_key: { on_delete: :cascade }
-
- t.timestamps_with_timezone
-
- # rubocop:disable Migration/AddLimitToTextColumns
- t.text :name, null: false
- t.text :description, null: false
- # rubocop:enable Migration/AddLimitToTextColumns
-
- t.index [:project_id, :name], unique: true
-
- t.text_limit :name, 255
- t.text_limit :description, 255
- end
- end
-
- def down
- with_lock_retries do
- drop_table :dast_profiles
- end
- end
-end
diff --git a/db/migrate/20210111053308_add_project_fk_for_dast_profile.rb b/db/migrate/20210111053308_add_project_fk_for_dast_profile.rb
deleted file mode 100644
index 5dc057b5f70..00000000000
--- a/db/migrate/20210111053308_add_project_fk_for_dast_profile.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddProjectFkForDastProfile < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_foreign_key :dast_profiles, :projects, column: :project_id, on_delete: :cascade
- end
-
- def down
- with_lock_retries do
- remove_foreign_key :dast_profiles, column: :project_id
- end
- end
-end
diff --git a/db/migrate/20210111075104_add_temporary_index_on_security_findings_scan_id.rb b/db/migrate/20210111075104_add_temporary_index_on_security_findings_scan_id.rb
deleted file mode 100644
index a8f4e130f07..00000000000
--- a/db/migrate/20210111075104_add_temporary_index_on_security_findings_scan_id.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class AddTemporaryIndexOnSecurityFindingsScanId < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- INDEX_NAME = 'tmp_index_on_security_findings_scan_id'
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :security_findings, :scan_id, where: 'uuid is null', name: INDEX_NAME
- end
-
- def down
- remove_concurrent_index_by_name :security_findings, INDEX_NAME
- end
-end
diff --git a/db/migrate/20210112084512_drop_tmp_index_on_emails_again.rb b/db/migrate/20210112084512_drop_tmp_index_on_emails_again.rb
deleted file mode 100644
index 6c2f9cbcb32..00000000000
--- a/db/migrate/20210112084512_drop_tmp_index_on_emails_again.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class DropTmpIndexOnEmailsAgain < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- EMAIL_INDEX_NAME = 'tmp_index_for_email_unconfirmation_migration'
-
- disable_ddl_transaction!
-
- def up
- remove_concurrent_index_by_name(:emails, EMAIL_INDEX_NAME)
- end
-
- def down
- add_concurrent_index(:emails, :id, where: 'confirmed_at IS NOT NULL', name: EMAIL_INDEX_NAME)
- end
-end
diff --git a/db/migrate/20210112202949_create_composer_cache_file.rb b/db/migrate/20210112202949_create_composer_cache_file.rb
deleted file mode 100644
index b1c2a1608dd..00000000000
--- a/db/migrate/20210112202949_create_composer_cache_file.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-# frozen_string_literal: true
-
-class CreateComposerCacheFile < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- # rubocop:disable Migration/AddLimitToTextColumns
- create_table_with_constraints :packages_composer_cache_files do |t|
- t.timestamps_with_timezone
-
- # record can be deleted after `delete_at`
- t.datetime_with_timezone :delete_at
-
- # which namespace it belongs to
- t.integer :namespace_id, null: true
-
- # file storage related fields
- t.integer :file_store, limit: 2, null: false, default: 1
- t.text :file, null: false
- t.binary :file_sha256, null: false
-
- t.index [:namespace_id, :file_sha256], name: "index_packages_composer_cache_namespace_and_sha", using: :btree, unique: true
- t.foreign_key :namespaces, column: :namespace_id, on_delete: :nullify
-
- t.text_limit :file, 255
- end
- end
-
- def down
- drop_table :packages_composer_cache_files
- end
-end
diff --git a/db/migrate/20210113224909_add_pipeline_configuration_full_path_to_compliance_pipeline.rb b/db/migrate/20210113224909_add_pipeline_configuration_full_path_to_compliance_pipeline.rb
deleted file mode 100644
index 408d0579031..00000000000
--- a/db/migrate/20210113224909_add_pipeline_configuration_full_path_to_compliance_pipeline.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-class AddPipelineConfigurationFullPathToCompliancePipeline < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- # rubocop:disable Migration/AddLimitToTextColumns
- # limit is added in 20210119162812_add_text_limit_to_compliance_pipeline_configuration_full_path.rb
- def up
- add_column :compliance_management_frameworks, :pipeline_configuration_full_path, :text
- end
- # rubocop:enable Migration/AddLimitToTextColumns
-
- def down
- remove_column :compliance_management_frameworks, :pipeline_configuration_full_path
- end
-end
diff --git a/db/migrate/20210113231532_add_converted_at_to_experiment_subjects.rb b/db/migrate/20210113231532_add_converted_at_to_experiment_subjects.rb
deleted file mode 100644
index 25571b25af9..00000000000
--- a/db/migrate/20210113231532_add_converted_at_to_experiment_subjects.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddConvertedAtToExperimentSubjects < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :experiment_subjects, :converted_at, :datetime_with_timezone
- end
-end
diff --git a/db/migrate/20210113231546_add_context_to_experiment_subjects.rb b/db/migrate/20210113231546_add_context_to_experiment_subjects.rb
deleted file mode 100644
index 7fac45e9952..00000000000
--- a/db/migrate/20210113231546_add_context_to_experiment_subjects.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddContextToExperimentSubjects < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :experiment_subjects, :context, :jsonb, default: {}, null: false
- end
-end
diff --git a/db/migrate/20210114033715_remove_group_id_title_index.rb b/db/migrate/20210114033715_remove_group_id_title_index.rb
deleted file mode 100644
index 8d63da3d400..00000000000
--- a/db/migrate/20210114033715_remove_group_id_title_index.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveGroupIdTitleIndex < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- INDEX_NAME = 'index_labels_on_group_id_and_title_with_null_project_id'
- LABELS_TABLE = :labels
-
- def up
- remove_concurrent_index_by_name LABELS_TABLE, INDEX_NAME
- end
-
- def down
- add_concurrent_index LABELS_TABLE, [:group_id, :title], where: 'project_id IS NULL', name: INDEX_NAME
- end
-end
diff --git a/db/migrate/20210114142443_add_indexes_to_onboarding_progresses.rb b/db/migrate/20210114142443_add_indexes_to_onboarding_progresses.rb
deleted file mode 100644
index 39964047e7f..00000000000
--- a/db/migrate/20210114142443_add_indexes_to_onboarding_progresses.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# frozen_string_literal: true
-
-class AddIndexesToOnboardingProgresses < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- CREATE_TRACK_INDEX_NAME = 'index_onboarding_progresses_for_create_track'
- VERIFY_TRACK_INDEX_NAME = 'index_onboarding_progresses_for_verify_track'
- TRIAL_TRACK_INDEX_NAME = 'index_onboarding_progresses_for_trial_track'
- TEAM_TRACK_INDEX_NAME = 'index_onboarding_progresses_for_team_track'
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :onboarding_progresses, :created_at, where: 'git_write_at IS NULL', name: CREATE_TRACK_INDEX_NAME
- add_concurrent_index :onboarding_progresses, :git_write_at, where: 'git_write_at IS NOT NULL AND pipeline_created_at IS NULL', name: VERIFY_TRACK_INDEX_NAME
- add_concurrent_index :onboarding_progresses, 'GREATEST(git_write_at, pipeline_created_at)', where: 'git_write_at IS NOT NULL AND pipeline_created_at IS NOT NULL AND trial_started_at IS NULL', name: TRIAL_TRACK_INDEX_NAME
- add_concurrent_index :onboarding_progresses, 'GREATEST(git_write_at, pipeline_created_at, trial_started_at)', where: 'git_write_at IS NOT NULL AND pipeline_created_at IS NOT NULL AND trial_started_at IS NOT NULL AND user_added_at IS NULL', name: TEAM_TRACK_INDEX_NAME
- end
-
- def down
- remove_concurrent_index_by_name :onboarding_progresses, CREATE_TRACK_INDEX_NAME
- remove_concurrent_index_by_name :onboarding_progresses, VERIFY_TRACK_INDEX_NAME
- remove_concurrent_index_by_name :onboarding_progresses, TRIAL_TRACK_INDEX_NAME
- remove_concurrent_index_by_name :onboarding_progresses, TEAM_TRACK_INDEX_NAME
- end
-end
diff --git a/db/migrate/20210115090452_create_group_repository_storage_move.rb b/db/migrate/20210115090452_create_group_repository_storage_move.rb
deleted file mode 100644
index bd168dce5ac..00000000000
--- a/db/migrate/20210115090452_create_group_repository_storage_move.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-# frozen_string_literal: true
-
-class CreateGroupRepositoryStorageMove < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- unless table_exists?(:group_repository_storage_moves)
- with_lock_retries do
- create_table :group_repository_storage_moves do |t|
- t.timestamps_with_timezone
- t.references :group, references: :namespace, column: :group_id, index: true, null: false
- t.integer :state, limit: 2, default: 1, null: false
- t.text :source_storage_name, null: false
- t.text :destination_storage_name, null: false
-
- t.foreign_key :namespaces, column: :group_id, on_delete: :cascade
- end
- end
- end
-
- add_text_limit(:group_repository_storage_moves, :source_storage_name, 255, constraint_name: 'group_repository_storage_moves_source_storage_name')
- add_text_limit(:group_repository_storage_moves, :destination_storage_name, 255, constraint_name: 'group_repository_storage_moves_destination_storage_name')
- end
-
- def down
- with_lock_retries do
- drop_table :group_repository_storage_moves
- end
- end
-end
diff --git a/db/migrate/20210117210226_add_has_external_issue_tracker_trigger.rb b/db/migrate/20210117210226_add_has_external_issue_tracker_trigger.rb
deleted file mode 100644
index 20fe0ee0fd1..00000000000
--- a/db/migrate/20210117210226_add_has_external_issue_tracker_trigger.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-# frozen_string_literal: true
-
-class AddHasExternalIssueTrackerTrigger < ActiveRecord::Migration[6.0]
- include Gitlab::Database::SchemaHelpers
-
- DOWNTIME = false
- FUNCTION_NAME = 'set_has_external_issue_tracker'
- TRIGGER_ON_INSERT_NAME = 'trigger_has_external_issue_tracker_on_insert'
- TRIGGER_ON_UPDATE_NAME = 'trigger_has_external_issue_tracker_on_update'
- TRIGGER_ON_DELETE_NAME = 'trigger_has_external_issue_tracker_on_delete'
-
- def up
- create_trigger_function(FUNCTION_NAME, replace: true) do
- <<~SQL
- UPDATE projects SET has_external_issue_tracker = (
- EXISTS
- (
- SELECT 1
- FROM services
- WHERE project_id = COALESCE(NEW.project_id, OLD.project_id)
- AND active = TRUE
- AND category = 'issue_tracker'
- )
- )
- WHERE projects.id = COALESCE(NEW.project_id, OLD.project_id);
- RETURN NULL;
- SQL
- end
-
- execute(<<~SQL)
- CREATE TRIGGER #{TRIGGER_ON_INSERT_NAME}
- AFTER INSERT ON services
- FOR EACH ROW
- WHEN (NEW.category = 'issue_tracker' AND NEW.active = TRUE AND NEW.project_id IS NOT NULL)
- EXECUTE FUNCTION #{FUNCTION_NAME}();
- SQL
-
- execute(<<~SQL)
- CREATE TRIGGER #{TRIGGER_ON_UPDATE_NAME}
- AFTER UPDATE ON services
- FOR EACH ROW
- WHEN (NEW.category = 'issue_tracker' AND OLD.active != NEW.active AND NEW.project_id IS NOT NULL)
- EXECUTE FUNCTION #{FUNCTION_NAME}();
- SQL
-
- execute(<<~SQL)
- CREATE TRIGGER #{TRIGGER_ON_DELETE_NAME}
- AFTER DELETE ON services
- FOR EACH ROW
- WHEN (OLD.category = 'issue_tracker' AND OLD.active = TRUE AND OLD.project_id IS NOT NULL)
- EXECUTE FUNCTION #{FUNCTION_NAME}();
- SQL
- end
-
- def down
- drop_trigger(:services, TRIGGER_ON_INSERT_NAME)
- drop_trigger(:services, TRIGGER_ON_UPDATE_NAME)
- drop_trigger(:services, TRIGGER_ON_DELETE_NAME)
- drop_function(FUNCTION_NAME)
- end
-end
diff --git a/db/migrate/20210118111307_add_enforce_ssh_key_expiration_to_application_settings.rb b/db/migrate/20210118111307_add_enforce_ssh_key_expiration_to_application_settings.rb
deleted file mode 100644
index fd1ed4f207b..00000000000
--- a/db/migrate/20210118111307_add_enforce_ssh_key_expiration_to_application_settings.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddEnforceSshKeyExpirationToApplicationSettings < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :application_settings, :enforce_ssh_key_expiration, :boolean, default: false, null: false
- end
-end
diff --git a/db/migrate/20210119153801_add_proxy_settings_to_jira_tracker_data.rb b/db/migrate/20210119153801_add_proxy_settings_to_jira_tracker_data.rb
deleted file mode 100644
index 237ea25554d..00000000000
--- a/db/migrate/20210119153801_add_proxy_settings_to_jira_tracker_data.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-class AddProxySettingsToJiraTrackerData < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :jira_tracker_data, :encrypted_proxy_address, :text
- add_column :jira_tracker_data, :encrypted_proxy_address_iv, :text
- add_column :jira_tracker_data, :encrypted_proxy_port, :text
- add_column :jira_tracker_data, :encrypted_proxy_port_iv, :text
- add_column :jira_tracker_data, :encrypted_proxy_username, :text
- add_column :jira_tracker_data, :encrypted_proxy_username_iv, :text
- add_column :jira_tracker_data, :encrypted_proxy_password, :text
- add_column :jira_tracker_data, :encrypted_proxy_password_iv, :text
- end
-end
diff --git a/db/migrate/20210119162812_add_text_limit_to_compliance_pipeline_configuration_full_path.rb b/db/migrate/20210119162812_add_text_limit_to_compliance_pipeline_configuration_full_path.rb
deleted file mode 100644
index 2958dc8d0ec..00000000000
--- a/db/migrate/20210119162812_add_text_limit_to_compliance_pipeline_configuration_full_path.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class AddTextLimitToCompliancePipelineConfigurationFullPath < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_text_limit :compliance_management_frameworks, :pipeline_configuration_full_path, 255
- end
-
- def down
- remove_text_limit :compliance_management_frameworks, :pipeline_configuration_full_path
- end
-end
diff --git a/db/migrate/20210120180956_extend_index_on_ci_builds_metadata.rb b/db/migrate/20210120180956_extend_index_on_ci_builds_metadata.rb
deleted file mode 100644
index 421a2fac1ae..00000000000
--- a/db/migrate/20210120180956_extend_index_on_ci_builds_metadata.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-# frozen_string_literal: true
-
-class ExtendIndexOnCiBuildsMetadata < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- OLD_INDEX = :index_ci_builds_metadata_on_build_id_and_interruptible
- NEW_INDEX = :index_ci_builds_metadata_on_build_id_and_id_and_interruptible
-
- TABLE = :ci_builds_metadata
-
- def up
- create_covering_index(TABLE, NEW_INDEX)
-
- remove_concurrent_index_by_name TABLE, OLD_INDEX
- end
-
- def down
- add_concurrent_index TABLE, :build_id, where: 'interruptible = true', name: OLD_INDEX
-
- remove_concurrent_index_by_name TABLE, NEW_INDEX
- end
-
- private
-
- def create_covering_index(table, name)
- return if index_exists_by_name?(table, name)
-
- disable_statement_timeout do
- execute <<~SQL
- CREATE INDEX CONCURRENTLY #{name}
- ON #{table} (build_id) INCLUDE (id)
- WHERE interruptible = true
- SQL
- end
- end
-end
diff --git a/db/migrate/20210120221743_delete_oauth_applications_tmp_index.rb b/db/migrate/20210120221743_delete_oauth_applications_tmp_index.rb
deleted file mode 100644
index d29e63ba5da..00000000000
--- a/db/migrate/20210120221743_delete_oauth_applications_tmp_index.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class DeleteOauthApplicationsTmpIndex < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- INDEX_NAME = 'tmp_index_oauth_applications_on_id_where_trusted'
-
- disable_ddl_transaction!
-
- def up
- remove_concurrent_index_by_name :oauth_applications, INDEX_NAME
- end
-
- def down
- add_concurrent_index :oauth_applications, :id, where: 'trusted = true', name: INDEX_NAME
- end
-end
diff --git a/db/migrate/20210121093618_remove_repository_read_only_to_groups.rb b/db/migrate/20210121093618_remove_repository_read_only_to_groups.rb
deleted file mode 100644
index 0b353ba5d88..00000000000
--- a/db/migrate/20210121093618_remove_repository_read_only_to_groups.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveRepositoryReadOnlyToGroups < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- if column_exists?(:namespaces, :repository_read_only)
- with_lock_retries do
- remove_column :namespaces, :repository_read_only # rubocop:disable Migration/RemoveColumn
- end
- end
- end
-
- def down
- unless column_exists?(:namespaces, :repository_read_only)
- with_lock_retries do
- add_column :namespaces, :repository_read_only, :boolean, default: false, null: false # rubocop:disable Migration/AddColumnsToWideTables
- end
- end
- end
-end
diff --git a/db/migrate/20210121100038_add_devops_adoption_group_segment.rb b/db/migrate/20210121100038_add_devops_adoption_group_segment.rb
deleted file mode 100644
index 619657e7f56..00000000000
--- a/db/migrate/20210121100038_add_devops_adoption_group_segment.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class AddDevopsAdoptionGroupSegment < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_column :analytics_devops_adoption_segments, :namespace_id, :integer, if_not_exists: true
- add_concurrent_index :analytics_devops_adoption_segments, :namespace_id, unique: true
- end
-
- def down
- remove_column :analytics_devops_adoption_segments, :namespace_id
- end
-end
diff --git a/db/migrate/20210121121102_optional_devops_adoption_segment_name.rb b/db/migrate/20210121121102_optional_devops_adoption_segment_name.rb
deleted file mode 100644
index d7fda093cfc..00000000000
--- a/db/migrate/20210121121102_optional_devops_adoption_segment_name.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-class OptionalDevopsAdoptionSegmentName < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- INDEX_NAME = 'index_analytics_devops_adoption_segments_on_name'
-
- def up
- change_column_null :analytics_devops_adoption_segments, :name, true
- remove_concurrent_index_by_name :analytics_devops_adoption_segments, INDEX_NAME
- end
-
- def down
- transaction do
- execute "DELETE FROM analytics_devops_adoption_segments WHERE name IS NULL"
- change_column_null :analytics_devops_adoption_segments, :name, false
- end
- add_concurrent_index :analytics_devops_adoption_segments, :name, unique: true, name: INDEX_NAME
- end
-end
diff --git a/db/migrate/20210122073805_add_repository_read_only_to_namespace_settings.rb b/db/migrate/20210122073805_add_repository_read_only_to_namespace_settings.rb
deleted file mode 100644
index f6479bdb3a4..00000000000
--- a/db/migrate/20210122073805_add_repository_read_only_to_namespace_settings.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddRepositoryReadOnlyToNamespaceSettings < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- add_column :namespace_settings, :repository_read_only, :boolean, default: false, null: false
- end
- end
-
- def down
- with_lock_retries do
- remove_column :namespace_settings, :repository_read_only
- end
- end
-end
diff --git a/db/migrate/20210122153259_add_state_to_merge_request_reviewers.rb b/db/migrate/20210122153259_add_state_to_merge_request_reviewers.rb
deleted file mode 100644
index dd0c98615f7..00000000000
--- a/db/migrate/20210122153259_add_state_to_merge_request_reviewers.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-class AddStateToMergeRequestReviewers < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- REVIEW_DEFAULT_STATE = 0
-
- def change
- add_column :merge_request_reviewers, :state, :smallint, default: REVIEW_DEFAULT_STATE, null: false
- end
-end
diff --git a/db/migrate/20210122155158_add_pipeline_step_to_bulk_imports_failures.rb b/db/migrate/20210122155158_add_pipeline_step_to_bulk_imports_failures.rb
deleted file mode 100644
index 749e0b16eaf..00000000000
--- a/db/migrate/20210122155158_add_pipeline_step_to_bulk_imports_failures.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-class AddPipelineStepToBulkImportsFailures < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- unless column_exists?(:bulk_import_failures, :pipeline_step, :text)
- with_lock_retries do
- add_column :bulk_import_failures, :pipeline_step, :text
- end
- end
-
- add_text_limit :bulk_import_failures, :pipeline_step, 255
- end
-
- def down
- with_lock_retries do
- remove_column :bulk_import_failures, :pipeline_step
- end
- end
-end
diff --git a/db/migrate/20210125105410_add_devops_adoption_segment_namespace_fk.rb b/db/migrate/20210125105410_add_devops_adoption_segment_namespace_fk.rb
deleted file mode 100644
index c7c18ae69d0..00000000000
--- a/db/migrate/20210125105410_add_devops_adoption_segment_namespace_fk.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class AddDevopsAdoptionSegmentNamespaceFk < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_foreign_key :analytics_devops_adoption_segments, :namespaces, column: :namespace_id
- end
-
- def down
- remove_foreign_key_if_exists :analytics_devops_adoption_segments, :namespaces, column: :namespace_id
- end
-end
diff --git a/db/migrate/20210126030249_add_security_dashboard_access_level_into_project_features.rb b/db/migrate/20210126030249_add_security_dashboard_access_level_into_project_features.rb
deleted file mode 100644
index cd325747282..00000000000
--- a/db/migrate/20210126030249_add_security_dashboard_access_level_into_project_features.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-class AddSecurityDashboardAccessLevelIntoProjectFeatures < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- PRIVATE_ACCESS_LEVEL = 10
-
- def up
- with_lock_retries do
- add_column :project_features, :security_and_compliance_access_level, :integer, default: PRIVATE_ACCESS_LEVEL, null: false
- end
- end
-
- def down
- with_lock_retries do
- remove_column :project_features, :security_and_compliance_access_level
- end
- end
-end
diff --git a/db/migrate/20210126091713_add_unique_index_services_project_id_and_type.rb b/db/migrate/20210126091713_add_unique_index_services_project_id_and_type.rb
deleted file mode 100644
index 272dca70a8b..00000000000
--- a/db/migrate/20210126091713_add_unique_index_services_project_id_and_type.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddUniqueIndexServicesProjectIdAndType < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- INDEX_NAME = 'index_services_on_project_id_and_type_unique'
-
- def up
- add_concurrent_index :services, [:project_id, :type], name: INDEX_NAME, unique: true
- end
-
- def down
- remove_concurrent_index_by_name :services, name: INDEX_NAME
- end
-end
diff --git a/db/migrate/20210126092102_remove_index_services_project_id_and_type.rb b/db/migrate/20210126092102_remove_index_services_project_id_and_type.rb
deleted file mode 100644
index 49780d03b7b..00000000000
--- a/db/migrate/20210126092102_remove_index_services_project_id_and_type.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveIndexServicesProjectIdAndType < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- INDEX_NAME = 'index_services_on_project_id_and_type'
-
- # Replaced by the index added in 20210126091713_add_unique_index_services_project_id_and_type.rb
- def up
- remove_concurrent_index_by_name :services, name: INDEX_NAME
- end
-
- def down
- add_concurrent_index :services, [:project_id, :type], name: INDEX_NAME
- end
-end
diff --git a/db/migrate/20210126233608_add_rubygems_max_file_size_to_plan_limits.rb b/db/migrate/20210126233608_add_rubygems_max_file_size_to_plan_limits.rb
deleted file mode 100644
index e0e7e773d17..00000000000
--- a/db/migrate/20210126233608_add_rubygems_max_file_size_to_plan_limits.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddRubygemsMaxFileSizeToPlanLimits < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :plan_limits, :rubygems_max_file_size, :bigint, default: 3.gigabytes, null: false
- end
-end
diff --git a/db/migrate/20210127052226_add_subgroup_events_to_web_hooks.rb b/db/migrate/20210127052226_add_subgroup_events_to_web_hooks.rb
deleted file mode 100644
index fe2b2ef412d..00000000000
--- a/db/migrate/20210127052226_add_subgroup_events_to_web_hooks.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddSubgroupEventsToWebHooks < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :web_hooks, :subgroup_events, :boolean, null: false, default: false
- end
-end
diff --git a/db/migrate/20210127143025_add_oldest_merge_requests_index.rb b/db/migrate/20210127143025_add_oldest_merge_requests_index.rb
deleted file mode 100644
index c25e12d89af..00000000000
--- a/db/migrate/20210127143025_add_oldest_merge_requests_index.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: true
-
-class AddOldestMergeRequestsIndex < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def up
- # replaced by db/migrate/20210201140434_add_oldest_merge_requests_index_again.rb
- end
-
- def down
- # replaced by db/migrate/20210201140434_add_oldest_merge_requests_index_again.rb
- end
-end
diff --git a/db/migrate/20210127152613_add_iterations_cadence_date_range_constraint.rb b/db/migrate/20210127152613_add_iterations_cadence_date_range_constraint.rb
deleted file mode 100644
index 95ecd167076..00000000000
--- a/db/migrate/20210127152613_add_iterations_cadence_date_range_constraint.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-class AddIterationsCadenceDateRangeConstraint < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- execute <<~SQL
- ALTER TABLE sprints
- ADD CONSTRAINT iteration_start_and_due_date_iterations_cadence_id_constraint
- EXCLUDE USING gist
- ( iterations_cadence_id WITH =,
- daterange(start_date, due_date, '[]') WITH &&
- )
- WHERE (group_id IS NOT NULL)
- SQL
- end
- end
-
- def down
- with_lock_retries do
- execute <<~SQL
- ALTER TABLE sprints
- DROP CONSTRAINT IF EXISTS iteration_start_and_due_date_iterations_cadence_id_constraint
- SQL
- end
- end
-end
diff --git a/db/migrate/20210127202613_remove_iteration_group_date_range_constraint.rb b/db/migrate/20210127202613_remove_iteration_group_date_range_constraint.rb
deleted file mode 100644
index e6c5eb1b411..00000000000
--- a/db/migrate/20210127202613_remove_iteration_group_date_range_constraint.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveIterationGroupDateRangeConstraint < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- execute <<~SQL
- ALTER TABLE sprints
- DROP CONSTRAINT IF EXISTS iteration_start_and_due_daterange_group_id_constraint
- SQL
- end
- end
-
- def down
- with_lock_retries do
- execute <<~SQL
- ALTER TABLE sprints
- ADD CONSTRAINT iteration_start_and_due_daterange_group_id_constraint
- EXCLUDE USING gist
- ( group_id WITH =,
- daterange(start_date, due_date, '[]') WITH &&
- )
- WHERE (group_id IS NOT NULL)
- SQL
- end
- end
-end
diff --git a/db/migrate/20210128044930_add_git_two_factor_session_expiry_to_application_settings.rb b/db/migrate/20210128044930_add_git_two_factor_session_expiry_to_application_settings.rb
deleted file mode 100644
index 77a1dd2131b..00000000000
--- a/db/migrate/20210128044930_add_git_two_factor_session_expiry_to_application_settings.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddGitTwoFactorSessionExpiryToApplicationSettings < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :application_settings, :git_two_factor_session_expiry, :integer, default: 15, null: false
- end
-end
diff --git a/db/migrate/20210128101707_add_prevent_merge_without_jira_issue_to_project_settings.rb b/db/migrate/20210128101707_add_prevent_merge_without_jira_issue_to_project_settings.rb
deleted file mode 100644
index 18f186294f1..00000000000
--- a/db/migrate/20210128101707_add_prevent_merge_without_jira_issue_to_project_settings.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class AddPreventMergeWithoutJiraIssueToProjectSettings < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
- DOWNTIME = false
-
- def up
- with_lock_retries do
- add_column :project_settings, :prevent_merge_without_jira_issue, :boolean, null: false, default: false
- end
- end
-
- def down
- with_lock_retries do
- remove_column :project_settings, :prevent_merge_without_jira_issue
- end
- end
-end
diff --git a/db/migrate/20210128114526_add_auto_delete_at_to_environments.rb b/db/migrate/20210128114526_add_auto_delete_at_to_environments.rb
deleted file mode 100644
index 8f89c2f2ad0..00000000000
--- a/db/migrate/20210128114526_add_auto_delete_at_to_environments.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddAutoDeleteAtToEnvironments < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- add_column :environments, :auto_delete_at, :datetime_with_timezone
- end
- end
-
- def down
- with_lock_retries do
- remove_column :environments, :auto_delete_at
- end
- end
-end
diff --git a/db/migrate/20210128140157_add_content_type_to_dependency_proxy_manifests.rb b/db/migrate/20210128140157_add_content_type_to_dependency_proxy_manifests.rb
deleted file mode 100644
index d016e3c20e2..00000000000
--- a/db/migrate/20210128140157_add_content_type_to_dependency_proxy_manifests.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-class AddContentTypeToDependencyProxyManifests < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- # rubocop:disable Migration/AddLimitToTextColumns
- # limit is added in 20210128140232_add_text_limit_to_dependency_proxy_manifests_content_type.rb
- def change
- add_column :dependency_proxy_manifests, :content_type, :text
- end
- # rubocop:enable Migration/AddLimitToTextColumns
-end
diff --git a/db/migrate/20210128140232_add_text_limit_to_dependency_proxy_manifests_content_type.rb b/db/migrate/20210128140232_add_text_limit_to_dependency_proxy_manifests_content_type.rb
deleted file mode 100644
index 035e4795ce0..00000000000
--- a/db/migrate/20210128140232_add_text_limit_to_dependency_proxy_manifests_content_type.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-class AddTextLimitToDependencyProxyManifestsContentType < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_text_limit :dependency_proxy_manifests, :content_type, 255
- end
-
- def down
- remove_text_limit :dependency_proxy_manifests, :content_type
- end
-end
diff --git a/db/migrate/20210128152830_create_ci_namespace_monthly_usage.rb b/db/migrate/20210128152830_create_ci_namespace_monthly_usage.rb
deleted file mode 100644
index d6ee057a56b..00000000000
--- a/db/migrate/20210128152830_create_ci_namespace_monthly_usage.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-class CreateCiNamespaceMonthlyUsage < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- with_lock_retries do
- create_table :ci_namespace_monthly_usages, if_not_exists: true do |t|
- t.references :namespace, index: false, null: false
- t.date :date, null: false
- t.integer :additional_amount_available, null: false, default: 0
- t.decimal :amount_used, null: false, default: 0.0, precision: 18, scale: 2
-
- t.index [:namespace_id, :date], unique: true
- end
- end
-
- add_check_constraint :ci_namespace_monthly_usages, "(date = date_trunc('month', date))", 'ci_namespace_monthly_usages_year_month_constraint'
- end
-
- def down
- with_lock_retries do
- drop_table :ci_namespace_monthly_usages
- end
- end
-end
diff --git a/db/migrate/20210128172149_create_background_migration_tracking_tables.rb b/db/migrate/20210128172149_create_background_migration_tracking_tables.rb
deleted file mode 100644
index 767bd8737a3..00000000000
--- a/db/migrate/20210128172149_create_background_migration_tracking_tables.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-# frozen_string_literal: true
-
-class CreateBackgroundMigrationTrackingTables < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- create_table_with_constraints :batched_background_migrations do |t|
- t.timestamps_with_timezone
- t.bigint :min_value, null: false, default: 1
- t.bigint :max_value, null: false
- t.integer :batch_size, null: false
- t.integer :sub_batch_size, null: false
- t.integer :interval, limit: 2, null: false
- t.integer :status, limit: 2, null: false, default: 0
- t.text :job_class_name, null: false
- t.text :batch_class_name, null: false,
- default: 'Gitlab::Database::BackgroundMigration::PrimaryKeyBatchingStrategy'
- t.text :table_name, null: false
- t.text :column_name, null: false
- t.jsonb :job_arguments, null: false, default: '[]'
-
- t.text_limit :job_class_name, 100
- t.text_limit :batch_class_name, 100
- t.text_limit :table_name, 63
- t.text_limit :column_name, 63
-
- t.check_constraint :check_positive_min_value, 'min_value > 0'
- t.check_constraint :check_max_value_in_range, 'max_value >= min_value'
-
- t.check_constraint :check_positive_sub_batch_size, 'sub_batch_size > 0'
- t.check_constraint :check_batch_size_in_range, 'batch_size >= sub_batch_size'
-
- t.index %i[job_class_name table_name column_name], name: :index_batched_migrations_on_job_table_and_column_name
- end
-
- create_table :batched_background_migration_jobs do |t|
- t.timestamps_with_timezone
- t.datetime_with_timezone :started_at
- t.datetime_with_timezone :finished_at
- t.references :batched_background_migration, null: false, index: false, foreign_key: { on_delete: :cascade }
- t.bigint :min_value, null: false
- t.bigint :max_value, null: false
- t.integer :batch_size, null: false
- t.integer :sub_batch_size, null: false
- t.integer :status, limit: 2, null: false, default: 0
- t.integer :attempts, limit: 2, null: false, default: 0
-
- t.index [:batched_background_migration_id, :id], name: :index_batched_jobs_by_batched_migration_id_and_id
- end
- end
-
- def down
- drop_table :batched_background_migration_jobs
-
- drop_table :batched_background_migrations
- end
-end
diff --git a/db/migrate/20210129225244_add_index_to_oncall_shfts_on_starts_at_and_ends_at.rb b/db/migrate/20210129225244_add_index_to_oncall_shfts_on_starts_at_and_ends_at.rb
deleted file mode 100644
index 8285aceb24a..00000000000
--- a/db/migrate/20210129225244_add_index_to_oncall_shfts_on_starts_at_and_ends_at.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-class AddIndexToOncallShftsOnStartsAtAndEndsAt < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- NEW_NAME = 'index_oncall_shifts_on_rotation_id_and_starts_at_and_ends_at'
- OLD_NAME = 'index_incident_management_oncall_shifts_on_rotation_id'
-
- def up
- add_concurrent_index :incident_management_oncall_shifts, %i[rotation_id starts_at ends_at], name: NEW_NAME
-
- remove_concurrent_index_by_name :incident_management_oncall_shifts, OLD_NAME
- end
-
- def down
- add_concurrent_index :incident_management_oncall_shifts, :rotation_id, name: OLD_NAME
-
- remove_concurrent_index_by_name :incident_management_oncall_shifts, NEW_NAME
- end
-end
diff --git a/db/migrate/20210201034649_add_active_periods_to_on_call_rotations.rb b/db/migrate/20210201034649_add_active_periods_to_on_call_rotations.rb
deleted file mode 100644
index 714187f60e0..00000000000
--- a/db/migrate/20210201034649_add_active_periods_to_on_call_rotations.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-# frozen_string_literal: true
-
-class AddActivePeriodsToOnCallRotations < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :incident_management_oncall_rotations, :active_period_start, :time, null: true
- add_column :incident_management_oncall_rotations, :active_period_end, :time, null: true
- end
-end
diff --git a/db/migrate/20210201140434_add_oldest_merge_requests_index_again.rb b/db/migrate/20210201140434_add_oldest_merge_requests_index_again.rb
deleted file mode 100644
index a3fed9e576a..00000000000
--- a/db/migrate/20210201140434_add_oldest_merge_requests_index_again.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-# frozen_string_literal: true
-
-class AddOldestMergeRequestsIndexAgain < ActiveRecord::Migration[6.0]
- include Gitlab::Database::SchemaHelpers
- include Gitlab::Database::MigrationHelpers
-
- disable_ddl_transaction!
-
- DOWNTIME = false
-
- INDEX = 'index_on_merge_requests_for_latest_diffs'
-
- def up
- execute "DROP INDEX CONCURRENTLY #{INDEX}" if invalid_index?
-
- return if index_exists_by_name?('merge_requests', INDEX)
-
- begin
- disable_statement_timeout do
- execute "CREATE INDEX CONCURRENTLY #{INDEX} ON merge_requests " \
- 'USING btree (target_project_id) INCLUDE (id, latest_merge_request_diff_id)'
- end
- rescue ActiveRecord::StatementInvalid => ex
- # Due to https://github.com/lfittl/pg_query/issues/184, if the CREATE
- # INDEX statement fails, we trigger a separate error due to the Gem not
- # supporting the INCLUDE syntax.
- #
- # To work around this, we raise a custom error instead, as these won't
- # have a query context injected.
- raise "The index #{INDEX} couldn't be added: #{ex.message}"
- end
-
- create_comment(
- 'INDEX',
- INDEX,
- 'Index used to efficiently obtain the oldest merge request for a commit SHA'
- )
- end
-
- def down
- return unless index_exists_by_name?('merge_requests', INDEX)
-
- disable_statement_timeout do
- execute "DROP INDEX CONCURRENTLY #{INDEX}"
- end
- end
-
- def invalid_index?
- result = execute(<<~SQL)
- SELECT pg_class.relname
- FROM pg_class, pg_index
- WHERE pg_index.indisvalid = false
- AND pg_index.indexrelid = pg_class.oid
- AND pg_class.relname = '#{INDEX}';
- SQL
-
- result.values.any?
- end
-end
diff --git a/db/migrate/20210203002331_drop_backup_label_index.rb b/db/migrate/20210203002331_drop_backup_label_index.rb
deleted file mode 100644
index 430d2d0fb79..00000000000
--- a/db/migrate/20210203002331_drop_backup_label_index.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class DropBackupLabelIndex < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- INDEX_NAME = 'backup_labels_project_id_title_idx'
-
- def up
- remove_concurrent_index_by_name(:backup_labels, name: INDEX_NAME)
- end
-
- def down
- add_concurrent_index :backup_labels, [:project_id, :title], name: INDEX_NAME, unique: true, where: 'group_id = NULL::integer'
- end
-end
diff --git a/db/migrate/20210203092540_remove_has_external_wiki_constraint.rb b/db/migrate/20210203092540_remove_has_external_wiki_constraint.rb
deleted file mode 100644
index 80b0cc11685..00000000000
--- a/db/migrate/20210203092540_remove_has_external_wiki_constraint.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveHasExternalWikiConstraint < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- # This reverts the following migration: add_not_null_constraint :projects, :has_external_wiki, validate: false
- if check_not_null_constraint_exists?(:projects, :has_external_wiki)
- remove_not_null_constraint :projects, :has_external_wiki
- end
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/migrate/20210203092549_restore_has_external_wiki_default_value.rb b/db/migrate/20210203092549_restore_has_external_wiki_default_value.rb
deleted file mode 100644
index 37111b370a5..00000000000
--- a/db/migrate/20210203092549_restore_has_external_wiki_default_value.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# frozen_string_literal: true
-
-class RestoreHasExternalWikiDefaultValue < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- class TmpProject < ActiveRecord::Base
- self.table_name = 'projects'
- end
-
- # This reverts the following migration: change_column_default(:projects, :has_external_wiki, from: nil, to: false)
- # We only change the column when the current default value is false
- def up
- # Find out the current default value
- column = TmpProject.columns.find { |c| c.name == 'has_external_wiki' }
- return unless column
-
- if column.default == 'false'
- with_lock_retries do
- change_column_default(:projects, :has_external_wiki, from: false, to: nil)
- end
- end
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/migrate/20210203221631_create_packages_rubygems_metadata.rb b/db/migrate/20210203221631_create_packages_rubygems_metadata.rb
deleted file mode 100644
index f4ad5abf7e5..00000000000
--- a/db/migrate/20210203221631_create_packages_rubygems_metadata.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-# frozen_string_literal: true
-
-class CreatePackagesRubygemsMetadata < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- create_table_with_constraints :packages_rubygems_metadata, id: false do |t|
- t.timestamps_with_timezone
- t.references :package, primary_key: true, index: false, default: nil, null: false, foreign_key: { to_table: :packages_packages, on_delete: :cascade }, type: :bigint
- t.text :authors
- t.text :files
- t.text :summary
-
- t.text :description
- t.text :email
- t.text :homepage
- t.text :licenses
- t.text :metadata
-
- t.text :author
- t.text :bindir
- t.text :cert_chain
- t.text :executables
- t.text :extensions
- t.text :extra_rdoc_files
- t.text :platform
- t.text :post_install_message
- t.text :rdoc_options
- t.text :require_paths
- t.text :required_ruby_version
- t.text :required_rubygems_version
- t.text :requirements
- t.text :rubygems_version
- t.text :signing_key
-
- t.text_limit :authors, 255
- t.text_limit :files, 255
- t.text_limit :summary, 1024
-
- t.text_limit :description, 1024
- t.text_limit :email, 255
- t.text_limit :homepage, 255
- t.text_limit :licenses, 255
- t.text_limit :metadata, 255
-
- t.text_limit :author, 255
- t.text_limit :bindir, 255
- t.text_limit :cert_chain, 255
- t.text_limit :executables, 255
- t.text_limit :extensions, 255
- t.text_limit :extra_rdoc_files, 255
- t.text_limit :platform, 255
- t.text_limit :post_install_message, 255
- t.text_limit :rdoc_options, 255
- t.text_limit :require_paths, 255
- t.text_limit :required_ruby_version, 255
- t.text_limit :required_rubygems_version, 255
- t.text_limit :requirements, 255
- t.text_limit :rubygems_version, 255
- t.text_limit :signing_key, 255
- end
- end
-
- def down
- drop_table :packages_rubygems_metadata
- end
-end
diff --git a/db/migrate/20210203222620_add_expired_index_to_composer_cache_files.rb b/db/migrate/20210203222620_add_expired_index_to_composer_cache_files.rb
deleted file mode 100644
index 9c6a27812a5..00000000000
--- a/db/migrate/20210203222620_add_expired_index_to_composer_cache_files.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddExpiredIndexToComposerCacheFiles < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- INDEX_NAME = 'composer_cache_files_index_on_deleted_at'
-
- def up
- add_concurrent_index :packages_composer_cache_files, [:delete_at, :id], name: INDEX_NAME
- end
-
- def down
- remove_concurrent_index_by_name :packages_composer_cache_files, INDEX_NAME
- end
-end
diff --git a/db/migrate/20210203223551_add_orphan_index_to_composer_cache_files.rb b/db/migrate/20210203223551_add_orphan_index_to_composer_cache_files.rb
deleted file mode 100644
index e2853977e5f..00000000000
--- a/db/migrate/20210203223551_add_orphan_index_to_composer_cache_files.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddOrphanIndexToComposerCacheFiles < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- INDEX_NAME = 'index_composer_cache_files_where_namespace_id_is_null'
-
- def up
- add_concurrent_index :packages_composer_cache_files, :id, name: INDEX_NAME, where: 'namespace_id IS NULL'
- end
-
- def down
- remove_concurrent_index_by_name :packages_composer_cache_files, INDEX_NAME
- end
-end
diff --git a/db/migrate/20210204152257_add_status_to_packages_packages.rb b/db/migrate/20210204152257_add_status_to_packages_packages.rb
deleted file mode 100644
index 4fd441048c6..00000000000
--- a/db/migrate/20210204152257_add_status_to_packages_packages.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddStatusToPackagesPackages < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :packages_packages, :status, :smallint, default: 0, null: false
- end
-end
diff --git a/db/migrate/20210204212850_add_group_id_to_ci_daily_build_group_report_results.rb b/db/migrate/20210204212850_add_group_id_to_ci_daily_build_group_report_results.rb
deleted file mode 100644
index ba0464f5ad6..00000000000
--- a/db/migrate/20210204212850_add_group_id_to_ci_daily_build_group_report_results.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddGroupIdToCiDailyBuildGroupReportResults < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column(:ci_daily_build_group_report_results, :group_id, :bigint)
- end
-end
diff --git a/db/migrate/20210205084357_create_ci_project_monthly_usage.rb b/db/migrate/20210205084357_create_ci_project_monthly_usage.rb
deleted file mode 100644
index c91bfa5ee1c..00000000000
--- a/db/migrate/20210205084357_create_ci_project_monthly_usage.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-class CreateCiProjectMonthlyUsage < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- with_lock_retries do
- create_table :ci_project_monthly_usages, if_not_exists: true do |t|
- t.references :project, foreign_key: { on_delete: :cascade }, index: false, null: false
- t.date :date, null: false
- t.decimal :amount_used, null: false, default: 0.0, precision: 18, scale: 2
-
- t.index [:project_id, :date], unique: true
- end
- end
-
- add_check_constraint :ci_project_monthly_usages, "(date = date_trunc('month', date))", 'ci_project_monthly_usages_year_month_constraint'
- end
-
- def down
- with_lock_retries do
- drop_table :ci_project_monthly_usages
- end
- end
-end
diff --git a/db/migrate/20210205134213_add_creator_id_to_custom_emoji.rb b/db/migrate/20210205134213_add_creator_id_to_custom_emoji.rb
deleted file mode 100644
index c01335767a8..00000000000
--- a/db/migrate/20210205134213_add_creator_id_to_custom_emoji.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-class AddCreatorIdToCustomEmoji < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def up
- # Custom Emoji is at the moment behind a default-disabled feature flag. It
- # will be unlikely there are any records in this table, but to able to
- # ensure a not-null constraint delete any existing rows.
- # Roll-out issue: https://gitlab.com/gitlab-org/gitlab/-/issues/231317
- execute 'DELETE FROM custom_emoji'
-
- add_reference :custom_emoji, # rubocop:disable Migration/AddReference
- :creator,
- index: true,
- null: false, # rubocop:disable Rails/NotNullColumn
- foreign_key: false # FK is added in 20210219100137
- end
-
- def down
- remove_reference :custom_emoji, :creator
- end
-end
diff --git a/db/migrate/20210205143926_remove_namespace_id_foreign_key_on_namespace_onboarding_actions.rb b/db/migrate/20210205143926_remove_namespace_id_foreign_key_on_namespace_onboarding_actions.rb
deleted file mode 100644
index 6fe66430dd0..00000000000
--- a/db/migrate/20210205143926_remove_namespace_id_foreign_key_on_namespace_onboarding_actions.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveNamespaceIdForeignKeyOnNamespaceOnboardingActions < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- remove_foreign_key :namespace_onboarding_actions, :namespaces
- end
- end
-
- def down
- with_lock_retries do
- add_foreign_key :namespace_onboarding_actions, :namespaces, on_delete: :cascade
- end
- end
-end
diff --git a/db/migrate/20210205213915_remove_foreign_keys_from_alerts_service_data.rb b/db/migrate/20210205213915_remove_foreign_keys_from_alerts_service_data.rb
deleted file mode 100644
index 1d539f783b4..00000000000
--- a/db/migrate/20210205213915_remove_foreign_keys_from_alerts_service_data.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveForeignKeysFromAlertsServiceData < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- remove_foreign_key_if_exists :alerts_service_data, column: :service_id
- end
- end
-
- def down
- with_lock_retries do
- add_foreign_key :alerts_service_data, :services, column: :service_id, on_delete: :cascade
- end
- end
-end
diff --git a/db/migrate/20210208103243_add_issue_created_at_to_onboarding_progress.rb b/db/migrate/20210208103243_add_issue_created_at_to_onboarding_progress.rb
deleted file mode 100644
index e8318ecd929..00000000000
--- a/db/migrate/20210208103243_add_issue_created_at_to_onboarding_progress.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddIssueCreatedAtToOnboardingProgress < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :onboarding_progresses, :issue_created_at, :datetime_with_timezone
- end
-end
diff --git a/db/migrate/20210208125050_add_status_expires_at_to_user_statuses.rb b/db/migrate/20210208125050_add_status_expires_at_to_user_statuses.rb
deleted file mode 100644
index 3ec1f6014a8..00000000000
--- a/db/migrate/20210208125050_add_status_expires_at_to_user_statuses.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddStatusExpiresAtToUserStatuses < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- add_column(:user_statuses, :clear_status_at, :datetime_with_timezone, null: true)
- end
- end
-
- def down
- with_lock_retries do
- remove_column(:user_statuses, :clear_status_at)
- end
- end
-end
diff --git a/db/migrate/20210208125248_add_index_on_user_statuses_status_expires_at.rb b/db/migrate/20210208125248_add_index_on_user_statuses_status_expires_at.rb
deleted file mode 100644
index 98f3449c2e8..00000000000
--- a/db/migrate/20210208125248_add_index_on_user_statuses_status_expires_at.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class AddIndexOnUserStatusesStatusExpiresAt < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- INDEX_NAME = 'index_user_statuses_on_clear_status_at_not_null'
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index(:user_statuses, :clear_status_at, name: INDEX_NAME, where: 'clear_status_at IS NOT NULL')
- end
-
- def down
- remove_concurrent_index_by_name(:user_statuses, INDEX_NAME)
- end
-end
diff --git a/db/migrate/20210208144134_add_index_group_id_to_ci_daily_build_group_report_results.rb b/db/migrate/20210208144134_add_index_group_id_to_ci_daily_build_group_report_results.rb
deleted file mode 100644
index 422d8174043..00000000000
--- a/db/migrate/20210208144134_add_index_group_id_to_ci_daily_build_group_report_results.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-class AddIndexGroupIdToCiDailyBuildGroupReportResults < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- INDEX_NAME = 'index_ci_daily_build_group_report_results_on_group_id'
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index(:ci_daily_build_group_report_results, :group_id, name: INDEX_NAME)
- add_concurrent_foreign_key(:ci_daily_build_group_report_results, :namespaces, column: :group_id)
- end
-
- def down
- remove_foreign_key_if_exists(:ci_daily_build_group_report_results, column: :group_id)
- remove_concurrent_index_by_name(:ci_daily_build_group_report_results, INDEX_NAME)
- end
-end
diff --git a/db/migrate/20210208161207_add_notes_create_limit_to_application_settings.rb b/db/migrate/20210208161207_add_notes_create_limit_to_application_settings.rb
deleted file mode 100644
index 4468da77e6c..00000000000
--- a/db/migrate/20210208161207_add_notes_create_limit_to_application_settings.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddNotesCreateLimitToApplicationSettings < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :application_settings, :notes_create_limit, :integer, default: 300, null: false
- end
-end
diff --git a/db/migrate/20210208200914_add_ends_at_to_oncall_rotations.rb b/db/migrate/20210208200914_add_ends_at_to_oncall_rotations.rb
deleted file mode 100644
index 5cd179c9a80..00000000000
--- a/db/migrate/20210208200914_add_ends_at_to_oncall_rotations.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddEndsAtToOncallRotations < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :incident_management_oncall_rotations, :ends_at, :datetime_with_timezone
- end
-end
diff --git a/db/migrate/20210209110019_create_external_approval_rules.rb b/db/migrate/20210209110019_create_external_approval_rules.rb
deleted file mode 100644
index 5d6780ec412..00000000000
--- a/db/migrate/20210209110019_create_external_approval_rules.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-
-class CreateExternalApprovalRules < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
- disable_ddl_transaction!
-
- DOWNTIME = false
-
- def up
- create_table_with_constraints :external_approval_rules, if_not_exists: true do |t|
- t.references :project, foreign_key: { on_delete: :cascade }, null: false, index: false
- t.timestamps_with_timezone
- t.text :external_url, null: false
- t.text_limit :external_url, 255
- t.text :name, null: false
- t.text_limit :name, 255
-
- t.index([:project_id, :name],
- unique: true,
- name: 'idx_on_external_approval_rules_project_id_name')
- t.index([:project_id, :external_url],
- unique: true,
- name: 'idx_on_external_approval_rules_project_id_external_url')
- end
-
- create_table :external_approval_rules_protected_branches do |t|
- t.bigint :external_approval_rule_id, null: false, index: { name: 'idx_eaprpb_external_approval_rule_id' }
- t.bigint :protected_branch_id, null: false
- t.index([:protected_branch_id, :external_approval_rule_id],
- unique: true,
- name: 'idx_protected_branch_id_external_approval_rule_id')
- end
- end
-
- def down
- with_lock_retries do
- drop_table :external_approval_rules_protected_branches, force: :cascade, if_exists: true
- end
-
- with_lock_retries do
- drop_table :external_approval_rules, force: :cascade, if_exists: true
- end
- end
-end
diff --git a/db/migrate/20210209160510_create_security_orchestration_policy_configurations.rb b/db/migrate/20210209160510_create_security_orchestration_policy_configurations.rb
deleted file mode 100644
index 896593c803f..00000000000
--- a/db/migrate/20210209160510_create_security_orchestration_policy_configurations.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-class CreateSecurityOrchestrationPolicyConfigurations < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- INDEX_PREFIX = 'index_sop_configs_'
-
- def up
- table_comment = { owner: 'group::container security', description: 'Configuration used to store relationship between project and security policy repository' }
-
- create_table_with_constraints :security_orchestration_policy_configurations, comment: table_comment.to_json do |t|
- t.references :project, null: false, foreign_key: { to_table: :projects, on_delete: :cascade }, index: { name: INDEX_PREFIX + 'on_project_id', unique: true }
- t.references :security_policy_management_project, null: false, foreign_key: { to_table: :projects, on_delete: :restrict }, index: { name: INDEX_PREFIX + 'on_security_policy_management_project_id', unique: true }
-
- t.timestamps_with_timezone
- end
- end
-
- def down
- with_lock_retries do
- drop_table :security_orchestration_policy_configurations, force: :cascade
- end
- end
-end
diff --git a/db/migrate/20210209171525_add_status_index_to_packages_packages.rb b/db/migrate/20210209171525_add_status_index_to_packages_packages.rb
deleted file mode 100644
index cb956165d6e..00000000000
--- a/db/migrate/20210209171525_add_status_index_to_packages_packages.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddStatusIndexToPackagesPackages < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- INDEX_NAME = 'index_packages_packages_on_project_id_and_status'
-
- def up
- add_concurrent_index :packages_packages, [:project_id, :status], name: INDEX_NAME
- end
-
- def down
- remove_concurrent_index_by_name :packages_packages, name: INDEX_NAME
- end
-end
diff --git a/db/migrate/20210209232508_add_markdown_surround_selection_to_user_preferences.rb b/db/migrate/20210209232508_add_markdown_surround_selection_to_user_preferences.rb
deleted file mode 100644
index c4063a55d18..00000000000
--- a/db/migrate/20210209232508_add_markdown_surround_selection_to_user_preferences.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-class AddMarkdownSurroundSelectionToUserPreferences < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- with_lock_retries do
- add_column :user_preferences, :markdown_surround_selection, :boolean, default: true, null: false
- end
- end
-
- def down
- with_lock_retries do
- remove_column :user_preferences, :markdown_surround_selection, :boolean
- end
- end
-end
diff --git a/db/migrate/20210210210232_add_notes_create_limit_allowlist_to_application_settings.rb b/db/migrate/20210210210232_add_notes_create_limit_allowlist_to_application_settings.rb
deleted file mode 100644
index 56feed3688c..00000000000
--- a/db/migrate/20210210210232_add_notes_create_limit_allowlist_to_application_settings.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddNotesCreateLimitAllowlistToApplicationSettings < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :application_settings, :notes_create_limit_allowlist, :text, array: true, default: [], null: false
- end
-end
diff --git a/db/migrate/20210211195543_add_created_by_user_for_cluster_agent_token.rb b/db/migrate/20210211195543_add_created_by_user_for_cluster_agent_token.rb
deleted file mode 100644
index 94dc8192037..00000000000
--- a/db/migrate/20210211195543_add_created_by_user_for_cluster_agent_token.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# frozen_string_literal: true
-
-class AddCreatedByUserForClusterAgentToken < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- INDEX_NAME = 'index_cluster_agent_tokens_on_created_by_user_id'
-
- disable_ddl_transaction!
-
- def up
- unless column_exists?(:cluster_agent_tokens, :created_by_user_id)
- add_column :cluster_agent_tokens, :created_by_user_id, :bigint
- end
-
- add_concurrent_index :cluster_agent_tokens, :created_by_user_id, name: INDEX_NAME
- add_concurrent_foreign_key :cluster_agent_tokens, :users, column: :created_by_user_id, on_delete: :nullify
- end
-
- def down
- with_lock_retries do
- remove_foreign_key_if_exists :cluster_agent_tokens, :users, column: :created_by_user_id
- end
-
- remove_concurrent_index_by_name :cluster_agent_tokens, INDEX_NAME
- remove_column :cluster_agent_tokens, :created_by_user_id
- end
-end
diff --git a/db/migrate/20210212153934_make_the_geo_oauth_application_trusted_by_default.rb b/db/migrate/20210212153934_make_the_geo_oauth_application_trusted_by_default.rb
deleted file mode 100644
index ab0343887e4..00000000000
--- a/db/migrate/20210212153934_make_the_geo_oauth_application_trusted_by_default.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-class MakeTheGeoOauthApplicationTrustedByDefault < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def up
- execute(<<-SQL.squish)
- UPDATE oauth_applications
- SET confidential = true, trusted = true
- WHERE id IN (SELECT oauth_application_id FROM geo_nodes);
- SQL
- end
-
- def down
- # We won't be able to tell which trusted applications weren't
- # confidential before the migration and setting all trusted
- # applications are not confidential would introduce security
- # issues.
- end
-end
diff --git a/db/migrate/20210212163231_add_merge_when_pipeline_succeeds_to_notification_settings.rb b/db/migrate/20210212163231_add_merge_when_pipeline_succeeds_to_notification_settings.rb
deleted file mode 100644
index 08d0a99436e..00000000000
--- a/db/migrate/20210212163231_add_merge_when_pipeline_succeeds_to_notification_settings.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# 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 AddMergeWhenPipelineSucceedsToNotificationSettings < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :notification_settings, :merge_when_pipeline_succeeds, :boolean, default: false, null: false
- end
-end
diff --git a/db/migrate/20210214201118_add_delayed_project_removal_to_namespace_settings.rb b/db/migrate/20210214201118_add_delayed_project_removal_to_namespace_settings.rb
deleted file mode 100644
index 1c6e0b0c27c..00000000000
--- a/db/migrate/20210214201118_add_delayed_project_removal_to_namespace_settings.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddDelayedProjectRemovalToNamespaceSettings < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :namespace_settings, :delayed_project_removal, :boolean, default: false, null: false
- end
-end
diff --git a/db/migrate/20210214205155_add_index_to_namespaces_delayed_project_removal.rb b/db/migrate/20210214205155_add_index_to_namespaces_delayed_project_removal.rb
deleted file mode 100644
index 8d09a5c9269..00000000000
--- a/db/migrate/20210214205155_add_index_to_namespaces_delayed_project_removal.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class AddIndexToNamespacesDelayedProjectRemoval < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- INDEX_NAME = 'tmp_idx_on_namespaces_delayed_project_removal'
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :namespaces, :id, name: INDEX_NAME, where: 'delayed_project_removal = TRUE'
- end
-
- def down
- remove_concurrent_index_by_name :namespaces, INDEX_NAME
- end
-end
diff --git a/db/migrate/20210215172449_remove_artifact_expiry_temp_index.rb b/db/migrate/20210215172449_remove_artifact_expiry_temp_index.rb
deleted file mode 100644
index 1e6619731a2..00000000000
--- a/db/migrate/20210215172449_remove_artifact_expiry_temp_index.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveArtifactExpiryTempIndex < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- disable_ddl_transaction!
-
- INDEX_NAME = 'expired_artifacts_temp_index'
- INDEX_CONDITION = "expire_at IS NULL AND date(created_at AT TIME ZONE 'UTC') < '2020-06-22'::date"
-
- def up
- remove_concurrent_index_by_name :ci_job_artifacts, INDEX_NAME
- end
-
- def down
- add_concurrent_index(:ci_job_artifacts, %i(id created_at), where: INDEX_CONDITION, name: INDEX_NAME)
- end
-end
diff --git a/db/migrate/20210216122140_add_in_product_marketing_emails_enabled_setting.rb b/db/migrate/20210216122140_add_in_product_marketing_emails_enabled_setting.rb
deleted file mode 100644
index 5813b1b5f33..00000000000
--- a/db/migrate/20210216122140_add_in_product_marketing_emails_enabled_setting.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddInProductMarketingEmailsEnabledSetting < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :application_settings, :in_product_marketing_emails_enabled, :boolean, null: false, default: true
- end
-end
diff --git a/db/migrate/20210216135504_add_created_by_to_cluster_agent.rb b/db/migrate/20210216135504_add_created_by_to_cluster_agent.rb
deleted file mode 100644
index fd679a1c525..00000000000
--- a/db/migrate/20210216135504_add_created_by_to_cluster_agent.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# frozen_string_literal: true
-
-class AddCreatedByToClusterAgent < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- INDEX_NAME = 'index_cluster_agents_on_created_by_user_id'
-
- disable_ddl_transaction!
-
- def up
- unless column_exists?(:cluster_agents, :created_by_user_id)
- with_lock_retries do
- add_column :cluster_agents, :created_by_user_id, :bigint
- end
- end
-
- add_concurrent_index :cluster_agents, :created_by_user_id, name: INDEX_NAME
- add_concurrent_foreign_key :cluster_agents, :users, column: :created_by_user_id, on_delete: :nullify
- end
-
- def down
- with_lock_retries do
- remove_column :cluster_agents, :created_by_user_id
- end
- end
-end
diff --git a/db/migrate/20210216193620_add_description_to_cluster_token.rb b/db/migrate/20210216193620_add_description_to_cluster_token.rb
deleted file mode 100644
index 67f7c6bd522..00000000000
--- a/db/migrate/20210216193620_add_description_to_cluster_token.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-class AddDescriptionToClusterToken < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- unless column_exists?(:cluster_agent_tokens, :description)
- add_column :cluster_agent_tokens, :description, :text
- end
-
- add_text_limit :cluster_agent_tokens, :description, 1024
- end
-
- def down
- remove_column :cluster_agent_tokens, :description
- end
-end
diff --git a/db/migrate/20210216223335_remove_index_on_issues_where_service_desk_reply_to_is_not_null.rb b/db/migrate/20210216223335_remove_index_on_issues_where_service_desk_reply_to_is_not_null.rb
deleted file mode 100644
index 5224b6f7031..00000000000
--- a/db/migrate/20210216223335_remove_index_on_issues_where_service_desk_reply_to_is_not_null.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveIndexOnIssuesWhereServiceDeskReplyToIsNotNull < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- INDEX_TABLE = :issues
- INDEX_NAME = 'idx_on_issues_where_service_desk_reply_to_is_not_null'
-
- def up
- Gitlab::BackgroundMigration.steal('PopulateIssueEmailParticipants')
- remove_concurrent_index_by_name INDEX_TABLE, INDEX_NAME
- end
-
- def down
- add_concurrent_index(INDEX_TABLE, [:id], name: INDEX_NAME, where: 'service_desk_reply_to IS NOT NULL')
- end
-end
diff --git a/db/migrate/20210217101901_create_epic_list_user_preferences.rb b/db/migrate/20210217101901_create_epic_list_user_preferences.rb
deleted file mode 100644
index 5aacea1938d..00000000000
--- a/db/migrate/20210217101901_create_epic_list_user_preferences.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-class CreateEpicListUserPreferences < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def up
- create_table :boards_epic_list_user_preferences do |t|
- t.bigint :user_id, null: false
- t.bigint :epic_list_id, index: true, null: false
- t.timestamps_with_timezone null: false
- t.boolean :collapsed, null: false, default: false
- end
-
- add_index :boards_epic_list_user_preferences, [:user_id, :epic_list_id], unique: true, name: 'index_epic_board_list_preferences_on_user_and_list'
- end
-
- def down
- drop_table :boards_epic_list_user_preferences
- end
-end
diff --git a/db/migrate/20210218040814_add_environment_scope_to_group_variables.rb b/db/migrate/20210218040814_add_environment_scope_to_group_variables.rb
deleted file mode 100644
index 5cc41f570aa..00000000000
--- a/db/migrate/20210218040814_add_environment_scope_to_group_variables.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-# frozen_string_literal: true
-
-class AddEnvironmentScopeToGroupVariables < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- OLD_INDEX = 'index_ci_group_variables_on_group_id_and_key'
- NEW_INDEX = 'index_ci_group_variables_on_group_id_and_key_and_environment'
-
- disable_ddl_transaction!
-
- def up
- unless column_exists?(:ci_group_variables, :environment_scope)
- # rubocop:disable Migration/AddLimitToTextColumns
- # Added in 20210305013509_add_text_limit_to_group_ci_variables_environment_scope
- add_column :ci_group_variables, :environment_scope, :text, null: false, default: '*'
- # rubocop:enable Migration/AddLimitToTextColumns
- end
-
- add_concurrent_index :ci_group_variables, [:group_id, :key, :environment_scope], unique: true, name: NEW_INDEX
- remove_concurrent_index_by_name :ci_group_variables, OLD_INDEX
- end
-
- def down
- remove_duplicates!
-
- add_concurrent_index :ci_group_variables, [:group_id, :key], unique: true, name: OLD_INDEX
- remove_concurrent_index_by_name :ci_group_variables, NEW_INDEX
-
- remove_column :ci_group_variables, :environment_scope
- end
-
- private
-
- def remove_duplicates!
- execute <<-SQL
- DELETE FROM ci_group_variables
- WHERE id NOT IN (
- SELECT MIN(id)
- FROM ci_group_variables
- GROUP BY group_id, key
- )
- SQL
- end
-end
diff --git a/db/migrate/20210218142626_change_finding_fingerprint_enum.rb b/db/migrate/20210218142626_change_finding_fingerprint_enum.rb
deleted file mode 100644
index 615509e0c04..00000000000
--- a/db/migrate/20210218142626_change_finding_fingerprint_enum.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-class ChangeFindingFingerprintEnum < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- change_column :vulnerability_finding_fingerprints, :algorithm_type, :integer, limit: 2
- end
-
- def down
- change_column :vulnerability_finding_fingerprints, :algorithm_type, :integer
- end
-end
diff --git a/db/migrate/20210218144056_add_sprints_start_date_not_null_check_constraint.rb b/db/migrate/20210218144056_add_sprints_start_date_not_null_check_constraint.rb
deleted file mode 100644
index 243080f49b2..00000000000
--- a/db/migrate/20210218144056_add_sprints_start_date_not_null_check_constraint.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class AddSprintsStartDateNotNullCheckConstraint < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_not_null_constraint(:sprints, :start_date, validate: false)
- end
-
- def down
- remove_not_null_constraint(:sprints, :start_date)
- end
-end
diff --git a/db/migrate/20210218144656_add_sprints_due_date_not_null_check_constraint.rb b/db/migrate/20210218144656_add_sprints_due_date_not_null_check_constraint.rb
deleted file mode 100644
index 9f3ed6fd13a..00000000000
--- a/db/migrate/20210218144656_add_sprints_due_date_not_null_check_constraint.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class AddSprintsDueDateNotNullCheckConstraint < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_not_null_constraint(:sprints, :due_date, validate: false)
- end
-
- def down
- remove_not_null_constraint(:sprints, :due_date)
- end
-end
diff --git a/db/migrate/20210219100137_add_creator_foreign_key_to_custom_emoji.rb b/db/migrate/20210219100137_add_creator_foreign_key_to_custom_emoji.rb
deleted file mode 100644
index a954ba5ba3b..00000000000
--- a/db/migrate/20210219100137_add_creator_foreign_key_to_custom_emoji.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-class AddCreatorForeignKeyToCustomEmoji < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- FK_NAME = 'fk_custom_emoji_creator_id'
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_foreign_key :custom_emoji, :users,
- on_delete: :cascade,
- column: :creator_id,
- name: FK_NAME
- end
-
- def down
- with_lock_retries do
- remove_foreign_key :custom_emoji, name: FK_NAME
- end
- end
-end
diff --git a/db/migrate/20210219111040_add_epic_issue_composite_index.rb b/db/migrate/20210219111040_add_epic_issue_composite_index.rb
deleted file mode 100644
index f1344baf0c7..00000000000
--- a/db/migrate/20210219111040_add_epic_issue_composite_index.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class AddEpicIssueCompositeIndex < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- INDEX_NAME = 'index_epic_issues_on_epic_id_and_issue_id'
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :epic_issues, [:epic_id, :issue_id], name: INDEX_NAME
- end
-
- def down
- remove_concurrent_index_by_name :epic_issues, INDEX_NAME
- end
-end
diff --git a/db/migrate/20210219211845_add_version_usage_data_id_to_raw_usage_data.rb b/db/migrate/20210219211845_add_version_usage_data_id_to_raw_usage_data.rb
deleted file mode 100644
index 1b49fdd98bd..00000000000
--- a/db/migrate/20210219211845_add_version_usage_data_id_to_raw_usage_data.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddVersionUsageDataIdToRawUsageData < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :raw_usage_data, :version_usage_data_id_value, :bigint
- end
-end
diff --git a/db/migrate/20210222030537_add_is_removed_to_oncall_participant.rb b/db/migrate/20210222030537_add_is_removed_to_oncall_participant.rb
deleted file mode 100644
index 83b81a067ab..00000000000
--- a/db/migrate/20210222030537_add_is_removed_to_oncall_participant.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddIsRemovedToOncallParticipant < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- add_column :incident_management_oncall_participants, :is_removed, :boolean, default: false, null: false
- end
- end
-
- def down
- with_lock_retries do
- remove_column :incident_management_oncall_participants, :is_removed
- end
- end
-end
diff --git a/db/migrate/20210222042745_add_is_removed_index_to_oncall_participant.rb b/db/migrate/20210222042745_add_is_removed_index_to_oncall_participant.rb
deleted file mode 100644
index cfa9b1b89c9..00000000000
--- a/db/migrate/20210222042745_add_is_removed_index_to_oncall_participant.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-class AddIsRemovedIndexToOncallParticipant < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- disable_ddl_transaction!
-
- DOWNTIME = false
- EXISTING_INDEX_NAME = 'index_inc_mgmnt_oncall_participants_on_oncall_rotation_id'
- NEW_INDEX_NAME = 'index_inc_mgmnt_oncall_pcpnt_on_oncall_rotation_id_is_removed'
-
- def up
- add_concurrent_index :incident_management_oncall_participants, [:oncall_rotation_id, :is_removed], name: NEW_INDEX_NAME
- remove_concurrent_index_by_name(:incident_management_oncall_participants, EXISTING_INDEX_NAME)
- end
-
- def down
- add_concurrent_index :incident_management_oncall_participants, :oncall_rotation_id, name: EXISTING_INDEX_NAME
- remove_concurrent_index_by_name(:incident_management_oncall_participants, NEW_INDEX_NAME)
- end
-end
diff --git a/db/migrate/20210222070356_add_storage_size_to_namespace_statistics.rb b/db/migrate/20210222070356_add_storage_size_to_namespace_statistics.rb
deleted file mode 100644
index 838c22382c6..00000000000
--- a/db/migrate/20210222070356_add_storage_size_to_namespace_statistics.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddStorageSizeToNamespaceStatistics < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- add_column :namespace_statistics, :storage_size, :bigint, default: 0, null: false
- end
- end
-
- def down
- with_lock_retries do
- remove_column :namespace_statistics, :storage_size
- end
- end
-end
diff --git a/db/migrate/20210222070413_add_wiki_size_to_namespace_statistics.rb b/db/migrate/20210222070413_add_wiki_size_to_namespace_statistics.rb
deleted file mode 100644
index 9e6ced9fd64..00000000000
--- a/db/migrate/20210222070413_add_wiki_size_to_namespace_statistics.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddWikiSizeToNamespaceStatistics < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- add_column :namespace_statistics, :wiki_size, :bigint, default: 0, null: false
- end
- end
-
- def down
- with_lock_retries do
- remove_column :namespace_statistics, :wiki_size
- end
- end
-end
diff --git a/db/migrate/20210222085529_add_epic_board_user_preference_user_fk.rb b/db/migrate/20210222085529_add_epic_board_user_preference_user_fk.rb
deleted file mode 100644
index 52de892a177..00000000000
--- a/db/migrate/20210222085529_add_epic_board_user_preference_user_fk.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddEpicBoardUserPreferenceUserFk < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_foreign_key :boards_epic_list_user_preferences, :users, column: :user_id, on_delete: :cascade
- end
-
- def down
- with_lock_retries do
- remove_foreign_key_if_exists :boards_epic_list_user_preferences, :users
- end
- end
-end
diff --git a/db/migrate/20210222085551_add_epic_board_user_preference_epic_list_fk.rb b/db/migrate/20210222085551_add_epic_board_user_preference_epic_list_fk.rb
deleted file mode 100644
index 3f62036b899..00000000000
--- a/db/migrate/20210222085551_add_epic_board_user_preference_epic_list_fk.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddEpicBoardUserPreferenceEpicListFk < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_foreign_key :boards_epic_list_user_preferences, :boards_epic_lists, column: :epic_list_id, on_delete: :cascade
- end
-
- def down
- with_lock_retries do
- remove_foreign_key_if_exists :boards_epic_list_user_preferences, :boards_epic_lists
- end
- end
-end
diff --git a/db/migrate/20210222105120_add_container_registry_access_level.rb b/db/migrate/20210222105120_add_container_registry_access_level.rb
deleted file mode 100644
index 2324866b0ef..00000000000
--- a/db/migrate/20210222105120_add_container_registry_access_level.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-class AddContainerRegistryAccessLevel < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- add_column(
- :project_features,
- :container_registry_access_level,
- :integer,
- default: 0, # ProjectFeature::DISABLED value
- null: false
- )
- end
- end
-
- def down
- with_lock_retries do
- remove_column :project_features, :container_registry_access_level
- end
- end
-end
diff --git a/db/migrate/20210223053451_add_branch_name_to_dast_profile.rb b/db/migrate/20210223053451_add_branch_name_to_dast_profile.rb
deleted file mode 100644
index 311e809103f..00000000000
--- a/db/migrate/20210223053451_add_branch_name_to_dast_profile.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-class AddBranchNameToDastProfile < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- with_lock_retries do
- add_column :dast_profiles, :branch_name, :text
- end
-
- add_text_limit :dast_profiles, :branch_name, 255
- end
-
- def down
- with_lock_retries do
- remove_column :dast_profiles, :branch_name
- end
- end
-end
diff --git a/db/migrate/20210223132934_add_foreign_key_to_external_approval_rules.rb b/db/migrate/20210223132934_add_foreign_key_to_external_approval_rules.rb
deleted file mode 100644
index b5f04672813..00000000000
--- a/db/migrate/20210223132934_add_foreign_key_to_external_approval_rules.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class AddForeignKeyToExternalApprovalRules < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_foreign_key :external_approval_rules_protected_branches, :external_approval_rules, column: :external_approval_rule_id, on_delete: :cascade
- end
-
- def down
- with_lock_retries do
- remove_foreign_key :external_approval_rules_protected_branches, column: :external_approval_rule_id
- end
- end
-end
diff --git a/db/migrate/20210223133116_add_foreign_key_to_external_approval_rules_protected_branches.rb b/db/migrate/20210223133116_add_foreign_key_to_external_approval_rules_protected_branches.rb
deleted file mode 100644
index ad51f765d8a..00000000000
--- a/db/migrate/20210223133116_add_foreign_key_to_external_approval_rules_protected_branches.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class AddForeignKeyToExternalApprovalRulesProtectedBranches < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_foreign_key :external_approval_rules_protected_branches, :protected_branches, column: :protected_branch_id, on_delete: :cascade
- end
-
- def down
- with_lock_retries do
- remove_foreign_key :external_approval_rules_protected_branches, column: :protected_branch_id
- end
- end
-end
diff --git a/db/migrate/20210223230600_update_rubygems_metadata_metadata.rb b/db/migrate/20210223230600_update_rubygems_metadata_metadata.rb
deleted file mode 100644
index 39e79be301e..00000000000
--- a/db/migrate/20210223230600_update_rubygems_metadata_metadata.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class UpdateRubygemsMetadataMetadata < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- remove_text_limit :packages_rubygems_metadata, :metadata
- add_text_limit :packages_rubygems_metadata, :metadata, 30000
- end
-
- def down
- remove_text_limit :packages_rubygems_metadata, :metadata
- add_text_limit :packages_rubygems_metadata, :metadata, 255, validate: false
- end
-end
diff --git a/db/migrate/20210224132547_add_null_constraint_to_terraform_state_name.rb b/db/migrate/20210224132547_add_null_constraint_to_terraform_state_name.rb
deleted file mode 100644
index d9f23311cf5..00000000000
--- a/db/migrate/20210224132547_add_null_constraint_to_terraform_state_name.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-class AddNullConstraintToTerraformStateName < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- change_column_null :terraform_states, :name, false
- end
-end
diff --git a/db/migrate/20210224133337_add_name_field_to_cluster_agent_token.rb b/db/migrate/20210224133337_add_name_field_to_cluster_agent_token.rb
deleted file mode 100644
index 2cec37f8477..00000000000
--- a/db/migrate/20210224133337_add_name_field_to_cluster_agent_token.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-class AddNameFieldToClusterAgentToken < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- # rubocop:disable Migration/AddLimitToTextColumns
- # limit is added in LimitClusterTokenSize
- def change
- add_column :cluster_agent_tokens, :name, :text
- end
- # rubocop:enable Migration/AddLimitToTextColumns
-end
diff --git a/db/migrate/20210224161552_add_jira_issue_transition_automatic_to_jira_tracker_data.rb b/db/migrate/20210224161552_add_jira_issue_transition_automatic_to_jira_tracker_data.rb
deleted file mode 100644
index 6c788b9d554..00000000000
--- a/db/migrate/20210224161552_add_jira_issue_transition_automatic_to_jira_tracker_data.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddJiraIssueTransitionAutomaticToJiraTrackerData < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- add_column :jira_tracker_data, :jira_issue_transition_automatic, :boolean, null: false, default: false
- end
-end
diff --git a/db/migrate/20210225090801_create_dora_daily_metrics.rb b/db/migrate/20210225090801_create_dora_daily_metrics.rb
deleted file mode 100644
index 65c1dbc23e4..00000000000
--- a/db/migrate/20210225090801_create_dora_daily_metrics.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# frozen_string_literal: true
-
-class CreateDoraDailyMetrics < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- with_lock_retries do
- create_table :dora_daily_metrics, if_not_exists: true do |t|
- t.references :environment, null: false, foreign_key: { on_delete: :cascade }, index: false
- t.date :date, null: false
- t.integer :deployment_frequency
- t.integer :lead_time_for_changes_in_seconds
-
- t.index [:environment_id, :date], unique: true
- end
- end
-
- add_check_constraint :dora_daily_metrics, "deployment_frequency >= 0", 'dora_daily_metrics_deployment_frequency_positive'
- add_check_constraint :dora_daily_metrics, "lead_time_for_changes_in_seconds >= 0", 'dora_daily_metrics_lead_time_for_changes_in_seconds_positive'
- end
-
- def down
- with_lock_retries do
- drop_table :dora_daily_metrics
- end
- end
-end
diff --git a/db/migrate/20210225135533_limit_cluster_token_size.rb b/db/migrate/20210225135533_limit_cluster_token_size.rb
deleted file mode 100644
index 6a1b6b7b4e8..00000000000
--- a/db/migrate/20210225135533_limit_cluster_token_size.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class LimitClusterTokenSize < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_text_limit :cluster_agent_tokens, :name, 255
- end
-
- def down
- remove_text_limit :cluster_agent_tokens, :name
- end
-end
diff --git a/db/migrate/20210225153522_add_allow_force_push_to_protected_branches.rb b/db/migrate/20210225153522_add_allow_force_push_to_protected_branches.rb
deleted file mode 100644
index 92a15cb45dd..00000000000
--- a/db/migrate/20210225153522_add_allow_force_push_to_protected_branches.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddAllowForcePushToProtectedBranches < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- add_column :protected_branches, :allow_force_push, :boolean, default: false, null: false
- end
- end
-
- def down
- with_lock_retries do
- remove_column :protected_branches, :allow_force_push
- end
- end
-end
diff --git a/db/migrate/20210301150451_add_tier_to_environments.rb b/db/migrate/20210301150451_add_tier_to_environments.rb
deleted file mode 100644
index 28592dd2bf6..00000000000
--- a/db/migrate/20210301150451_add_tier_to_environments.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddTierToEnvironments < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- add_column :environments, :tier, :smallint
- end
- end
-
- def down
- with_lock_retries do
- remove_column :environments, :tier
- end
- end
-end
diff --git a/db/migrate/20210301193412_add_optional_to_ci_build_needs.rb b/db/migrate/20210301193412_add_optional_to_ci_build_needs.rb
deleted file mode 100644
index 2c6e85f930d..00000000000
--- a/db/migrate/20210301193412_add_optional_to_ci_build_needs.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddOptionalToCiBuildNeeds < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- add_column :ci_build_needs, :optional, :boolean, default: false, null: false
- end
- end
-
- def down
- with_lock_retries do
- remove_column :ci_build_needs, :optional
- end
- end
-end
diff --git a/db/migrate/20210301200601_rename_asset_proxy_allowlist_on_application_settings.rb b/db/migrate/20210301200601_rename_asset_proxy_allowlist_on_application_settings.rb
deleted file mode 100644
index 8ac334fc6a4..00000000000
--- a/db/migrate/20210301200601_rename_asset_proxy_allowlist_on_application_settings.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-class RenameAssetProxyAllowlistOnApplicationSettings < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers::V2
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- cleanup_concurrent_column_rename :application_settings,
- :asset_proxy_whitelist,
- :asset_proxy_allowlist
-
- rename_column_concurrently :application_settings,
- :asset_proxy_allowlist,
- :asset_proxy_whitelist
- end
-
- def down
- undo_rename_column_concurrently :application_settings,
- :asset_proxy_allowlist,
- :asset_proxy_whitelist
-
- undo_cleanup_concurrent_column_rename :application_settings,
- :asset_proxy_whitelist,
- :asset_proxy_allowlist
- end
-end
diff --git a/db/migrate/20181228175414_init_schema.rb b/db/migrate/20210301200959_init_schema.rb
index df68927d79a..df68927d79a 100644
--- a/db/migrate/20181228175414_init_schema.rb
+++ b/db/migrate/20210301200959_init_schema.rb
diff --git a/db/migrate/20210811193033_add_unique_index_to_vulnerability_finding_links.rb b/db/migrate/20210811193033_add_unique_index_to_vulnerability_finding_links.rb
new file mode 100644
index 00000000000..1bcee89ae57
--- /dev/null
+++ b/db/migrate/20210811193033_add_unique_index_to_vulnerability_finding_links.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class AddUniqueIndexToVulnerabilityFindingLinks < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ NAME_URL_INDEX_NAME = 'finding_link_name_url_idx'
+ URL_INDEX_NAME = 'finding_link_url_idx'
+
+ def up
+ add_concurrent_index :vulnerability_finding_links, [:vulnerability_occurrence_id, :name, :url], unique: true, name: NAME_URL_INDEX_NAME
+ add_concurrent_index :vulnerability_finding_links, [:vulnerability_occurrence_id, :url], unique: true, where: 'name is null', name: URL_INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index :vulnerability_finding_links, [:vulnerability_occurrence_id, :name, :url], name: NAME_URL_INDEX_NAME
+ remove_concurrent_index :vulnerability_finding_links, [:vulnerability_occurrence_id, :url], name: URL_INDEX_NAME
+ end
+end
diff --git a/db/migrate/20211026124336_add_archive_trace_events_to_integrations.rb b/db/migrate/20211026124336_add_archive_trace_events_to_integrations.rb
new file mode 100644
index 00000000000..90e68f6a0ac
--- /dev/null
+++ b/db/migrate/20211026124336_add_archive_trace_events_to_integrations.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddArchiveTraceEventsToIntegrations < Gitlab::Database::Migration[1.0]
+ def change
+ add_column :integrations, :archive_trace_events, :boolean, null: false, default: false
+ end
+end
diff --git a/db/migrate/20211209230042_add_status_to_cluster_agent_tokens.rb b/db/migrate/20211209230042_add_status_to_cluster_agent_tokens.rb
new file mode 100644
index 00000000000..596c82eb209
--- /dev/null
+++ b/db/migrate/20211209230042_add_status_to_cluster_agent_tokens.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddStatusToClusterAgentTokens < Gitlab::Database::Migration[1.0]
+ def change
+ add_column :cluster_agent_tokens, :status, :smallint, null: false, default: 0
+ end
+end
diff --git a/db/migrate/20211210025754_alter_constraint_of_phone.rb b/db/migrate/20211210025754_alter_constraint_of_phone.rb
new file mode 100644
index 00000000000..1644fbe9000
--- /dev/null
+++ b/db/migrate/20211210025754_alter_constraint_of_phone.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AlterConstraintOfPhone < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ constraint_phone = check_constraint_name('verification_codes', 'phone', 'max_length')
+ remove_check_constraint(:verification_codes, constraint_phone)
+ add_check_constraint(:verification_codes, 'char_length(phone) <= 50', constraint_phone)
+ end
+
+ def down
+ constraint_phone = check_constraint_name('verification_codes', 'phone', 'max_length')
+ remove_check_constraint(:verification_codes, constraint_phone)
+ add_check_constraint(:verification_codes, 'char_length(phone) <= 32', constraint_phone)
+ end
+end
diff --git a/db/migrate/20211210031721_change_user_details_phone_text_limit.rb b/db/migrate/20211210031721_change_user_details_phone_text_limit.rb
new file mode 100644
index 00000000000..5432f6d3d24
--- /dev/null
+++ b/db/migrate/20211210031721_change_user_details_phone_text_limit.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class ChangeUserDetailsPhoneTextLimit < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ remove_text_limit :user_details, :phone
+ add_text_limit :user_details, :phone, 50
+ end
+
+ def down
+ remove_text_limit :user_details, :phone
+ add_text_limit :user_details, :phone, 32
+ end
+end
diff --git a/db/migrate/20211213142344_add_settings_user_email_lookup_limit.rb b/db/migrate/20211213142344_add_settings_user_email_lookup_limit.rb
new file mode 100644
index 00000000000..ac7027bf082
--- /dev/null
+++ b/db/migrate/20211213142344_add_settings_user_email_lookup_limit.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddSettingsUserEmailLookupLimit < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ add_column :application_settings, :user_email_lookup_limit, :integer, null: false, default: 60
+ end
+
+ def down
+ remove_column :application_settings, :user_email_lookup_limit
+ end
+end
diff --git a/db/migrate/20211213154259_add_status_to_packages_package_files.rb b/db/migrate/20211213154259_add_status_to_packages_package_files.rb
new file mode 100644
index 00000000000..38ea069a30b
--- /dev/null
+++ b/db/migrate/20211213154259_add_status_to_packages_package_files.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddStatusToPackagesPackageFiles < Gitlab::Database::Migration[1.0]
+ def change
+ add_column :packages_package_files, :status, :smallint, default: 0, null: false
+ end
+end
diff --git a/db/migrate/20211213154704_add_status_index_to_packages_package_files.rb b/db/migrate/20211213154704_add_status_index_to_packages_package_files.rb
new file mode 100644
index 00000000000..7067e3efa6c
--- /dev/null
+++ b/db/migrate/20211213154704_add_status_index_to_packages_package_files.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddStatusIndexToPackagesPackageFiles < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_packages_package_files_on_package_id_status_and_id'
+
+ def up
+ add_concurrent_index :packages_package_files, [:package_id, :status, :id], name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :packages_package_files, name: INDEX_NAME
+ end
+end
diff --git a/db/migrate/20211215182006_update_application_settings_protected_paths.rb b/db/migrate/20211215182006_update_application_settings_protected_paths.rb
new file mode 100644
index 00000000000..f1c1dde55e0
--- /dev/null
+++ b/db/migrate/20211215182006_update_application_settings_protected_paths.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+class UpdateApplicationSettingsProtectedPaths < Gitlab::Database::Migration[1.0]
+ REMOVE_PROTECTED_PATHS = [
+ '/oauth/authorize',
+ '/oauth/token'
+ ].freeze
+
+ NEW_DEFAULT_PROTECTED_PATHS = [
+ '/users/password',
+ '/users/sign_in',
+ '/api/v3/session.json',
+ '/api/v3/session',
+ '/api/v4/session.json',
+ '/api/v4/session',
+ '/users',
+ '/users/confirmation',
+ '/unsubscribes/',
+ '/import/github/personal_access_token',
+ '/admin/session'
+ ].freeze
+
+ OLD_DEFAULT_PROTECTED_PATHS = (NEW_DEFAULT_PROTECTED_PATHS + REMOVE_PROTECTED_PATHS).freeze
+
+ class ApplicationSetting < ActiveRecord::Base
+ self.table_name = 'application_settings'
+ end
+
+ def up
+ change_column_default(:application_settings, :protected_paths, NEW_DEFAULT_PROTECTED_PATHS)
+
+ ApplicationSetting.reset_column_information
+
+ ApplicationSetting.where.not(protected_paths: nil).each do |application_setting|
+ paths_to_remove = application_setting.protected_paths & REMOVE_PROTECTED_PATHS
+
+ next if paths_to_remove.empty?
+
+ updated_protected_paths = application_setting.protected_paths - paths_to_remove
+ application_setting.update!(protected_paths: updated_protected_paths)
+ end
+ end
+
+ def down
+ change_column_default(:application_settings, :protected_paths, OLD_DEFAULT_PROTECTED_PATHS)
+
+ ApplicationSetting.reset_column_information
+
+ ApplicationSetting.where.not(protected_paths: nil).each do |application_setting|
+ paths_to_add = REMOVE_PROTECTED_PATHS - application_setting.protected_paths
+
+ next if paths_to_add.empty?
+
+ updated_protected_paths = application_setting.protected_paths + paths_to_add
+ application_setting.update!(protected_paths: updated_protected_paths)
+ end
+ end
+end
diff --git a/db/migrate/20211216133107_add_cluster_agent_id_to_vulnerability_reads.rb b/db/migrate/20211216133107_add_cluster_agent_id_to_vulnerability_reads.rb
new file mode 100644
index 00000000000..0bbd5c25df4
--- /dev/null
+++ b/db/migrate/20211216133107_add_cluster_agent_id_to_vulnerability_reads.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class AddClusterAgentIdToVulnerabilityReads < Gitlab::Database::Migration[1.0]
+ # rubocop:disable Migration/AddLimitToTextColumns
+ # limit is added in 20211216134134_add_text_limit_to_vulnerability_reads_cluster_agent_id.rb
+ def change
+ add_column :vulnerability_reads, :cluster_agent_id, :text
+ end
+ # rubocop:enable Migration/AddLimitToTextColumns
+end
diff --git a/db/migrate/20211216134134_add_text_limit_to_vulnerability_reads_cluster_agent_id.rb b/db/migrate/20211216134134_add_text_limit_to_vulnerability_reads_cluster_agent_id.rb
new file mode 100644
index 00000000000..f4776ff10a4
--- /dev/null
+++ b/db/migrate/20211216134134_add_text_limit_to_vulnerability_reads_cluster_agent_id.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddTextLimitToVulnerabilityReadsClusterAgentId < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ add_text_limit :vulnerability_reads, :cluster_agent_id, 10
+ end
+
+ def down
+ remove_text_limit :vulnerability_reads, :cluster_agent_id
+ end
+end
diff --git a/db/migrate/20211216135651_add_index_to_cluster_agent_id.rb b/db/migrate/20211216135651_add_index_to_cluster_agent_id.rb
new file mode 100644
index 00000000000..05928083823
--- /dev/null
+++ b/db/migrate/20211216135651_add_index_to_cluster_agent_id.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddIndexToClusterAgentId < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = "index_vulnerability_reads_on_cluster_agent_id"
+ CLUSTER_IMAGE_SCANNING_REPORT_TYPE = 7
+
+ def up
+ add_concurrent_index :vulnerability_reads, :cluster_agent_id, where: "report_type = #{CLUSTER_IMAGE_SCANNING_REPORT_TYPE}", name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :vulnerability_reads, INDEX_NAME
+ end
+end
diff --git a/db/migrate/20211216220939_add_group_crm_settings.rb b/db/migrate/20211216220939_add_group_crm_settings.rb
new file mode 100644
index 00000000000..e931aa3709b
--- /dev/null
+++ b/db/migrate/20211216220939_add_group_crm_settings.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddGroupCrmSettings < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def change
+ create_table :group_crm_settings, id: false do |t|
+ t.references :group, primary_key: true, foreign_key: { to_table: :namespaces, on_delete: :cascade }
+ t.timestamps_with_timezone
+ t.boolean :enabled, null: false, default: false
+ end
+ end
+end
diff --git a/db/migrate/20211217050753_remove_artifacts_archive_id_foreign_key_from_project_pages_metadata.rb b/db/migrate/20211217050753_remove_artifacts_archive_id_foreign_key_from_project_pages_metadata.rb
new file mode 100644
index 00000000000..fa81fa512ae
--- /dev/null
+++ b/db/migrate/20211217050753_remove_artifacts_archive_id_foreign_key_from_project_pages_metadata.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveArtifactsArchiveIdForeignKeyFromProjectPagesMetadata < Gitlab::Database::Migration[1.0]
+ CONSTRAINT_NAME = 'fk_69366a119e'
+
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ execute('lock table ci_job_artifacts, project_pages_metadata in access exclusive mode')
+
+ remove_foreign_key :project_pages_metadata, to_table: :ci_job_artifacts, column: :artifacts_archive_id, on_delete: :nullify, name: CONSTRAINT_NAME
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key :project_pages_metadata, :ci_job_artifacts, column: :artifacts_archive_id, on_delete: :nullify, name: CONSTRAINT_NAME
+ end
+end
diff --git a/db/migrate/20211220174504_add_secure_scanning_actions_to_onboarding_progresses.rb b/db/migrate/20211220174504_add_secure_scanning_actions_to_onboarding_progresses.rb
new file mode 100644
index 00000000000..cf9f2511176
--- /dev/null
+++ b/db/migrate/20211220174504_add_secure_scanning_actions_to_onboarding_progresses.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddSecureScanningActionsToOnboardingProgresses < Gitlab::Database::Migration[1.0]
+ def change
+ change_table(:onboarding_progresses, bulk: true) do |t|
+ t.column :secure_dependency_scanning_run_at, :datetime_with_timezone
+ t.column :secure_container_scanning_run_at, :datetime_with_timezone
+ t.column :secure_dast_run_at, :datetime_with_timezone
+ t.column :secure_secret_detection_run_at, :datetime_with_timezone
+ t.column :secure_coverage_fuzzing_run_at, :datetime_with_timezone
+ t.column :secure_cluster_image_scanning_run_at, :datetime_with_timezone
+ t.column :secure_api_fuzzing_run_at, :datetime_with_timezone
+ end
+ end
+end
diff --git a/db/migrate/20211223125921_add_temp_index_to_members_state.rb b/db/migrate/20211223125921_add_temp_index_to_members_state.rb
new file mode 100644
index 00000000000..7dd2ec1a8aa
--- /dev/null
+++ b/db/migrate/20211223125921_add_temp_index_to_members_state.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddTempIndexToMembersState < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'tmp_index_members_on_state'
+
+ def up
+ # Temporary index to be removed in 14.9 https://gitlab.com/gitlab-org/gitlab/-/issues/349960
+ add_concurrent_index :members, :state, name: INDEX_NAME, where: 'state = 2'
+ end
+
+ def down
+ remove_concurrent_index_by_name :members, INDEX_NAME
+ end
+end
diff --git a/db/migrate/20211224112937_add_packages_cleanup_package_file_worker_capacity_to_application_settings.rb b/db/migrate/20211224112937_add_packages_cleanup_package_file_worker_capacity_to_application_settings.rb
new file mode 100644
index 00000000000..cb58033361f
--- /dev/null
+++ b/db/migrate/20211224112937_add_packages_cleanup_package_file_worker_capacity_to_application_settings.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddPackagesCleanupPackageFileWorkerCapacityToApplicationSettings < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def change
+ add_column :application_settings,
+ :packages_cleanup_package_file_worker_capacity,
+ :smallint,
+ default: 2,
+ null: false
+ end
+end
diff --git a/db/migrate/20211224114539_add_packages_cleanup_package_file_worker_capacity_check_constraint_to_app_settings.rb b/db/migrate/20211224114539_add_packages_cleanup_package_file_worker_capacity_check_constraint_to_app_settings.rb
new file mode 100644
index 00000000000..3a40540a1e1
--- /dev/null
+++ b/db/migrate/20211224114539_add_packages_cleanup_package_file_worker_capacity_check_constraint_to_app_settings.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddPackagesCleanupPackageFileWorkerCapacityCheckConstraintToAppSettings < Gitlab::Database::Migration[1.0]
+ CONSTRAINT_NAME = 'app_settings_p_cleanup_package_file_worker_capacity_positive'
+
+ disable_ddl_transaction!
+
+ def up
+ add_check_constraint :application_settings, 'packages_cleanup_package_file_worker_capacity >= 0', CONSTRAINT_NAME
+ end
+
+ def down
+ remove_check_constraint :application_settings, CONSTRAINT_NAME
+ end
+end
diff --git a/db/migrate/20220104174445_add_ci_runners_index_on_active_state.rb b/db/migrate/20220104174445_add_ci_runners_index_on_active_state.rb
new file mode 100644
index 00000000000..2cef570966b
--- /dev/null
+++ b/db/migrate/20220104174445_add_ci_runners_index_on_active_state.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddCiRunnersIndexOnActiveState < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_ci_runners_on_active'
+
+ def up
+ add_concurrent_index :ci_runners, [:active, :id], name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :ci_runners, INDEX_NAME
+ end
+end
diff --git a/db/migrate/20220105121325_add_route_namespace_reference.rb b/db/migrate/20220105121325_add_route_namespace_reference.rb
new file mode 100644
index 00000000000..77bd0530b8a
--- /dev/null
+++ b/db/migrate/20220105121325_add_route_namespace_reference.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddRouteNamespaceReference < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def up
+ add_column :routes, :namespace_id, :bigint unless column_exists?(:routes, :namespace_id)
+ end
+
+ def down
+ remove_column :routes, :namespace_id if column_exists?(:routes, :namespace_id)
+ end
+end
diff --git a/db/migrate/20220106141756_remove_lock_version_indexes.rb b/db/migrate/20220106141756_remove_lock_version_indexes.rb
new file mode 100644
index 00000000000..382f20dfc73
--- /dev/null
+++ b/db/migrate/20220106141756_remove_lock_version_indexes.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class RemoveLockVersionIndexes < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEXES = {
+ issues: 'index_issues_on_lock_version',
+ merge_requests: 'index_merge_requests_on_lock_version',
+ epics: 'index_epics_on_lock_version'
+ }
+
+ def up
+ INDEXES.each do |table, index_name|
+ remove_concurrent_index_by_name table, index_name
+ end
+ end
+
+ def down
+ INDEXES.each do |table, index_name|
+ add_concurrent_index table, :lock_version, where: "lock_version IS NULL", name: index_name
+ end
+ end
+end
diff --git a/db/migrate/20220106230629_add_registry_migration_application_settings.rb b/db/migrate/20220106230629_add_registry_migration_application_settings.rb
new file mode 100644
index 00000000000..191443de6eb
--- /dev/null
+++ b/db/migrate/20220106230629_add_registry_migration_application_settings.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddRegistryMigrationApplicationSettings < Gitlab::Database::Migration[1.0]
+ # rubocop:disable Migration/AddLimitToTextColumns
+ # limit is added in 20220118141950_add_text_limit_to_container_registry_import_target_plan.rb
+ def change
+ add_column :application_settings, :container_registry_import_max_tags_count, :integer, default: 100, null: false
+ add_column :application_settings, :container_registry_import_max_retries, :integer, default: 3, null: false
+ add_column :application_settings, :container_registry_import_start_max_retries, :integer, default: 50, null: false
+ add_column :application_settings, :container_registry_import_max_step_duration, :integer, default: 5.minutes, null: false
+ add_column :application_settings, :container_registry_import_target_plan, :text, default: 'free', null: false
+ add_column :application_settings, :container_registry_import_created_before, :datetime_with_timezone, default: '2022-01-23 00:00:00', null: false
+ end
+ # rubocop:enable Migration/AddLimitToTextColumns
+end
diff --git a/db/migrate/20220106230712_add_migration_columns_to_container_repositories.rb b/db/migrate/20220106230712_add_migration_columns_to_container_repositories.rb
new file mode 100644
index 00000000000..76dccbe785f
--- /dev/null
+++ b/db/migrate/20220106230712_add_migration_columns_to_container_repositories.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddMigrationColumnsToContainerRepositories < Gitlab::Database::Migration[1.0]
+ # rubocop:disable Migration/AddLimitToTextColumns
+ # limit is added in 20220117225936_add_text_limits_to_container_repositories_migration_columns.rb
+ def change
+ add_column :container_repositories, :migration_pre_import_started_at, :datetime_with_timezone
+ add_column :container_repositories, :migration_pre_import_done_at, :datetime_with_timezone
+ add_column :container_repositories, :migration_import_started_at, :datetime_with_timezone
+ add_column :container_repositories, :migration_import_done_at, :datetime_with_timezone
+ add_column :container_repositories, :migration_aborted_at, :datetime_with_timezone
+ add_column :container_repositories, :migration_skipped_at, :datetime_with_timezone
+ add_column :container_repositories, :migration_retries_count, :integer, default: 0, null: false
+ add_column :container_repositories, :migration_skipped_reason, :smallint
+ add_column :container_repositories, :migration_state, :text, default: 'default', null: false
+ add_column :container_repositories, :migration_aborted_in_state, :text
+ end
+ # rubocop:enable Migration/AddLimitToTextColumns
+end
diff --git a/db/migrate/20220107091629_add_route_namespace_index.rb b/db/migrate/20220107091629_add_route_namespace_index.rb
new file mode 100644
index 00000000000..bc1044a24da
--- /dev/null
+++ b/db/migrate/20220107091629_add_route_namespace_index.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddRouteNamespaceIndex < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+ INDEX_NAME = 'index_routes_on_namespace_id'
+
+ def up
+ add_concurrent_index :routes, :namespace_id, unique: true, name: INDEX_NAME
+ add_concurrent_foreign_key :routes, :namespaces, column: :namespace_id, on_delete: :nullify, reverse_lock_order: true
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key_if_exists :routes, column: :namespace_id
+ end
+
+ remove_concurrent_index_by_name :routes, INDEX_NAME
+ end
+end
diff --git a/db/migrate/20220107165036_remove_note_id_index.rb b/db/migrate/20220107165036_remove_note_id_index.rb
new file mode 100644
index 00000000000..15b4a3caf78
--- /dev/null
+++ b/db/migrate/20220107165036_remove_note_id_index.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class RemoveNoteIdIndex < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ TABLE = :suggestions
+ INDEX_NAME = 'index_suggestions_on_note_id'
+
+ def up
+ remove_concurrent_index_by_name TABLE, INDEX_NAME
+ end
+
+ def down
+ add_concurrent_index TABLE, :note_id, name: INDEX_NAME
+ end
+end
diff --git a/db/migrate/20220109133006_remove_ci_pipelines_lock_version_index.rb b/db/migrate/20220109133006_remove_ci_pipelines_lock_version_index.rb
new file mode 100644
index 00000000000..abbd54ff19b
--- /dev/null
+++ b/db/migrate/20220109133006_remove_ci_pipelines_lock_version_index.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveCiPipelinesLockVersionIndex < Gitlab::Database::Migration[1.0]
+ TABLE = :ci_pipelines
+ INDEX_NAME = 'tmp_index_ci_pipelines_lock_version'
+ COLUMN = :id
+
+ disable_ddl_transaction!
+
+ def up
+ remove_concurrent_index TABLE, COLUMN, where: "lock_version IS NULL", name: INDEX_NAME
+ end
+
+ def down
+ add_concurrent_index TABLE, COLUMN, where: "lock_version IS NULL", name: INDEX_NAME
+ end
+end
diff --git a/db/migrate/20220110170953_create_ci_secure_files.rb b/db/migrate/20220110170953_create_ci_secure_files.rb
new file mode 100644
index 00000000000..1498a2d0212
--- /dev/null
+++ b/db/migrate/20220110170953_create_ci_secure_files.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class CreateCiSecureFiles < Gitlab::Database::Migration[1.0]
+ def up
+ create_table :ci_secure_files do |t|
+ t.bigint :project_id, index: true, null: false
+ t.timestamps_with_timezone null: false
+ t.integer :file_store, limit: 2, null: false, default: 1
+ t.integer :permissions, null: false, default: 0, limit: 2
+ t.text :name, null: false, limit: 255
+ t.text :file, null: false, limit: 255
+ t.binary :checksum, null: false
+ end
+ end
+
+ def down
+ drop_table :ci_secure_files, if_exists: true
+ end
+end
diff --git a/db/migrate/20220111095006_add_maintainer_note_to_ci_runners.rb b/db/migrate/20220111095006_add_maintainer_note_to_ci_runners.rb
new file mode 100644
index 00000000000..969774983c4
--- /dev/null
+++ b/db/migrate/20220111095006_add_maintainer_note_to_ci_runners.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class AddMaintainerNoteToCiRunners < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def change
+ # rubocop:disable Migration/AddLimitToTextColumns
+ # limit is added in 20220111095007_add_text_limit_to_ci_runners_maintainer_note.rb
+ add_column :ci_runners, :maintainer_note, :text
+ # rubocop:enable Migration/AddLimitToTextColumns
+ end
+end
diff --git a/db/migrate/20220111095007_add_text_limit_to_ci_runners_maintainer_note.rb b/db/migrate/20220111095007_add_text_limit_to_ci_runners_maintainer_note.rb
new file mode 100644
index 00000000000..0a0a4171306
--- /dev/null
+++ b/db/migrate/20220111095007_add_text_limit_to_ci_runners_maintainer_note.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddTextLimitToCiRunnersMaintainerNote < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ add_text_limit :ci_runners, :maintainer_note, 255
+ end
+
+ def down
+ remove_text_limit :ci_runners, :maintainer_note
+ end
+end
diff --git a/db/migrate/20220111200254_remove_index_from_merge_requests.rb b/db/migrate/20220111200254_remove_index_from_merge_requests.rb
new file mode 100644
index 00000000000..0ac6019ad5e
--- /dev/null
+++ b/db/migrate/20220111200254_remove_index_from_merge_requests.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveIndexFromMergeRequests < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_merge_requests_on_title'
+
+ def up
+ remove_concurrent_index :merge_requests, :title, name: INDEX_NAME
+ end
+
+ def down
+ add_concurrent_index :merge_requests, :title, name: INDEX_NAME
+ end
+end
diff --git a/db/migrate/20220112115413_add_requires_verification_to_user_details.rb b/db/migrate/20220112115413_add_requires_verification_to_user_details.rb
new file mode 100644
index 00000000000..01fe4f1d5cf
--- /dev/null
+++ b/db/migrate/20220112115413_add_requires_verification_to_user_details.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddRequiresVerificationToUserDetails < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def change
+ add_column :user_details, :requires_credit_card_verification, :boolean, null: false, default: false
+ end
+end
diff --git a/db/migrate/20220112205111_create_security_training_providers.rb b/db/migrate/20220112205111_create_security_training_providers.rb
new file mode 100644
index 00000000000..afddec6a134
--- /dev/null
+++ b/db/migrate/20220112205111_create_security_training_providers.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class CreateSecurityTrainingProviders < Gitlab::Database::Migration[1.0]
+ def change
+ create_table :security_training_providers do |t|
+ t.text :name, limit: 256, null: false
+ t.text :description, limit: 512
+ t.text :url, limit: 512, null: false
+ t.text :logo_url, limit: 512
+
+ t.timestamps_with_timezone null: false
+ end
+ end
+end
diff --git a/db/migrate/20220112232037_add_member_namespace_reference.rb b/db/migrate/20220112232037_add_member_namespace_reference.rb
new file mode 100644
index 00000000000..d67ea09a78c
--- /dev/null
+++ b/db/migrate/20220112232037_add_member_namespace_reference.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddMemberNamespaceReference < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def up
+ add_column :members, :member_namespace_id, :bigint unless column_exists?(:members, :member_namespace_id)
+ end
+
+ def down
+ remove_column :members, :member_namespace_id if column_exists?(:members, :member_namespace_id)
+ end
+end
diff --git a/db/migrate/20220112232605_add_member_namespace_index.rb b/db/migrate/20220112232605_add_member_namespace_index.rb
new file mode 100644
index 00000000000..ba32df53ae7
--- /dev/null
+++ b/db/migrate/20220112232605_add_member_namespace_index.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddMemberNamespaceIndex < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+ INDEX_NAME = 'index_members_on_member_namespace_id'
+
+ def up
+ add_concurrent_index :members, :member_namespace_id, unique: false, name: INDEX_NAME
+ add_concurrent_foreign_key :members, :namespaces, column: :member_namespace_id, on_delete: :nullify, reverse_lock_order: true
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key_if_exists :members, column: :member_namespace_id
+ end
+
+ remove_concurrent_index_by_name :members, INDEX_NAME
+ end
+end
diff --git a/db/migrate/20220113125401_create_security_trainings.rb b/db/migrate/20220113125401_create_security_trainings.rb
new file mode 100644
index 00000000000..6924c7bd189
--- /dev/null
+++ b/db/migrate/20220113125401_create_security_trainings.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class CreateSecurityTrainings < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def change
+ create_table :security_trainings do |t|
+ t.references :project, null: false, foreign_key: { on_delete: :cascade }
+ t.references :provider, null: false, foreign_key: { to_table: :security_training_providers, on_delete: :cascade }
+ t.boolean :is_primary, default: false, null: false
+
+ t.timestamps_with_timezone null: false
+
+ # Guarantee that there will be only one primary per project
+ t.index :project_id, name: 'index_security_trainings_on_unique_project_id', unique: true, where: 'is_primary IS TRUE'
+ end
+ end
+end
diff --git a/db/migrate/20220114131950_add_status_only_index_to_packages_package_files.rb b/db/migrate/20220114131950_add_status_only_index_to_packages_package_files.rb
new file mode 100644
index 00000000000..948edea1138
--- /dev/null
+++ b/db/migrate/20220114131950_add_status_only_index_to_packages_package_files.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddStatusOnlyIndexToPackagesPackageFiles < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_packages_package_files_on_status'
+
+ def up
+ add_concurrent_index :packages_package_files, :status, name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :packages_package_files, name: INDEX_NAME
+ end
+end
diff --git a/db/migrate/20220117225936_add_text_limits_to_container_repositories_migration_columns.rb b/db/migrate/20220117225936_add_text_limits_to_container_repositories_migration_columns.rb
new file mode 100644
index 00000000000..91c0612716b
--- /dev/null
+++ b/db/migrate/20220117225936_add_text_limits_to_container_repositories_migration_columns.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddTextLimitsToContainerRepositoriesMigrationColumns < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ add_text_limit :container_repositories, :migration_state, 255
+ add_text_limit :container_repositories, :migration_aborted_in_state, 255
+ end
+
+ def down
+ remove_text_limit :container_repositories, :migration_state
+ remove_text_limit :container_repositories, :migration_aborted_in_state
+ end
+end
diff --git a/db/migrate/20220118141950_add_text_limit_to_container_registry_import_target_plan.rb b/db/migrate/20220118141950_add_text_limit_to_container_registry_import_target_plan.rb
new file mode 100644
index 00000000000..c7247d03423
--- /dev/null
+++ b/db/migrate/20220118141950_add_text_limit_to_container_registry_import_target_plan.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddTextLimitToContainerRegistryImportTargetPlan < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ add_text_limit :application_settings, :container_registry_import_target_plan, 255
+ end
+
+ def down
+ remove_text_limit :application_settings, :container_registry_import_target_plan
+ end
+end
diff --git a/db/migrate/20220118155846_add_runner_token_expiration_interval_settings_to_application_settings.rb b/db/migrate/20220118155846_add_runner_token_expiration_interval_settings_to_application_settings.rb
new file mode 100644
index 00000000000..32ca8a5fb12
--- /dev/null
+++ b/db/migrate/20220118155846_add_runner_token_expiration_interval_settings_to_application_settings.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddRunnerTokenExpirationIntervalSettingsToApplicationSettings < Gitlab::Database::Migration[1.0]
+ def change
+ [:runner_token_expiration_interval, :group_runner_token_expiration_interval, :project_runner_token_expiration_interval].each do |field|
+ add_column :application_settings, field, :integer
+ end
+ end
+end
diff --git a/db/migrate/20220118155847_add_runner_token_expiration_interval_settings_to_namespace_settings.rb b/db/migrate/20220118155847_add_runner_token_expiration_interval_settings_to_namespace_settings.rb
new file mode 100644
index 00000000000..7b83cb2dd55
--- /dev/null
+++ b/db/migrate/20220118155847_add_runner_token_expiration_interval_settings_to_namespace_settings.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class AddRunnerTokenExpirationIntervalSettingsToNamespaceSettings < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def change
+ [:runner_token_expiration_interval, :subgroup_runner_token_expiration_interval, :project_runner_token_expiration_interval].each do |field|
+ add_column :namespace_settings, field, :integer
+ end
+ end
+end
diff --git a/db/migrate/20220118155848_add_runner_token_expiration_interval_settings_to_project_settings.rb b/db/migrate/20220118155848_add_runner_token_expiration_interval_settings_to_project_settings.rb
new file mode 100644
index 00000000000..ef959171828
--- /dev/null
+++ b/db/migrate/20220118155848_add_runner_token_expiration_interval_settings_to_project_settings.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddRunnerTokenExpirationIntervalSettingsToProjectSettings < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def change
+ add_column :project_ci_cd_settings, :runner_token_expiration_interval, :integer
+ end
+end
diff --git a/db/post_migrate/20201211090634_schedule_populate_finding_uuid_for_vulnerability_feedback.rb b/db/post_migrate/20201211090634_schedule_populate_finding_uuid_for_vulnerability_feedback.rb
deleted file mode 100644
index 3ecb48dab0f..00000000000
--- a/db/post_migrate/20201211090634_schedule_populate_finding_uuid_for_vulnerability_feedback.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-class SchedulePopulateFindingUuidForVulnerabilityFeedback < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- MIGRATION_CLASS = 'PopulateFindingUuidForVulnerabilityFeedback'
- DELAY_INTERVAL = 2.minutes
- BATCH_SIZE = 1000
-
- disable_ddl_transaction!
-
- def up
- queue_background_migration_jobs_by_range_at_intervals(
- Gitlab::BackgroundMigration::PopulateFindingUuidForVulnerabilityFeedback::VulnerabilityFeedback,
- MIGRATION_CLASS,
- DELAY_INTERVAL,
- batch_size: BATCH_SIZE
- )
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/post_migrate/20201216185336_add_devops_adoption_snapshot_not_null.rb b/db/post_migrate/20201216185336_add_devops_adoption_snapshot_not_null.rb
deleted file mode 100644
index 1bb3c57f3cd..00000000000
--- a/db/post_migrate/20201216185336_add_devops_adoption_snapshot_not_null.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# frozen_string_literal: true
-
-class AddDevopsAdoptionSnapshotNotNull < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- with_lock_retries do
- execute(
- <<~SQL
- LOCK TABLE analytics_devops_adoption_snapshots IN ACCESS EXCLUSIVE MODE;
-
- UPDATE analytics_devops_adoption_snapshots SET end_time = date_trunc('month', recorded_at) - interval '1 millisecond';
-
- ALTER TABLE analytics_devops_adoption_snapshots ALTER COLUMN end_time SET NOT NULL;
- SQL
- )
- end
- end
-
- def down
- with_lock_retries do
- execute(<<~SQL)
- ALTER TABLE analytics_devops_adoption_snapshots ALTER COLUMN end_time DROP NOT NULL;
- SQL
- end
- end
-end
diff --git a/db/post_migrate/20201217112249_change_pages_deployment_size_to_bigint_cleanup.rb b/db/post_migrate/20201217112249_change_pages_deployment_size_to_bigint_cleanup.rb
deleted file mode 100644
index 4ed29ba61f9..00000000000
--- a/db/post_migrate/20201217112249_change_pages_deployment_size_to_bigint_cleanup.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class ChangePagesDeploymentSizeToBigintCleanup < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- cleanup_concurrent_column_type_change :pages_deployments, :size
- end
-
- def down
- undo_cleanup_concurrent_column_type_change :pages_deployments, :size, :integer, limit: 4
- end
-end
diff --git a/db/post_migrate/20201223012231_reindex_ci_pipelines_on_schedule_id_and_id.rb b/db/post_migrate/20201223012231_reindex_ci_pipelines_on_schedule_id_and_id.rb
deleted file mode 100644
index 9ed1aea911a..00000000000
--- a/db/post_migrate/20201223012231_reindex_ci_pipelines_on_schedule_id_and_id.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-class ReindexCiPipelinesOnScheduleIdAndId < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- OLD_INDEX_NAME = 'index_ci_pipelines_on_pipeline_schedule_id'
- NEW_INDEX_NAME = 'index_ci_pipelines_on_pipeline_schedule_id_and_id'
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :ci_pipelines, [:pipeline_schedule_id, :id], name: NEW_INDEX_NAME
- remove_concurrent_index_by_name :ci_pipelines, OLD_INDEX_NAME
- end
-
- def down
- add_concurrent_index :ci_pipelines, :pipeline_schedule_id, name: OLD_INDEX_NAME
- remove_concurrent_index_by_name :ci_pipelines, NEW_INDEX_NAME
- end
-end
diff --git a/db/post_migrate/20201231133921_schedule_set_default_iteration_cadences.rb b/db/post_migrate/20201231133921_schedule_set_default_iteration_cadences.rb
deleted file mode 100644
index 32645430e19..00000000000
--- a/db/post_migrate/20201231133921_schedule_set_default_iteration_cadences.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# frozen_string_literal: true
-
-class ScheduleSetDefaultIterationCadences < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- BATCH_SIZE = 1_000
- DELAY_INTERVAL = 2.minutes.to_i
- MIGRATION_CLASS = 'SetDefaultIterationCadences'
-
- class Iteration < ActiveRecord::Base # rubocop:disable Style/Documentation
- include EachBatch
-
- self.table_name = 'sprints'
- end
-
- disable_ddl_transaction!
-
- def up
- # Do nothing, rescheduling migration: 20210219102900_reschedule_set_default_iteration_cadences.rb
- end
-
- def down
- # Not needed
- end
-end
diff --git a/db/post_migrate/20210105030125_cleanup_projects_with_bad_has_external_wiki_data.rb b/db/post_migrate/20210105030125_cleanup_projects_with_bad_has_external_wiki_data.rb
deleted file mode 100644
index bc90a5f48ea..00000000000
--- a/db/post_migrate/20210105030125_cleanup_projects_with_bad_has_external_wiki_data.rb
+++ /dev/null
@@ -1,88 +0,0 @@
-# frozen_string_literal: true
-
-class CleanupProjectsWithBadHasExternalWikiData < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- TMP_INDEX_NAME = 'tmp_index_projects_on_id_where_has_external_wiki_is_true'
- BATCH_SIZE = 100
-
- disable_ddl_transaction!
-
- class Service < ActiveRecord::Base
- include EachBatch
- belongs_to :project
-
- self.table_name = 'services'
- self.inheritance_column = :_type_disabled
- end
-
- class Project < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'projects'
- end
-
- def up
- update_projects_with_active_external_wikis
- update_projects_without_active_external_wikis
- end
-
- def down
- # no-op : can't go back to incorrect data
- end
-
- private
-
- def update_projects_with_active_external_wikis
- # 11 projects are scoped in this query on GitLab.com.
- scope = Service.where(active: true, type: 'ExternalWikiService').where.not(project_id: nil)
-
- scope.each_batch(of: BATCH_SIZE) do |relation|
- scope_with_projects = relation
- .joins(:project)
- .select('project_id')
- .merge(Project.where(has_external_wiki: false).where(pending_delete: false).where(archived: false))
-
- execute(<<~SQL)
- WITH project_ids_to_update (id) AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported} (
- #{scope_with_projects.to_sql}
- )
- UPDATE projects SET has_external_wiki = true WHERE id IN (SELECT id FROM project_ids_to_update)
- SQL
- end
- end
-
- def update_projects_without_active_external_wikis
- # Add a temporary index to speed up the scoping of projects.
- index_where = <<~SQL
- (
- "projects"."has_external_wiki" = TRUE
- )
- AND "projects"."pending_delete" = FALSE
- AND "projects"."archived" = FALSE
- SQL
-
- add_concurrent_index(:projects, :id, where: index_where, name: TMP_INDEX_NAME)
-
- services_sub_query = Service
- .select('1')
- .where('services.project_id = projects.id')
- .where(type: 'ExternalWikiService')
- .where(active: true)
-
- # 322 projects are scoped in this query on GitLab.com.
- Project.where(index_where).each_batch(of: BATCH_SIZE) do |relation|
- relation_with_exists_query = relation.where('NOT EXISTS (?)', services_sub_query)
- execute(<<~SQL)
- WITH project_ids_to_update (id) AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported} (
- #{relation_with_exists_query.select(:id).to_sql}
- )
- UPDATE projects SET has_external_wiki = false WHERE id IN (SELECT id FROM project_ids_to_update)
- SQL
- end
-
- # Drop the temporary index.
- remove_concurrent_index_by_name(:projects, TMP_INDEX_NAME)
- end
-end
diff --git a/db/post_migrate/20210105052229_clean_up_asset_proxy_whitelist_rename_on_application_settings.rb b/db/post_migrate/20210105052229_clean_up_asset_proxy_whitelist_rename_on_application_settings.rb
deleted file mode 100644
index 87f391e240d..00000000000
--- a/db/post_migrate/20210105052229_clean_up_asset_proxy_whitelist_rename_on_application_settings.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class CleanUpAssetProxyWhitelistRenameOnApplicationSettings < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers::V2
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- # This migration has been made a no-op in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56352
- # because to revert the rename in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55419 we need
- # to cleanup the triggers on the `asset_proxy_allowlist` column. As such, this migration would do nothing.
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/post_migrate/20210105103649_delete_column_group_id_on_compliance_framework.rb b/db/post_migrate/20210105103649_delete_column_group_id_on_compliance_framework.rb
deleted file mode 100644
index b13d2fe2d0a..00000000000
--- a/db/post_migrate/20210105103649_delete_column_group_id_on_compliance_framework.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class DeleteColumnGroupIdOnComplianceFramework < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def change
- remove_column :compliance_management_frameworks, :group_id, :bigint
- end
-end
diff --git a/db/post_migrate/20210107194543_remove_alerts_service_records.rb b/db/post_migrate/20210107194543_remove_alerts_service_records.rb
deleted file mode 100644
index 51a2f96ac7f..00000000000
--- a/db/post_migrate/20210107194543_remove_alerts_service_records.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveAlertsServiceRecords < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- class Service < ActiveRecord::Base
- self.table_name = 'services'
- end
-
- def up
- Service.delete_by(type: 'AlertsService')
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/post_migrate/20210111075105_schedule_uuid_population_for_security_findings.rb b/db/post_migrate/20210111075105_schedule_uuid_population_for_security_findings.rb
deleted file mode 100644
index 43cfb27b94c..00000000000
--- a/db/post_migrate/20210111075105_schedule_uuid_population_for_security_findings.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-class ScheduleUuidPopulationForSecurityFindings < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- MIGRATION_CLASS = 'PopulateUuidsForSecurityFindings'
- DELAY_INTERVAL = 2.minutes
- BATCH_SIZE = 25
-
- disable_ddl_transaction!
-
- def up
- # no-op, replaced by 20210111075206_schedule_uuid_population_for_security_findings2.rb
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/post_migrate/20210111075206_schedule_uuid_population_for_security_findings2.rb b/db/post_migrate/20210111075206_schedule_uuid_population_for_security_findings2.rb
deleted file mode 100644
index 00569581ca4..00000000000
--- a/db/post_migrate/20210111075206_schedule_uuid_population_for_security_findings2.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-# frozen_string_literal: true
-
-# This replaces the previous post-deployment migration 20210111075105_schedule_uuid_population_for_security_findings.rb,
-# we have to run this again due to a bug in how we were receiving the arguments in the background migration.
-class ScheduleUuidPopulationForSecurityFindings2 < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- MIGRATION_CLASS = 'PopulateUuidsForSecurityFindings'
- DELAY_INTERVAL = 2.minutes
- BATCH_SIZE = 25
-
- disable_ddl_transaction!
-
- def up
- ::Gitlab::BackgroundMigration.steal(MIGRATION_CLASS) do |job|
- job.delete
-
- false
- end
-
- Gitlab::BackgroundMigration::PopulateUuidsForSecurityFindings.security_findings.each_batch(column: :scan_id, of: BATCH_SIZE) do |batch, index|
- migrate_in(
- DELAY_INTERVAL * index,
- MIGRATION_CLASS,
- batch.pluck(:scan_id)
- )
- end
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/post_migrate/20210112143418_remove_duplicate_services2.rb b/db/post_migrate/20210112143418_remove_duplicate_services2.rb
deleted file mode 100644
index 83d92a78473..00000000000
--- a/db/post_migrate/20210112143418_remove_duplicate_services2.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-# This replaces the previous post-deployment migration 20201207165956_remove_duplicate_services_spec.rb,
-# we have to run this again due to a bug in how we were receiving the arguments in the background migration.
-class RemoveDuplicateServices2 < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- INTERVAL = 2.minutes
- BATCH_SIZE = 5_000
- MIGRATION = 'RemoveDuplicateServices'
-
- disable_ddl_transaction!
-
- def up
- project_ids_with_duplicates = Gitlab::BackgroundMigration::RemoveDuplicateServices::Service.project_ids_with_duplicates
-
- project_ids_with_duplicates.each_batch(of: BATCH_SIZE, column: :project_id) do |batch, index|
- migrate_in(
- INTERVAL * index,
- MIGRATION,
- batch.pluck(:project_id)
- )
- end
- end
-
- def down
- end
-end
diff --git a/db/post_migrate/20210115215854_cancel_artifact_expiry_backfill.rb b/db/post_migrate/20210115215854_cancel_artifact_expiry_backfill.rb
deleted file mode 100644
index 8a03a90a1c5..00000000000
--- a/db/post_migrate/20210115215854_cancel_artifact_expiry_backfill.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-class CancelArtifactExpiryBackfill < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- MIGRATION = 'BackfillArtifactExpiryDate'
-
- disable_ddl_transaction!
-
- def up
- Gitlab::BackgroundMigration.steal(MIGRATION) do |job|
- job.delete
-
- false
- end
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/post_migrate/20210115220610_schedule_artifact_expiry_backfill.rb b/db/post_migrate/20210115220610_schedule_artifact_expiry_backfill.rb
deleted file mode 100644
index 4f49e8b75af..00000000000
--- a/db/post_migrate/20210115220610_schedule_artifact_expiry_backfill.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# frozen_string_literal: true
-
-class ScheduleArtifactExpiryBackfill < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- MIGRATION = 'BackfillArtifactExpiryDate'
- SWITCH_DATE = Date.new(2020, 06, 22).freeze
- INDEX_NAME = 'expired_artifacts_temp_index'
- OLD_INDEX_CONDITION = "expire_at IS NULL AND created_at < '#{SWITCH_DATE}'"
- INDEX_CONDITION = "expire_at IS NULL AND date(created_at AT TIME ZONE 'UTC') < '2020-06-22'::date"
-
- disable_ddl_transaction!
-
- class JobArtifact < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'ci_job_artifacts'
-
- scope :without_expiry_date, -> { where(expire_at: nil) }
- scope :before_switch, -> { where("date(created_at AT TIME ZONE 'UTC') < ?::date", SWITCH_DATE) }
- end
-
- def up
- # Create temporary index for expired artifacts
- # Needs to be removed in a later migration
- remove_concurrent_index_by_name :ci_job_artifacts, INDEX_NAME
- add_concurrent_index(:ci_job_artifacts, %i(id created_at), where: INDEX_CONDITION, name: INDEX_NAME)
-
- queue_background_migration_jobs_by_range_at_intervals(
- JobArtifact.without_expiry_date.before_switch,
- MIGRATION,
- 2.minutes,
- batch_size: 200_000
- )
- end
-
- def down
- remove_concurrent_index_by_name :ci_job_artifacts, INDEX_NAME
- add_concurrent_index(:ci_job_artifacts, %i(id created_at), where: OLD_INDEX_CONDITION, name: INDEX_NAME)
-
- Gitlab::BackgroundMigration.steal(MIGRATION) do |job|
- job.delete
-
- false
- end
- end
-end
diff --git a/db/post_migrate/20210119122354_alter_vsa_issue_first_mentioned_in_commit_value.rb b/db/post_migrate/20210119122354_alter_vsa_issue_first_mentioned_in_commit_value.rb
deleted file mode 100644
index 132d72e180b..00000000000
--- a/db/post_migrate/20210119122354_alter_vsa_issue_first_mentioned_in_commit_value.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-# frozen_string_literal: true
-
-class AlterVsaIssueFirstMentionedInCommitValue < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- ISSUE_FIRST_MENTIONED_IN_COMMIT_FOSS = 2
- ISSUE_FIRST_MENTIONED_IN_COMMIT_EE = 6
-
- class GroupStage < ActiveRecord::Base
- self.table_name = 'analytics_cycle_analytics_group_stages'
-
- include EachBatch
- end
-
- def up
- GroupStage.each_batch(of: 100) do |relation|
- relation
- .where(start_event_identifier: ISSUE_FIRST_MENTIONED_IN_COMMIT_EE)
- .update_all(start_event_identifier: ISSUE_FIRST_MENTIONED_IN_COMMIT_FOSS)
-
- relation
- .where(end_event_identifier: ISSUE_FIRST_MENTIONED_IN_COMMIT_EE)
- .update_all(end_event_identifier: ISSUE_FIRST_MENTIONED_IN_COMMIT_FOSS)
- end
- end
-
- def down
- # rollback is not needed, the identifier "6" is the same as identifier "2" on the application level
- end
-end
diff --git a/db/post_migrate/20210203143131_migrate_existing_devops_segments_to_groups.rb b/db/post_migrate/20210203143131_migrate_existing_devops_segments_to_groups.rb
deleted file mode 100644
index 5267e0fd658..00000000000
--- a/db/post_migrate/20210203143131_migrate_existing_devops_segments_to_groups.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-# Data migration to migrate multi-selection segments into separate segments.
-# Both tables involved are pretty-low traffic and the number
-# of records in DB cannot exceed 400
-class MigrateExistingDevopsSegmentsToGroups < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def up
- Gitlab::BackgroundMigration::MigrateDevopsSegmentsToGroups.new.perform
- end
-
- def down
- end
-end
diff --git a/db/post_migrate/20210205104425_add_new_post_eoa_plans.rb b/db/post_migrate/20210205104425_add_new_post_eoa_plans.rb
deleted file mode 100644
index d1a5afbd314..00000000000
--- a/db/post_migrate/20210205104425_add_new_post_eoa_plans.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-class AddNewPostEoaPlans < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def up
- execute "INSERT INTO plans (name, title, created_at, updated_at) VALUES ('premium', 'Premium (Formerly Silver)', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)"
- execute "INSERT INTO plans (name, title, created_at, updated_at) VALUES ('ultimate', 'Ultimate (Formerly Gold)', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)"
- end
-
- def down
- execute "DELETE FROM plans WHERE name IN ('premium', 'ultimate')"
- end
-end
diff --git a/db/post_migrate/20210205144537_remove_namespace_onboarding_actions_table.rb b/db/post_migrate/20210205144537_remove_namespace_onboarding_actions_table.rb
deleted file mode 100644
index 210b1d7822c..00000000000
--- a/db/post_migrate/20210205144537_remove_namespace_onboarding_actions_table.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveNamespaceOnboardingActionsTable < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- drop_table :namespace_onboarding_actions
- end
- end
-
- def down
- with_lock_retries do
- create_table :namespace_onboarding_actions do |t|
- t.references :namespace, index: true, null: false
- t.datetime_with_timezone :created_at, null: false
- t.integer :action, limit: 2, null: false
- end
- end
- end
-end
diff --git a/db/post_migrate/20210205174154_remove_bad_dependency_proxy_manifests.rb b/db/post_migrate/20210205174154_remove_bad_dependency_proxy_manifests.rb
deleted file mode 100644
index eb302fb7009..00000000000
--- a/db/post_migrate/20210205174154_remove_bad_dependency_proxy_manifests.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveBadDependencyProxyManifests < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def up
- # We run destroy on each record because we need the callback to remove
- # the underlying files
- DependencyProxy::Manifest.where.not(content_type: nil).destroy_all # rubocop:disable Cop/DestroyAll
- end
-
- def down
- # no op
- end
-end
diff --git a/db/post_migrate/20210205213933_drop_alerts_service_data.rb b/db/post_migrate/20210205213933_drop_alerts_service_data.rb
deleted file mode 100644
index 6ad6c90290e..00000000000
--- a/db/post_migrate/20210205213933_drop_alerts_service_data.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# frozen_string_literal: true
-
-class DropAlertsServiceData < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- with_lock_retries do
- drop_table :alerts_service_data
- end
- end
-
- # rubocop:disable Migration/PreventStrings
- def down
- with_lock_retries do
- create_table :alerts_service_data do |t|
- t.bigint :service_id, null: false
- t.timestamps_with_timezone
- t.string :encrypted_token, limit: 255
- t.string :encrypted_token_iv, limit: 255
- end
- end
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/post_migrate/20210205214003_remove_alerts_service_records_again.rb b/db/post_migrate/20210205214003_remove_alerts_service_records_again.rb
deleted file mode 100644
index aabc6fc00cd..00000000000
--- a/db/post_migrate/20210205214003_remove_alerts_service_records_again.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveAlertsServiceRecordsAgain < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- class Service < ActiveRecord::Base
- self.table_name = 'services'
- end
-
- def up
- Service.delete_by(type: 'AlertsService')
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/post_migrate/20210210093901_backfill_updated_at_after_repository_storage_move.rb b/db/post_migrate/20210210093901_backfill_updated_at_after_repository_storage_move.rb
deleted file mode 100644
index efd0eeb9d47..00000000000
--- a/db/post_migrate/20210210093901_backfill_updated_at_after_repository_storage_move.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-# frozen_string_literal: true
-
-class BackfillUpdatedAtAfterRepositoryStorageMove < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- BATCH_SIZE = 10_000
- INTERVAL = 2.minutes
- MIGRATION_CLASS = 'BackfillProjectUpdatedAtAfterRepositoryStorageMove'
-
- disable_ddl_transaction!
-
- class RepositoryStorageMove < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'project_repository_storage_moves'
- end
-
- def up
- RepositoryStorageMove.reset_column_information
-
- RepositoryStorageMove.select(:project_id).distinct.each_batch(of: BATCH_SIZE, column: :project_id) do |batch, index|
- migrate_in(
- INTERVAL * index,
- MIGRATION_CLASS,
- batch.pluck(:project_id)
- )
- end
- end
-
- def down
- # No-op
- end
-end
diff --git a/db/post_migrate/20210210221006_cleanup_projects_with_bad_has_external_issue_tracker_data.rb b/db/post_migrate/20210210221006_cleanup_projects_with_bad_has_external_issue_tracker_data.rb
deleted file mode 100644
index 7b17faeb4b4..00000000000
--- a/db/post_migrate/20210210221006_cleanup_projects_with_bad_has_external_issue_tracker_data.rb
+++ /dev/null
@@ -1,84 +0,0 @@
-# frozen_string_literal: true
-
-class CleanupProjectsWithBadHasExternalIssueTrackerData < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- TMP_INDEX_NAME = 'tmp_idx_projects_on_id_where_has_external_issue_tracker_is_true'
- BATCH_SIZE = 100
-
- disable_ddl_transaction!
-
- class Service < ActiveRecord::Base
- include EachBatch
- belongs_to :project
-
- self.table_name = 'services'
- self.inheritance_column = :_type_disabled
- end
-
- class Project < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'projects'
- end
-
- def up
- update_projects_with_active_external_issue_trackers
- update_projects_without_active_external_issue_trackers
- end
-
- def down
- # no-op : can't go back to incorrect data
- end
-
- private
-
- def update_projects_with_active_external_issue_trackers
- scope = Service.where(active: true, category: 'issue_tracker').where.not(project_id: nil).distinct(:project_id)
-
- scope.each_batch(of: BATCH_SIZE) do |relation|
- scope_with_projects = relation
- .joins(:project)
- .select('project_id')
- .merge(Project.where(has_external_issue_tracker: false).where(pending_delete: false))
-
- execute(<<~SQL)
- WITH project_ids_to_update (id) AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported} (
- #{scope_with_projects.to_sql}
- )
- UPDATE projects SET has_external_issue_tracker = true WHERE id IN (SELECT id FROM project_ids_to_update)
- SQL
- end
- end
-
- def update_projects_without_active_external_issue_trackers
- # Add a temporary index to speed up the scoping of projects.
- index_where = <<~SQL
- "projects"."has_external_issue_tracker" = TRUE
- AND "projects"."pending_delete" = FALSE
- SQL
-
- add_concurrent_index(:projects, :id, where: index_where, name: TMP_INDEX_NAME)
-
- services_sub_query = Service
- .select('1')
- .where('services.project_id = projects.id')
- .where(category: 'issue_tracker')
- .where(active: true)
-
- # 322 projects are scoped in this query on GitLab.com.
- Project.where(index_where).each_batch(of: BATCH_SIZE) do |relation|
- relation_with_exists_query = relation.where('NOT EXISTS (?)', services_sub_query)
- execute(<<~SQL)
- WITH project_ids_to_update (id) AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported} (
- #{relation_with_exists_query.select(:id).to_sql}
- )
- UPDATE projects SET has_external_issue_tracker = false WHERE id IN (SELECT id FROM project_ids_to_update)
- SQL
- end
-
- # Drop the temporary index.
- remove_concurrent_index_by_name(:projects, TMP_INDEX_NAME)
- end
-end
diff --git a/db/post_migrate/20210215095328_migrate_delayed_project_removal_from_namespaces_to_namespace_settings.rb b/db/post_migrate/20210215095328_migrate_delayed_project_removal_from_namespaces_to_namespace_settings.rb
deleted file mode 100644
index 12e156d3b8a..00000000000
--- a/db/post_migrate/20210215095328_migrate_delayed_project_removal_from_namespaces_to_namespace_settings.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# frozen_string_literal: true
-
-class MigrateDelayedProjectRemovalFromNamespacesToNamespaceSettings < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- class Namespace < ActiveRecord::Base
- self.table_name = 'namespaces'
-
- include ::EachBatch
- end
-
- def up
- Namespace.select(:id).where(delayed_project_removal: true).each_batch do |batch|
- values = batch.map { |record| "(#{record.id}, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)" }
-
- execute <<-EOF.strip_heredoc
- INSERT INTO namespace_settings (namespace_id, delayed_project_removal, created_at, updated_at)
- VALUES #{values.join(', ')}
- ON CONFLICT (namespace_id) DO UPDATE
- SET delayed_project_removal = TRUE
- EOF
- end
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/post_migrate/20210215144909_migrate_usage_trends_sidekiq_queue.rb b/db/post_migrate/20210215144909_migrate_usage_trends_sidekiq_queue.rb
deleted file mode 100644
index 3e6eabfba97..00000000000
--- a/db/post_migrate/20210215144909_migrate_usage_trends_sidekiq_queue.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class MigrateUsageTrendsSidekiqQueue < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- sidekiq_queue_migrate 'cronjob:analytics_instance_statistics_count_job_trigger', to: 'cronjob:analytics_usage_trends_count_job_trigger'
- sidekiq_queue_migrate 'analytics_instance_statistics_counter_job', to: 'analytics_usage_trends_counter_job'
- end
-
- def down
- sidekiq_queue_migrate 'cronjob:analytics_usage_trends_count_job_trigger', to: 'cronjob:analytics_instance_statistics_count_job_trigger'
- sidekiq_queue_migrate 'analytics_usage_trends_counter_job', to: 'analytics_instance_statistics_counter_job'
- end
-end
diff --git a/db/post_migrate/20210217100728_move_create_release_evidence_queue_out_of_cronjob_namespace.rb b/db/post_migrate/20210217100728_move_create_release_evidence_queue_out_of_cronjob_namespace.rb
deleted file mode 100644
index 22bead87dc1..00000000000
--- a/db/post_migrate/20210217100728_move_create_release_evidence_queue_out_of_cronjob_namespace.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-class MoveCreateReleaseEvidenceQueueOutOfCronjobNamespace < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- def up
- sidekiq_queue_migrate 'cronjob:releases_create_evidence', to: 'releases_create_evidence'
- end
-
- def down
- sidekiq_queue_migrate 'releases_create_evidence', to: 'cronjob:releases_create_evidence'
- end
-end
diff --git a/db/post_migrate/20210218105431_remove_deprecated_ci_builds_columns.rb b/db/post_migrate/20210218105431_remove_deprecated_ci_builds_columns.rb
deleted file mode 100644
index 6fa7a15a90d..00000000000
--- a/db/post_migrate/20210218105431_remove_deprecated_ci_builds_columns.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveDeprecatedCiBuildsColumns < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- with_lock_retries do
- remove_column :ci_builds, :artifacts_file
- remove_column :ci_builds, :artifacts_file_store
- remove_column :ci_builds, :artifacts_metadata
- remove_column :ci_builds, :artifacts_metadata_store
- remove_column :ci_builds, :artifacts_size
- remove_column :ci_builds, :commands
- end
- end
-
- def down
- # rubocop:disable Migration/AddColumnsToWideTables
- with_lock_retries do
- add_column :ci_builds, :artifacts_file, :text
- add_column :ci_builds, :artifacts_file_store, :integer
- add_column :ci_builds, :artifacts_metadata, :text
- add_column :ci_builds, :artifacts_metadata_store, :integer
- add_column :ci_builds, :artifacts_size, :bigint
- add_column :ci_builds, :commands, :text
- end
- # rubocop:enable Migration/AddColumnsToWideTables
-
- add_concurrent_index :ci_builds, :artifacts_expire_at, where: "artifacts_file <> ''::text", name: 'index_ci_builds_on_artifacts_expire_at'
- end
-end
diff --git a/db/post_migrate/20210218110552_remove_deprecated_ci_runner_column.rb b/db/post_migrate/20210218110552_remove_deprecated_ci_runner_column.rb
deleted file mode 100644
index 06fd900590b..00000000000
--- a/db/post_migrate/20210218110552_remove_deprecated_ci_runner_column.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveDeprecatedCiRunnerColumn < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- with_lock_retries do
- remove_column :ci_runners, :is_shared
- end
- end
-
- def down
- add_column :ci_runners, :is_shared, :boolean, default: false unless column_exists?(:ci_runners, :is_shared)
-
- add_concurrent_index :ci_runners, :is_shared
- end
-end
diff --git a/db/post_migrate/20210219102900_reschedule_set_default_iteration_cadences.rb b/db/post_migrate/20210219102900_reschedule_set_default_iteration_cadences.rb
deleted file mode 100644
index 6c7b46737aa..00000000000
--- a/db/post_migrate/20210219102900_reschedule_set_default_iteration_cadences.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-class RescheduleSetDefaultIterationCadences < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- BATCH_SIZE = 1_000
- DELAY_INTERVAL = 2.minutes.to_i
- MIGRATION_CLASS = 'SetDefaultIterationCadences'
-
- class Iteration < ActiveRecord::Base # rubocop:disable Style/Documentation
- include EachBatch
-
- self.table_name = 'sprints'
- end
-
- disable_ddl_transaction!
-
- def up
- Iteration.select(:group_id).distinct.each_batch(of: BATCH_SIZE, column: :group_id) do |batch, index|
- group_ids = batch.pluck(:group_id)
-
- migrate_in(index * DELAY_INTERVAL, MIGRATION_CLASS, group_ids)
- end
- end
-
- def down
- # Not needed
- end
-end
diff --git a/db/post_migrate/20210222185538_remove_backup_labels_foreign_keys.rb b/db/post_migrate/20210222185538_remove_backup_labels_foreign_keys.rb
deleted file mode 100644
index 614ec4875d6..00000000000
--- a/db/post_migrate/20210222185538_remove_backup_labels_foreign_keys.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveBackupLabelsForeignKeys < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- with_lock_retries do
- remove_foreign_key_if_exists(:backup_labels, :projects)
- remove_foreign_key_if_exists(:backup_labels, :namespaces)
- end
- end
-
- def down
- add_concurrent_foreign_key(:backup_labels, :projects, column: :project_id, on_delete: :cascade)
- add_concurrent_foreign_key(:backup_labels, :namespaces, column: :group_id, on_delete: :cascade)
- end
-end
diff --git a/db/post_migrate/20210222192144_remove_backup_labels_table.rb b/db/post_migrate/20210222192144_remove_backup_labels_table.rb
deleted file mode 100644
index 1208c3c970f..00000000000
--- a/db/post_migrate/20210222192144_remove_backup_labels_table.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveBackupLabelsTable < ActiveRecord::Migration[6.0]
- DOWNTIME = false
-
- def up
- drop_table :backup_labels
- end
-
- def down
- create_table :backup_labels, id: false do |t|
- t.integer :id, null: false
- t.string :title
- t.string :color
- t.integer :project_id
- t.timestamps null: true # rubocop:disable Migration/Timestamps
- t.boolean :template, default: false
- t.string :description
- t.text :description_html
- t.string :type
- t.integer :group_id
- t.integer :cached_markdown_version
- t.integer :restore_action
- t.string :new_title
- end
-
- execute 'ALTER TABLE backup_labels ADD PRIMARY KEY (id)'
-
- add_index :backup_labels, [:group_id, :project_id, :title], name: 'backup_labels_group_id_project_id_title_idx', unique: true
- add_index :backup_labels, [:group_id, :title], where: 'project_id = NULL::integer', name: 'backup_labels_group_id_title_idx'
- add_index :backup_labels, :project_id, name: 'backup_labels_project_id_idx'
- add_index :backup_labels, :template, name: 'backup_labels_template_idx', where: 'template'
- add_index :backup_labels, :title, name: 'backup_labels_title_idx'
- add_index :backup_labels, [:type, :project_id], name: 'backup_labels_type_project_id_idx'
- end
-end
diff --git a/db/post_migrate/20210224150506_reschedule_artifact_expiry_backfill.rb b/db/post_migrate/20210224150506_reschedule_artifact_expiry_backfill.rb
deleted file mode 100644
index 2c0fe405490..00000000000
--- a/db/post_migrate/20210224150506_reschedule_artifact_expiry_backfill.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-
-class RescheduleArtifactExpiryBackfill < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- MIGRATION = 'BackfillArtifactExpiryDate'
- SWITCH_DATE = Date.new(2020, 06, 22).freeze
-
- disable_ddl_transaction!
-
- class JobArtifact < ActiveRecord::Base
- include EachBatch
-
- self.inheritance_column = :_type_disabled
- self.table_name = 'ci_job_artifacts'
-
- scope :without_expiry_date, -> { where(expire_at: nil) }
- scope :before_switch, -> { where("date(created_at AT TIME ZONE 'UTC') < ?::date", SWITCH_DATE) }
- end
-
- def up
- Gitlab::BackgroundMigration.steal(MIGRATION) do |job|
- job.delete
-
- false
- end
-
- queue_background_migration_jobs_by_range_at_intervals(
- JobArtifact.without_expiry_date.before_switch,
- MIGRATION,
- 2.minutes,
- batch_size: 200_000
- )
- end
-
- def down
- Gitlab::BackgroundMigration.steal(MIGRATION) do |job|
- job.delete
-
- false
- end
- end
-end
diff --git a/db/post_migrate/20210226120851_move_container_registry_enabled_to_project_features.rb b/db/post_migrate/20210226120851_move_container_registry_enabled_to_project_features.rb
deleted file mode 100644
index fce31110866..00000000000
--- a/db/post_migrate/20210226120851_move_container_registry_enabled_to_project_features.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# frozen_string_literal: true
-
-class MoveContainerRegistryEnabledToProjectFeatures < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- BATCH_SIZE = 50_000
- MIGRATION = 'MoveContainerRegistryEnabledToProjectFeature'
-
- disable_ddl_transaction!
-
- class Project < ActiveRecord::Base
- include EachBatch
- self.table_name = 'projects'
- end
-
- def up
- # no-op
- # Superceded by db/post_migrate/20210401131948_move_container_registry_enabled_to_project_features2.rb
-
- # queue_background_migration_jobs_by_range_at_intervals(Project, MIGRATION, 2.minutes, batch_size: BATCH_SIZE)
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/post_migrate/20210226141517_dedup_issue_metrics.rb b/db/post_migrate/20210226141517_dedup_issue_metrics.rb
deleted file mode 100644
index 8228d509e07..00000000000
--- a/db/post_migrate/20210226141517_dedup_issue_metrics.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-# frozen_string_literal: true
-
-class DedupIssueMetrics < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- TMP_INDEX_NAME = 'tmp_unique_issue_metrics_by_issue_id'
- OLD_INDEX_NAME = 'index_issue_metrics'
- INDEX_NAME = 'index_unique_issue_metrics_issue_id'
- BATCH_SIZE = 1_000
-
- disable_ddl_transaction!
-
- class IssueMetrics < ActiveRecord::Base
- self.table_name = 'issue_metrics'
-
- include EachBatch
- end
-
- def up
- IssueMetrics.reset_column_information
-
- last_metrics_record_id = IssueMetrics.maximum(:id) || 0
-
- # This index will disallow further duplicates while we're deduplicating the data.
- add_concurrent_index(:issue_metrics, :issue_id, where: "id > #{Integer(last_metrics_record_id)}", unique: true, name: TMP_INDEX_NAME)
-
- IssueMetrics.each_batch(of: BATCH_SIZE) do |relation|
- duplicated_issue_ids = IssueMetrics
- .where(issue_id: relation.select(:issue_id))
- .select(:issue_id)
- .group(:issue_id)
- .having('COUNT(issue_metrics.issue_id) > 1')
- .pluck(:issue_id)
-
- duplicated_issue_ids.each do |issue_id|
- deduplicate_item(issue_id)
- end
- end
-
- add_concurrent_index(:issue_metrics, :issue_id, unique: true, name: INDEX_NAME)
- remove_concurrent_index_by_name(:issue_metrics, TMP_INDEX_NAME)
- remove_concurrent_index_by_name(:issue_metrics, OLD_INDEX_NAME)
- end
-
- def down
- add_concurrent_index(:issue_metrics, :issue_id, name: OLD_INDEX_NAME)
- remove_concurrent_index_by_name(:issue_metrics, TMP_INDEX_NAME)
- remove_concurrent_index_by_name(:issue_metrics, INDEX_NAME)
- end
-
- private
-
- def deduplicate_item(issue_id)
- issue_metrics_records = IssueMetrics.where(issue_id: issue_id).order(updated_at: :asc).to_a
-
- attributes = {}
- issue_metrics_records.each do |issue_metrics_record|
- params = issue_metrics_record.attributes.except('id')
- attributes.merge!(params.compact)
- end
-
- ActiveRecord::Base.transaction do
- record_to_keep = issue_metrics_records.pop
- records_to_delete = issue_metrics_records
-
- IssueMetrics.where(id: records_to_delete.map(&:id)).delete_all
- record_to_keep.update!(attributes)
- end
- end
-end
diff --git a/db/post_migrate/20210301200959_clean_up_asset_proxy_allowlist_rename_on_application_settings.rb b/db/post_migrate/20210301200959_clean_up_asset_proxy_allowlist_rename_on_application_settings.rb
deleted file mode 100644
index d0b372b84f0..00000000000
--- a/db/post_migrate/20210301200959_clean_up_asset_proxy_allowlist_rename_on_application_settings.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-class CleanUpAssetProxyAllowlistRenameOnApplicationSettings < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers::V2
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- cleanup_concurrent_column_rename :application_settings,
- :asset_proxy_allowlist,
- :asset_proxy_whitelist
- end
-
- def down
- undo_cleanup_concurrent_column_rename :application_settings,
- :asset_proxy_allowlist,
- :asset_proxy_whitelist
- end
-end
diff --git a/db/post_migrate/20210426225417_schedule_recalculate_uuid_on_vulnerabilities_occurrences2.rb b/db/post_migrate/20210426225417_schedule_recalculate_uuid_on_vulnerabilities_occurrences2.rb
index 96eea2d5d77..0e85fb40a36 100644
--- a/db/post_migrate/20210426225417_schedule_recalculate_uuid_on_vulnerabilities_occurrences2.rb
+++ b/db/post_migrate/20210426225417_schedule_recalculate_uuid_on_vulnerabilities_occurrences2.rb
@@ -1,34 +1,9 @@
# frozen_string_literal: true
class ScheduleRecalculateUuidOnVulnerabilitiesOccurrences2 < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- MIGRATION = 'RecalculateVulnerabilitiesOccurrencesUuid'
- DELAY_INTERVAL = 2.minutes.to_i
- BATCH_SIZE = 2_500
-
- disable_ddl_transaction!
-
- class VulnerabilitiesFinding < ActiveRecord::Base
- include ::EachBatch
- self.inheritance_column = :_type_disabled
-
- self.table_name = "vulnerability_occurrences"
- end
-
def up
- # Make sure that RemoveDuplicateVulnerabilitiesFindings has finished running
- # so that we don't run into duplicate UUID issues
- Gitlab::BackgroundMigration.steal('RemoveDuplicateVulnerabilitiesFindings')
-
- say "Scheduling #{MIGRATION} jobs"
- queue_background_migration_jobs_by_range_at_intervals(
- VulnerabilitiesFinding,
- MIGRATION,
- DELAY_INTERVAL,
- batch_size: BATCH_SIZE,
- track_jobs: true
- )
+ # no-op
+ # superseded by db/post_migrate/20211207125231_schedule_recalculate_uuid_on_vulnerabilities_occurrences4.rb
end
def down
diff --git a/db/post_migrate/20210813195518_schedule_recalculate_uuid_on_vulnerabilities_occurrences3.rb b/db/post_migrate/20210813195518_schedule_recalculate_uuid_on_vulnerabilities_occurrences3.rb
index c59c71708ca..0e6f1c50534 100644
--- a/db/post_migrate/20210813195518_schedule_recalculate_uuid_on_vulnerabilities_occurrences3.rb
+++ b/db/post_migrate/20210813195518_schedule_recalculate_uuid_on_vulnerabilities_occurrences3.rb
@@ -1,27 +1,9 @@
# frozen_string_literal: true
class ScheduleRecalculateUuidOnVulnerabilitiesOccurrences3 < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
- MIGRATION = 'RecalculateVulnerabilitiesOccurrencesUuid'
- DELAY_INTERVAL = 2.minutes.to_i
- BATCH_SIZE = 2_500
-
- disable_ddl_transaction!
-
def up
- # Make sure that RemoveDuplicateVulnerabilitiesFindings has finished running
- # so that we don't run into duplicate UUID issues
- Gitlab::BackgroundMigration.steal('RemoveDuplicateVulnerabilitiesFindings')
-
- say "Scheduling #{MIGRATION} jobs"
- queue_background_migration_jobs_by_range_at_intervals(
- define_batchable_model('vulnerability_occurrences'),
- MIGRATION,
- DELAY_INTERVAL,
- batch_size: BATCH_SIZE,
- track_jobs: true
- )
+ # no-op
+ # superseded by db/post_migrate/20211207125231_schedule_recalculate_uuid_on_vulnerabilities_occurrences4.rb
end
def down
diff --git a/db/post_migrate/20210918202855_reschedule_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid.rb b/db/post_migrate/20210918202855_reschedule_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid.rb
index 88351b3007a..c03c379dcc0 100644
--- a/db/post_migrate/20210918202855_reschedule_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid.rb
+++ b/db/post_migrate/20210918202855_reschedule_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid.rb
@@ -1,15 +1,9 @@
# frozen_string_literal: true
class ReschedulePendingJobsForRecalculateVulnerabilitiesOccurrencesUuid < Gitlab::Database::Migration[1.0]
- MIGRATION = "RecalculateVulnerabilitiesOccurrencesUuid"
- DELAY_INTERVAL = 2.minutes
-
- disable_ddl_transaction!
-
def up
- delete_queued_jobs(MIGRATION)
-
- requeue_background_migration_jobs_by_range_at_intervals(MIGRATION, DELAY_INTERVAL)
+ # no-op
+ # no replacement because we will reschedule this for the whole table
end
def down
diff --git a/db/post_migrate/20211123161906_cleanup_after_drop_invalid_security_findings.rb b/db/post_migrate/20211123161906_cleanup_after_drop_invalid_security_findings.rb
new file mode 100644
index 00000000000..599342e83e3
--- /dev/null
+++ b/db/post_migrate/20211123161906_cleanup_after_drop_invalid_security_findings.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class CleanupAfterDropInvalidSecurityFindings < Gitlab::Database::Migration[1.0]
+ MIGRATION = "DropInvalidSecurityFindings"
+ INDEX_NAME = "tmp_index_uuid_is_null"
+
+ disable_ddl_transaction!
+
+ def up
+ # Make sure all jobs scheduled by
+ # db/post_migrate/20211110151350_schedule_drop_invalid_security_findings.rb
+ # are finished
+ finalize_background_migration(MIGRATION)
+ # Created by db/post_migrate/20211110151320_add_temporary_index_on_security_findings_uuid.rb
+ remove_concurrent_index_by_name :security_findings, INDEX_NAME
+ end
+
+ def down
+ add_concurrent_index(
+ :security_findings,
+ :id,
+ where: "uuid IS NULL",
+ name: INDEX_NAME
+ )
+ end
+end
diff --git a/db/post_migrate/20211206161271_add_indexes_for_primary_email_cleanup_migration.rb b/db/post_migrate/20211206161271_add_indexes_for_primary_email_cleanup_migration.rb
new file mode 100644
index 00000000000..0e370dfc5f8
--- /dev/null
+++ b/db/post_migrate/20211206161271_add_indexes_for_primary_email_cleanup_migration.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class AddIndexesForPrimaryEmailCleanupMigration < Gitlab::Database::Migration[1.0]
+ USERS_INDEX = :index_users_on_id_for_primary_email_migration
+ EMAIL_INDEX = :index_emails_on_email_user_id
+
+ disable_ddl_transaction!
+
+ def up
+ unless index_exists_by_name?(:users, USERS_INDEX)
+
+ disable_statement_timeout do
+ execute <<~SQL
+ CREATE INDEX CONCURRENTLY #{USERS_INDEX}
+ ON users (id) INCLUDE (email, confirmed_at)
+ WHERE confirmed_at IS NOT NULL
+ SQL
+ end
+ end
+
+ add_concurrent_index :emails, [:email, :user_id], name: EMAIL_INDEX
+ end
+
+ def down
+ remove_concurrent_index_by_name :users, USERS_INDEX
+ remove_concurrent_index_by_name :emails, EMAIL_INDEX
+ end
+end
diff --git a/db/post_migrate/20211206162601_cleanup_after_add_primary_email_to_emails_if_user_confirmed.rb b/db/post_migrate/20211206162601_cleanup_after_add_primary_email_to_emails_if_user_confirmed.rb
new file mode 100644
index 00000000000..14f6c751e4d
--- /dev/null
+++ b/db/post_migrate/20211206162601_cleanup_after_add_primary_email_to_emails_if_user_confirmed.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+class CleanupAfterAddPrimaryEmailToEmailsIfUserConfirmed < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ MIGRATION_NAME = 'AddPrimaryEmailToEmailsIfUserConfirmed'
+ BATCH_SIZE = 10_000
+
+ # Stubbed class to access the User table
+ class User < ActiveRecord::Base
+ include ::EachBatch
+
+ self.table_name = 'users'
+ self.inheritance_column = :_type_disabled
+
+ scope :confirmed, -> { where.not(confirmed_at: nil) }
+
+ has_many :emails
+ end
+
+ # Stubbed class to access the Emails table
+ class Email < ActiveRecord::Base
+ self.table_name = 'emails'
+ self.inheritance_column = :_type_disabled
+
+ belongs_to :user
+ end
+
+ def up
+ finalize_background_migration(MIGRATION_NAME)
+
+ # Select confirmed users that do not have their primary email in the emails table,
+ # and create the email record. There should be none if the background migration
+ # completed, but in case there is any leftover, we deal with it synchronously.
+ not_exists_condition = 'NOT EXISTS (SELECT 1 FROM emails WHERE emails.email = users.email AND emails.user_id = users.id)'
+
+ User.confirmed.each_batch(of: BATCH_SIZE) do |user_batch|
+ user_batch.select(:id, :email, :confirmed_at).where(not_exists_condition).each do |user|
+ current_time = Time.now.utc
+
+ begin
+ Email.create(
+ user_id: user.id,
+ email: user.email,
+ confirmed_at: user.confirmed_at,
+ created_at: current_time,
+ updated_at: current_time
+ )
+ rescue StandardError => error
+ Gitlab::AppLogger.error("Could not add primary email #{user.email} to emails for user with ID #{user.id} due to #{error}")
+ end
+ end
+ end
+ end
+
+ def down
+ # Intentionally left blank
+ end
+end
diff --git a/db/post_migrate/20211207081708_add_index_ci_job_artifacts_project_id_file_type.rb b/db/post_migrate/20211207081708_add_index_ci_job_artifacts_project_id_file_type.rb
new file mode 100644
index 00000000000..959bf61a6cc
--- /dev/null
+++ b/db/post_migrate/20211207081708_add_index_ci_job_artifacts_project_id_file_type.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexCiJobArtifactsProjectIdFileType < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_ci_job_artifacts_on_id_project_id_and_file_type'
+
+ def up
+ add_concurrent_index :ci_job_artifacts, [:project_id, :file_type, :id], name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :ci_job_artifacts, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid.rb b/db/post_migrate/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid.rb
new file mode 100644
index 00000000000..cc37f2dc65d
--- /dev/null
+++ b/db/post_migrate/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class RemoveJobsForRecalculateVulnerabilitiesOccurrencesUuid < Gitlab::Database::Migration[1.0]
+ MIGRATION_NAME = 'RecalculateVulnerabilitiesOccurrencesUuid'
+
+ def up
+ delete_job_tracking(
+ MIGRATION_NAME,
+ status: %w[pending succeeded]
+ )
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4.rb b/db/post_migrate/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4.rb
new file mode 100644
index 00000000000..13abf8b5540
--- /dev/null
+++ b/db/post_migrate/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class ScheduleRecalculateUuidOnVulnerabilitiesOccurrences4 < Gitlab::Database::Migration[1.0]
+ MIGRATION = 'RecalculateVulnerabilitiesOccurrencesUuid'
+ DELAY_INTERVAL = 2.minutes.to_i
+ BATCH_SIZE = 2_500
+
+ disable_ddl_transaction!
+
+ def up
+ # Make sure the migration removing Findings with attributes for which UUID would be identical
+ # has finished
+ # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74008
+ Gitlab::BackgroundMigration.steal('RemoveOccurrencePipelinesAndDuplicateVulnerabilitiesFindings')
+
+ queue_background_migration_jobs_by_range_at_intervals(
+ define_batchable_model('vulnerability_occurrences'),
+ MIGRATION,
+ DELAY_INTERVAL,
+ batch_size: BATCH_SIZE,
+ track_jobs: true
+ )
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20211207173510_remove_extra_finding_evidence_tables_foreign_keys.rb b/db/post_migrate/20211207173510_remove_extra_finding_evidence_tables_foreign_keys.rb
new file mode 100644
index 00000000000..eaf07abe29d
--- /dev/null
+++ b/db/post_migrate/20211207173510_remove_extra_finding_evidence_tables_foreign_keys.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+class RemoveExtraFindingEvidenceTablesForeignKeys < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ remove_foreign_key :vulnerability_finding_evidence_assets, :vulnerability_finding_evidences
+ remove_foreign_key :vulnerability_finding_evidence_headers, :vulnerability_finding_evidence_requests
+ remove_foreign_key :vulnerability_finding_evidence_headers, :vulnerability_finding_evidence_responses
+ remove_foreign_key :vulnerability_finding_evidence_requests, :vulnerability_finding_evidences
+ remove_foreign_key :vulnerability_finding_evidence_requests, :vulnerability_finding_evidence_supporting_messages
+ remove_foreign_key :vulnerability_finding_evidence_responses, :vulnerability_finding_evidences
+ remove_foreign_key :vulnerability_finding_evidence_responses, :vulnerability_finding_evidence_supporting_messages
+ remove_foreign_key :vulnerability_finding_evidence_sources, :vulnerability_finding_evidences
+ remove_foreign_key :vulnerability_finding_evidence_supporting_messages, :vulnerability_finding_evidences
+ end
+ end
+
+ def down
+ with_lock_retries do
+ add_foreign_key :vulnerability_finding_evidence_assets, :vulnerability_finding_evidences, on_delete: :cascade
+ end
+
+ with_lock_retries do
+ add_foreign_key :vulnerability_finding_evidence_headers, :vulnerability_finding_evidence_requests, on_delete: :cascade
+ end
+
+ with_lock_retries do
+ add_foreign_key :vulnerability_finding_evidence_headers, :vulnerability_finding_evidence_responses, on_delete: :cascade
+ end
+
+ with_lock_retries do
+ add_foreign_key :vulnerability_finding_evidence_requests, :vulnerability_finding_evidences, on_delete: :cascade
+ end
+
+ with_lock_retries do
+ add_foreign_key :vulnerability_finding_evidence_requests, :vulnerability_finding_evidence_supporting_messages, on_delete: :cascade
+ end
+
+ with_lock_retries do
+ add_foreign_key :vulnerability_finding_evidence_responses, :vulnerability_finding_evidences, on_delete: :cascade
+ end
+
+ with_lock_retries do
+ add_foreign_key :vulnerability_finding_evidence_responses, :vulnerability_finding_evidence_supporting_messages, on_delete: :cascade
+ end
+
+ with_lock_retries do
+ add_foreign_key :vulnerability_finding_evidence_sources, :vulnerability_finding_evidences, on_delete: :cascade
+ end
+
+ with_lock_retries do
+ add_foreign_key :vulnerability_finding_evidence_supporting_messages, :vulnerability_finding_evidences, on_delete: :cascade
+ end
+ end
+end
diff --git a/db/post_migrate/20211207173511_remove_extra_finding_evidence_tables.rb b/db/post_migrate/20211207173511_remove_extra_finding_evidence_tables.rb
new file mode 100644
index 00000000000..9a246a8c707
--- /dev/null
+++ b/db/post_migrate/20211207173511_remove_extra_finding_evidence_tables.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+class RemoveExtraFindingEvidenceTables < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ drop_table :vulnerability_finding_evidence_assets, if_exists: true
+ drop_table :vulnerability_finding_evidence_headers, if_exists: true
+ drop_table :vulnerability_finding_evidence_requests, if_exists: true
+ drop_table :vulnerability_finding_evidence_responses, if_exists: true
+ drop_table :vulnerability_finding_evidence_sources, if_exists: true
+ drop_table :vulnerability_finding_evidence_supporting_messages, if_exists: true
+ end
+ end
+
+ def down
+ create_table :vulnerability_finding_evidence_assets, if_not_exists: true do |t|
+ t.timestamps_with_timezone null: false
+
+ t.references :vulnerability_finding_evidence, index: { name: 'finding_evidence_assets_on_finding_evidence_id' }, null: false
+ t.text :type, limit: 2048
+ t.text :name, limit: 2048
+ t.text :url, limit: 2048
+ end
+
+ create_table :vulnerability_finding_evidence_sources, if_not_exists: true do |t|
+ t.timestamps_with_timezone null: false
+
+ t.references :vulnerability_finding_evidence, index: { name: 'finding_evidence_sources_on_finding_evidence_id' }, null: false
+ t.text :name, limit: 2048
+ t.text :url, limit: 2048
+ end
+
+ create_table :vulnerability_finding_evidence_supporting_messages, if_not_exists: true do |t|
+ t.timestamps_with_timezone null: false
+
+ t.references :vulnerability_finding_evidence, index: { name: 'finding_evidence_supporting_messages_on_finding_evidence_id' }, null: false
+ t.text :name, limit: 2048
+ end
+
+ create_table :vulnerability_finding_evidence_requests, if_not_exists: true do |t|
+ t.timestamps_with_timezone null: false
+
+ t.references :vulnerability_finding_evidence, index: { name: 'finding_evidence_requests_on_finding_evidence_id' }, null: true
+ t.text :method, limit: 32
+ t.text :url, limit: 2048
+ t.text :body, limit: 2048
+ t.references :vulnerability_finding_evidence_supporting_message, index: { name: 'finding_evidence_requests_on_supporting_evidence_id' }, null: true
+ end
+
+ create_table :vulnerability_finding_evidence_responses, if_not_exists: true do |t|
+ t.timestamps_with_timezone null: false
+
+ t.references :vulnerability_finding_evidence, index: { name: 'finding_evidence_responses_on_finding_evidences_id' }, null: true
+ t.integer :status_code
+ t.text :reason_phrase, limit: 2048
+ t.text :body, limit: 2048
+ t.references :vulnerability_finding_evidence_supporting_message, index: { name: 'finding_evidence_responses_on_supporting_evidence_id' }, null: true
+ end
+
+ create_table :vulnerability_finding_evidence_headers, if_not_exists: true do |t|
+ t.timestamps_with_timezone null: false
+
+ t.references :vulnerability_finding_evidence_request, index: { name: 'finding_evidence_header_on_finding_evidence_request_id' }, null: true
+ t.references :vulnerability_finding_evidence_response, index: { name: 'finding_evidence_header_on_finding_evidence_response_id' }, null: true
+ t.text :name, null: false, limit: 255
+ t.text :value, null: false, limit: 8192
+ end
+ end
+end
diff --git a/db/post_migrate/20211208122200_schedule_backfill_ci_namespace_mirrors.rb b/db/post_migrate/20211208122200_schedule_backfill_ci_namespace_mirrors.rb
new file mode 100644
index 00000000000..3d39148f402
--- /dev/null
+++ b/db/post_migrate/20211208122200_schedule_backfill_ci_namespace_mirrors.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class ScheduleBackfillCiNamespaceMirrors < Gitlab::Database::Migration[1.0]
+ MIGRATION = 'BackfillCiNamespaceMirrors'
+ BATCH_SIZE = 10_000
+ DELAY_INTERVAL = 2.minutes
+
+ disable_ddl_transaction!
+
+ def up
+ queue_background_migration_jobs_by_range_at_intervals(
+ Gitlab::BackgroundMigration::BackfillCiNamespaceMirrors::Namespace.base_query,
+ MIGRATION,
+ DELAY_INTERVAL,
+ batch_size: BATCH_SIZE,
+ track_jobs: true
+ )
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20211208122201_schedule_backfill_ci_project_mirrors.rb b/db/post_migrate/20211208122201_schedule_backfill_ci_project_mirrors.rb
new file mode 100644
index 00000000000..5678ee9f292
--- /dev/null
+++ b/db/post_migrate/20211208122201_schedule_backfill_ci_project_mirrors.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class ScheduleBackfillCiProjectMirrors < Gitlab::Database::Migration[1.0]
+ MIGRATION = 'BackfillCiProjectMirrors'
+ BATCH_SIZE = 10_000
+ DELAY_INTERVAL = 2.minutes
+
+ disable_ddl_transaction!
+
+ def up
+ queue_background_migration_jobs_by_range_at_intervals(
+ Gitlab::BackgroundMigration::BackfillCiProjectMirrors::Project.base_query,
+ MIGRATION,
+ DELAY_INTERVAL,
+ batch_size: BATCH_SIZE,
+ track_jobs: true
+ )
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20211209203820_add_tmp_index_on_report_type.rb b/db/post_migrate/20211209203820_add_tmp_index_on_report_type.rb
new file mode 100644
index 00000000000..07a2c079511
--- /dev/null
+++ b/db/post_migrate/20211209203820_add_tmp_index_on_report_type.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+class AddTmpIndexOnReportType < Gitlab::Database::Migration[1.0]
+ # Temporary index to perform migration fixing invalid vulnerability_occurrences.raw_metadata rows
+ # Will be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/349605
+ INDEX_NAME = 'tmp_idx_vulnerability_occurrences_on_id_where_report_type_7_99'
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :vulnerability_occurrences, :id, where: 'report_type IN (7, 99)', name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :vulnerability_occurrences, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20211209203821_convert_stringified_raw_metadata_hash_to_json.rb b/db/post_migrate/20211209203821_convert_stringified_raw_metadata_hash_to_json.rb
new file mode 100644
index 00000000000..757cbf60d4d
--- /dev/null
+++ b/db/post_migrate/20211209203821_convert_stringified_raw_metadata_hash_to_json.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+class ConvertStringifiedRawMetadataHashToJson < 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,
+ DELAY_INTERVAL,
+ batch_size: BATCH_SIZE
+ )
+ 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/20211210140000_add_temporary_static_object_token_index.rb b/db/post_migrate/20211210140000_add_temporary_static_object_token_index.rb
new file mode 100644
index 00000000000..54997dc4cc4
--- /dev/null
+++ b/db/post_migrate/20211210140000_add_temporary_static_object_token_index.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddTemporaryStaticObjectTokenIndex < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_users_with_static_object_token'
+
+ def up
+ add_concurrent_index :users, :id, where: "static_object_token IS NOT NULL AND static_object_token_encrypted IS NULL", name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index :users, :id, name: INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20211210140629_encrypt_static_object_token.rb b/db/post_migrate/20211210140629_encrypt_static_object_token.rb
new file mode 100644
index 00000000000..fe4db9fc14c
--- /dev/null
+++ b/db/post_migrate/20211210140629_encrypt_static_object_token.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class EncryptStaticObjectToken < Gitlab::Database::Migration[1.0]
+ BATCH_SIZE = 10_000
+ MIGRATION = 'EncryptStaticObjectToken'
+
+ disable_ddl_transaction!
+
+ def up
+ queue_background_migration_jobs_by_range_at_intervals(
+ define_batchable_model('users').where.not(static_object_token: nil).where(static_object_token_encrypted: nil),
+ MIGRATION,
+ 2.minutes,
+ batch_size: BATCH_SIZE,
+ track_jobs: true
+ )
+ end
+
+ def down
+ # no ops
+ end
+end
diff --git a/db/post_migrate/20211214012507_backfill_incident_issue_escalation_statuses.rb b/db/post_migrate/20211214012507_backfill_incident_issue_escalation_statuses.rb
new file mode 100644
index 00000000000..7f0168be1a4
--- /dev/null
+++ b/db/post_migrate/20211214012507_backfill_incident_issue_escalation_statuses.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class BackfillIncidentIssueEscalationStatuses < Gitlab::Database::Migration[1.0]
+ MIGRATION = 'BackfillIncidentIssueEscalationStatuses'
+ DELAY_INTERVAL = 2.minutes
+ BATCH_SIZE = 20_000
+
+ disable_ddl_transaction!
+
+ class Issue < ActiveRecord::Base
+ include EachBatch
+
+ self.table_name = 'issues'
+ end
+
+ def up
+ relation = Issue.all
+
+ queue_background_migration_jobs_by_range_at_intervals(
+ relation, MIGRATION, DELAY_INTERVAL, batch_size: BATCH_SIZE, track_jobs: true)
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20211217120000_modify_kubernetes_resource_location_index_to_vulnerability_occurrences.rb b/db/post_migrate/20211217120000_modify_kubernetes_resource_location_index_to_vulnerability_occurrences.rb
new file mode 100644
index 00000000000..310a49a667e
--- /dev/null
+++ b/db/post_migrate/20211217120000_modify_kubernetes_resource_location_index_to_vulnerability_occurrences.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+class ModifyKubernetesResourceLocationIndexToVulnerabilityOccurrences < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ OLD_CLUSTER_ID_INDEX_NAME = 'index_vulnerability_occurrences_on_location_cluster_id'
+ OLD_AGENT_ID_INDEX_NAME = 'index_vulnerability_occurrences_on_location_agent_id'
+
+ NEW_CLUSTER_ID_INDEX_NAME = 'index_vulnerability_occurrences_on_location_k8s_cluster_id'
+ NEW_AGENT_ID_INDEX_NAME = 'index_vulnerability_occurrences_on_location_k8s_agent_id'
+
+ def up
+ add_concurrent_index :vulnerability_occurrences, "(location -> 'kubernetes_resource' -> 'cluster_id')",
+ using: 'GIN',
+ where: 'report_type = 7',
+ name: NEW_CLUSTER_ID_INDEX_NAME
+
+ add_concurrent_index :vulnerability_occurrences, "(location -> 'kubernetes_resource' -> 'agent_id')",
+ using: 'GIN',
+ where: 'report_type = 7',
+ name: NEW_AGENT_ID_INDEX_NAME
+
+ remove_concurrent_index_by_name :vulnerability_occurrences, OLD_CLUSTER_ID_INDEX_NAME
+ remove_concurrent_index_by_name :vulnerability_occurrences, OLD_AGENT_ID_INDEX_NAME
+ end
+
+ def down
+ add_concurrent_index :vulnerability_occurrences, "(location -> 'cluster_id')",
+ using: 'GIN',
+ where: 'report_type = 7',
+ name: OLD_CLUSTER_ID_INDEX_NAME
+
+ add_concurrent_index :vulnerability_occurrences, "(location -> 'agent_id')",
+ using: 'GIN',
+ where: 'report_type = 7',
+ name: OLD_AGENT_ID_INDEX_NAME
+
+ remove_concurrent_index_by_name :vulnerability_occurrences, NEW_CLUSTER_ID_INDEX_NAME
+ remove_concurrent_index_by_name :vulnerability_occurrences, NEW_AGENT_ID_INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20211217145923_add_index_to_events_on_author_id_and_action_and_id.rb b/db/post_migrate/20211217145923_add_index_to_events_on_author_id_and_action_and_id.rb
new file mode 100644
index 00000000000..a05d68279c3
--- /dev/null
+++ b/db/post_migrate/20211217145923_add_index_to_events_on_author_id_and_action_and_id.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class AddIndexToEventsOnAuthorIdAndActionAndId < Gitlab::Database::Migration[1.0]
+ # no-op
+ # see: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77436
+
+ def up
+ # no-op
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20211217174331_mark_recalculate_finding_signatures_as_completed.rb b/db/post_migrate/20211217174331_mark_recalculate_finding_signatures_as_completed.rb
new file mode 100644
index 00000000000..316209ae1f4
--- /dev/null
+++ b/db/post_migrate/20211217174331_mark_recalculate_finding_signatures_as_completed.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class MarkRecalculateFindingSignaturesAsCompleted < Gitlab::Database::Migration[1.0]
+ MIGRATION = 'RecalculateVulnerabilitiesOccurrencesUuid'
+
+ def up
+ # Only run migration for Gitlab.com
+ return unless ::Gitlab.com?
+
+ # In previous migration marking jobs as successful was missed
+ Gitlab::Database::BackgroundMigrationJob
+ .for_migration_class(MIGRATION)
+ .pending
+ .update_all(status: :succeeded)
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20211220064757_drop_temporary_indexes_for_primary_email_migration.rb b/db/post_migrate/20211220064757_drop_temporary_indexes_for_primary_email_migration.rb
new file mode 100644
index 00000000000..1d61aec401e
--- /dev/null
+++ b/db/post_migrate/20211220064757_drop_temporary_indexes_for_primary_email_migration.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class DropTemporaryIndexesForPrimaryEmailMigration < Gitlab::Database::Migration[1.0]
+ USERS_INDEX = :index_users_on_id_for_primary_email_migration
+ EMAIL_INDEX = :index_emails_on_email_user_id
+
+ disable_ddl_transaction!
+
+ def up
+ remove_concurrent_index_by_name :users, USERS_INDEX
+ remove_concurrent_index_by_name :emails, EMAIL_INDEX
+ end
+
+ def down
+ unless index_exists_by_name?(:users, USERS_INDEX)
+
+ disable_statement_timeout do
+ execute <<~SQL
+ CREATE INDEX CONCURRENTLY #{USERS_INDEX}
+ ON users (id) INCLUDE (email, confirmed_at)
+ WHERE confirmed_at IS NOT NULL
+ SQL
+ end
+ end
+
+ add_concurrent_index :emails, [:email, :user_id], name: EMAIL_INDEX
+ end
+end
diff --git a/db/post_migrate/20211220120402_add_index_on_ci_pipelines_user_id_id_failure_reason.rb b/db/post_migrate/20211220120402_add_index_on_ci_pipelines_user_id_id_failure_reason.rb
new file mode 100644
index 00000000000..c98d3d05f2f
--- /dev/null
+++ b/db/post_migrate/20211220120402_add_index_on_ci_pipelines_user_id_id_failure_reason.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexOnCiPipelinesUserIdIdFailureReason < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_ci_pipelines_on_user_id_and_id_desc_and_user_not_verified'
+
+ def up
+ add_concurrent_index :ci_pipelines, [:user_id, :id], order: { id: :desc }, where: 'failure_reason = 3', name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :ci_pipelines, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20211220123956_update_invalid_member_states.rb b/db/post_migrate/20211220123956_update_invalid_member_states.rb
new file mode 100644
index 00000000000..5da100f0ec2
--- /dev/null
+++ b/db/post_migrate/20211220123956_update_invalid_member_states.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+class UpdateInvalidMemberStates < Gitlab::Database::Migration[1.0]
+ class Member < ActiveRecord::Base
+ include EachBatch
+
+ self.table_name = 'members'
+
+ scope :in_invalid_state, -> { where(state: 2) }
+ end
+
+ def up
+ Member.in_invalid_state.each_batch do |relation|
+ relation.update_all(state: 0)
+ end
+ end
+
+ def down
+ # no-op as we don't need to revert any changed records
+ end
+end
diff --git a/db/post_migrate/20211229023654_add_async_index_ci_job_artifacts_project_id_file_type.rb b/db/post_migrate/20211229023654_add_async_index_ci_job_artifacts_project_id_file_type.rb
new file mode 100644
index 00000000000..5338cab3871
--- /dev/null
+++ b/db/post_migrate/20211229023654_add_async_index_ci_job_artifacts_project_id_file_type.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddAsyncIndexCiJobArtifactsProjectIdFileType < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_ci_job_artifacts_on_id_project_id_and_file_type'
+
+ def up
+ prepare_async_index :ci_job_artifacts, [:project_id, :file_type, :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/20211230112517_remove_index_events_on_author_id_and_action_and_id.rb b/db/post_migrate/20211230112517_remove_index_events_on_author_id_and_action_and_id.rb
new file mode 100644
index 00000000000..2215a49e286
--- /dev/null
+++ b/db/post_migrate/20211230112517_remove_index_events_on_author_id_and_action_and_id.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveIndexEventsOnAuthorIdAndActionAndId < Gitlab::Database::Migration[1.0]
+ INDEX_NAME = 'index_events_on_author_id_and_action_and_id'
+
+ disable_ddl_transaction!
+
+ def up
+ remove_concurrent_index_by_name :events, name: INDEX_NAME
+ end
+
+ def down
+ # no-op
+ # The index had been added in the same milestone.
+ # Adding back the index takes a long time and should not be needed.
+ end
+end
diff --git a/db/post_migrate/20211230113031_add_index_to_events_on_author_id_and_id.rb b/db/post_migrate/20211230113031_add_index_to_events_on_author_id_and_id.rb
new file mode 100644
index 00000000000..e4cdc9add39
--- /dev/null
+++ b/db/post_migrate/20211230113031_add_index_to_events_on_author_id_and_id.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexToEventsOnAuthorIdAndId < Gitlab::Database::Migration[1.0]
+ INDEX_NAME = 'index_events_on_author_id_and_id'
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :events, [:author_id, :id], name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :events, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20220104060049_remove_foreign_key_ci_group_variables_group_id.rb b/db/post_migrate/20220104060049_remove_foreign_key_ci_group_variables_group_id.rb
new file mode 100644
index 00000000000..9be81e00b50
--- /dev/null
+++ b/db/post_migrate/20220104060049_remove_foreign_key_ci_group_variables_group_id.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveForeignKeyCiGroupVariablesGroupId < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ CONSTRAINT_NAME = 'fk_33ae4d58d8'
+
+ def up
+ with_lock_retries do
+ remove_foreign_key_if_exists(:ci_group_variables, :namespaces, name: CONSTRAINT_NAME)
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key :ci_group_variables, :namespaces, column: :group_id, on_delete: :cascade, name: CONSTRAINT_NAME
+ end
+end
diff --git a/db/post_migrate/20220105020514_remove_ci_minutes_additional_packs_namespace_id_foreign_key_constraint.rb b/db/post_migrate/20220105020514_remove_ci_minutes_additional_packs_namespace_id_foreign_key_constraint.rb
new file mode 100644
index 00000000000..b072d5616f5
--- /dev/null
+++ b/db/post_migrate/20220105020514_remove_ci_minutes_additional_packs_namespace_id_foreign_key_constraint.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveCiMinutesAdditionalPacksNamespaceIdForeignKeyConstraint < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ CONSTRAINT_NAME = 'fk_rails_e0e0c4e4b1'
+
+ def up
+ with_lock_retries do
+ remove_foreign_key_if_exists(:ci_minutes_additional_packs, :namespaces, name: CONSTRAINT_NAME)
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key :ci_minutes_additional_packs, :namespaces, column: :namespace_id, on_delete: :cascade, name: CONSTRAINT_NAME
+ end
+end
diff --git a/db/post_migrate/20220106231518_remove_foreign_key_ci_daily_build_group_report_results_group_id.rb b/db/post_migrate/20220106231518_remove_foreign_key_ci_daily_build_group_report_results_group_id.rb
new file mode 100644
index 00000000000..ece20f8095d
--- /dev/null
+++ b/db/post_migrate/20220106231518_remove_foreign_key_ci_daily_build_group_report_results_group_id.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveForeignKeyCiDailyBuildGroupReportResultsGroupId < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ CONSTRAINT_NAME = 'fk_fd1858fefd'
+
+ def up
+ with_lock_retries do
+ remove_foreign_key_if_exists(:ci_daily_build_group_report_results, :namespaces, name: CONSTRAINT_NAME)
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key :ci_daily_build_group_report_results, :namespaces, column: :group_id, on_delete: :cascade, name: CONSTRAINT_NAME
+ end
+end
diff --git a/db/post_migrate/20220106233459_remove_foreign_key_ci_pending_builds_namespace_id.rb b/db/post_migrate/20220106233459_remove_foreign_key_ci_pending_builds_namespace_id.rb
new file mode 100644
index 00000000000..1304f19708e
--- /dev/null
+++ b/db/post_migrate/20220106233459_remove_foreign_key_ci_pending_builds_namespace_id.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveForeignKeyCiPendingBuildsNamespaceId < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ CONSTRAINT_NAME = 'fk_fdc0137e4a'
+
+ def up
+ with_lock_retries do
+ remove_foreign_key_if_exists(:ci_pending_builds, :namespaces, name: CONSTRAINT_NAME)
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key :ci_pending_builds, :namespaces, column: :namespace_id, on_delete: :cascade, name: CONSTRAINT_NAME
+ end
+end
diff --git a/db/post_migrate/20220106235626_remove_foreign_key_ci_runner_namespaces_namespace_id.rb b/db/post_migrate/20220106235626_remove_foreign_key_ci_runner_namespaces_namespace_id.rb
new file mode 100644
index 00000000000..61ca066401e
--- /dev/null
+++ b/db/post_migrate/20220106235626_remove_foreign_key_ci_runner_namespaces_namespace_id.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveForeignKeyCiRunnerNamespacesNamespaceId < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ CONSTRAINT_NAME = 'fk_rails_f9d9ed3308'
+
+ def up
+ with_lock_retries do
+ remove_foreign_key_if_exists(:ci_runner_namespaces, :namespaces, name: CONSTRAINT_NAME)
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key :ci_runner_namespaces, :namespaces, column: :namespace_id, on_delete: :cascade, name: CONSTRAINT_NAME
+ end
+end
diff --git a/db/post_migrate/20220109134455_add_idx_vulnerability_occurrences_dedup_again.rb b/db/post_migrate/20220109134455_add_idx_vulnerability_occurrences_dedup_again.rb
new file mode 100644
index 00000000000..06be8edd707
--- /dev/null
+++ b/db/post_migrate/20220109134455_add_idx_vulnerability_occurrences_dedup_again.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddIdxVulnerabilityOccurrencesDedupAgain < Gitlab::Database::Migration[1.0]
+ TABLE = :vulnerability_occurrences
+ INDEX_NAME = 'index_vulnerability_occurrences_deduplication'
+ COLUMNS = %i[project_id report_type project_fingerprint]
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index TABLE, COLUMNS, name: INDEX_NAME
+ end
+
+ def down
+ # nothing to do here
+ end
+end
diff --git a/db/post_migrate/20220110171049_schedule_populate_test_reports_issue_id.rb b/db/post_migrate/20220110171049_schedule_populate_test_reports_issue_id.rb
new file mode 100644
index 00000000000..dae93e1636d
--- /dev/null
+++ b/db/post_migrate/20220110171049_schedule_populate_test_reports_issue_id.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class SchedulePopulateTestReportsIssueId < Gitlab::Database::Migration[1.0]
+ MIGRATION = 'PopulateTestReportsIssueId'
+ DELAY_INTERVAL = 2.minutes.to_i
+ BATCH_SIZE = 30
+
+ disable_ddl_transaction!
+
+ def up
+ queue_background_migration_jobs_by_range_at_intervals(
+ define_batchable_model('requirements_management_test_reports').where(issue_id: nil),
+ MIGRATION,
+ DELAY_INTERVAL,
+ batch_size: BATCH_SIZE,
+ track_jobs: true
+ )
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20220110224913_remove_dast_scanner_profiles_builds_ci_build_id_fk.rb b/db/post_migrate/20220110224913_remove_dast_scanner_profiles_builds_ci_build_id_fk.rb
new file mode 100644
index 00000000000..d91cd3b43ef
--- /dev/null
+++ b/db/post_migrate/20220110224913_remove_dast_scanner_profiles_builds_ci_build_id_fk.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class RemoveDastScannerProfilesBuildsCiBuildIdFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ CONSTRAINT_NAME = 'fk_e4c49200f8'
+
+ def up
+ with_lock_retries do
+ execute('LOCK ci_builds, dast_scanner_profiles_builds IN ACCESS EXCLUSIVE MODE')
+ remove_foreign_key_if_exists(:dast_scanner_profiles_builds, :ci_builds, name: CONSTRAINT_NAME)
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key(:dast_scanner_profiles_builds, :ci_builds, column: :ci_build_id, on_delete: :cascade, name: CONSTRAINT_NAME)
+ end
+end
diff --git a/db/post_migrate/20220110231420_remove_requirements_management_test_reports_build_id_fk.rb b/db/post_migrate/20220110231420_remove_requirements_management_test_reports_build_id_fk.rb
new file mode 100644
index 00000000000..dd8c6de4aaf
--- /dev/null
+++ b/db/post_migrate/20220110231420_remove_requirements_management_test_reports_build_id_fk.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class RemoveRequirementsManagementTestReportsBuildIdFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ CONSTRAINT_NAME = 'fk_rails_e67d085910'
+
+ def up
+ with_lock_retries do
+ execute('LOCK ci_builds, requirements_management_test_reports IN ACCESS EXCLUSIVE MODE')
+ remove_foreign_key_if_exists(:requirements_management_test_reports, :ci_builds, name: CONSTRAINT_NAME)
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key(:requirements_management_test_reports, :ci_builds, column: :build_id, on_delete: :nullify, name: CONSTRAINT_NAME)
+ end
+end
diff --git a/db/post_migrate/20220110233155_remove_dast_site_profiles_builds_ci_build_id_fk.rb b/db/post_migrate/20220110233155_remove_dast_site_profiles_builds_ci_build_id_fk.rb
new file mode 100644
index 00000000000..00d8a39216b
--- /dev/null
+++ b/db/post_migrate/20220110233155_remove_dast_site_profiles_builds_ci_build_id_fk.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class RemoveDastSiteProfilesBuildsCiBuildIdFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ CONSTRAINT_NAME = 'fk_a325505e99'
+
+ def up
+ with_lock_retries do
+ execute('LOCK ci_builds, dast_site_profiles_builds IN ACCESS EXCLUSIVE MODE')
+ remove_foreign_key_if_exists(:dast_site_profiles_builds, :ci_builds, name: CONSTRAINT_NAME)
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key(:dast_site_profiles_builds, :ci_builds, column: :ci_build_id, on_delete: :cascade, name: CONSTRAINT_NAME)
+ end
+end
diff --git a/db/post_migrate/20220111002756_remove_security_scans_build_id_fk.rb b/db/post_migrate/20220111002756_remove_security_scans_build_id_fk.rb
new file mode 100644
index 00000000000..20782664f63
--- /dev/null
+++ b/db/post_migrate/20220111002756_remove_security_scans_build_id_fk.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class RemoveSecurityScansBuildIdFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ CONSTRAINT_NAME = 'fk_rails_4ef1e6b4c6'
+
+ def up
+ with_lock_retries do
+ execute('LOCK ci_builds, security_scans IN ACCESS EXCLUSIVE MODE')
+ remove_foreign_key_if_exists(:security_scans, :ci_builds, name: CONSTRAINT_NAME)
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key(:security_scans, :ci_builds, column: :build_id, on_delete: :cascade, name: CONSTRAINT_NAME)
+ end
+end
diff --git a/db/post_migrate/20220111023852_index_cluster_agent_tokens_on_status.rb b/db/post_migrate/20220111023852_index_cluster_agent_tokens_on_status.rb
new file mode 100644
index 00000000000..6de0f9424e8
--- /dev/null
+++ b/db/post_migrate/20220111023852_index_cluster_agent_tokens_on_status.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class IndexClusterAgentTokensOnStatus < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_cluster_agent_tokens_on_agent_id_status_last_used_at'
+
+ def up
+ add_concurrent_index :cluster_agent_tokens, 'agent_id, status, last_used_at DESC NULLS LAST', name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :cluster_agent_tokens, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20220111102314_truncate_ci_mirror_tables.rb b/db/post_migrate/20220111102314_truncate_ci_mirror_tables.rb
new file mode 100644
index 00000000000..795ec24f3bd
--- /dev/null
+++ b/db/post_migrate/20220111102314_truncate_ci_mirror_tables.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class TruncateCiMirrorTables < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ execute('TRUNCATE TABLE ci_namespace_mirrors')
+ execute('TRUNCATE TABLE ci_project_mirrors')
+ end
+
+ def down
+ # noop
+ end
+end
diff --git a/db/post_migrate/20220111221516_remove_projects_ci_pending_builds_fk.rb b/db/post_migrate/20220111221516_remove_projects_ci_pending_builds_fk.rb
new file mode 100644
index 00000000000..bc17c125ba7
--- /dev/null
+++ b/db/post_migrate/20220111221516_remove_projects_ci_pending_builds_fk.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiPendingBuildsFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ remove_foreign_key_if_exists(:ci_pending_builds, :projects, name: "fk_rails_480669c3b3")
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key(:ci_pending_builds, :projects, name: "fk_rails_480669c3b3", column: :project_id, target_column: :id, on_delete: "cascade")
+ end
+end
diff --git a/db/post_migrate/20220112015940_remove_projects_ci_running_builds_fk.rb b/db/post_migrate/20220112015940_remove_projects_ci_running_builds_fk.rb
new file mode 100644
index 00000000000..79d864e2c2a
--- /dev/null
+++ b/db/post_migrate/20220112015940_remove_projects_ci_running_builds_fk.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiRunningBuildsFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ execute('LOCK projects, ci_running_builds IN ACCESS EXCLUSIVE MODE')
+
+ remove_foreign_key_if_exists(:ci_running_builds, :projects, name: "fk_rails_dc1d0801e8")
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key(:ci_running_builds, :projects, name: "fk_rails_dc1d0801e8", column: :project_id, target_column: :id, on_delete: "cascade")
+ end
+end
diff --git a/db/post_migrate/20220112090556_remove_cascade_delete_from_project_namespace_foreign_key.rb b/db/post_migrate/20220112090556_remove_cascade_delete_from_project_namespace_foreign_key.rb
new file mode 100644
index 00000000000..d786c9d846a
--- /dev/null
+++ b/db/post_migrate/20220112090556_remove_cascade_delete_from_project_namespace_foreign_key.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class RemoveCascadeDeleteFromProjectNamespaceForeignKey < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ TARGET_COLUMN = :project_namespace_id
+
+ def up
+ with_lock_retries do
+ remove_foreign_key_if_exists(:projects, column: TARGET_COLUMN)
+ end
+
+ add_concurrent_foreign_key(:projects, :namespaces, column: TARGET_COLUMN, on_delete: :nullify)
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key_if_exists(:projects, column: TARGET_COLUMN)
+ end
+
+ add_concurrent_foreign_key(:projects, :namespaces, column: TARGET_COLUMN, on_delete: :cascade)
+ end
+end
diff --git a/db/post_migrate/20220112230642_remove_projects_ci_unit_tests_project_id_fk.rb b/db/post_migrate/20220112230642_remove_projects_ci_unit_tests_project_id_fk.rb
new file mode 100644
index 00000000000..9ad90a3a7a0
--- /dev/null
+++ b/db/post_migrate/20220112230642_remove_projects_ci_unit_tests_project_id_fk.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiUnitTestsProjectIdFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ remove_foreign_key_if_exists(:ci_unit_tests, :projects, name: "fk_7a8fabf0a8")
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key(:ci_unit_tests, :projects, name: "fk_7a8fabf0a8", column: :project_id, target_column: :id, on_delete: "cascade")
+ end
+end
diff --git a/db/post_migrate/20220112232723_remove_projects_ci_daily_build_group_report_results_project_id_fk.rb b/db/post_migrate/20220112232723_remove_projects_ci_daily_build_group_report_results_project_id_fk.rb
new file mode 100644
index 00000000000..ad7cf2a20c9
--- /dev/null
+++ b/db/post_migrate/20220112232723_remove_projects_ci_daily_build_group_report_results_project_id_fk.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiDailyBuildGroupReportResultsProjectIdFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ execute('LOCK projects, ci_daily_build_group_report_results IN ACCESS EXCLUSIVE MODE')
+ remove_foreign_key_if_exists(:ci_daily_build_group_report_results, :projects, name: "fk_rails_0667f7608c")
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key(:ci_daily_build_group_report_results, :projects, name: "fk_rails_0667f7608c", column: :project_id, target_column: :id, on_delete: "cascade")
+ end
+end
diff --git a/db/post_migrate/20220113013319_remove_projects_ci_freeze_periods_project_id_fk.rb b/db/post_migrate/20220113013319_remove_projects_ci_freeze_periods_project_id_fk.rb
new file mode 100644
index 00000000000..13cfacdc223
--- /dev/null
+++ b/db/post_migrate/20220113013319_remove_projects_ci_freeze_periods_project_id_fk.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiFreezePeriodsProjectIdFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ remove_foreign_key_if_exists(:ci_freeze_periods, :projects, name: "fk_2e02bbd1a6")
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key(:ci_freeze_periods, :projects, name: "fk_2e02bbd1a6", column: :project_id, target_column: :id, on_delete: "cascade")
+ end
+end
diff --git a/db/post_migrate/20220113014438_remove_projects_ci_resource_groups_project_id_fk.rb b/db/post_migrate/20220113014438_remove_projects_ci_resource_groups_project_id_fk.rb
new file mode 100644
index 00000000000..e86dd015493
--- /dev/null
+++ b/db/post_migrate/20220113014438_remove_projects_ci_resource_groups_project_id_fk.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiResourceGroupsProjectIdFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ remove_foreign_key_if_exists(:ci_resource_groups, :projects, name: "fk_774722d144")
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key(:ci_resource_groups, :projects, name: "fk_774722d144", column: :project_id, target_column: :id, on_delete: "cascade")
+ end
+end
diff --git a/db/post_migrate/20220113015830_remove_projects_ci_build_report_results_project_id_fk.rb b/db/post_migrate/20220113015830_remove_projects_ci_build_report_results_project_id_fk.rb
new file mode 100644
index 00000000000..3d2753bf9bf
--- /dev/null
+++ b/db/post_migrate/20220113015830_remove_projects_ci_build_report_results_project_id_fk.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiBuildReportResultsProjectIdFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ remove_foreign_key_if_exists(:ci_build_report_results, :projects, name: "fk_rails_056d298d48")
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key(:ci_build_report_results, :projects, name: "fk_rails_056d298d48", column: :project_id, target_column: :id, on_delete: "cascade")
+ end
+end
diff --git a/db/post_migrate/20220113035519_remove_users_ci_job_token_project_scope_links_added_by_id_fk.rb b/db/post_migrate/20220113035519_remove_users_ci_job_token_project_scope_links_added_by_id_fk.rb
new file mode 100644
index 00000000000..966286a6730
--- /dev/null
+++ b/db/post_migrate/20220113035519_remove_users_ci_job_token_project_scope_links_added_by_id_fk.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveUsersCiJobTokenProjectScopeLinksAddedByIdFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ remove_foreign_key_if_exists(:ci_job_token_project_scope_links, :users, name: "fk_rails_35f7f506ce")
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key(:ci_job_token_project_scope_links, :users, name: "fk_rails_35f7f506ce", column: :added_by_id, target_column: :id, on_delete: :nullify)
+ end
+end
diff --git a/db/post_migrate/20220113040447_remove_users_ci_pipeline_schedules_owner_id_fk.rb b/db/post_migrate/20220113040447_remove_users_ci_pipeline_schedules_owner_id_fk.rb
new file mode 100644
index 00000000000..2e5d4cfd22e
--- /dev/null
+++ b/db/post_migrate/20220113040447_remove_users_ci_pipeline_schedules_owner_id_fk.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveUsersCiPipelineSchedulesOwnerIdFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ remove_foreign_key_if_exists(:ci_pipeline_schedules, :users, name: "fk_9ea99f58d2")
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key(:ci_pipeline_schedules, :users, name: "fk_9ea99f58d2", column: :owner_id, target_column: :id, on_delete: :nullify)
+ end
+end
diff --git a/db/post_migrate/20220114105525_add_index_on_projects_path.rb b/db/post_migrate/20220114105525_add_index_on_projects_path.rb
new file mode 100644
index 00000000000..cef38f91b21
--- /dev/null
+++ b/db/post_migrate/20220114105525_add_index_on_projects_path.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddIndexOnProjectsPath < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ TABLE = :projects
+ INDEX_NAME = 'index_on_projects_path'
+ COLUMN = :path
+
+ def up
+ add_concurrent_index TABLE, COLUMN, name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index TABLE, COLUMN, name: INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20220116175851_add_author_index_to_design_management_versions.rb b/db/post_migrate/20220116175851_add_author_index_to_design_management_versions.rb
new file mode 100644
index 00000000000..1ea89609926
--- /dev/null
+++ b/db/post_migrate/20220116175851_add_author_index_to_design_management_versions.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddAuthorIndexToDesignManagementVersions < Gitlab::Database::Migration[1.0]
+ TABLE = :design_management_versions
+ INDEX_NAME = 'index_design_management_versions_on_author_id'
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index TABLE, :author_id, where: 'author_id IS NOT NULL', name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index TABLE, :author_id, name: INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20220119141736_remove_projects_ci_pipeline_artifacts_project_id_fk.rb b/db/post_migrate/20220119141736_remove_projects_ci_pipeline_artifacts_project_id_fk.rb
new file mode 100644
index 00000000000..59a003c8f8d
--- /dev/null
+++ b/db/post_migrate/20220119141736_remove_projects_ci_pipeline_artifacts_project_id_fk.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiPipelineArtifactsProjectIdFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ execute('LOCK projects, ci_pipeline_artifacts IN ACCESS EXCLUSIVE MODE')
+
+ remove_foreign_key_if_exists(:ci_pipeline_artifacts, :projects, name: "fk_rails_4a70390ca6")
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key(:ci_pipeline_artifacts, :projects, name: "fk_rails_4a70390ca6", column: :project_id, target_column: :id, on_delete: :cascade)
+ end
+end
diff --git a/db/schema_migrations/20181228175414 b/db/schema_migrations/20181228175414
deleted file mode 100644
index 4b17d9331e1..00000000000
--- a/db/schema_migrations/20181228175414
+++ /dev/null
@@ -1 +0,0 @@
-789496127df650700b043e55cf1198f778d4f290f320c629905e242f2d0b0664 \ No newline at end of file
diff --git a/db/schema_migrations/20201211090634 b/db/schema_migrations/20201211090634
deleted file mode 100644
index 0c11b8f85fb..00000000000
--- a/db/schema_migrations/20201211090634
+++ /dev/null
@@ -1 +0,0 @@
-5117b71950bec3c6c746eaf4851c111a335bf2280075ddc2c73b60a30e23d907 \ No newline at end of file
diff --git a/db/schema_migrations/20201211145950 b/db/schema_migrations/20201211145950
deleted file mode 100644
index f3c3687bc4f..00000000000
--- a/db/schema_migrations/20201211145950
+++ /dev/null
@@ -1 +0,0 @@
-ecf6b392f35bb0ef905144a4605bcb927ce767240e47ec3b0653a94139b987bd \ No newline at end of file
diff --git a/db/schema_migrations/20201214000000 b/db/schema_migrations/20201214000000
deleted file mode 100644
index 420b3f2768a..00000000000
--- a/db/schema_migrations/20201214000000
+++ /dev/null
@@ -1 +0,0 @@
-58f2bd74adf8b4ef616c8f341053dbeaa8116430a0f4493cbf5f8456d7f4b907 \ No newline at end of file
diff --git a/db/schema_migrations/20201214032220 b/db/schema_migrations/20201214032220
deleted file mode 100644
index ec14b260583..00000000000
--- a/db/schema_migrations/20201214032220
+++ /dev/null
@@ -1 +0,0 @@
-db23b5315386ad5d5fec5a14958769cc1e62a0a89ec3246edb9fc024607e917b \ No newline at end of file
diff --git a/db/schema_migrations/20201214084105 b/db/schema_migrations/20201214084105
deleted file mode 100644
index 1b5eb10e48e..00000000000
--- a/db/schema_migrations/20201214084105
+++ /dev/null
@@ -1 +0,0 @@
-e991bf621a2eb047903f796256ee65b781e5dd34aff12449f2347480bf7791a7 \ No newline at end of file
diff --git a/db/schema_migrations/20201214111858 b/db/schema_migrations/20201214111858
deleted file mode 100644
index 7d97a34eadf..00000000000
--- a/db/schema_migrations/20201214111858
+++ /dev/null
@@ -1 +0,0 @@
-e3eb306d7956e396f038f07a20c674929fc4aae3e188b24e1087305b3fea8b4d \ No newline at end of file
diff --git a/db/schema_migrations/20201214112752 b/db/schema_migrations/20201214112752
deleted file mode 100644
index af432649dea..00000000000
--- a/db/schema_migrations/20201214112752
+++ /dev/null
@@ -1 +0,0 @@
-59906a3528499dd9c0b4c30088539299c08383ad3b36be8c862a7cc9ef1d50b2 \ No newline at end of file
diff --git a/db/schema_migrations/20201214113729 b/db/schema_migrations/20201214113729
deleted file mode 100644
index 56bc2113a34..00000000000
--- a/db/schema_migrations/20201214113729
+++ /dev/null
@@ -1 +0,0 @@
-9c2f6c75126172d4876db33cfd814f974a381df97a23aec21f2550ec288946c2 \ No newline at end of file
diff --git a/db/schema_migrations/20201214184020 b/db/schema_migrations/20201214184020
deleted file mode 100644
index 5cf5065b251..00000000000
--- a/db/schema_migrations/20201214184020
+++ /dev/null
@@ -1 +0,0 @@
-adce3c714064991e93f8a587da3d5892c47dbc14963fa49638ebbbf8b5489359 \ No newline at end of file
diff --git a/db/schema_migrations/20201215084652 b/db/schema_migrations/20201215084652
deleted file mode 100644
index 1b0cab62c8b..00000000000
--- a/db/schema_migrations/20201215084652
+++ /dev/null
@@ -1 +0,0 @@
-8aa288d8f4a02030528e096c3aa4e109c57f4ca2515442ca0bfb3463cf9ff609 \ No newline at end of file
diff --git a/db/schema_migrations/20201215132151 b/db/schema_migrations/20201215132151
deleted file mode 100644
index e051fb91e12..00000000000
--- a/db/schema_migrations/20201215132151
+++ /dev/null
@@ -1 +0,0 @@
-916f29e6ab89551fd785c3a8584c24b72d9002ada30d159e9ff826cb247199b5 \ No newline at end of file
diff --git a/db/schema_migrations/20201215205404 b/db/schema_migrations/20201215205404
deleted file mode 100644
index 147ede2064d..00000000000
--- a/db/schema_migrations/20201215205404
+++ /dev/null
@@ -1 +0,0 @@
-b54cf8b75c5882f2dfca74b218a9eeac766ff65233d43de865717d3ab8c7a217 \ No newline at end of file
diff --git a/db/schema_migrations/20201216151616 b/db/schema_migrations/20201216151616
deleted file mode 100644
index a8b27610716..00000000000
--- a/db/schema_migrations/20201216151616
+++ /dev/null
@@ -1 +0,0 @@
-f1c6927431895c6ce03fe7e0be30fcd0a1f4ccfeac8277ee0662d7434b97d257 \ No newline at end of file
diff --git a/db/schema_migrations/20201216154457 b/db/schema_migrations/20201216154457
deleted file mode 100644
index 773218ff906..00000000000
--- a/db/schema_migrations/20201216154457
+++ /dev/null
@@ -1 +0,0 @@
-c878874bbb9bf2314b90c1328d6e27846fe71513ba1ce688a262d36761b66665 \ No newline at end of file
diff --git a/db/schema_migrations/20201216185336 b/db/schema_migrations/20201216185336
deleted file mode 100644
index 376429a2141..00000000000
--- a/db/schema_migrations/20201216185336
+++ /dev/null
@@ -1 +0,0 @@
-3647e8b944aedeb58c41d9b3f08c8fb657fab231b0ff25c276f6d2aaa2ea93ae \ No newline at end of file
diff --git a/db/schema_migrations/20201217070530 b/db/schema_migrations/20201217070530
deleted file mode 100644
index c09f3b03e3b..00000000000
--- a/db/schema_migrations/20201217070530
+++ /dev/null
@@ -1 +0,0 @@
-59e40a24e8422e64bc85c4d54e6da923512017bac6a167350affeff241046e9f \ No newline at end of file
diff --git a/db/schema_migrations/20201217111448 b/db/schema_migrations/20201217111448
deleted file mode 100644
index 02526b55a3d..00000000000
--- a/db/schema_migrations/20201217111448
+++ /dev/null
@@ -1 +0,0 @@
-32330327aa8db01b5bc2c533af5387e77ad3dc0c34eacaac16a793df75634ce6 \ No newline at end of file
diff --git a/db/schema_migrations/20201217112249 b/db/schema_migrations/20201217112249
deleted file mode 100644
index b5b280bbf07..00000000000
--- a/db/schema_migrations/20201217112249
+++ /dev/null
@@ -1 +0,0 @@
-938aa97919e5a15143a72f33bebb27e501d5ef7cc53cf4e7debe9dee398b7255 \ No newline at end of file
diff --git a/db/schema_migrations/20201217132603 b/db/schema_migrations/20201217132603
deleted file mode 100644
index d1db386cbf5..00000000000
--- a/db/schema_migrations/20201217132603
+++ /dev/null
@@ -1 +0,0 @@
-164bcc838beb7d51775f8b813b92d3ec7080d4c7937d6ad16cf973131b45359e \ No newline at end of file
diff --git a/db/schema_migrations/20201218194311 b/db/schema_migrations/20201218194311
deleted file mode 100644
index f9beba74a8c..00000000000
--- a/db/schema_migrations/20201218194311
+++ /dev/null
@@ -1 +0,0 @@
-7c33bd30af66ebb9a837c72e2ced107f015d4a22c7b6393554a9299bf3907cc0 \ No newline at end of file
diff --git a/db/schema_migrations/20201221124036 b/db/schema_migrations/20201221124036
deleted file mode 100644
index 7a1049a7dd0..00000000000
--- a/db/schema_migrations/20201221124036
+++ /dev/null
@@ -1 +0,0 @@
-15517956f3b5d7ce2c05d196a34881fa169df7b1bf5ccf0dbfbee74fb3143ba7 \ No newline at end of file
diff --git a/db/schema_migrations/20201221213415 b/db/schema_migrations/20201221213415
deleted file mode 100644
index 74df483ac70..00000000000
--- a/db/schema_migrations/20201221213415
+++ /dev/null
@@ -1 +0,0 @@
-8c123da6a380524c7269ffc67ea0e533a415d3c6eddf96cee4025ea152fc7582 \ No newline at end of file
diff --git a/db/schema_migrations/20201221225303 b/db/schema_migrations/20201221225303
deleted file mode 100644
index d1824217b99..00000000000
--- a/db/schema_migrations/20201221225303
+++ /dev/null
@@ -1 +0,0 @@
-06dcd1a1f4bc0598357d48d9a0e838d9af1cf078234f2aabaa53ff9df01d2c17 \ No newline at end of file
diff --git a/db/schema_migrations/20201222151823 b/db/schema_migrations/20201222151823
deleted file mode 100644
index 914e96473a0..00000000000
--- a/db/schema_migrations/20201222151823
+++ /dev/null
@@ -1 +0,0 @@
-d3af120a74b4c55345ac7fb524395251cd3c1b3cd9685f711196a134f427845c \ No newline at end of file
diff --git a/db/schema_migrations/20201223012231 b/db/schema_migrations/20201223012231
deleted file mode 100644
index 77813ca0655..00000000000
--- a/db/schema_migrations/20201223012231
+++ /dev/null
@@ -1 +0,0 @@
-e845a6704ac92881926cca56bf7fb01c6252f1fe2b2d94fc9d6548144126d6a5 \ No newline at end of file
diff --git a/db/schema_migrations/20201223114050 b/db/schema_migrations/20201223114050
deleted file mode 100644
index 25ac0eac211..00000000000
--- a/db/schema_migrations/20201223114050
+++ /dev/null
@@ -1 +0,0 @@
-35acb5bbabfd12f97c988776aafa6ff380e2cbe2267e856b8f439f7102a6fbf2 \ No newline at end of file
diff --git a/db/schema_migrations/20201224144948 b/db/schema_migrations/20201224144948
deleted file mode 100644
index 84e2816433c..00000000000
--- a/db/schema_migrations/20201224144948
+++ /dev/null
@@ -1 +0,0 @@
-a83762c788d4ec007a26da386dc36bce16b60f5642ed3e6405482acfebefc1be \ No newline at end of file
diff --git a/db/schema_migrations/20201228110136 b/db/schema_migrations/20201228110136
deleted file mode 100644
index 51496856ff9..00000000000
--- a/db/schema_migrations/20201228110136
+++ /dev/null
@@ -1 +0,0 @@
-6488e3542276042f302d79533e3e84c43a4ef471535137bcef11e73a0e4d961f \ No newline at end of file
diff --git a/db/schema_migrations/20201228110238 b/db/schema_migrations/20201228110238
deleted file mode 100644
index 300b53bacee..00000000000
--- a/db/schema_migrations/20201228110238
+++ /dev/null
@@ -1 +0,0 @@
-7be98c4f62df9fd837f7a547916dd5481c0b4da2d4fc6680b104b2a998be1eed \ No newline at end of file
diff --git a/db/schema_migrations/20201228184500 b/db/schema_migrations/20201228184500
deleted file mode 100644
index c6168e775b2..00000000000
--- a/db/schema_migrations/20201228184500
+++ /dev/null
@@ -1 +0,0 @@
-9018fed4aab19642fafee3e50bf41be422fc3f8256d0b5d78c8a70fc96f4090f \ No newline at end of file
diff --git a/db/schema_migrations/20201229105948 b/db/schema_migrations/20201229105948
deleted file mode 100644
index 73da30d5392..00000000000
--- a/db/schema_migrations/20201229105948
+++ /dev/null
@@ -1 +0,0 @@
-cf391e617ef16f70c0daa4584959d36eda4b29c7e211f3f90ad74b4ebbc7ebbd \ No newline at end of file
diff --git a/db/schema_migrations/20201230161206 b/db/schema_migrations/20201230161206
deleted file mode 100644
index 594ca5ea890..00000000000
--- a/db/schema_migrations/20201230161206
+++ /dev/null
@@ -1 +0,0 @@
-b3fcc73c6b61469d770e9eb9a14c88bb86398db4ab4b6dc5283718a147db0ac0 \ No newline at end of file
diff --git a/db/schema_migrations/20201230180202 b/db/schema_migrations/20201230180202
deleted file mode 100644
index 62a0e277a55..00000000000
--- a/db/schema_migrations/20201230180202
+++ /dev/null
@@ -1 +0,0 @@
-c2766b50914c6b4d8c96fb958cdfb67f0d29e40df45654c35d62792c272e3d5a \ No newline at end of file
diff --git a/db/schema_migrations/20201231133921 b/db/schema_migrations/20201231133921
deleted file mode 100644
index 40f792eac8f..00000000000
--- a/db/schema_migrations/20201231133921
+++ /dev/null
@@ -1 +0,0 @@
-26bf4abb73a53f71fbcb8b5cd1ae1e1539ec59e7052b3bbed95ab1de3fda3de7 \ No newline at end of file
diff --git a/db/schema_migrations/20210101110640 b/db/schema_migrations/20210101110640
deleted file mode 100644
index e21e6768e7b..00000000000
--- a/db/schema_migrations/20210101110640
+++ /dev/null
@@ -1 +0,0 @@
-8aac4108b658a7a0646ec230dc2568cb51fea0535b13dfba8b8c9e6edb401d07 \ No newline at end of file
diff --git a/db/schema_migrations/20210102164121 b/db/schema_migrations/20210102164121
deleted file mode 100644
index 87f9b9e17f4..00000000000
--- a/db/schema_migrations/20210102164121
+++ /dev/null
@@ -1 +0,0 @@
-d15dc3e57f050f037dd6b6b2b1efdafee49bf411580e35a7b4dbe14868c41e13 \ No newline at end of file
diff --git a/db/schema_migrations/20210104163218 b/db/schema_migrations/20210104163218
deleted file mode 100644
index c58a142f92e..00000000000
--- a/db/schema_migrations/20210104163218
+++ /dev/null
@@ -1 +0,0 @@
-37aa0564d2ade1cab56a669facccbaaf08e4d9856c7a4cc120968d33cff161bd \ No newline at end of file
diff --git a/db/schema_migrations/20210105030125 b/db/schema_migrations/20210105030125
deleted file mode 100644
index d2495a23b63..00000000000
--- a/db/schema_migrations/20210105030125
+++ /dev/null
@@ -1 +0,0 @@
-c5a780e5b5e62043fb04e77ebf89f7d04dfc9bfdc70df8d89c16a3f3fd960ea3 \ No newline at end of file
diff --git a/db/schema_migrations/20210105052034 b/db/schema_migrations/20210105052034
deleted file mode 100644
index d2c1eacddf6..00000000000
--- a/db/schema_migrations/20210105052034
+++ /dev/null
@@ -1 +0,0 @@
-4eef64fb237f783cdb07e012356d48a4ec9afc349721de1c53cf3def95e83858 \ No newline at end of file
diff --git a/db/schema_migrations/20210105052229 b/db/schema_migrations/20210105052229
deleted file mode 100644
index 19b7f359482..00000000000
--- a/db/schema_migrations/20210105052229
+++ /dev/null
@@ -1 +0,0 @@
-ef994f0c65154825906fb0952b9b3073f4cb0692f01c90280edf06a4ea2ec339 \ No newline at end of file
diff --git a/db/schema_migrations/20210105103649 b/db/schema_migrations/20210105103649
deleted file mode 100644
index 9b00aa2524c..00000000000
--- a/db/schema_migrations/20210105103649
+++ /dev/null
@@ -1 +0,0 @@
-0a318fbcf54860d9fe8b3e8372e10331d2b52df738e621f4b0eec5fd4f255739 \ No newline at end of file
diff --git a/db/schema_migrations/20210105153342 b/db/schema_migrations/20210105153342
deleted file mode 100644
index cb970b9b3cc..00000000000
--- a/db/schema_migrations/20210105153342
+++ /dev/null
@@ -1 +0,0 @@
-7a252c5d76c1e71421c3aa3e01584cdeeec6a5002ba6ef0824674c64f92e2764 \ No newline at end of file
diff --git a/db/schema_migrations/20210105154321 b/db/schema_migrations/20210105154321
deleted file mode 100644
index 2f7f2477526..00000000000
--- a/db/schema_migrations/20210105154321
+++ /dev/null
@@ -1 +0,0 @@
-9327676097c49bb1a221d79dd351ad8c57a434f19e32f49951c0d6d655c2fa4e \ No newline at end of file
diff --git a/db/schema_migrations/20210106061254 b/db/schema_migrations/20210106061254
deleted file mode 100644
index 3780e444cd3..00000000000
--- a/db/schema_migrations/20210106061254
+++ /dev/null
@@ -1 +0,0 @@
-f4c81be1168dc8dc3eaadbc9b0d46cfd5aefa0b9e4d61fa8276bbc4f59216da8 \ No newline at end of file
diff --git a/db/schema_migrations/20210106153021 b/db/schema_migrations/20210106153021
deleted file mode 100644
index a00c59a8534..00000000000
--- a/db/schema_migrations/20210106153021
+++ /dev/null
@@ -1 +0,0 @@
-71e005116082a59e40194fe5f9a500e31d67a011500d12aeecd59cb64d611848 \ No newline at end of file
diff --git a/db/schema_migrations/20210106155209 b/db/schema_migrations/20210106155209
deleted file mode 100644
index 10dde1cf874..00000000000
--- a/db/schema_migrations/20210106155209
+++ /dev/null
@@ -1 +0,0 @@
-4aeff45663a9f5a41a8dd92298afb4b0b57aa6f190f4648455df2fa1e39e174f \ No newline at end of file
diff --git a/db/schema_migrations/20210106191305 b/db/schema_migrations/20210106191305
deleted file mode 100644
index 5fd79e227e6..00000000000
--- a/db/schema_migrations/20210106191305
+++ /dev/null
@@ -1 +0,0 @@
-938977d6379e484a53857304c339a024c32d8b71c2175574a72314e461d67e3b \ No newline at end of file
diff --git a/db/schema_migrations/20210106225424 b/db/schema_migrations/20210106225424
deleted file mode 100644
index 84878ee30f4..00000000000
--- a/db/schema_migrations/20210106225424
+++ /dev/null
@@ -1 +0,0 @@
-a0561e52982756aded22563e833ab8005b4f45b84c81e872dd8c7188aeb84434 \ No newline at end of file
diff --git a/db/schema_migrations/20210107105306 b/db/schema_migrations/20210107105306
deleted file mode 100644
index fe66a041837..00000000000
--- a/db/schema_migrations/20210107105306
+++ /dev/null
@@ -1 +0,0 @@
-f76ce27a82f4773dcda324d79cc93a044f21317dbb9fdff035879502b5752da3 \ No newline at end of file
diff --git a/db/schema_migrations/20210107154615 b/db/schema_migrations/20210107154615
deleted file mode 100644
index f8b6f97d3fe..00000000000
--- a/db/schema_migrations/20210107154615
+++ /dev/null
@@ -1 +0,0 @@
-3e867ceefcab4f043b89d3c04e6e0a1182423039e1a9245e611128efe77c0e88 \ No newline at end of file
diff --git a/db/schema_migrations/20210107194543 b/db/schema_migrations/20210107194543
deleted file mode 100644
index 997bdd98b5a..00000000000
--- a/db/schema_migrations/20210107194543
+++ /dev/null
@@ -1 +0,0 @@
-d72cf1c88a060ccadd9f90cbef5ae7d4ea6a4416a6263d11a870e01b02d1f935 \ No newline at end of file
diff --git a/db/schema_migrations/20210108161039 b/db/schema_migrations/20210108161039
deleted file mode 100644
index d60bab2ec5a..00000000000
--- a/db/schema_migrations/20210108161039
+++ /dev/null
@@ -1 +0,0 @@
-7888a82e3bbc1f4c78badcbe8335ac823ebdedec843a9d90f91cf0d5c169a191 \ No newline at end of file
diff --git a/db/schema_migrations/20210111051045 b/db/schema_migrations/20210111051045
deleted file mode 100644
index 842c164fc20..00000000000
--- a/db/schema_migrations/20210111051045
+++ /dev/null
@@ -1 +0,0 @@
-6075e469081fcca124c0c4b485071a086545b502c398314cca05052765072caf \ No newline at end of file
diff --git a/db/schema_migrations/20210111053308 b/db/schema_migrations/20210111053308
deleted file mode 100644
index b7968a03c32..00000000000
--- a/db/schema_migrations/20210111053308
+++ /dev/null
@@ -1 +0,0 @@
-a98ca25378df3fc798b6ae361b3a47b697f6b853796975221329db023cb98466 \ No newline at end of file
diff --git a/db/schema_migrations/20210111075104 b/db/schema_migrations/20210111075104
deleted file mode 100644
index f0d8f6da529..00000000000
--- a/db/schema_migrations/20210111075104
+++ /dev/null
@@ -1 +0,0 @@
-3568bda1b43710880c8bfe2777d346aba1172217c27b5e690e7151aec9da2288 \ No newline at end of file
diff --git a/db/schema_migrations/20210111075105 b/db/schema_migrations/20210111075105
deleted file mode 100644
index d058560ead2..00000000000
--- a/db/schema_migrations/20210111075105
+++ /dev/null
@@ -1 +0,0 @@
-d48f5e042f3f919041f0c93e6492bcf56c19f4268d4819bd231ddffe70ba7c6b \ No newline at end of file
diff --git a/db/schema_migrations/20210111075206 b/db/schema_migrations/20210111075206
deleted file mode 100644
index 369c5316124..00000000000
--- a/db/schema_migrations/20210111075206
+++ /dev/null
@@ -1 +0,0 @@
-9da5955d9f71d671a41e6d03f76f87370d6e67b6853707adb164f7ffa8c75082 \ No newline at end of file
diff --git a/db/schema_migrations/20210112084512 b/db/schema_migrations/20210112084512
deleted file mode 100644
index 3091c8e2542..00000000000
--- a/db/schema_migrations/20210112084512
+++ /dev/null
@@ -1 +0,0 @@
-e8e26d49a8292e31ef0ea88a0262f0386b8deda83658ea4de7d464d79c5428e4 \ No newline at end of file
diff --git a/db/schema_migrations/20210112143418 b/db/schema_migrations/20210112143418
deleted file mode 100644
index 3183c8cf220..00000000000
--- a/db/schema_migrations/20210112143418
+++ /dev/null
@@ -1 +0,0 @@
-05d45e25ab9ef1565c04ca6515e0b01f2f98c5e98b1eeb09fa9dd43ebbe3c4d0 \ No newline at end of file
diff --git a/db/schema_migrations/20210112202949 b/db/schema_migrations/20210112202949
deleted file mode 100644
index 5926b701b1a..00000000000
--- a/db/schema_migrations/20210112202949
+++ /dev/null
@@ -1 +0,0 @@
-56595e67e9e78a9558e6874d75bdcc295b89ab0096d1b37e4d9366e1574d241c \ No newline at end of file
diff --git a/db/schema_migrations/20210113224909 b/db/schema_migrations/20210113224909
deleted file mode 100644
index ab03538f520..00000000000
--- a/db/schema_migrations/20210113224909
+++ /dev/null
@@ -1 +0,0 @@
-e6841491cd7d2cc015fd628f5c14270720d59cbb17b7efb160937963f074f5c2 \ No newline at end of file
diff --git a/db/schema_migrations/20210113231532 b/db/schema_migrations/20210113231532
deleted file mode 100644
index eb39ac161ba..00000000000
--- a/db/schema_migrations/20210113231532
+++ /dev/null
@@ -1 +0,0 @@
-1a430ce6d137ee896cbd37bb822ccd18c9e87204b765b1192928dd82efb28602 \ No newline at end of file
diff --git a/db/schema_migrations/20210113231546 b/db/schema_migrations/20210113231546
deleted file mode 100644
index 3286727b72c..00000000000
--- a/db/schema_migrations/20210113231546
+++ /dev/null
@@ -1 +0,0 @@
-5d7bbf376acbf5679d111866e70b69eebba26a487a9e7d6bd571f15dc423e3e3 \ No newline at end of file
diff --git a/db/schema_migrations/20210114033715 b/db/schema_migrations/20210114033715
deleted file mode 100644
index 6d25bd971e2..00000000000
--- a/db/schema_migrations/20210114033715
+++ /dev/null
@@ -1 +0,0 @@
-69aae8d967fdb8af816a969fd818ed325b8d780b4faaa205c78a66c5d533ab2a \ No newline at end of file
diff --git a/db/schema_migrations/20210114142443 b/db/schema_migrations/20210114142443
deleted file mode 100644
index d4e771a56f5..00000000000
--- a/db/schema_migrations/20210114142443
+++ /dev/null
@@ -1 +0,0 @@
-7ef5cb1f167c133c67fc98c0abe929516ec700179747d3353d19cf8219ebd0ef \ No newline at end of file
diff --git a/db/schema_migrations/20210115090452 b/db/schema_migrations/20210115090452
deleted file mode 100644
index 92c5574e71f..00000000000
--- a/db/schema_migrations/20210115090452
+++ /dev/null
@@ -1 +0,0 @@
-5415850ae27c507fd8b1df20951e25b42352f4f9ec8e1402019533170edabdb8 \ No newline at end of file
diff --git a/db/schema_migrations/20210115215854 b/db/schema_migrations/20210115215854
deleted file mode 100644
index c27de41ad0a..00000000000
--- a/db/schema_migrations/20210115215854
+++ /dev/null
@@ -1 +0,0 @@
-cb846ce5f6270cfdc543c3d4ad3e861b2a92445b952ee8f0a02f4171b9792411 \ No newline at end of file
diff --git a/db/schema_migrations/20210115220610 b/db/schema_migrations/20210115220610
deleted file mode 100644
index 002c37e54ec..00000000000
--- a/db/schema_migrations/20210115220610
+++ /dev/null
@@ -1 +0,0 @@
-541a6626d3afd4fd421fd59fe5eb8ab7764952ae780c83c3805fd4a29e3f42fb \ No newline at end of file
diff --git a/db/schema_migrations/20210117210226 b/db/schema_migrations/20210117210226
deleted file mode 100644
index a68f7f6d93e..00000000000
--- a/db/schema_migrations/20210117210226
+++ /dev/null
@@ -1 +0,0 @@
-c0d22d00d52a516347930e1a36f350113c0949214925176f08ceed81999746bd \ No newline at end of file
diff --git a/db/schema_migrations/20210118111307 b/db/schema_migrations/20210118111307
deleted file mode 100644
index 036d909f5ad..00000000000
--- a/db/schema_migrations/20210118111307
+++ /dev/null
@@ -1 +0,0 @@
-f33cc3eebc9197db381d81150a140582e30905d3964d6fb444caad6c9eff1b31 \ No newline at end of file
diff --git a/db/schema_migrations/20210119122354 b/db/schema_migrations/20210119122354
deleted file mode 100644
index a17b2dab2df..00000000000
--- a/db/schema_migrations/20210119122354
+++ /dev/null
@@ -1 +0,0 @@
-e8264993f6503268cd99e8ca26ccdc0e986f31a2818b9bbef2a9cef36191e686 \ No newline at end of file
diff --git a/db/schema_migrations/20210119153801 b/db/schema_migrations/20210119153801
deleted file mode 100644
index f84f7ad1d48..00000000000
--- a/db/schema_migrations/20210119153801
+++ /dev/null
@@ -1 +0,0 @@
-c8b5485f158fdec0ab6813e4014713786dfa231b901e77ea610a873d03f8f0f0 \ No newline at end of file
diff --git a/db/schema_migrations/20210119162812 b/db/schema_migrations/20210119162812
deleted file mode 100644
index dfbf33a9fcf..00000000000
--- a/db/schema_migrations/20210119162812
+++ /dev/null
@@ -1 +0,0 @@
-cd7643fc762d8b9236ef5ac7cc285ffbd29f1953178b9b6e129082efd7b9e07b \ No newline at end of file
diff --git a/db/schema_migrations/20210120180956 b/db/schema_migrations/20210120180956
deleted file mode 100644
index 395c9c09df9..00000000000
--- a/db/schema_migrations/20210120180956
+++ /dev/null
@@ -1 +0,0 @@
-897815c347f04093da5eba420e95b6310454bd493412914e60a296bd710ebde1 \ No newline at end of file
diff --git a/db/schema_migrations/20210120221743 b/db/schema_migrations/20210120221743
deleted file mode 100644
index ce54788b86c..00000000000
--- a/db/schema_migrations/20210120221743
+++ /dev/null
@@ -1 +0,0 @@
-4bf1d277affdfa9ee772d69cb713f49f257140fb58c40bc8659d563b4cc3de29 \ No newline at end of file
diff --git a/db/schema_migrations/20210121093618 b/db/schema_migrations/20210121093618
deleted file mode 100644
index f12566f1aa9..00000000000
--- a/db/schema_migrations/20210121093618
+++ /dev/null
@@ -1 +0,0 @@
-e2be30f71b2a4a410b21e57ee53c3b54cf0214a08bc65cd92b2cb4b93bde9451 \ No newline at end of file
diff --git a/db/schema_migrations/20210121100038 b/db/schema_migrations/20210121100038
deleted file mode 100644
index 0f9379ff019..00000000000
--- a/db/schema_migrations/20210121100038
+++ /dev/null
@@ -1 +0,0 @@
-12a5eba74f0bb5b63cddd32d32009ad073e638a9defb40eeee5c16f559ebe951 \ No newline at end of file
diff --git a/db/schema_migrations/20210121121102 b/db/schema_migrations/20210121121102
deleted file mode 100644
index 6bce3892276..00000000000
--- a/db/schema_migrations/20210121121102
+++ /dev/null
@@ -1 +0,0 @@
-359231b3f18a2c1e56ffba4872a51d01fd4ca834ef722e1133a5a9f01e4271e9 \ No newline at end of file
diff --git a/db/schema_migrations/20210122073805 b/db/schema_migrations/20210122073805
deleted file mode 100644
index 322c90eb820..00000000000
--- a/db/schema_migrations/20210122073805
+++ /dev/null
@@ -1 +0,0 @@
-f5231b1eec17ea1a67f2d2f4ca759314afb85b2c8fb431e3303d530d44bdb1ef \ No newline at end of file
diff --git a/db/schema_migrations/20210122153259 b/db/schema_migrations/20210122153259
deleted file mode 100644
index 887f0ac4a5c..00000000000
--- a/db/schema_migrations/20210122153259
+++ /dev/null
@@ -1 +0,0 @@
-4c697cc183a000ee8c18b516e4b1d77d0f8d2d3d7abe11121f2240a60c03216c \ No newline at end of file
diff --git a/db/schema_migrations/20210122155158 b/db/schema_migrations/20210122155158
deleted file mode 100644
index f521f910346..00000000000
--- a/db/schema_migrations/20210122155158
+++ /dev/null
@@ -1 +0,0 @@
-5f326f101ff06993e9160b0486d24d615abd6d5027b375e422f776181ad8a193 \ No newline at end of file
diff --git a/db/schema_migrations/20210125105410 b/db/schema_migrations/20210125105410
deleted file mode 100644
index d685894bd8a..00000000000
--- a/db/schema_migrations/20210125105410
+++ /dev/null
@@ -1 +0,0 @@
-0c80fa1c88f67ef34bbfab52b1b75eadc4a6f07557986f0fbe4ffd83e20df52a \ No newline at end of file
diff --git a/db/schema_migrations/20210126030249 b/db/schema_migrations/20210126030249
deleted file mode 100644
index 068f5eeb9c5..00000000000
--- a/db/schema_migrations/20210126030249
+++ /dev/null
@@ -1 +0,0 @@
-b5c219d1b1443ddf482f26d8280a1c7318456affce3ad57a082eb8f9efc32206 \ No newline at end of file
diff --git a/db/schema_migrations/20210126091713 b/db/schema_migrations/20210126091713
deleted file mode 100644
index b75636bd437..00000000000
--- a/db/schema_migrations/20210126091713
+++ /dev/null
@@ -1 +0,0 @@
-3906739d07514e6e59f79a4a81d28859a2481614a299c95ec1b1d9825a07ec64 \ No newline at end of file
diff --git a/db/schema_migrations/20210126092102 b/db/schema_migrations/20210126092102
deleted file mode 100644
index 803643389f6..00000000000
--- a/db/schema_migrations/20210126092102
+++ /dev/null
@@ -1 +0,0 @@
-124c5ae1a1ccade5dec01f72b726e03febc8f56411d7d8990f976bb2a9516037 \ No newline at end of file
diff --git a/db/schema_migrations/20210126233608 b/db/schema_migrations/20210126233608
deleted file mode 100644
index adab3a3f365..00000000000
--- a/db/schema_migrations/20210126233608
+++ /dev/null
@@ -1 +0,0 @@
-4105ae45742c2eda67fe5c54256732e55555ab7832e4cbf0fcb041599c23bd29 \ No newline at end of file
diff --git a/db/schema_migrations/20210127052226 b/db/schema_migrations/20210127052226
deleted file mode 100644
index ca7d44edff8..00000000000
--- a/db/schema_migrations/20210127052226
+++ /dev/null
@@ -1 +0,0 @@
-e978687e9b27db5288862ea85053f3fc04a8e841702b16ca17c01398a86654d0 \ No newline at end of file
diff --git a/db/schema_migrations/20210127143025 b/db/schema_migrations/20210127143025
deleted file mode 100644
index a4875304c0b..00000000000
--- a/db/schema_migrations/20210127143025
+++ /dev/null
@@ -1 +0,0 @@
-c173ba86340efe39977f1b319d1ebcead634e3bfe819a30e230fb4f81766f28a \ No newline at end of file
diff --git a/db/schema_migrations/20210127152613 b/db/schema_migrations/20210127152613
deleted file mode 100644
index f5d42ea2bc5..00000000000
--- a/db/schema_migrations/20210127152613
+++ /dev/null
@@ -1 +0,0 @@
-32f636ffad4d2c6a002129d6e3eaeaf5d8f420dcc1273665129dc4d23f2e0dbe \ No newline at end of file
diff --git a/db/schema_migrations/20210127202613 b/db/schema_migrations/20210127202613
deleted file mode 100644
index 42d38d4c1d7..00000000000
--- a/db/schema_migrations/20210127202613
+++ /dev/null
@@ -1 +0,0 @@
-951f46f88c1b07505e0b560e802a8bd701db7d379342d97b0bff3ad90e81fb02 \ No newline at end of file
diff --git a/db/schema_migrations/20210128044930 b/db/schema_migrations/20210128044930
deleted file mode 100644
index 4965cd9a9c6..00000000000
--- a/db/schema_migrations/20210128044930
+++ /dev/null
@@ -1 +0,0 @@
-6164ef91c60bd614310cbda6ad8ab1a205cae17c4d037fafa89eaf95d06323e4 \ No newline at end of file
diff --git a/db/schema_migrations/20210128101707 b/db/schema_migrations/20210128101707
deleted file mode 100644
index f10f080c1df..00000000000
--- a/db/schema_migrations/20210128101707
+++ /dev/null
@@ -1 +0,0 @@
-ae84fa35fcc5a0780d86887294a32e250d2ac13dcf607750f834df5828e5bece \ No newline at end of file
diff --git a/db/schema_migrations/20210128114526 b/db/schema_migrations/20210128114526
deleted file mode 100644
index 107c86913ba..00000000000
--- a/db/schema_migrations/20210128114526
+++ /dev/null
@@ -1 +0,0 @@
-ad83205a0203427ccad1c25933e28cf13ebfb0274865ce5f0f2d578e84bb07a3 \ No newline at end of file
diff --git a/db/schema_migrations/20210128140157 b/db/schema_migrations/20210128140157
deleted file mode 100644
index 2b71db39920..00000000000
--- a/db/schema_migrations/20210128140157
+++ /dev/null
@@ -1 +0,0 @@
-0fa84b2038f33e27e549bdb3eb137e1813f604b6e81abc67a49a54d3e1e4bcf5 \ No newline at end of file
diff --git a/db/schema_migrations/20210128140232 b/db/schema_migrations/20210128140232
deleted file mode 100644
index ee335323fce..00000000000
--- a/db/schema_migrations/20210128140232
+++ /dev/null
@@ -1 +0,0 @@
-93f337364eb5ca5c67f4d4767d1aee9972bfe0596c89f006317dd6103558e35c \ No newline at end of file
diff --git a/db/schema_migrations/20210128152830 b/db/schema_migrations/20210128152830
deleted file mode 100644
index 36d3de788eb..00000000000
--- a/db/schema_migrations/20210128152830
+++ /dev/null
@@ -1 +0,0 @@
-932509d18f1cfdfa09f1565e4ac2f197b7ca792263ff5da3e5b712fae7279925 \ No newline at end of file
diff --git a/db/schema_migrations/20210128172149 b/db/schema_migrations/20210128172149
deleted file mode 100644
index cc0e050be3e..00000000000
--- a/db/schema_migrations/20210128172149
+++ /dev/null
@@ -1 +0,0 @@
-1cf1305ad5eaaef51f99f057b8a2e81731d69a6d02629c0c9a7d94dfdecbea47 \ No newline at end of file
diff --git a/db/schema_migrations/20210129225244 b/db/schema_migrations/20210129225244
deleted file mode 100644
index 1b05096b07f..00000000000
--- a/db/schema_migrations/20210129225244
+++ /dev/null
@@ -1 +0,0 @@
-6cb54c71a9835ec1b3cf801a19c2cd385d224e0438c7924b6a29d298ecebe8a7 \ No newline at end of file
diff --git a/db/schema_migrations/20210201034649 b/db/schema_migrations/20210201034649
deleted file mode 100644
index 5cc99ebc893..00000000000
--- a/db/schema_migrations/20210201034649
+++ /dev/null
@@ -1 +0,0 @@
-e5492820a8618d5599429ece04ea941e869c84c22d213d536644bcefc5775363 \ No newline at end of file
diff --git a/db/schema_migrations/20210201140434 b/db/schema_migrations/20210201140434
deleted file mode 100644
index 00671276b1c..00000000000
--- a/db/schema_migrations/20210201140434
+++ /dev/null
@@ -1 +0,0 @@
-71220cfc36215f6c22d22d1fb0b74389e90c58733214b5fa36dcb8da0377a120 \ No newline at end of file
diff --git a/db/schema_migrations/20210203002331 b/db/schema_migrations/20210203002331
deleted file mode 100644
index f1ed6bf23f6..00000000000
--- a/db/schema_migrations/20210203002331
+++ /dev/null
@@ -1 +0,0 @@
-b8a19b2ebf648a1b79a488a7a2847f6a392e594464c1ba0ae96f274f583559e3 \ No newline at end of file
diff --git a/db/schema_migrations/20210203092540 b/db/schema_migrations/20210203092540
deleted file mode 100644
index 12367417d44..00000000000
--- a/db/schema_migrations/20210203092540
+++ /dev/null
@@ -1 +0,0 @@
-fa0b69df96069dd29971f69a51ce4eb691480904c5693fa480f6daa83b042e77 \ No newline at end of file
diff --git a/db/schema_migrations/20210203092549 b/db/schema_migrations/20210203092549
deleted file mode 100644
index 967b0d3acc7..00000000000
--- a/db/schema_migrations/20210203092549
+++ /dev/null
@@ -1 +0,0 @@
-096d13548e156a13b9ccdbb39ed83b3be7ef64a57df5daea2e3cd870f3e2b448 \ No newline at end of file
diff --git a/db/schema_migrations/20210203143131 b/db/schema_migrations/20210203143131
deleted file mode 100644
index 6b318f8c219..00000000000
--- a/db/schema_migrations/20210203143131
+++ /dev/null
@@ -1 +0,0 @@
-1f05176d9f6a88e9d740000084b7c9f5c72c61a59dbe1f68f43b3b5606ecd9d8 \ No newline at end of file
diff --git a/db/schema_migrations/20210203221631 b/db/schema_migrations/20210203221631
deleted file mode 100644
index ed9efcd2b5f..00000000000
--- a/db/schema_migrations/20210203221631
+++ /dev/null
@@ -1 +0,0 @@
-ec6832ba26fca8d8427383cd0189765191a0a7f17bb78d61b900c5b541d5725e \ No newline at end of file
diff --git a/db/schema_migrations/20210203222620 b/db/schema_migrations/20210203222620
deleted file mode 100644
index 2c8c3ffc111..00000000000
--- a/db/schema_migrations/20210203222620
+++ /dev/null
@@ -1 +0,0 @@
-6d3250533b72c6aa307570d386725fa3ebe1ec49c36edc0f7d6dc8a1d5092826 \ No newline at end of file
diff --git a/db/schema_migrations/20210203223551 b/db/schema_migrations/20210203223551
deleted file mode 100644
index 53b3a9f65aa..00000000000
--- a/db/schema_migrations/20210203223551
+++ /dev/null
@@ -1 +0,0 @@
-4ccf450bbc9061edae81cabcfafd9360f1f57cfd25af3ad016fbbb344f9fe694 \ No newline at end of file
diff --git a/db/schema_migrations/20210204152257 b/db/schema_migrations/20210204152257
deleted file mode 100644
index c98d4637d05..00000000000
--- a/db/schema_migrations/20210204152257
+++ /dev/null
@@ -1 +0,0 @@
-cb9f4b4e627cbc163653fc01c0542ef0ce87139b376c55bbaa4d7ab23e9b8973 \ No newline at end of file
diff --git a/db/schema_migrations/20210204212850 b/db/schema_migrations/20210204212850
deleted file mode 100644
index ffa4ca8393e..00000000000
--- a/db/schema_migrations/20210204212850
+++ /dev/null
@@ -1 +0,0 @@
-2a40acf9a3ac2716120388cfe79be13130e4587286d215596e9c75097af1e436 \ No newline at end of file
diff --git a/db/schema_migrations/20210205084357 b/db/schema_migrations/20210205084357
deleted file mode 100644
index 6babb782c70..00000000000
--- a/db/schema_migrations/20210205084357
+++ /dev/null
@@ -1 +0,0 @@
-5bd622f36126b06c7c585ee14a8140750843d36092e79b6cc35b62c06afb1178 \ No newline at end of file
diff --git a/db/schema_migrations/20210205104425 b/db/schema_migrations/20210205104425
deleted file mode 100644
index c51f201b5a6..00000000000
--- a/db/schema_migrations/20210205104425
+++ /dev/null
@@ -1 +0,0 @@
-4df2229fca7652cb836c867b621da91f1194899c50bb0a8be2fbae58f29dc788 \ No newline at end of file
diff --git a/db/schema_migrations/20210205134213 b/db/schema_migrations/20210205134213
deleted file mode 100644
index bc2525e85cd..00000000000
--- a/db/schema_migrations/20210205134213
+++ /dev/null
@@ -1 +0,0 @@
-7c368cad497ccfd86c6a92e2edfec1d2a16879eb749184b1d20c5ab4c702b974 \ No newline at end of file
diff --git a/db/schema_migrations/20210205143926 b/db/schema_migrations/20210205143926
deleted file mode 100644
index 00a8c3528a7..00000000000
--- a/db/schema_migrations/20210205143926
+++ /dev/null
@@ -1 +0,0 @@
-cdf55e9f2b1b9c375920198a438d29fe3c9ab7147f3c670b0d66b11d499573d9 \ No newline at end of file
diff --git a/db/schema_migrations/20210205144537 b/db/schema_migrations/20210205144537
deleted file mode 100644
index 6ca27521248..00000000000
--- a/db/schema_migrations/20210205144537
+++ /dev/null
@@ -1 +0,0 @@
-d9cfb7515805e642c562b8be58b6cd482c24e62e76245db35a7d91b25c327d8d \ No newline at end of file
diff --git a/db/schema_migrations/20210205174154 b/db/schema_migrations/20210205174154
deleted file mode 100644
index fc8c4b6cff1..00000000000
--- a/db/schema_migrations/20210205174154
+++ /dev/null
@@ -1 +0,0 @@
-483d1b4a24086fa57efe7f3b3fa872cf793352f80aba5c25614f07eafa2d30c5 \ No newline at end of file
diff --git a/db/schema_migrations/20210205213915 b/db/schema_migrations/20210205213915
deleted file mode 100644
index 5849abd1d03..00000000000
--- a/db/schema_migrations/20210205213915
+++ /dev/null
@@ -1 +0,0 @@
-c7c2936062f4a7c764938453fb28dc2f461a06f0a21cc74b1750edbde9398fa1 \ No newline at end of file
diff --git a/db/schema_migrations/20210205213933 b/db/schema_migrations/20210205213933
deleted file mode 100644
index f3ebb2672c7..00000000000
--- a/db/schema_migrations/20210205213933
+++ /dev/null
@@ -1 +0,0 @@
-caec7f6c66a0277561f650ae513fedaba581ab35bb238351eccccfef1132d118 \ No newline at end of file
diff --git a/db/schema_migrations/20210205214003 b/db/schema_migrations/20210205214003
deleted file mode 100644
index 4d1ea7570f5..00000000000
--- a/db/schema_migrations/20210205214003
+++ /dev/null
@@ -1 +0,0 @@
-6ca08c885fddccd3c82fc8651d20140655b65019e56f9c6136e92140401386d1 \ No newline at end of file
diff --git a/db/schema_migrations/20210208103243 b/db/schema_migrations/20210208103243
deleted file mode 100644
index c251beb4b2f..00000000000
--- a/db/schema_migrations/20210208103243
+++ /dev/null
@@ -1 +0,0 @@
-039962e291f9adde52379cac8f8278aa1b339d973fb33ae40ea7d8dc3e113fb6 \ No newline at end of file
diff --git a/db/schema_migrations/20210208125050 b/db/schema_migrations/20210208125050
deleted file mode 100644
index 35877cfc029..00000000000
--- a/db/schema_migrations/20210208125050
+++ /dev/null
@@ -1 +0,0 @@
-b9200d6c754f7c450ba0c718171806e8f4f9720d870e532f4800640ca707f24f \ No newline at end of file
diff --git a/db/schema_migrations/20210208125248 b/db/schema_migrations/20210208125248
deleted file mode 100644
index 91d5c4bb950..00000000000
--- a/db/schema_migrations/20210208125248
+++ /dev/null
@@ -1 +0,0 @@
-3a7fb1b7959f09b9ba464253a72d52bcb744e7f78aac4f44e1d9201fa3c8387d \ No newline at end of file
diff --git a/db/schema_migrations/20210208144134 b/db/schema_migrations/20210208144134
deleted file mode 100644
index 1afe893eba0..00000000000
--- a/db/schema_migrations/20210208144134
+++ /dev/null
@@ -1 +0,0 @@
-845636d8a0c6e9b6b39194cb44ffeceea3464023c22fadb2a4da44fed5dd973f \ No newline at end of file
diff --git a/db/schema_migrations/20210208161207 b/db/schema_migrations/20210208161207
deleted file mode 100644
index 7064a636822..00000000000
--- a/db/schema_migrations/20210208161207
+++ /dev/null
@@ -1 +0,0 @@
-818fcf0f0fec9d2833b091ef380005a2d485486522fb63e2a7b2fd01dbf1ff79 \ No newline at end of file
diff --git a/db/schema_migrations/20210208200914 b/db/schema_migrations/20210208200914
deleted file mode 100644
index 10a98a3d6e2..00000000000
--- a/db/schema_migrations/20210208200914
+++ /dev/null
@@ -1 +0,0 @@
-e7a0121e8e21acd356daa882d8fe83242f4db180915dd0f3c25835c6c664ce0b \ No newline at end of file
diff --git a/db/schema_migrations/20210209110019 b/db/schema_migrations/20210209110019
deleted file mode 100644
index d11e6e5a167..00000000000
--- a/db/schema_migrations/20210209110019
+++ /dev/null
@@ -1 +0,0 @@
-a24354264df3c12411af040903d26faf298f06a7334ef118f87b3e88b683b326 \ No newline at end of file
diff --git a/db/schema_migrations/20210209160510 b/db/schema_migrations/20210209160510
deleted file mode 100644
index 3aa90658d4e..00000000000
--- a/db/schema_migrations/20210209160510
+++ /dev/null
@@ -1 +0,0 @@
-601d67a2911c461881064ec18a2246ef9e5b2835eb0fdf40e701c9360e19eca4 \ No newline at end of file
diff --git a/db/schema_migrations/20210209171525 b/db/schema_migrations/20210209171525
deleted file mode 100644
index 0c421b99a39..00000000000
--- a/db/schema_migrations/20210209171525
+++ /dev/null
@@ -1 +0,0 @@
-5c661c453922181b350b8551d9a8f9b097e568459a2c2d128e41d9aefb026ab5 \ No newline at end of file
diff --git a/db/schema_migrations/20210209232508 b/db/schema_migrations/20210209232508
deleted file mode 100644
index d424fff0469..00000000000
--- a/db/schema_migrations/20210209232508
+++ /dev/null
@@ -1 +0,0 @@
-484751de711e873e0f0f22d5951e36bf60d4826ebc95afa45e4f6cdaa0e3c024 \ No newline at end of file
diff --git a/db/schema_migrations/20210210093901 b/db/schema_migrations/20210210093901
deleted file mode 100644
index c1bbb93de21..00000000000
--- a/db/schema_migrations/20210210093901
+++ /dev/null
@@ -1 +0,0 @@
-961c147e9c8e35eac5b8dd33f879582e173b7f6e31659b2d00989bc38afc6f5a \ No newline at end of file
diff --git a/db/schema_migrations/20210210210232 b/db/schema_migrations/20210210210232
deleted file mode 100644
index 96f31a2adef..00000000000
--- a/db/schema_migrations/20210210210232
+++ /dev/null
@@ -1 +0,0 @@
-e1bd58eeaf63caf473680a8c4b7269cc63e7c0d6e8d4e71636608e10c9731c85 \ No newline at end of file
diff --git a/db/schema_migrations/20210210221006 b/db/schema_migrations/20210210221006
deleted file mode 100644
index 5292b5c0dce..00000000000
--- a/db/schema_migrations/20210210221006
+++ /dev/null
@@ -1 +0,0 @@
-1ff1256d2deac0a1545ef7db30d8ba7969265d6c2df62f6bd20f9f1721a482cb \ No newline at end of file
diff --git a/db/schema_migrations/20210211195543 b/db/schema_migrations/20210211195543
deleted file mode 100644
index 7f15ca21d36..00000000000
--- a/db/schema_migrations/20210211195543
+++ /dev/null
@@ -1 +0,0 @@
-484338ddc83bfb44523d08da92ac7f5b9d13e1a66ad1c9c3f7590f91fc9305c0 \ No newline at end of file
diff --git a/db/schema_migrations/20210212153934 b/db/schema_migrations/20210212153934
deleted file mode 100644
index 28ef55d012c..00000000000
--- a/db/schema_migrations/20210212153934
+++ /dev/null
@@ -1 +0,0 @@
-233a976aab340f16ed1c896963580fb66f4c9b4dee6a34f9536a62a4f7688792 \ No newline at end of file
diff --git a/db/schema_migrations/20210212163231 b/db/schema_migrations/20210212163231
deleted file mode 100644
index e0ba3d83bf5..00000000000
--- a/db/schema_migrations/20210212163231
+++ /dev/null
@@ -1 +0,0 @@
-4c6061f6ab1cb9e070a3ae87d44caf12d2c110a6033f0b33898b4b7ea7e37055 \ No newline at end of file
diff --git a/db/schema_migrations/20210214201118 b/db/schema_migrations/20210214201118
deleted file mode 100644
index 9551d2ddf50..00000000000
--- a/db/schema_migrations/20210214201118
+++ /dev/null
@@ -1 +0,0 @@
-8c1da1c7edba16993da93d9075ad2a3624b8c12ccf73a241e1a166014a99e254 \ No newline at end of file
diff --git a/db/schema_migrations/20210214205155 b/db/schema_migrations/20210214205155
deleted file mode 100644
index 583d7ca1167..00000000000
--- a/db/schema_migrations/20210214205155
+++ /dev/null
@@ -1 +0,0 @@
-7678d97de752e7a9a571d80febc74eb44c699c7b1967690d9a2391036caea5d2 \ No newline at end of file
diff --git a/db/schema_migrations/20210215095328 b/db/schema_migrations/20210215095328
deleted file mode 100644
index b360aaf4ad8..00000000000
--- a/db/schema_migrations/20210215095328
+++ /dev/null
@@ -1 +0,0 @@
-25820a3d060826a082565f12a3ac96deafbbde750f5756d71e34d14801ec6148 \ No newline at end of file
diff --git a/db/schema_migrations/20210215144909 b/db/schema_migrations/20210215144909
deleted file mode 100644
index 02939e3dba5..00000000000
--- a/db/schema_migrations/20210215144909
+++ /dev/null
@@ -1 +0,0 @@
-2965d990ec9cf2edd610b063686f9a1d9de4c38bcba3c8439a18159812d529d4 \ No newline at end of file
diff --git a/db/schema_migrations/20210215172449 b/db/schema_migrations/20210215172449
deleted file mode 100644
index 5b310d80d6a..00000000000
--- a/db/schema_migrations/20210215172449
+++ /dev/null
@@ -1 +0,0 @@
-f72f0a31bca545d2528030019695b03e0858d7ae9a0fb32d407c25580731fa6b \ No newline at end of file
diff --git a/db/schema_migrations/20210216122140 b/db/schema_migrations/20210216122140
deleted file mode 100644
index 2d2faca6b19..00000000000
--- a/db/schema_migrations/20210216122140
+++ /dev/null
@@ -1 +0,0 @@
-0aa6f7385cf13c2b0ee9b7d2a51b63dd208feccffecee8f08ea3d183ebb5ffb4 \ No newline at end of file
diff --git a/db/schema_migrations/20210216135504 b/db/schema_migrations/20210216135504
deleted file mode 100644
index 99cda90b2ee..00000000000
--- a/db/schema_migrations/20210216135504
+++ /dev/null
@@ -1 +0,0 @@
-8c676b4142db828b1d2d5dc6bd891eb929d12ab13e9073693ab7d830bcea599a \ No newline at end of file
diff --git a/db/schema_migrations/20210216193620 b/db/schema_migrations/20210216193620
deleted file mode 100644
index 6c8e8d4c1c4..00000000000
--- a/db/schema_migrations/20210216193620
+++ /dev/null
@@ -1 +0,0 @@
-3587ba61d003385ea63ce900c1dd1c2bd1f2386abd921615b50421f1b798f553 \ No newline at end of file
diff --git a/db/schema_migrations/20210216223335 b/db/schema_migrations/20210216223335
deleted file mode 100644
index a086aaa8c91..00000000000
--- a/db/schema_migrations/20210216223335
+++ /dev/null
@@ -1 +0,0 @@
-52bf190bdb219366c790a5b7c081bfb383543498780cc95a25eafcecea036426 \ No newline at end of file
diff --git a/db/schema_migrations/20210217100728 b/db/schema_migrations/20210217100728
deleted file mode 100644
index 6027a27f8c2..00000000000
--- a/db/schema_migrations/20210217100728
+++ /dev/null
@@ -1 +0,0 @@
-281ea05a95785b7f1d2d805bf8fe071c0fa59425eb01b46eeb69ad21f5650e29 \ No newline at end of file
diff --git a/db/schema_migrations/20210217101901 b/db/schema_migrations/20210217101901
deleted file mode 100644
index f4c38be26e0..00000000000
--- a/db/schema_migrations/20210217101901
+++ /dev/null
@@ -1 +0,0 @@
-909aee5ed0ad447fec425f7252fc6dbec827a66ff720620bae1bf3a32536cb96 \ No newline at end of file
diff --git a/db/schema_migrations/20210218040814 b/db/schema_migrations/20210218040814
deleted file mode 100644
index 3c55d951c14..00000000000
--- a/db/schema_migrations/20210218040814
+++ /dev/null
@@ -1 +0,0 @@
-6fe34be82f9aee6cbdb729a67d1d4ac0702c8d9774a038bfd4fd9d9cb28b1a2b \ No newline at end of file
diff --git a/db/schema_migrations/20210218105431 b/db/schema_migrations/20210218105431
deleted file mode 100644
index 35dda4ac6f6..00000000000
--- a/db/schema_migrations/20210218105431
+++ /dev/null
@@ -1 +0,0 @@
-b5ff5aeb9cef243165d9c40db7211f61a632edb6a189c09112ef069d267bf64d \ No newline at end of file
diff --git a/db/schema_migrations/20210218110552 b/db/schema_migrations/20210218110552
deleted file mode 100644
index 5fb325bdfb5..00000000000
--- a/db/schema_migrations/20210218110552
+++ /dev/null
@@ -1 +0,0 @@
-7631c82f9762e643a4da9c03f3870ab1c97fae93da4975219d9ab7cd629720ec \ No newline at end of file
diff --git a/db/schema_migrations/20210218142626 b/db/schema_migrations/20210218142626
deleted file mode 100644
index e23a8139ffb..00000000000
--- a/db/schema_migrations/20210218142626
+++ /dev/null
@@ -1 +0,0 @@
-063c97800eec5bfc7f6879dbe559fa39952295d5ba947cf44ad03ac23212e924 \ No newline at end of file
diff --git a/db/schema_migrations/20210218144056 b/db/schema_migrations/20210218144056
deleted file mode 100644
index 566015ad8be..00000000000
--- a/db/schema_migrations/20210218144056
+++ /dev/null
@@ -1 +0,0 @@
-545747e86481c74832a6df55764ab97ecfefc4446df9cc2366a8ce9d9c400ea4 \ No newline at end of file
diff --git a/db/schema_migrations/20210218144656 b/db/schema_migrations/20210218144656
deleted file mode 100644
index 622877a279e..00000000000
--- a/db/schema_migrations/20210218144656
+++ /dev/null
@@ -1 +0,0 @@
-91969bfc791cd7bc78b940aa6fed345b13a3186db0b89828428b798aa4f7949e \ No newline at end of file
diff --git a/db/schema_migrations/20210219100137 b/db/schema_migrations/20210219100137
deleted file mode 100644
index c573c4fde5f..00000000000
--- a/db/schema_migrations/20210219100137
+++ /dev/null
@@ -1 +0,0 @@
-be2ddc15e16d7d59bd050a60faaa0b6941d94ba7c47a88be473bcf3a17bb2763 \ No newline at end of file
diff --git a/db/schema_migrations/20210219102900 b/db/schema_migrations/20210219102900
deleted file mode 100644
index b0a730c4361..00000000000
--- a/db/schema_migrations/20210219102900
+++ /dev/null
@@ -1 +0,0 @@
-42e06332b279aaac7044243df0a8bd5525025db7d8c22bc474c0874e85f525f5 \ No newline at end of file
diff --git a/db/schema_migrations/20210219111040 b/db/schema_migrations/20210219111040
deleted file mode 100644
index a006ece2f6c..00000000000
--- a/db/schema_migrations/20210219111040
+++ /dev/null
@@ -1 +0,0 @@
-546802f93f64e346b066438e78ace5d2dc54de8a5f6234c2d01296a239cfe74c \ No newline at end of file
diff --git a/db/schema_migrations/20210219211845 b/db/schema_migrations/20210219211845
deleted file mode 100644
index ad45eee91b5..00000000000
--- a/db/schema_migrations/20210219211845
+++ /dev/null
@@ -1 +0,0 @@
-b58f2853d7a2d9a821198f69c5913d290404a4961410dd66d256eefc7ecf1026 \ No newline at end of file
diff --git a/db/schema_migrations/20210222030537 b/db/schema_migrations/20210222030537
deleted file mode 100644
index ad30eb19333..00000000000
--- a/db/schema_migrations/20210222030537
+++ /dev/null
@@ -1 +0,0 @@
-44b0e2b3e32e45fb557a5c9c41f69de94a5d41bad43267f00090b9c527b2b1e1 \ No newline at end of file
diff --git a/db/schema_migrations/20210222042745 b/db/schema_migrations/20210222042745
deleted file mode 100644
index 306b8401e65..00000000000
--- a/db/schema_migrations/20210222042745
+++ /dev/null
@@ -1 +0,0 @@
-88bbd8cbc4398c3c05a834c4d8d36ee55aca9d698da3cf3c1df0afe916bc051f \ No newline at end of file
diff --git a/db/schema_migrations/20210222070356 b/db/schema_migrations/20210222070356
deleted file mode 100644
index 256bb771dde..00000000000
--- a/db/schema_migrations/20210222070356
+++ /dev/null
@@ -1 +0,0 @@
-2aa618cdbb6e55c3af1fa144ae3f3bd0d9d5400706db337301d2d165ba789ef0 \ No newline at end of file
diff --git a/db/schema_migrations/20210222070413 b/db/schema_migrations/20210222070413
deleted file mode 100644
index f1ba0c51922..00000000000
--- a/db/schema_migrations/20210222070413
+++ /dev/null
@@ -1 +0,0 @@
-e13856c6f65d86dae9a3268f91189bb90af236c555d2f645c6ba4c600c996cba \ No newline at end of file
diff --git a/db/schema_migrations/20210222085529 b/db/schema_migrations/20210222085529
deleted file mode 100644
index 63f47781b3b..00000000000
--- a/db/schema_migrations/20210222085529
+++ /dev/null
@@ -1 +0,0 @@
-858cd59ea324e3653801055c7f3fae2152b04ac175945a59faa00d67ae7fa223 \ No newline at end of file
diff --git a/db/schema_migrations/20210222085551 b/db/schema_migrations/20210222085551
deleted file mode 100644
index f0ba3562c3a..00000000000
--- a/db/schema_migrations/20210222085551
+++ /dev/null
@@ -1 +0,0 @@
-9e6f99ed0c3d4d76a8c290308805cabf84aa7e5fb6dc2b06d973d9d8726fc4d8 \ No newline at end of file
diff --git a/db/schema_migrations/20210222105120 b/db/schema_migrations/20210222105120
deleted file mode 100644
index 768aea442f5..00000000000
--- a/db/schema_migrations/20210222105120
+++ /dev/null
@@ -1 +0,0 @@
-4da0131929bf59dd4a72bf05a889063df7978f8b5782e5f3b27d466302dc44b6 \ No newline at end of file
diff --git a/db/schema_migrations/20210222185538 b/db/schema_migrations/20210222185538
deleted file mode 100644
index 20229c9be20..00000000000
--- a/db/schema_migrations/20210222185538
+++ /dev/null
@@ -1 +0,0 @@
-0bccf1ff356a4b9c08d472e8b63070b497f331c2dfaded1bdb2cf01860df8903 \ No newline at end of file
diff --git a/db/schema_migrations/20210222192144 b/db/schema_migrations/20210222192144
deleted file mode 100644
index b53b1668a1f..00000000000
--- a/db/schema_migrations/20210222192144
+++ /dev/null
@@ -1 +0,0 @@
-b2508d46edbfbba24df65731f6e285886acbb6352a900dd1c6a985a686252ef0 \ No newline at end of file
diff --git a/db/schema_migrations/20210223053451 b/db/schema_migrations/20210223053451
deleted file mode 100644
index ad40bb0fa71..00000000000
--- a/db/schema_migrations/20210223053451
+++ /dev/null
@@ -1 +0,0 @@
-1266bf92f23a42d96778bf546534882f03d2388f22640e4cfaa2a9a1aad19093 \ No newline at end of file
diff --git a/db/schema_migrations/20210223132934 b/db/schema_migrations/20210223132934
deleted file mode 100644
index 6e2b0696bad..00000000000
--- a/db/schema_migrations/20210223132934
+++ /dev/null
@@ -1 +0,0 @@
-99ee6773319af0fa7a1dfef92f67cc95141c892bf7adcf500d46adc1ebd4c70f \ No newline at end of file
diff --git a/db/schema_migrations/20210223133116 b/db/schema_migrations/20210223133116
deleted file mode 100644
index 235053e8fe8..00000000000
--- a/db/schema_migrations/20210223133116
+++ /dev/null
@@ -1 +0,0 @@
-991041c8d3092175165834a988eb32141e49d7785cda756c8a78170b4af6db64 \ No newline at end of file
diff --git a/db/schema_migrations/20210223230600 b/db/schema_migrations/20210223230600
deleted file mode 100644
index be6e0621771..00000000000
--- a/db/schema_migrations/20210223230600
+++ /dev/null
@@ -1 +0,0 @@
-18d64af208338baec9d56a6ac9d7fc35aaeb79d3f8036d3cf5bcc72879827299 \ No newline at end of file
diff --git a/db/schema_migrations/20210224132547 b/db/schema_migrations/20210224132547
deleted file mode 100644
index f38b394f082..00000000000
--- a/db/schema_migrations/20210224132547
+++ /dev/null
@@ -1 +0,0 @@
-ac0f71b427be1fb583474e352ce9468a1270c6e67fa40f9071751a0485f21160 \ No newline at end of file
diff --git a/db/schema_migrations/20210224133337 b/db/schema_migrations/20210224133337
deleted file mode 100644
index d5dafb9fb56..00000000000
--- a/db/schema_migrations/20210224133337
+++ /dev/null
@@ -1 +0,0 @@
-964e9f88018b2ab72fd370f6a8dccde218cfd4ffa3ccedf4f142ab341f5e858f \ No newline at end of file
diff --git a/db/schema_migrations/20210224150506 b/db/schema_migrations/20210224150506
deleted file mode 100644
index 672b2f53a46..00000000000
--- a/db/schema_migrations/20210224150506
+++ /dev/null
@@ -1 +0,0 @@
-cc9f56a872cf5e9084e863adc599545754594fb03f30f18433923e0429986e39 \ No newline at end of file
diff --git a/db/schema_migrations/20210224161552 b/db/schema_migrations/20210224161552
deleted file mode 100644
index 1fd37a69dd3..00000000000
--- a/db/schema_migrations/20210224161552
+++ /dev/null
@@ -1 +0,0 @@
-328e095123eb0b8822342b0d4a338d42265ca8eafbcadcc7e15628e9d02c863d \ No newline at end of file
diff --git a/db/schema_migrations/20210225090801 b/db/schema_migrations/20210225090801
deleted file mode 100644
index 364623d6634..00000000000
--- a/db/schema_migrations/20210225090801
+++ /dev/null
@@ -1 +0,0 @@
-65f27401a76856d6cb284078204bb1b80797fa344e1a4ef3d9638c296f2d72d7 \ No newline at end of file
diff --git a/db/schema_migrations/20210225135533 b/db/schema_migrations/20210225135533
deleted file mode 100644
index e7c24096aac..00000000000
--- a/db/schema_migrations/20210225135533
+++ /dev/null
@@ -1 +0,0 @@
-526174bd42327e0212b15ffbad99541887de1dec35cc4c592d4f02065026b3ca \ No newline at end of file
diff --git a/db/schema_migrations/20210225153522 b/db/schema_migrations/20210225153522
deleted file mode 100644
index 6c985a2ed14..00000000000
--- a/db/schema_migrations/20210225153522
+++ /dev/null
@@ -1 +0,0 @@
-ec071087de45291ae8fc0d6d6e778d16a7411a934e4a301f62890061abcaed4c \ No newline at end of file
diff --git a/db/schema_migrations/20210226120851 b/db/schema_migrations/20210226120851
deleted file mode 100644
index f03c7b332be..00000000000
--- a/db/schema_migrations/20210226120851
+++ /dev/null
@@ -1 +0,0 @@
-ced4e314f2653ff56a946d334b4cb12085825b8d21ceea42cb686bef688b714c \ No newline at end of file
diff --git a/db/schema_migrations/20210226141517 b/db/schema_migrations/20210226141517
deleted file mode 100644
index 00c57cbe827..00000000000
--- a/db/schema_migrations/20210226141517
+++ /dev/null
@@ -1 +0,0 @@
-400dd521f5c462afdcb3c556815f840e916df7576a6d6dd301fe5a49a1fe6011 \ No newline at end of file
diff --git a/db/schema_migrations/20210301150451 b/db/schema_migrations/20210301150451
deleted file mode 100644
index 1d644ccb62e..00000000000
--- a/db/schema_migrations/20210301150451
+++ /dev/null
@@ -1 +0,0 @@
-6c52ab55814241b37014949976c4f3a0c63bea0a4f9a301735cc9f4c509f433d \ No newline at end of file
diff --git a/db/schema_migrations/20210301193412 b/db/schema_migrations/20210301193412
deleted file mode 100644
index 7e5616b210f..00000000000
--- a/db/schema_migrations/20210301193412
+++ /dev/null
@@ -1 +0,0 @@
-2929e4796e85fa6cf8b5950fb57295ae87c48c914d0a71123a29d579d797d636 \ No newline at end of file
diff --git a/db/schema_migrations/20210301200601 b/db/schema_migrations/20210301200601
deleted file mode 100644
index 13907f9de8b..00000000000
--- a/db/schema_migrations/20210301200601
+++ /dev/null
@@ -1 +0,0 @@
-21ae7ea7cbf1d34c7b9dc300a641eaf975ed1e33f5bc519494cd37c4a661bec8 \ No newline at end of file
diff --git a/db/schema_migrations/20210811193033 b/db/schema_migrations/20210811193033
new file mode 100644
index 00000000000..0d97d5a238a
--- /dev/null
+++ b/db/schema_migrations/20210811193033
@@ -0,0 +1 @@
+a7e259fa72dfdfa40137d278499d6b63b84f939f46936c0f4ed289ed152d9356 \ No newline at end of file
diff --git a/db/schema_migrations/20211026124336 b/db/schema_migrations/20211026124336
new file mode 100644
index 00000000000..dc6663e81a8
--- /dev/null
+++ b/db/schema_migrations/20211026124336
@@ -0,0 +1 @@
+a6807d2c17c4efdc759f39101856d7a082ae4d531ca3ced525de10e3de808b9d \ No newline at end of file
diff --git a/db/schema_migrations/20211123161906 b/db/schema_migrations/20211123161906
new file mode 100644
index 00000000000..1370811b3af
--- /dev/null
+++ b/db/schema_migrations/20211123161906
@@ -0,0 +1 @@
+46767d804bde08ad4a076f20436652f980eb935a79b2ad30b4735b956be69a7a \ No newline at end of file
diff --git a/db/schema_migrations/20211206161271 b/db/schema_migrations/20211206161271
new file mode 100644
index 00000000000..8a2561eec24
--- /dev/null
+++ b/db/schema_migrations/20211206161271
@@ -0,0 +1 @@
+fa4a39c3bea70d31e8144f8830ef0353f22a7a663a891d9043e79f362058fbde \ No newline at end of file
diff --git a/db/schema_migrations/20211206162601 b/db/schema_migrations/20211206162601
new file mode 100644
index 00000000000..5e19e21507d
--- /dev/null
+++ b/db/schema_migrations/20211206162601
@@ -0,0 +1 @@
+529c7ea38bbaa0c29491c2dfdb654a4a6adba93122d9bc23d6632526ff7fdb05 \ No newline at end of file
diff --git a/db/schema_migrations/20211207081708 b/db/schema_migrations/20211207081708
new file mode 100644
index 00000000000..b2fbb704451
--- /dev/null
+++ b/db/schema_migrations/20211207081708
@@ -0,0 +1 @@
+e26065e63eca51e4138b6e9f07e9ec1ee45838afa82c5832849e360375beeae2 \ No newline at end of file
diff --git a/db/schema_migrations/20211207125331 b/db/schema_migrations/20211207125331
new file mode 100644
index 00000000000..833d5d0a383
--- /dev/null
+++ b/db/schema_migrations/20211207125331
@@ -0,0 +1 @@
+5ead867b7609248f702771078849c48c0558f5fe9a3021fbb32e4f9174af653a \ No newline at end of file
diff --git a/db/schema_migrations/20211207135331 b/db/schema_migrations/20211207135331
new file mode 100644
index 00000000000..b4085490cc8
--- /dev/null
+++ b/db/schema_migrations/20211207135331
@@ -0,0 +1 @@
+3d9dcab49ee409da8c1ab398101041092e566b06a7bb2764db49a9201a0e5f0c \ No newline at end of file
diff --git a/db/schema_migrations/20211207173510 b/db/schema_migrations/20211207173510
new file mode 100644
index 00000000000..09474e1c643
--- /dev/null
+++ b/db/schema_migrations/20211207173510
@@ -0,0 +1 @@
+0a4ac9de84b8351f39e549904d9e661648b496e6e3183c4ff5eb22b70d5ba7e9 \ No newline at end of file
diff --git a/db/schema_migrations/20211207173511 b/db/schema_migrations/20211207173511
new file mode 100644
index 00000000000..93b44c20390
--- /dev/null
+++ b/db/schema_migrations/20211207173511
@@ -0,0 +1 @@
+8f41f45c5ef23eafae2e67951497b5752f4b30ecf73ae3c08f61febfa4fb17be \ No newline at end of file
diff --git a/db/schema_migrations/20211208122200 b/db/schema_migrations/20211208122200
new file mode 100644
index 00000000000..1e4910d3a3c
--- /dev/null
+++ b/db/schema_migrations/20211208122200
@@ -0,0 +1 @@
+8dec4379f34773e979cf6b33ba608185827c37b1a95c74d6472b7562c16d6110 \ No newline at end of file
diff --git a/db/schema_migrations/20211208122201 b/db/schema_migrations/20211208122201
new file mode 100644
index 00000000000..fb770a6d5fd
--- /dev/null
+++ b/db/schema_migrations/20211208122201
@@ -0,0 +1 @@
+f58ccb07fa67ede2a50fa5ff6bddbe4bb89a622e84786fc4bfb404c11b9dbab4 \ No newline at end of file
diff --git a/db/schema_migrations/20211209203820 b/db/schema_migrations/20211209203820
new file mode 100644
index 00000000000..cdff024b597
--- /dev/null
+++ b/db/schema_migrations/20211209203820
@@ -0,0 +1 @@
+c501bc857cef21a8657508e9a286feb3c6f5db873247707e051a8702b1e80e79 \ No newline at end of file
diff --git a/db/schema_migrations/20211209203821 b/db/schema_migrations/20211209203821
new file mode 100644
index 00000000000..890d3db0b3a
--- /dev/null
+++ b/db/schema_migrations/20211209203821
@@ -0,0 +1 @@
+4e8e0917bcfcadf288425e82eeb3747d775bb301017a9b320b694cd43ed0d60a \ No newline at end of file
diff --git a/db/schema_migrations/20211209230042 b/db/schema_migrations/20211209230042
new file mode 100644
index 00000000000..818734c1330
--- /dev/null
+++ b/db/schema_migrations/20211209230042
@@ -0,0 +1 @@
+907fafc18fa515fff8f716f6464263ccc8a9b6e5ead36f30b05089100fd71b6b \ No newline at end of file
diff --git a/db/schema_migrations/20211210025754 b/db/schema_migrations/20211210025754
new file mode 100644
index 00000000000..f2fd6e506b8
--- /dev/null
+++ b/db/schema_migrations/20211210025754
@@ -0,0 +1 @@
+d39b46bfd4bdf81cd4969190d08dce2260b4f476564a2e6c3e05d69b87c1c6df \ No newline at end of file
diff --git a/db/schema_migrations/20211210031721 b/db/schema_migrations/20211210031721
new file mode 100644
index 00000000000..57bbcccd347
--- /dev/null
+++ b/db/schema_migrations/20211210031721
@@ -0,0 +1 @@
+6d62200480e46b356fe07eeb2c99b0fb441dadd00faf30079722c617facab7cc \ No newline at end of file
diff --git a/db/schema_migrations/20211210140000 b/db/schema_migrations/20211210140000
new file mode 100644
index 00000000000..b64d8251d69
--- /dev/null
+++ b/db/schema_migrations/20211210140000
@@ -0,0 +1 @@
+f02c1b7412d2bb6d8a20639704ad55cdbcc14bfccf0509b659c3ef9614bcfa2b \ No newline at end of file
diff --git a/db/schema_migrations/20211210140629 b/db/schema_migrations/20211210140629
new file mode 100644
index 00000000000..ad631461d87
--- /dev/null
+++ b/db/schema_migrations/20211210140629
@@ -0,0 +1 @@
+7940b0f692b62bcabbe98440082e2245fd28caba2c9e052e85e82acea0a98d23 \ No newline at end of file
diff --git a/db/schema_migrations/20211213142344 b/db/schema_migrations/20211213142344
new file mode 100644
index 00000000000..2bcbb15c218
--- /dev/null
+++ b/db/schema_migrations/20211213142344
@@ -0,0 +1 @@
+837539e12be12830d388bc6142622412b40ac061c397504eac03033a08f01e72 \ No newline at end of file
diff --git a/db/schema_migrations/20211213154259 b/db/schema_migrations/20211213154259
new file mode 100644
index 00000000000..0555d0c6600
--- /dev/null
+++ b/db/schema_migrations/20211213154259
@@ -0,0 +1 @@
+fccb1d6c7ac4e31cecaf7bc2e23f13f6c8147a3820cbd996a545a5b01cc03865 \ No newline at end of file
diff --git a/db/schema_migrations/20211213154704 b/db/schema_migrations/20211213154704
new file mode 100644
index 00000000000..0d9ba6457ba
--- /dev/null
+++ b/db/schema_migrations/20211213154704
@@ -0,0 +1 @@
+deec24bae35829454a09d4e97478c0b57d5f80e3271f96b2554b1ab10dc84d7f \ No newline at end of file
diff --git a/db/schema_migrations/20211214012507 b/db/schema_migrations/20211214012507
new file mode 100644
index 00000000000..7bac6c6d8c5
--- /dev/null
+++ b/db/schema_migrations/20211214012507
@@ -0,0 +1 @@
+a7aa1ffccce785d365720309e3773f167075a9d06805eea941e6cd47bc918471 \ No newline at end of file
diff --git a/db/schema_migrations/20211215182006 b/db/schema_migrations/20211215182006
new file mode 100644
index 00000000000..480a1e2369b
--- /dev/null
+++ b/db/schema_migrations/20211215182006
@@ -0,0 +1 @@
+ead2a1b13438514bb97bea3f1656f9bac352a8c733d9f808b2405685bce91e00 \ No newline at end of file
diff --git a/db/schema_migrations/20211216133107 b/db/schema_migrations/20211216133107
new file mode 100644
index 00000000000..c841207fffc
--- /dev/null
+++ b/db/schema_migrations/20211216133107
@@ -0,0 +1 @@
+a0c3a9746250aa67ffa8d05486fb6997c8d839b8bce7e870c0415c25600c5434 \ No newline at end of file
diff --git a/db/schema_migrations/20211216134134 b/db/schema_migrations/20211216134134
new file mode 100644
index 00000000000..09c3a59cc98
--- /dev/null
+++ b/db/schema_migrations/20211216134134
@@ -0,0 +1 @@
+c53a1e4405187620929b8fc6877786cb713d13218f7385d1b9b3daaf6072fa05 \ No newline at end of file
diff --git a/db/schema_migrations/20211216135651 b/db/schema_migrations/20211216135651
new file mode 100644
index 00000000000..a94bdb329f1
--- /dev/null
+++ b/db/schema_migrations/20211216135651
@@ -0,0 +1 @@
+9b733363587957b4044bc6806dfbb9632ec7f5f6ffc8c82280e025012b8acb5a \ No newline at end of file
diff --git a/db/schema_migrations/20211216220939 b/db/schema_migrations/20211216220939
new file mode 100644
index 00000000000..3fe48da6ca2
--- /dev/null
+++ b/db/schema_migrations/20211216220939
@@ -0,0 +1 @@
+649cf0eb794904457b230c1240d2bea8a6e80b00dbf6b2d25b95c66247460aa4 \ No newline at end of file
diff --git a/db/schema_migrations/20211217050753 b/db/schema_migrations/20211217050753
new file mode 100644
index 00000000000..bfc571acab1
--- /dev/null
+++ b/db/schema_migrations/20211217050753
@@ -0,0 +1 @@
+fe5cbf928d45d506132078678cf70264f01190cfe581628a5038d77f68a52961 \ No newline at end of file
diff --git a/db/schema_migrations/20211217120000 b/db/schema_migrations/20211217120000
new file mode 100644
index 00000000000..d4efb66b985
--- /dev/null
+++ b/db/schema_migrations/20211217120000
@@ -0,0 +1 @@
+d4360d6057602ec1f5e6e9d11c93cfbb16d878e9ecd4d5bfb1bed1c01e14c7a3 \ No newline at end of file
diff --git a/db/schema_migrations/20211217145923 b/db/schema_migrations/20211217145923
new file mode 100644
index 00000000000..8a94da00fc8
--- /dev/null
+++ b/db/schema_migrations/20211217145923
@@ -0,0 +1 @@
+2e35347592530f2a73e1cd75871438e29d277a206f621989e2c897fc587b6f5d \ No newline at end of file
diff --git a/db/schema_migrations/20211217174331 b/db/schema_migrations/20211217174331
new file mode 100644
index 00000000000..32657e28f96
--- /dev/null
+++ b/db/schema_migrations/20211217174331
@@ -0,0 +1 @@
+649360f4069aac4784f4d039015f8dda3f4bae28e8132f841e25b48f034a392e \ No newline at end of file
diff --git a/db/schema_migrations/20211220064757 b/db/schema_migrations/20211220064757
new file mode 100644
index 00000000000..675596f1ce6
--- /dev/null
+++ b/db/schema_migrations/20211220064757
@@ -0,0 +1 @@
+34bfe07fff59a415540ca2c5c96b33dc9030c15b2ffbb30cb7deedeb939ae132 \ No newline at end of file
diff --git a/db/schema_migrations/20211220120402 b/db/schema_migrations/20211220120402
new file mode 100644
index 00000000000..c2bb4f8da7e
--- /dev/null
+++ b/db/schema_migrations/20211220120402
@@ -0,0 +1 @@
+157128732c321577b7fa7a1b3d252ff70a2a62b34cd1e6edea59da4e632a1755 \ No newline at end of file
diff --git a/db/schema_migrations/20211220123956 b/db/schema_migrations/20211220123956
new file mode 100644
index 00000000000..291fdc306b5
--- /dev/null
+++ b/db/schema_migrations/20211220123956
@@ -0,0 +1 @@
+088d17a1f55522c48e69ec78717b39b8c7538474a9263621bba1fa0280a27ad7 \ No newline at end of file
diff --git a/db/schema_migrations/20211220174504 b/db/schema_migrations/20211220174504
new file mode 100644
index 00000000000..ed8f5f35efc
--- /dev/null
+++ b/db/schema_migrations/20211220174504
@@ -0,0 +1 @@
+80c1ad5815ef68ab1a7d63566d478683b3f9a5169ed15ecd6f44f7f542d40dc8 \ No newline at end of file
diff --git a/db/schema_migrations/20211223125921 b/db/schema_migrations/20211223125921
new file mode 100644
index 00000000000..b4e3a1583df
--- /dev/null
+++ b/db/schema_migrations/20211223125921
@@ -0,0 +1 @@
+e08c1634376ed78b78c4a54d874bed66c1ce40c7c509b67cfda00d1a8657f127 \ No newline at end of file
diff --git a/db/schema_migrations/20211224112937 b/db/schema_migrations/20211224112937
new file mode 100644
index 00000000000..98296f9a270
--- /dev/null
+++ b/db/schema_migrations/20211224112937
@@ -0,0 +1 @@
+3709c5c229e45ff0f594d6291d0b2b9a167b3bf4f5b29158b9abdac333a638b8 \ No newline at end of file
diff --git a/db/schema_migrations/20211224114539 b/db/schema_migrations/20211224114539
new file mode 100644
index 00000000000..2d7494e4291
--- /dev/null
+++ b/db/schema_migrations/20211224114539
@@ -0,0 +1 @@
+f4ac776ec4213d6fcd07ccfa913f51e1386ff212bf47d27817b24b501a78443b \ No newline at end of file
diff --git a/db/schema_migrations/20211229023654 b/db/schema_migrations/20211229023654
new file mode 100644
index 00000000000..f34b188c5d3
--- /dev/null
+++ b/db/schema_migrations/20211229023654
@@ -0,0 +1 @@
+8019915a00f62c137ee48c860c888e9d43f7253a5ea1a684ba2abe8bbe8016df \ No newline at end of file
diff --git a/db/schema_migrations/20211230112517 b/db/schema_migrations/20211230112517
new file mode 100644
index 00000000000..bd22204d82d
--- /dev/null
+++ b/db/schema_migrations/20211230112517
@@ -0,0 +1 @@
+32c4b0ad5b52b8990b4c0ab6e832d503be6fc802a30aa2de20c7d3ced7f04c36 \ No newline at end of file
diff --git a/db/schema_migrations/20211230113031 b/db/schema_migrations/20211230113031
new file mode 100644
index 00000000000..2f5b81768c8
--- /dev/null
+++ b/db/schema_migrations/20211230113031
@@ -0,0 +1 @@
+54201f4273226ed92ff0ed991fdba09c1108fccb764e6b9903e9f01e6acced1a \ No newline at end of file
diff --git a/db/schema_migrations/20220104060049 b/db/schema_migrations/20220104060049
new file mode 100644
index 00000000000..83c36018d73
--- /dev/null
+++ b/db/schema_migrations/20220104060049
@@ -0,0 +1 @@
+fa87b087b576d320f94028444a082b920870a2554209808849f9f3f42ead83c4 \ No newline at end of file
diff --git a/db/schema_migrations/20220104174445 b/db/schema_migrations/20220104174445
new file mode 100644
index 00000000000..fffb27113e2
--- /dev/null
+++ b/db/schema_migrations/20220104174445
@@ -0,0 +1 @@
+5e5e41ee4c8dc9c3fe791470862d15b8d213fcc931ef8b80937bdb5f5db20aed \ No newline at end of file
diff --git a/db/schema_migrations/20220105020514 b/db/schema_migrations/20220105020514
new file mode 100644
index 00000000000..4ad9266c7c0
--- /dev/null
+++ b/db/schema_migrations/20220105020514
@@ -0,0 +1 @@
+301c2f09f48aa3e34c2f679628a9542b4babc589e3d20e9ccf84a9209f5841ee \ No newline at end of file
diff --git a/db/schema_migrations/20220105121325 b/db/schema_migrations/20220105121325
new file mode 100644
index 00000000000..384616aba7f
--- /dev/null
+++ b/db/schema_migrations/20220105121325
@@ -0,0 +1 @@
+27ca3977a7569e98271eeb2bd224be1cfe5452ab3778665325b89bf966e07942 \ No newline at end of file
diff --git a/db/schema_migrations/20220106141756 b/db/schema_migrations/20220106141756
new file mode 100644
index 00000000000..7718a41500b
--- /dev/null
+++ b/db/schema_migrations/20220106141756
@@ -0,0 +1 @@
+cedca81a6dc1562cf0ed5f17217c52420a1cb9a74acece8d67eb1bcb948a7181 \ No newline at end of file
diff --git a/db/schema_migrations/20220106230629 b/db/schema_migrations/20220106230629
new file mode 100644
index 00000000000..e8751a6616c
--- /dev/null
+++ b/db/schema_migrations/20220106230629
@@ -0,0 +1 @@
+675d8f7bf77ddb860e707c25811d4eaaac1173c9fe62ce96c2708f0bbd0f4d48 \ No newline at end of file
diff --git a/db/schema_migrations/20220106230712 b/db/schema_migrations/20220106230712
new file mode 100644
index 00000000000..589b65d423c
--- /dev/null
+++ b/db/schema_migrations/20220106230712
@@ -0,0 +1 @@
+672b51ca014d208f971efe698edb8a8b32f541bf9d21a7f555c53f749ee936a4 \ No newline at end of file
diff --git a/db/schema_migrations/20220106231518 b/db/schema_migrations/20220106231518
new file mode 100644
index 00000000000..f7deaaa68b6
--- /dev/null
+++ b/db/schema_migrations/20220106231518
@@ -0,0 +1 @@
+aafb52337688e8b57712872f6f7e8e67da132406b244df5e11a736b01e23354f \ No newline at end of file
diff --git a/db/schema_migrations/20220106233459 b/db/schema_migrations/20220106233459
new file mode 100644
index 00000000000..2911e79d843
--- /dev/null
+++ b/db/schema_migrations/20220106233459
@@ -0,0 +1 @@
+fc44084057c5fd30f0e7918b4f856a60409f08ad1eb5c3fbc2d8ad5bad7f1ffd \ No newline at end of file
diff --git a/db/schema_migrations/20220106235626 b/db/schema_migrations/20220106235626
new file mode 100644
index 00000000000..d8d8e3b20d7
--- /dev/null
+++ b/db/schema_migrations/20220106235626
@@ -0,0 +1 @@
+34f966723cae63e831f7fc9d965cda90f1fd7bca522fc58e78a0de4b959a47a2 \ No newline at end of file
diff --git a/db/schema_migrations/20220107091629 b/db/schema_migrations/20220107091629
new file mode 100644
index 00000000000..a14f97d77eb
--- /dev/null
+++ b/db/schema_migrations/20220107091629
@@ -0,0 +1 @@
+ef1a7c5f7b10640a0ddc669528dcdb02fd2525d716562f928578e8902a07a832 \ No newline at end of file
diff --git a/db/schema_migrations/20220107165036 b/db/schema_migrations/20220107165036
new file mode 100644
index 00000000000..bab28284d04
--- /dev/null
+++ b/db/schema_migrations/20220107165036
@@ -0,0 +1 @@
+72639ba84675a6687864ef4cb6f02d0429124d7deb9ce9f3c8e255591e2f0a8d \ No newline at end of file
diff --git a/db/schema_migrations/20220109133006 b/db/schema_migrations/20220109133006
new file mode 100644
index 00000000000..e74845e2254
--- /dev/null
+++ b/db/schema_migrations/20220109133006
@@ -0,0 +1 @@
+192fc0b934c7d52e431a0ce7524a51beb24fa004a940e6b0675e36b0da143891 \ No newline at end of file
diff --git a/db/schema_migrations/20220109134455 b/db/schema_migrations/20220109134455
new file mode 100644
index 00000000000..7a4762e240e
--- /dev/null
+++ b/db/schema_migrations/20220109134455
@@ -0,0 +1 @@
+fee092680e22e579ea51f776d11bbfd6a49b936e4ab776760a153ce613e7a0cd \ No newline at end of file
diff --git a/db/schema_migrations/20220110170953 b/db/schema_migrations/20220110170953
new file mode 100644
index 00000000000..d4c2aa5fcf2
--- /dev/null
+++ b/db/schema_migrations/20220110170953
@@ -0,0 +1 @@
+da1c6f2db7cee1e4cb8b477d1892fa7206a95157a84864ad3d6022ab6cffbd1f \ No newline at end of file
diff --git a/db/schema_migrations/20220110171049 b/db/schema_migrations/20220110171049
new file mode 100644
index 00000000000..ab39a1afb25
--- /dev/null
+++ b/db/schema_migrations/20220110171049
@@ -0,0 +1 @@
+55ad00b1cf70f5d1a3f033efccf64c2c273ad03f65823a2281869849571ab35b \ No newline at end of file
diff --git a/db/schema_migrations/20220110224913 b/db/schema_migrations/20220110224913
new file mode 100644
index 00000000000..653324d1060
--- /dev/null
+++ b/db/schema_migrations/20220110224913
@@ -0,0 +1 @@
+d8b206e26f6dd7e9d5f2b2d8cc5ce2e2bbe2d8d33317948f8cf110fe41872a5d \ No newline at end of file
diff --git a/db/schema_migrations/20220110231420 b/db/schema_migrations/20220110231420
new file mode 100644
index 00000000000..b46bcdfd802
--- /dev/null
+++ b/db/schema_migrations/20220110231420
@@ -0,0 +1 @@
+768f97a38c0b741f7de99082ce7c8efb1578ac6600c3af4b30019bc987968bc9 \ No newline at end of file
diff --git a/db/schema_migrations/20220110233155 b/db/schema_migrations/20220110233155
new file mode 100644
index 00000000000..9301c7a2a7a
--- /dev/null
+++ b/db/schema_migrations/20220110233155
@@ -0,0 +1 @@
+e7d9d79ffb8989ab39fe719217f22736244df70c2b1461ef5a1a3f1e74e43870 \ No newline at end of file
diff --git a/db/schema_migrations/20220111002756 b/db/schema_migrations/20220111002756
new file mode 100644
index 00000000000..ca619e3eaf4
--- /dev/null
+++ b/db/schema_migrations/20220111002756
@@ -0,0 +1 @@
+34759cbf09171f6057b87af791f5e9f3045ac5e06558147436ba32e276f40a19 \ No newline at end of file
diff --git a/db/schema_migrations/20220111023852 b/db/schema_migrations/20220111023852
new file mode 100644
index 00000000000..15ab0470662
--- /dev/null
+++ b/db/schema_migrations/20220111023852
@@ -0,0 +1 @@
+fdb6e193748f9933aa3ae60fab41960e06d4edf271048fc5f6c9c465d30a8334 \ No newline at end of file
diff --git a/db/schema_migrations/20220111095006 b/db/schema_migrations/20220111095006
new file mode 100644
index 00000000000..b5fed6279f1
--- /dev/null
+++ b/db/schema_migrations/20220111095006
@@ -0,0 +1 @@
+0bc00cc8a5fa7cafa665ec113a4d0d1384c5acde37dfdf53ab1f5a2e1d6acb02 \ No newline at end of file
diff --git a/db/schema_migrations/20220111095007 b/db/schema_migrations/20220111095007
new file mode 100644
index 00000000000..77c70f8bccf
--- /dev/null
+++ b/db/schema_migrations/20220111095007
@@ -0,0 +1 @@
+65259b0e71c1883b81c61354325cfeeade0013b55af8901bf707f2a94ee3a46a \ No newline at end of file
diff --git a/db/schema_migrations/20220111102314 b/db/schema_migrations/20220111102314
new file mode 100644
index 00000000000..95c172c3587
--- /dev/null
+++ b/db/schema_migrations/20220111102314
@@ -0,0 +1 @@
+69c20daf6a23346288e516df3e70120819d76dcb5fe2b1b51af416349311820b \ No newline at end of file
diff --git a/db/schema_migrations/20220111200254 b/db/schema_migrations/20220111200254
new file mode 100644
index 00000000000..36ce3ad56f0
--- /dev/null
+++ b/db/schema_migrations/20220111200254
@@ -0,0 +1 @@
+72c7e04b1a34154c894f93da800c15c717c3340d34729577538d539881d2e8ca \ No newline at end of file
diff --git a/db/schema_migrations/20220111221516 b/db/schema_migrations/20220111221516
new file mode 100644
index 00000000000..b0c747f8e8a
--- /dev/null
+++ b/db/schema_migrations/20220111221516
@@ -0,0 +1 @@
+0cb120b0036b3f472edb57fcb8a52877d399edf8ff1f416ce76497d6aa8265d7 \ No newline at end of file
diff --git a/db/schema_migrations/20220112015940 b/db/schema_migrations/20220112015940
new file mode 100644
index 00000000000..0d012793ba0
--- /dev/null
+++ b/db/schema_migrations/20220112015940
@@ -0,0 +1 @@
+e4417c3367115d6adba023e18657d8aecd476b8d1c4227c73e06f97d05af07ad \ No newline at end of file
diff --git a/db/schema_migrations/20220112090556 b/db/schema_migrations/20220112090556
new file mode 100644
index 00000000000..12ffaeffe00
--- /dev/null
+++ b/db/schema_migrations/20220112090556
@@ -0,0 +1 @@
+e78e11a47017c67130fe88fa538578553b7015c18cf222b5e7fb7f503254dc6d \ No newline at end of file
diff --git a/db/schema_migrations/20220112115413 b/db/schema_migrations/20220112115413
new file mode 100644
index 00000000000..9c8c653f69b
--- /dev/null
+++ b/db/schema_migrations/20220112115413
@@ -0,0 +1 @@
+1199adba4c13e9234eabadefeb55ed3cfb19e9d5a87c07b90d438e4f48a973f7 \ No newline at end of file
diff --git a/db/schema_migrations/20220112205111 b/db/schema_migrations/20220112205111
new file mode 100644
index 00000000000..a2d2d42271e
--- /dev/null
+++ b/db/schema_migrations/20220112205111
@@ -0,0 +1 @@
+65d9a1d63e90dfc336d0c69503c0899259fda773bc68a330782c206ac0fc48fd \ No newline at end of file
diff --git a/db/schema_migrations/20220112230642 b/db/schema_migrations/20220112230642
new file mode 100644
index 00000000000..c2d8e1d0a6e
--- /dev/null
+++ b/db/schema_migrations/20220112230642
@@ -0,0 +1 @@
+c528730414c1dcda5d312f03d4e37a0dbb51ebb0b0b87ada786cf686c358daa7 \ No newline at end of file
diff --git a/db/schema_migrations/20220112232037 b/db/schema_migrations/20220112232037
new file mode 100644
index 00000000000..83267de0489
--- /dev/null
+++ b/db/schema_migrations/20220112232037
@@ -0,0 +1 @@
+775ac42ad194bd0175a6925e1c2e83c11d57a8d4430ad08a70e3d5275ca2e709 \ No newline at end of file
diff --git a/db/schema_migrations/20220112232605 b/db/schema_migrations/20220112232605
new file mode 100644
index 00000000000..fb5809b543e
--- /dev/null
+++ b/db/schema_migrations/20220112232605
@@ -0,0 +1 @@
+4813b55e933564851f2fec9a2fa5900409eff226fec34ae0be1895307f603904 \ No newline at end of file
diff --git a/db/schema_migrations/20220112232723 b/db/schema_migrations/20220112232723
new file mode 100644
index 00000000000..2dc2a592980
--- /dev/null
+++ b/db/schema_migrations/20220112232723
@@ -0,0 +1 @@
+cbea97a0d067939ba9d713489448cb6e0cc45b2bbd2c717ecf521493cc39d568 \ No newline at end of file
diff --git a/db/schema_migrations/20220113013319 b/db/schema_migrations/20220113013319
new file mode 100644
index 00000000000..0dc31b95004
--- /dev/null
+++ b/db/schema_migrations/20220113013319
@@ -0,0 +1 @@
+ccfbbbe52b27833453f867c4d7093187d21dbbfebe054b366ff010c54de50974 \ No newline at end of file
diff --git a/db/schema_migrations/20220113014438 b/db/schema_migrations/20220113014438
new file mode 100644
index 00000000000..936c801bafe
--- /dev/null
+++ b/db/schema_migrations/20220113014438
@@ -0,0 +1 @@
+08d8a5a605058598a2f033bbd461518c502fb3da8627240c5d66f887b43f3ac3 \ No newline at end of file
diff --git a/db/schema_migrations/20220113015830 b/db/schema_migrations/20220113015830
new file mode 100644
index 00000000000..a4897410077
--- /dev/null
+++ b/db/schema_migrations/20220113015830
@@ -0,0 +1 @@
+774a5ff616663d6d0e002bd04d33747982de10b02cbb9ad7d8abfe0b26a2b441 \ No newline at end of file
diff --git a/db/schema_migrations/20220113035519 b/db/schema_migrations/20220113035519
new file mode 100644
index 00000000000..eb908ae8982
--- /dev/null
+++ b/db/schema_migrations/20220113035519
@@ -0,0 +1 @@
+4a90811aace678528b75171868fb178ab885d5aac885048e8eacecaf8b0ee374 \ No newline at end of file
diff --git a/db/schema_migrations/20220113040447 b/db/schema_migrations/20220113040447
new file mode 100644
index 00000000000..465b51678f7
--- /dev/null
+++ b/db/schema_migrations/20220113040447
@@ -0,0 +1 @@
+983e5522b2798ca0d17ca3fd848f527b12afdbdd1482a2d420c4c6ce4fa2c9c4 \ No newline at end of file
diff --git a/db/schema_migrations/20220113125401 b/db/schema_migrations/20220113125401
new file mode 100644
index 00000000000..7241e2e29c7
--- /dev/null
+++ b/db/schema_migrations/20220113125401
@@ -0,0 +1 @@
+afe57b6b1b8b10e0e26d7f499b25adc5aef9f7c52af644d6a260f0ed3aab16d5 \ No newline at end of file
diff --git a/db/schema_migrations/20220114105525 b/db/schema_migrations/20220114105525
new file mode 100644
index 00000000000..728820cbaf0
--- /dev/null
+++ b/db/schema_migrations/20220114105525
@@ -0,0 +1 @@
+c9c7e8ff40fd3863095bb927f1aea27fecd5ca77dfc284a7673310e3501476c8 \ No newline at end of file
diff --git a/db/schema_migrations/20220114131950 b/db/schema_migrations/20220114131950
new file mode 100644
index 00000000000..ca1e1033d9b
--- /dev/null
+++ b/db/schema_migrations/20220114131950
@@ -0,0 +1 @@
+f427f4c0d75308f7c97685e10e27a735dcf284714acd49659f62a6f7752234ef \ No newline at end of file
diff --git a/db/schema_migrations/20220116175851 b/db/schema_migrations/20220116175851
new file mode 100644
index 00000000000..47c21071440
--- /dev/null
+++ b/db/schema_migrations/20220116175851
@@ -0,0 +1 @@
+3fa0d827ab8051d270a13ae5facb1560a87f9f4fef81368b9fbb5d6291948721 \ No newline at end of file
diff --git a/db/schema_migrations/20220117225936 b/db/schema_migrations/20220117225936
new file mode 100644
index 00000000000..7ced75915e4
--- /dev/null
+++ b/db/schema_migrations/20220117225936
@@ -0,0 +1 @@
+484eaf2ce1df1e2915b7ea8a5c9f4e044957c25d1ccf5841f24c75791d1a1a13 \ No newline at end of file
diff --git a/db/schema_migrations/20220118141950 b/db/schema_migrations/20220118141950
new file mode 100644
index 00000000000..7c6549a1e60
--- /dev/null
+++ b/db/schema_migrations/20220118141950
@@ -0,0 +1 @@
+a4131f86bc415f0c1897e3b975494806ffc5a834dca2b39c998c6a406e695e15 \ No newline at end of file
diff --git a/db/schema_migrations/20220118155846 b/db/schema_migrations/20220118155846
new file mode 100644
index 00000000000..b5247cb3743
--- /dev/null
+++ b/db/schema_migrations/20220118155846
@@ -0,0 +1 @@
+88935eee0781ee1faaf52e3bc89dc5c490c2095d6ccf83e4fd4186641507c173 \ No newline at end of file
diff --git a/db/schema_migrations/20220118155847 b/db/schema_migrations/20220118155847
new file mode 100644
index 00000000000..caa0dfc5901
--- /dev/null
+++ b/db/schema_migrations/20220118155847
@@ -0,0 +1 @@
+aa73b04aa355111564cdc7adb036a2030a28fbb3b524c3b3dbb8248e27b845d7 \ No newline at end of file
diff --git a/db/schema_migrations/20220118155848 b/db/schema_migrations/20220118155848
new file mode 100644
index 00000000000..bf3205b5dda
--- /dev/null
+++ b/db/schema_migrations/20220118155848
@@ -0,0 +1 @@
+4d5adffe1a3e835d6d23f6bd9634993c778fef23d134552d54b003af2a3ff4da \ No newline at end of file
diff --git a/db/schema_migrations/20220119141736 b/db/schema_migrations/20220119141736
new file mode 100644
index 00000000000..431ed37ea5c
--- /dev/null
+++ b/db/schema_migrations/20220119141736
@@ -0,0 +1 @@
+faa30b386af9adf3e9f54a0e8e2880310490e4dc1378eae68b346872d0bb8bfd \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 716b3e89be1..fff600c392a 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -166,7 +166,7 @@ CREATE TABLE verification_codes (
phone text NOT NULL,
CONSTRAINT check_9b84e6aaff CHECK ((char_length(code) <= 8)),
CONSTRAINT check_ccc542256b CHECK ((char_length(visitor_id_code) <= 64)),
- CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 32))
+ CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 50))
)
PARTITION BY RANGE (created_at);
@@ -10298,7 +10298,7 @@ CREATE TABLE application_settings (
throttle_protected_paths_enabled boolean DEFAULT false NOT NULL,
throttle_protected_paths_requests_per_period integer DEFAULT 10 NOT NULL,
throttle_protected_paths_period_in_seconds integer DEFAULT 60 NOT NULL,
- protected_paths character varying(255)[] DEFAULT '{/users/password,/users/sign_in,/api/v3/session.json,/api/v3/session,/api/v4/session.json,/api/v4/session,/users,/users/confirmation,/unsubscribes/,/import/github/personal_access_token,/admin/session,/oauth/authorize,/oauth/token}'::character varying[],
+ protected_paths character varying(255)[] DEFAULT '{/users/password,/users/sign_in,/api/v3/session.json,/api/v3/session,/api/v4/session.json,/api/v4/session,/users,/users/confirmation,/unsubscribes/,/import/github/personal_access_token,/admin/session}'::character varying[],
throttle_incident_management_notification_enabled boolean DEFAULT false NOT NULL,
throttle_incident_management_notification_period_in_seconds integer DEFAULT 3600,
throttle_incident_management_notification_per_period integer DEFAULT 3600,
@@ -10481,15 +10481,28 @@ CREATE TABLE application_settings (
max_ssh_key_lifetime integer,
static_objects_external_storage_auth_token_encrypted text,
future_subscriptions jsonb DEFAULT '[]'::jsonb NOT NULL,
+ user_email_lookup_limit integer DEFAULT 60 NOT NULL,
+ packages_cleanup_package_file_worker_capacity smallint DEFAULT 2 NOT NULL,
+ container_registry_import_max_tags_count integer DEFAULT 100 NOT NULL,
+ container_registry_import_max_retries integer DEFAULT 3 NOT NULL,
+ container_registry_import_start_max_retries integer DEFAULT 50 NOT NULL,
+ 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,
+ runner_token_expiration_interval integer,
+ group_runner_token_expiration_interval integer,
+ project_runner_token_expiration_interval integer,
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_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)),
CONSTRAINT app_settings_yaml_max_size_positive CHECK ((max_yaml_size_bytes > 0)),
CONSTRAINT check_17d9558205 CHECK ((char_length((kroki_url)::text) <= 1024)),
CONSTRAINT check_2dba05b802 CHECK ((char_length(gitpod_url) <= 255)),
CONSTRAINT check_32710817e9 CHECK ((char_length(static_objects_external_storage_auth_token_encrypted) <= 255)),
+ CONSTRAINT check_3559645ae5 CHECK ((char_length(container_registry_import_target_plan) <= 255)),
CONSTRAINT check_3def0f1829 CHECK ((char_length(sentry_clientside_dsn) <= 255)),
CONSTRAINT check_4f8b811780 CHECK ((char_length(sentry_dsn) <= 255)),
CONSTRAINT check_51700b31b5 CHECK ((char_length(default_branch_name) <= 255)),
@@ -12176,7 +12189,9 @@ CREATE TABLE ci_runners (
public_projects_minutes_cost_factor double precision DEFAULT 0.0 NOT NULL,
private_projects_minutes_cost_factor double precision DEFAULT 1.0 NOT NULL,
config jsonb DEFAULT '{}'::jsonb NOT NULL,
- executor_type smallint
+ executor_type smallint,
+ maintainer_note text,
+ CONSTRAINT check_56f5ea8804 CHECK ((char_length(maintainer_note) <= 255))
);
CREATE SEQUENCE ci_runners_id_seq
@@ -12206,6 +12221,29 @@ CREATE SEQUENCE ci_running_builds_id_seq
ALTER SEQUENCE ci_running_builds_id_seq OWNED BY ci_running_builds.id;
+CREATE TABLE ci_secure_files (
+ id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ file_store smallint DEFAULT 1 NOT NULL,
+ permissions smallint DEFAULT 0 NOT NULL,
+ name text NOT NULL,
+ file text NOT NULL,
+ checksum bytea NOT NULL,
+ CONSTRAINT check_320790634d CHECK ((char_length(file) <= 255)),
+ CONSTRAINT check_402c7b4a56 CHECK ((char_length(name) <= 255))
+);
+
+CREATE SEQUENCE ci_secure_files_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE ci_secure_files_id_seq OWNED BY ci_secure_files.id;
+
CREATE TABLE ci_sources_pipelines (
id integer NOT NULL,
project_id integer,
@@ -12383,6 +12421,7 @@ CREATE TABLE cluster_agent_tokens (
description text,
name text,
last_used_at timestamp with time zone,
+ status smallint DEFAULT 0 NOT NULL,
CONSTRAINT check_0fb634d04d CHECK ((name IS NOT NULL)),
CONSTRAINT check_2b79dbb315 CHECK ((char_length(name) <= 255)),
CONSTRAINT check_4e4ec5070a CHECK ((char_length(description) <= 1024)),
@@ -12878,7 +12917,19 @@ CREATE TABLE container_repositories (
status smallint,
expiration_policy_started_at timestamp with time zone,
expiration_policy_cleanup_status smallint DEFAULT 0 NOT NULL,
- expiration_policy_completed_at timestamp with time zone
+ expiration_policy_completed_at timestamp with time zone,
+ migration_pre_import_started_at timestamp with time zone,
+ migration_pre_import_done_at timestamp with time zone,
+ migration_import_started_at timestamp with time zone,
+ migration_import_done_at timestamp with time zone,
+ migration_aborted_at timestamp with time zone,
+ migration_skipped_at timestamp with time zone,
+ migration_retries_count integer DEFAULT 0 NOT NULL,
+ migration_skipped_reason smallint,
+ migration_state text DEFAULT 'default'::text NOT NULL,
+ migration_aborted_in_state text,
+ CONSTRAINT check_13c58fe73a CHECK ((char_length(migration_state) <= 255)),
+ CONSTRAINT check_97f0249439 CHECK ((char_length(migration_aborted_in_state) <= 255))
);
CREATE SEQUENCE container_repositories_id_seq
@@ -14711,6 +14762,22 @@ CREATE SEQUENCE grafana_integrations_id_seq
ALTER SEQUENCE grafana_integrations_id_seq OWNED BY grafana_integrations.id;
+CREATE TABLE group_crm_settings (
+ group_id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ enabled boolean DEFAULT false NOT NULL
+);
+
+CREATE SEQUENCE group_crm_settings_group_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE group_crm_settings_group_id_seq OWNED BY group_crm_settings.group_id;
+
CREATE TABLE group_custom_attributes (
id integer NOT NULL,
created_at timestamp with time zone NOT NULL,
@@ -15228,6 +15295,7 @@ CREATE TABLE integrations (
group_id bigint,
type_new text,
vulnerability_events boolean DEFAULT false NOT NULL,
+ archive_trace_events boolean DEFAULT false NOT NULL,
CONSTRAINT check_a948a0aa7e CHECK ((char_length(type_new) <= 255))
);
@@ -15936,7 +16004,8 @@ CREATE TABLE members (
ldap boolean DEFAULT false NOT NULL,
override boolean DEFAULT false NOT NULL,
state smallint DEFAULT 0,
- invite_email_success boolean DEFAULT true NOT NULL
+ invite_email_success boolean DEFAULT true NOT NULL,
+ member_namespace_id bigint
);
CREATE SEQUENCE members_id_seq
@@ -16458,6 +16527,9 @@ CREATE TABLE namespace_settings (
new_user_signups_cap integer,
setup_for_company boolean,
jobs_to_be_done smallint,
+ runner_token_expiration_interval integer,
+ subgroup_runner_token_expiration_interval integer,
+ project_runner_token_expiration_interval integer,
CONSTRAINT check_0ba93c78c7 CHECK ((char_length(default_branch_name) <= 255))
);
@@ -16760,7 +16832,14 @@ CREATE TABLE onboarding_progresses (
issue_auto_closed_at timestamp with time zone,
repository_imported_at timestamp with time zone,
repository_mirrored_at timestamp with time zone,
- issue_created_at timestamp with time zone
+ issue_created_at timestamp with time zone,
+ secure_dependency_scanning_run_at timestamp with time zone,
+ secure_container_scanning_run_at timestamp with time zone,
+ secure_dast_run_at timestamp with time zone,
+ secure_secret_detection_run_at timestamp with time zone,
+ secure_coverage_fuzzing_run_at timestamp with time zone,
+ secure_cluster_image_scanning_run_at timestamp with time zone,
+ secure_api_fuzzing_run_at timestamp with time zone
);
CREATE SEQUENCE onboarding_progresses_id_seq
@@ -17400,6 +17479,7 @@ CREATE TABLE packages_package_files (
verification_checksum bytea,
verification_state smallint DEFAULT 0 NOT NULL,
verification_started_at timestamp with time zone,
+ status smallint DEFAULT 0 NOT NULL,
CONSTRAINT check_4c5e6bb0b3 CHECK ((file_store IS NOT NULL))
);
@@ -18114,7 +18194,8 @@ CREATE TABLE project_ci_cd_settings (
auto_rollback_enabled boolean DEFAULT false NOT NULL,
keep_latest_artifact boolean DEFAULT true NOT NULL,
restrict_user_defined_variables boolean DEFAULT false NOT NULL,
- job_token_scope_enabled boolean DEFAULT false NOT NULL
+ job_token_scope_enabled boolean DEFAULT false NOT NULL,
+ runner_token_expiration_interval integer
);
CREATE SEQUENCE project_ci_cd_settings_id_seq
@@ -19210,7 +19291,8 @@ CREATE TABLE routes (
path character varying NOT NULL,
created_at timestamp without time zone,
updated_at timestamp without time zone,
- name character varying
+ name character varying,
+ namespace_id bigint
);
CREATE SEQUENCE routes_id_seq
@@ -19393,6 +19475,47 @@ CREATE SEQUENCE security_scans_id_seq
ALTER SEQUENCE security_scans_id_seq OWNED BY security_scans.id;
+CREATE TABLE security_training_providers (
+ id bigint NOT NULL,
+ name text NOT NULL,
+ description text,
+ url text NOT NULL,
+ logo_url text,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ CONSTRAINT check_544b3dc935 CHECK ((char_length(url) <= 512)),
+ CONSTRAINT check_6fe222f071 CHECK ((char_length(logo_url) <= 512)),
+ CONSTRAINT check_a8ff21ced5 CHECK ((char_length(description) <= 512)),
+ CONSTRAINT check_dae433eed6 CHECK ((char_length(name) <= 256))
+);
+
+CREATE SEQUENCE security_training_providers_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE security_training_providers_id_seq OWNED BY security_training_providers.id;
+
+CREATE TABLE security_trainings (
+ id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ provider_id bigint NOT NULL,
+ is_primary boolean DEFAULT false NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL
+);
+
+CREATE SEQUENCE security_trainings_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE security_trainings_id_seq OWNED BY security_trainings.id;
+
CREATE TABLE self_managed_prometheus_alert_events (
id bigint NOT NULL,
project_id bigint NOT NULL,
@@ -20204,8 +20327,9 @@ CREATE TABLE user_details (
pronunciation text,
registration_objective smallint,
phone text,
+ requires_credit_card_verification boolean DEFAULT false NOT NULL,
CONSTRAINT check_245664af82 CHECK ((char_length(webauthn_xid) <= 100)),
- CONSTRAINT check_a73b398c60 CHECK ((char_length(phone) <= 32)),
+ CONSTRAINT check_a73b398c60 CHECK ((char_length(phone) <= 50)),
CONSTRAINT check_b132136b01 CHECK ((char_length(other_role) <= 100)),
CONSTRAINT check_eeeaf8d4f0 CHECK ((char_length(pronouns) <= 50)),
CONSTRAINT check_f932ed37db CHECK ((char_length(pronunciation) <= 255))
@@ -20630,132 +20754,6 @@ CREATE SEQUENCE vulnerability_feedback_id_seq
ALTER SEQUENCE vulnerability_feedback_id_seq OWNED BY vulnerability_feedback.id;
-CREATE TABLE vulnerability_finding_evidence_assets (
- id bigint NOT NULL,
- created_at timestamp with time zone NOT NULL,
- updated_at timestamp with time zone NOT NULL,
- vulnerability_finding_evidence_id bigint NOT NULL,
- type text,
- name text,
- url text,
- CONSTRAINT check_5adf5d69de CHECK ((char_length(type) <= 2048)),
- CONSTRAINT check_839f29d7ca CHECK ((char_length(name) <= 2048)),
- CONSTRAINT check_9272d912c0 CHECK ((char_length(url) <= 2048))
-);
-
-CREATE SEQUENCE vulnerability_finding_evidence_assets_id_seq
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-ALTER SEQUENCE vulnerability_finding_evidence_assets_id_seq OWNED BY vulnerability_finding_evidence_assets.id;
-
-CREATE TABLE vulnerability_finding_evidence_headers (
- id bigint NOT NULL,
- created_at timestamp with time zone NOT NULL,
- updated_at timestamp with time zone NOT NULL,
- vulnerability_finding_evidence_request_id bigint,
- vulnerability_finding_evidence_response_id bigint,
- name text NOT NULL,
- value text NOT NULL,
- CONSTRAINT check_01d21e8d92 CHECK ((char_length(name) <= 255)),
- CONSTRAINT check_3f9011f903 CHECK ((char_length(value) <= 8192))
-);
-
-CREATE SEQUENCE vulnerability_finding_evidence_headers_id_seq
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-ALTER SEQUENCE vulnerability_finding_evidence_headers_id_seq OWNED BY vulnerability_finding_evidence_headers.id;
-
-CREATE TABLE vulnerability_finding_evidence_requests (
- id bigint NOT NULL,
- created_at timestamp with time zone NOT NULL,
- updated_at timestamp with time zone NOT NULL,
- vulnerability_finding_evidence_id bigint,
- method text,
- url text,
- body text,
- vulnerability_finding_evidence_supporting_message_id bigint,
- CONSTRAINT check_7e37f2d01a CHECK ((char_length(body) <= 2048)),
- CONSTRAINT check_8152fbb236 CHECK ((char_length(url) <= 2048)),
- CONSTRAINT check_d9d11300f4 CHECK ((char_length(method) <= 32))
-);
-
-CREATE SEQUENCE vulnerability_finding_evidence_requests_id_seq
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-ALTER SEQUENCE vulnerability_finding_evidence_requests_id_seq OWNED BY vulnerability_finding_evidence_requests.id;
-
-CREATE TABLE vulnerability_finding_evidence_responses (
- id bigint NOT NULL,
- created_at timestamp with time zone NOT NULL,
- updated_at timestamp with time zone NOT NULL,
- vulnerability_finding_evidence_id bigint,
- status_code integer,
- reason_phrase text,
- body text,
- vulnerability_finding_evidence_supporting_message_id bigint,
- CONSTRAINT check_58b124ab48 CHECK ((char_length(reason_phrase) <= 2048)),
- CONSTRAINT check_76bac0c32b CHECK ((char_length(body) <= 2048))
-);
-
-CREATE SEQUENCE vulnerability_finding_evidence_responses_id_seq
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-ALTER SEQUENCE vulnerability_finding_evidence_responses_id_seq OWNED BY vulnerability_finding_evidence_responses.id;
-
-CREATE TABLE vulnerability_finding_evidence_sources (
- id bigint NOT NULL,
- created_at timestamp with time zone NOT NULL,
- updated_at timestamp with time zone NOT NULL,
- vulnerability_finding_evidence_id bigint NOT NULL,
- name text,
- url text,
- CONSTRAINT check_0fe01298d6 CHECK ((char_length(url) <= 2048)),
- CONSTRAINT check_86b537ba1a CHECK ((char_length(name) <= 2048))
-);
-
-CREATE SEQUENCE vulnerability_finding_evidence_sources_id_seq
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-ALTER SEQUENCE vulnerability_finding_evidence_sources_id_seq OWNED BY vulnerability_finding_evidence_sources.id;
-
-CREATE TABLE vulnerability_finding_evidence_supporting_messages (
- id bigint NOT NULL,
- created_at timestamp with time zone NOT NULL,
- updated_at timestamp with time zone NOT NULL,
- vulnerability_finding_evidence_id bigint NOT NULL,
- name text,
- CONSTRAINT check_fa33b9ae85 CHECK ((char_length(name) <= 2048))
-);
-
-CREATE SEQUENCE vulnerability_finding_evidence_supporting_messages_id_seq
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-ALTER SEQUENCE vulnerability_finding_evidence_supporting_messages_id_seq OWNED BY vulnerability_finding_evidence_supporting_messages.id;
-
CREATE TABLE vulnerability_finding_evidences (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
@@ -21001,7 +20999,9 @@ CREATE TABLE vulnerability_reads (
resolved_on_default_branch boolean DEFAULT false NOT NULL,
uuid uuid NOT NULL,
location_image text,
- CONSTRAINT check_380451bdbe CHECK ((char_length(location_image) <= 2048))
+ cluster_agent_id text,
+ CONSTRAINT check_380451bdbe CHECK ((char_length(location_image) <= 2048)),
+ CONSTRAINT check_a105eb825a CHECK ((char_length(cluster_agent_id) <= 10))
);
CREATE SEQUENCE vulnerability_reads_id_seq
@@ -21535,6 +21535,8 @@ ALTER TABLE ONLY ci_runners ALTER COLUMN id SET DEFAULT nextval('ci_runners_id_s
ALTER TABLE ONLY ci_running_builds ALTER COLUMN id SET DEFAULT nextval('ci_running_builds_id_seq'::regclass);
+ALTER TABLE ONLY ci_secure_files ALTER COLUMN id SET DEFAULT nextval('ci_secure_files_id_seq'::regclass);
+
ALTER TABLE ONLY ci_sources_pipelines ALTER COLUMN id SET DEFAULT nextval('ci_sources_pipelines_id_seq'::regclass);
ALTER TABLE ONLY ci_sources_projects ALTER COLUMN id SET DEFAULT nextval('ci_sources_projects_id_seq'::regclass);
@@ -21759,6 +21761,8 @@ ALTER TABLE ONLY gpg_signatures ALTER COLUMN id SET DEFAULT nextval('gpg_signatu
ALTER TABLE ONLY grafana_integrations ALTER COLUMN id SET DEFAULT nextval('grafana_integrations_id_seq'::regclass);
+ALTER TABLE ONLY group_crm_settings ALTER COLUMN group_id SET DEFAULT nextval('group_crm_settings_group_id_seq'::regclass);
+
ALTER TABLE ONLY group_custom_attributes ALTER COLUMN id SET DEFAULT nextval('group_custom_attributes_id_seq'::regclass);
ALTER TABLE ONLY group_deploy_keys ALTER COLUMN id SET DEFAULT nextval('group_deploy_keys_id_seq'::regclass);
@@ -22141,6 +22145,10 @@ ALTER TABLE ONLY security_orchestration_policy_rule_schedules ALTER COLUMN id SE
ALTER TABLE ONLY security_scans ALTER COLUMN id SET DEFAULT nextval('security_scans_id_seq'::regclass);
+ALTER TABLE ONLY security_training_providers ALTER COLUMN id SET DEFAULT nextval('security_training_providers_id_seq'::regclass);
+
+ALTER TABLE ONLY security_trainings ALTER COLUMN id SET DEFAULT nextval('security_trainings_id_seq'::regclass);
+
ALTER TABLE ONLY self_managed_prometheus_alert_events ALTER COLUMN id SET DEFAULT nextval('self_managed_prometheus_alert_events_id_seq'::regclass);
ALTER TABLE ONLY sent_notifications ALTER COLUMN id SET DEFAULT nextval('sent_notifications_id_seq'::regclass);
@@ -22243,18 +22251,6 @@ ALTER TABLE ONLY vulnerability_external_issue_links ALTER COLUMN id SET DEFAULT
ALTER TABLE ONLY vulnerability_feedback ALTER COLUMN id SET DEFAULT nextval('vulnerability_feedback_id_seq'::regclass);
-ALTER TABLE ONLY vulnerability_finding_evidence_assets ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_evidence_assets_id_seq'::regclass);
-
-ALTER TABLE ONLY vulnerability_finding_evidence_headers ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_evidence_headers_id_seq'::regclass);
-
-ALTER TABLE ONLY vulnerability_finding_evidence_requests ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_evidence_requests_id_seq'::regclass);
-
-ALTER TABLE ONLY vulnerability_finding_evidence_responses ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_evidence_responses_id_seq'::regclass);
-
-ALTER TABLE ONLY vulnerability_finding_evidence_sources ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_evidence_sources_id_seq'::regclass);
-
-ALTER TABLE ONLY vulnerability_finding_evidence_supporting_messages ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_evidence_supporting_messages_id_seq'::regclass);
-
ALTER TABLE ONLY vulnerability_finding_evidences ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_evidences_id_seq'::regclass);
ALTER TABLE ONLY vulnerability_finding_links ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_links_id_seq'::regclass);
@@ -23035,6 +23031,9 @@ ALTER TABLE ONLY ci_runners
ALTER TABLE ONLY ci_running_builds
ADD CONSTRAINT ci_running_builds_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY ci_secure_files
+ ADD CONSTRAINT ci_secure_files_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY ci_sources_pipelines
ADD CONSTRAINT ci_sources_pipelines_pkey PRIMARY KEY (id);
@@ -23407,6 +23406,9 @@ ALTER TABLE ONLY gpg_signatures
ALTER TABLE ONLY grafana_integrations
ADD CONSTRAINT grafana_integrations_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY group_crm_settings
+ ADD CONSTRAINT group_crm_settings_pkey PRIMARY KEY (group_id);
+
ALTER TABLE ONLY group_custom_attributes
ADD CONSTRAINT group_custom_attributes_pkey PRIMARY KEY (id);
@@ -24088,6 +24090,12 @@ ALTER TABLE ONLY security_orchestration_policy_rule_schedules
ALTER TABLE ONLY security_scans
ADD CONSTRAINT security_scans_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY security_training_providers
+ ADD CONSTRAINT security_training_providers_pkey PRIMARY KEY (id);
+
+ALTER TABLE ONLY security_trainings
+ ADD CONSTRAINT security_trainings_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY self_managed_prometheus_alert_events
ADD CONSTRAINT self_managed_prometheus_alert_events_pkey PRIMARY KEY (id);
@@ -24274,24 +24282,6 @@ ALTER TABLE ONLY vulnerability_external_issue_links
ALTER TABLE ONLY vulnerability_feedback
ADD CONSTRAINT vulnerability_feedback_pkey PRIMARY KEY (id);
-ALTER TABLE ONLY vulnerability_finding_evidence_assets
- ADD CONSTRAINT vulnerability_finding_evidence_assets_pkey PRIMARY KEY (id);
-
-ALTER TABLE ONLY vulnerability_finding_evidence_headers
- ADD CONSTRAINT vulnerability_finding_evidence_headers_pkey PRIMARY KEY (id);
-
-ALTER TABLE ONLY vulnerability_finding_evidence_requests
- ADD CONSTRAINT vulnerability_finding_evidence_requests_pkey PRIMARY KEY (id);
-
-ALTER TABLE ONLY vulnerability_finding_evidence_responses
- ADD CONSTRAINT vulnerability_finding_evidence_responses_pkey PRIMARY KEY (id);
-
-ALTER TABLE ONLY vulnerability_finding_evidence_sources
- ADD CONSTRAINT vulnerability_finding_evidence_sources_pkey PRIMARY KEY (id);
-
-ALTER TABLE ONLY vulnerability_finding_evidence_supporting_messages
- ADD CONSTRAINT vulnerability_finding_evidence_supporting_messages_pkey PRIMARY KEY (id);
-
ALTER TABLE ONLY vulnerability_finding_evidences
ADD CONSTRAINT vulnerability_finding_evidences_pkey PRIMARY KEY (id);
@@ -25071,25 +25061,11 @@ CREATE UNIQUE INDEX epic_user_mentions_on_epic_id_and_note_id_index ON epic_user
CREATE UNIQUE INDEX epic_user_mentions_on_epic_id_index ON epic_user_mentions USING btree (epic_id) WHERE (note_id IS NULL);
-CREATE INDEX finding_evidence_assets_on_finding_evidence_id ON vulnerability_finding_evidence_assets USING btree (vulnerability_finding_evidence_id);
-
-CREATE INDEX finding_evidence_header_on_finding_evidence_request_id ON vulnerability_finding_evidence_headers USING btree (vulnerability_finding_evidence_request_id);
-
-CREATE INDEX finding_evidence_header_on_finding_evidence_response_id ON vulnerability_finding_evidence_headers USING btree (vulnerability_finding_evidence_response_id);
-
-CREATE INDEX finding_evidence_requests_on_finding_evidence_id ON vulnerability_finding_evidence_requests USING btree (vulnerability_finding_evidence_id);
-
-CREATE INDEX finding_evidence_requests_on_supporting_evidence_id ON vulnerability_finding_evidence_requests USING btree (vulnerability_finding_evidence_supporting_message_id);
-
-CREATE INDEX finding_evidence_responses_on_finding_evidences_id ON vulnerability_finding_evidence_responses USING btree (vulnerability_finding_evidence_id);
-
-CREATE INDEX finding_evidence_responses_on_supporting_evidence_id ON vulnerability_finding_evidence_responses USING btree (vulnerability_finding_evidence_supporting_message_id);
-
-CREATE INDEX finding_evidence_sources_on_finding_evidence_id ON vulnerability_finding_evidence_sources USING btree (vulnerability_finding_evidence_id);
+CREATE UNIQUE INDEX finding_evidences_on_unique_vulnerability_occurrence_id ON vulnerability_finding_evidences USING btree (vulnerability_occurrence_id);
-CREATE INDEX finding_evidence_supporting_messages_on_finding_evidence_id ON vulnerability_finding_evidence_supporting_messages USING btree (vulnerability_finding_evidence_id);
+CREATE UNIQUE INDEX finding_link_name_url_idx ON vulnerability_finding_links USING btree (vulnerability_occurrence_id, name, url);
-CREATE UNIQUE INDEX finding_evidences_on_unique_vulnerability_occurrence_id ON vulnerability_finding_evidences USING btree (vulnerability_occurrence_id);
+CREATE UNIQUE INDEX finding_link_url_idx ON vulnerability_finding_links USING btree (vulnerability_occurrence_id, url) WHERE (name IS NULL);
CREATE INDEX finding_links_on_vulnerability_occurrence_id ON vulnerability_finding_links USING btree (vulnerability_occurrence_id);
@@ -25599,6 +25575,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_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);
CREATE INDEX index_ci_job_artifacts_on_project_id ON ci_job_artifacts USING btree (project_id);
@@ -25705,6 +25683,8 @@ CREATE INDEX index_ci_pipelines_on_user_id_and_created_at_and_source ON ci_pipel
CREATE INDEX index_ci_pipelines_on_user_id_and_id_and_cancelable_status ON ci_pipelines USING btree (user_id, id) WHERE ((status)::text = ANY (ARRAY[('running'::character varying)::text, ('waiting_for_resource'::character varying)::text, ('preparing'::character varying)::text, ('pending'::character varying)::text, ('created'::character varying)::text, ('scheduled'::character varying)::text]));
+CREATE INDEX index_ci_pipelines_on_user_id_and_id_desc_and_user_not_verified ON ci_pipelines USING btree (user_id, id DESC) WHERE (failure_reason = 3);
+
CREATE INDEX index_ci_project_mirrors_on_namespace_id ON ci_project_mirrors USING btree (namespace_id);
CREATE UNIQUE INDEX index_ci_project_mirrors_on_project_id ON ci_project_mirrors USING btree (project_id);
@@ -25727,6 +25707,8 @@ CREATE INDEX index_ci_runner_projects_on_project_id ON ci_runner_projects USING
CREATE INDEX index_ci_runner_projects_on_runner_id ON ci_runner_projects USING btree (runner_id);
+CREATE INDEX index_ci_runners_on_active ON ci_runners USING btree (active, id);
+
CREATE INDEX index_ci_runners_on_contacted_at_and_id_desc ON ci_runners USING btree (contacted_at, id DESC);
CREATE INDEX index_ci_runners_on_contacted_at_and_id_where_inactive ON ci_runners USING btree (contacted_at DESC, id DESC) WHERE (active = false);
@@ -25755,6 +25737,8 @@ CREATE INDEX index_ci_running_builds_on_project_id ON ci_running_builds USING bt
CREATE INDEX index_ci_running_builds_on_runner_id ON ci_running_builds USING btree (runner_id);
+CREATE INDEX index_ci_secure_files_on_project_id ON ci_secure_files USING btree (project_id);
+
CREATE INDEX index_ci_sources_pipelines_on_pipeline_id ON ci_sources_pipelines USING btree (pipeline_id);
CREATE INDEX index_ci_sources_pipelines_on_project_id ON ci_sources_pipelines USING btree (project_id);
@@ -25801,6 +25785,8 @@ CREATE UNIQUE INDEX index_ci_variables_on_project_id_and_key_and_environment_sco
CREATE INDEX index_cluster_agent_tokens_on_agent_id_and_last_used_at ON cluster_agent_tokens USING btree (agent_id, last_used_at DESC NULLS LAST);
+CREATE INDEX index_cluster_agent_tokens_on_agent_id_status_last_used_at ON cluster_agent_tokens USING btree (agent_id, status, last_used_at DESC NULLS LAST);
+
CREATE INDEX index_cluster_agent_tokens_on_created_by_user_id ON cluster_agent_tokens USING btree (created_by_user_id);
CREATE UNIQUE INDEX index_cluster_agent_tokens_on_token_encrypted ON cluster_agent_tokens USING btree (token_encrypted);
@@ -26179,6 +26165,8 @@ CREATE INDEX index_events_on_author_id_and_created_at ON events USING btree (aut
CREATE INDEX index_events_on_author_id_and_created_at_merge_requests ON events USING btree (author_id, created_at) WHERE ((target_type)::text = 'MergeRequest'::text);
+CREATE INDEX index_events_on_author_id_and_id ON events USING btree (author_id, id);
+
CREATE INDEX index_events_on_created_at_and_id ON events USING btree (created_at, id) WHERE (created_at > '2021-08-27 00:00:00+00'::timestamp with time zone);
CREATE INDEX index_events_on_group_id_partial ON events USING btree (group_id) WHERE (group_id IS NOT NULL);
@@ -26331,6 +26319,8 @@ CREATE INDEX index_grafana_integrations_on_enabled ON grafana_integrations USING
CREATE INDEX index_grafana_integrations_on_project_id ON grafana_integrations USING btree (project_id);
+CREATE INDEX index_group_crm_settings_on_group_id ON group_crm_settings USING btree (group_id);
+
CREATE UNIQUE INDEX index_group_custom_attributes_on_group_id_and_key ON group_custom_attributes USING btree (group_id, key);
CREATE INDEX index_group_custom_attributes_on_key_and_value ON group_custom_attributes USING btree (key, value);
@@ -26659,6 +26649,8 @@ CREATE INDEX index_members_on_invite_email ON members USING btree (invite_email)
CREATE UNIQUE INDEX index_members_on_invite_token ON members USING btree (invite_token);
+CREATE INDEX index_members_on_member_namespace_id ON members USING btree (member_namespace_id);
+
CREATE INDEX index_members_on_requested_at ON members USING btree (requested_at);
CREATE INDEX index_members_on_source_id_and_source_type ON members USING btree (source_id, source_type);
@@ -26775,8 +26767,6 @@ CREATE INDEX index_merge_requests_on_target_project_id_and_updated_at_and_id ON
CREATE INDEX index_merge_requests_on_target_project_id_iid_jira_description ON merge_requests USING btree (target_project_id, iid) WHERE (description ~ '[A-Z][A-Z_0-9]+-\d+'::text);
-CREATE INDEX index_merge_requests_on_title ON merge_requests USING btree (title);
-
CREATE INDEX index_merge_requests_on_title_trigram ON merge_requests USING gin (title gin_trgm_ops);
CREATE INDEX index_merge_requests_on_tp_id_and_merge_commit_sha_and_id ON merge_requests USING btree (target_project_id, merge_commit_sha, id);
@@ -26953,6 +26943,8 @@ CREATE UNIQUE INDEX index_on_project_id_escalation_policy_name_unique ON inciden
CREATE INDEX index_on_projects_lower_path ON projects USING btree (lower((path)::text));
+CREATE INDEX index_on_projects_path ON projects USING btree (path);
+
CREATE INDEX index_on_routes_lower_path ON routes USING btree (lower((path)::text));
CREATE INDEX index_on_users_lower_email ON users USING btree (lower((email)::text));
@@ -27053,6 +27045,10 @@ CREATE INDEX index_packages_package_files_on_package_id_and_file_name ON package
CREATE INDEX index_packages_package_files_on_package_id_id ON packages_package_files USING btree (package_id, id);
+CREATE INDEX index_packages_package_files_on_package_id_status_and_id ON packages_package_files USING btree (package_id, status, id);
+
+CREATE INDEX index_packages_package_files_on_status ON packages_package_files USING btree (status);
+
CREATE INDEX index_packages_package_files_on_verification_state ON packages_package_files USING btree (verification_state);
CREATE INDEX index_packages_packages_on_creator_id ON packages_packages USING btree (creator_id);
@@ -27525,6 +27521,8 @@ CREATE INDEX index_reviews_on_project_id ON reviews USING btree (project_id);
CREATE INDEX index_route_on_name_trigram ON routes USING gin (name gin_trgm_ops);
+CREATE UNIQUE INDEX index_routes_on_namespace_id ON routes USING btree (namespace_id);
+
CREATE UNIQUE INDEX index_routes_on_path ON routes USING btree (path);
CREATE INDEX index_routes_on_path_text_pattern_ops ON routes USING btree (path varchar_pattern_ops);
@@ -27571,6 +27569,12 @@ 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 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);
+
+CREATE UNIQUE INDEX index_security_trainings_on_unique_project_id ON security_trainings USING btree (project_id) WHERE (is_primary IS TRUE);
+
CREATE INDEX index_self_managed_prometheus_alert_events_on_environment_id ON self_managed_prometheus_alert_events USING btree (environment_id);
CREATE INDEX index_sent_notifications_on_noteable_type_noteable_id ON sent_notifications USING btree (noteable_id) WHERE ((noteable_type)::text = 'Issue'::text);
@@ -27919,6 +27923,8 @@ CREATE INDEX index_users_star_projects_on_project_id ON users_star_projects USIN
CREATE UNIQUE INDEX index_users_star_projects_on_user_id_and_project_id ON users_star_projects USING btree (user_id, project_id);
+CREATE INDEX index_users_with_static_object_token ON users USING btree (id) WHERE ((static_object_token IS NOT NULL) AND (static_object_token_encrypted IS NULL));
+
CREATE UNIQUE INDEX index_verification_codes_on_phone_and_visitor_id_code ON ONLY verification_codes USING btree (visitor_id_code, phone, created_at);
COMMENT ON INDEX index_verification_codes_on_phone_and_visitor_id_code IS 'JiHu-specific index';
@@ -28005,11 +28011,11 @@ CREATE INDEX index_vulnerability_occurrences_deduplication ON vulnerability_occu
CREATE INDEX index_vulnerability_occurrences_for_issue_links_migration ON vulnerability_occurrences USING btree (project_id, report_type, encode(project_fingerprint, 'hex'::text));
-CREATE INDEX index_vulnerability_occurrences_on_location_agent_id ON vulnerability_occurrences USING gin (((location -> 'agent_id'::text))) WHERE (report_type = 7);
+CREATE INDEX index_vulnerability_occurrences_on_location_image ON vulnerability_occurrences USING gin (((location -> 'image'::text))) WHERE (report_type = ANY (ARRAY[2, 7]));
-CREATE INDEX index_vulnerability_occurrences_on_location_cluster_id ON vulnerability_occurrences USING gin (((location -> 'cluster_id'::text))) WHERE (report_type = 7);
+CREATE INDEX index_vulnerability_occurrences_on_location_k8s_agent_id ON vulnerability_occurrences USING gin ((((location -> 'kubernetes_resource'::text) -> 'agent_id'::text))) WHERE (report_type = 7);
-CREATE INDEX index_vulnerability_occurrences_on_location_image ON vulnerability_occurrences USING gin (((location -> 'image'::text))) WHERE (report_type = ANY (ARRAY[2, 7]));
+CREATE INDEX index_vulnerability_occurrences_on_location_k8s_cluster_id ON vulnerability_occurrences USING gin ((((location -> 'kubernetes_resource'::text) -> 'cluster_id'::text))) WHERE (report_type = 7);
CREATE INDEX index_vulnerability_occurrences_on_migrated_to_new_structure ON vulnerability_occurrences USING btree (migrated_to_new_structure, id);
@@ -28025,6 +28031,8 @@ CREATE UNIQUE INDEX index_vulnerability_occurrences_on_uuid ON vulnerability_occ
CREATE INDEX index_vulnerability_occurrences_on_vulnerability_id ON vulnerability_occurrences USING btree (vulnerability_id);
+CREATE INDEX index_vulnerability_reads_on_cluster_agent_id ON vulnerability_reads USING btree (cluster_agent_id) WHERE (report_type = 7);
+
CREATE INDEX index_vulnerability_reads_on_location_image ON vulnerability_reads USING btree (location_image) WHERE (report_type = ANY (ARRAY[2, 7]));
CREATE INDEX index_vulnerability_reads_on_scanner_id ON vulnerability_reads USING btree (scanner_id);
@@ -28147,6 +28155,10 @@ CREATE UNIQUE INDEX term_agreements_unique_index ON term_agreements USING btree
CREATE INDEX tmp_idx_deduplicate_vulnerability_occurrences ON vulnerability_occurrences USING btree (project_id, report_type, location_fingerprint, primary_identifier_id, id);
+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_members_on_state ON members USING btree (state) WHERE (state = 2);
+
CREATE INDEX tmp_index_namespaces_empty_traversal_ids_with_child_namespaces ON namespaces USING btree (id) WHERE ((parent_id IS NOT NULL) AND (traversal_ids = '{}'::integer[]));
CREATE INDEX tmp_index_namespaces_empty_traversal_ids_with_root_namespaces ON namespaces USING btree (id) WHERE ((parent_id IS NULL) AND (traversal_ids = '{}'::integer[]));
@@ -28155,8 +28167,6 @@ 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_uuid_is_null ON security_findings USING btree (id) WHERE (uuid IS 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);
@@ -29287,9 +29297,6 @@ ALTER TABLE ONLY agent_group_authorizations
ALTER TABLE ONLY deployment_approvals
ADD CONSTRAINT fk_2d060dfc73 FOREIGN KEY (deployment_id) REFERENCES deployments(id) ON DELETE CASCADE;
-ALTER TABLE ONLY ci_freeze_periods
- ADD CONSTRAINT fk_2e02bbd1a6 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY notes
ADD CONSTRAINT fk_2e82291620 FOREIGN KEY (review_id) REFERENCES reviews(id) ON DELETE SET NULL;
@@ -29311,9 +29318,6 @@ ALTER TABLE ONLY approvals
ALTER TABLE ONLY namespaces
ADD CONSTRAINT fk_319256d87a FOREIGN KEY (file_template_project_id) REFERENCES projects(id) ON DELETE SET NULL;
-ALTER TABLE ONLY ci_group_variables
- ADD CONSTRAINT fk_33ae4d58d8 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY namespaces
ADD CONSTRAINT fk_3448c97865 FOREIGN KEY (push_rule_id) REFERENCES push_rules(id) ON DELETE SET NULL;
@@ -29437,8 +29441,8 @@ ALTER TABLE ONLY merge_requests
ALTER TABLE ONLY ci_builds
ADD CONSTRAINT fk_6661f4f0e8 FOREIGN KEY (resource_group_id) REFERENCES ci_resource_groups(id) ON DELETE SET NULL;
-ALTER TABLE ONLY project_pages_metadata
- ADD CONSTRAINT fk_69366a119e FOREIGN KEY (artifacts_archive_id) REFERENCES ci_job_artifacts(id) ON DELETE SET NULL;
+ALTER TABLE ONLY routes
+ ADD CONSTRAINT fk_679ff8213d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE SET NULL;
ALTER TABLE ONLY application_settings
ADD CONSTRAINT fk_693b8795e4 FOREIGN KEY (push_rule_id) REFERENCES push_rules(id) ON DELETE SET NULL;
@@ -29465,7 +29469,7 @@ ALTER TABLE ONLY protected_branch_push_access_levels
ADD CONSTRAINT fk_7111b68cdb FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY projects
- ADD CONSTRAINT fk_71625606ac FOREIGN KEY (project_namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+ ADD CONSTRAINT fk_71625606ac FOREIGN KEY (project_namespace_id) REFERENCES namespaces(id) ON DELETE SET NULL;
ALTER TABLE ONLY integrations
ADD CONSTRAINT fk_71cce407f9 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -29488,9 +29492,6 @@ ALTER TABLE ONLY vulnerabilities
ALTER TABLE ONLY oauth_openid_requests
ADD CONSTRAINT fk_77114b3b09 FOREIGN KEY (access_grant_id) REFERENCES oauth_access_grants(id) ON DELETE CASCADE;
-ALTER TABLE ONLY ci_resource_groups
- ADD CONSTRAINT fk_774722d144 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY users
ADD CONSTRAINT fk_789cd90b35 FOREIGN KEY (accepted_term_id) REFERENCES application_setting_terms(id) ON DELETE CASCADE;
@@ -29503,9 +29504,6 @@ ALTER TABLE ONLY analytics_devops_adoption_snapshots
ALTER TABLE ONLY lists
ADD CONSTRAINT fk_7a5553d60f FOREIGN KEY (label_id) REFERENCES labels(id) ON DELETE CASCADE;
-ALTER TABLE ONLY ci_unit_tests
- ADD CONSTRAINT fk_7a8fabf0a8 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY protected_branches
ADD CONSTRAINT fk_7a9c6d93e7 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -29641,9 +29639,6 @@ ALTER TABLE ONLY protected_environments
ALTER TABLE ONLY alert_management_alerts
ADD CONSTRAINT fk_9e49e5c2b7 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-ALTER TABLE ONLY ci_pipeline_schedules
- ADD CONSTRAINT fk_9ea99f58d2 FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE SET NULL;
-
ALTER TABLE ONLY protected_branch_push_access_levels
ADD CONSTRAINT fk_9ffc86a3d9 FOREIGN KEY (protected_branch_id) REFERENCES protected_branches(id) ON DELETE CASCADE;
@@ -29659,9 +29654,6 @@ ALTER TABLE ONLY ci_builds
ALTER TABLE ONLY ci_pipelines
ADD CONSTRAINT fk_a23be95014 FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
-ALTER TABLE ONLY dast_site_profiles_builds
- ADD CONSTRAINT fk_a325505e99 FOREIGN KEY (ci_build_id) REFERENCES ci_builds(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY bulk_import_entities
ADD CONSTRAINT fk_a44ff95be5 FOREIGN KEY (parent_id) REFERENCES bulk_import_entities(id) ON DELETE CASCADE;
@@ -29683,6 +29675,9 @@ ALTER TABLE ONLY epics
ALTER TABLE ONLY dast_profiles
ADD CONSTRAINT fk_aa76ef30e9 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY members
+ ADD CONSTRAINT fk_aa82dcc1c6 FOREIGN KEY (member_namespace_id) REFERENCES namespaces(id) ON DELETE SET NULL;
+
ALTER TABLE ONLY alert_management_alerts
ADD CONSTRAINT fk_aad61aedca FOREIGN KEY (environment_id) REFERENCES environments(id) ON DELETE SET NULL;
@@ -29914,9 +29909,6 @@ ALTER TABLE ONLY gitlab_subscriptions
ALTER TABLE ONLY ci_triggers
ADD CONSTRAINT fk_e3e63f966e FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-ALTER TABLE ONLY dast_scanner_profiles_builds
- ADD CONSTRAINT fk_e4c49200f8 FOREIGN KEY (ci_build_id) REFERENCES ci_builds(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY merge_requests
ADD CONSTRAINT fk_e719a85f8a FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE SET NULL;
@@ -30013,15 +30005,9 @@ ALTER TABLE ONLY system_note_metadata
ALTER TABLE ONLY vulnerability_remediations
ADD CONSTRAINT fk_fc61a535a0 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-ALTER TABLE ONLY ci_daily_build_group_report_results
- ADD CONSTRAINT fk_fd1858fefd FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY merge_requests
ADD CONSTRAINT fk_fd82eae0b9 FOREIGN KEY (head_pipeline_id) REFERENCES ci_pipelines(id) ON DELETE SET NULL;
-ALTER TABLE ONLY ci_pending_builds
- ADD CONSTRAINT fk_fdc0137e4a FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY project_import_data
ADD CONSTRAINT fk_ffb9ee3a10 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -30076,12 +30062,6 @@ ALTER TABLE ONLY ip_restrictions
ALTER TABLE ONLY terraform_state_versions
ADD CONSTRAINT fk_rails_04f176e239 FOREIGN KEY (terraform_state_id) REFERENCES terraform_states(id) ON DELETE CASCADE;
-ALTER TABLE ONLY ci_build_report_results
- ADD CONSTRAINT fk_rails_056d298d48 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-
-ALTER TABLE ONLY ci_daily_build_group_report_results
- ADD CONSTRAINT fk_rails_0667f7608c FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY ci_subscriptions_projects
ADD CONSTRAINT fk_rails_0818751483 FOREIGN KEY (downstream_project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -30268,9 +30248,6 @@ ALTER TABLE ONLY service_desk_settings
ALTER TABLE ONLY saml_group_links
ADD CONSTRAINT fk_rails_22e312c530 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
-ALTER TABLE ONLY vulnerability_finding_evidence_responses
- ADD CONSTRAINT fk_rails_2390a09723 FOREIGN KEY (vulnerability_finding_evidence_id) REFERENCES vulnerability_finding_evidences(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY dast_profiles
ADD CONSTRAINT fk_rails_23cae5abe1 FOREIGN KEY (dast_scanner_profile_id) REFERENCES dast_scanner_profiles(id) ON DELETE CASCADE;
@@ -30379,9 +30356,6 @@ ALTER TABLE ONLY metrics_dashboard_annotations
ALTER TABLE ONLY wiki_page_slugs
ADD CONSTRAINT fk_rails_358b46be14 FOREIGN KEY (wiki_page_meta_id) REFERENCES wiki_page_meta(id) ON DELETE CASCADE;
-ALTER TABLE ONLY ci_job_token_project_scope_links
- ADD CONSTRAINT fk_rails_35f7f506ce FOREIGN KEY (added_by_id) REFERENCES users(id) ON DELETE SET NULL;
-
ALTER TABLE ONLY board_labels
ADD CONSTRAINT fk_rails_362b0600a3 FOREIGN KEY (label_id) REFERENCES labels(id) ON DELETE CASCADE;
@@ -30502,15 +30476,9 @@ ALTER TABLE ONLY vulnerability_feedback
ALTER TABLE ONLY user_custom_attributes
ADD CONSTRAINT fk_rails_47b91868a8 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
-ALTER TABLE ONLY ci_pending_builds
- ADD CONSTRAINT fk_rails_480669c3b3 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY upcoming_reconciliations
ADD CONSTRAINT fk_rails_497b4938ac FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
-ALTER TABLE ONLY ci_pipeline_artifacts
- ADD CONSTRAINT fk_rails_4a70390ca6 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY ci_job_token_project_scope_links
ADD CONSTRAINT fk_rails_4b2ee3290b FOREIGN KEY (source_project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -30547,9 +30515,6 @@ ALTER TABLE ONLY geo_repository_renamed_events
ALTER TABLE ONLY aws_roles
ADD CONSTRAINT fk_rails_4ed56f4720 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
-ALTER TABLE ONLY security_scans
- ADD CONSTRAINT fk_rails_4ef1e6b4c6 FOREIGN KEY (build_id) REFERENCES ci_builds(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY packages_debian_publications
ADD CONSTRAINT fk_rails_4fc8ebd03e FOREIGN KEY (distribution_id) REFERENCES packages_debian_project_distributions(id) ON DELETE CASCADE;
@@ -30727,9 +30692,6 @@ ALTER TABLE ONLY vulnerability_findings_remediations
ALTER TABLE ONLY resource_iteration_events
ADD CONSTRAINT fk_rails_6830c13ac1 FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
-ALTER TABLE ONLY vulnerability_finding_evidence_headers
- ADD CONSTRAINT fk_rails_683b8e000c FOREIGN KEY (vulnerability_finding_evidence_response_id) REFERENCES vulnerability_finding_evidence_responses(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY geo_hashed_storage_migrated_events
ADD CONSTRAINT fk_rails_687ed7d7c5 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -30751,9 +30713,6 @@ ALTER TABLE ONLY prometheus_alerts
ALTER TABLE ONLY term_agreements
ADD CONSTRAINT fk_rails_6ea6520e4a FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
-ALTER TABLE ONLY vulnerability_finding_evidence_assets
- ADD CONSTRAINT fk_rails_6edbbecba4 FOREIGN KEY (vulnerability_finding_evidence_id) REFERENCES vulnerability_finding_evidences(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY project_compliance_framework_settings
ADD CONSTRAINT fk_rails_6f5294f16c FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -30784,9 +30743,6 @@ ALTER TABLE ONLY dast_scanner_profiles
ALTER TABLE ONLY vulnerability_historical_statistics
ADD CONSTRAINT fk_rails_72b73ed023 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-ALTER TABLE ONLY vulnerability_finding_evidence_requests
- ADD CONSTRAINT fk_rails_72c87c8eb6 FOREIGN KEY (vulnerability_finding_evidence_id) REFERENCES vulnerability_finding_evidences(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY slack_integrations
ADD CONSTRAINT fk_rails_73db19721a FOREIGN KEY (service_id) REFERENCES integrations(id) ON DELETE CASCADE;
@@ -30802,6 +30758,9 @@ ALTER TABLE ONLY dast_site_profiles
ALTER TABLE ONLY merge_request_context_commit_diff_files
ADD CONSTRAINT fk_rails_74a00a1787 FOREIGN KEY (merge_request_context_commit_id) REFERENCES merge_request_context_commits(id) ON DELETE CASCADE;
+ALTER TABLE ONLY group_crm_settings
+ ADD CONSTRAINT fk_rails_74fdf2f13d FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY clusters_applications_ingress
ADD CONSTRAINT fk_rails_753a7b41c1 FOREIGN KEY (cluster_id) REFERENCES clusters(id) ON DELETE CASCADE;
@@ -30841,9 +30800,6 @@ ALTER TABLE ONLY terraform_states
ALTER TABLE ONLY analytics_cycle_analytics_project_stages
ADD CONSTRAINT fk_rails_796a7dbc9c FOREIGN KEY (project_value_stream_id) REFERENCES analytics_cycle_analytics_project_value_streams(id) ON DELETE CASCADE;
-ALTER TABLE ONLY vulnerability_finding_evidence_supporting_messages
- ADD CONSTRAINT fk_rails_79e77f6c5c FOREIGN KEY (vulnerability_finding_evidence_id) REFERENCES vulnerability_finding_evidences(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY software_license_policies
ADD CONSTRAINT fk_rails_7a7a2a92de FOREIGN KEY (software_license_id) REFERENCES software_licenses(id) ON DELETE CASCADE;
@@ -30874,6 +30830,9 @@ ALTER TABLE ONLY required_code_owners_sections
ALTER TABLE ONLY dast_site_profiles
ADD CONSTRAINT fk_rails_83e309d69e FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY security_trainings
+ ADD CONSTRAINT fk_rails_84c7951d72 FOREIGN KEY (provider_id) REFERENCES security_training_providers(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY zentao_tracker_data
ADD CONSTRAINT fk_rails_84efda7be0 FOREIGN KEY (integration_id) REFERENCES integrations(id) ON DELETE CASCADE;
@@ -30970,9 +30929,6 @@ ALTER TABLE ONLY project_error_tracking_settings
ALTER TABLE ONLY list_user_preferences
ADD CONSTRAINT fk_rails_916d72cafd FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
-ALTER TABLE ONLY vulnerability_finding_evidence_responses
- ADD CONSTRAINT fk_rails_929041a499 FOREIGN KEY (vulnerability_finding_evidence_supporting_message_id) REFERENCES vulnerability_finding_evidence_supporting_messages(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY merge_request_cleanup_schedules
ADD CONSTRAINT fk_rails_92dd0e705c FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
@@ -31333,18 +31289,12 @@ ALTER TABLE ONLY operations_strategies_user_lists
ALTER TABLE ONLY issue_tracker_data
ADD CONSTRAINT fk_rails_ccc0840427 FOREIGN KEY (service_id) REFERENCES integrations(id) ON DELETE CASCADE;
-ALTER TABLE ONLY vulnerability_finding_evidence_headers
- ADD CONSTRAINT fk_rails_ce7f121a03 FOREIGN KEY (vulnerability_finding_evidence_request_id) REFERENCES vulnerability_finding_evidence_requests(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY resource_milestone_events
ADD CONSTRAINT fk_rails_cedf8cce4d FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL;
ALTER TABLE ONLY resource_iteration_events
ADD CONSTRAINT fk_rails_cee126f66c FOREIGN KEY (iteration_id) REFERENCES sprints(id) ON DELETE CASCADE;
-ALTER TABLE ONLY vulnerability_finding_evidence_requests
- ADD CONSTRAINT fk_rails_cf0f278cb0 FOREIGN KEY (vulnerability_finding_evidence_supporting_message_id) REFERENCES vulnerability_finding_evidence_supporting_messages(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY upload_states
ADD CONSTRAINT fk_rails_d00f153613 FOREIGN KEY (upload_id) REFERENCES uploads(id) ON DELETE CASCADE;
@@ -31399,9 +31349,6 @@ ALTER TABLE ONLY issues_prometheus_alert_events
ALTER TABLE ONLY board_user_preferences
ADD CONSTRAINT fk_rails_dbebdaa8fe FOREIGN KEY (board_id) REFERENCES boards(id) ON DELETE CASCADE;
-ALTER TABLE ONLY ci_running_builds
- ADD CONSTRAINT fk_rails_dc1d0801e8 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY vulnerability_occurrence_pipelines
ADD CONSTRAINT fk_rails_dc3ae04693 FOREIGN KEY (occurrence_id) REFERENCES vulnerability_occurrences(id) ON DELETE CASCADE;
@@ -31429,9 +31376,6 @@ ALTER TABLE ONLY analytics_cycle_analytics_group_stages
ALTER TABLE ONLY bulk_import_export_uploads
ADD CONSTRAINT fk_rails_dfbfb45eca FOREIGN KEY (export_id) REFERENCES bulk_import_exports(id) ON DELETE CASCADE;
-ALTER TABLE ONLY ci_minutes_additional_packs
- ADD CONSTRAINT fk_rails_e0e0c4e4b1 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY label_priorities
ADD CONSTRAINT fk_rails_e161058b0f FOREIGN KEY (label_id) REFERENCES labels(id) ON DELETE CASCADE;
@@ -31471,9 +31415,6 @@ ALTER TABLE ONLY approval_merge_request_rule_sources
ALTER TABLE ONLY prometheus_alerts
ADD CONSTRAINT fk_rails_e6351447ec FOREIGN KEY (prometheus_metric_id) REFERENCES prometheus_metrics(id) ON DELETE CASCADE;
-ALTER TABLE ONLY requirements_management_test_reports
- ADD CONSTRAINT fk_rails_e67d085910 FOREIGN KEY (build_id) REFERENCES ci_builds(id) ON DELETE SET NULL;
-
ALTER TABLE ONLY merge_request_metrics
ADD CONSTRAINT fk_rails_e6d7c24d1b FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
@@ -31501,9 +31442,6 @@ ALTER TABLE ONLY vulnerability_issue_links
ALTER TABLE ONLY merge_request_blocks
ADD CONSTRAINT fk_rails_e9387863bc FOREIGN KEY (blocking_merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
-ALTER TABLE ONLY vulnerability_finding_evidence_sources
- ADD CONSTRAINT fk_rails_e9761bed4c FOREIGN KEY (vulnerability_finding_evidence_id) REFERENCES vulnerability_finding_evidences(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY protected_branch_unprotect_access_levels
ADD CONSTRAINT fk_rails_e9eb8dc025 FOREIGN KEY (protected_branch_id) REFERENCES protected_branches(id) ON DELETE CASCADE;
@@ -31594,15 +31532,15 @@ ALTER TABLE ONLY internal_ids
ALTER TABLE ONLY issues_self_managed_prometheus_alert_events
ADD CONSTRAINT fk_rails_f7db2d72eb FOREIGN KEY (self_managed_prometheus_alert_event_id) REFERENCES self_managed_prometheus_alert_events(id) ON DELETE CASCADE;
+ALTER TABLE ONLY security_trainings
+ ADD CONSTRAINT fk_rails_f80240fae0 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY merge_requests_closing_issues
ADD CONSTRAINT fk_rails_f8540692be FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE;
ALTER TABLE ONLY merge_trains
ADD CONSTRAINT fk_rails_f90820cb08 FOREIGN KEY (pipeline_id) REFERENCES ci_pipelines(id) ON DELETE SET NULL;
-ALTER TABLE ONLY ci_runner_namespaces
- ADD CONSTRAINT fk_rails_f9d9ed3308 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY banned_users
ADD CONSTRAINT fk_rails_fa5bb598e5 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
diff --git a/doc/.vale/gitlab/ReadingLevel.yml b/doc/.vale/gitlab/ReadingLevel.yml
index 2e78c3ef36c..cd7597ee8dc 100644
--- a/doc/.vale/gitlab/ReadingLevel.yml
+++ b/doc/.vale/gitlab/ReadingLevel.yml
@@ -3,11 +3,11 @@
#
# Checks the Flesch-Kincaid reading level.
#
-# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
-extends: readability
-message: "Grade level (%s) is high. To lower the score, use shorter sentences and words."
+# https://docs.errata.ai/vale/styles#metric
+extends: metric
+message: "The grade level - %s - refers to how hard the content is to understand. Aim for 8th grade or lower by using shorter sentences and words."
link: https://docs.gitlab.com/ee/development/documentation/testing.html#vale-readability-score
level: suggestion
-grade: 8
-metrics:
- - Flesch-Kincaid
+formula: |
+ (0.39 * (words / sentences)) + (11.8 * (syllables / words)) - 15.59
+condition: "> 1"
diff --git a/doc/.vale/gitlab/SubstitutionWarning.yml b/doc/.vale/gitlab/SubstitutionWarning.yml
index fefc0f85cf4..8000328a20c 100644
--- a/doc/.vale/gitlab/SubstitutionWarning.yml
+++ b/doc/.vale/gitlab/SubstitutionWarning.yml
@@ -11,6 +11,7 @@ link: https://about.gitlab.com/handbook/communication/#top-misused-terms
level: warning
ignorecase: true
swap:
+ click: select
code base: codebase
config: configuration
distro: distribution
diff --git a/doc/.vale/gitlab/Uppercase.yml b/doc/.vale/gitlab/Uppercase.yml
index ae011748748..c9021dc862e 100644
--- a/doc/.vale/gitlab/Uppercase.yml
+++ b/doc/.vale/gitlab/Uppercase.yml
@@ -53,6 +53,7 @@ exceptions:
- EOL
- EXIF
- FAQ
+ - FIDO
- FIFO
- FIPS
- FLAG
@@ -179,6 +180,7 @@ exceptions:
- TLS
- TODO
- TOML
+ - TOTP
- TTL
- UID
- UDP
diff --git a/doc/.vale/gitlab/spelling-exceptions.txt b/doc/.vale/gitlab/spelling-exceptions.txt
index 5ed8dc92249..98254c2259b 100644
--- a/doc/.vale/gitlab/spelling-exceptions.txt
+++ b/doc/.vale/gitlab/spelling-exceptions.txt
@@ -9,6 +9,7 @@ allowlist
allowlisted
allowlisting
allowlists
+AlmaLinux
anonymization
anonymized
Ansible
@@ -220,6 +221,7 @@ Fluentd
Flycheck
Forgerock
formatters
+Fortinet
Fugit
fuzzer
Gantt
@@ -364,7 +366,7 @@ Microsoft
middleware
middlewares
migratus
-Minikube
+minikube
MinIO
misconfiguration
misconfigurations
diff --git a/doc/.vale/vale.tmpl b/doc/.vale/vale.tmpl
index 36dfbd6b778..8a6c6e5157d 100644
--- a/doc/.vale/vale.tmpl
+++ b/doc/.vale/vale.tmpl
@@ -48,4 +48,4 @@
{{end -}}
{{end -}}
-{{- $e}} {{"errors" | red}}, {{$w}} {{"warnings" | yellow}}, and {{$s}} {{"suggestions" | blue}} found in {{$f}} {{$f | int | plural "file" "files"}}.
+{{- $e}} {{"errors" | red}}, {{$w}} {{"warnings" | yellow}}, and {{$s}} {{"suggestions" | blue}} found.
diff --git a/doc/administration/audit_event_streaming.md b/doc/administration/audit_event_streaming.md
index cee6cddbbf0..eac54416924 100644
--- a/doc/administration/audit_event_streaming.md
+++ b/doc/administration/audit_event_streaming.md
@@ -6,11 +6,11 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Audit event streaming **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332747) in GitLab 14.5 [with a flag](../administration/feature_flags.md) named `ff_external_audit_events_namespace`. Disabled by default.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332747) in GitLab 14.5 [with a flag](../administration/feature_flags.md) named `ff_external_audit_events_namespace`. Disabled by default.
+> - [Enabled on GitLab.com and by default on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/338939) in GitLab 14.7.
FLAG:
-On self-managed GitLab, by default this feature is not available. To make it available per group, ask an administrator to [enable the feature flag](../administration/feature_flags.md) named `ff_external_audit_events_namespace`. On GitLab.com, this feature is not available.
-You should not use this feature for production environments.
+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 `ff_external_audit_events_namespace`. On GitLab.com, this feature is available.
Event streaming allows owners of top-level groups to set an HTTP endpoint to receive **all** audit events about the group, and its
subgroups and projects.
diff --git a/doc/administration/auth/atlassian.md b/doc/administration/auth/atlassian.md
index 5fa10c4c119..08d07b13e22 100644
--- a/doc/administration/auth/atlassian.md
+++ b/doc/administration/auth/atlassian.md
@@ -1,7 +1,7 @@
---
type: reference
stage: Manage
-group: Access
+group: Authentication & 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/authentiq.md b/doc/administration/auth/authentiq.md
index 4220e552196..23735b75991 100644
--- a/doc/administration/auth/authentiq.md
+++ b/doc/administration/auth/authentiq.md
@@ -1,7 +1,7 @@
---
type: reference
stage: Manage
-group: Access
+group: Authentication & 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/cognito.md b/doc/administration/auth/cognito.md
index 718a2919ed0..2509bbb73d7 100644
--- a/doc/administration/auth/cognito.md
+++ b/doc/administration/auth/cognito.md
@@ -1,7 +1,7 @@
---
type: concepts, howto
stage: Manage
-group: Access
+group: Authentication & 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/crowd.md b/doc/administration/auth/crowd.md
index 265bba8a9b1..9a5f6b0a642 100644
--- a/doc/administration/auth/crowd.md
+++ b/doc/administration/auth/crowd.md
@@ -1,7 +1,7 @@
---
type: reference
stage: Manage
-group: Access
+group: Authentication & 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/index.md b/doc/administration/auth/index.md
index 959c5218554..d469988e719 100644
--- a/doc/administration/auth/index.md
+++ b/doc/administration/auth/index.md
@@ -2,7 +2,7 @@
comments: false
type: index
stage: Manage
-group: Access
+group: Authentication & 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/jwt.md b/doc/administration/auth/jwt.md
index 9298b04cbc1..ac2f699dd5d 100644
--- a/doc/administration/auth/jwt.md
+++ b/doc/administration/auth/jwt.md
@@ -1,7 +1,7 @@
---
type: reference
stage: Manage
-group: Access
+group: Authentication & 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/ldap/google_secure_ldap.md b/doc/administration/auth/ldap/google_secure_ldap.md
index 69f0bfdce4c..6b8e699e861 100644
--- a/doc/administration/auth/ldap/google_secure_ldap.md
+++ b/doc/administration/auth/ldap/google_secure_ldap.md
@@ -1,7 +1,7 @@
---
type: reference
stage: Manage
-group: Access
+group: Authentication & 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/ldap/index.md b/doc/administration/auth/ldap/index.md
index f551c362784..b773281b216 100644
--- a/doc/administration/auth/ldap/index.md
+++ b/doc/administration/auth/ldap/index.md
@@ -1,7 +1,7 @@
---
type: reference
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -21,7 +21,7 @@ This integration works with most LDAP-compliant directory servers, including:
Users added through LDAP:
-- Take a [licensed seat](../../../subscriptions/self_managed/index.md#billable-users).
+- Usually use a [licensed seat](../../../subscriptions/self_managed/index.md#billable-users).
- Can authenticate with Git using either their GitLab username or their email and LDAP password,
even if password authentication for Git
[is disabled](../../../user/admin_area/settings/sign_in_restrictions.md#password-authentication-enabled).
@@ -153,13 +153,22 @@ production:
### Basic configuration settings
+> `hosts` configuration setting [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/139) in GitLab 14.7.
+
+You can configure either:
+
+- A single LDAP server using `host` and `port`.
+- Many LDAP servers using `hosts`. This setting takes precedence over `host` and `port`. GitLab attempts to use the
+ LDAP servers in the order specified, and the first reachable LDAP server is used.
+
These configuration settings are available:
| Setting | Description | Required | Examples |
|--------------------|-------------|----------|----------|
| `label` | A human-friendly name for your LDAP server. It is displayed on your sign-in page. | **{check-circle}** Yes | `'Paris'` or `'Acme, Ltd.'` |
-| `host` | IP address or domain name of your LDAP server. | **{check-circle}** Yes | `'ldap.mydomain.com'` |
-| `port` | The port to connect with on your LDAP server. Always an integer, not a string. | **{check-circle}** Yes | `389` or `636` (for SSL) |
+| `host` | IP address or domain name of your LDAP server. Ignored when `hosts` is defined. | **{check-circle}** Yes | `'ldap.mydomain.com'` |
+| `port` | The port to connect with on your LDAP server. Always an integer, not a string. Ignored when `hosts` is defined. | **{check-circle}** Yes | `389` or `636` (for SSL) |
+| `hosts` (GitLab 14.7 and later) | An array of host and port pairs to open connections. | **{dotted-circle}** No | `[['ldap1.mydomain.com', 636], ['ldap2.mydomain.com', 636]]` |
| `uid` | LDAP attribute for username. Should be the attribute, not the value that maps to the `uid`. | **{check-circle}** Yes | `'sAMAccountName'` or `'uid'` or `'userPrincipalName'` |
| `bind_dn` | The full DN of the user you bind with. | **{dotted-circle}** No | `'america\momo'` or `'CN=Gitlab,OU=Users,DC=domain,DC=com'` |
| `password` | The password of the bind user. | **{dotted-circle}** No | `'your_great_password'` |
diff --git a/doc/administration/auth/ldap/ldap-troubleshooting.md b/doc/administration/auth/ldap/ldap-troubleshooting.md
index 63e4490e332..97a626f4a40 100644
--- a/doc/administration/auth/ldap/ldap-troubleshooting.md
+++ b/doc/administration/auth/ldap/ldap-troubleshooting.md
@@ -1,7 +1,7 @@
---
type: reference
stage: Manage
-group: Access
+group: Authentication & 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/ldap/ldap_synchronization.md b/doc/administration/auth/ldap/ldap_synchronization.md
index 8ccd8fecbcf..3329ea8e9cc 100644
--- a/doc/administration/auth/ldap/ldap_synchronization.md
+++ b/doc/administration/auth/ldap/ldap_synchronization.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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/oidc.md b/doc/administration/auth/oidc.md
index 7ab1f2f5feb..efe4b7440ee 100644
--- a/doc/administration/auth/oidc.md
+++ b/doc/administration/auth/oidc.md
@@ -1,7 +1,7 @@
---
type: reference
stage: Manage
-group: Access
+group: Authentication & 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/smartcard.md b/doc/administration/auth/smartcard.md
index d79837776b2..f77d3a36a7b 100644
--- a/doc/administration/auth/smartcard.md
+++ b/doc/administration/auth/smartcard.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
diff --git a/doc/administration/clusters/kas.md b/doc/administration/clusters/kas.md
index b5c0a6ee76a..ba0d7280b74 100644
--- a/doc/administration/clusters/kas.md
+++ b/doc/administration/clusters/kas.md
@@ -6,13 +6,13 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Install the GitLab Agent Server (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`.
> [Moved](https://gitlab.com/groups/gitlab-org/-/epics/6290) from GitLab Premium to GitLab Free in 14.5.
The GitLab Agent Server (KAS) is a GitLab backend service dedicated to
managing the [GitLab Agent](../../user/clusters/agent/index.md).
The KAS is already installed and available in GitLab.com under `wss://kas.gitlab.com`.
-See [how to use GitLab.com's KAS](../../user/clusters/agent/install/index.md#set-up-the-agent-server).
This document describes how to install a KAS for GitLab self-managed instances.
## Installation options
diff --git a/doc/administration/compliance.md b/doc/administration/compliance.md
index 7cecc0c30fd..843d5d0930a 100644
--- a/doc/administration/compliance.md
+++ b/doc/administration/compliance.md
@@ -6,37 +6,49 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Compliance features **(FREE)**
-These GitLab features can help ensure that your GitLab instance meets common compliance standards. For more information
-about compliance management, see the compliance management [solutions page](https://about.gitlab.com/solutions/compliance/).
+These GitLab features can help ensure that your GitLab instance meets common
+compliance standards. For more information about compliance management, see the
+compliance management [solutions page](https://about.gitlab.com/solutions/compliance/).
-The [security features](../security/index.md) in GitLab may also help you meet relevant compliance standards.
+The [security features](../security/index.md) in GitLab may also help you meet
+relevant compliance standards.
## Policy management
-Organizations have unique policy requirements, either due to organizational standards or mandates from regulatory bodies.
-The following features help you define rules and policies to adhere to workflow requirements, separation of duties, and
-secure supply chain best practices:
+Organizations have unique policy requirements, either due to organizational
+standards or mandates from regulatory bodies. The following features help you
+define rules and policies to adhere to workflow requirements, separation of duties,
+and secure supply chain best practices:
-- [**Credentials inventory**](../user/admin_area/credentials_inventory.md) (for instances): With a credentials inventory,
- GitLab administrators can keep track of the credentials used by all of the users in their GitLab instance.
-- [**Granular user roles and flexible permissions**](../user/permissions.md) (for instances, groups, and projects): Manage
- access and permissions with five different user roles and settings for external users. Set permissions according to people's
- role, rather than either read or write access to a repository. Don't share the source code with people that only need
- access to the issue tracker.
-- [**Merge request approvals**](../user/project/merge_requests/approvals/index.md) (for instances, groups, and projects):
- Configure approvals required for merge requests.
-- [**Push rules**](../push_rules/push_rules.md) (for instances, groups, and projects): Control pushes to your
- repositories.
+- [**Credentials inventory**](../user/admin_area/credentials_inventory.md) (for
+ instances): With a credentials inventory, GitLab administrators can keep track
+ of the credentials used by all of the users in their GitLab instance.
+- [**Granular user roles and flexible permissions**](../user/permissions.md)
+ (for instances, groups, and projects): Manage access and permissions with five
+ different user roles and settings for external users. Set permissions according
+ to people's role, rather than either read or write access to a repository. Don't
+ share the source code with people that only need access to the issue tracker.
+- [**Merge request approvals**](../user/project/merge_requests/approvals/index.md)
+ (for instances, groups, and projects): Configure approvals required for
+ merge requests.
+- [**Push rules**](../push_rules/push_rules.md) (for instances, groups, and
+ projects): Control pushes to your repositories.
- Separation of duties using [**protected branches**](../user/project/protected_branches.md#require-code-owner-approval-on-a-protected-branch)
- and [**custom CI/CD configuration paths**](../ci/pipelines/settings.md#specify-a-custom-cicd-configuration-file) (for projects):
- Users can leverage the GitLab cross-project YAML configurations to define deployers of code and developers of code.
- See how to use this setup to define these roles in:
+ and [**custom CI/CD configuration paths**](../ci/pipelines/settings.md#specify-a-custom-cicd-configuration-file) (for projects): Users can leverage the GitLab cross-project YAML configurations
+ to define deployers of code and developers of code. See how to use this setup
+ to define these roles in:
- The [Separation of Duties deploy project](https://gitlab.com/guided-explorations/separation-of-duties-deploy/blob/master/README.md).
- The [Separation of Duties project](https://gitlab.com/guided-explorations/separation-of-duties/blob/master/README.md).
## Compliant workflow automation
-It is important for compliance teams to be confident that their controls and requirements are set up correctly, but also that they _stay_ set up correctly. One way of doing this is manually checking settings periodically, but this is error prone and time consuming. A better approach is to use single-source-of-truth settings and automation to ensure that whatever a compliance team has configured, stays configured and working correctly. These features can help you automate compliance:
+It is important for compliance teams to be confident that their controls and
+requirements are set up correctly, but also that they _stay_ set up correctly.
+One way of doing this is manually checking settings periodically, but this is
+error prone and time consuming. A better approach is to use single-source-of-truth
+settings and automation to ensure that whatever a compliance team has configured,
+stays configured and working correctly. These features can help you automate
+compliance:
- [**Compliance frameworks**](../user/project/settings/index.md#compliance-frameworks) (for groups): Create a custom
compliance framework at the group level to describe the type of compliance requirements any child project needs to follow.
@@ -45,42 +57,59 @@ It is important for compliance teams to be confident that their controls and req
## Audit management
-An important part of any compliance program is being able to go back and understand what happened, when
-it happened, and who was responsible. This is useful in audit situations as well as for understanding
-the root cause of issues when they occur. It is useful to have both low-level, raw lists of audit data
-as well as high-level, summary lists of audit data. Between these two, compliance teams can quickly
-identify if problems exist and then drill down into the specifics of those issues. These features can help provide visibility into GitLab and audit what is happening:
+An important part of any compliance program is being able to go back and understand
+what happened, when it happened, and who was responsible. This is useful in audit
+situations as well as for understanding the root cause of issues when they occur.
+It is useful to have both low-level, raw lists of audit data as well as high-level,
+summary lists of audit data. Between these two, compliance teams can quickly
+identify if problems exist and then drill down into the specifics of those issues.
+These features can help provide visibility into GitLab and audit what is happening:
-- [**Audit events**](audit_events.md) (for instances, groups, and projects): To maintain the integrity of your code,
- audit events give administrators the ability to view any modifications made within the GitLab
- server in an advanced audit events system, so you can control, analyze, and track every change.
-- [**Auditor users**](auditor_users.md) (for instances): Auditor users are users who are given read-only access to all
- projects, groups, and other resources on the GitLab instance.
-- [**Compliance report**](../user/compliance/compliance_report/index.md) (for groups): Quickly get visibility into the
- compliance posture of your organization.
+- [**Audit events**](audit_events.md) (for instances, groups, and projects): To
+ maintain the integrity of your code, audit events give administrators the
+ ability to view any modifications made within the GitLab server in an advanced
+ audit events system, so you can control, analyze, and track every change.
+- [**Audit reports**](audit_reports.md) (for instances, groups, and projects):
+ Create and access reports based on the audit events that have occurred. Use
+ pre-built GitLab reports or the API to build your own.
+- [**Auditor users**](auditor_users.md) (for instances): Auditor users are users
+ who are given read-only access to all projects, groups, and other resources on
+ the GitLab instance.
+- [**Compliance report**](../user/compliance/compliance_report/index.md) (for
+ groups): Quickly get visibility into the compliance posture of your organization.
## Other compliance features
These features can also help with compliance requirements:
-- [**Email all users of a project, group, or entire server**](../tools/email.md) (for instances): An administrator can
- email groups of users based on project or group membership, or email everyone using the GitLab instance. These emails
+- [**Email all users of a project, group, or entire server**](../tools/email.md)
+ (for instances): An administrator can email groups of users based on project
+ or group membership, or email everyone using the GitLab instance. These emails
are great for scheduled maintenance or upgrades.
-- [**Enforce ToS acceptance**](../user/admin_area/settings/terms.md) (for instances): Enforce your users accepting new
- terms of service by blocking GitLab traffic.
-- [**External Status Checks**](../user/project/merge_requests/status_checks.md) (for projects): Interface with third-party
- systems you already use during development to ensure you remain compliant.
-- [**Generate reports on permission levels of users**](../user/admin_area/index.md#user-permission-export) (for
- instances): Administrators can generate a report listing all users' access permissions for groups and projects in the
- instance.
-- [**Lock project membership to group**](../user/group/index.md#prevent-members-from-being-added-to-projects-in-a-group) (for
- groups): Group owners can prevent new members from being added to projects within a group.
-- [**LDAP group sync**](auth/ldap/ldap_synchronization.md#group-sync) (for instances): Gives administrators the ability
- to automatically sync groups and manage SSH keys, permissions, and authentication, so you can focus on building your
- product, not configuring your tools.
-- [**LDAP group sync filters**](auth/ldap/ldap_synchronization.md#group-sync) (for instances): Gives more flexibility to
- synchronize with LDAP based on filters, meaning you can leverage LDAP attributes to map GitLab permissions.
+- [**Enforce ToS acceptance**](../user/admin_area/settings/terms.md) (for
+ instances): Enforce your users accepting new terms of service by blocking GitLab
+ traffic.
+- [**External Status Checks**](../user/project/merge_requests/status_checks.md)
+ (for projects): Interface with third-party systems you already use during
+ development to ensure you remain compliant.
+- [**Generate reports on permission levels of users**](../user/admin_area/index.md#user-permission-export)
+ (for instances): Administrators can generate a report listing all users' access
+ permissions for groups and projects in the instance.
+- [**License compliance**](../user/compliance/license_compliance/index.md) (for
+ projects): Search dependencies for their licenses. This lets you determine if
+ the licenses of your project's dependencies are compatible with your project's
+ license.
+- [**Lock project membership to group**](../user/group/index.md#prevent-members-from-being-added-to-projects-in-a-group)
+ (for groups): Group owners can prevent new members from being added to projects
+ within a group.
+- [**LDAP group sync**](auth/ldap/ldap_synchronization.md#group-sync) (for
+ instances): Gives administrators the ability to automatically sync groups and
+ manage SSH keys, permissions, and authentication, so you can focus on building
+ your product, not configuring your tools.
+- [**LDAP group sync filters**](auth/ldap/ldap_synchronization.md#group-sync)
+ (for instances): Gives more flexibility to synchronize with LDAP based on
+ filters, meaning you can leverage LDAP attributes to map GitLab permissions.
- [**Omnibus GitLab package supports log forwarding**](https://docs.gitlab.com/omnibus/settings/logs.html#udp-log-forwarding)
(for instances): Forward your logs to a central system.
-- [**Restrict SSH Keys**](../security/ssh_keys_restrictions.md) (for instances): Control the technology and key length
- of SSH keys used to access GitLab.
+- [**Restrict SSH Keys**](../security/ssh_keys_restrictions.md) (for instances):
+ Control the technology and key length of SSH keys used to access GitLab.
diff --git a/doc/administration/configure.md b/doc/administration/configure.md
index 822acc1a74e..e42eb632f14 100644
--- a/doc/administration/configure.md
+++ b/doc/administration/configure.md
@@ -15,7 +15,7 @@ Customize and configure your self-managed GitLab installation. Here are some qui
- [Geo](geo/index.md)
- [Packages](packages/index.md)
-The following tables are intended to guide you to choose the right combination of capabilties based on your requirements. It is common to want the most
+The following tables are intended to guide you to choose the right combination of capabilities based on your requirements. It is common to want the most
available, quickly recoverable, highly performant and fully data resilient solution. However, there are tradeoffs.
The tables lists features on the left and provides their capabilities to the right along with known trade-offs.
diff --git a/doc/administration/docs_self_host.md b/doc/administration/docs_self_host.md
new file mode 100644
index 00000000000..007055b5de7
--- /dev/null
+++ b/doc/administration/docs_self_host.md
@@ -0,0 +1,131 @@
+---
+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
+---
+
+# How to self-host the docs site **(FREE SELF)**
+
+If you have a self-managed instance of GitLab, you may not be able to access the
+product documentation as hosted on `docs.gitlab.com` from your GitLab instance.
+
+Be aware of the following items if you self-host the product documentation:
+
+- You must host the product documentation site under a subdirectory that matches
+ your installed GitLab version (for example, `14.5/`). The
+ [Docker images](https://gitlab.com/gitlab-org/gitlab-docs/container_registry/631635)
+ hosted by the GitLab Docs team provide this by default. We use a
+ [script](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/2995d1378175803b22fb8806ba77adf63e79f32c/scripts/normalize-links.sh#L28-82)
+ to normalize the links and prefix them with the respective version.
+- The version dropdown will display additional versions that don't exist, selecting
+ those versions will display a 404 Not Found page.
+- Results when using the search box will display results from `docs.gitlab.com`
+ and not the local documentation.
+- When you use the Docker images to serve the product documentation site, by
+ default the landing page redirects to the respective version (for example, `/14.5/`),
+ which causes the landing page <https://docs.gitlab.com> to not be displayed.
+
+## Documentation self-hosting options
+
+You can self-host the GitLab product documentation locally using one of these
+methods:
+
+- Docker
+- GitLab Pages
+- From your own webserver
+
+The examples on this page are based on GitLab 14.5.
+
+### Self-host the product documentation with Docker
+
+The Docker images use a built-in webserver listening on port `4000`, so you need
+to expose that.
+
+In the server that you host GitLab, or any other server that your GitLab instance
+can talk to, you can use Docker to pull the docs site:
+
+```shell
+docker run -it --rm -p 4000:4000 registry.gitlab.com/gitlab-org/gitlab-docs:14.5
+```
+
+If you use [Docker compose](../install/docker.md#install-gitlab-using-docker-compose)
+to host your GitLab instance, add the following to `docker-compose.yaml`:
+
+```yaml
+version: '3.6'
+services:
+ docs:
+ image: registry.gitlab.com/gitlab-org/gitlab-docs:14.5
+ hostname: 'https://gitlab.example.com'
+ ports:
+ - '4000:4000'
+```
+
+### Self-host the product documentation with GitLab Pages
+
+You use GitLab Pages to host the GitLab product documentation locally.
+
+Prerequisite:
+
+- The Pages site URL must not use a subfolder. Due to the nature of how the docs
+ site is pre-compiled, the CSS and JavaScript files are relative to the
+ main domain or subdomain. For example, URLs like `https://example.com/docs/`
+ are not supported.
+
+To host the product documentation site with GitLab Pages:
+
+1. [Create a new blank project](../user/project/working_with_projects.md#create-a-blank-project).
+1. Create a new or edit your existing `.gitlab-ci.yml` file, and add the following
+ `pages` job, while ensuring the version is the same as your GitLab installation:
+
+ ```yaml
+ image: registry.gitlab.com/gitlab-org/gitlab-docs:14.5
+ pages:
+ script:
+ - mkdir public
+ - cp -a /usr/share/nginx/html/* public/
+ artifacts:
+ paths:
+ - public
+ ```
+
+1. Optional. Set the GitLab Pages domain name. Depending on the type of the
+ GitLab Pages website, you have two options:
+
+ | Type of website | [Default domain](../user/project/pages/getting_started_part_one.md#gitlab-pages-default-domain-names) | [Custom domain](../user/project/pages/custom_domains_ssl_tls_certification/index.md) |
+ |-------------------------|----------------|---------------|
+ | [Project website](../user/project/pages/getting_started_part_one.md#project-website-examples) | Not supported | Supported |
+ | [User or group website](../user/project/pages/getting_started_part_one.md#user-and-group-website-examples) | Supported | Supported |
+
+### Self-host the product documentation on your own webserver
+
+Because the product documentation site is static, you can grab the directory from
+the container (in `/usr/share/nginx/html`) and use your own web server to host
+it wherever you want.
+
+Use the following commands, and replace `<destination>` with the directory where the
+documentation files will be copied to:
+
+```shell
+docker create -it --name gitlab-docs registry.gitlab.com/gitlab-org/gitlab-docs:14.5
+docker cp gitlab-docs:/usr/share/nginx/html <destination>
+docker rm -f gitlab-docs
+```
+
+## Redirect the `/help` links to the new docs page
+
+After your local product documentation site is running, [redirect the help
+links](../user/admin_area/settings/help_page.md#redirect-help-pages) in the GitLab
+application to your local site.
+
+Be sure to use the fully qualified domain name as the docs URL. For example, if you
+used the [Docker method](#self-host-the-product-documentation-with-docker), enter `http://0.0.0.0:4000`.
+
+You don't need to append the version, as GitLab will detect it and append it to
+any documentation URL requests, as needed. For example, if your GitLab version is
+14.5, the GitLab Docs URL becomes `http://0.0.0.0:4000/14.5/`. The link
+inside GitLab displays as `<instance_url>/help/user/admin_area/settings/help_page#destination-requirements`,
+but when you select it, you are redirected to
+`http://0.0.0.0:4000/14.5/ee/user/admin_area/settings/help_page/#destination-requirements`.
+
+To test the setting, select a **Learn more** link within the GitLab application.
diff --git a/doc/administration/geo/disaster_recovery/background_verification.md b/doc/administration/geo/disaster_recovery/background_verification.md
index caa806c92c8..d7db48bb6cf 100644
--- a/doc/administration/geo/disaster_recovery/background_verification.md
+++ b/doc/administration/geo/disaster_recovery/background_verification.md
@@ -2,7 +2,6 @@
stage: Enablement
group: Geo
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: howto
---
# Automatic background verification **(PREMIUM SELF)**
@@ -89,8 +88,6 @@ in sync.
## Repository re-verification
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/8550) in GitLab 11.6.
-
Due to bugs or transient infrastructure failures, it is possible for Git
repositories to change unexpectedly without being marked for verification.
Geo constantly reverifies the repositories to ensure the integrity of the
diff --git a/doc/administration/geo/disaster_recovery/index.md b/doc/administration/geo/disaster_recovery/index.md
index bf28eb76ffd..f7367ef863b 100644
--- a/doc/administration/geo/disaster_recovery/index.md
+++ b/doc/administration/geo/disaster_recovery/index.md
@@ -2,7 +2,6 @@
stage: Enablement
group: Geo
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: howto
---
# Disaster Recovery (Geo) **(PREMIUM SELF)**
@@ -503,7 +502,7 @@ secondary domain, like changing Git remotes and API URLs.
This command uses the changed `external_url` configuration defined
in `/etc/gitlab/gitlab.rb`.
-1. For GitLab 11.11 through 12.7 only, you may need to update the **primary**
+1. For GitLab 12.0 through 12.7, you may need to update the **primary**
node's name in the database. This bug has been fixed in GitLab 12.8.
To determine if you need to do this, search for the
@@ -672,7 +671,7 @@ Data that was created on the primary while the secondary was paused is lost.
If you are running GitLab 14.5 and later:
-1. SSH to every Sidekiq, PostgresSQL, and Gitaly node in the **secondary** site and run one of the following commands:
+1. For each node outside of the **secondary** Kubernetes cluster using Omnibus such as PostgreSQL or Gitaly, SSH into the node and run one of the following commands:
- To promote the secondary node to primary:
@@ -686,19 +685,17 @@ If you are running GitLab 14.5 and later:
sudo gitlab-ctl geo promote --force
```
-1. SSH into each Rails node on your **secondary** site and run one of the following commands:
+1. Find the `toolbox` pod:
- - To promote the secondary node to primary:
-
- ```shell
- sudo gitlab-ctl geo promote
- ```
+ ```shell
+ kubectl --namespace gitlab get pods -lapp=toolbox
+ ```
- - To promote the secondary node to primary **without any further confirmation**:
+1. Promote the secondary:
- ```shell
- sudo gitlab-ctl geo promote --force
- ```
+ ```shell
+ kubectl --namespace gitlab exec -ti gitlab-geo-toolbox-XXX -- gitlab-rake geo:set_secondary_as_primary
+ ```
If you are running GitLab 14.4 and earlier:
@@ -709,8 +706,6 @@ If you are running GitLab 14.4 and earlier:
sudo gitlab-ctl promote-db
```
- In GitLab 12.8 and earlier, see [Message: `sudo: gitlab-pg-ctl: command not found`](../replication/troubleshooting.md#message-sudo-gitlab-pg-ctl-command-not-found).
-
1. Edit `/etc/gitlab/gitlab.rb` on the database node in the **secondary** site to
reflect its new status as **primary** by removing any lines that enabled the
`geo_secondary_role`:
diff --git a/doc/administration/geo/index.md b/doc/administration/geo/index.md
index 2cb1a424ce8..b5eb0ba5841 100644
--- a/doc/administration/geo/index.md
+++ b/doc/administration/geo/index.md
@@ -25,7 +25,8 @@ For a video introduction to Geo, see [Introduction to GitLab Geo - GitLab Featur
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).
-Geo uses a set of defined terms that is described in the [Geo Glossary](glossary.md), please familiarize yourself with those terms.
+Geo uses a set of defined terms that are described in the [Geo Glossary](glossary.md).
+Be sure to familiarize yourself with those terms.
## Use cases
@@ -119,7 +120,8 @@ The following are required to run Geo:
The following operating systems are known to ship with a current version of OpenSSH:
- [CentOS](https://www.centos.org) 7.4 or later
- [Ubuntu](https://ubuntu.com) 16.04 or later
-- PostgreSQL 12 or later with [Streaming Replication](https://wiki.postgresql.org/wiki/Streaming_Replication)
+- PostgreSQL 12 with [Streaming Replication](https://wiki.postgresql.org/wiki/Streaming_Replication)
+ - PostgreSQL 13 is not supported for Geo, see [epic 3832](https://gitlab.com/groups/gitlab-org/-/epics/3832)
- Git 2.9 or later
- Git-lfs 2.4.2 or later on the user side when using LFS
- All sites must run the same GitLab version.
diff --git a/doc/administration/geo/replication/configuration.md b/doc/administration/geo/replication/configuration.md
index 3cbde77903d..16b4848e6d3 100644
--- a/doc/administration/geo/replication/configuration.md
+++ b/doc/administration/geo/replication/configuration.md
@@ -199,20 +199,21 @@ keys must be manually replicated to the **secondary** site.
gitlab-ctl reconfigure
```
-1. On the top bar, select **Menu > Admin**.
-1. On the left sidebar, select **Geo > Sites**.
-1. Select **New site**.
+1. Navigate to the Primary Node GitLab Instance:
+ 1. On the top bar, select **Menu > Admin**.
+ 1. On the left sidebar, select **Geo > Sites**.
+ 1. Select **Add site**.
![Add secondary site](img/adding_a_secondary_v13_3.png)
-1. Fill in **Name** with the `gitlab_rails['geo_node_name']` in
+ 1. Fill in **Name** with the `gitlab_rails['geo_node_name']` in
`/etc/gitlab/gitlab.rb`. These values must always match *exactly*, character
for character.
-1. Fill in **URL** with the `external_url` in `/etc/gitlab/gitlab.rb`. These
+ 1. Fill in **URL** with the `external_url` in `/etc/gitlab/gitlab.rb`. These
values must always match, but it doesn't matter if one ends with a `/` and
the other doesn't.
-1. Optionally, choose which groups or storage shards should be replicated by the
+ 1. (Optional) Choose which groups or storage shards should be replicated by the
**secondary** site. Leave blank to replicate all. Read more in
[selective synchronization](#selective-synchronization).
-1. Select **Add site** to add the **secondary** site.
+ 1. Select **Save changes** to add the **secondary** site.
1. SSH into **each Rails, and Sidekiq node on your secondary** site and restart the services:
```shell
diff --git a/doc/administration/geo/replication/datatypes.md b/doc/administration/geo/replication/datatypes.md
index 31bc473d74b..0fa08dcc9e0 100644
--- a/doc/administration/geo/replication/datatypes.md
+++ b/doc/administration/geo/replication/datatypes.md
@@ -188,8 +188,8 @@ successfully, you must replicate their data using some other means.
|[Project repository](../../../user/project/repository/) | **Yes** (10.2) | **Yes** (10.7) | No | |
|[Project wiki repository](../../../user/project/wiki/) | **Yes** (10.2) | **Yes** (10.7) | No | |
|[Group wiki repository](../../../user/project/wiki/group.md) | [**Yes** (13.10)](https://gitlab.com/gitlab-org/gitlab/-/issues/208147) | No | No | Behind feature flag `geo_group_wiki_repository_replication`, enabled by default. |
-|[Uploads](../../uploads.md) | **Yes** (10.2) | **Yes** (14.6) | Via Object Storage provider if supported. Native Geo support (Beta). | Replication is behind the feature flag `geo_upload_replication`, enabled by default. Verification is behind the feature flag `geo_upload_verification` introduced and enabled by default in 14.6. |
-|[LFS objects](../../lfs/index.md) | **Yes** (10.2) | **Yes** (14.6) | Via Object Storage provider if supported. Native Geo support (Beta). | GitLab versions 11.11.x and 12.0.x are affected by [a bug that prevents any new LFS objects from replicating](https://gitlab.com/gitlab-org/gitlab/-/issues/32696).<br /><br />Replication is behind the feature flag `geo_lfs_object_replication`, enabled by default. Verification is behind the feature flag `geo_lfs_object_verification` introduced and enabled by default in 14.6. |
+|[Uploads](../../uploads.md) | **Yes** (10.2) | **Yes** (14.6) | Via Object Storage provider if supported. Native Geo support (Beta). | Replication is behind the feature flag `geo_upload_replication`, enabled by default. Verification was behind the feature flag `geo_upload_verification`, removed in 14.8. |
+|[LFS objects](../../lfs/index.md) | **Yes** (10.2) | **Yes** (14.6) | Via Object Storage provider if supported. Native Geo support (Beta). | GitLab versions 11.11.x and 12.0.x are affected by [a bug that prevents any new LFS objects from replicating](https://gitlab.com/gitlab-org/gitlab/-/issues/32696).<br /><br />Replication is behind the feature flag `geo_lfs_object_replication`, enabled by default. Verification was behind the feature flag `geo_lfs_object_verification`, removed in 14.7. |
|[Personal snippets](../../../user/snippets.md) | **Yes** (10.2) | **Yes** (10.2) | No | |
|[Project snippets](../../../user/snippets.md) | **Yes** (10.2) | **Yes** (10.2) | No | |
|[CI job artifacts](../../../ci/pipelines/job_artifacts.md) | **Yes** (10.4) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/8923) | Via Object Storage provider if supported. Native Geo support (Beta). | Verified only manually using [Integrity Check Rake Task](../../raketasks/check.md) on both sites and comparing the output between them. Job logs also verified on transfer. |
@@ -200,9 +200,9 @@ successfully, you must replicate their data using some other means.
|[Project designs repository](../../../user/project/issues/design_management.md) | **Yes** (12.7) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/32467) | No | Designs also require replication of LFS objects and Uploads. |
|[Package Registry](../../../user/packages/package_registry/index.md) | **Yes** (13.2) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. |
|[Versioned Terraform State](../../terraform_state.md) | **Yes** (13.5) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (13.12) | Via Object Storage provider if supported. Native Geo support (Beta). | Replication is behind the feature flag `geo_terraform_state_version_replication`, enabled by default. Verification was behind the feature flag `geo_terraform_state_version_verification`, which was removed in 14.0. |
-|[External merge request diffs](../../merge_request_diffs.md) | **Yes** (13.5) | **Yes** (14.6) | Via Object Storage provider if supported. Native Geo support (Beta). | Replication is behind the feature flag `geo_merge_request_diff_replication`, enabled by default. Verification is behind the feature flag `geo_merge_request_diff_verification`, enabled by default in 14.6.|
+|[External merge request diffs](../../merge_request_diffs.md) | **Yes** (13.5) | **Yes** (14.6) | Via Object Storage provider if supported. Native Geo support (Beta). | Replication is behind the feature flag `geo_merge_request_diff_replication`, enabled by default. Verification was behind the feature flag `geo_merge_request_diff_verification`, removed in 14.7.|
|[Versioned snippets](../../../user/snippets.md#versioned-snippets) | [**Yes** (13.7)](https://gitlab.com/groups/gitlab-org/-/epics/2809) | [**Yes** (14.2)](https://gitlab.com/groups/gitlab-org/-/epics/2810) | No | Verification was implemented behind the feature flag `geo_snippet_repository_verification` in 13.11, and the feature flag was removed in 14.2. |
-|[GitLab Pages](../../pages/index.md) | [**Yes** (14.3)](https://gitlab.com/groups/gitlab-org/-/epics/589) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (14.6) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_pages_deployment_replication`, enabled by default. Verification is behind the feature flag `geo_pages_deployment_verification`, enabled by default in 14.6. |
+|[GitLab Pages](../../pages/index.md) | [**Yes** (14.3)](https://gitlab.com/groups/gitlab-org/-/epics/589) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (14.6) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_pages_deployment_replication`, enabled by default. Verification was behind the feature flag `geo_pages_deployment_verification`, removed in 14.7. |
|[Server-side Git hooks](../../server_hooks.md) | [Not planned](https://gitlab.com/groups/gitlab-org/-/epics/1867) | No | No | Not planned because of current implementation complexity, low customer interest, and availability of alternatives to hooks. |
|[Elasticsearch integration](../../../integration/elasticsearch.md) | [Not planned](https://gitlab.com/gitlab-org/gitlab/-/issues/1186) | No | No | Not planned because further product discovery is required and Elasticsearch (ES) clusters can be rebuilt. Secondaries use the same ES cluster as the primary. |
|[Dependency proxy images](../../../user/packages/dependency_proxy/index.md) | [Not planned](https://gitlab.com/gitlab-org/gitlab/-/issues/259694) | No | No | Blocked by [Geo: Secondary Mimicry](https://gitlab.com/groups/gitlab-org/-/epics/1528). Replication of this cache is not needed for disaster recovery purposes because it can be recreated from external sources. |
diff --git a/doc/administration/geo/replication/faq.md b/doc/administration/geo/replication/faq.md
index e613a9b5670..12b3b382bf7 100644
--- a/doc/administration/geo/replication/faq.md
+++ b/doc/administration/geo/replication/faq.md
@@ -2,7 +2,6 @@
stage: Enablement
group: Geo
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: howto
---
# Geo Frequently Asked Questions **(PREMIUM SELF)**
@@ -54,7 +53,7 @@ For more details, see the [supported Geo data types](datatypes.md).
## Can I `git push` to a **secondary** site?
-Yes! Pushing directly to a **secondary** site (for both HTTP and SSH, including Git LFS) was [introduced](https://about.gitlab.com/releases/2018/09/22/gitlab-11-3-released/) in GitLab 11.3.
+Pushing directly to a **secondary** site (for both HTTP and SSH, including Git LFS) is supported.
## How long does it take to have a commit replicated to a **secondary** site?
diff --git a/doc/administration/geo/replication/geo_validation_tests.md b/doc/administration/geo/replication/geo_validation_tests.md
index a4c2f156216..ce1bd8a9d3c 100644
--- a/doc/administration/geo/replication/geo_validation_tests.md
+++ b/doc/administration/geo/replication/geo_validation_tests.md
@@ -2,7 +2,6 @@
stage: Enablement
group: Geo
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: howto
---
# Geo validation tests **(PREMIUM SELF)**
@@ -175,7 +174,7 @@ The following are PostgreSQL upgrade validation tests we performed.
[Test and validate PostgreSQL 10.0 upgrade for Geo](https://gitlab.com/gitlab-org/gitlab/-/issues/12092):
- Description: With the 12.0 release, GitLab required an upgrade to PostgreSQL 10.0. We tested
- various upgrade scenarios from GitLab 11.11.5 through to GitLab 12.1.8.
+ various upgrade scenarios up to GitLab 12.1.8.
- Outcome: Multiple issues were found when upgrading and addressed in follow-up issues.
- Follow up issues:
- [`gitlab-ctl` reconfigure fails on Redis node in multi-node Geo setup](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/4706).
diff --git a/doc/administration/geo/replication/troubleshooting.md b/doc/administration/geo/replication/troubleshooting.md
index 673d8388af1..a6ea41171a9 100644
--- a/doc/administration/geo/replication/troubleshooting.md
+++ b/doc/administration/geo/replication/troubleshooting.md
@@ -2,19 +2,18 @@
stage: Enablement
group: Geo
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: howto
---
# Troubleshooting Geo **(PREMIUM SELF)**
-Setting up Geo requires careful attention to details and sometimes it's easy to
+Setting up Geo requires careful attention to details, and sometimes it's easy to
miss a step.
Here is a list of steps you should take to attempt to fix problem:
-- Perform [basic troubleshooting](#basic-troubleshooting).
-- Fix any [replication errors](#fixing-replication-errors).
-- Fix any [common](#fixing-common-errors) errors.
+1. Perform [basic troubleshooting](#basic-troubleshooting).
+1. Fix any [replication errors](#fixing-replication-errors).
+1. Fix any [common](#fixing-common-errors) errors.
## Basic troubleshooting
@@ -41,11 +40,11 @@ to help identify if something is wrong:
![Geo health check](img/geo_site_health_v14_0.png)
-For information on how to resolve common errors reported from the UI, see
-[Fixing Common Errors](#fixing-common-errors).
+For information about how to resolve common error messages reported from the user interface,
+see [Fixing Common Errors](#fixing-common-errors).
-If the UI is not working, or you are unable to log in, you can run the Geo
-health check manually to get this information as well as a few more details.
+If the user interface is not working, or you are unable to sign in, you can run the Geo
+health check manually to get this information and a few more details.
#### Health check Rake task
@@ -173,124 +172,129 @@ HINT: Close open transactions soon to avoid wraparound problems.
You might also need to commit or roll back old prepared transactions, or drop stale replication slots.
```
-To fix this, do the following:
+To fix this:
1. [Connect to the primary database](https://docs.gitlab.com/omnibus/settings/database.html#connecting-to-the-bundled-postgresql-database).
+
1. Run `SELECT * FROM pg_replication_slots;`.
-1. Note the `slot_name` that reports `active` as `f` (false).
-1. Follow [all these steps to remove that Geo site](remove_geo_site.md).
+ Note the `slot_name` that reports `active` as `f` (false).
+
+1. Follow [the steps to remove that Geo site](remove_geo_site.md).
## Fixing errors found when running the Geo check Rake task
-When running this Rake task, you may see errors if the nodes are not properly configured:
+When running this Rake task, you may see error messages if the nodes are not properly configured:
```shell
sudo gitlab-rake gitlab:geo:check
```
-1. Rails did not provide a password when connecting to the database
+- Rails did not provide a password when connecting to the database.
- ```plaintext
- Checking Geo ...
+ ```plaintext
+ Checking Geo ...
- GitLab Geo is available ... Exception: fe_sendauth: no password supplied
- GitLab Geo is enabled ... Exception: fe_sendauth: no password supplied
- ...
- Checking Geo ... Finished
- ```
+ GitLab Geo is available ... Exception: fe_sendauth: no password supplied
+ GitLab Geo is enabled ... Exception: fe_sendauth: no password supplied
+ ...
+ Checking Geo ... Finished
+ ```
- - Ensure that you have the `gitlab_rails['db_password']` set to the plain text-password used when creating the hash for `postgresql['sql_user_password']`.
+ Ensure you have the `gitlab_rails['db_password']` set to the plain-text
+ password used when creating the hash for `postgresql['sql_user_password']`.
-1. Rails is unable to connect to the database
+- Rails is unable to connect to the database.
- ```plaintext
- Checking Geo ...
+ ```plaintext
+ Checking Geo ...
- GitLab Geo is available ... Exception: FATAL: no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL on
- FATAL: no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL off
- GitLab Geo is enabled ... Exception: FATAL: no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL on
- FATAL: no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL off
- ...
- Checking Geo ... Finished
- ```
+ GitLab Geo is available ... Exception: FATAL: no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL on
+ FATAL: no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL off
+ GitLab Geo is enabled ... Exception: FATAL: no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL on
+ FATAL: no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL off
+ ...
+ Checking Geo ... Finished
+ ```
- - Ensure that you have the IP address of the rails node included in `postgresql['md5_auth_cidr_addresses']`.
- - Ensure that you have included the subnet mask on the IP address: `postgresql['md5_auth_cidr_addresses'] = ['1.1.1.1/32']`.
+ Ensure you have the IP address of the rails node included in `postgresql['md5_auth_cidr_addresses']`.
+ Also, ensure you have included the subnet mask on the IP address: `postgresql['md5_auth_cidr_addresses'] = ['1.1.1.1/32']`.
-1. Rails has supplied the incorrect password
+- Rails has supplied the incorrect password.
- ```plaintext
- Checking Geo ...
- GitLab Geo is available ... Exception: FATAL: password authentication failed for user "gitlab"
- FATAL: password authentication failed for user "gitlab"
- GitLab Geo is enabled ... Exception: FATAL: password authentication failed for user "gitlab"
- FATAL: password authentication failed for user "gitlab"
- ...
- Checking Geo ... Finished
- ```
+ ```plaintext
+ Checking Geo ...
+ GitLab Geo is available ... Exception: FATAL: password authentication failed for user "gitlab"
+ FATAL: password authentication failed for user "gitlab"
+ GitLab Geo is enabled ... Exception: FATAL: password authentication failed for user "gitlab"
+ FATAL: password authentication failed for user "gitlab"
+ ...
+ Checking Geo ... Finished
+ ```
- - Verify the correct password is set for `gitlab_rails['db_password']` that was used when creating the hash in `postgresql['sql_user_password']` by running `gitlab-ctl pg-password-md5 gitlab` and entering the password.
+ Verify the correct password is set for `gitlab_rails['db_password']` that was
+ used when creating the hash in `postgresql['sql_user_password']` by running
+ `gitlab-ctl pg-password-md5 gitlab` and entering the password.
-1. Check returns `not a secondary node`
+- Check returns `not a secondary node`.
- ```plaintext
- Checking Geo ...
+ ```plaintext
+ Checking Geo ...
- GitLab Geo is available ... yes
- GitLab Geo is enabled ... yes
- GitLab Geo secondary database is correctly configured ... not a secondary node
- Database replication enabled? ... not a secondary node
- ...
- Checking Geo ... Finished
- ```
+ GitLab Geo is available ... yes
+ GitLab Geo is enabled ... yes
+ GitLab Geo secondary database is correctly configured ... not a secondary node
+ Database replication enabled? ... not a secondary node
+ ...
+ Checking Geo ... Finished
+ ```
- - Ensure that you have added the secondary node in the Admin Area of the **primary** node.
- - Ensure that you entered the `external_url` or `gitlab_rails['geo_node_name']` when adding the secondary node in the Admin Area of the **primary** node.
- - Prior to GitLab 12.4, edit the secondary node in the Admin Area of the **primary** node and ensure that there is a trailing `/` in the `Name` field.
+ Ensure you have added the secondary node in the Admin Area of the **primary** node.
+ Also ensure you entered the `external_url` or `gitlab_rails['geo_node_name']`
+ when adding the secondary node in the Admin Area of the **primary** node.
+ In GitLab 12.3 and earlier, edit the secondary node in the Admin Area of the **primary**
+ node and ensure that there is a trailing `/` in the `Name` field.
-1. Check returns `Exception: PG::UndefinedTable: ERROR: relation "geo_nodes" does not exist`
+- Check returns `Exception: PG::UndefinedTable: ERROR: relation "geo_nodes" does not exist`.
- ```plaintext
- Checking Geo ...
+ ```plaintext
+ Checking Geo ...
- GitLab Geo is available ... no
- Try fixing it:
- Upload 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
- LINE 8: WHERE a.attrelid = '"geo_nodes"'::regclass
+ GitLab Geo is available ... no
+ Try fixing it:
+ Upload 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
+ LINE 8: WHERE a.attrelid = '"geo_nodes"'::regclass
^
- : SELECT a.attname, format_type(a.atttypid, a.atttypmod),
- pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
- c.collname, col_description(a.attrelid, a.attnum) AS comment
- FROM pg_attribute a
- LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
- LEFT JOIN pg_type t ON a.atttypid = t.oid
- LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
- WHERE a.attrelid = '"geo_nodes"'::regclass
- AND a.attnum > 0 AND NOT a.attisdropped
- ORDER BY a.attnum
- ...
- Checking Geo ... Finished
- ```
-
- When performing a PostgreSQL major version (9 > 10) update this is expected. Follow:
+ : SELECT a.attname, format_type(a.atttypid, a.atttypmod),
+ pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
+ c.collname, col_description(a.attrelid, a.attnum) AS comment
+ FROM pg_attribute a
+ LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
+ LEFT JOIN pg_type t ON a.atttypid = t.oid
+ LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
+ WHERE a.attrelid = '"geo_nodes"'::regclass
+ AND a.attnum > 0 AND NOT a.attisdropped
+ ORDER BY a.attnum
+ ...
+ Checking Geo ... Finished
+ ```
- - [initiate-the-replication-process](../setup/database.md#step-3-initiate-the-replication-process)
+ When performing a PostgreSQL major version (9 > 10) update this is expected. Follow
+ the [initiate-the-replication-process](../setup/database.md#step-3-initiate-the-replication-process).
## Fixing replication errors
The following sections outline troubleshooting steps for fixing replication
-errors (indicated by `Database replication working? ... no` in the
+error messages (indicated by `Database replication working? ... no` in the
[`geo:check` output](#health-check-rake-task).
### Message: `ERROR: replication slots can only be used if max_replication_slots > 0`?
This means that the `max_replication_slots` PostgreSQL variable needs to
-be set on the **primary** database. In GitLab 9.4, we have made this setting
-default to 1. You may need to increase this value if you have more
-**secondary** nodes.
+be set on the **primary** database. This setting defaults to 1. You may need to
+increase this value if you have more **secondary** nodes.
Be sure to restart PostgreSQL for this to take effect. See the
[PostgreSQL replication setup](../setup/database.md#postgresql-replication) guide for more details.
@@ -306,7 +310,7 @@ process](../setup/database.md) on the **secondary** node .
### Message: "Command exceeded allowed execution time" when setting up replication?
This may happen while [initiating the replication process](../setup/database.md#step-3-initiate-the-replication-process) on the **secondary** node,
-and indicates that your initial dataset is too large to be replicated in the default timeout (30 minutes).
+and indicates your initial dataset is too large to be replicated in the default timeout (30 minutes).
Re-run `gitlab-ctl replicate-geo-database`, but include a larger value for
`--backup-timeout`:
@@ -320,7 +324,7 @@ sudo gitlab-ctl \
```
This gives the initial replication up to six hours to complete, rather than
-the default thirty minutes. Adjust as required for your installation.
+the default 30 minutes. Adjust as required for your installation.
### Message: "PANIC: could not write to file `pg_xlog/xlogtemp.123`: No space left on device"
@@ -336,7 +340,7 @@ log data to build up in `pg_xlog`. Removing the unused slots can reduce the amou
NOTE:
Using `gitlab-rails dbconsole` does not work, because managing replication slots requires superuser permissions.
-1. View your replication slots with:
+1. View your replication slots:
```sql
SELECT * FROM pg_replication_slots;
@@ -345,7 +349,7 @@ log data to build up in `pg_xlog`. Removing the unused slots can reduce the amou
Slots where `active` is `f` are not active.
- When this slot should be active, because you have a **secondary** node configured using that slot,
- log in to that **secondary** node and check the [PostgreSQL logs](../../logs.md#postgresql-logs)
+ sign in to that **secondary** node and check the [PostgreSQL logs](../../logs.md#postgresql-logs)
to view why the replication is not running.
- If you are no longer using the slot (for example, you no longer have Geo enabled), you can remove it with in the
@@ -357,11 +361,11 @@ Slots where `active` is `f` are not active.
### Message: "ERROR: canceling statement due to conflict with recovery"
-This error occurs infrequently under normal usage, and the system is resilient
+This error message occurs infrequently under normal usage, and the system is resilient
enough to recover.
However, under certain conditions, some database queries on secondaries may run
-excessively long, which increases the frequency of this error. This can lead to a situation
+excessively long, which increases the frequency of this error message. This can lead to a situation
where some queries never complete due to being canceled on every replication.
These long-running queries are
@@ -428,7 +432,16 @@ If large repositories are affected by this problem,
their resync may take a long time and cause significant load on your Geo nodes,
storage and network systems.
-If you get the error `Synchronization failed - Error syncing repository` along with the following log messages, this indicates that the expected `geo` remote is not present in the `.git/config` file
+If you see the error message `Synchronization failed - Error syncing repository` along with `fatal: fsck error in packed object`, this indicates
+a consistency check error when syncing the repository.
+
+One example of a consistency error is: `error: object f4a87a3be694fbbd6e50a668a31a8513caeaafe3: hasDotgit: contains '.git`.
+
+Removing the malformed objects causing consistency errors require rewriting the repository history, which is not always an option. However,
+it's possible to override the consistency checks instead. To do that, follow
+[the instructions in the Gitaly docs](../../gitaly/configure_gitaly.md#repository-consistency-checks).
+
+You can also get the error message `Synchronization failed - Error syncing repository` along with the following log messages, this indicates that the expected `geo` remote is not present in the `.git/config` file
of a repository on the secondary Geo node's file system:
```json
@@ -451,11 +464,11 @@ of a repository on the secondary Geo node's file system:
To solve this:
-1. Log into the secondary Geo node.
+1. Sign in to the secondary Geo node.
1. Back up [the `.git` folder](../../repository_storage_types.md#translate-hashed-storage-paths).
-1. Optional: [Spot-check](../../troubleshooting/log_parsing.md#find-all-projects-affected-by-a-fatal-git-problem)
+1. Optional. [Spot-check](../../troubleshooting/log_parsing.md#find-all-projects-affected-by-a-fatal-git-problem)
a few of those IDs whether they indeed correspond
to a project with known Geo replication failures.
Use `fatal: 'geo'` as the `grep` term and the following API call:
@@ -490,18 +503,19 @@ GitLab places a timeout on all repository clones, including project imports
and Geo synchronization operations. If a fresh `git clone` of a repository
on the **primary** takes more than the default three hours, you may be affected by this.
-To increase the timeout, add the following line to `/etc/gitlab/gitlab.rb`
-on the **secondary** node:
+To increase the timeout:
-```ruby
-gitlab_rails['gitlab_shell_git_timeout'] = 14400
-```
+1. On the **secondary** node, add the following line to `/etc/gitlab/gitlab.rb`:
-Then reconfigure GitLab:
+ ```ruby
+ gitlab_rails['gitlab_shell_git_timeout'] = 14400
+ ```
-```shell
-sudo gitlab-ctl reconfigure
-```
+1. Reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
This increases the timeout to four hours (14400 seconds). Choose a time
long enough to accommodate a full clone of your largest repositories.
@@ -512,7 +526,7 @@ If new LFS objects are never replicated to secondary Geo nodes, check the versio
GitLab you are running. GitLab versions 11.11.x or 12.0.x are affected by
[a bug that results in new LFS objects not being replicated to Geo secondary nodes](https://gitlab.com/gitlab-org/gitlab/-/issues/32696).
-To resolve the issue, upgrade to GitLab 12.1 or newer.
+To resolve the issue, upgrade to GitLab 12.1 or later.
### Failures during backfill
@@ -524,7 +538,7 @@ of the backfill queue, therefore these failures only clear up **after** the back
If you get a **secondary** node in a broken state and want to reset the replication state,
to start again from scratch, there are a few steps that can help you:
-1. Stop Sidekiq and the Geo LogCursor
+1. Stop Sidekiq and the Geo LogCursor.
It's possible to make Sidekiq stop gracefully, but making it stop getting new jobs and
wait until the current jobs to finish processing.
@@ -547,7 +561,7 @@ to start again from scratch, there are a few steps that can help you:
gitlab-ctl tail sidekiq
```
-1. Rename repository storage folders and create new ones. If you are not concerned about possible orphaned directories and files, then you can simply skip this step.
+1. Rename repository storage folders and create new ones. If you are not concerned about possible orphaned directories and files, you can skip this step.
```shell
mv /var/opt/gitlab/git-data/repositories /var/opt/gitlab/git-data/repositories.old
@@ -559,14 +573,14 @@ to start again from scratch, there are a few steps that can help you:
You may want to remove the `/var/opt/gitlab/git-data/repositories.old` in the future
as soon as you confirmed that you don't need it anymore, to save disk space.
-1. Optional. Rename other data folders and create new ones
+1. Optional. Rename other data folders and create new ones.
WARNING:
You may still have files on the **secondary** node that have been removed from the **primary** node, but this
- removal has not been reflected. If you skip this step, these files are not removed at all from the Geo node.
+ removal has not been reflected. If you skip this step, these files are not removed from the Geo node.
- Any uploaded content like file attachments, avatars or LFS objects are stored in a
- subfolder in one of the two paths below:
+ Any uploaded content (like file attachments, avatars, or LFS objects) is stored in a
+ subfolder in one of these paths:
- `/var/opt/gitlab/gitlab-rails/shared`
- `/var/opt/gitlab/gitlab-rails/uploads`
@@ -593,7 +607,7 @@ to start again from scratch, there are a few steps that can help you:
gitlab-ctl reconfigure
```
-1. Reset the Tracking Database
+1. Reset the Tracking Database.
```shell
gitlab-rake geo:db:drop # on a secondary app node
@@ -601,7 +615,7 @@ to start again from scratch, there are a few steps that can help you:
gitlab-rake geo:db:setup # on a secondary app node
```
-1. Restart previously stopped services
+1. Restart previously stopped services.
```shell
gitlab-ctl start
@@ -611,10 +625,10 @@ to start again from scratch, there are a few steps that can help you:
On the top bar, under **Menu > Admin > Geo > Nodes**,
if the Design repositories progress bar shows
-`Synced` and `Failed` greater than 100%, and negative `Queued`, then the instance
+`Synced` and `Failed` greater than 100%, and negative `Queued`, the instance
is likely affected by
[a bug in GitLab 13.2 and 13.3](https://gitlab.com/gitlab-org/gitlab/-/issues/241668).
-It was [fixed in 13.4+](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40643).
+It was [fixed in GitLab 13.4 and later](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40643).
To determine the actual replication status of design repositories in
a [Rails console](../../operations/rails_console.md):
@@ -665,7 +679,7 @@ determine the actual replication status of Design repositories.
`gitlab-ctl promote-to-primary-node` fails since it runs preflight checks.
If the [previous snippet](#design-repository-failures-on-mirrored-projects-and-project-imports)
-shows that all designs are synced, then you can use the
+shows that all designs are synced, you can use the
`--skip-preflight-checks` option or the `--force` option to move forward with
promotion.
@@ -676,15 +690,70 @@ promotion.
[previous snippet](#design-repository-failures-on-mirrored-projects-and-project-imports) to
determine the actual replication status of Design repositories.
+### Sync failure message: "Verification failed with: Error during verification: File is not checksummable"
+
+In GitLab 14.5 and earlier, certain data types which were missing on the Geo primary site were marked as "synced" on Geo secondary sites. This was because from the perspective of Geo secondary sites, the state matched the primary site and nothing more could be done on secondary sites.
+
+Secondaries would regularly try to sync these files again by using the "verification" feature:
+
+- Verification fails since the file doesn't exist.
+- The file is marked "sync failed".
+- Sync is retried.
+- The file is marked "sync succeeded".
+- The file is marked "needs verification".
+- Repeat until the file is available again on the primary site.
+
+This can be confusing to troubleshoot, since the registry entries are moved through a logical loop by various background jobs. Also, `last_sync_failure` and `verification_failure` are empty after "sync succeeded" but before verification is retried.
+
+If you see sync failures repeatedly and alternately increase, while successes decrease and vice versa, this is likely to be caused by missing files on the primary site. You can confirm this by searching `geo.log` on secondary sites for `File is not checksummable` affecting the same files over and over.
+
+After confirming this is the problem, the files on the primary site need to be fixed. Some possible causes:
+
+- An NFS share became unmounted.
+- A disk died or became corrupted.
+- Someone unintentionally deleted a file or directory.
+- Bugs in GitLab application:
+ - A file was moved when it shouldn't have been moved.
+ - A file wasn't moved when it should have been moved.
+ - A wrong path was generated in the code.
+- A non-atomic backup was restored.
+- Services or servers or network infrastructure was interrupted/restarted during use.
+
+The appropriate action sometimes depends on the cause. For example, you can remount an NFS share. Often, a root cause may not be apparent or not useful to discover. If you have regular backups, it may be expedient to look through them and pull files from there.
+
+In some cases, a file may be determined to be of low value, and so it may be worth deleting the record.
+
+Geo itself is an excellent mitigation for files missing on the primary. If a file disappears on the primary but it was already synced to the secondary, you can grab the secondary's file. In cases like this, the `File is not checksummable` error message will not occur on Geo secondary sites, and only the primary will log this error message.
+
+This problem is more likely to show up in Geo secondary sites which were set up long after the original GitLab site. In this case, Geo is only surfacing an existing problem.
+
+This behavior affects only the following data types through GitLab 14.6:
+
+| Data type | From version |
+| ------------------------ | ------------ |
+| Package Registry | 13.10 |
+| Pipeline Artifacts | 13.11 |
+| Terraform State Versions | 13.12 |
+| Infrastructure Registry | 14.0 |
+| External MR diffs | 14.6 |
+| LFS Objects | 14.6 |
+| Pages Deployments | 14.6 |
+| Uploads | 14.6 |
+| CI Job Artifacts | 14.6 |
+
+[Since GitLab 14.7, files that are missing on the primary site are now treated as sync failures](https://gitlab.com/gitlab-org/gitlab/-/issues/348745)
+to make Geo visibly surface data loss risks. The sync/verification loop is
+therefore short-circuited. `last_sync_failure` is now set to `The file is missing on the Geo primary site`.
+
## Fixing errors during a failover or when promoting a secondary to a primary node
-The following are possible errors that might be encountered during failover or
+The following are possible error messages that might be encountered during failover or
when promoting a secondary to a primary node with strategies to resolve them.
### Message: ActiveRecord::RecordInvalid: Validation failed: Name has already been taken
When [promoting a **secondary** site](../disaster_recovery/index.md#step-3-promoting-a-secondary-site),
-you might encounter the following error:
+you might encounter the following error message:
```plaintext
Running gitlab-rake geo:set_secondary_as_primary...
@@ -712,7 +781,7 @@ or `gitlab-ctl promote-to-primary-node`, either:
Rake::Task['geo:set_secondary_as_primary'].invoke
```
-- Upgrade to GitLab 12.6.3 or newer if it is safe to do so. For example,
+- Upgrade to GitLab 12.6.3 or later if it is safe to do so. For example,
if the failover was just a test. A [caching-related
bug](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/22021) was
fixed.
@@ -720,8 +789,8 @@ or `gitlab-ctl promote-to-primary-node`, either:
### Message: ActiveRecord::RecordInvalid: Validation failed: Enabled Geo primary node cannot be disabled
If you disabled a secondary node, either with the [replication pause task](../index.md#pausing-and-resuming-replication)
-(13.2) or by using the user interface (13.1 and earlier), you must first
-re-enable the node before you can continue. This is fixed in 13.4.
+(GitLab 13.2) or by using the user interface (GitLab 13.1 and earlier), you must first
+re-enable the node before you can continue. This is fixed in GitLab 13.4.
This can be fixed in the database.
@@ -747,12 +816,12 @@ This can be fixed in the database.
UPDATE geo_nodes SET enabled = true WHERE url = 'https://<secondary url>/' AND enabled = false;"
```
- This should update 1 row.
+ This should update one row.
### Message: ``NoMethodError: undefined method `secondary?' for nil:NilClass``
When [promoting a **secondary** site](../disaster_recovery/index.md#step-3-promoting-a-secondary-site),
-you might encounter the following error:
+you might encounter the following error message:
```plaintext
sudo gitlab-rake geo:set_secondary_as_primary
@@ -767,7 +836,7 @@ Tasks: TOP => geo:set_secondary_as_primary
(See full trace by running task with --trace)
```
-This command is intended to be executed on a secondary site only, and this error
+This command is intended to be executed on a secondary site only, and this error message
is displayed if you attempt to run this command on a primary site.
### Message: `sudo: gitlab-pg-ctl: command not found`
@@ -789,7 +858,7 @@ In this case, the workaround is to use the full path to the binary, for example:
sudo /opt/gitlab/embedded/bin/gitlab-pg-ctl promote
```
-GitLab 12.9 and later are [unaffected by this error](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5147).
+GitLab 12.9 and later are [unaffected by this error message](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5147).
### Message: `ERROR - Replication is not up-to-date` during `gitlab-ctl promotion-preflight-checks`
@@ -807,7 +876,7 @@ shows that it is complete, you can add `--skip-preflight-checks` to make the com
### Errors when using `--skip-preflight-checks` or `--force`
-Before GitLab 13.5, you could bump into one of the following errors when using
+In GitLab 13.4 and earlier, you could receive one of the following error messages when using
`--skip-preflight-checks` or `--force`:
```plaintext
@@ -817,7 +886,7 @@ get_ctl_options': invalid option: --force (OptionParser::InvalidOption)
```
This can happen with XFS or file systems that list files in lexical order, because the
-load order of the Omnibus command files can be different than expected, and a global function would get redefined.
+load order of the Omnibus GitLab command files can be different than expected, and a global function would get redefined.
More details can be found in [the related issue](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/6076).
The workaround is to manually run the preflight checks and promote the database, by running
@@ -843,8 +912,8 @@ registry record related to the orphan files on disk.
### Message: The redirect URI included is not valid
-If you are able to log in to the **primary** node, but you receive this error
-when attempting to log into a **secondary**, you should check that the Geo
+If you are able to sign in to the **primary** node, but you receive this error message
+when attempting to sign in to a **secondary**, you should verify the Geo
node's URL matches its external URL.
On the **primary** node:
@@ -858,7 +927,7 @@ On the **primary** node:
## Fixing common errors
-This section documents common errors reported in the Admin Area and how to fix them.
+This section documents common error messages reported in the Admin Area, and how to fix them.
### Geo database configuration file is missing
@@ -879,20 +948,28 @@ It is safest to use a fresh secondary, or reset the whole secondary by following
### Geo node has a database that is writable which is an indication it is not configured for replication with the primary node
-This error refers to a problem with the database replica on a **secondary** node,
+This error message refers to a problem with the database replica on a **secondary** node,
which Geo expects to have access to. It usually means, either:
- An unsupported replication method was used (for example, logical replication).
-- The instructions to setup a [Geo database replication](../setup/database.md) were not followed correctly.
+- The instructions to set up a [Geo database replication](../setup/database.md) were not followed correctly.
- Your database connection details are incorrect, that is you have specified the wrong
user in your `/etc/gitlab/gitlab.rb` file.
-A common source of confusion with **secondary** nodes is that it requires two separate
-PostgreSQL instances:
+Geo **secondary** sites require two separate PostgreSQL instances:
- A read-only replica of the **primary** node.
- A regular, writable instance that holds replication metadata. That is, the Geo tracking database.
+This error message indicates that the replica database in the **secondary** site is misconfigured and replication has stopped.
+
+To restore the database and resume replication, you can do one of the following:
+
+- [Reset the Geo secondary site replication](#resetting-geo-secondary-node-replication).
+- [Set up a new secondary Geo Omnibus instance](../setup/index.md#using-omnibus-gitlab).
+
+If you set up a new secondary from scratch, you must also [remove the old site from the Geo cluster](remove_geo_site.md#removing-secondary-geo-sites).
+
### Geo node does not appear to be replicating the database from the primary node
The most common problems that prevent the database from replicating correctly are:
@@ -920,7 +997,7 @@ This can be caused by orphaned records in the project registry. You can clear th
### Geo Admin Area returns 404 error for a secondary node
Sometimes `sudo gitlab-rake gitlab:geo:check` indicates that the **secondary** node is
-healthy, but a 404 error for the **secondary** node is returned in the Geo Admin Area on
+healthy, but a 404 Not Found error message for the **secondary** node is returned in the Geo Admin Area on
the **primary** node.
To resolve this issue:
@@ -938,7 +1015,7 @@ If using a load balancer, ensure that the load balancer's URL is set as the `ext
### Geo Admin Area shows 'Unhealthy' after enabling Maintenance Mode
-In GitLab 13.9 through GitLab 14.3, when [GitLab Maintenance Mode](../../maintenance_mode/index.md) is enabled, the status of Geo secondary sites will stop getting updated. After 10 minutes, the status will become `Unhealthy`.
+In GitLab 13.9 through GitLab 14.3, when [GitLab Maintenance Mode](../../maintenance_mode/index.md) is enabled, the status of Geo secondary sites will stop getting updated. After 10 minutes, the status changes to `Unhealthy`.
Geo secondary sites will continue to replicate and verify data, and the secondary sites should still be usable. You can use the [Sync status Rake task](#sync-status-rake-task) to determine the actual status of a secondary site during Maintenance Mode.
@@ -947,7 +1024,7 @@ This bug was [fixed in GitLab 14.4](https://gitlab.com/gitlab-org/gitlab/-/issue
### GitLab Pages return 404 errors after promoting
This is due to [Pages data not being managed by Geo](datatypes.md#limitations-on-replicationverification).
-Find advice to resolve those errors in the
+Find advice to resolve those error messages in the
[Pages administration documentation](../../../administration/pages/index.md#404-error-after-promoting-a-geo-secondary-to-a-primary-node).
## Fixing client errors
@@ -958,4 +1035,4 @@ You may have problems if you're running a version of [Git LFS](https://git-lfs.g
As noted in [this authentication issue](https://github.com/git-lfs/git-lfs/issues/3025),
requests redirected from the secondary to the primary node do not properly send the
Authorization header. This may result in either an infinite `Authorization <-> Redirect`
-loop, or Authorization errors.
+loop, or Authorization error messages.
diff --git a/doc/administration/geo/replication/usage.md b/doc/administration/geo/replication/usage.md
index f3c8f6ac759..b1183e56cd0 100644
--- a/doc/administration/geo/replication/usage.md
+++ b/doc/administration/geo/replication/usage.md
@@ -2,7 +2,6 @@
stage: Enablement
group: Geo
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: howto
---
<!-- Please update EE::GitLab::GeoGitAccess::GEO_SERVER_DOCS_URL if this file is moved) -->
@@ -11,7 +10,8 @@ type: howto
After you set up the [database replication and configure the Geo nodes](../index.md#setup-instructions), use your closest GitLab site as you would do with the primary one.
-You can push directly to a **secondary** site (for both HTTP, SSH including Git LFS), and the request will be proxied to the primary site instead ([introduced](https://about.gitlab.com/releases/2018/09/22/gitlab-11-3-released/) in GitLab 11.3).
+You can push directly to a **secondary** site (for both HTTP, SSH including
+Git LFS), and the request will be proxied to the primary site instead.
Example of the output you will see when pushing to a **secondary** site:
diff --git a/doc/administration/geo/replication/version_specific_updates.md b/doc/administration/geo/replication/version_specific_updates.md
index 883e335ff94..d3a132a6666 100644
--- a/doc/administration/geo/replication/version_specific_updates.md
+++ b/doc/administration/geo/replication/version_specific_updates.md
@@ -2,7 +2,6 @@
stage: Enablement
group: Geo
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: howto
---
# Version-specific update instructions **(PREMIUM SELF)**
@@ -378,10 +377,3 @@ WARNING:
This version is affected by a [bug that results in new LFS objects not being
replicated to Geo secondary nodes](https://gitlab.com/gitlab-org/gitlab/-/issues/32696).
The issue is fixed in GitLab 12.1. Be sure to upgrade to GitLab 12.1 or later.
-
-## Updating to GitLab 11.11
-
-WARNING:
-This version is affected by a [bug that results in new LFS objects not being
-replicated to Geo secondary nodes](https://gitlab.com/gitlab-org/gitlab/-/issues/32696).
-The issue is fixed in GitLab 12.1. Be sure to upgrade to GitLab 12.1 or later.
diff --git a/doc/administration/geo/setup/external_database.md b/doc/administration/geo/setup/external_database.md
index 756e73f022f..cd77647e7dc 100644
--- a/doc/administration/geo/setup/external_database.md
+++ b/doc/administration/geo/setup/external_database.md
@@ -2,7 +2,6 @@
stage: Enablement
group: Geo
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: howto
---
# Geo with external PostgreSQL instances **(PREMIUM SELF)**
@@ -184,7 +183,7 @@ To configure the connection to the external read-replica database and enable Log
database to keep track of replication status and automatically recover from
potential replication issues. Omnibus automatically configures a tracking database
when `roles ['geo_secondary_role']` is set.
-If you want to run this database external to Omnibus, please follow the instructions below.
+If you want to run this database external to Omnibus GitLab, use the following instructions.
If you are using a cloud-managed service for the tracking database, you may need
to grant additional roles to your tracking database user (by default, this is
diff --git a/doc/administration/get_started.md b/doc/administration/get_started.md
index bff2aee1d2d..3be3c11947e 100644
--- a/doc/administration/get_started.md
+++ b/doc/administration/get_started.md
@@ -1,5 +1,7 @@
---
info: For assistance with this TAM Onboarding page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-other-projects-and-subjects.
+stage: none
+group: unassigned
---
# Get started administering GitLab **(FREE)**
diff --git a/doc/administration/git_protocol.md b/doc/administration/git_protocol.md
index c8c532e9a01..29156d9b3e1 100644
--- a/doc/administration/git_protocol.md
+++ b/doc/administration/git_protocol.md
@@ -1,20 +1,17 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference
+info: 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: "Set and configure Git protocol v2"
---
# Configuring Git Protocol v2 **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/46555) in GitLab 11.4.
-> - [Temporarily disabled](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/55769) in GitLab 11.5.8, 11.6.6, 11.7.1, and 11.8+.
-> - [Re-enabled](https://gitlab.com/gitlab-org/gitlab/-/issues/27828) in GitLab 12.8.
+> [Re-enabled](https://gitlab.com/gitlab-org/gitlab/-/issues/27828) in GitLab 12.8.
Git protocol v2 improves the v1 wire protocol in several ways and is
-enabled by default in GitLab for HTTP requests. In order to enable SSH,
-further configuration is needed by the administrator.
+enabled by default in GitLab for HTTP requests. To enable SSH, additional
+configuration is required by an administrator.
More details about the new features and improvements are available in
the [Google Open Source Blog](https://opensource.googleblog.com/2018/05/introducing-git-protocol-version-2.html)
@@ -51,7 +48,7 @@ sudo systemctl restart ssh
## Instructions
-In order to use the new protocol, clients need to either pass the configuration
+To use the new protocol, clients need to either pass the configuration
`-c protocol.version=2` to the Git command, or set it globally:
```shell
diff --git a/doc/administration/gitaly/configure_gitaly.md b/doc/administration/gitaly/configure_gitaly.md
index b31a02aae0a..a0c959d5de9 100644
--- a/doc/administration/gitaly/configure_gitaly.md
+++ b/doc/administration/gitaly/configure_gitaly.md
@@ -565,6 +565,12 @@ Note the following:
- You can configure Gitaly servers with both an unencrypted listening address `listen_addr` and an
encrypted listening address `tls_listen_addr` at the same time. This allows you to gradually
transition from unencrypted to encrypted traffic if necessary.
+- When running Praefect sub-commands such as `dial-nodes` and `list-untracked-repositories` from the command line with Gitaly TLS enabled, you must set
+ the `SSL_CERT_DIR` or `SSL_CERT_FILE` 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
+ ```
To configure Gitaly with TLS:
@@ -1125,3 +1131,66 @@ Example:
"time":"2021-03-25T14:57:53.543Z"
}
```
+
+## Repository consistency checks
+
+Gitaly runs repository consistency checks:
+
+- When triggering a repository check.
+- When changes are fetched from a mirrored repository.
+- When users push changes into repository.
+
+These consistency checks verify that a repository has all required objects and
+that these objects are valid objects. They can be categorized as:
+
+- Basic checks that assert that a repository doesn't become corrupt. This
+ includes connectivity checks and checks that objects can be parsed.
+- Security checks that recognize objects that are suitable to exploit past
+ security-related bugs in Git.
+- Cosmetic checks that verify that all object metadata is valid. Older Git
+ versions and other Git implementations may have produced objects with invalid
+ metadata, but newer versions can interpret these malformed objects.
+
+Removing malformed objects that fail the consistency checks requires a
+rewrite of the repository's history, which often can't be done. Therefore,
+Gitaly by default disables consistency checks for a range of cosmetic issues
+that don't negatively impact repository consistency.
+
+By default, Gitaly doesn't disable basic or security-related checks so
+to not distribute objects that can trigger known vulnerabilities in Git
+clients. This also limits the ability to import repositories containing such
+objects even if the project doesn't have malicious intent.
+
+### Override repository consistency checks
+
+Instance administrators can override consistency checks if they must
+process repositories that do not pass consistency checks.
+
+For Omnibus GitLab installations, edit `/etc/gitlab/gitlab.rb` and set the
+following keys (in this example, to disable the `hasDotgit` consistency check):
+
+```ruby
+ignored_git_errors = ["hasDotgit = ignore"]
+omnibus_gitconfig['system'] = {
+ "fsck" => ignored_git_errors,
+ "fetch.fsck" => ignored_git_errors,
+ "receive.fsck" => ignored_git_errors,
+}
+```
+
+For source installs, edit the Gitaly configuration (`gitaly.toml`) to do the
+equivalent:
+
+```toml
+[[git.config]]
+key = "fsck.hasDotgit"
+value = "ignore"
+
+[[git.config]]
+key = "fetch.fsck.hasDotgit"
+value = "ignore"
+
+[[git.config]]
+key = "receive.fsck.hasDotgit"
+value = "ignore"
+```
diff --git a/doc/administration/gitaly/index.md b/doc/administration/gitaly/index.md
index f99bbf21840..4d60832720b 100644
--- a/doc/administration/gitaly/index.md
+++ b/doc/administration/gitaly/index.md
@@ -490,7 +490,15 @@ The following are useful queries for monitoring Gitaly:
### Monitor Gitaly Cluster
-To monitor Gitaly Cluster (Praefect), you can use these Prometheus metrics:
+To monitor Gitaly Cluster (Praefect), you can use these Prometheus metrics. There are two separate metrics
+endpoints from which metrics can be scraped:
+
+- The default `/metrics` endpoint.
+- `/db_metrics`, which contains metrics that require database queries.
+
+#### Default Prometheus `/metrics` endpoint
+
+The following metrics are available from the `/metrics` endpoint:
- `gitaly_praefect_read_distribution`, a counter to track [distribution of reads](#distributed-reads).
It has two labels:
@@ -523,6 +531,18 @@ To monitor [strong consistency](#strong-consistency), you can use the following
You can also monitor the [Praefect logs](../logs.md#praefect-logs).
+#### Database metrics `/db_metrics` endpoint
+
+> [Introduced](https://gitlab.com/gitlab-org/gitaly/-/issues/3286) in GitLab 14.5.
+
+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.
+ 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.
+
## Recover from failure
Gitaly Cluster can [recover from certain types of failure](recovery.md).
diff --git a/doc/administration/gitaly/praefect.md b/doc/administration/gitaly/praefect.md
index d3a8662080f..e2db30b8358 100644
--- a/doc/administration/gitaly/praefect.md
+++ b/doc/administration/gitaly/praefect.md
@@ -20,6 +20,9 @@ Configure Gitaly Cluster using either:
Smaller GitLab installations may need only [Gitaly itself](index.md).
+To upgrade a Gitaly Cluster, follow the documentation for
+[zero downtime upgrades](../../update/zero_downtime.md#gitaly-cluster).
+
## Requirements
The minimum recommended configuration for a Gitaly Cluster requires:
@@ -376,8 +379,8 @@ configuration option is set. For more details, consult the PgBouncer documentati
If there are multiple Praefect nodes:
-- Complete the following steps for **each** node.
-- Designate one node as the "deploy node", and configure it first.
+1. Designate one node as the deploy node, and configure it using the following steps.
+1. Complete the following steps for each additional node.
To complete this section you need a [configured PostgreSQL server](#postgresql), including:
@@ -405,7 +408,7 @@ On the **Praefect** node:
# Enable only the Praefect service
praefect['enable'] = true
- # Prevent database connections during 'gitlab-ctl reconfigure'
+ # Disable database migrations to prevent database connections during 'gitlab-ctl reconfigure'
gitlab_rails['auto_migrate'] = false
praefect['auto_migrate'] = false
```
@@ -415,10 +418,21 @@ On the **Praefect** node:
```ruby
praefect['listen_addr'] = '0.0.0.0:2305'
+ ```
+1. Configure Prometheus metrics by editing
+ `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
# Enable Prometheus metrics access to Praefect. You must use firewalls
# to restrict access to this address/port.
+ # The default metrics endpoint is /metrics
praefect['prometheus_listen_addr'] = '0.0.0.0:9652'
+
+ # Some metrics run queries against the database. Enabling separate database metrics allows
+ # these metrics to be collected when the metrics are
+ # scraped on a separate /db_metrics endpoint.
+ praefect['separate_database_metrics'] = true
```
1. Configure a strong `auth_token` for **Praefect** by editing
@@ -517,7 +531,7 @@ On the **Praefect** node:
1. For:
- The "deploy node":
- 1. Enable Praefect auto-migration again by setting `praefect['auto_migrate'] = true` in
+ 1. Enable Praefect database auto-migration again by setting `praefect['auto_migrate'] = true` in
`/etc/gitlab/gitlab.rb`.
1. To ensure database migrations are only run during reconfigure and not automatically on
upgrade, run:
@@ -556,8 +570,6 @@ On the **Praefect** node:
edit `/etc/gitlab/gitlab.rb`, remember to run `sudo gitlab-ctl reconfigure`
again before trying the `sql-ping` command.
-**The steps above must be completed for each Praefect node!**
-
#### Enabling TLS support
> [Introduced](https://gitlab.com/gitlab-org/gitaly/-/issues/1698) in GitLab 13.2.
@@ -755,7 +767,7 @@ For more information on Gitaly server configuration, see our
# Enable Prometheus if needed
prometheus['enable'] = true
- # Prevent database connections during 'gitlab-ctl reconfigure'
+ # Disable database migrations to prevent database connections during 'gitlab-ctl reconfigure'
gitlab_rails['auto_migrate'] = false
```
@@ -883,9 +895,9 @@ of choice already. Some examples include [HAProxy](https://www.haproxy.org/)
Big-IP LTM, and Citrix Net Scaler. This documentation outlines what ports
and protocols you need configure.
-WARNING:
-Long-running background jobs can maintain an idle connection with Praefect for up 6 hours. Set your load balancer timeout to be at least
-6 hours long.
+NOTE:
+We recommend the equivalent of HAProxy `leastconn` load-balancing strategy because long-running operations (for example,
+clones) keep some connections open for extended periods.
| LB Port | Backend Port | Protocol |
|:--------|:-------------|:---------|
@@ -1217,9 +1229,9 @@ To migrate existing clusters:
1. Praefect nodes didn't historically keep database records of every repository stored on the cluster. When
the `per_repository` election strategy is configured, Praefect expects to have database records of
- each repository. A [background migration](https://gitlab.com/gitlab-org/gitaly/-/merge_requests/2749) is
- included in GitLab 13.6 and later to create any missing database records for repositories. Before migrating
- you should verify the migration has run by checking Praefect's logs:
+ each repository. A [background database migration](https://gitlab.com/gitlab-org/gitaly/-/merge_requests/2749) is
+ included in GitLab 13.6 and later to create any missing database records for repositories. Before migrating,
+ check Praefect's logs to verify that the database migration ran.
Check Praefect's logs for `repository importer finished` message. The `virtual_storages` field contains
the names of virtual storages and whether they've had any missing database records created.
@@ -1236,8 +1248,8 @@ To migrate existing clusters:
{"level":"info","msg":"repository importer finished","pid":19752,"time":"2021-04-28T11:41:36.743Z","virtual_storages":{"default":false}}
```
- The migration is ran when Praefect starts up. If the migration is unsuccessful, you can restart
- a Praefect node to reattempt it. The migration only runs with `sql` election strategy configured.
+ The database migration runs when Praefect starts. If the database migration is unsuccessful, you can restart
+ a Praefect node to reattempt it.
1. Running two different election strategies side by side can cause a split brain, where different
Praefect nodes consider repositories to have different primaries. This can be avoided either:
diff --git a/doc/administration/img/instance_review_button.png b/doc/administration/img/instance_review_button.png
deleted file mode 100644
index b7604d7c7e5..00000000000
--- a/doc/administration/img/instance_review_button.png
+++ /dev/null
Binary files differ
diff --git a/doc/administration/img/instance_review_v14_7.png b/doc/administration/img/instance_review_v14_7.png
new file mode 100644
index 00000000000..e9f6316c237
--- /dev/null
+++ b/doc/administration/img/instance_review_v14_7.png
Binary files differ
diff --git a/doc/administration/incoming_email.md b/doc/administration/incoming_email.md
index 3f54f5dd576..84b30724dff 100644
--- a/doc/administration/incoming_email.md
+++ b/doc/administration/incoming_email.md
@@ -170,6 +170,15 @@ Reply by email should now be working.
cd /home/git/gitlab
```
+1. Install the `gitlab-mail_room` gem manually:
+
+ ```shell
+ gem install gitlab-mail_room
+ ```
+
+ NOTE: This step is necessary to avoid thread deadlocks and to support the latest MailRoom features. See
+ [this explanation](../development/emails.md#mailroom-gem-updates) for more details.
+
1. Find the `incoming_email` section in `config/gitlab.yml`, enable the feature
and fill in the details for your specific IMAP server and email account (see [examples](#configuration-examples) below).
@@ -470,6 +479,10 @@ incoming_email:
##### Dedicated email address
+NOTE:
+Supports [Reply by Email](reply_by_email.md) only.
+Cannot support [Service Desk](../user/project/service_desk.md).
+
Assumes the dedicated email address `incoming@exchange.example.com`.
Example for Omnibus installs:
@@ -531,19 +544,20 @@ enabled by default, and must be enabled through PowerShell.
This series of PowerShell commands enables [sub-addressing](#email-sub-addressing)
at the organization level in Office 365. This allows all mailboxes in the organization
-to receive sub-addressed mail:
+to receive sub-addressed mail.
-```powershell
-Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
+To enable sub-addressing:
-$UserCredential = Get-Credential
+1. Download and install the `ExchangeOnlineManagement` module from the [PowerShell gallery](https://www.powershellgallery.com/packages/ExchangeOnlineManagement/).
+1. In PowerShell, run the following commands:
-$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
-
-Import-PSSession $Session -DisableNameChecking
-
-Set-OrganizationConfig -AllowPlusAddressInRecipients $true
-```
+ ```powershell
+ Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
+ Import-Module ExchangeOnlineManagement
+ Connect-ExchangeOnline
+ Set-OrganizationConfig -AllowPlusAddressInRecipients $true
+ Disconnect-ExchangeOnline
+ ```
This example for Omnibus GitLab assumes the mailbox `incoming@office365.example.com`:
@@ -655,6 +669,10 @@ incoming_email:
##### Dedicated email address
+NOTE:
+Supports [Reply by Email](reply_by_email.md) only.
+Cannot support [Service Desk](../user/project/service_desk.md).
+
This example for Omnibus installs assumes the dedicated email address `incoming@office365.example.com`:
```ruby
diff --git a/doc/administration/index.md b/doc/administration/index.md
index d78c9d80b5f..bd6549fca80 100644
--- a/doc/administration/index.md
+++ b/doc/administration/index.md
@@ -55,7 +55,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- [File hooks](file_hooks.md): With custom file hooks, GitLab administrators can
introduce custom integrations without modifying GitLab source code.
- [Enforcing Terms of Service](../user/admin_area/settings/terms.md)
-- [Third party offers](../user/admin_area/settings/third_party_offers.md)
+- [Customer experience improvement and third-party offers](../user/admin_area/settings/third_party_offers.md)
- [Compliance](compliance.md): A collection of features from across the
application that you may configure to help ensure that your GitLab instance
and DevOps workflow meet compliance standards.
@@ -172,7 +172,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- [Job artifacts](job_artifacts.md): Enable, disable, and configure job artifacts (a set of files and directories which are outputted by a job when it completes successfully).
- [Job logs](job_logs.md): Information about the job logs.
- [Register runners](../ci/runners/runners_scope.md): Learn how to register and configure runners.
-- [Shared runners pipelines quota](../user/admin_area/settings/continuous_integration.md#shared-runners-pipeline-minutes-quota): Limit the usage of pipeline minutes for shared runners.
+- [Shared runners quota of CI/CD minutes](../ci/pipelines/cicd_minutes.md): Limit the usage of CI/CD minutes for shared runners.
- [Enable or disable Auto DevOps](../topics/autodevops/index.md#enable-or-disable-auto-devops): Enable or disable Auto DevOps for your instance.
## Snippet settings
diff --git a/doc/administration/instance_limits.md b/doc/administration/instance_limits.md
index bfe59d5277b..3bedb6b01bd 100644
--- a/doc/administration/instance_limits.md
+++ b/doc/administration/instance_limits.md
@@ -151,7 +151,7 @@ Plan.default.actual_limits.update!(web_hook_calls: 10)
Set the limit to `0` to disable it.
-- **Default rate limit**: Disabled.
+- **Default rate limit**: Disabled (unlimited).
## Gitaly concurrency limit
@@ -230,10 +230,8 @@ There is a limit when embedding metrics in GitLab Flavored Markdown (GFM) for pe
## Number of webhooks
-On GitLab.com, the [maximum number of webhooks and their size](../user/gitlab_com/index.md#webhooks) per project, and per group, is limited.
-
-To set this limit for a self-managed installation, where the default is `100` project webhooks and `50` group webhooks, run the following in the
-[GitLab Rails console](operations/rails_console.md#starting-a-rails-console-session):
+To set the maximum number of group or project webhooks for a self-managed installation,
+run the following in the [GitLab Rails console](operations/rails_console.md#starting-a-rails-console-session):
```ruby
# If limits don't exist for the default plan, you can create one with:
@@ -248,6 +246,11 @@ Plan.default.actual_limits.update!(group_hooks: 100)
Set the limit to `0` to disable it.
+- **Default maximum number of webhooks**: `100` per project, `50` per group
+- **Maximum payload size**: 25 MB
+
+For GitLab.com, see the [webhook limits for GitLab.com](../user/gitlab_com/index.md#webhooks).
+
## Pull Mirroring Interval
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/237891) in GitLab 13.7.
@@ -640,7 +643,7 @@ To set this limit to `100` on a self-managed instance, run the following command
[GitLab Rails console](operations/rails_console.md#starting-a-rails-console-session):
```ruby
-Plan.default.actual_limits.update!(dotenv_variable_limit: 100)
+Plan.default.actual_limits.update!(dotenv_variables: 100)
```
This limit is [enabled on GitLab.com](../user/gitlab_com/index.md#gitlab-cicd).
@@ -658,7 +661,7 @@ To set this limit to 5KB on a self-managed installation, run the following in th
[GitLab Rails console](operations/rails_console.md#starting-a-rails-console-session):
```ruby
-Plan.default.actual_limits.update!(dotenv_size_limit: 5.kilobytes)
+Plan.default.actual_limits.update!(dotenv_size: 5.kilobytes)
```
## Instance monitoring and metrics
diff --git a/doc/administration/instance_review.md b/doc/administration/instance_review.md
index 872cdb239bd..f444589bdf3 100644
--- a/doc/administration/instance_review.md
+++ b/doc/administration/instance_review.md
@@ -4,26 +4,26 @@ group: Conversion
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Instance Review **(FREE SELF)**
+# Instance review **(FREE SELF)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/6995) in GitLab 11.3.
+If you run a self-managed instance with 50 or more users on the Free tier
+([either Community Edition or unlicensed Enterprise Edition](https://about.gitlab.com/install/ce-or-ee/)),
+you can request a free instance review.
-If you run a medium-sized self-managed instance (50+ users) of a free version of GitLab,
-[either Community Edition or unlicensed Enterprise Edition](https://about.gitlab.com/install/ce-or-ee/),
-you qualify for a free Instance Review.
+<!-- vale gitlab.FutureTense = NO -->
-1. Sign in as an administrator.
-1. In the top menu, click your user icon, and select
- **Get a free instance review**:
+After you submit the request, a GitLab team member will review your instance
+details and contact you with suggestions to improve your use of GitLab.
- ![Instance Review button](img/instance_review_button.png)
+<!-- vale gitlab.FutureTense = YES -->
-1. GitLab redirects you to a form with prefilled data obtained from your instance.
-1. Click **Submit** to see the initial report.
+To request an instance review:
-<!-- vale gitlab.FutureTense = NO -->
+1. Sign in as an administrator.
+1. On the top bar, in the top right corner, select your avatar.
+1. Select **Get a free instance review**.
-You will be contacted by a GitLab team member for further review, to provide suggestions
-intended to help you improve your usage of GitLab.
+ ![Instance review](img/instance_review_v14_7.png)
-<!-- vale gitlab.FutureTense = YES -->
+1. On the instance review page, enter your contact details.
+1. Select **Request Instance Review**.
diff --git a/doc/administration/job_artifacts.md b/doc/administration/job_artifacts.md
index 64b5ddbd165..62c403bfe43 100644
--- a/doc/administration/job_artifacts.md
+++ b/doc/administration/job_artifacts.md
@@ -6,7 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Jobs artifacts administration **(FREE SELF)**
-This is the administration documentation. For the user guide see [pipelines/job_artifacts](../ci/pipelines/job_artifacts.md).
+This is the administration documentation. To learn how to use job artifacts in your GitLab CI/CD pipeline,
+see the [job artifacts configuration documentation](../ci/pipelines/job_artifacts.md).
An artifact is a list of files and directories attached to a job after it
finishes. This feature is enabled by default in all GitLab installations.
diff --git a/doc/administration/job_logs.md b/doc/administration/job_logs.md
index f2748305c24..5c6ea7f52eb 100644
--- a/doc/administration/job_logs.md
+++ b/doc/administration/job_logs.md
@@ -150,8 +150,8 @@ server, these two locations on the file system have to be shared using NFS.
To eliminate both file system requirements:
-- [Enable the incremental logging feature](#enable-or-disable-incremental-logging), which uses Redis instead of disk space for temporary caching of job logs.
-- Configure [object storage](job_artifacts.md#object-storage-settings) for storing archived job logs.
+1. Configure [object storage](job_artifacts.md#object-storage-settings) for storing archived job logs.
+1. [Enable the incremental logging feature](#enable-or-disable-incremental-logging), which uses Redis instead of disk space for temporary caching of job logs.
### Technical details
diff --git a/doc/administration/logs.md b/doc/administration/logs.md
index 263fe699529..0d7635405d6 100644
--- a/doc/administration/logs.md
+++ b/doc/administration/logs.md
@@ -20,6 +20,54 @@ including adjusting log retention, log forwarding,
switching logs from JSON to plain text logging, and more.
- [How to parse and analyze JSON logs](troubleshooting/log_parsing.md).
+## Log Levels
+
+Each log message has an assigned log level that indicates its importance and verbosity.
+Each logger has an assigned minimum log level.
+A logger emits a log message only if its log level is equal to or above the minimum log level.
+
+The following log levels are supported:
+
+| Level | Name |
+|:------|:----------|
+| 0 | `DEBUG` |
+| 1 | `INFO` |
+| 2 | `WARN` |
+| 3 | `ERROR` |
+| 4 | `FATAL` |
+| 5 | `UNKNOWN` |
+
+GitLab loggers emit all log messages because they are set to `DEBUG` by default.
+
+### Override default log level
+
+You can override the minimum log level for GitLab loggers using the `GITLAB_LOG_LEVEL` environment variable.
+Valid values are either a value of `0` to `5`, or the name of the log level.
+
+Example:
+
+```shell
+GITLAB_LOG_LEVEL=info
+```
+
+For some services, other log levels are in place that are not affected by this setting.
+Some of these services have their own environment variables to override the log level. For example:
+
+| Service | Log level | Environment variable |
+|:---------------------|:----------|:---------------------|
+| GitLab API | `INFO` | |
+| GitLab Cleanup | `INFO` | `DEBUG` |
+| GitLab Doctor | `INFO` | `VERBOSE` |
+| GitLab Export | `INFO` | `EXPORT_DEBUG` |
+| GitLab Geo | `INFO` | |
+| GitLab Import | `INFO` | `IMPORT_DEBUG` |
+| GitLab QA Runtime | `ERROR` | `QA_DEBUG` |
+| Google APIs | `INFO` | |
+| Rack Timeout | `ERROR` | |
+| Sidekiq (server) | `INFO` | |
+| Snowplow Tracker | `FATAL` | |
+| gRPC Client (Gitaly) | `WARN` | `GRPC_LOG_LEVEL` |
+
## Log Rotation
The logs for a given service may be managed and rotated by:
@@ -36,26 +84,26 @@ are written to a file called `current`. The `logrotate` service built into GitLa
[manages all logs](https://docs.gitlab.com/omnibus/settings/logs.html#logrotate)
except those captured by `runit`.
-| Log type | Managed by logrotate | Managed by svlogd/runit |
-|-------------------------------------------------|------------------------|-------------------------|
-| [Alertmanager Logs](#alertmanager-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
-| [Crond Logs](#crond-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
-| [Gitaly](#gitaly-logs) | **{check-circle}** Yes | **{check-circle}** Yes |
-| [GitLab Exporter for Omnibus](#gitlab-exporter) | **{dotted-circle}** No | **{check-circle}** Yes |
-| [GitLab Pages Logs](#pages-logs) | **{check-circle}** Yes | **{check-circle}** Yes |
-| GitLab Rails | **{check-circle}** Yes | **{dotted-circle}** No |
-| [GitLab Shell Logs](#gitlab-shelllog) | **{check-circle}** Yes | **{dotted-circle}** No |
-| [Grafana Logs](#grafana-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
-| [LogRotate Logs](#logrotate-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
-| [Mailroom](#mail_room_jsonlog-default) | **{check-circle}** Yes | **{check-circle}** Yes |
-| [NGINX](#nginx-logs) | **{check-circle}** Yes | **{check-circle}** Yes |
-| [PostgreSQL Logs](#postgresql-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
-| [Praefect Logs](#praefect-logs) | **{dotted-circle}** Yes| **{check-circle}** Yes |
-| [Prometheus Logs](#prometheus-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
-| [Puma](#puma-logs) | **{check-circle}** Yes | **{check-circle}** Yes |
-| [Redis Logs](#redis-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
-| [Registry Logs](#registry-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
-| [Workhorse Logs](#workhorse-logs) | **{check-circle}** Yes | **{check-circle}** Yes |
+| Log type | Managed by logrotate | Managed by svlogd/runit |
+|:------------------------------------------------|:------------------------|:------------------------|
+| [Alertmanager Logs](#alertmanager-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
+| [Crond Logs](#crond-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
+| [Gitaly](#gitaly-logs) | **{check-circle}** Yes | **{check-circle}** Yes |
+| [GitLab Exporter for Omnibus](#gitlab-exporter) | **{dotted-circle}** No | **{check-circle}** Yes |
+| [GitLab Pages Logs](#pages-logs) | **{check-circle}** Yes | **{check-circle}** Yes |
+| GitLab Rails | **{check-circle}** Yes | **{dotted-circle}** No |
+| [GitLab Shell Logs](#gitlab-shelllog) | **{check-circle}** Yes | **{dotted-circle}** No |
+| [Grafana Logs](#grafana-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
+| [LogRotate Logs](#logrotate-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
+| [Mailroom](#mail_room_jsonlog-default) | **{check-circle}** Yes | **{check-circle}** Yes |
+| [NGINX](#nginx-logs) | **{check-circle}** Yes | **{check-circle}** Yes |
+| [PostgreSQL Logs](#postgresql-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
+| [Praefect Logs](#praefect-logs) | **{dotted-circle}** Yes | **{check-circle}** Yes |
+| [Prometheus Logs](#prometheus-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
+| [Puma](#puma-logs) | **{check-circle}** Yes | **{check-circle}** Yes |
+| [Redis Logs](#redis-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
+| [Registry Logs](#registry-logs) | **{dotted-circle}** No | **{check-circle}** Yes |
+| [Workhorse Logs](#workhorse-logs) | **{check-circle}** Yes | **{check-circle}** Yes |
## `production_json.log`
diff --git a/doc/administration/maintenance_mode/index.md b/doc/administration/maintenance_mode/index.md
index 2d17062e955..50c0f0ecc63 100644
--- a/doc/administration/maintenance_mode/index.md
+++ b/doc/administration/maintenance_mode/index.md
@@ -193,7 +193,8 @@ Replication and verification continues to work but proxied Git pushes to primary
### Secure features
-Features that depend on creating issues or creating or approving Merge Requests, do not work.
+Features that depend on creating issues or creating or approving merge requests,
+do not work.
Exporting a vulnerability list from a Vulnerability Report page does not work.
diff --git a/doc/administration/merge_request_diffs.md b/doc/administration/merge_request_diffs.md
index d6b9fa2b8d3..01576eb4abf 100644
--- a/doc/administration/merge_request_diffs.md
+++ b/doc/administration/merge_request_diffs.md
@@ -1,14 +1,11 @@
---
stage: Create
group: Editor
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference
+info: 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
---
# Merge request diffs storage **(FREE SELF)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/52568) in GitLab 11.8.
-
Merge request diffs are size-limited copies of diffs associated with merge
requests. When viewing a merge request, diffs are sourced from these copies
wherever possible as a performance optimization.
@@ -17,7 +14,8 @@ By default, merge request diffs are stored in the database, in a table named
`merge_request_diff_files`. Larger installations may find this table grows too
large, in which case, switching to external storage is recommended.
-Merge request diffs can be stored on disk, or in object storage. In general, it
+Merge request diffs can be stored [on disk](#using-external-storage), or in
+[object storage](#using-object-storage). In general, it
is better to store the diffs in the database than on disk. A compromise is available
that only [stores outdated diffs](#alternative-in-database-storage) outside of database.
@@ -41,6 +39,7 @@ that only [stores outdated diffs](#alternative-in-database-storage) outside of d
```
1. Save the file and [reconfigure GitLab](restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+ GitLab then migrates your existing merge request diffs to external storage.
**In installations from source:**
@@ -64,6 +63,7 @@ that only [stores outdated diffs](#alternative-in-database-storage) outside of d
```
1. Save the file and [restart GitLab](restart_gitlab.md#installations-from-source) for the changes to take effect.
+ GitLab then migrates your existing merge request diffs to external storage.
## Using object storage
@@ -84,6 +84,7 @@ be configured already.
1. Set [object storage settings](#object-storage-settings).
1. Save the file and [reconfigure GitLab](restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+ GitLab then migrates your existing merge request diffs to external storage.
**In installations from source:**
@@ -97,6 +98,7 @@ be configured already.
1. Set [object storage settings](#object-storage-settings).
1. Save the file and [restart GitLab](restart_gitlab.md#installations-from-source) for the changes to take effect.
+ GitLab then migrates your existing merge request diffs to external storage.
[Read more about using object storage with GitLab](object_storage.md).
diff --git a/doc/administration/monitoring/github_imports.md b/doc/administration/monitoring/github_imports.md
index cd35b8b3f9e..e91483eb79d 100644
--- a/doc/administration/monitoring/github_imports.md
+++ b/doc/administration/monitoring/github_imports.md
@@ -6,8 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Monitoring GitHub imports **(FREE SELF)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/14731) in GitLab 10.2.
-
The GitHub importer exposes various Prometheus metrics that you can use to
monitor the health and progress of the importer.
diff --git a/doc/administration/monitoring/ip_whitelist.md b/doc/administration/monitoring/ip_whitelist.md
index b6df176ea87..75b09f8a366 100644
--- a/doc/administration/monitoring/ip_whitelist.md
+++ b/doc/administration/monitoring/ip_whitelist.md
@@ -6,8 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# IP whitelist **(FREE SELF)**
-> Introduced in GitLab 9.4.
-
NOTE:
We intend to [rename IP whitelist as `IP allowlist`](https://gitlab.com/groups/gitlab-org/-/epics/3478).
diff --git a/doc/administration/monitoring/prometheus/gitlab_metrics.md b/doc/administration/monitoring/prometheus/gitlab_metrics.md
index 4a504b07a1b..c5b87afd94b 100644
--- a/doc/administration/monitoring/prometheus/gitlab_metrics.md
+++ b/doc/administration/monitoring/prometheus/gitlab_metrics.md
@@ -22,10 +22,8 @@ GitLab monitors its own internal service metrics, and makes them available at th
`/-/metrics` endpoint. Unlike other [Prometheus](https://prometheus.io) exporters, to access
the metrics, the client IP address must be [explicitly allowed](../ip_whitelist.md).
-For [Omnibus GitLab](https://docs.gitlab.com/omnibus/) and Chart installations,
-these metrics are enabled and collected as of
-[GitLab 9.4](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/1702).
-For source installations, these metrics must be enabled
+These metrics are enabled and collected for [Omnibus GitLab](https://docs.gitlab.com/omnibus/)
+and Chart installations. For source installations, these metrics must be enabled
manually and collected by a Prometheus server.
For enabling and viewing metrics from Sidekiq nodes, see [Sidekiq metrics](#sidekiq-metrics).
@@ -107,7 +105,7 @@ The following metrics are available:
| `pipelines_created_total` | Counter | 9.4 | Counter of pipelines created | |
| `rack_uncaught_errors_total` | Counter | 9.4 | Rack connections handling uncaught errors count | |
| `user_session_logins_total` | Counter | 9.4 | Counter of how many users have logged in since GitLab was started or restarted | |
-| `upload_file_does_not_exist` | Counter | 10.7 | Number of times an upload record could not find its file. Made available in all tiers in GitLab 11.5. | |
+| `upload_file_does_not_exist` | Counter | 10.7 | Number of times an upload record could not find its file. | |
| `failed_login_captcha_total` | Gauge | 11.0 | Counter of failed CAPTCHA attempts during login | |
| `successful_login_captcha_total` | Gauge | 11.0 | Counter of successful CAPTCHA attempts during login | |
| `auto_devops_pipelines_completed_total` | Counter | 12.7 | Counter of completed Auto DevOps pipelines, labeled by status | |
@@ -288,7 +286,7 @@ configuration option in `gitlab.yml`. These metrics are served from the
| `geo_uploads_verified` | Gauge | 14.6 | Number of uploads verified on secondary | `url` |
| `geo_uploads_verification_failed` | Gauge | 14.6 | Number of uploads verifications failed on secondary | `url` |
| `gitlab_sli:rails_request_apdex:total` | Counter | 14.4 | The number of request-apdex measurements, [more information the development documentation](../../../development/application_slis/rails_request_apdex.md) | `endpoint_id`, `feature_category`, `request_urgency` |
-| `gitlab_sli:rails_request_apdex:success_total` | Counter | 14.4 | The number of succesful requests that met the target duration for their urgency. Devide by `gitlab_sli:rails_requests_apdex:total` to get a success ratio | `endpoint_id`, `feature_category`, `request_urgency` |
+| `gitlab_sli:rails_request_apdex:success_total` | Counter | 14.4 | The number of successful requests that met the target duration for their urgency. Divide by `gitlab_sli:rails_requests_apdex:total` to get a success ratio | `endpoint_id`, `feature_category`, `request_urgency` |
## Database load balancing metrics **(PREMIUM SELF)**
diff --git a/doc/administration/monitoring/prometheus/index.md b/doc/administration/monitoring/prometheus/index.md
index 3268c0fc14c..acdcdb41dca 100644
--- a/doc/administration/monitoring/prometheus/index.md
+++ b/doc/administration/monitoring/prometheus/index.md
@@ -1,6 +1,6 @@
---
-stage: Monitor
-group: Monitor
+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
---
@@ -59,8 +59,8 @@ Although possible, it's not recommended to change the port Prometheus listens
on, as this might affect or conflict with other services running on the GitLab
server. Proceed at your own risk.
-To access Prometheus from outside the GitLab server, set an FQDN or IP in
-`prometheus['listen_address']`. To change the address/port that Prometheus
+To access Prometheus from outside the GitLab server,
+change the address/port that Prometheus
listens on:
1. Edit `/etc/gitlab/gitlab.rb`
diff --git a/doc/administration/monitoring/prometheus/pgbouncer_exporter.md b/doc/administration/monitoring/prometheus/pgbouncer_exporter.md
index d42c471ac71..aba1561500a 100644
--- a/doc/administration/monitoring/prometheus/pgbouncer_exporter.md
+++ b/doc/administration/monitoring/prometheus/pgbouncer_exporter.md
@@ -6,8 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# PgBouncer exporter **(FREE SELF)**
-> Introduced in [Omnibus GitLab 11.0](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/2493).
-
The [PgBouncer exporter](https://github.com/prometheus-community/pgbouncer_exporter) enables
you to measure various [PgBouncer](https://www.pgbouncer.org/) metrics.
diff --git a/doc/administration/monitoring/prometheus/registry_exporter.md b/doc/administration/monitoring/prometheus/registry_exporter.md
index 87b51aaed08..3a2acd47338 100644
--- a/doc/administration/monitoring/prometheus/registry_exporter.md
+++ b/doc/administration/monitoring/prometheus/registry_exporter.md
@@ -6,8 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Registry exporter **(FREE SELF)**
-> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/2884) in GitLab 11.9.
-
The Registry exporter allows you to measure various Registry metrics.
To enable it:
diff --git a/doc/administration/nfs.md b/doc/administration/nfs.md
index a0170e6c4ef..87a10a0ec04 100644
--- a/doc/administration/nfs.md
+++ b/doc/administration/nfs.md
@@ -12,6 +12,8 @@ recommended for performance reasons.
For data objects such as LFS, Uploads, Artifacts, and so on, an [Object Storage service](object_storage.md)
is recommended over NFS where possible, due to better performance.
+When eliminating the usage of NFS, there are [additional steps you need to take](object_storage.md#other-alternatives-to-file-system-storage)
+in addition to moving to Object Storage.
File system performance can impact overall GitLab performance, especially for
actions that read or write to Git repositories. For steps you can use to test
diff --git a/doc/administration/object_storage.md b/doc/administration/object_storage.md
index c6490e365a5..0976fc3684e 100644
--- a/doc/administration/object_storage.md
+++ b/doc/administration/object_storage.md
@@ -48,6 +48,9 @@ There are two ways of specifying object storage configuration in GitLab:
For more information on the differences and to transition from one form to another, see
[Transition to consolidated form](#transition-to-consolidated-form).
+If you are currently storing data locally, see
+[Migrate to object storage](#migrate-to-object-storage) for migration details.
+
### Consolidated object storage configuration
> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/4368) in GitLab 13.2.
@@ -485,9 +488,9 @@ This is the list of valid `objects` that can be used:
| `uploads` | [User uploads](uploads.md) |
| `lfs` | [Git Large File Storage objects](lfs/index.md) |
| `packages` | [Project packages (for example, PyPI, Maven, or NuGet)](packages/index.md) |
-| `dependency_proxy` | [GitLab Dependency Proxy](packages/dependency_proxy.md) |
+| `dependency_proxy` | [Dependency Proxy](packages/dependency_proxy.md) |
| `terraform_state` | [Terraform state files](terraform_state.md) |
-| `pages` | [GitLab Pages](pages/index.md) |
+| `pages` | [Pages](pages/index.md) |
Within each object type, three parameters can be defined:
@@ -514,6 +517,19 @@ no bucket is needed if CI artifacts are disabled with this setting:
gitlab_rails['artifacts_enabled'] = false
```
+### Migrate to object storage
+
+To migrate existing local data to object storage see the following guides:
+
+- [Job artifacts](job_artifacts.md#migrating-to-object-storage) including archived job logs
+- [LFS objects](lfs/index.md#migrating-to-object-storage)
+- [Uploads](raketasks/uploads/migrate.md#migrate-to-object-storage)
+- [Merge request diffs](merge_request_diffs.md#using-object-storage)
+- [Packages](packages/index.md#migrating-local-packages-to-object-storage) (optional feature)
+- Dependency Proxy - [migration not yet supported](https://gitlab.com/gitlab-org/gitlab/-/issues/343064)
+- [Terraform state files](terraform_state.md#migrate-to-object-storage)
+- [Pages content](pages/index.md#migrate-pages-deployments-to-object-storage)
+
### Transition to consolidated form
Prior to GitLab 13.2:
@@ -565,11 +581,11 @@ supported by consolidated configuration form, refer to the following guides:
| [Merge request diffs](merge_request_diffs.md#using-object-storage) | **{check-circle}** Yes |
| [Mattermost](https://docs.mattermost.com/administration/config-settings.html#file-storage)| **{dotted-circle}** No |
| [Packages](packages/index.md#using-object-storage) (optional feature) | **{check-circle}** Yes |
-| [Dependency Proxy](packages/dependency_proxy.md#using-object-storage) (optional feature) **(PREMIUM SELF)** | **{check-circle}** Yes |
+| [Dependency Proxy](packages/dependency_proxy.md#using-object-storage) (optional feature) | **{check-circle}** Yes |
| [Pseudonymizer](pseudonymizer.md) (optional feature) | **{dotted-circle}** No |
| [Autoscale runner caching](https://docs.gitlab.com/runner/configuration/autoscale.html#distributed-runners-caching) (optional for improved performance) | **{dotted-circle}** No |
| [Terraform state files](terraform_state.md#using-object-storage) | **{check-circle}** Yes |
-| [GitLab Pages content](pages/index.md#using-object-storage) | **{check-circle}** Yes |
+| [Pages content](pages/index.md#using-object-storage) | **{check-circle}** Yes |
### Other alternatives to file system storage
@@ -585,6 +601,12 @@ See the following additional guides:
## Warnings, limitations, and known issues
+### Objects are not included in GitLab backups
+
+As noted in [our backup documentation](../raketasks/backup_restore.md),
+objects are not included in GitLab backups. You can enable backups with
+your object storage provider instead.
+
### Use separate buckets
Using separate buckets for each data type is the recommended approach for GitLab.
diff --git a/doc/administration/operations/cleaning_up_redis_sessions.md b/doc/administration/operations/cleaning_up_redis_sessions.md
deleted file mode 100644
index ed5014b65e1..00000000000
--- a/doc/administration/operations/cleaning_up_redis_sessions.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: 'index.md'
-remove_date: '2021-12-10'
----
-
-This document was moved to [another location](index.md).
-
-<!-- This redirect file can be deleted after 2021-12-10. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/administration/operations/fast_ssh_key_lookup.md b/doc/administration/operations/fast_ssh_key_lookup.md
index c99f94589d7..ddedb3fe76a 100644
--- a/doc/administration/operations/fast_ssh_key_lookup.md
+++ b/doc/administration/operations/fast_ssh_key_lookup.md
@@ -27,13 +27,13 @@ lookup of authorized SSH keys.
WARNING:
OpenSSH version 6.9+ is required because `AuthorizedKeysCommand` must be
-able to accept a fingerprint. Check the version of OpenSSH on your server.
+able to accept a fingerprint. Check the version of OpenSSH on your server with `sshd -V`.
## Fast lookup is required for Geo **(PREMIUM)**
By default, GitLab manages an `authorized_keys` file that is located in the
`git` user's home directory. For most installations, this will be located under
-`/var/opt/gitlab/.ssh/authorized_keys`, but you can use the following command to locate the `authorized_keys` on your system.:
+`/var/opt/gitlab/.ssh/authorized_keys`, but you can use the following command to locate the `authorized_keys` on your system:
```shell
getent passwd git | cut -d: -f6 | awk '{print $1"/.ssh/authorized_keys"}'
@@ -77,9 +77,13 @@ sudo service sshd reload
```
Confirm that SSH is working by commenting out your user's key in the `authorized_keys`
-file (start the line with a `#` to comment it), and attempting to pull a repository.
+file (start the line with a `#` to comment it), and from your local machine, attempt to pull a repository or run:
-A successful pull would mean that GitLab was able to find the key in the database,
+```shell
+ssh -T git@gitlab.example.com
+```
+
+A successful pull or [welcome message](../../ssh/index.md#verify-that-you-can-connect) would mean that GitLab was able to find the key in the database,
since it is not present in the file anymore.
NOTE:
@@ -114,7 +118,7 @@ adding a new one, and attempting to pull a repository.
Then you can backup and delete your `authorized_keys` file for best performance.
The current users' keys are already present in the database, so there is no need for migration
-or for asking users to re-add their keys.
+or for users to re-add their keys.
## How to go back to using the `authorized_keys` file
diff --git a/doc/administration/operations/moving_repositories.md b/doc/administration/operations/moving_repositories.md
index 84e6dca1f2b..f0eb5792a96 100644
--- a/doc/administration/operations/moving_repositories.md
+++ b/doc/administration/operations/moving_repositories.md
@@ -184,8 +184,8 @@ Each of the approaches we list can or does overwrite data in the target director
### Recommended approach in all cases
-The GitLab [backup and restore capability](../../raketasks/backup_restore.md) should be used. Git
-repositories are accessed, managed, and stored on GitLab servers by Gitaly as a database. Data loss
+For either Gitaly or Gitaly Cluster targets, the GitLab [backup and restore capability](../../raketasks/backup_restore.md)
+should be used. Git repositories are accessed, managed, and stored on GitLab servers by Gitaly as a database. Data loss
can result from directly accessing and copying Gitaly's files using tools like `rsync`.
- From GitLab 13.3, backup performance can be improved by
@@ -193,13 +193,15 @@ can result from directly accessing and copying Gitaly's files using tools like `
- Backups can be created of just the repositories using the
[skip feature](../../raketasks/backup_restore.md#excluding-specific-directories-from-the-backup).
+No other method works for Gitaly Cluster targets.
+
### Target directory is empty: use a `tar` pipe
-If the target directory `/mnt/gitlab/repositories` is empty the
-simplest thing to do is to use a `tar` pipe. This method has low
-overhead and `tar` is almost always already installed on your system.
-However, it is not possible to resume an interrupted `tar` pipe: if
-that happens then all data must be copied again.
+For Gitaly targets (use [recommended approach](#recommended-approach-in-all-cases) for Gitaly Cluster targets), if the
+target directory `/mnt/gitlab/repositories` is empty the simplest thing to do is to use a `tar` pipe. This method has
+low overhead and `tar` is almost always already installed on your system.
+
+However, it is not possible to resume an interrupted `tar` pipe; if that happens then all data must be copied again.
```shell
sudo -u git sh -c 'tar -C /var/opt/gitlab/git-data/repositories -cf - -- . |\
@@ -210,9 +212,9 @@ If you want to see progress, replace `-xf` with `-xvf`.
#### `tar` pipe to another server
-You can also use a `tar` pipe to copy data to another server. If your
-`git` user has SSH access to the new server as `git@newserver`, you
-can pipe the data through SSH.
+For Gitaly targets (use [recommended approach](#recommended-approach-in-all-cases) for Gitaly Cluster targets), you can
+also use a `tar` pipe to copy data to another server. If your `git` user has SSH access to the new server as
+`git@newserver`, you can pipe the data through SSH.
```shell
sudo -u git sh -c 'tar -C /var/opt/gitlab/git-data/repositories -cf - -- . |\
@@ -228,11 +230,11 @@ WARNING:
Using `rsync` to migrate Git data can cause data loss and repository corruption.
[These instructions are being reviewed](https://gitlab.com/gitlab-org/gitlab/-/issues/270422).
-If the target directory already contains a partial / outdated copy
-of the repositories it may be wasteful to copy all the data again
-with `tar`. In this scenario it is better to use `rsync`. This utility
-is either already installed on your system, or installable
-by using `apt` or `yum`.
+If the target directory already contains a partial or outdated copy of the repositories it may be wasteful to copy all
+the data again with `tar`. In this scenario it is better to use `rsync` for Gitaly targets (use
+[recommended approach](#recommended-approach-in-all-cases) for Gitaly Cluster targets).
+
+This utility is either already installed on your system, or installable using `apt` or `yum`.
```shell
sudo -u git sh -c 'rsync -a --delete /var/opt/gitlab/git-data/repositories/. \
@@ -249,8 +251,9 @@ WARNING:
Using `rsync` to migrate Git data can cause data loss and repository corruption.
[These instructions are being reviewed](https://gitlab.com/gitlab-org/gitlab/-/issues/270422).
-If the `git` user on your source system has SSH access to the target
-server you can send the repositories over the network with `rsync`.
+For Gitaly targets (use [recommended approach](#recommended-approach-in-all-cases) for Gitaly Cluster targets), if the
+`git` user on your source system has SSH access to the target server you can send the repositories over the network with
+`rsync`.
```shell
sudo -u git sh -c 'rsync -a --delete /var/opt/gitlab/git-data/repositories/. \
@@ -269,17 +272,18 @@ Every time you start an `rsync` job it must:
- Inspect all files in the target directory.
- Decide whether or not to copy files.
-If the source or target directory
-has many contents, this startup phase of `rsync` can become a burden
-for your GitLab server. You can reduce the workload of `rsync` by dividing its
-work in smaller pieces, and sync one repository at a time.
+If the source or target directory has many contents, this startup phase of `rsync` can become a burden for your GitLab
+server. You can reduce the workload of `rsync` by dividing its work into smaller pieces, and sync one repository at a
+time.
In addition to `rsync` we use [GNU Parallel](http://www.gnu.org/software/parallel/).
This utility is not included in GitLab, so you must install it yourself with `apt`
or `yum`.
-This process does not clean up repositories at the target location that no
-longer exist at the source.
+This process:
+
+- Doesn't clean up repositories at the target location that no longer exist at the source.
+- Only works for Gitaly targets. Use [recommended approach](#recommended-approach-in-all-cases) for Gitaly Cluster targets.
#### Parallel `rsync` for all repositories known to GitLab
diff --git a/doc/administration/operations/rails_console.md b/doc/administration/operations/rails_console.md
index 8c366e311b8..a93365c08b2 100644
--- a/doc/administration/operations/rails_console.md
+++ b/doc/administration/operations/rails_console.md
@@ -35,7 +35,7 @@ sudo -u git -H bundle exec rails console -e production
**For Kubernetes deployments**
-The console is in the task-runner pod. Refer to our [Kubernetes cheat sheet](../troubleshooting/kubernetes_cheat_sheet.md#gitlab-specific-kubernetes-information) for details.
+The console is in the toolbox pod. Refer to our [Kubernetes cheat sheet](../troubleshooting/kubernetes_cheat_sheet.md#gitlab-specific-kubernetes-information) for details.
To exit the console, type: `quit`.
diff --git a/doc/administration/package_information/defaults.md b/doc/administration/package_information/defaults.md
index 95d6135c28c..54e68392aa5 100644
--- a/doc/administration/package_information/defaults.md
+++ b/doc/administration/package_information/defaults.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 defaults **(FREE SELF)**
@@ -14,42 +14,43 @@ the package will assume the defaults as noted below.
See the table below for the list of ports that the Omnibus GitLab assigns
by default:
-| Component | On by default | Communicates via | Alternative | Connection port |
-|:-------------------:|:-------------:|:----------------:|:-----------:|:------------------------------------------:|
-| GitLab Rails | Yes | Port | X | 80 or 443 |
-| GitLab Shell | Yes | Port | X | 22 |
-| PostgreSQL | Yes | Socket | Port (5432) | X |
-| Redis | Yes | Socket | Port (6379) | X |
-| Puma | Yes | Socket | Port (8080) | X |
-| GitLab Workhorse | Yes | Socket | Port (8181) | X |
-| NGINX status | Yes | Port | X | 8060 |
-| Prometheus | Yes | Port | X | 9090 |
-| Node exporter | Yes | Port | X | 9100 |
-| Redis exporter | Yes | Port | X | 9121 |
-| PostgreSQL exporter | Yes | Port | X | 9187 |
-| PgBouncer exporter | No | Port | X | 9188 |
-| GitLab Exporter | Yes | Port | X | 9168 |
-| Sidekiq exporter | Yes | Port | X | 8082 |
-| Puma exporter | No | Port | X | 8083 |
-| Geo PostgreSQL | No | Socket | Port (5431) | X |
-| Redis Sentinel | No | Port | X | 26379 |
-| Incoming email | No | Port | X | 143 |
-| Elastic search | No | Port | X | 9200 |
-| GitLab Pages | No | Port | X | 80 or 443 |
-| GitLab Registry | No* | Port | X | 80, 443 or 5050 |
-| GitLab Registry | No | Port | X | 5000 |
-| LDAP | No | Port | X | Depends on the component configuration |
-| Kerberos | No | Port | X | 8443 or 8088 |
-| OmniAuth | Yes | Port | X | Depends on the component configuration |
-| SMTP | No | Port | X | 465 |
-| Remote syslog | No | Port | X | 514 |
-| Mattermost | No | Port | X | 8065 |
-| Mattermost | No | Port | X | 80 or 443 |
-| PgBouncer | No | Port | X | 6432 |
-| Consul | No | Port | X | 8300, 8301(UDP), 8500, 8600[^Consul-notes] |
-| Patroni | No | Port | X | 8008 |
-| GitLab KAS | No | Port | X | 8150 |
-| Gitaly | No | Port | X | 8075 |
+| Component | On by default | Communicates via | Alternative | Connection port |
+|:--------------------:|:-------------:|:----------------:|:-----------:|:------------------------------------------:|
+| GitLab Rails | Yes | Port | X | 80 or 443 |
+| GitLab Shell | Yes | Port | X | 22 |
+| PostgreSQL | Yes | Socket | Port (5432) | X |
+| Redis | Yes | Socket | Port (6379) | X |
+| Puma | Yes | Socket | Port (8080) | X |
+| GitLab Workhorse | Yes | Socket | Port (8181) | X |
+| NGINX status | Yes | Port | X | 8060 |
+| Prometheus | Yes | Port | X | 9090 |
+| Node exporter | Yes | Port | X | 9100 |
+| Redis exporter | Yes | Port | X | 9121 |
+| PostgreSQL exporter | Yes | Port | X | 9187 |
+| PgBouncer exporter | No | Port | X | 9188 |
+| GitLab Exporter | Yes | Port | X | 9168 |
+| Sidekiq exporter | Yes | Port | X | 8082 |
+| Sidekiq health check | No | Port | X | 8092[^Sidekiq-health] |
+| Puma exporter | No | Port | X | 8083 |
+| Geo PostgreSQL | No | Socket | Port (5431) | X |
+| Redis Sentinel | No | Port | X | 26379 |
+| Incoming email | No | Port | X | 143 |
+| Elastic search | No | Port | X | 9200 |
+| GitLab Pages | No | Port | X | 80 or 443 |
+| GitLab Registry | No* | Port | X | 80, 443 or 5050 |
+| GitLab Registry | No | Port | X | 5000 |
+| LDAP | No | Port | X | Depends on the component configuration |
+| Kerberos | No | Port | X | 8443 or 8088 |
+| OmniAuth | Yes | Port | X | Depends on the component configuration |
+| SMTP | No | Port | X | 465 |
+| Remote syslog | No | Port | X | 514 |
+| Mattermost | No | Port | X | 8065 |
+| Mattermost | No | Port | X | 80 or 443 |
+| PgBouncer | No | Port | X | 6432 |
+| Consul | No | Port | X | 8300, 8301(UDP), 8500, 8600[^Consul-notes] |
+| Patroni | No | Port | X | 8008 |
+| GitLab KAS | No | Port | X | 8150 |
+| Gitaly | No | Port | X | 8075 |
Legend:
@@ -70,3 +71,5 @@ NOTE:
In some cases, the GitLab Registry will be automatically enabled by default. Please see [our documentation](../packages/container_registry.md) for more details
[^Consul-notes]: If using additional Consul functionality, more ports may need to be opened. See the [official documentation](https://www.consul.io/docs/install/ports#ports-table) for the list.
+
+ [^Sidekiq-health]: If Sidekiq health check settings are not set, they will default to the Sidekiq metrics exporter settings. This default is deprecated and is set to be removed in [GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/347509).
diff --git a/doc/administration/package_information/deprecation_policy.md b/doc/administration/package_information/deprecation_policy.md
index 905de387dcb..7298bce6c95 100644
--- a/doc/administration/package_information/deprecation_policy.md
+++ b/doc/administration/package_information/deprecation_policy.md
@@ -38,7 +38,7 @@ We can differentiate two different types of configuration:
- Sensitive: Configuration that can cause major service outage (like data integrity,
installation integrity, or preventing users from reaching the installation)
- Regular: Configuration that can make a feature unavailable but still makes the
- installation useable (like a change in default project/group settings, or
+ installation usable (like a change in default project/group settings, or
miscommunication with other components)
We also need to differentiate deprecation and removal procedure.
diff --git a/doc/administration/package_information/index.md b/doc/administration/package_information/index.md
index ab4b1edfa30..2781f789409 100644
--- a/doc/administration/package_information/index.md
+++ b/doc/administration/package_information/index.md
@@ -76,7 +76,7 @@ characters on each line.
## Init system detection
-Omnibus GitLab attempts to query the underlaying system in order to
+Omnibus GitLab attempts to query the underlying system in order to
check which init system it uses.
This manifests itself as a `WARNING` during the `sudo gitlab-ctl reconfigure`
run.
diff --git a/doc/administration/package_information/postgresql_versions.md b/doc/administration/package_information/postgresql_versions.md
index 252e0cad76d..97a35fb29ed 100644
--- a/doc/administration/package_information/postgresql_versions.md
+++ b/doc/administration/package_information/postgresql_versions.md
@@ -26,7 +26,7 @@ Read more about update policies and warnings in the PostgreSQL
| GitLab version | PostgreSQL versions | Default version for fresh installs | Default version for upgrades | Notes |
| -------------- | --------------------- | ---------------------------------- | ---------------------------- | ----- |
-| 14.1 | 12.6, 13.3 | 12.6 | 12.6 | PostgreSQL 13 available for fresh installations if not using Geo or High Availability. |
+| 14.1 | 12.6, 13.3 | 12.6 | 12.6 | PostgreSQL 13 available for fresh installations if not using [Geo](../geo/index.md#requirements-for-running-geo) or [Patroni](../postgresql/index.md#postgresql-replication-and-failover-with-omnibus-gitlab).
| 14.0 | 12.6 | 12.6 | 12.6 | HA installations with repmgr are no longer supported and will be prevented from upgrading to Omnibus GitLab 14.0 |
| 13.8 | 11.9, 12.4 | 12.4 | 12.4 | Package upgrades automatically performed PostgreSQL upgrade for nodes that are not part of a Geo or HA cluster.). |
| 13.7 | 11.9, 12.4 | 12.4 | 11.9 | For upgrades users can manually upgrade to 12.4 following the [upgrade docs](https://docs.gitlab.com/omnibus/settings/database.html#gitlab-133-and-later). |
diff --git a/doc/administration/package_information/supported_os.md b/doc/administration/package_information/supported_os.md
index fcc2fef3e63..78f496a3998 100644
--- a/doc/administration/package_information/supported_os.md
+++ b/doc/administration/package_information/supported_os.md
@@ -17,6 +17,7 @@ The following lists the currently supported OSs and their possible EOL dates.
| OS Version | First supported GitLab version | Arch | OS EOL | Details |
| ---------------- | ------------------------------ | --------------- | ------------- | ------------------------------------------------------------ |
+| AlmaLinux 8 | GitLab CE / GitLab EE 14.5.0 | x86_64, aarch64 | 2029 | <https://almalinux.org/> |
| CentOS 7 | GitLab CE / GitLab EE 7.10.0 | x86_64 | June 2024 | <https://wiki.centos.org/About/Product> |
| CentOS 8 | GitLab CE / GitLab EE 12.8.1 | x86_64, aarch64 | Dec 2021 | <https://wiki.centos.org/About/Product> |
| Debian 9 | GitLab CE / GitLab EE 9.3.0 | amd64 | 2022 | <https://wiki.debian.org/LTS> |
diff --git a/doc/administration/packages/container_registry.md b/doc/administration/packages/container_registry.md
index 0877fe510de..43293385ed9 100644
--- a/doc/administration/packages/container_registry.md
+++ b/doc/administration/packages/container_registry.md
@@ -694,7 +694,7 @@ project, you can [disable it from your project's settings](../../user/project/se
## Use an external container registry with GitLab as an auth endpoint
If you use an external container registry, some features associated with the
-container registry may be unavailable or have [inherent risks](../../user/packages/container_registry/index.md#use-with-external-container-registries).
+container registry may be unavailable or have [inherent risks](../../user/packages/container_registry/reduce_container_registry_storage.md#use-with-external-container-registries).
For the integration to work, the external registry must be configured to
use a JSON Web Token to authenticate with GitLab. The
@@ -883,7 +883,7 @@ project.container_repositories.find_each do |repo|
end
```
-You can also [run cleanup on a schedule](../../user/packages/container_registry/index.md#cleanup-policy).
+You can also [run cleanup on a schedule](../../user/packages/container_registry/reduce_container_registry_storage.md#cleanup-policy).
## Container Registry garbage collection
@@ -965,8 +965,6 @@ understand the implications.
### Removing untagged manifests and unreferenced layers
-> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/3097) in Omnibus GitLab 11.10.
-
WARNING:
This is a destructive operation.
@@ -1341,7 +1339,10 @@ Start with a value between `25000000` (25MB) and `50000000` (50MB).
### Supporting older Docker clients
-As of GitLab 11.9, we began shipping version 2.7.1 of the Docker container registry, which disables the schema1 manifest by default. If you are still using older Docker clients (1.9 or older), you may experience an error pushing images. See [omnibus-4145](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/4145) for more details.
+The Docker container registry shipped with GitLab disables the schema1 manifest
+by default. If you are still using older Docker clients (1.9 or older), you may
+experience an error pushing images. See
+[omnibus-4145](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/4145) for more details.
You can add a configuration option for backwards compatibility.
diff --git a/doc/administration/packages/dependency_proxy.md b/doc/administration/packages/dependency_proxy.md
index a394a32fc18..b3dc6ffc2b2 100644
--- a/doc/administration/packages/dependency_proxy.md
+++ b/doc/administration/packages/dependency_proxy.md
@@ -14,68 +14,84 @@ GitLab can be used as a dependency proxy for a variety of common package manager
This is the administration documentation. If you want to learn how to use the
dependency proxies, see the [user guide](../../user/packages/dependency_proxy/index.md).
-## Enabling the Dependency Proxy feature
+The GitLab Dependency Proxy:
-NOTE:
-Dependency proxy requires the Puma web server to be enabled.
+- Is turned on by default.
+- Can be turned off by an administrator.
+- Requires the [Puma web server](../operations/puma.md)
+ to be enabled. Puma is enabled by default in GitLab 13.0 and later.
-To enable the dependency proxy feature:
+## Turn off the Dependency Proxy
-**Omnibus GitLab installations**
+The Dependency Proxy is enabled by default. If you are an administrator, you
+can turn off the Dependency Proxy. To turn off the Dependency Proxy, follow the instructions that
+correspond to your GitLab installation:
+
+- [Omnibus GitLab installations](#omnibus-gitlab-installations)
+- [Helm chart installations](#helm-chart-installations)
+- [Installations from source](#installations-from-source)
+
+### Omnibus GitLab installations
1. Edit `/etc/gitlab/gitlab.rb` and add the following line:
```ruby
- gitlab_rails['dependency_proxy_enabled'] = true
+ gitlab_rails['dependency_proxy_enabled'] = false
```
-1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-1. Enable the [Puma web server](../operations/puma.md).
+1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure)
+ for the changes to take effect.
-**Helm chart installations**
+### Helm chart installations
-1. After the installation is complete, update the global `appConfig` to enable the feature:
+After the installation is complete, update the global `appConfig` to turn off the Dependency Proxy:
- ```yaml
- global:
- appConfig:
- dependencyProxy:
- enabled: true
- bucket: gitlab-dependency-proxy
- connection: {}
- secret:
- key:
- ```
+```yaml
+global:
+ appConfig:
+ dependencyProxy:
+ enabled: false
+ bucket: gitlab-dependency-proxy
+ connection: {}
+ secret:
+ key:
+```
For more information, see [Configure Charts using Globals](https://docs.gitlab.com/charts/charts/globals.html#configure-appconfig-settings).
-**Installations from source**
+### Installations from source
-1. After the installation is complete, configure the `dependency_proxy`
- section in `config/gitlab.yml`. Set to `true` to enable it:
+1. After the installation is complete, configure the `dependency_proxy` section in
+ `config/gitlab.yml`. Set `enabled` to `false` to turn off the Dependency Proxy:
```yaml
dependency_proxy:
- enabled: true
+ enabled: false
```
-1. [Restart GitLab](../restart_gitlab.md#installations-from-source "How to restart GitLab") for the changes to take effect.
+1. [Restart GitLab](../restart_gitlab.md#installations-from-source "How to restart GitLab")
+ for the changes to take effect.
+
+### Multi-node GitLab installations
-Since Puma is already the default web server for installations from source as of GitLab 12.9,
-no further changes are needed.
+Follow the steps for [Omnibus GitLab installations](#omnibus-gitlab-installations)
+for each Web and Sidekiq node.
-**Multi-node GitLab installations**
+## Turn on the Dependency Proxy
-Follow the steps for **Omnibus GitLab installation** for each Web and Sidekiq nodes.
+The Dependency Proxy is turned on by default, but can be turned off by an
+administrator. To turn on the Dependency Proxy, follow the instructions in
+[Turn off the Dependency Proxy](#turn-off-the-dependency-proxy),
+but set the `enabled` fields to `true`.
## Changing the storage path
-By default, the dependency proxy files are stored locally, but you can change the default
+By default, the Dependency Proxy files are stored locally, but you can change the default
local location or even use object storage.
### Changing the local storage path
-The dependency proxy files for Omnibus GitLab installations are stored under
+The Dependency Proxy files for Omnibus GitLab installations are stored under
`/var/opt/gitlab/gitlab-rails/shared/dependency_proxy/` and for source
installations under `shared/dependency_proxy/` (relative to the Git home directory).
To change the local storage path:
@@ -105,7 +121,7 @@ To change the local storage path:
### Using object storage
Instead of relying on the local storage, you can use an object storage to
-store the blobs of the dependency proxy.
+store the blobs of the Dependency Proxy.
[Read more about using object storage with GitLab](../object_storage.md).
@@ -199,5 +215,3 @@ Feature.disable(:dependency_proxy_for_private_groups)
# Re-enable the authentication
Feature.enable(:dependency_proxy_for_private_groups)
```
-
-The ability to disable this feature will be [removed in 13.9](https://gitlab.com/gitlab-org/gitlab/-/issues/276777).
diff --git a/doc/administration/pages/index.md b/doc/administration/pages/index.md
index f3ad474771c..53510688794 100644
--- a/doc/administration/pages/index.md
+++ b/doc/administration/pages/index.md
@@ -192,6 +192,33 @@ to use the HTTPS protocol.
WARNING:
Multiple wildcards for one instance is not supported. Only one wildcard per instance can be assigned.
+### Wildcard domains with TLS-terminating Load Balancer
+
+**Requirements:**
+
+- [Wildcard DNS setup](#dns-configuration)
+- [TLS-terminating load balancer](../../install/aws/manual_install_aws.md#load-balancer)
+
+---
+
+URL scheme: `https://<namespace>.example.io/<project_slug>`
+
+This setup is primarily intended to be used when [installing a GitLab POC on Amazon Web Services](../../install/aws/manual_install_aws.md). This includes a TLS-terminating [classic load balancer](../../install/aws/manual_install_aws.md#load-balancer) that listens for HTTPS connections, manages TLS certificates, and forwards HTTP traffic to the instance.
+
+1. In `/etc/gitlab/gitlab.rb` specify the following configuration:
+
+ ```ruby
+ external_url "https://gitlab.example.com" # external_url here is only for reference
+ pages_external_url "https://pages.example.com" # not a subdomain of external_url
+
+ pages_nginx['enable'] = true
+ pages_nginx['listen_port'] = 80
+ pages_nginx['listen_https'] = false
+ pages_nginx['redirect_http_to_https'] = true
+ ```
+
+1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+
### Global settings
Below is a table of all configuration settings known to Pages in Omnibus GitLab,
@@ -262,6 +289,8 @@ control over how the Pages daemon runs and serves content in your environment.
| `use_legacy_storage` | Temporarily-introduced parameter allowing to use legacy domain configuration source and storage. [Removed in 14.3](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/6166). |
| `rate_limit_source_ip` | Rate limit per source IP in number of requests per second. Set to `0` to disable this feature. |
| `rate_limit_source_ip_burst` | Rate limit per source IP maximum burst allowed per second. |
+| `rate_limit_domain` | Rate limit per domain in number of requests per second. Set to `0` to disable this feature. |
+| `rate_limit_domain_burst` | Rate limit per domain maximum burst allowed per second. |
## Advanced configuration
@@ -518,6 +547,14 @@ After an archive reaches `zip_cache_expiration`, it's marked as expired and remo
![ZIP cache configuration](img/zip_cache_configuration.png)
+### HTTP Strict Transport Security (HSTS) support
+
+HTTP Strict Transport Security (HSTS) can be enabled through the `gitlab_pages['headers']` configuration option. HSTS informs browsers that the website they are visiting should always provide its content over HTTPS to ensure that attackers cannot force subsequent connections to happen unencrypted. It can also improve loading speed of pages as it prevents browsers from attempting to connect over an unencrypted HTTP channel before being redirected to HTTPS.
+
+```ruby
+gitlab_pages['headers'] = ['Strict-Transport-Security: max-age=63072000']
+```
+
## Activate verbose logging for daemon
Follow the steps below to configure verbose logging of GitLab Pages daemon.
@@ -695,6 +732,9 @@ database encryption. Proceed with caution.
pages_external_url "http://<pages_server_URL>"
gitlab_pages['gitlab_server'] = 'http://<gitlab_server_IP_or_URL>'
+
+ ## If access control was enabled on step 3
+ gitlab_pages['access_control'] = true
```
1. If you have custom UID/GID settings on the **GitLab server**, add them to the **Pages server** `/etc/gitlab/gitlab.rb` as well,
@@ -717,7 +757,7 @@ database encryption. Proceed with caution.
mv /var/opt/gitlab/gitlab-rails/shared/pages/gitlab-secrets.json /etc/gitlab/gitlab-secrets.json
```
-1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+1. [Reconfigure the **Pages server**](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
1. On the **GitLab server**, make the following changes to `/etc/gitlab/gitlab.rb`:
@@ -727,7 +767,7 @@ database encryption. Proceed with caution.
pages_nginx['enable'] = false
```
-1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+1. [Reconfigure the **GitLab server**](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
It's possible to run GitLab Pages on multiple servers if you wish to distribute
the load. You can do this through standard load balancing practices such as
@@ -925,7 +965,7 @@ However, some projects may fail to be migrated for different reasons.
To verify that all projects have been migrated successfully, you can manually run the migration:
```shell
-gitlab-rake gitlab:pages:migrate_legacy_storage
+sudo gitlab-rake gitlab:pages:migrate_legacy_storage
```
It's safe to interrupt this task and run it multiple times.
@@ -1039,15 +1079,22 @@ than GitLab to prevent XSS attacks.
> [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/631) in GitLab 14.5.
-You can enforce source-IP rate limits to help minimize the risk of a Denial of Service (DoS) attack. GitLab Pages
+You can enforce rate limits to help minimize the risk of a Denial of Service (DoS) attack. GitLab Pages
uses a [token bucket algorithm](https://en.wikipedia.org/wiki/Token_bucket) to enforce rate limiting. By default,
requests that exceed the specified limits are reported but not rejected.
-Source-IP rate limits are enforced using the following:
+GitLab Pages supports the following types of rate limiting:
+
+- Per `source_ip`. It limits how many requests are allowed from the single client IP address.
+- Per `domain`. It limits how many requests are allowed per domain hosted on GitLab Pages. It can be a custom domain like `example.com`, or group domain like `group.gitlab.io`.
-- `rate_limit_source_ip`: Set the maximum threshold in number of requests per second. Set to 0 to disable this feature.
-- `rate_limit_source_ip_burst`: Sets the maximum threshold of number of requests allowed in an initial outburst of requests.
+Rate limits are enforced using the following:
+
+- `rate_limit_source_ip`: Set the maximum threshold in number of requests per client IP per second. Set to 0 to disable this feature.
+- `rate_limit_source_ip_burst`: Sets the maximum threshold of number of requests allowed in an initial outburst of requests per client IP.
For example, when you load a web page that loads a number of resources at the same time.
+- `rate_limit_domain_ip`: Set the maximum threshold in number of requests per hosted pages domain per second. Set to 0 to disable this feature.
+- `rate_limit_domain_burst`: Sets the maximum threshold of number of requests allowed in an initial outburst of requests per hosted pages domain.
#### Enable source-IP rate limits
@@ -1067,6 +1114,24 @@ Source-IP rate limits are enforced using the following:
1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+#### Enable domain rate limits
+
+1. Set rate limits in `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_pages['rate_limit_domain'] = 1000
+ gitlab_pages['rate_limit_domain_burst'] = 5000
+ ```
+
+1. To reject requests that exceed the specified limits, enable the `FF_ENFORCE_DOMAIN_RATE_LIMITS` feature flag in
+ `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_pages['env'] = {'FF_ENFORCE_DOMAIN_RATE_LIMITS' => 'true'}
+ ```
+
+1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
@@ -1282,6 +1347,15 @@ 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
+
+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.
+
+AWS [recommends using an IP target type](https://aws.amazon.com/premiumsupport/knowledge-center/target-connection-fails-load-balancer/)
+to resolve this issue.
+
### 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).
@@ -1332,8 +1406,11 @@ Once added, reconfigure with `sudo gitlab-ctl reconfigure` and restart GitLab wi
### `The redirect URI included is not valid.` when using Pages Access Control
-Verify that the **Callback URL**/Redirect URI in the GitLab Pages [System OAuth application](../../integration/oauth_provider.md#instance-wide-applications)
+You may see this error if `pages_external_url` was updated at some point of time. Verify the following:
+
+1. The **Callback URL**/Redirect URI in the GitLab Pages [System OAuth application](../../integration/oauth_provider.md#instance-wide-applications)
is using the protocol (HTTP or HTTPS) that `pages_external_url` is configured to use.
+1. The domain and path components of `Redirect URI` are valid: they should look like `projects.<pages_external_url>/auth`.
### 500 error `cannot serve from disk`
diff --git a/doc/administration/pages/source.md b/doc/administration/pages/source.md
index 45e9dadd1cf..c4b1756d8a1 100644
--- a/doc/administration/pages/source.md
+++ b/doc/administration/pages/source.md
@@ -35,16 +35,17 @@ In the case of [custom domains](#custom-domains) (but not
ports `80` and/or `443`. For that reason, there is some flexibility in the way
which you can set it up:
-1. Run the Pages daemon in the same server as GitLab, listening on a secondary IP.
-1. Run the Pages daemon in a separate server. In that case, the
- [Pages path](#change-storage-path) must also be present in the server that
- the Pages daemon is installed, so you must share it through the network.
-1. Run the Pages daemon in the same server as GitLab, listening on the same IP
- but on different ports. In that case, you must proxy the traffic with
- a load balancer. If you choose that route, you should use TCP load
- balancing for HTTPS. If you use TLS-termination (HTTPS-load balancing), the
- pages aren't able to be served with user-provided certificates. For
- HTTP, it's OK to use HTTP or TCP load balancing.
+- Run the Pages daemon in the same server as GitLab, listening on a secondary
+ IP.
+- Run the Pages daemon in a separate server. In that case, the
+ [Pages path](#change-storage-path) must also be present in the server that
+ the Pages daemon is installed, so you must share it through the network.
+- Run the Pages daemon in the same server as GitLab, listening on the same IP
+ but on different ports. In that case, you must proxy the traffic with a load
+ balancer. If you choose that route, you should use TCP load balancing for
+ HTTPS. If you use TLS-termination (HTTPS-load balancing), the pages aren't
+ able to be served with user-provided certificates. For HTTP, you can use HTTP
+ or TCP load balancing.
In this document, we proceed assuming the first option. If you aren't
supporting custom domains, a secondary IP isn't needed.
@@ -53,16 +54,16 @@ supporting custom domains, a secondary IP isn't needed.
Before proceeding with the Pages configuration, make sure that:
-1. You have a separate domain to serve GitLab Pages from. In
- this document we assume that to be `example.io`.
-1. You have configured a **wildcard DNS record** for that domain.
-1. You have installed the `zip` and `unzip` packages in the same server that
- GitLab is installed since they are needed to compress and decompress the
- Pages artifacts.
-1. Optional. You have a **wildcard certificate** for the Pages domain if you
- decide to serve Pages (`*.example.io`) under HTTPS.
-1. Optional but recommended. You have configured and enabled the [shared runners](../../ci/runners/index.md)
- so that your users don't have to bring their own.
+- You have a separate domain to serve GitLab Pages from. In this document we
+ assume that to be `example.io`.
+- You have configured a **wildcard DNS record** for that domain.
+- You have installed the `zip` and `unzip` packages in the same server that
+ GitLab is installed since they are needed to compress and decompress the
+ Pages artifacts.
+- Optional. You have a **wildcard certificate** for the Pages domain if you
+ decide to serve Pages (`*.example.io`) under HTTPS.
+- Optional but recommended. You have configured and enabled the [shared runners](../../ci/runners/index.md)
+ so your users don't have to bring their own.
### DNS configuration
@@ -417,8 +418,6 @@ server_name ~^.*\.pages\.example\.io$;
## Access control
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/33422) in GitLab 11.5.
-
GitLab Pages access control can be configured per-project, and allows access to a Pages
site to be controlled based on a user's membership to that project.
diff --git a/doc/administration/pseudonymizer.md b/doc/administration/pseudonymizer.md
index bd6982bea12..24d9792dcb0 100644
--- a/doc/administration/pseudonymizer.md
+++ b/doc/administration/pseudonymizer.md
@@ -4,7 +4,12 @@ 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
---
-# Pseudonymizer **(ULTIMATE)**
+# Pseudonymizer (DEPRECATED) **(ULTIMATE)**
+
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/219952) in GitLab 14.7.
+
+WARNING:
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/219952) in GitLab 14.7.
Your GitLab database contains sensitive information. To protect sensitive information
when you run analytics on your database, you can use the Pseudonymizer service, which:
diff --git a/doc/administration/raketasks/check.md b/doc/administration/raketasks/check.md
index 1d60b8c6f50..fba151fefe1 100644
--- a/doc/administration/raketasks/check.md
+++ b/doc/administration/raketasks/check.md
@@ -7,6 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Integrity check Rake task **(FREE SELF)**
GitLab provides Rake tasks to check the integrity of various components.
+See also the [check GitLab configuration Rake task](maintenance.md#check-gitlab-configuration).
## Repository integrity
@@ -118,9 +119,9 @@ and these checks verify them against current files.
Integrity checks are supported for the following types of file:
-- CI artifacts (Available from version 10.7.0)
-- LFS objects (Available from version 10.6.0)
-- User uploads (Available from version 10.6.0)
+- CI artifacts (introduced in GitLab 10.7.0)
+- LFS objects (introduced in GitLab 10.6.0)
+- User uploads (introduced in GitLab 10.6.0)
**Omnibus Installation**
@@ -200,6 +201,84 @@ The LDAP check Rake task tests the bind DN and password credentials
executed as part of the `gitlab:check` task, but can run independently.
See [LDAP Rake Tasks - LDAP Check](ldap.md#check) for details.
+## Verify database values can be decrypted using the current secrets
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20069) in GitLab 13.1.
+
+This task runs through all possible encrypted values in the
+database, verifying that they are decryptable using the current
+secrets file (`gitlab-secrets.json`).
+
+Automatic resolution is not yet implemented. If you have values that
+cannot be decrypted, you can follow steps to reset them, see our
+docs on what to do [when the secrets file is lost](../../raketasks/backup_restore.md#when-the-secrets-file-is-lost).
+
+This can take a very long time, depending on the size of your
+database, as it checks all rows in all tables.
+
+**Omnibus Installation**
+
+```shell
+sudo gitlab-rake gitlab:doctor:secrets
+```
+
+**Source Installation**
+
+```shell
+bundle exec rake gitlab:doctor:secrets RAILS_ENV=production
+```
+
+**Example output**
+
+```plaintext
+I, [2020-06-11T17:17:54.951815 #27148] INFO -- : Checking encrypted values in the database
+I, [2020-06-11T17:18:12.677708 #27148] INFO -- : - ApplicationSetting failures: 0
+I, [2020-06-11T17:18:12.823692 #27148] INFO -- : - User failures: 0
+[...] other models possibly containing encrypted data
+I, [2020-06-11T17:18:14.938335 #27148] INFO -- : - Group failures: 1
+I, [2020-06-11T17:18:15.559162 #27148] INFO -- : - Operations::FeatureFlagsClient failures: 0
+I, [2020-06-11T17:18:15.575533 #27148] INFO -- : - ScimOauthAccessToken failures: 0
+I, [2020-06-11T17:18:15.575678 #27148] INFO -- : Total: 1 row(s) affected
+I, [2020-06-11T17:18:15.575711 #27148] INFO -- : Done!
+```
+
+### Verbose mode
+
+To get more detailed information about which rows and columns can't be
+decrypted, you can pass a `VERBOSE` environment variable:
+
+**Omnibus Installation**
+
+```shell
+sudo gitlab-rake gitlab:doctor:secrets VERBOSE=1
+```
+
+**Source Installation**
+
+```shell
+bundle exec rake gitlab:doctor:secrets RAILS_ENV=production VERBOSE=1
+```
+
+**Example verbose output**
+
+<!-- vale gitlab.SentenceSpacing = NO -->
+
+```plaintext
+I, [2020-06-11T17:17:54.951815 #27148] INFO -- : Checking encrypted values in the database
+I, [2020-06-11T17:18:12.677708 #27148] INFO -- : - ApplicationSetting failures: 0
+I, [2020-06-11T17:18:12.823692 #27148] INFO -- : - User failures: 0
+[...] other models possibly containing encrypted data
+D, [2020-06-11T17:19:53.224344 #27351] DEBUG -- : > Something went wrong for Group[10].runners_token: Validation failed: Route can't be blank
+I, [2020-06-11T17:19:53.225178 #27351] INFO -- : - Group failures: 1
+D, [2020-06-11T17:19:53.225267 #27351] DEBUG -- : - Group[10]: runners_token
+I, [2020-06-11T17:18:15.559162 #27148] INFO -- : - Operations::FeatureFlagsClient failures: 0
+I, [2020-06-11T17:18:15.575533 #27148] INFO -- : - ScimOauthAccessToken failures: 0
+I, [2020-06-11T17:18:15.575678 #27148] INFO -- : Total: 1 row(s) affected
+I, [2020-06-11T17:18:15.575711 #27148] INFO -- : Done!
+```
+
+<!-- vale gitlab.SentenceSpacing = YES -->
+
## Troubleshooting
The following are solutions to problems you might discover using the Rake tasks documented
diff --git a/doc/administration/raketasks/doctor.md b/doc/administration/raketasks/doctor.md
index 02d1557b6a4..bed3cdcbcfe 100644
--- a/doc/administration/raketasks/doctor.md
+++ b/doc/administration/raketasks/doctor.md
@@ -1,88 +1,9 @@
---
-stage: Enablement
-group: Geo
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+redirect_to: 'check.md#verify-database-values-can-be-decrypted-using-the-current-secrets'
+remove_date: '2022-03-04'
---
-# Doctor Rake tasks **(FREE SELF)**
+This document was moved to [another location](check.md#verify-database-values-can-be-decrypted-using-the-current-secrets).
-This is a collection of tasks to help investigate and repair
-problems caused by data integrity issues.
-
-## Verify database values can be decrypted using the current secrets
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20069) in GitLab 13.1.
-
-This task runs through all possible encrypted values in the
-database, verifying that they are decryptable using the current
-secrets file (`gitlab-secrets.json`).
-
-Automatic resolution is not yet implemented. If you have values that
-cannot be decrypted, you can follow steps to reset them, see our
-docs on what to do [when the secrets file is lost](../../raketasks/backup_restore.md#when-the-secrets-file-is-lost).
-
-This can take a very long time, depending on the size of your
-database, as it checks all rows in all tables.
-
-**Omnibus Installation**
-
-```shell
-sudo gitlab-rake gitlab:doctor:secrets
-```
-
-**Source Installation**
-
-```shell
-bundle exec rake gitlab:doctor:secrets RAILS_ENV=production
-```
-
-**Example output**
-
-```plaintext
-I, [2020-06-11T17:17:54.951815 #27148] INFO -- : Checking encrypted values in the database
-I, [2020-06-11T17:18:12.677708 #27148] INFO -- : - ApplicationSetting failures: 0
-I, [2020-06-11T17:18:12.823692 #27148] INFO -- : - User failures: 0
-[...] other models possibly containing encrypted data
-I, [2020-06-11T17:18:14.938335 #27148] INFO -- : - Group failures: 1
-I, [2020-06-11T17:18:15.559162 #27148] INFO -- : - Operations::FeatureFlagsClient failures: 0
-I, [2020-06-11T17:18:15.575533 #27148] INFO -- : - ScimOauthAccessToken failures: 0
-I, [2020-06-11T17:18:15.575678 #27148] INFO -- : Total: 1 row(s) affected
-I, [2020-06-11T17:18:15.575711 #27148] INFO -- : Done!
-```
-
-### Verbose mode
-
-To get more detailed information about which rows and columns can't be
-decrypted, you can pass a `VERBOSE` environment variable:
-
-**Omnibus Installation**
-
-```shell
-sudo gitlab-rake gitlab:doctor:secrets VERBOSE=1
-```
-
-**Source Installation**
-
-```shell
-bundle exec rake gitlab:doctor:secrets RAILS_ENV=production VERBOSE=1
-```
-
-**Example verbose output**
-
-<!-- vale gitlab.SentenceSpacing = NO -->
-
-```plaintext
-I, [2020-06-11T17:17:54.951815 #27148] INFO -- : Checking encrypted values in the database
-I, [2020-06-11T17:18:12.677708 #27148] INFO -- : - ApplicationSetting failures: 0
-I, [2020-06-11T17:18:12.823692 #27148] INFO -- : - User failures: 0
-[...] other models possibly containing encrypted data
-D, [2020-06-11T17:19:53.224344 #27351] DEBUG -- : > Something went wrong for Group[10].runners_token: Validation failed: Route can't be blank
-I, [2020-06-11T17:19:53.225178 #27351] INFO -- : - Group failures: 1
-D, [2020-06-11T17:19:53.225267 #27351] DEBUG -- : - Group[10]: runners_token
-I, [2020-06-11T17:18:15.559162 #27148] INFO -- : - Operations::FeatureFlagsClient failures: 0
-I, [2020-06-11T17:18:15.575533 #27148] INFO -- : - ScimOauthAccessToken failures: 0
-I, [2020-06-11T17:18:15.575678 #27148] INFO -- : Total: 1 row(s) affected
-I, [2020-06-11T17:18:15.575711 #27148] INFO -- : Done!
-```
-
-<!-- vale gitlab.SentenceSpacing = YES -->
+<!-- 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 -->
diff --git a/doc/administration/raketasks/geo.md b/doc/administration/raketasks/geo.md
index 3112e5f61b1..6306e54bdc6 100644
--- a/doc/administration/raketasks/geo.md
+++ b/doc/administration/raketasks/geo.md
@@ -7,6 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Geo Rake Tasks **(PREMIUM SELF)**
The following Rake tasks are for [Geo installations](../geo/index.md).
+See also [troubleshooting Geo](../geo/replication/troubleshooting.md) for additional Geo Rake tasks.
## Git housekeeping
diff --git a/doc/administration/raketasks/ldap.md b/doc/administration/raketasks/ldap.md
index 62ddd9be2b3..e6adb98a92a 100644
--- a/doc/administration/raketasks/ldap.md
+++ b/doc/administration/raketasks/ldap.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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/raketasks/maintenance.md b/doc/administration/raketasks/maintenance.md
index 950b508ab0c..d66f3b1ed35 100644
--- a/doc/administration/raketasks/maintenance.md
+++ b/doc/administration/raketasks/maintenance.md
@@ -106,17 +106,22 @@ The `gitlab:check` Rake task runs the following Rake tasks:
- `gitlab:gitlab_shell:check`
- `gitlab:gitaly:check`
- `gitlab:sidekiq:check`
+- `gitlab:incoming_email:check`
+- `gitlab:ldap:check`
- `gitlab:app:check`
It checks that each component was set up according to the installation guide and suggest fixes
for issues found. This command must be run from your application server and doesn't work correctly on
component servers like [Gitaly](../gitaly/configure_gitaly.md#run-gitaly-on-its-own-server).
+If you're running Geo, see also the [Geo Health check Rake task](../geo/replication/troubleshooting.md#health-check-rake-task).
You may also have a look at our troubleshooting guides for:
- [GitLab](../index.md#troubleshooting)
- [Omnibus GitLab](https://docs.gitlab.com/omnibus/index.html#troubleshooting)
+Additionally you should also [verify database values can be decrypted using the current secrets](check.md#verify-database-values-can-be-decrypted-using-the-current-secrets).
+
To run `gitlab:check`, run:
**Omnibus Installation**
diff --git a/doc/administration/redis/replication_and_failover.md b/doc/administration/redis/replication_and_failover.md
index db652a80780..086057d80b4 100644
--- a/doc/administration/redis/replication_and_failover.md
+++ b/doc/administration/redis/replication_and_failover.md
@@ -648,6 +648,7 @@ persistence classes.
| `actioncable` | Pub/Sub queue backend for ActionCable. |
| `trace_chunks` | Store [CI trace chunks](../job_logs.md#enable-or-disable-incremental-logging) data. |
| `rate_limiting` | Store [rate limiting](../../user/admin_area/settings/user_and_ip_rate_limits.md) state. |
+| `sessions` | Store [sessions](../../../ee/development/session.md#gitlabsession). |
To make this work with Sentinel:
@@ -661,6 +662,7 @@ To make this work with Sentinel:
gitlab_rails['redis_actioncable_instance'] = REDIS_ACTIONCABLE_URL
gitlab_rails['redis_trace_chunks_instance'] = REDIS_TRACE_CHUNKS_URL
gitlab_rails['redis_rate_limiting_instance'] = REDIS_RATE_LIMITING_URL
+ gitlab_rails['redis_sessions_instance'] = REDIS_SESSIONS_URL
# Configure the Sentinels
gitlab_rails['redis_cache_sentinels'] = [
@@ -687,6 +689,10 @@ To make this work with Sentinel:
{ host: RATE_LIMITING_SENTINEL_HOST, port: 26379 },
{ host: RATE_LIMITING_SENTINEL_HOST2, port: 26379 }
]
+ gitlab_rails['redis_sessions_sentinels'] = [
+ { host: SESSIONS_SENTINEL_HOST, port: 26379 },
+ { host: SESSIONS_SENTINEL_HOST2, port: 26379 }
+ ]
```
- Redis URLs should be in the format: `redis://:PASSWORD@SENTINEL_PRIMARY_NAME`, where:
diff --git a/doc/administration/reference_architectures/10k_users.md b/doc/administration/reference_architectures/10k_users.md
index fa8dfdf667b..a5c60af47b1 100644
--- a/doc/administration/reference_architectures/10k_users.md
+++ b/doc/administration/reference_architectures/10k_users.md
@@ -1833,7 +1833,7 @@ On each node perform the following:
external_url 'https://gitlab.example.com'
# git_data_dirs get configured for the Praefect virtual storage
- # Address is Interal Load Balancer for Praefect
+ # Address is Internal Load Balancer for Praefect
# Token is praefect_external_token
git_data_dirs({
"default" => {
@@ -2228,17 +2228,16 @@ use Google Cloud's Kubernetes Engine (GKE) and associated machine types, but the
and CPU requirements should translate to most other providers. We hope to update this in the
future with further specific cloud provider details.
-| Service | Nodes<sup>1</sup> | Configuration | GCP | Allocatable CPUs and Memory |
-|-------------------------------------------------------|-------------------|-------------------------|------------------|-----------------------------|
-| Webservice | 4 | 32 vCPU, 28.8 GB memory | `n1-highcpu-32` | 127.5 vCPU, 118 GB memory |
-| Sidekiq | 4 | 4 vCPU, 15 GB memory | `n1-standard-4` | 15.5 vCPU, 50 GB memory |
-| Supporting services such as NGINX, Prometheus | 2 | 4 vCPU, 15 GB memory | `n1-standard-4` | 7.75 vCPU, 25 GB memory |
+| Service | Nodes | Configuration | GCP | Allocatable CPUs and Memory |
+|-------------------------------------------------------|-------|-------------------------|------------------|-----------------------------|
+| Webservice | 4 | 32 vCPU, 28.8 GB memory | `n1-highcpu-32` | 127.5 vCPU, 118 GB memory |
+| Sidekiq | 4 | 4 vCPU, 15 GB memory | `n1-standard-4` | 15.5 vCPU, 50 GB memory |
+| Supporting services such as NGINX, Prometheus | 2 | 4 vCPU, 15 GB memory | `n1-standard-4` | 7.75 vCPU, 25 GB memory |
-<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
-<!-- markdownlint-disable MD029 -->
-1. Nodes configuration is shown as it is forced to ensure pod vcpu / memory ratios and avoid scaling during **performance testing**.
- In production deployments there is no need to assign pods to nodes. A minimum of three nodes in three different availability zones is strongly recommended to align with resilient cloud architecture practices.
-<!-- markdownlint-enable MD029 -->
+- For this setup, we **recommend** and regularly [test](index.md#testing-process-and-results)
+[Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary.
+- Nodes configuration is shown as it is forced to ensure pod vcpu / memory ratios and avoid scaling during **performance testing**.
+ - In production deployments, there is no need to assign pods to nodes. A minimum of three nodes in three different availability zones is strongly recommended to align with resilient cloud architecture practices.
Next are the backend components that run on static compute VMs via Omnibus (or External PaaS
services where applicable):
diff --git a/doc/administration/reference_architectures/25k_users.md b/doc/administration/reference_architectures/25k_users.md
index 24b3350bd75..8cc355db951 100644
--- a/doc/administration/reference_architectures/25k_users.md
+++ b/doc/administration/reference_architectures/25k_users.md
@@ -26,7 +26,7 @@ full list of reference architectures, see
| PgBouncer<sup>1</sup> | 3 | 2 vCPU, 1.8 GB memory | `n1-highcpu-2` | `c5.large` | `F2s v2` |
| Internal load balancing node<sup>3</sup> | 1 | 4 vCPU, 3.6GB memory | `n1-highcpu-4` | `c5.large` | `F2s v2` |
| Redis/Sentinel - Cache<sup>2</sup> | 3 | 4 vCPU, 15 GB memory | `n1-standard-4` | `m5.xlarge` | `D4s v3` |
-| Redis/Sentinel - Persistent<sup>2</sup> | 3 | 4 vCPU, 15 GB memory | `n1-standard-4` | `m5.large` | `D4s v3` |
+| Redis/Sentinel - Persistent<sup>2</sup> | 3 | 4 vCPU, 15 GB memory | `n1-standard-4` | `m5.xlarge` | `D4s v3` |
| Gitaly<sup>5</sup> | 3 | 32 vCPU, 120 GB memory | `n1-standard-32` | `m5.8xlarge` | `D32s v3` |
| Praefect<sup>5</sup> | 3 | 4 vCPU, 3.6 GB memory | `n1-highcpu-4` | `c5.xlarge` | `F4s v2` |
| Praefect PostgreSQL<sup>1</sup> | 1+ | 2 vCPU, 1.8 GB memory | `n1-highcpu-2` | `c5.large` | `F2s v2` |
@@ -2226,17 +2226,16 @@ use Google Cloud's Kubernetes Engine (GKE) and associated machine types, but the
and CPU requirements should translate to most other providers. We hope to update this in the
future with further specific cloud provider details.
-| Service | Nodes<sup>1</sup> | Configuration | GCP | Allocatable CPUs and Memory |
-|-------------------------------------------------------|-------------------|-------------------------|------------------|-----------------------------|
-| Webservice | 7 | 32 vCPU, 28.8 GB memory | `n1-highcpu-32` | 223 vCPU, 206.5 GB memory |
-| Sidekiq | 4 | 4 vCPU, 15 GB memory | `n1-standard-4` | 15.5 vCPU, 50 GB memory |
-| Supporting services such as NGINX, Prometheus | 2 | 4 vCPU, 15 GB memory | `n1-standard-4` | 7.75 vCPU, 25 GB memory |
+| Service | Nodes | Configuration | GCP | Allocatable CPUs and Memory |
+|-------------------------------------------------------|-------|-------------------------|------------------|-----------------------------|
+| Webservice | 7 | 32 vCPU, 28.8 GB memory | `n1-highcpu-32` | 223 vCPU, 206.5 GB memory |
+| Sidekiq | 4 | 4 vCPU, 15 GB memory | `n1-standard-4` | 15.5 vCPU, 50 GB memory |
+| Supporting services such as NGINX, Prometheus | 2 | 4 vCPU, 15 GB memory | `n1-standard-4` | 7.75 vCPU, 25 GB memory |
-<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
-<!-- markdownlint-disable MD029 -->
-1. Nodes configuration is shown as it is forced to ensure pod vcpu / memory ratios and avoid scaling during **performance testing**.
- In production deployments there is no need to assign pods to nodes. A minimum of three nodes in three different availability zones is strongly recommended to align with resilient cloud architecture practices.
-<!-- markdownlint-enable MD029 -->
+- For this setup, we **recommend** and regularly [test](index.md#testing-process-and-results)
+[Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary.
+- Nodes configuration is shown as it is forced to ensure pod vcpu / memory ratios and avoid scaling during **performance testing**.
+ - In production deployments, there is no need to assign pods to nodes. A minimum of three nodes in three different availability zones is strongly recommended to align with resilient cloud architecture practices.
Next are the backend components that run on static compute VMs via Omnibus (or External PaaS
services where applicable):
diff --git a/doc/administration/reference_architectures/2k_users.md b/doc/administration/reference_architectures/2k_users.md
index f72c0877ddb..467c64b8279 100644
--- a/doc/administration/reference_architectures/2k_users.md
+++ b/doc/administration/reference_architectures/2k_users.md
@@ -1016,17 +1016,16 @@ use Google Cloud's Kubernetes Engine (GKE) and associated machine types, but the
and CPU requirements should translate to most other providers. We hope to update this in the
future with further specific cloud provider details.
-| Service | Nodes<sup>1</sup> | Configuration | GCP | Allocatable CPUs and Memory |
-|-------------------------------------------------------|-------------------|------------------------|-----------------|-----------------------------|
-| Webservice | 3 | 8 vCPU, 7.2 GB memory | `n1-highcpu-8` | 23.7 vCPU, 16.9 GB memory |
-| Sidekiq | 2 | 2 vCPU, 7.5 GB memory | `n1-standard-2` | 3.9 vCPU, 11.8 GB memory |
-| Supporting services such as NGINX, Prometheus | 2 | 1 vCPU, 3.75 GB memory | `n1-standard-1` | 1.9 vCPU, 5.5 GB memory |
-
-<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
-<!-- markdownlint-disable MD029 -->
-1. Nodes configuration is shown as it is forced to ensure pod vcpu / memory ratios and avoid scaling during **performance testing**.
- In production deployments there is no need to assign pods to nodes. A minimum of three nodes in three different availability zones is strongly recommended to align with resilient cloud architecture practices.
-<!-- markdownlint-enable MD029 -->
+| Service | Nodes | Configuration | GCP | Allocatable CPUs and Memory |
+|-------------------------------------------------------|-------|------------------------|-----------------|-----------------------------|
+| Webservice | 3 | 8 vCPU, 7.2 GB memory | `n1-highcpu-8` | 23.7 vCPU, 16.9 GB memory |
+| Sidekiq | 2 | 2 vCPU, 7.5 GB memory | `n1-standard-2` | 3.9 vCPU, 11.8 GB memory |
+| Supporting services such as NGINX, Prometheus | 2 | 1 vCPU, 3.75 GB memory | `n1-standard-1` | 1.9 vCPU, 5.5 GB memory |
+
+- For this setup, we **recommend** and regularly [test](index.md#testing-process-and-results)
+[Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary.
+- Nodes configuration is shown as it is forced to ensure pod vcpu / memory ratios and avoid scaling during **performance testing**.
+ - In production deployments, there is no need to assign pods to nodes. A minimum of three nodes in three different availability zones is strongly recommended to align with resilient cloud architecture practices.
Next are the backend components that run on static compute VMs via Omnibus (or External PaaS
services where applicable):
diff --git a/doc/administration/reference_architectures/3k_users.md b/doc/administration/reference_architectures/3k_users.md
index c788a73753b..01d9987739b 100644
--- a/doc/administration/reference_architectures/3k_users.md
+++ b/doc/administration/reference_architectures/3k_users.md
@@ -1794,7 +1794,7 @@ On each node perform the following:
external_url 'https://gitlab.example.com'
# git_data_dirs get configured for the Praefect virtual storage
- # Address is Interal Load Balancer for Praefect
+ # Address is Internal Load Balancer for Praefect
# Token is praefect_external_token
git_data_dirs({
"default" => {
@@ -2185,17 +2185,16 @@ use Google Cloud's Kubernetes Engine (GKE) and associated machine types, but the
and CPU requirements should translate to most other providers. We hope to update this in the
future with further specific cloud provider details.
-| Service | Nodes<sup>1</sup> | Configuration | GCP | Allocatable CPUs and Memory |
-|-------------------------------------------------------|-------------------|-------------------------|------------------|-----------------------------|
-| Webservice | 2 | 16 vCPU, 14.4 GB memory | `n1-highcpu-16` | 31.8 vCPU, 24.8 GB memory |
-| Sidekiq | 3 | 4 vCPU, 15 GB memory | `n1-standard-4` | 11.8 vCPU, 38.9 GB memory |
-| Supporting services such as NGINX, Prometheus | 2 | 2 vCPU, 7.5 GB memory | `n1-standard-2` | 3.9 vCPU, 11.8 GB memory |
+| Service | Nodes | Configuration | GCP | Allocatable CPUs and Memory |
+|-------------------------------------------------------|-------|-------------------------|------------------|-----------------------------|
+| Webservice | 2 | 16 vCPU, 14.4 GB memory | `n1-highcpu-16` | 31.8 vCPU, 24.8 GB memory |
+| Sidekiq | 3 | 4 vCPU, 15 GB memory | `n1-standard-4` | 11.8 vCPU, 38.9 GB memory |
+| Supporting services such as NGINX, Prometheus | 2 | 2 vCPU, 7.5 GB memory | `n1-standard-2` | 3.9 vCPU, 11.8 GB memory |
-<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
-<!-- markdownlint-disable MD029 -->
-1. Nodes configuration is shown as it is forced to ensure pod vcpu / memory ratios and avoid scaling during **performance testing**.
- In production deployments there is no need to assign pods to nodes. A minimum of three nodes in three different availability zones is strongly recommended to align with resilient cloud architecture practices.
-<!-- markdownlint-enable MD029 -->
+- For this setup, we **recommend** and regularly [test](index.md#testing-process-and-results)
+[Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary.
+- Nodes configuration is shown as it is forced to ensure pod vcpu / memory ratios and avoid scaling during **performance testing**.
+ - In production deployments, there is no need to assign pods to nodes. A minimum of three nodes in three different availability zones is strongly recommended to align with resilient cloud architecture practices.
Next are the backend components that run on static compute VMs via Omnibus (or External PaaS
services where applicable):
diff --git a/doc/administration/reference_architectures/50k_users.md b/doc/administration/reference_architectures/50k_users.md
index 4f576fc1c19..d5bb9c4ad64 100644
--- a/doc/administration/reference_architectures/50k_users.md
+++ b/doc/administration/reference_architectures/50k_users.md
@@ -1855,7 +1855,7 @@ On each node perform the following:
external_url 'https://gitlab.example.com'
# git_data_dirs get configured for the Praefect virtual storage
- # Address is Interal Load Balancer for Praefect
+ # Address is Internal Load Balancer for Praefect
# Token is praefect_external_token
git_data_dirs({
"default" => {
@@ -2242,17 +2242,16 @@ use Google Cloud's Kubernetes Engine (GKE) and associated machine types, but the
and CPU requirements should translate to most other providers. We hope to update this in the
future with further specific cloud provider details.
-| Service | Nodes<sup>1</sup> | Configuration | GCP | Allocatable CPUs and Memory |
-|-------------------------------------------------------|-------------------|-------------------------|------------------|-----------------------------|
-| Webservice | 16 | 32 vCPU, 28.8 GB memory | `n1-highcpu-32` | 510 vCPU, 472 GB memory |
-| Sidekiq | 4 | 4 vCPU, 15 GB memory | `n1-standard-4` | 15.5 vCPU, 50 GB memory |
-| Supporting services such as NGINX, Prometheus | 2 | 4 vCPU, 15 GB memory | `n1-standard-4` | 7.75 vCPU, 25 GB memory |
+| Service | Nodes | Configuration | GCP | Allocatable CPUs and Memory |
+|-------------------------------------------------------|-------|-------------------------|------------------|-----------------------------|
+| Webservice | 16 | 32 vCPU, 28.8 GB memory | `n1-highcpu-32` | 510 vCPU, 472 GB memory |
+| Sidekiq | 4 | 4 vCPU, 15 GB memory | `n1-standard-4` | 15.5 vCPU, 50 GB memory |
+| Supporting services such as NGINX, Prometheus | 2 | 4 vCPU, 15 GB memory | `n1-standard-4` | 7.75 vCPU, 25 GB memory |
-<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
-<!-- markdownlint-disable MD029 -->
-1. Nodes configuration is shown as it is forced to ensure pod vcpu / memory ratios and avoid scaling during **performance testing**.
- In production deployments there is no need to assign pods to nodes. A minimum of three nodes in three different availability zones is strongly recommended to align with resilient cloud architecture practices.
-<!-- markdownlint-enable MD029 -->
+- For this setup, we **recommend** and regularly [test](index.md#testing-process-and-results)
+[Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary.
+- Nodes configuration is shown as it is forced to ensure pod vcpu / memory ratios and avoid scaling during **performance testing**.
+ - In production deployments, there is no need to assign pods to nodes. A minimum of three nodes in three different availability zones is strongly recommended to align with resilient cloud architecture practices.
Next are the backend components that run on static compute VMs via Omnibus (or External PaaS
services where applicable):
diff --git a/doc/administration/reference_architectures/5k_users.md b/doc/administration/reference_architectures/5k_users.md
index 92950806cfb..33ca4e4899f 100644
--- a/doc/administration/reference_architectures/5k_users.md
+++ b/doc/administration/reference_architectures/5k_users.md
@@ -1791,7 +1791,7 @@ On each node perform the following:
external_url 'https://gitlab.example.com'
# git_data_dirs get configured for the Praefect virtual storage
- # Address is Interal Load Balancer for Praefect
+ # Address is Internal Load Balancer for Praefect
# Token is praefect_external_token
git_data_dirs({
"default" => {
@@ -2161,17 +2161,16 @@ use Google Cloud's Kubernetes Engine (GKE) and associated machine types, but the
and CPU requirements should translate to most other providers. We hope to update this in the
future with further specific cloud provider details.
-| Service | Nodes<sup>1</sup> | Configuration | GCP | Allocatable CPUs and Memory |
-|-------------------------------------------------------|-------------------|-------------------------|------------------|-----------------------------|
-| Webservice | 5 | 16 vCPU, 14.4 GB memory | `n1-highcpu-16` | 79.5 vCPU, 62 GB memory |
-| Sidekiq | 3 | 4 vCPU, 15 GB memory | `n1-standard-4` | 11.8 vCPU, 38.9 GB memory |
-| Supporting services such as NGINX, Prometheus | 2 | 2 vCPU, 7.5 GB memory | `n1-standard-2` | 3.9 vCPU, 11.8 GB memory |
+| Service | Nodes | Configuration | GCP | Allocatable CPUs and Memory |
+|-------------------------------------------------------|-------|-------------------------|------------------|-----------------------------|
+| Webservice | 5 | 16 vCPU, 14.4 GB memory | `n1-highcpu-16` | 79.5 vCPU, 62 GB memory |
+| Sidekiq | 3 | 4 vCPU, 15 GB memory | `n1-standard-4` | 11.8 vCPU, 38.9 GB memory |
+| Supporting services such as NGINX, Prometheus | 2 | 2 vCPU, 7.5 GB memory | `n1-standard-2` | 3.9 vCPU, 11.8 GB memory |
-<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
-<!-- markdownlint-disable MD029 -->
-1. Nodes configuration is shown as it is forced to ensure pod vcpu / memory ratios and avoid scaling during **performance testing**.
- In production deployments there is no need to assign pods to nodes. A minimum of three nodes in three different availability zones is strongly recommended to align with resilient cloud architecture practices.
-<!-- markdownlint-enable MD029 -->
+- For this setup, we **recommend** and regularly [test](index.md#testing-process-and-results)
+[Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary.
+- Nodes configuration is shown as it is forced to ensure pod vcpu / memory ratios and avoid scaling during **performance testing**.
+ - In production deployments, there is no need to assign pods to nodes. A minimum of three nodes in three different availability zones is strongly recommended to align with resilient cloud architecture practices.
Next are the backend components that run on static compute VMs via Omnibus (or External PaaS
services where applicable):
diff --git a/doc/administration/reference_architectures/index.md b/doc/administration/reference_architectures/index.md
index 6bf35ba6e22..bd796600564 100644
--- a/doc/administration/reference_architectures/index.md
+++ b/doc/administration/reference_architectures/index.md
@@ -208,19 +208,16 @@ Note the following about the testing process:
- We aim to have a "test smart" approach where architectures tested have a good range that can also apply to others. Testing focuses on 10k Omnibus on GCP as the testing has shown this is a good bellwether for the other architectures and cloud providers as well as Cloud Native Hybrids.
- Testing is done publicly and all results are shared.
-Τhe following table details the testing done against the reference architectures along with the frequency and results.
-
-| Reference Architecture | Tests Run<sup>1</sup> |
-|------------------------|----------------------------------------------------------------------------------------------------------------------|
-| 1k | [Omnibus - Daily (GCP)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/1k)<sup>2</sup> |
-| 2k | [Omnibus - Daily (GCP)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/2k)<sup>2</sup> |
-| 3k | [Omnibus - Weekly (GCP)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/3k)<sup>2</sup> |
-| 5k | [Omnibus - Weekly (GCP)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/5k)<sup>2</sup> |
-| 10k | [Omnibus - Daily (GCP)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/10k)<sup>2</sup><br/>[Omnibus - Ad-Hoc (GCP, AWS, Azure)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k)<br/><br/>[Cloud Native Hybrid - Ad-Hoc (GCP, AWS)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k-Cloud-Native-Hybrid) |
-| 25k | [Omnibus - Weekly (GCP)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/25k)<sup>2</sup><br/>[Omnibus - Ad-Hoc (Azure)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/25k) |
-| 50k | [Omnibus - Weekly (GCP)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/50k)<sup>2</sup><br/>[Omnibus - Ad-Hoc (AWS)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/50k) |
-
-Note that:
-
-1. The list above is non exhaustive. Additional testing is continuously evaluated and iterated on, and the table is updated regularly.
-1. The Omnibus reference architectures are VM-based only and testing has shown that they perform similarly on equivalently specced hardware regardless of Cloud Provider or if run on premises.
+Τhe following table details the testing done against the reference architectures along with the frequency and results. Note that this list above is non exhaustive. Additional testing is continuously evaluated and iterated on, and the table is updated accordingly.
+
+| Reference<br/>Architecture<br/>Size | Bare-Metal | GCP | AWS | Azure |
+|-----------------------------|------------|-----|-----|-------|
+| 1k | <i>Refer to GCP<sup>1</sup></i> | [Standard - Weekly](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/1k)<sup>1</sup> | - | - |
+| 2k | <i>Refer to GCP<sup>1</sup></i> | [Standard - Weekly](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/2k)<sup>1</sup> | - | - |
+| 3k | <i>Refer to GCP<sup>1</sup></i> | [Standard - Weekly](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/3k)<sup>1</sup> | - | - |
+| 5k | <i>Refer to GCP<sup>1</sup></i> | [Standard - Weekly](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/5k)<sup>1</sup> | - | - |
+| 10k | <i>Refer to GCP<sup>1</sup></i> | [Standard - Daily](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/10k)<sup>1</sup> <br/> [Standard (inc Cloud Services) - Ad-Hoc](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k) <br/> [Cloud Native Hybrid - Ad-Hoc](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k-Cloud-Native-Hybrid) | [Standard (inc Cloud Services) - Ad-Hoc](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k) <br/> [Cloud Native Hybrid - Ad-Hoc](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k-Cloud-Native-Hybrid) | [Standard - Ad-Hoc](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k) |
+| 25k | <i>Refer to GCP<sup>1</sup></i> | [Standard - Weekly](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/25k)<sup>1</sup> | - | [Standard - Ad-Hoc](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/25k) |
+| 50k | <i>Refer to GCP<sup>1</sup></i> | [Standard - Weekly](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/50k)<sup>1</sup> | [Standard (inc Cloud Services) - Ad-Hoc](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/50k) | - |
+
+1. The Standard Reference Architectures are designed to be platform agnostic, with everything being run on VMs via [Omnibus GitLab](https://docs.gitlab.com/omnibus/). While testing occurs primarily on GCP, ad-hoc testing has shown that they perform similarly on equivalently specced hardware on other Cloud Providers or if run on premises (bare-metal).
diff --git a/doc/administration/sidekiq.md b/doc/administration/sidekiq.md
index 8f1119f6868..989a024d6ab 100644
--- a/doc/administration/sidekiq.md
+++ b/doc/administration/sidekiq.md
@@ -2,7 +2,6 @@
stage: Enablement
group: Distribution
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: reference
---
# Configuring Sidekiq **(FREE SELF)**
@@ -21,8 +20,6 @@ you want using steps 1 and 2 from the GitLab downloads page.
1. Generate the Sidekiq configuration:
```ruby
- sidekiq['listen_address'] = "10.10.1.48"
-
## Optional: Enable extra Sidekiq processes
sidekiq_cluster['enable'] = true
sidekiq['queue_groups'] = [
@@ -128,6 +125,34 @@ you want using steps 1 and 2 from the GitLab downloads page.
external_url 'https://gitlab.example.com'
```
+1. (Optional) If you want to collect Sidekiq metrics, enable the Sidekiq metrics server.
+ To make metrics available from `localhost:8082/metrics`, set the following values:
+
+ ```ruby
+ sidekiq['metrics_enabled'] = true
+ sidekiq['listen_address'] = "localhost"
+ sidekiq['listen_port'] = "8082"
+
+ # Optionally log all the metrics server logs to log/sidekiq_exporter.log
+ sidekiq['exporter_log_enabled'] = true
+ ```
+
+1. (Optional) If you use health check probes to observe Sidekiq,
+ set a separate port for health checks.
+ Configuring health checks is only necessary if there is something that actually probes them.
+ For more information about health checks, see the [Sidekiq health check page](sidekiq_health_check.md).
+ Enable health checks for Sidekiq:
+
+ ```ruby
+ sidekiq['health_checks_enabled'] = true
+ sidekiq['health_checks_listen_address'] = "localhost"
+ sidekiq['health_checks_listen_port'] = "8092"
+ ```
+
+ NOTE:
+ If health check settings are not set, they will default to the metrics exporter settings.
+ This default is deprecated and is set to be removed in [GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/347509).
+
1. Run `gitlab-ctl reconfigure`.
You will need to restart the Sidekiq nodes after an update has occurred and database
@@ -196,7 +221,13 @@ gitlab_rails['auto_migrate'] = false
#######################################
### Sidekiq configuration ###
#######################################
-sidekiq['listen_address'] = "10.10.1.48"
+sidekiq['metrics_enabled'] = true
+sidekiq['exporter_log_enabled'] = false
+sidekiq['listen_port'] = "8082"
+
+sidekiq['health_checks_enabled'] = true
+sidekiq['health_checks_listen_address'] = "localhost"
+sidekiq['health_checks_listen_port'] = "8092"
#######################################
### Monitoring configuration ###
@@ -230,3 +261,4 @@ Related Sidekiq configuration:
1. [Extra Sidekiq processes](operations/extra_sidekiq_processes.md)
1. [Extra Sidekiq routing](operations/extra_sidekiq_routing.md)
1. [Using the GitLab-Sidekiq chart](https://docs.gitlab.com/charts/charts/gitlab/sidekiq/)
+1. [Sidekiq health checks](sidekiq_health_check.md)
diff --git a/doc/administration/sidekiq_health_check.md b/doc/administration/sidekiq_health_check.md
new file mode 100644
index 00000000000..2ed736bac2c
--- /dev/null
+++ b/doc/administration/sidekiq_health_check.md
@@ -0,0 +1,60 @@
+---
+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
+---
+
+# Sidekiq Health Check **(FREE SELF)**
+
+GitLab provides liveness and readiness probes to indicate service health and
+reachability to the Sidekiq cluster. These endpoints
+[can be provided to schedulers like Kubernetes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/)
+to hold traffic until the system is ready or restart the container as needed.
+
+The health check server can be set up when [configuring Sidekiq](sidekiq.md).
+
+## Readiness
+
+The readiness probe checks whether the Sidekiq workers are ready to process jobs.
+
+```plaintext
+GET /readiness
+```
+
+Assuming you set up Sidekiq's address and port to be `localhost` and `8092` respectively,
+here's an example request:
+
+```shell
+curl "http://localhost:8092/readiness"
+```
+
+On success, the endpoint returns a `200` HTTP status code, and a response like the following:
+
+```json
+{
+ "status": "ok"
+}
+```
+
+## Liveness
+
+Checks whether the Sidekiq cluster is running.
+
+```plaintext
+GET /liveness
+```
+
+Assuming you set up Sidekiq's address and port to be `localhost` and `8092` respectively,
+here's an example request:
+
+```shell
+curl "http://localhost:8092/liveness"
+```
+
+On success, the endpoint returns a `200` HTTP status code, and a response like the following:
+
+```json
+{
+ "status": "ok"
+}
+```
diff --git a/doc/administration/terraform_state.md b/doc/administration/terraform_state.md
index 582ffc9dc9c..d1113125c4e 100644
--- a/doc/administration/terraform_state.md
+++ b/doc/administration/terraform_state.md
@@ -101,6 +101,11 @@ The following settings are:
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/247042) in GitLab 13.9.
+WARNING:
+It's not possible to migrate Terraform state files from object storage back to local storage,
+so proceed with caution. [An issue exists](https://gitlab.com/gitlab-org/gitlab/-/issues/350187)
+to change this behavior.
+
To migrate Terraform state files to object storage, follow the instructions below.
- For Omnibus package installations:
diff --git a/doc/administration/troubleshooting/defcon.md b/doc/administration/troubleshooting/defcon.md
index 1b263f70b46..a7cc47f8547 100644
--- a/doc/administration/troubleshooting/defcon.md
+++ b/doc/administration/troubleshooting/defcon.md
@@ -23,7 +23,7 @@ Side effects:
## `ci_queueing_disaster_recovery_disable_quota`
-This feature flag, if temporarily enabled, disables enforcing CI minutes quota
+This feature flag, if temporarily enabled, disables enforcing CI/CD minutes quota
on shared runners. This can help to reduce system resource usage on the
`jobs/request` endpoint by significantly reducing the computations being
performed.
diff --git a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
index ccfa93d9bc8..33a81c12811 100644
--- a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
+++ b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
@@ -2,7 +2,6 @@
stage: Enablement
group: Distribution
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: reference
---
# GitLab Rails Console Cheat Sheet **(FREE SELF)**
@@ -526,7 +525,7 @@ master f05321a5b5728bd8a89b7bf530aa44043c951dce...7d02e575fd790e76
### Find mirrors with "bad decrypt" errors
-This content has been converted to a Rake task, see the [Doctor Rake tasks docs](../raketasks/doctor.md).
+This content has been converted to a Rake task, see [verify database values can be decrypted using the current secrets](../raketasks/check.md#verify-database-values-can-be-decrypted-using-the-current-secrets).
### Transfer mirror users and tokens to a single service account
@@ -909,6 +908,14 @@ end
Gitlab::CurrentSettings.current_application_settings.runners_registration_token
```
+### Seed runners registration token
+
+```ruby
+appSetting = Gitlab::CurrentSettings.current_application_settings
+appSetting.set_runners_registration_token('<new-runners-registration-token>')
+appSetting.save!
+```
+
### Run pipeline schedules manually
You can run pipeline schedules manually through the Rails console to reveal any errors that are usually not visible.
@@ -979,7 +986,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#license-history):
+To clean up the [License History table](../../user/admin_area/license.md#view-license-details-and-history):
```ruby
TYPE = :trial?
@@ -1065,7 +1072,7 @@ area on disk. It remains to be seen exactly how or whether the deletion is usefu
### Bad Decrypt Script (for encrypted variables)
-This content has been converted to a Rake task, see the [Doctor Rake tasks docs](../raketasks/doctor.md).
+This content has been converted to a Rake task, see [verify database values can be decrypted using the current secrets](../raketasks/check.md#verify-database-values-can-be-decrypted-using-the-current-secrets).
As an example of repairing, if `ProjectImportData Bad count:` is detected and the decision is made to delete the
encrypted credentials to allow manual reentry:
@@ -1108,7 +1115,7 @@ gitlab-rails runner /tmp/encrypted-tokens.rb
### Decrypt Script for encrypted tokens
-This content has been converted to a Rake task, see the [Doctor Rake tasks docs](../raketasks/doctor.md).
+This content has been converted to a Rake task, see [verify database values can be decrypted using the current secrets](../raketasks/check.md#verify-database-values-can-be-decrypted-using-the-current-secrets).
## Geo
@@ -1262,10 +1269,20 @@ registry = Geo::SnippetRepositoryRegistry.find(registry_id)
registry.replicator.send(:sync_repository)
```
+## Gitaly
+
+### Find available and used space
+
+A Gitaly storage resource can be polled through Rails to determine the available and used space.
+
+```ruby
+Gitlab::GitalyClient::ServerService.new("default").storage_disk_statistics
+```
+
## Generate Service Ping
-The [Service Ping Guide](../../development/service_ping/index.md) in our developer documentation
-has more information about Service Ping.
+The [Service Ping Guide](../../development/service_ping/index.md) in our developer documentation
+has more information about Service Ping.
### Generate or get the cached Service Ping
@@ -1291,7 +1308,7 @@ rake gitlab:usage_data:generate
Generates Service Ping data in YAML format:
-```shell
+```shell
rake gitlab:usage_data:dump_sql_in_yaml
```
diff --git a/doc/administration/troubleshooting/group_saml_scim.md b/doc/administration/troubleshooting/group_saml_scim.md
index d052688363c..8ec6b35ec39 100644
--- a/doc/administration/troubleshooting/group_saml_scim.md
+++ b/doc/administration/troubleshooting/group_saml_scim.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
diff --git a/doc/administration/troubleshooting/img/okta_setting_username.png b/doc/administration/troubleshooting/img/okta_setting_username.png
index c413b9d3a27..5f87d14bb8b 100644
--- a/doc/administration/troubleshooting/img/okta_setting_username.png
+++ b/doc/administration/troubleshooting/img/okta_setting_username.png
Binary files differ
diff --git a/doc/administration/troubleshooting/kubernetes_cheat_sheet.md b/doc/administration/troubleshooting/kubernetes_cheat_sheet.md
index 64a6979c016..290d6d9f21d 100644
--- a/doc/administration/troubleshooting/kubernetes_cheat_sheet.md
+++ b/doc/administration/troubleshooting/kubernetes_cheat_sheet.md
@@ -118,15 +118,18 @@ and they will assist you with any issues you are having.
kubectl get events -w --namespace=gitlab
```
-- Most of the useful GitLab tools (console, Rake tasks, etc) are found in the task-runner
- pod. You may enter it and run commands inside or run them from the outside:
+- Most of the useful GitLab tools (console, Rake tasks, etc) are found in the toolbox
+ pod. You may enter it and run commands inside or run them from the outside.
+
+ NOTE:
+ The `task-runner` pod was renamed to `toolbox` in GitLab 14.2 (charts 5.2).
```shell
# find the pod
- kubectl get pods | grep task-runner
+ kubectl --namespace gitlab get pods -lapp=toolbox
# enter it
- kubectl exec -it <task-runner-pod-name> -- bash
+ kubectl exec -it <toolbox-pod-name> -- bash
# open rails console
# rails console can be also called from other GitLab pods
@@ -139,10 +142,10 @@ and they will assist you with any issues you are having.
/usr/local/bin/gitlab-rake gitlab:check
# open console without entering pod
- kubectl exec -it <task-runner-pod-name> -- /srv/gitlab/bin/rails console
+ kubectl exec -it <toolbox-pod-name> -- /srv/gitlab/bin/rails console
# check the status of DB migrations
- kubectl exec -it <task-runner-pod-name> -- /usr/local/bin/gitlab-rake db:migrate:status
+ kubectl exec -it <toolbox-pod-name> -- /usr/local/bin/gitlab-rake db:migrate:status
```
You can also use `gitlab-rake`, instead of `/usr/local/bin/gitlab-rake`.
@@ -163,12 +166,15 @@ and they will assist you with any issues you are having.
kubectl get secret <secret-name> -ojsonpath={.data.password} | base64 --decode ; echo
```
-- How to connect to a GitLab PostgreSQL database:
+- How to connect to a GitLab PostgreSQL database.
+
+ NOTE:
+ The `task-runner` pod was renamed to `toolbox` in GitLab 14.2 (charts 5.2).
In GitLab 14.2 (chart 5.2) and later:
```shell
- kubectl exec -it <task-runner-pod-name> -- /srv/gitlab/bin/rails dbconsole --include-password --database main
+ kubectl exec -it <toolbox-pod-name> -- /srv/gitlab/bin/rails dbconsole --include-password --database main
```
In GitLab 14.1 (chart 5.1) and earlier:
@@ -215,9 +221,9 @@ all Kubernetes resources and dependent charts:
helm get manifest <release name>
```
-## Installation of minimal GitLab configuration via Minikube on macOS
+## Installation of minimal GitLab configuration via minikube on macOS
-This section is based on [Developing for Kubernetes with Minikube](https://docs.gitlab.com/charts/development/minikube/index.html)
+This section is based on [Developing for Kubernetes with minikube](https://docs.gitlab.com/charts/development/minikube/index.html)
and [Helm](https://docs.gitlab.com/charts/installation/tools.html#helm). Refer
to those documents for details.
@@ -227,13 +233,13 @@ to those documents for details.
brew install kubernetes-cli
```
-- Install Minikube via Homebrew:
+- Install minikube via Homebrew:
```shell
brew cask install minikube
```
-- Start Minikube and configure it. If Minikube cannot start, try running `minikube delete && minikube start`
+- Start minikube and configure it. If minikube cannot start, try running `minikube delete && minikube start`
and repeat the steps:
```shell
@@ -247,7 +253,7 @@ to those documents for details.
brew install helm
```
-- Copy the [Minikube minimum values YAML file](https://gitlab.com/gitlab-org/charts/gitlab/raw/master/examples/values-minikube-minimum.yaml)
+- Copy the [minikube minimum values YAML file](https://gitlab.com/gitlab-org/charts/gitlab/raw/master/examples/values-minikube-minimum.yaml)
to your workstation:
```shell
diff --git a/doc/administration/troubleshooting/postgresql.md b/doc/administration/troubleshooting/postgresql.md
index f8cb45dd00d..e4d1696ea93 100644
--- a/doc/administration/troubleshooting/postgresql.md
+++ b/doc/administration/troubleshooting/postgresql.md
@@ -179,3 +179,43 @@ Once saved, [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure
NOTE:
These are Omnibus GitLab settings. If an external database, such as a customer's PostgreSQL installation or Amazon RDS is being used, these values don't get set, and would have to be set externally.
+
+### Temporarily changing the statement timeout
+
+WARNING:
+The following advice does not apply in case
+[PgBouncer](../postgresql/pgbouncer.md) is enabled,
+because the changed timeout might affect more transactions than intended.
+
+In some situations, it may be desirable to set a different statement timeout
+without having to [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure),
+which in this case would restart Puma and Sidekiq.
+
+For example, a backup may fail with the following errors in the output of the
+[backup command](../../raketasks/backup_restore.md#back-up-gitlab)
+because the statement timeout was too short:
+
+```plaintext
+pg_dump: error: Error message from server: server closed the connection unexpectedly
+```
+
+You may also see errors in the [PostgreSQL logs](../logs.md#postgresql-logs):
+
+```plaintext
+canceling statement due to statement timeout
+```
+
+To temporarily change the statement timeout:
+
+1. Open `/var/opt/gitlab/gitlab-rails/etc/database.yml` in an editor
+1. Set the value of `statement_timeout` to `0`, which sets an unlimited statement timeout.
+1. [Confirm in a new Rails console session](../operations/rails_console.md#using-the-rails-runner)
+ that this value is used:
+
+ ```shell
+ sudo gitlab-rails runner "ActiveRecord::Base.connection_config[:variables]"
+ ```
+
+1. Perform the action for which you need a different timeout
+ (for example the backup or the Rails command).
+1. Revert the edit in `/var/opt/gitlab/gitlab-rails/etc/database.yml`.
diff --git a/doc/administration/troubleshooting/sidekiq.md b/doc/administration/troubleshooting/sidekiq.md
index a606a3712ba..62ea3bcfa3c 100644
--- a/doc/administration/troubleshooting/sidekiq.md
+++ b/doc/administration/troubleshooting/sidekiq.md
@@ -387,7 +387,7 @@ blocking all jobs on that worker from proceeding. If Rugged calls performed by S
background task processing.
By default, Rugged is used when Git repository data is stored on local storage or on an NFS mount.
-[Using Rugged is recommened when using NFS](../nfs.md#improving-nfs-performance-with-gitlab), but if
+[Using Rugged is recommended when using NFS](../nfs.md#improving-nfs-performance-with-gitlab), but if
you are using local storage, disabling Rugged can improve Sidekiq performance:
```shell
diff --git a/doc/administration/troubleshooting/ssl.md b/doc/administration/troubleshooting/ssl.md
index 01a4c4af65b..83df9ba19ff 100644
--- a/doc/administration/troubleshooting/ssl.md
+++ b/doc/administration/troubleshooting/ssl.md
@@ -18,7 +18,7 @@ main SSL docs available here:
## Using an internal CA certificate with GitLab
After configuring a GitLab instance with an internal CA certificate, you might
-not be able to access it by using various CLI tools. You may see experience the
+not be able to access it by using various CLI tools. You may experience the
following issues:
- `curl` fails:
diff --git a/doc/administration/user_settings.md b/doc/administration/user_settings.md
index 891c11afaf4..2c1bb781882 100644
--- a/doc/administration/user_settings.md
+++ b/doc/administration/user_settings.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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/api/access_requests.md b/doc/api/access_requests.md
index df830a1607d..9c217a98c3d 100644
--- a/doc/api/access_requests.md
+++ b/doc/api/access_requests.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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/api/api_resources.md b/doc/api/api_resources.md
index f489cb780ef..783823f80fb 100644
--- a/doc/api/api_resources.md
+++ b/doc/api/api_resources.md
@@ -25,7 +25,7 @@ The following API resources are available in the project context:
| Resource | Available endpoints |
|:------------------------------------------------------------------------|:--------------------|
| [Access requests](access_requests.md) | `/projects/:id/access_requests` (also available for groups) |
-| [Access tokens](resource_access_tokens.md) | `/projects/:id/access_tokens` |
+| [Access tokens](resource_access_tokens.md) | `/projects/:id/access_tokens` (also available for groups) |
| [Award emoji](award_emoji.md) | `/projects/:id/issues/.../award_emoji`, `/projects/:id/merge_requests/.../award_emoji`, `/projects/:id/snippets/.../award_emoji` |
| [Branches](branches.md) | `/projects/:id/repository/branches/`, `/projects/:id/repository/merged_branches` |
| [Commits](commits.md) | `/projects/:id/repository/commits`, `/projects/:id/statuses` |
@@ -34,6 +34,7 @@ The following API resources are available in the project context:
| [Debian distributions](packages/debian_project_distributions.md) | `/projects/:id/debian_distributions` (also available for groups) |
| [Dependencies](dependencies.md) **(ULTIMATE)** | `/projects/:id/dependencies` |
| [Deploy keys](deploy_keys.md) | `/projects/:id/deploy_keys` (also available standalone) |
+| [Deploy tokens](deploy_tokens.md) | `/projects/:id/deploy_tokens` (also available for groups and standalone) |
| [Deployments](deployments.md) | `/projects/:id/deployments` |
| [Discussions](discussions.md) (threaded comments) | `/projects/:id/issues/.../discussions`, `/projects/:id/snippets/.../discussions`, `/projects/:id/merge_requests/.../discussions`, `/projects/:id/commits/.../discussions` (also available for groups) |
| [Environments](environments.md) | `/projects/:id/environments` |
@@ -99,8 +100,10 @@ The following API resources are available in the group context:
| Resource | Available endpoints |
|:-----------------------------------------------------------------|:--------------------|
| [Access requests](access_requests.md) | `/groups/:id/access_requests/` (also available for projects) |
+| [Access tokens](group_access_tokens.md) | `/groups/:id/access_tokens` (also available for projects) |
| [Custom attributes](custom_attributes.md) | `/groups/:id/custom_attributes` (also available for projects and users) |
| [Debian distributions](packages/debian_group_distributions.md) | `/groups/:id/-/packages/debian` (also available for projects) |
+| [Deploy tokens](deploy_tokens.md) | `/groups/:id/deploy_tokens` (also available for projects and standalone) |
| [Discussions](discussions.md) (threaded comments) **(ULTIMATE)** | `/groups/:id/epics/.../discussions` (also available for projects) |
| [Epic issues](epic_issues.md) **(ULTIMATE)** | `/groups/:id/epics/.../issues` |
| [Epic links](epic_links.md) **(ULTIMATE)** | `/groups/:id/epics/.../epics` |
@@ -137,6 +140,7 @@ The following API resources are available outside of project and group contexts
| [Code snippets](snippets.md) | `/snippets` |
| [Custom attributes](custom_attributes.md) | `/users/:id/custom_attributes` (also available for groups and projects) |
| [Deploy keys](deploy_keys.md) | `/deploy_keys` (also available for projects) |
+| [Deploy tokens](deploy_tokens.md) | `/deploy_tokens` (also available for projects and groups) |
| [Events](events.md) | `/events`, `/users/:id/events` (also available for projects) |
| [Feature flags](features.md) | `/features` |
| [Geo Nodes](geo_nodes.md) **(PREMIUM SELF)** | `/geo_nodes` |
diff --git a/doc/api/appearance.md b/doc/api/appearance.md
index 5689cacd9ce..5e7ffbff25c 100644
--- a/doc/api/appearance.md
+++ b/doc/api/appearance.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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/api/applications.md b/doc/api/applications.md
index 22d858bd68a..bbf12438f28 100644
--- a/doc/api/applications.md
+++ b/doc/api/applications.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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/api/avatar.md b/doc/api/avatar.md
index 200d7524b7f..5db8c30cb9a 100644
--- a/doc/api/avatar.md
+++ b/doc/api/avatar.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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/api/commits.md b/doc/api/commits.md
index 94d1ced181c..6347af451a2 100644
--- a/doc/api/commits.md
+++ b/doc/api/commits.md
@@ -1,7 +1,7 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
+info: 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
---
# Commits API **(FREE)**
@@ -502,9 +502,8 @@ Example response:
Adds a comment to a commit.
-In order to post a comment in a particular line of a particular file, you must
-specify the full commit SHA, the `path`, the `line` and `line_type` should be
-`new`.
+To post a comment in a particular line of a particular file, you must specify
+the full commit SHA, the `path`, the `line`, and `line_type` should be `new`.
The comment is added at the end of the last commit if at least one of the
cases below is valid:
diff --git a/doc/api/container_registry.md b/doc/api/container_registry.md
index 1b9778a01b3..68d339837b2 100644
--- a/doc/api/container_registry.md
+++ b/doc/api/container_registry.md
@@ -6,8 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Container Registry API **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/55978) in GitLab 11.8.
-> - The use of `CI_JOB_TOKEN` scoped to the current project was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49750) in GitLab 13.12.
+> The use of `CI_JOB_TOKEN` scoped to the current project was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49750) in GitLab 13.12.
This is the API documentation of the [GitLab Container Registry](../user/packages/container_registry/index.md).
@@ -395,7 +394,7 @@ The number of tags deleted by this API is limited on GitLab.com
because of the scale of the Container Registry there.
If your Container Registry has a large number of tags to delete,
only some of them will be deleted, and you might need to call this API multiple times.
-To schedule tags for automatic deletion, use a [cleanup policy](../user/packages/container_registry/index.md#cleanup-policy) instead.
+To schedule tags for automatic deletion, use a [cleanup policy](../user/packages/container_registry/reduce_container_registry_storage.md#cleanup-policy) instead.
NOTE:
In GitLab 12.4 and later, individual tags are deleted.
diff --git a/doc/api/dependencies.md b/doc/api/dependencies.md
index 1ecb78aa26d..6fb99d11f4f 100644
--- a/doc/api/dependencies.md
+++ b/doc/api/dependencies.md
@@ -16,7 +16,7 @@ across GitLab releases.
Every call to this endpoint requires authentication. To perform this call, user should be authorized to read repository.
To see vulnerabilities in response, user should be authorized to read
-[Project Security Dashboard](../user/application_security/security_dashboard/index.md#project-security-dashboard).
+[Project Security Dashboard](../user/application_security/security_dashboard/index.md).
## List project dependencies
diff --git a/doc/api/deployments.md b/doc/api/deployments.md
index 253bc76737b..70b3e76c3dd 100644
--- a/doc/api/deployments.md
+++ b/doc/api/deployments.md
@@ -375,3 +375,38 @@ It supports the same parameters as the [Merge Requests API](merge_requests.md#li
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/deployments/42/merge_requests"
```
+
+## Approve or reject a blocked deployment **(PREMIUM)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/343864) in GitLab 14.7 [with a flag](../administration/feature_flags.md) named `deployment_approvals`. Disabled by default. This feature is not ready for production use.
+
+```plaintext
+POST /projects/:id/deployments/:deployment_id/approval
+```
+
+| 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. |
+| `deployment_id` | integer | yes | The ID of the deployment. |
+| `status` | string | yes | The status of the approval (either `approved` or `rejected`). |
+
+```shell
+curl --data "status=approved" \
+ --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/deployments/1/approval"
+```
+
+Example response:
+
+```json
+{
+ "user": {
+ "name": "Administrator",
+ "username": "root",
+ "id": 1,
+ "state": "active",
+ "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
+ "web_url": "http://localhost:3000/root"
+ },
+ "status": "approved"
+}
+```
diff --git a/doc/api/epics.md b/doc/api/epics.md
index 6d572303460..f3137559220 100644
--- a/doc/api/epics.md
+++ b/doc/api/epics.md
@@ -64,6 +64,7 @@ GET /groups/:id/epics?state=opened
| ------------------- | ---------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) owned by the authenticated user |
| `author_id` | integer | no | Return epics created by the given user `id` |
+| `author_username` | string | no | Return epics created by the user with the given `username`. Available in [GitLab 14.7](https://gitlab.com/gitlab-org/gitlab/-/issues/348257) and later |
| `labels` | string | no | Return epics matching a comma-separated list of labels names. Label names from the epic group or a parent group can be used |
| `with_labels_details` | boolean | no | If `true`, response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. Available in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) and later |
| `order_by` | string | no | Return epics ordered by `created_at`, `updated_at`, or `title` fields. Default is `created_at` |
@@ -77,7 +78,7 @@ GET /groups/:id/epics?state=opened
| `include_ancestor_groups` | boolean | no | Include epics from the requested group's ancestors. Default is `false` |
| `include_descendant_groups` | boolean | no | Include epics from the requested group's descendants. Default is `true` |
| `my_reaction_emoji` | string | no | Return epics reacted by the authenticated user by the given emoji. `None` returns epics not given a reaction. `Any` returns epics given at least one reaction. Available in [GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31479) and later |
-| `not` | Hash | no | Return epics that do not match the parameters supplied. Accepts: `author_id` and `labels`. Available in [GitLab 14.6](https://gitlab.com/gitlab-org/gitlab/-/issues/347525) and later |
+| `not` | Hash | no | Return epics that do not match the parameters supplied. Accepts: `author_id`, `author_username` ([GitLab 14.7](https://gitlab.com/gitlab-org/gitlab/-/issues/348257) and later) and `labels`. Available in [GitLab 14.6](https://gitlab.com/gitlab-org/gitlab/-/issues/347525) and later |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics"
@@ -366,21 +367,22 @@ PUT /groups/:id/epics/:epic_iid
| ------------------- | ---------------- | ---------- | ---------------------------------------------------------------------------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) owned by the authenticated user |
| `epic_iid` | integer/string | yes | The internal ID of the epic |
-| `title` | string | no | The title of an epic |
-| `description` | string | no | The description of an epic. Limited to 1,048,576 characters. |
+| `add_labels` | string | no | Comma-separated label names to add to an issue. |
| `confidential` | boolean | no | Whether the epic should be confidential |
+| `description` | string | no | The description of an epic. Limited to 1,048,576 characters. |
+| `due_date_fixed` | string | no | The fixed due date of an epic (in GitLab 11.3 and later) |
+| `due_date_is_fixed` | boolean | no | Whether due date should be sourced from `due_date_fixed` or from milestones (in GitLab 11.3 and later) |
| `labels` | string | no | Comma-separated label names for an issue. Set to an empty string to unassign all labels. |
-| `add_labels` | string | no | Comma-separated label names to add to an issue. |
+| `parent_id` | integer/string | no | The ID of a parent epic. Available in [GitLab 14.6](https://gitlab.com/gitlab-org/gitlab/-/issues/348123) and later |
| `remove_labels` | string | no | Comma-separated label names to remove from an issue. |
-| `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) |
-| `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) |
| `start_date_fixed` | string | no | The fixed start date of an epic (in GitLab 11.3 and later) |
-| `due_date_is_fixed` | boolean | no | Whether due date should be sourced from `due_date_fixed` or from milestones (in GitLab 11.3 and later) |
-| `due_date_fixed` | string | no | The fixed due date of an epic (in GitLab 11.3 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) |
| `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) |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics/5?title=New%20Title"
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics/5?title=New%20Title&parent_id=29"
```
Example response:
@@ -390,8 +392,8 @@ Example response:
"id": 33,
"iid": 6,
"group_id": 7,
- "parent_id": null,
- "parent_iid": null,
+ "parent_id": 29,
+ "parent_iid": 4,
"title": "New Title",
"description": "Epic description",
"state": "opened",
diff --git a/doc/api/geo_nodes.md b/doc/api/geo_nodes.md
index 3952a87e698..fe1674649b6 100644
--- a/doc/api/geo_nodes.md
+++ b/doc/api/geo_nodes.md
@@ -62,7 +62,7 @@ Example response:
"container_repositories_max_capacity": 10,
"sync_object_storage": false,
"clone_protocol": "http",
- "web_edit_url": "https://primary.example.com/admin/geo/nodes/3/edit",
+ "web_edit_url": "https://primary.example.com/admin/geo/sites/3/edit",
"web_geo_projects_url": "http://secondary.example.com/admin/geo/projects",
"_links": {
"self": "https://primary.example.com/api/v4/geo_nodes/3",
@@ -103,7 +103,7 @@ Example response:
"selective_sync_namespace_ids": [1, 25],
"minimum_reverification_interval": 7,
"clone_protocol": "http",
- "web_edit_url": "https://primary.example.com/admin/geo/nodes/1/edit",
+ "web_edit_url": "https://primary.example.com/admin/geo/sites/1/edit",
"_links": {
"self": "https://primary.example.com/api/v4/geo_nodes/1",
"status":"https://primary.example.com/api/v4/geo_nodes/1/status",
@@ -128,7 +128,7 @@ Example response:
"minimum_reverification_interval": 7,
"sync_object_storage": true,
"clone_protocol": "http",
- "web_edit_url": "https://primary.example.com/admin/geo/nodes/2/edit",
+ "web_edit_url": "https://primary.example.com/admin/geo/sites/2/edit",
"web_geo_projects_url": "https://secondary.example.com/admin/geo/projects",
"_links": {
"self":"https://primary.example.com/api/v4/geo_nodes/2",
@@ -169,7 +169,7 @@ Example response:
"selective_sync_namespace_ids": [1, 25],
"minimum_reverification_interval": 7,
"clone_protocol": "http",
- "web_edit_url": "https://primary.example.com/admin/geo/nodes/1/edit",
+ "web_edit_url": "https://primary.example.com/admin/geo/sites/1/edit",
"_links": {
"self": "https://primary.example.com/api/v4/geo_nodes/1",
"status":"https://primary.example.com/api/v4/geo_nodes/1/status",
@@ -226,7 +226,7 @@ Example response:
"minimum_reverification_interval": 7,
"sync_object_storage": true,
"clone_protocol": "http",
- "web_edit_url": "https://primary.example.com/admin/geo/nodes/2/edit",
+ "web_edit_url": "https://primary.example.com/admin/geo/sites/2/edit",
"web_geo_projects_url": "https://secondary.example.com/admin/geo/projects",
"_links": {
"self":"https://primary.example.com/api/v4/geo_nodes/2",
@@ -277,7 +277,7 @@ Example response:
"container_repositories_max_capacity": 10,
"verification_max_capacity": 100,
"clone_protocol": "http",
- "web_edit_url": "https://primary.example.com/admin/geo/nodes/1/edit",
+ "web_edit_url": "https://primary.example.com/admin/geo/sites/1/edit",
"_links": {
"self": "https://primary.example.com/api/v4/geo_nodes/1",
"status":"https://primary.example.com/api/v4/geo_nodes/1/status",
diff --git a/doc/api/graphql/getting_started.md b/doc/api/graphql/getting_started.md
index e3cf81148c2..258f781528b 100644
--- a/doc/api/graphql/getting_started.md
+++ b/doc/api/graphql/getting_started.md
@@ -44,8 +44,7 @@ you to explore the schema and types.
The examples below:
-- Can be run directly against GitLab 11.0 or later, though some of the types
- and fields may not be supported in older versions.
+- Can be run directly against GitLab.
- Works against GitLab.com without any further setup. Make sure you are signed
in and navigate to the [GraphiQL Explorer](https://gitlab.com/-/graphql-explorer).
@@ -60,7 +59,7 @@ either:
Refer to [running GraphiQL](index.md#graphiql) for more information.
NOTE:
-If you are running GitLab 11.0 to 12.0, enable the `graphql`
+If you are running GitLab 12.0, enable the `graphql`
[feature flag](../features.md#set-or-create-a-feature).
## Queries and mutations
diff --git a/doc/api/graphql/index.md b/doc/api/graphql/index.md
index bcaa5930faf..14512286ade 100644
--- a/doc/api/graphql/index.md
+++ b/doc/api/graphql/index.md
@@ -6,8 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GraphQL API **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/19008) in GitLab 11.0 [with a flag](../../administration/feature_flags.md) named `graphql`.
-> - [Enabled](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30444) in GitLab 12.1.
+> [Generally available](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30444) in GitLab 12.1. [Feature flag `graphql`](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30444) removed.
[GraphQL](https://graphql.org/) is a query language for APIs. You can use it to
request the exact data you need, and therefore limit the number of requests you need.
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 123e65162d8..3148fd1a6df 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -73,7 +73,7 @@ Returns [`CiConfig`](#ciconfig).
### `Query.ciMinutesUsage`
-Monthly CI minutes usage data for the current user.
+CI/CD minutes usage data for a namespace.
Returns [`CiMinutesNamespaceMonthlyUsageConnection`](#ciminutesnamespacemonthlyusageconnection).
@@ -81,6 +81,12 @@ 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="queryciminutesusagenamespaceid"></a>`namespaceId` | [`NamespaceID`](#namespaceid) | Global ID of the Namespace for the monthly CI/CD minutes usage. |
+
### `Query.containerRepository`
Find a container repository.
@@ -948,6 +954,10 @@ Input type: `ClusterAgentTokenCreateInput`
### `Mutation.clusterAgentTokenDelete`
+WARNING:
+**Deprecated** in 14.7.
+Tokens must be revoked with ClusterAgentTokenRevoke.
+
Input type: `ClusterAgentTokenDeleteInput`
#### Arguments
@@ -964,6 +974,24 @@ Input type: `ClusterAgentTokenDeleteInput`
| <a id="mutationclusteragenttokendeleteclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationclusteragenttokendeleteerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+### `Mutation.clusterAgentTokenRevoke`
+
+Input type: `ClusterAgentTokenRevokeInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationclusteragenttokenrevokeclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationclusteragenttokenrevokeid"></a>`id` | [`ClustersAgentTokenID!`](#clustersagenttokenid) | Global ID of the agent token that will be revoked. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationclusteragenttokenrevokeclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationclusteragenttokenrevokeerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+
### `Mutation.commitCreate`
Input type: `CommitCreateInput`
@@ -2913,6 +2941,48 @@ Input type: `IssueSetEpicInput`
| <a id="mutationissuesetepicerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationissuesetepicissue"></a>`issue` | [`Issue`](#issue) | Issue after mutation. |
+### `Mutation.issueSetEscalationPolicy`
+
+Input type: `IssueSetEscalationPolicyInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationissuesetescalationpolicyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationissuesetescalationpolicyescalationpolicyid"></a>`escalationPolicyId` | [`IncidentManagementEscalationPolicyID`](#incidentmanagementescalationpolicyid) | Global ID of the escalation policy to assign to the issue. Policy will be removed if absent or set to null. |
+| <a id="mutationissuesetescalationpolicyiid"></a>`iid` | [`String!`](#string) | IID of the issue to mutate. |
+| <a id="mutationissuesetescalationpolicyprojectpath"></a>`projectPath` | [`ID!`](#id) | Project the issue to mutate is in. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationissuesetescalationpolicyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationissuesetescalationpolicyerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| <a id="mutationissuesetescalationpolicyissue"></a>`issue` | [`Issue`](#issue) | Issue after mutation. |
+
+### `Mutation.issueSetEscalationStatus`
+
+Input type: `IssueSetEscalationStatusInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationissuesetescalationstatusclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationissuesetescalationstatusiid"></a>`iid` | [`String!`](#string) | IID of the issue to mutate. |
+| <a id="mutationissuesetescalationstatusprojectpath"></a>`projectPath` | [`ID!`](#id) | Project the issue to mutate is in. |
+| <a id="mutationissuesetescalationstatusstatus"></a>`status` | [`IssueEscalationStatus!`](#issueescalationstatus) | Set the escalation status. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationissuesetescalationstatusclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationissuesetescalationstatuserrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| <a id="mutationissuesetescalationstatusissue"></a>`issue` | [`Issue`](#issue) | Issue after mutation. |
+
### `Mutation.issueSetIteration`
Input type: `IssueSetIterationInput`
@@ -4266,6 +4336,25 @@ Input type: `TerraformStateUnlockInput`
| <a id="mutationterraformstateunlockclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationterraformstateunlockerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+### `Mutation.timelineEventDestroy`
+
+Input type: `TimelineEventDestroyInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationtimelineeventdestroyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationtimelineeventdestroyid"></a>`id` | [`IncidentManagementTimelineEventID!`](#incidentmanagementtimelineeventid) | Timeline event ID to remove. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationtimelineeventdestroyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationtimelineeventdestroyerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| <a id="mutationtimelineeventdestroytimelineevent"></a>`timelineEvent` | [`TimelineEventType`](#timelineeventtype) | Timeline event. |
+
### `Mutation.todoCreate`
Input type: `TodoCreateInput`
@@ -4907,6 +4996,27 @@ Input type: `VulnerabilityExternalIssueLinkDestroyInput`
| <a id="mutationvulnerabilityexternalissuelinkdestroyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationvulnerabilityexternalissuelinkdestroyerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+### `Mutation.vulnerabilityFindingDismiss`
+
+Input type: `VulnerabilityFindingDismissInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationvulnerabilityfindingdismissclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationvulnerabilityfindingdismisscomment"></a>`comment` | [`String`](#string) | Comment why finding should be dismissed. |
+| <a id="mutationvulnerabilityfindingdismissdismissalreason"></a>`dismissalReason` | [`VulnerabilityDismissalReason`](#vulnerabilitydismissalreason) | Reason why finding should be dismissed. |
+| <a id="mutationvulnerabilityfindingdismissid"></a>`id` | [`VulnerabilitiesFindingID!`](#vulnerabilitiesfindingid) | ID of the finding to be dismissed. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationvulnerabilityfindingdismissclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationvulnerabilityfindingdismisserrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| <a id="mutationvulnerabilityfindingdismissfinding"></a>`finding` | [`PipelineSecurityReportFinding`](#pipelinesecurityreportfinding) | Finding after dismissal. |
+
### `Mutation.vulnerabilityResolve`
Input type: `VulnerabilityResolveInput`
@@ -4945,6 +5055,30 @@ Input type: `VulnerabilityRevertToDetectedInput`
| <a id="mutationvulnerabilityreverttodetectederrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationvulnerabilityreverttodetectedvulnerability"></a>`vulnerability` | [`Vulnerability`](#vulnerability) | Vulnerability after revert. |
+### `Mutation.workItemCreate`
+
+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.
+
+Input type: `WorkItemCreateInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationworkitemcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationworkitemcreatedescription"></a>`description` | [`String`](#string) | Description of the work item. |
+| <a id="mutationworkitemcreateprojectpath"></a>`projectPath` | [`ID!`](#id) | Full path of the project the work item is associated with. |
+| <a id="mutationworkitemcreatetitle"></a>`title` | [`String!`](#string) | Title of the work item. |
+| <a id="mutationworkitemcreateworkitemtypeid"></a>`workItemTypeId` | [`WorkItemsTypeID!`](#workitemstypeid) | Global ID of a work item type. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationworkitemcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationworkitemcreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| <a id="mutationworkitemcreateworkitem"></a>`workItem` | [`WorkItem`](#workitem) | Created work item. |
+
## Connections
Some types in our schema are `Connection` types - they represent a paginated
@@ -5430,6 +5564,7 @@ The connection type for [`CiRunner`](#cirunner).
| Name | Type | Description |
| ---- | ---- | ----------- |
+| <a id="cirunnerconnectioncount"></a>`count` | [`Int!`](#int) | Total count of collection. |
| <a id="cirunnerconnectionedges"></a>`edges` | [`[CiRunnerEdge]`](#cirunneredge) | A list of edges. |
| <a id="cirunnerconnectionnodes"></a>`nodes` | [`[CiRunner]`](#cirunner) | A list of nodes. |
| <a id="cirunnerconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
@@ -7439,6 +7574,29 @@ The edge type for [`ScanExecutionPolicy`](#scanexecutionpolicy).
| <a id="scanexecutionpolicyedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="scanexecutionpolicyedgenode"></a>`node` | [`ScanExecutionPolicy`](#scanexecutionpolicy) | The item at the end of the edge. |
+#### `ScanResultPolicyConnection`
+
+The connection type for [`ScanResultPolicy`](#scanresultpolicy).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="scanresultpolicyconnectionedges"></a>`edges` | [`[ScanResultPolicyEdge]`](#scanresultpolicyedge) | A list of edges. |
+| <a id="scanresultpolicyconnectionnodes"></a>`nodes` | [`[ScanResultPolicy]`](#scanresultpolicy) | A list of nodes. |
+| <a id="scanresultpolicyconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
+
+#### `ScanResultPolicyEdge`
+
+The edge type for [`ScanResultPolicy`](#scanresultpolicy).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="scanresultpolicyedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="scanresultpolicyedgenode"></a>`node` | [`ScanResultPolicy`](#scanresultpolicy) | The item at the end of the edge. |
+
#### `ScannedResourceConnection`
The connection type for [`ScannedResource`](#scannedresource).
@@ -7741,6 +7899,29 @@ The edge type for [`TestSuiteSummary`](#testsuitesummary).
| <a id="testsuitesummaryedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="testsuitesummaryedgenode"></a>`node` | [`TestSuiteSummary`](#testsuitesummary) | The item at the end of the edge. |
+#### `TimelineEventTypeConnection`
+
+The connection type for [`TimelineEventType`](#timelineeventtype).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="timelineeventtypeconnectionedges"></a>`edges` | [`[TimelineEventTypeEdge]`](#timelineeventtypeedge) | A list of edges. |
+| <a id="timelineeventtypeconnectionnodes"></a>`nodes` | [`[TimelineEventType]`](#timelineeventtype) | A list of nodes. |
+| <a id="timelineeventtypeconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
+
+#### `TimelineEventTypeEdge`
+
+The edge type for [`TimelineEventType`](#timelineeventtype).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="timelineeventtypeedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="timelineeventtypeedgenode"></a>`node` | [`TimelineEventType`](#timelineeventtype) | The item at the end of the edge. |
+
#### `TimelogConnection`
The connection type for [`Timelog`](#timelog).
@@ -8063,6 +8244,29 @@ The edge type for [`VulnerabilityScanner`](#vulnerabilityscanner).
| <a id="vulnerabilityscanneredgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="vulnerabilityscanneredgenode"></a>`node` | [`VulnerabilityScanner`](#vulnerabilityscanner) | The item at the end of the edge. |
+#### `WorkItemTypeConnection`
+
+The connection type for [`WorkItemType`](#workitemtype).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="workitemtypeconnectionedges"></a>`edges` | [`[WorkItemTypeEdge]`](#workitemtypeedge) | A list of edges. |
+| <a id="workitemtypeconnectionnodes"></a>`nodes` | [`[WorkItemType]`](#workitemtype) | A list of nodes. |
+| <a id="workitemtypeconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
+
+#### `WorkItemTypeEdge`
+
+The edge type for [`WorkItemType`](#workitemtype).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="workitemtypeedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="workitemtypeedgenode"></a>`node` | [`WorkItemType`](#workitemtype) | The item at the end of the edge. |
+
## Object types
Object types represent the resources that the GitLab GraphQL API can return.
@@ -8655,6 +8859,7 @@ Represents the total number of issues and their weights for a particular day.
| <a id="ciconfigmergedyaml"></a>`mergedYaml` | [`String`](#string) | Merged CI configuration YAML. |
| <a id="ciconfigstages"></a>`stages` | [`CiConfigStageConnection`](#ciconfigstageconnection) | Stages of the pipeline. (see [Connections](#connections)) |
| <a id="ciconfigstatus"></a>`status` | [`CiConfigStatus`](#ciconfigstatus) | Status of linting, can be either valid or invalid. |
+| <a id="ciconfigwarnings"></a>`warnings` | [`[String!]`](#string) | Linting warnings. |
### `CiConfigGroup`
@@ -8738,6 +8943,7 @@ Represents the total number of issues and their weights for a particular day.
| <a id="cijobcreatedat"></a>`createdAt` | [`Time!`](#time) | When the job was created. |
| <a id="cijobcreatedbytag"></a>`createdByTag` | [`Boolean!`](#boolean) | Whether the job was created by a tag. |
| <a id="cijobdetailedstatus"></a>`detailedStatus` | [`DetailedStatus`](#detailedstatus) | Detailed status of the job. |
+| <a id="cijobdownstreampipeline"></a>`downstreamPipeline` | [`Pipeline`](#pipeline) | Downstream pipeline for a bridge. |
| <a id="cijobduration"></a>`duration` | [`Int`](#int) | Duration of the job in seconds. |
| <a id="cijobfinishedat"></a>`finishedAt` | [`Time`](#time) | When a job has finished running. |
| <a id="cijobid"></a>`id` | [`JobID`](#jobid) | ID of the job. |
@@ -8789,6 +8995,7 @@ Represents the total number of issues and their weights for a particular day.
| ---- | ---- | ----------- |
| <a id="ciminutesnamespacemonthlyusageminutes"></a>`minutes` | [`Int`](#int) | Total number of minutes used by all projects in the namespace. |
| <a id="ciminutesnamespacemonthlyusagemonth"></a>`month` | [`String`](#string) | Month related to the usage data. |
+| <a id="ciminutesnamespacemonthlyusagemonthiso8601"></a>`monthIso8601` | [`ISO8601Date`](#iso8601date) | Month related to the usage data in ISO 8601 date format. |
| <a id="ciminutesnamespacemonthlyusageprojects"></a>`projects` | [`CiMinutesProjectMonthlyUsageConnection`](#ciminutesprojectmonthlyusageconnection) | CI minutes usage data for projects in the namespace. (see [Connections](#connections)) |
| <a id="ciminutesnamespacemonthlyusagesharedrunnersduration"></a>`sharedRunnersDuration` | [`Int`](#int) | Total numbers of minutes used by the shared runners in the namespace. |
@@ -8810,8 +9017,11 @@ Represents the total number of issues and their weights for a particular day.
| <a id="cirunneraccesslevel"></a>`accessLevel` | [`CiRunnerAccessLevel!`](#cirunneraccesslevel) | Access level of the runner. |
| <a id="cirunneractive"></a>`active` | [`Boolean!`](#boolean) | Indicates the runner is allowed to receive jobs. |
| <a id="cirunneradminurl"></a>`adminUrl` | [`String`](#string) | Admin URL of the runner. Only available for administrators. |
-| <a id="cirunnercontactedat"></a>`contactedAt` | [`Time`](#time) | Last contact from the runner. |
+| <a id="cirunnercontactedat"></a>`contactedAt` | [`Time`](#time) | Timestamp of last contact from this runner. |
+| <a id="cirunnercreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp of creation of this runner. |
| <a id="cirunnerdescription"></a>`description` | [`String`](#string) | Description of the runner. |
+| <a id="cirunnereditadminurl"></a>`editAdminUrl` | [`String`](#string) | Admin form URL of the runner. Only available for administrators. |
+| <a id="cirunnerexecutorname"></a>`executorName` | [`String`](#string) | Executor last advertised by the runner. Available only when feature flag `graphql_ci_runner_executor` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. |
| <a id="cirunnerid"></a>`id` | [`CiRunnerID!`](#cirunnerid) | ID of the runner. |
| <a id="cirunneripaddress"></a>`ipAddress` | [`String`](#string) | IP address of the runner. |
| <a id="cirunnerjobcount"></a>`jobCount` | [`Int`](#int) | Number of jobs processed by the runner (limited to 1000, plus one to indicate that more items exist). |
@@ -8879,10 +9089,27 @@ GitLab CI/CD configuration template.
| <a id="clusteragentid"></a>`id` | [`ID!`](#id) | ID of the cluster agent. |
| <a id="clusteragentname"></a>`name` | [`String`](#string) | Name of the cluster agent. |
| <a id="clusteragentproject"></a>`project` | [`Project`](#project) | Project this cluster agent is associated with. |
-| <a id="clusteragenttokens"></a>`tokens` | [`ClusterAgentTokenConnection`](#clusteragenttokenconnection) | Tokens associated with the cluster agent. (see [Connections](#connections)) |
| <a id="clusteragentupdatedat"></a>`updatedAt` | [`Time`](#time) | Timestamp the cluster agent was updated. |
| <a id="clusteragentwebpath"></a>`webPath` | [`String`](#string) | Web path of the cluster agent. |
+#### Fields with arguments
+
+##### `ClusterAgent.tokens`
+
+Tokens associated with the cluster agent.
+
+Returns [`ClusterAgentTokenConnection`](#clusteragenttokenconnection).
+
+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="clusteragenttokensstatus"></a>`status` | [`AgentTokenStatus`](#agenttokenstatus) | Status of the token. |
+
### `ClusterAgentActivityEvent`
#### Fields
@@ -8908,6 +9135,7 @@ GitLab CI/CD configuration template.
| <a id="clusteragenttokenid"></a>`id` | [`ClustersAgentTokenID!`](#clustersagenttokenid) | Global ID of the token. |
| <a id="clusteragenttokenlastusedat"></a>`lastUsedAt` | [`Time`](#time) | Timestamp the token was last used. |
| <a id="clusteragenttokenname"></a>`name` | [`String`](#string) | Name given to the token. |
+| <a id="clusteragenttokenstatus"></a>`status` | [`AgentTokenStatus`](#agenttokenstatus) | Current status of the token. |
### `CodeCoverageActivity`
@@ -8955,6 +9183,7 @@ Represents a code quality degradation on the pipeline.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="commitauthor"></a>`author` | [`UserCore`](#usercore) | Author of the commit. |
+| <a id="commitauthoremail"></a>`authorEmail` | [`String`](#string) | Commit author's email. |
| <a id="commitauthorgravatar"></a>`authorGravatar` | [`String`](#string) | Commit authors gravatar. |
| <a id="commitauthorname"></a>`authorName` | [`String`](#string) | Commit authors name. |
| <a id="commitauthoreddate"></a>`authoredDate` | [`Time`](#time) | Timestamp of when the commit was authored. |
@@ -8991,7 +9220,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="commitpipelinesref"></a>`ref` | [`String`](#string) | Filter pipelines by the ref they are run for. |
| <a id="commitpipelinesscope"></a>`scope` | [`PipelineScopeEnum`](#pipelinescopeenum) | Filter pipelines by scope. |
| <a id="commitpipelinessha"></a>`sha` | [`String`](#string) | Filter pipelines by the sha of the commit they are run for. |
-| <a id="commitpipelinessource"></a>`source` | [`String`](#string) | Filter pipelines by their source. Will be ignored if `dast_view_scans` feature flag is disabled. |
+| <a id="commitpipelinessource"></a>`source` | [`String`](#string) | Filter pipelines by their source. |
| <a id="commitpipelinesstatus"></a>`status` | [`PipelineStatusEnum`](#pipelinestatusenum) | Filter pipelines by their status. |
### `ComplianceFramework`
@@ -10127,6 +10356,8 @@ Relationship between an epic and an issue.
| <a id="epicissueemailsdisabled"></a>`emailsDisabled` | [`Boolean!`](#boolean) | Indicates if a project has email notifications disabled: `true` if email notifications are disabled. |
| <a id="epicissueepic"></a>`epic` | [`Epic`](#epic) | Epic to which this issue belongs. |
| <a id="epicissueepicissueid"></a>`epicIssueId` | [`ID!`](#id) | ID of the epic-issue relation. |
+| <a id="epicissueescalationpolicy"></a>`escalationPolicy` | [`EscalationPolicyType`](#escalationpolicytype) | Escalation policy associated with the issue. Available for issues which support escalation. |
+| <a id="epicissueescalationstatus"></a>`escalationStatus` | [`IssueEscalationStatus`](#issueescalationstatus) | Escalation status of the issue. |
| <a id="epicissuehealthstatus"></a>`healthStatus` | [`HealthStatus`](#healthstatus) | Current health status. |
| <a id="epicissuehidden"></a>`hidden` | [`Boolean`](#boolean) | Indicates the issue is hidden because the author has been banned. Will always return `null` if `ban_user_feature_flag` feature flag is disabled. |
| <a id="epicissuehumantimeestimate"></a>`humanTimeEstimate` | [`String`](#string) | Human-readable time estimate of the issue. |
@@ -10556,6 +10787,7 @@ 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
@@ -10882,6 +11114,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="groupmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="groupmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <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="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. |
@@ -11308,6 +11541,8 @@ Returns [`VulnerabilitySeveritiesCount`](#vulnerabilityseveritiescount).
| <a id="issueduedate"></a>`dueDate` | [`Time`](#time) | Due date of the issue. |
| <a id="issueemailsdisabled"></a>`emailsDisabled` | [`Boolean!`](#boolean) | Indicates if a project has email notifications disabled: `true` if email notifications are disabled. |
| <a id="issueepic"></a>`epic` | [`Epic`](#epic) | Epic to which this issue belongs. |
+| <a id="issueescalationpolicy"></a>`escalationPolicy` | [`EscalationPolicyType`](#escalationpolicytype) | Escalation policy associated with the issue. Available for issues which support escalation. |
+| <a id="issueescalationstatus"></a>`escalationStatus` | [`IssueEscalationStatus`](#issueescalationstatus) | Escalation status of the issue. |
| <a id="issuehealthstatus"></a>`healthStatus` | [`HealthStatus`](#healthstatus) | Current health status. |
| <a id="issuehidden"></a>`hidden` | [`Boolean`](#boolean) | Indicates the issue is hidden because the author has been banned. Will always return `null` if `ban_user_feature_flag` feature flag is disabled. |
| <a id="issuehumantimeestimate"></a>`humanTimeEstimate` | [`String`](#string) | Human-readable time estimate of the issue. |
@@ -11424,6 +11659,7 @@ Represents an iteration object.
| <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. |
@@ -11620,6 +11856,7 @@ Maven metadata.
| <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="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. |
@@ -11652,7 +11889,7 @@ Maven metadata.
| <a id="mergerequestmergestatus"></a>`mergeStatus` **{warning-solid}** | [`String`](#string) | **Deprecated** in 14.0. This was renamed. Use: [`MergeRequest.mergeStatusEnum`](#mergerequestmergestatusenum). |
| <a id="mergerequestmergestatusenum"></a>`mergeStatusEnum` | [`MergeStatus`](#mergestatus) | Merge status of the merge request. |
| <a id="mergerequestmergetrainscount"></a>`mergeTrainsCount` | [`Int`](#int) | Number of merge requests in the merge train. |
-| <a id="mergerequestmergeuser"></a>`mergeUser` | [`UserCore`](#usercore) | User who merged this merge request. |
+| <a id="mergerequestmergeuser"></a>`mergeUser` | [`UserCore`](#usercore) | User who merged this merge request or set it to merge when pipeline succeeds. |
| <a id="mergerequestmergewhenpipelinesucceeds"></a>`mergeWhenPipelineSucceeds` | [`Boolean`](#boolean) | Indicates if the merge has been set to be merged when its pipeline succeeds (MWPS). |
| <a id="mergerequestmergeable"></a>`mergeable` | [`Boolean!`](#boolean) | Indicates if the merge request is mergeable. |
| <a id="mergerequestmergeablediscussionsstate"></a>`mergeableDiscussionsState` | [`Boolean`](#boolean) | Indicates if all discussions in the merge request have been resolved, allowing the merge request to be merged. |
@@ -11742,7 +11979,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestpipelinesref"></a>`ref` | [`String`](#string) | Filter pipelines by the ref they are run for. |
| <a id="mergerequestpipelinesscope"></a>`scope` | [`PipelineScopeEnum`](#pipelinescopeenum) | Filter pipelines by scope. |
| <a id="mergerequestpipelinessha"></a>`sha` | [`String`](#string) | Filter pipelines by the sha of the commit they are run for. |
-| <a id="mergerequestpipelinessource"></a>`source` | [`String`](#string) | Filter pipelines by their source. Will be ignored if `dast_view_scans` feature flag is disabled. |
+| <a id="mergerequestpipelinessource"></a>`source` | [`String`](#string) | Filter pipelines by their source. |
| <a id="mergerequestpipelinesstatus"></a>`status` | [`PipelineStatusEnum`](#pipelinestatusenum) | Filter pipelines by their status. |
##### `MergeRequest.reference`
@@ -11815,6 +12052,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestassigneeassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="mergerequestassigneeassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="mergerequestassigneeassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="mergerequestassigneeassignedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="mergerequestassigneeassignedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="mergerequestassigneeassignedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="mergerequestassigneeassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
@@ -11846,6 +12084,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestassigneeauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
| <a id="mergerequestassigneeauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="mergerequestassigneeauthoredmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="mergerequestassigneeauthoredmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="mergerequestassigneeauthoredmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="mergerequestassigneeauthoredmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="mergerequestassigneeauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
@@ -11862,7 +12101,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
##### `MergeRequestAssignee.groups`
-Groups where the user has access. Will always return `null` if `paginatable_namespace_drop_down_for_project_creation` feature flag is disabled.
+Groups where the user has access.
Returns [`GroupConnection`](#groupconnection).
@@ -11895,6 +12134,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestassigneereviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="mergerequestassigneereviewrequestedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="mergerequestassigneereviewrequestedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="mergerequestassigneereviewrequestedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="mergerequestassigneereviewrequestedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="mergerequestassigneereviewrequestedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="mergerequestassigneereviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
@@ -12067,6 +12307,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestreviewerassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="mergerequestreviewerassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="mergerequestreviewerassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="mergerequestreviewerassignedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="mergerequestreviewerassignedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="mergerequestreviewerassignedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="mergerequestreviewerassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
@@ -12098,6 +12339,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestreviewerauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
| <a id="mergerequestreviewerauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="mergerequestreviewerauthoredmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="mergerequestreviewerauthoredmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="mergerequestreviewerauthoredmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="mergerequestreviewerauthoredmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="mergerequestreviewerauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
@@ -12114,7 +12356,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
##### `MergeRequestReviewer.groups`
-Groups where the user has access. Will always return `null` if `paginatable_namespace_drop_down_for_project_creation` feature flag is disabled.
+Groups where the user has access.
Returns [`GroupConnection`](#groupconnection).
@@ -12147,6 +12389,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestreviewerreviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="mergerequestreviewerreviewrequestedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="mergerequestreviewerreviewrequestedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="mergerequestreviewerreviewrequestedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="mergerequestreviewerreviewrequestedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="mergerequestreviewerreviewrequestedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="mergerequestreviewerreviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
@@ -12577,15 +12820,23 @@ Represents a package details in the Package Registry. Note that this type is in
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="packagedetailstypecandestroy"></a>`canDestroy` | [`Boolean!`](#boolean) | Whether the user can destroy the package. |
+| <a id="packagedetailstypecomposerconfigrepositoryurl"></a>`composerConfigRepositoryUrl` | [`String`](#string) | Url of the Composer setup endpoint. |
+| <a id="packagedetailstypecomposerurl"></a>`composerUrl` | [`String`](#string) | Url of the Composer endpoint. |
+| <a id="packagedetailstypeconanurl"></a>`conanUrl` | [`String`](#string) | Url of the Conan project endpoint. |
| <a id="packagedetailstypecreatedat"></a>`createdAt` | [`Time!`](#time) | Date of creation. |
| <a id="packagedetailstypedependencylinks"></a>`dependencyLinks` | [`PackageDependencyLinkConnection`](#packagedependencylinkconnection) | Dependency link. (see [Connections](#connections)) |
| <a id="packagedetailstypeid"></a>`id` | [`PackagesPackageID!`](#packagespackageid) | ID of the package. |
+| <a id="packagedetailstypemavenurl"></a>`mavenUrl` | [`String`](#string) | Url of the Maven project endpoint. |
| <a id="packagedetailstypemetadata"></a>`metadata` | [`PackageMetadata`](#packagemetadata) | Package metadata. |
| <a id="packagedetailstypename"></a>`name` | [`String!`](#string) | Name of the package. |
+| <a id="packagedetailstypenpmurl"></a>`npmUrl` | [`String`](#string) | Url of the NPM project endpoint. |
+| <a id="packagedetailstypenugeturl"></a>`nugetUrl` | [`String`](#string) | Url of the Nuget project endpoint. |
| <a id="packagedetailstypepackagefiles"></a>`packageFiles` | [`PackageFileConnection`](#packagefileconnection) | Package files. (see [Connections](#connections)) |
| <a id="packagedetailstypepackagetype"></a>`packageType` | [`PackageTypeEnum!`](#packagetypeenum) | Package type. |
| <a id="packagedetailstypepipelines"></a>`pipelines` **{warning-solid}** | [`PipelineConnection`](#pipelineconnection) | **Deprecated** in 14.6. Due to scalability concerns, this field is going to be removed. |
| <a id="packagedetailstypeproject"></a>`project` | [`Project!`](#project) | Project where the package is stored. |
+| <a id="packagedetailstypepypisetupurl"></a>`pypiSetupUrl` | [`String`](#string) | Url of the PyPi project setup endpoint. |
+| <a id="packagedetailstypepypiurl"></a>`pypiUrl` | [`String`](#string) | Url of the PyPi project endpoint. |
| <a id="packagedetailstypestatus"></a>`status` | [`PackageStatus!`](#packagestatus) | Package status. |
| <a id="packagedetailstypetags"></a>`tags` | [`PackageTagConnection`](#packagetagconnection) | Package tags. (see [Connections](#connections)) |
| <a id="packagedetailstypeupdatedat"></a>`updatedAt` | [`Time!`](#time) | Date of most recent update. |
@@ -12768,7 +13019,7 @@ Represents a file or directory in the project repository that has been locked.
| <a id="pipelineconfigsource"></a>`configSource` | [`PipelineConfigSourceEnum`](#pipelineconfigsourceenum) | Configuration source of the pipeline (UNKNOWN_SOURCE, REPOSITORY_SOURCE, AUTO_DEVOPS_SOURCE, WEBIDE_SOURCE, REMOTE_SOURCE, EXTERNAL_PROJECT_SOURCE, BRIDGE_SOURCE, PARAMETER_SOURCE, COMPLIANCE_SOURCE). |
| <a id="pipelinecoverage"></a>`coverage` | [`Float`](#float) | Coverage percentage. |
| <a id="pipelinecreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp of the pipeline's creation. |
-| <a id="pipelinedastprofile"></a>`dastProfile` | [`DastProfile`](#dastprofile) | DAST profile associated with the pipeline. Returns `null`if `dast_view_scans` feature flag is disabled. |
+| <a id="pipelinedastprofile"></a>`dastProfile` | [`DastProfile`](#dastprofile) | DAST profile associated with the pipeline. |
| <a id="pipelinedetailedstatus"></a>`detailedStatus` | [`DetailedStatus!`](#detailedstatus) | Detailed status of the pipeline. |
| <a id="pipelinedownstream"></a>`downstream` | [`PipelineConnection`](#pipelineconnection) | Pipelines this pipeline will trigger. (see [Connections](#connections)) |
| <a id="pipelineduration"></a>`duration` | [`Int`](#int) | Duration of the pipeline in seconds. |
@@ -12780,9 +13031,9 @@ Represents a file or directory in the project repository that has been locked.
| <a id="pipelineproject"></a>`project` | [`Project`](#project) | Project the pipeline belongs to. |
| <a id="pipelinequeuedduration"></a>`queuedDuration` | [`Duration`](#duration) | How long the pipeline was queued before starting. |
| <a id="pipelineref"></a>`ref` | [`String`](#string) | Reference to the branch from which the pipeline was triggered. |
+| <a id="pipelinerefpath"></a>`refPath` | [`String`](#string) | Reference path to the branch from which the pipeline was triggered. |
| <a id="pipelineretryable"></a>`retryable` | [`Boolean!`](#boolean) | Specifies if a pipeline can be retried. |
| <a id="pipelinesecurityreportsummary"></a>`securityReportSummary` | [`SecurityReportSummary`](#securityreportsummary) | Vulnerability and scanned resource counts for each security scanner of the pipeline. |
-| <a id="pipelinesha"></a>`sha` | [`String!`](#string) | SHA of the pipeline's commit. |
| <a id="pipelinesourcejob"></a>`sourceJob` | [`CiJob`](#cijob) | Job where pipeline was triggered from. |
| <a id="pipelinestages"></a>`stages` | [`CiStageConnection`](#cistageconnection) | Stages of the pipeline. (see [Connections](#connections)) |
| <a id="pipelinestartedat"></a>`startedAt` | [`Time`](#time) | Timestamp when the pipeline was started. |
@@ -12793,6 +13044,7 @@ Represents a file or directory in the project repository that has been locked.
| <a id="pipelineuser"></a>`user` | [`UserCore`](#usercore) | Pipeline user. |
| <a id="pipelineuserpermissions"></a>`userPermissions` | [`PipelinePermissions!`](#pipelinepermissions) | Permissions for the current user on the resource. |
| <a id="pipelineusesneeds"></a>`usesNeeds` | [`Boolean`](#boolean) | Indicates if the pipeline has jobs with `needs` dependencies. |
+| <a id="pipelinewarningmessages"></a>`warningMessages` | [`[PipelineMessage!]`](#pipelinemessage) | Pipeline warning messages. |
| <a id="pipelinewarnings"></a>`warnings` | [`Boolean!`](#boolean) | Indicates if a pipeline has warnings. |
#### Fields with arguments
@@ -12846,6 +13098,18 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="pipelinesecurityreportfindingsseverity"></a>`severity` | [`[String!]`](#string) | Filter vulnerability findings by severity. |
| <a id="pipelinesecurityreportfindingsstate"></a>`state` | [`[VulnerabilityState!]`](#vulnerabilitystate) | Filter vulnerability findings by state. |
+##### `Pipeline.sha`
+
+SHA of the pipeline's commit.
+
+Returns [`String`](#string).
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="pipelineshaformat"></a>`format` | [`ShaFormat`](#shaformat) | Format of the SHA. |
+
##### `Pipeline.testSuite`
A specific test suite in a pipeline test report.
@@ -12893,6 +13157,15 @@ Represents the Geo sync and verification state of a pipeline artifact.
| <a id="pipelineartifactregistryretrycount"></a>`retryCount` | [`Int`](#int) | Number of consecutive failed sync attempts of the PipelineArtifactRegistry. |
| <a id="pipelineartifactregistrystate"></a>`state` | [`RegistryState`](#registrystate) | Sync state of the PipelineArtifactRegistry. |
+### `PipelineMessage`
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="pipelinemessagecontent"></a>`content` | [`String!`](#string) | Content of the pipeline message. |
+| <a id="pipelinemessageid"></a>`id` | [`ID!`](#id) | ID of the pipeline message. |
+
### `PipelinePermissions`
#### Fields
@@ -12989,6 +13262,7 @@ Represents vulnerability finding of a security report on the pipeline.
| <a id="projectrequestaccessenabled"></a>`requestAccessEnabled` | [`Boolean`](#boolean) | Indicates if users can request member access to the project. |
| <a id="projectrequirementstatescount"></a>`requirementStatesCount` | [`RequirementStatesCount`](#requirementstatescount) | Number of requirements for the project by their state. |
| <a id="projectsastciconfiguration"></a>`sastCiConfiguration` | [`SastCiConfiguration`](#sastciconfiguration) | SAST CI configuration for the project. |
+| <a id="projectscanresultpolicies"></a>`scanResultPolicies` | [`ScanResultPolicyConnection`](#scanresultpolicyconnection) | Scan Result Policies of the project. (see [Connections](#connections)) |
| <a id="projectsecuritydashboardpath"></a>`securityDashboardPath` | [`String`](#string) | Path to project's security dashboard. |
| <a id="projectsecurityscanners"></a>`securityScanners` | [`SecurityScanners`](#securityscanners) | Information about security analyzers used in the project. |
| <a id="projectsentryerrors"></a>`sentryErrors` | [`SentryErrorCollection`](#sentryerrorcollection) | Paginated collection of Sentry errors on the project. |
@@ -13010,6 +13284,7 @@ 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
@@ -13187,7 +13462,7 @@ Returns [`DastProfile`](#dastprofile).
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="projectdastprofilehasdastprofileschedule"></a>`hasDastProfileSchedule` | [`Boolean`](#boolean) | Filter DAST Profiles by whether or not they have a schedule. Will be ignored if `dast_view_scans` feature flag is disabled. |
+| <a id="projectdastprofilehasdastprofileschedule"></a>`hasDastProfileSchedule` | [`Boolean`](#boolean) | Filter DAST Profiles by whether or not they have a schedule. |
| <a id="projectdastprofileid"></a>`id` | [`DastProfileID!`](#dastprofileid) | ID of the DAST Profile. |
##### `Project.dastProfiles`
@@ -13204,7 +13479,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="projectdastprofileshasdastprofileschedule"></a>`hasDastProfileSchedule` | [`Boolean`](#boolean) | Filter DAST Profiles by whether or not they have a schedule. Will be ignored if `dast_view_scans` feature flag is disabled. |
+| <a id="projectdastprofileshasdastprofileschedule"></a>`hasDastProfileSchedule` | [`Boolean`](#boolean) | Filter DAST Profiles by whether or not they have a schedule. |
##### `Project.dastSiteProfile`
@@ -13295,6 +13570,35 @@ four standard [pagination arguments](#connection-pagination-arguments):
| ---- | ---- | ----------- |
| <a id="projectincidentmanagementoncallschedulesiids"></a>`iids` | [`[ID!]`](#id) | IIDs of on-call schedules. |
+##### `Project.incidentManagementTimelineEvent`
+
+Incident Management Timeline event associated with the incident.
+
+Returns [`TimelineEventType`](#timelineeventtype).
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="projectincidentmanagementtimelineeventid"></a>`id` | [`IncidentManagementTimelineEventID!`](#incidentmanagementtimelineeventid) | ID of the timeline event. |
+| <a id="projectincidentmanagementtimelineeventincidentid"></a>`incidentId` | [`IssueID!`](#issueid) | ID of the incident. |
+
+##### `Project.incidentManagementTimelineEvents`
+
+Incident Management Timeline events associated with the incident.
+
+Returns [`TimelineEventTypeConnection`](#timelineeventtypeconnection).
+
+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="projectincidentmanagementtimelineeventsincidentid"></a>`incidentId` | [`IssueID!`](#issueid) | ID of the incident. |
+
##### `Project.issue`
A single issue of the project.
@@ -13532,6 +13836,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="projectmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="projectmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="projectmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="projectmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="projectmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="projectmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="projectmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
@@ -13635,7 +13940,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="projectpipelinesref"></a>`ref` | [`String`](#string) | Filter pipelines by the ref they are run for. |
| <a id="projectpipelinesscope"></a>`scope` | [`PipelineScopeEnum`](#pipelinescopeenum) | Filter pipelines by scope. |
| <a id="projectpipelinessha"></a>`sha` | [`String`](#string) | Filter pipelines by the sha of the commit they are run for. |
-| <a id="projectpipelinessource"></a>`source` | [`String`](#string) | Filter pipelines by their source. Will be ignored if `dast_view_scans` feature flag is disabled. |
+| <a id="projectpipelinessource"></a>`source` | [`String`](#string) | Filter pipelines by their source. |
| <a id="projectpipelinesstatus"></a>`status` | [`PipelineStatusEnum`](#pipelinestatusenum) | Filter pipelines by their status. |
##### `Project.projectMembers`
@@ -13739,6 +14044,18 @@ four standard [pagination arguments](#connection-pagination-arguments):
| ---- | ---- | ----------- |
| <a id="projectscanexecutionpoliciesactionscantypes"></a>`actionScanTypes` | [`[SecurityReportTypeEnum!]`](#securityreporttypeenum) | Filters policies by the action scan type. Only these scan types are supported: `dast`, `secret_detection`, `cluster_image_scanning`, `container_scanning`, `sast`. |
+##### `Project.securityTrainingProviders`
+
+List of security training providers for the project.
+
+Returns [`[ProjectSecurityTraining!]`](#projectsecuritytraining).
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="projectsecuritytrainingprovidersonlyenabled"></a>`onlyEnabled` | [`Boolean`](#boolean) | Filter the list by only enabled security trainings. |
+
##### `Project.sentryDetailedError`
Detailed version of a Sentry error on the project.
@@ -13962,6 +14279,20 @@ Represents a Project Membership.
| <a id="projectpermissionsupdatewiki"></a>`updateWiki` | [`Boolean!`](#boolean) | Indicates the user can perform `update_wiki` on this resource. |
| <a id="projectpermissionsuploadfile"></a>`uploadFile` | [`Boolean!`](#boolean) | Indicates the user can perform `upload_file` on this resource. |
+### `ProjectSecurityTraining`
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="projectsecuritytrainingdescription"></a>`description` | [`String`](#string) | Description of the training provider. |
+| <a id="projectsecuritytrainingid"></a>`id` | [`GlobalID!`](#globalid) | ID of the training provider. |
+| <a id="projectsecuritytrainingisenabled"></a>`isEnabled` | [`Boolean!`](#boolean) | Represents whether the provider is enabled or not. |
+| <a id="projectsecuritytrainingisprimary"></a>`isPrimary` | [`Boolean!`](#boolean) | Represents whether the provider is set as primary or not. |
+| <a id="projectsecuritytraininglogourl"></a>`logoUrl` | [`String`](#string) | Logo URL of the provider. |
+| <a id="projectsecuritytrainingname"></a>`name` | [`String!`](#string) | Name of the training provider. |
+| <a id="projectsecuritytrainingurl"></a>`url` | [`String!`](#string) | URL of the provider. |
+
### `ProjectStatistics`
#### Fields
@@ -14202,13 +14533,18 @@ Returns [`Tree`](#tree).
| Name | Type | Description |
| ---- | ---- | ----------- |
+| <a id="repositoryblobarchived"></a>`archived` | [`Boolean`](#boolean) | Whether the current project is archived. |
+| <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="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="repositoryblobexternalstorage"></a>`externalStorage` | [`String`](#string) | External storage being used, if enabled (for instance, 'LFS'). |
| <a id="repositoryblobexternalstorageurl"></a>`externalStorageUrl` | [`String`](#string) | Web path to download the raw blob via external storage, if enabled. |
| <a id="repositoryblobfiletype"></a>`fileType` | [`String`](#string) | 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="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. |
| <a id="repositoryblobideforkandeditpath"></a>`ideForkAndEditPath` | [`String`](#string) | Web path to edit this blob in the Web IDE using a forked project. |
@@ -14217,6 +14553,7 @@ Returns [`Tree`](#tree).
| <a id="repositoryblobname"></a>`name` | [`String`](#string) | Blob name. |
| <a id="repositorybloboid"></a>`oid` | [`String!`](#string) | OID of the blob. |
| <a id="repositoryblobpath"></a>`path` | [`String!`](#string) | Path of the blob. |
+| <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="repositoryblobrawblob"></a>`rawBlob` | [`String`](#string) | Raw content of the blob. |
@@ -14429,6 +14766,20 @@ Represents the scan execution policy.
| <a id="scanexecutionpolicyupdatedat"></a>`updatedAt` | [`Time!`](#time) | Timestamp of when the policy YAML was last updated. |
| <a id="scanexecutionpolicyyaml"></a>`yaml` | [`String!`](#string) | YAML definition of the policy. |
+### `ScanResultPolicy`
+
+Represents the scan result policy.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="scanresultpolicydescription"></a>`description` | [`String!`](#string) | Description of the policy. |
+| <a id="scanresultpolicyenabled"></a>`enabled` | [`Boolean!`](#boolean) | Indicates whether this policy is enabled. |
+| <a id="scanresultpolicyname"></a>`name` | [`String!`](#string) | Name of the policy. |
+| <a id="scanresultpolicyupdatedat"></a>`updatedAt` | [`Time!`](#time) | Timestamp of when the policy YAML was last updated. |
+| <a id="scanresultpolicyyaml"></a>`yaml` | [`String!`](#string) | YAML definition of the policy. |
+
### `ScannedResource`
Represents a resource scanned by a security scan.
@@ -14999,6 +15350,27 @@ Represents a historically accurate report about the timebox.
| <a id="timeboxreportburnuptimeseries"></a>`burnupTimeSeries` | [`[BurnupChartDailyTotals!]`](#burnupchartdailytotals) | Daily scope and completed totals for burnup charts. |
| <a id="timeboxreportstats"></a>`stats` | [`TimeReportStats`](#timereportstats) | Represents the time report stats for the timebox. |
+### `TimelineEventType`
+
+Describes an incident management timeline event.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="timelineeventtypeaction"></a>`action` | [`String!`](#string) | Indicates the timeline event icon. |
+| <a id="timelineeventtypeauthor"></a>`author` | [`UserCore`](#usercore) | User that created the timeline event. |
+| <a id="timelineeventtypecreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp when the event created. |
+| <a id="timelineeventtypeeditable"></a>`editable` | [`Boolean!`](#boolean) | Indicates the timeline event is editable. |
+| <a id="timelineeventtypeid"></a>`id` | [`IncidentManagementTimelineEventID!`](#incidentmanagementtimelineeventid) | ID of the timeline event. |
+| <a id="timelineeventtypeincident"></a>`incident` | [`Issue!`](#issue) | Incident of the timeline event. |
+| <a id="timelineeventtypenote"></a>`note` | [`String`](#string) | Text note of the timeline event. |
+| <a id="timelineeventtypenotehtml"></a>`noteHtml` | [`String`](#string) | HTML note of the timeline event. |
+| <a id="timelineeventtypeoccurredat"></a>`occurredAt` | [`Time!`](#time) | Timestamp when the event occurred. |
+| <a id="timelineeventtypepromotedfromnote"></a>`promotedFromNote` | [`Note`](#note) | Note from which the timeline event was created. |
+| <a id="timelineeventtypeupdatedat"></a>`updatedAt` | [`Time!`](#time) | Timestamp when the event updated. |
+| <a id="timelineeventtypeupdatedbyuser"></a>`updatedByUser` | [`UserCore`](#usercore) | User that updated the timeline event. |
+
### `Timelog`
#### Fields
@@ -15155,6 +15527,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="usercoreassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="usercoreassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="usercoreassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="usercoreassignedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="usercoreassignedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="usercoreassignedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="usercoreassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
@@ -15186,6 +15559,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="usercoreauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
| <a id="usercoreauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="usercoreauthoredmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="usercoreauthoredmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="usercoreauthoredmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="usercoreauthoredmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="usercoreauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
@@ -15202,7 +15576,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
##### `UserCore.groups`
-Groups where the user has access. Will always return `null` if `paginatable_namespace_drop_down_for_project_creation` feature flag is disabled.
+Groups where the user has access.
Returns [`GroupConnection`](#groupconnection).
@@ -15235,6 +15609,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="usercorereviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="usercorereviewrequestedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="usercorereviewrequestedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="usercorereviewrequestedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="usercorereviewrequestedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="usercorereviewrequestedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="usercorereviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
@@ -15861,6 +16236,30 @@ Represents vulnerability letter grades with associated projects.
| <a id="vulnerableprojectsbygradegrade"></a>`grade` | [`VulnerabilityGrade!`](#vulnerabilitygrade) | Grade based on the highest severity vulnerability present. |
| <a id="vulnerableprojectsbygradeprojects"></a>`projects` | [`ProjectConnection!`](#projectconnection) | Projects within this grade. (see [Connections](#connections)) |
+### `WorkItem`
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="workitemdescription"></a>`description` | [`String`](#string) | Description of the work item. |
+| <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="workitemtitle"></a>`title` | [`String!`](#string) | Title of the work item. |
+| <a id="workitemtitlehtml"></a>`titleHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `title`. |
+| <a id="workitemworkitemtype"></a>`workItemType` | [`WorkItemType!`](#workitemtype) | Type assigned to the work item. |
+
+### `WorkItemType`
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="workitemtypeiconname"></a>`iconName` | [`String`](#string) | Icon name of the work item type. |
+| <a id="workitemtypeid"></a>`id` | [`WorkItemsTypeID!`](#workitemstypeid) | Global ID of the work item type. |
+| <a id="workitemtypename"></a>`name` | [`String!`](#string) | Name of the work item type. |
+
## Enumeration types
Also called _Enums_, enumeration types are a special kind of scalar that
@@ -15884,6 +16283,15 @@ Access level to a resource.
| <a id="accesslevelenumowner"></a>`OWNER` | Owner access. |
| <a id="accesslevelenumreporter"></a>`REPORTER` | Reporter access. |
+### `AgentTokenStatus`
+
+Agent token statuses.
+
+| Value | Description |
+| ----- | ----------- |
+| <a id="agenttokenstatusactive"></a>`ACTIVE` | Active agent token. |
+| <a id="agenttokenstatusrevoked"></a>`REVOKED` | Revoked agent token. |
+
### `AlertManagementAlertSort`
Values for sorting alerts.
@@ -16444,6 +16852,7 @@ Group member relation.
| <a id="groupmemberrelationdescendants"></a>`DESCENDANTS` | Members in the group's subgroups. |
| <a id="groupmemberrelationdirect"></a>`DIRECT` | Members in the group itself. |
| <a id="groupmemberrelationinherited"></a>`INHERITED` | Members in the group's ancestor groups. |
+| <a id="groupmemberrelationshared_from_groups"></a>`SHARED_FROM_GROUPS` | Invited group's members. |
### `GroupPermission`
@@ -16503,6 +16912,17 @@ Iteration ID wildcard values for issue creation.
| ----- | ----------- |
| <a id="issuecreationiterationwildcardidcurrent"></a>`CURRENT` | Current iteration. |
+### `IssueEscalationStatus`
+
+Issue escalation status values.
+
+| Value | Description |
+| ----- | ----------- |
+| <a id="issueescalationstatusacknowledged"></a>`ACKNOWLEDGED` | Someone is actively investigating the problem. |
+| <a id="issueescalationstatusignored"></a>`IGNORED` | No action will be taken. |
+| <a id="issueescalationstatusresolved"></a>`RESOLVED` | The problem has been addressed. |
+| <a id="issueescalationstatustriggered"></a>`TRIGGERED` | Investigation has not started. |
+
### `IssueSort`
Values for sorting issues.
@@ -17114,6 +17534,15 @@ State of a Sentry error.
| <a id="servicetypeyoutrack_service"></a>`YOUTRACK_SERVICE` | YoutrackService type. |
| <a id="servicetypezentao_service"></a>`ZENTAO_SERVICE` | ZentaoService type. |
+### `ShaFormat`
+
+How to format SHA strings.
+
+| Value | Description |
+| ----- | ----------- |
+| <a id="shaformatlong"></a>`LONG` | Unabbreviated format. |
+| <a id="shaformatshort"></a>`SHORT` | Abbreviated format. Short SHAs are typically eight characters long. |
+
### `SharedRunnersSetting`
| Value | Description |
@@ -17214,6 +17643,7 @@ Name of the feature that the callout is for.
| <a id="usercalloutfeaturenameenumactive_user_count_threshold"></a>`ACTIVE_USER_COUNT_THRESHOLD` | Callout feature name for active_user_count_threshold. |
| <a id="usercalloutfeaturenameenumbuy_pipeline_minutes_notification_dot"></a>`BUY_PIPELINE_MINUTES_NOTIFICATION_DOT` | Callout feature name for buy_pipeline_minutes_notification_dot. |
| <a id="usercalloutfeaturenameenumcanary_deployment"></a>`CANARY_DEPLOYMENT` | Callout feature name for canary_deployment. |
+| <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. |
| <a id="usercalloutfeaturenameenumcloud_licensing_subscription_activation_banner"></a>`CLOUD_LICENSING_SUBSCRIPTION_ACTIVATION_BANNER` | Callout feature name for cloud_licensing_subscription_activation_banner. |
| <a id="usercalloutfeaturenameenumcluster_security_warning"></a>`CLUSTER_SECURITY_WARNING` | Callout feature name for cluster_security_warning. |
| <a id="usercalloutfeaturenameenumeoa_bronze_plan_banner"></a>`EOA_BRONZE_PLAN_BANNER` | Callout feature name for eoa_bronze_plan_banner. |
@@ -17387,10 +17817,10 @@ The state of the vulnerability.
| Value | Description |
| ----- | ----------- |
-| <a id="vulnerabilitystateconfirmed"></a>`CONFIRMED` | Confirmed vulnerability. |
-| <a id="vulnerabilitystatedetected"></a>`DETECTED` | Detected vulnerability. |
-| <a id="vulnerabilitystatedismissed"></a>`DISMISSED` | Dismissed vulnerability. |
-| <a id="vulnerabilitystateresolved"></a>`RESOLVED` | Resolved vulnerability. |
+| <a id="vulnerabilitystateconfirmed"></a>`CONFIRMED` | For details, see [vulnerability status values](https://docs.gitlab.com/ee/user/application_security/vulnerabilities/index.html#vulnerability-status-values). |
+| <a id="vulnerabilitystatedetected"></a>`DETECTED` | For details, see [vulnerability status values](https://docs.gitlab.com/ee/user/application_security/vulnerabilities/index.html#vulnerability-status-values). |
+| <a id="vulnerabilitystatedismissed"></a>`DISMISSED` | For details, see [vulnerability status values](https://docs.gitlab.com/ee/user/application_security/vulnerabilities/index.html#vulnerability-status-values). |
+| <a id="vulnerabilitystateresolved"></a>`RESOLVED` | For details, see [vulnerability status values](https://docs.gitlab.com/ee/user/application_security/vulnerabilities/index.html#vulnerability-status-values). |
### `WeightWildcardId`
@@ -17691,6 +18121,12 @@ A `IncidentManagementOncallRotationID` is a global ID. It is encoded as a string
An example `IncidentManagementOncallRotationID` is: `"gid://gitlab/IncidentManagement::OncallRotation/1"`.
+### `IncidentManagementTimelineEventID`
+
+A `IncidentManagementTimelineEventID` is a global ID. It is encoded as a string.
+
+An example `IncidentManagementTimelineEventID` is: `"gid://gitlab/IncidentManagement::TimelineEvent/1"`.
+
### `Int`
Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.
@@ -17925,6 +18361,12 @@ A `VulnerabilitiesExternalIssueLinkID` is a global ID. It is encoded as a string
An example `VulnerabilitiesExternalIssueLinkID` is: `"gid://gitlab/Vulnerabilities::ExternalIssueLink/1"`.
+### `VulnerabilitiesFindingID`
+
+A `VulnerabilitiesFindingID` is a global ID. It is encoded as a string.
+
+An example `VulnerabilitiesFindingID` is: `"gid://gitlab/Vulnerabilities::Finding/1"`.
+
### `VulnerabilitiesScannerID`
A `VulnerabilitiesScannerID` is a global ID. It is encoded as a string.
@@ -17937,6 +18379,18 @@ A `VulnerabilityID` is a global ID. It is encoded as a string.
An example `VulnerabilityID` is: `"gid://gitlab/Vulnerability/1"`.
+### `WorkItemID`
+
+A `WorkItemID` is a global ID. It is encoded as a string.
+
+An example `WorkItemID` is: `"gid://gitlab/WorkItem/1"`.
+
+### `WorkItemsTypeID`
+
+A `WorkItemsTypeID` is a global ID. It is encoded as a string.
+
+An example `WorkItemsTypeID` is: `"gid://gitlab/WorkItems::Type/1"`.
+
## Abstract types
Abstract types (unions and interfaces) are ways the schema can represent
@@ -18180,6 +18634,23 @@ Implementations:
| <a id="noteableinterfacediscussions"></a>`discussions` | [`DiscussionConnection!`](#discussionconnection) | All discussions on this noteable. (see [Connections](#connections)) |
| <a id="noteableinterfacenotes"></a>`notes` | [`NoteConnection!`](#noteconnection) | All notes on this noteable. (see [Connections](#connections)) |
+#### `OrchestrationPolicy`
+
+Implementations:
+
+- [`ScanExecutionPolicy`](#scanexecutionpolicy)
+- [`ScanResultPolicy`](#scanresultpolicy)
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="orchestrationpolicydescription"></a>`description` | [`String!`](#string) | Description of the policy. |
+| <a id="orchestrationpolicyenabled"></a>`enabled` | [`Boolean!`](#boolean) | Indicates whether this policy is enabled. |
+| <a id="orchestrationpolicyname"></a>`name` | [`String!`](#string) | Name of the policy. |
+| <a id="orchestrationpolicyupdatedat"></a>`updatedAt` | [`Time!`](#time) | Timestamp of when the policy YAML was last updated. |
+| <a id="orchestrationpolicyyaml"></a>`yaml` | [`String!`](#string) | YAML definition of the policy. |
+
#### `PackageFileMetadata`
Represents metadata associated with a Package file.
@@ -18291,6 +18762,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="userassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="userassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="userassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="userassignedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="userassignedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="userassignedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="userassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
@@ -18322,6 +18794,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="userauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
| <a id="userauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="userauthoredmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="userauthoredmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="userauthoredmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="userauthoredmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="userauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
@@ -18338,7 +18811,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
###### `User.groups`
-Groups where the user has access. Will always return `null` if `paginatable_namespace_drop_down_for_project_creation` feature flag is disabled.
+Groups where the user has access.
Returns [`GroupConnection`](#groupconnection).
@@ -18371,6 +18844,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="userreviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="userreviewrequestedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="userreviewrequestedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="userreviewrequestedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="userreviewrequestedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="userreviewrequestedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="userreviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
diff --git a/doc/api/group_access_tokens.md b/doc/api/group_access_tokens.md
new file mode 100644
index 00000000000..37471b9d89d
--- /dev/null
+++ b/doc/api/group_access_tokens.md
@@ -0,0 +1,112 @@
+---
+stage: Manage
+group: Authentication & 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
+---
+
+# Group access tokens API **(FREE)**
+
+You can read more about [group access tokens](../user/group/settings/group_access_tokens.md).
+
+## List group access tokens
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77236) in GitLab 14.7.
+
+Get a list of [group access tokens](../user/group/settings/group_access_tokens.md).
+
+```plaintext
+GET groups/:id/access_tokens
+```
+
+| Attribute | Type | required | Description |
+|-----------|---------|----------|---------------------|
+| `id` | integer or string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/<group_id>/access_tokens"
+```
+
+```json
+[
+ {
+ "user_id" : 141,
+ "scopes" : [
+ "api"
+ ],
+ "name" : "token",
+ "expires_at" : "2021-01-31",
+ "id" : 42,
+ "active" : true,
+ "created_at" : "2021-01-20T22:11:48.151Z",
+ "revoked" : false,
+ "access_level": 40
+ }
+]
+```
+
+## Create a group access token
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77236) in GitLab 14.7.
+
+Create a [group access token](../user/group/settings/group_access_tokens.md).
+
+```plaintext
+POST groups/:id/access_tokens
+```
+
+| Attribute | Type | required | Description |
+|-----------|---------|----------|---------------------|
+| `id` | integer or string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) |
+| `name` | String | yes | The name of the group access token |
+| `scopes` | `Array[String]` | yes | [List of scopes](../user/project/settings/project_access_tokens.md#scopes-for-a-project-access-token) |
+| `access_level` | Integer | no | A valid access level. Default value is 40 (Maintainer). Other allowed values are 10 (Guest), 20 (Reporter), and 30 (Developer). |
+| `expires_at` | Date | no | The token expires at midnight UTC on that date |
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
+--header "Content-Type:application/json" \
+--data '{ "name":"test_token", "scopes":["api", "read_repository"], "expires_at":"2021-01-31", "access_level": 30 }' \
+"https://gitlab.example.com/api/v4/groups/<group_id>/access_tokens"
+```
+
+```json
+{
+ "scopes" : [
+ "api",
+ "read_repository"
+ ],
+ "active" : true,
+ "name" : "test",
+ "revoked" : false,
+ "created_at" : "2021-01-21T19:35:37.921Z",
+ "user_id" : 166,
+ "id" : 58,
+ "expires_at" : "2021-01-31",
+ "token" : "D4y...Wzr",
+ "access_level": 30
+}
+```
+
+## Revoke a group access token
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77236) in GitLab 14.7.
+
+Revoke a [group access token](../user/group/settings/group_access_tokens.md).
+
+```plaintext
+DELETE groups/:id/access_tokens/:token_id
+```
+
+| Attribute | Type | required | Description |
+|-----------|---------|----------|---------------------|
+| `id` | integer or string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) |
+| `token_id` | integer or string | yes | The ID of the group access token |
+
+```shell
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/<group_id>/access_tokens/<token_id>"
+```
+
+### Responses
+
+- `204: No Content` if successfully revoked.
+- `400 Bad Request` or `404 Not Found` if not revoked successfully.
diff --git a/doc/api/group_badges.md b/doc/api/group_badges.md
index 1e830237b50..ecb73aa8a5e 100644
--- a/doc/api/group_badges.md
+++ b/doc/api/group_badges.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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/api/group_iterations.md b/doc/api/group_iterations.md
index af27b558dfe..7f663515fee 100644
--- a/doc/api/group_iterations.md
+++ b/doc/api/group_iterations.md
@@ -43,6 +43,7 @@ Example response:
{
"id": 53,
"iid": 13,
+ "sequence": 1,
"group_id": 5,
"title": "Iteration II",
"description": "Ipsum Lorem ipsum",
diff --git a/doc/api/group_protected_environments.md b/doc/api/group_protected_environments.md
index 0e1cd149c51..6ce4e1791b0 100644
--- a/doc/api/group_protected_environments.md
+++ b/doc/api/group_protected_environments.md
@@ -48,12 +48,13 @@ Example response:
"name":"production",
"deploy_access_levels":[
{
- "access_level":40,
- "access_level_description":"Maintainers",
- "user_id":null,
- "group_id":null
+ "access_level": 40,
+ "access_level_description": "Maintainers",
+ "user_id": null,
+ "group_id": null
}
- ]
+ ],
+ "required_approval_count": 0
}
]
```
@@ -87,7 +88,8 @@ Example response:
"user_id":null,
"group_id":null
}
- ]
+ ],
+ "required_approval_count": 0
}
```
@@ -104,6 +106,7 @@ POST /groups/:id/protected_environments
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) maintained by the authenticated user. |
| `name` | string | yes | The deployment tier of the protected environment. One of `production`, `staging`, `testing`, `development`, or `other`. Read more about [deployment tiers](../ci/environments/index.md#deployment-tier-of-environments).|
| `deploy_access_levels` | array | yes | Array of access levels allowed to deploy, with each described by a hash. One of `user_id`, `group_id` or `access_level`. They take the form of `{user_id: integer}`, `{group_id: integer}` or `{access_level: integer}` respectively. |
+| `required_approval_count` | integer | no | The number of approvals required to deploy to this environment. This is part of Deployment Approvals, which isn't yet available for use. For details, see [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/343864). |
The assignable `user_id` are the users who belong to the given group with the Maintainer role (or above).
The assignable `group_id` are the sub-groups under the given group.
@@ -119,12 +122,13 @@ Example response:
"name":"production",
"deploy_access_levels":[
{
- "access_level":40,
- "access_level_description":"protected-access-group",
- "user_id":null,
- "group_id":9899826
+ "access_level": 40,
+ "access_level_description": "protected-access-group",
+ "user_id": null,
+ "group_id": 9899826
}
- ]
+ ],
+ "required_approval_count": 0
}
```
diff --git a/doc/api/groups.md b/doc/api/groups.md
index 13dea42f3c6..d7b4f0c8b54 100644
--- a/doc/api/groups.md
+++ b/doc/api/groups.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -802,9 +802,9 @@ Parameters:
| `lfs_enabled` | boolean | no | Enable/disable Large File Storage (LFS) for the projects in this group. |
| `request_access_enabled` | boolean | no | Allow users to request member access. |
| `parent_id` | integer | no | The parent group ID for creating nested group. |
-| `default_branch_protection` | integer | no | See [Options for `default_branch_protection`](#options-for-default_branch_protection). Default to the global level default branch protection setting. |
-| `shared_runners_minutes_limit` **(PREMIUM SELF)** | integer | no | Pipeline minutes quota for this group (included in plan). Can be `nil` (default; inherit system default), `0` (unlimited) or `> 0` |
-| `extra_shared_runners_minutes_limit` **(PREMIUM SELF)** | integer | no | Extra pipeline minutes quota for this group (purchased in addition to the minutes included in the plan). |
+| `default_branch_protection` | integer | no | See [Options for `default_branch_protection`](#options-for-default_branch_protection). Default to the global level default branch protection setting. |
+| `shared_runners_minutes_limit` **(PREMIUM)** | integer | no | Can be set by administrators only. Maximum number of monthly CI/CD minutes for this group. Can be `nil` (default; inherit system default), `0` (unlimited), or `> 0`. |
+| `extra_shared_runners_minutes_limit` **(PREMIUM)** | integer | no | Can be set by administrators only. Additional CI/CD minutes for this group. |
### Options for `default_branch_protection`
@@ -905,8 +905,8 @@ PUT /groups/:id
| `request_access_enabled` | boolean | no | Allow users to request member access. |
| `default_branch_protection` | integer | no | See [Options for `default_branch_protection`](#options-for-default_branch_protection). |
| `file_template_project_id` **(PREMIUM)** | integer | no | The ID of a project to load custom file templates from. |
-| `shared_runners_minutes_limit` **(PREMIUM SELF)** | integer | no | Pipeline minutes quota for this group (included in plan). Can be `nil` (default; inherit system default), `0` (unlimited) or `> 0` |
-| `extra_shared_runners_minutes_limit` **(PREMIUM SELF)** | integer | no | Extra pipeline minutes quota for this group (purchased in addition to the minutes included in the plan). |
+| `shared_runners_minutes_limit` **(PREMIUM)** | integer | no | Can be set by administrators only. Maximum number of monthly CI/CD minutes for this group. Can be `nil` (default; inherit system default), `0` (unlimited), or `> 0`. |
+| `extra_shared_runners_minutes_limit` **(PREMIUM)** | integer | no | Can be set by administrators only. Additional CI/CD minutes for this group. |
| `prevent_forking_outside_group` **(PREMIUM)** | boolean | no | When enabled, users can **not** fork projects from this group to external namespaces
| `shared_runners_setting` | string | no | See [Options for `shared_runners_setting`](#options-for-shared_runners_setting). Enable or disable shared runners for a group's subgroups and projects. |
| `prevent_sharing_groups_outside_hierarchy` | boolean | no | See [Prevent group sharing outside the group hierarchy](../user/group/index.md#prevent-group-sharing-outside-the-group-hierarchy). This attribute is only available on top-level groups. [Introduced in GitLab 14.1](https://gitlab.com/gitlab-org/gitlab/-/issues/333721) |
diff --git a/doc/api/index.md b/doc/api/index.md
index a4e7a893618..69db971f58c 100644
--- a/doc/api/index.md
+++ b/doc/api/index.md
@@ -64,8 +64,7 @@ For the changes between v3 and v4, see the [v3 to v4 documentation](v3_to_v4.md)
### Current status
-Only API version v4 is available. Version v3 was removed in
-[GitLab 11.0](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/36819).
+Only API version v4 is available.
## How to use the API
@@ -170,24 +169,24 @@ for examples requesting a new access token using a refresh token.
A default refresh setting of two hours is tracked in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/336598).
-### Personal/project access tokens
+### Personal/project/group access tokens
You can use access tokens to authenticate with the API by passing it in either
the `private_token` parameter or the `PRIVATE-TOKEN` header.
-Example of using the personal or project access token in a parameter:
+Example of using the personal, project, or group access token in a parameter:
```shell
curl "https://gitlab.example.com/api/v4/projects?private_token=<your_access_token>"
```
-Example of using the personal or project access token in a header:
+Example of using the personal, project, or group access token in a header:
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects"
```
-You can also use personal or project access tokens with OAuth-compliant headers:
+You can also use personal, project, or group access tokens with OAuth-compliant headers:
```shell
curl --header "Authorization: Bearer <your_access_token>" "https://gitlab.example.com/api/v4/projects"
@@ -224,8 +223,6 @@ header.
#### Disable impersonation
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/40385) in GitLab 11.6.
-
By default, impersonation is enabled. To disable impersonation:
**For Omnibus installations**
diff --git a/doc/api/integrations.md b/doc/api/integrations.md
index 8f57e915b4e..dd5a8c568fb 100644
--- a/doc/api/integrations.md
+++ b/doc/api/integrations.md
@@ -314,13 +314,15 @@ PUT /projects/:id/integrations/datadog
Parameters:
-| Parameter | Type | Required | Description |
-| --------- | ---- | -------- | ----------- |
-| `api_key` | string | true | API key used for authentication with Datadog |
-| `api_url` | string | false | (Advanced) Define the full URL for your Datadog site directly |
-| `datadog_site` | string | false | Choose the Datadog site to send data to. Set to `datadoghq.eu` to send data to the EU site |
-| `datadog_service` | string | false | Name of this GitLab instance that all data will be tagged with |
-| `datadog_env` | string | false | The environment tag that traces will be tagged with |
+| Parameter | Type | Required | Description |
+| ---------------------- | ------- | -------- | ----------- |
+| `api_key` | string | true | API key used for authentication with Datadog |
+| `api_url` | string | false | (Advanced) The full URL for your Datadog site |
+<!-- | `archive_trace_events` | boolean | false | When enabled, job logs are collected by Datadog and displayed along with pipeline execution traces ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/346339) in GitLab 14.7) | -->
+<!-- TODO: uncomment the archive_trace_events field once :datadog_integration_logs_collection is rolled out. Rollout issue: https://gitlab.com/gitlab-org/gitlab/-/issues/346339 -->
+| `datadog_env` | string | false | For self-managed deployments, set the env% tag for all the data sent to Datadog. |
+| `datadog_service` | string | false | Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments |
+| `datadog_site` | string | false | The Datadog site to send data to. To send data to the EU site, use `datadoghq.eu` |
### Disable Datadog integration
diff --git a/doc/api/issues.md b/doc/api/issues.md
index 204d75e9ee4..5d22952a876 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -54,14 +54,15 @@ GET /issues?state=opened
| Attribute | Type | Required | Description |
| ------------------- | ---------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13004) in GitLab 9.5)_ |
+| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. |
| `assignee_username` | string array | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In GitLab CE, the `assignee_username` array should only contain a single value. Otherwise, an invalid parameter error is returned. |
-| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13004) in GitLab 9.5)_ |
+| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. |
| `author_username` | string | no | Return issues created by the given `username`. Similar to `author_id` and mutually exclusive with `author_id`. |
| `confidential` | boolean | no | Filter confidential or public issues. |
| `created_after` | datetime | no | Return issues created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `created_before` | datetime | no | Return issues created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233420) in GitLab 13.3)_ |
+| `epic_id` **(PREMIUM)** | integer | no | Return issues associated with the given epic ID. `None` returns issues that are not associated with an epic. `Any` returns issues that are associated with an epic. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46887) in GitLab 13.6)_
| `iids[]` | integer array | no | Return only the issues having the given `iid` |
| `in` | string | no | Modify the scope of the `search` attribute. `title`, `description`, or a string joining them with comma. Default is `title,description` |
| `issue_type` | string | no | Filter to a given type of issue. One of `issue`, `incident`, or `test_case`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/260375) in GitLab 13.12)_ |
@@ -70,11 +71,11 @@ GET /issues?state=opened
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
| `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. Using `None` or `Any` will be [deprecated in the future](https://gitlab.com/gitlab-org/gitlab/-/issues/336044). Please use `milestone_id` attribute instead. `milestone` and `milestone_id` are mutually exclusive. |
| `milestone_id` | string | no | Returns issues assigned to milestones with a given timebox value (`None`, `Any`, `Upcoming`, and `Started`). `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. `Upcoming` lists all issues assigned to milestones due in the future. `Started` lists all issues assigned to open, started milestones. `milestone` and `milestone_id` are mutually exclusive. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/335939) in GitLab 14.3)_ |
-| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/14016) in GitLab 10.0)_ |
+| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. |
| `non_archived` | boolean | no | Return issues only from non-archived projects. If `false`, the response returns issues from both archived and non-archived projects. Default is `true`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/197170) in GitLab 13.0)_ |
| `not` | Hash | no | Return issues that do not match the parameters supplied. Accepts: `assignee_id`, `assignee_username`, `author_id`, `author_username`, `iids`, `iteration_id`, `iteration_title`, `labels`, `milestone`, `milestone_id` and `weight`. |
| `order_by` | string | no | Return issues ordered by `created_at`, `due_date`, `label_priority`, `milestone_due`, `popularity`, `priority`, `relative_position`, `title`, `updated_at`, or `weight` fields. Default is `created_at`. |
-| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`. Defaults to `created_by_me`<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead.<br> _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13004) in GitLab 9.5. [Changed to snake_case](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/18935) in GitLab 11.0)_ |
+| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`. Defaults to `created_by_me`. |
| `search` | string | no | Search issues against their `title` and `description` |
| `sort` | string | no | Return issues sorted in `asc` or `desc` order. Default is `desc` |
| `state` | string | no | Return `all` issues or just those that are `opened` or `closed` |
@@ -228,11 +229,6 @@ WARNING:
The `epic_iid` attribute is deprecated and [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5.
Please use `iid` of the `epic` attribute instead.
-NOTE:
-The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6.
-This value is only present for issues closed after GitLab 10.6 and if the user account
-that closed the issue still exists.
-
## List group issues
> The `weight` property moved to GitLab Premium in 13.9.
@@ -261,14 +257,15 @@ GET /groups/:id/issues?state=opened
| Attribute | Type | Required | Description |
| ------------------- | ---------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
-| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13004) in GitLab 9.5)_ |
+| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. |
| `assignee_username` | string array | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In GitLab CE, the `assignee_username` array should only contain a single value. Otherwise, an invalid parameter error is returned. |
-| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13004) in GitLab 9.5)_ |
+| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. |
| `author_username` | string | no | Return issues created by the given `username`. Similar to `author_id` and mutually exclusive with `author_id`. |
| `confidential` | boolean | no | Filter confidential or public issues. |
| `created_after` | datetime | no | Return issues created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `created_before` | datetime | no | Return issues created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233420) in GitLab 13.3)_ |
+| `epic_id` **(PREMIUM)** | integer | no | Return issues associated with the given epic ID. `None` returns issues that are not associated with an epic. `Any` returns issues that are associated with an epic. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46887) in GitLab 13.6)_
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) owned by the authenticated user |
| `iids[]` | integer array | no | Return only the issues having the given `iid` |
| `issue_type` | string | no | Filter to a given type of issue. One of `issue`, `incident`, or `test_case`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/260375) in GitLab 13.12)_ |
@@ -276,11 +273,11 @@ GET /groups/:id/issues?state=opened
| `iteration_title` **(PREMIUM)** | string | no | Return issues assigned to the iteration with the given title. Similar to `iteration_id` and mutually exclusive with `iteration_id`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
| `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. |
-| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/14016) in GitLab 10.0)_ |
+| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. |
| `non_archived` | boolean | no | Return issues from non archived projects. Default is true. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23785) in GitLab 12.8)_ |
| `not` | Hash | no | Return issues that do not match the parameters supplied. Accepts: `labels`, `milestone`, `author_id`, `author_username`, `assignee_id`, `assignee_username`, `my_reaction_emoji`, `search`, `in` |
| `order_by` | string | no | Return issues ordered by `created_at`, `updated_at`, `priority`, `due_date`, `relative_position`, `label_priority`, `milestone_due`, `popularity`, `weight` fields. Default is `created_at` |
-| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`.<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead.<br> _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13004) in GitLab 9.5. [Changed to snake_case](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/18935) in GitLab 11.0)_ |
+| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`. Defaults to `all`. |
| `search` | string | no | Search group issues against their `title` and `description` |
| `sort` | string | no | Return issues sorted in `asc` or `desc` order. Default is `desc` |
| `state` | string | no | Return all issues or just those that are `opened` or `closed` |
@@ -432,11 +429,6 @@ WARNING:
The `epic_iid` attribute is deprecated and [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5.
Please use `iid` of the `epic` attribute instead.
-NOTE:
-The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6.
-This value is only present for issues closed after GitLab 10.6 and if the user account that closed
-the issue still exists.
-
## List project issues
> The `weight` property moved to GitLab Premium in 13.9.
@@ -465,14 +457,15 @@ GET /projects/:id/issues?state=opened
| Attribute | Type | Required | Description |
| ------------------- | ---------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
-| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13004) in GitLab 9.5)_ |
+| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. |
| `assignee_username` | string array | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In GitLab CE, the `assignee_username` array should only contain a single value. Otherwise, an invalid parameter error is returned. |
-| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13004) in GitLab 9.5)_ |
+| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. |
| `author_username` | string | no | Return issues created by the given `username`. Similar to `author_id` and mutually exclusive with `author_id`. |
| `confidential` | boolean | no | Filter confidential or public issues. |
| `created_after` | datetime | no | Return issues created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `created_before` | datetime | no | Return issues created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233420) in GitLab 13.3)_ |
+| `epic_id` **(PREMIUM)** | integer | no | Return issues associated with the given epic ID. `None` returns issues that are not associated with an epic. `Any` returns issues that are associated with an epic. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46887) in GitLab 13.6)_
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
| `iids[]` | integer array | no | Return only the issues having the given `iid` |
| `issue_type` | string | no | Filter to a given type of issue. One of `issue`, `incident`, or `test_case`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/260375) in GitLab 13.12)_ |
@@ -480,10 +473,10 @@ GET /projects/:id/issues?state=opened
| `iteration_title` **(PREMIUM)** | string | no | Return issues assigned to the iteration with the given title. Similar to `iteration_id` and mutually exclusive with `iteration_id`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
| `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. |
-| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/14016) in GitLab 10.0)_ |
+| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. |
| `not` | Hash | no | Return issues that do not match the parameters supplied. Accepts: `labels`, `milestone`, `author_id`, `author_username`, `assignee_id`, `assignee_username`, `my_reaction_emoji`, `search`, `in` |
| `order_by` | string | no | Return issues ordered by `created_at`, `updated_at`, `priority`, `due_date`, `relative_position`, `label_priority`, `milestone_due`, `popularity`, `weight` fields. Default is `created_at` |
-| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`.<br> For versions before 11.0, use the deprecated `created-by-me` or `assigned-to-me` scopes instead.<br> _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13004) in GitLab 9.5. [Changed to snake_case](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/18935) in GitLab 11.0)_ |
+| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`. Defaults to `all`. |
| `search` | string | no | Search project issues against their `title` and `description` |
| `sort` | string | no | Return issues sorted in `asc` or `desc` order. Default is `desc` |
| `state` | string | no | Return all issues or just those that are `opened` or `closed` |
@@ -642,10 +635,6 @@ WARNING:
The `epic_iid` attribute is deprecated and [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5.
Please use `iid` of the `epic` attribute instead.
-NOTE:
-The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6. This value is only present for issues closed after GitLab 10.6 and if the user account that closed
-the issue still exists.
-
## Single issue
Only for administrators. Get a single issue.
@@ -807,11 +796,6 @@ WARNING:
The `epic_iid` attribute is deprecated, and [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5.
Please use `iid` of the `epic` attribute instead.
-NOTE:
-The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6.
-This value is only present for issues closed after GitLab 10.6 and if the user account
-that closed the issue still exists.
-
## Single project issue
Get a single project issue.
@@ -968,10 +952,6 @@ WARNING:
The `epic_iid` attribute is deprecated and [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5.
Please use `iid` of the `epic` attribute instead.
-NOTE:
-The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6. This value is only present for issues closed after GitLab 10.6 and if the user account that closed
-the issue still exists.
-
## New issue
> The `weight` property moved to GitLab Premium in 13.9.
@@ -1118,10 +1098,6 @@ WARNING:
The `epic_iid` attribute is deprecated and [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5.
Please use `iid` of the `epic` attribute instead.
-NOTE:
-The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6. This value is only present for issues closed after GitLab 10.6 and if the user account that closed
-the issue still exists.
-
## Rate limits
To help avoid abuse, users can be limited to a specific number of `Create` requests per minute.
@@ -1289,10 +1265,6 @@ Issues created by users on GitLab Ultimate include the `health_status` property:
]
```
-NOTE:
-The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6. This value is only present for issues closed after GitLab 10.6 and if the user account that closed
-the issue still exists.
-
WARNING:
The `epic_iid` attribute is deprecated and [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5.
Please use `iid` of the `epic` attribute instead.
@@ -1483,10 +1455,6 @@ WARNING:
The `epic_iid` attribute is deprecated and [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5.
Please use `iid` of the `epic` attribute instead.
-NOTE:
-The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6. This value is only present for issues closed after GitLab 10.6 and if the user account that closed
-the issue still exists.
-
## Clone an issue
Clone the issue to given project. If the user has insufficient permissions,
@@ -1735,10 +1703,6 @@ WARNING:
The `epic_iid` attribute is deprecated and [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5.
Please use `iid` of the `epic` attribute instead.
-NOTE:
-The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6. This value is only present for issues closed after GitLab 10.6 and if the user account that closed
-the issue still exists.
-
## Unsubscribe from an issue
Unsubscribes the authenticated user from the issue to not receive notifications
@@ -1929,10 +1893,6 @@ Example response:
WARNING:
The `assignee` column is deprecated. We now show it as a single-sized array `assignees` to conform to the GitLab EE API.
-NOTE:
-The `closed_by` attribute was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042) in GitLab 10.6. This value is only present for issues closed after GitLab 10.6 and if the user account that closed
-the issue still exists.
-
## Promote an issue to an epic **(PREMIUM)**
Promotes an issue to an epic by adding a comment with the `/promote`
diff --git a/doc/api/issues_statistics.md b/doc/api/issues_statistics.md
index 11f24d94763..7687124fb3a 100644
--- a/doc/api/issues_statistics.md
+++ b/doc/api/issues_statistics.md
@@ -41,6 +41,7 @@ GET /issues_statistics?confidential=true
| `author_username` | string | no | Return issues created by the given `username`. Similar to `author_id` and mutually exclusive with `author_id`. |
| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. |
| `assignee_username` | string array | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In GitLab CE `assignee_username` array should only contain a single value or an invalid parameter error is returned otherwise. |
+| `epic_id` **(PREMIUM)** | integer | no | Return issues associated with the given epic ID. `None` returns issues that are not associated with an epic. `Any` returns issues that are associated with an epic. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46887) in GitLab 13.6)_
| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. |
| `iids[]` | integer array | no | Return only the issues having the given `iid` |
| `search` | string | no | Search issues against their `title` and `description` |
diff --git a/doc/api/job_artifacts.md b/doc/api/job_artifacts.md
index 7c7847bf368..a874379506f 100644
--- a/doc/api/job_artifacts.md
+++ b/doc/api/job_artifacts.md
@@ -259,7 +259,7 @@ Example response:
}
```
-## Delete artifacts
+## Delete job artifacts
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/25522) in GitLab 11.9.
@@ -284,3 +284,33 @@ NOTE:
At least Maintainer role is required to delete artifacts.
If the artifacts were deleted successfully, a response with status `204 No Content` is returned.
+
+## Delete project artifacts
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/223793) in GitLab 14.7 [with a flag](../administration/feature_flags.md) named `bulk_expire_project_artifacts`. Enabled by default on GitLab self-managed. Enabled on GitLab.com.
+
+FLAG:
+On self-managed GitLab, by default this feature is available. To hide the feature, ask an administrator to
+[disable the `bulk_expire_project_artifacts` flag](../administration/feature_flags.md). On GitLab.com, this feature is available.
+
+[Expire artifacts of a project that can be deleted](https://gitlab.com/gitlab-org/gitlab/-/issues/223793) but that don't have an expiry time.
+
+```plaintext
+DELETE /projects/:id/artifacts
+```
+
+| Attribute | Type | Required | Description |
+|-----------|----------------|----------|-----------------------------------------------------------------------------|
+| `id` | integer/string | yes | ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) |
+
+Example request:
+
+```shell
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/artifacts"
+```
+
+NOTE:
+At least Maintainer role is required to delete artifacts.
+
+Schedules a worker to update to the current time the expiry of all artifacts that can be deleted.
+A response with status `202 Accepted` is returned.
diff --git a/doc/api/markdown.md b/doc/api/markdown.md
index d83b7420829..c128e8512df 100644
--- a/doc/api/markdown.md
+++ b/doc/api/markdown.md
@@ -1,14 +1,11 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, api
+info: 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
---
# Markdown API **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/18926) in GitLab 11.0.
-
Available only in APIv4.
## Render an arbitrary Markdown document
diff --git a/doc/api/members.md b/doc/api/members.md
index bc476980d2d..ee6d2cfa2d8 100644
--- a/doc/api/members.md
+++ b/doc/api/members.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -88,15 +88,20 @@ Example response:
]
```
-## List all members of a group or project including inherited members
+## List all members of a group or project including inherited and invited members
-Gets a list of group or project members viewable by the authenticated user, including inherited members and permissions through ancestor groups.
+Gets a list of group or project members viewable by the authenticated user, including inherited members, invited users, and permissions through ancestor groups.
If a user is a member of this group or project and also of one or more ancestor groups,
only its membership with the highest `access_level` is returned.
([Improved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56677) in GitLab 13.11.)
This represents the effective permission of the user.
+Members from an invited group are returned if either:
+
+- The invited group is public.
+- The requester is also a member of the invited group.
+
This function takes pagination parameters `page` and `per_page` to restrict the list of users.
```plaintext
@@ -109,7 +114,7 @@ GET /projects/:id/members/all
| `id` | integer/string | yes | The ID or [URL-encoded path of the project or group](index.md#namespaced-path-encoding) owned by the authenticated user |
| `query` | string | no | A query string to search for members |
| `user_ids` | array of integers | no | Filter the results on the given user IDs |
-| `state` | string | no | Filter results by member state, one of `awaiting`, `active` or `created` **(PREMIUM)** |
+| `state` | string | no | Filter results by member state, one of `awaiting` or `active` **(PREMIUM)** |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/members/all"
@@ -202,11 +207,11 @@ Example response:
}
```
-## Get a member of a group or project, including inherited members
+## Get a member of a group or project, including inherited and invited members
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17744) in GitLab 12.4.
-Gets a member of a group or project, including members inherited through ancestor groups. See the corresponding [endpoint to list all inherited members](#list-all-members-of-a-group-or-project-including-inherited-members) for details.
+Gets a member of a group or project, including members inherited or invited through ancestor groups. See the corresponding [endpoint to list all inherited members](#list-all-members-of-a-group-or-project-including-inherited-and-invited-members) for details.
```plaintext
GET /groups/:id/members/all/:user_id
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index fa713558684..905ecd05d52 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -6,13 +6,10 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Merge requests API **(FREE)**
-> - `with_labels_details` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) in GitLab 12.7.
-> - `author_username` and `author_username` were [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13060) in GitLab 12.10.
> - `reference` was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20354) in GitLab 12.10 in favour of `references`.
-> - `with_merge_status_recheck` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31890) in GitLab 13.0.
> - `reviewer_username` and `reviewer_id` were [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49341) in GitLab 13.8.
-> - `reviewer_ids` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51186) in GitLab 13.8.
-> - `draft` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63473) as an eventual replacement for `work_in_progress` in GitLab 14.0
+> - `draft` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63473) as a replacement for `work_in_progress` in GitLab 14.0.
+> - `merge_user` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/349031) as an eventual replacement for `merged_by` in GitLab 14.7.
Every API call to merge requests must be authenticated.
@@ -46,6 +43,11 @@ This approach is generally slower and more resource-intensive, but isn't subject
placed on database-backed diffs. [Limits inherent to Gitaly](../development/diffs.md#diff-limits)
still apply.
+- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/349031) in GitLab 14.7,
+field `merge_user` can be either user who merged this merge request,
+user who set it to merge when pipeline succeeds or `null`.
+Field `merged_by` (user who merged this merge request or `null`) has been deprecated.
+
## List merge requests
Get all merge requests the authenticated user has access to. By
@@ -53,9 +55,10 @@ default it returns only merge requests created by the current user. To
get all merge requests, use parameter `scope=all`.
The `state` parameter can be used to get only merge requests with a
-given state (`opened`, `closed`, `locked`, or `merged`) or all of them (`all`). It should be noted that when searching by `locked` it mostly returns no results as it is a short-lived, transitional state.
-The pagination parameters `page` and `per_page` can be used to
-restrict the list of merge requests.
+given state (`opened`, `closed`, `locked`, or `merged`) or all of them (`all`).
+It should be noted that when searching by `locked` it mostly returns no results
+as it is a short-lived, transitional state. The pagination parameters `page` and
+`per_page` can be used to restrict the list of merge requests.
```plaintext
GET /merge_requests
@@ -79,21 +82,21 @@ Parameters:
| `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc`. |
| `milestone` | string | no | Return merge requests for a specific milestone. `None` returns merge requests with no milestone. `Any` returns merge requests that have an assigned milestone. |
| `view` | string | no | If `simple`, returns the `iid`, URL, title, description, and basic state of merge request. |
-| `labels` | string | no | Return merge requests matching a comma-separated list of labels. `None` lists all merge requests with no labels. `Any` lists all merge requests with at least one label. `No+Label` (Deprecated) lists all merge requests with no labels. Predefined names are case-insensitive. |
-| `with_labels_details` | boolean | no | If `true`, response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. |
-| `with_merge_status_recheck` | boolean | no | If `true`, this projection requests (but does not guarantee) that the `merge_status` field be recalculated asynchronously. Default is `false`. |
+| `labels` | string | no | Return merge requests matching a comma-separated list of labels. `None` lists all merge requests with no labels. `Any` lists all merge requests with at least one label. Predefined names are case-insensitive. |
+| `with_labels_details` | boolean | no | If `true`, response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) in GitLab 12.7. |
+| `with_merge_status_recheck` | boolean | no | If `true`, this projection requests (but does not guarantee) that the `merge_status` field be recalculated asynchronously. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31890) in GitLab 13.0. |
| `created_after` | datetime | no | Return merge requests created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `created_before` | datetime | no | Return merge requests created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `updated_after` | datetime | no | Return merge requests updated on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `updated_before` | datetime | no | Return merge requests updated on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
-| `scope` | string | no | Return merge requests for the given scope: `created_by_me`, `assigned_to_me` or `all`. Defaults to `created_by_me`<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead. |
+| `scope` | string | no | Return merge requests for the given scope: `created_by_me`, `assigned_to_me` or `all`. Defaults to `created_by_me`. |
| `author_id` | integer | no | Returns merge requests created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. |
-| `author_username` | string | no | Returns merge requests created by the given `username`. Mutually exclusive with `author_id`. |
+| `author_username` | string | no | Returns merge requests created by the given `username`. Mutually exclusive with `author_id`. [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13060) in GitLab 12.10. |
| `assignee_id` | integer | no | Returns merge requests assigned to the given user `id`. `None` returns unassigned merge requests. `Any` returns merge requests with an assignee. |
| `approver_ids` **(PREMIUM)** | integer array | no | Returns merge requests which have specified all the users with the given `id`s as individual approvers. `None` returns merge requests without approvers. `Any` returns merge requests with an approver. |
| `approved_by_ids` **(PREMIUM)** | integer array | no | Returns merge requests which have been approved by all the users with the given `id`s (Max: 5). `None` returns merge requests with no approvals. `Any` returns merge requests with an approval. |
| `reviewer_id` | integer | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given user `id`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_username`. |
-| `reviewer_username` | string | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. |
+| `reviewer_username` | string | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49341) in GitLab 13.8. |
| `my_reaction_emoji` | string | no | Return merge requests reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. |
| `source_branch` | string | no | Return merge requests with the given source branch. |
| `target_branch` | string | no | Return merge requests with the given target branch. |
@@ -114,7 +117,15 @@ Parameters:
"title": "test1",
"description": "fixed login page css paddings",
"state": "merged",
- "merged_by": {
+ "merged_by": { // Deprecated and will be removed in API v5, use `merge_user` instead
+ "id": 87854,
+ "name": "Douwe Maan",
+ "username": "DouweM",
+ "state": "active",
+ "avatar_url": "https://gitlab.example.com/uploads/-/system/user/avatar/87854/avatar.png",
+ "web_url": "https://gitlab.com/DouweM"
+ },
+ "merge_user": {
"id": 87854,
"name": "Douwe Maan",
"username": "DouweM",
@@ -266,21 +277,21 @@ Parameters:
| `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc`. |
| `milestone` | string | no | Return merge requests for a specific milestone. `None` returns merge requests with no milestone. `Any` returns merge requests that have an assigned milestone. |
| `view` | string | no | If `simple`, returns the `iid`, URL, title, description, and basic state of merge request. |
-| `labels` | string | no | Return merge requests matching a comma-separated list of labels. `None` lists all merge requests with no labels. `Any` lists all merge requests with at least one label. `No+Label` (Deprecated) lists all merge requests with no labels. Predefined names are case-insensitive. |
-| `with_labels_details` | boolean | no | If `true`, response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. |
-| `with_merge_status_recheck` | boolean | no | If `true`, this projection requests (but does not guarantee) that the `merge_status` field be recalculated asynchronously. Default is `false`. |
+| `labels` | string | no | Return merge requests matching a comma-separated list of labels. `None` lists all merge requests with no labels. `Any` lists all merge requests with at least one label. Predefined names are case-insensitive. |
+| `with_labels_details` | boolean | no | If `true`, response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) in GitLab 12.7. |
+| `with_merge_status_recheck` | boolean | no | If `true`, this projection requests (but does not guarantee) that the `merge_status` field be recalculated asynchronously. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31890) in GitLab 13.0. |
| `created_after` | datetime | no | Return merge requests created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `created_before` | datetime | no | Return merge requests created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `updated_after` | datetime | no | Return merge requests updated on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `updated_before` | datetime | no | Return merge requests updated on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `scope` | string | no | Return merge requests for the given scope: `created_by_me`, `assigned_to_me`, or `all`. |
| `author_id` | integer | no | Returns merge requests created by the given user `id`. Mutually exclusive with `author_username`. |
-| `author_username` | string | no | Returns merge requests created by the given `username`. Mutually exclusive with `author_id`.|
+| `author_username` | string | no | Returns merge requests created by the given `username`. Mutually exclusive with `author_id`. [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13060) in GitLab 12.10. |
| `assignee_id` | integer | no | Returns merge requests assigned to the given user `id`. `None` returns unassigned merge requests. `Any` returns merge requests with an assignee. |
| `approver_ids` **(PREMIUM)** | integer array | no | Returns merge requests which have specified all the users with the given `id`s as individual approvers. `None` returns merge requests without approvers. `Any` returns merge requests with an approver. |
| `approved_by_ids` **(PREMIUM)** | integer array | no | Returns merge requests which have been approved by all the users with the given `id`s (Max: 5). `None` returns merge requests with no approvals. `Any` returns merge requests with an approval. |
| `reviewer_id` | integer | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given user `id`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_username`. |
-| `reviewer_username` | string | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. |
+| `reviewer_username` | string | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49341) in GitLab 13.8. |
| `my_reaction_emoji` | string | no | Return merge requests reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. |
| `source_branch` | string | no | Return merge requests with the given source branch. |
@@ -298,7 +309,15 @@ Parameters:
"title": "test1",
"description": "fixed login page css paddings",
"state": "merged",
- "merged_by": {
+ "merged_by": { // Deprecated and will be removed in API v5, use `merge_user` instead
+ "id": 87854,
+ "name": "Douwe Maan",
+ "username": "DouweM",
+ "state": "active",
+ "avatar_url": "https://gitlab.example.com/uploads/-/system/user/avatar/87854/avatar.png",
+ "web_url": "https://gitlab.com/DouweM"
+ },
+ "merge_user": {
"id": 87854,
"name": "Douwe Maan",
"username": "DouweM",
@@ -453,8 +472,8 @@ Parameters:
| `sort` | string | no | Return merge requests sorted in `asc` or `desc` order. Default is `desc`. |
| `milestone` | string | no | Return merge requests for a specific milestone. `None` returns merge requests with no milestone. `Any` returns merge requests that have an assigned milestone. |
| `view` | string | no | If `simple`, returns the `iid`, URL, title, description, and basic state of merge request. |
-| `labels` | string | no | Return merge requests matching a comma-separated list of labels. `None` lists all merge requests with no labels. `Any` lists all merge requests with at least one label. `No+Label` (Deprecated) lists all merge requests with no labels. Predefined names are case-insensitive. |
-| `with_labels_details` | boolean | no | If `true`, response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) in GitLab 12.7.|
+| `labels` | string | no | Return merge requests matching a comma-separated list of labels. `None` lists all merge requests with no labels. `Any` lists all merge requests with at least one label. Predefined names are case-insensitive. |
+| `with_labels_details` | boolean | no | If `true`, response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) in GitLab 12.7. |
| `with_merge_status_recheck` | boolean | no | If `true`, this projection requests (but does not guarantee) that the `merge_status` field be recalculated asynchronously. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31890) in GitLab 13.0. |
| `created_after` | datetime | no | Return merge requests created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). |
| `created_before` | datetime | no | Return merge requests created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). |
@@ -462,12 +481,12 @@ Parameters:
| `updated_before` | datetime | no | Return merge requests updated on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). |
| `scope` | string | no | Return merge requests for the given scope: `created_by_me`, `assigned_to_me` or `all`. |
| `author_id` | integer | no | Returns merge requests created by the given user `id`. Mutually exclusive with `author_username`. |
-| `author_username` | string | no | Returns merge requests created by the given `username`. Mutually exclusive with `author_id`. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13060) in GitLab 12.10)_. |
+| `author_username` | string | no | Returns merge requests created by the given `username`. Mutually exclusive with `author_id`. [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13060) in GitLab 12.10. |
| `assignee_id` | integer | no | Returns merge requests assigned to the given user `id`. `None` returns unassigned merge requests. `Any` returns merge requests with an assignee. |
| `approver_ids` **(PREMIUM)** | integer array | no | Returns merge requests which have specified all the users with the given `id`s as individual approvers. `None` returns merge requests without approvers. `Any` returns merge requests with an approver. |
| `approved_by_ids` **(PREMIUM)** | integer array | no | Returns merge requests which have been approved by all the users with the given `id`s (Max: 5). `None` returns merge requests with no approvals. `Any` returns merge requests with an approval. |
| `reviewer_id` | integer | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given user `id`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_username`. |
-| `reviewer_username` | string | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. |
+| `reviewer_username` | string | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49341) in GitLab 13.8. |
| `my_reaction_emoji` | string | no | Return merge requests reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. |
| `source_branch` | string | no | Return merge requests with the given source branch. |
| `target_branch` | string | no | Return merge requests with the given target branch. |
@@ -484,7 +503,15 @@ Parameters:
"title": "test1",
"description": "fixed login page css paddings",
"state": "merged",
- "merged_by": {
+ "merged_by": { // Deprecated and will be removed in API v5, use `merge_user` instead
+ "id": 87854,
+ "name": "Douwe Maan",
+ "username": "DouweM",
+ "state": "active",
+ "avatar_url": "https://gitlab.example.com/uploads/-/system/user/avatar/87854/avatar.png",
+ "web_url": "https://gitlab.com/DouweM"
+ },
+ "merge_user": {
"id": 87854,
"name": "Douwe Maan",
"username": "DouweM",
@@ -720,7 +747,15 @@ Parameters:
"squash": false,
"subscribed": false,
"changes_count": "1",
- "merged_by": {
+ "merged_by": { // Deprecated and will be removed in API v5, use `merge_user` instead
+ "id": 87854,
+ "name": "Douwe Maan",
+ "username": "DouweM",
+ "state": "active",
+ "avatar_url": "https://gitlab.example.com/uploads/-/system/user/avatar/87854/avatar.png",
+ "web_url": "https://gitlab.com/DouweM"
+ },
+ "merge_user": {
"id": 87854,
"name": "Douwe Maan",
"username": "DouweM",
@@ -1074,14 +1109,14 @@ POST /projects/:id/merge_requests
| `title` | string | yes | Title of MR. |
| `assignee_id` | integer | no | Assignee user ID. |
| `assignee_ids` | integer array | no | The ID of the user(s) to assign the MR to. Set to `0` or provide an empty value to unassign all assignees. |
-| `reviewer_ids` | integer array | no | The ID of the user(s) added as a reviewer to the MR. If set to `0` or left empty, no reviewers are added. |
+| `reviewer_ids` | integer array | no | The ID of the user(s) added as a reviewer to the MR. If set to `0` or left empty, no reviewers are added. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49341) in GitLab 13.8. |
| `description` | string | no | Description of MR. Limited to 1,048,576 characters. |
| `target_project_id` | integer | no | The target project (numeric ID). |
| `labels` | string | no | Labels for MR as a comma-separated list. |
| `milestone_id` | integer | no | The global ID of a milestone. |
| `remove_source_branch` | boolean | no | Flag indicating if a merge request should remove the source branch when merging. |
| `allow_collaboration` | boolean | no | Allow commits from members who can merge to the target branch. |
-| `allow_maintainer_to_push` | boolean | no | Deprecated, see `allow_collaboration`. |
+| `allow_maintainer_to_push` | boolean | no | [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/22665), see `allow_collaboration`. |
| `squash` | boolean | no | Squash commits into a single commit when merging. |
```json
@@ -1162,7 +1197,15 @@ POST /projects/:id/merge_requests
"squash": false,
"subscribed": false,
"changes_count": "1",
- "merged_by": {
+ "merged_by": { // Deprecated and will be removed in API v5, use `merge_user` instead
+ "id": 87854,
+ "name": "Douwe Maan",
+ "username": "DouweM",
+ "state": "active",
+ "avatar_url": "https://gitlab.example.com/uploads/-/system/user/avatar/87854/avatar.png",
+ "web_url": "https://gitlab.com/DouweM"
+ },
+ "merge_user": {
"id": 87854,
"name": "Douwe Maan",
"username": "DouweM",
@@ -1224,7 +1267,7 @@ PUT /projects/:id/merge_requests/:merge_request_iid
| `title` | string | no | Title of MR. |
| `assignee_id` | integer | no | The ID of the user to assign the merge request to. Set to `0` or provide an empty value to unassign all assignees. |
| `assignee_ids` | integer array | no | The ID of the user(s) to assign the MR to. Set to `0` or provide an empty value to unassign all assignees. |
-| `reviewer_ids` | integer array | no | The ID of the user(s) set as a reviewer to the MR. Set the value to `0` or provide an empty value to unset all reviewers. |
+| `reviewer_ids` | integer array | no | The ID of the user(s) set as a reviewer to the MR. Set the value to `0` or provide an empty value to unset all reviewers. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49341) in GitLab 13.8. |
| `milestone_id` | integer | no | The global ID of a milestone to assign the merge request to. Set to `0` or provide an empty value to unassign a milestone.|
| `labels` | string | no | Comma-separated label names for a merge request. Set to an empty string to unassign all labels. |
| `add_labels` | string | no | Comma-separated label names to add to a merge request. |
@@ -1235,7 +1278,7 @@ PUT /projects/:id/merge_requests/:merge_request_iid
| `squash` | boolean | no | Squash commits into a single commit when merging. |
| `discussion_locked` | boolean | no | Flag indicating if the merge request's discussion is locked. If the discussion is locked only project members can add, edit or resolve comments. |
| `allow_collaboration` | boolean | no | Allow commits from members who can merge to the target branch. |
-| `allow_maintainer_to_push` | boolean | no | Deprecated, see `allow_collaboration`. |
+| `allow_maintainer_to_push` | boolean | no | [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/22665), see `allow_collaboration`. |
Must include at least one non-required attribute from above.
@@ -1333,7 +1376,15 @@ Must include at least one non-required attribute from above.
"squash": false,
"subscribed": false,
"changes_count": "1",
- "merged_by": {
+ "merged_by": { // Deprecated and will be removed in API v5, use `merge_user` instead
+ "id": 87854,
+ "name": "Douwe Maan",
+ "username": "DouweM",
+ "state": "active",
+ "avatar_url": "https://gitlab.example.com/uploads/-/system/user/avatar/87854/avatar.png",
+ "web_url": "https://gitlab.com/DouweM"
+ },
+ "merge_user": {
"id": 87854,
"name": "Douwe Maan",
"username": "DouweM",
@@ -1519,7 +1570,15 @@ Parameters:
"squash": false,
"subscribed": false,
"changes_count": "1",
- "merged_by": {
+ "merged_by": { // Deprecated and will be removed in API v5, use `merge_user` instead
+ "id": 87854,
+ "name": "Douwe Maan",
+ "username": "DouweM",
+ "state": "active",
+ "avatar_url": "https://gitlab.example.com/uploads/-/system/user/avatar/87854/avatar.png",
+ "web_url": "https://gitlab.com/DouweM"
+ },
+ "merge_user": {
"id": 87854,
"name": "Douwe Maan",
"username": "DouweM",
@@ -1708,7 +1767,15 @@ Parameters:
"squash": false,
"subscribed": false,
"changes_count": "1",
- "merged_by": {
+ "merged_by": { // Deprecated and will be removed in API v5, use `merge_user` instead
+ "id": 87854,
+ "name": "Douwe Maan",
+ "username": "DouweM",
+ "state": "active",
+ "avatar_url": "https://gitlab.example.com/uploads/-/system/user/avatar/87854/avatar.png",
+ "web_url": "https://gitlab.com/DouweM"
+ },
+ "merge_user": {
"id": 87854,
"name": "Douwe Maan",
"username": "DouweM",
@@ -2009,7 +2076,15 @@ Example response:
"squash": false,
"subscribed": false,
"changes_count": "1",
- "merged_by": {
+ "merged_by": { // Deprecated and will be removed in API v5, use `merge_user` instead
+ "id": 87854,
+ "name": "Douwe Maan",
+ "username": "DouweM",
+ "state": "active",
+ "avatar_url": "https://gitlab.example.com/uploads/-/system/user/avatar/87854/avatar.png",
+ "web_url": "https://gitlab.com/DouweM"
+ },
+ "merge_user": {
"id": 87854,
"name": "Douwe Maan",
"username": "DouweM",
@@ -2169,7 +2244,15 @@ Example response:
"squash": false,
"subscribed": false,
"changes_count": "1",
- "merged_by": {
+ "merged_by": { // Deprecated and will be removed in API v5, use `merge_user` instead
+ "id": 87854,
+ "name": "Douwe Maan",
+ "username": "DouweM",
+ "state": "active",
+ "avatar_url": "https://gitlab.example.com/uploads/-/system/user/avatar/87854/avatar.png",
+ "web_url": "https://gitlab.com/DouweM"
+ },
+ "merge_user": {
"id": 87854,
"name": "Douwe Maan",
"username": "DouweM",
@@ -2603,7 +2686,7 @@ Example response:
## Approvals
-For approvals, please see [Merge Request Approvals](merge_request_approvals.md)
+For approvals, see [Merge Request Approvals](merge_request_approvals.md)
## List merge request state events
diff --git a/doc/api/namespaces.md b/doc/api/namespaces.md
index 9a52b0983a7..a02d44136d1 100644
--- a/doc/api/namespaces.md
+++ b/doc/api/namespaces.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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/api/oauth2.md b/doc/api/oauth2.md
index 778c229e3c8..ef7d133e907 100644
--- a/doc/api/oauth2.md
+++ b/doc/api/oauth2.md
@@ -1,7 +1,7 @@
---
type: reference, howto
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -43,6 +43,8 @@ During registration, by enabling proper scopes, you can limit the range of
resources which the `application` can access. Upon creation, you obtain the
`application` credentials: _Application ID_ and _Client Secret_ - **keep them secure**.
+For a list of scopes in GitLab, see [the provider documentation](../integration/oauth_provider.md#authorized-applications).
+
### Prevent CSRF attacks
To [protect redirect-based flows](https://tools.ietf.org/id/draft-ietf-oauth-security-topics-13.html#rec_redirect),
@@ -97,7 +99,7 @@ Before starting the flow, generate the `STATE`, the `CODE_VERIFIER` and the `COD
This page asks the user to approve the request from the app to access their
account based on the scopes specified in `REQUESTED_SCOPES`. The user is then
- redirected back to the specified `REDIRECT_URI`. The [scope parameter](https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes#requesting-particular-scopes)
+ redirected back to the specified `REDIRECT_URI`. The [scope parameter](../integration/oauth_provider.md#authorized-applications)
is a space-separated list of scopes associated with the user.
For example,`scope=read_user+profile` requests the `read_user` and `profile` scopes.
The redirect includes the authorization `code`, for example:
@@ -177,7 +179,7 @@ be used as a CSRF token.
This page asks the user to approve the request from the app to access their
account based on the scopes specified in `REQUESTED_SCOPES`. The user is then
- redirected back to the specified `REDIRECT_URI`. The [scope parameter](https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes#requesting-particular-scopes)
+ redirected back to the specified `REDIRECT_URI`. The [scope parameter](../integration/oauth_provider.md#authorized-applications)
is a space-separated list of scopes associated with the user.
For example,`scope=read_user+profile` requests the `read_user` and `profile` scopes.
The redirect includes the authorization `code`, for example:
@@ -265,7 +267,7 @@ https://gitlab.example.com/oauth/authorize?client_id=APP_ID&redirect_uri=REDIREC
This prompts the user to approve the applications access to their account
based on the scopes specified in `REQUESTED_SCOPES` and then redirect back to
-the `REDIRECT_URI` you provided. The [scope parameter](https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes#requesting-particular-scopes)
+the `REDIRECT_URI` you provided. The [scope parameter](../integration/oauth_provider.md#authorized-applications)
is a space-separated list of scopes you want to have access to (for example, `scope=read_user+profile`
would request `read_user` and `profile` scopes). The redirect
includes a fragment with `access_token` as well as token details in GET
@@ -371,6 +373,12 @@ or you can put the token to the Authorization header:
curl --header "Authorization: Bearer OAUTH-TOKEN" "https://gitlab.example.com/api/v4/user"
```
+## Access Git over HTTPS with `access token`
+
+A token with [scope](../integration/oauth_provider.md#authorized-applications)
+`read_repository` or `write_repository` can access Git over HTTPS. Use the token as the password.
+The username must be `oauth2`, not your username.
+
## Retrieve the token information
To verify the details of a token, use the `token/info` endpoint provided by the
diff --git a/doc/api/packages.md b/doc/api/packages.md
index a75b2e376fa..555b8d5e054 100644
--- a/doc/api/packages.md
+++ b/doc/api/packages.md
@@ -12,8 +12,6 @@ This is the API documentation of [GitLab Packages](../administration/packages/in
### Within a project
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9259) in GitLab 11.8.
-
Get a list of project packages. All package types are included in results. When
accessed without authentication, only packages of public projects are returned.
@@ -26,7 +24,7 @@ GET /projects/:id/packages
| `id` | integer/string | yes | ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) |
| `order_by`| string | no | The field to use as order. One of `created_at` (default), `name`, `version`, or `type`. |
| `sort` | string | no | The direction of the order, either `asc` (default) for ascending order or `desc` for descending order. |
-| `package_type` | string | no | Filter the returned packages by type. One of `conan`, `maven`, `npm`, `pypi`, `composer`, `nuget`, `helm`, or `golang`. (_Introduced in GitLab 12.9_)
+| `package_type` | string | no | Filter the returned packages by type. One of `conan`, `maven`, `npm`, `pypi`, `composer`, `nuget`, `helm`, `terraform_module`, or `golang`. (_Introduced in GitLab 12.9_)
| `package_name` | string | no | Filter the project packages with a fuzzy search by name. (_Introduced in GitLab 12.9_)
| `include_versionless` | boolean | no | When set to true, versionless packages are included in the response. (_Introduced in GitLab 13.8_)
| `status` | string | no | Filter the returned packages by status. One of `default` (default), `hidden`, or `processing`. (_Introduced in GitLab 13.9_)
@@ -176,8 +174,6 @@ can result in malformed data or broken packages.
## Get a project package
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9667) in GitLab 11.9.
-
Get a single project package.
```plaintext
@@ -258,8 +254,6 @@ The `_links` object contains the following properties:
## List package files
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9305) in GitLab 11.8.
-
Get a list of package files of a single package.
```plaintext
@@ -331,8 +325,6 @@ By default, the `GET` request returns 20 results, because the API is [paginated]
## Delete a project package
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9623) in GitLab 11.9.
-
Deletes a project package.
```plaintext
diff --git a/doc/api/packages/maven.md b/doc/api/packages/maven.md
index b046b0dc411..27bc4da07a1 100644
--- a/doc/api/packages/maven.md
+++ b/doc/api/packages/maven.md
@@ -22,8 +22,6 @@ for details on which headers and token types are supported.
## Download a package file at the instance-level
-> Introduced in GitLab 11.6.
-
Download a Maven package file:
```plaintext
@@ -49,8 +47,6 @@ This writes the downloaded file to `mypkg-1.0-SNAPSHOT.jar` in the current direc
## Download a package file at the group-level
-> Introduced in GitLab 11.7.
-
Download a Maven package file:
```plaintext
@@ -76,8 +72,6 @@ This writes the downloaded file to `mypkg-1.0-SNAPSHOT.jar` in the current direc
## Download a package file at the project-level
-> Introduced in GitLab 11.3.
-
Download a Maven package file:
```plaintext
@@ -103,8 +97,6 @@ This writes the downloaded file to `mypkg-1.0-SNAPSHOT.jar` in the current direc
## Upload a package file
-> Introduced in GitLab 11.3.
-
Upload a Maven package file:
```plaintext
diff --git a/doc/api/packages/npm.md b/doc/api/packages/npm.md
index 24ac1a640c9..846271015cc 100644
--- a/doc/api/packages/npm.md
+++ b/doc/api/packages/npm.md
@@ -22,8 +22,6 @@ for details on which headers and token types are supported.
## Download a package
-> Introduced in GitLab 11.8.
-
Downloads the npm package. This URL is provided by the [metadata endpoint](#metadata).
```plaintext
@@ -50,8 +48,6 @@ This writes the downloaded file to `@myscope/my-pkg-0.0.1.tgz` in the current di
## Upload a package file
-> Introduced in GitLab 11.8.
-
Upload a package.
```plaintext
@@ -153,8 +149,6 @@ The examples in this document all use the project-level prefix.
## Metadata
-> Introduced in GitLab 11.8.
-
Returns the metadata for a given package.
```plaintext
diff --git a/doc/api/packages/pypi.md b/doc/api/packages/pypi.md
index a1c96d03297..592b976da59 100644
--- a/doc/api/packages/pypi.md
+++ b/doc/api/packages/pypi.md
@@ -166,8 +166,6 @@ This writes the downloaded file to `simple.html` in the current directory.
## Upload a package
-> Introduced in GitLab 11.3.
-
Upload a PyPI package:
```plaintext
diff --git a/doc/api/pipelines.md b/doc/api/pipelines.md
index d850113f9b6..b05c71d2748 100644
--- a/doc/api/pipelines.md
+++ b/doc/api/pipelines.md
@@ -280,7 +280,7 @@ POST /projects/:id/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 |
-| `ref` | string | yes | Reference to commit |
+| `ref` | string | yes | The branch or tag to run the pipeline on. |
| `variables` | array | no | An array containing the variables available in the pipeline, matching the structure `[{ 'key': 'UPLOAD_TO_S3', 'variable_type': 'file', 'value': 'true' }, {'key': 'TEST', 'value': 'test variable'}]`. If `variable_type` is excluded, it defaults to `env_var`. |
```shell
diff --git a/doc/api/plan_limits.md b/doc/api/plan_limits.md
index 8bd87f5a896..8d37189ef2a 100644
--- a/doc/api/plan_limits.md
+++ b/doc/api/plan_limits.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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/api/project_access_tokens.md b/doc/api/project_access_tokens.md
new file mode 100644
index 00000000000..125797a802f
--- /dev/null
+++ b/doc/api/project_access_tokens.md
@@ -0,0 +1,112 @@
+---
+stage: Manage
+group: Authentication & 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
+---
+
+# Project access tokens API **(FREE)**
+
+You can read more about [project access tokens](../user/project/settings/project_access_tokens.md).
+
+## List project access tokens
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/238991) in GitLab 13.9.
+
+Get a list of [project access tokens](../user/project/settings/project_access_tokens.md).
+
+```plaintext
+GET projects/:id/access_tokens
+```
+
+| Attribute | Type | required | Description |
+|-----------|---------|----------|---------------------|
+| `id` | integer or string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/<project_id>/access_tokens"
+```
+
+```json
+[
+ {
+ "user_id" : 141,
+ "scopes" : [
+ "api"
+ ],
+ "name" : "token",
+ "expires_at" : "2021-01-31",
+ "id" : 42,
+ "active" : true,
+ "created_at" : "2021-01-20T22:11:48.151Z",
+ "revoked" : false,
+ "access_level": 40
+ }
+]
+```
+
+## Create a project access token
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55408) in GitLab 13.10.
+
+Create a [project access token](../user/project/settings/project_access_tokens.md).
+
+```plaintext
+POST projects/:id/access_tokens
+```
+
+| Attribute | Type | required | Description |
+|-----------|---------|----------|---------------------|
+| `id` | integer or string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) |
+| `name` | String | yes | The name of the project access token |
+| `scopes` | `Array[String]` | yes | [List of scopes](../user/project/settings/project_access_tokens.md#scopes-for-a-project-access-token) |
+| `access_level` | Integer | no | A valid access level. Default value is 40 (Maintainer). Other allowed values are 10 (Guest), 20 (Reporter), and 30 (Developer). |
+| `expires_at` | Date | no | The token expires at midnight UTC on that date |
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
+--header "Content-Type:application/json" \
+--data '{ "name":"test_token", "scopes":["api", "read_repository"], "expires_at":"2021-01-31", "access_level": 30 }' \
+"https://gitlab.example.com/api/v4/projects/<project_id>/access_tokens"
+```
+
+```json
+{
+ "scopes" : [
+ "api",
+ "read_repository"
+ ],
+ "active" : true,
+ "name" : "test",
+ "revoked" : false,
+ "created_at" : "2021-01-21T19:35:37.921Z",
+ "user_id" : 166,
+ "id" : 58,
+ "expires_at" : "2021-01-31",
+ "token" : "D4y...Wzr",
+ "access_level": 30
+}
+```
+
+## Revoke a project access token
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/238991) in GitLab 13.9.
+
+Revoke a [project access token](../user/project/settings/project_access_tokens.md).
+
+```plaintext
+DELETE projects/:id/access_tokens/:token_id
+```
+
+| Attribute | Type | required | Description |
+|-----------|---------|----------|---------------------|
+| `id` | integer or string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) |
+| `token_id` | integer or string | yes | The ID of the project access token |
+
+```shell
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/<project_id>/access_tokens/<token_id>"
+```
+
+### Responses
+
+- `204: No Content` if successfully revoked.
+- `400 Bad Request` or `404 Not Found` if not revoked successfully.
diff --git a/doc/api/project_badges.md b/doc/api/project_badges.md
index c6f979c1643..846c0241dd1 100644
--- a/doc/api/project_badges.md
+++ b/doc/api/project_badges.md
@@ -1,14 +1,11 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, api
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Project badges API **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17082) in GitLab 10.6.
-
## Placeholder tokens
Badges support placeholders that are replaced in real-time in both the link and image URL. The allowed placeholders are:
diff --git a/doc/api/project_import_export.md b/doc/api/project_import_export.md
index 39c68041725..e7609d34998 100644
--- a/doc/api/project_import_export.md
+++ b/doc/api/project_import_export.md
@@ -1,14 +1,11 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, api
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Project import/export API **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41899) in GitLab 10.6.
-
See also:
- [Project import/export documentation](../user/project/settings/import_export.md).
@@ -23,7 +20,7 @@ all the necessary information to upload the exported project to a web server or
to any S3-compatible platform. At the moment we only support binary
data file uploads to the final server.
-From GitLab 10.7, the `upload[url]` parameter is required if the `upload` parameter is present.
+The `upload[url]` parameter is required if the `upload` parameter is present.
```plaintext
POST /projects/:id/export
diff --git a/doc/api/project_snippets.md b/doc/api/project_snippets.md
index 569270e5de1..c5f317f7540 100644
--- a/doc/api/project_snippets.md
+++ b/doc/api/project_snippets.md
@@ -1,8 +1,7 @@
---
stage: Create
group: Editor
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, api
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Project snippets **(FREE)**
@@ -247,8 +246,6 @@ curl "https://gitlab.com/api/v4/projects/1/snippets/2/files/master/snippet%2Erb/
## Get user agent details
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/29508) in GitLab 9.4.
-
Available only for users with the Administrator [role](../user/permissions.md).
```plaintext
diff --git a/doc/api/project_templates.md b/doc/api/project_templates.md
index 2ec30c80a6b..4c0a1890729 100644
--- a/doc/api/project_templates.md
+++ b/doc/api/project_templates.md
@@ -1,8 +1,7 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, api
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Project templates API **(FREE)**
@@ -21,9 +20,7 @@ It deprecates these endpoints, which are scheduled for removal in API version 5.
In addition to templates common to the entire instance, project-specific
templates are also available from this API endpoint.
-Support for [Group-level file templates](../user/group/index.md#group-file-templates) **(PREMIUM)**
-was [added](https://gitlab.com/gitlab-org/gitlab/-/issues/5987)
-in GitLab 11.5
+Support is also available for [group-level file templates](../user/group/index.md#group-file-templates). **(PREMIUM)**
## Get all templates of a particular type
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 65911567f87..791be613c71 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -619,7 +619,7 @@ GET /users/:user_id/projects
## List projects starred by a user
-Get a list of visible projects owned by the given user. When accessed without
+Get a list of visible projects starred by the given user. When accessed without
authentication, only public projects are returned.
```plaintext
@@ -1049,8 +1049,10 @@ The `web_url` and `avatar_url` attributes on `namespace` were
[introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/27427)
in GitLab 11.11.
-If the project is a fork, and you provide a valid token to authenticate, the
-`forked_from_project` field appears in the response.
+If the project is a fork, the `forked_from_project` field appears in the response.
+For this field, if the upstream project is private, a valid token for authentication must be provided.
+The field `mr_default_target_self` appears as well. If this value is `false`, then all merge requests
+will target the upstream project by default.
```json
{
@@ -1058,6 +1060,7 @@ If the project is a fork, and you provide a valid token to authenticate, the
...
+ "mr_default_target_self": false,
"forked_from_project":{
"id":13083,
"description":"GitLab Community Edition",
@@ -1448,6 +1451,7 @@ Supported attributes:
| `issues_template` **(PREMIUM)** | string | **{dotted-circle}** No | Default description for Issues. Description is parsed with GitLab Flavored Markdown. See [Templates for issues and merge requests](#templates-for-issues-and-merge-requests). |
| `merge_requests_template` **(PREMIUM)** | string | **{dotted-circle}** No | Default description for Merge Requests. Description is parsed with GitLab Flavored Markdown. See [Templates for issues and merge requests](#templates-for-issues-and-merge-requests). |
| `keep_latest_artifact` | boolean | **{dotted-circle}** No | Disable or enable the ability to keep the latest artifact for this project. |
+| `mr_default_target_self` | boolean | **{dotted-circle}** No | For forked projects, target merge requests to this project. If `false`, the target will be the upstream project. |
## Fork project
@@ -1471,6 +1475,7 @@ POST /projects/:id/fork
| `path` | string | **{dotted-circle}** No | The path assigned to the resultant project after forking. |
| `description` | string | **{dotted-circle}** No | The description assigned to the resultant project after forking. |
| `visibility` | string | **{dotted-circle}** No | The [visibility level](#project-visibility-level) assigned to the resultant project after forking. |
+| `mr_default_target_self` | boolean | **{dotted-circle}** No | For forked projects, target merge requests to this project. If `false`, the target will be the upstream project. |
## List Forks of a project
@@ -2386,6 +2391,7 @@ POST /projects/:id/hooks
| `token` | string | **{dotted-circle}** No | Secret token to validate received payloads; this isn't returned in the response. |
| `url` | string | **{check-circle}** Yes | The hook URL. |
| `wiki_page_events` | boolean | **{dotted-circle}** No | Trigger hook on wiki events. |
+| `releases_events` | boolean | **{dotted-circle}** No | Trigger hook on release events. |
### Edit project hook
diff --git a/doc/api/protected_branches.md b/doc/api/protected_branches.md
index d17341759ad..ea2412515a0 100644
--- a/doc/api/protected_branches.md
+++ b/doc/api/protected_branches.md
@@ -1,14 +1,11 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, api
+info: 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
---
# Protected branches API **(FREE)**
-> Introduced in GitLab 9.5.
-
**Valid access levels**
The access levels are defined in the `ProtectedRefAccess.allowed_access_levels` method. Currently, these levels are recognized:
@@ -201,13 +198,13 @@ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitla
| -------------------------------------------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
| `name` | string | yes | The name of the branch or wildcard |
-| `push_access_level` | string | no | Access levels allowed to push (defaults: `40`, Maintainer role) |
-| `merge_access_level` | string | no | Access levels allowed to merge (defaults: `40`, Maintainer role) |
-| `unprotect_access_level` | string | no | Access levels allowed to unprotect (defaults: `40`, Maintainer role) |
+| `push_access_level` | integer | no | Access levels allowed to push (defaults: `40`, Maintainer role) |
+| `merge_access_level` | integer | no | Access levels allowed to merge (defaults: `40`, Maintainer role) |
+| `unprotect_access_level` | integer | no | Access levels allowed to unprotect (defaults: `40`, Maintainer role) |
| `allow_force_push` | boolean | no | Allow all users with push access to force push. (default: `false`) |
-| `allowed_to_push` **(PREMIUM)** | array | no | Array of access levels allowed to push, with each described by a hash |
-| `allowed_to_merge` **(PREMIUM)** | array | no | Array of access levels allowed to merge, with each described by a hash |
-| `allowed_to_unprotect` **(PREMIUM)** | array | no | Array of access levels allowed to unprotect, with each described by a hash |
+| `allowed_to_push` **(PREMIUM)** | array | no | Array of access levels allowed to push, with each described by a hash of the form `{user_id: integer}`, `{group_id: integer}`, or `{access_level: integer}` |
+| `allowed_to_merge` **(PREMIUM)** | array | no | Array of access levels allowed to merge, with each described by a hash of the form `{user_id: integer}`, `{group_id: integer}`, or `{access_level: integer}` |
+| `allowed_to_unprotect` **(PREMIUM)** | array | no | Array of access levels allowed to unprotect, with each described by a hash of the form `{user_id: integer}`, `{group_id: integer}`, or `{access_level: integer}` |
| `code_owner_approval_required` **(PREMIUM)** | boolean | no | Prevent pushes to this branch if it matches an item in the [`CODEOWNERS` file](../user/project/code_owners.md). (defaults: false) |
Example response:
@@ -332,7 +329,6 @@ curl --request POST \
--header "PRIVATE-TOKEN: <your_access_token>" \
--header "Content-Type: application/json" \
--data '{
- "id": 5,
"name": "master",
"allowed_to_push": [{"access_level": 30}],
"allowed_to_merge": [{
diff --git a/doc/api/protected_environments.md b/doc/api/protected_environments.md
index c7de4c504a4..61587136a14 100644
--- a/doc/api/protected_environments.md
+++ b/doc/api/protected_environments.md
@@ -49,7 +49,8 @@ Example response:
"user_id":null,
"group_id":null
}
- ]
+ ],
+ "required_approval_count": 0
}
]
```
@@ -78,12 +79,13 @@ Example response:
"name":"production",
"deploy_access_levels":[
{
- "access_level":40,
- "access_level_description":"Maintainers",
- "user_id":null,
- "group_id":null
+ "access_level": 40,
+ "access_level_description": "Maintainers",
+ "user_id": null,
+ "group_id": null
}
- ]
+ ],
+ "required_approval_count": 0
}
```
@@ -107,6 +109,7 @@ curl --header 'Content-Type: application/json' --request POST \
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
| `name` | string | yes | The name of the environment. |
| `deploy_access_levels` | array | yes | Array of access levels allowed to deploy, with each described by a hash. |
+| `required_approval_count` | integer | no | The number of approvals required to deploy to this environment. This is part of Deployment Approvals, which isn't yet available for use. For details, see [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/343864). |
Elements in the `deploy_access_levels` array should be one of `user_id`, `group_id` or
`access_level`, and take the form `{user_id: integer}`, `{group_id: integer}` or
@@ -125,7 +128,8 @@ Example response:
"user_id": null,
"group_id": 9899826
}
- ]
+ ],
+ "required_approval_count": 0
}
```
diff --git a/doc/api/protected_tags.md b/doc/api/protected_tags.md
index 7a46a2dbf12..e2b27692373 100644
--- a/doc/api/protected_tags.md
+++ b/doc/api/protected_tags.md
@@ -1,14 +1,11 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, api
+info: 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
---
# Protected tags API **(FREE)**
-> Introduced in GitLab 11.3.
-
**Valid access levels**
Currently, these levels are recognized:
diff --git a/doc/api/releases/index.md b/doc/api/releases/index.md
index c253358f01f..c603be9489c 100644
--- a/doc/api/releases/index.md
+++ b/doc/api/releases/index.md
@@ -6,15 +6,15 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Releases API **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41766) in GitLab 11.7.
-> - Using this API you can manipulate GitLab [Release](../../user/project/releases/index.md) entries.
-> - For manipulating links as a release asset, see [Release Links API](links.md).
> - Release Evidences were [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/26019) in GitLab 12.5.
> - `description_html` became an opt-in field [with GitLab 13.12 for performance reasons](https://gitlab.com/gitlab-org/gitlab/-/issues/299447).
Please pass the `include_html_description` query string parameter if you need it.
> - [The permission model for create, update and delete actions was fixed](https://gitlab.com/gitlab-org/gitlab/-/issues/327505) in GitLab 14.1.
See [Release permissions](../../user/project/releases/index.md#release-permissions) for more information.
+Use this API to manipulate GitLab [Release](../../user/project/releases/index.md)
+entries. For manipulating links as a release asset, see [Release Links API](links.md).
+
## Authentication
For authentication, the Releases API accepts either:
diff --git a/doc/api/releases/links.md b/doc/api/releases/links.md
index c9d183b8351..282ef0adc78 100644
--- a/doc/api/releases/links.md
+++ b/doc/api/releases/links.md
@@ -6,9 +6,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Release links API **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41766) in GitLab 11.7.
+Use this API to manipulate GitLab [Release](../../user/project/releases/index.md)
+links. For manipulating other Release assets, see [Release API](index.md).
-Using this API you can manipulate GitLab [Release](../../user/project/releases/index.md) links. For manipulating other Release assets, see [Release API](index.md).
GitLab supports links to `http`, `https`, and `ftp` assets.
## Get links
diff --git a/doc/api/repository_submodules.md b/doc/api/repository_submodules.md
index 06f9e514009..cbd6a369e97 100644
--- a/doc/api/repository_submodules.md
+++ b/doc/api/repository_submodules.md
@@ -1,14 +1,11 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, api
+info: 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
---
# Repository submodules API **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41213) in GitLab 11.5
-
## Update existing submodule reference in repository
In some workflows, especially automated ones, it can be useful to update a
diff --git a/doc/api/resource_access_tokens.md b/doc/api/resource_access_tokens.md
index 90e9769b896..c77a8f5d0d6 100644
--- a/doc/api/resource_access_tokens.md
+++ b/doc/api/resource_access_tokens.md
@@ -1,112 +1,9 @@
---
-stage: Manage
-group: Access
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+redirect_to: 'project_access_tokens.md'
+remove_date: '2022-04-06'
---
-# Project access tokens API **(FREE)**
+This document was moved to [another location](project_access_tokens.md).
-You can read more about [project access tokens](../user/project/settings/project_access_tokens.md).
-
-## List project access tokens
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/238991) in GitLab 13.9.
-
-Get a list of project access tokens.
-
-```plaintext
-GET projects/:id/access_tokens
-```
-
-| Attribute | Type | required | Description |
-|-----------|---------|----------|---------------------|
-| `id` | integer or string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) |
-
-```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/<project_id>/access_tokens"
-```
-
-```json
-[
- {
- "user_id" : 141,
- "scopes" : [
- "api"
- ],
- "name" : "token",
- "expires_at" : "2021-01-31",
- "id" : 42,
- "active" : true,
- "created_at" : "2021-01-20T22:11:48.151Z",
- "revoked" : false,
- "access_level": 40
- }
-]
-```
-
-## Create a project access token
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55408) in GitLab 13.10.
-
-Create a project access token.
-
-```plaintext
-POST projects/:id/access_tokens
-```
-
-| Attribute | Type | required | Description |
-|-----------|---------|----------|---------------------|
-| `id` | integer or string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) |
-| `name` | String | yes | The name of the project access token |
-| `scopes` | `Array[String]` | yes | [List of scopes](../user/project/settings/project_access_tokens.md#scopes-for-a-project-access-token) |
-| `access_level` | Integer | no | A valid access level. Default value is 40 (Maintainer). Other allowed values are 10 (Guest), 20 (Reporter), and 30 (Developer). |
-| `expires_at` | Date | no | The token expires at midnight UTC on that date |
-
-```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
---header "Content-Type:application/json" \
---data '{ "name":"test_token", "scopes":["api", "read_repository"], "expires_at":"2021-01-31", "access_level": 30 }' \
-"https://gitlab.example.com/api/v4/projects/<project_id>/access_tokens"
-```
-
-```json
-{
- "scopes" : [
- "api",
- "read_repository"
- ],
- "active" : true,
- "name" : "test",
- "revoked" : false,
- "created_at" : "2021-01-21T19:35:37.921Z",
- "user_id" : 166,
- "id" : 58,
- "expires_at" : "2021-01-31",
- "token" : "D4y...Wzr",
- "access_level": 30
-}
-```
-
-## Revoke a project access token
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/238991) in GitLab 13.9.
-
-Revoke a project access token.
-
-```plaintext
-DELETE projects/:id/access_tokens/:token_id
-```
-
-| Attribute | Type | required | Description |
-|-----------|---------|----------|---------------------|
-| `id` | integer or string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) |
-| `token_id` | integer or string | yes | The ID of the project access token |
-
-```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/<project_id>/access_tokens/<token_id>"
-```
-
-### Responses
-
-- `204: No Content` if successfully revoked.
-- `400 Bad Request` or `404 Not Found` if not revoked successfully.
+<!-- 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 -->
diff --git a/doc/api/runners.md b/doc/api/runners.md
index 5e84080ecb5..e53062ce074 100644
--- a/doc/api/runners.md
+++ b/doc/api/runners.md
@@ -573,17 +573,18 @@ Register a new runner for the instance.
POST /runners
```
-| Attribute | Type | Required | Description |
-|--------------|---------|----------|---------------------|
-| `token` | string | yes | [Registration token](#registration-and-authentication-tokens). |
-| `description`| string | no | Runner's description|
-| `info` | hash | no | Runner's metadata. You can include `name`, `version`, `revision`, `platform`, and `architecture`, but only `version` is displayed in the Admin area of the UI. |
-| `active` | boolean | no | Whether the runner is active |
-| `locked` | boolean | no | Whether the runner should be locked for current project |
-| `run_untagged` | boolean | no | Whether the runner should handle untagged jobs |
-| `tag_list` | string array | no | List of runner's tags |
-| `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 |
+| Attribute | Type | Required | Description |
+|-------------------|----------------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `token` | string | yes | [Registration token](#registration-and-authentication-tokens). |
+| `description` | string | no | Runner's description |
+| `info` | hash | no | Runner's metadata. You can include `name`, `version`, `revision`, `platform`, and `architecture`, but only `version` is displayed in the Admin area of the UI. |
+| `active` | boolean | no | Whether the runner is active |
+| `locked` | boolean | no | Whether the runner should be locked for current project |
+| `run_untagged` | boolean | no | Whether the runner should handle untagged jobs |
+| `tag_list` | string array | no | List of runner's tags |
+| `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 | Free-form maintainer notes for the runner (255 characters) |
```shell
curl --request POST "https://gitlab.example.com/api/v4/runners" \
diff --git a/doc/api/scim.md b/doc/api/scim.md
index 2d9cc148412..acc6a6ae686 100644
--- a/doc/api/scim.md
+++ b/doc/api/scim.md
@@ -1,7 +1,7 @@
---
type: reference, howto
stage: Manage
-group: Access
+group: Authentication & 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/api/search.md b/doc/api/search.md
index d3f0cba9234..2969cf439dd 100644
--- a/doc/api/search.md
+++ b/doc/api/search.md
@@ -1,14 +1,12 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, api
+info: 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
---
# Search API **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41763) in GitLab 10.5.
-> - [Feature flag `search_filter_by_confidential` removed](https://gitlab.com/gitlab-org/gitlab/-/issues/244923) in GitLab 13.6.
+> [Feature flag `search_filter_by_confidential` removed](https://gitlab.com/gitlab-org/gitlab/-/issues/244923) in GitLab 13.6.
Every API call to search must be authenticated.
diff --git a/doc/api/settings.md b/doc/api/settings.md
index e953990c091..2ed841b885c 100644
--- a/doc/api/settings.md
+++ b/doc/api/settings.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -385,7 +385,7 @@ listed in the descriptions of the relevant settings.
| `send_user_confirmation_email` | boolean | no | Send confirmation email on sign-up. |
| `session_expire_delay` | integer | no | Session duration in minutes. GitLab restart is required to apply changes. |
| `shared_runners_enabled` | boolean | no | (**If enabled, requires:** `shared_runners_text` and `shared_runners_minutes`) Enable shared runners for new projects. |
-| `shared_runners_minutes` **(PREMIUM)** | integer | required by: `shared_runners_enabled` | Set the maximum number of pipeline minutes that a group can use on shared runners per month. |
+| `shared_runners_minutes` **(PREMIUM)** | integer | required by: `shared_runners_enabled` | Set the maximum number of CI/CD minutes that a group can use on shared runners per month. |
| `shared_runners_text` | string | required by: `shared_runners_enabled` | Shared runners text. |
| `sidekiq_job_limiter_mode` | string | no | `track` or `compress`. Sets the behavior for [Sidekiq job size limits](../user/admin_area/settings/sidekiq_job_limits.md). Default: 'compress'. |
| `sidekiq_job_limiter_compression_threshold_bytes` | integer | no | The threshold in bytes at which Sidekiq jobs are compressed before being stored in Redis. Default: 100 000 bytes (100KB). |
diff --git a/doc/api/snippets.md b/doc/api/snippets.md
index 629dfebbefc..52bcd072de9 100644
--- a/doc/api/snippets.md
+++ b/doc/api/snippets.md
@@ -1,14 +1,11 @@
---
stage: Create
group: Editor
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, api
+info: 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
---
# Snippets API **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/6373) in GitLab 8.15.
-
Snippets API operates on [snippets](../user/snippets.md). Related APIs exist for
[project snippets](project_snippets.md) and
[moving snippets between storages](snippet_repository_storage_moves.md).
@@ -449,8 +446,6 @@ Example response:
## Get user agent details
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12655) in GitLab 9.4.
-
NOTE:
Available only for administrators.
diff --git a/doc/api/statistics.md b/doc/api/statistics.md
index 75dfa0de705..59197260988 100644
--- a/doc/api/statistics.md
+++ b/doc/api/statistics.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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/api/tags.md b/doc/api/tags.md
index bbde6c1491b..6aa40cf476d 100644
--- a/doc/api/tags.md
+++ b/doc/api/tags.md
@@ -1,16 +1,14 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, api
+info: 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
---
# Tags API **(FREE)**
## List project repository tags
-Get a list of repository tags from a project, sorted by name in reverse
-alphabetical order. This endpoint can be accessed without authentication if the
+Get a list of repository tags from a project, sorted by update date and time in descending order. This endpoint can be accessed without authentication if the
repository is publicly accessible.
```plaintext
@@ -26,8 +24,6 @@ Parameters:
| `sort` | string | no | Return tags sorted in `asc` or `desc` order. Default is `desc` |
| `search` | string | no | Return list of tags matching the search criteria. You can use `^term` and `term$` to find tags that begin and end with `term` respectively. |
-> Support for `search` was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/54401) in GitLab 11.8.
-
```json
[
{
diff --git a/doc/api/users.md b/doc/api/users.md
index 292dc411e5b..28e1512ea12 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -434,7 +434,7 @@ Parameters:
| `email` | Yes | Email |
| `extern_uid` | No | External UID |
| `external` | No | Flags the user as external - true or false (default) |
-| `extra_shared_runners_minutes_limit` | No | Extra pipeline minutes quota for this user (purchased in addition to the minutes included in the plan) **(PREMIUM)** |
+| `extra_shared_runners_minutes_limit` **(PREMIUM)** | No | Can be set by administrators only. Additional CI/CD minutes for this user. |
| `force_random_password` | No | Set user password to a random value - true or false (default) |
| `group_id_for_saml` | No | ID of group where SAML has been configured |
| `linkedin` | No | LinkedIn |
@@ -447,7 +447,7 @@ Parameters:
| `projects_limit` | No | Number of projects user can create |
| `provider` | No | External provider name |
| `reset_password` | No | Send user password reset link - true or false(default) |
-| `shared_runners_minutes_limit` | No | Pipeline minutes quota for this user (included in plan). Can be `nil` (default; inherit system default), `0` (unlimited) or `> 0` **(PREMIUM)** |
+| `shared_runners_minutes_limit` **(PREMIUM)** | No | Can be set by administrators only. Maximum number of monthly CI/CD minutes for this user. Can be `nil` (default; inherit system default), `0` (unlimited), or `> 0`. |
| `skip_confirmation` | No | Skip confirmation - true or false (default) |
| `skype` | No | Skype ID |
| `theme_id` | No | The GitLab theme for the user (see [the user preference docs](../user/profile/preferences.md#navigation-theme) for more information) |
@@ -476,7 +476,7 @@ Parameters:
| `email` | No | Email |
| `extern_uid` | No | External UID |
| `external` | No | Flags the user as external - true or false (default) |
-| `extra_shared_runners_minutes_limit` | No | Extra pipeline minutes quota for this user (purchased in addition to the minutes included in the plan) **(PREMIUM)** |
+| `extra_shared_runners_minutes_limit` **(PREMIUM)** | No | Can be set by administrators only. Additional CI/CD minutes for this user. |
| `group_id_for_saml` | No | ID of group where SAML has been configured |
| `id` | Yes | The ID of the user |
| `linkedin` | No | LinkedIn |
@@ -489,7 +489,7 @@ Parameters:
| `projects_limit` | No | Limit projects each user can create |
| `provider` | No | External provider name |
| `public_email` | No | The public email of the user (must be already verified) |
-| `shared_runners_minutes_limit` | No | Pipeline minutes quota for this user (included in plan). Can be `nil` (default; inherit system default), `0` (unlimited) or `> 0` **(PREMIUM)** |
+| `shared_runners_minutes_limit` **(PREMIUM)** | No | Can be set by administrators only. Maximum number of monthly CI/CD minutes for this user. Can be `nil` (default; inherit system default), `0` (unlimited) or `> 0`. |
| `skip_reconfirmation` | No | Skip reconfirmation - true or false (default) |
| `skype` | No | Skype ID |
| `theme_id` | No | The GitLab theme for the user (see [the user preference docs](../user/profile/preferences.md#navigation-theme) for more information) |
diff --git a/doc/api/vulnerabilities.md b/doc/api/vulnerabilities.md
index 1c6f7a760e6..18d97e30643 100644
--- a/doc/api/vulnerabilities.md
+++ b/doc/api/vulnerabilities.md
@@ -19,7 +19,7 @@ This API is in the process of being deprecated and considered unstable.
The response payload may be subject to change or breakage
across GitLab releases. Please use the
[GraphQL API](graphql/reference/index.md#queryvulnerabilities)
-instead.
+instead. See the [GraphQL examples](#replace-vulnerability-rest-api-with-graphql) to get started.
Every API call to vulnerabilities must be [authenticated](index.md#authentication).
@@ -272,3 +272,185 @@ Example response:
"closed_at": null
}
```
+
+## Replace Vulnerability REST API with GraphQL
+
+To prepare for the [upcoming deprecation](https://gitlab.com/groups/gitlab-org/-/epics/5118) of
+the Vulnerability REST API endpoint, use the examples below to perform the equivalent operations
+with the GraphQL API.
+
+### GraphQL - Single vulnerability
+
+Use [`Query.vulnerability`](graphql/reference/#queryvulnerability).
+
+```graphql
+{
+ vulnerability(id: "gid://gitlab/Vulnerability/20345379") {
+ title
+ description
+ state
+ severity
+ reportType
+ project {
+ id
+ name
+ fullPath
+ }
+ detectedAt
+ confirmedAt
+ resolvedAt
+ resolvedBy {
+ id
+ username
+ }
+ }
+}
+```
+
+Example response:
+
+```json
+{
+ "data": {
+ "vulnerability": {
+ "title": "Improper Input Validation in railties",
+ "description": "A remote code execution vulnerability in development mode Rails beta3 can allow an attacker to guess the automatically generated development mode secret token. This secret token can be used in combination with other Rails internals to escalate to a remote code execution exploit.",
+ "state": "RESOLVED",
+ "severity": "CRITICAL",
+ "reportType": "DEPENDENCY_SCANNING",
+ "project": {
+ "id": "gid://gitlab/Project/6102100",
+ "name": "security-reports",
+ "fullPath": "gitlab-examples/security/security-reports"
+ },
+ "detectedAt": "2021-10-14T03:13:41Z",
+ "confirmedAt": "2021-12-14T01:45:56Z",
+ "resolvedAt": "2021-12-14T01:45:59Z",
+ "resolvedBy": {
+ "id": "gid://gitlab/User/480804",
+ "username": "thiagocsf"
+ }
+ }
+ }
+}
+```
+
+### GraphQL - Confirm vulnerability
+
+Use [`Mutation.vulnerabilityConfirm`](graphql/reference/#mutationvulnerabilityconfirm).
+
+```graphql
+mutation {
+ vulnerabilityConfirm(input: { id: "gid://gitlab/Vulnerability/23577695"}) {
+ vulnerability {
+ state
+ }
+ errors
+ }
+}
+```
+
+Example response:
+
+```json
+{
+ "data": {
+ "vulnerabilityConfirm": {
+ "vulnerability": {
+ "state": "CONFIRMED"
+ },
+ "errors": []
+ }
+ }
+}
+```
+
+### GraphQL - Resolve vulnerability
+
+Use [`Mutation.vulnerabilityResolve`](graphql/reference/#mutationvulnerabilityresolve).
+
+```graphql
+mutation {
+ vulnerabilityResolve(input: { id: "gid://gitlab/Vulnerability/23577695"}) {
+ vulnerability {
+ state
+ }
+ errors
+ }
+}
+```
+
+Example response:
+
+```json
+{
+ "data": {
+ "vulnerabilityConfirm": {
+ "vulnerability": {
+ "state": "RESOLVED"
+ },
+ "errors": []
+ }
+ }
+}
+```
+
+### GraphQL - Dismiss vulnerability
+
+Use [`Mutation.vulnerabilityDismiss`](graphql/reference/#mutationvulnerabilitydismiss).
+
+```graphql
+mutation {
+ vulnerabilityDismiss(input: { id: "gid://gitlab/Vulnerability/23577695"}) {
+ vulnerability {
+ state
+ }
+ errors
+ }
+}
+```
+
+Example response:
+
+```json
+{
+ "data": {
+ "vulnerabilityConfirm": {
+ "vulnerability": {
+ "state": "DISMISSED"
+ },
+ "errors": []
+ }
+ }
+}
+```
+
+### GraphQL - Revert vulnerability to detected state
+
+Use [`Mutation.vulnerabilityRevertToDetected`](graphql/reference/#mutationvulnerabilityreverttodetected).
+
+```graphql
+mutation {
+ vulnerabilityRevertToDetected(input: { id: "gid://gitlab/Vulnerability/20345379"}) {
+ vulnerability {
+ state
+ }
+ errors
+ }
+}
+```
+
+Example response:
+
+```json
+{
+ "data": {
+ "vulnerabilityConfirm": {
+ "vulnerability": {
+ "state": "DETECTED"
+ },
+ "errors": []
+ }
+ }
+}
+```
diff --git a/doc/api/vulnerability_findings.md b/doc/api/vulnerability_findings.md
index 36604ebf87d..20bbe66549d 100644
--- a/doc/api/vulnerability_findings.md
+++ b/doc/api/vulnerability_findings.md
@@ -25,9 +25,11 @@ If a user is able to access the project but does not have permission to
any request for vulnerability findings of this project results in a `403` status code.
WARNING:
-This API is in an alpha stage and considered unstable.
+This API is in the process of being deprecated and considered unstable.
The response payload may be subject to change or breakage
-across GitLab releases.
+across GitLab releases. Please use the
+[GraphQL API](graphql/reference/index.md#queryvulnerabilities)
+instead. See the [GraphQL examples](#replace-vulnerability-findings-rest-api-with-graphql) to get started.
## Vulnerability findings pagination
@@ -137,3 +139,130 @@ Example response:
}
]
```
+
+## Replace Vulnerability Findings REST API with GraphQL
+
+To prepare for the [upcoming deprecation](https://gitlab.com/groups/gitlab-org/-/epics/5118) of
+the Vulnerability Findings REST API endpoint, use the examples below to perform the equivalent operations
+with the GraphQL API.
+
+### GraphQL - Project vulnerabilities
+
+Use [`Project.vulnerabilities`](graphql/reference/#projectvulnerabilities).
+
+```graphql
+{
+ project(fullPath: "root/security-reports") {
+ vulnerabilities {
+ nodes{
+ id
+ reportType
+ title
+ severity
+ scanner {
+ externalId
+ name
+ vendor
+ }
+ identifiers {
+ externalType
+ externalId
+ name
+ url
+ }
+ falsePositive
+ project {
+ id
+ name
+ fullPath
+ }
+ description
+ links {
+ name
+ url
+ }
+ location {
+ ... on
+ VulnerabilityLocationSast {
+ file
+ startLine
+ endLine
+ vulnerableClass
+ vulnerableMethod
+ blobPath
+ }
+ }
+ details {
+ ... on
+ VulnerabilityDetailCode {
+ description
+ fieldName
+ lang
+ name
+ value
+ }
+ }
+ state
+ }
+ }
+ }
+}
+```
+
+Example response:
+
+```json
+{
+ "data": {
+ "project": {
+ "vulnerabilities": {
+ "nodes": [
+ {
+ "id": "gid://gitlab/Vulnerability/236",
+ "reportType": "SAST",
+ "title": "Generic Object Injection Sink",
+ "severity": "CRITICAL",
+ "scanner": {
+ "externalId": "eslint",
+ "name": "ESLint",
+ "vendor": "GitLab"
+ },
+ "identifiers": [
+ {
+ "externalType": "eslint_rule_id",
+ "externalId": "security/detect-object-injection",
+ "name": "ESLint rule ID security/detect-object-injection",
+ "url": "https://github.com/nodesecurity/eslint-plugin-security#detect-object-injection"
+ },
+ {
+ "externalType": "cwe",
+ "externalId": "94",
+ "name": "CWE-94",
+ "url": "https://cwe.mitre.org/data/definitions/94.html"
+ }
+ ],
+ "falsePositive": false,
+ "project": {
+ "id": "gid://gitlab/Project/20",
+ "name": "Security Reports",
+ "fullPath": "root/security-reports"
+ },
+ "description": "Bracket object notation with user input is present, this might allow an attacker to access all properties of the object and even it's prototype, leading to possible code execution.",
+ "links": [],
+ "location": {
+ "file": "src/js/main.js",
+ "startLine": "28",
+ "endLine": "28",
+ "vulnerableClass": null,
+ "vulnerableMethod": null,
+ "blobPath": "/root/security-reports/-/blob/91031428a5b5dbb81e8d889738b1875c1bfea787/src/js/main.js"
+ },
+ "details": [],
+ "state": "DETECTED"
+ }
+ ]
+ }
+ }
+ }
+}
+```
diff --git a/doc/api/wikis.md b/doc/api/wikis.md
index 8f71097aa0f..fb49e9465bc 100644
--- a/doc/api/wikis.md
+++ b/doc/api/wikis.md
@@ -1,14 +1,11 @@
---
stage: Create
group: Editor
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, api
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Project wikis API **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13372) in GitLab 10.0.
-
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.
diff --git a/doc/architecture/blueprints/ci_data_decay/index.md b/doc/architecture/blueprints/ci_data_decay/index.md
new file mode 100644
index 00000000000..155c781b04a
--- /dev/null
+++ b/doc/architecture/blueprints/ci_data_decay/index.md
@@ -0,0 +1,255 @@
+---
+stage: none
+group: unassigned
+comments: false
+description: 'CI/CD data time decay'
+---
+
+# CI/CD data time decay
+
+## Summary
+
+GitLab CI/CD is one of the most data and compute intensive components of GitLab.
+Since its [initial release in November 2012](https://about.gitlab.com/blog/2012/11/13/continuous-integration-server-from-gitlab/),
+the CI/CD subsystem has evolved significantly. It was [integrated into GitLab in September 2015](https://about.gitlab.com/releases/2015/09/22/gitlab-8-0-released/)
+and has become [one of the most beloved CI/CD solutions](https://about.gitlab.com/blog/2017/09/27/gitlab-leader-continuous-integration-forrester-wave/).
+
+On February 1st, 2021, GitLab.com surpassed 1 billion CI/CD builds, and the number of
+builds [continues to grow exponentially](../ci_scale/index.md).
+
+GitLab CI/CD has come a long way since the initial release, but the design of
+the data storage for pipeline builds remains almost the same since 2012. In
+2021 we started working on database decomposition and extracting CI/CD data to
+ia separate database. Now we want to improve the architecture of GitLab CI/CD
+product to enable further scaling.
+
+_Disclaimer: The following 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 in this document and linked pages 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._
+
+## Goals
+
+**Implement a new architecture of CI/CD data storage to enable scaling.**
+
+## Challenges
+
+There are more than two billion rows describing CI/CD builds in GitLab.com's
+database. This data represents a sizable portion of the whole data stored in
+PostgreSQL database running on GitLab.com.
+
+This volume contributes to significant performance problems, development
+challenges and is often related to production incidents.
+
+We also expect a [significant growth in the number of builds executed on
+GitLab.com](../ci_scale/index.md) in the upcoming years.
+
+## Opportunity
+
+CI/CD data is subject to
+[time-decay](https://about.gitlab.com/company/team/structure/working-groups/database-scalability/time-decay.html)
+because, usually, pipelines that are a few months old are not frequently
+accessed or are even not relevant anymore. Restricting access to processing
+pipelines that are older than a few months might help us to move this data out
+of the primary database, to a different storage, that is more performant and
+cost effective.
+
+It is already possible to prevent processing builds [that have been
+archived](../../../user/admin_area/settings/continuous_integration.md#archive-jobs).
+When a build gets archived it will not be possible to retry it, but we still do
+keep all the processing metadata in the database, and it consumes resources
+that are scarce in the primary database.
+
+In order to improve performance and make it easier to scale CI/CD data storage
+we might want to follow these three tracks described below.
+
+![pipeline data time decay](pipeline_data_time_decay.png)
+
+<!-- markdownlint-disable MD029 -->
+
+1. Partition builds queuing tables
+2. Archive CI/CD data into partitioned database schema
+3. Migrate archived builds metadata out of primary database
+
+<!-- markdownlint-enable MD029 -->
+
+### Migrate archived builds metadata out of primary database
+
+Once a build (or a pipeline) gets archived, it is no longer possible to resume
+pipeline processing in such pipeline. It means that all the metadata, we store
+in PostgreSQL, that is needed to efficiently and reliably process builds can be
+safely moved to a different data store.
+
+Currently, storing pipeline processing data is expensive as this kind of CI/CD
+data represents a significant portion of data stored in CI/CD tables. Once we
+restrict access to processing archived pipelines, we can move this metadata to
+a different place - preferably object storage - and make it accessible on
+demand, when it is really needed again (for example for compliance or auditing purposes).
+
+We need to evaluate whether moving data is the most optimal solution. We might
+be able to use de-duplication of metadata entries and other normalization
+strategies to consume less storage while retaining ability to query this
+dataset. Technical evaluation will be required to find the best solution here.
+
+Epic: [Migrate archived builds metadata out of primary database](https://gitlab.com/groups/gitlab-org/-/epics/7216).
+
+### Archive CI/CD data into partitioned database schema
+
+After we move CI/CD metadata to a different store, the problem of having
+billions of rows describing pipelines, builds and artifacts, remains. We still
+need to keep reference to the metadata we store in object storage and we still
+do need to be able to retrieve this information reliably in bulk (or search
+through it).
+
+It means that by moving data to object storage we might not be able to reduce
+the number of rows in CI/CD tables. Moving data to object storage should help
+with reducing the data size, but not the quantity of entries describing this
+data. Because of this limitation, we still want to partition CI/CD data to
+reduce the impact on the database (indices size, auto-vacuum time and
+frequency).
+
+Our intent here is not to move this data out of our primary database elsewhere.
+What want to divide very large database tables, that store CI/CD data, into
+multiple smaller ones, using PostgreSQL partitioning features.
+
+There are a few approaches we can take to partition CI/CD data. A promising one
+is using list-based partitioning where a partition number is assigned a
+pipeline, and gets propagated to all resources that are related to this
+pipeline. We assign the partition number based on when the pipeline was created
+or when we observed the last processing activity in it. This is very flexible
+because we can extend this partitioning strategy at will; for example with this
+strategy we can assign an arbitrary partition number based on multiple
+partitioning keys, combining time-decay-based partitioning with tenant-based
+partitioning on the application level.
+
+Partitioning rarely accessed data should also follow the policy defined for
+builds archival, to make it consistent and reliable.
+
+Epic: [Archive CI/CD data into partitioned database schema](https://gitlab.com/groups/gitlab-org/-/epics/5417).
+
+### Partition builds queuing tables
+
+While working on the [CI/CD Scale](../ci_scale/index.md) blueprint, we have
+introduced a [new architecture for queuing CI/CD builds](https://gitlab.com/groups/gitlab-org/-/epics/5909#note_680407908)
+for execution.
+
+This allowed us to significantly improve performance. We still consider the new
+solution as an intermediate mechanism, needed before we start working on the
+next iteration. The following iteration that should improve the architecture of
+builds queuing even more (it might require moving off the PostgreSQL fully or
+partially).
+
+In the meantime we want to ship another iteration, an intermediate step towards
+more flexible and reliable solution. We want to partition the new queuing
+tables, to reduce the impact on the database, to improve reliability and
+database health.
+
+Partitioning of CI/CD queuing tables does not need to follow the policy defined
+for builds archival. Instead we should leverage a long-standing policy saying
+that builds created more 24 hours ago need to be removed from the queue. This
+business rule is present in the product since the inception of GitLab CI.
+
+Epic: [Partition builds queuing tables](https://gitlab.com/gitlab-org/gitlab/-/issues/347027).
+
+## Principles
+
+All the three tracks we will use to implement CI/CD time decay pattern are
+associated with some challenges. As we progress with the implementation we will
+need to solve many problems and devise many implementation details to make this
+successful.
+
+Below, we documented a few foundational principles to make it easier for
+everyone to understand the vision described in this architectural blueprint.
+
+### Removing pipeline data
+
+While it might be tempting to simply remove old or archived data from our
+databases this should be avoided. It is usually not desired to permanently
+remove user data unless consent is given to do so. We can, however, move data
+to a different data store, like object storage.
+
+Archived data can still be needed sometimes (for example for compliance or
+auditing reasons). We want to be able to retrieve this data if needed, as long
+as permanent removal has not been requested or approved by a user.
+
+### Accessing pipeline data in the UI
+
+Implementing CI/CD data time-decay through partitioning might be challenging
+when we still want to make it possible for users to access data stored in many
+partitions.
+
+We want to retain simplicity of accessing pipeline data in the UI. It will
+require some backstage changes in how we reference pipeline data from other
+resources, but we don't want to make it more difficult for users to find their
+pipelines in the UI.
+
+We may need to add "Archived" tab on the pipelines / builds list pages, but we
+should be able to avoid additional steps / clicks when someone wants to view
+pipeline status or builds associated with a merge request or a deployment.
+
+We also may need to disable search in the "Archived" tab on pipelines / builds
+list pages.
+
+### Accessing pipeline data through the API
+
+We accept the possible necessity of building a separate API endpoint /
+endpoints needed to access pipeline data through the API.
+
+In the new API users might need to provide a time range in which the data has
+been created to search through their pipelines / builds. In order to make it
+efficient it might be necessary to restrict access to querying data residing in
+more than two partitions at once. We can do that by supporting time ranges
+spanning the duration that equals to the builds archival policy.
+
+It is possible to still allow users to use the old API to access archived
+pipelines data, although a user provided partition identifier may be required.
+
+## Iterations
+
+All three tracks can be worked on in parallel:
+
+1. [Migrate archived build metadata to object storage](https://gitlab.com/groups/gitlab-org/-/epics/7216).
+1. [Partition CI/CD data that have been archived](https://gitlab.com/groups/gitlab-org/-/epics/5417).
+1. [Partition CI/CD queuing tables using list partitioning](https://gitlab.com/gitlab-org/gitlab/-/issues/347027)
+
+## Status
+
+In progress.
+
+## Who
+
+Proposal:
+
+<!-- vale gitlab.Spelling = NO -->
+
+| Role | Who
+|------------------------------|-------------------------|
+| Author | Grzegorz Bizon |
+| Engineering Leader | Cheryl Li |
+| Product Manager | Jackie Porter |
+| Architecture Evolution Coach | Kamil Trzciński |
+
+DRIs:
+
+| Role | Who
+|------------------------------|------------------------|
+| Leadership | Cheryl Li |
+| Product | Jackie Porter |
+| Engineering | Grzegorz Bizon |
+
+Domain experts:
+
+| Area | Who
+|------------------------------|------------------------|
+| Verify / Pipeline execution | Fabio Pitino |
+| Verify / Pipeline execution | Marius Bobin |
+| PostgreSQL Database | Andreas Brandl |
+
+<!-- vale gitlab.Spelling = YES -->
diff --git a/doc/architecture/blueprints/ci_data_decay/pipeline_data_time_decay.png b/doc/architecture/blueprints/ci_data_decay/pipeline_data_time_decay.png
new file mode 100644
index 00000000000..e094b87933a
--- /dev/null
+++ b/doc/architecture/blueprints/ci_data_decay/pipeline_data_time_decay.png
Binary files differ
diff --git a/doc/architecture/blueprints/container_registry_metadata_database/index.md b/doc/architecture/blueprints/container_registry_metadata_database/index.md
index a38a8727dc4..c1aac235085 100644
--- a/doc/architecture/blueprints/container_registry_metadata_database/index.md
+++ b/doc/architecture/blueprints/container_registry_metadata_database/index.md
@@ -78,7 +78,7 @@ The single entrypoint for the registry is the [HTTP API](https://gitlab.com/gitl
| Operation | UI | Background | Observations |
| ------------------------------------------------------------ | ------------------ | ------------------------ | ------------------------------------------------------------ |
| [Check API version](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#api-version-check) | **{check-circle}** Yes | **{check-circle}** Yes | Used globally to ensure that the registry supports the Docker Distribution V2 API, as well as for identifying whether GitLab Rails is talking to the GitLab Container Registry or a third-party one (used to toggle features only available in the former). |
-| [List repository tags](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#listing-image-tags) | **{check-circle}** Yes | **{check-circle}** Yes | Used to list and show tags in the UI. Used to list tags in the background for [cleanup policies](../../../user/packages/container_registry/#cleanup-policy) and [Geo replication](../../../administration/geo/replication/docker_registry.md). |
+| [List repository tags](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#listing-image-tags) | **{check-circle}** Yes | **{check-circle}** Yes | Used to list and show tags in the UI. Used to list tags in the background for [cleanup policies](../../../user/packages/container_registry/reduce_container_registry_storage.md#cleanup-policy) and [Geo replication](../../../administration/geo/replication/docker_registry.md). |
| [Check if manifest exists](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#existing-manifests) | **{check-circle}** Yes | **{dotted-circle}** No | Used to get the digest of a manifest by tag. This is then used to pull the manifest and show the tag details in the UI. |
| [Pull manifest](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#pulling-an-image-manifest) | **{check-circle}** Yes | **{dotted-circle}** No | Used to show the image size and the manifest digest in the tag details UI. |
| [Pull blob](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md#pulling-a-layer) | **{check-circle}** Yes | **{dotted-circle}** No | Used to show the configuration digest and the creation date in the tag details UI. |
diff --git a/doc/architecture/blueprints/database_testing/index.md b/doc/architecture/blueprints/database_testing/index.md
index 38629e7348d..4676caab85d 100644
--- a/doc/architecture/blueprints/database_testing/index.md
+++ b/doc/architecture/blueprints/database_testing/index.md
@@ -1,4 +1,7 @@
---
+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
comments: false
description: 'Database Testing'
---
diff --git a/doc/architecture/blueprints/runner_scaling/gitlab-autoscaling-overview.png b/doc/architecture/blueprints/runner_scaling/gitlab-autoscaling-overview.png
new file mode 100644
index 00000000000..c3ba615784f
--- /dev/null
+++ b/doc/architecture/blueprints/runner_scaling/gitlab-autoscaling-overview.png
Binary files differ
diff --git a/doc/architecture/blueprints/runner_scaling/index.md b/doc/architecture/blueprints/runner_scaling/index.md
new file mode 100644
index 00000000000..8e47b5fda8c
--- /dev/null
+++ b/doc/architecture/blueprints/runner_scaling/index.md
@@ -0,0 +1,239 @@
+---
+stage: none
+group: unassigned
+comments: false
+description: 'Next Runner Auto-scaling Architecture'
+---
+
+# Next Runner Auto-scaling Architecture
+
+## Summary
+
+GitLab Runner is a core component of GitLab CI/CD. It makes it possible to run
+CI/CD jobs in a reliable and concurrent environment. It has been initially
+introduced by Kamil Trzciński in early 2015 to replace a Ruby version of the
+same service. GitLab Runner written in Go turned out to be easier to use by the
+wider community, it was more efficient and reliable than the previous,
+Ruby-based, version.
+
+In February 2016 Kamil Trzciński [implemented an auto-scaling feature](https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/53)
+to leverage cloud infrastructure to run many CI/CD jobs in parallel. This
+feature has become a foundation supporting CI/CD adoption on GitLab.com over
+the years, where we now run around 4 million builds per day at peak.
+
+During the initial implementation a decision was made to use Docker Machine:
+
+> Is easy to use. Is well documented. Is well supported and constantly
+> extended. It supports almost any cloud provider or virtualization
+> infrastructure. We need minimal amount of changes to support Docker Machine:
+> machine enumeration and inspection. We don't need to implement any "cloud
+> specific" features.
+
+This design choice was crucial for the GitLab Runner success. Since that time
+the auto-scaling feature has been used by many users and customers and enabled
+rapid growth of CI/CD adoption on GitLab.com.
+
+We can not, however, continue using Docker Machine. Work on that project [was
+paused in July 2018](https://github.com/docker/machine/issues/4537) and there
+was no development made since that time (except for some highly important
+security fixes). In 2018, after Docker Machine entered the “maintenance modeâ€,
+we decided to create [our own fork](https://gitlab.com/gitlab-org/ci-cd/docker-machine)
+to be able to keep using this and ship fixes and updates needed for our use case.
+[On September 26th, 2021 the project got archived](https://github.com/docker/docker.github.io/commit/2dc8b49dcbe85686cc7230e17aff8e9944cb47a5)
+and the documentation for it has been removed from the official page. This
+means that the original reason to use Docker Machine is no longer valid too.
+
+To keep supporting our customers and the wider community we need to design a
+new mechanism for GitLab Runner autoscaling. It not only needs to support
+auto-scaling, but it also needs to do that in the way to enable us to build on
+top of it to improve efficiency, reliability and availability.
+
+We call this new mechanism the “next GitLab Runner Scaling architectureâ€.
+
+_Disclaimer The following contain 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 in this document and linked pages 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._
+
+## Proposal
+
+Currently, GitLab Runner auto-scaling can be configured in a few ways. Some
+customers are successfully using an auto-scaled environment in Kubernetes. We
+know that a custom and unofficial GitLab Runner version has been built to make
+auto-scaling on Kubernetes more reliable. We recognize the importance of having
+a really good Kubernetes solution for running multiple jobs in parallel, but
+refinements in this area are out of scope for this architectural initiative.
+
+We want to focus on resolving problems with Docker Machine and replacing this
+mechanism with a reliable and flexible mechanism. We might be unable to build a
+drop-in replacement for Docker Machine, as there are presumably many reasons
+why it has been deprecated. It is very difficult to maintain compatibility with
+so many cloud providers, and it seems that Docker Machine has been deprecated
+in favor of Docker Desktop, which is not a viable replacement for us. [This
+issue](https://github.com/docker/roadmap/issues/245) contains a discussion
+about how people are using Docker Machine right now, and it seems that GitLab
+CI is one of the most frequent reasons for people to keep using Docker Machine.
+
+There is also an opportunity in being able to optionally run multiple jobs in a
+single, larger virtual machine. We can’t do that today, but we know that this
+can potentially significantly improve efficiency. We might want to build a new
+architecture that makes it easier and allows us to test how efficient it is
+with PoCs. Running multiple jobs on a single machine can also make it possible
+to reuse what we call a “sticky context†- a space for build artifacts / user
+data that can be shared between job runs.
+
+### 💡 Design a simple abstraction that users will be able to build on top of
+
+Because there is no viable replacement and we might be unable to support all
+cloud providers that Docker Machine used to support, the key design requirement
+is to make it really simple and easy for the wider community to write a custom
+GitLab auto-scaling plugin, whatever cloud provider they might be using. We
+want to design a simple abstraction that users will be able to build on top, as
+will we to support existing workflows on GitLab.com.
+
+The designed mechanism should abstract what Docker Machine executor has been doing:
+providing a way to create an external Docker environment, waiting to execute
+jobs by provisioning this environment and returning credentials required to
+perform these operations.
+
+The new plugin system should be available for all major platforms: Linux,
+Windows, MacOS.
+
+### 💡 Migrate existing Docker Machine solution to a plugin
+
+Once we design and implement the new abstraction, we should be able to migrate
+existing Docker Machine mechanisms to a plugin. This will make it possible for
+users and customers to immediately start using the new architecture, but still
+keep their existing workflows and configuration for Docker Machine. This will
+give everyone time to migrate to the new architecture before we drop support
+for the legacy auto-scaling entirely.
+
+### 💡 Build plugins for AWS, Google Cloud Platform and Azure
+
+Although we might be unable to add support for all the cloud providers that
+Docker Machine used to support, it seems to be important to provide
+GitLab-maintained plugins for the major cloud providers like AWS, Google Cloud
+Platform and Azure.
+
+We should build them, presumably in separate repositories, in a way that they
+are easy to contribute to, fork, modify for certain needs the wider community
+team members might have. It should be also easy to install a new plugin without
+the need of rebuilding GitLab Runner whenever it happens.
+
+### 💡 Write a solid documentation about how to build your own plugin
+
+It is important to show users how to build an auto-scaling plugin, so that they
+can implement support for their own cloud infrastructure.
+
+Building new plugins should be simple, and with the support of great
+documentation it should not require advanced skills, like understanding how
+gRPC works. We want to design the plugin system in a way that the entry barrier
+for contributing new plugins is very low.
+
+### 💡 Build a PoC to run multiple builds on a single machine
+
+We want to better understand what kind of efficiency can running multiple jobs
+on a single machine bring. It is difficult to predict that, so ideally we
+should build a PoC that will help us to better understand what we can expect
+from this.
+
+To run this experiement we most likely we will need to build an experimental
+plugin, that not only allows us to schedule running multiple builds on a single
+machine, but also has a set of comprehensive metrics built into it, to make it
+easier to understand how it performs.
+
+## Details
+
+How the abstraction for the custom provider will look exactly is something that
+we will need to prototype, PoC and decide in a data-informed way. There are a
+few proposals that we should describe in detail, develop requirements for, PoC
+and score. We will choose the solution that seems to support our goals the
+most.
+
+In order to describe the proposals we first need to better explain what part of
+the GitLab Runner needs to be abstracted away. To make this easier to grasp
+these concepts, let's take a look at the current auto-scaling architecture and
+sequence diagram.
+
+![GitLab Runner Autoscaling Overview](gitlab-autoscaling-overview.png)
+
+On the diagrams above we see that currently a GitLab Runner Manager runs on a
+machine that has access to a cloud provider’s API. It is using Docker Machine
+to provision new Virtual Machines with Docker Engine installed and it
+configures the Docker daemon there to allow external authenticated requests. It
+stores credentials to such ephemeral Docker environments on disk. Once a
+machine has been provisioned and made available for GitLab Runner Manager to
+run builds, it is using one of the existing executors to run a user-provided
+script. In auto-scaling, this is typically done using Docker executor.
+
+### Custom provider
+
+In order to reduce the scope of work, we only want to introduce the new
+abstraction layer in one place.
+
+A few years ago we introduced the [Custom Executor](https://docs.gitlab.com/runner/executors/custom.html)
+feature in GitLab Runner. It allows users to design custom build execution
+methods. The custom executor driver can be implemented in any way - from a
+simple shell script to a dedicated binary - that is then used by a Runner
+through os/exec system calls.
+
+Thanks to the custom executor abstraction there is no more need to implement
+new executors internally in Runner. Users who have specific needs can implement
+their own drivers and don’t need to wait for us to make their work part of the
+“official†GitLab Runner. As each driver is a separate project, it also makes
+it easier to create communities around them, where interested people can
+collaborate together on improvements and bug fixes.
+
+We want to design the new Custom Provider to replicate the success of the
+Custom Executor. It will make it easier for users to build their own ways to
+provide a context and an environment in which a build will be executed by one
+of the Custom Executors.
+
+There are multiple solutions to implementing a custom provider abstraction. We
+can use raw Go plugins, Hashcorp’s Go Plugin, HTTP interface or gRPC based
+facade service. There are many solutions, and we want to choose the most
+optimal one. In order to do that, we will describe the solutions in a separate
+document, define requirements and score the solution accordingly. This will
+allow us to choose a solution that will work best for us and the wider
+community.
+
+## Status
+
+Status: RFC.
+
+## Who
+
+Proposal:
+
+<!-- vale gitlab.Spelling = NO -->
+
+| Role | Who
+|------------------------------|------------------------------------------|
+| Authors | Grzegorz Bizon, Tomasz Maczukin |
+| Architecture Evolution Coach | Kamil Trzciński |
+| Engineering Leader | Elliot Rushton, Cheryl Li |
+| Product Manager | Darren Eastman, Jackie Porter |
+| Domain Expert / Runner | Arran Walker |
+
+DRIs:
+
+| Role | Who
+|------------------------------|------------------------|
+| Leadership | Elliot Rushton |
+| Product | Darren Eastman |
+| Engineering | Tomasz Maczukin |
+
+Domain experts:
+
+| Area | Who
+|------------------------------|------------------------|
+| Domain Expert / Runner | Arran Walker |
+
+<!-- vale gitlab.Spelling = YES -->
diff --git a/doc/ci/caching/index.md b/doc/ci/caching/index.md
index 491454aed28..c634491662d 100644
--- a/doc/ci/caching/index.md
+++ b/doc/ci/caching/index.md
@@ -235,6 +235,39 @@ test_async:
- node ./specs/start.js ./specs/async.spec.js
```
+#### Compute the cache key from the lock file
+
+You can use [`cache:key:files`](../yaml/index.md#cachekeyfiles) to compute the cache
+key from a lock file like `package-lock.json` or `yarn.lock`, and reuse it in many jobs.
+
+```yaml
+# Cache modules using lock file
+cache:
+ key:
+ files:
+ - package-lock.json
+ paths:
+ - .npm/
+```
+
+If you're using [Yarn](https://yarnpkg.com/), you can use [`yarn-offline-mirror`](https://classic.yarnpkg.com/blog/2016/11/24/offline-mirror/)
+to cache the zipped `node_modules` tarballs. The cache generates more quickly, because
+fewer files have to be compressed:
+
+```yaml
+job:
+ script:
+ - echo 'yarn-offline-mirror ".yarn-cache/"' >> .yarnrc
+ - echo 'yarn-offline-mirror-pruning true' >> .yarnrc
+ - yarn install --frozen-lockfile --no-progress
+ cache:
+ key:
+ files:
+ - yarn.lock
+ paths:
+ - .yarn-cache/
+```
+
### Cache PHP dependencies
If your project uses [Composer](https://getcomposer.org/) to install
diff --git a/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md b/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md
index cf4e846ebb4..0aa7f157602 100644
--- a/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md
+++ b/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md
@@ -65,8 +65,7 @@ To use GitLab CI/CD with a Bitbucket Cloud repository:
1. In Bitbucket, add a script to push the pipeline status to Bitbucket.
NOTE:
- Changes made in GitLab are overwritten by any changes made
- upstream in Bitbucket.
+ The changes must be made in Bitbucket as any changes in the GitLab repository are overwritten by Bitbucket when GitLab next mirrors the repository.
Create a file `build_status` and insert the script below and run
`chmod +x build_status` in your terminal to make the script executable.
diff --git a/doc/ci/ci_cd_for_external_repos/img/ci_cd_for_external_repo.png b/doc/ci/ci_cd_for_external_repos/img/ci_cd_for_external_repo.png
deleted file mode 100644
index f068688146b..00000000000
--- a/doc/ci/ci_cd_for_external_repos/img/ci_cd_for_external_repo.png
+++ /dev/null
Binary files differ
diff --git a/doc/ci/ci_cd_for_external_repos/index.md b/doc/ci/ci_cd_for_external_repos/index.md
index 7bc138d083d..4e0cd7609cb 100644
--- a/doc/ci/ci_cd_for_external_repos/index.md
+++ b/doc/ci/ci_cd_for_external_repos/index.md
@@ -9,10 +9,6 @@ type: index, howto
>[Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/4642) in GitLab 10.6.
-INFO:
-Get external repo access and more by upgrading to GitLab Ultimate.
-[Try a free 30-day trial now](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=p-ci-cd-external-docs).
-
GitLab CI/CD can be used with [GitHub](github_integration.md), [Bitbucket Cloud](bitbucket_integration.md), or any other
Git server.
diff --git a/doc/ci/cloud_services/aws/index.md b/doc/ci/cloud_services/aws/index.md
new file mode 100644
index 00000000000..f09b23db2c5
--- /dev/null
+++ b/doc/ci/cloud_services/aws/index.md
@@ -0,0 +1,92 @@
+---
+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
+---
+
+# Configure OpenID Connect in AWS to retrieve temporary credentials
+
+In this tutorial, we'll show you how to use a GitLab CI/CD job with a JSON web token (JWT) to retrieve temporary credentials from AWS without needing to store secrets.
+To do this, you must configure OpenID Connect (OIDC) for ID federation between GitLab and AWS. For background and requirements for integrating GitLab using OIDC, see [Connect to cloud services](../index.md).
+
+To complete this tutorial:
+
+1. [Add the identity provider](#add-the-identity-provider)
+1. [Configure the role and trust](#configure-a-role-and-trust)
+1. [Retrieve a temporary credential](#retrieve-temporary-credentials)
+
+## Add the identity provider
+
+Create GitLab as a IAM OIDC provider in AWS following these [instructions](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html).
+
+Include the following information:
+
+- **Provider URL**: The address of your GitLab instance, such as `https://gitlab.com` or `http://gitlab.example.com`.
+- **Audience**: The address of your GitLab instance, such as `https://gitlab.com` or `http://gitlab.example.com`.
+ - The address must include `https://`.
+ - Do not include a trailing slash.
+
+## Configure a role and trust
+
+After you create the identity provider, configure a [web identity role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_oidc.html) with conditions for limiting access to GitLab resources. Temporary credentials are obtained using [AWS Security Token Service](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html), so set the `Action` to [sts:AssumeRoleWithWebIdentity](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html).
+
+For the full list of supported filtering types, see [Connect to cloud services](../index.md).
+
+```json
+{
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Allow",
+ "Principal": {
+ "Federated": "arn:aws:iam::AWS_ACCOUNT:oidc-provider/gitlab.example.com"
+ },
+ "Action": "sts:AssumeRoleWithWebIdentity",
+ "Condition": {
+ "StringEquals": {
+ "gitlab.example.com:sub": "project_path:mygroup/myproject:ref_type:branch:ref:main"
+ }
+ }
+ }
+ ]
+}
+```
+
+After the role is created, attach a policy defining permissions to an AWS service (S3, EC2, Secrets Manager).
+
+## Retrieve temporary credentials
+
+After you configure the OIDC and role, the GitLab CI/CD job can retrieve a temporary credential from [AWS Security Token Service (STS)](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html).
+
+```yaml
+assume role:
+ script:
+ - >
+ STS=($(aws sts assume-role-with-web-identity
+ --role-arn ${ROLE_ARN}
+ --role-session-name "GitLabRunner-${CI_PROJECT_ID}-${CI_PIPELINE_ID}"
+ --web-identity-token $CI_JOB_JWT_V2
+ --duration-seconds 3600
+ --query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]'
+ --output text))
+ - export AWS_ACCESS_KEY_ID="${STS[0]}"
+ - export AWS_SECRET_ACCESS_KEY="${STS[1]}"
+ - export AWS_SESSION_TOKEN="${STS[2]}"
+ - aws sts get-caller-identity
+```
+
+- `CI_JOB_JWT_V2`: Predefined variable.
+- `ROLE_ARN`: The role ARN defined in this [step](#configure-a-role-and-trust).
+
+## Working example
+
+See this [reference project](https://gitlab.com/guided-explorations/aws/configure-openid-connect-in-aws) for provisioning OIDC in AWS using Terraform and a sample script to retrieve temporary credentials.
+
+## Troubleshooting
+
+### `An error occurred (AccessDenied) when calling the AssumeRoleWithWebIdentity operation: Not authorized to perform sts:AssumeRoleWithWebIdentity`
+
+This error can occur for multiple reasons:
+
+- The cloud administrator has not configured the project to use OIDC with GitLab.
+- The role is restricted from being run on the branch or tag. See [configure a conditional role](../index.md).
diff --git a/doc/ci/cloud_services/index.md b/doc/ci/cloud_services/index.md
new file mode 100644
index 00000000000..73e726ea8a9
--- /dev/null
+++ b/doc/ci/cloud_services/index.md
@@ -0,0 +1,133 @@
+---
+stage: Configure
+group: Configure
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Connect to cloud services
+
+> - `CI_JOB_JWT` variable for reading secrets from Vault [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207125) in GitLab 12.10.
+> - `CI_JOB_JWT_V2` variable to support additional OIDC providers [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/346737) in GitLab 14.7.
+
+GitLab CI/CD supports [OpenID Connect (OIDC)](https://openid.net/connect/faq/) that allows your build and deployment job access to cloud credentials and services. Historically, teams stored secrets in projects or applied permissions on the GitLab Runner instance to build and deploy. To support this, a predefined variable named `CI_JOB_JWT_V2` is included in the CI/CD job allowing you to follow a scalable and least-privilege security approach.
+
+## Requirements
+
+- Account on GitLab.
+- Access to a cloud provider that supports OIDC to configure authorization and create roles.
+
+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.
+
+WARNING:
+The `CI_JOB_JWT_V2` variable is under development [(alpha)](https://about.gitlab.com/handbook/product/gitlab-the-product/#alpha) and is not yet suitable for production use.
+
+## Use cases
+
+- Removes the need to store secrets in your GitLab group or project. Temporary credentials can be retrieved from your cloud provider through OIDC.
+- Provides temporary access to cloud resources with granular GitLab conditionals including a group, project, branch, or tag.
+- Enables you to define separation of duties in the CI/CD job with conditional access to environments. Historically, apps may have been deployed with a designated GitLab Runner that had only access to staging or production environments. This led to Runner sprawl as each machine had dedicated permissions.
+- Allows shared runners to securely access multiple cloud accounts. The access is determined by the JWT token, which is specific to the user running the pipeline.
+- Removes the need to create logic to rotate secrets by retrieving temporary credentials by default.
+
+## How it works
+
+Each job has a JSON web token (JWT) provided as a CI/CD [predefined variable](../variables/predefined_variables.md) named `CI_JOB_JWT` or `CI_JOB_JWT_V2`. This JWT can be used to authenticate with the OIDC-supported cloud provider such as AWS, GCP, or Vault.
+
+The following fields are included in the JWT:
+
+| Field | When | Description |
+| ----------------------- | ------ | ----------- |
+| `jti` | Always | Unique identifier for this token |
+| `iss` | Always | Issuer, the domain of your GitLab instance |
+| `iat` | Always | Issued at |
+| `nbf` | Always | Not valid before |
+| `exp` | Always | Expires at |
+| `aud` | Always | Issuer, the domain of your GitLab instance |
+| `sub` | Always |`project_path:{group}/{project}:ref_type:{type}:ref:{branch_name}` |
+| `namespace_id` | Always | Use this to scope to group or user level namespace by ID |
+| `namespace_path` | Always | Use this to scope to group or user level namespace by path |
+| `project_id` | Always | Use this to scope to project by ID |
+| `project_path` | Always | Use this to scope to project by path |
+| `user_id` | Always | ID of the user executing the job |
+| `user_login` | Always | Username of the user executing the job |
+| `user_email` | Always | Email of the user executing the job |
+| `pipeline_id` | Always | ID of this pipeline |
+| `pipeline_source` | Always | [Pipeline source](../jobs/job_control.md#common-if-clauses-for-rules) |
+| `job_id` | Always | ID of this job |
+| `ref` | Always | Git ref for this job |
+| `ref_type` | Always | Git ref type, either `branch` or `tag` |
+| `ref_protected` | Always | `true` if this Git ref is protected, `false` otherwise |
+| `environment` | Job is creating a deployment | Environment this job deploys to ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/294440) in GitLab 13.9) |
+| `environment_protected` | Job is creating a deployment |`true` if deployed environment is protected, `false` otherwise ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/294440) in GitLab 13.9) |
+
+```json
+{
+ "jti": "c82eeb0c-5c6f-4a33-abf5-4c474b92b558",
+ "iss": "https://gitlab.example.com",
+ "aud": "https://gitlab.example.com",
+ "iat": 1585710286,
+ "nbf": 1585798372,
+ "exp": 1585713886,
+ "sub": "project_path:mygroup/myproject:ref_type:branch:ref:main",
+ "namespace_id": "1",
+ "namespace_path": "mygroup",
+ "project_id": "22",
+ "project_path": "mygroup/myproject",
+ "user_id": "42",
+ "user_login": "myuser",
+ "user_email": "myuser@example.com",
+ "pipeline_id": "1212",
+ "pipeline_source": "web",
+ "job_id": "1212",
+ "ref": "auto-deploy-2020-04-01",
+ "ref_type": "branch",
+ "ref_protected": "true",
+ "environment": "production",
+ "environment_protected": "true"
+}
+```
+
+### Authorization workflow
+
+```mermaid
+sequenceDiagram
+ participant GitLab
+ Note right of Cloud: Create OIDC identity provider
+ Note right of Cloud: Create role with conditionals
+ Note left of GitLab: CI/CD job with CI_JOB_JWT_V2
+ GitLab->>+Cloud: Call cloud API with CI_JOB_JWT_V2
+ Note right of Cloud: Decode & verify JWT with public key (https://gitlab/-/jwks)
+ Note right of Cloud: Validate audience defined in OIDC
+ Note right of Cloud: Validate conditional (sub, aud) role
+ Note right of Cloud: Generate credential or fetch secret
+ Cloud->>GitLab: Return temporary credential
+ Note left of GitLab: Perform operation
+
+```
+
+1. Create an OIDC identity provider in the cloud (for example, AWS, GCP, Vault).
+1. Create a conditional role in the cloud service that filters to a group, project, branch, or tag.
+1. The CI/CD job includes a predefined variable `CI_JOB_JWT_V2` that is a JWT token. You can use this token for authorization with your cloud API.
+1. The cloud verifies the token, validates the conditional role from the payload, and returns a temporary credential.
+
+## Configure a conditional role with OIDC claims
+
+To configure the trust between GitLab and OIDC, you must create a conditional role in the cloud provider that checks against the JWT token. The condition is validated against the JWT to create a trust specifically against two claims, the audience and subject.
+
+- Audience or `aud`: The URL of the GitLab instance. This is defined when the identity provider is first configured in your cloud provider.
+- Subject or `sub`: A concatenation of metadata describing the GitLab CI/CD workflow including the group, project, branch, and tag. The `sub` field is in the following format:
+ - `project_path:{group}/{project}:ref_type:{type}:ref:{branch_name}`
+
+| Filter type | Example |
+| ------------------------------------ | ------------------------------------------------------------ |
+| Filter to main branch | `project_path:mygroup/myproject:ref_type:branch:ref:main` |
+| Filter to any branch | Wildcard supported. `project_path:mygroup/myproject:ref_type:branch:ref:*` |
+| Filter to specific project | `project_path:mygroup/myproject:ref_type:branch:ref:main` |
+| Filter to all projects under a group | Wildcard supported. `project_path:mygroup/*:ref_type:branch:ref:main` |
+| Filter to a Git tag | Wildcard supported. `project_path:mygroup/*:ref_type:tag:ref:1.0` |
+
+## OIDC authorization with your cloud provider
+
+To connect with your cloud provider, see the following tutorials:
+
+- [Configure OpenID Connect in AWS](aws/index.md)
diff --git a/doc/ci/docker/using_docker_build.md b/doc/ci/docker/using_docker_build.md
index 3a05e9aa7d9..9b91cd40338 100644
--- a/doc/ci/docker/using_docker_build.md
+++ b/doc/ci/docker/using_docker_build.md
@@ -19,7 +19,7 @@ GitLab Runner to support `docker` commands.
To enable Docker commands for your CI/CD jobs, you can use:
- [The shell executor](#use-the-shell-executor)
-- [The Docker executor with the Docker image (Docker-in-Docker)](#use-the-docker-executor-with-the-docker-image-docker-in-docker)
+- [Docker-in-Docker](#use-docker-in-docker)
- [Docker socket binding](#use-docker-socket-binding)
If you don't want to execute a runner in privileged mode,
@@ -78,54 +78,29 @@ You can now use `docker` commands (and install `docker-compose` if needed).
When you add `gitlab-runner` to the `docker` group, you are effectively granting `gitlab-runner` full root permissions.
Learn more about the [security of the `docker` group](https://blog.zopyx.com/on-docker-security-docker-group-considered-harmful/).
-### Use the Docker executor with the Docker image (Docker-in-Docker)
+### Use Docker-in-Docker
"Docker-in-Docker" (`dind`) means:
-- Your registered runner uses the [Docker executor](https://docs.gitlab.com/runner/executors/docker.html).
+- Your registered runner uses the [Docker executor](https://docs.gitlab.com/runner/executors/docker.html) or the [Kubernetes executor](https://docs.gitlab.com/runner/executors/kubernetes.html).
- The executor uses a [container image of Docker](https://hub.docker.com/_/docker/), provided
by Docker, to run your CI/CD jobs.
The Docker image has all of the `docker` tools installed and can run
the job script in context of the image in privileged mode.
-We recommend you use [Docker-in-Docker with TLS enabled](#docker-in-docker-with-tls-enabled),
+We recommend you use Docker-in-Docker with TLS enabled,
which is supported by [GitLab.com shared runners](../runners/index.md).
You should always specify a specific version of the image, like `docker:19.03.12`.
If you use a tag like `docker:stable`, you have no control over which version is used.
Unpredictable behavior can result, especially when new versions are released.
-#### Limitations of Docker-in-Docker
+#### Use the Docker executor with Docker-in-Docker
-Docker-in-Docker is the recommended configuration, but is
-not without its own challenges:
+You can use the Docker executor to run jobs in a Docker container.
-- **The `docker-compose` command**: This command is not available in this configuration by default.
- To use `docker-compose` in your job scripts, follow the `docker-compose`
- [installation instructions](https://docs.docker.com/compose/install/).
-- **Cache**: Each job runs in a new environment. Concurrent jobs work fine,
- because every build gets its own instance of Docker engine and they don't conflict with each other.
- However, jobs can be slower because there's no caching of layers.
-- **Storage drivers**: By default, earlier versions of Docker use the `vfs` storage driver,
- which copies the file system for each job. Docker 17.09 and later use `--storage-driver overlay2`, which is
- the recommended storage driver. See [Using the OverlayFS driver](#use-the-overlayfs-driver) for details.
-- **Root file system**: Because the `docker:19.03.12-dind` container and the runner container don't share their
- root file system, you can use the job's working directory as a mount point for
- child containers. For example, if you have files you want to share with a
- child container, you might create a subdirectory under `/builds/$CI_PROJECT_PATH`
- and use it as your mount point. For a more detailed explanation, view [issue
- #41227](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41227).
-
- ```yaml
- variables:
- MOUNT_POINT: /builds/$CI_PROJECT_PATH/mnt
- script:
- - mkdir -p "$MOUNT_POINT"
- - docker run -v "$MOUNT_POINT:/mnt" my-docker-image
- ```
-
-#### Docker-in-Docker with TLS enabled
+##### Docker-in-Docker with TLS enabled in the Docker executor
> Introduced in GitLab Runner 11.11.
@@ -198,7 +173,7 @@ To use Docker-in-Docker with TLS enabled:
# https://github.com/docker-library/docker/blob/d45051476babc297257df490d22cbd806f1b11e4/19.03/docker-entrypoint.sh#L23-L29
#
# The 'docker' hostname is the alias of the service container as described at
- # https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#accessing-the-services.
+ # https://docs.gitlab.com/ee/ci/services/#accessing-the-services.
#
# Specify to Docker where to create the certificates. Docker
# creates them automatically on boot, and creates
@@ -219,7 +194,72 @@ To use Docker-in-Docker with TLS enabled:
- docker run my-docker-image /script/to/run/tests
```
-#### Docker-in-Docker with TLS enabled in Kubernetes
+##### Docker-in-Docker with TLS disabled in the Docker executor
+
+Sometimes you might have legitimate reasons to disable TLS.
+For example, you have no control over the GitLab Runner configuration
+that you are using.
+
+Assuming that the runner's `config.toml` is similar to:
+
+```toml
+[[runners]]
+ url = "https://gitlab.com/"
+ token = TOKEN
+ executor = "docker"
+ [runners.docker]
+ tls_verify = false
+ image = "docker:19.03.12"
+ privileged = true
+ disable_cache = false
+ volumes = ["/cache"]
+ [runners.cache]
+ [runners.cache.s3]
+ [runners.cache.gcs]
+```
+
+You can now use `docker` in the job script. Note the inclusion of the
+`docker:19.03.12-dind` service:
+
+```yaml
+image: docker:19.03.12
+
+variables:
+ # When using dind service, you must instruct docker to talk with the
+ # daemon started inside of the service. The daemon is available with
+ # a network connection instead of the default /var/run/docker.sock socket.
+ #
+ # The 'docker' hostname is the alias of the service container as described at
+ # https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#accessing-the-services
+ #
+ # If you're using GitLab Runner 12.7 or earlier with the Kubernetes executor and Kubernetes 1.6 or earlier,
+ # the variable must be set to tcp://localhost:2375 because of how the
+ # Kubernetes executor connects services to the job container
+ # DOCKER_HOST: tcp://localhost:2375
+ #
+ DOCKER_HOST: tcp://docker:2375
+ #
+ # This instructs Docker not to start over TLS.
+ DOCKER_TLS_CERTDIR: ""
+
+services:
+ - docker:19.03.12-dind
+
+before_script:
+ - docker info
+
+build:
+ stage: build
+ script:
+ - docker build -t my-docker-image .
+ - docker run my-docker-image /script/to/run/tests
+```
+
+#### Use the Kubernetes executor with Docker-in-Docker
+
+You can use the Kubernetes executor to run jobs in a Docker container.
+
+##### Docker-in-Docker with TLS enabled in Kubernetes
> [Introduced](https://gitlab.com/gitlab-org/charts/gitlab-runner/-/issues/106) in GitLab Runner Helm Chart 0.23.0.
@@ -257,7 +297,7 @@ To use Docker-in-Docker with TLS enabled in Kubernetes:
DOCKER_HOST: tcp://docker:2376
#
# The 'docker' hostname is the alias of the service container as described at
- # https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#accessing-the-services.
+ # https://docs.gitlab.com/ee/ci/services/#accessing-the-services.
# If you're using GitLab Runner 12.7 or earlier with the Kubernetes executor and Kubernetes 1.6 or earlier,
# the variable must be set to tcp://localhost:2376 because of how the
# Kubernetes executor connects services to the job container
@@ -287,66 +327,34 @@ To use Docker-in-Docker with TLS enabled in Kubernetes:
- docker run my-docker-image /script/to/run/tests
```
-#### Docker-in-Docker with TLS disabled
-
-Sometimes you might have legitimate reasons to disable TLS.
-For example, you have no control over the GitLab Runner configuration
-that you are using.
-
-Assuming that the runner's `config.toml` is similar to:
-
-```toml
-[[runners]]
- url = "https://gitlab.com/"
- token = TOKEN
- executor = "docker"
- [runners.docker]
- tls_verify = false
- image = "docker:19.03.12"
- privileged = true
- disable_cache = false
- volumes = ["/cache"]
- [runners.cache]
- [runners.cache.s3]
- [runners.cache.gcs]
-```
-
-You can now use `docker` in the job script. Note the inclusion of the
-`docker:19.03.12-dind` service:
-
-```yaml
-image: docker:19.03.12
-
-variables:
- # When using dind service, you must instruct docker to talk with the
- # daemon started inside of the service. The daemon is available with
- # a network connection instead of the default /var/run/docker.sock socket.
- #
- # The 'docker' hostname is the alias of the service container as described at
- # https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#accessing-the-services
- #
- # If you're using GitLab Runner 12.7 or earlier with the Kubernetes executor and Kubernetes 1.6 or earlier,
- # the variable must be set to tcp://localhost:2375 because of how the
- # Kubernetes executor connects services to the job container
- # DOCKER_HOST: tcp://localhost:2375
- #
- DOCKER_HOST: tcp://docker:2375
- #
- # This instructs Docker not to start over TLS.
- DOCKER_TLS_CERTDIR: ""
+#### Limitations of Docker-in-Docker
-services:
- - docker:19.03.12-dind
+Docker-in-Docker is the recommended configuration, but is
+not without its own challenges:
-before_script:
- - docker info
+- **The `docker-compose` command**: This command is not available in this configuration by default.
+ To use `docker-compose` in your job scripts, follow the `docker-compose`
+ [installation instructions](https://docs.docker.com/compose/install/).
+- **Cache**: Each job runs in a new environment. Concurrent jobs work fine,
+ because every build gets its own instance of Docker engine and they don't conflict with each other.
+ However, jobs can be slower because there's no caching of layers.
+- **Storage drivers**: By default, earlier versions of Docker use the `vfs` storage driver,
+ which copies the file system for each job. Docker 17.09 and later use `--storage-driver overlay2`, which is
+ the recommended storage driver. See [Using the OverlayFS driver](#use-the-overlayfs-driver) for details.
+- **Root file system**: Because the `docker:19.03.12-dind` container and the runner container don't share their
+ root file system, you can use the job's working directory as a mount point for
+ child containers. For example, if you have files you want to share with a
+ child container, you might create a subdirectory under `/builds/$CI_PROJECT_PATH`
+ and use it as your mount point. For a more detailed explanation, view [issue
+ #41227](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41227).
-build:
- stage: build
+ ```yaml
+ variables:
+ MOUNT_POINT: /builds/$CI_PROJECT_PATH/mnt
script:
- - docker build -t my-docker-image .
- - docker run my-docker-image /script/to/run/tests
-```
+ - mkdir -p "$MOUNT_POINT"
+ - docker run -v "$MOUNT_POINT:/mnt" my-docker-image
+ ```
### Use Docker socket binding
@@ -359,87 +367,50 @@ If you bind the Docker socket and you are
you can no longer use `docker:19.03.12-dind` as a service. Volume bindings
are done to the services as well, making these incompatible.
-To make Docker available in the context of the image:
+#### Use the Docker executor with Docker socket binding
-1. Install [GitLab Runner](https://docs.gitlab.com/runner/install/).
-1. From the command line, register a runner with the `docker` executor and share `/var/run/docker.sock`:
+To make Docker available in the context of the image, you will need to mount
+`/var/run/docker.sock` into the launched containers. To do this with the Docker
+executor, you need to add `"/var/run/docker.sock:/var/run/docker.sock"` to the
+[Volumes in the `[runners.docker]` section](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#volumes-in-the-runnersdocker-section).
- ```shell
- sudo gitlab-runner register -n \
- --url https://gitlab.com/ \
- --registration-token REGISTRATION_TOKEN \
- --executor docker \
- --description "My Docker Runner" \
- --docker-image "docker:19.03.12" \
- --docker-volumes /var/run/docker.sock:/var/run/docker.sock
- ```
-
- This command registers a new runner to use the
- `docker:19.03.12` image provided by Docker. The command uses
- the Docker daemon of the runner itself. Any containers spawned by Docker
- commands are siblings of the runner rather than children of the runner.
- This may have complications and limitations that are unsuitable for your workflow.
-
- Your `config.toml` file should now have an entry like this:
-
- ```toml
- [[runners]]
- url = "https://gitlab.com/"
- token = REGISTRATION_TOKEN
- executor = "docker"
- [runners.docker]
- tls_verify = false
- image = "docker:19.03.12"
- privileged = false
- disable_cache = false
- volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
- [runners.cache]
- Insecure = false
- ```
-
-1. Use `docker` in the job script. You don't need to
- include the `docker:19.03.12-dind` service, like you do when you're using
- the Docker-in-Docker executor:
-
- ```yaml
- image: docker:19.03.12
-
- before_script:
- - docker info
+Your configuration should look something like this:
- build:
- stage: build
- script:
- - docker build -t my-docker-image .
- - docker run my-docker-image /script/to/run/tests
- ```
-
-This method avoids using Docker in privileged mode. However,
-the implications of this method are:
+```toml
+[[runners]]
+ url = "https://gitlab.com/"
+ token = RUNNER_TOKEN
+ executor = "docker"
+ [runners.docker]
+ tls_verify = false
+ image = "docker:19.03.12"
+ privileged = false
+ disable_cache = false
+ volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
+ [runners.cache]
+ Insecure = false
+```
-- By sharing the Docker daemon, you are effectively disabling all
- the security mechanisms of containers and exposing your host to privilege
- escalation, which can lead to container breakout. For example, if a project
- ran `docker rm -f $(docker ps -a -q)` it would remove the GitLab Runner
- containers.
-- Concurrent jobs may not work; if your tests
- create containers with specific names, they may conflict with each other.
-- Sharing files and directories from the source repository into containers may not
- work as expected. Volume mounting is done in the context of the host
- machine, not the build container. For example:
+You can also do this while registering your runner by providing the following options:
- ```shell
- docker run --rm -t -i -v $(pwd)/src:/home/app/src test-image:latest run_app_tests
- ```
+```shell
+sudo gitlab-runner register -n \
+ --url https://gitlab.com/ \
+ --registration-token REGISTRATION_TOKEN \
+ --executor docker \
+ --description "My Docker Runner" \
+ --docker-image "docker:19.03.12" \
+ --docker-volumes /var/run/docker.sock:/var/run/docker.sock
+```
-#### Enable registry mirror for `docker:dind` service
+##### Enable registry mirror for `docker:dind` service
When the Docker daemon starts inside of the service container, it uses
the default configuration. You may want to configure a [registry
mirror](https://docs.docker.com/registry/recipes/mirror/) for
performance improvements and to ensure you don't reach Docker Hub rate limits.
-##### The service in the `.gitlab-ci.yml` file
+###### The service in the `.gitlab-ci.yml` file
You can append extra CLI flags to the `dind` service to set the registry
mirror:
@@ -450,7 +421,7 @@ services:
command: ["--registry-mirror", "https://registry-mirror.example.com"] # Specify the registry mirror to use
```
-##### The service in the GitLab Runner configuration file
+###### The service in the GitLab Runner configuration file
> [Introduced](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27173) in GitLab Runner 13.6.
@@ -487,7 +458,7 @@ Kubernetes:
command = ["--registry-mirror", "https://registry-mirror.example.com"]
```
-##### The Docker executor in the GitLab Runner configuration file
+###### The Docker executor in the GitLab Runner configuration file
If you are a GitLab Runner administrator, you can use
the mirror for every `dind` service. Update the
@@ -520,7 +491,7 @@ picked up by the `dind` service.
volumes = ["/opt/docker/daemon.json:/etc/docker/daemon.json:ro"]
```
-##### The Kubernetes executor in the GitLab Runner configuration file
+###### The Kubernetes executor in the GitLab Runner configuration file
> [Introduced](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/3223) in GitLab Runner 13.6.
@@ -569,6 +540,45 @@ The configuration is picked up by the `dind` service.
sub_path = "daemon.json"
```
+##### Limitations of Docker socket binding
+
+When you use Docker socket binding, you avoid running Docker in privileged mode. However,
+the implications of this method are:
+
+- By sharing the Docker daemon, you are effectively disabling all
+ the security mechanisms of containers and exposing your host to privilege
+ escalation, which can lead to container breakout. For example, if a project
+ ran `docker rm -f $(docker ps -a -q)` it would remove the GitLab Runner
+ containers.
+- Concurrent jobs may not work; if your tests
+ create containers with specific names, they may conflict with each other.
+- Any containers spawned by Docker commands are siblings of the runner rather
+ than children of the runner. This may have complications and limitations that
+ are unsuitable for your workflow.
+- Sharing files and directories from the source repository into containers may not
+ work as expected. Volume mounting is done in the context of the host
+ machine, not the build container. For example:
+
+ ```shell
+ docker run --rm -t -i -v $(pwd)/src:/home/app/src test-image:latest run_app_tests
+ ```
+
+You don't need to include the `docker:19.03.12-dind` service, like you do when
+you're using the Docker-in-Docker executor:
+
+```yaml
+image: docker:19.03.12
+
+before_script:
+ - docker info
+
+build:
+ stage: build
+ script:
+ - docker build -t my-docker-image .
+ - docker run my-docker-image /script/to/run/tests
+```
+
## Authenticate with registry in Docker-in-Docker
When you use Docker-in-Docker, the
@@ -831,13 +841,13 @@ After you've built a Docker image, you can push it up to the built-in
### `docker: Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?`
This is a common error when you are using
-[Docker-in-Docker](#use-the-docker-executor-with-the-docker-image-docker-in-docker)
+[Docker-in-Docker](#use-docker-in-docker)
v19.03 or later.
This issue occurs because Docker starts on TLS automatically.
- If this is your first time setting it up, read
- [use the Docker executor with the Docker image](#use-the-docker-executor-with-the-docker-image-docker-in-docker).
+ [use the Docker executor with the Docker image](#use-docker-in-docker).
- If you are upgrading from v18.09 or earlier, read our
[upgrade guide](https://about.gitlab.com/blog/2019/07/31/docker-in-docker-with-docker-19-dot-03/).
diff --git a/doc/ci/docker/using_docker_images.md b/doc/ci/docker/using_docker_images.md
index def7703231c..5bd9293924d 100644
--- a/doc/ci/docker/using_docker_images.md
+++ b/doc/ci/docker/using_docker_images.md
@@ -401,10 +401,10 @@ pulling from Docker Hub fails. Docker daemon tries to use the same credentials f
> Introduced in GitLab Runner 12.0.
-As an example, let's assume that you want to use the `aws_account_id.dkr.ecr.region.amazonaws.com/private/image:latest`
+As an example, let's assume that you want to use the `<aws_account_id>.dkr.ecr.<region>.amazonaws.com/private/image:latest`
image. This image is private and requires you to log in into a private container registry.
-To configure access for `aws_account_id.dkr.ecr.region.amazonaws.com`, follow these steps:
+To configure access for `<aws_account_id>.dkr.ecr.<region>.amazonaws.com`, follow these steps:
1. Make sure `docker-credential-ecr-login` is available in the GitLab Runner `$PATH`.
1. Have any of the following [AWS credentials setup](https://github.com/awslabs/amazon-ecr-credential-helper#aws-credentials).
@@ -418,7 +418,7 @@ To configure access for `aws_account_id.dkr.ecr.region.amazonaws.com`, follow th
```json
{
"credHelpers": {
- "aws_account_id.dkr.ecr.region.amazonaws.com": "ecr-login"
+ "<aws_account_id>.dkr.ecr.<region>.amazonaws.com": "ecr-login"
}
}
```
@@ -438,14 +438,14 @@ To configure access for `aws_account_id.dkr.ecr.region.amazonaws.com`, follow th
GitLab Runner reads this configuration file and uses the needed helper for this
specific repository.
-1. You can now use any private image from `aws_account_id.dkr.ecr.region.amazonaws.com` defined in
+1. You can now use any private image from `<aws_account_id>.dkr.ecr.<region>.amazonaws.com` defined in
`image` and/or `services` in your `.gitlab-ci.yml` file:
```yaml
- image: aws_account_id.dkr.ecr.region.amazonaws.com/private/image:latest
+ image: <aws_account_id>.dkr.ecr.<region>.amazonaws.com/private/image:latest
```
- In the example, GitLab Runner looks at `aws_account_id.dkr.ecr.region.amazonaws.com` for the
+ In the example, GitLab Runner looks at `<aws_account_id>.dkr.ecr.<region>.amazonaws.com` for the
image `private/image:latest`.
You can add configuration for as many registries as you want, adding more
diff --git a/doc/ci/docker/using_kaniko.md b/doc/ci/docker/using_kaniko.md
index ea3e81329d3..098ec9bdd02 100644
--- a/doc/ci/docker/using_kaniko.md
+++ b/doc/ci/docker/using_kaniko.md
@@ -13,7 +13,7 @@ type: howto
container images from a Dockerfile, inside a container or Kubernetes cluster.
kaniko solves two problems with using the
-[Docker-in-Docker build](using_docker_build.md#use-the-docker-executor-with-the-docker-image-docker-in-docker)
+[Docker-in-Docker build](using_docker_build.md#use-docker-in-docker)
method:
- Docker-in-Docker requires [privileged mode](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities)
diff --git a/doc/ci/environments/deployment_approvals.md b/doc/ci/environments/deployment_approvals.md
new file mode 100644
index 00000000000..d60e5704877
--- /dev/null
+++ b/doc/ci/environments/deployment_approvals.md
@@ -0,0 +1,114 @@
+---
+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
+description: Require approvals prior to deploying to a Protected Environment
+---
+
+# Deployment approvals **(PREMIUM)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/343864) in GitLab 14.7 with a flag named `deployment_approvals`. Disabled by default.
+
+WARNING:
+This feature is in an alpha 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.
+
+When a protected environment requires one or more approvals, all deployments to that environment become blocked and wait for the required approvals before running.
+
+NOTE:
+See the [epic](https://gitlab.com/groups/gitlab-org/-/epics/6832) for planned features.
+
+## Requirements
+
+- Basic knowledge of [GitLab Environments and Deployments](index.md).
+- Basic knowledge of [Protected Environments](protected_environments.md).
+
+## Configure deployment approvals for a project
+
+To configure deployment approvals for a project:
+
+1. [Create a deployment job](#create-a-deployment-job).
+1. [Require approvals for a protected environment](#require-approvals-for-a-protected-environment).
+
+### Create a deployment job
+
+Create a deployment job in the `.gitlab-ci.yaml` file of the desired project. The job does **not** need to be manual (`when: manual`).
+
+Example:
+
+ ```yaml
+ stages:
+ - deploy
+
+ production:
+ stage: deploy
+ script:
+ - 'echo "Deploying to ${CI_ENVIRONMENT_NAME}"'
+ environment:
+ name: ${CI_JOB_NAME}
+ ```
+
+### Require approvals for a protected environment
+
+NOTE:
+At this time, only API-based configuration is available. UI-based configuration is planned for the near future. See [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/344675).
+
+Use the [Protected Environments API](../../api/protected_environments.md#protect-repository-environments) to create an environment with `required_approval_count` > 0. After this is set, all jobs deploying to this environment automatically go into a blocked state and wait for approvals before running.
+
+Example:
+
+```shell
+curl --header 'Content-Type: application/json' --request POST \
+ --data '{"name": "production", "deploy_access_levels": [{"group_id": 9899826}], "required_approval_count": 1}' \
+ --header "PRIVATE-TOKEN: <your_access_token>" \
+ "https://gitlab.example.com/api/v4/projects/22034114/protected_environments"
+```
+
+To protect, update, or unprotect an environment, you must have at least the
+[Maintainer role](../../user/permissions.md).
+
+## 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/).
+
+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.
+
+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.
+
+Example:
+
+```shell
+curl --data "status=approved" \
+ --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/deployments/1/approval"
+```
+
+### How to see blocked deployments
+
+#### 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
+
+Use the [Deployments API](../../api/deployments.md) to see deployments. The `status` field indicates if a deployment is blocked.
+
+## Related features
+
+For details about other GitLab features aimed at protecting deployments, see [safe deployments](deployment_safety.md).
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/ci/environments/deployment_safety.md b/doc/ci/environments/deployment_safety.md
index ca7b01edf39..55c3c83338d 100644
--- a/doc/ci/environments/deployment_safety.md
+++ b/doc/ci/environments/deployment_safety.md
@@ -144,6 +144,10 @@ appropriate permissions in the other project.
For more information, see [Custom CI/CD configuration path](../pipelines/settings.md#specify-a-custom-cicd-configuration-file).
+## Require an approval before deploying
+
+Before promoting a deployment to a production environment, cross-verifying it with a dedicated testing group is an effective way to ensure safety. For more information, see [Deployment Approvals](deployment_approvals.md).
+
## Troubleshooting
### Pipelines jobs fail with `The deployment job is older than the previously succeeded deployment job...`
diff --git a/doc/ci/environments/index.md b/doc/ci/environments/index.md
index 561507cab97..794e4320fc6 100644
--- a/doc/ci/environments/index.md
+++ b/doc/ci/environments/index.md
@@ -166,7 +166,7 @@ deploy_prod:
The `when: manual` action:
-- Exposes a play button for the job in the GitLab UI.
+- Exposes a play button for the job in the GitLab UI, with the text **Can be manually deployed to &lt;environment&gt;**.
- Means the `deploy_prod` job is only triggered when the play button is clicked.
You can find the play button in the pipelines, environments, deployments, and jobs views.
@@ -774,10 +774,8 @@ fetch = +refs/environments/*:refs/remotes/origin/environments/*
### Archive Old Deployments
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73628) in GitLab 14.5.
-> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/337507) in GitLab 14.6.
-
-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 flag](../../administration/feature_flags.md) named `deployments_archive`. On GitLab.com, this feature is available.
+> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/345027) in GitLab 14.6.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73628) in GitLab 14.0. [Feature flag `deployments_archive`](https://gitlab.com/gitlab-org/gitlab/-/issues/345027) removed.
When a new deployment happens in your project,
GitLab creates [a special Git-ref to the deployment](#check-out-deployments-locally).
diff --git a/doc/ci/environments/protected_environments.md b/doc/ci/environments/protected_environments.md
index 57fd72863c1..78db2345de4 100644
--- a/doc/ci/environments/protected_environments.md
+++ b/doc/ci/environments/protected_environments.md
@@ -248,6 +248,10 @@ NOTE:
Configuration [with the UI](https://gitlab.com/gitlab-org/gitlab/-/issues/325249)
is scheduled for a later release.
+## Deployment approvals
+
+Protected environments can also be used to require manual approvals before deployments. See [Deployment approvals](deployment_approvals.md) for more information.
+
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
diff --git a/doc/ci/examples/authenticating-with-hashicorp-vault/index.md b/doc/ci/examples/authenticating-with-hashicorp-vault/index.md
index 1141583df3f..aed45951239 100644
--- a/doc/ci/examples/authenticating-with-hashicorp-vault/index.md
+++ b/doc/ci/examples/authenticating-with-hashicorp-vault/index.md
@@ -189,6 +189,28 @@ Combined with [protected branches](../../../user/project/protected_branches.md),
[`bound_claims_type`](https://www.vaultproject.io/api-docs/auth/jwt#bound_claims_type) configures the interpretation of the `bound_claims` values. If set to `glob`, the values are interpreted as globs, with `*` matching any number of characters.
+The claim fields listed in [the table above](#how-it-works) can also be accessed for [Vault's policy path templating](https://learn.hashicorp.com/tutorials/vault/policy-templating?in=vault/policies) purposes by using the accessor name of the JWT auth within Vault. The [mount accessor name](https://learn.hashicorp.com/tutorials/vault/identity#step-1-create-an-entity-with-alias) (`ACCESSOR_NAME` in the example below) can be retrieved by running `vault auth list`.
+
+Policy template example making use of a named metadata field named `project_path`:
+
+```plaintext
+path "secret/data/{{identity.entity.aliases.ACCESSOR_NAME.metadata.project_path}}/staging/*" {
+ capabilities = [ "read" ]
+}
+```
+
+Role example to support the templated policy above, mapping the claim field `project_path` as a metadata field through use of [`claim_mappings`](https://www.vaultproject.io/api-docs/auth/jwt#claim_mappings) configuration:
+
+```plaintext
+{
+ "role_type": "jwt",
+ ...
+ "claim_mappings": {
+ "project_path": "project_path"
+ }
+}
+```
+
For the full list of options, see Vault's [Create Role documentation](https://www.vaultproject.io/api/auth/jwt#create-role).
WARNING:
diff --git a/doc/ci/examples/end_to_end_testing_webdriverio/index.md b/doc/ci/examples/end_to_end_testing_webdriverio/index.md
index a9794afaf10..9881c9657bc 100644
--- a/doc/ci/examples/end_to_end_testing_webdriverio/index.md
+++ b/doc/ci/examples/end_to_end_testing_webdriverio/index.md
@@ -4,8 +4,6 @@ group: Testing
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
author: Vincent Tunru
author_gitlab: Vinnl
-type: tutorial
-date: 2019-02-18
description: 'Confidence checking your entire app every time a new feature is added can quickly become repetitive. Learn how to automate it with GitLab CI/CD.'
---
diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md b/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
index e2e12235eba..be33e62b75c 100644
--- a/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
+++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
@@ -5,8 +5,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
disqus_identifier: 'https://docs.gitlab.com/ee/articles/laravel_with_gitlab_and_envoy/index.html'
author: Mehran Rasulian
author_gitlab: mehranrasulian
-type: tutorial
-date: 2017-08-31
---
<!-- vale off -->
diff --git a/doc/ci/git_submodules.md b/doc/ci/git_submodules.md
index 2a002b8fb9f..cdc75fd2bec 100644
--- a/doc/ci/git_submodules.md
+++ b/doc/ci/git_submodules.md
@@ -64,3 +64,14 @@ If you use the [`CI_JOB_TOKEN`](jobs/ci_job_token.md) to clone a submodule in a
pipeline job, the user executing the job must be assigned to a role that has
[permission](../user/permissions.md#gitlab-cicd-permissions) to trigger a pipeline
in the upstream submodule project.
+
+## Troubleshooting
+
+### Can't find the `.gitmodules` file
+
+The `.gitmodules` file might be hard to find because it is usually a hidden file.
+You can check documentation for your specific OS to learn how to find and display
+hidden files.
+
+If there is no `.gitmodules` file, it's possible the submodule settings are in a
+[gitconfig](https://www.atlassian.com/git/tutorials/setting-up-a-repository/git-config) file.
diff --git a/doc/ci/index.md b/doc/ci/index.md
index 5dcb0bcb242..c557e9e6f57 100644
--- a/doc/ci/index.md
+++ b/doc/ci/index.md
@@ -81,6 +81,7 @@ GitLab CI/CD features, grouped by DevOps stage, include:
| **Configure** | |
| [Auto DevOps](../topics/autodevops/index.md) | Set up your app's entire lifecycle. |
| [ChatOps](chatops/index.md) | Trigger CI jobs from chat, with results sent back to the channel. |
+| [Connect to cloud services](cloud_services/index.md) | Connect to cloud providers using OpenID Connect (OIDC) to retrieve temporary credentials to access services or secrets. |
|-------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------|
| **Verify** | |
| [Browser Performance Testing](../user/project/merge_requests/browser_performance_testing.md) | Quickly determine the browser performance impact of pending code changes. |
diff --git a/doc/ci/interactive_web_terminal/index.md b/doc/ci/interactive_web_terminal/index.md
index 5724c56b096..f49fdd6c39f 100644
--- a/doc/ci/interactive_web_terminal/index.md
+++ b/doc/ci/interactive_web_terminal/index.md
@@ -32,10 +32,18 @@ Two things need to be configured for the interactive web terminal to work:
- If you are using a reverse proxy with your GitLab instance, web terminals need to be
[enabled](../../administration/integration/terminal.md#enabling-and-disabling-terminal-support)
-NOTE:
-Interactive web terminals are not yet supported by
-[`gitlab-runner` Helm chart](https://docs.gitlab.com/charts/charts/gitlab/gitlab-runner/index.html).
-Support is tracked [in this issue](https://gitlab.com/gitlab-org/charts/gitlab-runner/-/issues/79).
+### Partial support for Helm chart
+
+Interactive web terminals are partially supported in `gitlab-runner` Helm chart.
+They are enabled when:
+
+- The number of replica is one
+- You use the `loadBalancer` service
+
+Support for fixing these limitations is tracked in the following issues:
+
+- [Support of more than one replica](https://gitlab.com/gitlab-org/charts/gitlab-runner/-/issues/323)
+- [Support of more service types](https://gitlab.com/gitlab-org/charts/gitlab-runner/-/issues/324)
## Debugging a running job
diff --git a/doc/ci/jobs/ci_job_token.md b/doc/ci/jobs/ci_job_token.md
index 532a0dffbce..1906d9cdb6c 100644
--- a/doc/ci/jobs/ci_job_token.md
+++ b/doc/ci/jobs/ci_job_token.md
@@ -24,7 +24,10 @@ You can use a GitLab CI/CD job token to authenticate with specific API endpoints
- [Terraform plan](../../user/infrastructure/index.md).
The token has the same permissions to access the API as the user that executes the
-job. Therefore, this user must be assigned to [a role that has the required privileges](../../user/permissions.md#gitlab-cicd-permissions).
+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
+[a role that has the required privileges](../../user/permissions.md#gitlab-cicd-permissions).
The token is valid only while the pipeline job runs. After the job finishes, you can't
use the token anymore.
diff --git a/doc/ci/jobs/job_control.md b/doc/ci/jobs/job_control.md
index 596df34b5c2..a2406a68bb2 100644
--- a/doc/ci/jobs/job_control.md
+++ b/doc/ci/jobs/job_control.md
@@ -404,10 +404,7 @@ build:
If you change multiple files, but only one file ends in `.md`,
the `build` job is still skipped. The job does not run for any of the files.
-Read more about how to use `only:changes` and `except:changes`:
-
-- [New branches or tags *without* pipelines for merge requests](#use-onlychanges-without-pipelines-for-merge-requests).
-- [Scheduled pipelines](#use-onlychanges-with-scheduled-pipelines).
+With some configurations that use `changes`, [jobs or pipelines might run unexpectedly](#jobs-or-pipelines-run-unexpectedly-when-using-changes)
#### Use `only:changes` with pipelines for merge requests
@@ -459,22 +456,6 @@ it doesn't matter that an earlier pipeline failed because of a change that has n
When you use this configuration, ensure that the most recent pipeline
properly corrects any failures from previous pipelines.
-#### Use `only:changes` without pipelines for merge requests
-
-Without [pipelines for merge requests](../pipelines/merge_request_pipelines.md), pipelines
-run on branches or tags that don't have an explicit association with a merge request.
-In this case, a previous SHA is used to calculate the diff, which is equivalent to `git diff HEAD~`.
-This can result in some unexpected behavior, including:
-
-- When pushing a new branch or a new tag to GitLab, the policy always evaluates to true.
-- When pushing a new commit, the changed files are calculated by using the previous commit
- as the base SHA.
-
-#### Use `only:changes` with scheduled pipelines
-
-`only:changes` always evaluates as true in [Scheduled pipelines](../pipelines/schedules.md).
-All files are considered to have changed when a scheduled pipeline runs.
-
### Combine multiple keywords with `only` or `except`
If you use multiple keywords with `only` or `except`, the keywords are evaluated
@@ -777,7 +758,7 @@ job1:
- echo
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- - if: $CI_PIPELINE_SOURCE == "scheduled"
+ - if: $CI_PIPELINE_SOURCE == "schedule"
- if: $CI_PIPELINE_SOURCE == "push"
when: never
```
@@ -943,3 +924,23 @@ For example:
- `($VARIABLE1 =~ /^content.*/ || $VARIABLE2) && ($VARIABLE3 =~ /thing$/ || $VARIABLE4)`
- `($VARIABLE1 =~ /^content.*/ || $VARIABLE2 =~ /thing$/) && $VARIABLE3`
- `$CI_COMMIT_BRANCH == "my-branch" || (($VARIABLE1 == "thing" || $VARIABLE2 == "thing") && $VARIABLE3)`
+
+## Troubleshooting
+
+### Jobs or pipelines run unexpectedly when using `changes:`
+
+You might have jobs or pipelines that run unexpectedly when using [`rules: changes`](../yaml/index.md#ruleschanges)
+or [`only: changes`](../yaml/index.md#onlychanges--exceptchanges) without
+[pipelines for merge requests](../pipelines/merge_request_pipelines.md).
+
+Pipelines on branches or tags that don't have an explicit association with a merge request
+use a previous SHA to calculate the diff. This calculation is equivalent to `git diff HEAD~`
+and can cause unexpected behavior, including:
+
+- The `changes` rule always evaluates to true when pushing a new branch or a new tag to GitLab.
+- When pushing a new commit, the changed files are calculated by using the previous commit
+ as the base SHA.
+
+Additionally, rules with `changes` always evaluate as true in [scheduled pipelines](../pipelines/schedules.md).
+All files are considered to have changed when a scheduled pipeline runs, so jobs
+might always be added to scheduled pipelines that use `changes`.
diff --git a/doc/ci/pipeline_editor/index.md b/doc/ci/pipeline_editor/index.md
index 5be016aff40..d72cb14681d 100644
--- a/doc/ci/pipeline_editor/index.md
+++ b/doc/ci/pipeline_editor/index.md
@@ -83,7 +83,41 @@ where:
- Configuration imported with [`include`](../yaml/index.md#include) is copied into the view.
- Jobs that use [`extends`](../yaml/index.md#extends) display with the
[extended configuration merged into the job](../yaml/yaml_optimization.md#merge-details).
-- YAML anchors are [replaced with the linked configuration](../yaml/yaml_optimization.md#anchors).
+- [YAML anchors](../yaml/yaml_optimization.md#anchors) are replaced with the linked configuration.
+- [YAML `!reference` tags](../yaml/yaml_optimization.md#reference-tags) are also replaced
+ with the linked configuration.
+
+Using `!refence` tags can cause nested configuration that display with
+multiple hyphens (`-`) in the expanded view. This behavior is expected, and the extra
+hyphens do not affect the job's execution. For example, this configuration and
+fully expanded version are both valid:
+
+- `.gitlab-ci.yml` file:
+
+ ```yaml
+ .python-req:
+ script:
+ - pip install pyflakes
+
+ lint-python:
+ image: python:latest
+ script:
+ - !reference [.python-req, script]
+ - pyflakes python/
+ ```
+
+- Expanded configuration in **View merged YAML** tab:
+
+ ```yaml
+ ".python-req":
+ script:
+ - pip install pyflakes
+ lint-python:
+ script:
+ - - pip install pyflakes # <- The extra hyphens do not affect the job's execution.
+ - pyflakes python/
+ image: python:latest
+ ```
## Commit changes to CI configuration
@@ -97,3 +131,20 @@ If you enter a new branch name, the **Start a new merge request with these chang
checkbox appears. Select it to start a new merge request after you commit the changes.
![The commit form with a new branch](img/pipeline_editor_commit_v13_8.png)
+
+## Troubleshooting
+
+### `Configuration validation currently not available` message
+
+This message is due to a problem with the syntax validation in the pipeline editor.
+If GitLab is unable to communicate with the service that validates the syntax, the
+information in these sections may not display properly:
+
+- The syntax status on the **Edit** tab (valid or invalid).
+- The **Visualize** tab.
+- The **Lint** tab.
+- The **View merged YAML** tab.
+
+You can still work on your CI/CD configuration and commit the changes you made without
+any issues. As soon as the service becomes available again, the syntax validation
+should display immediately.
diff --git a/doc/ci/pipelines/cicd_minutes.md b/doc/ci/pipelines/cicd_minutes.md
new file mode 100644
index 00000000000..e0fb5b45986
--- /dev/null
+++ b/doc/ci/pipelines/cicd_minutes.md
@@ -0,0 +1,221 @@
+---
+stage: Verify
+group: Pipeline Execution
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+type: reference
+---
+
+# CI/CD minutes quota **(PREMIUM)**
+
+[Shared runners](../runners/runners_scope.md#shared-runners) are shared with every project and group in a GitLab instance.
+When jobs run on shared runners, CI/CD minutes are used.
+
+You can set limits on the number of CI/CD minutes that are used each month.
+
+- On GitLab.com, the quota of CI/CD minutes is set for each [namespace](../../user/group/index.md#namespaces),
+ and is determined by [your license tier](https://about.gitlab.com/pricing/).
+- On self-managed GitLab instances, the quota of CI/CD minutes for each namespace is set by administrators.
+
+In addition to the monthly quota, you can add more CI/CD minutes when needed.
+
+- On GitLab.com, you can [purchase additional CI/CD minutes](#purchase-additional-cicd-minutes).
+- On self-managed GitLab instances, administrators can [assign more CI/CD minutes](#set-the-quota-of-cicd-minutes-for-a-specific-namespace).
+
+[Specific runners](../runners/runners_scope.md#specific-runners)
+are not subject to a quota of CI/CD minutes.
+
+## Set the quota of CI/CD minutes for all namespaces
+
+> [Moved](https://about.gitlab.com/blog/2021/01/26/new-gitlab-product-subscription-model/) to GitLab Premium in 13.9.
+
+By default, GitLab instances do not have a quota of CI/CD minutes.
+The default value for the quota is `0`, which grants unlimited CI/CD minutes.
+However, you can change this default value.
+
+Prerequisite:
+
+- You must be a GitLab administrator.
+
+To change the default quota that applies to all namespaces:
+
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > CI/CD**.
+1. Expand **Continuous Integration and Deployment**.
+1. In the **Quota of CI/CD minutes** box, enter the maximum number of CI/CD minutes.
+1. Select **Save changes**.
+
+If a quota is already defined for a specific namespace, this value does not change that quota.
+
+## Set the quota of CI/CD minutes for a specific namespace
+
+> [Moved](https://about.gitlab.com/blog/2021/01/26/new-gitlab-product-subscription-model/) to GitLab Premium in 13.9.
+
+You can override the global value and set a quota of CI/CD minutes
+for a specific namespace.
+
+Prerequisite:
+
+- You must be a GitLab administrator.
+
+To set a quota of CI/CD minutes for a namespace:
+
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Overview > Groups**.
+1. For the group you want to update, select **Edit**.
+1. In the **Quota of CI/CD minutes** box, enter the maximum number of CI/CD minutes.
+1. Select **Save changes**.
+
+You can also use the [update group API](../../api/groups.md#update-group) or the
+[update user API](../../api/users.md#user-modification) instead.
+
+NOTE:
+You can set a quota of CI/CD minutes for only top-level groups or user namespaces.
+If you set a quota for a subgroup, it is not used.
+
+## View CI/CD minutes used by a group
+
+You can view the number of CI/CD minutes being used by a group.
+
+Prerequisite:
+
+- You must have the Owner role for the group.
+
+To view CI/CD minutes being used for your group:
+
+1. On the top bar, select **Menu > Groups** and find your group. The group must not be a subgroup.
+1. On the left sidebar, select **Settings > Usage Quotas**.
+1. Select the **Pipelines** tab.
+
+![Group CI/CD minutes quota](img/group_cicd_minutes_quota.png)
+
+## View CI/CD minutes used by a personal namespace
+
+You can view the number of CI/CD minutes being used by a personal namespace:
+
+1. On the top bar, in the top right corner, select your avatar.
+1. Select **Edit profile**.
+1. On the left sidebar, select **Usage Quotas**.
+
+## Purchase additional CI/CD minutes **(FREE SAAS)**
+
+If you're using GitLab SaaS, you can purchase additional packs of CI/CD minutes.
+These additional CI/CD minutes:
+
+- Are used only after the monthly quota included in your subscription runs out.
+- Are carried over to the next month, if any remain at the end of the month.
+- Don't expire.
+
+If you use more CI/CD minutes than your monthly quota, when you purchase more,
+those CI/CD minutes are deducted from your quota. For example, with a GitLab SaaS
+Premium license:
+
+- You have `10,000` monthly minutes.
+- You purchase an additional `5,000` minutes.
+- Your total limit is `15,000` minutes.
+
+If you use `13,000` minutes during the month, the next month your additional minutes become
+`2,000`. If you use `9,000` minutes during the month, your additional minutes remain the same.
+
+You can find pricing for additional CI/CD minutes on the
+[GitLab Pricing page](https://about.gitlab.com/pricing/).
+
+### Purchase CI/CD minutes for a group **(FREE SAAS)**
+
+You can purchase additional CI/CD minutes for your group.
+You cannot transfer purchased CI/CD minutes from one group to another,
+so be sure to select the correct group.
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Settings > Usage Quotas**.
+1. Select **Buy additional minutes**.
+1. Complete the details of the transaction.
+
+After your payment is processed, the additional CI/CD minutes are added to your group
+namespace.
+
+### Purchase CI/CD minutes for a personal namespace **(FREE SAAS)**
+
+To purchase additional minutes for your personal namespace:
+
+1. On the top bar, in the top right corner, select your avatar.
+1. Select **Edit profile**.
+1. On the left sidebar, select **Usage Quotas**.
+1. Select **Buy additional minutes**. GitLab redirects you to the Customers Portal.
+1. Locate the subscription card that's linked to your personal namespace on GitLab SaaS, select **Buy more CI minutes**,
+ and complete the details of the transaction.
+
+After your payment is processed, the additional CI/CD minutes are added to your personal
+namespace.
+
+## How CI/CD minutes are calculated
+
+CI/CD minutes are calculated based on:
+
+- The duration the job runs.
+- The visibility of the projects where the job runs.
+
+GitLab uses this formula to calculate CI/CD minutes consumed by a job:
+
+```plaintext
+Job duration * Cost factor
+```
+
+- **Job duration**: The time, in seconds, that a job took to run on a shared runner.
+ It does not include time spent in `created` or `pending` status.
+- **Cost factor**: A number based on project visibility.
+
+The number is transformed into minutes and added to the overall quota in the job's top-level namespace.
+
+For example:
+
+- A user, `alice`, runs a pipeline under the `gitlab-org` namespace.
+- The CI/CD minutes consumed by each job in the pipeline are added to the
+ overall consumption for the `gitlab-org` namespace, not the `alice` namespace.
+- If a pipeline runs for one of the personal projects for `alice`, the CI/CD minutes
+ are added to the overall consumption for the `alice` namespace.
+
+### Cost factor
+
+The cost factor for a job running on a shared runner is:
+
+- `0.008` for public projects on GitLab SaaS, if [created 2021-07-17 or later](https://gitlab.com/gitlab-org/gitlab/-/issues/332708).
+ (For every 125 minutes of job time, you accrue 1 CD/CD minute.)
+- `0.008` for projects members of GitLab [Open Source program](../../subscriptions/index.md#gitlab-for-open-source).
+ (For every 125 minutes of job time, you accrue 1 CD/CD minute.)
+- `0` for public projects on GitLab self-managed instances, and for GitLab SaaS public projects created before 2021-07-17.
+- `1` for internal and private projects.
+
+### Additional costs on GitLab SaaS
+
+On GitLab SaaS, shared runners can have different cost factors depending on the cost involved
+in executing the runner. For example, a high spec shared runner could be set to have a cost factor of `2`.
+Conversely, a shared runner that executes jobs for public projects could have a low cost factor, like `0.008`.
+
+### Monthly reset of CI/CD minutes
+
+On the first day of each calendar month, the accumulated usage of CI/CD minutes is reset to `0`
+for all namespaces that use shared runners.
+
+Usage data for the previous month is kept to show historical view of the consumption over time.
+
+## What happens when you exceed the quota
+
+When the quota of CI/CD minutes is used for the current month, GitLab stops
+processing new jobs.
+
+- Any non-running job that should be picked by shared runners is automatically dropped.
+- Any job being retried is automatically dropped.
+- Any running job can be dropped at any point if the overall namespace usage goes over-quota
+ by a grace period.
+
+The grace period for running jobs is `1,000` CI/CD minutes.
+
+Jobs on specific runners are not affected by the quota of CI/CD minutes.
+
+### GitLab SaaS usage notifications
+
+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.
diff --git a/doc/user/admin_area/settings/img/group_pipelines_quota.png b/doc/ci/pipelines/img/group_cicd_minutes_quota.png
index 318527426bd..318527426bd 100644
--- a/doc/user/admin_area/settings/img/group_pipelines_quota.png
+++ b/doc/ci/pipelines/img/group_cicd_minutes_quota.png
Binary files differ
diff --git a/doc/ci/pipelines/img/pipeline-fork_v13_7.png b/doc/ci/pipelines/img/pipeline_fork_v13_7.png
index eb44290aa66..eb44290aa66 100644
--- a/doc/ci/pipelines/img/pipeline-fork_v13_7.png
+++ b/doc/ci/pipelines/img/pipeline_fork_v13_7.png
Binary files differ
diff --git a/doc/ci/pipelines/index.md b/doc/ci/pipelines/index.md
index 24e518b1f69..b873b2ae30f 100644
--- a/doc/ci/pipelines/index.md
+++ b/doc/ci/pipelines/index.md
@@ -50,10 +50,6 @@ Pipelines can be configured in many different ways:
followed by the next stage.
- [Directed Acyclic Graph Pipeline (DAG) pipelines](../directed_acyclic_graph/index.md) are based on relationships
between jobs and can run more quickly than basic pipelines.
-- [Multi-project pipelines](multi_project_pipelines.md) combine pipelines for different projects together.
-- [Parent-Child pipelines](parent_child_pipelines.md) break down complex pipelines
- into one parent pipeline that can trigger multiple child sub-pipelines, which all
- run in the same project and with the same SHA. This pipeline architecture is commonly used for mono-repos.
- [Pipelines for Merge Requests](../pipelines/merge_request_pipelines.md) run for merge
requests only (rather than for every commit).
- [Pipelines for Merged Results](../pipelines/pipelines_for_merged_results.md)
@@ -61,6 +57,44 @@ Pipelines can be configured in many different ways:
already been merged into the target branch.
- [Merge Trains](../pipelines/merge_trains.md)
use pipelines for merged results to queue merges one after the other.
+- [Parent-Child pipelines](parent_child_pipelines.md) break down complex pipelines
+ into one parent pipeline that can trigger multiple child sub-pipelines, which all
+ run in the same project and with the same SHA. This pipeline architecture is commonly used for mono-repos.
+- [Multi-project pipelines](multi_project_pipelines.md) combine pipelines for different projects together.
+
+### How parent-child pipelines compare to multi-project pipelines
+
+Parent-child pipelines and multi-project pipelines can sometimes be used for similar
+purposes, but there are some key differences:
+
+Parent-child pipelines:
+
+- Run under the same project, ref, and commit SHA as the parent pipeline.
+- Affect the overall status of the ref the pipeline runs against. For example,
+ if a pipeline fails for the main branch, it's common to say that "main is broken".
+ The status of child pipelines don't directly affect the status of the ref, unless the child
+ pipeline is triggered with [`strategy:depend`](../yaml/index.md#triggerstrategy).
+- Are automatically canceled if the pipeline is configured with [`interruptible`](../yaml/index.md#interruptible)
+ when a new pipeline is created for the same ref.
+- Display only the parent pipelines in the pipeline index page. Child pipelines are
+ visible when visiting their parent pipeline's page.
+- Are limited to 2 levels of nesting. A parent pipeline can trigger multiple child pipelines,
+ and those child pipeline can trigger multiple child pipelines (`A -> B -> C`).
+
+Multi-project pipelines:
+
+- Are triggered from another pipeline, but the upstream (triggering) pipeline does
+ not have much control over the downstream (triggered) pipeline. However, it can
+ choose the ref of the downstream pipeline, and pass CI/CD variables to it.
+- Affect the overall status of the ref of the project it runs in, but does not
+ affect the status of the triggering pipeline's ref, unless it was triggered with
+ [`strategy:depend`](../yaml/index.md#triggerstrategy).
+- Are not automatically canceled in the downstream project when using [`interruptible`](../yaml/index.md#interruptible)
+ if a new pipeline runs for the same ref in the upstream pipeline. They can be
+ automatically canceled if a new pipeline is triggered for the same ref on the downstream project.
+- Multi-project pipelines are standalone pipelines because they are normal pipelines
+ that happened to be triggered by an external project. They are all visible on the pipeline index page.
+- Are independent, so there are no nesting limits.
## Configure a pipeline
@@ -257,14 +291,33 @@ WARNING:
Deleting a pipeline expires all pipeline caches, and deletes all related objects,
such as builds, logs, artifacts, and triggers. **This action cannot be undone.**
-### Pipeline quotas
+### Pipeline security on protected branches
+
+A strict security model is enforced when pipelines are executed on
+[protected branches](../../user/project/protected_branches.md).
+
+The following actions are allowed on protected branches only if the user is
+[allowed to merge or push](../../user/project/protected_branches.md)
+on that specific branch:
+
+- Run manual pipelines (using the [Web UI](#run-a-pipeline-manually) or [pipelines API](#pipelines-api)).
+- Run scheduled pipelines.
+- Run pipelines using triggers.
+- Run on-demand DAST scan.
+- Trigger manual actions on existing pipelines.
+- Retry or cancel existing jobs (using the Web UI or pipelines API).
-Each user has a personal pipeline quota that tracks the usage of shared runners in all personal projects.
-Each group has a [usage quota](../../subscriptions/gitlab_com/index.md#ci-pipeline-minutes) that tracks the usage of shared runners for all projects created within the group.
+**Variables** marked as **protected** are accessible only to jobs that
+run on protected branches, preventing untrusted users getting unintended access to
+sensitive information like deployment credentials and tokens.
-When a pipeline is triggered, regardless of who triggered it, the pipeline quota for the project owner's [namespace](../../user/group/index.md#namespaces) is used. In this case, the namespace can be the user or group that owns the project.
+**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
+runners do not use regular runners, they must be tagged accordingly.
-#### How pipeline duration is calculated
+### How pipeline duration is calculated
Total running time for a given pipeline excludes retries and pending
(queued) time.
@@ -301,44 +354,6 @@ The union of A, B, and C is (1, 4) and (6, 7). Therefore, the total running time
(4 - 1) + (7 - 6) => 4
```
-#### How pipeline quota usage is calculated
-
-Pipeline quota usage is calculated as the sum of the duration of each individual job. This is slightly different to how pipeline _duration_ is [calculated](#how-pipeline-duration-is-calculated). Pipeline quota usage doesn't consider any overlap of jobs running in parallel.
-
-For example, a pipeline consists of the following jobs:
-
-- Job A takes 3 minutes.
-- Job B takes 3 minutes.
-- Job C takes 2 minutes.
-
-The pipeline quota usage is the sum of each job's duration. In this example, 8 runner minutes would be used, calculated as: 3 + 3 + 2.
-
-### Pipeline security on protected branches
-
-A strict security model is enforced when pipelines are executed on
-[protected branches](../../user/project/protected_branches.md).
-
-The following actions are allowed on protected branches only if the user is
-[allowed to merge or push](../../user/project/protected_branches.md)
-on that specific branch:
-
-- Run manual pipelines (using the [Web UI](#run-a-pipeline-manually) or [pipelines API](#pipelines-api)).
-- Run scheduled pipelines.
-- Run pipelines using triggers.
-- Run on-demand DAST scan.
-- Trigger manual actions on existing pipelines.
-- Retry or cancel existing jobs (using the Web UI or pipelines API).
-
-**Variables** marked as **protected** are accessible only to jobs that
-run on protected branches, preventing untrusted users getting unintended access to
-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
-runners do not use regular runners, they must be tagged accordingly.
-
## Visualize pipelines
Pipelines can be complex structures with many sequential and parallel jobs.
diff --git a/doc/ci/pipelines/job_artifacts.md b/doc/ci/pipelines/job_artifacts.md
index e47b6dddc5f..1710c57b36b 100644
--- a/doc/ci/pipelines/job_artifacts.md
+++ b/doc/ci/pipelines/job_artifacts.md
@@ -405,3 +405,27 @@ generated. Check the job log for these messages.
If you find no helpful messages, retry the failed job after activating
[CI/CD debug logging](../variables/index.md#debug-logging).
This logging should provide information to help you investigate further.
+
+### Error message `Missing /usr/bin/gitlab-runner-helper. Uploading artifacts is disabled.`
+
+There is a [known issue](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/3068) where setting a CI/CD variable named `DEBUG` can cause artifact uploads to fail.
+
+To work around this, either use a different variable name or set it inline with `script`:
+
+```yaml
+# This job might fail due to issue gitlab-org/gitlab-runner#3068
+failing_test_job:
+ variables:
+ DEBUG: true
+ script: bin/mycommand
+ artifacts:
+ paths:
+ - bin/results
+
+# This job does not define a CI/CD variable named `DEBUG` and is not affected by the issue
+successful_test_job:
+ script: DEBUG=true bin/mycommand
+ artifacts:
+ paths:
+ - bin/results
+```
diff --git a/doc/ci/pipelines/merge_request_pipelines.md b/doc/ci/pipelines/merge_request_pipelines.md
index 85e5b62b0c4..4d7ebc09e6f 100644
--- a/doc/ci/pipelines/merge_request_pipelines.md
+++ b/doc/ci/pipelines/merge_request_pipelines.md
@@ -2,214 +2,197 @@
stage: Verify
group: Pipeline Execution
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: reference, index
-last_update: 2019-07-03
---
-# Pipelines for merge requests **(FREE)**
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/15310) in GitLab 11.6.
-In a [basic configuration](pipeline_architectures.md#basic-pipelines), GitLab runs a pipeline each time
-changes are pushed to a branch.
+# Pipelines for merge requests **(FREE)**
-If you want the pipeline to run jobs **only** on commits associated with a merge request,
-you can use *pipelines for merge requests*.
+You can configure your [pipeline](index.md) to run every time you commit changes to a branch.
+This type of pipeline is called a *branch pipeline*.
-These pipelines are labeled as `detached` in the UI, and they do not have access to [protected variables](../variables/index.md#protect-a-cicd-variable).
-Otherwise, these pipelines are the same as other pipelines.
+Alternatively, you can configure your pipeline to run every time you make changes to the
+source branch for a merge request. This type of pipeline is called a *pipeline for merge requests*.
-Pipelines for merge requests can run when you:
+Branch pipelines:
-- Create a new merge request.
-- Commit changes to the source branch for the merge request.
-- Select the **Run pipeline** button from the **Pipelines** tab in the merge request.
+- Run when you push a new commit to a branch.
+- Are the default type of pipeline.
+- Have access to [some predefined variables](../variables/predefined_variables.md).
+- Have access to [protected variables](../variables/index.md#protect-a-cicd-variable).
-If you use this feature with [merge when pipeline succeeds](../../user/project/merge_requests/merge_when_pipeline_succeeds.md),
-pipelines for merge requests take precedence over other pipelines.
+Pipelines for merge requests:
-## Prerequisites
+- Run when you:
+ - Create a new merge request.
+ - Push a new commit to the source branch for a merge request.
+ - Select **Run pipeline** from the **Pipelines** tab in a merge request. This option
+ is only available when pipelines for merge requests are configured for the pipeline.
+- Do not run by default. The jobs in the CI/CD configuration file [must be configured](#prerequisites)
+ to run in pipelines for merge request.
+- Have access to [more predefined variables](#available-predefined-variables).
+- Do not have access to [protected variables](../variables/index.md#protect-a-cicd-variable).
-To enable pipelines for merge requests:
+Both of these types of pipelines can appear on the **Pipelines** tab of a merge request.
-- Your repository must be a GitLab repository, not an
- [external repository](../ci_cd_for_external_repos/index.md).
-- You must have the Developer [role](../../user/permissions.md)
- to run a pipeline for merge requests.
+## Types of pipelines for merge requests
-## Configure pipelines for merge requests
+The three types of pipelines for merge requests are:
-To configure pipelines for merge requests, you must configure your [CI/CD configuration file](../yaml/index.md).
-To do this, you can use [`rules`](#use-rules-to-run-pipelines-for-merge-requests) or [`only/except`](#use-only-or-except-to-run-pipelines-for-merge-requests).
+- Pipelines for merge requests, which run on the changes in the merge request's
+ source branch. These pipelines display a `detached` label to indicate that the
+ pipeline ran only on the contents of the source branch, ignoring the target branch.
+- [Pipelines for merged results](pipelines_for_merged_results.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
+ at the same time. The changes from each merge request are combined into the
+ target branch with the changes in the earlier enqueued merge requests, to ensure
+ they all work together.
-### Use `rules` to run pipelines for merge requests
+## Prerequisites
-GitLab recommends that you use the `rules` keyword, which is available in
-[`workflow:rules` templates](../yaml/workflow.md#workflowrules-templates).
+To use pipelines for merge requests:
-### Use `only` or `except` to run pipelines for merge requests
+- Your project's [CI/CD configuration file](../yaml/index.md) must be configured with
+ jobs that run in pipelines for merge requests. To do this, you can use:
+ - [`rules`](#use-rules-to-add-jobs).
+ - [`only/except`](#use-only-to-add-jobs).
+- You must have at least the Developer [role](../../user/permissions.md) in the
+ source project to run a pipeline for merge requests.
+- Your repository must be a GitLab repository, not an [external repository](../ci_cd_for_external_repos/index.md).
-You can use the `only/except` keywords. However, with this method, you must specify `only: - merge_requests` for each job.
+## Use `rules` to add jobs
-In the following example, the pipeline contains a `test` job that is configured to run on merge requests.
-The `build` and `deploy` jobs don't have the `only: - merge_requests` keyword,
-so they don't run on merge requests.
+You can use the [`rules`](../yaml/index.md#rules) keyword to configure jobs to run in
+pipelines for merge requests. For example:
```yaml
-build:
- stage: build
- script: ./build
- only:
- - main
-
-test:
- stage: test
- script: ./test
- only:
- - merge_requests
-
-deploy:
- stage: deploy
- script: ./deploy
- only:
- - main
+job1:
+ script:
+ - echo "This job runs in pipelines for merge requests"
+ rules:
+ - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
```
-#### Exclude specific jobs
-
-When you use `only: [merge_requests]`, only jobs with
-that keyword are run in the context of a merge request. No other jobs run.
-
-However, you can invert this behavior and have all of your jobs run except
-for one or two. For example, you might have a pipeline with jobs `A`, `B`, and `C`, and you want:
-
-- All pipelines to always run `A` and `B`.
-- `C` to run only for merge requests.
-
-To achieve this outcome, configure your `.gitlab-ci.yml` file as follows:
+You can also use the [`workflow: rules`](../yaml/index.md#workflowrules) keyword
+to configure the entire pipeline to run in pipelines for merge requests. For example:
```yaml
-.only-default: &only-default
- only:
- - main
- - merge_requests
- - tags
+workflow:
+ rules:
+ - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
-A:
- <<: *only-default
+job1:
script:
- - ...
+ - echo "This job runs in pipelines for merge requests"
-B:
- <<: *only-default
+job2:
script:
- - ...
-
-C:
- script:
- - ...
- only:
- - merge_requests
+ - echo "This job also runs in pipelines for merge requests"
```
-- `A` and `B` always run, because they get the `only` rule to execute in all cases.
-- `C` only runs for merge requests. It doesn't run for any pipeline
- except a merge request pipeline.
-
-In this example, you don't have to add the `only` rule to all of your jobs to make
-them always run. You can use this format to set up a Review App, which helps to
-save resources.
+## Use `only` to add jobs
-#### Exclude specific branches
-
-Branch refs use this format: `refs/heads/my-feature-branch`.
-Merge request refs use this format: `refs/merge-requests/:iid/head`.
-
-Because of this difference, the following configuration does not work as expected:
-
-```yaml
-# Does not exclude a branch named "docs-my-fix"!
-test:
- only: [merge_requests]
- except: [/^docs-/]
-```
-
-Instead, use the
-[`$CI_COMMIT_REF_NAME` predefined environment
-variable](../variables/predefined_variables.md) in
-combination with
-[`only:variables`](../yaml/index.md#onlyvariables--exceptvariables) to
-accomplish this behavior:
+You can use the [`only`](../yaml/index.md#onlyrefs--exceptrefs) keyword with `merge_requests`
+to configure jobs to run in pipelines for merge requests.
```yaml
-test:
- only: [merge_requests]
- except:
- variables:
- - $CI_COMMIT_REF_NAME =~ /^docs-/
+job1:
+ script:
+ - echo "This job runs in pipelines for merge requests"
+ only:
+ - merge_requests
```
-## Run pipelines in the parent project for merge requests from a forked project **(PREMIUM)**
+## Use with forked projects
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217451) in GitLab 13.3.
> - [Moved](https://about.gitlab.com/blog/2021/01/26/new-gitlab-product-subscription-model/) to GitLab Premium in 13.9.
-By default, external contributors who work in forks can't create pipelines in the
-parent project. When a merge request that comes from a fork triggers a pipeline:
+External contributors who work in forks can't create pipelines in the parent project.
-- The pipeline is created and runs in the fork (source) project, not the parent (target) project.
-- The pipeline uses the fork project's CI/CD configuration and resources.
+A merge request from a fork that is submitted to the parent project triggers a
+pipeline that:
-If a pipeline runs in a fork, a **fork** badge appears for the pipeline in the merge request.
+- Is created and runs in the fork (source) project, not the parent (target) project.
+- Uses the fork project's CI/CD configuration, resources, and project CI/CD variables.
-![Pipeline ran in fork](img/pipeline-fork_v13_7.png)
+Pipelines for forks display with the **fork** badge in the parent project:
-Sometimes parent project members want the pipeline to run in the parent
-project. They may want to ensure that the post-merge pipeline passes in the parent project.
-For example, a fork project could try to use a corrupted runner that doesn't execute
-test scripts properly, but reports a passed pipeline. Reviewers in the parent project
-could mistakenly trust the merge request because it passed a faked pipeline.
+![Pipeline ran in fork](img/pipeline_fork_v13_7.png)
-Parent project members with at least the [Developer role](../../user/permissions.md)
-can create pipelines in the parent project for merge requests
-from a forked project. In the merge request, go to the **Pipelines** tab and select
-**Run pipeline**.
+### Run pipelines in the parent project **(PREMIUM)**
+
+Project members in the parent project can choose to run a pipeline for merge requests
+for a merge request submitted from a fork project. This pipeline:
+
+- Is created and runs in the parent (target) project, not the fork (source) project.
+- Uses the CI/CD configuration present in the fork project's branch
+- Uses the parent project's CI/CD configuration, resources, and project CI/CD variables.
+- Uses the permissions of the parent project member that triggers the pipeline.
+
+Run pipelines in fork project MRs to ensure that the post-merge pipeline passes in
+the parent project. Additionally, if you do not trust the fork project's runner,
+running the pipeline in the parent project uses the parent project's trusted runners.
WARNING:
Fork merge requests can contain malicious code that tries to steal secrets in the
-parent project when the pipeline runs, even before merge. As a reviewer, you must carefully
+parent project when the pipeline runs, even before merge. As a reviewer, carefully
check the changes in the merge request before triggering the pipeline. GitLab shows
a warning that you must accept before you can trigger the pipeline.
-## Predefined variables available for pipelines for merge requests
+Parent project members with at least the [Developer role](../../user/permissions.md)
+can create pipelines in the parent project for merge requests from a forked project:
-When you use pipelines for merge requests, [additional predefined variables](../variables/predefined_variables.md#predefined-variables-for-merge-request-pipelines) are available to the CI/CD jobs.
-These variables contain information from the associated merge request, so that you can
-integrate your job with the [GitLab Merge Request API](../../api/merge_requests.md).
+1. In the merge request, go to the **Pipelines** tab.
+1. Select **Run pipeline**. You must accept the warning, or the pipeline does not run.
-## Troubleshooting
+## Available predefined variables
-### Two pipelines created when pushing to a merge request
+When you use pipelines for merge requests, you can use:
+
+- All the same [predefined variables](../variables/predefined_variables.md) that are
+ available in branch pipelines.
+- [Additional predefined variables](../variables/predefined_variables.md#predefined-variables-for-merge-request-pipelines)
+ available only to jobs in pipelines for merge requests. These variables contain
+ information from the associated merge request, which can be when calling the
+ [GitLab Merge Request API endpoint](../../api/merge_requests.md) from a job.
+
+## Troubleshooting
-If you are experiencing duplicated pipelines when using `rules`, take a look at
-the [important differences between `rules` and `only`/`except`](../jobs/job_control.md#avoid-duplicate-pipelines),
-which helps you get your starting configuration correct.
+### Two pipelines when pushing to a branch
-If you are seeing two pipelines when using `only/except`, please see the caveats
-related to using `only/except` above (or, consider moving to `rules`).
+If you get duplicate pipelines in merge requests, your pipeline might be configured
+to run for both branches and merge requests at the same time. Adjust your pipeline
+configuration to [avoid duplicate pipelines](../jobs/job_control.md#avoid-duplicate-pipelines).
In [GitLab 13.7 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/201845),
-you can add `workflow:rules` to [switch from branch pipelines to merge request pipelines](../yaml/workflow.md#switch-between-branch-pipelines-and-merge-request-pipelines).
+you can add `workflow:rules` to [switch from branch pipelines to pipelines for merge requests](../yaml/workflow.md#switch-between-branch-pipelines-and-merge-request-pipelines).
After a merge request is open on the branch, the pipeline switches to a merge request pipeline.
-### Two pipelines created when pushing an invalid CI configuration file
+### Two pipelines when pushing an invalid CI/CD configuration file
+
+If you push an invalid CI/CD configuration to a merge request's branch, two failed
+pipelines appear in the pipelines tab. One pipeline is a failed branch pipeline,
+the other is a failed pipeline for merge requests.
+
+When the configuration syntax is fixed, no further failed pipelines should appear.
+To find and fix the configuration problem, you can use:
+
+- The [pipeline editor](../pipeline_editor/index.md).
+- The [CI lint tool](../lint.md).
+
+### The merge request's pipeline is marked as failed but the latest pipeline succeeded
+
+It's possible to have both branch pipelines and pipelines for merge requests in the
+**Pipelines** tab of a single merge request. This might be [by configuration](../yaml/workflow.md#switch-between-branch-pipelines-and-merge-request-pipelines),
+or [by accident](#two-pipelines-when-pushing-to-a-branch).
-Pushing to a branch with an invalid CI configuration file can trigger
-the creation of two types of failed pipelines. One pipeline is a failed merge request
-pipeline, and the other is a failed branch pipeline, but both are caused by the same
-invalid configuration.
+If both types of pipelines are in one merge request, the merge request's pipeline
+is not considered successful if:
-## Related topics
+- The branch pipeline succeeds.
+- The pipeline for merge request fails.
-- [Pipelines for merged results](pipelines_for_merged_results.md).
-- [Merge trains](merge_trains.md).
+When using the [merge when pipeline succeeds](../../user/project/merge_requests/merge_when_pipeline_succeeds.md)
+feature and both pipelines types are present, the pipelines for merge requests are checked,
+not the branch pipelines.
diff --git a/doc/ci/pipelines/merge_trains.md b/doc/ci/pipelines/merge_trains.md
index 593cdb68b3f..d47cbf5f47c 100644
--- a/doc/ci/pipelines/merge_trains.md
+++ b/doc/ci/pipelines/merge_trains.md
@@ -2,8 +2,6 @@
stage: Verify
group: Pipeline Execution
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: reference
-last_update: 2019-07-03
---
# Merge trains **(PREMIUM)**
@@ -11,10 +9,6 @@ last_update: 2019-07-03
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9186) in GitLab 12.0.
> - [Squash and merge](../../user/project/merge_requests/squash_and_merge.md) support [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13001) in GitLab 12.6.
-INFO:
-Get merge trains and more in GitLab Ultimate.
-[Try a free 30-day trial now](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=p-ci-cd-external-docs).
-
For more information about why you might want to use merge trains, read [How merge trains keep your master green](https://about.gitlab.com/blog/2020/01/30/all-aboard-merge-trains/).
When [pipelines for merged results](pipelines_for_merged_results.md) are
@@ -84,7 +78,7 @@ To enable merge trains:
To enable merge trains for your project:
1. If you are on a self-managed GitLab instance, ensure the [feature flag](#merge-trains-feature-flag) is set correctly.
-1. [Configure your CI/CD configuration file](merge_request_pipelines.md#configure-pipelines-for-merge-requests)
+1. [Configure your CI/CD configuration file](merge_request_pipelines.md#prerequisites)
so that the pipeline or individual jobs run for merge requests.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > General**.
diff --git a/doc/ci/pipelines/pipelines_for_merged_results.md b/doc/ci/pipelines/pipelines_for_merged_results.md
index 718519faf48..91a49a48882 100644
--- a/doc/ci/pipelines/pipelines_for_merged_results.md
+++ b/doc/ci/pipelines/pipelines_for_merged_results.md
@@ -2,18 +2,12 @@
stage: Verify
group: Pipeline Execution
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: reference
-last_update: 2019-07-03
---
# Pipelines for merged results **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7380) in GitLab 11.10.
-INFO:
-Get these pipelines and more in GitLab Ultimate.
-[Try a free 30-day trial now](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=p-ci-cd-external-docs).
-
When you submit a merge request, you are requesting to merge changes from a
source branch into a target branch. By default, the CI pipeline runs jobs
against the source branch.
@@ -61,7 +55,7 @@ To enable pipelines for merge results:
To enable pipelines for merged results for your project:
-1. [Configure your CI/CD configuration file](merge_request_pipelines.md#configure-pipelines-for-merge-requests)
+1. [Configure your CI/CD configuration file](merge_request_pipelines.md#prerequisites)
so that the pipeline or individual jobs run for merge requests.
1. Visit your project's **Settings > General** and expand **Merge requests**.
1. Check **Enable merged results pipelines**.
diff --git a/doc/ci/pipelines/settings.md b/doc/ci/pipelines/settings.md
index cf470836e32..85824dfb7c7 100644
--- a/doc/ci/pipelines/settings.md
+++ b/doc/ci/pipelines/settings.md
@@ -21,11 +21,7 @@ For public and internal projects, you can change who can see your:
- Pipelines
- Job output logs
- Job artifacts
-- [Pipeline security dashboard](../../user/application_security/security_dashboard/index.md#pipeline-security)
-
-However:
-
-- Job output logs and artifacts are [never visible for Guest users and non-project members](https://gitlab.com/gitlab-org/gitlab/-/issues/25649).
+- [Pipeline security dashboard](../../user/application_security/security_dashboard/index.md#view-vulnerabilities-in-a-pipeline)
To change the visibility of your pipelines and related features:
@@ -41,8 +37,10 @@ To change the visibility of your pipelines and related features:
When it is cleared:
- - For **public** projects, pipelines are visible to everyone. Related features are visible
- only to project members (Reporter or higher).
+ - For **public** projects, job logs, job artifacts, the pipeline security dashboard,
+ and the **CI/CD** menu items are visible only to project members (Reporter or higher).
+ Other users, including guest users, can only view the status of pipelines and jobs, and only
+ when viewing merge requests or commits.
- For **internal** projects, pipelines are visible to all logged in users except [external users](../../user/permissions.md#external-users).
Related features are visible only to project members (Reporter or higher).
- For **private** projects, pipelines and related features are visible to project members (Reporter or higher) only.
@@ -161,7 +159,8 @@ in the `.gitlab-ci.yml` file.
## Limit the number of changes fetched during clone
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/28919) in GitLab 12.0.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/28919) in GitLab 12.0.
+> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77576) `git depth` value in GitLab 14.7.
You can limit the number of changes that GitLab CI/CD fetches when it clones
a repository.
@@ -173,8 +172,8 @@ a repository.
The maximum value is `1000`. To disable shallow clone and make GitLab CI/CD
fetch all branches and tags each time, keep the value empty or set to `0`.
-In GitLab 12.0 and later, newly created projects automatically have a default
-`git depth` value of `50`.
+In GitLab versions 14.7 and later, newly created projects have a default `git depth`
+value of `20`. GitLab versions 14.6 and earlier have a default `git depth` value of `50`.
This value can be overridden by the [`GIT_DEPTH` variable](../large_repositories/index.md#shallow-cloning)
in the `.gitlab-ci.yml` file.
diff --git a/doc/ci/review_apps/index.md b/doc/ci/review_apps/index.md
index c67282643a4..37005939eb7 100644
--- a/doc/ci/review_apps/index.md
+++ b/doc/ci/review_apps/index.md
@@ -181,7 +181,7 @@ After you have the route mapping set up, it takes effect in the following locati
![View app file list in merge request widget](img/view_on_mr_widget.png)
-- In the diff for a merge request, comparison, or commit.
+- In the diff for a comparison or commit.
![View on environment button in merge request diff](img/view_on_env_mr.png)
diff --git a/doc/ci/runners/configure_runners.md b/doc/ci/runners/configure_runners.md
index b2885262e9d..d826b28acce 100644
--- a/doc/ci/runners/configure_runners.md
+++ b/doc/ci/runners/configure_runners.md
@@ -2,7 +2,6 @@
stage: Verify
group: Runner
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: reference
---
# Configuring runners **(FREE)**
@@ -640,7 +639,7 @@ support this feature.
A meter can be enabled to provide the rate of transfer for uploads and downloads.
-You can set a maximum time for cache upload and download with the `CACHE_REQUEST_TIMEOUT` setting.
+You can set a maximum time for cache upload and download with the `CACHE_REQUEST_TIMEOUT` setting.
This setting can be useful when slow cache uploads substantially increase the duration of your job.
```yaml
diff --git a/doc/ci/runners/index.md b/doc/ci/runners/index.md
index b4e9fe818cf..064ad64b79f 100644
--- a/doc/ci/runners/index.md
+++ b/doc/ci/runners/index.md
@@ -17,6 +17,6 @@ No configuration is required. Your jobs can run on:
- [Windows runners](build_cloud/windows_build_cloud.md) (beta).
- [macOS runners](build_cloud/macos_build_cloud.md) (beta).
-The number of minutes you can use on these runners depends on your
-[quota](../../user/admin_area/settings/continuous_integration.md#shared-runners-pipeline-minutes-quota),
-which depends on your [subscription plan](../../subscriptions/gitlab_com/index.md#ci-pipeline-minutes).
+The number of minutes you can use on these runners depends on the
+[maximum number of CI/CD minutes](../pipelines/cicd_minutes.md)
+in your [subscription plan](https://about.gitlab.com/pricing/).
diff --git a/doc/ci/runners/runners_scope.md b/doc/ci/runners/runners_scope.md
index b16957ae83c..f76a767abec 100644
--- a/doc/ci/runners/runners_scope.md
+++ b/doc/ci/runners/runners_scope.md
@@ -28,13 +28,13 @@ If you are using a self-managed instance of GitLab:
going to your project's **Settings > CI/CD**, expanding the **Runners** section,
and clicking **Show runner installation instructions**.
These instructions are also available [in the documentation](https://docs.gitlab.com/runner/install/index.html).
-- The administrator can also configure a maximum number of shared runner [pipeline minutes for
- each group](../../user/admin_area/settings/continuous_integration.md#shared-runners-pipeline-minutes-quota).
+- The administrator can also configure a maximum number of shared runner [CI/CD minutes for
+ each group](../pipelines/cicd_minutes.md#set-the-quota-of-cicd-minutes-for-a-specific-namespace).
If you are using GitLab.com:
- You can select from a list of [shared runners that GitLab maintains](index.md).
-- The shared runners consume the [pipelines minutes](../../subscriptions/gitlab_com/index.md#ci-pipeline-minutes)
+- The shared runners consume the [CI/CD minutes](../pipelines/cicd_minutes.md)
included with your account.
### Enable shared runners
diff --git a/doc/ci/runners/saas/windows_saas_runner.md b/doc/ci/runners/saas/windows_saas_runner.md
index 87ee542fb14..b08be14dbc3 100644
--- a/doc/ci/runners/saas/windows_saas_runner.md
+++ b/doc/ci/runners/saas/windows_saas_runner.md
@@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
SaaS runners on Windows are in [beta](https://about.gitlab.com/handbook/product/gitlab-the-product/#beta)
and shouldn't be used for production workloads.
-During this beta period, the [shared runner pipeline quota](../../../user/admin_area/settings/continuous_integration.md#shared-runners-pipeline-minutes-quota)
+During this beta period, the [shared runner quota for CI/CD minutes](../../pipelines/cicd_minutes.md)
applies for groups and projects in the same manner as Linux runners. This may
change when the beta period ends, as discussed in this [related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/30834).
diff --git a/doc/ci/test_cases/index.md b/doc/ci/test_cases/index.md
index 4c840125d24..384bfc10779 100644
--- a/doc/ci/test_cases/index.md
+++ b/doc/ci/test_cases/index.md
@@ -11,10 +11,6 @@ type: reference
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233479) in GitLab 13.6.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/241983) in GitLab 13.7.
-INFO:
-Create test cases in GitLab Ultimate.
-[Try it free for 30 days](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=u-test-cases-docs).
-
Test cases in GitLab can help your teams create testing scenarios in their existing development platform.
Now your Implementation and Testing teams can collaborate better, as they no longer have to
diff --git a/doc/ci/triggers/index.md b/doc/ci/triggers/index.md
index d3ac1de7c3b..1b648a486ef 100644
--- a/doc/ci/triggers/index.md
+++ b/doc/ci/triggers/index.md
@@ -54,7 +54,7 @@ For example:
```shell
curl --request POST \
--form token=<token> \
- --formref=<ref_name> \
+ --form ref=<ref_name> \
"https://gitlab.example.com/api/v4/projects/<project_id>/trigger/pipeline"
```
@@ -104,20 +104,18 @@ To trigger a pipeline from another project's webhook, use a webhook URL like the
for push and tag events:
```plaintext
-https://gitlab.example.com/api/v4/projects/9/ref/main/trigger/pipeline?token=TOKEN
+https://gitlab.example.com/api/v4/projects/<project_id>/ref/<ref_name>/trigger/pipeline?token=<token>
```
Replace:
- The URL with `https://gitlab.com` or the URL of your instance.
-- `<token>` with your trigger token.
-- `<ref_name>` with a branch or tag name, like `main`.
- `<project_id>` with your project ID, like `123456`. The project ID is displayed
at the top of the project's landing page.
-
-The `ref` in the URL takes precedence over the `ref` in the webhook payload. The
-payload `ref` is the branch that fired the trigger in the source repository.
-You must URL-encode `ref` if it contains slashes.
+- `<ref_name>` with a branch or tag name, like `main`. This value takes precedence over the `ref_name` in the webhook payload.
+ The payload's `ref` is the branch that fired the trigger in the source repository.
+ You must URL-encode the `ref_name` if it contains slashes.
+- `<token>` with your trigger token.
#### Use a webhook payload
diff --git a/doc/ci/variables/index.md b/doc/ci/variables/index.md
index acc3489143a..7ce58b015ca 100644
--- a/doc/ci/variables/index.md
+++ b/doc/ci/variables/index.md
@@ -81,7 +81,7 @@ to execute scripts. Each shell has its own set of reserved variable names.
Make sure each variable is defined for the [scope you want to use it in](where_variables_can_be_used.md).
By default, pipelines from forked projects can't access CI/CD variables in the parent project.
-If you [run a merge request pipeline in the parent project for a merge request from a fork](../pipelines/merge_request_pipelines.md#run-pipelines-in-the-parent-project-for-merge-requests-from-a-forked-project),
+If you [run a merge request pipeline in the parent project for a merge request from a fork](../pipelines/merge_request_pipelines.md#run-pipelines-in-the-parent-project),
all variables become available to the pipeline.
### Create a custom CI/CD variable in the `.gitlab-ci.yml` file
@@ -394,7 +394,7 @@ runs on a [protected branch](../../user/project/protected_branches.md) or
Review all merge requests that introduce changes to the `.gitlab-ci.yml` file before you:
-- [Run a pipeline in the parent project for a merge request submitted from a forked project](../pipelines/merge_request_pipelines.md#run-pipelines-in-the-parent-project-for-merge-requests-from-a-forked-project).
+- [Run a pipeline in the parent project for a merge request submitted from a forked project](../pipelines/merge_request_pipelines.md#run-pipelines-in-the-parent-project).
- Merge the changes.
The following example shows malicious code in a `.gitlab-ci.yml` file:
@@ -554,37 +554,45 @@ export GITLAB_USER_ID="42"
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22638) in GitLab 13.0.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/217834) in GitLab 13.1.
-You can pass environment variables from one job to another job in a later stage.
+You can pass environment variables from one job to another job in a later stage
+through variable inheritance.
These variables cannot be used as CI/CD variables to configure a pipeline, but
they can be used in job scripts.
1. In the job script, save the variable as a `.env` file.
+ - The format of the file must be one variable definition per line.
+ - Each defined line must be of the form `VARIABLE_NAME=ANY VALUE HERE`.
+ - Values can be wrapped in quotes, but cannot contain newline characters.
1. Save the `.env` file as an [`artifacts:reports:dotenv`](../yaml/artifacts_reports.md#artifactsreportsdotenv)
artifact.
-1. Set a job in a later stage to receive the artifact by using the [`dependencies`](../yaml/index.md#dependencies)
- or the [`needs`](../yaml/index.md#needs) keywords.
-1. The later job can then [use the variable in scripts](#use-cicd-variables-in-job-scripts).
+1. Jobs in later stages can then [use the variable in scripts](#use-cicd-variables-in-job-scripts).
-For example, with the [`dependencies`](../yaml/index.md#dependencies) keyword:
+Inherited variables [take precedence](#cicd-variable-precedence) over
+certain types of new variable definitions such as job defined variables.
```yaml
build:
stage: build
script:
- - echo "BUILD_VERSION=hello" >> build.env
+ - echo "BUILD_VARIABLE=value_from_build_job" >> build.env
artifacts:
reports:
dotenv: build.env
deploy:
stage: deploy
+ variables:
+ BUILD_VARIABLE: value_from_deploy_job
script:
- - echo "$BUILD_VERSION" # Output is: 'hello'
- dependencies:
- - build
+ - echo "$BUILD_VARIABLE" # Output is: 'value_from_build_job' due to precedence
```
-For example, with the [`needs:artifacts`](../yaml/index.md#needsartifacts) keyword:
+The [`dependencies`](../yaml/index.md#dependencies) or
+[`needs`](../yaml/index.md#needs) keywords can be used to control
+which jobs receive inherited values.
+
+To have no inherited dotenv environment variables, pass an empty `dependencies` or
+`needs` list, or pass [`needs:artifacts`](../yaml/index.md#needsartifacts) as `false`
```yaml
build:
@@ -595,15 +603,46 @@ build:
reports:
dotenv: build.env
-deploy:
+deploy_one:
+ stage: deploy
+ script:
+ - echo "$BUILD_VERSION" # Output is: 'hello'
+ dependencies:
+ - build
+
+deploy_two:
+ stage: deploy
+ script:
+ - echo "$BUILD_VERSION" # Output is empty
+ dependencies: []
+
+deploy_three:
stage: deploy
script:
- echo "$BUILD_VERSION" # Output is: 'hello'
needs:
- - job: build
- artifacts: true
+ - build
+
+deploy_four:
+ stage: deploy
+ script:
+ - echo "$BUILD_VERSION" # Output is: 'hello'
+ needs:
+ job: build
+ artifacts: true
+
+deploy_five:
+ stage: deploy
+ script:
+ - echo "$BUILD_VERSION" # Output is empty
+ needs:
+ job: build
+ artifacts: false
```
+[Multi-project pipelines](../pipelines/multi_project_pipelines.md#pass-cicd-variables-to-a-downstream-pipeline-by-using-variable-inheritance)
+can also inherit variables from their upstream pipelines.
+
## CI/CD variable precedence
You can use CI/CD variables with the same name in different places, but the values
diff --git a/doc/ci/variables/predefined_variables.md b/doc/ci/variables/predefined_variables.md
index c06ca6878c4..60888cd9b97 100644
--- a/doc/ci/variables/predefined_variables.md
+++ b/doc/ci/variables/predefined_variables.md
@@ -62,6 +62,8 @@ There are also a number of [variables you can use to configure runner behavior](
| `CI_JOB_ID` | 9.0 | all | The internal ID of the job, unique across all jobs in the GitLab instance. |
| `CI_JOB_IMAGE` | 12.9 | 12.9 | The name of the Docker image running the job. |
| `CI_JOB_JWT` | 12.10 | all | A RS256 JSON web token to authenticate with third party systems that support JWT authentication, for example [HashiCorp's Vault](../secrets/index.md). |
+| `CI_JOB_JWT_V1` | 14.6 | all | The same value as `CI_JOB_JWT`. |
+| `CI_JOB_JWT_V2` | 14.6 | all | [**alpha:**](https://about.gitlab.com/handbook/product/gitlab-the-product/#alpha-beta-ga) A newly formatted RS256 JSON web token to increase compatibility. Similar to `CI_JOB_JWT`, except the issuer (`iss`) claim is changed from `gitlab.com` to `https://gitlab.com`, `sub` has changed from `job_id` to a string that contains the project path, and an `aud` claim is added. Format is subject to change. Be aware, the `aud` field is a constant value. Trusting JWTs in multiple relying parties can lead to [one RP sending a JWT to another one and acting maliciously as a job](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72555#note_769112331). |
| `CI_JOB_MANUAL` | 8.12 | all | `true` if a job was started manually. |
| `CI_JOB_NAME` | 9.0 | 0.5 | The name of the job. |
| `CI_JOB_STAGE` | 9.0 | 0.5 | The name of the job's stage. |
diff --git a/doc/ci/variables/where_variables_can_be_used.md b/doc/ci/variables/where_variables_can_be_used.md
index e32f0391d2e..4f304a10256 100644
--- a/doc/ci/variables/where_variables_can_be_used.md
+++ b/doc/ci/variables/where_variables_can_be_used.md
@@ -22,20 +22,25 @@ There are two places defined variables can be used. On the:
### `.gitlab-ci.yml` file
-| Definition | Can be expanded? | Expansion place | Description |
-|:-------------------------------------------|:-----------------|:-----------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| `environment:url` | yes | GitLab | The variable expansion is made by the [internal variable expansion mechanism](#gitlab-internal-variable-expansion-mechanism) in GitLab.<br/><br/>Supported are all variables defined for a job (project/group variables, variables from `.gitlab-ci.yml`, variables from triggers, variables from pipeline schedules).<br/><br/>Not supported are variables defined in the GitLab Runner `config.toml` and variables created in the job's `script`. |
-| `environment:name` | yes | GitLab | Similar to `environment:url`, but the variables expansion doesn't support the following:<br/><br/>- Variables that are based on the environment's name (`CI_ENVIRONMENT_NAME`, `CI_ENVIRONMENT_SLUG`).<br/>- Any other variables related to environment (currently only `CI_ENVIRONMENT_URL`).<br/>- [Persisted variables](#persisted-variables). |
-| `resource_group` | yes | GitLab | Similar to `environment:url`, but the variables expansion doesn't support the following:<br/>- `CI_ENVIRONMENT_URL`<br/>- [Persisted variables](#persisted-variables) |
-| `include` | yes | GitLab | The variable expansion is made by the [internal variable expansion mechanism](#gitlab-internal-variable-expansion-mechanism) in GitLab. <br/><br/>Predefined project variables are supported: `GITLAB_FEATURES`, `CI_DEFAULT_BRANCH`, and all variables that start with `CI_PROJECT_` (for example `CI_PROJECT_NAME`). |
-| `variables` | yes | GitLab/Runner | The variable expansion is first made by the [internal variable expansion mechanism](#gitlab-internal-variable-expansion-mechanism) in GitLab, and then any unrecognized or unavailable variables are expanded by GitLab Runner's [internal variable expansion mechanism](#gitlab-runner-internal-variable-expansion-mechanism). |
-| `image` | yes | Runner | The variable expansion is made by GitLab Runner's [internal variable expansion mechanism](#gitlab-runner-internal-variable-expansion-mechanism) |
-| `services:[]` | yes | Runner | The variable expansion is made by GitLab Runner's [internal variable expansion mechanism](#gitlab-runner-internal-variable-expansion-mechanism) |
-| `services:[]:name` | yes | Runner | The variable expansion is made by GitLab Runner's [internal variable expansion mechanism](#gitlab-runner-internal-variable-expansion-mechanism) |
-| `cache:key` | yes | Runner | The variable expansion is made by GitLab Runner's [internal variable expansion mechanism](#gitlab-runner-internal-variable-expansion-mechanism) |
-| `artifacts:name` | yes | Runner | The variable expansion is made by GitLab Runner's shell environment |
-| `script`, `before_script`, `after_script` | yes | Script execution shell | The variable expansion is made by the [execution shell environment](#execution-shell-environment) |
-| `only:variables:[]`, `except:variables:[]`, `rules:if` | no | n/a | The variable must be in the form of `$variable`. Not supported are the following:<br/><br/>- Variables that are based on the environment's name (`CI_ENVIRONMENT_NAME`, `CI_ENVIRONMENT_SLUG`).<br/>- Any other variables related to environment (currently only `CI_ENVIRONMENT_URL`).<br/>- [Persisted variables](#persisted-variables). |
+| Definition | Can be expanded? | Expansion place | Description |
+|:----------------------|:-----------------|:-----------------------|:------------|
+| `after_script` | yes | Script execution shell | The variable expansion is made by the [execution shell environment](#execution-shell-environment). |
+| `artifacts:name` | yes | Runner | The variable expansion is made by GitLab Runner's shell environment. |
+| `before_script` | yes | Script execution shell | The variable expansion is made by the [execution shell environment](#execution-shell-environment) |
+| `cache:key` | yes | Runner | The variable expansion is made by GitLab Runner's [internal variable expansion mechanism](#gitlab-runner-internal-variable-expansion-mechanism). |
+| `environment:name` | yes | GitLab | Similar to `environment:url`, but the variables expansion doesn't support the following:<br/><br/>- Variables that are based on the environment's name (`CI_ENVIRONMENT_NAME`, `CI_ENVIRONMENT_SLUG`).<br/>- Any other variables related to environment (currently only `CI_ENVIRONMENT_URL`).<br/>- [Persisted variables](#persisted-variables). |
+| `environment:url` | yes | GitLab | The variable expansion is made by the [internal variable expansion mechanism](#gitlab-internal-variable-expansion-mechanism) in GitLab.<br/><br/>Supported are all variables defined for a job (project/group variables, variables from `.gitlab-ci.yml`, variables from triggers, variables from pipeline schedules).<br/><br/>Not supported are variables defined in the GitLab Runner `config.toml` and variables created in the job's `script`. |
+| `except:variables:[]` | no | n/a | The variable must be in the form of `$variable`. Not supported are the following:<br/><br/>- Variables that are based on the environment's name (`CI_ENVIRONMENT_NAME`, `CI_ENVIRONMENT_SLUG`).<br/>- Any other variables related to environment (currently only `CI_ENVIRONMENT_URL`).<br/>- [Persisted variables](#persisted-variables). |
+| `image` | yes | Runner | The variable expansion is made by GitLab Runner's [internal variable expansion mechanism](#gitlab-runner-internal-variable-expansion-mechanism). |
+| `include` | yes | GitLab | The variable expansion is made by the [internal variable expansion mechanism](#gitlab-internal-variable-expansion-mechanism) in GitLab. <br/><br/>Predefined project variables are supported: `GITLAB_FEATURES`, `CI_DEFAULT_BRANCH`, and all variables that start with `CI_PROJECT_` (for example `CI_PROJECT_NAME`). |
+| `only:variables:[]` | no | n/a | The variable must be in the form of `$variable`. Not supported are the following:<br/><br/>- Variables that are based on the environment's name (`CI_ENVIRONMENT_NAME`, `CI_ENVIRONMENT_SLUG`).<br/>- Any other variables related to environment (currently only `CI_ENVIRONMENT_URL`).<br/>- [Persisted variables](#persisted-variables). |
+| `resource_group` | yes | GitLab | Similar to `environment:url`, but the variables expansion doesn't support the following:<br/>- `CI_ENVIRONMENT_URL`<br/>- [Persisted variables](#persisted-variables). |
+| `rules:if` | no | n/a | The variable must be in the form of `$variable`. Not supported are the following:<br/><br/>- Variables that are based on the environment's name (`CI_ENVIRONMENT_NAME`, `CI_ENVIRONMENT_SLUG`).<br/>- Any other variables related to environment (currently only `CI_ENVIRONMENT_URL`).<br/>- [Persisted variables](#persisted-variables). |
+| `script` | yes | Script execution shell | The variable expansion is made by the [execution shell environment](#execution-shell-environment). |
+| `services:[]:name` | yes | Runner | The variable expansion is made by GitLab Runner's [internal variable expansion mechanism](#gitlab-runner-internal-variable-expansion-mechanism). |
+| `services:[]` | yes | Runner | The variable expansion is made by GitLab Runner's [internal variable expansion mechanism](#gitlab-runner-internal-variable-expansion-mechanism). |
+| `tags` | yes | GitLab | The variable expansion is made by the [internal variable expansion mechanism](#gitlab-internal-variable-expansion-mechanism) in GitLab. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35742) in GitLab 14.1. |
+| `variables` | yes | GitLab/Runner | The variable expansion is first made by the [internal variable expansion mechanism](#gitlab-internal-variable-expansion-mechanism) in GitLab, and then any unrecognized or unavailable variables are expanded by GitLab Runner's [internal variable expansion mechanism](#gitlab-runner-internal-variable-expansion-mechanism). |
### `config.toml` file
diff --git a/doc/ci/yaml/artifacts_reports.md b/doc/ci/yaml/artifacts_reports.md
index cd38cf58c71..25fb861cfb7 100644
--- a/doc/ci/yaml/artifacts_reports.md
+++ b/doc/ci/yaml/artifacts_reports.md
@@ -52,7 +52,7 @@ GitLab can display the results of one or more reports in:
- The merge request [security widget](../../user/application_security/api_fuzzing/index.md#view-details-of-an-api-fuzzing-vulnerability).
- The [Project Vulnerability report](../../user/application_security/vulnerability_report/index.md).
-- The pipeline [**Security** tab](../../user/application_security/security_dashboard/index.md#pipeline-security).
+- The pipeline [**Security** tab](../../user/application_security/security_dashboard/index.md#view-vulnerabilities-in-a-pipeline).
- The [security dashboard](../../user/application_security/api_fuzzing/index.md#security-dashboard).
## `artifacts:reports:browser_performance` **(PREMIUM)**
@@ -117,7 +117,7 @@ The collected Container Scanning report uploads to GitLab as an artifact.
GitLab can display the results of one or more reports in:
- The merge request [container scanning widget](../../user/application_security/container_scanning/index.md).
-- The pipeline [**Security** tab](../../user/application_security/security_dashboard/index.md#pipeline-security).
+- The pipeline [**Security** tab](../../user/application_security/security_dashboard/index.md#view-vulnerabilities-in-a-pipeline).
- The [security dashboard](../../user/application_security/security_dashboard/index.md).
- The [Project Vulnerability report](../../user/application_security/vulnerability_report/index.md).
@@ -131,7 +131,7 @@ The collected coverage fuzzing report uploads to GitLab as an artifact.
GitLab can display the results of one or more reports in:
- The merge request [coverage fuzzing widget](../../user/application_security/coverage_fuzzing/index.md#interacting-with-the-vulnerabilities).
-- The pipeline [**Security** tab](../../user/application_security/security_dashboard/index.md#pipeline-security).
+- The pipeline [**Security** tab](../../user/application_security/security_dashboard/index.md#view-vulnerabilities-in-a-pipeline).
- The [Project Vulnerability report](../../user/application_security/vulnerability_report/index.md).
- The [security dashboard](../../user/application_security/security_dashboard/index.md).
@@ -143,7 +143,7 @@ report uploads to GitLab as an artifact.
GitLab can display the results of one or more reports in:
- The merge request [security widget](../../user/application_security/dast/index.md#view-details-of-a-vulnerability-detected-by-dast).
-- The pipeline [**Security** tab](../../user/application_security/security_dashboard/index.md#pipeline-security).
+- The pipeline [**Security** tab](../../user/application_security/security_dashboard/index.md#view-vulnerabilities-in-a-pipeline).
- The [Project Vulnerability report](../../user/application_security/vulnerability_report/index.md).
- The [security dashboard](../../user/application_security/security_dashboard/index.md).
@@ -155,7 +155,7 @@ The collected Dependency Scanning report uploads to GitLab as an artifact.
GitLab can display the results of one or more reports in:
- The merge request [dependency scanning widget](../../user/application_security/dependency_scanning/index.md#overview).
-- The pipeline [**Security** tab](../../user/application_security/security_dashboard/index.md#pipeline-security).
+- The pipeline [**Security** tab](../../user/application_security/security_dashboard/index.md#view-vulnerabilities-in-a-pipeline).
- The [security dashboard](../../user/application_security/security_dashboard/index.md).
- The [Project Vulnerability report](../../user/application_security/vulnerability_report/index.md).
- The [dependency list](../../user/application_security/dependency_list/).
diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md
index ed05ef08d02..4530e2675c4 100644
--- a/doc/ci/yaml/index.md
+++ b/doc/ci/yaml/index.md
@@ -24,12 +24,13 @@ A GitLab CI/CD pipeline configuration includes:
- [Global keywords](#global-keywords) that configure pipeline behavior:
- | Keyword | Description |
- |-------------------------|:------------|
- | [`default`](#default) | Custom default values for job keywords. |
- | [`include`](#include) | Import configuration from other YAML files. |
- | [`stages`](#stages) | The names and order of the pipeline stages. |
- | [`workflow`](#workflow) | Control what types of pipeline run. |
+ | Keyword | Description |
+ |---------------------------|:------------|
+ | [`default`](#default) | Custom default values for job keywords. |
+ | [`include`](#include) | Import configuration from other YAML files. |
+ | [`stages`](#stages) | The names and order of the pipeline stages. |
+ | [`variables`](#variables) | Define CI/CD variables for all job in the pipeline. |
+ | [`workflow`](#workflow) | Control what types of pipeline run. |
- [Jobs](../jobs/index.md) configured with [job keywords](#job-keywords):
@@ -414,6 +415,7 @@ and the pipeline is for either:
- You can use the [`workflow:rules` templates](workflow.md#workflowrules-templates) to import
a preconfigured `workflow: rules` entry.
- [Common `if` clauses for `workflow:rules`](workflow.md#common-if-clauses-for-workflowrules).
+- [Use `rules` to run pipelines for merge requests](../pipelines/merge_request_pipelines.md#use-rules-to-add-jobs).
#### `workflow:rules:variables`
@@ -1429,13 +1431,13 @@ test osx:
stage: test
script: make test:osx
dependencies:
- - build:osx
+ - build osx
test linux:
stage: test
script: make test:linux
dependencies:
- - build:linux
+ - build linux
deploy:
stage: deploy
@@ -2506,8 +2508,7 @@ docker build:
- [`only: changes` and `except: changes` examples](../jobs/job_control.md#onlychanges--exceptchanges-examples).
- If you use `changes` with [only allow merge requests to be merged if the pipeline succeeds](../../user/project/merge_requests/merge_when_pipeline_succeeds.md#only-allow-merge-requests-to-be-merged-if-the-pipeline-succeeds),
you should [also use `only:merge_requests`](../jobs/job_control.md#use-onlychanges-with-pipelines-for-merge-requests).
-- Use `changes` with [new branches or tags *without* pipelines for merge requests](../jobs/job_control.md#use-onlychanges-without-pipelines-for-merge-requests).
-- Use `changes` with [scheduled pipelines](../jobs/job_control.md#use-onlychanges-with-scheduled-pipelines).
+- [Jobs or pipelines can run unexpectedly when using `only: changes`](../jobs/job_control.md#jobs-or-pipelines-run-unexpectedly-when-using-changes).
#### `only:kubernetes` / `except:kubernetes`
@@ -3066,8 +3067,10 @@ job:
- If a rule matches and has no `when` defined, the rule uses the `when`
defined for the job, which defaults to `on_success` if not defined.
-- You can define `when` once per rule, or once at the job-level, which applies to
- all rules. You can't mix `when` at the job-level with `when` in rules.
+- In GitLab 14.5 and earlier, you can define `when` once per rule, or once at the job-level,
+ which applies to all rules. You can't mix `when` at the job-level with `when` in rules.
+- In GitLab 14.6 and later, you can [mix `when` at the job-level with `when` in rules](https://gitlab.com/gitlab-org/gitlab/-/issues/219437).
+ `when` configuration in `rules` takes precedence over `when` at the job-level.
- Unlike variables in [`script`](../variables/index.md#use-cicd-variables-in-job-scripts)
sections, variables in rules expressions are always formatted as `$VARIABLE`.
- You can use `rules:if` with `include` to [conditionally include other configuration files](includes.md#use-rules-with-include).
@@ -3076,6 +3079,7 @@ job:
- [Common `if` expressions for `rules`](../jobs/job_control.md#common-if-clauses-for-rules).
- [Avoid duplicate pipelines](../jobs/job_control.md#avoid-duplicate-pipelines).
+- [Use `rules` to run pipelines for merge requests](../pipelines/merge_request_pipelines.md#use-rules-to-add-jobs).
#### `rules:changes`
@@ -3120,6 +3124,10 @@ docker build:
- You can use `when: never` to implement a rule similar to [`except:changes`](#onlychanges--exceptchanges).
- `changes` resolves to `true` if any of the matching files are changed (an `OR` operation).
+**Related topics**:
+
+- [Jobs or pipelines can run unexpectedly when using `rules: changes`](../jobs/job_control.md#jobs-or-pipelines-run-unexpectedly-when-using-changes).
+
#### `rules:exists`
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24021) in GitLab 12.4.
@@ -3834,13 +3842,13 @@ The following keywords are deprecated.
### Globally-defined `types`
WARNING:
-`types` is deprecated, and could be removed in a future release.
+`types` is deprecated, and is [scheduled to be removed in GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/346823).
Use [`stages`](#stages) instead.
### Job-defined `type`
WARNING:
-`type` is deprecated, and could be removed in one of the future releases.
+`type` is deprecated, and is [scheduled to be removed in GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/346823).
Use [`stage`](#stage) instead.
### Globally-defined `image`, `services`, `cache`, `before_script`, `after_script`
diff --git a/doc/ci/yaml/script.md b/doc/ci/yaml/script.md
index fdec0947df5..ca1e79c2395 100644
--- a/doc/ci/yaml/script.md
+++ b/doc/ci/yaml/script.md
@@ -164,10 +164,14 @@ Second command line.
When you omit the `>` or `|` block scalar indicators, GitLab concatenates non-empty
lines to form the command. Make sure the lines can run when concatenated.
-[These documents](https://en.wikipedia.org/wiki/Here_document) work with the
+<!-- vale gitlab.MeaningfulLinkWords = NO -->
+
+[Shell here documents](https://en.wikipedia.org/wiki/Here_document) work with the
`|` and `>` operators as well. The example below transliterates lower case letters
to upper case:
+<!-- vale gitlab.MeaningfulLinkWords = YES -->
+
```yaml
job:
script:
diff --git a/doc/development/application_limits.md b/doc/development/application_limits.md
index 2075e7cda3c..15d21883bb8 100644
--- a/doc/development/application_limits.md
+++ b/doc/development/application_limits.md
@@ -141,6 +141,8 @@ end
### Subscription Plans
+> The `opensource` plan was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/346399) in GitLab 14.7.
+
Self-managed:
- `default`: Everyone.
@@ -156,5 +158,6 @@ GitLab.com:
- `gold`: Namespaces and projects with an Ultimate subscription.
- `ultimate`: Namespaces and projects with an Ultimate subscription.
- `ultimate_trial`: Namespaces and projects with an Ultimate Trial subscription.
+- `opensource`: Namespaces and projects that are member of GitLab Open Source program.
The `test` environment doesn't have any plans.
diff --git a/doc/development/architecture.md b/doc/development/architecture.md
index 078eb5dd0de..36d3655ba93 100644
--- a/doc/development/architecture.md
+++ b/doc/development/architecture.md
@@ -339,7 +339,7 @@ Component statuses are linked to configuration documentation for each component.
### Component list
-| Component | Description | [Omnibus GitLab](https://docs.gitlab.com/omnibus/) | [GitLab Environment Toolkit (GET)](https://gitlab.com/gitlab-org/quality/gitlab-environment-toolkit) | [GitLab chart](https://docs.gitlab.com/charts/) | [Minikube Minimal](https://docs.gitlab.com/charts/development/minikube/#deploying-gitlab-with-minimal-settings) | [GitLab.com](https://gitlab.com) | [Source](../install/installation.md) | [GDK](https://gitlab.com/gitlab-org/gitlab-development-kit) | [CE/EE](https://about.gitlab.com/install/ce-or-ee/) |
+| Component | Description | [Omnibus GitLab](https://docs.gitlab.com/omnibus/) | [GitLab Environment Toolkit (GET)](https://gitlab.com/gitlab-org/quality/gitlab-environment-toolkit) | [GitLab chart](https://docs.gitlab.com/charts/) | [minikube Minimal](https://docs.gitlab.com/charts/development/minikube/#deploying-gitlab-with-minimal-settings) | [GitLab.com](https://gitlab.com) | [Source](../install/installation.md) | [GDK](https://gitlab.com/gitlab-org/gitlab-development-kit) | [CE/EE](https://about.gitlab.com/install/ce-or-ee/) |
|-------------------------------------------------------|----------------------------------------------------------------------|:--------------:|:--------------:|:------------:|:----------------:|:----------:|:------:|:---:|:-------:|
| [Certificate Management](#certificate-management) | TLS Settings, Let's Encrypt | ✅ | ✅ | ✅ | ⚙ | ✅ | ⚙ | ⚙ | CE & EE |
| [Consul](#consul) | Database node discovery, failover | ⚙ | ✅ | ⌠| ⌠| ✅ | ⌠| ⌠| EE Only |
@@ -797,7 +797,7 @@ For monitoring deployed apps, see the [Sentry integration docs](../operations/er
- 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/sidekiq/)
- - [Minikube Minimal](https://docs.gitlab.com/charts/charts/gitlab/sidekiq/index.html)
+ - [minikube Minimal](https://docs.gitlab.com/charts/charts/gitlab/sidekiq/index.html)
- [Source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/gitlab.yml.example)
- [GDK](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/gitlab.yml.example)
- Layer: Core Service (Processor)
diff --git a/doc/development/avoiding_downtime_in_migrations.md b/doc/development/avoiding_downtime_in_migrations.md
index a5fc1909551..1d36bbf1212 100644
--- a/doc/development/avoiding_downtime_in_migrations.md
+++ b/doc/development/avoiding_downtime_in_migrations.md
@@ -228,100 +228,9 @@ can take a very long time to complete, preventing a deployment from proceeding.
They can also produce a lot of pressure on the database due to it rapidly
updating many rows in sequence.
-To reduce database pressure you should instead use
-`change_column_type_using_background_migration` or `rename_column_using_background_migration`
-when migrating a column in a large table (for example, `issues`). These methods work
-similarly to the concurrent counterparts but uses background migration to spread
-the work / load over a longer time period, without slowing down deployments.
-
-For example, to change the column type using a background migration:
-
-```ruby
-class ExampleMigration < Gitlab::Database::Migration[1.0]
- disable_ddl_transaction!
-
- class Issue < ActiveRecord::Base
- self.table_name = 'issues'
-
- include EachBatch
-
- def self.to_migrate
- where('closed_at IS NOT NULL')
- end
- end
-
- def up
- change_column_type_using_background_migration(
- Issue.to_migrate,
- :closed_at,
- :datetime_with_timezone
- )
- end
-
- def down
- change_column_type_using_background_migration(
- Issue.to_migrate,
- :closed_at,
- :datetime
- )
- end
-end
-```
-
-This would change the type of `issues.closed_at` to `timestamp with time zone`.
-
-Keep in mind that the relation passed to
-`change_column_type_using_background_migration` _must_ include `EachBatch`,
-otherwise it will raise a `TypeError`.
-
-This migration then needs to be followed in a separate release (_not_ a patch
-release) by a cleanup migration, which should steal from the queue and handle
-any remaining rows. For example:
-
-```ruby
-class MigrateRemainingIssuesClosedAt < Gitlab::Database::Migration[1.0]
- disable_ddl_transaction!
-
- class Issue < ActiveRecord::Base
- self.table_name = 'issues'
- include EachBatch
- end
-
- def up
- Gitlab::BackgroundMigration.steal('CopyColumn')
- Gitlab::BackgroundMigration.steal('CleanupConcurrentTypeChange')
-
- migrate_remaining_rows if migrate_column_type?
- end
-
- def down
- # Previous migrations already revert the changes made here.
- end
-
- def migrate_remaining_rows
- Issue.where('closed_at_for_type_change IS NULL AND closed_at IS NOT NULL').each_batch do |batch|
- batch.update_all('closed_at_for_type_change = closed_at')
- end
-
- cleanup_concurrent_column_type_change(:issues, :closed_at)
- end
-
- def migrate_column_type?
- # Some environments may have already executed the previous version of this
- # migration, thus we don't need to migrate those environments again.
- column_for('issues', 'closed_at').type == :datetime # rubocop:disable Migration/Datetime
- end
-end
-```
-
-The same applies to `rename_column_using_background_migration`:
-
-1. Create a migration using the helper, which will schedule background
- migrations to spread the writes over a longer period of time.
-1. In the next monthly release, create a clean-up migration to steal from the
- Sidekiq queues, migrate any missing rows, and cleanup the rename. This
- migration should skip the steps after stealing from the Sidekiq queues if the
- column has already been renamed.
+To reduce database pressure you should instead use a background migration
+when migrating a column in a large table (for example, `issues`). This will
+spread the work / load over a longer time period, without slowing down deployments.
For more information, see [the documentation on cleaning up background
migrations](background_migrations.md#cleaning-up).
diff --git a/doc/development/background_migrations.md b/doc/development/background_migrations.md
index 4a18b2123da..49835085f96 100644
--- a/doc/development/background_migrations.md
+++ b/doc/development/background_migrations.md
@@ -83,23 +83,11 @@ replacing the class name and arguments with whatever values are necessary for
your migration:
```ruby
-migrate_async('BackgroundMigrationClassName', [arg1, arg2, ...])
+migrate_in('BackgroundMigrationClassName', [arg1, arg2, ...])
```
-Usually it's better to enqueue jobs in bulk, for this you can use
-`bulk_migrate_async`:
-
-```ruby
-bulk_migrate_async(
- [['BackgroundMigrationClassName', [1]],
- ['BackgroundMigrationClassName', [2]]]
-)
-```
-
-Note that this will queue a Sidekiq job immediately: if you have a large number
-of records, this may not be what you want. You can use the function
-`queue_background_migration_jobs_by_range_at_intervals` to split the job into
-batches:
+You can use the function `queue_background_migration_jobs_by_range_at_intervals`
+to automatically split the job into batches:
```ruby
queue_background_migration_jobs_by_range_at_intervals(
@@ -117,16 +105,6 @@ consuming migrations it's best to schedule a background job using an
updates. Removals in turn can be handled by simply defining foreign keys with
cascading deletes.
-If you would like to schedule jobs in bulk with a delay, you can use
-`BackgroundMigrationWorker.bulk_perform_in`:
-
-```ruby
-jobs = [['BackgroundMigrationClassName', [1]],
- ['BackgroundMigrationClassName', [2]]]
-
-bulk_migrate_in(5.minutes, jobs)
-```
-
### Rescheduling background migrations
If one of the background migrations contains a bug that is fixed in a patch
@@ -197,53 +175,47 @@ the new format.
## Example
-To explain all this, let's use the following example: the table `services` has a
+To explain all this, let's use the following example: the table `integrations` has a
field called `properties` which is stored in JSON. For all rows you want to
-extract the `url` key from this JSON object and store it in the `services.url`
-column. There are millions of services and parsing JSON is slow, thus you can't
+extract the `url` key from this JSON object and store it in the `integrations.url`
+column. There are millions of integrations and parsing JSON is slow, thus you can't
do this in a regular migration.
To do this using a background migration we'll start with defining our migration
class:
```ruby
-class Gitlab::BackgroundMigration::ExtractServicesUrl
- class Service < ActiveRecord::Base
- self.table_name = 'services'
+class Gitlab::BackgroundMigration::ExtractIntegrationsUrl
+ class Integration < ActiveRecord::Base
+ self.table_name = 'integrations'
end
- def perform(service_id)
- # A row may be removed between scheduling and starting of a job, thus we
- # need to make sure the data is still present before doing any work.
- service = Service.select(:properties).find_by(id: service_id)
+ def perform(start_id, end_id)
+ Integration.where(id: start_id..end_id).each do |integration|
+ json = JSON.load(integration.properties)
- return unless service
-
- begin
- json = JSON.load(service.properties)
+ integration.update(url: json['url']) if json['url']
rescue JSON::ParserError
# If the JSON is invalid we don't want to keep the job around forever,
# instead we'll just leave the "url" field to whatever the default value
# is.
- return
+ next
end
-
- service.update(url: json['url']) if json['url']
end
end
```
Next we'll need to adjust our code so we schedule the above migration for newly
-created and updated services. We can do this using something along the lines of
+created and updated integrations. We can do this using something along the lines of
the following:
```ruby
-class Service < ActiveRecord::Base
- after_commit :schedule_service_migration, on: :update
- after_commit :schedule_service_migration, on: :create
+class Integration < ActiveRecord::Base
+ after_commit :schedule_integration_migration, on: :update
+ after_commit :schedule_integration_migration, on: :create
- def schedule_service_migration
- BackgroundMigrationWorker.perform_async('ExtractServicesUrl', [id])
+ def schedule_integration_migration
+ BackgroundMigrationWorker.perform_async('ExtractIntegrationsUrl', [id, id])
end
end
```
@@ -253,21 +225,20 @@ before the transaction completes as doing so can lead to race conditions where
the changes are not yet visible to the worker.
Next we'll need a post-deployment migration that schedules the migration for
-existing data. Since we're dealing with a lot of rows we'll schedule jobs in
-batches instead of doing this one by one:
+existing data.
```ruby
-class ScheduleExtractServicesUrl < Gitlab::Database::Migration[1.0]
+class ScheduleExtractIntegrationsUrl < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
- def up
- define_batchable_model('services').select(:id).in_batches do |relation|
- jobs = relation.pluck(:id).map do |id|
- ['ExtractServicesUrl', [id]]
- end
+ MIGRATION = 'ExtractIntegrationsUrl'
+ DELAY_INTERVAL = 2.minutes
- BackgroundMigrationWorker.bulk_perform_async(jobs)
- end
+ def up
+ queue_background_migration_jobs_by_range_at_intervals(
+ define_batchable_model('integrations'),
+ MIGRATION,
+ DELAY_INTERVAL)
end
def down
@@ -284,18 +255,18 @@ jobs and manually run on any un-migrated rows. Such a migration would look like
this:
```ruby
-class ConsumeRemainingExtractServicesUrlJobs < Gitlab::Database::Migration[1.0]
+class ConsumeRemainingExtractIntegrationsUrlJobs < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
# This must be included
- Gitlab::BackgroundMigration.steal('ExtractServicesUrl')
+ Gitlab::BackgroundMigration.steal('ExtractIntegrationsUrl')
# This should be included, but can be skipped - see below
- define_batchable_model('services').where(url: nil).each_batch(of: 50) do |batch|
+ define_batchable_model('integrations').where(url: nil).each_batch(of: 50) do |batch|
range = batch.pluck('MIN(id)', 'MAX(id)').first
- Gitlab::BackgroundMigration::ExtractServicesUrl.new.perform(*range)
+ Gitlab::BackgroundMigration::ExtractIntegrationsUrl.new.perform(*range)
end
end
@@ -313,9 +284,9 @@ If the application does not depend on the data being 100% migrated (for
instance, the data is advisory, and not mission-critical), then this final step
can be skipped.
-This migration will then process any jobs for the ExtractServicesUrl migration
+This migration will then process any jobs for the ExtractIntegrationsUrl migration
and continue once all jobs have been processed. Once done you can safely remove
-the `services.properties` column.
+the `integrations.properties` column.
## Testing
diff --git a/doc/development/cascading_settings.md b/doc/development/cascading_settings.md
index d04761400ac..f9c96e414d0 100644
--- a/doc/development/cascading_settings.md
+++ b/doc/development/cascading_settings.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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/development/cicd/index.md b/doc/development/cicd/index.md
index 82fd37eacaf..17a70393c96 100644
--- a/doc/development/cicd/index.md
+++ b/doc/development/cicd/index.md
@@ -109,6 +109,11 @@ After the server receives the request it selects a `pending` job based on the [`
Once all jobs are completed for the current stage, the server "unlocks" all the jobs from the next stage by changing their state to `pending`. These can now be picked by the scheduling algorithm when the runner requests new jobs, and continues like this until all stages are completed.
+If a job is not picked up by a runner in 24 hours it is automatically removed from
+the processing queue after that time. If a pending job is stuck, when there is no
+runner available that can process it, it is removed from the queue after 1 hour.
+In both cases the job's status is changed to `failed` with an appropriate failure reason.
+
### Communication between runner and GitLab server
After the runner is [registered](https://docs.gitlab.com/runner/register/) using the registration token, the server knows what type of jobs it can execute. This depends on:
@@ -169,18 +174,18 @@ We have a few inconsistencies in our codebase that should be refactored.
For example, `CommitStatus` should be `Ci::Job` and `Ci::JobArtifact` should be `Ci::BuildArtifact`.
See [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/16111) for the full refactoring plan.
-## CI Minutes
+## CI/CD Minutes
-This diagram shows how the [CI minutes](../../subscriptions/gitlab_com/index.md#ci-pipeline-minutes)
+This diagram shows how the [CI/CD minutes](../../ci/pipelines/cicd_minutes.md)
feature and its components work.
-![CI Minutes architecture](img/ci_minutes.png)
+![CI/CD minutes architecture](img/ci_minutes.png)
<!-- Editable diagram available at https://app.diagrams.net/?libs=general;flowchart#G1XjLPvJXbzMofrC3eKRyDEk95clV6ypOb -->
Watch a walkthrough of this feature in details in the video below.
<div class="video-fallback">
- See the video: <a href="https://www.youtube.com/watch?v=NmdWRGT8kZg">CI Minutes - architectural overview</a>.
+ See the video: <a href="https://www.youtube.com/watch?v=NmdWRGT8kZg">CI/CD minutes - architectural overview</a>.
</div>
<figure class="video-container">
<iframe src="https://www.youtube.com/embed/NmdWRGT8kZg" frameborder="0" allowfullscreen="true"> </iframe>
diff --git a/doc/development/code_review.md b/doc/development/code_review.md
index 742d183e15c..1ed510c6ad7 100644
--- a/doc/development/code_review.md
+++ b/doc/development/code_review.md
@@ -394,9 +394,9 @@ the roulette is not available, choose someone else from that list.
It is the responsibility of the author for the merge request to be reviewed. If it stays in the `ready for review` state too long it is recommended to request a review from a specific reviewer.
-#### List of merge requests ready for review
+### Volunteering to review
-Developers who have capacity can regularly check the list of [merge requests to review](https://gitlab.com/groups/gitlab-org/-/merge_requests?state=opened&label_name%5B%5D=workflow%3A%3Aready%20for%20review) and add themselves as a reviewer for any merge request they want to review.
+GitLab engineers who have capacity can regularly check the list of [merge requests to review](https://gitlab.com/groups/gitlab-org/-/merge_requests?state=opened&label_name%5B%5D=workflow%3A%3Aready%20for%20review) and add themselves as a reviewer for any merge request they want to review.
### Reviewing a merge request
@@ -501,7 +501,7 @@ Merge Results against the latest `main` at the time of the pipeline creation.
WARNING:
**Review all changes thoroughly for malicious code before starting a
-[Pipeline for Merged Results](../ci/pipelines/merge_request_pipelines.md#run-pipelines-in-the-parent-project-for-merge-requests-from-a-forked-project).**
+[Pipeline for Merged Results](../ci/pipelines/merge_request_pipelines.md#run-pipelines-in-the-parent-project).**
When reviewing merge requests added by wider community contributors:
@@ -522,9 +522,12 @@ If the MR source branch is more than 1,000 commits behind the target branch:
or check with the contributor first when they're actively working on the MR.
- The rebase can usually be done inside GitLab with the `/rebase` [quick action](../user/project/quick_actions.md).
+#### Taking over a community merge request
+
When an MR needs further changes but the author is not responding for a long period of time,
-or unable to finish the MR, we can take it over in accordance with our
-[Closing policy for issues and merge requests](contributing/#closing-policy-for-issues-and-merge-requests):
+or is unable to finish the MR, GitLab can take it over in accordance with our
+[Closing policy for issues and merge requests](contributing/#closing-policy-for-issues-and-merge-requests).
+A GitLab engineer (generally the merge request coach) will:
1. Add a comment to their MR saying you'll take it over to be able to get it merged.
1. Add the label `~"coach will finish"` to their MR.
diff --git a/doc/development/database/efficient_in_operator_queries.md b/doc/development/database/efficient_in_operator_queries.md
index 1e706890f64..76518a6f5e2 100644
--- a/doc/development/database/efficient_in_operator_queries.md
+++ b/doc/development/database/efficient_in_operator_queries.md
@@ -589,6 +589,87 @@ LIMIT 20
NOTE:
To make the query efficient, the following columns need to be covered with an index: `project_id`, `issue_type`, `created_at`, and `id`.
+#### Using calculated ORDER BY expression
+
+The following example orders epic records by the duration between the creation time and closed
+time. It is calculated with the following formula:
+
+```sql
+SELECT EXTRACT('epoch' FROM epics.closed_at - epics.created_at) FROM epics
+```
+
+The query above returns the duration in seconds (`double precision`) between the two timestamp
+columns in seconds. To order the records by this expression, you must reference it
+in the `ORDER BY` clause:
+
+```sql
+SELECT EXTRACT('epoch' FROM epics.closed_at - epics.created_at)
+FROM epics
+ORDER BY EXTRACT('epoch' FROM epics.closed_at - epics.created_at) DESC
+```
+
+To make this ordering efficient on the group-level with the in-operator optimization, use a
+custom `ORDER BY` configuration. Since the duration is not a distinct value (no unique index
+present), you must add a tie-breaker column (`id`).
+
+The following example shows the final `ORDER BY` clause:
+
+```sql
+ORDER BY extract('epoch' FROM epics.closed_at - epics.created_at) DESC, epics.id DESC
+```
+
+Snippet for loading records ordered by the calcualted duration:
+
+```ruby
+arel_table = Epic.arel_table
+order = Gitlab::Pagination::Keyset::Order.build([
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'duration_in_seconds',
+ order_expression: Arel.sql('EXTRACT(EPOCH FROM epics.closed_at - epics.created_at)').desc,
+ distinct: false,
+ sql_type: 'double precision' # important for calculated SQL expressions
+ ),
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'id',
+ order_expression: arel_table[:id].desc
+ )
+])
+
+records = Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder.new(
+ scope: Epic.where.not(closed_at: nil).reorder(order), # filter out NULL values
+ array_scope: Group.find(9970).self_and_descendants.select(:id),
+ array_mapping_scope: -> (id_expression) { Epic.where(Epic.arel_table[:group_id].eq(id_expression)) }
+).execute.limit(20)
+
+puts records.pluck(:duration_in_seconds, :id) # other columnns are not available
+```
+
+Building the query requires quite a bit of configuration. For the order configuration you
+can find more information within the
+[complex order configuration](keyset_pagination.md#complex-order-configuration)
+section for keyset paginated database queries.
+
+The query requires a specialized database index:
+
+```sql
+CREATE INDEX index_epics_on_duration ON epics USING btree (group_id, EXTRACT(EPOCH FROM epics.closed_at - epics.created_at) DESC, id DESC) WHERE (closed_at IS NOT NULL);
+```
+
+Notice that the `finder_query` parameter is not used. The query only returns the `ORDER BY` columns
+which are the `duration_in_seconds` (calculated column) and the `id` columns. This is a limitation
+of the feature, defining the `finder_query` with calculated `ORDER BY` expressions is not supported.
+To get the complete database records, an extra query can be invoked by the returned `id` column:
+
+```ruby
+records_by_id = records.index_by(&:id)
+complete_records = Epic.where(id: records_by_id.keys).index_by(&:id)
+
+# Printing the complete records according to the `ORDER BY` clause
+records_by_id.each do |id, _|
+ puts complete_records[id].attributes
+end
+```
+
#### Batch iteration
Batch iteration over the records is possible via the keyset `Iterator` class.
diff --git a/doc/development/database/loose_foreign_keys.md b/doc/development/database/loose_foreign_keys.md
index c60989f225d..97d150b1a18 100644
--- a/doc/development/database/loose_foreign_keys.md
+++ b/doc/development/database/loose_foreign_keys.md
@@ -43,7 +43,7 @@ we can:
1. Create a `DELETE` trigger on the `projects` table.
Record the deletions in a separate table (`deleted_records`).
-1. A job checks the `deleted_records` table every 5 minutes.
+1. A job checks the `deleted_records` table every minute or two.
1. For each record in the table, delete the associated `ci_pipelines` records
using the `project_id` column.
@@ -89,9 +89,10 @@ ci_pipelines:
### Track record changes
-To know about deletions in the `projects` table, configure a `DELETE` trigger using a database
-migration (post-migration). The trigger needs to be configured only once. If the model already has
-at least one `loose_foreign_key` definition, then this step can be skipped:
+To know about deletions in the `projects` table, configure a `DELETE` trigger
+using a [post-deployment migration](../post_deployment_migrations.md). The
+trigger needs to be configured only once. If the model already has at least one
+`loose_foreign_key` definition, then this step can be skipped:
```ruby
class TrackProjectRecordChanges < Gitlab::Database::Migration[1.0]
@@ -122,15 +123,20 @@ REFERENCES projects(id)
ON DELETE CASCADE;
```
-The migration should run after the `DELETE` trigger is installed. If the foreign key is deleted
-earlier, there is a good chance of introducing data inconsistency which needs manual cleanup:
+The migration must run after the `DELETE` trigger is installed and the loose
+foreign key definition is deployed. As such, it must be a [post-deployment
+migration](../post_deployment_migrations.md) dated after the migration for the
+trigger. If the foreign key is deleted earlier, there is a good chance of
+introducing data inconsistency which needs manual cleanup:
```ruby
class RemoveProjectsCiPipelineFk < Gitlab::Database::Migration[1.0]
- enable_lock_retries!
+ disable_ddl_transaction!
def up
- remove_foreign_key_if_exists(:ci_pipelines, :projects, name: "fk_86635dbd80")
+ with_lock_retries do
+ remove_foreign_key_if_exists(:ci_pipelines, :projects, name: "fk_86635dbd80")
+ end
end
def down
@@ -155,6 +161,17 @@ it_behaves_like 'it has loose foreign keys' do
end
```
+**After** [removing a foreign key](#remove-the-foreign-key),
+use the "`cleanup by a loose foreign key`" shared example to test a child record's deletion or nullification
+via the added loose foreign key:
+
+```ruby
+it_behaves_like 'cleanup by a loose foreign key' do
+ let!(:model) { create(:ci_pipeline, user: create(:user)) }
+ let!(:parent) { model.user }
+end
+```
+
## Caveats of loose foreign keys
### Record creation
diff --git a/doc/development/database_review.md b/doc/development/database_review.md
index 45be797b720..082c843a12c 100644
--- a/doc/development/database_review.md
+++ b/doc/development/database_review.md
@@ -132,6 +132,18 @@ test its execution using `CREATE INDEX CONCURRENTLY` in the `#database-lab` Slac
- This job runs migrations in a production-like environment (similar to `#database_lab`) and posts to the MR its findings (queries, runtime, size change).
- Review migration runtimes and any warnings.
+#### Preparation when adding data migrations
+
+Data migrations are inherently risky. Additional actions are required to reduce the possibility
+of error that would result in corruption or loss of production data.
+
+Include in the MR description:
+
+- If the migration itself is not reversible, details of how data changes could be reverted in the event of an incident. For example, in the case of a migration that deletes records (an operation that most of the times is not automatically revertable), how _could_ the deleted records be recovered.
+- If the migration deletes data, apply the label `~data-deletion`.
+- Concise descriptions of possible user experience impact of an error; for example, "Issues would unexpectedly go missing from Epics".
+- Relevant data from the [query plans](#query-plans) that indicate the query works as expected; such as the approximate number of records that will be modified/deleted.
+
#### Preparation when adding or modifying queries
##### Raw SQL
diff --git a/doc/development/documentation/feature_flags.md b/doc/development/documentation/feature_flags.md
index 6a618e47211..1e4698ff867 100644
--- a/doc/development/documentation/feature_flags.md
+++ b/doc/development/documentation/feature_flags.md
@@ -1,6 +1,7 @@
---
-type: reference, dev
info: For assistance with this Style Guide page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-other-projects-and-subjects.
+stage: none
+group: unassigned
description: "GitLab development - how to document features deployed behind feature flags"
---
diff --git a/doc/development/documentation/redirects.md b/doc/development/documentation/redirects.md
index ef94c33a276..8f13048f663 100644
--- a/doc/development/documentation/redirects.md
+++ b/doc/development/documentation/redirects.md
@@ -94,7 +94,6 @@ To add a redirect:
```
If you don't want to use the Rake task, you can use the following template.
- However, the file paths must be relative to the `doc` or `docs` directory.
Replace the value of `redirect_to` with the new file path and `YYYY-MM-DD`
with the date the file should be removed.
diff --git a/doc/development/documentation/restful_api_styleguide.md b/doc/development/documentation/restful_api_styleguide.md
index 5dc627c93e9..4d654b6b901 100644
--- a/doc/development/documentation/restful_api_styleguide.md
+++ b/doc/development/documentation/restful_api_styleguide.md
@@ -1,5 +1,7 @@
---
info: For assistance with this Style Guide page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-other-projects-and-subjects.
+stage: none
+group: unassigned
description: 'Writing styles, markup, formatting, and other standards for the GitLab RESTful APIs.'
---
diff --git a/doc/development/documentation/styleguide/index.md b/doc/development/documentation/styleguide/index.md
index 7f2e5a1ba26..e57ffb90028 100644
--- a/doc/development/documentation/styleguide/index.md
+++ b/doc/development/documentation/styleguide/index.md
@@ -1,5 +1,7 @@
---
info: For assistance with this Style Guide page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-other-projects-and-subjects.
+stage: none
+group: unassigned
description: 'Writing styles, markup, formatting, and other standards for GitLab Documentation.'
---
@@ -13,7 +15,7 @@ use the `#docs-processes` channel.
In addition to this page, the following resources can help you craft and contribute to documentation:
- [Doc contribution guidelines](../index.md)
-- [A-Z word list](word_list.md)
+- [Recommended word list](word_list.md)
- [Doc style and consistency testing](../testing.md)
- [UI text guidelines](https://design.gitlab.com/content/error-messages/)
- [GitLab Handbook style guidelines](https://about.gitlab.com/handbook/communication/#writing-style-guidelines)
@@ -392,39 +394,26 @@ especially in tutorials, instructional documentation, and
Some contractions, however, should be avoided:
-- Do not use the word "GitLab" in a contraction.
+<!-- vale gitlab.Possessive = NO -->
-- Do not use contractions with a proper noun and a verb. For example:
+| Do not use a contraction | Example | Use instead |
+|-------------------------------|--------------------------------------------------|------------------------------------------------------------------|
+| With a proper noun and a verb | The **Container Registry's** a powerful feature. | The **Container Registry** is a powerful feature. |
+| To emphasize a negative | **Don't** install X with Y. | **Do not** install X with Y. |
+| In reference documentation | **Don't** set a limit. | **Do not** set a limit. |
+| In error messages | Requests to localhost **aren't** allowed. | Requests to localhost **are not** allowed. |
- | Do | Don't |
- |------------------------------------------|-----------------------------------------|
- | Canada is establishing X. | Canada's establishing X. |
-
-- Do not use contractions when you need to emphasize a negative. For example:
-
- | Do | Don't |
- |------------------------------------------|-----------------------------------------|
- | Do not install X with Y. | Don't install X with Y. |
-
-- Do not use contractions in reference documentation. For example:
-
- | Do | Don't |
- |------------------------------------------|-----------------------------------------|
- | Do not set a limit greater than 1000. | Don't set a limit greater than 1000. |
- | For `parameter1`, the default is 10. | For `parameter1`, the default's 10. |
-
-- Avoid contractions in error messages. Examples:
-
- | Do | Don't |
- |------------------------------------------|-----------------------------------------|
- | Requests to localhost are not allowed. | Requests to localhost aren't allowed. |
- | Specified URL cannot be used. | Specified URL can't be used. |
+<!-- vale gitlab.Possessive = YES -->
### Acronyms
If you use an acronym, spell it out on first use on a page. You do not need to spell it out more than once on a page.
When possible, try to avoid acronyms in headings.
+### Numbers
+
+When using numbers in text, spell out zero through nine, and use numbers for 10 and greater. For details, see the [Microsoft Style Guide](https://docs.microsoft.com/en-us/style-guide/numbers).
+
## Text
- [Write in Markdown](#markdown).
@@ -1626,7 +1615,7 @@ the section. The version information must:
- Be surrounded by blank lines.
- Start with `>`. If there are multiple bullets, each line must start with `> -`.
- The string must include these words in this order (capitalization doesn't matter):
- - `introduced`, `deprecated`, `changed`, `moved`, `recommended` (as in the
+ - `introduced`, `enabled`, `deprecated`, `changed`, `moved`, `recommended` (as in the
[feature flag documentation](../feature_flags.md)), `removed`, or `renamed`
- `in` or `to`
- `GitLab`
@@ -1667,24 +1656,6 @@ If a feature is moved to another tier:
> - [Moved](<link-to-issue>) from GitLab Premium to GitLab Free in 12.0.
```
-If a feature is deprecated, include a link to a replacement (when available):
-
-```markdown
-> - [Deprecated](<link-to-issue>) in GitLab 11.3. Replaced by [meaningful text](<link-to-appropriate-documentation>).
-```
-
-You can also describe the replacement in surrounding text, if available. If the
-deprecation isn't obvious in existing text, you may want to include a warning:
-
-```markdown
-WARNING:
-This feature was [deprecated](link-to-issue) in GitLab 12.3 and replaced by
-[Feature name](link-to-feature-documentation).
-```
-
-In the first major GitLab version after the feature was deprecated, be sure to
-remove information about that deprecated feature.
-
#### Inline version text
If you're adding content to an existing topic, you can add version information
@@ -1784,6 +1755,47 @@ To view historical information about a feature, review GitLab
[release posts](https://about.gitlab.com/releases/), or search for the issue or
merge request where the work was done.
+### Deprecated features
+
+When a feature is deprecated, add `(DEPRECATED)` to the page title or to
+the heading of the section documenting the feature, immediately before
+the tier badge:
+
+```markdown
+<!-- Page title example: -->
+# Feature A (DEPRECATED) **(ALL TIERS)**
+
+<!-- Doc section example: -->
+## Feature B (DEPRECATED) **(PREMIUM SELF)**
+```
+
+Add the deprecation to the version history note (you can include a link
+to a replacement when available):
+
+```markdown
+> - [Deprecated](<link-to-issue>) in GitLab 11.3. Replaced by [meaningful text](<link-to-appropriate-documentation>).
+```
+
+You can also describe the replacement in surrounding text, if available. If the
+deprecation isn't obvious in existing text, you may want to include a warning:
+
+```markdown
+WARNING:
+This feature was [deprecated](link-to-issue) in GitLab 12.3 and replaced by
+[Feature name](link-to-feature-documentation).
+```
+
+If you add `(DEPRECATED)` to the page's title and the document is linked from the docs
+navigation, either remove the page from the nav or update the nav item to include the
+same text before the feature name:
+
+```yaml
+ - doc_title: (DEPRECATED) Feature A
+```
+
+In the first major GitLab version after the feature was deprecated, be sure to
+remove information about that deprecated feature.
+
## Products and features
Refer to the information in this section when describing products and features
diff --git a/doc/development/documentation/styleguide/word_list.md b/doc/development/documentation/styleguide/word_list.md
index 9c375379685..dc3dcba0c95 100644
--- a/doc/development/documentation/styleguide/word_list.md
+++ b/doc/development/documentation/styleguide/word_list.md
@@ -25,6 +25,13 @@ Try to avoid **`@mention`**. Say **mention** instead, and consider linking to th
[mentions topic](../../../user/discussions/index.md#mentions).
Don't use backticks.
+## 2FA, two-factor authentication
+
+Spell out **two-factor authentication** in sentence case for the first use and in section headings, and **2FA**
+thereafter. If the first word in a sentence, do not capitalize `factor` or `authentication`. For example:
+
+- Two-factor authentication (2FA) helps secure your account. Set up 2FA when you first log in.
+
## above
Try to avoid using **above** when referring to an example or table in a documentation page. If required, use **previous** instead. For example:
@@ -182,6 +189,11 @@ Use **check out** as a verb. For the Git command, use `checkout`.
CI/CD is always uppercase. No need to spell it out on first use.
+## CI/CD minutes
+
+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).
+
## click
Do not use **click**. Instead, use **select** with buttons, links, menu items, and lists.
@@ -197,11 +209,19 @@ Use **confirmation dialog** to describe the dialog box that asks you to confirm
- On the confirmation dialog, select **OK**.
+## Container Registry
+
+Use title case for the GitLab Container Registry.
+
## currently
Do not use **currently** when talking about the product or its features. The documentation describes the product as it is today.
([Vale](../testing.md#vale) rule: [`CurrentStatus.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/CurrentStatus.yml))
+## Dependency Proxy
+
+Use title case for the GitLab Dependency Proxy.
+
## deploy board
Use lowercase for **deploy board**.
@@ -614,6 +634,10 @@ When writing about the Owner role:
Do not use **Owner permissions**. A user who is assigned the Owner role has a set of associated permissions.
+## Package Registry
+
+Use title case for the GitLab Package Registry.
+
## permissions
Do not use [**roles**](#roles) and **permissions** interchangeably. Each user is assigned a role. Each role includes a set of permissions.
@@ -634,6 +658,10 @@ Use **press** when talking about keyboard keys. For example:
Do not use profanity. Doing so may negatively affect other users and contributors, which is contrary to the GitLab value of [Diversity, Inclusion, and Belonging](https://about.gitlab.com/handbook/values/#diversity-inclusion).
+## push rules
+
+Use lowercase for **push rules**.
+
## Reporter
When writing about the Reporter role:
@@ -825,6 +853,10 @@ You **turn on** or **turn off** a toggle. For example:
- Turn on the **blah** toggle.
+## TFA, two-factor authentication
+
+Use [**2FA** and **two-factor authentication**](#2fa-two-factor-authentication) instead.
+
## type
Do not use **type** if you can avoid it. Use **enter** instead.
diff --git a/doc/development/documentation/testing.md b/doc/development/documentation/testing.md
index 13648a7c710..134183a0e75 100644
--- a/doc/development/documentation/testing.md
+++ b/doc/development/documentation/testing.md
@@ -234,15 +234,8 @@ As a general guideline, the lower the score, the more readable the documentation
For example, a page that scores `12` before a set of changes, and `9` after, indicates an iterative improvement to readability. The score is not an exact science, but is meant to help indicate the
general complexity level of the page.
-The readability score is calculated by using the following formula:
-
-```plaintext
-(.39 x ASL) + (11.8 x ASW) – 15.59
-```
-
-- `ASL` is average sentence length (the number of words divided by the number of sentences).
-- `ASW` is the average number of syllables per word (the number of syllables divided by the number of words).
-- The score excludes headings, code blocks, and lists.
+The readability score is calculated based on the number of words per sentence, and the number
+of syllables per word. For more information, see [the Vale documentation](https://docs.errata.ai/vale/styles#metric).
### Install linters
diff --git a/doc/development/ee_features.md b/doc/development/ee_features.md
index 70d7ea7c1a5..9f705f2c6f1 100644
--- a/doc/development/ee_features.md
+++ b/doc/development/ee_features.md
@@ -23,7 +23,33 @@ when no license is active. So EE features always should be guarded by
`project.feature_available?` or `group.licensed_feature_available?` (or
`License.feature_available?` if it is a system-wide feature).
-Frontend features should be guarded by pushing a flag from the backend by [using `push_licensed_feature`](licensed_feature_availability.md#restricting-frontend-features), and checked using `this.glFeatures.someFeature` in the frontend.
+Frontend features should be guarded by pushing a flag from the backend by [using `push_licensed_feature`](licensed_feature_availability.md#restricting-frontend-features), and checked using `this.glFeatures.someFeature` in the frontend. For example:
+
+```html
+<script>
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+
+export default {
+ mixins: [glFeatureFlagMixin()],
+ components: {
+ EEComponent: () => import('ee_component/components/test.vue'),
+ },
+ computed: {
+ shouldRenderComponent() {
+ return this.glFeatures.myEEFeature;
+ }
+ },
+};
+</script>
+
+<template>
+ <div>
+ <ee-component v-if="shouldRenderComponent"/>
+ </div>
+</template>
+```
+
+Look in `ee/app/models/license.rb` for the names of the licensed features.
CE specs should remain untouched as much as possible and extra specs
should be added for EE. Licensed features can be stubbed using the
diff --git a/doc/development/emails.md b/doc/development/emails.md
index f99b914e2de..811619bb0ff 100644
--- a/doc/development/emails.md
+++ b/doc/development/emails.md
@@ -139,6 +139,44 @@ These are the only valid legacy formats for an email handler:
In GitLab, the handler for the Service Desk feature is `path/to/project`.
+### MailRoom Gem updates
+
+We use [`gitlab-mail_room`](https://gitlab.com/gitlab-org/gitlab-mail_room), a
+fork of [`MailRoom`](https://github.com/tpitale/mail_room/), to ensure
+that we can make updates quickly to the gem if necessary. We try to upstream
+changes as soon as possible and keep the two projects in sync.
+
+Updating the `gitlab-mail_room` dependency in `Gemfile` is deprecated at
+the moment in favor of updating the version in
+[Omnibus](https://gitlab.com/gitlab-org/omnibus-gitlab/-/blob/master/config/software/mail_room.rb)
+(see [example merge request](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/5816))
+and Helm Chart configuration (see [example merge request](https://gitlab.com/gitlab-org/build/CNG/-/merge_requests/854)).
+
+#### Rationale
+
+This was done because to avoid [thread deadlocks](https://github.com/ruby/net-imap/issues/14), `MailRoom` needs
+an updated version of the `net-imap` gem. However, this [version of the net-imap cannot be installed by an unprivileged
+user](https://github.com/ruby/net-imap/issues/14) due to [an error installing the digest
+gem](https://github.com/ruby/digest/issues/14). [This bug in the Ruby interpreter](https://bugs.ruby-lang.org/issues/17761) was fixed in Ruby
+3.0.2.
+
+Updating the gem directly in the GitLab Rails `Gemfile` caused a [production incident](https://gitlab.com/gitlab-com/gl-infra/production/-/issues/4053)
+since Kubernetes pods do not run as privileged users.
+
+Note that Omnibus GitLab runs `/opt/gitlab/embedded/bin/mail_room`
+instead of `bundle exec rake` to avoid loading the older version. With a
+Kubernetes install, the MailRoom version has always been explicitly set
+in the Helm Chart configuration rather than the `Gemfile`.
+
+#### Preserving backwards compatibility
+
+Removing the `Gemfile` would break incoming e-mail processing for source
+installs. For now, source installs are advised to upgrade manually to
+the version specified in Omnibus and run `bin/mail_room` directly as
+done with Omnibus.
+
+We can reconsider this deprecation once we upgrade to Ruby 3.0.
+
---
[Return to Development documentation](index.md)
diff --git a/doc/development/event_store.md b/doc/development/event_store.md
new file mode 100644
index 00000000000..7f2b9c86d27
--- /dev/null
+++ b/doc/development/event_store.md
@@ -0,0 +1,292 @@
+---
+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
+---
+
+# GitLab EventStore
+
+## Background
+
+The monolithic GitLab project is becoming larger and more domains are being defined.
+As a result, these domains are becoming entangled with each others due to temporal coupling.
+
+An emblematic example is the [`PostReceive`](https://gitlab.com/gitlab-org/gitlab/blob/master/app/workers/post_receive.rb)
+worker where a lot happens across multiple domains. If a new behavior reacts to
+a new commit being pushed, then we add code somewhere in `PostReceive` or its sub-components
+(`Git::ProcessRefChangesService`, for example).
+
+This type of architecture:
+
+- Is a violation of the Single Responsibility Principle.
+- Increases the risk of adding code to a codebase you are not familiar with.
+ There may be nuances you don't know about which may introduce bugs or a performance degradation.
+- Violates domain boundaries. Inside a specific namespace (for example `Git::`) we suddenly see
+ classes from other domains chiming in (like `Ci::` or `MergeRequests::`).
+
+## What is EventStore?
+
+`Gitlab:EventStore` is a basic pub-sub system built on top of the existing Sidekiq workers and observability we have today.
+We use this system to apply an event-driven approach when modeling a domain while keeping coupling
+to a minimum.
+
+This essentially leaves the existing Sidekiq workers as-is to perform asynchronous work but inverts
+the dependency.
+
+### EventStore example
+
+When a CI pipeline is created we update the head pipeline for any merge request matching the
+pipeline's `ref`. The merge request can then display the status of the latest pipeline.
+
+#### Without the EventStore
+
+We change `Ci::CreatePipelineService` and add logic (like an `if` statement) to check if the
+pipeline is created. Then we schedule a worker to run some side-effects for the `MergeRequests::` domain.
+
+This style violates the [Open-Closed Principle](https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle)
+and unnecessarily add side-effects logic from other domains, increasing coupling:
+
+```mermaid
+graph LR
+ subgraph ci[CI]
+ cp[CreatePipelineService]
+ end
+
+ subgraph mr[MergeRequests]
+ upw[UpdateHeadPipelineWorker]
+ end
+
+ subgraph no[Namespaces::Onboarding]
+ pow[PipelinesOnboardedWorker]
+ end
+
+ cp -- perform_async --> upw
+ cp -- perform_async --> pow
+```
+
+#### With the EventStore
+
+`Ci::CreatePipelineService` publishes an event `Ci::PipelineCreatedEvent` and its responsibility stops here.
+
+The `MergeRequests::` domain can subscribe to this event with a worker `MergeRequests::UpdateHeadPipelineWorker`, so:
+
+- Side-effects are scheduled asynchronously and don't impact the main business transaction that
+ emits the domain event.
+- More side-effects can be added without modifying the main business transaction.
+- We can clearly see what domains are involved and their ownership.
+- We can identify what events occur in the system because they are explicitly declared.
+
+With `Gitlab::EventStore` there is still coupling between the subscriber (Sidekiq worker) and the schema of the domain event.
+This level of coupling is much smaller than having the main transaction (`Ci::CreatePipelineService`) coupled to:
+
+- multiple subscribers.
+- multiple ways of invoking subscribers (including conditional invocations).
+- multiple ways of passing parameters.
+
+```mermaid
+graph LR
+ subgraph ci[CI]
+ cp[CreatePipelineService]
+ cp -- publish --> e[PipelineCreateEvent]
+ end
+
+ subgraph mr[MergeRequests]
+ upw[UpdateHeadPipelineWorker]
+ end
+
+ subgraph no[Namespaces::Onboarding]
+ pow[PipelinesOnboardedWorker]
+ end
+
+ upw -. subscribe .-> e
+ pow -. subscribe .-> e
+```
+
+Each subscriber, being itself a Sidekiq worker, can specify any attributes that are related
+to the type of work they are responsible for. For example, one subscriber could define
+`urgency: high` while another one less critical could set `urgency: low`.
+
+The EventStore is only an abstraction that allows us to have Dependency Inversion. This helps
+separating a business transaction from side-effects (often executed in other domains).
+
+When an event is published, the EventStore calls `perform_async` on each subscribed worker,
+passing in the event information as arguments. This essentially schedules a Sidekiq job on each
+subscriber's queue.
+
+This means that nothing else changes with regards to how subscribers work, as they are just
+Sidekiq workers. For example: if a worker (subscriber) fails to execute a job, the job is put
+back into Sidekiq to be retried.
+
+## EventStore advantages
+
+- Subscribers (Sidekiq workers) can be set to run quicker by changing the worker weight
+ if the side-effect is critical.
+- Automatically enforce the fact that side-effects run asynchronously.
+ This makes it safe for other domains to subscribe to events without affecting the performance of the
+ main business transaction.
+
+## Define an event
+
+An `Event` object represents a domain event that occurred in a bounded context.
+Notify other bounded contexts about something
+that happened by publishing events, so that they can react to it.
+
+Define new event classes under `app/events/<namespace>/` with a name representing something that happened in the past:
+
+```ruby
+class Ci::PipelineCreatedEvent < Gitlab::EventStore::Event
+ def schema
+ {
+ 'type' => 'object',
+ 'required' => ['pipeline_id'],
+ 'properties' => {
+ 'pipeline_id' => { 'type' => 'integer' },
+ 'ref' => { 'type' => 'string' }
+ }
+ }
+ end
+end
+```
+
+The schema is validated immediately when we initialize the event object so we can ensure that
+publishers follow the contract with the subscribers.
+
+We recommend using optional properties as much as possible, which require fewer rollouts for schema changes.
+However, `required` properties could be used for unique identifiers of the event's subject. For example:
+
+- `pipeline_id` can be a required property for a `Ci::PipelineCreatedEvent`.
+- `project_id` can be a required property for a `Projects::ProjectDeletedEvent`.
+
+Publish only properties that are needed by the subscribers without tailoring the payload to specific subscribers.
+The payload should fully represent the event and not contain loosely related properties. For example:
+
+```ruby
+Ci::PipelineCreatedEvent.new(data: {
+ pipeline_id: pipeline.id,
+ # unless all subscribers need merge request IDs,
+ # this is data that can be fetched by the subscriber.
+ merge_request_ids: pipeline.all_merge_requests.pluck(:id)
+})
+```
+
+Publishing events with more properties provides the subscribers with the data
+they need in the first place. Otherwise subscribers have to fetch the additional data from the database.
+However, this can lead to continuous changes to the schema and possibly adding properties that may not
+represent the single source of truth.
+It's best to use this technique as a performance optimization. For example: when an event has many
+subscribers that all fetch the same data again from the database.
+
+### Update the schema
+
+Changes to the schema require multiple rollouts. While the new version is being deployed:
+
+- Existing publishers can publish events using the old version.
+- Existing subscribers can consume events using the old version.
+- Events get persisted in the Sidekiq queue as job arguments, so we could have 2 versions of the schema during deployments.
+
+As changing the schema ultimately impacts the Sidekiq arguments, please refer to our
+[Sidekiq style guide](sidekiq_style_guide.md#changing-the-arguments-for-a-worker) with regards to multiple rollouts.
+
+#### Add properties
+
+1. Rollout 1:
+ - Add new properties as optional (not `required`).
+ - Update the subscriber so it can consume events with and without the new properties.
+1. Rollout 2:
+ - Change the publisher to provide the new property
+1. Rollout 3: (if the property should be `required`):
+ - Change the schema and the subscriber code to always expect it.
+
+#### Remove properties
+
+1. Rollout 1:
+ - If the property is `required`, make it optional.
+ - Update the subscriber so it does not always expect the property.
+1. Rollout 2:
+ - Remove the property from the event publishing.
+ - Remove the code from the subscriber that processes the property.
+
+#### Other changes
+
+For other changes, like renaming a property, use the same steps:
+
+1. Remove the old property
+1. Add the new property
+
+## Publish an event
+
+To publish the event from the [previous example](#define-an-event):
+
+```ruby
+Gitlab::EventStore.publish(
+ Ci::PipelineCreatedEvent.new(data: { pipeline_id: pipeline.id })
+)
+```
+
+## Create a subscriber
+
+A subscriber is a Sidekiq worker that includes the `Gitlab::EventStore::Subscriber` module.
+This module takes care of the `perform` method and provides a better abstraction to handle
+the event safely via the `handle_event` method. For example:
+
+```ruby
+module MergeRequests
+ class UpdateHeadPipelineWorker
+ include ApplicationWorker
+ include Gitlab::EventStore::Subscriber
+
+ def handle_event(event)
+ Ci::Pipeline.find_by_id(event.data[:pipeline_id]).try do |pipeline|
+ # ...
+ end
+ end
+ end
+end
+```
+
+## Register the subscriber to the event
+
+To subscribe the worker to a specific event in `lib/gitlab/event_store.rb`,
+add a line like this to the `Gitlab::EventStore.configure!` method:
+
+```ruby
+module Gitlab
+ module EventStore
+ def self.configure!
+ Store.new.tap do |store|
+ # ...
+
+ store.subscribe ::MergeRequests::UpdateHeadPipelineWorker, to: ::Ci::PipelineCreatedEvent
+
+ # ...
+ end
+ end
+ end
+end
+```
+
+Subscriptions are stored in memory when the Rails app is loaded and they are immediately frozen.
+It's not possible to modify subscriptions at runtime.
+
+### Conditional dispatch of events
+
+A subscription can specify a condition when to accept an event:
+
+```ruby
+store.subscribe ::MergeRequests::UpdateHeadPipelineWorker,
+ to: ::Ci::PipelineCreatedEvent,
+ if: -> (event) { event.data[:merge_request_id].present? }
+```
+
+This tells the event store to dispatch `Ci::PipelineCreatedEvent`s to the subscriber if
+the condition is met.
+
+This technique can avoid scheduling Sidekiq jobs if the subscriber is interested in a
+small subset of events.
+
+WARNING:
+When using conditional dispatch it must contain only cheap conditions because they are
+executed synchronously every time the given event is published.
+
+For complex conditions it's best to subscribe to all the events and then handle the logic
+in the `handle_event` method of the subscriber worker.
diff --git a/doc/development/experiment_guide/experimentation.md b/doc/development/experiment_guide/experimentation.md
index b242646c549..bb782af80cc 100644
--- a/doc/development/experiment_guide/experimentation.md
+++ b/doc/development/experiment_guide/experimentation.md
@@ -1,402 +1,9 @@
---
-stage: Growth
-group: Activation
-info: 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: 'gitlab_experiment.md'
+remove_date: '2022-04-13'
---
-# Create an A/B test with `Experimentation Module`
+This document was moved to [another location](gitlab_experiment.md).
-NOTE:
-We recommend using [GLEX](gitlab_experiment.md) for new experiments.
-
-## Implement the experiment
-
-1. Add the experiment to the `Gitlab::Experimentation::EXPERIMENTS` hash in
- [`experimentation.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib%2Fgitlab%2Fexperimentation.rb):
-
- ```ruby
- EXPERIMENTS = {
- other_experiment: {
- #...
- },
- # Add your experiment here:
- signup_flow: {
- tracking_category: 'Growth::Activation::Experiment::SignUpFlow' # Used for providing the category when setting up tracking data
- }
- }.freeze
- ```
-
-1. Use the experiment in the code.
-
- Experiments can be performed on a `subject`. The provided `subject` should
- respond to `to_global_id` or `to_s`.
- The resulting string is bucketed and assigned to either the control or the
- experimental group, so you must always provide the same `subject`
- for an experiment to have the same experience.
-
- 1. Use this standard for the experiment in a controller:
-
- - Experiment run for a user:
-
- ```ruby
- class ProjectController < ApplicationController
- def show
- # experiment_enabled?(:experiment_key) is also available in views and helpers
- if experiment_enabled?(:signup_flow, subject: current_user)
- # render the experiment
- else
- # render the original version
- end
- end
- end
- ```
-
- - Experiment run for a namespace:
-
- ```ruby
- if experiment_enabled?(:signup_flow, subject: namespace)
- # experiment code
- else
- # control code
- end
- ```
-
- When no subject is given, it falls back to a cookie that gets set and is consistent until
- the cookie gets deleted.
-
- ```ruby
- class RegistrationController < ApplicationController
- def show
- # falls back to a cookie
- if experiment_enabled?(:signup_flow)
- # render the experiment
- else
- # render the original version
- end
- end
- end
- ```
-
- 1. Make the experiment available to the frontend in a controller. This example
- checks whether the experiment is enabled and pushes the result to the frontend:
-
- ```ruby
- before_action do
- push_frontend_experiment(:signup_flow, subject: current_user)
- end
- ```
-
- You can check the state of the feature flag in JavaScript:
-
- ```javascript
- import { isExperimentEnabled } from '~/experimentation';
-
- if ( isExperimentEnabled('signupFlow') ) {
- // ...
- }
- ```
-
-You can also run an experiment outside of the controller scope, such as in a worker:
-
-```ruby
-class SomeWorker
- def perform
- # Check if the experiment is active at all (the percentage_of_time_value > 0)
- return unless Gitlab::Experimentation.active?(:experiment_key)
-
- # Since we cannot access cookies in a worker, we need to bucket models
- # based on a unique, unchanging attribute instead.
- # It is therefore necessary to always provide the same subject.
- if Gitlab::Experimentation.in_experiment_group?(:experiment_key, subject: user)
- # execute experimental code
- else
- # execute control code
- end
- end
-end
-```
-
-## Implement tracking events
-
-To determine whether the experiment is a success or not, we must implement tracking events
-to acquire data for analyzing. We can send events to Snowplow via either the backend or frontend.
-Read the [product intelligence guide](https://about.gitlab.com/handbook/product/product-intelligence-guide/) for more details.
-
-### Track backend events
-
-The framework provides a helper method that is available in controllers:
-
-```ruby
-before_action do
- track_experiment_event(:signup_flow, 'action', 'value', subject: current_user)
-end
-```
-
-To test it:
-
-```ruby
-context 'when the experiment is active and the user is in the experimental group' do
- before do
- stub_experiment(signup_flow: true)
- stub_experiment_for_subject(signup_flow: true)
- end
-
- it 'tracks an event', :snowplow do
- subject
-
- expect_snowplow_event(
- category: 'Growth::Activation::Experiment::SignUpFlow',
- action: 'action',
- value: 'value',
- label: 'experimentation_subject_id',
- property: 'experimental_group'
- )
- end
-end
-```
-
-### Track frontend events
-
-The framework provides a helper method that is available in controllers:
-
-```ruby
-before_action do
- push_frontend_experiment(:signup_flow, subject: current_user)
- frontend_experimentation_tracking_data(:signup_flow, 'action', 'value', subject: current_user)
-end
-```
-
-This pushes tracking data to `gon.experiments` and `gon.tracking_data`.
-
-```ruby
-expect(Gon.experiments['signupFlow']).to eq(true)
-
-expect(Gon.tracking_data).to eq(
- {
- category: 'Growth::Activation::Experiment::SignUpFlow',
- action: 'action',
- value: 'value',
- label: 'experimentation_subject_id',
- property: 'experimental_group'
- }
-)
-```
-
-To track it:
-
-```javascript
-import { isExperimentEnabled } from '~/lib/utils/experimentation';
-import Tracking from '~/tracking';
-
-document.addEventListener('DOMContentLoaded', () => {
- const signupFlowExperimentEnabled = isExperimentEnabled('signupFlow');
-
- if (signupFlowExperimentEnabled && gon.tracking_data) {
- const { category, action, ...data } = gon.tracking_data;
-
- Tracking.event(category, action, data);
- }
-}
-```
-
-To test it in Jest:
-
-```javascript
-import { withGonExperiment } from 'helpers/experimentation_helper';
-import Tracking from '~/tracking';
-
-describe('event tracking', () => {
- describe('with tracking data', () => {
- withGonExperiment('signupFlow');
-
- beforeEach(() => {
- jest.spyOn(Tracking, 'event').mockImplementation(() => {});
-
- gon.tracking_data = {
- category: 'Growth::Activation::Experiment::SignUpFlow',
- action: 'action',
- value: 'value',
- label: 'experimentation_subject_id',
- property: 'experimental_group'
- };
- });
-
- it('should track data', () => {
- performAction()
-
- expect(Tracking.event).toHaveBeenCalledWith(
- 'Growth::Activation::Experiment::SignUpFlow',
- 'action',
- {
- value: 'value',
- label: 'experimentation_subject_id',
- property: 'experimental_group'
- },
- );
- });
- });
-});
-```
-
-## Record experiment user
-
-In addition to the anonymous tracking of events, we can also record which users
-have participated in which experiments, and whether they were given the control
-experience or the experimental experience.
-
-The `record_experiment_user` helper method is available to all controllers, and it
-enables you to record these experiment participants (the current user) and which
-experience they were given:
-
-```ruby
-before_action do
- record_experiment_user(:signup_flow)
-end
-```
-
-Subsequent calls to this method for the same experiment and the same user have no
-effect unless the user is then enrolled into a different experience. This happens
-when we roll out the experimental experience to a greater percentage of users.
-
-This data is completely separate from the [events tracking data](#implement-tracking-events).
-They are not linked together in any way.
-
-### Add context
-
-You can add arbitrary context data in a hash which gets stored as part of the experiment
-user record. New calls to the `record_experiment_user` with newer contexts are merged
-deeply into the existing context.
-
-This data can then be used by data analytics dashboards.
-
-```ruby
-before_action do
- record_experiment_user(:signup_flow, foo: 42, bar: { a: 22})
- # context is { "foo" => 42, "bar" => { "a" => 22 }}
-end
-
-# Additional contexts for newer record calls are merged deeply
-record_experiment_user(:signup_flow, foo: 40, bar: { b: 2 }, thor: 3)
-# context becomes { "foo" => 40, "bar" => { "a" => 22, "b" => 2 }, "thor" => 3}
-```
-
-## Record experiment conversion event
-
-Along with the tracking of backend and frontend events and the
-[recording of experiment participants](#record-experiment-user), we can also record
-when a user performs the desired conversion event action. For example:
-
-- **Experimental experience:** Show an in-product nudge to test if the change causes more
- people to sign up for trials.
-- **Conversion event:** The user starts a trial.
-
-The `record_experiment_conversion_event` helper method is available to all controllers.
-Use it to record the conversion event for the current user, regardless of whether
-the user is in the control or experimental group:
-
-```ruby
-before_action do
- record_experiment_conversion_event(:signup_flow)
-end
-```
-
-Note that the use of this method requires that we have first
-[recorded the user](#record-experiment-user) as being part of the experiment.
-
-## Enable the experiment
-
-After all merge requests have been merged, use [ChatOps](../../ci/chatops/index.md) in the
-[appropriate channel](../feature_flags/controls.md#communicate-the-change) to start the experiment for 10% of the users.
-The feature flag should have the name of the experiment with the `_experiment_percentage` suffix appended.
-For visibility, share any commands run against production in the `#s_growth` channel:
-
- ```shell
- /chatops run feature set signup_flow_experiment_percentage 10
- ```
-
- If you notice issues with the experiment, you can disable the experiment by removing the feature flag:
-
- ```shell
- /chatops run feature delete signup_flow_experiment_percentage
- ```
-
-## Add user to experiment group manually
-
-To force the application to add your current user into the experiment group,
-add a query string parameter to the path where the experiment runs. If you add the
-query string parameter, the experiment works only for this request, and doesn't work
-after following links or submitting forms.
-
-For example, to forcibly enable the `EXPERIMENT_KEY` experiment, add `force_experiment=EXPERIMENT_KEY`
-to the URL:
-
-```shell
-https://gitlab.com/<EXPERIMENT_ENTRY_URL>?force_experiment=<EXPERIMENT_KEY>
-```
-
-## Add user to experiment group with a cookie
-
-You can force the current user into the experiment group for `<EXPERIMENT_KEY>`
-during the browser session by using your browser's developer tools:
-
-```javascript
-document.cookie = "force_experiment=<EXPERIMENT_KEY>; path=/";
-```
-
-Use a comma to list more than one experiment to be forced:
-
-```javascript
-document.cookie = "force_experiment=<EXPERIMENT_KEY>,<ANOTHER_EXPERIMENT_KEY>; path=/";
-```
-
-To clear the experiments, unset the `force_experiment` cookie:
-
-```javascript
-document.cookie = "force_experiment=; path=/";
-```
-
-## Testing and test helpers
-
-### RSpec
-
-Use the following in RSpec to mock the experiment:
-
-```ruby
-context 'when the experiment is active' do
- before do
- stub_experiment(signup_flow: true)
- end
-
- context 'when the user is in the experimental group' do
- before do
- stub_experiment_for_subject(signup_flow: true)
- end
-
- it { is_expected.to do_experimental_thing }
- end
-
- context 'when the user is in the control group' do
- before do
- stub_experiment_for_subject(signup_flow: false)
- end
-
- it { is_expected.to do_control_thing }
- end
-end
-```
-
-### Jest
-
-Use the following in Jest to mock the experiment:
-
-```javascript
-import { withGonExperiment } from 'helpers/experimentation_helper';
-
-describe('given experiment is enabled', () => {
- withGonExperiment('signupFlow');
-
- it('should do the experimental thing', () => {
- expect(wrapper.find('.js-some-experiment-triggered-element')).toEqual(expect.any(Element));
- });
-});
-```
+<!-- 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 -->
diff --git a/doc/development/experiment_guide/gitlab_experiment.md b/doc/development/experiment_guide/gitlab_experiment.md
index 288823bb41f..36d2a4f6fbf 100644
--- a/doc/development/experiment_guide/gitlab_experiment.md
+++ b/doc/development/experiment_guide/gitlab_experiment.md
@@ -71,6 +71,8 @@ class Cached cached
## Implement an experiment
+[Examples](https://gitlab.com/gitlab-org/growth/growth/-/wikis/GLEX-Framework-code-examples)
+
Start by generating a feature flag using the `bin/feature-flag` command as you
normally would for a development feature flag, making sure to use `experiment` for
the type. For the sake of documentation let's name our feature flag (and experiment)
diff --git a/doc/development/experiment_guide/index.md b/doc/development/experiment_guide/index.md
index 9937cb2ebd1..8d62f92e0b9 100644
--- a/doc/development/experiment_guide/index.md
+++ b/doc/development/experiment_guide/index.md
@@ -48,10 +48,7 @@ If the experiment is successful and becomes part of the product, any items that
For more information, see [Implementing an A/B/n experiment using GLEX](gitlab_experiment.md).
-There are still some longer running experiments using the [`Exerimentation Module`](experimentation.md).
-
-Both approaches use [experiment](../feature_flags/index.md#experiment-type) feature flags.
-`GLEX` is the preferred option for new experiments.
+This uses [experiment](../feature_flags/index.md#experiment-type) feature flags.
### Add new icons and illustrations for experiments
diff --git a/doc/development/fe_guide/style/javascript.md b/doc/development/fe_guide/style/javascript.md
index a2035eb1b55..f22e3ea6395 100644
--- a/doc/development/fe_guide/style/javascript.md
+++ b/doc/development/fe_guide/style/javascript.md
@@ -189,24 +189,6 @@ are loaded dynamically with webpack.
Do not use `innerHTML`, `append()` or `html()` to set content. It opens up too many
vulnerabilities.
-## Avoid single-line conditional statements
-
-Indentation is important when scanning code as it gives a quick indication of the existence of branches, loops, and return points.
-This can help to quickly understand the control flow.
-
-```javascript
-// bad
-if (isThingNull) return '';
-
-if (isThingNull)
- return '';
-
-// good
-if (isThingNull) {
- return '';
-}
-```
-
## ESLint
ESLint behavior can be found in our [tooling guide](../tooling.md).
diff --git a/doc/development/fe_guide/vue3_migration.md b/doc/development/fe_guide/vue3_migration.md
index 2b783eb21b7..6e994d5e95d 100644
--- a/doc/development/fe_guide/vue3_migration.md
+++ b/doc/development/fe_guide/vue3_migration.md
@@ -37,32 +37,8 @@ If you need cross-component communication (between different Vue apps), then per
**What to use instead**
-Vue documentation recommends using the [mitt](https://github.com/developit/mitt) library. It's relatively small (200 bytes, compressed) and has a clear API:
+We have created a factory that you can use to instantiate a new [mitt](https://github.com/developit/mitt)-like event hub.
-```javascript
-import mitt from 'mitt'
-
-const emitter = mitt()
-
-// listen to an event
-emitter.on('foo', e => console.log('foo', e) )
-
-// listen to all events
-emitter.on('*', (type, e) => console.log(type, e) )
-
-// fire an event
-emitter.emit('foo', { a: 'b' })
-
-// working with handler references:
-function onFoo() {}
-
-emitter.on('foo', onFoo) // listen
-emitter.off('foo', onFoo) // unlisten
-```
-
-**Event hub factory**
-
-We have created a factory that you can use to instantiate a new mitt-based event hub.
This makes it easier to migrate existing event hubs to the new recommended approach, or
to create new ones.
diff --git a/doc/development/feature_flags/controls.md b/doc/development/feature_flags/controls.md
index 4843b58c3fd..6bf5be23ace 100644
--- a/doc/development/feature_flags/controls.md
+++ b/doc/development/feature_flags/controls.md
@@ -69,7 +69,7 @@ Slack channel for the stage the feature is relevant to. For example, use the
`#s_monitor` channel for features developed by the Monitor stage, Health
group.
-To enable a feature for 25% of all users, run the following in Slack:
+To enable a feature for 25% of the time, run the following in Slack:
```shell
/chatops run feature set new_navigation_bar 25 --dev
@@ -303,6 +303,19 @@ and reduces confidence in our testing suite covering all possible combinations.
Additionally, a feature flag overwritten in some of the environments can result
in undefined and untested system behavior.
+`development` type feature flags should have a short life-cycle because their purpose
+is for rolling out a persistent change. `development` feature flags that are older
+than 2 milestones are reported to engineering managers. The
+[report tool](https://gitlab.com/gitlab-org/gitlab-feature-flag-alert) runs on a
+monthly basis. For example, see [the report for December 2021](https://gitlab.com/gitlab-org/quality/triage-reports/-/issues/5480).
+
+If a `development` feature flag is still present in the codebase after 6 months we should
+take one of the following actions:
+
+- Enable the feature flag by default and remove it.
+- Convert it to an instance, group, or project setting.
+- Revert the changes if it's still disabled and not needed anymore.
+
To remove a feature flag, open **one merge request** to make the changes. In the MR:
1. Add the ~"feature flag" label so release managers are aware the changes are hidden behind a feature flag.
diff --git a/doc/development/feature_flags/index.md b/doc/development/feature_flags/index.md
index 86dc4c73062..820b4bab802 100644
--- a/doc/development/feature_flags/index.md
+++ b/doc/development/feature_flags/index.md
@@ -171,6 +171,7 @@ Each feature flag is defined in a separate YAML file consisting of a number of f
| `default_enabled` | yes | The default state of the feature flag that is strictly validated, with `default_enabled:` passed as an argument. |
| `introduced_by_url` | no | The URL to the Merge Request that introduced the feature flag. |
| `rollout_issue_url` | no | The URL to the Issue covering the feature flag rollout. |
+| `milestone` | no | Milestone in which the feature was added. |
| `group` | no | The [group](https://about.gitlab.com/handbook/product/categories/#devops-stages) that owns the feature flag. |
NOTE:
diff --git a/doc/development/features_inside_dot_gitlab.md b/doc/development/features_inside_dot_gitlab.md
index 3a9decaad69..73ba9cbd674 100644
--- a/doc/development/features_inside_dot_gitlab.md
+++ b/doc/development/features_inside_dot_gitlab.md
@@ -16,7 +16,7 @@ When implementing new features, please refer to these existing features to avoid
- [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`.
-- [GitLab managed apps CI/CD](../user/clusters/applications.md#usage): `.gitlab/managed-apps/config.yaml`.
+- [GitLab managed apps CI/CD](../user/clusters/applications.md#prerequisites): `.gitlab/managed-apps/config.yaml`.
- [Insights](../user/project/insights/index.md#configure-your-insights): `.gitlab/insights.yml`.
- [Service Desk Templates](../user/project/service_desk.md#using-customized-email-templates): `.gitlab/service_desk_templates/`.
- [Web IDE](../user/project/web_ide/#web-ide-configuration-file): `.gitlab/.gitlab-webide.yml`.
diff --git a/doc/development/geo.md b/doc/development/geo.md
index 7d5aae49749..9f5fd674d38 100644
--- a/doc/development/geo.md
+++ b/doc/development/geo.md
@@ -7,8 +7,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Geo (development) **(PREMIUM SELF)**
Geo connects GitLab instances together. One GitLab instance is
-designated as a **primary** node and can be run with multiple
-**secondary** nodes. Geo orchestrates quite a few components that can be seen on
+designated as a **primary** site and can be run with multiple
+**secondary** sites. Geo orchestrates quite a few components that can be seen on
the diagram below and are described in more detail within this document.
![Geo Architecture Diagram](../administration/geo/replication/img/geo_architecture.png)
@@ -22,16 +22,16 @@ Geo handles replication for different components:
- [Uploaded blobs](#uploads-replication): includes anything from images attached on issues
to raw logs and assets from CI.
-With the exception of the Database replication, on a *secondary* node, everything is coordinated
+With the exception of the Database replication, on a *secondary* site, everything is coordinated
by the [Geo Log Cursor](#geo-log-cursor).
### Geo Log Cursor daemon
The [Geo Log Cursor daemon](#geo-log-cursor-daemon) is a separate process running on
-each **secondary** node. It monitors the [Geo Event Log](#geo-event-log)
+each **secondary** site. It monitors the [Geo Event Log](#geo-event-log)
for new events and creates background jobs for each specific event type.
-For example when a repository is updated, the Geo **primary** node creates
+For example when a repository is updated, the Geo **primary** site creates
a Geo event with an associated repository updated event. The Geo Log Cursor daemon
picks the event up and schedules a `Geo::ProjectSyncWorker` job which will
use the `Geo::RepositorySyncService` and `Geo::WikiSyncService` classes
@@ -41,7 +41,7 @@ The Geo Log Cursor daemon can operate in High Availability mode automatically.
The daemon will try to acquire a lock from time to time and once acquired, it
will behave as the *active* daemon.
-Any additional running daemons on the same node, will be in standby
+Any additional running daemons on the same site, will be in standby
mode, ready to resume work if the *active* daemon releases its lock.
We use the [`ExclusiveLease`](https://www.rubydoc.info/github/gitlabhq/gitlabhq/Gitlab/ExclusiveLease) lock type with a small TTL, that is renewed at every
@@ -53,14 +53,14 @@ the lock, it switches to standby mode.
### Database replication
Geo uses [streaming replication](#streaming-replication) to replicate
-the database from the **primary** to the **secondary** nodes. This
-replication gives the **secondary** nodes access to all the data saved
+the database from the **primary** to the **secondary** sites. This
+replication gives the **secondary** sites access to all the data saved
in the database. So users can log in on the **secondary** and read all
-the issues, merge requests, and so on, on the **secondary** node.
+the issues, merge requests, and so on, on the **secondary** site.
### Repository replication
-Geo also replicates repositories. Each **secondary** node keeps track of
+Geo also replicates repositories. Each **secondary** site keeps track of
the state of every repository in the [tracking database](#tracking-database).
There are a few ways a repository gets replicated by the:
@@ -92,7 +92,7 @@ background and it searches the `Geo::ProjectRegistry` model for
projects that need updating. Those projects can be:
- Unsynced: Projects that have never been synced on the **secondary**
- node and so do not exist yet.
+ site and so do not exist yet.
- Updated recently: Projects that have a `last_repository_updated_at`
timestamp that is more recent than the `last_repository_successful_sync_at`
timestamp in the `Geo::ProjectRegistry` model.
@@ -106,7 +106,7 @@ it's successful, we replace the main repository with the newly cloned one.
### Uploads replication
-File uploads are also being replicated to the **secondary** node. To
+File uploads are also being replicated to the **secondary** site. To
track the state of syncing, the `Geo::UploadRegistry` model is used.
#### Upload Registry
@@ -123,7 +123,7 @@ models respectively.
Also similar to the [Repository Sync worker](#repository-sync-worker),
there is a `Geo::FileDownloadDispatchWorker` class that is run
periodically to sync all uploads that aren't synced to the Geo
-**secondary** node yet.
+**secondary** site yet.
Files are copied via HTTP(s) and initiated via the
`/api/v4/geo/transfers/:type/:id` endpoint,
@@ -136,18 +136,18 @@ To authenticate file transfers, each `GeoNode` record has two fields:
- A public access key (`access_key` field).
- A secret access key (`secret_access_key` field).
-The **secondary** node authenticates itself via a [JWT request](https://jwt.io/).
-When the **secondary** node wishes to download a file, it sends an
+The **secondary** site authenticates itself via a [JWT request](https://jwt.io/).
+When the **secondary** site wishes to download a file, it sends an
HTTP request with the `Authorization` header:
```plaintext
Authorization: GL-Geo <access_key>:<JWT payload>
```
-The **primary** node uses the `access_key` field to look up the
-corresponding **secondary** node and decrypts the JWT payload,
+The **primary** site uses the `access_key` field to look up the
+corresponding **secondary** site and decrypts the JWT payload,
which contains additional information to identify the file
-request. This ensures that the **secondary** node downloads the right
+request. This ensures that the **secondary** site downloads the right
file for the right database ID. For example, for an LFS object, the
request must also include the SHA256 sum of the file. An example JWT
payload looks like:
@@ -157,7 +157,7 @@ payload looks like:
```
If the requested file matches the requested SHA256 sum, then the Geo
-**primary** node sends data via the [X-Sendfile](https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/)
+**primary** site sends data via the [X-Sendfile](https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/)
feature, which allows NGINX to handle the file transfer without tying
up Rails or Workhorse.
@@ -168,34 +168,34 @@ involved, otherwise it may fail with an encryption error.
## Git Push to Geo secondary
The Git Push Proxy exists as a functionality built inside the `gitlab-shell` component.
-It is active on a **secondary** node only. It allows the user that has cloned a repository
-from the secondary node to push to the same URL.
+It is active on a **secondary** site only. It allows the user that has cloned a repository
+from the secondary site to push to the same URL.
-Git `push` requests directed to a **secondary** node will be sent over to the **primary** node,
-while `pull` requests will continue to be served by the **secondary** node for maximum efficiency.
+Git `push` requests directed to a **secondary** site will be sent over to the **primary** site,
+while `pull` requests will continue to be served by the **secondary** site for maximum efficiency.
HTTPS and SSH requests are handled differently:
-- With HTTPS, we will give the user a `HTTP 302 Redirect` pointing to the project on the **primary** node.
+- With HTTPS, we will give the user a `HTTP 302 Redirect` pointing to the project on the **primary** site.
The Git client is wise enough to understand that status code and process the redirection.
- With SSH, because there is no equivalent way to perform a redirect, we have to proxy the request.
This is done inside [`gitlab-shell`](https://gitlab.com/gitlab-org/gitlab-shell), by first translating the request
- to the HTTP protocol, and then proxying it to the **primary** node.
+ to the HTTP protocol, and then proxying it to the **primary** site.
The [`gitlab-shell`](https://gitlab.com/gitlab-org/gitlab-shell) daemon knows when to proxy based on the response
from `/api/v4/allowed`. A special `HTTP 300` status code is returned and we execute a "custom action",
specified in the response body. The response contains additional data that allows the proxied `push` operation
-to happen on the **primary** node.
+to happen on the **primary** site.
## Using the Tracking Database
Along with the main database that is replicated, a Geo **secondary**
-node has its own separate [Tracking database](#tracking-database).
+site has its own separate [Tracking database](#tracking-database).
-The tracking database contains the state of the **secondary** node.
+The tracking database contains the state of the **secondary** site.
Any database migration that needs to be run as part of an upgrade
-needs to be applied to the tracking database on each **secondary** node.
+needs to be applied to the tracking database on each **secondary** site.
### Configuration
@@ -223,12 +223,12 @@ projects/attachments/ and so on, in the tracking database and main database.
## Redis
-Redis on the **secondary** node works the same as on the **primary**
-node. It is used for caching, storing sessions, and other persistent
+Redis on the **secondary** site works the same as on the **primary**
+site. It is used for caching, storing sessions, and other persistent
data.
-Redis data replication between **primary** and **secondary** node is
-not used, so sessions and so on, aren't shared between nodes.
+Redis data replication between **primary** and **secondary** site is
+not used, so sessions and so on, aren't shared between sites.
## Object Storage
@@ -244,7 +244,7 @@ ignores items in object storage. Either:
- The object storage layer should take care of its own geographical
replication.
-- All secondary nodes should use the same storage node.
+- All secondary sites should use the same storage site.
## Verification
@@ -252,29 +252,29 @@ ignores items in object storage. Either:
Repositories are verified with a checksum.
-The **primary** node calculates a checksum on the repository. It
+The **primary** site calculates a checksum on the repository. It
basically hashes all Git refs together and stores that hash in the
`project_repository_states` table of the database.
-The **secondary** node does the same to calculate the hash of its
-clone, and compares the hash with the value the **primary** node
+The **secondary** site does the same to calculate the hash of its
+clone, and compares the hash with the value the **primary** site
calculated. If there is a mismatch, Geo will mark this as a mismatch
and the administrator can see this in the [Geo admin panel](../user/admin_area/geo_nodes.md).
## Glossary
-### Primary node
+### Primary site
-A **primary** node is the single node in a Geo setup that read-write
+A **primary** site is the single site in a Geo setup that read-write
capabilities. It's the single source of truth and the Geo
-**secondary** nodes replicate their data from there.
+**secondary** sites replicate their data from there.
-In a Geo setup, there can only be one **primary** node. All
-**secondary** nodes connect to that **primary**.
+In a Geo setup, there can only be one **primary** site. All
+**secondary** sites connect to that **primary**.
-### Secondary node
+### Secondary site
-A **secondary** node is a read-only replica of the **primary** node
+A **secondary** site is a read-only replica of the **primary** site
running in a different geographical location.
### Streaming replication
@@ -287,11 +287,11 @@ Streaming replication depends on the Write Ahead Logs, or WAL. Those
logs are copied over to the replica and replayed there.
Since streaming replication also replicates the schema, the database
-migration do not need to run on the secondary nodes.
+migration do not need to run on the secondary sites.
### Tracking database
-A database on each Geo **secondary** node that keeps state for the node
+A database on each Geo **secondary** site that keeps state for the site
on which it resides. Read more in [Using the Tracking database](#using-the-tracking-database).
## Geo Event Log
@@ -312,7 +312,7 @@ events include:
### Geo Log Cursor
-The process running on the **secondary** node that looks for new
+The process running on the **secondary** site that looks for new
`Geo::EventLog` rows.
## Code features
@@ -327,51 +327,51 @@ Many of these methods are cached using the `RequestStore` class, to
reduce the performance impact of using the methods throughout the
codebase.
-#### Current node
+#### Current site
The class method `.current_node` returns the `GeoNode` record for the
-current node.
+current site.
We use the `host`, `port`, and `relative_url_root` values from
-`gitlab.yml` and search in the database to identify which node we are
+`gitlab.yml` and search in the database to identify which site we are
in (see `GeoNode.current_node`).
#### Primary or secondary
-To determine whether the current node is a **primary** node or a
-**secondary** node use the `.primary?` and `.secondary?` class
+To determine whether the current site is a **primary** site or a
+**secondary** site use the `.primary?` and `.secondary?` class
methods.
-It is possible for these methods to both return `false` on a node when
-the node is not enabled. See [Enablement](#enablement).
+It is possible for these methods to both return `false` on a site when
+the site is not enabled. See [Enablement](#enablement).
#### Geo Database configured?
There is also an additional gotcha when dealing with things that
happen during initialization time. In a few places, we use the
-`Gitlab::Geo.geo_database_configured?` method to check if the node has
+`Gitlab::Geo.geo_database_configured?` method to check if the site has
the tracking database, which only exists on the **secondary**
-node. This overcomes race conditions that could happen during
-bootstrapping of a new node.
+site. This overcomes race conditions that could happen during
+bootstrapping of a new site.
#### Enablement
We consider Geo feature enabled when the user has a valid license with the
-feature included, and they have at least one node defined at the Geo Nodes
+feature included, and they have at least one site defined at the Geo Nodes
screen.
See `Gitlab::Geo.enabled?` and `Gitlab::Geo.license_allows?` methods.
#### Read-only
-All Geo **secondary** nodes are read-only.
+All Geo **secondary** sites are read-only.
The general principle of a [read-only database](verifying_database_capabilities.md#read-only-database)
-applies to all Geo **secondary** nodes. So the
+applies to all Geo **secondary** sites. So the
`Gitlab::Database.read_only?` method will always return `true` on a
-**secondary** node.
+**secondary** site.
-When some write actions are not allowed because the node is a
+When some write actions are not allowed because the site is a
**secondary**, consider adding the `Gitlab::Database.read_only?` or
`Gitlab::Database.read_write?` guard, instead of `Gitlab::Geo.secondary?`.
@@ -393,7 +393,7 @@ that need to be taken care of:
- Verification.
- Cleaner. When sync settings are changed for the secondary site, some resources need to be cleaned up.
- Geo Node Status. We need to provide API endpoints as well as some presentation in the GitLab Admin Area.
-- Health Check. If we can perform some pre-cheÑks and make node unhealthy if something is wrong, we should do that.
+- Health Check. If we can perform some pre-cheÑks and make site unhealthy if something is wrong, we should do that.
The `rake gitlab:geo:check` command has to be updated too.
## History of communication channel
@@ -404,7 +404,7 @@ check here historic decisions and why we moved to new implementations.
### Custom code (GitLab 8.6 and earlier)
In GitLab versions before 8.6, custom code is used to handle
-notification from **primary** node to **secondary** nodes by HTTP
+notification from **primary** site to **secondary** sites by HTTP
requests.
### System hooks (GitLab 8.7 to 9.5)
diff --git a/doc/development/geo/framework.md b/doc/development/geo/framework.md
index 4460e6f66a8..778387986d8 100644
--- a/doc/development/geo/framework.md
+++ b/doc/development/geo/framework.md
@@ -14,7 +14,7 @@ team to discuss the options. You can contact them in `#g_geo` on Slack
or mention `@geo-team` in the issue or merge request.
Geo provides an API to make it possible to easily replicate data types
-across Geo nodes. This API is presented as a Ruby Domain-Specific
+across Geo sites. This API is presented as a Ruby Domain-Specific
Language (DSL) and aims to make it possible to replicate data with
minimal effort of the engineer who created a data type.
@@ -43,7 +43,7 @@ naming conventions:
For more detail, see [Data types](../../administration/geo/replication/datatypes.md).
- **Geo Replicable**:
- A Replicable is a resource Geo wants to sync across Geo nodes. There
+ A Replicable is a resource Geo wants to sync across Geo sites. There
is a limited set of supported data types of replicables. The effort
required to implement replication of a resource that belongs to one
of the known data types is minimal.
@@ -57,7 +57,7 @@ naming conventions:
It's tied to the Geo Replicable data type. All replicators have a
common interface that can be used to process (that is, produce and
consume) events. It takes care of the communication between the
- primary node (where events are produced) and the secondary node
+ primary site (where events are produced) and the secondary site
(where events are consumed). The engineer who wants to incorporate
Geo in their feature will use the API of replicators to make this
happen.
@@ -117,7 +117,7 @@ the model code:
```ruby
class Packages::PackageFile < ApplicationRecord
- include ::Gitlab::Geo::ReplicableModel
+ include ::Geo::ReplicableModel
with_replicator Geo::PackageFileReplicator
end
diff --git a/doc/development/gitaly.md b/doc/development/gitaly.md
index 5a7a5a6abcb..275e9421983 100644
--- a/doc/development/gitaly.md
+++ b/doc/development/gitaly.md
@@ -112,10 +112,9 @@ bundle exec rake gitlab:features:disable_rugged
Most of this code exists in the `lib/gitlab/git/rugged_impl` directory.
NOTE:
-You should *not* need to add or modify code related to
-Rugged unless explicitly discussed with the
-[Gitaly Team](https://gitlab.com/groups/gl-gitaly/group_members). This code does
-NOT work on GitLab.com or other GitLab instances that do not use NFS.
+You should *not* have to add or modify code related to Rugged unless explicitly discussed with the
+[Gitaly Team](https://gitlab.com/groups/gl-gitaly/group_members). This code does not work on GitLab.com or other GitLab
+instances that do not use NFS.
## `TooManyInvocationsError` errors
@@ -197,7 +196,7 @@ If you make changes to your local Gitaly in between test runs you need
to manually run `make` again.
Note that CI tests do not use your locally modified version of
-Gitaly. To use a custom Gitaly version in CI you need to update
+Gitaly. To use a custom Gitaly version in CI, you must update
GITALY_SERVER_VERSION as described at the beginning of this section.
To use a different Gitaly repository, such as if your changes are present
@@ -326,7 +325,7 @@ default value. The default value depends on the GitLab version.
To be sure that the flag is set correctly and it goes into Gitaly, you can check
the integration by using GDK:
-1. The state of the flag must be observable. To check it, you need to enable it
+1. The state of the flag must be observable. To check it, you must enable it
by fetching the Prometheus metrics:
1. Navigate to GDK's root directory.
1. Make sure you have the proper branch checked out for Gitaly.
diff --git a/doc/development/import_project.md b/doc/development/import_project.md
index 9872aa239dc..9e236b4cfce 100644
--- a/doc/development/import_project.md
+++ b/doc/development/import_project.md
@@ -16,7 +16,7 @@ There are several ways to import a project.
### Importing via UI
-The first option is to simply [import the Project tarball file via the GitLab UI](../user/project/settings/import_export.md#import-the-project):
+The first option is to simply [import the Project tarball file via the GitLab UI](../user/project/settings/import_export.md#import-a-project-and-its-data):
1. Create the group `qa-perf-testing`
1. Import the [GitLab FOSS project tarball](https://gitlab.com/gitlab-org/quality/performance-data/-/blob/master/projects_export/gitlabhq_export.tar.gz) into the Group.
diff --git a/doc/development/index.md b/doc/development/index.md
index 1398104abda..197c7f48398 100644
--- a/doc/development/index.md
+++ b/doc/development/index.md
@@ -164,6 +164,7 @@ the [reviewer values](https://about.gitlab.com/handbook/engineering/workflow/rev
### General
- [Directory structure](directory_structure.md)
+- [GitLab EventStore](event_store.md) to publish/subscribe to domain events
- [GitLab utilities](utilities.md)
- [Newlines style guide](newlines_styleguide.md)
- [Logging](logging.md)
@@ -263,8 +264,7 @@ the [reviewer values](https://about.gitlab.com/handbook/engineering/workflow/rev
- [Caching guidelines](caching.md) for using caching in Rails under a GitLab environment.
- [Merge request performance guidelines](merge_request_performance_guidelines.md)
for ensuring merge requests do not negatively impact GitLab performance
-- [Profiling](profiling.md) a URL, measuring performance using Sherlock, or
- tracking down N+1 queries using Bullet.
+- [Profiling](profiling.md) a URL or tracking down N+1 queries using Bullet.
- [Cached queries guidelines](cached_queries.md), for tracking down N+1 queries
masked by query caching, memory profiling and why should we avoid cached
queries.
diff --git a/doc/development/integrations/jenkins.md b/doc/development/integrations/jenkins.md
index 3987c6658c3..8a3f64f0a0d 100644
--- a/doc/development/integrations/jenkins.md
+++ b/doc/development/integrations/jenkins.md
@@ -54,8 +54,8 @@ To set up the Jenkins project you intend to run your build on, read
You can configure your integration between Jenkins and GitLab:
-- With the [recommended approach for Jenkins integration](../../integration/jenkins.md#recommended-jenkins-integration).
-- [Using a webhook](../../integration/jenkins.md#webhook-integration).
+- With the [recommended approach for Jenkins integration](../../integration/jenkins.md#configure-a-jenkins-integration-recommended).
+- [Using a webhook](../../integration/jenkins.md#configure-a-webhook).
## Test your setup
diff --git a/doc/development/integrations/jira_connect.md b/doc/development/integrations/jira_connect.md
index ca3dc3660ee..fc7204fdd5a 100644
--- a/doc/development/integrations/jira_connect.md
+++ b/doc/development/integrations/jira_connect.md
@@ -89,6 +89,3 @@ To add a [namespace](../../user/group/index.md#namespaces) to Jira:
`--cookies "<cookies from the request>"`.
1. Submit the cURL request.
1. If the response is `{"success":true}`, the namespace was added.
-1. Append the cookies to the cURL command in your terminal `--cookies "PASTE COOKIES HERE"`.
-1. Submit the cURL request.
-1. If the response is `{"success":true}` the namespace was added.
diff --git a/doc/development/integrations/secure.md b/doc/development/integrations/secure.md
index 356e731aa87..147d379cec7 100644
--- a/doc/development/integrations/secure.md
+++ b/doc/development/integrations/secure.md
@@ -327,21 +327,42 @@ You can find the schemas for these scanners here:
- [Coverage Fuzzing](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/dist/coverage-fuzzing-report-format.json)
- [Secret Detection](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/dist/secret-detection-report-format.json)
-### Version
+### Enable report validation
-This field specifies the version of the [Security Report Schemas](https://gitlab.com/gitlab-org/security-products/security-report-schemas) you are using. Please refer to the [releases](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/releases) of the schemas for the specific versions to use.
+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"`.
-### Vulnerabilities
+Reports that don't pass validation are not ingested by GitLab, and an error message
+displays on the corresponding pipeline.
+
+You should ensure that reports generated by the scanner pass validation against the schema version
+declared in your reports. 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).
+
+### Report Fields
+
+#### Version
+
+This field specifies which [Security Report Schemas](https://gitlab.com/gitlab-org/security-products/security-report-schemas) version you are using. For information about the versions to use, see [releases](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/releases).
+
+In GitLab 14.10 and later, GitLab validates your report against the version of the schema specified by this value.
+The versions supported by GitLab can be found in
+[`gitlab/ee/lib/ee/gitlab/ci/parsers/security/validators/schemas`](https://gitlab.com/gitlab-org/gitlab/-/tree/master/ee/lib/ee/gitlab/ci/parsers/security/validators/schemas).
+
+#### Vulnerabilities
The `vulnerabilities` field of the report is an array of vulnerability objects.
-#### ID
+##### ID
The `id` field is the unique identifier of the vulnerability.
It is used to reference a fixed vulnerability from a [remediation objects](#remediations).
We recommend that you generate a UUID and use it as the `id` field's value.
-#### Category
+##### Category
The value of the `category` field matches the report type:
@@ -351,12 +372,12 @@ The value of the `category` field matches the report type:
- `sast`
- `dast`
-#### Scanner
+##### Scanner
The `scanner` field is an object that embeds a human-readable `name` and a technical `id`.
The `id` should not collide with any other scanner another integrator would provide.
-#### Name, message, and description
+##### Name, message, and description
The `name` and `message` fields contain a short description of the vulnerability.
The `description` field provides more details.
@@ -400,13 +421,13 @@ It should not repeat the other fields of the vulnerability object.
In particular, the `description` should not repeat the `location` (what is affected)
or the `solution` (how to mitigate the risk).
-#### Solution
+##### Solution
You can use the `solution` field to instruct users how to fix the identified vulnerability or to mitigate
the risk. End-users interact with this field, whereas GitLab automatically processes the
`remediations` objects.
-#### Identifiers
+##### Identifiers
The `identifiers` array describes the detected vulnerability. An identifier object's `type` and
`value` fields are used to tell if two identifiers are the same. The user interface uses the
@@ -440,15 +461,14 @@ Not all vulnerabilities have CVEs, and a CVE can be identified multiple times. A
isn't a stable identifier and you shouldn't assume it as such when tracking vulnerabilities.
The maximum number of identifiers for a vulnerability is set as 20. If a vulnerability has more than 20 identifiers,
-the system saves only the first 20 of them. Note that vulnerabilities in the [Pipeline
-Security](../../user/application_security/security_dashboard/#pipeline-security)
+the system saves only the first 20 of them. Note that vulnerabilities in the [Pipeline Security](../../user/application_security/security_dashboard/#view-vulnerabilities-in-a-pipeline)
tab do not enforce this limit and all identifiers present in the report artifact are displayed.
-### Details
+#### Details
The `details` field is an object that supports many different content elements that are displayed when viewing vulnerability information. An example of the various data elements can be seen in the [security-reports repository](https://gitlab.com/gitlab-examples/security/security-reports/-/tree/master/samples/details-example).
-### Location
+#### Location
The `location` indicates where the vulnerability has been detected.
The format of the location depends on the type of scanning.
@@ -458,7 +478,7 @@ which is used to track vulnerabilities
as new commits are pushed to the repository.
The attributes used to generate the location fingerprint also depend on the type of scanning.
-#### Dependency Scanning
+##### Dependency Scanning
The `location` of a Dependency Scanning vulnerability is composed of a `dependency` and a `file`.
The `dependency` object describes the affected `package` and the dependency `version`.
@@ -488,7 +508,7 @@ combines the `file` and the package `name`,
so these attributes are mandatory.
All other attributes are optional.
-#### Container Scanning
+##### Container Scanning
Similar to Dependency Scanning,
the `location` of a Container Scanning vulnerability has a `dependency` and a `file`.
@@ -519,7 +539,7 @@ so these attributes are mandatory.
The `image` is also mandatory.
All other attributes are optional.
-#### Cluster Image Scanning
+##### Cluster Image Scanning
The `location` of a `cluster_image_scanning` vulnerability has a `dependency` field. It also has
an `operating_system` field. For example, here is the `location` object for a vulnerability
@@ -553,7 +573,7 @@ as well as the package `name`, so these fields are required. The `image` field i
The `cluster_id` and `agent_id` are mutually exclusive, and one of them must be present.
All other fields are optional.
-#### SAST
+##### SAST
The `location` of a SAST vulnerability must have a `file` and a `start_line` field,
giving the path of the affected file, and the affected line number, respectively.
@@ -578,7 +598,7 @@ combines `file`, `start_line`, and `end_line`,
so these attributes are mandatory.
All other attributes are optional.
-### Tracking and merging vulnerabilities
+#### Tracking and merging vulnerabilities
Users may give feedback on a vulnerability:
@@ -606,7 +626,7 @@ and at least one [identifier](#identifiers). Two identifiers are the same if the
CWE and WASC identifiers are not considered because they describe categories of vulnerability flaws,
but not specific security flaws.
-#### Severity and confidence
+##### Severity and confidence
The `severity` field describes how much the vulnerability impacts the software,
whereas the `confidence` field describes how reliable the assessment of the vulnerability is.
@@ -623,7 +643,7 @@ Valid values are: `Ignore`, `Unknown`, `Experimental`, `Low`, `Medium`, `High`,
and needs to be investigated. We have [provided a chart](../../user/application_security/sast/analyzers.md#analyzers-data)
of the available SAST Analyzers and what data is currently available.
-### Remediations
+#### Remediations
The `remediations` field of the report is an array of remediation objects.
Each remediation describes a patch that can be applied to
@@ -667,28 +687,16 @@ Here is an example of a report that contains remediations.
}
```
-#### Summary
+##### Summary
The `summary` field is an overview of how the vulnerabilities can be fixed. This field is required.
-#### Fixed vulnerabilities
+##### Fixed vulnerabilities
The `fixes` field is an array of objects that reference the vulnerabilities fixed by the
remediation. `fixes[].id` contains a fixed vulnerability's [unique identifier](#id). This field is required.
-#### Diff
+##### Diff
The `diff` field is a base64-encoded remediation code diff, compatible with
[`git apply`](https://git-scm.com/docs/git-format-patch#_discussion). This field is required.
-
-## Limitations
-
-### Container Scanning
-
-Container Scanning currently has these limitations:
-
-- Although the Security Dashboard can display scan results from multiple images, if multiple
- vulnerabilities have the same fingerprint, only the first instance of that vulnerability is
- displayed. We're working on removing this limitation. You can follow our progress on the issue
- [Change location fingerprint for Container Scanning](https://gitlab.com/gitlab-org/gitlab/-/issues/215466).
-- Different scanners may each report the same vulnerability, resulting in duplicate findings.
diff --git a/doc/development/internal_api/index.md b/doc/development/internal_api/index.md
index 543c5f40f88..96910892022 100644
--- a/doc/development/internal_api/index.md
+++ b/doc/development/internal_api/index.md
@@ -703,10 +703,10 @@ Example response:
- CustomersDot
-## CI minute provisioning
+## CI/CD minutes provisioning
-The CI Minute endpoints are used by [CustomersDot](https://gitlab.com/gitlab-org/customers-gitlab-com) (`customers.gitlab.com`)
-to apply additional packs of CI minutes, for personal namespaces or top-level groups within GitLab.com.
+The CI/CD Minutes endpoints are used by [CustomersDot](https://gitlab.com/gitlab-org/customers-gitlab-com) (`customers.gitlab.com`)
+to apply additional packs of CI/CD minutes, for personal namespaces or top-level groups within GitLab.com.
### Creating an additional pack
@@ -826,6 +826,32 @@ Example response:
200
```
+### Deleting an `upcoming_reconciliation`
+
+Use a DELETE command to delete an `upcoming_reconciliation`.
+
+```plaintext
+DELETE /internal/upcoming_reconciliations
+```
+
+| Attribute | Type | Required | Description |
+|:---------------|:--------|:---------|:----------------------------------------------------------------------------------|
+| `namespace_id` | integer | yes | The ID of the GitLab.com namespace that no longer has an upcoming reconciliation. |
+
+Example request:
+
+```shell
+curl --request DELETE \
+ --url "http://localhost:3000/api/v4/internal/upcoming_reconciliations?namespace_id=22" \
+ --header 'PRIVATE-TOKEN: <admin_access_token>'
+```
+
+Example response:
+
+```plaintext
+204
+```
+
### Known consumers
- CustomersDot
diff --git a/doc/development/licensing.md b/doc/development/licensing.md
index 23871bf3c68..a50c514733e 100644
--- a/doc/development/licensing.md
+++ b/doc/development/licensing.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitLab Licensing and Compatibility
-[GitLab Community Edition](https://gitlab.com/gitlab-org/gitlab-foss/) (CE) is licensed [under the terms of the MIT License](https://gitlab.com/gitlab-org/gitlab-foss/blob/master/LICENSE). [GitLab Enterprise Edition](https://gitlab.com/gitlab-org/gitlab/) (EE) is licensed under "[The GitLab Enterprise Edition (EE) license](https://gitlab.com/gitlab-org/gitlab/-/blob/master/LICENSE)" wherein there are more restrictions.
+[GitLab Community Edition](https://gitlab.com/gitlab-org/gitlab-foss/) (CE) is licensed [under the terms of the MIT License](https://gitlab.com/gitlab-org/gitlab-foss/blob/master/LICENSE). [GitLab Enterprise Edition](https://gitlab.com/gitlab-org/gitlab/) (EE) is licensed under "[The GitLab Enterprise Edition (EE) license](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/LICENSE)" wherein there are more restrictions.
## Automated Testing
diff --git a/doc/development/merge_request_performance_guidelines.md b/doc/development/merge_request_performance_guidelines.md
index 69e9f7d16e3..106db862122 100644
--- a/doc/development/merge_request_performance_guidelines.md
+++ b/doc/development/merge_request_performance_guidelines.md
@@ -13,9 +13,7 @@ _every_ merge request **should** adhere to the guidelines outlined in this
document. There are no exceptions to this rule unless specifically discussed
with and agreed upon by backend maintainers and performance specialists.
-To measure the impact of a merge request you can use
-[Sherlock](profiling.md#sherlock). It's also highly recommended that you read
-the following guides:
+It's also highly recommended that you read the following guides:
- [Performance Guidelines](performance.md)
- [Avoiding downtime in migrations](avoiding_downtime_in_migrations.md)
diff --git a/doc/development/migration_style_guide.md b/doc/development/migration_style_guide.md
index 0bd9979e790..d85b7372814 100644
--- a/doc/development/migration_style_guide.md
+++ b/doc/development/migration_style_guide.md
@@ -162,6 +162,9 @@ def down
end
```
+Migrations like this are inherently risky and [additional actions](database_review.md#preparation-when-adding-data-migrations)
+are required when preparing the migration for review.
+
## Atomicity
By default, migrations are single transaction. That is, a transaction is opened
@@ -769,6 +772,32 @@ to run on a large table, as long as it is only updating a small subset of the
rows in the table, but do not ignore that without validating on the GitLab.com
staging environment - or asking someone else to do so for you - beforehand.
+## Removing a foreign key constraint
+
+When removing a foreign key constraint, we need to acquire a lock on both tables
+that are related to the foreign key. For tables with heavy write patterns, it's a good
+idea to use `with_lock_retries`, otherwise you might fail to acquire a lock in time.
+You might also run into deadlocks when acquiring a lock, because ordinarily
+the application writes in `parent,child` order. However, removing a foreign
+key acquires the lock in `child,parent` order. To resolve this, you can
+explicitly acquire the lock in `parent,child`, for example:
+
+```ruby
+disable_ddl_transaction!
+
+def up
+ with_lock_retries do
+ execute('lock table ci_pipelines, ci_builds in access exclusive mode')
+
+ remove_foreign_key :ci_builds, to_table: :ci_pipelines, column: :pipeline_id, on_delete: :cascade, name: 'the_fk_name'
+ end
+end
+
+def down
+ add_concurrent_foreign_key :ci_builds, :ci_pipelines, column: :pipeline_id, on_delete: :cascade, name: 'the_fk_name'
+end
+```
+
## Dropping a database table
Dropping a database table is uncommon, and the `drop_table` method
diff --git a/doc/development/permissions.md b/doc/development/permissions.md
index b7079e9fb8e..72e20d31cf8 100644
--- a/doc/development/permissions.md
+++ b/doc/development/permissions.md
@@ -1,10 +1,10 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
-# GitLab permissions guide
+# Implementing permissions
There are multiple types of permissions across GitLab, and when implementing
anything that deals with permissions, all of them should be considered.
diff --git a/doc/development/pipelines.md b/doc/development/pipelines.md
index c7443032d78..a9c68905095 100644
--- a/doc/development/pipelines.md
+++ b/doc/development/pipelines.md
@@ -170,10 +170,9 @@ After that, the next pipeline uses the up-to-date `knapsack/report-master.json`
### Flaky tests
-Tests that are [known to be flaky](testing_guide/flaky_tests.md#automatic-retries-and-flaky-tests-detection) are:
-
-- skipped if the `$SKIP_FLAKY_TESTS_AUTOMATICALLY` variable is set to `true` (`false` by default)
-- run if `$SKIP_FLAKY_TESTS_AUTOMATICALLY` variable is not set to `true` or if the `~"pipeline:run-flaky-tests"` label is set on the MR
+Tests that are [known to be flaky](testing_guide/flaky_tests.md#automatic-retries-and-flaky-tests-detection) are
+skipped unless the `$SKIP_FLAKY_TESTS_AUTOMATICALLY` variable is set to `false` or if the `~"pipeline:run-flaky-tests"`
+label is set on the MR.
### Monitoring
@@ -222,6 +221,13 @@ The `* as-if-jh` jobs are run in addition to the regular EE-context jobs. The `j
The intent is to ensure that a change doesn't introduce a failure after the `gitlab-org/gitlab` project is synced to
the `gitlab-jh/gitlab` project.
+### Corresponding JH branch
+
+You can create a corresponding JH branch on the `gitlab-jh/gitlab` project by
+appending `-jh` to the branch name. If a corresponding JH branch is found,
+`* as-if-jh` jobs grab the `jh` folder from the respective branch,
+rather than from the default branch.
+
## `undercover` RSpec test
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74859) in GitLab 14.6.
@@ -266,318 +272,123 @@ We follow the [PostgreSQL versions shipped with Omnibus GitLab](../administratio
## Pipelines types for merge requests
-In general, pipelines for an MR fall into one or more of the following types,
-depending on the changes made in the MR:
+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:
+
+- [Documentation pipeline](#documentation-pipeline): For MRs that touch documentation.
+- [Backend pipeline](#backend-pipeline): For MRs that touch backend code.
+- [Frontend pipeline](#frontend-pipeline): For MRs that touch frontend code.
+- [End-to-end pipeline](#end-to-end-pipeline): For MRs that touch code in the `qa/` folder.
-- [Documentation only MR pipeline](#documentation-only-mr-pipeline): This is typically created for an MR that only changes documentation.
-- [Code-only MR pipeline](#code-only-mr-pipeline): This is typically created for an MR that only changes code, either backend or frontend.
-- [Frontend-only MR pipeline](#frontend-only-mr-pipeline): This is typically created for an MR that only changes frontend code.
-- [QA-only MR pipeline](#qa-only-mr-pipeline): This is typically created for an MR that only changes end to end tests related code.
+A "pipeline type" is an abstract term that mostly describes the "critical path" (i.e. the chain of jobs for which the sum
+of individual duration equals the pipeline's duration).
+We use these "pipeline types" in [metrics dashboards](https://app.periscopedata.com/app/gitlab/858266/GitLab-Pipeline-Durations)
+in order to detect what types and jobs need to be optimized first.
+
+An MR that touches multiple areas would be associated with the longest type applicable. For instance, an MR that touches backend
+and frontend would fall into the "Frontend" pipeline type since this type takes longer to finish than the "Backend" pipeline type.
We use the [`rules:`](../ci/yaml/index.md#rules) and [`needs:`](../ci/yaml/index.md#needs) keywords extensively
to determine the jobs that need to be run in a pipeline. Note that an MR that includes multiple types of changes would
have a pipelines that include jobs from multiple types (for example, a combination of docs-only and code-only pipelines).
-### Documentation only MR pipeline
+Following are graphs of the critical paths for each pipeline type. Jobs that aren't part of the critical path are ommitted.
+
+### Documentation pipeline
-[Reference pipeline](https://gitlab.com/gitlab-org/gitlab/-/pipelines/250546928):
+[Reference pipeline](https://gitlab.com/gitlab-org/gitlab/-/pipelines/432049110).
```mermaid
graph LR
- subgraph "No needed jobs";
- 1-1["danger-review (2.3 minutes)"];
- click 1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8100542&udv=0"
- 1-2["docs-lint markdown (1.5 minutes)"];
- click 1-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=10224335&udv=0"
- 1-3["docs-lint links (5 minutes)"];
- click 1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356757&udv=0"
- 1-4["ui-docs-links lint (2.5 minutes)"];
- click 1-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=10823717&udv=1020379"
- end
+ classDef criticalPath fill:#f66;
+
+ 1-3["docs-lint links (5 minutes)"];
+ class 1-3 criticalPath;
+ click 1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356757&udv=0"
```
-### Code-only MR pipeline
+### Backend pipeline
-[Reference pipeline](https://gitlab.com/gitlab-org/gitlab/pipelines/136295694)
+[Reference pipeline](https://gitlab.com/gitlab-org/gitlab/-/pipelines/433316063).
```mermaid
graph RL;
classDef criticalPath fill:#f66;
- subgraph "No needed jobs";
- 1-1["danger-review (2.3 minutes)"];
- click 1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8100542&udv=0"
- 1-2["build-qa-image (2 minutes)"];
- click 1-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914325&udv=0"
- 1-3["compile-test-assets (6 minutes)"];
- click 1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914317&udv=0"
- 1-4["compile-test-assets as-if-foss (7 minutes)"];
- click 1-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356616&udv=0"
- 1-5["compile-production-assets (14 minutes)"];
- click 1-5 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914312&udv=0"
- 1-6["setup-test-env (4 minutes)"];
- click 1-6 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914315&udv=0"
- 1-7["review-delete-deployment"];
- 1-8["dependency_scanning"];
- 1-9["qa:internal, qa:internal-as-if-foss"];
- 1-11["qa:selectors, qa:selectors-as-if-foss"];
- 1-14["retrieve-tests-metadata (1 minutes)"];
- click 1-14 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356697&udv=0"
- 1-15["code_quality"];
- 1-16["brakeman-sast"];
- 1-17["eslint-sast"];
- 1-18["kubesec-sast"];
- 1-20["secrets-sast"];
- 1-21["static-analysis (14 minutes)"];
- click 1-21 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914471&udv=0"
-
- class 1-3 criticalPath;
- class 1-6 criticalPath;
- end
-
- 2_1-1["graphql-verify (2.3 minutes)"];
- click 2_1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356715&udv=0"
- 2_1-2["memory-static (4.75 minutes)"];
- click 2_1-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356721&udv=0"
- 2_1-3["run-dev-fixtures (3 minutes)"];
- click 2_1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356729&udv=0"
- 2_1-4["run-dev-fixtures-ee (4 minutes)"];
- click 2_1-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356731&udv=0"
- subgraph "Needs `setup-test-env`";
- 2_1-1 & 2_1-2 & 2_1-3 & 2_1-4 --> 1-6;
- end
-
- 2_2-2["rspec-all frontend_fixture (7 minutes)"];
- class 2_2-2 criticalPath;
- click 2_2-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7910143&udv=0"
- 2_2-4["memory-on-boot (3.5 minutes)"];
- click 2_2-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356727&udv=0"
- 2_2-5["webpack-dev-server (4 minutes)"];
- click 2_2-5 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8404303&udv=0"
- subgraph "Needs `setup-test-env` & `compile-test-assets`";
- 2_2-2 & 2_2-4 & 2_2-5 --> 1-6 & 1-3;
- end
-
- 2_3-1["build-assets-image (1.6 minutes)"];
- subgraph "Needs `compile-production-assets`";
- 2_3-1 --> 1-5
- end
-
- 2_4-1["package-and-qa (manual)"];
- subgraph "Needs `build-qa-image`";
- 2_4-1 --> 1-2;
- click 2_4-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914305&udv=0"
- end
-
- 2_5-1["rspec & db jobs (12-22 minutes)"];
- subgraph "Needs `compile-test-assets`, `setup-test-env`, & `retrieve-tests-metadata`";
- 2_5-1 --> 1-3 & 1-6 & 1-14;
- class 2_5-1 criticalPath;
- click 2_5-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations"
- end
-
- 3_1-1["jest (14.5 minutes)"];
- class 3_1-1 criticalPath;
- click 3_1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914204&udv=0"
- subgraph "Needs `rspec-all frontend_fixture`";
- 3_1-1 --> 2_2-2;
- end
-
- 3_2-1["rspec:coverage (4 minutes)"];
- subgraph "Depends on `rspec` jobs";
- 3_2-1 -.->|"(don't use needs because of limitations)"| 2_5-1;
- click 3_2-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7248745&udv=0"
- end
-
- 4_1-1["coverage-frontend (2 minutes)"];
- subgraph "Needs `jest`";
- 4_1-1 --> 3_1-1;
- class 4_1-1 criticalPath;
- click 4_1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7910777&udv=0"
- end
+ 1-3["compile-test-assets (6 minutes)"];
+ class 1-3 criticalPath;
+ click 1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914317&udv=0"
+ 1-6["setup-test-env (4 minutes)"];
+ click 1-6 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914315&udv=0"
+ 1-14["retrieve-tests-metadata"];
+ click 1-14 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356697&udv=0"
+ 1-15["detect-tests"];
+ click 1-15 "https://app.periscopedata.com/app/gitlab/652085/EP---Jobs-Durations?widget=10113603&udv=1005715"
+
+ 2_5-1["rspec & db jobs (24 minutes)"];
+ class 2_5-1 criticalPath;
+ click 2_5-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations"
+ 2_5-1 --> 1-3 & 1-6 & 1-14 & 1-15;
+
+ 3_2-1["rspec:coverage (5.35 minutes)"];
+ class 3_2-1 criticalPath;
+ click 3_2-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7248745&udv=0"
+ 3_2-1 -.->|"(don't use needs<br/>because of limitations)"| 2_5-1;
+
+ 4_3-1["rspec:undercoverage (3.5 minutes)"];
+ class 4_3-1 criticalPath;
+ click 4_3-1 "https://app.periscopedata.com/app/gitlab/652085/EP---Jobs-Durations?widget=13446492&udv=1005715"
+ 4_3-1 --> 3_2-1;
+
```
-### Frontend-only MR pipeline
+### Frontend pipeline
-[Reference pipeline](https://gitlab.com/gitlab-org/gitlab/pipelines/134661039):
+[Reference pipeline](https://gitlab.com/gitlab-org/gitlab/-/pipelines/431913287).
```mermaid
graph RL;
classDef criticalPath fill:#f66;
- subgraph "No needed jobs";
- 1-1["danger-review (2.3 minutes)"];
- click 1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8100542&udv=0"
- 1-2["build-qa-image (2 minutes)"];
- click 1-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914325&udv=0"
- 1-3["compile-test-assets (6 minutes)"];
- click 1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914317&udv=0"
- 1-4["compile-test-assets as-if-foss (7 minutes)"];
- click 1-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356616&udv=0"
- 1-5["compile-production-assets (14 minutes)"];
- click 1-5 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914312&udv=0"
- 1-6["setup-test-env (4 minutes)"];
- click 1-6 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914315&udv=0"
- 1-7["review-stop-failed-deployment"];
- 1-8["dependency_scanning"];
- 1-9["qa:internal, qa:internal-as-if-foss"];
- 1-11["qa:selectors, qa:selectors-as-if-foss"];
- 1-14["retrieve-tests-metadata (1 minutes)"];
- click 1-14 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356697&udv=0"
- 1-15["code_quality"];
- 1-16["brakeman-sast"];
- 1-17["eslint-sast"];
- 1-18["kubesec-sast"];
- 1-20["secrets-sast"];
- 1-21["static-analysis (14 minutes)"];
- click 1-21 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914471&udv=0"
-
- class 1-3 criticalPath;
- class 1-5 criticalPath;
- class 1-6 criticalPath;
- end
-
- 2_1-1["graphql-verify (2.3 minutes)"];
- click 2_1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356715&udv=0"
- 2_1-2["memory-static (4.75 minutes)"];
- click 2_1-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356721&udv=0"
- 2_1-3["run-dev-fixtures (3 minutes)"];
- click 2_1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356729&udv=0"
- 2_1-4["run-dev-fixtures-ee (4 minutes)"];
- click 2_1-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356731&udv=0"
- subgraph "Needs `setup-test-env`";
- 2_1-1 & 2_1-2 & 2_1-3 & 2_1-4 --> 1-6;
- end
-
- 2_2-2["rspec-all frontend_fixture (7 minutes)"];
- class 2_2-2 criticalPath;
- click 2_2-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7910143&udv=0"
- 2_2-4["memory-on-boot (3.5 minutes)"];
- click 2_2-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356727&udv=0"
- 2_2-5["webpack-dev-server (4 minutes)"];
- click 2_2-5 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8404303&udv=0"
- subgraph "Needs `setup-test-env` & `compile-test-assets`";
- 2_2-2 & 2_2-4 & 2_2-5 --> 1-6 & 1-3;
- end
-
- 2_3-1["build-assets-image (1.6 minutes)"];
+ 1-2["build-qa-image (2 minutes)"];
+ click 1-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914325&udv=0"
+ 1-5["compile-production-assets (16 minutes)"];
+ class 1-5 criticalPath;
+ click 1-5 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914312&udv=0"
+
+ 2_3-1["build-assets-image (1.3 minutes)"];
class 2_3-1 criticalPath;
- subgraph "Needs `compile-production-assets`";
- 2_3-1 --> 1-5
- end
-
- 2_4-1["package-and-qa (manual)"];
- subgraph "Needs `build-qa-image` & `build-assets-image`";
- 2_4-1 --> 1-2 & 2_3-1;
- click 2_4-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914305&udv=0"
- end
-
- 2_5-1["rspec & db jobs (12-22 minutes)"];
- subgraph "Needs `compile-test-assets`, `setup-test-env, & `retrieve-tests-metadata`";
- 2_5-1 --> 1-3 & 1-6 & 1-14;
- class 2_5-1 criticalPath;
- click 2_5-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations"
- end
-
- 2_6-1["review-build-cng (27 minutes)"];
- subgraph "Needs `build-assets-image`";
- 2_6-1 --> 2_3-1;
- class 2_6-1 criticalPath;
- click 2_6-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914314&udv=0"
- end
-
- 3_1-1["jest (14.5 minutes)"];
- class 3_1-1 criticalPath;
- click 3_1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914204&udv=0"
- subgraph "Needs `rspec-all frontend_fixture`";
- 3_1-1 --> 2_2-2;
- end
-
- 3_2-1["rspec:coverage (4 minutes)"];
- subgraph "Depends on `rspec` jobs";
- 3_2-1 -.->|"(don't use needs because of limitations)"| 2_5-1;
- click 3_2-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7248745&udv=0"
- end
-
- 4_1-1["coverage-frontend (2 minutes)"];
- subgraph "Needs `jest`";
- 4_1-1 --> 3_1-1;
- class 4_1-1 criticalPath;
- click 4_1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7910777&udv=0"
- end
-
- 3_3-1["review-deploy (9 minutes)"];
- subgraph "Played by `review-build-cng`";
- 3_3-1 --> 2_6-1;
- class 3_3-1 criticalPath;
- click 3_3-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6721130&udv=0"
- end
-
- 4_2-1["review-qa-smoke (7.4 minutes)"];
- click 4_2-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6729805&udv=0"
- 4_2-2["review-performance (2.5 minutes)"];
- click 4_2-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356817&udv=0"
- subgraph "Played by `review-deploy`";
- 4_2-1 & 4_2-2 --> 3_3-1;
- end
+ 2_3-1 --> 1-5
+
+ 2_6-1["start-review-app-pipeline (49 minutes)"];
+ class 2_6-1 criticalPath;
+ click 2_6-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations"
+ 2_6-1 --> 2_3-1 & 1-2;
```
-### QA-only MR pipeline
+### End-to-end pipeline
-[Reference pipeline](https://gitlab.com/gitlab-org/gitlab/pipelines/134645109):
+[Reference pipeline](https://gitlab.com/gitlab-org/gitlab/-/pipelines/431918463).
```mermaid
graph RL;
classDef criticalPath fill:#f66;
- subgraph "No needed jobs";
- 1-1["danger-review (2.3 minutes)"];
- click 1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8100542&udv=0"
- 1-2["build-qa-image (2 minutes)"];
- click 1-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914325&udv=0"
- 1-3["compile-test-assets (6 minutes)"];
- click 1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914317&udv=0"
- 1-4["compile-test-assets as-if-foss (7 minutes)"];
- click 1-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356616&udv=0"
- 1-5["compile-production-assets (14 minutes)"];
- click 1-5 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914312&udv=0"
- 1-6["setup-test-env (4 minutes)"];
- click 1-6 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914315&udv=0"
- 1-7["review-stop-failed-deployment"];
- 1-8["dependency_scanning"];
- 1-9["qa:internal, qa:internal-as-if-foss"];
- 1-11["qa:selectors, qa:selectors-as-if-foss"];
- 1-14["retrieve-tests-metadata (1 minutes)"];
- click 1-14 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356697&udv=0"
- 1-15["code_quality"];
- 1-16["brakeman-sast"];
- 1-17["eslint-sast"];
- 1-18["kubesec-sast"];
- 1-20["secrets-sast"];
- 1-21["static-analysis (14 minutes)"];
- click 1-21 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914471&udv=0"
-
- class 1-5 criticalPath;
- end
-
- 2_1-1["graphql-verify (2.3 minutes)"];
- click 2_1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356715&udv=0"
- subgraph "Needs `setup-test-env`";
- 2_1-1 --> 1-6;
- end
-
- 2_3-1["build-assets-image (1.6 minutes)"];
- subgraph "Needs `compile-production-assets`";
- 2_3-1 --> 1-5
- class 2_3-1 criticalPath;
- end
-
- 2_4-1["package-and-qa (113 minutes)"];
- subgraph "Needs `build-qa-image` & `build-assets-image`";
- 2_4-1 --> 1-2 & 2_3-1;
- class 2_4-1 criticalPath;
- click 2_4-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914305&udv=0"
- end
+ 1-2["build-qa-image (2 minutes)"];
+ click 1-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914325&udv=0"
+ 1-5["compile-production-assets (16 minutes)"];
+ class 1-5 criticalPath;
+ click 1-5 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914312&udv=0"
+ 1-15["detect-tests"];
+ click 1-15 "https://app.periscopedata.com/app/gitlab/652085/EP---Jobs-Durations?widget=10113603&udv=1005715"
+
+ 2_3-1["build-assets-image (1.3 minutes)"];
+ class 2_3-1 criticalPath;
+ 2_3-1 --> 1-5
+
+ 2_4-1["package-and-qa (102 minutes)"];
+ class 2_4-1 criticalPath;
+ click 2_4-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914305&udv=0"
+ 2_4-1 --> 1-2 & 2_3-1 & 1-15;
```
## CI configuration internals
diff --git a/doc/development/policies.md b/doc/development/policies.md
index 9a977a49329..61cc6e0edf5 100644
--- a/doc/development/policies.md
+++ b/doc/development/policies.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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/development/profiling.md b/doc/development/profiling.md
index 656b30402a6..789e0640933 100644
--- a/doc/development/profiling.md
+++ b/doc/development/profiling.md
@@ -108,20 +108,6 @@ Find more information about different sampling modes in the [Stackprof docs](htt
This is enabled for all users that can access the performance bar.
-## Sherlock
-
-Sherlock is a custom profiling tool built into GitLab. Sherlock is _only_
-available when running GitLab in development mode _and_ when setting the
-environment variable `ENABLE_SHERLOCK` to a non empty value. For example:
-
-```shell
-ENABLE_SHERLOCK=1 bundle exec rails s
-```
-
-Sherlock is also [available though the GitLab GDK](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/sherlock.md).
-
-Recorded transactions can be found by navigating to `/sherlock/transactions`.
-
## Bullet
Bullet is a Gem that can be used to track down N+1 query problems. Bullet section is
diff --git a/doc/development/redis/new_redis_instance.md b/doc/development/redis/new_redis_instance.md
index 37ee51ebb82..dcd79be0e5c 100644
--- a/doc/development/redis/new_redis_instance.md
+++ b/doc/development/redis/new_redis_instance.md
@@ -110,6 +110,131 @@ documentation for feature flags.
When we have been using the new instance 100% of the time in production for a
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 also want the ability to fall back to the "old" Redis instance if something goes wrong with the new instance.
+
+Migration Requirements:
+
+- No downtime.
+- No loss of stored data until the TTL for storing data expires.
+- Partial rollout using Feature Flags or ENV vars or combinations of both.
+- Monitoring of the switch.
+- Prometheus metrics in place.
+- Easy rollback without downtime in case the new instance or logic does not behave as expected.
+
+It is somewhat similar to the zero-downtime DB table rename.
+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).
+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),
+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
+module Gitlab
+ module Redis
+ class Foo < ::Gitlab::Redis::Wrapper
+ ...
+ def self.redis
+ # Don't use multistore if redis.foo configuration is not provided
+ return super if config_fallback?
+
+ primary_store = ::Redis.new(params)
+ secondary_store = ::Redis.new(config_fallback.params)
+
+ MultiStore.new(primary_store, secondary_store, store_name)
+ end
+ end
+ end
+end
+```
+
+MultiStore is initialized by providing the new Redis instance as a primary store, and [old (fallback-instance)](#fallback-instance) as a secondary store.
+The third argument is `store_name` which is used for logs, metrics and feature flag names, in case we use MultiStore implementation for different Redis stores at the same time.
+
+By default, the MultiStore reads and writes only from the default Redis store.
+The default Redis store is `secondary_store` (the old fallback-instance).
+This allows us to introduce MultiStore without changing the default behavior.
+
+MultiStore uses two feature flags to control the actual migration:
+
+- `use_primary_and_secondary_stores_for_[store_name]`
+- `use_primary_store_as_default_for_[store_name]`
+
+For example, if our new Redis instance is called `Gitlab::Redis::Foo`, we can [create](../../../ee/development/feature_flags/#create-a-new-feature-flag) two feature flags by executing:
+
+```shell
+bin/feature-flag use_primary_and_secondary_stores_for_foo
+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).
+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`.
+Once we stop seeing them, this means that we are no longer relying on the data stored on the old Redis store.
+At this point, we are probably safe to move the traffic to the new Redis store.
+
+By enabling `use_primary_store_as_default_for_foo` feature flag, the `MultiStore` will use `primary_store` (new instance) as default Redis store.
+
+Once this feature flag is enabled, we can disable `use_primary_and_secondary_stores_for_foo` feature flag.
+This will allow the MultiStore to read and write only from the primary Redis store (new store), moving all the traffic to the new Redis store.
+
+Once we have moved all our traffic to the primary store, our data migration is complete.
+We can safely remove the MultiStore implementation and continue to use newly introduced Redis store instance.
+
+#### Implementation details
+
+MultiStore implements read and write Redis commands separately.
+
+##### Read commands
+
+- `get`
+- `mget`
+- `smembers`
+- `scard`
+
+##### Write commands
+
+- `set`
+- `setnx`
+- `setex`
+- `sadd`
+- `srem`
+- `del`
+- `pipelined`
+- `flushdb`
+
+When a command outside of the supported list is used, `method_missing` will pass it to the old Redis instance and keep track of it.
+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`,
+a developer will need to add an implementation for missing Redis commands before proceeding with the migration.
+
+##### Errors
+
+| error | message |
+|-------------------------------------------------|-----------------------------------------------------------------------|
+| `Gitlab::Redis::MultiStore::ReadFromPrimaryError` | Value not found on the Redis primary store. Read from the Redis secondary store successful. |
+| `Gitlab::Redis::MultiStore::MethodMissingError` | Method missing. Falling back to execute method on the Redis secondary store. |
+
+##### Metrics
+
+| metrics name | type | labels | description |
+|-------------------------------------------------|--------------------|------------------------|----------------------------------------------------|
+| gitlab_redis_multi_store_read_fallback_total | Prometheus Counter | command, instance_name | Client side Redis MultiStore reading fallback total|
+| gitlab_redis_multi_store_method_missing_total | Prometheus Counter | command, instance_name | Client side Redis MultiStore method missing total |
+
## Step 4: clean up after the migration
<!-- markdownlint-disable MD044 -->
diff --git a/doc/development/secure_coding_guidelines.md b/doc/development/secure_coding_guidelines.md
index 21655d6a8fb..51d3338e5ed 100644
--- a/doc/development/secure_coding_guidelines.md
+++ b/doc/development/secure_coding_guidelines.md
@@ -767,3 +767,354 @@ In the example above, the `is_admin?` method is overwritten when passing it to t
- If you must, be **very** confident that you've sanitized the values correctly.
Consider creating an allowlist of values, and validating the user input against that.
- When extending classes that use metaprogramming, make sure you don't inadvertently override any method definition safety checks.
+
+## Working with archive files
+
+Working with archive files like `zip`, `tar`, `jar`, `war`, `cpio`, `apk`, `rar` and `7z` presents an area where potentially critical security vulnerabilities can sneak into an application.
+
+### Zip Slip
+
+In 2018, the security company Snyk [released a blog post](https://snyk.io/research/zip-slip-vulnerability) describing research into a widespread and critical vulnerability present in many libraries and applications which allows an attacker to overwrite arbitrary files on the server file system which, in many cases, can be leveraged to achieve remote code execution. The vulnerability was dubbed Zip Slip.
+
+A Zip Slip vulnerability happens when an application extracts an archive without validating and sanitizing the filenames inside the archive for directory traversal sequences that change the file location when the file is extracted.
+
+Example malicious file names:
+
+- `../../etc/passwd`
+- `../../root/.ssh/authorized_keys`
+- `../../etc/gitlab/gitlab.rb`
+
+If a vulnerable application extracts an archive file with any of these file names, the attacker can overwrite these files with arbitrary content.
+
+### Insecure archive extraction examples
+
+#### Ruby
+
+For zip files, the [rubyzip](https://rubygems.org/gems/rubyzip) Ruby gem is already patched against the Zip Slip vulnerability and will refuse to extract files that try to perform directory traversal, so for this vulnerable example we will extract a `tar.gz` file with `Gem::Package::TarReader`:
+
+```ruby
+# Vulnerable tar.gz extraction example!
+
+begin
+ tar_extract = Gem::Package::TarReader.new(Zlib::GzipReader.open("/tmp/uploaded.tar.gz"))
+rescue Errno::ENOENT
+ STDERR.puts("archive file does not exist or is not readable")
+ exit(false)
+end
+tar_extract.rewind
+
+tar_extract.each do |entry|
+ next unless entry.file? # Only process files in this example for simplicity.
+
+ destination = "/tmp/extracted/#{entry.full_name}" # Oops! We blindly use the entry file name for the destination.
+ File.open(destination, "wb") do |out|
+ out.write(entry.read)
+ end
+end
+```
+
+#### Go
+
+```golang
+// unzip INSECURELY extracts source zip file to destination.
+func unzip(src, dest string) error {
+ r, err := zip.OpenReader(src)
+ if err != nil {
+ return err
+ }
+ defer r.Close()
+
+ os.MkdirAll(dest, 0750)
+
+ for _, f := range r.File {
+ if f.FileInfo().IsDir() { // Skip directories in this example for simplicity.
+ continue
+ }
+
+ rc, err := f.Open()
+ if err != nil {
+ return err
+ }
+ defer rc.Close()
+
+ path := filepath.Join(dest, f.Name) // Oops! We blindly use the entry file name for the destination.
+ os.MkdirAll(filepath.Dir(path), f.Mode())
+ f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+
+ if _, err := io.Copy(f, rc); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+```
+
+#### Best practices
+
+Always expand the destination file path by resolving all potential directory traversals and other sequences that can alter the path and refuse extraction if the final destination path does not start with the intended destination directory.
+
+##### Ruby
+
+```ruby
+# tar.gz extraction example with protection against Zip Slip attacks.
+
+begin
+ tar_extract = Gem::Package::TarReader.new(Zlib::GzipReader.open("/tmp/uploaded.tar.gz"))
+rescue Errno::ENOENT
+ STDERR.puts("archive file does not exist or is not readable")
+ exit(false)
+end
+tar_extract.rewind
+
+tar_extract.each do |entry|
+ next unless entry.file? # Only process files in this example for simplicity.
+
+ # safe_destination will raise an exception in case of Zip Slip / directory traversal.
+ destination = safe_destination(entry.full_name, "/tmp/extracted")
+
+ File.open(destination, "wb") do |out|
+ out.write(entry.read)
+ end
+end
+
+def safe_destination(filename, destination_dir)
+ raise "filename cannot start with '/'" if filename.start_with?("/")
+
+ destination_dir = File.realpath(destination_dir)
+ destination = File.expand_path(filename, destination_dir)
+
+ raise "filename is outside of destination directory" unless
+ destination.start_with?(destination_dir + "/"))
+
+ destination
+end
+```
+
+```ruby
+# zip extraction example using rubyzip with built-in protection against Zip Slip attacks.
+require 'zip'
+
+Zip::File.open("/tmp/uploaded.zip") do |zip_file|
+ zip_file.each do |entry|
+ # Extract entry to /tmp/extracted directory.
+ entry.extract("/tmp/extracted")
+ end
+end
+```
+
+##### Go
+
+You are encouraged to use the secure archive utilities provided by [LabSec](https://gitlab.com/gitlab-com/gl-security/appsec/labsec) which will handle Zip Slip and other types of vulnerabilities for you. The LabSec utilities are also context aware which makes it possible to cancel or timeout extractions:
+
+```golang
+package main
+
+import "gitlab-com/gl-security/appsec/labsec/archive/zip"
+
+func main() {
+ f, err := os.Open("/tmp/uploaded.zip")
+ if err != nil {
+ panic(err)
+ }
+ defer f.Close()
+
+ fi, err := f.Stat()
+ if err != nil {
+ panic(err)
+ }
+
+ if err := zip.Extract(context.Background(), f, fi.Size(), "/tmp/extracted"); err != nil {
+ panic(err)
+ }
+}
+```
+
+In case the LabSec utilities do not fit your needs, here is an example for extracting a zip file with protection against Zip Slip attacks:
+
+```golang
+// unzip extracts source zip file to destination with protection against Zip Slip attacks.
+func unzip(src, dest string) error {
+ r, err := zip.OpenReader(src)
+ if err != nil {
+ return err
+ }
+ defer r.Close()
+
+ os.MkdirAll(dest, 0750)
+
+ for _, f := range r.File {
+ if f.FileInfo().IsDir() { // Skip directories in this example for simplicity.
+ continue
+ }
+
+ rc, err := f.Open()
+ if err != nil {
+ return err
+ }
+ defer rc.Close()
+
+ path := filepath.Join(dest, f.Name)
+
+ // Check for Zip Slip / directory traversal
+ if !strings.HasPrefix(path, filepath.Clean(dest) + string(os.PathSeparator)) {
+ return fmt.Errorf("illegal file path: %s", path)
+ }
+
+ os.MkdirAll(filepath.Dir(path), f.Mode())
+ f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+
+ if _, err := io.Copy(f, rc); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+```
+
+### Symlink attacks
+
+Symlink attacks makes it possible for an attacker to read the contents of arbitrary files on the server of a vulnerable application. While it is a high-severity vulnerability that can often lead to remote code execution and other critical vulnerabilities, it is only exploitable in scenarios where a vulnerable application accepts archive files from the attacker and somehow displays the extracted contents back to the attacker without any validation or sanitization of symbolic links inside the archive.
+
+### Insecure archive symlink extraction examples
+
+#### Ruby
+
+For zip files, the [rubyzip](https://rubygems.org/gems/rubyzip) Ruby gem is already patched against symlink attacks as it simply ignores symbolic links, so for this vulnerable example we will extract a `tar.gz` file with `Gem::Package::TarReader`:
+
+```ruby
+# Vulnerable tar.gz extraction example!
+
+begin
+ tar_extract = Gem::Package::TarReader.new(Zlib::GzipReader.open("/tmp/uploaded.tar.gz"))
+rescue Errno::ENOENT
+ STDERR.puts("archive file does not exist or is not readable")
+ exit(false)
+end
+tar_extract.rewind
+
+# Loop over each entry and output file contents
+tar_extract.each do |entry|
+ next if entry.directory?
+
+ # Oops! We don't check if the file is actually a symbolic link to a potentially sensitive file.
+ puts entry.read
+end
+```
+
+#### Go
+
+```golang
+// printZipContents INSECURELY prints contents of files in a zip file.
+func printZipContents(src string) error {
+ r, err := zip.OpenReader(src)
+ if err != nil {
+ return err
+ }
+ defer r.Close()
+
+ // Loop over each entry and output file contents
+ for _, f := range r.File {
+ if f.FileInfo().IsDir() {
+ continue
+ }
+
+ rc, err := f.Open()
+ if err != nil {
+ return err
+ }
+ defer rc.Close()
+
+ // Oops! We don't check if the file is actually a symbolic link to a potentially sensitive file.
+ buf, err := ioutil.ReadAll(rc)
+ if err != nil {
+ return err
+ }
+
+ fmt.Println(buf.String())
+ }
+
+ return nil
+}
+```
+
+#### Best practices
+
+Always check the type of the archive entry before reading the contents and ignore entries that are not plain files. If you absolutely must support symbolic links, ensure that they only point to files inside the archive and nowhere else.
+
+##### Ruby
+
+```ruby
+# tar.gz extraction example with protection against symlink attacks.
+
+begin
+ tar_extract = Gem::Package::TarReader.new(Zlib::GzipReader.open("/tmp/uploaded.tar.gz"))
+rescue Errno::ENOENT
+ STDERR.puts("archive file does not exist or is not readable")
+ exit(false)
+end
+tar_extract.rewind
+
+# Loop over each entry and output file contents
+tar_extract.each do |entry|
+ next if entry.directory?
+
+ # By skipping symbolic links entirely, we are sure they can't cause any trouble!
+ next if entry.symlink?
+
+ puts entry.read
+end
+```
+
+##### Go
+
+You are encouraged to use the secure archive utilities provided by [LabSec](https://gitlab.com/gitlab-com/gl-security/appsec/labsec) which will handle Zip Slip and symlink vulnerabilities for you. The LabSec utilities are also context aware which makes it possible to cancel or timeout extractions.
+
+In case the LabSec utilities do not fit your needs, here is an example for extracting a zip file with protection against symlink attacks:
+
+```golang
+// printZipContents prints contents of files in a zip file with protection against symlink attacks.
+func printZipContents(src string) error {
+ r, err := zip.OpenReader(src)
+ if err != nil {
+ return err
+ }
+ defer r.Close()
+
+ // Loop over each entry and output file contents
+ for _, f := range r.File {
+ if f.FileInfo().IsDir() {
+ continue
+ }
+
+ // By skipping all irregular file types (including symbolic links), we are sure they can't cause any trouble!
+ if !zf.Mode().IsRegular() {
+ continue
+ }
+
+ rc, err := f.Open()
+ if err != nil {
+ return err
+ }
+ defer rc.Close()
+
+ buf, err := ioutil.ReadAll(rc)
+ if err != nil {
+ return err
+ }
+
+ fmt.Println(buf.String())
+ }
+
+ return nil
+}
+```
diff --git a/doc/development/service_ping/index.md b/doc/development/service_ping/index.md
index 1f751eea4d8..315ff2b090c 100644
--- a/doc/development/service_ping/index.md
+++ b/doc/development/service_ping/index.md
@@ -311,7 +311,8 @@ The following is example content of the Service Ping payload.
"database": {
"adapter": "postgresql",
"version": "9.6.15",
- "pg_system_id": 6842684531675334351
+ "pg_system_id": 6842684531675334351,
+ "flavor": "Cloud SQL for PostgreSQL"
},
"analytics_unique_visits": {
"g_analytics_contribution": 999,
@@ -435,6 +436,10 @@ The following is example content of the Service Ping payload.
## Notable changes
+In GitLab 14.6, [`flavor`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75587) was added to try to detect the underlying managed database variant.
+Possible values are "Amazon Aurora PostgreSQL", "PostgreSQL on Amazon RDS", "Cloud SQL for PostgreSQL",
+"Azure Database for PostgreSQL - Flexible Server", or "null".
+
In GitLab 13.5, `pg_system_id` was added to send the [PostgreSQL system identifier](https://www.2ndquadrant.com/en/blog/support-for-postgresqls-system-identifier-in-barman/).
## Export Service Ping SQL queries and definitions
diff --git a/doc/development/service_ping/metrics_instrumentation.md b/doc/development/service_ping/metrics_instrumentation.md
index 6fdbd1eea31..c98b0df92aa 100644
--- a/doc/development/service_ping/metrics_instrumentation.md
+++ b/doc/development/service_ping/metrics_instrumentation.md
@@ -33,6 +33,12 @@ We have built a domain-specific language (DSL) to define the metrics instrumenta
## Database metrics
+- `operation`: Operations for the given `relation`, one of `count`, `distinct_count`.
+- `relation`: `ActiveRecord::Relation` for the objects we want to perform the `operation`.
+- `start`: Specifies the start value of the batch counting, by default is `relation.minimum(:id)`.
+- `finish`: Specifies the end value of the batch counting, by default is `relation.maximum(:id)`.
+- `cache_start_and_finish_as`: Specifies the cache key for `start` and `finish` values and sets up caching them. Use this call when `start` and `finish` are expensive queries that should be reused between different metric calculations.
+
[Example of a merge request that adds a database metric](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60022).
```ruby
diff --git a/doc/development/service_ping/performance_indicator_metrics.md b/doc/development/service_ping/performance_indicator_metrics.md
new file mode 100644
index 00000000000..48c123171fa
--- /dev/null
+++ b/doc/development/service_ping/performance_indicator_metrics.md
@@ -0,0 +1,17 @@
+---
+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
+---
+
+# Performance Indicator Metrics guide
+
+This guide describes how to use metrics definitions to define [performance indicator](https://about.gitlab.com/handbook/product/product-intelligence-guide/#implementing-product-performance-indicators) metrics.
+
+To use a metric definition to manage a performance indicator:
+
+1. Create a new issue and use the [Performance Indicator Metric issue template](https://gitlab.com/gitlab-org/gitlab/-/issues/new?issuable_template=Performance%20Indicator%20Metric).
+1. Use labels `~"product intelligence"`, `"~Data Warehouse::Impact Check"`.
+1. Create a merge request that includes changes related only to the metric performance indicator.
+1. Update the metric definition `performance_indicator_type` [field](metrics_dictionary.md#metrics-definition-and-validation).
+1. Create an issue in GitLab Data Team project with the [Product Performance Indicator template](https://gitlab.com/gitlab-data/analytics/-/issues/new?issuable_template=Product%20Performance%20Indicator%20Template).
diff --git a/doc/development/sidekiq_style_guide.md b/doc/development/sidekiq_style_guide.md
index 2137a7d83e6..af994e7138d 100644
--- a/doc/development/sidekiq_style_guide.md
+++ b/doc/development/sidekiq_style_guide.md
@@ -13,7 +13,7 @@ modifying Sidekiq workers.
All workers should include `ApplicationWorker` instead of `Sidekiq::Worker`,
which adds some convenience methods and automatically sets the queue based on
-the worker's name.
+the [routing rules](../administration/operations/extra_sidekiq_routing.md#queue-routing-rules).
## Retries
@@ -45,19 +45,26 @@ Each retry for a worker is counted as a failure in our metrics. A worker
which always fails 9 times and succeeds on the 10th would have a 90%
error rate.
-## Dedicated Queues
+## Sidekiq Queues
-All workers should use their own queue, which is automatically set based on the
+Previously, each worker had its own queue, which was automatically set based on the
worker class name. For a worker named `ProcessSomethingWorker`, the queue name
-would be `process_something`. If you're not sure what queue a worker uses,
+would be `process_something`. You can now route workers to a specific queue using
+[queue routing rules](../administration/operations/extra_sidekiq_routing.md#queue-routing-rules).
+In GDK, new workers are routed to a queue named `default`.
+
+If you're not sure what queue a worker uses,
you can find it using `SomeWorker.queue`. There is almost never a reason to
manually override the queue name using `sidekiq_options queue: :some_queue`.
-After adding a new queue, run `bin/rake
+After adding a new worker, run `bin/rake
gitlab:sidekiq:all_queues_yml:generate` to regenerate
`app/workers/all_queues.yml` or `ee/app/workers/all_queues.yml` so that
it can be picked up by
-[`sidekiq-cluster`](../administration/operations/extra_sidekiq_processes.md).
+[`sidekiq-cluster`](../administration/operations/extra_sidekiq_processes.md)
+in installations that don't use routing rules. To learn more about potential changes,
+read [Use routing rules by default and deprecate queue selectors for self-managed](https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/596).
+
Additionally, run
`bin/rake gitlab:sidekiq:sidekiq_queues_yml:generate` to regenerate
`config/sidekiq_queues.yml`.
diff --git a/doc/development/snowplow/dictionary.md b/doc/development/snowplow/dictionary.md
deleted file mode 100644
index 02e9ba5ce20..00000000000
--- a/doc/development/snowplow/dictionary.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-redirect_to: 'https://metrics.gitlab.com/snowplow.html'
-remove_date: '2021-12-28'
----
diff --git a/doc/development/snowplow/implementation.md b/doc/development/snowplow/implementation.md
index 6da4896c7e7..439485c9e73 100644
--- a/doc/development/snowplow/implementation.md
+++ b/doc/development/snowplow/implementation.md
@@ -397,6 +397,7 @@ Before you test frontend events in development, you must:
All URLs are pseudonymized. The entity identifier [replaces](https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/javascript-trackers/javascript-tracker/javascript-tracker-v2/tracker-setup/other-parameters-2/#Setting_a_custom_page_URL_and_referrer_URL) personally identifiable
information (PII). PII includes usernames, group, and project names.
+Page titles are hardcoded as `GitLab` for the same reason.
#### Snowplow Analytics Debugger Chrome Extension
diff --git a/doc/development/snowplow/schemas.md b/doc/development/snowplow/schemas.md
index f66e0566a9c..eb57e7d98a5 100644
--- a/doc/development/snowplow/schemas.md
+++ b/doc/development/snowplow/schemas.md
@@ -19,6 +19,7 @@ The [`StandardContext`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/g
| `project_id` | **{dotted-circle}** | integer | |
| `namespace_id` | **{dotted-circle}** | integer | |
| `user_id` | **{dotted-circle}** | integer | User database record ID attribute. This file undergoes a pseudonymization process at the collector level. |
+| `context_generated_at` | **{dotted-circle}** | string (date time format) | Timestamp indicating when context was generated. |
| `environment` | **{check-circle}** | string (max 32 chars) | Name of the source environment, such as `production` or `staging` |
| `source` | **{check-circle}** | string (max 32 chars) | Name of the source application, such as `gitlab-rails` or `gitlab-javascript` |
| `plan` | **{dotted-circle}** | string (max 32 chars) | Name of the plan for the namespace, such as `free`, `premium`, or `ultimate`. Automatically picked from the `namespace`. |
@@ -30,6 +31,7 @@ The [`StandardContext`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/g
Frontend events include a [web-specific schema](https://docs.snowplowanalytics.com/docs/understanding-your-pipeline/canonical-event/#Web-specific_fields) provided by Snowplow.
All URLs are pseudonymized. The entity identifier [replaces](https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/javascript-trackers/javascript-tracker/javascript-tracker-v2/tracker-setup/other-parameters-2/#Setting_a_custom_page_URL_and_referrer_URL) personally identifiable
information (PII). PII includes usernames, group, and project names.
+Page titles are hardcoded as `GitLab` for the same reason.
| Field Name | Required | Type | Description |
|--------------------------|---------------------|-----------|----------------------------------------------------------------------------------------------------------------------------------|
@@ -105,7 +107,7 @@ information (PII). PII includes usernames, group, and project names.
| `os_name` | **{dotted-circle}** | string | Name of operating system |
| `os_timezone` | **{dotted-circle}** | string | Client operating system time zone |
| `page_referrer` | **{dotted-circle}** | string | Referrer URL |
-| `page_title` | **{dotted-circle}** | string | Page title |
+| `page_title` | **{dotted-circle}** | string | To not expose personal identifying information, the page title is hardcoded as `GitLab` |
| `page_url` | **{dotted-circle}** | string | Page URL |
| `page_urlfragment` | **{dotted-circle}** | string | Fragment aka anchor |
| `page_urlhost` | **{dotted-circle}** | string | Host aka domain |
diff --git a/doc/development/testing_guide/best_practices.md b/doc/development/testing_guide/best_practices.md
index 0f768a51b66..fe0c4c13ba2 100644
--- a/doc/development/testing_guide/best_practices.md
+++ b/doc/development/testing_guide/best_practices.md
@@ -642,6 +642,11 @@ should either:
It takes around one second to load tests that are using `fast_spec_helper`
instead of 30+ seconds in case of a regular `spec_helper`.
+WARNING:
+To verify that code and its specs are well-isolated from Rails, run the spec
+individually via `bin/rspec`. Don't use `bin/spring rspec` as it loads
+`spec_helper` automatically.
+
### `subject` and `let` variables
The GitLab RSpec suite has made extensive use of `let`(along with its strict, non-lazy
diff --git a/doc/development/testing_guide/ci.md b/doc/development/testing_guide/ci.md
deleted file mode 100644
index de024084c9c..00000000000
--- a/doc/development/testing_guide/ci.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: '../pipelines.md'
-remove_date: '2022-01-12'
----
-
-This file was moved to [another location](../pipelines.md).
-
-<!-- This redirect file can be deleted after <2022-01-12>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
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 de34e6a1872..48157a961e1 100644
--- a/doc/development/testing_guide/end_to_end/feature_flags.md
+++ b/doc/development/testing_guide/end_to_end/feature_flags.md
@@ -118,6 +118,32 @@ view 'app/views/devise/passwords/new_edit_behind_ff.html.haml' do
end
```
+## Working with resource classes
+
+If a resource class must behave differently when a feature flag is active, toggle a
+variable with the name of the feature flag inside the class. This variable and condition
+ensure all actions are handled appropriately.
+
+You can set this variable inside the `fabricate_via_api` call. For a consistent approach:
+
+- Use an `activated` check, not a deactivated one.
+- Add the word `activated` to the end of a variable's name.
+- Inside the `initialize` method, set the variable's default value.
+
+For example:
+
+```ruby
+def initialize
+ name_of_the_future_flag_activated = false
+ ...
+end
+```
+
+### Cleanup
+
+After the feature flag is removed, clean up the resource class and delete the variable.
+All methods should use the condition procedures of the now-default state.
+
## Running a scenario with a feature flag enabled
It's also possible to run an entire scenario with a feature flag enabled, without having to edit
diff --git a/doc/development/testing_guide/end_to_end/index.md b/doc/development/testing_guide/end_to_end/index.md
index 57c8c3bf59c..1fc9bc8258a 100644
--- a/doc/development/testing_guide/end_to_end/index.md
+++ b/doc/development/testing_guide/end_to_end/index.md
@@ -170,6 +170,35 @@ Helm chart](https://gitlab.com/gitlab-org/charts/gitlab/), itself deployed with
See [Review Apps](../review_apps.md) for more details about Review Apps.
+### Run tests in parallel
+
+To run tests in parallel on CI, the [Knapsack](https://github.com/KnapsackPro/knapsack)
+gem is used. Knapsack reports are generated automatically and stored in the `GCS` bucket
+`knapsack-reports` in the `gitlab-qa-resources` project. The [`KnapsackReport`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/qa/qa/tools/knapsack_report.rb)
+helper handles automated report generation and upload.
+
+## Test metrics
+
+For additional test health visibility, use a custom setup to export test execution
+results to your [InfluxDb](https://influxdb.quality.gitlab.net/) instance, and visualize
+results as [Grafana](https://dashboards.quality.gitlab.net/) dashboards.
+
+### Provisioning
+
+Provisioning of all components is performed by the
+[`engineering-productivity-infrastructure`](https://gitlab.com/gitlab-org/quality/engineering-productivity-infrastructure) project.
+
+### Exporting metrics in CI
+
+Use these environment variables to configure metrics export:
+
+| Variable | Required | Information |
+| -------- | -------- | ----------- |
+| `QA_INFLUXDB_URL` | `true` | Should be set to `https://influxdb.quality.gitlab.net`. No default value. |
+| `QA_INFLUXDB_TOKEN` | `true` | InfluxDB write token that can be found under `Influxdb auth tokens` document in `Gitlab-QA` `1Password` vault. No default value. |
+| `QA_RUN_TYPE` | `false` | Arbitrary name for test execution, like `package-and-qa`. Automatically inferred from the project name for live environment test executions. No default value. |
+| `QA_EXPORT_TEST_METRICS` | `false` | Flag to enable or disable metrics export. Defaults to `true`. |
+
## Test reports
### Allure report
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 cb15dbe023f..bb214976926 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
@@ -34,7 +34,7 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec
| `:packages` | The test requires a GitLab instance that has the [Package Registry](../../../administration/packages/#gitlab-package-registry-administration) enabled. |
| `:quarantine` | The test has been [quarantined](https://about.gitlab.com/handbook/engineering/quality/guidelines/debugging-qa-test-failures/#quarantining-tests), runs in a separate job that only includes quarantined tests, and is allowed to fail. The test is skipped in its regular job so that if it fails it doesn't hold up the pipeline. Note that you can also [quarantine a test only when it runs in a specific context](execution_context_selection.md#quarantine-a-test-for-a-specific-environment). |
| `:relative_url` | The test requires a GitLab instance to be installed under a [relative URL](../../../install/relative_url.md). |
-| `:reliable` | The test has been [promoted to a reliable test](https://about.gitlab.com/handbook/engineering/quality/guidelines/reliable-tests/#promoting-an-existing-test-to-reliable) meaning it passes consistently in all pipelines, including merge requests. |
+| `:reliable` | The test has been [promoted to a reliable test](https://about.gitlab.com/handbook/engineering/quality/quality-engineering/reliable-tests/#promoting-an-existing-test-to-reliable) meaning it passes consistently in all pipelines, including merge requests. |
| `:repository_storage` | The test requires a GitLab instance to be configured to use multiple [repository storage paths](../../../administration/repository_storage_paths.md). Paired with the `:orchestrated` tag. |
| `:requires_admin` | The test requires an administrator account. Tests with the tag are excluded when run against Canary and Production environments. |
| `:requires_git_protocol_v2` | The test requires that Git protocol version 2 is enabled on the server. It's assumed to be enabled by default but if not the test can be skipped by setting `QA_CAN_TEST_GIT_PROTOCOL_V2` to `false`. |
@@ -46,4 +46,4 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec
| `:smtp` | The test requires a GitLab instance to be configured to use an SMTP server. Tests SMTP notification email delivery from GitLab by using MailHog. |
| `:testcase` | The link to the test case issue in the [GitLab Project Test Cases](https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases). |
| `:transient` | The test tests transient bugs. It is excluded by default. |
-| `:issue`, `:issue_${num}` | Optional links to issues which might be related to the spec. Helps keeping track of related issues and can also be used by tools that create test reports. Currently added automatically to `Allure` test report. Multiple tags can be used by adding optional number postfix like `issue_1`, `issue_2` etc. |
+| `:issue`, `:issue_${num}` | Optional links to issues which might be related to the spec. Helps keep track of related issues and can also be used by tools that create test reports. Currently added automatically to `Allure` test report. Multiple tags can be used by adding an optional numeric suffix like `issue_1`, `issue_2` etc. |
diff --git a/doc/development/testing_guide/review_apps.md b/doc/development/testing_guide/review_apps.md
index 31a807697c5..aef83109b9b 100644
--- a/doc/development/testing_guide/review_apps.md
+++ b/doc/development/testing_guide/review_apps.md
@@ -14,6 +14,7 @@ For any of the following scenarios, the `start-review-app-pipeline` job would be
- for merge requests with CI config changes
- for merge requests with frontend changes
+- for merge requests with changes to `{,ee/,jh/}{app/controllers}/**/*`
- for merge requests with QA changes
- for scheduled pipelines
- the MR has the `pipeline:run-review-app` label set
@@ -21,13 +22,13 @@ For any of the following scenarios, the `start-review-app-pipeline` job would be
## QA runs on Review Apps
On every [pipeline](https://gitlab.com/gitlab-org/gitlab/pipelines/125315730) in the `qa` stage (which comes after the
-`review` stage), the `review-qa-smoke` job is automatically started and it runs
-the QA smoke suite.
+`review` stage), the `review-qa-smoke` and `review-qa-reliable` jobs are automatically started. The `review-qa-smoke` runs
+the QA smoke suite and the `review-qa-reliable` executes E2E tests identified as [reliable](https://about.gitlab.com/handbook/engineering/quality/quality-engineering/reliable-tests).
You can also manually start the `review-qa-all`: it runs the full QA suite.
After the end-to-end test runs have finished, [Allure reports](https://github.com/allure-framework/allure2) are generated and published by
-the `allure-report-qa-smoke` and `allure-report-qa-all` jobs. A comment with links to the reports are added to the merge request.
+the `allure-report-qa-smoke`, `allure-report-qa-reliable`, and `allure-report-qa-all` jobs. A comment with links to the reports are added to the merge request.
## Performance Metrics
@@ -121,7 +122,7 @@ graph TD
B[review-build-cng];
C[review-deploy];
D[CNG-mirror];
- E[review-qa-smoke];
+ E[review-qa-smoke, review-qa-reliable];
A -->|once the `prepare` stage is done| B
B -.->|triggers a CNG-mirror pipeline and wait for it to be done| D
@@ -142,7 +143,7 @@ subgraph "3. gitlab `review` stage"
end
subgraph "4. gitlab `qa` stage"
- E[review-qa-smoke<br><br>gitlab-qa runs the smoke suite against the Review App.]
+ E[review-qa-smoke, review-qa-reliable<br><br>gitlab-qa runs the smoke and reliable suites against the Review App.]
end
subgraph "CNG-mirror pipeline"
@@ -196,7 +197,7 @@ subgraph "CNG-mirror pipeline"
issue with a link to your merge request. Note that the deployment failure can
reveal an actual problem introduced in your merge request (that is, this isn't
necessarily a transient failure)!
-- If the `review-qa-smoke` job keeps failing (note that we already retry it twice),
+- If the `review-qa-smoke` or `review-qa-reliable` job keeps failing (note that we already retry them once),
please check the job's logs: you could discover an actual problem introduced in
your merge request. You can also download the artifacts to see screenshots of
the page at the time the failures occurred. If you don't find the cause of the
@@ -250,7 +251,7 @@ Leading indicators may be health check failures leading to restarts or majority
The [Review Apps Overview dashboard](https://console.cloud.google.com/monitoring/classic/dashboards/6798952013815386466?project=gitlab-review-apps&timeDomain=1d)
aids in identifying load spikes on the cluster, and if nodes are problematic or the entire cluster is trending towards unhealthy.
-### Database related errors in `review-deploy` or `review-qa-smoke`
+### Database related errors in `review-deploy`, `review-qa-smoke`, or `review-qa-reliable`
Occasionally the state of a Review App's database could diverge from the database schema. This could be caused by
changes to migration files or schema, such as a migration being renamed or deleted. This typically manifests in migration errors such as:
diff --git a/doc/development/wikis.md b/doc/development/wikis.md
index 994312da98e..deea3d38470 100644
--- a/doc/development/wikis.md
+++ b/doc/development/wikis.md
@@ -1,5 +1,4 @@
---
-type: reference, dev
stage: Create
group: Editor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
@@ -91,8 +90,6 @@ Only some data is persisted in the database:
The web UI uploads attachments through the REST API, which stores the files as commits in the wiki repository.
-Prior to GitLab 11.3 attachments were stored outside of the repository, [see this issue](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/33475).
-
## Related topics
- [Gollum installation instructions](https://github.com/gollum/gollum/wiki/Installation)
diff --git a/doc/gitlab-basics/command-line-commands.md b/doc/gitlab-basics/command-line-commands.md
index fe69346c316..02e9117fa3a 100644
--- a/doc/gitlab-basics/command-line-commands.md
+++ b/doc/gitlab-basics/command-line-commands.md
@@ -1,15 +1,14 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: howto, reference
+info: 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
---
# Edit files through the command line **(FREE)**
When [working with Git from the command line](start-using-git.md), you need to
use more than just the Git commands. There are several basic commands that you should
-learn, in order to make full use of the command line.
+learn to make full use of the command line.
## Start working on your project
diff --git a/doc/install/aws/gitlab_hybrid_on_aws.md b/doc/install/aws/gitlab_hybrid_on_aws.md
index dbd23ff2b30..2183f351efd 100644
--- a/doc/install/aws/gitlab_hybrid_on_aws.md
+++ b/doc/install/aws/gitlab_hybrid_on_aws.md
@@ -238,7 +238,7 @@ If EKS node autoscaling is employed, it is likely that your average loading will
**Deploy Now**
-Deploy Now links leverage the AWS Quick Start automation and only prepopulate the number of instances and instance types for the Quick Start based on the Bill of Meterials below. You must provide appropriate input for all other parameters by following the guidance in the [Quick Start documentation's Deployment steps](https://aws-quickstart.github.io/quickstart-eks-gitlab/#_deployment_steps) section.
+Deploy Now links leverage the AWS Quick Start automation and only prepopulate the number of instances and instance types for the Quick Start based on the Bill of Materials below. You must provide appropriate input for all other parameters by following the guidance in the [Quick Start documentation's Deployment steps](https://aws-quickstart.github.io/quickstart-eks-gitlab/#_deployment_steps) section.
- **[Deploy Now: AWS Quick Start for 2 AZs](https://us-east-2.console.aws.amazon.com/cloudformation/home?region=us-east-2#/stacks/quickcreate?templateUrl=https://aws-quickstart.s3.us-east-1.amazonaws.com/quickstart-eks-gitlab/templates/gitlab-entry-new-vpc.template.yaml&stackName=Gitlab-EKS-5K-Users-2AZs&param_NumberOfAZs=2&param_NodeInstanceType=c5.2xlarge&param_NumberOfNodes=5&param_MaxNumberOfNodes=5&param_DBInstanceClass=db.r6g.2xlarge&param_CacheNodes=2&param_CacheNodeType=cache.m6g.xlarge&param_GitalyInstanceType=m5.2xlarge&param_NumberOfGitalyReplicas=2&param_PraefectInstanceType=c5.large&param_NumberOfPraefectReplicas=2)**
- **[Deploy Now: AWS Quick Start for 3 AZs](https://us-east-2.console.aws.amazon.com/cloudformation/home?region=us-east-2#/stacks/quickcreate?templateUrl=https://aws-quickstart.s3.us-east-1.amazonaws.com/quickstart-eks-gitlab/templates/gitlab-entry-new-vpc.template.yaml&stackName=Gitlab-EKS-5K-Users-3AZs&param_NumberOfAZs=3&param_NodeInstanceType=c5.2xlarge&param_NumberOfNodes=5&param_MaxNumberOfNodes=5&param_DBInstanceClass=db.r6g.2xlarge&param_CacheNodes=3&param_CacheNodeType=cache.m6g.xlarge&param_GitalyInstanceType=m5.2xlarge&param_NumberOfGitalyReplicas=3&param_PraefectInstanceType=c5.large&param_NumberOfPraefectReplicas=3)**
@@ -292,7 +292,7 @@ If EKS node autoscaling is employed, it is likely that your average loading will
**Deploy Now**
-Deploy Now links leverage the AWS Quick Start automation and only prepopulate the number of instances and instance types for the Quick Start based on the Bill of Meterials below. You must provide appropriate input for all other parameters by following the guidance in the [Quick Start documentation's Deployment steps](https://aws-quickstart.github.io/quickstart-eks-gitlab/#_deployment_steps) section.
+Deploy Now links leverage the AWS Quick Start automation and only prepopulate the number of instances and instance types for the Quick Start based on the Bill of Materials below. You must provide appropriate input for all other parameters by following the guidance in the [Quick Start documentation's Deployment steps](https://aws-quickstart.github.io/quickstart-eks-gitlab/#_deployment_steps) section.
- **[Deploy Now: AWS Quick Start for 3 AZs](https://us-east-2.console.aws.amazon.com/cloudformation/home?region=us-east-2#/stacks/quickcreate?templateUrl=https://aws-quickstart.s3.us-east-1.amazonaws.com/quickstart-eks-gitlab/templates/gitlab-entry-new-vpc.template.yaml&stackName=Gitlab-EKS-10K-Users-3AZs&param_NumberOfAZs=3&param_NodeInstanceType=c5.4xlarge&param_NumberOfNodes=9&param_MaxNumberOfNodes=9&param_DBInstanceClass=db.r6g.2xlarge&param_CacheNodes=3&param_CacheNodeType=cache.m6g.2xlarge&param_GitalyInstanceType=m5.4xlarge&param_NumberOfGitalyReplicas=3&param_PraefectInstanceType=c5.large&param_NumberOfPraefectReplicas=3)**
@@ -345,7 +345,7 @@ If EKS node autoscaling is employed, it is likely that your average loading will
**Deploy Now**
-Deploy Now links leverage the AWS Quick Start automation and only prepopulate the number of instances and instance types for the Quick Start based on the Bill of Meterials below. You must provide appropriate input for all other parameters by following the guidance in the [Quick Start documentation's Deployment steps](https://aws-quickstart.github.io/quickstart-eks-gitlab/#_deployment_steps) section.
+Deploy Now links leverage the AWS Quick Start automation and only prepopulate the number of instances and instance types for the Quick Start based on the Bill of Materials below. You must provide appropriate input for all other parameters by following the guidance in the [Quick Start documentation's Deployment steps](https://aws-quickstart.github.io/quickstart-eks-gitlab/#_deployment_steps) section.
- **[Deploy Now: AWS Quick Start for 3 AZs - 1/4 Scale EKS](https://us-east-2.console.aws.amazon.com/cloudformation/home?region=us-east-2#/stacks/quickcreate?templateUrl=https://aws-quickstart.s3.us-east-1.amazonaws.com/quickstart-eks-gitlab/templates/gitlab-entry-new-vpc.template.yaml&stackName=Gitlab-EKS-50K-Users-3AZs&param_NumberOfAZs=3&param_NodeInstanceType=c5.4xlarge&param_NumberOfNodes=7&param_MaxNumberOfNodes=9&param_DBInstanceClass=db.r6g.8xlarge&param_CacheNodes=3&param_CacheNodeType=cache.m6g.2xlarge&param_GitalyInstanceType=m5.16xlarge&param_NumberOfGitalyReplicas=3&param_PraefectInstanceType=c5.xlarge&param_NumberOfPraefectReplicas=3)**
diff --git a/doc/install/aws/index.md b/doc/install/aws/index.md
index bec1f3e1142..8dbda7420b0 100644
--- a/doc/install/aws/index.md
+++ b/doc/install/aws/index.md
@@ -43,6 +43,7 @@ The following repository is self-contained in regard to enabling this pattern: [
- Using GitLab and AWS together.
- Running GitLab infrastructure on AWS.
+- Retrieving temporary credentials for access to AWS services.
## AWS known issues list
@@ -62,7 +63,7 @@ When deploying a GitLab instance using the official AMI, the root password to th
Instances running on Community Edition (CE) require a migration to Enterprise Edition (EE) in order to subscribe to the GitLab Premium or Ultimate plan. If you want to pursue a subscription, using the Free-forever plan of Enterprise Edition is the least disruptive method.
NOTE:
-Since any given GitLab upgrade might involve data disk updates or database schema upgrades, simply swapping out the AMI is not sufficent for taking upgrades.
+Since any given GitLab upgrade might involve data disk updates or database schema upgrades, simply swapping out the AMI is not sufficent for taking upgrades.
1. Log in to the AWS Web Console, so that clicking the links in the following step take you directly to the AMI list.
1. Pick the edition you want:
diff --git a/doc/install/aws/manual_install_aws.md b/doc/install/aws/manual_install_aws.md
index 6dacd8df3e4..531a006dbf3 100644
--- a/doc/install/aws/manual_install_aws.md
+++ b/doc/install/aws/manual_install_aws.md
@@ -268,8 +268,7 @@ On the EC2 dashboard, look for Load Balancer in the left navigation bar:
1. Click **Configure Health Check** and set up a health check for your EC2 instances.
1. For **Ping Protocol**, select HTTP.
1. For **Ping Port**, enter 80.
- 1. For **Ping Path**, enter `/users/sign_in`. (We use `/users/sign_in` as it's a public endpoint that does
- not require authentication.)
+ 1. For **Ping Path** - we recommend that you [use the Readiness check endpoint](../../administration/load_balancer.md#readiness-check). You'll need to add [the VPC IP Adddress Range (CIDR)](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-groups.html#elb-vpc-nacl) to the [IP Allowlist](../../administration/monitoring/ip_whitelist.md) for the [Health Check endpoints](../../user/admin_area/monitoring/health_check.md)
1. Keep the default **Advanced Details** or adjust them according to your needs.
1. Click **Add EC2 Instances** - don't add anything as we will create an Auto Scaling Group later to manage instances for us.
1. Click **Add Tags** and add any tags you need.
diff --git a/doc/install/docker.md b/doc/install/docker.md
index 2efe6a3640b..ed5e1dda5d5 100644
--- a/doc/install/docker.md
+++ b/doc/install/docker.md
@@ -141,23 +141,25 @@ install, and upgrade your Docker-based GitLab installation:
1. Create a `docker-compose.yml` file (or [download an example](https://gitlab.com/gitlab-org/omnibus-gitlab/raw/master/docker/docker-compose.yml)):
```yaml
- web:
- image: 'gitlab/gitlab-ee:latest'
- restart: always
- hostname: 'gitlab.example.com'
- environment:
- GITLAB_OMNIBUS_CONFIG: |
- external_url 'https://gitlab.example.com'
- # Add any other gitlab.rb configuration here, each on its own line
- ports:
- - '80:80'
- - '443:443'
- - '22:22'
- volumes:
- - '$GITLAB_HOME/config:/etc/gitlab'
- - '$GITLAB_HOME/logs:/var/log/gitlab'
- - '$GITLAB_HOME/data:/var/opt/gitlab'
- shm_size: '256m'
+ version: '3.6'
+ services:
+ web:
+ image: 'gitlab/gitlab-ee:latest'
+ restart: always
+ hostname: 'gitlab.example.com'
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ external_url 'https://gitlab.example.com'
+ # Add any other gitlab.rb configuration here, each on its own line
+ ports:
+ - '80:80'
+ - '443:443'
+ - '22:22'
+ volumes:
+ - '$GITLAB_HOME/config:/etc/gitlab'
+ - '$GITLAB_HOME/logs:/var/log/gitlab'
+ - '$GITLAB_HOME/data:/var/opt/gitlab'
+ shm_size: '256m'
```
1. Make sure you are in the same directory as `docker-compose.yml` and start
@@ -176,22 +178,24 @@ HTTP and SSH port. Notice how the `GITLAB_OMNIBUS_CONFIG` variables match the
`ports` section:
```yaml
-web:
- image: 'gitlab/gitlab-ee:latest'
- restart: always
- hostname: 'gitlab.example.com'
- environment:
- GITLAB_OMNIBUS_CONFIG: |
- external_url 'http://gitlab.example.com:8929'
- gitlab_rails['gitlab_shell_ssh_port'] = 2224
- ports:
- - '8929:8929'
- - '2224:22'
- volumes:
- - '$GITLAB_HOME/config:/etc/gitlab'
- - '$GITLAB_HOME/logs:/var/log/gitlab'
- - '$GITLAB_HOME/data:/var/opt/gitlab'
- shm_size: '256m'
+version: '3.6'
+services:
+ web:
+ image: 'gitlab/gitlab-ee:latest'
+ restart: always
+ hostname: 'gitlab.example.com'
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ external_url 'http://gitlab.example.com:8929'
+ gitlab_rails['gitlab_shell_ssh_port'] = 2224
+ ports:
+ - '8929:8929'
+ - '2224:22'
+ volumes:
+ - '$GITLAB_HOME/config:/etc/gitlab'
+ - '$GITLAB_HOME/logs:/var/log/gitlab'
+ - '$GITLAB_HOME/data:/var/opt/gitlab'
+ shm_size: '256m'
```
This is the same as using `--publish 8929:8929 --publish 2224:22`.
@@ -653,3 +657,15 @@ purpose.
### Docker containers exhausts space due to the `json-file`
Docker's [default logging driver is `json-file`](https://docs.docker.com/config/containers/logging/configure/#configure-the-default-logging-driver), which performs no log rotation by default. As a result of this lack of rotation, log files stored by the `json-file` driver can consume a significant amount of disk space for containers that generate a lot of output. This can lead to disk space exhaustion. To address this, use [`journald`](https://docs.docker.com/config/containers/logging/journald/) as the logging driver when available, or [another supported driver](https://docs.docker.com/config/containers/logging/configure/#supported-logging-drivers) with native rotation support.
+
+### Buffer overflow error when starting Docker
+
+If you receive this buffer overflow error, you should purge old log files in
+`/var/log/gitlab`:
+
+```plaintext
+buffer overflow detected : terminated
+xargs: tail: terminated by signal 6
+```
+
+Removing old log files helps fix the error, and ensures a clean startup of the instance.
diff --git a/doc/install/next_steps.md b/doc/install/next_steps.md
index b5cfbfc9bbb..1db2bf9b7b6 100644
--- a/doc/install/next_steps.md
+++ b/doc/install/next_steps.md
@@ -20,9 +20,11 @@ installation.
Runners, the agents that are responsible for all of the GitLab CI/CD features.
- [GitLab Pages](../administration/pages/index.md): Configure GitLab Pages to
allow hosting of static sites.
-- [GitLab Registry](../administration/packages/container_registry.md): With the
- GitLab Container Registry, every project can have its own space to store Docker
+- [GitLab Registry](../administration/packages/container_registry.md): Set up the
+ GitLab Container Registry so every project can have its own space to store Docker
images.
+- [GitLab Dependency Proxy](../administration/packages/dependency_proxy.md): Set up the dependency
+ proxy so you can cache container images from Docker Hub for faster, more reliable builds.
## Security
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index 037fbd7063d..665e80e6e00 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -4,10 +4,10 @@ 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
---
-# Installation requirements **(FREE SELF)**
+# GitLab installation minimum requirements **(FREE SELF)**
-This page includes useful information on the supported Operating Systems as well
-as the hardware requirements that are needed to install and use GitLab.
+This page includes information about both the supported operating systems and
+the minimum requirements needed to install and use GitLab.
## Operating Systems
@@ -15,12 +15,13 @@ as the hardware requirements that are needed to install and use GitLab.
- Ubuntu (16.04/18.04/20.04)
- Debian (9/10)
-- CentOS (7/8)
+- AlmaLinux (8)
+- CentOS (7)
- openSUSE Leap (15.2)
- SUSE Linux Enterprise Server (12 SP2/12 SP5)
-- Red Hat Enterprise Linux (please use the CentOS packages and instructions)
-- Scientific Linux (please use the CentOS packages and instructions)
-- Oracle Linux (please use the CentOS packages and instructions)
+- Red Hat Enterprise Linux (use the AlmaLinux or CentOS instructions)
+- Scientific Linux (use the CentOS instructions)
+- Oracle Linux (use the CentOS instructions)
For the installation options, see [the main installation page](index.md).
diff --git a/doc/integration/bitbucket.md b/doc/integration/bitbucket.md
index db7e7d74efe..2fc80aa1769 100644
--- a/doc/integration/bitbucket.md
+++ b/doc/integration/bitbucket.md
@@ -6,10 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Integrate your GitLab server with Bitbucket Cloud **(FREE SELF)**
-NOTE:
-Starting from GitLab 11.4, OmniAuth is enabled by default. If you're using an
-earlier version, you must explicitly enable it.
-
You can set up Bitbucket.org as an OAuth 2.0 provider to use your Bitbucket.org
account credentials to sign in to GitLab. You can also import your projects from
Bitbucket.org.
diff --git a/doc/integration/datadog.md b/doc/integration/datadog.md
index 89e08d330e8..4be0089703a 100644
--- a/doc/integration/datadog.md
+++ b/doc/integration/datadog.md
@@ -32,9 +32,11 @@ project, group, or instance level:
1. Scroll to **Add an integration**, and select **Datadog**.
1. Select **Active** to enable the integration.
1. Specify the [**Datadog site**](https://docs.datadoghq.com/getting_started/site/) to send data to.
+1. Provide your Datadog **API key**.
+<!-- 1. Optional. Select **Enable logs collection** to enable logs collection for the output of jobs. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/346339) in GitLab 14.8.) -->
+<!-- TODO: uncomment the archive_trace_events field once :datadog_integration_logs_collection is rolled out. Rollout issue: https://gitlab.com/gitlab-org/gitlab/-/issues/346339 -->
1. Optional. To override the API URL used to send data directly, provide an **API URL**.
Used only in advanced scenarios.
-1. Provide your Datadog **API key**.
1. Optional. If you use more than one GitLab instance, provide a unique **Service** name
to differentiate between your GitLab instances.
1. Optional. If you use groups of GitLab instances (such as staging and production
diff --git a/doc/integration/elasticsearch.md b/doc/integration/elasticsearch.md
index 8461aca8c8d..7356574a33e 100644
--- a/doc/integration/elasticsearch.md
+++ b/doc/integration/elasticsearch.md
@@ -478,6 +478,8 @@ The following are some available Rake tasks:
| [`sudo gitlab-rake gitlab:elastic:mark_reindex_failed`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/tasks/gitlab/elastic.rake) | Mark the most recent re-index job as failed. |
| [`sudo gitlab-rake gitlab:elastic:list_pending_migrations`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/tasks/gitlab/elastic.rake) | List pending migrations. Pending migrations include those that have not yet started, have started but not finished, and those that are halted. |
| [`sudo gitlab-rake gitlab:elastic:estimate_cluster_size`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/tasks/gitlab/elastic.rake) | Get an estimate of cluster size based on the total repository size. |
+| [`sudo gitlab-rake gitlab:elastic:enable_search_with_elasticsearch`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/tasks/gitlab/elastic.rake) | Enable advanced search with Elasticsearch. |
+| [`sudo gitlab-rake gitlab:elastic:disable_search_with_elasticsearch`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/tasks/gitlab/elastic.rake) | Disables advanced search with Elasticsearch. |
### Environment variables
diff --git a/doc/integration/jenkins.md b/doc/integration/jenkins.md
index 822530775e5..bae52622966 100644
--- a/doc/integration/jenkins.md
+++ b/doc/integration/jenkins.md
@@ -4,100 +4,80 @@ 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
---
-# Jenkins CI service **(FREE)**
+# Jenkins integration **(FREE)**
> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/246756) to GitLab Free in 13.7.
-From GitLab, you can trigger a Jenkins build when you push code to a repository, or when a merge
-request is created. In return, the Jenkins pipeline status is shown on merge requests widgets and
-on the GitLab project's home page.
+You can trigger a build in Jenkins when you push code to your repository or
+create a merge request in GitLab. The Jenkins pipeline status displays on merge
+requests widgets and on the GitLab project's home page.
-To better understand the GitLab Jenkins integration, watch the following video:
+<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
+For an overview of the Jenkins integration for GitLab, see
+[GitLab workflow with Jira issues and Jenkins pipelines](https://youtu.be/Jn-_fyra7xQ).
-- [GitLab workflow with Jira issues and Jenkins pipelines](https://youtu.be/Jn-_fyra7xQ)
+Use the Jenkins integration when:
-Use the Jenkins integration with GitLab when:
-
-- You plan to migrate your CI from Jenkins to [GitLab CI/CD](../ci/index.md) in the future, but
-need an interim solution.
-- You're invested in [Jenkins Plugins](https://plugins.jenkins.io/) and choose to keep using Jenkins
-to build your apps.
-
-For a real use case, read the blog post [Continuous integration: From Jenkins to GitLab using Docker](https://about.gitlab.com/blog/2017/07/27/docker-my-precious/).
-
-Moving from a traditional CI plug-in to a single application for the entire software development
-life cycle can decrease hours spent on maintaining toolchains by 10% or more. For more details, see
-the ['GitLab vs. Jenkins' comparison page](https://about.gitlab.com/devops-tools/jenkins-vs-gitlab/).
+- You plan to migrate your CI from Jenkins to [GitLab CI/CD](../ci/index.md)
+ in the future, but need an interim solution.
+- You're invested in [Jenkins plugins](https://plugins.jenkins.io/) and choose
+ to keep using Jenkins to build your apps.
NOTE:
-This documentation focuses only on how to **configure** a Jenkins *integration* with
+This documentation focuses only on how to configure a Jenkins *integration* with
GitLab. Learn how to set up Jenkins [on your local machine](../development/integrations/jenkins.md)
-in our developer documentation, and how to **migrate** from Jenkins to GitLab CI/CD in our
+in the developer documentation, and how to migrate from Jenkins to GitLab CI/CD in the
[Migrating from Jenkins](../ci/migration/jenkins.md) documentation.
-## Configure GitLab integration with Jenkins
-
-The GitLab Jenkins integration requires installation and configuration in both GitLab and Jenkins.
-In GitLab, you need to grant Jenkins access to the relevant projects. In Jenkins, you need to
-install and configure several plugins.
-
-### GitLab requirements
-
-- [Grant Jenkins permission to GitLab project](#grant-jenkins-access-to-gitlab-project)
-- [Configure GitLab API access](#configure-gitlab-api-access)
-- [Configure the GitLab project](#configure-the-gitlab-project)
-
-### Jenkins requirements
+The Jenkins integration requires configuration in both GitLab and Jenkins.
-- [Configure the Jenkins server](#configure-the-jenkins-server)
-- [Configure the Jenkins project](#configure-the-jenkins-project)
+## Grant Jenkins access to the GitLab project
-## Grant Jenkins access to GitLab project
-
-Grant a GitLab user access to the select GitLab projects.
+Grant a GitLab user access to the relevant GitLab projects.
1. Create a new GitLab user, or choose an existing GitLab user.
This account is used by Jenkins to access the GitLab projects. We recommend creating a GitLab
user for only this purpose. If you use a person's account, and their account is deactivated or
- deleted, the GitLab-Jenkins integration stops working.
+ deleted, the Jenkins integration stops working.
1. Grant the user permission to the GitLab projects.
- If you're integrating Jenkins with many GitLab projects, consider granting the user the global
- Administrator role. Otherwise, add the user to each project, and grant the Developer role.
+ If you're integrating Jenkins with many GitLab projects, consider granting the
+ user the administrator access level. Otherwise, add the user to each project
+ and grant the Developer role.
-## Configure GitLab API access
+## Grant Jenkins access to the GitLab API
-Create a personal access token to authorize Jenkins' access to GitLab.
+Create a personal access token to authorize Jenkins to access GitLab.
1. Sign in to GitLab as the user to be used with Jenkins.
-1. In the top-right corner, select your avatar.
+1. On the top bar, in the top right corner, select your avatar.
1. Select **Edit profile**.
1. On the left sidebar, select **Access Tokens**.
-1. Create a personal access token with the **API** scope checkbox checked. For more details, see
- [Personal access tokens](../user/profile/personal_access_tokens.md).
-1. Record the personal access token's value, because it's required in [Configure the Jenkins server](#configure-the-jenkins-server) section.
+1. Create a [personal access token](../user/profile/personal_access_tokens.md) and
+ select the **API** scope.
+1. Copy the personal access token. You need it to [configure the Jenkins server](#configure-the-jenkins-server).
## Configure the Jenkins server
Install and configure the Jenkins plugin. The plugin must be installed and configured to
authorize the connection to GitLab.
-1. On the Jenkins server, go to **Manage Jenkins > Manage Plugins**.
+1. On the Jenkins server, select **Manage Jenkins > Manage Plugins**.
1. Install the [Jenkins GitLab Plugin](https://wiki.jenkins.io/display/JENKINS/GitLab+Plugin).
-1. Go to **Manage Jenkins > Configure System**.
-1. In the **GitLab** section, check the **Enable authentication for '/project' end-point** checkbox.
-1. Click **Add**, then choose **Jenkins Credential Provider**.
-1. Choose **GitLab API token** as the token type.
-1. Enter the GitLab personal access token's value in the **API Token** field and click **Add**.
-1. Enter the GitLab server's URL in the **GitLab host URL** field.
-1. Click **Test Connection**, ensuring the connection is successful before proceeding.
-
-For more information, see GitLab Plugin documentation about
-[Jenkins-to-GitLab authentication](https://github.com/jenkinsci/gitlab-plugin#jenkins-to-gitlab-authentication).
+1. Select **Manage Jenkins > Configure System**.
+1. In the **GitLab** section, select **Enable authentication for '/project' end-point**.
+1. Select **Add**, then choose **Jenkins Credential Provider**.
+1. Select **GitLab API token** as the token type.
+1. Enter the GitLab personal access token's value in **API Token** and select **Add**.
+1. Enter the GitLab server's URL in **GitLab host URL**.
+1. To test the connection, select **Test Connection**.
-![Jenkins GitLab plugin configuration](img/jenkins_gitlab_plugin_config.png)
+ ![Jenkins plugin configuration](img/jenkins_gitlab_plugin_config.png)
+
+For more information, see
+[Jenkins-to-GitLab authentication](https://github.com/jenkinsci/gitlab-plugin#jenkins-to-gitlab-authentication).
## Configure the Jenkins project
@@ -105,15 +85,15 @@ Set up the Jenkins project you intend to run your build on.
1. On your Jenkins instance, go to **New Item**.
1. Enter the project's name.
-1. Choose between **Freestyle** or **Pipeline** and click **OK**.
- We recommend a Freestyle project, because the Jenkins plugin updates the build status on
- GitLab. In a Pipeline project, you must configure a script to update the status on GitLab.
-1. Choose your GitLab connection from the dropdown.
-1. Check the **Build when a change is pushed to GitLab** checkbox.
-1. Check the following checkboxes:
+1. Select **Freestyle** or **Pipeline** and select **OK**.
+ We recommend a Freestyle project, because the Jenkins plugin updates the build status on
+ GitLab. In a Pipeline project, you must configure a script to update the status on GitLab.
+1. Choose your GitLab connection from the dropdown list.
+1. Select **Build when a change is pushed to GitLab**.
+1. Select the following checkboxes:
- **Accepted Merge Request Events**
- **Closed Merge Request Events**
-1. Specify how build status is reported to GitLab:
+1. Specify how the build status is reported to GitLab:
- If you created a **Freestyle** project, in the **Post-build Actions** section, choose
**Publish build status to GitLab**.
- If you created a **Pipeline** project, you must use a Jenkins Pipeline script to update the status on
@@ -143,39 +123,49 @@ Set up the Jenkins project you intend to run your build on.
Configure the GitLab integration with Jenkins in one of the following ways.
-### Recommended Jenkins integration
+### Configure a Jenkins integration (recommended)
GitLab recommends this approach for Jenkins integrations because it is easier to configure
-than the [webhook integration](#webhook-integration).
+than the [webhook integration](#configure-a-webhook).
-1. Create a new GitLab project or choose an existing one.
-1. Go to **Settings > Integrations**, then select **Jenkins CI**.
-1. Turn on the **Active** toggle.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Settings > Integrations**.
+1. Select **Jenkins**.
+1. Select the **Active** checkbox.
1. Select the events you want GitLab to trigger a Jenkins build for:
- Push
- Merge request
- Tag push
-1. Enter the **Jenkins URL**.
+1. Enter the **Jenkins server URL**.
1. Enter the **Project name**.
The project name should be URL-friendly, where spaces are replaced with underscores. To ensure
the project name is valid, copy it from your browser's address bar while viewing the Jenkins
project.
-1. Enter the **Username** and **Password** if your Jenkins server requires
- authentication.
-1. Click **Test settings and save changes**. GitLab tests the connection to Jenkins.
+1. If your Jenkins server requires
+ authentication, enter the **Username** and **Password**.
+1. To test the connection to Jenkins, select **Test settings**.
+1. Select **Save changes**.
-### Webhook integration
+### Configure a webhook
If you are unable to provide GitLab with your Jenkins server login, you can use this option
to integrate GitLab and Jenkins.
-1. In the configuration of your Jenkins job, in the GitLab configuration section, click **Advanced**.
-1. Click the **Generate** button under the **Secret Token** field.
-1. Copy the resulting token, and save the job configuration.
+1. In the configuration of your Jenkins job, in the GitLab configuration section, select **Advanced**.
+1. Under **Secret Token**, select **Generate**.
+1. Copy the token, and save the job configuration.
1. In GitLab, create a webhook for your project, enter the trigger URL
- (such as `https://JENKINS_URL/project/YOUR_JOB`) and paste the token in the **Secret Token** field.
-1. After you add the webhook, click the **Test** button, and it should succeed.
+ (such as `https://JENKINS_URL/project/YOUR_JOB`) and paste the token in **Secret Token**.
+1. To test the webhook, select **Test**.
+
+## Related topics
+
+- For a real use case, read the blog post
+ [Continuous integration: From Jenkins to GitLab using Docker](https://about.gitlab.com/blog/2017/07/27/docker-my-precious/).
+- See the ['GitLab vs. Jenkins' comparison page](https://about.gitlab.com/devops-tools/jenkins-vs-gitlab/)
+ for information on how moving to a single application for the entire software development
+ lifecycle can decrease hours spent on maintaining toolchains by 10% or more.
## Troubleshooting
@@ -188,24 +178,31 @@ If you get this error message while configuring GitLab, the following are possib
- The Jenkins instance is at a local address and is not included in the
[GitLab installation's allowlist](../security/webhooks.md#allowlist-for-local-requests).
- The credentials for the Jenkins instance do not have sufficient access or are invalid.
-- The **Enable authentication for ‘/project’ end-point checkbox** is not selected in your [Jenkin's plugin configuration](#configure-the-jenkins-server).
+- The **Enable authentication for ‘/project’ end-point** checkbox is not selected in your [Jenkin's plugin configuration](#configure-the-jenkins-server).
### Error in merge requests - "Could not connect to the CI server"
-This integration relies on Jenkins reporting the build status back to GitLab via
-the [Commit Status API](../api/commits.md#commit-status).
+You might get the `Could not connect to the CI server` error if GitLab did not
+receive a build status update from Jenkins via the [Commit Status API](../api/commits.md#commit-status).
+
+This issue occurs when Jenkins is not properly
+configured or there is an error reporting the status via the API.
-The error 'Could not connect to the CI server' usually means that GitLab did not
-receive a build status update via the API. Either Jenkins was not properly
-configured or there was an error reporting the status via the API.
+To fix this issue, ensure you:
-1. [Configure the Jenkins server](#configure-the-jenkins-server) for GitLab API access
+1. [Configure the Jenkins server](#configure-the-jenkins-server) for GitLab API access.
1. [Configure the Jenkins project](#configure-the-jenkins-project), including the
'Publish build status to GitLab' post-build action.
-### Merge Request event does not trigger a Jenkins Pipeline
+### Merge request event does not trigger a Jenkins pipeline
-Check [service hook logs](../user/project/integrations/overview.md#troubleshooting-integrations) for request failures or check the `/var/log/gitlab/gitlab-rails/production.log` file for messages like:
+This issue can occur when the request exceeds the
+[webhook timeout](../user/project/integrations/webhooks.md#webhook-fails-or-multiple-webhook-requests-are-triggered),
+which is set to 10 seconds by default.
+
+Check the [service hook logs](../user/project/integrations/overview.md#troubleshooting-integrations)
+for request failures or check the `/var/log/gitlab/gitlab-rails/production.log`
+file for messages like:
```plaintext
WebHook Error => Net::ReadTimeout
@@ -217,30 +214,38 @@ or
WebHook Error => execution expired
```
-If those are present, the request is exceeding the
-[webhook timeout](../user/project/integrations/webhooks.md#webhook-fails-or-multiple-webhook-requests-are-triggered),
-which is set to 10 seconds by default.
-
-To fix this the `gitlab_rails['webhook_timeout']` value must be increased
-in the `gitlab.rb` configuration file, followed by the [`gitlab-ctl reconfigure` command](../administration/restart_gitlab.md).
-
-If you don't find the errors above, but do find *duplicate* entries like below (in `/var/log/gitlab/gitlab-rail`),
-[webhook requests may be timing out](../user/project/integrations/webhooks.md#webhook-fails-or-multiple-webhook-requests-are-triggered):
+Or check for duplicate messages in `/var/log/gitlab/gitlab-rail`, like:
```plaintext
2019-10-25_04:22:41.25630 2019-10-25T04:22:41.256Z 1584 TID-ovowh4tek WebHookWorker JID-941fb7f40b69dff3d833c99b INFO: start
2019-10-25_04:22:41.25630 2019-10-25T04:22:41.256Z 1584 TID-ovowh4tek WebHookWorker JID-941fb7f40b69dff3d833c99b INFO: start
```
+To fix this issue:
+
+1. Increase the `gitlab_rails['webhook_timeout']` value in the `gitlab.rb`
+ configuration file.
+1. [Restart](../administration/restart_gitlab.md) GitLab:
+
+ ```shell
+ gitlab-ctl reconfigure
+ ```
+
### Enable job logs in Jenkins
-When troubleshooting an integration issue, it is useful to enable job logs in Jenkins to see more details about what is happening under the hood.
+To troubleshoot an integration issue, you can enable job logs in Jenkins to get
+more details about your builds.
+
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` in the text field.
+1. On the next screen, select **Add** and enter `org.jenkinsci.plugins.workflow.job`.
1. Make sure that the Log Level is **All** and select **Save**.
-Now, after you run a build, you can go to the loggers page (**Dashboard > Manage Jenkins > System Log**), select your logger, and check the logs.
+To view your logs:
+
+1. Run a build.
+1. Go to **Dashboard > Manage Jenkins > System Log**.
+1. Select your logger and check the logs.
diff --git a/doc/integration/kerberos.md b/doc/integration/kerberos.md
index 0f9bf3ba1d1..04a02b8fa68 100644
--- a/doc/integration/kerberos.md
+++ b/doc/integration/kerberos.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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"
---
@@ -9,9 +9,8 @@ info: "To determine the technical writer assigned to the Stage/Group associated
GitLab can integrate with [Kerberos](https://web.mit.edu/kerberos/) as an authentication mechanism.
WARNING:
-GitLab CI/CD does not work with a Kerberos-enabled GitLab instance due to an unresolved
-[bug in Git CLI](https://lore.kernel.org/git/YKNVop80H8xSTCjz@coredump.intra.peff.net/T/#mab47fd7dcb61fee651f7cc8710b8edc6f62983d5)
-that fails to use job token authentication from the GitLab Runners.
+GitLab CI/CD doesn't work with a Kerberos-enabled GitLab instance unless the integration is
+[set to use a dedicated port](#http-git-access-with-kerberos-token-passwordless-authentication).
## Overview
@@ -235,19 +234,23 @@ know the `libcurl` version installed, run `curl-config --version`.
### HTTP Git access with Kerberos token (passwordless authentication)
-#### Support for Git before 2.4
-
-Until Git version 2.4, the `git` command uses only the `negotiate` authentication
+Because of [a bug in current Git versions](https://lore.kernel.org/git/YKNVop80H8xSTCjz@coredump.intra.peff.net/T/#mab47fd7dcb61fee651f7cc8710b8edc6f62983d5),
+the `git` CLI command uses only the `negotiate` authentication
method if the HTTP server offers it, even if this method fails (such as when
the client does not have a Kerberos token). It is thus not possible to fall back
-to username/password (also known as `basic`) authentication if Kerberos
+to an embedded username and password (also known as `basic`) authentication if Kerberos
authentication fails.
For GitLab users to be able to use either `basic` or `negotiate` authentication
-with older Git versions, it is possible to offer Kerberos ticket-based
+with current Git versions, it is possible to offer Kerberos ticket-based
authentication on a different port (for example, `8443`) while the standard port
offers only `basic` authentication.
+NOTE:
+[Git 2.4 and later](https://github.com/git/git/blob/master/Documentation/RelNotes/2.4.0.txt#L225-L228) supports falling back to `basic` authentication if the
+username and password is passed interactively or through a credentials manager. It fails to fall back when the username and password is passed as part of the URL instead. For example,
+this can happen in GitLab CI/CD jobs that [authenticate with the CI/CD job token](../ci/jobs/ci_job_token.md).
+
**For source installations with HTTPS**
1. Edit the NGINX configuration file for GitLab
diff --git a/doc/integration/mattermost/index.md b/doc/integration/mattermost/index.md
index 97da971dd75..02fe0f4ea71 100644
--- a/doc/integration/mattermost/index.md
+++ b/doc/integration/mattermost/index.md
@@ -340,7 +340,8 @@ Below is a list of Mattermost versions for GitLab 11.10 and later:
| 14.3 | 5.38 |
| 14.4 | 5.39 |
| 14.5 | 5.39 |
-| 14.6 | 6.1 |
+| 14.6 | 6.1 |
+| 14.7 | 6.2 |
- GitLab 14.5 remained on Mattermost 5.39
- GitLab 14.6 updates to Mattermost 6.1 instead of 6.0
diff --git a/doc/integration/oauth_provider.md b/doc/integration/oauth_provider.md
index af715e47ab9..ff144d9985b 100644
--- a/doc/integration/oauth_provider.md
+++ b/doc/integration/oauth_provider.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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/integration/omniauth.md b/doc/integration/omniauth.md
index dd51d823109..4c05f94148c 100644
--- a/doc/integration/omniauth.md
+++ b/doc/integration/omniauth.md
@@ -46,10 +46,6 @@ GitLab supports the following OmniAuth providers.
## Configure initial settings
-NOTE:
-In GitLab 11.4 and later, OmniAuth is enabled by default. If you're using an
-earlier version, you must explicitly enable it.
-
Before you configure the OmniAuth provider,
configure the settings that are common for all providers.
@@ -153,7 +149,7 @@ To enable or disable an OmniAuth provider:
## Disable OmniAuth
-In GitLab 11.4 and later, OmniAuth is enabled by default. However, OmniAuth only works
+OmniAuth is enabled by default. However, OmniAuth only works
if providers are configured and [enabled](#enable-or-disable-sign-in-with-an-omniauth-provider-without-disabling-import-sources).
If OmniAuth providers are causing problems even when individually disabled, you
@@ -385,3 +381,9 @@ then override the icon in one of two ways:
...
}
```
+
+## Limitations
+
+Most supported OmniAuth providers don't support Git over HTTP password authentication.
+The only exception is [Atlassian Crowd](../administration/auth/crowd.md) (since GitLab [13.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46935)).
+As a workaround, you can authenticate using a [personal access token](../user/profile/personal_access_tokens.md).
diff --git a/doc/integration/openid_connect_provider.md b/doc/integration/openid_connect_provider.md
index 54d4a5b6bb7..e85231d1c25 100644
--- a/doc/integration/openid_connect_provider.md
+++ b/doc/integration/openid_connect_provider.md
@@ -47,20 +47,19 @@ The following user information is shared with clients:
| Claim | Type | Description |
|:-----------------|:----------|:------------|
-| `sub` | `string` | The ID of the user
-| `sub_legacy` | `string` | An opaque token that uniquely identifies the user<br><br>**Deprecation notice:** this token isn't stable because it's tied to the Rails secret key base, and is provided only for migration to the new stable `sub` value available from GitLab 11.1
-| `auth_time` | `integer` | The timestamp for the user's last authentication
-| `name` | `string` | The user's full name
-| `nickname` | `string` | The user's GitLab username
-| `email` | `string` | The user's email address<br>This is the user's *primary* email address if the application has access to the `email` claim and the user's *public* email address otherwise
-| `email_verified` | `boolean` | Whether the user's email address was verified
-| `website` | `string` | URL for the user's website
-| `profile` | `string` | URL for the user's GitLab profile
-| `picture` | `string` | URL for the user's GitLab avatar
-| `groups` | `array` | Paths for the groups the user is a member of, either directly or through an ancestor group.
-| `groups_direct` | `array` | Paths for the groups the user is a direct member of.
-| `https://gitlab.org/claims/groups/owner` | `array` | Names of the groups the user is a direct member of with Owner role
-| `https://gitlab.org/claims/groups/maintainer` | `array` | Names of the groups the user is a direct member of with Maintainer role
-| `https://gitlab.org/claims/groups/developer` | `array` | Names of the groups the user is a direct member of with Developer role
+| `sub` | `string` | The ID of the user |
+| `auth_time` | `integer` | The timestamp for the user's last authentication |
+| `name` | `string` | The user's full name |
+| `nickname` | `string` | The user's GitLab username |
+| `email` | `string` | The user's email address<br>This is the user's *primary* email address if the application has access to the `email` claim and the user's *public* email address otherwise |
+| `email_verified` | `boolean` | Whether the user's email address was verified |
+| `website` | `string` | URL for the user's website |
+| `profile` | `string` | URL for the user's GitLab profile |
+| `picture` | `string` | URL for the user's GitLab avatar |
+| `groups` | `array` | Paths for the groups the user is a member of, either directly or through an ancestor group. |
+| `groups_direct` | `array` | Paths for the groups the user is a direct member of. |
+| `https://gitlab.org/claims/groups/owner` | `array` | Names of the groups the user is a direct member of with Owner role |
+| `https://gitlab.org/claims/groups/maintainer` | `array` | Names of the groups the user is a direct member of with Maintainer role |
+| `https://gitlab.org/claims/groups/developer` | `array` | Names of the groups the user is a direct member of with Developer role |
The claims `sub`, `sub_legacy`, `email`, `email_verified` and `groups_direct` are included in the ID token. All other claims are available from the `/oauth/userinfo` endpoint used by OIDC clients.
diff --git a/doc/integration/saml.md b/doc/integration/saml.md
index 70d6932b9eb..61d09b4e173 100644
--- a/doc/integration/saml.md
+++ b/doc/integration/saml.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -917,8 +917,10 @@ You may also find the [SAML Tracer](https://addons.mozilla.org/en-US/firefox/add
### Invalid audience
This error means that the IdP doesn't recognize GitLab as a valid sender and
-receiver of SAML requests. Make sure to add the GitLab callback URL to the approved
-audiences of the IdP server.
+receiver of SAML requests. Make sure to:
+
+- Add the GitLab callback URL to the approved audiences of the IdP server.
+- Avoid trailing whitespace in the `issuer` string.
### Missing claims, or `Email can't be blank` errors
diff --git a/doc/integration/sourcegraph.md b/doc/integration/sourcegraph.md
index 6f0027aedc7..b2e5f7b4b7d 100644
--- a/doc/integration/sourcegraph.md
+++ b/doc/integration/sourcegraph.md
@@ -7,8 +7,13 @@ type: reference, how-to
# Sourcegraph integration **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16556) in GitLab 12.5.
-> - Note that this integration is in BETA and deployed [behind a feature flag](#enable-the-sourcegraph-feature-flag) disabled by default. Self-managed instances can opt to enable it.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16556) in GitLab 12.5 [with a flag](../administration/feature_flags.md) named `sourcegraph`. Disabled by default.
+> - Enabled on GitLab.com in GitLab 12.5.
+> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73116) 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 flag](../administration/feature_flags.md) named `sourcegraph`.
+On GitLab.com, this feature is available for public projects only.
[Sourcegraph](https://sourcegraph.com) provides code intelligence features, natively integrated into the GitLab UI.
@@ -26,41 +31,9 @@ you can choose to enable Sourcegraph [through your user preferences](#enable-sou
## Set up for self-managed GitLab instances **(FREE SELF)**
Before you can enable Sourcegraph code intelligence in GitLab you must:
+configure a Sourcegraph instance with your GitLab instance as an external service.
-- Enable the `sourcegraph` feature flag for your GitLab instance.
-- Configure a Sourcegraph instance with your GitLab instance as an external service.
-
-### Enable the Sourcegraph feature flag
-
-NOTE:
-If you are running a self-managed instance, the Sourcegraph integration is unavailable
-unless the feature flag `sourcegraph` is enabled. This can be done from the Rails console
-by instance administrators.
-
-Use these commands to start the Rails console:
-
-```shell
-# Omnibus GitLab
-gitlab-rails console
-
-# Installation from source
-cd /home/git/gitlab
-sudo -u git -H bin/rails console -e production
-```
-
-Then run the following command to enable the feature flag:
-
-```ruby
-Feature.enable(:sourcegraph)
-```
-
-You can also enable the feature flag only for specific projects with:
-
-```ruby
-Feature.enable(:sourcegraph, Project.find_by_full_path('my_group/my_project'))
-```
-
-### Set up a self-managed Sourcegraph instance
+### Set up a self-managed Sourcegraph instance **(FREE SELF)**
If you are new to Sourcegraph, head over to the [Sourcegraph installation documentation](https://docs.sourcegraph.com/admin) and get your instance up and running.
diff --git a/doc/operations/error_tracking.md b/doc/operations/error_tracking.md
index 68a0d492c5d..7533646aa34 100644
--- a/doc/operations/error_tracking.md
+++ b/doc/operations/error_tracking.md
@@ -6,8 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Error Tracking **(FREE)**
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/169) in GitLab 11.8.
-
Error Tracking allows developers to easily discover and view the errors that their application may be generating. By surfacing error information where the code is being developed, efficiency and awareness can be increased.
## How error tracking works
diff --git a/doc/operations/feature_flags.md b/doc/operations/feature_flags.md
index 49898d2e904..b0a180b5635 100644
--- a/doc/operations/feature_flags.md
+++ b/doc/operations/feature_flags.md
@@ -6,8 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Feature Flags **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/7433) in GitLab 11.4.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212318) from GitLab Premium to GitLab Free in 13.5.
+> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212318) from GitLab Premium to GitLab Free in 13.5.
With Feature Flags, you can deploy your application's new features to production in smaller batches.
You can toggle a feature on and off to subsets of users, helping you achieve Continuous Delivery.
diff --git a/doc/operations/incident_management/incidents.md b/doc/operations/incident_management/incidents.md
index 64dea795d3c..ada1f426dd8 100644
--- a/doc/operations/incident_management/incidents.md
+++ b/doc/operations/incident_management/incidents.md
@@ -47,8 +47,6 @@ To create an incident from the Issues List:
### Create incidents automatically **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4925) in GitLab 11.11.
-
With at least the Maintainer [role](../../user/permissions.md), you can enable
GitLab to create incident automatically whenever an alert is triggered:
diff --git a/doc/operations/index.md b/doc/operations/index.md
index ec54b6c57b9..5a83e47b556 100644
--- a/doc/operations/index.md
+++ b/doc/operations/index.md
@@ -9,11 +9,17 @@ info: To determine the technical writer assigned to the Stage/Group associated w
GitLab provides a variety of tools to help operate and maintain
your applications.
-## Measure reliability and stability with metrics
+## Measure reliability and stability with metrics (DEPRECATED)
+
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346485) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346485)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
Metrics help you understand the health and performance of your infrastructure,
applications, and systems by providing insights into your application's reliability,
-stability, and performance. GitLab provides a dashboard out-of-the-box, which you
+stability, and performance. GitLab provides a default dashboard that you
can extend with custom metrics, and augment with additional custom dashboards. You
can track the metrics that matter most to your team, generate automated alerts when
performance degrades, and manage those alerts - all within GitLab.
@@ -30,13 +36,13 @@ performance degrades, and manage those alerts - all within GitLab.
GitLab helps reduce alert fatigue for IT responders by providing tools to identify
issues across multiple systems and aggregate alerts in a centralized place. Your
team needs a single, central interface where they can easily investigate alerts
-using metrics and logs, and promote the critical alerts to incidents.
+and promote the critical alerts to incidents.
Are your alerts too noisy? Alerts configured on GitLab metrics can configured
and fine-tuned in GitLab immediately following a fire-fight.
- [Manage alerts and incidents](incident_management/index.md) in GitLab.
-- [Configure alerts for metrics](metrics/alerts.md) in GitLab.
+- [Configure alerts for metrics](metrics/alerts.md) in GitLab. (DEPRECATED)
- Create a [status page](incident_management/status_page.md)
to communicate efficiently to your users during an incident.
@@ -51,7 +57,13 @@ and the work required to fix them - all without leaving GitLab.
- Discover and view errors generated by your applications with
[Error Tracking](error_tracking.md).
-## Trace application health and performance
+## Trace application health and performance (DEPRECATED)
+
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346485) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346485)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
Application tracing in GitLab is a way to measure an application's performance and
health while it's running. After configuring your application to enable tracing, you
@@ -65,7 +77,13 @@ microservices-based distributed systems - and displays results within GitLab.
- [Trace the performance and health](tracing.md) of a deployed application.
-## Aggregate and store logs
+## Aggregate and store logs (DEPRECATED)
+
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346485) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346485)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
Developers need to troubleshoot application changes in development, and incident
responders need aggregated, real-time logs when troubleshooting problems with
diff --git a/doc/operations/metrics/alerts.md b/doc/operations/metrics/alerts.md
index 44999ad7cd6..712ee04e916 100644
--- a/doc/operations/metrics/alerts.md
+++ b/doc/operations/metrics/alerts.md
@@ -19,8 +19,7 @@ Alerts are not currently supported for [Prometheus cluster integrations](../../u
## External Prometheus instances
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9258) in GitLab Ultimate 11.8.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/42640) to GitLab Free in 12.10.
+> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/42640) to GitLab Free in 12.10.
For manually configured Prometheus servers, GitLab provides a notify endpoint for
use with Prometheus webhooks. If you have manual configuration enabled, an
@@ -61,8 +60,6 @@ Prometheus server to use the
## Trigger actions from alerts **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4925) in GitLab 11.11.
-
Alerts can be used to trigger actions, like opening an issue automatically
(disabled by default since `13.1`). To configure the actions:
diff --git a/doc/operations/metrics/dashboards/default.md b/doc/operations/metrics/dashboards/default.md
index 2be26e843c4..295c146f0d5 100644
--- a/doc/operations/metrics/dashboards/default.md
+++ b/doc/operations/metrics/dashboards/default.md
@@ -4,7 +4,13 @@ group: Monitor
info: 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-defined metrics dashboards **(FREE)**
+# GitLab-defined metrics dashboards (DEPRECATED) **(FREE)**
+
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
GitLab provides some dashboards out-of-the-box for any project with
[Prometheus available](../../../user/project/integrations/prometheus.md). You can
diff --git a/doc/operations/metrics/dashboards/develop.md b/doc/operations/metrics/dashboards/develop.md
index 28a4488014a..38f375c40a6 100644
--- a/doc/operations/metrics/dashboards/develop.md
+++ b/doc/operations/metrics/dashboards/develop.md
@@ -4,7 +4,13 @@ group: Monitor
info: 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
---
-# Developing templates for custom dashboards **(FREE)**
+# Developing templates for custom dashboards (DEPRECATED) **(FREE)**
+
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
GitLab provides a template to make it easier for you to create templates for
[custom dashboards](index.md). Templates provide helpful guidance and
diff --git a/doc/operations/metrics/dashboards/index.md b/doc/operations/metrics/dashboards/index.md
index d59f72f2a91..9a75703a2f1 100644
--- a/doc/operations/metrics/dashboards/index.md
+++ b/doc/operations/metrics/dashboards/index.md
@@ -4,9 +4,14 @@ group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Custom dashboards **(FREE)**
+# Custom dashboards (DEPRECATED) **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/59974) in GitLab 12.1.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/59974) in GitLab 12.1.
+> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
By default, all projects include a [GitLab-defined Prometheus dashboard](default.md), which
includes a few key metrics, but you can also define your own custom dashboards.
diff --git a/doc/operations/metrics/dashboards/panel_types.md b/doc/operations/metrics/dashboards/panel_types.md
index 140e18b5b13..9b015760fe9 100644
--- a/doc/operations/metrics/dashboards/panel_types.md
+++ b/doc/operations/metrics/dashboards/panel_types.md
@@ -4,7 +4,13 @@ group: Monitor
info: 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
---
-# Panel types for dashboards **(FREE)**
+# Panel types for dashboards (DEPRECATED) **(FREE)**
+
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
The below panel types are supported in monitoring dashboards.
diff --git a/doc/operations/metrics/dashboards/settings.md b/doc/operations/metrics/dashboards/settings.md
index f14d326a0d3..f4c37718c52 100644
--- a/doc/operations/metrics/dashboards/settings.md
+++ b/doc/operations/metrics/dashboards/settings.md
@@ -4,7 +4,13 @@ group: Monitor
info: 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
---
-# Dashboard settings **(FREE)**
+# Dashboard settings (DEPRECATED) **(FREE)**
+
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
You can configure your [Monitoring dashboard](../index.md) to
display the time zone of your choice, and the links of your choice.
diff --git a/doc/operations/metrics/dashboards/templating_variables.md b/doc/operations/metrics/dashboards/templating_variables.md
index 20071300dec..8ccd334dac3 100644
--- a/doc/operations/metrics/dashboards/templating_variables.md
+++ b/doc/operations/metrics/dashboards/templating_variables.md
@@ -4,9 +4,14 @@ group: Monitor
info: 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
---
-# Templating variables for metrics dashboards **(FREE)**
+# Templating variables for metrics dashboards (DEPRECATED) **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214539) in GitLab 13.0.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214539) in GitLab 13.0.
+> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
Templating variables can be used to make your metrics dashboard more versatile.
diff --git a/doc/operations/metrics/dashboards/variables.md b/doc/operations/metrics/dashboards/variables.md
index fa79524883d..0008706df40 100644
--- a/doc/operations/metrics/dashboards/variables.md
+++ b/doc/operations/metrics/dashboards/variables.md
@@ -4,7 +4,13 @@ group: Monitor
info: 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 variables **(FREE)**
+# Using variables (DEPRECATED) **(FREE)**
+
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
## Query variables
diff --git a/doc/operations/metrics/dashboards/yaml.md b/doc/operations/metrics/dashboards/yaml.md
index 8068a66d5c4..9d1c270388e 100644
--- a/doc/operations/metrics/dashboards/yaml.md
+++ b/doc/operations/metrics/dashboards/yaml.md
@@ -4,7 +4,13 @@ group: Monitor
info: 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
---
-# Dashboard YAML properties **(FREE)**
+# Dashboard YAML properties (DEPRECATED) **(FREE)**
+
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
Dashboards have several components:
diff --git a/doc/operations/tracing.md b/doc/operations/tracing.md
index 1593607cc98..09a31c12bf4 100644
--- a/doc/operations/tracing.md
+++ b/doc/operations/tracing.md
@@ -4,10 +4,14 @@ group: Monitor
info: 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
---
-# Tracing **(FREE)**
+# Tracing (DEPRECATED) **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/7903) in GitLab 11.5.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/42645) from GitLab Ultimate to GitLab Free in 13.5.
+> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346540) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346540)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
Tracing provides insight into the performance and health of a deployed application, tracking each
function or microservice that handles a given request. Tracing makes it easy to understand the
diff --git a/doc/policy/alpha-beta-support.md b/doc/policy/alpha-beta-support.md
index be634bbf7be..ba988b38af2 100644
--- a/doc/policy/alpha-beta-support.md
+++ b/doc/policy/alpha-beta-support.md
@@ -4,6 +4,8 @@ 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
---
+<!-- any changes made to this page should be reflected in https://about.gitlab.com/support/statement-of-support.html#alpha--beta-features and https://about.gitlab.com/handbook/product/gitlab-the-product/#alpha-beta-ga -->
+
# Support for Alpha, Beta, and Generally Available Features **(PREMIUM)**
Some GitLab features are released as [Alpha or Beta versions](https://about.gitlab.com/support/statement-of-support.html#alpha--beta-features) which are not fully supported. All other features are considered to be Generally Available (GA).
@@ -30,7 +32,7 @@ Characteristics of beta features:
- Features and functions are not likely to change.
- Data loss is not likely.
-Your Support Contract provides **best-efforts** support for Beta features, with the expectation that issues will require extra time and assistance from development to troubleshoot.
+Your Support Contract provides **commercially-reasonable effort** support for Beta features, with the expectation that issues will require extra time and assistance from development to troubleshoot.
## Generally Available (GA)
diff --git a/doc/push_rules/push_rules.md b/doc/push_rules/push_rules.md
index 425275a0370..c37853ffe81 100644
--- a/doc/push_rules/push_rules.md
+++ b/doc/push_rules/push_rules.md
@@ -14,10 +14,6 @@ GitLab already offers [protected branches](../user/project/protected_branches.md
cases when you need some specific rules. Some common scenarios: preventing Git tag removal, or
enforcing a special format for commit messages.
-INFO:
-Get access to push rules and more with a
-[free 30-day trial of GitLab Ultimate](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=p-push-rules-docs).
-
Push rules are [pre-receive Git hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) you
can enable in a user-friendly interface. They are defined either:
@@ -147,76 +143,80 @@ Feature.disable(:reject_unsigned_commits_by_gitlab)
> Moved to GitLab Premium in 13.9.
-Secrets such as credential files, SSH private keys, and other files containing secrets should never be committed to source control.
-GitLab enables you to turn on a predefined denylist of files which can't be
-pushed to a repository. The list stops those commits from reaching the remote repository.
-
-By selecting the checkbox *Prevent committing secrets to Git*, GitLab prevents
-pushes to the repository when a file matches a regular expression as read from
-[`files_denylist.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/gitlab/checks/files_denylist.yml) (make sure you are at the right branch
-as your GitLab version when viewing this file).
-
-NOTE:
-Files already committed aren't restricted by this push rule.
-
-Below is an example list of what GitLab rejects with these regular expressions:
-
-```shell
-#####################
-# AWS CLI credential blobs
-#####################
-.aws/credentials
-aws/credentials
-homefolder/aws/credentials
-
-#####################
-# Private RSA SSH keys
-#####################
-/ssh/id_rsa
-/.ssh/personal_rsa
-/config/server_rsa
-id_rsa
-.id_rsa
-
-#####################
-# Private DSA SSH keys
-#####################
-/ssh/id_dsa
-/.ssh/personal_dsa
-/config/server_dsa
-id_dsa
-.id_dsa
-
-#####################
-# Private ed25519 SSH keys
-#####################
-/ssh/id_ed25519
-/.ssh/personal_ed25519
-/config/server_ed25519
-id_ed25519
-.id_ed25519
-
-#####################
-# Private ECDSA SSH keys
-#####################
-/ssh/id_ecdsa
-/.ssh/personal_ecdsa
-/config/server_ecdsa
-id_ecdsa
-.id_ecdsa
-
-#####################
-# Any file with .pem or .key extensions
-#####################
-*.pem
-*.key
-
-#####################
-# Any file ending with _history or .history extension
-#####################
-*.history
-*_history
-```
+Secrets, such as credential files and SSH private keys, should never be committed to a version control
+system. In GitLab, you can use a predefined list of files to block those files from a
+repository. Any merge request containing a file matching the list is blocked from being merged.
+Files already committed to the repository are not restricted by this push rule.
+
+Files blocked by this rule are listed below. For a complete list of criteria, see
+[`files_denylist.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/gitlab/checks/files_denylist.yml).
+
+- AWS CLI credential blobs:
+
+ - `.aws/credentials`
+ - `aws/credentials`
+ - `homefolder/aws/credentials`
+
+- Private RSA SSH keys:
+
+ - `/ssh/id_rsa`
+ - `/.ssh/personal_rsa`
+ - `/config/server_rsa`
+ - `id_rsa`
+ - `.id_rsa`
+
+- Private DSA SSH keys:
+
+ - `/ssh/id_dsa`
+ - `/.ssh/personal_dsa`
+ - `/config/server_dsa`
+ - `id_dsa`
+ - `.id_dsa`
+
+- Private ed25519 SSH keys:
+
+ - `/ssh/id_ed25519`
+ - `/.ssh/personal_ed25519`
+ - `/config/server_ed25519`
+ - `id_ed25519`
+ - `.id_ed25519`
+
+- Private ECDSA SSH keys:
+
+ - `/ssh/id_ecdsa`
+ - `/.ssh/personal_ecdsa`
+ - `/config/server_ecdsa`
+ - `id_ecdsa`
+ - `.id_ecdsa`
+
+- Any files ending with these suffixes:
+
+ - `*.pem`
+ - `*.key`
+ - `*.history`
+ - `*_history`
+
+### Prevent pushing secrets to all projects
+
+To set a global push rule to prevent pushing secrets to all projects:
+
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Push Rules**.
+1. Expand **Push rules**.
+1. Select **Prevent pushing secret files**.
+1. Select **Save push rules**.
+
+### Prevent pushing secrets to a project
+
+The push rule of a project overrides the global push rule.
+
+To prevent pushing secrets 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 **Push rules**.
+1. Select **Prevent pushing secret files**.
+1. Select **Save push rules**.
## Prohibited file names
diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md
index 676cc529c98..539908cd7bc 100644
--- a/doc/raketasks/backup_restore.md
+++ b/doc/raketasks/backup_restore.md
@@ -12,11 +12,11 @@ An application data backup creates an archive file that contains the database,
all repositories and all attachments.
You can only restore a backup to **exactly the same version and type (CE/EE)**
-of GitLab on which it was created. The best way to migrate your repositories
-from one server to another is through a backup and restore.
+of GitLab on which it was created. The best way to [migrate your projects
+from one server to another](#migrate-to-a-new-server) is through a backup and restore.
WARNING:
-GitLab doesn't back up items that aren't stored in the file system. If you're
+GitLab doesn't back up items that aren't stored on the file system. If you're
using [object storage](../administration/object_storage.md), be sure to enable
backups with your object storage provider, if desired.
@@ -58,16 +58,17 @@ including:
- CI/CD job output logs
- CI/CD job artifacts
- LFS objects
+- Terraform states ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/331806) in GitLab 14.7)
- Container Registry images
- GitLab Pages content
+- Packages ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332006) in GitLab 14.7)
- Snippets
- [Group wikis](../user/project/wiki/group.md)
Backups do not include:
-- [Terraform state files](../administration/terraform_state.md)
-- [Package registry files](../administration/packages/index.md)
- [Mattermost data](https://docs.mattermost.com/administration/config-settings.html#file-storage)
+- Redis (and thus Sidekiq jobs)
WARNING:
GitLab does not back up any configuration files (`/etc/gitlab`), TLS keys and certificates, or system
@@ -115,12 +116,8 @@ the host, based on your installed version of GitLab:
If you're using the [GitLab Helm chart](https://gitlab.com/gitlab-org/charts/gitlab)
on a Kubernetes cluster, you can run the backup task by using `kubectl` to run the `backup-utility`
-script on the GitLab task runner pod. For more details, see
-[backing up a GitLab installation](https://gitlab.com/gitlab-org/charts/gitlab/blob/master/doc/backup-restore/backup.md#backing-up-a-gitlab-installation).
-
-```shell
-kubectl exec -it <gitlab task-runner pod> -- backup-utility
-```
+script on the GitLab toolbox pod. For more details, see the
+[charts backup documentation](https://docs.gitlab.com/charts/backup-restore/backup.html).
Similar to the Kubernetes case, if you have scaled out your GitLab cluster to
use multiple application servers, you should pick a designated node (that isn't
@@ -276,9 +273,11 @@ You can exclude specific directories from the backup by adding the environment v
- `builds` (CI job output logs)
- `artifacts` (CI job artifacts)
- `lfs` (LFS objects)
+- `terraform_state` (Terraform states)
- `registry` (Container Registry images)
- `pages` (Pages content)
- `repositories` (Git repositories data)
+- `packages` (Packages)
All wikis are backed up as part of the `repositories` group. Non-existent wikis are skipped during a backup.
@@ -985,7 +984,7 @@ your installation is using PgBouncer, for either performance reasons or when usi
Next, restore `/etc/gitlab/gitlab-secrets.json` if necessary,
[as previously mentioned](#restore-prerequisites).
-Reconfigure, restart and check GitLab:
+Reconfigure, restart and [check](../administration/raketasks/maintenance.md#check-gitlab-configuration) GitLab:
```shell
sudo gitlab-ctl reconfigure
@@ -993,7 +992,7 @@ sudo gitlab-ctl restart
sudo gitlab-rake gitlab:check SANITIZE=true
```
-In GitLab 13.1 and later, check [database values can be decrypted](../administration/raketasks/doctor.md)
+In GitLab 13.1 and later, check [database values can be decrypted](../administration/raketasks/check.md#verify-database-values-can-be-decrypted-using-the-current-secrets)
especially if `/etc/gitlab/gitlab-secrets.json` was restored, or if a different server is
the target for the restore.
@@ -1001,6 +1000,14 @@ the target for the restore.
sudo gitlab-rake gitlab:doctor:secrets
```
+For added assurance, you can perform [an integrity check on the uploaded files](../administration/raketasks/check.md#uploaded-files-integrity):
+
+```shell
+sudo gitlab-rake gitlab:artifacts:check
+sudo gitlab-rake gitlab:lfs:check
+sudo gitlab-rake gitlab:uploads:check
+```
+
### Restore for Docker image and GitLab Helm chart installations
For GitLab installations using the Docker image or the GitLab Helm chart on a
@@ -1182,7 +1189,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) to place GitLab in a read-only state.
+- Use [maintenance mode](../administration/maintenance_mode/index.md) **(PREMIUM SELF)** to place GitLab in a read-only state.
- Create explicit downtime by stopping all Gitaly services before backing up the repositories:
```shell
@@ -1284,6 +1291,198 @@ sudo GITLAB_BACKUP_PGHOST=192.168.1.10 GITLAB_BACKUP_PGPORT=5432 /opt/gitlab/bin
See the [PostgreSQL documentation](https://www.postgresql.org/docs/12/libpq-envars.html)
for more details on what these parameters do.
+## Migrate to a new server
+
+<!-- some details borrowed from GitLab.com move from Azure to GCP detailed at https://gitlab.com/gitlab-com/migration/-/blob/master/.gitlab/issue_templates/failover.md -->
+
+You can use GitLab backup and restore to migrate your instance to a new server. This section outlines a typical procedure for a GitLab deployment running on a single server.
+If you're running GitLab Geo, an alternative option is [Geo disaster recovery for planned failover](../administration/geo/disaster_recovery/planned_failover.md).
+
+WARNING:
+Avoid uncoordinated data processing by both the new and old servers, where multiple
+servers could connect concurrently and process the same data. For example, when using
+[incoming email](../administration/incoming_email.md), if both GitLab instances are
+processing email at the same time, then both instances will end up missing some data.
+This type of problem can occur with other services as well, such as a
+[non-packaged database](https://docs.gitlab.com/omnibus/settings/database.html#using-a-non-packaged-postgresql-database-management-server),
+a non-packaged Redis instance, or non-packaged Sidekiq.
+
+Prerequisites:
+
+- Some time before your migration, consider notifying your users of upcoming
+ scheduled maintenance with a [broadcast message banner](../user/admin_area/broadcast_messages.md).
+- Ensure your backups are complete and current. Create a complete system-level backup, or
+ take a snapshot of all servers involved in the migration, in case destructive commands
+ (like `rm`) are run incorrectly.
+
+### Prepare the new server
+
+To prepare the new server:
+
+1. Copy the
+ [SSH host keys](https://superuser.com/questions/532040/copy-ssh-keys-from-one-server-to-another-server/532079#532079)
+ from the old server to avoid man-in-the-middle attack warnings.
+1. [Install and configure GitLab](https://about.gitlab.com/install) except
+ [incoming email](../administration/incoming_email.md):
+ 1. Install GitLab.
+ 1. Configure by copying `/etc/gitlab` files from the old server to the new server, and update as necessary.
+ Read the
+ [Omnibus configuration backup and restore instructions](https://docs.gitlab.com/omnibus/settings/backups.html) for more detail.
+ 1. If applicable, disable [incoming email](../administration/incoming_email.md).
+ 1. Block new CI/CD jobs from starting upon initial startup after the backup and restore.
+ Edit `/etc/gitlab/gitlab.rb` and set the following:
+
+ ```ruby
+ nginx['custom_gitlab_server_config'] = "location /api/v4/jobs/request {\n deny all;\n return 503;\n}\n"
+ ```
+
+ 1. Reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+1. Stop GitLab to avoid any potential unnecessary and unintentional data processing:
+
+ ```shell
+ sudo gitlab-ctl stop
+ ```
+
+1. Configure the new server to allow receiving the Redis database and GitLab backup files:
+
+ ```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
+ ```
+
+### 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)**,
+ if supported by your GitLab edition.
+1. Block new CI/CD jobs from starting:
+ 1. Edit `/etc/gitlab/gitlab.rb`, and set the following:
+
+ ```ruby
+ nginx['custom_gitlab_server_config'] = "location /api/v4/jobs/request {\n deny all;\n return 503;\n}\n"
+ ```
+
+ 1. Reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+1. Disable periodic background jobs:
+ 1. On the top bar, select **Menu > Admin**.
+ 1. On the left sidebar, select **Monitoring > Background Jobs**.
+ 1. Under the Sidekiq dashboard, select **Cron** tab and then
+ **Disable All**.
+1. Wait for the currently running CI/CD jobs to finish, or accept that jobs that have not completed may be lost.
+ To view jobs currently running, on the left sidebar, select **Overviews > Jobs**,
+ and then select **Running**.
+1. Wait for Sidekiq jobs to finish:
+ 1. On the left sidebar, select **Monitoring > Background Jobs**.
+ 1. Under the Sidekiq dashboard, select **Queues** and then **Live Poll**.
+ Wait for **Busy** and **Enqueued** to drop to 0.
+ These queues contain work that has been submitted by your users;
+ shutting down before these jobs complete may cause the work to be lost.
+ Make note of the numbers shown in the Sidekiq dashboard for post-migration verification.
+1. Flush the Redis database to disk, and stop GitLab other than the services needed for migration:
+
+ ```shell
+ sudo /opt/gitlab/embedded/bin/redis-cli -s /var/opt/gitlab/redis/redis.socket save && sudo gitlab-ctl stop && sudo gitlab-ctl start postgresql
+ ```
+
+1. Create a GitLab backup:
+
+ ```shell
+ sudo gitlab-backup create
+ ```
+
+1. Disable the following GitLab services and prevent unintentional restarts by adding the following to the bottom of `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ alertmanager['enable'] = false
+ gitlab_exporter['enable'] = false
+ gitlab_pages['enable'] = false
+ gitlab_workhorse['enable'] = false
+ grafana['enable'] = false
+ logrotate['enable'] = false
+ gitlab_rails['incoming_email_enabled'] = false
+ nginx['enable'] = false
+ node_exporter['enable'] = false
+ postgres_exporter['enable'] = false
+ postgresql['enable'] = false
+ prometheus['enable'] = false
+ puma['enable'] = false
+ redis['enable'] = false
+ redis_exporter['enable'] = false
+ registry['enable'] = false
+ sidekiq['enable'] = false
+ ```
+
+1. Reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+1. Verify everything is stopped, and confirm no services are running:
+
+ ```shell
+ sudo gitlab-ctl status
+ ```
+
+1. Transfer the Redis database and GitLab backups to the new server:
+
+ ```shell
+ sudo scp /var/opt/gitlab/redis/dump.rdb <your-linux-username>@new-server:/var/opt/gitlab/redis
+ sudo scp /var/opt/gitlab/backups/your-backup.tar <your-linux-username>@new-server:/var/opt/gitlab/backups
+ ```
+
+### Restore data on the new server
+
+1. Restore appropriate file system permissions:
+
+ ```shell
+ sudo chown gitlab-redis /var/opt/gitlab/redis
+ sudo chown gitlab-redis:gitlab-redis /var/opt/gitlab/redis/dump.rdb
+ sudo chown git:root /var/opt/gitlab/backups
+ sudo chown git:git /var/opt/gitlab/backups/your-backup.tar
+ ```
+
+1. [Restore the GitLab backup](#restore-gitlab).
+1. Verify that the Redis database restored correctly:
+ 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.
+ 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. 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.
+1. Unblock new CI/CD jobs from starting by removing the custom NGINX config
+ you added previously:
+
+ ```ruby
+ # The following line must be removed
+ nginx['custom_gitlab_server_config'] = "location /api/v4/jobs/request {\n deny all;\n return 503;\n}\n"
+ ```
+
+1. Reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+1. Remove the scheduled maintenance [broadcast message banner](../user/admin_area/broadcast_messages.md).
+
## Additional notes
This documentation is for GitLab Community and Enterprise Edition. We back up
@@ -1308,9 +1507,11 @@ If you're using backup restore procedures, you may encounter the following
warning messages:
```plaintext
-psql:/var/opt/gitlab/backups/db/database.sql:22: ERROR: must be owner of extension plpgsql
-psql:/var/opt/gitlab/backups/db/database.sql:2931: WARNING: no privileges could be revoked for "public" (two occurrences)
-psql:/var/opt/gitlab/backups/db/database.sql:2933: WARNING: no privileges were granted for "public" (two occurrences)
+ERROR: must be owner of extension pg_trgm
+ERROR: must be owner of extension btree_gist
+ERROR: must be owner of extension plpgsql
+WARNING: no privileges could be revoked for "public" (two occurrences)
+WARNING: no privileges were granted for "public" (two occurrences)
```
Be advised that the backup is successfully restored in spite of these warning
@@ -1362,8 +1563,8 @@ Use the information in the following sections at your own risk.
#### Verify that all values can be decrypted
-You can determine if your database contains values that can't be decrypted by using the
-[Secrets Doctor Rake task](../administration/raketasks/doctor.md).
+You can determine if your database contains values that can't be decrypted by using a
+[Rake task](../administration/raketasks/check.md#verify-database-values-can-be-decrypted-using-the-current-secrets).
#### Take a backup
@@ -1619,10 +1820,12 @@ There can be
[risks when disabling released features](../administration/feature_flags.md#risks-when-disabling-released-features).
Refer to this feature's version history for more details.
-`gitaly-backup` is used by the backup Rake task to create and restore repository backups from Gitaly.
+The `gitaly-backup` binary is used by the backup Rake task to create and restore repository backups from Gitaly.
`gitaly-backup` replaces the previous backup method that directly calls RPCs on Gitaly from GitLab.
-The backup Rake task must be able to find this executable. It can be configured in Omnibus GitLab packages:
+The backup Rake task must be able to find this executable. In most cases, you don't need to change
+the path to the binary as it should work fine with the default path `/opt/gitlab/embedded/bin/gitaly-backup`.
+If you have a specific reason to change the path, it can be configured in Omnibus GitLab packages:
1. Add the following to `/etc/gitlab/gitlab.rb`:
diff --git a/doc/raketasks/index.md b/doc/raketasks/index.md
index 6227731e807..96c31047d8d 100644
--- a/doc/raketasks/index.md
+++ b/doc/raketasks/index.md
@@ -26,7 +26,6 @@ The following Rake tasks are available for use with GitLab:
| [Back up and restore](backup_restore.md) | Back up, restore, and migrate GitLab instances between servers. |
| [Clean up](cleanup.md) | Clean up unneeded items from GitLab instances. |
| [Development](../development/rake_tasks.md) | Tasks for GitLab contributors. |
-| [Doctor tasks](../administration/raketasks/doctor.md) | Checks for data integrity issues. |
| [Elasticsearch](../integration/elasticsearch.md#gitlab-advanced-search-rake-tasks) | Maintain Elasticsearch in a GitLab instance. |
| [Enable namespaces](features.md) | Enable usernames and namespaces for user projects. |
| [General maintenance](../administration/raketasks/maintenance.md) | General maintenance and self-check tasks. |
@@ -34,7 +33,7 @@ The following Rake tasks are available for use with GitLab:
| [GitHub import](../administration/raketasks/github_import.md) | Retrieve and import repositories from GitHub. |
| [Import repositories](import.md) | Import bare repositories into your GitLab instance. |
| [Import large project exports](../development/import_project.md#importing-via-a-rake-task) | Import large GitLab [project exports](../user/project/settings/import_export.md). |
-| [Integrity checks](../administration/raketasks/check.md) | Check the integrity of repositories, files, and LDAP. |
+| [Integrity checks](../administration/raketasks/check.md) | Check the integrity of repositories, files, LDAP, and more. |
| [LDAP maintenance](../administration/raketasks/ldap.md) | [LDAP](../administration/auth/ldap/index.md)-related tasks. |
| [List repositories](list_repos.md) | List all GitLab-managed Git repositories on disk. |
| [Migrate snippets to Git](migrate_snippets.md) | Migrate GitLab Snippets to Git repositories, and show the migration status. |
diff --git a/doc/security/asset_proxy.md b/doc/security/asset_proxy.md
index 6c3bce939df..45c1c71158a 100644
--- a/doc/security/asset_proxy.md
+++ b/doc/security/asset_proxy.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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/security/crime_vulnerability.md b/doc/security/crime_vulnerability.md
index 801a294dd81..1abb0c9e918 100644
--- a/doc/security/crime_vulnerability.md
+++ b/doc/security/crime_vulnerability.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
diff --git a/doc/security/img/unlock_user_v14_7.png b/doc/security/img/unlock_user_v14_7.png
new file mode 100644
index 00000000000..51015d932cb
--- /dev/null
+++ b/doc/security/img/unlock_user_v14_7.png
Binary files differ
diff --git a/doc/security/index.md b/doc/security/index.md
index 832af93b95e..ab554e9135f 100644
--- a/doc/security/index.md
+++ b/doc/security/index.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
comments: false
type: index
diff --git a/doc/security/information_exclusivity.md b/doc/security/information_exclusivity.md
index 162346c8874..07b5a688671 100644
--- a/doc/security/information_exclusivity.md
+++ b/doc/security/information_exclusivity.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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: concepts
---
diff --git a/doc/security/password_length_limits.md b/doc/security/password_length_limits.md
index bedf2ac3ab1..1cfff358c9d 100644
--- a/doc/security/password_length_limits.md
+++ b/doc/security/password_length_limits.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
diff --git a/doc/security/password_storage.md b/doc/security/password_storage.md
index 7d8ac3bad39..6b71933b1ae 100644
--- a/doc/security/password_storage.md
+++ b/doc/security/password_storage.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
diff --git a/doc/security/passwords_for_integrated_authentication_methods.md b/doc/security/passwords_for_integrated_authentication_methods.md
index 9931fd56e83..7281b310a30 100644
--- a/doc/security/passwords_for_integrated_authentication_methods.md
+++ b/doc/security/passwords_for_integrated_authentication_methods.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
diff --git a/doc/security/project_import_decompressed_archive_size_limits.md b/doc/security/project_import_decompressed_archive_size_limits.md
index 3c5099b1f75..9727ba1c5f0 100644
--- a/doc/security/project_import_decompressed_archive_size_limits.md
+++ b/doc/security/project_import_decompressed_archive_size_limits.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
diff --git a/doc/security/rack_attack.md b/doc/security/rack_attack.md
deleted file mode 100644
index a8b55007d2e..00000000000
--- a/doc/security/rack_attack.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: '../user/admin_area/settings/protected_paths.md'
-remove_date: '2022-01-14'
----
-
-This document was moved to [another location](../user/admin_area/settings/protected_paths.md).
-
-<!-- This redirect file can be deleted after <2022-01-14>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/security/rate_limits.md b/doc/security/rate_limits.md
index 9d49297c9de..14fc526ca7e 100644
--- a/doc/security/rate_limits.md
+++ b/doc/security/rate_limits.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -87,6 +87,33 @@ There is a rate limit for [testing webhooks](../user/project/integrations/webhoo
The **rate limit** is 5 requests per minute per user.
+### Users sign up
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77835) 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.
+
+The **rate limit** is 20 calls per minute per IP address.
+
+### Update username
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77221) in GitLab 14.7.
+
+There is a rate limit on the update username action. This is enforced to mitigate misuse of the feature. For example, to mass discover
+which usernames are in use.
+
+The **rate limit** is 10 calls per minute per signed-in user.
+
+### Username exists
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77119) in GitLab 14.7.
+
+There is a rate limit for the internal endpoint `/users/:username/exists`, used by registration to perform a client-side validation for
+uniqueness of the chosen username. 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.
+
## Troubleshooting
### Rack Attack is denylisting the load balancer
diff --git a/doc/security/reset_user_password.md b/doc/security/reset_user_password.md
index a61660f6a2f..f67b1934dc5 100644
--- a/doc/security/reset_user_password.md
+++ b/doc/security/reset_user_password.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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: howto
---
@@ -68,12 +68,12 @@ If you know the username, user ID, or email address, you can use the Rails conso
user = User.find(123)
```
- - By email address:
+ - By email address:
```ruby
user = User.find_by(email: 'user@example.com')
```
-
+
1. Reset the password:
```ruby
@@ -105,7 +105,7 @@ To reset the root password, follow the steps listed previously.
- If the root account name hasn't changed, use the username `root`.
- If the root account name has changed and you don't know the new username,
- you might be able to use a Rails console with user ID `1`. In almost all
+ you might be able to use a Rails console with user ID `1`. In almost all
cases, the first user is the default administrator account.
## Troubleshooting
diff --git a/doc/security/ssh_keys_restrictions.md b/doc/security/ssh_keys_restrictions.md
index 1f1c7457441..a7d852e2754 100644
--- a/doc/security/ssh_keys_restrictions.md
+++ b/doc/security/ssh_keys_restrictions.md
@@ -1,7 +1,7 @@
---
type: reference, howto
stage: Manage
-group: Access
+group: Authentication & 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/security/token_overview.md b/doc/security/token_overview.md
index 333548fa1c9..578bb03563f 100644
--- a/doc/security/token_overview.md
+++ b/doc/security/token_overview.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -93,17 +93,19 @@ This table shows available scopes per token. Scopes can be limited further on to
| | API access | Registry access | Repository access |
|-----------------------------|------------|-----------------|-------------------|
-| Personal access token | ✅ | ✅ | ✅ |
-| OAuth2 token | ✅ | 🚫 | ✅ |
-| Impersonation token | ✅ | ✅ | ✅ |
-| Project access token | ✅(1) | ✅(1) | ✅(1) |
-| Deploy token | 🚫 | ✅ | ✅ |
-| Deploy key | 🚫 | 🚫 | ✅ |
-| Runner registration token | 🚫 | 🚫 | ✴ï¸(2) |
-| Runner authentication token | 🚫 | 🚫 | ✴ï¸(2) |
-| Job token | ✴ï¸(3) | 🚫 | ✅ |
+| Personal access token | ✅ | ✅ | ✅ |
+| OAuth2 token | ✅ | 🚫 | ✅ |
+| Impersonation token | ✅ | ✅ | ✅ |
+| Project access token | ✅(1) | ✅(1) | ✅(1) |
+| Group access token | ✅(2) | ✅(2) | ✅(2) |
+| Deploy token | 🚫 | ✅ | ✅ |
+| Deploy key | 🚫 | 🚫 | ✅ |
+| Runner registration token | 🚫 | 🚫 | ✴ï¸(3) |
+| Runner authentication token | 🚫 | 🚫 | ✴ï¸(3) |
+| Job token | ✴ï¸(4) | 🚫 | ✅ |
1. Limited to the one project.
+1. Limited to the one group.
1. Runner registration and authentication token don't provide direct access to repositories, but can be used to register and authenticate a new runner that may execute jobs which do have access to the repository
1. Limited to certain [endpoints](../ci/jobs/ci_job_token.md).
@@ -113,7 +115,7 @@ Access tokens should be treated like passwords and kept secure.
Adding them to URLs is a security risk. This is especially true when cloning or adding a remote, as Git then writes the URL to its `.git/config` file in plain text. URLs are also generally logged by proxies and application servers, which makes those credentials visible to system administrators.
-Instead, API calls can be passed an access token using headers, like [the `Private-Token` header](../api/index.md#personalproject-access-tokens).
+Instead, API calls can be passed an access token using headers, like [the `Private-Token` header](../api/index.md#personalprojectgroup-access-tokens).
Tokens can also be stored using a [Git credential storage](https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage).
diff --git a/doc/security/two_factor_authentication.md b/doc/security/two_factor_authentication.md
index 61b26204599..b83d81722fa 100644
--- a/doc/security/two_factor_authentication.md
+++ b/doc/security/two_factor_authentication.md
@@ -1,7 +1,7 @@
---
type: howto
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -49,7 +49,7 @@ Gitlab::CurrentSettings.update!('require_two_factor_authentication': false)
To enforce 2FA only for certain groups:
1. Go to the group's **Settings > General** page.
-1. Expand the **Permissions, LFS, 2FA** section.
+1. Expand the **Permissions and group features** section.
1. Select the **Require all users in this group to set up two-factor authentication** option.
You can also specify a grace period in the **Time before enforced** option.
@@ -76,7 +76,7 @@ The following are important notes about 2FA:
groups) the shortest grace period is used.
- It is possible to disallow subgroups from setting up their own 2FA requirements:
1. Go to the top-level group's **Settings > General**.
- 1. Expand the **Permissions, LFS, 2FA** section.
+ 1. Expand the **Permissions and group features** section.
1. Uncheck the **Allow subgroups to set up their own two-factor authentication rule** field.
This action causes all subgroups with 2FA requirements to stop requiring that from their members.
diff --git a/doc/security/unlock_user.md b/doc/security/unlock_user.md
index ceb375a9ad1..057d4e87efa 100644
--- a/doc/security/unlock_user.md
+++ b/doc/security/unlock_user.md
@@ -1,13 +1,27 @@
---
stage: Manage
-group: Access
+group: Authentication & 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: howto
---
-# How to unlock a locked user from the command line **(FREE SELF)**
+# Locked users **(FREE SELF)**
-After ten failed login attempts a user gets in a locked state.
+Users are locked after ten failed sign-in attempts. These users remain locked:
+
+- For 10 minutes, after which time they are automatically unlocked.
+- Until an admin unlocks them from the [Admin Area](../user/admin_area/index.md) or the command line in under 10 minutes.
+
+## Unlock a user from the Admin Area
+
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Overview > Users**.
+1. Use the search bar to find the locked user.
+1. From the **User administration** dropdown select **Unlock**.
+
+![Unlock a user from the Admin Area](img/unlock_user_v14_7.png)
+
+## Unlock a user from the command line
To unlock a locked user:
diff --git a/doc/security/user_email_confirmation.md b/doc/security/user_email_confirmation.md
index 48538e413b4..8baddaf1383 100644
--- a/doc/security/user_email_confirmation.md
+++ b/doc/security/user_email_confirmation.md
@@ -1,7 +1,7 @@
---
type: howto
stage: Manage
-group: Access
+group: Authentication & 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/security/user_file_uploads.md b/doc/security/user_file_uploads.md
index 7a8a78cc5f8..734a4cde7e8 100644
--- a/doc/security/user_file_uploads.md
+++ b/doc/security/user_file_uploads.md
@@ -1,7 +1,7 @@
---
type: reference
stage: Manage
-group: Access
+group: Authentication & 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/security/webhooks.md b/doc/security/webhooks.md
index 47ef90cbe55..621e6d595bf 100644
--- a/doc/security/webhooks.md
+++ b/doc/security/webhooks.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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: concepts, reference, howto
---
@@ -74,7 +74,8 @@ allowlist:
The allowed entries can be separated by semicolons, commas or whitespaces
(including newlines) and be in different formats like hostnames, IP addresses and/or
IP ranges. IPv6 is supported. Hostnames that contain Unicode characters should
-use Internationalising Domain Names in Applications (IDNA) encoding.
+use [Internationalized Domain Names in Applications](https://www.icann.org/resources/pages/glossary-2014-02-04-en#i)
+(IDNA) encoding.
The allowlist can hold a maximum of 1000 entries. Each entry can be a maximum of
255 characters.
diff --git a/doc/ssh/index.md b/doc/ssh/index.md
index 2fae3512b9d..6196ee5465b 100644
--- a/doc/ssh/index.md
+++ b/doc/ssh/index.md
@@ -1,14 +1,14 @@
---
stage: Manage
-group: Access
+group: Authentication & 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: howto, reference
---
-# GitLab and SSH keys **(FREE)**
+# Use SSH keys to communicate with GitLab **(FREE)**
Git is a distributed version control system, which means you can work locally,
-then share or "push" your changes to a server. In this case, the server is GitLab.
+then share or *push* your changes to a server. In this case, the server you push to is GitLab.
GitLab uses the SSH protocol to securely communicate with Git.
When you use SSH keys to authenticate to the GitLab remote server,
@@ -376,7 +376,9 @@ Git user has default SSH configuration? ... no
Remove the custom configuration as soon as you can. These customizations
are **explicitly not supported** and may stop working at any time.
-## Troubleshooting SSH connections
+## Troubleshooting
+
+### Password prompt with `git clone`
When you run `git clone`, you may be prompted for a password, like `git@gitlab.example.com's password:`.
This indicates that something is wrong with your SSH setup.
@@ -386,3 +388,13 @@ This indicates that something is wrong with your SSH setup.
- Try to manually register your private SSH key by using `ssh-agent`.
- Try to debug the connection by running `ssh -Tv git@example.com`.
Replace `example.com` with your GitLab URL.
+
+### `Could not resolve hostname` error
+
+You may receive the following error when [verifying that you can connect](#verify-that-you-can-connect):
+
+```shell
+ssh: Could not resolve hostname gitlab.example.com: nodename nor servname provided, or not known
+```
+
+If you receive this error, restart your terminal and try the command again.
diff --git a/doc/subscriptions/bronze_starter.md b/doc/subscriptions/bronze_starter.md
index 3a58dd84614..2c66d32f669 100644
--- a/doc/subscriptions/bronze_starter.md
+++ b/doc/subscriptions/bronze_starter.md
@@ -98,8 +98,8 @@ the tiers are no longer mentioned in GitLab documentation:
- [Bidirectional mirroring](../user/project/repository/mirror/bidirectional.md)
- [Mirror with Perforce Helix with Git Fusion](../user/project/repository/mirror/bidirectional.md#mirror-with-perforce-helix-with-git-fusion)
- Runners:
- - Run pipelines in the parent project [for merge requests from a forked project](../ci/pipelines/merge_request_pipelines.md#run-pipelines-in-the-parent-project-for-merge-requests-from-a-forked-project)
- - [Shared runners pipeline minutes quota](../user/admin_area/settings/continuous_integration.md#shared-runners-pipeline-minutes-quota)
+ - Run pipelines in the parent project [for merge requests from a forked project](../ci/pipelines/merge_request_pipelines.md#run-pipelines-in-the-parent-project)
+ - [Shared runners CI/CD minutes](../ci/pipelines/cicd_minutes.md)
- [Push rules](../push_rules/push_rules.md)
- SAML for self-managed GitLab instance:
- [Administrator groups](../integration/saml.md#administrator-groups)
diff --git a/doc/subscriptions/gitlab_com/index.md b/doc/subscriptions/gitlab_com/index.md
index e174a144cfc..b72fad02b3d 100644
--- a/doc/subscriptions/gitlab_com/index.md
+++ b/doc/subscriptions/gitlab_com/index.md
@@ -11,25 +11,32 @@ GitLab SaaS is the GitLab software-as-a-service offering, which is available at
You don't need to install anything to use GitLab SaaS, you only need to
[sign up](https://gitlab.com/users/sign_up). When you sign up, you choose:
-- [A license tier](https://about.gitlab.com/pricing/).
+- [A subscription](https://about.gitlab.com/pricing/).
- [The number of seats you want](#how-seat-usage-is-determined).
-All GitLab SaaS public projects, regardless of the subscription, get access to features in the **Ultimate** tier.
-Qualifying open source projects also get 50,000 CI minutes and free access to the **Ultimate** tier
+The subscription determines which features are available for your private projects. Public projects automatically get **Ultimate** tier features.
+
+Qualifying open source projects also get 50,000 CI/CD minutes and free access to the **Ultimate** tier
through the [GitLab for Open Source program](https://about.gitlab.com/solutions/open-source/).
## Obtain a GitLab SaaS subscription
+A GitLab SaaS subscription applies to a top-level group.
+Members of every subgroup and project in the group:
+
+- Can use the features of the subscription.
+- Consume seats in the subscription.
+
To subscribe to GitLab SaaS:
1. View the [GitLab SaaS feature comparison](https://about.gitlab.com/pricing/gitlab-com/feature-comparison/)
and decide which tier you want.
1. Create a user account for yourself by using the
[sign up page](https://gitlab.com/users/sign_up).
-1. Create a [group](../../user/group/index.md#create-a-group). You use the group to grant users access to several projects
- at once. A group is not required if you plan to have projects in a personal namespace instead.
+1. Create a [group](../../user/group/index.md#create-a-group). Your license tier applies to the top-level group, its subgroups, and projects.
1. Create additional users and
- [add them to the group](../../user/group/index.md#add-users-to-a-group).
+ [add them to the group](../../user/group/index.md#add-users-to-a-group). The users in this group, its subgroups, and projects can use
+ the features of your license tier, and they consume a seat in your subscription.
1. On the left sidebar, select **Billing** and choose a tier.
1. Fill out the form to complete your purchase.
@@ -62,10 +69,12 @@ The following information is displayed:
email address.
A GitLab SaaS subscription uses a concurrent (_seat_) model. You pay for a
-subscription according to the maximum number of users enabled at one time. You can
+subscription according to the maximum number of users assigned to the top-level group or its children during the billing period. You can
add and remove users during the subscription period, as long as the total users
at any given time doesn't exceed the subscription count.
+A top-level group can be [changed](../../user/group/index.md#change-a-groups-path) like any other group.
+
Every user is included in seat usage, with the following exceptions:
- Users who are pending approval.
@@ -77,6 +86,12 @@ Every user is included in seat usage, with the following exceptions:
Seat usage is reviewed [quarterly or annually](../quarterly_reconciliation.md).
+If a user navigates to a different top-level group (one they have created themselves, for example)
+and that group does not have a paid subscription, they would not see any of the paid features.
+
+It is also possible for users to belong to two different top-level groups with different subscriptions.
+In this case, they would see only the features available to that subscription.
+
### View seat usage
To view a list of seats being used:
@@ -124,7 +139,7 @@ and is not affected by the current search.
A GitLab subscription is valid for a specific number of users.
If the number of billable users exceeds the number included in the subscription, known
-as the number of **seats owed**, you must pay for the excess number of users before renewal.
+as the number of **seats owed**, you must pay for the excess number of users.
For example, if you purchase a subscription for 10 users:
@@ -138,9 +153,9 @@ Seats owed = 12 - 10 (Maximum users - users in subscription)
### Add users to your subscription
-You can add users to your subscription at any time during the subscription period. The cost of
-additional users added during the subscription period is prorated from the date of purchase through
-the end of the subscription period.
+Your subscription cost is based on the maximum number of seats you use during the billing period.
+Even if you reach the number of seats in your subscription, you can continue to add users.
+GitLab [bills you for the overage](../quarterly_reconciliation.md).
To add users to a subscription:
@@ -219,6 +234,8 @@ of the date of expiry with a banner in the GitLab user interface.
To renew your subscription:
1. Log in to the [Customers Portal](https://customers.gitlab.com/customers/sign_in) and beneath your existing subscription, select **Renew**.
+The **Renew** button remains disabled (grayed-out) until 15 days before a subscription expires.
+You can hover your mouse on the **Renew** button to see the date when it will become active.
1. Review your renewal details and complete the payment process.
1. Select **Confirm purchase**.
@@ -250,132 +267,30 @@ previous period), log in to the [Customers Portal](https://customers.gitlab.com/
If you have difficulty during the renewal process, contact the
[Support team](https://support.gitlab.com/hc/en-us/requests/new?ticket_form_id=360000071293) for assistance.
-## Change the contact person for your subscription
-
-To change the contact person who manages your subscription,
-contact the GitLab [Support team](https://support.gitlab.com/hc/en-us/requests/new?ticket_form_id=360000071293).
-
-## CI pipeline minutes
-
-CI pipeline minutes are the execution time for your [pipelines](../../ci/pipelines/index.md)
-on GitLab shared runners. Each [GitLab SaaS tier](https://about.gitlab.com/pricing/)
-includes a monthly quota of CI pipeline minutes for private and public projects in
-the namespace:
-
-| Plan | CI pipeline minutes |
-|----------|---------------------|
-| Free | 400 |
-| Premium | 10,000 |
-| Ultimate | 50,000 |
-
-The consumption rate for CI pipeline minutes is based on the visibility of the projects:
-
-- Private projects in the namespace consume pipeline minutes at a rate of 1 CI pipeline minute
- per 1 minute of execution time on GitLab shared runners.
-- Public projects in:
- - Namespaces [created on or after 2021-07-17](https://gitlab.com/gitlab-org/gitlab/-/issues/332708)
- consume pipeline minutes at a slower rate, 1 CI pipeline minute per 125 minutes
- of execution time on GitLab shared runners. The per-minute rate for public projects
- is 0.008 CI pipeline minutes per 1 minute of execution time on GitLab shared runners.
- - Namespaces created before 2021-07-17 do not consume CI pipeline minutes.
-
-| Plan | CI pipeline minutes | Maximum **private** project execution time (all namespaces) | Maximum **public** project execution time (namespaces created 2021-07-17 and later) |
-|----------|---------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------|
-| Free | 400 | 400 minutes | 50,000 minutes |
-| Premium | 10,000 | 10,000 minutes | 1,250,000 minutes |
-| Ultimate | 50,000 | 50,000 minutes | 6,250,000 minutes |
-
-Quotas apply to:
-
-- Groups, where the minutes are shared across all members of the group, its
- subgroups, and nested projects. To view the group's usage, navigate to the group,
- then **Settings > Usage Quotas**.
-- Your personal account, where the minutes are available for your personal projects.
- To view and buy personal minutes:
-
- 1. In the top-right corner, select your avatar.
- 1. Select **Edit profile**.
- 1. On the left sidebar, select **[Usage Quotas](https://gitlab.com/-/profile/usage_quotas#pipelines-quota-tab)**.
-
-Only pipeline minutes for GitLab shared runners are restricted. If you have a
-specific runner set up for your projects, there is no limit to your build time on GitLab SaaS.
-
-The available quota is reset on the first of each calendar month at midnight UTC.
+## Add or change the contacts for your subscription
-When the CI minutes are depleted, an email is sent automatically to notify the owner(s)
-of the namespace. You can [purchase additional CI minutes](#purchase-additional-ci-minutes),
-or upgrade your account to a higher [plan](https://about.gitlab.com/pricing/).
-Your own runners can still be used even if you reach your limits.
+Contacts can renew a subscription, cancel a subscription, or transfer the subscription to a different namespace.
-### Purchase additional CI minutes
+To change the contacts:
-If you're using GitLab SaaS, you can purchase additional CI minutes so your
-pipelines aren't blocked after you have used all your CI minutes from your
-main quota. You can find pricing for additional CI/CD minutes on the
-[GitLab Pricing page](https://about.gitlab.com/pricing/). Additional minutes:
+1. Ensure an account exists in the
+ [Customers Portal](https://customers.gitlab.com/customers/sign_in) for the user you want to add.
+1. Verify you have access to at least one of
+ [these requirements](https://about.gitlab.com/handbook/support/license-and-renewals/workflows/customersdot/associating_purchases.html).
+1. [Create a ticket with the Support team](https://support.gitlab.com/hc/en-us/requests/new?ticket_form_id=360000071293). Include any relevant material in your request.
-- Are only used after the shared quota included in your subscription runs out.
-- Roll over month to month.
-
-To purchase additional minutes for your personal namespace:
-
-1. In the top-right corner, select your avatar.
-1. Select **Edit profile**.
-1. On the left sidebar, select **Usage Quotas**.
-1. Select **Buy additional minutes** and GitLab redirects you to the Customers Portal.
-1. Locate the subscription card that's linked to your personal namespace on GitLab SaaS, click **Buy more CI minutes**, and complete the details about the transaction.
-
-After we process your payment, the extra CI minutes are synced to your group
-namespace.
-
-To confirm the available CI minutes for your personal projects, go to the **Usage Quotas** settings again.
-
-The **Additional minutes** displayed now includes the purchased additional CI
-minutes, plus any minutes rolled over from last month.
-
-Be aware that:
-
-- Extra CI minutes assigned to one group cannot be transferred to a different
- group.
-- If you have used more minutes than your default quota, those minutes are
- deducted from your Additional Minutes quota immediately after your purchase of
- additional minutes.
-
-### Purchase additional CI minutes on GitLab SaaS
-
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/6574) in GitLab 14.5.
-
-If you're using GitLab SaaS, you can purchase additional CI minutes so your
-pipelines aren't blocked after you have used all your CI minutes from your
-main quota. You can find pricing for additional CI/CD minutes on the
-[GitLab Pricing page](https://about.gitlab.com/pricing/). Additional minutes:
-
-- Are only used after the shared quota included in your subscription runs out.
-- Roll over month to month.
-
-To purchase additional minutes for your group on GitLab SaaS:
-
-1. On the top bar, select **Menu > Groups** and find your group.
-1. On the left sidebar, select **Settings > Usage Quotas**.
-1. Select **Buy additional minutes**.
-1. Complete the details about the transaction.
-
-After we process your payment, the extra CI minutes are synced to your group
-namespace.
+## CI/CD minutes
-To confirm the available CI minutes, go to your group, and then select
-**Settings > Usage Quotas**.
+CI/CD minutes are the execution time for your [pipelines](../../ci/pipelines/index.md)
+on GitLab shared runners.
-The **Additional minutes** displayed now includes the purchased additional CI
-minutes, plus any minutes rolled over from last month.
+Refer to [CI/CD minutes](../../ci/pipelines/cicd_minutes.md)
+for more information.
-Be aware that:
+### Purchase additional CI/CD minutes
-- Extra CI minutes assigned to one group cannot be transferred to a different
- group.
-- If you have used more minutes than your default quota, those minutes are
- deducted from your Additional Minutes quota immediately after your purchase of
- additional minutes.
+You can [purchase additional minutes](../../ci/pipelines/cicd_minutes.md#purchase-additional-cicd-minutes)
+for your personal or group namespace.
## Storage subscription
diff --git a/doc/subscriptions/img/quarterly_reconciliation.png b/doc/subscriptions/img/quarterly_reconciliation.png
new file mode 100644
index 00000000000..1990d64616e
--- /dev/null
+++ b/doc/subscriptions/img/quarterly_reconciliation.png
Binary files differ
diff --git a/doc/subscriptions/index.md b/doc/subscriptions/index.md
index 2cf3b9f7074..4e4c0309c3d 100644
--- a/doc/subscriptions/index.md
+++ b/doc/subscriptions/index.md
@@ -7,11 +7,6 @@ type: index, reference
# GitLab subscription **(PREMIUM)**
-INFO:
-Get advanced search and more with
-[a trial of GitLab Ultimate](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=u-subscription-docs).
-Free for 30 days.
-
GitLab offers tiers of features. Your subscription determines which tier you
have access to. Subscriptions are valid for 12 months.
@@ -177,7 +172,7 @@ To change the password for this customers portal account:
### GitLab for Education
For qualifying non-profit educational institutions, the [GitLab for Education](https://about.gitlab.com/solutions/education/) program provides
-the top GitLab tier, plus 50,000 CI minutes per month.
+the top GitLab tier, plus 50,000 CI/CD minutes per month.
The GitLab for Education license can only be used for instructional-use or
non-commercial academic research.
@@ -188,7 +183,7 @@ Find more information on how to apply and renew at
### GitLab for Open Source
For qualifying open source projects, the [GitLab for Open Source](https://about.gitlab.com/solutions/open-source/) program provides
-the top GitLab tier, plus 50,000 CI minutes per month.
+the top GitLab tier, plus 50,000 CI/CD minutes per month.
You can find more information about the [program requirements](https://about.gitlab.com/solutions/open-source/join/#requirements),
[renewals](https://about.gitlab.com/solutions/open-source/join/#renewals),
@@ -253,7 +248,7 @@ if a project holds sensitive data. Email `opensource@gitlab.com` with details of
### GitLab for Startups
For qualifying startups, the [GitLab for Startups](https://about.gitlab.com/solutions/startups/) program provides
-the top GitLab tier, plus 50,000 CI minutes per month for 12 months.
+the top GitLab tier, plus 50,000 CI/CD minutes per month for 12 months.
For more information, including program requirements, see the [Startup program's landing page](https://about.gitlab.com/solutions/startups/).
diff --git a/doc/subscriptions/quarterly_reconciliation.md b/doc/subscriptions/quarterly_reconciliation.md
index cdac50748d0..3398902da1b 100644
--- a/doc/subscriptions/quarterly_reconciliation.md
+++ b/doc/subscriptions/quarterly_reconciliation.md
@@ -9,14 +9,44 @@ info: To determine the technical writer assigned to the Stage/Group associated w
GitLab reviews your seat usage and sends you an invoice for any overages.
This review can occur:
-- **Annually**, also known as the annual true-up process. This process requires you to pay the full annual subscription fee
+- **Annually**. This process is also known as **the annual true-up process**. This process requires you to pay the full annual subscription fee
for users added anytime during the year.
-- **Quarterly**. With this process, you only pay for the remaining period of your subscription term.
+- **Quarterly**. With this process, you pay only for the remaining period of your subscription term.
-## Quarterly reconciliation process
+## Quarterly reconciliation vs. annual true-ups
-With the quarterly reconciliation process, if you add users in the third quarter of your subscription term, for example,
-you only pay 25% of what you would have paid previously. This calculation results in substantial savings.
+Quarterly reconciliation can result in substantial savings.
+
+Let's say in January you purchased an annual license for 100 users. This chart shows your usage during the year.
+The number of users went up and down, with 120 as the maximum. The dark purple indicates the most users you had each quarter.
+
+![License overview](img/quarterly_reconciliation.png)
+
+If you are being billed annually:
+
+- During the year, you went over the license by 20 users.
+- If we pretend each extra seat is $100, then you pay $100 x 20 users.
+
+Annual total: **$2000**
+
+If you are being billed quarterly, you pay for the maximum number of seats you used during the quarter,
+and for only the remaining quarters.
+
+Using the same example, if a seat is $100 per year, then it is $25 per quarter.
+
+- In Q1, you had a maximum of 110 users. 10 users over license x $25 per user x 3 quarters = **$750**
+ The license is now paid for 110 users.
+
+- In Q2, 105 users was the maximum. You did not go over 110 users, so no charge.
+
+- In Q3, you had 120 users. 10 users over license x $25 per user x 1 remaining quarter = **$250**
+ The license is now paid for 120 users.
+
+- In Q4, you had 120 users. You did not exceed the number of users. However, if you had, you would not be charged, because in Q4, there are no charges for exceeding the number.
+
+Annual total: **$1000**
+
+With quarterly reconciliation, you pay less annually.
If it's not possible for you to participate in quarterly reconciliations, you can opt out of the
process by using a contract amendment. In that case, you default to the annual review.
diff --git a/doc/subscriptions/self_managed/index.md b/doc/subscriptions/self_managed/index.md
index 94180da2bbd..5ac2c5a5037 100644
--- a/doc/subscriptions/self_managed/index.md
+++ b/doc/subscriptions/self_managed/index.md
@@ -254,7 +254,7 @@ 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#uploading-your-license).
+ which must be [uploaded to your GitLab instance](../../user/admin_area/license.md#upload-your-license).
NOTE:
If you're purchasing a subscription for an existing **Free** GitLab self-managed
@@ -373,7 +373,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#uploading-your-license) to your instance to use it.
+- A new license. [Upload this license](../../user/admin_area/license.md#upload-your-license) to your instance to use it.
### Renew a subscription
@@ -384,6 +384,8 @@ 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. 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.
+You can hover your mouse on the **Renew** button to see the date when it will become active.
NOTE:
If you need to change your [GitLab tier](https://about.gitlab.com/pricing/), contact our sales team via [the sales contact form](https://about.gitlab.com/sales/) for assistance as this can't be done in the Customers Portal.
@@ -392,7 +394,7 @@ We recommend following these steps during 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#uploading-your-license) your new license to your instance.
+1. [Upload](../../user/admin_area/license.md#upload-your-license) your new license 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.
@@ -414,9 +416,21 @@ The following is emailed to you:
[**View invoices**](https://customers.gitlab.com/receipts).
- A new license.
-[Upload the new license](../../user/admin_area/license.md#uploading-your-license) to your instance.
+[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 or change the contacts for your subscription
+
+Contacts can renew a subscription, cancel a subscription, or transfer the subscription to a different namespace.
+
+To change the contacts:
+
+1. Ensure an account exists in the
+ [Customers Portal](https://customers.gitlab.com/customers/sign_in) for the user you want to add.
+1. Verify you have access to at least one of
+ [these requirements](https://about.gitlab.com/handbook/support/license-and-renewals/workflows/customersdot/associating_purchases.html).
+1. [Create a ticket with the Support team](https://support.gitlab.com/hc/en-us/requests/new?ticket_form_id=360000071293). Include any relevant material in your request.
+
## Subscription expiry
When your license expires, GitLab locks down features, like Git pushes
diff --git a/doc/system_hooks/system_hooks.md b/doc/system_hooks/system_hooks.md
index 72106a00191..44429754747 100644
--- a/doc/system_hooks/system_hooks.md
+++ b/doc/system_hooks/system_hooks.md
@@ -45,7 +45,7 @@ System hooks can be used, for example, for logging or changing information in an
LDAP server.
In addition to these default events, you can enable triggers for other events,
-such as push events, and disable the `repository_update` event
+such as push events, and disable the `repository_update` event
when you create a system hook.
NOTE:
diff --git a/doc/topics/authentication/index.md b/doc/topics/authentication/index.md
index da96e88bb21..2a301e6ff5b 100644
--- a/doc/topics/authentication/index.md
+++ b/doc/topics/authentication/index.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -11,7 +11,7 @@ This page gathers all the resources for the topic **Authentication** within GitL
## GitLab users
- [SSH](../../ssh/index.md)
-- [Two-factor authentication (2FA)](../../user/profile/account/two_factor_authentication.md#two-factor-authentication)
+- [Two-factor authentication](../../user/profile/account/two_factor_authentication.md)
- [Why do I keep getting signed out?](../../user/profile/index.md#why-do-i-keep-getting-signed-out)
- **Articles:**
- [Support for Universal 2nd Factor Authentication - YubiKeys](https://about.gitlab.com/blog/2016/06/22/gitlab-adds-support-for-u2f/)
@@ -40,8 +40,9 @@ This page gathers all the resources for the topic **Authentication** within GitL
## API
- [OAuth 2 Tokens](../../api/index.md#oauth2-tokens)
-- [Personal access tokens](../../api/index.md#personalproject-access-tokens)
-- [Project access tokens](../../api/index.md#personalproject-access-tokens)
+- [Personal access tokens](../../api/index.md#personalprojectgroup-access-tokens)
+- [Project access tokens](../../api/index.md#personalprojectgroup-access-tokens)
+- [Group access tokens](../../api/index.md#personalprojectgroup-access-tokens)
- [Impersonation tokens](../../api/index.md#impersonation-tokens)
- [OAuth 2.0 identity provider API](../../api/oauth2.md)
diff --git a/doc/topics/autodevops/customize.md b/doc/topics/autodevops/customize.md
index 925f657c099..177e10b99b9 100644
--- a/doc/topics/autodevops/customize.md
+++ b/doc/topics/autodevops/customize.md
@@ -131,7 +131,7 @@ You can extend and manage your Auto DevOps configuration with GitLab APIs:
## Forward CI/CD variables to the build environment
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/25514) in GitLab 12.3, but available in versions 11.9 and above.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/25514) in GitLab 12.3, but available in GitLab 12.0 and later.
CI/CD variables can be forwarded into the build environment using the
`AUTO_DEVOPS_BUILD_IMAGE_FORWARDED_CI_VARIABLES` CI/CD variable.
@@ -408,14 +408,15 @@ applications.
| `AUTO_DEVOPS_BUILD_IMAGE_FORWARDED_CI_VARIABLES` | A [comma-separated list of CI/CD variable names](#forward-cicd-variables-to-the-build-environment) to be forwarded to the build environment (the buildpack builder or `docker build`). |
| `AUTO_DEVOPS_CHART` | Helm Chart used to deploy your apps. Defaults to the one [provided by GitLab](https://gitlab.com/gitlab-org/cluster-integration/auto-deploy-image/-/tree/master/assets/auto-deploy-app). |
| `AUTO_DEVOPS_CHART_REPOSITORY` | Helm Chart repository used to search for charts. Defaults to `https://charts.gitlab.io`. |
-| `AUTO_DEVOPS_CHART_REPOSITORY_NAME` | From GitLab 11.11, used to set the name of the Helm repository. Defaults to `gitlab`. |
-| `AUTO_DEVOPS_CHART_REPOSITORY_USERNAME` | From GitLab 11.11, used to set a username to connect to the Helm repository. Defaults to no credentials. Also set `AUTO_DEVOPS_CHART_REPOSITORY_PASSWORD`. |
-| `AUTO_DEVOPS_CHART_REPOSITORY_PASSWORD` | From GitLab 11.11, used to set a password to connect to the Helm repository. Defaults to no credentials. Also set `AUTO_DEVOPS_CHART_REPOSITORY_USERNAME`. |
+| `AUTO_DEVOPS_CHART_REPOSITORY_NAME` | Used to set the name of the Helm repository. Defaults to `gitlab`. |
+| `AUTO_DEVOPS_CHART_REPOSITORY_USERNAME` | Used to set a username to connect to the Helm repository. Defaults to no credentials. Also set `AUTO_DEVOPS_CHART_REPOSITORY_PASSWORD`. |
+| `AUTO_DEVOPS_CHART_REPOSITORY_PASSWORD` | Used to set a password to connect to the Helm repository. Defaults to no credentials. Also set `AUTO_DEVOPS_CHART_REPOSITORY_USERNAME`. |
| `AUTO_DEVOPS_CHART_REPOSITORY_PASS_CREDENTIALS` | From GitLab 14.2, set to a non-empty value to enable forwarding of the Helm repository credentials to the chart server when the chart artifacts are on a different host than repository. |
| `AUTO_DEVOPS_DEPLOY_DEBUG` | From GitLab 13.1, if this variable is present, Helm outputs debug logs. |
| `AUTO_DEVOPS_ALLOW_TO_FORCE_DEPLOY_V<N>` | From [auto-deploy-image](https://gitlab.com/gitlab-org/cluster-integration/auto-deploy-image) v1.0.0, if this variable is present, a new major version of chart is forcibly deployed. For more information, see [Ignore warnings and continue deploying](upgrading_auto_deploy_dependencies.md#ignore-warnings-and-continue-deploying). |
| `BUILDPACK_URL` | Buildpack's full URL. [Must point to a URL supported by Pack or Herokuish](#custom-buildpacks). |
-| `CANARY_ENABLED` | From GitLab 11.0, used to define a [deploy policy for canary environments](#deploy-policy-for-canary-environments). |
+| `CANARY_ENABLED` | Used to define a [deploy policy for canary environments](#deploy-policy-for-canary-environments). |
+| `BUILDPACK_VOLUMES` | Specify one or more [Buildpack volumes to mount](stages.md#mount-volumes-into-the-build-container). Use a pipe `|` as list separator. |
| `CANARY_PRODUCTION_REPLICAS` | Number of canary replicas to deploy for [Canary Deployments](../../user/project/canary_deployments.md) in the production environment. Takes precedence over `CANARY_REPLICAS`. Defaults to 1. |
| `CANARY_REPLICAS` | Number of canary replicas to deploy for [Canary Deployments](../../user/project/canary_deployments.md). Defaults to 1. |
| `CI_APPLICATION_REPOSITORY` | The repository of container image being built or deployed, `$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG`. For more details, read [Custom container image](#custom-container-image). |
@@ -424,18 +425,18 @@ applications.
| `DOCKERFILE_PATH` | From GitLab 13.2, allows overriding the [default Dockerfile path for the build stage](#custom-dockerfile) |
| `HELM_RELEASE_NAME` | From GitLab 12.1, allows the `helm` release name to be overridden. Can be used to assign unique release names when deploying multiple projects to a single namespace. |
| `HELM_UPGRADE_VALUES_FILE` | From GitLab 12.6, allows the `helm upgrade` values file to be overridden. Defaults to `.gitlab/auto-deploy-values.yaml`. |
-| `HELM_UPGRADE_EXTRA_ARGS` | From GitLab 11.11, allows extra options in `helm upgrade` commands when deploying the application. Note that using quotes doesn't prevent word splitting. |
-| `INCREMENTAL_ROLLOUT_MODE` | From GitLab 11.4, 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_*` | From GitLab 11.7, any variable prefixed with [`K8S_SECRET_`](#application-secret-variables) is made available by Auto DevOps as environment variables to the deployed application. |
+| `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_INGRESS_BASE_DOMAIN` | From GitLab 11.8, 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_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. |
| `PRODUCTION_REPLICAS` | Number of replicas to deploy in the production environment. Takes precedence over `REPLICAS` and defaults to 1. For zero downtime upgrades, set to 2 or greater. |
| `REPLICAS` | Number of replicas to deploy. Defaults to 1. |
-| `ROLLOUT_RESOURCE_TYPE` | From GitLab 11.9, allows specification of the resource type being deployed when using a custom Helm chart. Default value is `deployment`. |
+| `ROLLOUT_RESOURCE_TYPE` | Allows specification of the resource type being deployed when using a custom Helm chart. Default value is `deployment`. |
| `ROLLOUT_STATUS_DISABLED` | From GitLab 12.0, used to disable rollout status check because it does not support all resource types, for example, `cronjob`. |
-| `STAGING_ENABLED` | From GitLab 10.8, used to define a [deploy policy for staging and production environments](#deploy-policy-for-staging-and-production-environments). |
+| `STAGING_ENABLED` | Used to define a [deploy policy for staging and production environments](#deploy-policy-for-staging-and-production-environments). |
NOTE:
After you set up your replica variables using a
@@ -453,8 +454,8 @@ The following table lists CI/CD variables related to the database.
| **CI/CD Variable** | **Description** |
|-----------------------------------------|------------------------------------|
-| `DB_INITIALIZE` | From GitLab 11.4, used to specify the command to run to initialize the application's PostgreSQL database. Runs inside the application pod. |
-| `DB_MIGRATE` | From GitLab 11.4, used to specify the command to run to migrate the application's PostgreSQL database. Runs inside the application pod. |
+| `DB_INITIALIZE` | Used to specify the command to run to initialize the application's PostgreSQL database. Runs inside the application pod. |
+| `DB_MIGRATE` | Used to specify the command to run to migrate the application's PostgreSQL database. Runs inside the application pod. |
| `POSTGRES_ENABLED` | Whether PostgreSQL is enabled. Defaults to `true`. Set to `false` to disable the automatic deployment of PostgreSQL. |
| `POSTGRES_USER` | The PostgreSQL user. Defaults to `user`. Set it to use a custom username. |
| `POSTGRES_PASSWORD` | The PostgreSQL password. Defaults to `testing-password`. Set it to use a custom password. |
@@ -478,12 +479,11 @@ The following table lists variables used to disable jobs.
| `bundler-audit-dependency_scanning` | `DEPENDENCY_SCANNING_DISABLED` | | If the variable is present, the job isn't created. |
| `canary` | `CANARY_ENABLED` | | This manual job is created if the variable is present. |
| `code_intelligence` | `CODE_INTELLIGENCE_DISABLED` | From GitLab 13.6 | If the variable is present, the job isn't created. |
-| `codequality` | `CODE_QUALITY_DISABLED` | Until GitLab 11.0 | If the variable is present, the job isn't created. |
-| `code_quality` | `CODE_QUALITY_DISABLED` | [From GitLab 11.0](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/5773) | If the variable is present, the job isn't created. |
-| `container_scanning` | `CONTAINER_SCANNING_DISABLED` | From GitLab 11.0 | If the variable is present, the job isn't created. |
-| `dast` | `DAST_DISABLED` | From GitLab 11.0 | If the variable is present, the job isn't created. |
+| `code_quality` | `CODE_QUALITY_DISABLED` | | If the variable is present, the job isn't created. |
+| `container_scanning` | `CONTAINER_SCANNING_DISABLED` | | If the variable is present, the job isn't created. |
+| `dast` | `DAST_DISABLED` | | If the variable is present, the job isn't created. |
| `dast_environment_deploy` | `DAST_DISABLED_FOR_DEFAULT_BRANCH` or `DAST_DISABLED` | [From GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17789) | If either variable is present, the job isn't created. |
-| `dependency_scanning` | `DEPENDENCY_SCANNING_DISABLED` | From GitLab 11.0 | If the variable is present, the job isn't created. |
+| `dependency_scanning` | `DEPENDENCY_SCANNING_DISABLED` | | If the variable is present, the job isn't created. |
| `eslint-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
| `flawfinder-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
| `gemnasium-dependency_scanning` | `DEPENDENCY_SCANNING_DISABLED` | | If the variable is present, the job isn't created. |
@@ -491,34 +491,32 @@ The following table lists variables used to disable jobs.
| `gemnasium-python-dependency_scanning` | `DEPENDENCY_SCANNING_DISABLED` | | If the variable is present, the job isn't created. |
| `gosec-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
| `kubesec-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
-| `license_management` | `LICENSE_MANAGEMENT_DISABLED` | GitLab 11.0 to 12.7 | If the variable is present, the job isn't created. Job deprecated [from GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/22773) |
+| `license_management` | `LICENSE_MANAGEMENT_DISABLED` | GitLab 12.7 and earlier | If the variable is present, the job isn't created. Job deprecated [from GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/22773) |
| `license_scanning` | `LICENSE_MANAGEMENT_DISABLED` | [From GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/22773) | If the variable is present, the job isn't created. |
| `load_performance` | `LOAD_PERFORMANCE_DISABLED` | From GitLab 13.2 | If the variable is present, the job isn't created. |
| `nodejs-scan-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
-| `performance` | `PERFORMANCE_DISABLED` | GitLab 11.0 to GitLab 13.12 | Browser performance. If the variable is present, the job isn't created. Replaced by `browser_performance`. |
+| `performance` | `PERFORMANCE_DISABLED` | GitLab 13.12 and earlier | Browser performance. If the variable is present, the job isn't created. Replaced by `browser_performance`. |
| `browser_performance` | `BROWSER_PERFORMANCE_DISABLED` | From GitLab 14.0 | Browser performance. If the variable is present, the job isn't created. Replaces `performance`. |
| `phpcs-security-audit-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
| `pmd-apex-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
| `retire-js-dependency_scanning` | `DEPENDENCY_SCANNING_DISABLED` | | If the variable is present, the job isn't created. |
-| `review` | `REVIEW_DISABLED` | From GitLab 11.0 | If the variable is present, the job isn't created. |
-| `review:stop` | `REVIEW_DISABLED` | From GitLab 11.0 | Manual job. If the variable is present, the job isn't created. |
-| `sast` | `SAST_DISABLED` | From GitLab 11.0 | If the variable is present, the job isn't created. |
-| `sast:container` | `CONTAINER_SCANNING_DISABLED` | From GitLab 11.0 | If the variable is present, the job isn't created. |
+| `review` | `REVIEW_DISABLED` | | If the variable is present, the job isn't created. |
+| `review:stop` | `REVIEW_DISABLED` | | Manual job. If the variable is present, the job isn't created. |
+| `sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
+| `sast:container` | `CONTAINER_SCANNING_DISABLED` | | If the variable is present, the job isn't created. |
| `secret_detection` | `SECRET_DETECTION_DISABLED` | From GitLab 13.1 | If the variable is present, the job isn't created. |
| `secret_detection_default_branch` | `SECRET_DETECTION_DISABLED` | [From GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/22773) | If the variable is present, the job isn't created. |
| `security-code-scan-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
-| `secrets-sast` | `SAST_DISABLED` | From GitLab 11.0 | If the variable is present, the job isn't created. |
+| `secrets-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
| `sobelaw-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
| `stop_dast_environment` | `DAST_DISABLED_FOR_DEFAULT_BRANCH` or `DAST_DISABLED` | [From GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17789) | If either variable is present, the job isn't created. |
| `spotbugs-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
-| `test` | `TEST_DISABLED` | From GitLab 11.0 | If the variable is present, the job isn't created. |
+| `test` | `TEST_DISABLED` | | If the variable is present, the job isn't created. |
| `staging` | `STAGING_ENABLED` | | The job is created if the variable is present. |
| `stop_review` | `REVIEW_DISABLED` | | If the variable is present, the job isn't created. |
### Application secret variables
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/49056) in GitLab 11.7.
-
Some applications need to define secret variables that are accessible by the deployed
application. Auto DevOps detects CI/CD variables starting with `K8S_SECRET_`, and makes
these prefixed variables available to the deployed application as environment variables.
@@ -623,8 +621,6 @@ service:
### Deploy policy for staging and production environments
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-ci-yml/-/merge_requests/160) in GitLab 10.8.
-
NOTE:
You can also set this inside your [project's settings](requirements.md#auto-devops-deployment-strategy).
@@ -640,8 +636,6 @@ you when you're ready to manually deploy to production.
### Deploy policy for canary environments **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-ci-yml/-/merge_requests/171) in GitLab 11.0.
-
You can use a [canary environment](../../user/project/canary_deployments.md) before
deploying any changes to production.
@@ -652,8 +646,6 @@ If you define `CANARY_ENABLED` with a non-empty value, then two manual jobs are
### Incremental rollout to production **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5415) in GitLab 10.8.
-
NOTE:
You can also set this inside your [project's settings](requirements.md#auto-devops-deployment-strategy).
@@ -703,14 +695,10 @@ With `INCREMENTAL_ROLLOUT_MODE` set to `manual` and with `STAGING_ENABLED`
![Rollout and staging enabled](img/rollout_staging_enabled.png)
WARNING:
-Before GitLab 11.4, the presence of the `INCREMENTAL_ROLLOUT_ENABLED` CI/CD variable
-enabled this feature. This configuration is deprecated, and is scheduled to be
-removed in the future.
+This configuration is deprecated, and is scheduled to be removed in the future.
### Timed incremental rollout to production **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7545) in GitLab 11.4.
-
NOTE:
You can also set this inside your [project's settings](requirements.md#auto-devops-deployment-strategy).
diff --git a/doc/topics/autodevops/stages.md b/doc/topics/autodevops/stages.md
index ca004662395..8b3966526ec 100644
--- a/doc/topics/autodevops/stages.md
+++ b/doc/topics/autodevops/stages.md
@@ -65,6 +65,30 @@ Auto Test still uses Herokuish, as test suite detection is not
yet part of the Cloud Native Buildpack specification. For more information, see
[this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/212689).
+#### Mount volumes into the build container
+
+> - [Introduced](https://gitlab.com/gitlab-org/cluster-integration/auto-build-image/-/merge_requests/65) in GitLab 14.2.
+> - Multiple volume support (or `auto-build-image` v1.6.0) [introduced](https://gitlab.com/gitlab-org/cluster-integration/auto-build-image/-/merge_requests/80) in GitLab 14.6.
+
+The variable `BUILDPACK_VOLUMES` can be used to pass volume mount definitions to the
+`pack` command. The mounts are passed to `pack build` using `--volume` arguments.
+Each volume definition can include any of the capabilities provided by `build pack`
+such as the host path, the target path, whether the volume is writable, and
+one or more volume options.
+
+Use a pipe `|` character to pass multiple volumes.
+Each item from the list is passed to `build back` using a separate `--volume` argument.
+
+In this example, three volumes are mounted in the container as `/etc/foo`, `/opt/foo`, and `/var/opt/foo`:
+
+```yaml
+buildjob:
+ variables:
+ BUILDPACK_VOLUMES: /mnt/1:/etc/foo:ro|/mnt/2:/opt/foo:ro|/mnt/3:/var/opt/foo:rw
+```
+
+Read more about defining volumes in the [`pack build` documentation](https://buildpacks.io/docs/tools/pack/cli/pack_build/).
+
### Auto Build using Herokuish
> [Replaced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63351) with Cloud Native Buildpacks in GitLab 14.0.
diff --git a/doc/topics/build_your_application.md b/doc/topics/build_your_application.md
index 9750af5ba1c..d7097e55052 100644
--- a/doc/topics/build_your_application.md
+++ b/doc/topics/build_your_application.md
@@ -1,6 +1,6 @@
---
-stage:
-group:
+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
---
diff --git a/doc/topics/git/how_to_install_git/index.md b/doc/topics/git/how_to_install_git/index.md
index fc9c0e0ec63..422919ea46c 100644
--- a/doc/topics/git/how_to_install_git/index.md
+++ b/doc/topics/git/how_to_install_git/index.md
@@ -3,96 +3,83 @@ 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
description: 'This article describes how to install Git on macOS, Ubuntu Linux and Windows.'
-type: howto
---
# Installing Git **(FREE)**
-To begin contributing to GitLab projects,
-you must install the Git client on your computer.
-
-This article shows you how to install Git on macOS, Ubuntu Linux and Windows.
-
-Information on [installing Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
+To begin contributing to GitLab projects, you must install the appropriate Git client
+on your computer. Information about [installing Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
is also available at the official Git website.
-## Install Git on macOS using the Homebrew package manager
-
-Although you can use the version of Git shipped with macOS or install the latest
-version of Git on macOS by downloading it from the project website, we recommend
-installing Git with Homebrew to get access to an extensive selection of
-dependency-managed libraries and applications.
-
-If you don't need access to any additional development libraries or don't have
-approximately 15 GB of available disk space for Xcode and Homebrew, use one of
-the previously mentioned methods.
-
-### Installing Xcode
-
-To build dependencies, Homebrew needs the XCode Command Line Tools. Install
-it by running in your terminal:
+## Supported operating systems
-```shell
-xcode-select --install
-```
+Git is available for the following operating systems:
-Click **Install** to download and install it. Alternatively, you can install
-the entire [XCode](https://developer.apple.com/xcode/) package through the
-macOS App Store.
+- [macOS](#macos)
+- [Ubuntu Linux](#ubuntu-linux)
+- [Microsoft Windows](#windows)
-### Installing Homebrew
+### macOS
-With Xcode installed, browse to the [Homebrew website](https://brew.sh/index.html)
-for the official Homebrew installation instructions.
+A version of Git is supplied by macOS. You can use this version, or install the latest
+version of Git on macOS by downloading it from the project website. We recommend
+installing Git with [Homebrew](https://brew.sh/index.html). With Homebrew, you can
+access an extensive selection of libraries and applications, with their dependencies
+managed for you.
-### Installing Git via Homebrew
+Prerequisites:
-With Homebrew installed, you are now ready to install Git.
-Open a terminal and enter the following command:
+- 15 GB of available disk space for Homebrew and Xcode.
+- Extra disk space for any additional development libraries.
-```shell
-brew install git
-```
+To install Git on macOS:
-Congratulations! You should now have Git installed via Homebrew.
+1. Open a terminal and install the XCode Command Line Tools:
-To verify that Git works on your system, run:
+ ```shell
+ xcode-select --install
+ ```
-```shell
-git --version
-```
+ Alternatively, you can install the entire [XCode](https://developer.apple.com/xcode/)
+ package through the macOS App Store.
-Next, read our article on [adding an SSH key to GitLab](../../../ssh/index.md).
+1. Select **Install** to download and install XCode Command Line Tools.
+1. Install Homebrew according to the [official Homebrew installation instructions](https://brew.sh/index.html).
+1. Install Git by running `brew install git` from your terminal.
+1. In a terminal, verify that Git works on your computer:
-## Install Git on Ubuntu Linux
+ ```shell
+ git --version
+ ```
-On Ubuntu and other Linux operating systems
-it is recommended to use the built-in package manager to install Git.
+### Ubuntu Linux
-Open a terminal and enter the following commands
-to install the latest Git from the official Git maintained package archives:
+On Ubuntu and other Linux operating systems, use the built-in package manager
+to install Git:
-```shell
-sudo apt-add-repository ppa:git-core/ppa
-sudo apt-get update
-sudo apt-get install git
-```
+1. Open a terminal and run these commands to install the latest Git
+from the officially
+ maintained package archives:
-Congratulations! You should now have Git installed via the Ubuntu package manager.
+ ```shell
+ sudo apt-add-repository ppa:git-core/ppa
+ sudo apt-get update
+ sudo apt-get install git
+ ```
-To verify that Git works on your system, run:
+1. To verify that Git works on your computer, run:
-```shell
-git --version
-```
+ ```shell
+ git --version
+ ```
-Next, read our article on [adding an SSH key to GitLab](../../../ssh/index.md).
+### Windows
-## Installing Git on Windows from the Git website
+Go to the [Git website](https://git-scm.com/), and then download and install Git for Windows.
-Open the [Git website](https://git-scm.com/) and download and install Git for Windows.
+## After you install Git
-Next, read our article on [adding an SSH key to GitLab](../../../ssh/index.md).
+After you successfully install Git on your computer, read about [adding an SSH key to GitLab](../../../ssh/index.md).
<!-- ## Troubleshooting
diff --git a/doc/topics/git/lfs/index.md b/doc/topics/git/lfs/index.md
index 0fe38e25df5..a94caf2bf33 100644
--- a/doc/topics/git/lfs/index.md
+++ b/doc/topics/git/lfs/index.md
@@ -99,7 +99,7 @@ and are not pushed to the remote repository.
### Migrate an existing repository to Git LFS
-Read the documentation on how to [migrate an existing Git repository with Git LFS](migrate_to_git_lfs.md).
+Read the documentation on how to [migrate an existing Git repository with Git LFS](https://github.com/git-lfs/git-lfs/blob/main/docs/man/git-lfs-migrate.1.ronn).
### Removing objects from LFS
@@ -114,13 +114,9 @@ See the documentation on [File Locking](../../../user/project/file_lock.md).
## LFS objects in project archives
-> - Support for including Git LFS blobs inside [project source downloads](../../../user/project/repository/index.md) was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15079) in GitLab 13.5.
-> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/268409) in GitLab 13.6.
-> - Enabled on GitLab.com.
-> - Recommended for production use.
-
-WARNING:
-This feature might not be available to you. Check the **version history** note above for details.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15079) support for including Git LFS blobs inside [project source downloads](../../../user/project/repository/index.md) in GitLab 13.5 [with a flag](../../../administration/feature_flags.md) named `include_lfs_blobs_in_archive`. Disabled by default.
+> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46572) in GitLab 13.6.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62539) in GitLab 14.0. Feature flag `include_lfs_blobs_in_archive` removed.
Prior to GitLab 13.5, [project source
downloads](../../../user/project/repository/index.md) would include Git
diff --git a/doc/topics/git/troubleshooting_git.md b/doc/topics/git/troubleshooting_git.md
index ae1667376b0..f881826e74a 100644
--- a/doc/topics/git/troubleshooting_git.md
+++ b/doc/topics/git/troubleshooting_git.md
@@ -45,7 +45,7 @@ set to 50MB. The default is 1MB.
**If pushing over SSH**, first check your SSH configuration as 'Broken pipe'
errors can sometimes be caused by underlying issues with SSH (such as
authentication). Make sure that SSH is correctly configured by following the
-instructions in the [SSH troubleshooting](../../ssh/index.md#troubleshooting-ssh-connections) documentation.
+instructions in the [SSH troubleshooting](../../ssh/index.md#password-prompt-with-git-clone) documentation.
If you're a GitLab administrator with server access, you can also prevent
session timeouts by configuring SSH `keep-alive` on the client or the server.
@@ -110,6 +110,13 @@ ssh_exchange_identification: Connection closed by remote host
fatal: The remote end hung up unexpectedly
```
+or
+
+```plaintext
+kex_exchange_identification: Connection closed by remote host
+Connection closed by x.x.x.x port 22
+```
+
This error usually indicates that SSH daemon's `MaxStartups` value is throttling
SSH connections. This setting specifies the maximum number of concurrent, unauthenticated
connections to the SSH daemon. This affects users with proper authentication
diff --git a/doc/topics/gitlab_flow.md b/doc/topics/gitlab_flow.md
index e831c35a8ea..7675bba8d83 100644
--- a/doc/topics/gitlab_flow.md
+++ b/doc/topics/gitlab_flow.md
@@ -1,7 +1,7 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
disqus_identifier: 'https://docs.gitlab.com/ee/workflow/gitlab_flow.html'
---
@@ -47,9 +47,11 @@ For a video introduction of how this works in GitLab, see [GitLab Flow](https://
<!-- vale gitlab.Spelling = YES -->
-Git flow was one of the first proposals to use Git branches, and it has received a lot of attention.
-It suggests a `main` branch and a separate `develop` branch, as well as supporting branches for features, releases, and hotfixes.
-The development happens on the `develop` branch, moves to a release branch, and is finally merged into the `main` branch.
+Git flow was one of the first proposals to use Git branches, and it has received
+a lot of attention. It suggests a `main` branch and a separate `develop` branch,
+with supporting branches for features, releases, and hotfixes. The development
+happens on the `develop` branch, moves to a release branch, and is finally merged
+into the `main` branch.
Git flow is a well-defined standard, but its complexity introduces two problems.
The first problem is that developers must use the `develop` branch and not `main`. `main` is reserved for code that is released to production.
diff --git a/doc/topics/release_your_application.md b/doc/topics/release_your_application.md
index cbd7cfab720..3a0080fe21c 100644
--- a/doc/topics/release_your_application.md
+++ b/doc/topics/release_your_application.md
@@ -1,6 +1,6 @@
---
-stage:
-group:
+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
---
@@ -9,6 +9,58 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Deploy your application internally or to the public. Use
flags to release features incrementally.
-- [Environments and deployments](../ci/environments/index.md)
-- [Releases](../user/project/releases/index.md)
-- [Feature flags](../operations/feature_flags.md)
+## Deployments
+
+Deployment is the step of the software delivery process when your application gets deployed to its
+final, target infrastructure.
+
+### Deploy with Auto DevOps
+
+[Auto DevOps](autodevops/index.md) is an automated CI/CD-based workflow that supports the entire software
+supply chain: build, test, lint, package, deploy, secure, and monitor applications using GitLab CI/CD.
+It provides a set of ready-to-use templates that serve the vast majority of use cases.
+
+[Auto Deploy](autodevops/stages.md#auto-deploy) is the DevOps stage dedicated to software
+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).
+
+#### GitOps deployments **(PREMIUM)**
+
+With the [GitLab Agent](../user/clusters/agent/install/index.md), you can perform pull-based
+deployments using Kubernetes manifests. This provides a scalable, secure, and cloud-native
+approach to manage Kubernetes deployments.
+
+#### Deploy to Kubernetes with the CI/CD Tunnel
+
+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
+a secure and reliable connection between GitLab and your Kubernetes cluster.
+
+### Deploy to AWS with GitLab CI/CD
+
+GitLab provides Docker images that you can use to run AWS commands from GitLab CI/CD, and a template to
+facilitate [deployment to AWS](../ci/cloud_deployment). Moreover, Auto Deploy has built-in support
+for EC2 and ECS deployments.
+
+### General software deployment with GitLab CI/CD
+
+You can use GitLab CI/CD to target any type of infrastructure accessible by the GitLab Runner.
+[User and pre-defined environment variables](../ci/variables/index.md) and CI/CD templates
+support setting up a vast number of deployment strategies.
+
+## Environments
+
+To keep track of your deployments and gain insights into your infrastructure, we recommend
+connecting them to [a GitLab Environment](../ci/environments/index.md).
+
+## Releases
+
+Use GitLab [Releases](../user/project/releases/index.md) to plan, build, and deliver your applications.
+
+### Feature flags
+
+Use [feature flags](../operations/feature_flags.md) to control and strategically roullout application deployments.
diff --git a/doc/topics/set_up_organization.md b/doc/topics/set_up_organization.md
index 3758435d297..3f8a00f9981 100644
--- a/doc/topics/set_up_organization.md
+++ b/doc/topics/set_up_organization.md
@@ -1,6 +1,6 @@
---
-stage:
-group:
+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
---
diff --git a/doc/topics/use_gitlab.md b/doc/topics/use_gitlab.md
index f73e41c251b..a7189284fe6 100644
--- a/doc/topics/use_gitlab.md
+++ b/doc/topics/use_gitlab.md
@@ -1,6 +1,6 @@
---
-stage:
-group:
+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
---
diff --git a/doc/tutorials/index.md b/doc/tutorials/index.md
new file mode 100644
index 00000000000..1f866aeb889
--- /dev/null
+++ b/doc/tutorials/index.md
@@ -0,0 +1,123 @@
+---
+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
+---
+
+# Get started with GitLab tutorials
+
+These tutorials can help you learn how to use GitLab.
+
+## Find your way around GitLab
+
+Get to know the features of GitLab and where to find them so you can get up
+and running quickly.
+
+| Topic | Description | Good for beginners |
+|-------|-------------|--------------------|
+| [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}** |
+| [GitLab 201](https://gitlab.edcast.com/pathways/ECL-44010cf6-7a9c-4b9b-b684-fa08508a3252) | Go beyond the basics to learn more about using GitLab for your work. | |
+| Learn GitLab project | You might already have the **Learn GitLab** project, which has tutorial-style issues to help you learn GitLab. If not, download [this export file](https://gitlab.com/gitlab-org/gitlab/-/blob/master/vendor/project_templates/learn_gitlab_ultimate.tar.gz) and [import it to a new project](../user/project/settings/import_export.md#import-a-project-and-its-data). | |
+| [Productivity tips](https://about.gitlab.com/blog/2021/02/18/improve-your-gitlab-productivity-with-these-10-tips/) | Get tips to help make you a productive GitLab user. | |
+| <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Structure a multi-team organization](https://www.youtube.com/watch?v=KmASFwSap7c) (37m 37s) | Learn to use issues, milestones, epics, labels, and more to plan and manage your work. | |
+
+## Use Git
+
+GitLab is a Git-based platform, so understanding Git is important to get
+the most out of GitLab.
+
+| Topic | Description | Good for beginners |
+|-------|-------------|--------------------|
+| [Start using Git on the command line](../gitlab-basics/start-using-git.md) | Learn how to set up Git, clone repositories, and work with branches. | **{star}** |
+| [Git cheat sheet](https://about.gitlab.com/images/press/git-cheat-sheet.pdf) | Download a PDF of common Git commands. | |
+
+## Plan your work in projects
+
+Your work takes place in a project, from creating code, to planning,
+collaborating, and more.
+
+| Topic | Description | Good for beginners |
+|-------|-------------|--------------------|
+| [Create a project from a template](https://gitlab.com/projects/new#create_from_template) | For hands-on learning, select **Sample GitLab Project** and create a project with example issues and merge requests. | **{star}** |
+| [Migrate to GitLab](../user/project/import/index.md) | If you are coming to GitLab from another platform, you can import or convert your projects. | |
+
+## Use CI/CD pipelines
+
+CI/CD pipelines are used to automatically build, test, and deploy your code.
+
+| Topic | Description | Good for beginners |
+|-------|-------------|--------------------|
+| [Get started: Create a pipeline](../ci/quick_start/index.md) | Create a `.gitlab-ci.yml` file and start a pipeline. | **{star}** |
+| <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Get started: Learn about CI/CD](https://www.youtube.com/watch?v=sIegJaLy2ug) (9m 02s) | Learn about the `.gitlab-ci.yml` file and how it's used. | **{star}** |
+| <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [CI deep dive](https://www.youtube.com/watch?v=ZVUbmVac-m8&list=PL05JrBw4t0KorkxIFgZGnzzxjZRCGROt_&index=27) (22m 51s) | Take a closer look at pipelines and continuous integration concepts. | |
+| <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [CD deep dive](https://www.youtube.com/watch?v=Cn0rzND-Yjw&list=PL05JrBw4t0KorkxIFgZGnzzxjZRCGROt_&index=10) (47m 54s) | Learn about deploying in GitLab. | |
+| [Set up CI/CD in the cloud](../ci/examples/index.md#cicd-in-the-cloud) | Learn how to set up CI/CD in different cloud-based environments. | |
+| [Find CI/CD examples and templates](../ci/examples/index.md#cicd-examples) | Use these examples and templates to set up CI/CD for your use case. | |
+| <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Understand CI/CD rules](https://www.youtube.com/watch?v=QjQc-zeL16Q) (8m 56s) | Learn more about how to use CI/CD rules. | |
+
+## Configure your applications and infrastructure
+
+Use GitLab configuration features to reduce the effort needed to
+configure the infrastructure for your application.
+
+| Topic | Description | Good for beginners |
+|-------|-------------|--------------------|
+| [Connect with a Kubernetes cluster](https://about.gitlab.com/blog/2021/11/18/gitops-with-gitlab-connecting-the-cluster/) | Connect a Kubernetes cluster with GitLab for pull and push based deployments and security integrations. | |
+| [Use Auto DevOps to deploy an application](../topics/autodevops/quick_start_guide.md) | Deploy an application to Google Kubernetes Engine (GKE). | |
+
+## Publish a static website
+
+Use GitLab Pages to publish a static website directly from your project.
+
+| Topic | Description | Good for beginners |
+|-------|-------------|--------------------|
+| [Create a Pages website from a CI/CD template](../user/project/pages/getting_started/pages_ci_cd_template.md) | Quickly generate a Pages website for your project using a CI/CD template for a popular Static Site Generator (SSG). | **{star}** |
+| [Create a Pages website from scratch](../user/project/pages/getting_started/pages_from_scratch.md) | Create all the components of a Pages website from a blank project. | |
+
+## Secure your application
+
+GitLab can check your application for security vulnerabilities.
+
+| Topic | Description | Good for beginners |
+|-------|-------------|--------------------|
+| [Set up dependency scanning](https://about.gitlab.com/blog/2021/01/14/try-dependency-scanning/) | Try out dependency scanning, which checks for known vulnerabilities in dependencies. | **{star}** |
+
+## Work with a self-managed instance
+
+If you're an administrator of a self-managed instance of GitLab, these tutorials
+can help you manage and configure your instance.
+
+| Topic | Description | Good for beginners |
+|-------|-------------|--------------------|
+| [Install GitLab](../install/index.md) | Install GitLab according to your requirements.| |
+| [Get started administering GitLab](../administration/get_started.md) | Configure your organization and its authentication, then secure, monitor, and back up GitLab. | |
+| [Secure your instance](https://about.gitlab.com/blog/2020/05/20/gitlab-instance-security-best-practices/) | Implement security features for your instance. | |
+
+## Integrate with GitLab
+
+GitLab [integrates](../integration/index.md) with a number of third-party services,
+enabling you to work with those services directly from GitLab.
+
+| Topic | Description | Good for beginners |
+|-------|-------------|--------------------|
+| [Integrate with Jira](https://about.gitlab.com/blog/2021/04/12/gitlab-jira-integration-selfmanaged/) | Configure the Jira integration, so you can work with Jira issues from GitLab. | |
+| [Integrate with Gitpod](https://about.gitlab.com/blog/2021/07/19/teams-gitpod-integration-gitlab-speed-up-development/) | Integrate with Gitpod, to help speed up your development. | |
+
+## Find more tutorial content
+
+If you're learning about GitLab, here are some ways you can find more tutorial
+content:
+
+- Find learning tracks and certification options at [GitLab Learn](https://about.gitlab.com/learn/).
+ GitLab learning platform login required (email and password for non-GitLab team members).
+ For more information, see [First time login details](https://about.gitlab.com/handbook/people-group/learning-and-development/gitlab-learn/user/#first-time-login-to-gitlab-learn).
+
+- Find recent tutorials on the GitLab blog by [searching by the `tutorial` tag](https://about.gitlab.com/blog/tags.html#tutorial).
+
+- Browse the **Learn@GitLab** [playlist on YouTube](https://www.youtube.com/playlist?list=PLFGfElNsQthYDx0A_FaNNfUm9NHsK6zED)
+ to find video tutorials.
+
+If you find an article, video, or other resource that would be a
+great addition to this page, add it in a [merge request](../development/documentation/index.md).
diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md
index 8bf14bc2dce..7388f4baf83 100644
--- a/doc/update/deprecations.md
+++ b/doc/update/deprecations.md
@@ -4,7 +4,7 @@ group: none
info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-development-guidelines"
---
-# Deprecated feature removal schedule
+# Deprecations by milestone
DISCLAIMER:
This page contains information related to upcoming products, features, and functionality.
@@ -36,68 +36,118 @@ For deprecation reviewers (Technical Writers only):
https://about.gitlab.com/handbook/marketing/blog/release-posts/#update-the-deprecations-doc
-->
-## 14.5
-
-### Rename Task Runner pod to Toolbox
-
-The Task Runner pod is used to execute periodic housekeeping tasks within the GitLab application and is often confused with the GitLab Runner. Thus, [Task Runner will be renamed to Toolbox](https://gitlab.com/groups/gitlab-org/charts/-/epics/25).
+## 14.0
-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`.
+### NFS for Git repository storage deprecated
-Announced: 2021-08-22
-Planned removal: 2021-11-22
+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.
-## 14.6
+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.
-### Release CLI be distributed as a generic package
+Gitaly Cluster offers tremendous benefits for our customers such as:
-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.
+- [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).
-Announced: 2021-08-22
-Planned removal: 2021-12-22
+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).
-## 14.8
+**Planned removal milestone: 15.0 (2022-05-22)**
-### openSUSE Leap 15.2 packages
+## 14.2
-Distribution support and security updates for openSUSE Leap 15.2 are [ending December 2021](https://en.opensuse.org/Lifetime#openSUSE_Leap).
+### Release CLI distributed as a generic package
-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 [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.
-Announced: 2021-11-22
-Planned removal: 2022-02-22
+**Planned removal milestone: 14.6 (2021-12-22)**
-## 15.0
+### Rename Task Runner pod to Toolbox
-### API: `stale` status returned instead of `offline` or `not_connected`
+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).
-A breaking change will occur for the Runner [API](https://docs.gitlab.com/ee/api/runners.html#runners-api) endpoints in 15.0.
+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`.
-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.5 (2021-11-22)**
-Announced: 2021-12-22
-Planned removal: 2022-05-22
+## 14.3
### Audit events for repository push events
+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.
+
Audit events for [repository events](https://docs.gitlab.com/ee/administration/audit_events.html#repository-push) are now deprecated and will be removed in GitLab 15.0.
These events have always been disabled by default and had to be manually enabled with a
feature flag. Enabling them can cause too many events to be generated which can
dramatically slow down GitLab instances. For this reason, they are being removed.
-Announced: 2021-09-22
-Planned removal: 2022-05-22
+**Planned removal milestone: 15.0 (2022-05-22)**
-### CI/CD job name length limit
+### GitLab Serverless
-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.
+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.
+
+[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.
-Announced: 2021-12-22
-Planned removal: 2022-05-22
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+### Legacy database configuration
+
+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.
+
+The syntax of [GitLabs database](https://docs.gitlab.com/omnibus/settings/database.html)
+configuration located in `database.yml` is changing and the legacy format is deprecated. The legacy format
+supported using a single PostgreSQL adapter, whereas the new format is changing to support multiple databases. The `main:` database needs to be defined as a first configuration item.
+
+This deprecation mainly impacts users compiling GitLab from source because Omnibus will handle this configuration automatically.
+
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+### OmniAuth Kerberos gem
+
+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.
+
+The `omniauth-kerberos` gem will be removed in our next major release, GitLab 15.0.
+
+This gem has not been maintained and has very little usage. We therefore plan to remove support for this authentication method and recommend using the Kerberos [SPNEGO](https://en.wikipedia.org/wiki/SPNEGO) integration instead. You can follow the [upgrade instructions](https://docs.gitlab.com/ee/integration/kerberos.html#upgrading-from-password-based-to-ticket-based-kerberos-sign-ins) to upgrade from the `omniauth-kerberos` integration to the supported one.
+
+Note that we are not deprecating the Kerberos SPNEGO integration, only the old password-based Kerberos integration.
+
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+## 14.5
### Certificate-based integration with Kubernetes
+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.
+
[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 not yet planned and we will communicate
more details as they emerge. The certificate-based integration will continue to receive security and
@@ -108,227 +158,561 @@ For updates and details, follow this [epic](https://gitlab.com/groups/gitlab-org
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.
-Announced: 2021-11-15
-Planned removal: 2022-05-22
+**Planned removal milestone: 15.0 (2022-05-22)**
### Converting an instance (shared) runner to a project (specific) runner is deprecated
+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.
+
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.
-Announced: 2021-11-22
-Planned removal: 2022-05-22
+**Planned removal milestone: 15.0 (2022-05-22)**
### Deprecate `Versions` on base `PackageType`
+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.
+
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`.
-Announced: 2021-11-22
-Planned removal: 2022-05-22
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+### Deprecate support for SLES 12 SP2
+
+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.
+
+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: 15.0 (2022-05-22)**
+
+### Known host required for GitLab Runner SSH executor
+
+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.
+
+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)**
+
+### Must explicitly assign `AuthenticationType` for `[runners.cache.s3]`
+
+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.
+
+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.
+
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+### Package pipelines in API payload is paginated
+
+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.
+
+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 contain `paused`
+
+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.
+
+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
+`active` to be `false` instead. When checking if a runner is `active`, check if `active` is `true`.
+
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+### Removal of `defaultMergeCommitMessageWithDescription` GraphQL API field
+
+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.
+
+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)**
+
+### Removal of `promote-db` command from `gitlab-ctl`
+
+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.
+
+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)**
+
+### Removal of `promote-to-primary-node` command from `gitlab-ctl`
+
+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.
+
+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.
+
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+### Remove the `:dependency_proxy_for_private_groups` feature flag
+
+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.
+
+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.
+
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+### Remove the `pipelines` field from the `version` field
+
+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.
+
+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.
+
+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)**
+
+### Update to the Container Registry group-level API
+
+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.
+
+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.
+
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+### Value Stream Analytics filtering calculation change
+
+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.
+
+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.
+
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+### openSUSE Leap 15.2 packages
+
+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.
+
+**Planned removal milestone: 14.8 (2022-02-22)**
+
+## 14.6
+
+### API: `stale` status returned instead of `offline` or `not_connected`
+
+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.
+
+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.
+
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+### CI/CD job name length limit
+
+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.
+
+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)**
### Deprecate `pipelines` fields in the Package GraphQL types
+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.
+
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).
-Announced: 2021-12-22
-Planned removal: 2022-05-22
+**Planned removal milestone: 15.0 (2022-05-22)**
### Deprecate legacy approval status names from License Compliance API
-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.
+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.
-Announced: 2021-12-22
-Planned removal: 2022-05-22
+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.
-### Deprecate support for SLES 12 SP2
-
-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.
+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.
-Announced: 2021-11-22
-Planned removal: 2022-05-22
+**Planned removal milestone: 15.0 (2022-05-22)**
### Deprecation of Runner status `not_connected` API value
+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.
+
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.
-Announced: 2021-12-22
-Planned removal: 2022-05-22
+**Planned removal milestone: 15.0 (2022-05-22)**
### Deprecation of bundler-audit Dependency Scanning tool
-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.
+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.
+
+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.
-Announced: 2021-12-22
-Planned removal: 2022-05-22
+**Planned removal milestone: 15.0 (2022-05-22)**
-### GitLab Serverless
+### Remove `type` and `types` keyword in CI/CD configuration
-[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.
+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.
-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 `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.
-Announced: 2021-09-22
-Planned removal: 2022-05-22
+**Planned removal milestone: 15.0 (2022-05-22)**
-### Known host required for GitLab Runner SSH executor
+### apiFuzzingCiConfigurationCreate GraphQL mutation
-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.
+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.
-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.
+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.
-Announced: 2021-11-22
-Planned removal: 2022-05-22
+**Planned removal milestone: 15.0 (2022-05-22)**
-### Legacy database configuration
+## 14.7
-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.
+### Container scanning schemas below 14.0.0
-This deprecation mainly impacts users compiling GitLab from source because Omnibus will handle this configuration automatically.
+[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.
-Announced: 2021-09-22
-Planned removal: 2022-05-22
+Third-party tools that [integrate with GitLab by outputting a container scanning security report](https://docs.gitlab.com/ee/development/integrations/secure.html#report)
+as a pipeline job artifact are affected. You must ensure that all output reports adhere to the correct schema with a minimum version of 14.0.0. Reports with a lower version or that fail to validate against the declared schema version will not be processed, and vulnerability findings will not display in MRs, pipelines, or Vulnerability Reports.
-### Must explicitly assign `AuthenticationType` for `[runners.cache.s3]`
+To help with the transition, from GitLab 14.10, non-compliant reports will display a
+[warning](https://gitlab.com/gitlab-org/gitlab/-/issues/335789#note_672853791)
+in the Vulnerability Report.
-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`.
+**Planned removal milestone: 15.0 (2022-05-22)**
-Prior to 14.5, if you did not define the `AuthenticationType`, GitLab Runner chose a type for you.
+### Coverage guided fuzzing schemas below 14.0.0
-Announced: 2021-11-22
-Planned removal: 2022-05-22
+[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.
-### NFS for Git repository storage deprecated
+Third-party tools that [integrate with GitLab by outputting a coverage guided fuzzing security report](https://docs.gitlab.com/ee/development/integrations/secure.html#report)
+as a pipeline job artifact are affected. You must ensure that all output reports adhere to the correct
+schema with a minimum version of 14.0.0. Any reports with a lower version or that fail to validate
+against the declared schema version will not be processed, and vulnerability
+findings will not display in MRs, pipelines, or Vulnerability Reports.
-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.
+To help with the transition, from GitLab 14.10, non-compliant reports will display a
+[warning](https://gitlab.com/gitlab-org/gitlab/-/issues/335789#note_672853791)
+in the Vulnerability Report.
-Gitaly Cluster offers tremendous benefits for our customers such as:
+**Planned removal milestone: 15.0 (2022-05-22)**
-- [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).
+### DAST schemas below 14.0.0
-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).
+[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.
-Announced: 2021-06-22
-Planned removal: 2022-05-22
+Third-party tools that [integrate with GitLab by outputting a DAST security report](https://docs.gitlab.com/ee/development/integrations/secure.html#report)
+as a pipeline job artifact are affected. You must ensure that all output reports adhere to the correct
+schema with a minimum version of 14.0.0. Reports with a lower version or that fail to validate
+against the declared schema version will not be processed, and vulnerability
+findings will not display in MRs, pipelines, or Vulnerability Reports.
-### OmniAuth Kerberos gem
+To help with the transition, from GitLab 14.10, non-compliant reports will cause a
+[warning to be displayed](https://gitlab.com/gitlab-org/gitlab/-/issues/335789#note_672853791)
+in the Vulnerability Report.
-The `omniauth-kerberos` gem will be removed in our next major release, GitLab 15.0.
+**Planned removal milestone: 15.0 (2022-05-22)**
-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.
+### Dependency scanning schemas below 14.0.0
-Note that we are not deprecating the Kerberos SPNEGO integration, only the old password-based Kerberos integration.
+[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.
-Announced: 2021-09-22
-Planned removal: 2022-05-22
+Third-party tools that [integrate with GitLab by outputting a Dependency scanning security report](https://docs.gitlab.com/ee/development/integrations/secure.html#report)
+as a pipeline job artifact are affected. You must ensure that all output reports adhere to the correct
+schema with a minimum version of 14.0.0. Reports with a lower version or that fail to validate
+against the declared schema version will not be processed, and vulnerability
+findings will not display in MRs, pipelines, or Vulnerability Reports.
-### Package pipelines in API payload is paginated
+To help with the transition, from GitLab 14.10, non-compliant reports will cause a
+[warning to be displayed](https://gitlab.com/gitlab-org/gitlab/-/issues/335789#note_672853791)
+in the Vulnerability Report.
-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.
+**Planned removal milestone: 15.0 (2022-05-22)**
-In milestone 15.0, we will remove the `pipelines` attribute from the API response.
+### Enforced validation of security report schemas
-Announced: 2021-11-22
-Planned removal: 2022-05-22
+[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.
-### REST API Runner will not contain `paused`
+Security tools that [integrate with GitLab by outputting security reports](https://docs.gitlab.com/ee/development/integrations/secure.html#report)
+as pipeline job artifacts are affected. You must ensure that all output reports adhere to the correct
+schema with a minimum version of 14.0.0. Reports with a lower version or that fail to validate
+against the declared schema version will not be processed, and vulnerability
+findings will not display in MRs, pipelines, or Vulnerability Reports.
-The GitLab Runner REST and GraphQL API endpoints will not return `paused` or `active` as a status in GitLab 15.0.
+To help with the transition, from GitLab 14.10, non-compliant reports will display a
+[warning](https://gitlab.com/gitlab-org/gitlab/-/issues/335789#note_672853791)
+in the Vulnerability Report.
-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.
+**Planned removal milestone: 15.0 (2022-05-22)**
-When checking if a runner is `paused`, API users are advised to check the boolean attribute
-`active` to be `false` instead. When checking if a runner is `active`, check if `active` is `true`.
+### Godep support in License Compliance
-Announced: 2021-11-22
-Planned removal: 2022-05-22
+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
+and will remove it in GitLab 15.0
-### Removal of `defaultMergeCommitMessageWithDescription` GraphQL API field
+**Planned removal milestone: 15.0 (2022-05-22)**
-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.
+### Logging in GitLab
-Announced: 2021-11-22
-Planned removal: 2022-05-22
+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.
-### Removal of `promote-db` command from `gitlab-ctl`
+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).
-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)**
-Announced: 2021-11-22
-Planned removal: 2022-05-22
+### Monitor performance metrics through Prometheus
-### Removal of `promote-to-primary-node` command from `gitlab-ctl`
+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.
-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.
+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.
-Announced: 2021-11-22
-Planned removal: 2022-05-22
+**Planned removal milestone: 15.0 (2022-05-22)**
-### Remove `type` and `types` keyword in CI/CD configuration
+### Pseudonymizer
-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 Pseudonymizer feature is generally unused,
+can cause production issues with large databases,
+and can interfere with object storage development.
+It is now considered deprecated, and will be removed in GitLab 15.0.
-Announced: 2021-12-22
-Planned removal: 2022-05-22
+**Planned removal milestone: 15.0 (2022-05-22)**
-### Remove the `:dependency_proxy_for_private_groups` feature flag
+### Removal of Static Site Editor
-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 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.
-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)**
-Announced: 2021-11-22
-Planned removal: 2022-05-22
+### Removal of `artifacts:report:cobertura` keyword
-### Remove the `pipelines` field from the `version` field
+Currently, test coverage visualizations in GitLab only support Cobertura reports. Starting 15.0, the
+`artifacts:report:cobertura` keyword will be replaced by
+[`artifacts:reports:coverage_report`](https://gitlab.com/gitlab-org/gitlab/-/issues/344533). Cobertura will be the
+only supported report file in 15.0, but this is the first step towards GitLab supporting other report types.
-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:
+**Planned removal milestone: 15.0 (2022-05-22)**
-- 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.
+### SAST schemas below 14.0.0
-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.
+[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.
-Announced: 2021-11-22
-Planned removal: 2022-05-22
+Third-party tools that [integrate with GitLab by outputting a SAST security report](https://docs.gitlab.com/ee/development/integrations/secure.html#report)
+as a pipeline job artifact are affected. You must ensure that all output reports adhere to the correct
+schema with a minimum version of 14.0.0. Reports with a lower version or that fail to validate
+against the declared schema version will not be processed, and vulnerability
+findings will not display in MRs, pipelines, or Vulnerability Reports.
-### Update to the Container Registry group-level API
+To help with the transition, from GitLab 14.10, non-compliant reports will display a
+[warning](https://gitlab.com/gitlab-org/gitlab/-/issues/335789#note_672853791)
+in the Vulnerability Report.
-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).
+**Planned removal milestone: 15.0 (2022-05-22)**
-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.
+### Secret detection schemas below 14.0.0
-Announced: 2021-11-22
-Planned removal: 2022-05-22
+[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.
-### Value Stream Analytics filtering calculation change
+Third-party tools that [integrate with GitLab by outputting a Secret detection security report](https://docs.gitlab.com/ee/development/integrations/secure.html#report)
+as a pipeline job artifact are affected. You must ensure that all output reports adhere to the correct
+schema with a minimum version of 14.0.0. Reports with a lower version or that fail to validate
+against the declared schema version will not be processed, and vulnerability
+findings will not display in MRs, pipelines, or Vulnerability Reports.
-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.
+To help with the transition, from GitLab 14.10, non-compliant reports will display a
+[warning](https://gitlab.com/gitlab-org/gitlab/-/issues/335789#note_672853791)
+in the Vulnerability Report.
-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)**
-Announced: 2021-11-22
-Planned removal: 2022-05-22
+### Sidekiq metrics and health checks configuration
-### apiFuzzingCiConfigurationCreate GraphQL mutation
+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.
-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.
+Exporting Sidekiq metrics and health checks using a single process and port is deprecated.
+Support will be removed in 15.0.
+
+We have updated Sidekiq to export [metrics and health checks from two separate processes](https://gitlab.com/groups/gitlab-org/-/epics/6409)
+to improve stability and availability and prevent data loss in edge cases.
+As those are two separate servers, a configuration change will be required in 15.0
+to explicitly set separate ports for metrics and health-checks.
+The newly introduced settings for `sidekiq['health_checks_*']`
+should always be set in `gitlab.rb`.
+For more information, check the documentation for [configuring Sidekiq](https://docs.gitlab.com/ee/administration/sidekiq.html).
+
+These changes also require updates in either Prometheus to scrape the new endpoint or k8s health-checks to target the new
+health-check port to work properly, otherwise either metrics or health-checks will disappear.
+
+For the deprecation period those settings are optional
+and GitLab will default the Sidekiq health-checks port to the same port as `sidekiq_exporter`
+and only run one server (not changing the current behaviour).
+Only if they are both set and a different port is provided, a separate metrics server will spin up
+to serve the Sidekiq metrics, similar to the way Sidekiq will behave in 15.0.
+
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+### Tracing in GitLab
+
+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.
+
+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).
+
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+### merged_by API field
+
+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.
+
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+## 14.8
+
+### `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.
-Announced: 2021-12-22
-Planned removal: 2022-05-22
+**Planned removal milestone: 15.0 (2022-06-22)**
diff --git a/doc/update/index.md b/doc/update/index.md
index 98dfee04a41..3a17d3c01d7 100644
--- a/doc/update/index.md
+++ b/doc/update/index.md
@@ -85,7 +85,7 @@ Certain releases may require different migrations to be
finished before you update to the newer version.
[Batched migrations](#batched-background-migrations) are a migration type available in GitLab 14.0 and later.
-Background migrations and batched migrations not the same, so you should check that both are
+Background migrations and batched migrations are not the same, so you should check that both are
complete before updating.
Decrease the time required to complete these migrations by increasing the number of
@@ -98,7 +98,7 @@ that can process jobs in the `background_migration` queue.
```shell
sudo gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
-sudo gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.pending'
+sudo gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigrationJob.pending'
```
**For installations from source:**
@@ -106,7 +106,7 @@ sudo gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.pending
```shell
cd /home/git/gitlab
sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
-sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::BackgroundMigration.pending'
+sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::Database::BackgroundMigrationJob.pending'
```
### Batched background migrations
@@ -193,9 +193,9 @@ To address the above two scenario's, it is advised to do the following prior to
1. Wait until all jobs are finished.
1. Upgrade GitLab.
-## Checking for pending Advanced Search migrations
+## Checking for pending Advanced Search migrations **(PREMIUM SELF)**
-This section is only applicable if you have enabled the [Elasticsearch integration](../integration/elasticsearch.md).
+This section is only applicable if you have enabled the [Elasticsearch integration](../integration/elasticsearch.md) **(PREMIUM SELF)**.
Major releases require all [Advanced Search migrations](../integration/elasticsearch.md#advanced-search-migrations)
to be finished from the most recent minor release in your current version
@@ -239,14 +239,12 @@ It is required to follow the following upgrade steps to ensure a successful *maj
Identify a [supported upgrade path](#upgrade-paths).
-It's also important to ensure that any background migrations have been fully completed
-before upgrading to a new major version. To see the current size of the `background_migration` queue,
-[Check for background migrations before upgrading](#checking-for-background-migrations-before-upgrading).
+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.
-If you have enabled the [Elasticsearch integration](../integration/elasticsearch.md), then ensure
-all Advanced Search migrations are completed in the last minor version within
-your current version. Be sure to
-[check for pending Advanced Search migrations](#checking-for-pending-advanced-search-migrations)
+If you have enabled the [Elasticsearch integration](../integration/elasticsearch.md) **(PREMIUM SELF)**, then
+[ensure all Advanced Search migrations are completed](#checking-for-pending-advanced-search-migrations) in the last minor version within
+your current version
before proceeding with the major version upgrade.
If your GitLab instance has any runners associated with it, it is very
@@ -539,6 +537,31 @@ See [Maintenance mode issue in GitLab 13.9 to 14.4](#maintenance-mode-issue-in-g
- See [Maintenance mode issue in GitLab 13.9 to 14.4](#maintenance-mode-issue-in-gitlab-139-to-144).
+- For GitLab Enterprise Edition customers, we noticed an issue when [subscription expiration is upcoming, and you create new subgroups and projects](https://gitlab.com/gitlab-org/gitlab/-/issues/322546). If you fall under that category and get 500 errors, you can work around this issue:
+
+ 1. SSH into you GitLab server, and open a Rails console:
+
+ ```shell
+ sudo gitlab-rails console
+ ```
+
+ 1. Disable the following features:
+
+ ```ruby
+ Feature.disable(:subscribable_subscription_banner)
+ Feature.disable(:subscribable_license_banner)
+ ```
+
+ 1. Restart Puma or Unicorn:
+
+ ```shell
+ #For installations using Puma
+ sudo gitlab-ctl restart puma
+
+ #For installations using Unicorn
+ sudo gitlab-ctl restart unicorn
+ ```
+
### 13.8.8
GitLab 13.8 includes a background migration to address [an issue with duplicate service records](https://gitlab.com/gitlab-org/gitlab/-/issues/290008). If duplicate services are present, this background migration must complete before a unique index is applied to the services table, which was [introduced in GitLab 13.9](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52563). Upgrades from GitLab 13.8 and earlier to later versions must include an intermediate upgrade to GitLab 13.8.8 and [must wait until the background migrations complete](#checking-for-background-migrations-before-upgrading) before proceeding.
diff --git a/doc/update/plan_your_upgrade.md b/doc/update/plan_your_upgrade.md
index 98549cc136a..665d2f6783e 100644
--- a/doc/update/plan_your_upgrade.md
+++ b/doc/update/plan_your_upgrade.md
@@ -35,7 +35,7 @@ to ensure the major components of GitLab are working:
sudo gitlab-rake gitlab:check
```
-1. Confirm that encrypted database values [can be decrypted](../administration/raketasks/doctor.md#verify-database-values-can-be-decrypted-using-the-current-secrets):
+1. Confirm that encrypted database values [can be decrypted](../administration/raketasks/check.md#verify-database-values-can-be-decrypted-using-the-current-secrets):
```shell
sudo gitlab-rake gitlab:doctor:secrets
@@ -60,6 +60,16 @@ to ensure the major components of GitLab are working:
1. If using Elasticsearch, verify that searches are successful.
+1. If you are using [Reply by Email](../administration/reply_by_email.md) or [Service Desk](../user/project/service_desk.md),
+ manually install the latest version of `gitlab-mail_room`:
+
+ ```shell
+ gem install gitlab-mail_room
+ ```
+
+ NOTE: This step is necessary to avoid thread deadlocks and to support the latest MailRoom features. See
+ [this explanation](../development/emails.md#mailroom-gem-updates) for more details.
+
If in any case something goes wrong, see [how to troubleshoot](#troubleshooting).
## Rollback plan
diff --git a/doc/update/removals.md b/doc/update/removals.md
new file mode 100644
index 00000000000..94ce815a110
--- /dev/null
+++ b/doc/update/removals.md
@@ -0,0 +1,390 @@
+---
+stage: none
+group: none
+info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-development-guidelines"
+---
+
+# Removals by milestone
+
+<!-- vale off -->
+
+<!--
+DO NOT EDIT THIS PAGE DIRECTLY
+
+This page is automatically generated from the YAML files in `/data/removals` by the rake task
+located at `lib/tasks/gitlab/docs/compile_removals.rake`.
+
+For removal authors (usually Product Managers and Engineering Managers):
+
+- To add a removal, use the example.yml file in `/data/removals/templates` as a template.
+- For more information about authoring removals, check the the removal item guidance:
+ https://about.gitlab.com/handbook/marketing/blog/release-posts/#creating-a-removal-entry
+
+For removal reviewers (Technical Writers only):
+
+- To update the removal doc, run: `bin/rake gitlab:docs:compile_removals`
+- To verify the removals doc is up to date, run: `bin/rake gitlab:docs:check_removals`
+- For more information about updating the removal doc, see the removal doc update guidance:
+ https://about.gitlab.com/handbook/marketing/blog/release-posts/#update-the-removals-doc
+-->
+
+## 14.0
+
+### Breaking changes to Terraform CI template
+
+GitLab 14.0 renews the Terraform CI template to the latest version. The new template is set up for the GitLab Managed Terraform state, with a dependency on the GitLab `terraform-images` image, to provide a good user experience around GitLab's Infrastructure-as-Code features.
+
+The current stable and latest templates are not compatible, and the current latest template becomes the stable template beginning with GitLab 14.0, your Terraform pipeline might encounter an unexpected failure if you run a custom `init` job.
+
+### Code Quality RuboCop support changed
+
+By default, the Code Quality feature has not provided support for Ruby 2.6+ if you're using the Code Quality template. To better support the latest versions of Ruby, the default RuboCop version is updated to add support for Ruby 2.4 through 3.0. As a result, support for Ruby 2.1, 2.2, and 2.3 is removed. You can re-enable support for older versions by [customizing your configuration](https://docs.gitlab.com/ee/user/project/merge_requests/code_quality.html#rubocop-errors).
+
+Relevant Issue: [Default `codeclimate-rubocop` engine does not support Ruby 2.6+](https://gitlab.com/gitlab-org/ci-cd/codequality/-/issues/28)
+
+### Container Scanning Engine Clair
+
+Clair, the default container scanning engine, was deprecated in GitLab 13.9 and is removed from GitLab 14.0 and replaced by Trivy. We advise customers who are customizing variables for their container scanning job to [follow these instructions](https://docs.gitlab.com/ee/user/application_security/container_scanning/#change-scanners) to ensure that their container scanning jobs continue to work.
+
+### DAST environment variable renaming and removal
+
+GitLab 13.8 renamed multiple environment variables to support their broader usage in different workflows. In GitLab 14.0, the old variables have been permanently removed and will no longer work. Any configurations using these variables must be updated to the new variable names. Any scans using these variables in GitLab 14.0 and later will fail to be configured correctly. These variables are:
+
+- `DAST_AUTH_EXCLUDE_URLS` becomes `DAST_EXCLUDE_URLS`.
+- `AUTH_EXCLUDE_URLS` becomes `DAST_EXCLUDE_URLS`.
+- `AUTH_USERNAME` becomes `DAST_USERNAME`.
+- `AUTH_PASSWORD` becomes `DAST_PASSWORD`.
+- `AUTH_USERNAME_FIELD` becomes `DAST_USERNAME_FIELD`.
+- `AUTH_PASSWORD_FIELD` becomes `DAST_PASSWORD_FIELD`.
+- `DAST_ZAP_USE_AJAX_SPIDER` will now be `DAST_USE_AJAX_SPIDER`.
+- `DAST_FULL_SCAN_DOMAIN_VALIDATION_REQUIRED` will be removed, since the feature is being removed.
+
+### Default Browser Performance testing job renamed in GitLab 14.0
+
+Browser Performance Testing has run in a job named `performance` by default. With the introduction of [Load Performance Testing](https://docs.gitlab.com/ee/user/project/merge_requests/load_performance_testing.html) in GitLab 13.2, this naming could be confusing. To make it clear which job is running [Browser Performance Testing](https://docs.gitlab.com/ee/user/project/merge_requests/browser_performance_testing.html), the default job name is changed from `performance` to `browser_performance` in the template in GitLab 14.0.
+
+Relevant Issue: [Rename default Browser Performance Testing job](https://gitlab.com/gitlab-org/gitlab/-/issues/225914)
+
+### Default DAST spider begins crawling at target URL
+
+In GitLab 14.0, DAST has removed the current method of resetting the scan to the hostname when starting to spider. Prior to GitLab 14.0, the spider would not begin at the specified target path for the URL but would instead reset the URL to begin crawling at the host root. GitLab 14.0 changes the default for the new variable `DAST_SPIDER_START_AT_HOST` to `false` to better support users' intention of beginning spidering and scanning at the specified target URL, rather than the host root URL. This change has an added benefit: scans can take less time, if the specified path does not contain links to the entire site. This enables easier scanning of smaller sections of an application, rather than crawling the entire app during every scan.
+
+### Default branch name for new repositories now `main`
+
+Every Git repository has an initial branch, which is named `master` by default. It's the first branch to be created automatically when you create a new repository. Future [Git versions](https://lore.kernel.org/git/pull.656.v4.git.1593009996.gitgitgadget@gmail.com/) will change the default branch name in Git from `master` to `main`. In coordination with the Git project and the broader community, [GitLab has changed the default branch name](https://gitlab.com/gitlab-org/gitlab/-/issues/223789) for new projects on both our SaaS (GitLab.com) and self-managed offerings starting with GitLab 14.0. This will not affect existing projects.
+
+GitLab has already introduced changes that allow you to change the default branch name both at the [instance level](https://docs.gitlab.com/ee/user/project/repository/branches/default.html#instance-level-custom-initial-branch-name) (for self-managed users) and at the [group level](https://docs.gitlab.com/ee/user/group/#use-a-custom-name-for-the-initial-branch) (for both SaaS and self-managed users). We encourage you to make use of these features to set default branch names on new projects.
+
+For more information, check out our [blog post](https://about.gitlab.com/blog/2021/03/10/new-git-default-branch-name/).
+
+### Deprecated GraphQL fields have been removed
+
+In accordance with our [GraphQL deprecation and removal process](https://docs.gitlab.com/ee/api/graphql/#deprecation-process), the following fields that were deprecated prior to 13.7 are [fully removed in 14.0](https://gitlab.com/gitlab-org/gitlab/-/issues/267966):
+
+- `Mutations::Todos::MarkAllDone`, `Mutations::Todos::RestoreMany` - `:updated_ids`
+- `Mutations::DastScannerProfiles::Create`, `Types::DastScannerProfileType` - `:global_id`
+- `Types::SnippetType` - `:blob`
+- `EE::Types::GroupType`, `EE::Types::QueryType` - `:vulnerabilities_count_by_day_and_severity`
+- `DeprecatedMutations (concern**)` - `AddAwardEmoji`, `RemoveAwardEmoji`, `ToggleAwardEmoji`
+- `EE::Types::DeprecatedMutations (concern***)` - `Mutations::Pipelines::RunDastScan`, `Mutations::Vulnerabilities::Dismiss`, `Mutations::Vulnerabilities::RevertToDetected`
+
+### Deprecations for Dependency Scanning
+
+As mentioned in [13.9](https://about.gitlab.com/releases/2021/02/22/gitlab-13-9-released/#deprecations-for-dependency-scanning) and [this blog post](https://about.gitlab.com/blog/2021/02/08/composition-analysis-14-deprecations-and-removals/) several removals for Dependency Scanning take effect.
+
+Previously, to exclude a DS analyzer, you needed to remove it from the default list of analyzers, and use that to set the `DS_DEFAULT_ANALYZERS` variable in your project’s CI template. We determined it should be easier to avoid running a particular analyzer without losing the benefit of newly added analyzers. As a result, we ask you to migrate from `DS_DEFAULT_ANALYZERS` to `DS_EXCLUDED_ANALYZERS` when it is available. Read about it in [issue #287691](https://gitlab.com/gitlab-org/gitlab/-/issues/287691).
+
+Previously, to prevent the Gemnasium analyzers to fetch the advisory database at runtime, you needed to set the `GEMNASIUM_DB_UPDATE` variable. However, this is not documented properly, and its naming is inconsistent with the equivalent `BUNDLER_AUDIT_UPDATE_DISABLED` variable. As a result, we ask you to migrate from `GEMNASIUM_DB_UPDATE` to `GEMNASIUM_UPDATE_DISABLED` when it is available. Read about it in [issue #215483](https://gitlab.com/gitlab-org/gitlab/-/issues/215483).
+
+### External Pipeline Validation Service Code Changes
+
+For self-managed instances using the experimental [external pipeline validation service](https://docs.gitlab.com/ee/administration/external_pipeline_validation.html), the range of error codes GitLab accepts will be reduced. Currently, pipelines are invalidated when the validation service returns a response code from `400` to `499`. In GitLab 14.0 and later, pipelines will be invalidated for the `406: Not Accepted` response code only.
+
+### Geo Foreign Data Wrapper settings removed
+
+As [announced in GitLab 13.3](https://about.gitlab.com/releases/2020/08/22/gitlab-13-3-released/#geo-foreign-data-wrapper-settings-deprecated), the following configuration settings in `/etc/gitlab/gitlab.rb` have been removed in 14.0:
+
+- `geo_secondary['db_fdw']`
+- `geo_postgresql['fdw_external_user']`
+- `geo_postgresql['fdw_external_password']`
+- `gitlab-_rails['geo_migrated_local_files_clean_up_worker_cron']`
+
+### GitLab OAuth implicit grant deprecation
+
+GitLab is deprecating the [OAuth 2 implicit grant flow](https://docs.gitlab.com/ee/api/oauth2.html#implicit-grant-flow) as it has been removed for [OAuth 2.1](https://oauth.net/2.1/).
+
+Beginning in 14.0, new applications can't be created with the OAuth 2 implicit grant flow. Existing OAuth implicit grant flows are no longer supported in 14.4. Migrate your existing applications to other supported [OAuth2 flows](https://docs.gitlab.com/ee/api/oauth2.html#supported-oauth2-flows) before release 14.4.
+
+### GitLab Runner helper image in GitLab.com Container Registry
+
+In 14.0, we are now pulling the GitLab Runner [helper image](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#helper-image) from the GitLab Container Registry instead of Docker Hub. Refer to [issue #27218](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27218) for details.
+
+### GitLab Runner installation to ignore the `skel` directory
+
+In GitLab Runner 14.0, the installation process will ignore the `skel` directory by default when creating the user home directory. Refer to [issue #4845](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4845) for details.
+
+### Gitaly Cluster SQL primary elector has been removed
+
+Now that Praefect supports a [primary election strategy](https://docs.gitlab.com/ee/administration/gitaly/praefect.html#repository-specific-primary-nodes) for each repository, we have removed the `sql` election strategy.
+The `per_repository` election strategy is the new default, which is automatically used if no election strategy was specified.
+
+If you had configured the `sql` election strategy, you must follow the [migration instructions](https://docs.gitlab.com/ee/administration/gitaly/praefect.html#migrate-to-repository-specific-primary-gitaly-nodes) before upgrading to 14.0.
+
+### Helm v2 support
+
+Helm v2 was [officially deprecated](https://helm.sh/blog/helm-v2-deprecation-timeline/) in November of 2020, with the `stable` repository being [de-listed from the Helm Hub](https://about.gitlab.com/blog/2020/11/09/ensure-auto-devops-work-after-helm-stable-repo/) shortly thereafter. With the release of GitLab 14.0, which will include the 5.0 release of the [GitLab Helm chart](https://docs.gitlab.com/charts/), Helm v2 will no longer be supported.
+
+Users of the chart should [upgrade to Helm v3](https://helm.sh/docs/topics/v2_v3_migration/) to deploy GitLab 14.0 and later.
+
+### Legacy feature flags removed
+
+Legacy feature flags became read-only in GitLab 13.4. GitLab 14.0 removes support for legacy feature flags, so you must migrate them to the [new version](https://docs.gitlab.com/ee/operations/feature_flags.html). You can do this by first taking a note (screenshot) of the legacy flag, then deleting the flag through the API or UI (you don't need to alter the code), and finally create a new Feature Flag with the same name as the legacy flag you deleted. Also, make sure the strategies and environments match the deleted flag. We created a [video tutorial](https://www.youtube.com/watch?v=CAJY2IGep7Y) to help with this migration.
+
+### Legacy storage removed
+
+As [announced in GitLab 13.0](https://about.gitlab.com/releases/2020/05/22/gitlab-13-0-released/#planned-removal-of-legacy-storage-in-14.0), [legacy storage](https://docs.gitlab.com/ee/administration/repository_storage_types.html#legacy-storage) has been removed in GitLab 14.0.
+
+### Limit projects returned in `GET /groups/:id/`
+
+To improve performance, we are limiting the number of projects returned from the `GET /groups/:id/` API call to 100. A complete list of projects can still be retrieved with the `GET /groups/:id/projects` API call.
+
+### Make `pwsh` the default shell for newly-registered Windows Runners
+
+In GitLab Runner 13.2, PowerShell Core support was added to the Shell executor. In 14.0, PowerShell Core, `pwsh` is now the default shell for newly-registered Windows runners. Windows `CMD` will still be available as a shell option for Windows runners. Refer to [issue #26419](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/26419) for details.
+
+### Migrate from `SAST_DEFAULT_ANALYZERS` to `SAST_EXCLUDED_ANALYZERS`
+
+Until GitLab 13.9, if you wanted to avoid running one particular GitLab SAST analyzer, you needed to remove it from the [long string of analyzers in the `SAST.gitlab-ci.yml` file](https://gitlab.com/gitlab-org/gitlab/-/blob/390afc431e7ce1ac253b35beb39f19e49c746bff/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml#L12) and use that to set the [`SAST_DEFAULT_ANALYZERS`](https://docs.gitlab.com/ee/user/application_security/sast/#docker-images) variable in your project's CI file. If you did this, it would exclude you from future new analyzers because this string hard codes the list of analyzers to execute. We avoid this problem by inverting this variable's logic to exclude, rather than choose default analyzers.
+Beginning with 13.9, [we migrated](https://gitlab.com/gitlab-org/gitlab/-/blob/14fed7a33bfdbd4663d8928e46002a5ef3e3282c/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml#L13) to `SAST_EXCLUDED_ANALYZERS` in our `SAST.gitlab-ci.yml` file. We encourage anyone who uses a [customized SAST configuration](https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings) in their project CI file to migrate to this new variable. If you have not overridden `SAST_DEFAULT_ANALYZERS`, no action is needed. The CI/CD variable `SAST_DEFAULT_ANALYZERS` has been removed in GitLab 14.0, which released on June 22, 2021.
+
+### New Terraform template version
+
+As we continuously [develop GitLab's Terraform integrations](https://gitlab.com/gitlab-org/gitlab/-/issues/325312), to minimize customer disruption, we maintain two GitLab CI/CD templates for Terraform:
+
+- The ["latest version" template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml), which is updated frequently between minor releases of GitLab (such as 13.10, 13.11, etc).
+- The ["major version" template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml), which is updated only at major releases (such as 13.0, 14.0, etc).
+
+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).
+
+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).
+
+### OpenSUSE Leap 15.1
+
+Support for [OpenSUSE Leap 15.1 is being deprecated](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/5135). Support for 15.1 will be dropped in 14.0. We are now providing support for openSUSE Leap 15.2 packages.
+
+### PostgreSQL 11 support
+
+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).
+
+### Removal of deprecated `trace` parameter from `jobs` API endpoint
+
+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.
+
+### Removal of legacy fields from DAST report
+
+As a part of the migration to a common report format for all of the Secure scanners in GitLab, DAST is making changes to the DAST JSON report. Certain legacy fields were deprecated in 13.8 and have been completely removed in 14.0. These fields are `@generated`, `@version`, `site`, and `spider`. This should not affect any normal DAST operation, but does affect users who consume the JSON report in an automated way and use these fields. Anyone affected by these changes, and needs these fields for business reasons, is encouraged to open a new GitLab issue and explain the need.
+
+For more information, see [the removal issue](https://gitlab.com/gitlab-org/gitlab/-/issues/33915).
+
+### Removal of release description in the Tags API
+
+GitLab 14.0 removes support for the release description in the Tags API. You can no longer add a release description when [creating a new tag](https://docs.gitlab.com/ee/api/tags.html#create-a-new-tag). You also can no longer [create](https://docs.gitlab.com/ee/api/tags.html#create-a-new-release) or [update](https://docs.gitlab.com/ee/api/tags.html#update-a-release) a release through the Tags API. Please migrate to use the [Releases API](https://docs.gitlab.com/ee/api/releases/#create-a-release) instead.
+
+### Removals for License Compliance
+
+In 13.0, we deprecated the License-Management CI template and renamed it License-Scanning. We have been providing backward compatibility by warning users of the old template to switch. Now in 14.0, we are completely removing the License-Management CI template. Read about it in [issue #216261](https://gitlab.com/gitlab-org/gitlab/-/issues/216261) or [this blog post](https://about.gitlab.com/blog/2021/02/08/composition-analysis-14-deprecations-and-removals/).
+
+### Remove DAST default template stages
+
+In GitLab 14.0, we've removed the stages defined in the current `DAST.gitlab-ci.yml` template to avoid the situation where the template overrides manual changes made by DAST users. We're making this change in response to customer issues where the stages in the template cause problems when used with customized DAST configurations. Because of this removal, `gitlab-ci.yml` configurations that do not specify a `dast` stage must be updated to include this stage.
+
+### Remove SAST analyzer `SAST_GOSEC_CONFIG` variable in favor of custom rulesets
+
+With the release of [SAST Custom Rulesets](https://docs.gitlab.com/ee/user/application_security/sast/#customize-rulesets) in GitLab 13.5 we allow greater flexibility in configuration options for our Go analyzer (GoSec). As a result we no longer plan to support our less flexible [`SAST_GOSEC_CONFIG`](https://docs.gitlab.com/ee/user/application_security/sast/#analyzer-settings) analyzer setting. This variable was deprecated in GitLab 13.10.
+GitLab 14.0 removes the old `SAST_GOSEC_CONFIG variable`. If you use or override `SAST_GOSEC_CONFIG` in your CI file, update your SAST CI configuration or pin to an older version of the GoSec analyzer. We strongly encourage [inheriting and overriding our managed CI templates](https://docs.gitlab.com/ee/user/application_security/sast/#overriding-sast-jobs) to future-proof your CI templates.
+
+### Remove Ubuntu 19.10 (Eoan Ermine) package
+
+Ubuntu 19.10 (Eoan Ermine) reached end of life on Friday, July 17, 2020. In GitLab Runner 14.0, Ubuntu 19.10 (Eoan Ermine) is no longer available from our package distribution. Refer to [issue #26036](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/26036) for details.
+
+### Remove `/usr/lib/gitlab-runner` symlink from package
+
+In GitLab Runner 13.3, a symlink was added from `/user/lib/gitlab-runner/gitlab-runner` to `/usr/bin/gitlab-runner`. In 14.0, the symlink has been removed and the runner is now installed in `/usr/bin/gitlab-runner`. Refer to [issue #26651](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/26651) for details.
+
+### Remove `?w=1` URL parameter to ignore whitespace changes
+
+To create a consistent experience for users based on their preferences, support for toggling whitespace changes via URL parameter has been removed in GitLab 14.0.
+
+### Remove `FF_RESET_HELPER_IMAGE_ENTRYPOINT` feature flag
+
+In 14.0, we have deactivated the `FF_RESET_HELPER_IMAGE_ENTRYPOINT` feature flag. Refer to issue [#26679](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/26679) for details.
+
+### Remove `FF_SHELL_EXECUTOR_USE_LEGACY_PROCESS_KILL` feature flag
+
+In [GitLab Runner 13.1](https://docs.gitlab.com/runner/executors/shell.html#gitlab-131-and-later), [issue #3376](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/3376), we introduced `sigterm` and then `sigkill` to a process in the Shell executor. We also introduced a new feature flag, `FF_SHELL_EXECUTOR_USE_LEGACY_PROCESS_KILL`, so you can use the previous process termination sequence. In GitLab Runner 14.0, [issue #6413](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/6413), the feature flag has been removed.
+
+### Remove `FF_USE_GO_CLOUD_WITH_CACHE_ARCHIVER` feature flag
+
+GitLab Runner 14.0 removes the `FF_USE_GO_CLOUD_WITH_CACHE_ARCHIVER` feature flag. Refer to [issue #27175](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27175) for details.
+
+### Remove `secret_detection_default_branch` job
+
+To ensure Secret Detection was scanning both default branches and feature branches, we introduced two separate secret detection CI jobs (`secret_detection_default_branch` and `secret_detection`) in our managed [`Secret-Detection.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml) template. These two CI jobs created confusion and complexity in the CI rules logic. This deprecation moves the `rule` logic into the `script` section, which then determines how the `secret_detection` job is run (historic, on a branch, commits, etc).
+If you override or maintain custom versions of `SAST.gitlab-ci.yml` or `Secret-Detection.gitlab-ci.yml`, you must update your CI templates. We strongly encourage [inheriting and overriding our managed CI templates](https://docs.gitlab.com/ee/user/application_security/secret_detection/#custom-settings-example) to future-proof your CI templates. GitLab 14.0 no longer supports the old `secret_detection_default_branch` job.
+
+### Remove disk source configuration for GitLab Pages
+
+GitLab Pages [API-based configuration](https://docs.gitlab.com/ee/administration/pages/#gitlab-api-based-configuration) has been available since GitLab 13.0. It replaces the unsupported `disk` source configuration removed in GitLab 14.0, which can no longer be chosen. You should stop using `disk` source configuration, and move to `gitlab` for an API-based configuration. To migrate away from the 'disk' source configuration, set `gitlab_pages['domain_config_source'] = "gitlab"` in your `/etc/gitlab/gitlab.rb` file. We recommend you migrate before updating to GitLab 14.0, to identify and troubleshoot any potential problems before upgrading.
+
+### Remove legacy DAST domain validation
+
+The legacy method of DAST Domain Validation for CI/CD scans was deprecated in GitLab 13.8, and is removed in GitLab 14.0. This method of domain validation only disallows scans if the `DAST_FULL_SCAN_DOMAIN_VALIDATION_REQUIRED` environment variable is set to `true` in the `gitlab-ci.yml` file, and a `Gitlab-DAST-Permission` header on the site is not set to `allow`. This two-step method required users to opt in to using the variable before they could opt out from using the header.
+
+For more information, see the [removal issue](https://gitlab.com/gitlab-org/gitlab/-/issues/293595).
+
+### Remove off peak time mode configuration for Docker Machine autoscaling
+
+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).
+
+### Remove redundant timestamp field from DORA metrics API payload
+
+The [deployment frequency project-level API](https://docs.gitlab.com/ee/api/dora4_project_analytics.html#list-project-deployment-frequencies) endpoint has been deprecated in favor of the [DORA 4 API](https://docs.gitlab.com/ee/api/dora/metrics.html), which consolidates all the metrics under one API with the specific metric as a required field. As a result, the timestamp field, which doesn't allow adding future extensions and causes performance issues, will be removed. With the old API, an example response would be `{ "2021-03-01": 3, "date": "2021-03-01", "value": 3 }`. The first key/value (`"2021-03-01": 3`) will be removed and replaced by the last two (`"date": "2021-03-01", "value": 3`).
+
+### Remove success and failure for finished build metric conversion
+
+In GitLab Runner 13.5, we introduced `failed` and `success` states for a job. To support Prometheus rules, we chose to convert `success/failure` to `finished` for the metric. In 14.0, the conversion has now been removed. Refer to [issue #26900](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/26900) for details.
+
+### Remove support for Windows Server 1903 image
+
+In 14.0, we have removed Windows Server 1903. Microsoft ended support for this version on 2020-08-12. Refer to [issue #27551](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27551) for details.
+
+### Remove support for Windows Server 1909 image
+
+In 14.0, we have removed Windows Server 1909. Microsoft ended support for this version on 2021-05-11. Refer to [issue #27899](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27899) for details.
+
+### Removed Global `SAST_ANALYZER_IMAGE_TAG` in SAST CI template
+
+With the maturity of GitLab Secure scanning tools, we've needed to add more granularity to our release process. Previously, GitLab shared a major version number for [all analyzers and tools](https://docs.gitlab.com/ee/user/application_security/sast/#supported-languages-and-frameworks). This requires all tools to share a major version, and prevents the use of [semantic version numbering](https://semver.org/). In GitLab 14.0, SAST removes the `SAST_ANALYZER_IMAGE_TAG` global variable in our [managed `SAST.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/SAST.gitlab-ci.yml) CI template, in favor of the analyzer job variable setting the `major.minor` tag in the SAST vendored template.
+
+Each analyzer job now has a scoped `SAST_ANALYZER_IMAGE_TAG` variable, which will be actively managed by GitLab and set to the `major` tag for the respective analyzer. To pin to a specific version, [change the variable value to the specific version tag](https://docs.gitlab.com/ee/user/application_security/sast/#pinning-to-minor-image-version).
+If you override or maintain custom versions of `SAST.gitlab-ci.yml`, update your CI templates to stop referencing the global `SAST_ANALYZER_IMAGE_TAG`, and move it to a scoped analyzer job tag. We strongly encourage [inheriting and overriding our managed CI templates](https://docs.gitlab.com/ee/user/application_security/sast/#overriding-sast-jobs) to future-proof your CI templates. This change allows you to more granularly control future analyzer updates with a pinned `major.minor` version.
+This deprecation and removal changes our [previously announced plan](https://about.gitlab.com/releases/2021/02/22/gitlab-13-9-released/#pin-static-analysis-analyzers-and-tools-to-minor-versions) to pin the Static Analysis tools.
+
+### Ruby version changed in `Ruby.gitlab-ci.yml`
+
+By default, the `Ruby.gitlab-ci.yml` file has included Ruby 2.5.
+
+To better support the latest versions of Ruby, the template is changed to use `ruby:latest`, which is currently 3.0. To better understand the changes in Ruby 3.0, please reference the [Ruby-lang.org release announcement](https://www.ruby-lang.org/en/news/2020/12/25/ruby-3-0-0-released/).
+
+Relevant Issue: [Updates Ruby version 2.5 to 3.0](https://gitlab.com/gitlab-org/gitlab/-/issues/329160)
+
+### Segments removed from DevOps Adoption API
+
+The first release of the DevOps Adoption report had a concept of **Segments**. Segments were [quickly removed from the report](https://gitlab.com/groups/gitlab-org/-/epics/5251) because they introduced an additional layer of complexity on top of **Groups** and **Projects**. Subsequent iterations of the DevOps Adoption report focus on comparing adoption across groups rather than segments. GitLab 14.0 removes all references to **Segments** [from the GraphQL API](https://gitlab.com/gitlab-org/gitlab/-/issues/324414) and replaces them with **Enabled groups**.
+
+### Service Templates removed
+
+Service Templates are [removed in GitLab 14.0](https://gitlab.com/groups/gitlab-org/-/epics/5672). They were used to apply identical settings to a large number of projects, but they only did so at the time of project creation.
+
+While they solved part of the problem, _updating_ those values later proved to be a major pain point. [Project Integration Management](https://docs.gitlab.com/ee/user/admin_area/settings/project_integration_management.html) solves this problem by enabling you to create settings at the Group or Instance level, and projects within that namespace inheriting those settings.
+
+### Sidekiq queue selector options no longer accept the 'experimental' prefix
+
+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.
+
+### Ubuntu 16.04 support
+
+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.
+
+### Unicorn removed in favor of Puma for GitLab self-managed
+
+[Support for Unicorn](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/6078) has been removed in GitLab 14.0 in favor of Puma. [Puma has a multi-threaded architecture](https://docs.gitlab.com/ee/administration/operations/puma.html) which uses less memory than a multi-process application server like Unicorn. On GitLab.com, we saw a 40% reduction in memory consumption by using Puma.
+
+### Update Auto Deploy template version
+
+In GitLab 14.0, we will update the [Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/stages.html#auto-deploy) CI template to the latest version. This includes new features, bug fixes, and performance improvements with a dependency on the v2 [auto-deploy-image](https://gitlab.com/gitlab-org/cluster-integration/auto-deploy-image). Auto Deploy CI tempalte v1 will is deprecated going forward.
+
+Since the v1 and v2 versions are not backward-compatible, your project might encounter an unexpected failure if you already have a deployed application. Follow the [upgrade guide](https://docs.gitlab.com/ee/topics/autodevops/upgrading_auto_deploy_dependencies.html#upgrade-guide) to upgrade your environments. You can also start using the latest template today by following the [early adoption guide](https://docs.gitlab.com/ee/topics/autodevops/upgrading_auto_deploy_dependencies.html#early-adopters).
+
+### Update CI/CD templates to stop using hardcoded `master`
+
+Our CI/CD templates have been updated to no longer use hard-coded references to a `master` branch. In 14.0, they all use a variable that points to your project's configured default branch instead. If your CI/CD pipeline relies on our built-in templates, verify that this change works with your current configuration. For example, if you have a `master` branch and a different default branch, the updates to the templates may cause changes to your pipeline behavior. For more information, [read the issue](https://gitlab.com/gitlab-org/gitlab/-/issues/324131).
+
+### WIP merge requests renamed 'draft merge requests'
+
+The WIP (work in progress) status for merge requests signaled to reviewers that the merge request in question wasn't ready to merge. We've renamed the WIP feature to **Draft**, a more inclusive and self-explanatory term. **Draft** clearly communicates the merge request in question isn't ready for review, and makes no assumptions about the progress being made toward it. **Draft** also reduces the cognitive load for new users, non-English speakers, and anyone unfamiliar with the WIP acronym.
+
+### Web Application Firewall (WAF)
+
+The Web Application Firewall (WAF) was deprecated in GitLab 13.6 and is removed from GitLab 14.0. The WAF had limitations inherent in the architectural design that made it difficult to meet the requirements traditionally expected of a WAF. By removing the WAF, GitLab is able to focus on improving other areas in the product where more value can be provided to users. Users who currently rely on the WAF can continue to use the free and open source [ModSecurity](https://github.com/SpiderLabs/ModSecurity) project, which is independent from GitLab. Additional details are available in the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/271276).
+
+### `CI_PROJECT_CONFIG_PATH` removed in GitLab 14.0
+
+GitLab 14.0 removes the `CI_PROJECT_CONFIG_PATH` pre-defined project variable in favor of `CI_CONFIG_PATH`, which is functionally the same. If you are using `CI_PROJECT_CONFIG_PATH` in your pipeline configurations, update them to use `CI_CONFIG_PATH` instead.
+
+### `CI_PROJECT_CONFIG_PATH` variable has been removed
+
+The `CI_PROJECT_CONFIG_PATH` [predefined project variable](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html)
+has been removed in favor of `CI_CONFIG_PATH`, which is functionally the same.
+
+If you are using `CI_PROJECT_CONFIG_PATH` in your pipeline configurations,
+please update them to use `CI_CONFIG_PATH` instead.
+
+## 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.
diff --git a/doc/user/admin_area/analytics/dev_ops_report.md b/doc/user/admin_area/analytics/dev_ops_report.md
index ede9e342a2e..df34cd03d71 100644
--- a/doc/user/admin_area/analytics/dev_ops_report.md
+++ b/doc/user/admin_area/analytics/dev_ops_report.md
@@ -59,7 +59,7 @@ You can use Group DevOps Adoption to:
- Identify specific subgroups that are lagging in their adoption of GitLab features, so you can guide them on
their DevOps journey.
-- Find subgroups that have adopted certain features, and provide guidance to other subgroups on
+- Find subgroups that have adopted certain features, and provide guidance to other subgroups on
how to use those features.
- Verify if you are getting the return on investment that you expected from GitLab.
diff --git a/doc/user/admin_area/appearance.md b/doc/user/admin_area/appearance.md
index 0b264ef22b9..2083cb06f93 100644
--- a/doc/user/admin_area/appearance.md
+++ b/doc/user/admin_area/appearance.md
@@ -2,7 +2,6 @@
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: howto
disqus_identifier: 'https://docs.gitlab.com/ee/customization/branded_login_page.html'
---
@@ -28,8 +27,6 @@ GitLab pipeline emails also display the custom logo.
## Favicon
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/14497) in GitLab 11.0.
-
By default, the favicon (used by the browser as the tab icon, as well as the CI status icon)
uses the GitLab logo, but this can be customized with any icon desired. It must be a
32x32 `.png` or `.ico` image.
@@ -39,8 +36,6 @@ of the page to activate it in the GitLab instance.
## System header and footer messages
-> - [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/55057) from GitLab Premium to GitLab Free in 11.9.
-
You can add a small header message, a small footer message, or both, to the interface
of your GitLab instance. These messages appear on all projects and pages of the
instance, including the sign in / sign up page. The default color is white text on
diff --git a/doc/user/admin_area/credentials_inventory.md b/doc/user/admin_area/credentials_inventory.md
index d79508e5b68..f9b5168fb08 100644
--- a/doc/user/admin_area/credentials_inventory.md
+++ b/doc/user/admin_area/credentials_inventory.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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: howto
---
diff --git a/doc/user/admin_area/geo_nodes.md b/doc/user/admin_area/geo_nodes.md
index f2b899f0be9..b3b2c14adbd 100644
--- a/doc/user/admin_area/geo_nodes.md
+++ b/doc/user/admin_area/geo_nodes.md
@@ -2,7 +2,6 @@
stage: Enablement
group: Geo
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: howto
---
# Geo sites Admin Area **(PREMIUM SELF)**
@@ -50,20 +49,27 @@ download them all at once; so, GitLab places an upper limit on the concurrency o
these operations.
How long the backfill takes is dependent on the maximum concurrency, but higher
-values place more strain on the **primary** site. From [GitLab 10.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/3107),
-the limits are configurable. If your **primary** site has lots of surplus capacity,
+values place more strain on the **primary** site. The limits are configurable.
+If your **primary** site has lots of surplus capacity,
you can increase the values to complete backfill in a shorter time. If it's
under heavy load and backfill reduces its availability for normal requests,
you can decrease them.
-## Using a different URL for synchronization
+## Set up the internal URLs
+
+> Setting up internal URLs in secondary sites was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77179) in GitLab 14.7.
+
+You can set up a different URL for synchronization between the primary and secondary site.
The **primary** site's Internal URL is used by **secondary** sites to contact it
(to sync repositories, for example). The name Internal URL distinguishes it from
[External URL](https://docs.gitlab.com/omnibus/settings/configuration.html#configuring-the-external-url-for-gitlab),
which is used by users. Internal URL does not need to be a private address.
-Internal URL defaults to external URL, but you can also customize it:
+When [Geo secondary proxying](../../administration/geo/secondary_proxy/index.md) is enabled,
+the primary uses the secondary's internal URL to contact it directly.
+
+The internal URL defaults to external URL. To change it:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Geo > Nodes**.
@@ -71,6 +77,9 @@ Internal URL defaults to external URL, but you can also customize it:
1. Edit the internal URL.
1. Select **Save changes**.
+When enabled, the Admin Area for Geo shows replication details for each site directly
+from the primary site's UI, and through the Geo secondary proxy, if enabled.
+
WARNING:
We recommend using an HTTPS connection while configuring the Geo sites. To avoid
breaking communication between **primary** and **secondary** sites when using
@@ -85,7 +94,7 @@ to the internal URL instead of the external one.
## Multiple secondary sites behind a load balancer
-In GitLab 11.11, **secondary** sites can use identical external URLs if
+**Secondary** sites can use identical external URLs if
a unique `name` is set for each Geo site. The `gitlab.rb` setting
`gitlab_rails['geo_node_name']` must:
diff --git a/doc/user/admin_area/img/admin_labels.png b/doc/user/admin_area/img/admin_labels.png
deleted file mode 100644
index a9ea059ccf9..00000000000
--- a/doc/user/admin_area/img/admin_labels.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/admin_area/img/admin_labels_v14_7.png b/doc/user/admin_area/img/admin_labels_v14_7.png
new file mode 100644
index 00000000000..01a4ea0c2cc
--- /dev/null
+++ b/doc/user/admin_area/img/admin_labels_v14_7.png
Binary files differ
diff --git a/doc/user/admin_area/img/license_upload_v13_12.png b/doc/user/admin_area/img/license_upload_v13_12.png
deleted file mode 100644
index 81dc162c1f0..00000000000
--- a/doc/user/admin_area/img/license_upload_v13_12.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/admin_area/index.md b/doc/user/admin_area/index.md
index b0f38e8cfb9..ba0802b3b7a 100644
--- a/doc/user/admin_area/index.md
+++ b/doc/user/admin_area/index.md
@@ -110,13 +110,13 @@ You can combine the filter options. For example, to list only public projects wi
#### Projects pending deletion **(PREMIUM SELF)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37014) in GitLab 13.3.
-> - [Tab renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/347468) from **Deleted projects** in GitLab 14.7.
+> - [Tab renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/347468) from **Deleted projects** in GitLab 14.6.
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:
1. On the top bar, select **Menu > Projects > Explore projects**.
-1. Select the **Pending deletion** tab (in GitLab 14.7 and later) or the **Deleted projects** tab (GitLab 14.6 and earlier).
+1. Select the **Pending deletion** tab (in GitLab 14.6 and later) or the **Deleted projects** tab (GitLab 14.5 and earlier).
Listed for each project is:
@@ -202,6 +202,8 @@ The following data is included in the export:
- Access level ([Project](../permissions.md#project-members-permissions) and [Group](../permissions.md#group-members-permissions))
- Date of last activity ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345388) in GitLab 14.6). For a list of activities that populate this column, see the [Users API documentation](../../api/users.md#get-user-activities-admin-only).
+Only the first 100,000 user accounts are exported.
+
![user permission export button](img/export_permissions_v13_11.png)
#### Users statistics
diff --git a/doc/user/admin_area/labels.md b/doc/user/admin_area/labels.md
index b5dbf835d70..93114186e75 100644
--- a/doc/user/admin_area/labels.md
+++ b/doc/user/admin_area/labels.md
@@ -7,13 +7,12 @@ type: reference
# Labels administration **(FREE SELF)**
-In the Admin Area, you can manage labels for the GitLab instance. For more details, see [Labels](../project/labels.md).
+To manage labels for the GitLab instance, select **Labels** (**{labels}**) from the Admin Area sidebar. For more details on how to manage labels, see [Labels](../project/labels.md).
-## Default Labels
+Labels created in the Admin Area are automatically added to new projects.
+Updating or adding labels in the Admin Area does not modify labels in existing projects.
-Labels created in the Admin Area become available to each _new_ project.
-
-![Default label set](img/admin_labels.png)
+![Default label set](img/admin_labels_v14_7.png)
<!-- ## Troubleshooting
diff --git a/doc/user/admin_area/license.md b/doc/user/admin_area/license.md
index d984f6f4092..c3f0c94db21 100644
--- a/doc/user/admin_area/license.md
+++ b/doc/user/admin_area/license.md
@@ -2,173 +2,179 @@
stage: Growth
group: Conversion
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: howto
---
-# Activating GitLab EE **(PREMIUM SELF)**
+# Activate GitLab Enterprise Edition (EE) **(PREMIUM SELF)**
-To enable features of GitLab Enterprise Edition (EE), you need to activate your instance. Ensure you are running an enterprise edition. To verify, sign in to GitLab and browse to `/help`. The GitLab edition and version are listed at the top of the **Help** page.
+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.
-If you are running GitLab Community Edition (CE), upgrade your installation to GitLab Enterprise Edition (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 please [contact GitLab Support](https://about.gitlab.com/support/#contact-support).
+## Verify your GitLab edition
-As of GitLab Enterprise Edition 9.4.0, a newly-installed instance without an
-uploaded license only has the Free features active. A trial license activates all Ultimate features, but after [the trial expires](#what-happens-when-your-license-expires), some functionality
-is locked.
+To activate your instance, make sure you are running GitLab Enterprise Edition (EE).
-## Activate GitLab EE with an Activation Code
+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.
-As of GitLab Enterprise Edition 14.1, you need an activation code to activate your instance. You can obtain an activation code by [purchasing a license](https://about.gitlab.com/pricing/) or by signing up for a [free trial](https://about.gitlab.com/free-trial/). This 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.
+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).
-To begin the activation process with your activation code:
+## Activate GitLab EE with an activation code
+
+In GitLab Enterprise Edition 14.1 and later, you need an activation code to activate
+your instance. To get an activation code, [purchase a license](https://about.gitlab.com/pricing/)
+or sign up for a [free trial](https://about.gitlab.com/free-trial/). 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.
+
+To activate your instance with an activation code:
1. Sign in to your GitLab self-managed instance.
-1. From the top menu, select the Admin Area **{admin}**.
-1. From the left sidebar, select **Subscription**.
-1. Paste the activation code onto the input field.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Subscription**.
+1. Enter 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 a new trial), you can upload it by signing into your GitLab instance as an administrator or adding it during installation. The license is a base64-encoded ASCII text file with a `.gitlab-license` extension.
+## Activate GitLab EE with a license file
-## Uploading your license
+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 visit your GitLab EE installation signed in as an administrator,
-you should see a note urging you to upload a license with a link that takes you
-to the **Subscription** area.
+## Upload your license
-Otherwise, to manually go to the **Subscription** area:
-
-1. Sign in to your GitLab self-managed instance.
-1. From the top menu, select the Admin Area **{admin}**.
-1. From the left sidebar, select **Subscription**, and select **Upload a license file**.
+The first time you sign in to your GitLab instance, a note with a
+link to the **Upload license** page should be displayed.
- - *If you've received a `.gitlab-license` file:*
- 1. Download the license file to your local machine.
- 1. Select **Upload `.gitlab-license` file**.
- 1. Select **Choose file** and select the license file.
- In this example the license file is named `GitLab.gitlab-license`.
- 1. Select the **Terms of Service** checkbox.
- 1. Select **Upload License**.
+Otherwise, to upload your license:
- ![Upload license](img/license_upload_v13_12.png)
+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, select **Upload `.gitlab-license` file**, **Choose file**, and
+ select the license file from your local machine.
+ - 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**.
- - *If you've received your license as plain text:*
- 1. Select **Enter license key**.
- 1. Copy the license and paste it into the **License key** field.
- 1. Select the **Terms of Service** checkbox.
- 1. Select **Upload License**.
+## Add your license during installation
-## Add your license at install time
+You can import a license file when you install GitLab.
-A license can be automatically imported at install time by placing a file named
-`Gitlab.gitlab-license` in `/etc/gitlab/` for Omnibus GitLab, or `config/` for source installations.
+- **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:
-You can also specify a custom location and filename for the license:
+ ```shell
+ export GITLAB_LICENSE_FILE="/path/to/license/file"
+ ```
-- Source installations should set the `GITLAB_LICENSE_FILE` environment
- variable with the path to a valid GitLab Enterprise Edition license.
+- **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`:
- ```shell
- export GITLAB_LICENSE_FILE="/path/to/license/file"
- ```
-
-- Omnibus GitLab installations should add this entry to `gitlab.rb`:
-
- ```ruby
- gitlab_rails['initial_license_file'] = "/path/to/license/file"
- ```
+ ```ruby
+ gitlab_rails['initial_license_file'] = "/path/to/license/file"
+ ```
WARNING:
-These methods only add a license at the time of installation. Use the
-**{admin}** **Admin Area** in the web user interface to renew or upgrade licenses.
-
----
-
-After the license is uploaded, all GitLab Enterprise Edition functionality
-is active until the end of the license period. When that period ends, the
-instance will [fall back](#what-happens-when-your-license-expires) to Free-only
-functionality.
-
-You can review the license details at any time by going to **Admin Area > Subscription**.
-
-## Notification before the license expires
-
-One month before the license expires, a message informing about the expiration
-date is displayed to GitLab administrators. Make sure that you update your
-license, otherwise you miss all the paid features if your license expires.
+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
-When your license expires, GitLab locks down features, like Git pushes
-and issue creation. Then, your instance becomes read-only and
-an expiration message is displayed to all administrators.
+Fifteen days before the license expires, a notification banner with the upcoming expiration
+date displays to GitLab administrators.
-For GitLab self-managed instances, you have a 14-day grace period
+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.
-- To fall back to Free features, delete all expired licenses.
+To resume functionality, [upload a new license](#upload-your-license).
-### Remove a license file
+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. From the top menu, select the Admin Area **{admin}**.
-1. From the left sidebar, select **Subscription**.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Subscription**.
1. Select **Remove license**.
-These steps may need to be repeated to completely remove all licenses, including those applied in the past.
+Repeat these steps to remove all licenses, including those applied in the past.
+
+## View license details and history
-## License history
+To view your license details:
-You can upload and view more than one license, but only the latest license in the current date
-range is used as the active license.
+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 of your active subscriptions in the **Subscription history** table.
+You can view all active subscriptions in the **Subscription history** table.
NOTE:
-In GitLab 13.6 and earlier, a notification banner about an expiring license may continue to be displayed even after a new license has been uploaded.
-This happens when the newly uploaded license's start date is in the future and the expiring one is still active.
+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
-### There is no Subscription tab in the Admin Area
+### No Subscription area in the Admin Area
-If you originally installed Community Edition rather than Enterprise Edition you must
-[upgrade to Enterprise Edition](../../update/index.md#community-to-enterprise-edition)
-before uploading your license.
+You cannot upload your license because there is no **Subscription** area.
+This issue might occur if:
-GitLab.com users can't upload and use a self-managed license. If you
-want to use paid features on GitLab.com, you can
-[purchase a separate subscription](../../subscriptions/gitlab_com/index.md).
+- 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
-If you've added new users to your GitLab instance prior to renewal, you may need to
-purchase additional seats to cover those users. If this is the case, and a license
-without enough users is uploaded, GitLab displays a message prompting you to purchase
-additional users. More information on how to determine the required number of users
-and how to add additional seats can be found in the
-[licensing FAQ](https://about.gitlab.com/pricing/licensing-faq/).
+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, you can exceed the number of purchased users and still activate your license.
+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 subscription,
- the license is applied and the overage is paid in the next true-up.
-- If the users over license are more than 10% of the users in the subscription,
+- 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 purchased a license for 100 users, you can have 110 users when you activate
-your license. However, if you have 111, you must purchase more users before you can activate.
+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.
-### There is a connectivity issue
+### Cannot activate instance due to connectivity error
-In GitLab 14.1 and later, to activate your subscription, your GitLab instance must be connected to the internet.
+In GitLab 14.1 and later, to activate your subscription with an activation code,
+your GitLab instance must be connected to the internet.
-If you have an offline or airgapped environment, you can [upload a license file](license.md#activate-gitlab-ee-with-a-license-file) instead.
+If you have an offline or airgapped environment,
+[upload a license file](license.md#activate-gitlab-ee-with-a-license-file) instead.
-If you have questions or need assistance activating your instance, please [contact GitLab Support](https://about.gitlab.com/support/#contact-support).
+If you have questions or need assistance activating your instance,
+[contact GitLab Support](https://about.gitlab.com/support/#contact-support).
diff --git a/doc/user/admin_area/moderate_users.md b/doc/user/admin_area/moderate_users.md
index 3f15bd5b4e6..ee38664fa66 100644
--- a/doc/user/admin_area/moderate_users.md
+++ b/doc/user/admin_area/moderate_users.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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: howto
---
@@ -100,7 +100,7 @@ A blocked user can be unblocked from the Admin Area. To do this:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Users**.
-1. Select on the **Blocked** tab.
+1. Select the **Blocked** tab.
1. Optional. Select a user.
1. Select the **{settings}** **User administration** dropdown.
1. Select **Unblock**.
@@ -111,6 +111,16 @@ The user's state is set to active and they consume a
NOTE:
Users can also be unblocked using the [GitLab API](../../api/users.md#unblock-user).
+The unblock option may be unavailable for LDAP users. To enable the unblock option,
+the LDAP identity first needs to be deleted:
+
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Overview > Users**.
+1. Select the **Blocked** tab.
+1. Select a user.
+1. Select the **Identities** tab.
+1. Find the LDAP provider and select **Delete**.
+
## Activate and deactivate users
GitLab administrators can deactivate and activate users.
diff --git a/doc/user/admin_area/monitoring/background_migrations.md b/doc/user/admin_area/monitoring/background_migrations.md
index 66001a987a4..260a8515a1a 100644
--- a/doc/user/admin_area/monitoring/background_migrations.md
+++ b/doc/user/admin_area/monitoring/background_migrations.md
@@ -145,6 +145,8 @@ or [manually finish it](#manually-finishing-a-batched-background-migration).
### Manually finishing a batched background migration
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62634) in GitLab 14.1
+
If you need to manually finish a batched background migration due to an
error, you can run:
diff --git a/doc/user/admin_area/monitoring/health_check.md b/doc/user/admin_area/monitoring/health_check.md
index 1d2d7be146c..75905d60c4e 100644
--- a/doc/user/admin_area/monitoring/health_check.md
+++ b/doc/user/admin_area/monitoring/health_check.md
@@ -6,12 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Health Check **(FREE SELF)**
-> - Liveness and readiness probes were [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10416) in GitLab 9.1.
-> - The `health_check` endpoint was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/3888) in GitLab 8.8 and was
-> deprecated in GitLab 9.1.
-> - [Access token](#access-token-deprecated) has been deprecated in GitLab 9.4
-> in favor of [IP whitelist](#ip-whitelist).
-
GitLab provides liveness and readiness probes to indicate service health and
reachability to required services. These probes report on the status of the
database connection, Redis connection, and access to the file system. These
@@ -137,28 +131,9 @@ On failure, the endpoint returns a `503` HTTP status code.
This check is being exempt from Rack Attack.
-## Access token (Deprecated)
-
-NOTE:
-Access token has been deprecated in GitLab 9.4 in favor of [IP whitelist](#ip-whitelist).
-
-An access token needs to be provided while accessing the probe endpoints. You can
-find the current accepted token in the user interface:
-
-1. On the top bar, select **Menu > Admin**.
-1. On the left sidebar, select **Monitoring > Health Check**. (`admin/health_check`)
-
-![access token](img/health_check_token.png)
-
-The access token can be passed as a URL parameter:
-
-```plaintext
-https://gitlab.example.com/-/readiness?token=ACCESS_TOKEN
-```
+## Sidekiq
-NOTE:
-In case the database or Redis service are inaccessible, the probe endpoints response is not guaranteed to be correct.
-You should switch to [IP whitelist](#ip-whitelist) from deprecated access token to avoid it.
+Learn how to configure the [Sidekiq health checks](../../../administration/sidekiq_health_check.md).
<!-- ## Troubleshooting
diff --git a/doc/user/admin_area/monitoring/img/health_check_token.png b/doc/user/admin_area/monitoring/img/health_check_token.png
deleted file mode 100644
index 8d4cf710176..00000000000
--- a/doc/user/admin_area/monitoring/img/health_check_token.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/admin_area/review_abuse_reports.md b/doc/user/admin_area/review_abuse_reports.md
index 6a8b48e7ba7..4c5a241ab18 100644
--- a/doc/user/admin_area/review_abuse_reports.md
+++ b/doc/user/admin_area/review_abuse_reports.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
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 5868f20d0d8..f748f575419 100644
--- a/doc/user/admin_area/settings/account_and_limit_settings.md
+++ b/doc/user/admin_area/settings/account_and_limit_settings.md
@@ -36,17 +36,19 @@ can create in their personal namespace:
## Max attachment size
-You can change the maximum file size for attachments in comments and replies in GitLab:
+The maximum file size for attachments in GitLab comments and replies is 10 MB.
+To change the maximum attachment size:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > General**, then expand **Account and limit**.
1. Increase or decrease by changing the value in **Maximum attachment size (MB)**.
-NOTE:
If you choose a size larger than the configured value for the web server,
-you may receive errors. See the [troubleshooting section](#troubleshooting) for more
+you may receive errors. Read the [troubleshooting section](#troubleshooting) for more
details.
+For GitLab.com repository size limits, read [accounts and limit settings](../../gitlab_com/index.md#account-and-limit-settings).
+
## Max push size
You can change the maximum push size for your repository:
@@ -64,17 +66,20 @@ Use [Git LFS](../../../topics/git/lfs/index.md) to add large files to a reposito
## Max import size
-You can change the maximum file size for imports in GitLab:
+> [Modified](https://gitlab.com/gitlab-org/gitlab/-/issues/251106) from 50 MB to unlimited in GitLab 13.8.
+
+To modify the maximum file size for imports in GitLab:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > General**, then expand **Account and limit**.
1. Increase or decrease by changing the value in **Maximum import size (MB)**.
-NOTE:
If you choose a size larger than the configured value for the web server,
you may receive errors. See the [troubleshooting section](#troubleshooting) for more
details.
+For GitLab.com repository size limits, read [accounts and limit settings](../../gitlab_com/index.md#account-and-limit-settings).
+
## Personal access token prefix
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20968) in GitLab 13.7.
@@ -118,6 +123,9 @@ For instance, consider the following workflow:
1. Before you exceed available storage, you set up a limit of 10 GB
per repository.
+NOTE:
+For GitLab.com repository size limits, read [accounts and limit settings](../../gitlab_com/index.md#account-and-limit-settings).
+
### How it works
Only a GitLab administrator can set those limits. Setting the limit to `0` means
@@ -150,9 +158,6 @@ wiki, packages, or snippets. The repository size limit applies to both private a
For details on manually purging files, see [reducing the repository size using Git](../../project/repository/reducing_the_repo_size_using_git.md).
-NOTE:
-For GitLab.com repository size limits, see [accounts and limit settings](../../gitlab_com/index.md#account-and-limit-settings).
-
## Troubleshooting
### 413 Request Entity Too Large
@@ -196,11 +201,7 @@ To set a limit on how long these sessions are valid:
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1007) in GitLab 14.6 [with a flag](../../../administration/feature_flags.md) named `ff_limit_ssh_key_lifetime`. Disabled by default.
> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/346753) in GitLab 14.6.
-
-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 `ff_limit_ssh_key_lifetime`.
-On GitLab.com, this feature is not available.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/1007) in GitLab 14.7. [Feature flag ff_limit_ssh_key_lifetime](https://gitlab.com/gitlab-org/gitlab/-/issues/347408) removed.
Users can optionally specify a lifetime for
[SSH keys](../../../ssh/index.md).
diff --git a/doc/user/admin_area/settings/continuous_integration.md b/doc/user/admin_area/settings/continuous_integration.md
index c6ebce03b06..e18808ffb41 100644
--- a/doc/user/admin_area/settings/continuous_integration.md
+++ b/doc/user/admin_area/settings/continuous_integration.md
@@ -134,44 +134,9 @@ A new pipeline must run before the latest artifacts can expire and be deleted.
NOTE:
All application settings have a [customizable cache expiry interval](../../../administration/application_settings_cache.md) which can delay the settings affect.
-## Shared runners pipeline minutes quota **(PREMIUM SELF)**
+## Shared runners CI/CD minutes
-> [Moved](https://about.gitlab.com/blog/2021/01/26/new-gitlab-product-subscription-model/) to GitLab Premium in 13.9.
-
-If you have enabled shared runners for your GitLab instance, you can limit their
-usage by setting a maximum number of pipeline minutes that a group can use on
-shared runners per month. Setting this to `0` (default value) grants
-unlimited pipeline minutes. While build limits are stored as minutes, the
-counting is done in seconds. Usage resets on the first day of each month.
-On GitLab.com, the quota is calculated based on your
-[subscription plan](../../../subscriptions/gitlab_com/index.md#ci-pipeline-minutes).
-
-To change the pipelines minutes quota:
-
-1. On the top bar, select **Menu > Admin**.
-1. On the left sidebar, select **Settings > CI/CD**.
-1. Expand **Continuous Integration and Deployment**.
-1. In the **Pipeline minutes quota** box, enter the maximum number of minutes.
-1. Click **Save changes** for the changes to take effect.
-
-While the setting in the Admin Area has a global effect, as an administrator you can
-also change each group's pipeline minutes quota to override the global value.
-
-1. Navigate to the **Admin Area > Overview > Groups** and hit the **Edit**
- button for the group you wish to change the pipeline minutes quota.
-1. In the **Pipeline Minutes Quota** box, enter the maximum number of minutes.
-1. Click **Save changes** for the changes to take effect.
-
-Once saved, you can see the build quota in the group settings.
-The quota can also be viewed in the project settings if shared runners
-are enabled.
-
-![Project admin information](img/admin_project_quota_view.png)
-
-You can see an overview of the pipeline minutes quota of all projects of
-a group in the **Usage Quotas** page available to the group page settings list.
-
-![Group pipelines quota](img/group_pipelines_quota.png)
+As an administrator you can set either a global or namespace-specific limit on the number of [CI/CD minutes](../../../ci/pipelines/cicd_minutes.md) you can use.
## Archive jobs
@@ -303,13 +268,12 @@ To set the maximum file size:
1. Enter the maximum file size, in bytes.
1. Click **Save size limits**.
-## Runner registration
+## Prevent users from registering runners
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22225) in GitLab 14.1.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22225) in GitLab 14.1.
-> - [Deployed behind a feature flag](../../feature_flags.md), disabled by default.
-> - Disabled on GitLab.com.
-> - Not recommended for production use.
-> - To use in GitLab self-managed instances, ask a GitLab administrator to enable it.
+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 `runner_registration_control`. On GitLab.com, this feature is not available.
GitLab administrators can adjust who is allowed to register runners, by showing and hiding areas of the UI.
@@ -318,29 +282,14 @@ By default, all members of a project and group are able to register runners.
To change this:
1. On the top bar, select **Menu > Admin**.
-1. Go to **Settings > CI/CD**.
-1. Expand the **Runner registration** section.
-1. Select the desired options.
-1. Click **Save changes**.
-
-When the registration sections are hidden in the UI, members of the project or group that need to register runners must contact the administrators.
-
-This feature is currently behind a feature flag.
-To enable it:
-
-**In Omnibus installations:**
-
-1. Enter the Rails console:
-
- ```shell
- sudo gitlab-rails console
- ```
-
-1. Flip the switch and enable the feature flag:
+1. On the left sidebar, select **Settings > CI/CD**.
+1. Expand **Runner registration**.
+1. Clear the checkbox if you don't want to display runner registration
+ information in the UI for group or project members.
+1. Select **Save changes**.
- ```ruby
- Feature.enable(:runner_registration_control)
- ```
+WARNING:
+When the registration sections are hidden in the UI, members of the project or group that need to register runners must contact the administrators. If you plan to prevent registration, ensure users have access to the runners they need to run jobs.
## Troubleshooting
diff --git a/doc/user/admin_area/settings/external_authorization.md b/doc/user/admin_area/settings/external_authorization.md
index 5f007c83e4b..4fd7c59ef24 100644
--- a/doc/user/admin_area/settings/external_authorization.md
+++ b/doc/user/admin_area/settings/external_authorization.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -29,39 +29,13 @@ functionality that render cross-project data. That includes:
Labels, Milestones, Merge requests).
- Global and Group search are disabled.
-This is to prevent performing to many requests at once to the external
+This is to prevent performing too many requests at once to the external
authorization service.
Whenever access is granted or denied this is logged in a log file called
`external-policy-access-control.log`. Read more about the logs GitLab keeps in
the [Omnibus GitLab documentation](https://docs.gitlab.com/omnibus/settings/logs.html).
-## Configuration
-
-The external authorization service can be enabled by an administrator:
-
-1. On the top bar, select **Menu > Admin**.
-1. On the left sidebar, select **Settings > General**:
- ![Enable external authorization service](img/external_authorization_service_settings.png)
-
-The available required properties are:
-
-- **Service URL**: The URL to make authorization requests to. When leaving the
- URL blank, cross project features remain available while still being able
- to specify classification labels for projects.
-- **External authorization request timeout**: The timeout after which an
- authorization request is aborted. When a request times out, access is denied
- to the user.
-- **Client authentication certificate**: The certificate to use to authenticate
- with the external authorization service.
-- **Client authentication key**: Private key for the certificate when
- authentication is required for the external authorization service, this is
- encrypted when stored.
-- **Client authentication key password**: Passphrase to use for the private key
- when authenticating with the external service this is encrypted when stored.
-- **Default classification label**: The classification label to use when
- requesting authorization if no specific label is defined on the project
-
When using TLS Authentication with a self signed certificate, the CA certificate
needs to be trusted by the OpenSSL installation. When using GitLab installed
using Omnibus, learn to install a custom CA in the
@@ -69,6 +43,16 @@ using Omnibus, learn to install a custom CA in the
Alternatively, learn where to install custom certificates by using
`openssl version -d`.
+## Configuration
+
+The external authorization service can be enabled by an administrator:
+
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
+1. Expand **External authorization**.
+1. Complete the fields.
+1. Select **Save changes**.
+
## How it works
When GitLab requests access, it sends a JSON POST request to the external
diff --git a/doc/user/admin_area/settings/img/admin_project_quota_view.png b/doc/user/admin_area/settings/img/admin_project_quota_view.png
deleted file mode 100644
index 8320be860da..00000000000
--- a/doc/user/admin_area/settings/img/admin_project_quota_view.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/admin_area/settings/img/external_authorization_service_settings.png b/doc/user/admin_area/settings/img/external_authorization_service_settings.png
deleted file mode 100644
index 9b8658fd1a1..00000000000
--- a/doc/user/admin_area/settings/img/external_authorization_service_settings.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/admin_area/settings/img/file_template_admin_area_v14_0.png b/doc/user/admin_area/settings/img/file_template_admin_area_v14_0.png
deleted file mode 100644
index 33fce8a2b77..00000000000
--- a/doc/user/admin_area/settings/img/file_template_admin_area_v14_0.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/admin_area/settings/index.md b/doc/user/admin_area/settings/index.md
index 7945e5d790f..2820f3ae9df 100644
--- a/doc/user/admin_area/settings/index.md
+++ b/doc/user/admin_area/settings/index.md
@@ -64,7 +64,7 @@ The **CI/CD** settings contain:
This pipeline configuration is run after the project's own configuration.
- [Package Registry](continuous_integration.md#package-registry-configuration) -
Settings related to the use and experience of using the GitLab Package Registry. Some
- [risks are involved](../../packages/container_registry/index.md#use-with-external-container-registries)
+ [risks are involved](../../packages/container_registry/reduce_container_registry_storage.md#use-with-external-container-registries)
in enabling some of these settings.
### Geo **(PREMIUM SELF)**
@@ -91,7 +91,8 @@ The **Integrations** settings contain:
Slack integration allows you to interact with GitLab via slash commands in a chat window.
This option is only available on GitLab.com, though it may be
[available for self-managed instances in the future](https://gitlab.com/gitlab-org/gitlab/-/issues/28164).
-- [Third party offers](third_party_offers.md) - Control the display of third-party offers.
+- [Customer experience improvement and third-party offers](third_party_offers.md) -
+ Control the display of customer experience improvement content and third-party offers.
- [Snowplow](../../../development/snowplow/index.md) - Configure the Snowplow integration.
- [Google GKE](../../project/clusters/add_gke_clusters.md) - Google GKE integration enables
you to provision GKE clusters from GitLab.
diff --git a/doc/user/admin_area/settings/instance_template_repository.md b/doc/user/admin_area/settings/instance_template_repository.md
index 71eb7bbbdc9..51695ef7fd2 100644
--- a/doc/user/admin_area/settings/instance_template_repository.md
+++ b/doc/user/admin_area/settings/instance_template_repository.md
@@ -7,7 +7,8 @@ type: reference
# Instance template repository **(PREMIUM SELF)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5986) in GitLab 11.3.
+> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52360) to behave like group-level templates in GitLab 13.9.
+> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/321247) in GitLab 14.0.
In hosted systems, enterprises often have a need to share their own templates
across teams. This feature allows an administrator to pick a project to be the
@@ -21,10 +22,9 @@ To select a project to serve as the custom template repository:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Templates**.
-1. Select the project:
-
- ![File templates in the Admin Area](img/file_template_admin_area_v14_0.png)
-
+1. Expand **Templates**
+1. From the dropdown list, select the project to use as the template repository.
+1. Select **Save changes**.
1. Add custom templates to the selected repository.
After you add templates, you can use them for the entire instance.
diff --git a/doc/user/admin_area/settings/sign_in_restrictions.md b/doc/user/admin_area/settings/sign_in_restrictions.md
index 8cee63b0ac2..52b20d5b437 100644
--- a/doc/user/admin_area/settings/sign_in_restrictions.md
+++ b/doc/user/admin_area/settings/sign_in_restrictions.md
@@ -2,7 +2,6 @@
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: reference
---
# Sign-in restrictions **(FREE SELF)**
@@ -21,8 +20,11 @@ To access sign-in restriction settings:
You can restrict the password authentication for web interface and Git over HTTP(S):
-- **Web interface**: When this feature is disabled, the **Standard** sign-in tab is removed and an [external authentication provider](../../../administration/auth/index.md) must be used.
-- **Git over HTTP(S)**: When this feature is disabled, a [Personal Access Token](../../profile/personal_access_tokens.md) must be used to authenticate.
+- **Web interface**: When this feature is disabled, the **Standard** sign-in tab
+ is removed and an [external authentication provider](../../../administration/auth/index.md)
+ must be used.
+- **Git over HTTP(S)**: When this feature is disabled, a [Personal Access Token](../../profile/personal_access_tokens.md)
+ or LDAP password must be used to authenticate.
In the event of an external authentication provider outage, use the [GitLab Rails console](../../../administration/operations/rails_console.md) to [re-enable the standard web sign-in form](../../../administration/troubleshooting/gitlab_rails_cheat_sheet.md#re-enable-standard-web-sign-in-form). This configuration can also be changed over the [Application settings REST API](../../../api/settings.md#change-application-settings) while authenticating with an administrator account's personal access token.
diff --git a/doc/user/admin_area/settings/third_party_offers.md b/doc/user/admin_area/settings/third_party_offers.md
index c9d48b14a6c..04ec9ed652f 100644
--- a/doc/user/admin_area/settings/third_party_offers.md
+++ b/doc/user/admin_area/settings/third_party_offers.md
@@ -1,11 +1,11 @@
---
-stage: none
-group: unassigned
+stage: Manage
+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
type: reference
---
-# Third-party offers **(FREE SELF)**
+# Customer experience improvement and third-party offers **(FREE SELF)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/20379) in GitLab 11.1.
@@ -13,11 +13,14 @@ Within GitLab, we inform users of available third-party offers they might find v
to enhance the development of their projects. An example is the Google Cloud Platform free credit
for using [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/).
-To toggle the display of third-party offers:
+Furthermore, we use content to improve customer experience. An example are the personalization
+questions when creating a group.
+
+To toggle the display of customer experience improvement content and third-party offers:
1. On the top bar, select **Menu > Admin**.
-1. On the left sidebar, select **Settings**, and expand **Third-party offers**.
-1. Select **Do not display offers from third parties**.
+1. On the left sidebar, select **Settings**, and expand **Customer experience improvement & third-party offers**.
+1. Select **Do not display content for customer experience improvement and offers from third parties**.
1. Select **Save changes**.
<!-- ## Troubleshooting
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 1087f50b215..82e0d3d27d4 100644
--- a/doc/user/admin_area/settings/visibility_and_access_controls.md
+++ b/doc/user/admin_area/settings/visibility_and_access_controls.md
@@ -188,6 +188,9 @@ To restrict visibility levels for projects, snippets, and selected pages:
1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility and access controls** section.
1. In the **Restricted visibility levels** section, select the desired visibility levels to restrict.
+ If you restrict the **Public** level:
+ - User profiles are only visible to logged in users via the Web interface.
+ - User attributes are only visible to authenticated users via the GraphQL API.
1. Select **Save changes**.
For more details on project visibility, see
diff --git a/doc/user/analytics/ci_cd_analytics.md b/doc/user/analytics/ci_cd_analytics.md
index f083f886924..1bc0c2b8fb0 100644
--- a/doc/user/analytics/ci_cd_analytics.md
+++ b/doc/user/analytics/ci_cd_analytics.md
@@ -10,8 +10,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/38318) to CI/CD Analytics in GitLab 12.8.
-GitLab tracks the history of your pipeline successes and failures, as well as how long each pipeline
-ran. To view this information for a project, go to **Analytics > CI/CD Analytics**.
+CI/CD Analytics shows the history of your pipeline successes and failures, as well as how long each pipeline
+ran.
View successful pipelines:
@@ -27,6 +27,13 @@ on when the pipeline was created. The total pipeline calculation includes child
pipelines and pipelines that failed with invalid YAML. If you are interested in
filtering pipelines based on other attributes, consider using the [Pipelines API](../../api/pipelines.md#list-project-pipelines).
+## View CI/CD analytics
+
+To view CI/CD analytics:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Analytics > CI/CD Analytics**.
+
## DevOps Research and Assessment (DORA) key metrics **(ULTIMATE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/275991) in GitLab 13.7.
diff --git a/doc/user/analytics/code_review_analytics.md b/doc/user/analytics/code_review_analytics.md
index 496e768456f..066b45aeb39 100644
--- a/doc/user/analytics/code_review_analytics.md
+++ b/doc/user/analytics/code_review_analytics.md
@@ -17,16 +17,10 @@ requests, and:
- Take action on individual merge requests.
- Reduce overall cycle time.
-NOTE:
-Initially, no data appears. Data is populated as users comment on open merge requests.
-
-## Overview
-
Code Review Analytics is available to users with at least the Reporter [role](../permissions.md), and displays a table of open merge requests that have at least one non-author comment. The review time is measured from the time the first non-author comment was submitted.
-To access Code Review Analytics, from your project's menu, go to **Analytics > Code Review**.
-
-You can filter the list of merge requests by milestone and label.
+NOTE:
+Initially, no data appears. Data is populated as users comment on open merge requests.
![Code Review Analytics](img/code_review_analytics_v13_11.png "List of code reviews; oldest review first.")
@@ -36,6 +30,14 @@ The table is sorted by:
or to be broken down into smaller parts.
- Other columns: Display the author, approvers, comment count, and line change (-/+) counts.
+## View Code Review Analytics
+
+To view Code Review Analytics:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Analytics > Code Review**.
+1. Filter merge requests by milestone and label.
+
## Use cases
This feature is designed for [development team leaders](https://about.gitlab.com/handbook/marketing/strategic-marketing/roles-personas/#delaney-development-team-lead)
diff --git a/doc/user/analytics/img/repository_analytics_v13_0.png b/doc/user/analytics/img/repository_analytics_v13_0.png
deleted file mode 100644
index dd943b4f44d..00000000000
--- a/doc/user/analytics/img/repository_analytics_v13_0.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/analytics/index.md b/doc/user/analytics/index.md
index 6a157dbb5ae..01ee9857060 100644
--- a/doc/user/analytics/index.md
+++ b/doc/user/analytics/index.md
@@ -23,7 +23,7 @@ in one place.
GitLab provides several analytics features at the group level. Some of these features require you to use a higher tier than GitLab Free.
-- [Application Security](../application_security/security_dashboard/#group-security-dashboard)
+- [Application Security](../application_security/security_dashboard/index.md)
- [Contribution](../group/contribution_analytics/index.md)
- [DevOps Adoption](../group/devops_adoption/index.md)
- [Insights](../group/insights/index.md)
@@ -36,7 +36,7 @@ GitLab provides several analytics features at the group level. Some of these fea
You can use GitLab to review analytics at the project level. Some of these features require you to use a higher tier than GitLab Free.
-- [Application Security](../application_security/security_dashboard/#project-security-dashboard)
+- [Application Security](../application_security/security_dashboard/index.md)
- [CI/CD](ci_cd_analytics.md)
- [Code Review](code_review_analytics.md)
- [Insights](../project/insights/index.md)
diff --git a/doc/user/analytics/issue_analytics.md b/doc/user/analytics/issue_analytics.md
index af7307eab39..6aa2f594532 100644
--- a/doc/user/analytics/issue_analytics.md
+++ b/doc/user/analytics/issue_analytics.md
@@ -5,11 +5,11 @@ group: Optimize
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Issue Analytics **(PREMIUM)**
+# Issue analytics for projects **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196561) in GitLab 12.9.
-Issue Analytics is a bar graph which illustrates the number of issues created each month.
+Issue analytics is a bar graph which illustrates the number of issues created each month.
The default time span is 13 months, which includes the current month, and the 12 months
prior.
diff --git a/doc/user/analytics/repository_analytics.md b/doc/user/analytics/repository_analytics.md
index 936504187b4..5fd4a567b58 100644
--- a/doc/user/analytics/repository_analytics.md
+++ b/doc/user/analytics/repository_analytics.md
@@ -4,38 +4,36 @@ group: Optimize
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Repository Analytics **(FREE)**
+# Repository analytics for projects **(FREE)**
-Get high-level overview of the project's Git repository.
+Use repository analytics to view information about a project's Git repository:
-![Repository Analytics](img/repository_analytics_v13_0.png)
+- Programming languages used in the repository.
+- Code coverage history from last 3 months ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33743) in GitLab 13.1).
+- Commit statistics (last month).
+- Commits per day of month.
+- Commits per weekday.
+- Commits per day hour (UTC).
-## Availability
+Repository analytics is part of [GitLab Community Edition](https://gitlab.com/gitlab-org/gitlab-foss). It's available to anyone who has permission to clone the repository.
-Repository Analytics is part of [GitLab Community Edition](https://gitlab.com/gitlab-org/gitlab-foss). It's available to anyone who has permission to clone the repository.
-
-The feature requires:
+Repository analytics requires:
- An initialized Git repository.
- At least one commit in the default branch (`master` by default).
-## Overview
-
-You can find Repository Analytics in the project's sidebar. To access the page, go to **{chart}** **Analytics > Repository**.
-
NOTE:
-Without a Git commit in the default branch, the menu item won't be visible.
+Without a Git commit in the default branch, the menu item isn't visible.
Commits in a project's [wiki](../project/wiki/index.md#track-wiki-events) are not included in the analysis.
-### Charts
+## View repository analytics
+
+To review repository analytics for a project:
-The data in the charts are queued. Background workers update the charts 10 minutes after each commit in the default branch. Depending on the size of the GitLab installation, it may take longer for data to refresh due to variations in the size of background job queues.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Analytics > Repository**.
-Available charts:
+## How repository analytics chart data is updated
-- Programming languages used in the repository
-- Code coverage history (last 3 months) ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33743) in GitLab 13.1)
-- Commit statistics (last month)
-- Commits per day of month
-- Commits per weekday
-- Commits per day hour (UTC)
+Data in the charts are queued. Background workers update the charts 10 minutes after each commit in the default branch.
+Depending on the size of the GitLab installation, it may take longer for data to refresh due to variations in the size of background job queues.
diff --git a/doc/user/analytics/value_stream_analytics.md b/doc/user/analytics/value_stream_analytics.md
index cb6b2e49f60..6bad374c371 100644
--- a/doc/user/analytics/value_stream_analytics.md
+++ b/doc/user/analytics/value_stream_analytics.md
@@ -4,31 +4,34 @@ group: Optimize
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Value Stream Analytics **(FREE)**
+# Value stream analytics for projects **(FREE)**
-> - Introduced as Cycle Analytics prior to GitLab 12.3 at the project level.
+> - Introduced as cycle analytics prior to GitLab 12.3 at the project level.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12077) in GitLab Premium 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.
+> - [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
+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
+(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.
-You can use Value Stream Analytics to determine the velocity of a given
+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.
-For information about how to contribute to the development of Value Stream Analytics, see our [contributor documentation](../../development/value_stream_analytics.md).
+For information about how to contribute to the development of value stream analytics, see our [contributor documentation](../../development/value_stream_analytics.md).
-Project-level Value Stream Analytics is available by using **Project > Analytics > Value Stream**.
+To access value stream analytics for a project:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Analytics > Value stream**.
NOTE:
-[Group-level Value Stream Analytics](../group/value_stream_analytics) is also available.
+[Value stream analytics for groups](../group/value_stream_analytics) is also available.
## Default stages
-The stages tracked by Value Stream Analytics by default represent the [GitLab flow](../../topics/gitlab_flow.md). You can customize these stages in group-level 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.
- **Issue** (Tracker)
- Time to schedule an issue (by milestone or by adding it to an issue board)
@@ -43,7 +46,7 @@ The stages tracked by Value Stream Analytics by default represent the [GitLab fl
- **Staging** (Continuous Deployment)
- Time between merging and deploying to production
-## Filter Value Stream Analytics data
+## Filter value stream analytics data
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/326701) in GitLab 14.3
@@ -60,7 +63,7 @@ To filter results:
1. Select a parameter.
1. Select a value. To find a value in the list, enter the value name.
-![Value stream analytics filter bar](img/project_vsa_filter_v14_3.png "Active filter bar for a project's Value Stream Analytics")
+![Value stream analytics filter bar](img/project_vsa_filter_v14_3.png "Active filter bar for a project's value stream analytics")
### Date ranges
@@ -72,7 +75,7 @@ from the date picker (default: last 30 days).
> Sorting the stage table [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/335974) in GitLab 14.4.
-![Value Stream Analytics Stage table](img/project_vsa_stage_table_v14_4.png "Project VSA stage table")
+![Value stream analytics stage table](img/project_vsa_stage_table_v14_4.png "Project VSA stage table")
The stage table shows a list of related workflow items for the selected stage. This can include:
@@ -108,18 +111,18 @@ The **Time** metrics near the top of the page are measured as follows:
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/337256) in GitLab 11.3.
-Value Stream Analytics exposes two deployment related metrics near the top of the page:
+Value stream analytics exposes two deployment related metrics near the top of the page:
- **Deploys:** The number of successful deployments in the date range.
- **Deployment Frequency:** The average number of successful deployments.
The deployment metrics calculation uses the same method as the
-[group-level Value Stream Analytics](../group/value_stream_analytics/index.md#how-metrics-are-measured).
+[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).
## How the stages are measured
-Value Stream Analytics uses start events and end events to measure the time that an issue or merge request spends in each stage.
+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.
@@ -143,7 +146,7 @@ How this works:
1. For the remaining pairs, review information needed for stages, including
issue creation date and merge request merge time.
-In short, the Value Stream Analytics dashboard tracks data related to [GitLab flow](../../topics/gitlab_flow.md). It does not include data for:
+In short, the value stream analytics dashboard tracks data related to [GitLab flow](../../topics/gitlab_flow.md). It does not include data for:
- Merge requests that do not close an issue.
- Issues that do not include labels present in the issue board.
@@ -152,7 +155,7 @@ In short, the Value Stream Analytics dashboard tracks data related to [GitLab fl
## How the production environment is identified
-Value Stream Analytics identifies production environments based on the
+Value stream analytics identifies production environments based on the
[deployment tier of environments](../../ci/environments/index.md#deployment-tier-of-environments).
## Example workflow
@@ -197,12 +200,12 @@ More information:
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
+ stream analytics, on its dashboard, shows the calculated median elapsed time
for these issues.
## Permissions
-The permissions for the project-level Value Stream Analytics dashboard include:
+The permissions for the value stream analytics for projects dashboard include:
| Project type | Permissions |
|--------------|---------------------------------------|
@@ -214,8 +217,8 @@ You can [read more about permissions](../../user/permissions.md) in general.
## More resources
-Learn more about Value Stream Analytics with the following 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/).
+- [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/application_security/api_fuzzing/index.md b/doc/user/application_security/api_fuzzing/index.md
index a0f14ea59a1..be6b06a0797 100644
--- a/doc/user/application_security/api_fuzzing/index.md
+++ b/doc/user/application_security/api_fuzzing/index.md
@@ -12,10 +12,6 @@ parameters to unexpected values in an effort to cause unexpected behavior and er
backend. This helps you discover bugs and potential security issues that other QA processes may
miss.
-INFO:
-Try fuzz testing in GitLab Ultimate.
-[It's free for 30 days](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=u-api-fuzzing-docs).
-
We recommend that you use fuzz testing in addition to [GitLab Secure](../index.md)'s
other security scanners and your own test processes. If you're using [GitLab CI/CD](../../../ci/index.md),
you can run fuzz tests as part your CI/CD workflow.
@@ -572,6 +568,7 @@ profile increases as the number of tests increases.
|[`FUZZAPI_PROFILE`](#api-fuzzing-profiles) | Configuration profile to use during testing. Defaults to `Quick-10`. |
|[`FUZZAPI_EXCLUDE_PATHS`](#exclude-paths) | Exclude API URL paths from testing. |
|[`FUZZAPI_OPENAPI`](#openapi-specification) | OpenAPI Specification file or URL. |
+|[`FUZZAPI_OPENAPI_RELAXED_VALIDATION`](#openapi-specification) | Relax document validation. Default is disabled. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345950) in GitLab 14.7. |
|[`FUZZAPI_HAR`](#http-archive-har) | HTTP Archive (HAR) file. |
|[`FUZZAPI_POSTMAN_COLLECTION`](#postman-collection) | Postman Collection file. |
|[`FUZZAPI_POSTMAN_COLLECTION_VARIABLES`](#postman-variables) | Path to a JSON file to extract Postman variable values. |
@@ -1293,6 +1290,41 @@ The API Fuzzing template supports launching a docker container containing an API
TODO
-->
+### Use OpenAPI with an invalid schema
+
+There are cases where the document is autogenerated with an invalid schema or cannot be edited manually in a timely manner. In those scenarios, the API Security is able to perform a relaxed validation by setting the variable `FUZZAPI_OPENAPI_RELAXED_VALIDATION`. We recommend providing a fully compliant OpenAPI document to prevent unexpected behaviors.
+
+#### Edit a non-compliant OpenAPI file
+
+To detect and correct elements that don't comply with the OpenAPI specifications, we recommend using an editor. An editor commonly provides document validation, and suggestions to create a schema-compliant OpenAPI document. Suggested editors include:
+
+| Editor | OpenAPI 2.0 | OpenAPI 3.0.x | OpenAPI 3.1.x |
+| -- | -- | -- | -- |
+| [Swagger Editor](https://editor.swagger.io/) | **{check-circle}** YAML, JSON | **{check-circle}** YAML, JSON | **{dotted-circle}** YAML, JSON |
+| [Stoplight Studio](https://stoplight.io/studio/) | **{check-circle}** YAML, JSON | **{check-circle}** YAML, JSON | **{check-circle}** YAML, JSON |
+
+If your OpenAPI document is generated manually, load your document in the editor and fix anything that is non-compliant. If your document is generated automatically, load it in your editor to identify the issues in the schema, then go to the application and perform the corrections based on the framework you are using.
+
+#### Enable OpenAPI relaxed validation
+
+Relaxed validation is meant for cases when the OpenAPI document cannot meet OpenAPI specifications, but it still has enough content to be consumed by different tools. A validation is performed but less strictly in regards to document schema.
+
+API Security can still try to consume an OpenAPI document that does not fully comply with OpenAPI specifications. To instruct API Security to perform a relaxed validation, set the variable `FUZZAPI_OPENAPI_RELAXED_VALIDATION` to any value, for example:
+
+```yaml
+ stages:
+ - fuzz
+
+ include:
+ - template: API-Fuzzing.gitlab-ci.yml
+
+ variables:
+ FUZZAPI_PROFILE: Quick-10
+ FUZZAPI_TARGET_URL: http://test-deployment/
+ FUZZAPI_OPENAPI: test-api-specification.json
+ FUZZAPI_OPENAPI_RELAXED_VALIDATION: On
+```
+
## Get support or request an improvement
To get support for your particular problem please use the [getting help channels](https://about.gitlab.com/get-help/).
diff --git a/doc/user/application_security/cluster_image_scanning/index.md b/doc/user/application_security/cluster_image_scanning/index.md
index c3a2c179590..5f2dd626526 100644
--- a/doc/user/application_security/cluster_image_scanning/index.md
+++ b/doc/user/application_security/cluster_image_scanning/index.md
@@ -41,6 +41,8 @@ in your existing `.gitlab-ci.yml` file.
To enable cluster image scanning in your pipeline, you need the following:
+- Cluster Image 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)
@@ -172,10 +174,10 @@ You can [configure](#customize-the-cluster-image-scanning-settings) analyzers by
| CI/CD Variable | Default | Description |
| ------------------------------ | ------------- | ----------- |
| `CIS_KUBECONFIG` | `""` | File used to configure access to the Kubernetes cluster. See the [Kubernetes documentation](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/) for more details. |
-| `CIS_CONTAINER_NAME` | `""` | Name of the container used in the Kubernetes resource you want to filter vulnerabilities for. For example, `alpine`. |
-| `CIS_RESOURCE_NAME` | `""` | Name of the Kubernetes resource you want to filter vulnerabilities for. For example, `nginx`. |
-| `CIS_RESOURCE_NAMESPACE` | `""` | Namespace of the Kubernetes resource you want to filter vulnerabilities for. For example, `production`. |
-| `CIS_RESOURCE_KIND` | `""` | Kind of the Kubernetes resource you want to filter vulnerabilities for. For example, `deployment`. |
+| `CIS_CONTAINER_NAMES` | `""` | A comma-separated list of container names used in the Kubernetes resources you want to filter vulnerabilities for. For example, `alpine,postgres`. |
+| `CIS_RESOURCE_NAMES` | `""` | A comma-separated list of Kubernetes resources you want to filter vulnerabilities for. For example, `nginx,redis`. |
+| `CIS_RESOURCE_NAMESPACES` | `""` | A comma-separated list of namespaces of the Kubernetes resources you want to filter vulnerabilities for. For example, `production,staging`. |
+| `CIS_RESOURCE_KINDS` | `""` | A comma-separated list of the kinds of Kubernetes resources to filter vulnerabilities for. For example, `deployment,pod`. |
| `CIS_CLUSTER_IDENTIFIER` | `""` | ID of the Kubernetes cluster integrated with GitLab. This is used to map vulnerabilities to the cluster so they can be filtered in the Vulnerability Report page. |
| `CIS_CLUSTER_AGENT_IDENTIFIER` | `""` | ID of the Kubernetes cluster agent integrated with GitLab. This maps vulnerabilities to the agent so they can be filtered in the Vulnerability Report page. |
diff --git a/doc/user/application_security/container_scanning/index.md b/doc/user/application_security/container_scanning/index.md
index bea9284873c..5a2dd5eb54f 100644
--- a/doc/user/application_security/container_scanning/index.md
+++ b/doc/user/application_security/container_scanning/index.md
@@ -9,10 +9,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/3672) in GitLab 10.4.
-INFO:
-Try out Container Scanning in GitLab Ultimate.
-[It's free for 30 days](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=u-container-scanning-docs).
-
Your application's Docker image may itself be based on Docker images that contain known
vulnerabilities. By including an extra Container Scanning job in your pipeline that scans for those
vulnerabilities and displays them in a merge request, you can use GitLab to audit your Docker-based
@@ -52,6 +48,7 @@ information directly in the merge request.
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.
- Docker `18.09.03` or higher installed on the same computer as the runner. If you're using the
@@ -62,6 +59,7 @@ To enable container scanning in your pipeline, you need the following:
- If you're using a third-party container registry, you might need to provide authentication
credentials through the `DOCKER_USER` and `DOCKER_PASSWORD` [configuration variables](#available-cicd-variables).
For more details on how to use these variables, see [authenticate to a remote registry](#authenticate-to-a-remote-registry).
+- GitLab CI/CD pipeline must include the `test` stage, which is available unless overridden with the [`stages`](../../../ci/yaml/index.md#stages) keyword.
## Configuration
diff --git a/doc/user/application_security/coverage_fuzzing/index.md b/doc/user/application_security/coverage_fuzzing/index.md
index b35c2ed79cf..89b4cdcc34d 100644
--- a/doc/user/application_security/coverage_fuzzing/index.md
+++ b/doc/user/application_security/coverage_fuzzing/index.md
@@ -7,14 +7,14 @@ type: reference, howto
# Coverage-guided fuzz testing **(ULTIMATE)**
-Coverage-guided fuzzing sends random inputs to an instrumented version of your application in an
-effort to cause unexpected behavior. Such behavior indicates a bug that you should address.
+Coverage-guided fuzz testing sends random inputs to an instrumented version of your application in
+an effort to cause unexpected behavior. Such behavior indicates a bug that you should address.
GitLab allows you to add coverage-guided fuzz testing to your pipelines. This helps you discover
bugs and potential security issues that other QA processes may miss.
We recommend that you use fuzz testing in addition to the other security scanners in [GitLab Secure](../index.md)
and your own test processes. If you're using [GitLab CI/CD](../../../ci/index.md),
-you can run your coverage-guided fuzz tests as part your CI/CD workflow.
+you can run your coverage-guided fuzz testing as part your CI/CD workflow.
## Coverage-guided fuzz testing process
@@ -30,30 +30,40 @@ The results of the coverage-guided fuzz testing are available in the CI/CD pipel
## Supported fuzzing engines and languages
-GitLab supports these languages through the fuzzing engine listed for each. We currently provide a
-Docker image for apps written in Go, but you can test the other languages below by providing a
-Docker image with the fuzz engine to run your app.
-
-| Language | Fuzzing Engine | Example |
-|----------|----------------|---------|
-| C/C++ | [libFuzzer](https://llvm.org/docs/LibFuzzer.html) | [c-cpp-example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/c-cpp-fuzzing-example) |
-| GoLang | [go-fuzz (libFuzzer support)](https://github.com/dvyukov/go-fuzz) | [go-fuzzing-example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/go-fuzzing-example) |
-| Swift | [libFuzzer](https://github.com/apple/swift/blob/master/docs/libFuzzerIntegration.md) | [swift-fuzzing-example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/swift-fuzzing-example) |
-| Rust | [cargo-fuzz (libFuzzer support)](https://github.com/rust-fuzz/cargo-fuzz) | [rust-fuzzing-example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/rust-fuzzing-example) |
-| Java | [Javafuzz](https://gitlab.com/gitlab-org/security-products/analyzers/fuzzers/javafuzz) (recommended) | [javafuzz-fuzzing-example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/javafuzz-fuzzing-example) |
-| Java | [JQF](https://github.com/rohanpadhye/JQF) (not preferred) | [jqf-fuzzing-example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/java-fuzzing-example) |
-| JavaScript | [`jsfuzz`](https://gitlab.com/gitlab-org/security-products/analyzers/fuzzers/jsfuzz)| [jsfuzz-fuzzing-example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/jsfuzz-fuzzing-example) |
-| Python | [`pythonfuzz`](https://gitlab.com/gitlab-org/security-products/analyzers/fuzzers/pythonfuzz)| [pythonfuzz-fuzzing-example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/pythonfuzz-fuzzing-example) |
-| AFL (any language that works on top of AFL) | [AFL](https://lcamtuf.coredump.cx/afl/)| [afl-fuzzing-example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/afl-fuzzing-example) |
+You can use the following fuzzing engines to test the specified languages.
+
+| Language | Fuzzing Engine | Example |
+|---------------------------------------------|------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------|
+| C/C++ | [libFuzzer](https://llvm.org/docs/LibFuzzer.html) | [c-cpp-example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/c-cpp-fuzzing-example) |
+| GoLang | [go-fuzz (libFuzzer support)](https://github.com/dvyukov/go-fuzz) | [go-fuzzing-example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/go-fuzzing-example) |
+| Swift | [libFuzzer](https://github.com/apple/swift/blob/master/docs/libFuzzerIntegration.md) | [swift-fuzzing-example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/swift-fuzzing-example) |
+| Rust | [cargo-fuzz (libFuzzer support)](https://github.com/rust-fuzz/cargo-fuzz) | [rust-fuzzing-example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/rust-fuzzing-example) |
+| Java | [Javafuzz](https://gitlab.com/gitlab-org/security-products/analyzers/fuzzers/javafuzz) (recommended) | [javafuzz-fuzzing-example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/javafuzz-fuzzing-example) |
+| Java | [JQF](https://github.com/rohanpadhye/JQF) (not preferred) | [jqf-fuzzing-example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/java-fuzzing-example) |
+| JavaScript | [`jsfuzz`](https://gitlab.com/gitlab-org/security-products/analyzers/fuzzers/jsfuzz) | [jsfuzz-fuzzing-example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/jsfuzz-fuzzing-example) |
+| Python | [`pythonfuzz`](https://gitlab.com/gitlab-org/security-products/analyzers/fuzzers/pythonfuzz) | [pythonfuzz-fuzzing-example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/pythonfuzz-fuzzing-example) |
+| AFL (any language that works on top of AFL) | [AFL](https://lcamtuf.coredump.cx/afl/) | [afl-fuzzing-example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/afl-fuzzing-example) |
## Configuration
-To enable fuzzing, you must
-[include](../../../ci/yaml/index.md#includetemplate)
-the [`Coverage-Fuzzing.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml)
-provided as part of your GitLab installation.
+To enable coverage-guided fuzz testing, edit the `.gitlab-ci.yml` file:
+
+1. Add the `fuzz` stage to the list of stages.
+
+1. If your application is not written in Go, [provide a Docker image](../../../ci/yaml/index.md#image) using the matching fuzzing
+ engine. For example:
+
+ ```yaml
+ image: python:latest
+ ```
+
+1. [Include](../../../ci/yaml/index.md#includetemplate) the
+ [`Coverage-Fuzzing.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml)
+ provided as part of your GitLab installation.
-To do so, add the following to your `.gitlab-ci.yml` file:
+1. Customize the `my_fuzz_target` job to meet your requirements.
+
+### Example extract of coverage-guided fuzzing configuration
```yaml
stages:
@@ -65,96 +75,62 @@ include:
my_fuzz_target:
extends: .fuzz_base
script:
- # Build your fuzz target binary in these steps, then run it with gitlab-cov-fuzz>
+ # Build your fuzz target binary in these steps, then run it with gitlab-cov-fuzz
# See our example repos for how you could do this with any of our supported languages
- ./gitlab-cov-fuzz run --regression=$REGRESSION -- <your fuzz target>
```
-The included template makes available the [hidden job](../../../ci/jobs/index.md#hide-jobs)
-`.fuzz_base`, which you must [extend](../../../ci/yaml/index.md#extends) for each of your fuzz
-targets. Each fuzz target **must** have a separate job. For example, the
+The `Coverage-Fuzzing` template includes the [hidden job](../../../ci/jobs/index.md#hide-jobs)
+`.fuzz_base`, which you must [extend](../../../ci/yaml/index.md#extends) for each of your fuzzing
+targets. Each fuzzing target **must** have a separate job. For example, the
[go-fuzzing-example project](https://gitlab.com/gitlab-org/security-products/demos/go-fuzzing-example)
-contains one job that extends `.fuzz_base` for its single fuzz target.
+contains one job that extends `.fuzz_base` for its single fuzzing target.
Note that the hidden job `.fuzz_base` uses several YAML keys that you must not override in your own
-job. If you include these keys in your own job, you must copy their original content. These keys
-are:
+job. If you include these keys in your own job, you must copy their original content:
- `before_script`
- `artifacts`
- `rules`
-The `my_fuzz_target` job (the separate job for your fuzz target) does the following:
+### Available CI/CD variables
+
+Use the following variables to configure coverage-guided fuzz testing in your CI/CD pipeline.
-- Extends `.fuzz_base`.
-- Compiles the fuzz target with [go-fuzz](https://github.com/dvyukov/go-fuzz).
-- Runs the target with the `gitlab-cov-fuzz` command, which is available to each job that extends
- `.fuzz_base`.
-- Runs on a fuzz stage that usually comes after a test stage.
+| CI/CD variable | Description |
+|---------------------------|---------------------------------------------------------------------------------|
+| `COVFUZZ_ADDITIONAL_ARGS` | Arguments passed to `gitlab-cov-fuzz`. Used to customize the behavior of the underlying fuzzing engine. Read the fuzzing engine's documentation for a complete list of arguments. |
+| `COVFUZZ_BRANCH` | The branch on which long-running fuzzing jobs are to be run. On all other branches, only fuzzing regression tests are run. Default: Repository's default branch. |
+| `COVFUZZ_SEED_CORPUS` | Path to a seed corpus directory. Default: empty. |
+| `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`. |
-The `gitlab-cov-fuzz` is a command-line tool that runs the instrumented application. It parses and
-analyzes the exception information that the fuzzer outputs. It also downloads the [corpus](../terminology/index.md#corpus)
-and crash events from previous pipelines automatically. This helps your fuzz targets build on the
-progress of previous fuzzing jobs. The parsed crash events and data are written to
-`gl-coverage-fuzzing-report.json`.
+#### Seed corpus
-### Artifacts
+Files in the [seed corpus](../terminology/index.md#seed-corpus) must be updated manually. They are
+not updated or overwritten by the coverage-guide fuzz testing job.
+
+## Output
Each fuzzing step outputs these artifacts:
-- `gl-coverage-fuzzing-report.json`: This file's format may change in future releases.
+- `gl-coverage-fuzzing-report.json`: A report containing details of the coverage-guided fuzz testing
+ and its results.
- `artifacts.zip`: This file contains two directories:
- - `corpus`: Holds all test cases generated by the current and all previous jobs.
- - `crashes`: Holds all crash events the current job encountered as well as those not fixed in
+ - `corpus`: Contains all test cases generated by the current and all previous jobs.
+ - `crashes`: Contains all crash events the current job found and those not fixed in
previous jobs.
-### Types of fuzzing jobs
-
-There are two types of jobs:
-
-- Fuzzing: Standard fuzzing session. You can configure a long session through a user defined
- timeout.
-- Regression: Run the fuzz targets through the accumulated test cases generated by previous fuzzing
- sessions plus fixed crashes from previous sessions. This is usually very quick.
-
-Here's our current suggestion for configuring your fuzz target's timeout:
-
-- Set `COVFUZZ_BRANCH` to the branch where you want to run long-running (asynchronous) fuzzing
- jobs. This is normally the default branch.
-- Use regression or short-running fuzzing jobs for other branches or merge requests.
-
-This suggestion helps find new bugs on the development branch and catch old bugs in merge requests
-(like unit tests).
-
-You can configure this by passing `--regression=false/true` to `gitlab-cov-fuzz` as the [Go example](https://gitlab.com/gitlab-org/security-products/demos/go-fuzzing-example/-/blob/master/.gitlab-ci.yml)
-shows. Also note that `gitlab-cov-fuzz` is a wrapper, so you can pass those arguments to configure
-any option available in the underlying fuzzing engine.
-
-### Available CI/CD variables
-
-| CI/CD variable | Description |
-|-----------------------|--------------------------------------------------------------------------------|
-| `COVFUZZ_BRANCH` | The branch for long-running fuzzing jobs. This is normally the default branch. |
-| `COVFUZZ_SEED_CORPUS` | Path to a seed corpus directory. The default is empty. |
-| `COVFUZZ_URL_PREFIX` | Path to the `gitlab-cov-fuzz` repository cloned for use with an offline environment. You should only change this when using an offline environment. The default value is `https://gitlab.com/gitlab-org/security-products/analyzers/gitlab-cov-fuzz/-/raw`. |
-
-The files in the [seed corpus](../terminology/index.md#seed-corpus) (`COVFUZZ_SEED_CORPUS`), if provided, aren't updated unless you commit new
-files to your Git repository. There's usually no need to frequently update the seed corpus. As part
-of the GitLab artifacts system, GitLab saves in a corpus directory the new test cases that every run
-generates. In any subsequent runs, GitLab also reuses the generated corpus together with the seed
-corpus.
+You can download the JSON report file from the CI/CD pipelines page. For more information, see
+[Downloading artifacts](../../../ci/pipelines/job_artifacts.md#download-job-artifacts).
-### Reports JSON format
+### Coverage-guided fuzz testing report
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/220062) in GitLab 13.3 as an [Alpha feature](https://about.gitlab.com/handbook/product/gitlab-the-product/#alpha).
-The `gitlab-cov-fuzz` tool emits a JSON report file. For more information, see the
-[schema for this report](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/dist/coverage-fuzzing-report-format.json).
-
-You can download the JSON report file from the CI pipelines page. For more information, see
-[Downloading artifacts](../../../ci/pipelines/job_artifacts.md#download-job-artifacts).
+For detailed information about the `gl-coverage-fuzzing-report.json` file's format, read the
+[schema](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/dist/coverage-fuzzing-report-format.json).
-Here's an example coverage fuzzing report:
+Example coverage-guided fuzzing report:
```json-doc
{
@@ -183,38 +159,30 @@ Here's an example coverage fuzzing report:
}
```
-### Additional configuration
-
-The `gitlab-cov-fuzz` command passes all arguments it receives to the underlying fuzzing engine. You
-can therefore use all the options available in that fuzzing engine. For more information on these
-options, see the underlying fuzzing engine's documentation.
-
-### Offline environment
+## Duration of coverage-guided fuzz testing
-To use coverage fuzzing in an offline environment, follow these steps:
+The available durations for coverage-guided fuzz testing are: 10 minutes (default) and 60 minutes.
-1. Clone [`gitlab-cov-fuzz`](https://gitlab.com/gitlab-org/security-products/analyzers/gitlab-cov-fuzz)
- to a private repository that your offline GitLab instance can access.
+- 10-minute duration: Recommended for the default branch.
+- 60-minute duration: Recommended for the development branch and merge requests. The longer duration provides greater coverage.
+ In the `COVFUZZ_ADDITIONAL_ARGS` variable set the value `--regression=true`.
-1. For each fuzzing step, set `COVFUZZ_URL_PREFIX` to `${NEW_URL_GITLAB_COV_FUZ}/-/raw`, where
- `NEW_URL_GITLAB_COV_FUZ` is the URL of the private `gitlab-cov-fuzz` clone that you set up in the
- first step.
+For a complete example, read the [Go coverage-guided fuzzing example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/go-fuzzing-example/-/blob/master/.gitlab-ci.yml).
-### Continuous fuzzing (long-running asynchronous fuzzing jobs)
+### Continuous coverage-guided fuzz testing
-It's also possible to run the fuzzing jobs longer and without blocking your main pipeline. This
-configuration uses the GitLab [parent-child pipelines](../../../ci/pipelines/parent_child_pipelines.md).
-The full example is available in the [repository](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/go-fuzzing-example/-/tree/continuous_fuzzing#running-go-fuzz-from-ci).
-This example uses Go, but is applicable for any other supported languages.
+It's also possible to run the coverage-guided fuzzing jobs longer and without blocking your main
+pipeline. This configuration uses the GitLab
+[parent-child pipelines](../../../ci/pipelines/parent_child_pipelines.md).
-The suggested workflow in this scenario is to have long-running, asynchronous fuzzing jobs on a
-main/development branch, and short, blocking sync fuzzing jobs on all other branches and MRs. This
-is a good way to balance the needs of letting a developer's per-commit pipeline complete quickly,
-and also giving the fuzzer a large amount of time to fully explore and test the app.
+The suggested workflow in this scenario is to have long-running, asynchronous fuzzing jobs on the
+main or development branch, and short synchronous fuzzing jobs on all other branches and MRs. This
+balances the needs of completing the per-commit pipeline complete quickly, while also giving the
+fuzzer a large amount of time to fully explore and test the app. Long-running fuzzing jobs are
+usually necessary for the coverage-guided fuzzer to find deeper bugs in your codebase.
-Long-running fuzzing jobs are usually necessary for the coverage guided fuzzer to find deeper bugs
-in your latest codebase. The following is an example of what `.gitlab-ci.yml` looks like in this
-workflow (for the full example, see the [repository](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/go-fuzzing-example/-/tree/continuous_fuzzing)):
+The following is an extract of the `.gitlab-ci.yml` file for this
+workflow. For the full example, see the [Go fuzzing example's repository](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/go-fuzzing-example/-/tree/continuous_fuzzing):
```yaml
@@ -236,7 +204,7 @@ async_fuzzing:
- if: $CI_COMMIT_BRANCH == 'continuous_fuzzing' && $CI_PIPELINE_SOURCE != 'merge_request_event'
```
-This essentially creates two steps:
+This creates two jobs:
1. `sync_fuzzing`: Runs all your fuzz targets for a short period of time in a blocking
configuration. This finds simple bugs and allows you to be confident that your MRs aren't
@@ -246,6 +214,17 @@ This essentially creates two steps:
The `covfuzz-ci.yml` is the same as that in the [original synchronous example](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/go-fuzzing-example#running-go-fuzz-from-ci).
+## Offline environment
+
+To use coverage fuzzing in an offline environment:
+
+1. Clone [`gitlab-cov-fuzz`](https://gitlab.com/gitlab-org/security-products/analyzers/gitlab-cov-fuzz)
+ to a private repository that your offline GitLab instance can access.
+
+1. For each fuzzing step, set `COVFUZZ_URL_PREFIX` to `${NEW_URL_GITLAB_COV_FUZ}/-/raw`, where
+ `NEW_URL_GITLAB_COV_FUZ` is the URL of the private `gitlab-cov-fuzz` clone that you set up in the
+ first step.
+
## Interacting with the vulnerabilities
After a vulnerability is found, you can [address it](../vulnerabilities/index.md).
diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md
index 4de7a566769..aeaa93f4a85 100644
--- a/doc/user/application_security/dast/index.md
+++ b/doc/user/application_security/dast/index.md
@@ -16,10 +16,6 @@ Dynamic Application Security Testing (DAST) examines applications for
vulnerabilities like these in deployed environments. DAST uses the open source
tool [OWASP Zed Attack Proxy](https://www.zaproxy.org/) for analysis.
-INFO:
-Want to try out security scanning?
-[Try GitLab Ultimate free for 30 days](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=u-dast-docs).
-
After DAST creates its report, GitLab evaluates it for discovered
vulnerabilities between the source and target branches. Relevant
findings are noted in the merge request.
@@ -57,6 +53,7 @@ results. On failure, the analyzer outputs an
- [GitLab Runner](../../../ci/runners/index.md) available, with the
[`docker` executor](https://docs.gitlab.com/runner/executors/docker.html).
- Target application deployed. For more details, read [Deployment options](#deployment-options).
+- DAST 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.
### Deployment options
@@ -638,7 +635,7 @@ These CI/CD variables are specific to DAST. They can be used to customize the be
| `DAST_XML_REPORT` | string | The filename of the XML report written at the end of a scan. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12652) in GitLab 13.1. |
| `DAST_WEBSITE` <sup>1</sup> | URL | The URL of the website to scan. The variable `DAST_API_OPENAPI` must be specified if this is omitted. |
| `DAST_ZAP_CLI_OPTIONS` | string | ZAP server command-line options. For example, `-Xmx3072m` would set the Java maximum memory allocation pool size. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12652) in GitLab 13.1. |
-| `DAST_ZAP_LOG_CONFIGURATION` | string | Set to a semicolon-separated list of additional log4j properties for the ZAP Server. Example: `log4j.logger.org.parosproxy.paros.network.HttpSender=DEBUG;log4j.logger.com.crawljax=DEBUG` |
+| `DAST_ZAP_LOG_CONFIGURATION` | string | Set to a semicolon-separated list of additional log4j properties for the ZAP Server. Example: `logger.httpsender.name=org.parosproxy.paros.network.HttpSender;logger.httpsender.level=debug;logger.sitemap.name=org.parosproxy.paros.model.SiteMap;logger.sitemap.level=debug;` |
| `SECURE_ANALYZERS_PREFIX` | URL | Set the Docker registry base address from which to download the analyzer. |
1. Available to an on-demand DAST scan.
@@ -969,6 +966,8 @@ To view running completed and scheduled on-demand DAST scans for a project, go t
failed, or was canceled.
- To view scheduled scans, select **Scheduled**. It shows on-demand scans that have a schedule
set up. Those are _not_ included in the **All** tab.
+- To view saved on-demand scan profiles, select **Scan library**.
+ Those are _not_ included in the **All** tab.
#### Cancel an on-demand scan
@@ -1036,10 +1035,8 @@ The on-demand DAST scan runs and the project's dashboard shows the results.
To run a saved on-demand scan:
1. On the top bar, select **Menu > Projects** and find your project.
-1. On the left sidebar, select **Security & Compliance > Configuration**.
-1. Select **Manage DAST scans**.
-1. In the **DAST Profiles** row, select **Manage**.
-1. Select the **Saved Scans** tab.
+1. On the left sidebar, select **Security & Compliance > On-demand Scans**.
+1. Select the **Scan library** tab.
1. In the scan's row, select **Run scan**.
If the branch saved in the scan no longer exists, you must first
@@ -1075,27 +1072,23 @@ To schedule a scan:
To list saved on-demand scans:
-1. From your project's home page, go to **Security & Compliance > Configuration**.
-1. Select the **Saved Scans** tab.
+1. From your project's home page, go to **Security & Compliance > On-demand Scans**.
+1. Select the **Scan library** tab.
#### View details of an on-demand scan
To view details of an on-demand scan:
-1. From your project's home page, go to **Security & Compliance > Configuration**.
-1. Select **Manage DAST scans**.
-1. Select **Manage** in the **DAST Profiles** row.
-1. Select the **Saved Scans** tab.
+1. From your project's home page, go to **Security & Compliance > On-demand Scans**.
+1. Select the **Scan library** tab.
1. In the saved scan's row select **More actions** (**{ellipsis_v}**), then select **Edit**.
#### Edit an on-demand scan
To edit an on-demand scan:
-1. From your project's home page, go to **Security & Compliance > Configuration**.
-1. Select **Manage DAST scans**.
-1. Select **Manage** in the **DAST Profiles** row.
-1. Select the **Saved Scans** tab.
+1. From your project's home page, go to **Security & Compliance > On-demand Scans**.
+1. Select the **Scan library** tab.
1. In the saved scan's row select **More actions** (**{ellipsis_v}**), then select **Edit**.
1. Edit the form.
1. Select **Save scan**.
@@ -1104,10 +1097,8 @@ To edit an on-demand scan:
To delete an on-demand scan:
-1. From your project's home page, go to **Security & Compliance > Configuration**.
-1. Select **Manage DAST scans**.
-1. Select **Manage** in the **DAST Profiles** row.
-1. Select the **Saved Scans** tab.
+1. From your project's home page, go to **Security & Compliance > On-demand Scans**.
+1. Select the **Scan library** tab.
1. In the saved scan's row select **More actions** (**{ellipsis_v}**), then select **Delete**.
1. Select **Delete** to confirm the deletion.
@@ -1132,6 +1123,9 @@ A site profile contains the following:
When an API site type is selected, a [host override](#host-override) is used to ensure the API being scanned is on the same host as the target. This is done to reduce the risk of running an active scan against the wrong API.
+When configured, request headers and password fields are encrypted using [`aes-256-gcm`](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) before being stored in the database.
+This data can only be read and decrypted with a valid secrets file.
+
#### Site profile validation
> - Site profile validation [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233020) in GitLab 13.8.
diff --git a/doc/user/application_security/dast_api/index.md b/doc/user/application_security/dast_api/index.md
index 0db5fb2d868..f1eba505589 100644
--- a/doc/user/application_security/dast_api/index.md
+++ b/doc/user/application_security/dast_api/index.md
@@ -214,7 +214,7 @@ target API to test:
DAST_API_PROFILE: Quick
```
-1. Provide the location of the HAR specification. You can provide the specification as a file
+1. Provide the location of the HAR file. You can provide the location as a file path
or URL. [URL support was introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/285020) in GitLab 13.10 and later. Specify the location by adding the `DAST_API_HAR` variable:
```yaml
@@ -314,7 +314,7 @@ information about the target API to test:
DAST_API_PROFILE: Quick
```
-1. Provide the location of the Postman Collection specification. You can provide the specification as a file or URL. Specify the location by adding the `DAST_API_POSTMAN_COLLECTION` variable:
+1. Provide the location of the Postman Collection file. You can provide the location as a file or URL. Specify the location by adding the `DAST_API_POSTMAN_COLLECTION` variable:
```yaml
stages:
@@ -637,6 +637,7 @@ can be added, removed, and modified by creating a custom configuration.
|[`DAST_API_PROFILE`](#configuration-files) | Configuration profile to use during testing. Defaults to `Quick`. |
|[`DAST_API_EXCLUDE_PATHS`](#exclude-paths) | Exclude API URL paths from testing. |
|[`DAST_API_OPENAPI`](#openapi-specification) | OpenAPI specification file or URL. |
+|[`DAST_API_OPENAPI_RELAXED_VALIDATION`](#openapi-specification) | Relax document validation. Default is disabled. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345950) in GitLab 14.7. |
|[`DAST_API_HAR`](#http-archive-har) | HTTP Archive (HAR) file. |
|[`DAST_API_POSTMAN_COLLECTION`](#postman-collection) | Postman Collection file. |
|[`DAST_API_POSTMAN_COLLECTION_VARIABLES`](#postman-variables) | Path to a JSON file to extract postman variable values. |
@@ -1209,6 +1210,41 @@ deploy-test-target:
- environment_url.txt
```
+### Use OpenAPI with an invalid schema
+
+There are cases where the document is autogenerated with an invalid schema or cannot be edited manually in a timely manner. In those scenarios, the API Security is able to perform a relaxed validation by setting the variable `DAST_API_OPENAPI_RELAXED_VALIDATION`. We recommend providing a fully compliant OpenAPI document to prevent unexpected behaviors.
+
+#### Edit a non-compliant OpenAPI file
+
+To detect and correct elements that don't comply with the OpenAPI specifications, we recommend using an editor. An editor commonly provides document validation, and suggestions to create a schema-compliant OpenAPI document. Suggested editors include:
+
+| Editor | OpenAPI 2.0 | OpenAPI 3.0.x | OpenAPI 3.1.x |
+| -- | -- | -- | -- |
+| [Swagger Editor](https://editor.swagger.io/) | **{check-circle}** YAML, JSON | **{check-circle}** YAML, JSON | **{dotted-circle}** YAML, JSON |
+| [Stoplight Studio](https://stoplight.io/studio/) | **{check-circle}** YAML, JSON | **{check-circle}** YAML, JSON | **{check-circle}** YAML, JSON |
+
+If your OpenAPI document is generated manually, load your document in the editor and fix anything that is non-compliant. If your document is generated automatically, load it in your editor to identify the issues in the schema, then go to the application and perform the corrections based on the framework you are using.
+
+#### Enable OpenAPI relaxed validation
+
+Relaxed validation is meant for cases when the OpenAPI document cannot meet OpenAPI specifications, but it still has enough content to be consumed by different tools. A validation is performed but less strictly in regards to document schema.
+
+API Security can still try to consume an OpenAPI document that does not fully comply with OpenAPI specifications. To instruct API Security to perform a relaxed validation, set the variable `DAST_API_OPENAPI_RELAXED_VALIDATION` to any value, for example:
+
+```yaml
+ stages:
+ - dast
+
+ include:
+ - template: DAST-API.gitlab-ci.yml
+
+ variables:
+ DAST_API_PROFILE: Quick
+ DAST_API_TARGET_URL: http://test-deployment/
+ DAST_API_OPENAPI: test-api-specification.json
+ DAST_API_OPENAPI_RELAXED_VALIDATION: On
+```
+
## Get support or request an improvement
To get support for your particular problem please use the [getting help channels](https://about.gitlab.com/get-help/).
diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md
index 192d8449297..a8cc33d5545 100644
--- a/doc/user/application_security/dependency_scanning/index.md
+++ b/doc/user/application_security/dependency_scanning/index.md
@@ -7,10 +7,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Dependency Scanning **(ULTIMATE)**
-INFO:
-Try out Dependency Scanning in GitLab Ultimate.
-[It's free for 30 days](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=u-dependency-scanning-docs).
-
The Dependency Scanning feature can automatically find security vulnerabilities in your
software dependencies while you're developing and testing your applications. For example,
dependency scanning lets you know if your application uses an external (open source)
@@ -67,6 +63,9 @@ vulnerability.
## Requirements
+Dependency 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.
+
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.
@@ -922,6 +921,8 @@ gemnasium-dependency_scanning:
## Warnings
+We recommend that you use the most recent version of all containers, and the most recent supported version of all package managers and languages. Using previous versions carries an increased security risk because unsupported versions may no longer benefit from active security reporting and backporting of security fixes.
+
### Python projects
Extra care needs to be taken when using the [`PIP_EXTRA_INDEX_URL`](https://pipenv.pypa.io/en/latest/cli/#envvar-PIP_EXTRA_INDEX_URL)
diff --git a/doc/user/application_security/iac_scanning/index.md b/doc/user/application_security/iac_scanning/index.md
index c17ebc68b4d..4d5c1da3c47 100644
--- a/doc/user/application_security/iac_scanning/index.md
+++ b/doc/user/application_security/iac_scanning/index.md
@@ -14,6 +14,8 @@ Currently, IaC scanning supports configuration files for Terraform, Ansible, AWS
## Requirements
+IaC 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.
+
To run IaC 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.
@@ -48,7 +50,7 @@ as shown in the following table:
| Capability | In Free | In Ultimate |
|:---------------------------------------------------------------------------------------|:--------------------|:-------------------|
-| [Configure IaC Scanners](#configuration) v | **{check-circle}** | **{check-circle}** |
+| [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}** |
| [Address vulnerabilities](../../application_security/vulnerabilities/index.md) | **{dotted-circle}** | **{check-circle}** |
diff --git a/doc/user/application_security/index.md b/doc/user/application_security/index.md
index 5500f5a10c4..f5c727a1418 100644
--- a/doc/user/application_security/index.md
+++ b/doc/user/application_security/index.md
@@ -16,10 +16,6 @@ GitLab can check your application for security vulnerabilities including:
Statistics and details on vulnerabilities are included in the merge request. Providing
actionable information _before_ changes are merged enables you to be proactive.
-INFO:
-Want to try out security scanning?
-[Try GitLab Ultimate free for 30 days](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=u-application-security-docs).
-
GitLab also provides high-level statistics of vulnerabilities across projects and groups:
- The [Security Dashboard](security_dashboard/index.md) provides a
@@ -119,7 +115,9 @@ rules:
If you add the security scanning jobs as described in [Security scanning with Auto DevOps](#security-scanning-with-auto-devops) or [Security scanning without Auto DevOps](#security-scanning-without-auto-devops) to your `.gitlab-ci.yml` each added [security scanning tool](#security-scanning-tools) behave as described below.
-For each compatible analyzer, a job is created in the `test`, `dast` or `fuzz` stage of your pipeline and runs on the next new branch pipeline. Features such as the [Security Dashboard](security_dashboard/index.md), [Vulnerability Report](vulnerability_report/index.md), and [Dependency List](dependency_list/index.md) that rely on this scan data only show results from pipelines on the default branch. One tool might use many analyzers.
+For each compatible analyzer, a job is created in the `test`, `dast` or `fuzz` stage of your pipeline and runs on the next new branch pipeline.
+Features such as the [Security Dashboard](security_dashboard/index.md), [Vulnerability Report](vulnerability_report/index.md), and [Dependency List](dependency_list/index.md)
+that rely on this scan data only show results from pipelines on the default branch, only if all jobs are finished, including manual ones. One tool might use many analyzers.
Our language and package manager specific jobs attempt to assess which analyzer(s) they should run for your project so that you can do less configuration.
@@ -172,7 +170,7 @@ From the merge request security widget, select **Expand** to unfold the widget,
A pipeline's security tab lists all findings in the current branch. It includes new findings introduced by this branch and existing vulnerabilities that were already present when the branch was created. These results likely do not match the findings displayed in the Merge Request security widget as those do not include the existing vulnerabilities (with the exception of showing any existing vulnerabilities that are no longer detected in the feature branch).
-For more details, see [security tab](security_dashboard/index.md#pipeline-security).
+For more details, see [security tab](security_dashboard/index.md#view-vulnerabilities-in-a-pipeline).
## View security scan information in the Security Dashboard
@@ -406,9 +404,9 @@ sast:
You can interact with the results of the security scanning tools in several locations:
- [Scan information in merge requests](#view-security-scan-information-in-merge-requests)
-- [Project Security Dashboard](security_dashboard/#project-security-dashboard)
-- [Security pipeline tab](security_dashboard/#pipeline-security)
-- [Group Security Dashboard](security_dashboard/#group-security-dashboard)
+- [Project Security Dashboard](security_dashboard/index.md)
+- [Security pipeline tab](security_dashboard/index.md)
+- [Group Security Dashboard](security_dashboard/index.md)
- [Security Center](security_dashboard/#security-center)
- [Vulnerability Report](vulnerability_report/index.md)
- [Vulnerability Pages](vulnerabilities/index.md)
@@ -441,6 +439,46 @@ When customizing the configuration:
version contains the most recent changes, but may have significant changes between minor GitLab versions.
- Only override values in the template as needed. All other values are inherited from the template.
+### Enforce scan execution
+
+Security and compliance teams must ensure that security scans:
+
+- Run on a regular basis for all projects.
+- Can't be disabled by developers.
+
+GitLab provides two methods of accomplishing this, each with advantages and disadvantages.
+
+- [Compliance framework pipelines](../project/settings/#compliance-pipeline-configuration)
+ are recommended when:
+
+ - Scan execution enforcement is required for SAST IaC, Container Scanning, Dependency Scanning,
+ License Compliance, API Fuzzing, or Coverage-guided Fuzzing.
+ - Scan execution enforcement of SAST or Secret Detection when customization of the default scan
+ variables is required.
+ - Scan execution enforcement is required for scanners external to GitLab.
+ - Enforced execution is required for custom jobs other than security scans.
+
+- [Scan execution policies](policies/#scan-execution-policies)
+ are recommended when:
+
+ - Scan execution enforcement is required for DAST.
+ - Scan execution enforcement is required for SAST or Secret Detection with the default scan
+ variables.
+ - Scans are required to run on a regular, scheduled cadence.
+
+Additional details about the differences between the two solutions are outlined below:
+
+| | Compliance Framework Pipelines | Scan Execution Policies |
+| ------ | ------ | ------ |
+| **Flexibility** | Supports anything that can be done in a CI file. | Limited to only the items for which GitLab has explicitly added support. DAST, SAST, and Secret Detection scans are supported. |
+| **Usability** | Requires knowledge of CI YAML. | Follows a `rules` and `actions`-based YAML structure. |
+| **Inclusion in CI pipeline** | The compliance pipeline is executed instead of the project's `gitlab-ci.yml` file. To include the project's `gitlab-ci.yml` file, use an `include` statement. Defined variables aren't allowed to be overwritten by the included project's YAML file. | Forced inclusion of a new job into the CI pipeline. DAST jobs that must be customized on a per-project basis can have project-level Site Profiles and Scan Profiles defined. To ensure separation of duties, these profiles are immutable when referenced in a scan execution policy. |
+| **Schedulable** | Can be scheduled through a scheduled pipeline on the group. | Can be scheduled natively through the policy configuration itself. |
+| **Separation of Duties** | Only group owners can create compliance framework labels. Only project owners can apply compliance framework labels to projects. The ability to make or approve changes to the compliance pipeline definition is limited to individuals who are explicitly given access to the project that contains the compliance pipeline. | Only project owners can define a linked security policy project. The ability to make or approve changes to security policies is limited to individuals who are explicitly given access to the security policy project. |
+| **Ability to apply one standard to multiple projects** | The same compliance framework label can be applied to multiple projects inside a group. | The same security policy project can be used for multiple projects across GitLab with no requirement of being located in the same group. |
+
+Feedback is welcome on our vision for [unifying the user experience for these two features](https://gitlab.com/groups/gitlab-org/-/epics/7312)
+
## Troubleshooting
### Secure job failing with exit code 1
@@ -609,3 +647,15 @@ such as changing `variables` or the `stage`, but they cannot be used to define s
There [is an issue open to improve extendability](https://gitlab.com/gitlab-org/gitlab/-/issues/218444).
Please upvote the issue to help with prioritization, and
[contributions are welcomed](https://about.gitlab.com/community/contribute/).
+
+### Empty Vulnerability Report, Dependency List, License list pages
+
+If the pipeline has manual steps with a job that has the `allow_failure: false` option, and this job is not finished,
+GitLab can't populate listed pages with the data from security reports.
+In this case, [the Vulnerability Report](vulnerability_report/index.md), [the Dependency List](dependency_list/index.md),
+and [the License list](../compliance/license_compliance/index.md#license-list) pages will be empty.
+These security pages can be populated by running the jobs from the manual step of the pipeline.
+
+There is [an issue open to handle this scenario](https://gitlab.com/gitlab-org/gitlab/-/issues/346843).
+Please upvote the issue to help with prioritization, and
+[contributions are welcomed](https://about.gitlab.com/community/contribute/).
diff --git a/doc/user/application_security/policies/img/scan_execution_policy_yaml_mode_v14_3.png b/doc/user/application_security/policies/img/scan_execution_policy_yaml_mode_v14_3.png
deleted file mode 100644
index d04905eda59..00000000000
--- a/doc/user/application_security/policies/img/scan_execution_policy_yaml_mode_v14_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/application_security/policies/img/scan_execution_policy_yaml_mode_v14_7.png b/doc/user/application_security/policies/img/scan_execution_policy_yaml_mode_v14_7.png
new file mode 100644
index 00000000000..04768d2e18a
--- /dev/null
+++ b/doc/user/application_security/policies/img/scan_execution_policy_yaml_mode_v14_7.png
Binary files differ
diff --git a/doc/user/application_security/policies/index.md b/doc/user/application_security/policies/index.md
index e6dbd96537f..11f2b91177a 100644
--- a/doc/user/application_security/policies/index.md
+++ b/doc/user/application_security/policies/index.md
@@ -236,20 +236,32 @@ Project owners can unlink Security Policy projects from development projects. To
the steps described in [Security Policy project selection](#security-policy-project-selection),
but select the trash can icon in the modal.
+## Scan execution policies
+
+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.
+
+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).
+
### Scan Execution Policy editor
NOTE:
Only project Owners have the [permissions](../../permissions.md#project-members-permissions)
to select Security Policy Project.
-Once your policy is complete, save it by selecting **Create merge request**
+Once your policy is complete, save it by selecting **Create via merge request**
at the bottom of the editor. You are redirected to the merge request on the project's
configured security policy project. If one does not link to your project, a security
policy project is automatically created. Existing policies can also be
removed from the editor interface by selecting **Delete policy**
at the bottom of the editor.
-![Scan Execution Policy Editor YAML Mode](img/scan_execution_policy_yaml_mode_v14_3.png)
+![Scan Execution Policy Editor YAML Mode](img/scan_execution_policy_yaml_mode_v14_7.png)
The policy editor currently only supports the YAML mode. The Rule mode is tracked in the [Allow Users to Edit Rule-mode Scan Execution Policies in the Policy UI](https://gitlab.com/groups/gitlab-org/-/epics/5363) epic.
@@ -301,10 +313,10 @@ Use this schema to define `clusters` objects in the [`schedule` rule type](#sche
| Field | Type | Possible values | Description |
|--------------|---------------------|--------------------------|-------------|
-| `containers` | `array` of `string` | | The container name to be scanned (only the first value is currently supported). |
-| `resources` | `array` of `string` | | The resource name to be scanned (only the first value is currently supported). |
-| `namespaces` | `array` of `string` | | The namespace to be scanned (only the first value is currently supported). |
-| `kinds` | `array` of `string` | `deployment`/`daemonset` | The resource kind to be scanned (only the first value is currently supported). |
+| `containers` | `array` of `string` | | The container name that is scanned (only the first value is currently supported). |
+| `resources` | `array` of `string` | | The resource name that is scanned (only the first value is currently supported). |
+| `namespaces` | `array` of `string` | | The namespace that is scanned (only the first value is currently supported). |
+| `kinds` | `array` of `string` | `deployment`/`daemonset` | The resource kind that should be scanned (only the first value is currently supported). |
### `scan` action type
@@ -389,7 +401,7 @@ scan_execution_policy:
enabled: true
rules:
- type: schedule
- cadence: "15 3 * * *
+ cadence: "15 3 * * *"
clusters:
production-cluster:
containers:
diff --git a/doc/user/application_security/sast/analyzers.md b/doc/user/application_security/sast/analyzers.md
index 8c7e03f69fd..7529bf90ccf 100644
--- a/doc/user/application_security/sast/analyzers.md
+++ b/doc/user/application_security/sast/analyzers.md
@@ -6,8 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# SAST Analyzers **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3775) in GitLab 10.3.
-> - [Moved](https://gitlab.com/groups/gitlab-org/-/epics/2098) from GitLab Ultimate to GitLab Free in 13.3.
+> [Moved](https://gitlab.com/groups/gitlab-org/-/epics/2098) from GitLab Ultimate to GitLab Free in 13.3.
SAST relies on underlying third party tools that are wrapped into what we call
"Analyzers". An analyzer is a
diff --git a/doc/user/application_security/sast/index.md b/doc/user/application_security/sast/index.md
index fd05ecad8f2..de2f9af82c7 100644
--- a/doc/user/application_security/sast/index.md
+++ b/doc/user/application_security/sast/index.md
@@ -2,13 +2,11 @@
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/#assignments
-type: reference, howto
---
# Static Application Security Testing (SAST) **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3775) in GitLab 10.3.
-> - All open source (OSS) analyzers were moved from GitLab Ultimate to GitLab Free in GitLab 13.3.
+> All open source (OSS) analyzers were moved from GitLab Ultimate to GitLab Free in GitLab 13.3.
NOTE:
The whitepaper ["A Seismic Shift in Application Security"](https://about.gitlab.com/resources/whitepaper-seismic-shift-application-security/)
@@ -51,6 +49,8 @@ the analyzer outputs an [exit code](../../../development/integrations/secure.md#
## Requirements
+SAST 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.
+
To run SAST 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.
@@ -168,10 +168,9 @@ To configure SAST for a project you can:
### Configure SAST manually
-For GitLab 11.9 and later, to enable SAST you must [include](../../../ci/yaml/index.md#includetemplate)
+To enable SAST you must [include](../../../ci/yaml/index.md#includetemplate)
the [`SAST.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml)
-provided as a part of your GitLab installation. For GitLab versions earlier than 11.9, you
-can copy and use the job as defined that template.
+provided as a part of your GitLab installation.
Add the following to your `.gitlab-ci.yml` file:
@@ -269,7 +268,7 @@ versions are pulled, there are certain cases where it can be beneficial to pin
an analyzer to a specific release. To do so, override the `SAST_ANALYZER_IMAGE_TAG` CI/CD variable
in the job template directly.
-In the example below, we pin to a specific patch version of the `spotbugs` analyzer and minor version of the `semgrep` analyzer:
+In the example below, we pin to a minor version of the `semgrep` analyzer and a specific patch version of the `brakeman` analyzer:
```yaml
include:
@@ -277,11 +276,11 @@ include:
semgrep-sast:
variables:
- SAST_ANALYZER_IMAGE_TAG: "2.12"
+ SAST_ANALYZER_IMAGE_TAG: "2.16"
-spotbugs-sast:
+brakeman-sast:
variables:
- SAST_ANALYZER_IMAGE_TAG: "2.28.1"
+ SAST_ANALYZER_IMAGE_TAG: "2.21.1"
```
### Customize rulesets **(ULTIMATE)**
@@ -311,9 +310,9 @@ To disable analyzer rules:
1. Set the `disabled` flag to `true` in the context of a `ruleset` section
-1. In one or more `ruleset.identifier` sub sections, list the rules that you want disabled. Every `ruleset.identifier` section has:
+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 `type` field, to name the predefined rule identifier that the targeted analyzer uses.
- a `value` field, to name the rule to be disabled.
@@ -346,7 +345,7 @@ and `sobelow` by matching the `type` and `value` of identifiers:
#### Synthesize a custom configuration
-To create a custom configuration, you can use passthrough chains.
+To create a custom configuration, you can use passthrough chains.
A passthrough is a single step in a passthrough chain. The passthrough is evaluated
in a sequence to incrementally build a configuration. The configuration is then
@@ -360,8 +359,8 @@ parameters:
| `description` | Description about the analyzer configuration section. |
| `targetdir` | The `targetdir` parameter defines the directory where the final configuration is located. If `targetdir` is empty, the analyzer uses a random directory. The maximum size of `targetdir` is 100MB. |
| `validate` | If set to `true`, the target files for passthroughs (`raw`, `file` and `url`) are validated. The validation works for `yaml`, `xml`, `json` and `toml` files. The proper validator is identified based on the extension of the target file. By default, `validate` is set to `false`. |
-| `interpolate` | If set to `true`, environment variable interpolation is enabled so that the configuration uses secrets/tokens. We advise using this feature with caution to not leak any secrets. By default, `interpolate` is set to `false`. |
-| `timeout` | The total `timeout` for the evaluation of a passthrough chain is set to 60 seconds. If `timeout` is not set, the default timeout is 60 seconds. The timeout cannot exceed 300 seconds. |
+| `interpolate` | If set to `true`, environment variable interpolation is enabled so that the configuration uses secrets/tokens. We advise using this feature with caution to not leak any secrets. By default, `interpolate` is set to `false`. |
+| `timeout` | The total `timeout` for the evaluation of a passthrough chain is set to 60 seconds. If `timeout` is not set, the default timeout is 60 seconds. The timeout cannot exceed 300 seconds. |
A configuration section can include one or more passthrough sections. The maximum number of passthrough sections is 20.
There are several types of passthroughs:
@@ -374,12 +373,12 @@ There are several types of passthroughs:
| `url` | Fetch the analyzer configuration through HTTP. |
If multiple passthrough sections are defined in a passthrough chain, their
-position in the chain defines the order in which they are evaluated.
+position in the chain defines the order in which they are evaluated.
-- Passthroughs listed later in the chain sequence have a higher precedence.
+- Passthroughs listed later in the chain sequence have a higher precedence.
- Passthroughs with a higher precedence overwrite (default) and append data
yielded by previous passthroughs. This is useful for cases where you need to
- use or modify an existing configuration.
+ use or modify an existing configuration.
Configure a passthrough these parameters:
@@ -454,7 +453,7 @@ file `gosec-config.json`:
##### Passthrough chain for semgrep
In the below example, we generate a custom configuration under the `/sgrules`
-target directory with a total `timeout` of 60 seconds.
+target directory with a total `timeout` of 60 seconds.
Several passthrouh types generate a configuration for the target analyzer:
@@ -463,17 +462,17 @@ Several passthrouh types generate a configuration for the target analyzer:
`97f7686` from the `sast-rules` Git repostory. From the `sast-rules` Git
repository, only data from the `go` subdirectory is considered.
- The `sast-rules` entry has a higher precedence because it appears later in
- the configuration.
+ the configuration.
- If there is a filename collision between files in both repositories, files
from the `sast` repository overwrite files from the `myrules` repository,
as `sast-rules` has higher precedence.
- The `raw` entry creates a file named `insecure.yml` under `/sgrules`. The
- full path is `/sgrules/insecure.yml`.
+ full path is `/sgrules/insecure.yml`.
- The `url` entry fetches a configuration made available through a URL and
- stores it in the `/sgrules/gosec.yml` file.
+ stores it in the `/sgrules/gosec.yml` file.
Afterwards, semgrep is invoked with the final configuration located under
-`/sgrules`.
+`/sgrules`.
```toml
[semgrep]
@@ -537,17 +536,17 @@ It does not explicitly store credentials in the configuration file. To reduce th
##### Configure the append mode for passthroughs
To append data to previous passthroughs, use the `append` mode for the
-passthrough types `file`, `url`, and `raw`.
+passthrough types `file`, `url`, and `raw`.
Passthroughs in `override` mode overwrite files
created when preceding passthroughs in the chain find a naming
collision. If `mode` is set to `append`, a passthrough appends data to the
-files created by its predecessors instead of overwriting.
+files created by its predecessors instead of overwriting.
In the below semgrep configuration,`/sgrules/insecure.yml` assembles two passthroughs. The rules are:
- `insecure`
-- `secret`
+- `secret`
These rules add a search pattern to the analyzer and extends semgrep capabilities.
@@ -1057,6 +1056,12 @@ For Maven builds, add the following to your `pom.xml` file:
</properties>
```
+### SpotBugs Error: `Project couldn't be built`
+
+If your job is failing at the build step with the message "Project couldn't be built", it's most likely because your job is asking SpotBugs to build with a tool that isn't part of its default tools. For a list of the SpotBugs default tools, see [SpotBugs' asdf dependencies](https://gitlab.com/gitlab-org/security-products/analyzers/spotbugs/-/raw/master/config/.tool-versions).
+
+The solution is to use [pre-compilation](#pre-compilation). Pre-compilation ensures the images required by SpotBugs are available in the job's container.
+
### Flawfinder encoding error
This occurs when Flawfinder encounters an invalid UTF-8 character. To fix this, convert all source code in your project to UTF-8 character encoding. This can be done with [`cvt2utf`](https://github.com/x1angli/cvt2utf) or [`iconv`](https://www.gnu.org/software/libiconv/documentation/libiconv-1.13/iconv.1.html) either over the entire project or per job using the [`before_script`](../../../ci/yaml/index.md#before_script) feature.
diff --git a/doc/user/application_security/secret_detection/index.md b/doc/user/application_security/secret_detection/index.md
index b5e54e35e58..c5761a5743f 100644
--- a/doc/user/application_security/secret_detection/index.md
+++ b/doc/user/application_security/secret_detection/index.md
@@ -1,5 +1,4 @@
---
-type: reference, howto
stage: Secure
group: Static Analysis
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
@@ -7,38 +6,33 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Secret Detection **(FREE)**
-> - [Introduced](https://about.gitlab.com/releases/2019/03/22/gitlab-11-9-released/#detect-secrets-and-credentials-in-the-repository) in GitLab 11.9.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/222788) from GitLab Ultimate to GitLab Free in 13.3.
+> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/222788) from GitLab Ultimate to GitLab Free in 13.3.
-A recurring problem when developing applications is that developers may unintentionally commit
-secrets and credentials to their remote repositories. If other people have access to the source,
-or if the project is public, the sensitive information is then exposed and can be leveraged by
-malicious users to gain access to resources like deployment environments.
+A recurring problem when developing applications is that people may accidentally commit secrets to
+their remote Git repositories. Secrets include keys, passwords, API tokens, and other sensitive
+information. Anyone with access to the repository could use the secrets for malicious purposes.
+Secrets exposed in this way must be treated as compromised, and be replaced, which can be costly.
+It's important to prevent secrets from being committed to a Git repository.
-GitLab 11.9 includes a new check called Secret Detection. It scans the content of the repository
-to find API keys and other information that should not be there.
+Secret Detection uses the [Gitleaks](https://github.com/zricethezav/gitleaks) tool to scan the
+repository for secrets. All identified secrets are reported in the:
-GitLab displays identified secrets visibly in a few places:
-
-- [Security Dashboard](../security_dashboard/)
+- Merge request widget
- Pipelines' **Security** tab
-- Report in the merge request widget
+- [Security Dashboard](../security_dashboard/)
![Secret Detection in merge request widget](img/secret_detection_v13_2.png)
-## Use cases
-
-- Detecting unintentional commit of secrets like keys, passwords, and API tokens.
-- Performing a single or recurring scan of the full history of your repository for secrets.
-
-## Supported secrets
+WARNING:
+Secret Detection does not support scanning binary files.
-Secret Detection detects a variety of common secrets by default. You can also customize the secret detection patterns using [custom rulesets](#custom-rulesets).
-The [default ruleset](https://gitlab.com/gitlab-org/security-products/analyzers/secrets/-/blob/master/gitleaks.toml) includes **90+ secret detection patterns**.
-You can contribute "well-identifiable" secrets by follow the steps detailed in the [community contributions guidelines](https://gitlab.com/gitlab-org/gitlab/-/issues/345453).
+## Detected secrets
-WARNING:
-Gitleaks does not support scanning binary files.
+Secret Detection uses a [default ruleset](https://gitlab.com/gitlab-org/security-products/analyzers/secrets/-/blob/master/gitleaks.toml)
+containing more than 90 secret detection patterns. You can also customize the secret detection
+patterns using [custom rulesets](#custom-rulesets). If you want to contribute rulesets for
+"well-identifiable" secrets, follow the steps detailed in the
+[community contributions guidelines](https://gitlab.com/gitlab-org/gitlab/-/issues/345453).
## Requirements
@@ -376,10 +370,10 @@ For information on this, see the [general Application Security troubleshooting s
### Error: `Couldn't run the gitleaks command: exit status 2`
-If a pipeline is triggered from a Merge Request containing 60 commits while the `GIT_DEPTH` variable
-is set to 50 (a [project default](../../../ci/pipelines/settings.md#limit-the-number-of-changes-fetched-during-clone)),
-the Secret Detection job fails as the clone is not deep enough to contain all of the
-relevant commits.
+If a pipeline is triggered from a Merge Request containing 60 commits while the `GIT_DEPTH` variable's
+value is less than that, the Secret Detection job fails as the clone is not deep enough to contain all of the
+relevant commits. For information on the current default value, see the
+[pipeline configuration documentation](../../../ci/pipelines/settings.md#limit-the-number-of-changes-fetched-during-clone).
To confirm this as the cause of the error, set the
[logging level](../../application_security/secret_detection/index.md#logging-level) to `debug`, then
diff --git a/doc/user/application_security/security_dashboard/img/group_security_dashboard_v13_3.png b/doc/user/application_security/security_dashboard/img/group_security_dashboard_v13_3.png
deleted file mode 100644
index 4d51f57a98d..00000000000
--- a/doc/user/application_security/security_dashboard/img/group_security_dashboard_v13_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/application_security/security_dashboard/img/pipeline_security_dashboard_v14_4.png b/doc/user/application_security/security_dashboard/img/pipeline_security_dashboard_v14_4.png
deleted file mode 100644
index ad9122ee23c..00000000000
--- a/doc/user/application_security/security_dashboard/img/pipeline_security_dashboard_v14_4.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/application_security/security_dashboard/img/project_security_dashboard_chart_v13_11.png b/doc/user/application_security/security_dashboard/img/project_security_dashboard_chart_v13_11.png
deleted file mode 100644
index cc9f0061a31..00000000000
--- a/doc/user/application_security/security_dashboard/img/project_security_dashboard_chart_v13_11.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/application_security/security_dashboard/img/security_center_settings_v13_4.png b/doc/user/application_security/security_dashboard/img/security_center_settings_v13_4.png
deleted file mode 100644
index 6578c0bf4cf..00000000000
--- a/doc/user/application_security/security_dashboard/img/security_center_settings_v13_4.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/application_security/security_dashboard/index.md b/doc/user/application_security/security_dashboard/index.md
index 5afbe1ca54e..937ca33c3a1 100644
--- a/doc/user/application_security/security_dashboard/index.md
+++ b/doc/user/application_security/security_dashboard/index.md
@@ -7,193 +7,186 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitLab Security Dashboards and Security Center **(ULTIMATE)**
-INFO:
-Want to try out security scanning?
-[Try GitLab Ultimate free for 30 days](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=u-security-dashboard-docs).
+You can use Security Dashboards to view details about vulnerabilities
+detected by [security scanners](../index.md#security-scanning-tools).
+These details are shown in pipelines, projects, and groups.
-GitLab provides a comprehensive set of features for viewing and managing vulnerabilities:
+To use the Security Dashboards, you must:
-- Security dashboards: An overview of the security status in your personal [Security Center](#security-center), [groups](#group-security-dashboard), and
- [projects](#project-security-dashboard).
-- [Vulnerability reports](../vulnerability_report/index.md): Detailed lists of all vulnerabilities for the Security Center, group, project, or
- pipeline. This is where you triage and manage vulnerabilities.
-- [Security Center](#security-center): A dedicated area for personalized vulnerability management. This
- includes a security dashboard, vulnerability report, and settings.
+- Configure at least one [security scanner](../index.md#security-scanning-tools) in a project.
+- Configure jobs to use the [`reports` syntax](../../../ci/yaml/index.md#artifactsreports).
+- Use [GitLab Runner](https://docs.gitlab.com/runner/) 11.5 or later. If you use the
+ shared runners on GitLab.com, you are using the correct version.
-You can also drill down into a vulnerability and get extra information on the
-[Vulnerability Page](../vulnerabilities/index.md). This view includes the project it
-comes from, any related file(s), and metadata that helps you analyze the risk it poses.
-You can also confirm, dismiss, or resolve a vulnerability, create an issue for it,
-and in some cases, generate a merge request to fix the vulnerability.
+## When Security Dashboards are updated
-To benefit from these features, you must first configure one of the
-[security scanners](../index.md).
+The Security Dashboards show results of the most recent security scan on the
+[default branch](../../project/repository/branches/default.md).
+Security scans run only when the default branch updates, so
+information on the Security Dashboard might not reflect newly-discovered vulnerabilities.
-## Supported reports
+To run a daily security scan,
+[configure a scheduled pipeline](../../../ci/pipelines/schedules.md).
-The security dashboard and vulnerability report displays information about vulnerabilities detected by scanners such as:
+## Reduce false negatives in dependency scans
-- [Container Scanning](../container_scanning/index.md)
-- [Dynamic Application Security Testing](../dast/index.md)
-- [Dependency Scanning](../dependency_scanning/index.md)
-- [Static Application Security Testing](../sast/index.md)
-- [Cluster Image Scanning](../cluster_image_scanning/index.md)
-- And [others](../index.md#security-scanning-tools)!
+WARNING:
+False negatives occur when you resolve dependency versions during a scan, which differ from those
+resolved when your project built and released in a previous pipeline.
-## Prerequisites
+To reduce false negatives in [dependency scans](../../../user/application_security/dependency_scanning/index.md) in scheduled pipelines, ensure you:
-1. At least one project inside a group must be configured with at least one of
- the [supported reports](#supported-reports).
-1. The configured jobs must use the [new `reports` syntax](../../../ci/yaml/index.md#artifactsreports).
-1. [GitLab Runner](https://docs.gitlab.com/runner/) 11.5 or newer must be used.
- If you're using the shared runners on GitLab.com, this is already the case.
+- Include a lock file in your project. A lock file lists all transient dependencies and tracks their versions.
+ - Java projects can't have lock files.
+ - Python projects can have lock files, but GitLab Secure tools don't support them.
+- Configure your project for [Continuous Delivery](../../../ci/introduction/index.md).
-## Pipeline Security
+## View vulnerabilities in a pipeline
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13496) in GitLab 12.3.
-At the pipeline level, the Security section displays the vulnerabilities present in the branch of
-the project the pipeline ran against.
-
-![Pipeline Security Dashboard](img/pipeline_security_dashboard_v14_4.png)
+To view vulnerabilities in a pipeline:
-Visit the page for any pipeline that ran any of the [supported reports](#supported-reports). To view
-the pipeline's security findings, select the **Security** tab when viewing the pipeline.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **CI/CD > Pipelines**.
+1. From the list, select the pipeline you want to check for vulnerabilities.
+1. Select the **Security** tab.
-A pipeline consists of multiple jobs, including SAST and DAST scanning. If any job fails to finish
-for any reason, the security dashboard doesn't show SAST scanner output. For example, if the SAST
+A pipeline consists of multiple jobs, such as SAST and DAST scans. If a job fails to finish,
+the security dashboard doesn't show SAST scanner output. For example, if the SAST
job finishes but the DAST job fails, the security dashboard doesn't show SAST results. On failure,
-the analyzer outputs an
-[exit code](../../../development/integrations/secure.md#exit-code).
+the analyzer outputs an [exit code](../../../development/integrations/secure.md#exit-code).
+
+## View total number of vulnerabilities per scan
+
+To view the total number of vulnerabilities per scan:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **CI/CD > Pipelines**.
+1. Select the **Status** of a branch.
+1. Select the **Security** tab.
-### Scan details
+**Scan details** show the total number of vulnerabilities found per scan in the pipeline.
+
+### Download security scan outputs
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3728) in GitLab 13.10.
> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/333660) in GitLab 14.2.
-The **Scan details** section lists the scans run in the pipeline and the total number of vulnerabilities
-per scan.
+Depending on the type of security scanner, you can download:
+
+- A JSON artifact that contains the security scanner [report]('https://docs.gitlab.com/ee/development/integrations/secure.html#report').
+- A CSV file that contains URLs and endpoints scanned by the security scanner.
+
+To download a security scan output:
-You can download the JSON artifacts from each security scan. Select **Download results** then
-select the JSON artifact. Additionally for the DAST scan, from the **Download results** dropdown select
-**Download scanned resources** to download a CSV file containing details of the resources scanned.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **CI/CD > Pipelines**.
+1. Select the **Status** of a branch.
+1. Select the **Security** tab.
+1. In **Scan details**, select **Download results**:
+ - To download a JSON file, select the JSON artifact.
+ - To download a CSV file, select **Download scanned resources**.
-## Project Security Dashboard
+## View vulnerabilities over time for a project
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/235558) in GitLab 13.6.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/285476) in GitLab 13.10, options to zoom in on a date range, and download the vulnerabilities chart.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/285477) in GitLab 13.11, date range slider to visualize data between given dates.
-A project's Security Dashboard displays a chart with the total number of vulnerabilities
-over time with up to 365 days of historical data. Data is refreshed daily at 1:15am UTC. By default,
-it shows statistics for all vulnerability severities.
+The project Security Dashboard shows the total number of vulnerabilities
+over time, with up to 365 days of historical data. Data refreshes daily at 01:15 UTC.
+It shows statistics for all vulnerabilities.
-To access the dashboard, from your project's home page go to **Security & Compliance > Security Dashboard**.
+To view total number of vulnerabilities over time:
-![Project Security Dashboard](img/project_security_dashboard_chart_v13_11.png)
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Security & Compliance > Security Dashboard**.
+1. Filter and search for what you need.
+ - To filter the chart by severity, select the legend name.
+ - To view a specific time frame, use the time range handles (**{scroll-handle}**).
+ - To view a specific area of the chart, select the left-most icon (**{marquee-selection}**) and drag
+ across the chart.
+ - To reset to the original range, select **Remove Selection** (**{redo}**).
-### Filter the vulnerabilities chart
+### Download the vulnerabilities chart
-To filter the chart by vulnerability severity, select the corresponding legend name.
+To download an SVG image of the vulnerabilities chart:
-In the previous example, the chart shows statistics only for vulnerabilities of medium or unknown severity.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Security & Compliance > Security dashboard**.
+1. Select **Save chart as an image** (**{download}**).
-### Customize vulnerabilities chart display
+## View vulnerabilities over time for a group
-To customize the view of the vulnerability chart, you can select:
+The group Security Dashboard gives an overview of vulnerabilities found in the default
+branches of projects in a group and its subgroups.
-- A specific time frame by using the time range handles (**{scroll-handle}**).
-- A specific area of the chart by using the left-most icon (**{marquee-selection}**) then drag
- across the chart. To reset to the original range, select **Remove Selection** (**{redo}**).
+To view vulnerabilities over time for a group:
-### Download a copy of the vulnerabilities chart
+1. On the top bar, select **Menu > Groups** and select a group.
+1. Select **Security > Security Dashboard**.
+1. Hover over the chart to get more details about vulnerabilities.
+ - You can display the vulnerability trends over a 30, 60, or 90-day time frame (the default is 90 days).
+ - To view aggregated data beyond a 90-day time frame, use the
+ [VulnerabilitiesCountByDay GraphQL API](../../../api/graphql/reference/index.md#vulnerabilitiescountbyday).
+ GitLab retains the data for 365 days.
-To download an SVG image of the chart, select **Save chart to an image** (**{download}**).
+## View project security status for a group
-## Group Security Dashboard
+Use the group Security Dashboard to view the security status of projects. The security status is based
+on the number of detected vulnerabilities.
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6709) in GitLab 11.5.
+To view project security status for a group:
-The group Security Dashboard gives an overview of the vulnerabilities found in the default branches of the
-projects in a group and its subgroups. Access it by navigating to **Security > Security Dashboard**
-after selecting your group. By default, the Security Dashboard displays all detected and confirmed
-vulnerabilities. If you don't see the vulnerabilities over time graph, the likely cause is that you
-have not selected a group.
+1. On the top bar, select **Menu > Groups** and select a group.
+1. Select **Security > Security Dashboard**.
-Note that the Security Dashboard only shows projects with
-[security reports](#supported-reports)
-enabled in a group.
+Projects are [graded](#project-vulnerability-grades) by vulnerability severity. Dismissed vulnerabilities are excluded.
-![Dashboard with action buttons and metrics](img/group_security_dashboard_v13_3.png)
+To view vulnerabilities, go to the group's [vulnerability report](../vulnerability_report/index.md).
-There is a timeline chart that shows how many open
-vulnerabilities your projects had at various points in time. You can display the vulnerability
-trends over a 30, 60, or 90-day time frame (the default is 90 days). Hover over the chart to get
-more details about the open vulnerabilities at a specific time. Aggregated data beyond 90 days can be accessed by querying our [VulnerabilitiesCountByDay GraphQL API](../../../api/graphql/reference/index.md#vulnerabilitiescountbyday). This data is retained for 365 days.
-
-Next to the timeline chart is a list of projects, grouped and sorted by the severity of the vulnerability found:
+### Project vulnerability grades
| Grade | Description |
-| F | One or more "critical" |
-| D | One or more "high" or "unknown" |
-| C | One or more "medium" |
-| B | One or more "low" |
-| A | Zero vulnerabilities |
-
-Projects with no vulnerability tests configured don't appear in the list. Additionally, dismissed
-vulnerabilities are excluded.
-
-Navigate to the group's [vulnerability report](../vulnerability_report/index.md) to view the vulnerabilities found.
+| --- | --- |
+| **F** | One or more `critical` vulnerabilities |
+| **D** | One or more `high` or `unknown` vulnerabilities |
+| **C** | One or more `medium` vulnerabilities |
+| **B** | One or more `low` vulnerabilities |
+| **A** | Zero vulnerabilities |
## Security Center
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3426) in GitLab 13.4.
-The Security Center is personal space where you manage vulnerabilities across all your projects. It
-displays the vulnerabilities present in the default branches of all the projects you configure. It includes
-the following:
+The Security Center is a personal space where you view vulnerabilities across all your projects. It
+shows the vulnerabilities present in the default branches of the projects.
+
+The Security Center includes:
-- The [group security dashboard's](#group-security-dashboard) features.
+- The group Security Dashboard.
- A [vulnerability report](../vulnerability_report/index.md).
-- A dedicated settings area to configure which projects to display.
+- A settings area to configure which projects to display.
![Security Center Dashboard with projects](img/security_center_dashboard_v13_4.png)
+### View the Security Center
+
To view the Security Center, on the top bar, select **Menu > Security**.
-### Adding projects to the Security Center
+### Add projects to the Security Center
To add projects to the Security Center:
-1. Click **Settings** in the left navigation bar or click the **Add projects** button.
-1. Search for and add one or more projects using the **Search your projects** field.
-1. Click the **Add projects** button.
+1. On the top bar, select **Menu > Security**.
+1. On the left sidebar, select **Settings**, or select **Add projects**.
+1. Use the **Search your projects** text box to search for and select projects.
+1. Select **Add projects**.
-![Adding projects to Security Center](img/security_center_settings_v13_4.png)
-
-After you add projects, the security dashboard and vulnerability report display the vulnerabilities
+After you add projects, the security dashboard and vulnerability report show the vulnerabilities
found in those projects' default branches.
-## Keep dashboards up to date
-
-The Security Dashboard displays results of the most recent security scan on the
-[default branch](../../project/repository/branches/default.md). By default, security scans are run
-only when the default branch is updated. Information on the Security Dashboard may not reflect
-newly-discovered vulnerabilities.
-
-To ensure the information on the Security Dashboard is regularly updated,
-[configure a scheduled pipeline](../../../ci/pipelines/schedules.md) to run a daily security scan.
-This updates the information displayed on the Security Dashboard regardless of how often the default
-branch is updated.
-
-WARNING:
-Running Dependency Scanning from a scheduled pipeline might result in false negatives if your
-project doesn't have a lock file and isn't configured for Continuous Delivery. A lock file is a file
-that lists all transient dependencies and keeps track of their exact versions. The false negative
-can occur because the dependency version resolved during the scan might differ from the ones
-resolved when your project was built and released, in a previous pipeline. Java projects can't have
-lock files. Python projects can have lock files, but GitLab Secure tools don't support them.
-
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
@@ -206,4 +199,8 @@ 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. -->
-Read more on how to [address the vulnerabilities](../vulnerabilities/index.md).
+## Related topics
+
+- [Address the vulnerabilities](../vulnerabilities/index.md)
+- [Vulnerability reports](../vulnerability_report/index.md)
+- [Vulnerability Page](../vulnerabilities/index.md)
diff --git a/doc/user/application_security/vulnerabilities/index.md b/doc/user/application_security/vulnerabilities/index.md
index 7bdc8cc8479..9aa8a0cd3cd 100644
--- a/doc/user/application_security/vulnerabilities/index.md
+++ b/doc/user/application_security/vulnerabilities/index.md
@@ -37,7 +37,7 @@ A vulnerability's status can be one of the following:
| Status | Description |
|:----------|:------------|
-| Detected | The default state for a newly discovered vulnerability. |
+| Detected | The default state for a newly discovered vulnerability. Appears as "Needs triage" in the UI. |
| Confirmed | A user has seen this vulnerability and confirmed it to be accurate. |
| Dismissed | A user has seen this vulnerability and dismissed it because it is not accurate or otherwise not to be resolved. |
| Resolved | The vulnerability has been fixed or is no longer present. |
@@ -168,7 +168,7 @@ The following vulnerability scanners and their databases are regularly updated:
| Secure scanning tool | Vulnerabilities database updates |
|:----------------------------------------------------------------|----------------------------------|
| [Container Scanning](../container_scanning/index.md) | A job runs on a daily basis to build new images with the latest vulnerability database updates from the upstream scanner. |
-| [Dependency Scanning](../dependency_scanning/index.md) | Relies on `bundler-audit` (for Ruby gems), `retire.js` (for npm packages), and `gemnasium` (the GitLab tool for all libraries). Both `bundler-audit` and `retire.js` fetch their vulnerabilities data from GitHub repositories, so vulnerabilities added to `ruby-advisory-db` and `retire.js` are immediately available. The tools themselves are updated once per month if there's a new version. The [Gemnasium DB](https://gitlab.com/gitlab-org/security-products/gemnasium-db) is updated at least once a week. See our [current measurement of time from CVE being issued to our product being updated](https://about.gitlab.com/handbook/engineering/development/performance-indicators/#cve-issue-to-update). |
+| [Dependency Scanning](../dependency_scanning/index.md) | Relies on `bundler-audit` (for Ruby gems), `retire.js` (for npm packages), and `gemnasium` (the GitLab tool for all libraries). Both `bundler-audit` and `retire.js` fetch their vulnerabilities data from GitHub repositories, so vulnerabilities added to `ruby-advisory-db` and `retire.js` are immediately available. The tools themselves are updated once per month if there's a new version. The [Gemnasium DB](https://gitlab.com/gitlab-org/security-products/gemnasium-db) is updated on a daily basis using [data from NVD, the `ruby-advisory-db` and the GitHub Security Advisory Database as data sources](https://gitlab.com/gitlab-org/security-products/gemnasium-db/-/blob/master/SOURCES.md). See our [current measurement of time from CVE being issued to our product being updated](https://about.gitlab.com/handbook/engineering/development/performance-indicators/#cve-issue-to-update). |
| [Dynamic Application Security Testing (DAST)](../dast/index.md) | The scanning engine is updated on a periodic basis. See the [version of the underlying tool `zaproxy`](https://gitlab.com/gitlab-org/security-products/dast/blob/main/Dockerfile#L1). The scanning rules are downloaded at scan runtime. |
| [Static Application Security Testing (SAST)](../sast/index.md) | Relies exclusively on [the tools GitLab wraps](../sast/index.md#supported-languages-and-frameworks). The underlying analyzers are updated at least once per month if a relevant update is available. The vulnerabilities database is updated by the upstream tools. |
diff --git a/doc/user/application_security/vulnerability_report/index.md b/doc/user/application_security/vulnerability_report/index.md
index 3773bb59c5a..05ff5c511f9 100644
--- a/doc/user/application_security/vulnerability_report/index.md
+++ b/doc/user/application_security/vulnerability_report/index.md
@@ -100,7 +100,7 @@ The content of the Project filter depends on the current level:
| Level | Content of the Project filter |
|:---------------|:------------------------------|
-| Security Center | Only projects you've [added to your personal Security Center](../security_dashboard/index.md#adding-projects-to-the-security-center). |
+| Security Center | Only projects you've [added to your personal Security Center](../security_dashboard/index.md#add-projects-to-the-security-center). |
| Group level | All projects in the group. |
| Project level | Not applicable. |
diff --git a/doc/user/clusters/agent/ci_cd_tunnel.md b/doc/user/clusters/agent/ci_cd_tunnel.md
index 93768164df2..f1c49b87383 100644
--- a/doc/user/clusters/agent/ci_cd_tunnel.md
+++ b/doc/user/clusters/agent/ci_cd_tunnel.md
@@ -19,11 +19,8 @@ Only CI/CD jobs set in the configuration project can access one of the configure
## Prerequisites
-- A running [`kas` instance](install/index.md#set-up-the-agent-server).
-- A [configuration repository](install/index.md#define-a-configuration-repository) with an agent config file
- installed (`.gitlab/agents/<agent-name>/config.yaml`).
-- A [registered agent](install/index.md#register-an-agent-with-gitlab).
-- The agent [installed in the cluster](install/index.md#install-the-agent-into-the-cluster).
+- An existing Kubernetes cluster.
+- An agent [installed on your cluster](install/index.md#install-the-agent-into-the-cluster).
## Use the CI/CD Tunnel to run Kubernetes commands from GitLab CI/CD
diff --git a/doc/user/clusters/agent/index.md b/doc/user/clusters/agent/index.md
index c950a4f0dc0..a235c0ef6f8 100644
--- a/doc/user/clusters/agent/index.md
+++ b/doc/user/clusters/agent/index.md
@@ -18,10 +18,6 @@ is an active in-cluster component for connecting Kubernetes clusters to GitLab s
The Agent is installed into the cluster through code, providing you with a fast, safe, stable, and scalable solution.
-INFO:
-Get Network Security Alerts in GitLab by upgrading to Ultimate.
-[Try a free 30-day trial now](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=p-cluster-agent-docs).
-
With GitOps, you can manage containerized clusters and applications from a Git repository that:
- Is the single source of truth of your system.
@@ -136,7 +132,22 @@ with the following differences:
## Remove an agent
-1. Get the `<cluster-agent-id>` and the `<cluster-agent-token-id>` from a query in the interactive GraphQL explorer.
+You can remove an agent using the [GitLab UI](#remove-an-agent-through-the-gitlab-ui) or through 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. Go to your agent's configuration repository.
+1. From your project's sidebar, select **Infrastructure > Kubernetes clusters**.
+1. Select your agent from the table, and then in the **Options** column, click the vertical ellipsis
+(**{ellipsis_v}**) button and 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 instances, go to `https://gitlab.example.com/-/graphql-explorer`, replacing `gitlab.example.com` with your own instance's URL.
@@ -157,7 +168,7 @@ For self-managed GitLab instances, go to `https://gitlab.example.com/-/graphql-e
}
```
-1. Remove an Agent record with GraphQL by deleting the `clusterAgent` and the `clusterAgentToken`.
+1. Remove an agent record with GraphQL by deleting the `clusterAgentToken`.
```graphql
mutation deleteAgent {
@@ -190,6 +201,10 @@ For self-managed GitLab instances, go to `https://gitlab.example.com/-/graphql-e
kubectl delete -n gitlab-kubernetes-agent -f ./resources.yml
```
+## Migrating to the GitLab Agent from the legacy certificate-based integration
+
+Find out how to [migrate to the GitLab Agent for Kubernetes](../../infrastructure/clusters/migrate_to_gitlab_agent.md) from the certificate-based integration depending on the features you use.
+
## Troubleshooting
If you face any issues while using the Agent, read the
diff --git a/doc/user/clusters/agent/install/index.md b/doc/user/clusters/agent/install/index.md
index cf8467a8d28..b2372789284 100644
--- a/doc/user/clusters/agent/install/index.md
+++ b/doc/user/clusters/agent/install/index.md
@@ -10,42 +10,27 @@ info: To determine the technical writer assigned to the Stage/Group associated w
To get started with the Agent, install it in your cluster.
-Pre-requisites:
+## Prerequisites **(SELF)**
- An existing Kubernetes cluster.
-- An account on GitLab.
+- On self-managed GitLab instances, a GitLab administrator needs to set up the [GitLab Agent Server (KAS)](../../../../administration/clusters/kas.md).
## Installation steps
To install the [Agent](../index.md) in your cluster:
-1. [Set up the Agent Server](#set-up-the-agent-server) for your GitLab instance.
1. [Define a configuration repository](#define-a-configuration-repository).
1. [Register an agent with GitLab](#register-an-agent-with-gitlab).
1. [Install the agent into the cluster](#install-the-agent-into-the-cluster).
-1. [Generate and copy a Secret token used to connect to the agent](#create-the-kubernetes-secret).
-1. [Create manifest files](#create-manifest-files).
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i> Watch a GitLab 14.2 [walking-through video](https://www.youtube.com/watch?v=XuBpKtsgGkE) with this process.
-### Set up the Agent Server
-
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3834) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.10, the GitLab Agent Server (KAS) became available on GitLab.com under `wss://kas.gitlab.com`.
-
-To use the KAS:
-
-- If you are a self-managed user, follow the instructions to [install the Agent Server](../../../../administration/clusters/kas.md).
-- If you are a GitLab.com user, when you [set up the configuration repository](#define-a-configuration-repository) for your agent, use `wss://kas.gitlab.com` as the `--kas-address`.
-
### Define a configuration repository
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/259669) in GitLab 13.7, the Agent manifest configuration can be added to multiple directories (or subdirectories) of its repository.
> - Group authorization was [introduced](https://gitlab.com/groups/gitlab-org/-/epics/5784) in GitLab 14.3.
-To create an agent, you need:
-
-1. A GitLab repository to hold the configuration file.
-1. Install the Agent in a cluster.
+To create an agent, you need a GitLab repository to hold the configuration file.
After installed, when you update the configuration file, GitLab transmits the
information to the cluster automatically without downtime.
@@ -62,7 +47,7 @@ WARNING:
The agent is only recognized if you use `.yaml` extension for the `config.yaml` file. The extension `.yml` is **not** recognized.
You **don't have to add any content** to this file when you create it. The fact that the file exists
-tells GitLab that this is an agent configuration file. It doesn't do anything so far, but, later on, you can use this
+tells GitLab that this is an agent configuration file and enables the [CI/CD tunnel](../ci_cd_tunnel.md#example-for-a-kubectl-command-using-the-cicd-tunnel). Later on, you can use this
file to [configure the agent](../repository.md) by setting up parameters such as:
- Groups and projects that can access the agent via the [CI/CD Tunnel](../ci_cd_tunnel.md).
@@ -71,10 +56,6 @@ file to [configure the agent](../repository.md) by setting up parameters such as
To see all the settings available, read the [Agent configuration repository documentation](../repository.md).
-### Access your cluster from GitLab CI/CD
-
-Use the [CI/CD Tunnel](../ci_cd_tunnel.md#example-for-a-kubectl-command-using-the-cicd-tunnel) to access your cluster from GitLab CI/CD.
-
### Register an agent with GitLab
> [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.
@@ -92,242 +73,53 @@ In GitLab:
1. The form reveals your registration token. Securely store this secret token as you cannot view it again.
1. Copy the command under **Recommended installation method**.
+### Install the agent into the cluster
+
In your computer:
1. Open your local terminal and connect to your cluster.
-1. Run the command you copied from the installation form.
+1. Run the command you copied when registering your cluster in the previous step.
-### Install the agent into the cluster
+See the following sections to learn about customizing the installation.
-To install the in-cluster component of the Agent, first you need to define a namespace. To create a new namespace,
-for example, `gitlab-kubernetes-agent`, run:
+## Simple installation method
-```shell
-kubectl create namespace gitlab-kubernetes-agent
-```
+The command provided by GitLab does the following things:
-To perform a one-liner installation, run the command below. Make sure to replace:
+- Creates a namespace for the deployment (`gitlab-kubernetes-agent`).
+- Sets up a service account with `cluster-admin` rights. Read more on [how you can restrict this service account](#customize-the-permissions-for-the-agentk-service-account).
+- Creates a `Secret` resource for the agent registration token.
+- Creates a `Deployment` resource for the `agentk` pod.
-- `your-agent-token` with the token received from the previous step (identified as `secret` in the JSON output).
-- `gitlab-kubernetes-agent` with the namespace you defined in the previous step.
-- `wss://kas.gitlab.example.com` with the configured access of the Agent Server (KAS). For GitLab.com users, the KAS is available under `wss://kas.gitlab.com`.
-- `--agent-version=vX.Y.Z` with the latest released patch version matching your GitLab installation's major and minor versions. For example, for GitLab v13.9.0, use `--agent-version=v13.9.1`. You can find your GitLab version under the "Help/Help" menu.
+The one-liner installer can be customized at the command line. To find out the various options the above Docker container supports, run:
```shell
-docker run --pull=always --rm registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/cli:stable generate --agent-token=your-agent-token --kas-address=wss://kas.gitlab.example.com --agent-version=vX.Y.Z --namespace gitlab-kubernetes-agent | kubectl apply -f -
+docker run --pull=always --rm registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/cli:stable generate --help
```
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.
-To find out the various options the above Docker container supports, run:
-
-```shell
-docker run --pull=always --rm registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/cli:stable generate --help
-```
-
-## Advanced installation
+## Advanced installation method
For more advanced configurations, we recommend to use [the `kpt` based installation method](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/tree/master/build/deployment/gitlab-agent).
Otherwise, follow the manual installation steps described below.
-### Create the Kubernetes secret
-
-After generating the token, you must apply it to the Kubernetes cluster.
-
-To create your Secret, run:
-
-```shell
-kubectl create secret generic -n gitlab-kubernetes-agent gitlab-kubernetes-agent-token --from-literal=token='YOUR_AGENT_TOKEN'
-```
-
-The following example file contains the
-Kubernetes resources required for the Agent to be installed. You can modify this
-example [`resources.yml` file](#example-resourcesyml-file) in the following ways:
-
-- Replace `namespace: gitlab-kubernetes-agent` with `namespace: <YOUR-DESIRED-NAMESPACE>`.
-- You can configure `kas-address` (Agent Server) in several ways.
- The agent can use the WebSockets or gRPC protocols to connect to the Agent Server.
- Select the option appropriate for your cluster configuration and GitLab architecture:
- - The `wss` scheme (an encrypted WebSockets connection) is specified by default
- after you install the `gitlab-kas` sub-chart, or enable `gitlab-kas` for Omnibus GitLab.
- When using the sub-chart, you must set `wss://kas.host.tld:443` as
- `kas-address`, where `host.tld` is the domain you've setup for your GitLab installation.
- When using Omnibus GitLab, you must set `wss://GitLab.host.tld:443/-/kubernetes-agent/` as
- `kas-address`, where `GitLab.host.tld` is your GitLab hostname.
- - When using the sub-chart, specify the `ws` scheme (such as `ws://kas.host.tld:80`)
- to use an unencrypted WebSockets connection.
- When using the Omnibus GitLab, specify the `ws` scheme (such as `ws://GitLab.host.tld:80/-/kubernetes-agent/`).
- - Specify the `grpc` scheme if both Agent and Server are installed in one cluster.
- In this case, you may specify `kas-address` value as
- `grpc://gitlab-kas.<your-namespace>:8150`) to use gRPC directly, where `gitlab-kas`
- is the name of the service created by `gitlab-kas` chart, and `<your-namespace>`
- is the namespace where the chart was installed.
- - Specify the `grpcs` scheme to use an encrypted gRPC connection.
- - When deploying KAS through the [GitLab chart](https://docs.gitlab.com/charts/), it's possible to customize the
- `kas-address` for `wss` and `ws` schemes to whatever you need.
- Check the [chart's KAS Ingress documentation](https://docs.gitlab.com/charts/charts/gitlab/kas/#ingress)
- to learn more about it.
- - In the near future, Omnibus GitLab intends to provision `gitlab-kas` under a sub-domain by default, instead of the `/-/kubernetes-agent/` path. Please follow [this issue](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5784) for details.
-- If you defined your own secret name, replace `gitlab-kubernetes-agent-token` with your
- secret name in the `secretName:` section.
-
-To apply this file, run the following command:
+### Customize the permissions for the `agentk` service account
-```shell
-kubectl apply -n gitlab-kubernetes-agent -f ./resources.yml
-```
-
-To review your configuration, run the following command:
-
-```shell
-$ kubectl get pods -n gitlab-kubernetes-agent
-
-NAMESPACE NAME READY STATUS RESTARTS AGE
-gitlab-kubernetes-agent gitlab-kubernetes-agent-77689f7dcb-5skqk 1/1 Running 0 51s
-```
-
-#### Example `resources.yml` file
-
-```yaml
----
-apiVersion: v1
-kind: Namespace
-metadata:
- name: gitlab-kubernetes-agent
----
-apiVersion: v1
-kind: ServiceAccount
-metadata:
- name: gitlab-kubernetes-agent
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: gitlab-kubernetes-agent
-spec:
- replicas: 1
- selector:
- matchLabels:
- app: gitlab-kubernetes-agent
- template:
- metadata:
- labels:
- app: gitlab-kubernetes-agent
- spec:
- serviceAccountName: gitlab-kubernetes-agent
- containers:
- - name: agent
- # Make sure to specify a matching version for production
- image: "registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/agentk:vX.Y.Z"
- args:
- - --token-file=/config/token
- - --kas-address
- - wss://kas.host.tld:443 # replace this line with the line below if using Omnibus GitLab or GitLab.com.
- # - wss://gitlab.host.tld:443/-/kubernetes-agent/
- # - wss://kas.gitlab.com # for GitLab.com users, use this KAS.
- # - grpc://host.docker.internal:8150 # use this attribute when connecting from Docker.
- volumeMounts:
- - name: token-volume
- mountPath: /config
- volumes:
- - name: token-volume
- secret:
- secretName: gitlab-kubernetes-agent-token
- strategy:
- type: RollingUpdate
- rollingUpdate:
- maxSurge: 0
- maxUnavailable: 1
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- name: gitlab-kubernetes-agent-write
-rules:
-- resources:
- - '*'
- apiGroups:
- - '*'
- verbs:
- - create
- - update
- - delete
- - patch
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
- name: gitlab-kubernetes-agent-write-binding
-roleRef:
- name: gitlab-kubernetes-agent-write
- kind: ClusterRole
- apiGroup: rbac.authorization.k8s.io
-subjects:
-- name: gitlab-kubernetes-agent
- kind: ServiceAccount
- namespace: gitlab-kubernetes-agent
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- name: gitlab-kubernetes-agent-read
-rules:
-- resources:
- - '*'
- apiGroups:
- - '*'
- verbs:
- - get
- - list
- - watch
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
- name: gitlab-kubernetes-agent-read-binding
-roleRef:
- name: gitlab-kubernetes-agent-read
- kind: ClusterRole
- apiGroup: rbac.authorization.k8s.io
-subjects:
-- name: gitlab-kubernetes-agent
- kind: ServiceAccount
- namespace: gitlab-kubernetes-agent
-```
-
-### Create manifest files
+The GitLab Agent for Kubernetes allows you to fully own your cluster and requires only the permissions you give. Still, for easy getting started, by default the generated manifests provide `cluster-admin` rights to the agent.
-In a previous step, you configured a `config.yaml` to point to the GitLab projects
-the Agent should synchronize. Agent monitors each of those projects for changes to the manifest files it contains. You can auto-generate manifest files with a
-templating engine or other means.
+As part of the advanced installation method, you can restrict the agent 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.
-The agent is authorized to download manifests for the configuration
-project, and public projects. Support for other private projects is
-planned in the issue [Agent authorization for private manifest
-projects](https://gitlab.com/gitlab-org/gitlab/-/issues/220912).
+To create restricted permissions:
-Each time you push a change to a monitored manifest repository, the Agent logs the change:
+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.
-```plaintext
-2020-09-15_14:09:04.87946 gitlab-k8s-agent : time="2020-09-15T10:09:04-04:00" level=info msg="Config: new commit" agent_id=1 commit_id=e6a3651f1faa2e928fe6120e254c122451be4eea
-```
-
-#### Example manifest file
-
-This file creates a minimal `ConfigMap`:
-
-```yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
- name: demo-map
- namespace: gitlab-kubernetes-agent # Can be any namespace managed by you that the agent has access to.
-data:
- key: value
-```
+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.
## Example projects
diff --git a/doc/user/clusters/agent/repository.md b/doc/user/clusters/agent/repository.md
index c8ab037118e..22964fde395 100644
--- a/doc/user/clusters/agent/repository.md
+++ b/doc/user/clusters/agent/repository.md
@@ -12,9 +12,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [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.
-WARNING:
-This feature might not be available to you. Check the **version history** note above for details.
-
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.
diff --git a/doc/user/clusters/applications.md b/doc/user/clusters/applications.md
index 88382648b04..f880e603133 100644
--- a/doc/user/clusters/applications.md
+++ b/doc/user/clusters/applications.md
@@ -54,7 +54,7 @@ Supported applications:
- [PostHog](#install-posthog-using-gitlab-cicd)
- [Prometheus](#install-prometheus-using-gitlab-cicd)
-### Usage
+### Prerequisites
You can find and import all the files referenced below
in the [example cluster applications
@@ -95,7 +95,7 @@ applications you have configured. In case of pipeline failure, the
output of the [Helm Tiller](https://v2.helm.sh/docs/install/#running-tiller-locally) binary
is saved as a [CI job artifact](../../ci/pipelines/job_artifacts.md).
-#### Usage in GitLab versions earlier than 13.5
+#### Prerequisites in GitLab versions earlier than 13.5
For GitLab versions 13.5 and earlier, the Ingress, Fluentd, Prometheus, and Sentry
apps were fetched from the central Helm stable repository (`https://kubernetes-charts.storage.googleapis.com/`).
@@ -443,7 +443,7 @@ You can check the recommended variables for each cluster type in the official do
- [Google GKE](https://docs.cilium.io/en/v1.8/gettingstarted/k8s-install-gke/#deploy-cilium)
- [AWS EKS](https://docs.cilium.io/en/v1.8/gettingstarted/k8s-install-eks/#deploy-cilium)
-Do not use `clusterType` for sandbox environments like [Minikube](https://minikube.sigs.k8s.io/docs/).
+Do not use `clusterType` for sandbox environments like [minikube](https://minikube.sigs.k8s.io/docs/).
You can customize Cilium's Helm variables by defining the
`.gitlab/managed-apps/cilium/values.yaml` file in your cluster
diff --git a/doc/user/compliance/index.md b/doc/user/compliance/index.md
index 61b65bf254f..7b46886e236 100644
--- a/doc/user/compliance/index.md
+++ b/doc/user/compliance/index.md
@@ -7,15 +7,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Compliance **(ULTIMATE)**
-The compliance tools provided by GitLab let you keep an eye on various aspects of your project. The
-following compliance tools are available:
-
-- [Compliance report](compliance_report/index.md): View recent merge request activity across
- all projects in a group. This lets you see if merge requests were approved, and by whom.
-- [License Compliance](license_compliance/index.md): Search your project's dependencies for their
- licenses. This lets you determine if the licenses of your project's dependencies are compatible
- with your project's license.
-- [Compliance framework labels](../project/settings/index.md#compliance-frameworks): Label your projects that have unique compliance requirements.
-- [Compliance pipelines](../project/settings/index.md#compliance-pipeline-configuration): Ensure that needed compliance jobs are always run for compliance-labeled projects.
-- [Audit Events](../../administration/audit_events.md): Get visibility into individual actions that have taken place in your GitLab instance, group, or project.
-- [Audit Reports](../../administration/audit_reports.md): Create and access reports based on the audit events that have occurred. Use pre-built GitLab reports or the API to build your own.
+The compliance tools provided by GitLab help you keep an eye on various aspects of your project. For more information
+on GitLab compliance features for projects, groups, and instances, see
+[Compliance features](../../administration/compliance.md).
diff --git a/doc/user/compliance/license_compliance/index.md b/doc/user/compliance/license_compliance/index.md
index f89165e7e2d..04d3cc0595e 100644
--- a/doc/user/compliance/license_compliance/index.md
+++ b/doc/user/compliance/license_compliance/index.md
@@ -5,7 +5,7 @@ group: Composition Analysis
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# License Compliance **(ULTIMATE)**
+# License compliance **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5483) in GitLab 11.0.
@@ -14,10 +14,6 @@ project's dependencies for their licenses. You can then decide whether to allow
each license. For example, if your application uses an external (open source) library whose license
is incompatible with yours, then you can deny the use of that license.
-INFO:
-Try License Compliance scanning to search project dependencies in GitLab Ultimate.
-[It's free for 30 days](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=u-compliance-docs).
-
You can take advantage of License Compliance by either:
- [Including the job](#configuration)
@@ -73,7 +69,7 @@ Gradle 1.x projects are not supported. The minimum supported version of Maven is
| Language | Package managers | Notes |
|------------|----------------------------------------------------------------------------------------------|-------|
| JavaScript | [Bower](https://bower.io/), [npm](https://www.npmjs.com/) (7 and earlier) | |
-| Go | [Godep](https://github.com/tools/godep), [go mod](https://github.com/golang/go/wiki/Modules) | |
+| Go | [Godep](https://github.com/tools/godep) ([deprecated](../../../update/deprecations.md#godep-support-in-license-compliance)), [go mod](https://github.com/golang/go/wiki/Modules) | |
| Java | [Gradle](https://gradle.org/), [Maven](https://maven.apache.org/) | |
| .NET | [NuGet](https://www.nuget.org/) | The .NET Framework is supported via the [mono project](https://www.mono-project.com/). There are, however, some limitations. The scanner doesn't support Windows-specific dependencies and doesn't report dependencies of your project's listed dependencies. Also, the scanner always marks detected licenses for all dependencies as `unknown`. |
| Python | [pip](https://pip.pypa.io/en/stable/) | Python is supported through [requirements.txt](https://pip.pypa.io/en/stable/user_guide/#requirements-files) and [Pipfile.lock](https://github.com/pypa/pipfile#pipfilelock). |
@@ -92,7 +88,6 @@ 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/) |
-| Scala | [sbt](https://www.scala-sbt.org/) |
| Rust | [Cargo](https://crates.io) |
| PHP | [Composer](https://getcomposer.org/) |
@@ -809,6 +804,10 @@ An approval is optional when a license report:
- Contains no software license violations.
- Contains only new licenses that are `allowed` or unknown.
+## Warnings
+
+We recommend that you use the most recent version of all containers, and the most recent supported version of all package managers and languages. Using previous versions carries an increased security risk because unsupported versions may no longer benefit from active security reporting and backporting of security fixes.
+
## Troubleshooting
### ASDF_PYTHON_VERSION does not automatically install the version
diff --git a/doc/user/crm/index.md b/doc/user/crm/index.md
index d68ce0a4f7a..f0f9a907a73 100644
--- a/doc/user/crm/index.md
+++ b/doc/user/crm/index.md
@@ -6,13 +6,7 @@ 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.
-You should not use this feature for production environments.
+> - [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.
With customer relations management (CRM) you can create a record of contacts
(individuals) and organizations (companies) and relate them to issues.
@@ -20,6 +14,25 @@ With customer relations management (CRM) you can create a record of contacts
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).
+## Permissions
+
+| Permission | Guest | Reporter | Developer, Maintainer, and Owner |
+| ---------- | ---------------- | -------- | -------------------------------- |
+| View contacts/organizations | | ✓ | ✓ |
+| View issue contacts | | ✓ | ✓ |
+| Add/remove issue contacts | | ✓ | ✓ |
+| Create/edit contacts/organizations | | | ✓ |
+
+## Enable customer relations management (CRM)
+
+To enable customer relations management in a group:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Settings > General**.
+1. Expand the **Permissions and group features** section.
+1. Select **Enable customer relations**.
+1. Select **Save changes**.
+
## Contacts
### View contacts linked to a group
@@ -118,10 +131,6 @@ API.
### Add or remove issue contacts
-Prerequisites:
-
-- You must have at least the [Developer role](../permissions.md#project-members-permissions) for a group.
-
### Add contacts to an issue
To add contacts to an issue use the `/add_contacts`
diff --git a/doc/user/gitlab_com/index.md b/doc/user/gitlab_com/index.md
index 8d858a282dd..f02073b477b 100644
--- a/doc/user/gitlab_com/index.md
+++ b/doc/user/gitlab_com/index.md
@@ -70,7 +70,7 @@ To back up an entire project on GitLab.com, you can export it either:
can also use the API to programmatically upload exports to a storage platform,
such as Amazon S3.
-With exports, be aware of [what is and is not](../project/settings/import_export.md#exported-contents)
+With exports, be aware of [what is and is not](../project/settings/import_export.md#items-that-are-exported)
included in a project export.
GitLab is built on Git, so you can back up just the repository of a project by
@@ -162,17 +162,18 @@ varies by format:
## Account and limit settings
-GitLab.com has the following [account limits](../admin_area/settings/account_and_limit_settings.md)
-enabled. If a setting is not listed, it is set to the default value.
+GitLab.com has the following account limits enabled. If a setting is not listed,
+the default value [is the same as for self-managed instances](../admin_area/settings/account_and_limit_settings.md):
-If you are near or over the repository size limit, you can either
-[reduce your repository size with Git](../project/repository/reducing_the_repo_size_using_git.md) or [purchase additional storage](https://about.gitlab.com/pricing/licensing-faq/#can-i-buy-more-storage).
+| Setting | GitLab.com default |
+|-------------------------------|--------------------|
+| [Repository size including LFS](../admin_area/settings/account_and_limit_settings.md#repository-size-limit) | 10 GB |
+| Maximum import size | 5 GB |
+| Maximum attachment size | 10 MB |
-| Setting | GitLab.com | Default |
-|-------------------------------|-------------|---------|
-| [Repository size including LFS](../admin_area/settings/account_and_limit_settings.md#repository-size-limit) | 10 GB | Unlimited |
-| Maximum import size | 5 GB | Unlimited ([Modified](https://gitlab.com/gitlab-org/gitlab/-/issues/251106) from 50MB to unlimited in GitLab 13.8.) |
-| Maximum attachment size | 10 MB | 10 MB |
+If you are near or over the repository size limit, you can either
+[reduce your repository size with Git](../project/repository/reducing_the_repo_size_using_git.md)
+or [purchase additional storage](https://about.gitlab.com/pricing/licensing-faq/#can-i-buy-more-storage).
NOTE:
`git push` and GitLab project imports are limited to 5 GB per request through
@@ -209,13 +210,17 @@ also load certain page content directly from common public CDN hostnames.
## Webhooks
-The following limits apply for [Webhooks](../project/integrations/webhooks.md):
+The following limits apply for [webhooks](../project/integrations/webhooks.md):
+
+| Setting | Default for GitLab.com |
+|----------------------|-------------------------|
+| Webhook rate limit | `120` calls per minute for GitLab Free, unlimited for GitLab Premium and GitLab Ultimate |
+| Number of webhooks | `100` per project, `50` per group |
+| Maximum payload size | 25 MB |
-| Setting | GitLab.com | Default |
-|----------------------|-------------|---------|
-| [Webhook rate limit](../../administration/instance_limits.md#webhook-rate-limit) | `120` calls per minute for GitLab Free, unlimited for GitLab Premium and GitLab Ultimate | Unlimited |
-| [Number of webhooks](../../administration/instance_limits.md#number-of-webhooks) | `100` per project, `50` per group | `100` per project, `50` per group |
-| Maximum payload size | 25 MB | 25 MB |
+For self-managed instance limits, see
+[Webhook rate limit](../../administration/instance_limits.md#webhook-rate-limit)
+and [Number of webhooks](../../administration/instance_limits.md#number-of-webhooks).
## Runner SaaS
diff --git a/doc/user/group/epics/epic_boards.md b/doc/user/group/epics/epic_boards.md
index 1bc1e4d703b..d184030718a 100644
--- a/doc/user/group/epics/epic_boards.md
+++ b/doc/user/group/epics/epic_boards.md
@@ -9,10 +9,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5067) in GitLab 13.10.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/290039) in GitLab 14.1.
-INFO:
-Try epic boards and more with a
-[free 30-day trial of GitLab Ultimate](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=p-epics-boards-docs).
-
Epic boards build on the existing [epic tracking functionality](index.md) and
[labels](../../project/labels.md). Your epics appear as cards in vertical lists, organized by their assigned
labels.
diff --git a/doc/user/group/epics/img/epics_search_v13_11.png b/doc/user/group/epics/img/epics_search_v13_11.png
deleted file mode 100644
index c11aca96a99..00000000000
--- a/doc/user/group/epics/img/epics_search_v13_11.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/group/epics/img/epics_search_v14_7.png b/doc/user/group/epics/img/epics_search_v14_7.png
new file mode 100644
index 00000000000..baed532c736
--- /dev/null
+++ b/doc/user/group/epics/img/epics_search_v14_7.png
Binary files differ
diff --git a/doc/user/group/epics/img/epics_sort.png b/doc/user/group/epics/img/epics_sort.png
deleted file mode 100644
index b23c65fd0ef..00000000000
--- a/doc/user/group/epics/img/epics_sort.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/group/epics/img/epics_sort_14_7.png b/doc/user/group/epics/img/epics_sort_14_7.png
new file mode 100644
index 00000000000..df84dccd06c
--- /dev/null
+++ b/doc/user/group/epics/img/epics_sort_14_7.png
Binary files differ
diff --git a/doc/user/group/epics/index.md b/doc/user/group/epics/index.md
index 3889398e2f8..d6f87a026b8 100644
--- a/doc/user/group/epics/index.md
+++ b/doc/user/group/epics/index.md
@@ -8,10 +8,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> Single-level epics were [moved](https://gitlab.com/gitlab-org/gitlab/-/issues/37081) from GitLab Ultimate to GitLab Premium in 12.8.
-INFO:
-Check out [multi-level child epics](manage_epics.md#multi-level-child-epics) with a
-[free 30-day trial of GitLab Ultimate](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=p-epics-docs).
-
When [issues](../../project/issues/index.md) share a theme across projects and milestones,
you can manage them by using epics.
diff --git a/doc/user/group/epics/manage_epics.md b/doc/user/group/epics/manage_epics.md
index f5b1a2a6ee6..caca10a05a2 100644
--- a/doc/user/group/epics/manage_epics.md
+++ b/doc/user/group/epics/manage_epics.md
@@ -163,6 +163,8 @@ than 1000. The cached value is rounded to thousands or millions and updated ever
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/37081) from GitLab Ultimate to GitLab Premium in 12.8.
> - Searching by the user's reaction emoji [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/325630) in GitLab 13.11.
> - Sorting by epic titles [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/331625) in GitLab 14.1.
+> - Searching by milestone and confidentiality [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/268372) in GitLab 14.2 [with a flag](../../../administration/feature_flags.md) named `vue_epics_list`. Disabled by default.
+> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/276189) in GitLab 14.7.
You can search for an epic from the list of epics using filtered search bar based on following
parameters:
@@ -170,9 +172,11 @@ parameters:
- Title or description
- Author name / username
- Labels
+- Milestones
+- Confidentiality
- Reaction emoji
-![epics search](img/epics_search_v13_11.png)
+![epics search](img/epics_search_v14_7.png)
To search:
@@ -184,8 +188,6 @@ To search:
You can also sort epics list by:
-- Created date
-- Last updated
- Start date
- Due date
- Title
@@ -194,7 +196,7 @@ Each option contains a button that can toggle the order between **Ascending** an
The sort option and order is saved and used wherever you browse epics, including the
[Roadmap](../roadmap/index.md).
-![epics sort](img/epics_sort.png)
+![epics sort](img/epics_sort_14_7.png)
## Change activity sort order
diff --git a/doc/user/group/img/group_code_coverage_analytics_v13_9.png b/doc/user/group/img/group_code_coverage_analytics_v13_9.png
deleted file mode 100644
index 8cd71396381..00000000000
--- a/doc/user/group/img/group_code_coverage_analytics_v13_9.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/group/index.md b/doc/user/group/index.md
index db6ed02f405..8aa9b8e799d 100644
--- a/doc/user/group/index.md
+++ b/doc/user/group/index.md
@@ -1,7 +1,7 @@
---
type: reference, howto
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -100,6 +100,14 @@ You can give a user access to all projects in a group.
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.
+1. Select **Invite**.
+
+Members that are not automatically added are displayed on the **Invited** tab.
+Users can be on this tab because they:
+
+- Have not yet accepted the invitation.
+- Are waiting for [approval from an administrator](../admin_area/moderate_users.md).
+- [Exceed the group user cap](#user-cap-for-groups).
## Request access to a group
@@ -123,7 +131,7 @@ your group.
1. Select **Your Groups**.
1. Find the group and select it.
1. From the left menu, select **Settings > General**.
-1. Expand the **Permissions, LFS, 2FA** section.
+1. Expand the **Permissions and group features** section.
1. Clear the **Allow users to request access** checkbox.
1. Select **Save changes**.
@@ -219,7 +227,7 @@ To change this setting for a specific group:
1. Select **Your Groups**.
1. Find the group and select it.
1. From the left menu, select **Settings > General**.
-1. Expand the **Permissions, LFS, 2FA** section.
+1. Expand the **Permissions and group features** section.
1. Select the desired option in the **Default branch protection** dropdown list.
1. Select **Save changes**.
@@ -250,7 +258,7 @@ To change this setting for a specific group:
1. Select **Your Groups**.
1. Find the group and select it.
1. From the left menu, select **Settings > General**.
-1. Expand the **Permissions, LFS, 2FA** section.
+1. Expand the **Permissions and group features** section.
1. Select the desired option in the **Allowed to create projects** dropdown list.
1. Select **Save changes**.
@@ -489,7 +497,7 @@ If you select this setting in the **Animals** group:
To prevent sharing outside of the group's hierarchy:
1. Go to the group's **Settings > General** page.
-1. Expand the **Permissions, LFS, 2FA** section.
+1. Expand the **Permissions and group features** section.
1. Select **Prevent members from sending invitations to groups outside of `<group_name>` and its subgroups**.
1. Select **Save changes**.
@@ -501,13 +509,81 @@ a project with another group](../project/members/share_project_with_groups.md) t
To prevent a project from being shared with other groups:
1. Go to the group's **Settings > General** page.
-1. Expand the **Permissions, LFS, 2FA** section.
+1. Expand the **Permissions and group features** section.
1. Select **Prevent sharing a project within `<group_name>` with other groups**.
1. Select **Save changes**.
This setting applies to all subgroups unless overridden by a group owner. Groups already
added to a project lose access when the setting is enabled.
+## User cap for groups
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/330027) in GitLab 14.7.
+
+FLAG:
+On self-managed GitLab, this feature is not available. On GitLab.com, this feature is available for some groups.
+This feature is not ready for production use.
+
+When the number of billable members reaches the user cap, new users can't be added to the group
+without being approved by the group owner.
+
+Groups with the user cap feature enabled have [group sharing](#share-a-group-with-another-group)
+disabled for the group and its subgroups.
+
+### Specify a user cap for a group
+
+Prerequisite:
+
+- You must be assigned the [Owner role](../permissions.md#group-members-permissions) for the group.
+
+To specify a user cap:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+ You can set a cap on the top-level group only.
+1. On the left sidebar, select **Settings > General**.
+1. Expand **Permissions and group features**.
+1. In the **User cap** box, enter the desired number of users.
+1. Select **Save changes**.
+
+If you already have more users in the group than the user cap value, users
+are not removed. However, you can't add more without approval.
+
+Increasing the user cap does not approve pending members.
+
+### Remove the user cap for a group
+
+You can remove the user cap, so there is no limit on the number of members you can add to a group.
+
+Prerequisite:
+
+- You must be assigned the [Owner role](../permissions.md#group-members-permissions) for the group.
+
+To remove the user cap:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Settings > General**.
+1. Expand **Permissions and group features**.
+1. In the **User cap** box, delete the value.
+1. Select **Save changes**.
+
+Decreasing the user cap does not approve pending members.
+
+### Approve pending members for a group
+
+When the number of billable users reaches the user cap, any new member is put in a pending state
+and must be approved.
+
+Prerequisite:
+
+- You must be assigned the [Owner role](../permissions.md#group-members-permissions) for the group.
+
+To approve members that are pending because they've exceeded the user cap:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Settings > Usage Quotas**.
+1. On the **Seats** tab, under the alert, select **View pending approvals**.
+1. For each member you want to approve, select **Approve**.
+
## Prevent members from being added to projects in a group **(PREMIUM)**
As a group owner, you can prevent any new project membership for all
@@ -523,7 +599,7 @@ The setting does not cascade. Projects in subgroups observe the subgroup configu
To prevent members from being added to projects in a group:
1. Go to the group's **Settings > General** page.
-1. Expand the **Permissions, LFS, 2FA** section.
+1. Expand the **Permissions and group features** section.
1. Under **Member lock**, select **Prevent adding new members to project membership within this group**.
1. Select **Save changes**.
@@ -535,9 +611,9 @@ API requests to add a new user to a project are not possible.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/287940) in GitLab 14.2.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/336520) in GitLab 14.5.
-You can export a list of members in a group as a CSV.
+You can export a list of members in a group or subgroup as a CSV.
-1. Go to your project and select **Project information > Members**.
+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.
@@ -574,7 +650,7 @@ You should consider these security implications before configuring IP address re
To restrict group access by IP address:
1. Go to the group's **Settings > General** page.
-1. Expand the **Permissions, LFS, 2FA** section.
+1. Expand the **Permissions and group features** section.
1. In the **Allow access to the following IP addresses** field, enter IP address ranges in CIDR notation.
1. Select **Save changes**.
@@ -591,13 +667,15 @@ You can prevent users with email addresses in specific domains from being added
To restrict group access by domain:
1. Go to the group's **Settings > General** page.
-1. Expand the **Permissions, LFS, 2FA** section.
+1. Expand the **Permissions and group features** section.
1. In the **Restrict membership by email** field, enter the domain names.
1. Select **Save changes**.
![Domain restriction by email](img/restrict-by-email.gif)
-Any time you attempt to add a new user, they are compared against this list.
+Any time you attempt to add a new user, the user's [primary email](../profile/index.md#change-your-primary-email) is compared against this list.
+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:
@@ -645,7 +723,7 @@ You can disable all email notifications related to the group, which includes its
To disable email notifications:
1. Go to the group's **Settings > General** page.
-1. Expand the **Permissions, LFS, 2FA** section.
+1. Expand the **Permissions and group features** section.
1. Select **Disable email notifications**.
1. Select **Save changes**.
@@ -663,7 +741,7 @@ This is particularly helpful for groups with a large number of users.
To disable group mentions:
1. Go to the group's **Settings > General** page.
-1. Expand the **Permissions, LFS, 2FA** section.
+1. Expand the **Permissions and group features** section.
1. Select **Disable group mentions**.
1. Select **Save changes**.
@@ -688,7 +766,7 @@ the default setting.
To enable delayed deletion of projects in a group:
1. Go to the group's **Settings > General** page.
-1. Expand the **Permissions, LFS, 2FA** section.
+1. Expand the **Permissions and group features** section.
1. Check **Enable delayed project deletion**.
1. Optional. To prevent subgroups from changing this setting, select **Enforce for all subgroups**.
1. Select **Save changes**.
@@ -713,7 +791,7 @@ If even one is set to `true`, then the group does not allow outside forks.
To prevent projects from being forked outside the group:
1. Go to the top-level group's **Settings > General** page.
-1. Expand the **Permissions, LFS, 2FA** section.
+1. Expand the **Permissions and group features** section.
1. Check **Prevent project forking outside current group**.
1. Select **Save changes**.
@@ -774,7 +852,7 @@ To view the merge request approval rules for a group:
- [Webhooks](../project/integrations/webhooks.md).
- [Kubernetes cluster integration](clusters/index.md).
- [Audit Events](../../administration/audit_events.md#group-events).
-- [Pipelines quota](../admin_area/settings/continuous_integration.md): Keep track of the pipeline quota for the group.
+- [CI/CD minutes quota](../../ci/pipelines/cicd_minutes.md): Keep track of the CI/CD minute quota for the group.
- [Integrations](../admin_area/settings/project_integration_management.md).
- [Transfer a project into a group](../project/settings/index.md#transferring-an-existing-project-into-another-namespace).
- [Share a project with a group](../project/members/share_project_with_groups.md): Give all group members access to the project at once.
diff --git a/doc/user/group/issues_analytics/index.md b/doc/user/group/issues_analytics/index.md
index ac5df6b052f..62337dabcc0 100644
--- a/doc/user/group/issues_analytics/index.md
+++ b/doc/user/group/issues_analytics/index.md
@@ -5,15 +5,18 @@ group: Project Management
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Issue Analytics **(PREMIUM)**
+# Issue analytics for groups **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7478) in GitLab 11.5.
-Issue Analytics is a bar graph which illustrates the number of issues created each month.
+Issue analytics is a bar graph which illustrates the number of issues created each month.
The default time span is 13 months, which includes the current month, and the 12 months
prior.
-To access the chart, navigate to your group sidebar and select **{chart}** **Analytics > Issue Analytics**.
+To access the chart:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Analytics > Issue Analytics**.
Hover over each bar to see the total number of issues.
diff --git a/doc/user/group/repositories_analytics/index.md b/doc/user/group/repositories_analytics/index.md
index c6cd763355b..2487ab188e8 100644
--- a/doc/user/group/repositories_analytics/index.md
+++ b/doc/user/group/repositories_analytics/index.md
@@ -5,11 +5,15 @@ group: Testing
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Repositories Analytics **(PREMIUM)**
+# Repositories analytics for groups **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/215104) in GitLab 13.4.
-![Group repositories analytics](../img/group_code_coverage_analytics_v13_9.png)
+Repositories analytics for groups provides information about test coverage for all projects in a group. An
+[issue exists](https://gitlab.com/gitlab-org/gitlab/-/issues/273527) to also extend support for all projects in
+subgroups.
+
+It is similar to [repository analytics for projects](../../analytics/repository_analytics.md).
## Current group code coverage
diff --git a/doc/user/group/saml_sso/group_managed_accounts.md b/doc/user/group/saml_sso/group_managed_accounts.md
index d62b569a795..06e666f4d24 100644
--- a/doc/user/group/saml_sso/group_managed_accounts.md
+++ b/doc/user/group/saml_sso/group_managed_accounts.md
@@ -1,7 +1,7 @@
---
type: reference, howto
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -113,7 +113,7 @@ on the lifetime of personal access tokens apply.
To set a limit on how long personal access tokens are valid for users in a group managed account:
1. Navigate to the **Settings > General** page in your group's sidebar.
-1. Expand the **Permissions, LFS, 2FA** section.
+1. Expand the **Permissions and group features** section.
1. Fill in the **Maximum allowable lifetime for personal access tokens (days)** field.
1. Click **Save changes**.
diff --git a/doc/user/group/saml_sso/index.md b/doc/user/group/saml_sso/index.md
index 7443be250bb..20ff4a201f5 100644
--- a/doc/user/group/saml_sso/index.md
+++ b/doc/user/group/saml_sso/index.md
@@ -1,7 +1,7 @@
---
type: reference, howto
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -14,10 +14,6 @@ This page describes SAML for groups. For instance-wide SAML on self-managed GitL
SAML on GitLab.com allows users to sign in through their SAML identity provider. If the user is not already a member, the sign-in process automatically adds the user to the appropriate group.
-INFO:
-Use your own SAML authentication to log in to [GitLab.com](http://gitlab.com/).
-[Try GitLab Ultimate free for 30 days](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=p-saml-sso-docs).
-
User synchronization of SAML SSO groups is supported through [SCIM](scim_setup.md). SCIM supports adding and removing users from the GitLab group automatically.
For example, if you remove a user from the SCIM app, SCIM removes that same user from the GitLab group.
@@ -72,10 +68,10 @@ To create users with the correct information for improved [user access and manag
the user's details must be passed to GitLab as attributes in the SAML assertion. At a minimum, the user's email address
must be specified as an attribute named `email` or `mail`.
-GitLab.com supports the following attributes:
+You can configure the following attributes with GitLab.com Group SAML:
- `username` or `nickname`. We recommend you configure only one of these.
-- The [attributes also available](../../../integration/saml.md#assertions) to self-managed GitLab instances.
+- The [attributes available](../../../integration/saml.md#assertions) to self-managed GitLab instances.
### Metadata configuration
@@ -110,6 +106,7 @@ The certificate [fingerprint algorithm](../../../integration/saml.md#notes-on-co
> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/292811) in GitLab 13.8, with an updated timeout experience.
> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/211962) in GitLab 13.8 with allowing group owners to not go through SSO.
> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/9152) in GitLab 13.11 with enforcing open SSO session to use Git if this setting is switched on.
+> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/339888) in GitLab 14.7 to not enforce SSO checks for Git activity originating from CI/CD jobs.
With this option enabled, users (except users with the Owner role) must access GitLab using your group GitLab single sign-on URL to access group resources. Users added manually as members can't access group resources.
@@ -127,6 +124,7 @@ SSO has the following effects when enabled:
even if the project is forked.
- For Git activity over SSH and HTTPS, users must have at least one active session signed-in through SSO before they can push to or
pull from a GitLab repository.
+- Git activity originating from CI/CD jobs do not have the SSO check enforced.
- Credentials that are not tied to regular users (for example, access tokens and deploy keys) do not have the SSO check enforced.
- Users must be signed-in through SSO before they can pull images using the [Dependency Proxy](../../packages/dependency_proxy/index.md).
<!-- Add bullet for API activity when https://gitlab.com/gitlab-org/gitlab/-/issues/9152 is complete -->
@@ -137,8 +135,6 @@ When SSO is enforced, users are not immediately revoked. If the user:
- Has an active session, they can continue accessing the group for up to 24 hours until the identity
provider session times out.
-When SCIM updates, the user's access is immediately revoked.
-
## Providers
The SAML standard means that you can use a wide range of identity providers with GitLab. Your identity provider might have relevant documentation. It can be generic SAML documentation or specifically targeted for GitLab.
@@ -167,10 +163,11 @@ objectID mapping and the [SCIM documentation should be followed](scim_setup.md#a
| Identity provider single sign-on URL | Login URL |
| Certificate fingerprint | Thumbprint |
-We recommend:
+The recommended attributes and claims settings are:
- **Unique User Identifier (Name identifier)** set to `user.objectID`.
- **nameid-format** set to persistent.
+- Additional claims set to [supported attributes](#user-attributes).
If using [Group Sync](#group-sync), customize the name of the group claim to match the required attribute.
@@ -304,7 +301,14 @@ If a user is already a member of the group, linking the SAML identity does not c
### Blocking access
-Please refer to [Blocking access via SCIM](scim_setup.md#blocking-access).
+To rescind a user's access to the group when only SAML SSO is configured, either:
+
+- Remove (in order) the user from:
+ 1. The user data store on the identity provider or the list of users on the specific app.
+ 1. The GitLab.com group.
+- Use Group Sync at the top-level of your group to [automatically remove the user](#automatic-member-removal).
+
+To rescind a user's access to the group when also using SCIM, refer to [Blocking access](scim_setup.md#blocking-access).
### Unlinking accounts
@@ -349,6 +353,10 @@ Ensure your SAML identity provider sends an attribute statement named `Groups` o
</saml:AttributeStatement>
```
+WARNING:
+Setting up Group Sync can disconnect users from SAML IDP if there is any mismatch in the configuration. Ensure the
+`Groups` attribute is included in the SAML response, and the **SAML Group Name** matches the `AttributeValue` attribute.
+
Other attribute names such as `http://schemas.microsoft.com/ws/2008/06/identity/claims/groups`
are not accepted as a source of groups.
See the [SAML troubleshooting page](../../../administration/troubleshooting/group_saml_scim.md)
diff --git a/doc/user/group/saml_sso/scim_setup.md b/doc/user/group/saml_sso/scim_setup.md
index 2651bcb9e12..d7d663f4115 100644
--- a/doc/user/group/saml_sso/scim_setup.md
+++ b/doc/user/group/saml_sso/scim_setup.md
@@ -1,7 +1,7 @@
---
type: howto, reference
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -184,8 +184,7 @@ For role information, please see the [Group SAML page](index.md#user-access-and-
### Blocking access
To rescind access to the top-level group, all sub-groups, and projects, remove or deactivate the user
-on the identity provider. SCIM providers generally update GitLab with the changes on demand, which
-is minutes at most. The user's membership is revoked and they immediately lose access.
+on the identity provider. After the identity provider performs a sync, based on its configured schedule, the user's membership is revoked and they lose access.
NOTE:
Deprovisioning does not delete the GitLab user account.
diff --git a/doc/user/group/settings/group_access_tokens.md b/doc/user/group/settings/group_access_tokens.md
new file mode 100644
index 00000000000..816edb629f5
--- /dev/null
+++ b/doc/user/group/settings/group_access_tokens.md
@@ -0,0 +1,147 @@
+---
+stage: Manage
+group: Authentication & 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
+---
+
+# Group access tokens
+
+With group access tokens, you can use a single token to:
+
+- Perform actions for groups.
+- Manage the projects within the group.
+
+You can use a group access token to authenticate:
+
+- With the [GitLab API](../../../api/index.md#personalprojectgroup-access-tokens).
+- In [GitLab 14.2](https://gitlab.com/gitlab-org/gitlab/-/issues/330718) and later, authenticate with Git over HTTPS.
+
+After you configure a group access token, you don't need a password when you authenticate.
+Instead, you can enter any non-blank value.
+
+Group access tokens are similar to [project access tokens](../../project/settings/project_access_tokens.md)
+and [personal access tokens](../../profile/personal_access_tokens.md), except they are
+associated with a group rather than a project or user.
+
+You can use group access tokens:
+
+- On GitLab SaaS if you have the Premium license tier or higher. Group access tokens are not available with a [trial license](https://about.gitlab.com/free-trial/).
+- On self-managed instances of GitLab, with any license tier. If you have the Free tier:
+ - Review your security and compliance policies around
+ [user self-enrollment](../../admin_area/settings/sign_up_restrictions.md#disable-new-sign-ups).
+ - Consider [disabling group access tokens](#enable-or-disable-group-access-token-creation) to
+ lower potential abuse.
+
+Group access tokens inherit the [default prefix setting](../../admin_area/settings/account_and_limit_settings.md#personal-access-token-prefix)
+configured for personal access tokens.
+
+## Create a group access token using UI
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214045) in GitLab 14.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. 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).
+1. Select **Create group access token**.
+
+A group access token is displayed. Save the group access token somewhere safe. After you leave or refresh the page, you can't view it again.
+
+## Create a group access token using Rails console
+
+GitLab 14.6 and earlier doesn't support creating group access tokens using the UI
+or API. However, administrators can use a workaround:
+
+1. Run the following commands in a [Rails console](../../../administration/operations/rails_console.md):
+
+ ```ruby
+ # Set the GitLab administration user to use. If user ID 1 is not available or is not an administrator, use 'admin = User.admins.first' instead to select an administrator.
+ admin = User.find(1)
+
+ # Set the group group you want to create a token for. For example, group with ID 109.
+ group = Group.find(109)
+
+ # Create the group bot user. For further group access tokens, the username should be group_#{group.id}_bot#{bot_count}. For example, group_109_bot2 and email address group_109_bot2@example.com.
+ bot = Users::CreateService.new(admin, { name: 'group_token', username: "group_#{group.id}_bot", email: "group_#{group.id}_bot@example.com", user_type: :project_bot }).execute
+
+ # Confirm the group bot.
+ bot.confirm
+
+ # Add the bot to the group with the required role.
+ group.add_user(bot, :maintainer)
+
+ # Give the bot a personal access token.
+ token = bot.personal_access_tokens.create(scopes:[:api, :write_repository], name: 'group_token')
+
+ # Get the token value.
+ gtoken = token.token
+ ```
+
+1. Test if the generated group access token works:
+
+ 1. Use the group access token in the `PRIVATE-TOKEN` header with GitLab REST APIs. For example:
+
+ - [Create an epic](../../../api/epics.md#new-epic) in the group.
+ - [Create a project pipeline](../../../api/pipelines.md#create-a-new-pipeline) in one of the group's projects.
+ - [Create an issue](../../../api/issues.md#new-issue) in one of the group's projects.
+
+ 1. Use the group token to [clone a group's project](../../../gitlab-basics/start-using-git.md#clone-with-https)
+ using HTTPS.
+
+## Revoke a group access token using the UI
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214045) in GitLab 14.7.
+
+To revoke 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. Next to the group access token to revoke, select **Revoke**.
+
+## Revoke a group access token using Rails console
+
+GitLab 14.6 and earlier doesn't support revoking group access tokens using the UI
+or API. However, administrators can use a workaround.
+
+To revoke a group access token, run the following command in a [Rails console](../../../administration/operations/rails_console.md):
+
+```ruby
+bot = User.find_by(username: 'group_109_bot') # the owner of the token you want to revoke
+token = bot.personal_access_tokens.last # the token you want to revoke
+token.revoke!
+```
+
+## Scopes for a group access token
+
+The scope determines the actions you can perform when you authenticate with a group access token.
+
+| Scope | Description |
+|:-------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `api` | Grants complete read and write access to the scoped group and related project API, including the [Package Registry](../../packages/package_registry/index.md). |
+| `read_api` | Grants read access to the scoped group and related project API, including the [Package Registry](../../packages/package_registry/index.md). |
+| `read_registry` | Allows read access (pull) to the [Container Registry](../../packages/container_registry/index.md) images if any project within a group is private and authorization is required. |
+| `write_registry` | Allows write access (push) to the [Container Registry](../../packages/container_registry/index.md). |
+| `read_repository` | Allows read access (pull) to all repositories within a group. |
+| `write_repository` | Allows read and write access (pull and push) to all repositories within a group. |
+
+## Enable or disable group access token creation
+
+To enable or disable group access token creation for all sub-groups in a top-level group:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Settings > General**.
+1. Expand **Permissions and group features**.
+1. Under **Permissions**, turn on or off **Allow project and group access token creation**.
+
+Even when creation is disabled, you can still use and revoke existing group access tokens.
+
+## Bot users
+
+Each time you create a group access token, a bot user is created and added to the group.
+These bot users are similar to [project bot users](../../project/settings/project_access_tokens.md#project-bot-users), but are added to groups instead of projects. For more information, see
+[Project bot users](../../project/settings/project_access_tokens.md#project-bot-users).
diff --git a/doc/user/group/subgroups/index.md b/doc/user/group/subgroups/index.md
index acce296da93..ef984a76a7d 100644
--- a/doc/user/group/subgroups/index.md
+++ b/doc/user/group/subgroups/index.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -101,7 +101,7 @@ You can change this setting:
- As group owner:
1. Select the group.
1. On the left sidebar, select **Settings > General**.
- 1. Expand **Permissions, LFS, 2FA**.
+ 1. Expand **Permissions and group features**.
- As an administrator:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Groups**.
diff --git a/doc/user/group/value_stream_analytics/img/vsa_stage_table_v13_12.png b/doc/user/group/value_stream_analytics/img/vsa_stage_table_v13_12.png
deleted file mode 100644
index 24d485306be..00000000000
--- a/doc/user/group/value_stream_analytics/img/vsa_stage_table_v13_12.png
+++ /dev/null
Binary files differ
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
new file mode 100644
index 00000000000..c9074cbb5ea
--- /dev/null
+++ 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 b91e258b04a..4663cfc8bfd 100644
--- a/doc/user/group/value_stream_analytics/index.md
+++ b/doc/user/group/value_stream_analytics/index.md
@@ -5,34 +5,35 @@ 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
---
-# Value Stream Analytics **(PREMIUM)**
+# 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
+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
+(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 can help you quickly determine the velocity of a given
+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.
-For information on how to contribute to the development of Value Stream Analytics, see our [contributor documentation](../../../development/value_stream_analytics.md).
+For information on how to contribute to the development of value stream analytics, see our [contributor documentation](../../../development/value_stream_analytics.md).
-To view group-level Value Stream Analytics:
+To view value stream analytics for groups:
1. On the top bar, select **Menu > Groups** and find your group.
1. On the left sidebar, select **Analytics > Value stream**.
-Value Stream Analytics at the group level includes data for the selected group and its subgroups.
+Value stream analytics at the group level includes data for the selected group and its subgroups.
NOTE:
-[Project-level Value Stream Analytics](../../analytics/value_stream_analytics.md) is also available.
+[Value stream analytics for projects](../../analytics/value_stream_analytics.md) is also available.
## Default stages
-The stages tracked by Value Stream Analytics by default represent the [GitLab flow](../../../topics/gitlab_flow.md). These stages can be customized in Group Level Value Stream Analytics.
+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.
- **Issue** (Tracker)
- Time to schedule an issue (by milestone or by adding it to an issue board)
@@ -100,8 +101,7 @@ sole discretion of GitLab Inc.
## How metrics are measured
-> DORA API-based deployment metrics for group-level Value Stream Analytics were
-> [moved](https://gitlab.com/gitlab-org/gitlab/-/issues/337256) from GitLab Ultimate to GitLab Premium in 14.3.
+> 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:
@@ -134,11 +134,11 @@ You can learn more about these metrics in our [analytics definitions](../../anal
## How the stages are measured
-Value Stream Analytics measures each stage from its start event to its end event.
+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.
+Value stream analytics excludes work in progress, meaning it ignores any items that have not reached the end event.
-Each stage of Value Stream Analytics is further described in the table below.
+Each stage of value stream analytics is further described in the table below.
| **Stage** | **Description** |
| --------- | --------------- |
@@ -162,7 +162,7 @@ How this works, behind the scenes:
and so on.
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:
+value stream analytics dashboard does not present any data for:
- Merge requests that do not close an issue.
- Issues not labeled with a label present in the issue board or for issues not assigned a milestone.
@@ -170,7 +170,7 @@ Value Stream Analytics dashboard does not present any data for:
## How the production environment is identified
-Value Stream Analytics identifies production environments by looking for project
+Value stream analytics identifies production environments by looking for project
[environments](../../../ci/yaml/index.md#environment) with a name matching any of these patterns:
- `prod` or `prod/*`
@@ -228,7 +228,7 @@ A few notes:
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.
+ value stream analytics is showing.
## Custom value streams
@@ -236,7 +236,7 @@ A few notes:
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.
+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.
@@ -272,7 +272,7 @@ Hovering over a stage item displays a popover with the following information:
> [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")
+![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.
@@ -288,7 +288,7 @@ Shown metrics and charts includes:
> Sorting the stage table [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/301082) in GitLab 13.12.
-![Value Stream Analytics Stage table](img/vsa_stage_table_v13_12.png "VSA stage table")
+![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:
@@ -378,7 +378,7 @@ In this example, we'd like to measure times for deployment from a staging enviro
- When the code is deployed to staging, the `workflow::staging` label is added to the merge request.
- When the code is deployed to production, the `workflow::production` label is added to the merge request.
-![Label Based Value Stream Analytics Stage](img/vsa_label_based_stage_v14_0.png "Creating a label based Value Stream Analytics Stage")
+![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
@@ -443,14 +443,14 @@ select up to a total of 15 labels.
## Permissions
-To access Group-level Value Stream Analytics, users must have at least the Reporter role.
+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:
+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/).
+- [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/infrastructure/clusters/manage/management_project_applications/cilium.md b/doc/user/infrastructure/clusters/manage/management_project_applications/cilium.md
index b5959624954..5d704a2c6df 100644
--- a/doc/user/infrastructure/clusters/manage/management_project_applications/cilium.md
+++ b/doc/user/infrastructure/clusters/manage/management_project_applications/cilium.md
@@ -37,7 +37,7 @@ You can check the recommended variables for each cluster type in the official do
- [Google GKE](https://docs.cilium.io/en/v1.8/gettingstarted/k8s-install-gke/#deploy-cilium)
- [AWS EKS](https://docs.cilium.io/en/v1.8/gettingstarted/k8s-install-eks/#deploy-cilium)
-Do not use `clusterType` for sandbox environments like [Minikube](https://minikube.sigs.k8s.io/docs/).
+Do not use `clusterType` for sandbox environments like [minikube](https://minikube.sigs.k8s.io/docs/).
You can customize Cilium's Helm variables by defining the
`applications/cilium/values.yaml` file in your cluster
diff --git a/doc/user/infrastructure/clusters/migrate_to_gitlab_agent.md b/doc/user/infrastructure/clusters/migrate_to_gitlab_agent.md
new file mode 100644
index 00000000000..1dd1c760bcc
--- /dev/null
+++ b/doc/user/infrastructure/clusters/migrate_to_gitlab_agent.md
@@ -0,0 +1,88 @@
+---
+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
+---
+
+# 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 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.
+
+The certificate-based integration was used for some popular GitLab features such as,
+GitLab Managed Apps, GitLab-managed clusters, and Auto DevOps.
+
+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.
+
+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.
+
+## 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.
+
+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)
+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.
+
+### Migrate from Auto DevOps
+
+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. 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. 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**.
+
+### 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:
+
+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:
+
+ ```yaml
+ <your job name>:
+ script:
+ - kubectl config use-context $KUBE_CONTEXT
+ ```
+
+## 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).
+
+## Migrating 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).
+
+## Migrate cluster monitoring features
+
+Cluster monitoring features are not supported by the GitLab Agent for Kubernetes yet.
diff --git a/doc/user/infrastructure/iac/index.md b/doc/user/infrastructure/iac/index.md
index 15a680e2193..ceb6101688b 100644
--- a/doc/user/infrastructure/iac/index.md
+++ b/doc/user/infrastructure/iac/index.md
@@ -15,12 +15,14 @@ GitLab, and support Terraform best practices.
## Quick Start
+> SAST test was [introduced](https://gitlab.com/groups/gitlab-org/-/epics/6655) in GitLab 14.6.
+
Use the following `.gitlab-ci.yml` to set up a basic Terraform project integration
for GitLab versions 14.0 and later:
```yaml
include:
- - template: Terraform.gitlab-ci.yml
+ - template: Terraform.latest.gitlab-ci.yml
variables:
# If not using GitLab's HTTP backend, remove this line and specify TF_HTTP_* variables
@@ -30,15 +32,23 @@ variables:
# TF_ROOT: terraform/production
```
-This template includes some opinionated decisions, which you can override:
+This template includes the following parameters that you can override:
-- Including the latest [GitLab Terraform Image](https://gitlab.com/gitlab-org/terraform-images).
-- Using the [GitLab managed Terraform State](#gitlab-managed-terraform-state) as
+- Uses the latest [GitLab Terraform image](https://gitlab.com/gitlab-org/terraform-images).
+- Uses the [GitLab-managed Terraform State](#gitlab-managed-terraform-state) as
the Terraform state storage backend.
-- Creating [four pipeline stages](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml):
- `init`, `validate`, `build`, and `deploy`. These stages
- [run the Terraform commands](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml)
- `init`, `validate`, `plan`, `plan-json`, and `apply`. The `apply` command only runs on the default branch.
+- Creates [four pipeline stages](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml):
+ `test`, `validate`, `build`, and `deploy`. These stages
+ [run the Terraform commands](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml)
+ `test`, `validate`, `plan`, `plan-json`, and `apply`. The `apply` command only runs on the default branch.
+- Runs the [Terraform SAST scanner](../../application_security/iac_scanning/index.md#configure-iac-scanning-manually),
+ that you can disable by creating a `SAST_DISABLED` environment variable and setting it to `1`.
+
+The latest template described above might contain breaking changes between major GitLab releases. For users requiring more stable setups, we
+recommend using the stable templates:
+
+- [A ready to use version](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml)
+- [A base template for customized setups](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml)
This video from January 2021 walks you through all the GitLab Terraform integration features:
diff --git a/doc/user/markdown.md b/doc/user/markdown.md
index 1b3cd5d4478..3d640185a55 100644
--- a/doc/user/markdown.md
+++ b/doc/user/markdown.md
@@ -1,8 +1,7 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, howto
+info: 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 Flavored Markdown **(FREE)**
@@ -1507,56 +1506,3 @@ entry and paste the spreadsheet:
at Daring Fireball is an excellent resource for a detailed explanation of standard Markdown.
- You can find the detailed specification for CommonMark in the [CommonMark Spec](https://spec.commonmark.org/current/).
- The [CommonMark Dingus](https://spec.commonmark.org/dingus/) helps you test CommonMark syntax.
-
-## Transition from Redcarpet to CommonMark
-
-- In GitLab 11.8, the [Redcarpet Ruby library](https://github.com/vmg/redcarpet)
- was removed. All issues and comments, including those in 11.1 and earlier, are now processed
- by using the [CommonMark Ruby Library](https://github.com/gjtorikian/commonmarker).
-- In GitLab 11.3 and later, CommonMark processes wiki pages and Markdown
- files (`*.md`) in repositories.
-- In GitLab 11.1 and later, the [CommonMark Ruby Library](https://github.com/gjtorikian/commonmarker)
- for Markdown processes all new issues, merge requests, comments, and other Markdown
- content.
-
-The documentation website migrated its Markdown engine
-[from Redcarpet to Kramdown](https://gitlab.com/gitlab-org/gitlab-docs/-/merge_requests/108)
-in October 2018.
-
-You may have older issues, merge requests, or Markdown documents in your
-repository that relied upon nuances of the GitLab RedCarpet version
-of Markdown. Because CommonMark uses slightly stricter syntax, these documents
-may now appear differently after the transition to CommonMark.
-
-For example, numbered lists with nested lists may
-render incorrectly:
-
-```markdown
-1. Chocolate
- - dark
- - milk
-```
-
-To fix this issue, add a space to each nested item. The `-` must be aligned with the first
-character of the top list item (`C` in this case):
-
-```markdown
-1. Chocolate
- - dark
- - milk
-```
-
-1. Chocolate
- - dark
- - milk
-
-We flag any significant differences between Redcarpet and CommonMark Markdown in this document.
-
-If you have many Markdown files, it can be tedious to determine
-if they display correctly or not. You can use the
-[`diff_redcarpet_cmark`](https://gitlab.com/digitalmoksha/diff_redcarpet_cmark)
-tool to generate a list of files and the
-differences between how RedCarpet and CommonMark render the files. It indicates
-if any changes are needed.
-
-`diff_redcarpet_cmark` is not an officially supported product.
diff --git a/doc/user/operations_dashboard/index.md b/doc/user/operations_dashboard/index.md
index 47c41e85345..20284328918 100644
--- a/doc/user/operations_dashboard/index.md
+++ b/doc/user/operations_dashboard/index.md
@@ -6,9 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Operations Dashboard **(PREMIUM)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5781) in GitLab 11.5.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/9218) from GitLab Ultimate to GitLab Premium in 11.10.
-
The Operations Dashboard provides a summary of each project's operational health,
including pipeline and alert status.
diff --git a/doc/user/packages/container_registry/index.md b/doc/user/packages/container_registry/index.md
index 9497dd1625b..c77fc5a0f4b 100644
--- a/doc/user/packages/container_registry/index.md
+++ b/doc/user/packages/container_registry/index.md
@@ -6,13 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitLab Container Registry **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/4040) in GitLab 8.8.
-> - Docker Registry manifest `v1` support was added in GitLab 8.9 to support Docker
-> versions earlier than 1.10.
-> - Starting in GitLab 8.12, if you have [two-factor authentication](../../profile/account/two_factor_authentication.md) enabled in your account, you need
-> to pass a [personal access token](../../profile/personal_access_tokens.md) instead of your password to
-> sign in to the Container Registry.
-> - Support for multiple level image names was added in GitLab 9.1.
> - The group-level Container Registry was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23315) in GitLab 12.10.
> - Searching by image repository name was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31322) in GitLab 13.0.
@@ -42,6 +35,21 @@ Only members of the project or group can access a private project's Container Re
If a project is public, so is the Container Registry.
+### View the tags of a specific image
+
+You can view a list of tags associated with a given container image:
+
+1. Go to your project or group.
+1. Go to **Packages & Registries > Container Registry**.
+1. Select the container image you are interested in.
+
+This brings up the Container Registry **Tag Details** page. You can view details about each tag,
+such as when it was published, how much storage it consumes, and the manifest and configuration
+digests.
+
+You can search, sort (by tag name), filter, and [delete](#delete-images-from-within-gitlab)
+tags on this page. You can share a filtered view by copying the URL from your browser.
+
## Use images from the Container Registry
To download and run a container image hosted in the GitLab Container Registry:
@@ -306,7 +314,7 @@ is set to `always`.
To use your own Docker images for Docker-in-Docker, follow these steps
in addition to the steps in the
-[Docker-in-Docker](../../../ci/docker/using_docker_build.md#use-the-docker-executor-with-the-docker-image-docker-in-docker) section:
+[Docker-in-Docker](../../../ci/docker/using_docker_build.md#use-docker-in-docker) section:
1. Update the `image` and `service` to point to your registry.
1. Add a service [alias](../../../ci/services/index.md#available-settings-for-services).
@@ -336,7 +344,7 @@ error during connect: Get http://docker:2376/v1.39/info: dial tcp: lookup docker
To use your own Docker images with Dependency Proxy, follow these steps
in addition to the steps in the
-[Docker-in-Docker](../../../ci/docker/using_docker_build.md#use-the-docker-executor-with-the-docker-image-docker-in-docker) section:
+[Docker-in-Docker](../../../ci/docker/using_docker_build.md#use-docker-in-docker) section:
1. Update the `image` and `service` to point to your registry.
1. Add a service [alias](../../../ci/services/index.md#available-settings-for-services).
@@ -475,256 +483,9 @@ defined in the `delete_image` job.
### Delete images by using a cleanup policy
-You can create a per-project [cleanup policy](#cleanup-policy) to ensure older tags and images are regularly removed from the
+You can create a per-project [cleanup policy](reduce_container_registry_storage.md#cleanup-policy) to ensure older tags and images are regularly removed from the
Container Registry.
-## Cleanup policy
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15398) in GitLab 12.8.
-> - [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/218737) from "expiration policy" to "cleanup policy" in GitLab 13.2.
-
-The cleanup policy is a scheduled job you can use to remove tags from the Container Registry.
-For the project where it's defined, tags matching the regex pattern are removed.
-The underlying layers and images remain.
-
-To delete the underlying layers and images that aren't associated with any tags, administrators can use
-[garbage collection](../../../administration/packages/container_registry.md#removing-untagged-manifests-and-unreferenced-layers) with the `-m` switch.
-
-### Enable the cleanup policy
-
-Cleanup policies can be run on all projects, with these exceptions:
-
-- For GitLab.com, the project must have been created after 2020-02-22.
- Support for projects created earlier is tracked
- [in this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/196124).
-- For self-managed GitLab instances, the project must have been created
- in GitLab 12.8 or later. However, an administrator can enable the cleanup policy
- for all projects (even those created before 12.8) in
- [GitLab application settings](../../../api/settings.md#change-application-settings)
- by setting `container_expiration_policies_enable_historic_entries` to true.
- Alternatively, you can execute the following command in the [Rails console](../../../administration/operations/rails_console.md#starting-a-rails-console-session):
-
- ```ruby
- ApplicationSetting.last.update(container_expiration_policies_enable_historic_entries: true)
- ```
-
- There are performance risks with enabling it for all projects, especially if you
- are using an [external registry](index.md#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
-GitLab.com that don't have a container image.
-
-### How the cleanup policy works
-
-The cleanup policy collects all tags in the Container Registry and excludes tags
-until only the tags to be deleted remain.
-
-The cleanup policy searches for images based on the tag name. Support for the full path [has not yet been implemented](https://gitlab.com/gitlab-org/gitlab/-/issues/281071), but would allow you to clean up dynamically-named tags.
-
-The cleanup policy:
-
-1. Collects all tags for a given repository in a list.
-1. Excludes the tag named `latest` from the list.
-1. Evaluates the `name_regex` (tags to expire), excluding non-matching names from the list.
-1. Excludes from the list any tags matching the `name_regex_keep` value (tags to preserve).
-1. Excludes any tags that do not have a manifest (not part of the options in the UI).
-1. Orders the remaining tags by `created_date`.
-1. Excludes from the list the N tags based on the `keep_n` value (Number of tags to retain).
-1. Excludes from the list the tags more recent than the `older_than` value (Expiration interval).
-1. Finally, the remaining tags in the list are deleted from the Container Registry.
-
-WARNING:
-On GitLab.com, the execution time for the cleanup policy is limited, and some of the tags may remain in
-the Container Registry after the policy runs. The next time the policy runs, the remaining tags are included,
-so it may take multiple runs for all tags to be deleted.
-
-WARNING:
-GitLab self-managed installs support for third-party container registries that comply with the
-[Docker Registry HTTP API V2](https://docs.docker.com/registry/spec/api/)
-specification. However, this specification does not include a tag delete operation. Therefore, when
-interacting with third-party container registries, GitLab uses a workaround to delete tags. See the
-[related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/15737)
-for more information. Due to possible implementation variations, this workaround is not guaranteed
-to work with all third-party registries in the same predictable way. If you use the GitLab Container
-Registry, this workaround is not required because we implemented a special tag delete operation. In
-this case, you can expect cleanup policies to be consistent and predictable.
-
-### Create a cleanup policy
-
-You can create a cleanup policy in [the API](#use-the-cleanup-policy-api) or the UI.
-
-To create a cleanup policy in the UI:
-
-1. For your project, go to **Settings > Packages & Registries**.
-1. Expand the **Clean up image tags** section.
-1. Complete the fields.
-
- | Field | Description |
- |---------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|
- | **Toggle** | Turn the policy on or off. |
- | **Run cleanup** | How often the policy should run. |
- | **Keep the most recent** | How many tags to _always_ keep for each image. |
- | **Keep tags matching** | The regex pattern that determines which tags to preserve. The `latest` tag is always preserved. For all tags, use `.*`. See other [regex pattern examples](#regex-pattern-examples). |
- | **Remove tags older than** | Remove only tags older than X days. |
- | **Remove tags matching** | The regex pattern that determines which tags to remove. This value cannot be blank. For all tags, use `.*`. See other [regex pattern examples](#regex-pattern-examples). |
-
-1. Click **Save**.
-
-Depending on the interval you chose, the policy is scheduled to run.
-
-NOTE:
-If you edit the policy and click **Save** again, the interval is reset.
-
-### Regex pattern examples
-
-Cleanup policies use regex patterns to determine which tags should be preserved or removed, both in the UI and the API.
-
-Regex patterns are automatically surrounded with `\A` and `\Z` anchors. Do not include any `\A`, `\Z`, `^` or `$` token in the regex patterns as they are not necessary.
-
-Here are examples of regex patterns you may want to use:
-
-- Match all tags:
-
- ```plaintext
- .*
- ```
-
- This is the default value for the expiration regex.
-
-- Match tags that start with `v`:
-
- ```plaintext
- v.+
- ```
-
-- Match only the tag named `main`:
-
- ```plaintext
- main
- ```
-
-- Match tags that are either named or start with `release`:
-
- ```plaintext
- release.*
- ```
-
-- Match tags that either start with `v`, are named `main`, or begin with `release`:
-
- ```plaintext
- (?:v.+|main|release.*)
- ```
-
-### 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).
-
-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.
-
-For self-managed instances, those settings can be updated in the [Rails console](../../../administration/operations/rails_console.md#starting-a-rails-console-session):
-
- ```ruby
- 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):
-
-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.
-
-Examples:
-
-- Select all tags, keep at least 1 tag per image, clean up any tag older than 14 days, run once a month, preserve any images with the name `main` and the policy is enabled:
-
- ```shell
- curl --request PUT --header 'Content-Type: application/json;charset=UTF-8' --header "PRIVATE-TOKEN: <your_access_token>" \
- --data-binary '{"container_expiration_policy_attributes":{"cadence":"1month","enabled":true,"keep_n":1,"older_than":"14d","name_regex":"","name_regex_delete":".*","name_regex_keep":".*-main"}}' \
- "https://gitlab.example.com/api/v4/projects/2"
- ```
-
-Valid values for `cadence` when using the API are:
-
-- `1d` (every day)
-- `7d` (every week)
-- `14d` (every two weeks)
-- `1month` (every month)
-- `3month` (every quarter)
-
-See the API documentation for further details: [Edit project](../../../api/projects.md#edit-project).
-
-### Use with external container registries
-
-When using an [external container registry](../../../administration/packages/container_registry.md#use-an-external-container-registry-with-gitlab-as-an-auth-endpoint),
-running a cleanup policy on a project may have some performance risks.
-If a project runs a policy to remove thousands of tags
-the GitLab background jobs may get backed up or fail completely.
-It is recommended you only enable container cleanup
-policies for projects that were created before GitLab 12.8 if you are confident the number of tags
-being cleaned up is minimal.
-
-### Troubleshooting cleanup policies
-
-If you see the following message:
-
-"Something went wrong while updating the cleanup policy."
-
-Check the regex patterns to ensure they are valid.
-
-GitLab uses [RE2 syntax](https://github.com/google/re2/wiki/Syntax) for regular expressions in the cleanup policy. You can test them with the [regex101 regex tester](https://regex101.com/).
-View some common [regex pattern examples](#regex-pattern-examples).
-
## Limitations
- Moving or renaming existing Container Registry repositories is not supported
@@ -844,7 +605,7 @@ There can be different reasons behind this:
To fix this, there are two workarounds:
- - If you are on GitLab 13.9 or later, you can [set limits for the cleanup policy](#set-cleanup-limits-to-conserve-resources).
+ - If you are on GitLab 13.9 or later, you can [set limits for the cleanup policy](reduce_container_registry_storage.md#set-cleanup-limits-to-conserve-resources).
This limits the cleanup execution in time, and avoids the expired token error.
- Extend the expiration delay of the Container Registry authentication tokens. This defaults to 5
@@ -869,14 +630,14 @@ these steps:
If you have Rails console access, you can enter the following commands to retrieve a list of tags limited by date:
- ```shell
+ ```shell
output = File.open( "/tmp/list_o_tags.out","w" )
Project.find(<Project_id>).container_repositories.find(<container_repo_id>).tags.each do |tag|
output << tag.name + "\n" if tag.created_at < 1.month.ago
end;nil
output.close
```
-
+
This set of commands creates a `/tmp/list_o_tags.out` file listing all tags with a `created_at` date of older than one month.
1. Remove from the `list_o_tags.out` file any tags that you want to keep. Here are some example
@@ -963,3 +724,55 @@ Use your own URLs to complete the following steps:
```
Follow [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/18383) for details.
+
+### Tags on S3 backend remain after successful deletion requests
+
+With S3 as your storage backend, tags may remain even though:
+
+- In the UI, you see that the tags are scheduled for deletion.
+- In the API, you get an HTTP `200` response.
+- The registry log shows a successful `Delete` request.
+
+An example `DELETE` request in the registry log:
+
+```shell
+{"content_type":"","correlation_id":"01FQGNSKVMHQEAVE21KYTJN2P4","duration_ms":62,"host":"localhost:5000","level":"info","method":"DELETE","msg":"access","proto":"HTTP/1.1","referrer":"","remote_addr":"127.0.0.1:47498","remote_ip":"127.0.0.1","status":202,"system":"http","time":"2021-12-22T08:58:15Z","ttfb_ms":62,"uri":"/v2/<path to repo>/tags/reference/<tag_name>","user_agent":"GitLab/<version>","written_bytes":0}
+```
+
+There may be some errors not properly cached. Follow these steps to investigate further:
+
+1. In your configuration file, set the registry's log level to `debug`, and the S3 driver's log
+ level to `logdebugwithhttpbody`. For Omnibus, make these edits in the `gitlab.rb` file:
+
+ ```shell
+ # Change the registry['log_level'] to debug
+ registry['log_level'] = 'debug'
+
+ # Set log level for registry log from storage side
+ registry['storage'] = {
+ 's3' => {
+ 'bucket' => 'your-s3-bucket',
+ 'region' => 'your-s3-region'
+ },
+
+ 'loglevel' = "logdebugwithhttpbody"
+ }
+ ```
+
+ Then save and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+1. Attempt to delete one or more tags using the GitLab UI or API.
+
+1. Inspect the registry logs and look for a response from S3. Although the response could be
+ `200 OK`, the body might have the error `AccessDenied`. This indicates a permission problem from
+ the S3 side.
+
+1. Ensure your S3 configuration has the `deleteObject` permisson scope. Here's an
+ [example role for an S3 bucket](../../../administration/object_storage.md#iam-permissions).
+ 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.
diff --git a/doc/user/packages/container_registry/reduce_container_registry_storage.md b/doc/user/packages/container_registry/reduce_container_registry_storage.md
new file mode 100644
index 00000000000..e2242a85b75
--- /dev/null
+++ b/doc/user/packages/container_registry/reduce_container_registry_storage.md
@@ -0,0 +1,272 @@
+---
+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/#assignments
+---
+
+# Reduce Container Registry Storage **(FREE)**
+
+Container registries become large over time without cleanup. When a large number of images or tags are added:
+
+- Fetching the list of available tags or images becomes slower.
+- They take up a large amount of storage space on the server.
+
+We recommend deleting unnecessary images and tags, and setting up a [cleanup policy](#cleanup-policy)
+to automatically manage your container registry usage.
+
+## Check Container Registry Storage Use
+
+The Usage Quotas page (**Settings > Usage Quotas > Storage**) displays storage usage for Packages, which includes Container Registry,
+however, the storage is not being calculated.
+
+## Cleanup policy
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15398) in GitLab 12.8.
+> - [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/218737) from "expiration policy" to "cleanup policy" in GitLab 13.2.
+
+The cleanup policy is a scheduled job you can use to remove tags from the Container Registry.
+For the project where it's defined, tags matching the regex pattern are removed.
+The underlying layers and images remain.
+
+To delete the underlying layers and images that aren't associated with any tags, administrators can use
+[garbage collection](../../../administration/packages/container_registry.md#removing-untagged-manifests-and-unreferenced-layers) with the `-m` switch.
+
+### Enable the cleanup policy
+
+Cleanup policies can be run on all projects, with these exceptions:
+
+- For self-managed GitLab instances, the project must have been created
+ in GitLab 12.8 or later. However, an administrator can enable the cleanup policy
+ for all projects (even those created before 12.8) in
+ [GitLab application settings](../../../api/settings.md#change-application-settings)
+ by setting `container_expiration_policies_enable_historic_entries` to true.
+ Alternatively, you can execute the following command in the [Rails console](../../../administration/operations/rails_console.md#starting-a-rails-console-session):
+
+ ```ruby
+ ApplicationSetting.last.update(container_expiration_policies_enable_historic_entries: true)
+ ```
+
+ 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
+GitLab.com that don't have a container image.
+
+### How the cleanup policy works
+
+The cleanup policy collects all tags in the Container Registry and excludes tags
+until only the tags to be deleted remain.
+
+The cleanup policy searches for images based on the tag name. Support for the full path [has not yet been implemented](https://gitlab.com/gitlab-org/gitlab/-/issues/281071), but would allow you to clean up dynamically-named tags.
+
+The cleanup policy:
+
+1. Collects all tags for a given repository in a list.
+1. Excludes the tag named `latest` from the list.
+1. Evaluates the `name_regex` (tags to expire), excluding non-matching names from the list.
+1. Excludes from the list any tags matching the `name_regex_keep` value (tags to preserve).
+1. Excludes any tags that do not have a manifest (not part of the options in the UI).
+1. Orders the remaining tags by `created_date`.
+1. Excludes from the list the N tags based on the `keep_n` value (Number of tags to retain).
+1. Excludes from the list the tags more recent than the `older_than` value (Expiration interval).
+1. Finally, the remaining tags in the list are deleted from the Container Registry.
+
+WARNING:
+On GitLab.com, the execution time for the cleanup policy is limited, and some of the tags may remain in
+the Container Registry after the policy runs. The next time the policy runs, the remaining tags are included,
+so it may take multiple runs for all tags to be deleted.
+
+WARNING:
+GitLab self-managed installs support for third-party container registries that comply with the
+[Docker Registry HTTP API V2](https://docs.docker.com/registry/spec/api/)
+specification. However, this specification does not include a tag delete operation. Therefore, when
+interacting with third-party container registries, GitLab uses a workaround to delete tags. See the
+[related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/15737)
+for more information. Due to possible implementation variations, this workaround is not guaranteed
+to work with all third-party registries in the same predictable way. If you use the GitLab Container
+Registry, this workaround is not required because we implemented a special tag delete operation. In
+this case, you can expect cleanup policies to be consistent and predictable.
+
+### Create a cleanup policy
+
+You can create a cleanup policy in [the API](#use-the-cleanup-policy-api) or the UI.
+
+To create a cleanup policy in the UI:
+
+1. For your project, go to **Settings > Packages & Registries**.
+1. Expand the **Clean up image tags** section.
+1. Complete the fields.
+
+ | Field | Description |
+ |---------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|
+ | **Toggle** | Turn the policy on or off. |
+ | **Run cleanup** | How often the policy should run. |
+ | **Keep the most recent** | How many tags to _always_ keep for each image. |
+ | **Keep tags matching** | The regex pattern that determines which tags to preserve. The `latest` tag is always preserved. For all tags, use `.*`. See other [regex pattern examples](#regex-pattern-examples). |
+ | **Remove tags older than** | Remove only tags older than X days. |
+ | **Remove tags matching** | The regex pattern that determines which tags to remove. This value cannot be blank. For all tags, use `.*`. See other [regex pattern examples](#regex-pattern-examples). |
+
+1. Click **Save**.
+
+Depending on the interval you chose, the policy is scheduled to run.
+
+NOTE:
+If you edit the policy and click **Save** again, the interval is reset.
+
+### Regex pattern examples
+
+Cleanup policies use regex patterns to determine which tags should be preserved or removed, both in the UI and the API.
+
+Regex patterns are automatically surrounded with `\A` and `\Z` anchors. Do not include any `\A`, `\Z`, `^` or `$` token in the regex patterns as they are not necessary.
+
+Here are examples of regex patterns you may want to use:
+
+- Match all tags:
+
+ ```plaintext
+ .*
+ ```
+
+ This is the default value for the expiration regex.
+
+- Match tags that start with `v`:
+
+ ```plaintext
+ v.+
+ ```
+
+- Match only the tag named `main`:
+
+ ```plaintext
+ main
+ ```
+
+- Match tags that are either named or start with `release`:
+
+ ```plaintext
+ release.*
+ ```
+
+- Match tags that either start with `v`, are named `main`, or begin with `release`:
+
+ ```plaintext
+ (?:v.+|main|release.*)
+ ```
+
+### 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).
+
+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.
+
+For self-managed instances, those settings can be updated in the [Rails console](../../../administration/operations/rails_console.md#starting-a-rails-console-session):
+
+ ```ruby
+ 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):
+
+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.
+
+Examples:
+
+- Select all tags, keep at least 1 tag per image, clean up any tag older than 14 days, run once a month, preserve any images with the name `main` and the policy is enabled:
+
+ ```shell
+ curl --request PUT --header 'Content-Type: application/json;charset=UTF-8' --header "PRIVATE-TOKEN: <your_access_token>" \
+ --data-binary '{"container_expiration_policy_attributes":{"cadence":"1month","enabled":true,"keep_n":1,"older_than":"14d","name_regex":"","name_regex_delete":".*","name_regex_keep":".*-main"}}' \
+ "https://gitlab.example.com/api/v4/projects/2"
+ ```
+
+Valid values for `cadence` when using the API are:
+
+- `1d` (every day)
+- `7d` (every week)
+- `14d` (every two weeks)
+- `1month` (every month)
+- `3month` (every quarter)
+
+See the API documentation for further details: [Edit project](../../../api/projects.md#edit-project).
+
+### Use with external container registries
+
+When using an [external container registry](../../../administration/packages/container_registry.md#use-an-external-container-registry-with-gitlab-as-an-auth-endpoint),
+running a cleanup policy on a project may have some performance risks.
+If a project runs a policy to remove thousands of tags
+the GitLab background jobs may get backed up or fail completely.
+It is recommended you only enable container cleanup
+policies for projects that were created before GitLab 12.8 if you are confident the number of tags
+being cleaned up is minimal.
+
+## Related topics
+
+- [Delete images](index.md#delete-images)
+- [Delete registry repository](../../../api/container_registry.md#delete-registry-repository)
+- [Delete a registry repository tag](../../../api/container_registry.md#delete-a-registry-repository-tag)
+- [Delete registry repository tags in bulk](../../../api/container_registry.md#delete-registry-repository-tags-in-bulk)
+- [Delete a package](../package_registry/index.md#delete-a-package)
+
+## Troubleshooting cleanup policies
+
+If you see the following message:
+
+"Something went wrong while updating the cleanup policy."
+
+Check the regex patterns to ensure they are valid.
+
+GitLab uses [RE2 syntax](https://github.com/google/re2/wiki/Syntax) for regular expressions in the cleanup policy. You can test them with the [regex101 regex tester](https://regex101.com/).
+View some common [regex pattern examples](#regex-pattern-examples).
diff --git a/doc/user/packages/debian_repository/index.md b/doc/user/packages/debian_repository/index.md
index 89427174dcd..a8f0672e376 100644
--- a/doc/user/packages/debian_repository/index.md
+++ b/doc/user/packages/debian_repository/index.md
@@ -67,7 +67,7 @@ Creating a Debian package is documented [on the Debian Wiki](https://wiki.debian
To create a distribution, publish a package, or install a private package, you need one of the
following:
-- [Personal access token](../../../api/index.md#personalproject-access-tokens)
+- [Personal access token](../../../api/index.md#personalprojectgroup-access-tokens)
- [CI/CD job token](../../../ci/jobs/ci_job_token.md)
- [Deploy token](../../project/deploy_tokens/index.md)
diff --git a/doc/user/packages/dependency_proxy/index.md b/doc/user/packages/dependency_proxy/index.md
index 8b34634318c..52f5a1fcc0d 100644
--- a/doc/user/packages/dependency_proxy/index.md
+++ b/doc/user/packages/dependency_proxy/index.md
@@ -6,7 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Dependency Proxy **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7934) in GitLab 11.11.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/273655) from GitLab Premium to GitLab Free in 13.6.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11582) support for private groups in GitLab 13.7.
> - Anonymous access to images in public groups is no longer available starting in GitLab 13.7.
@@ -20,7 +19,8 @@ upstream image from a registry, acting as a pull-through cache.
## Prerequisites
-- The Dependency Proxy is enabled by default but can be [turned off by an administrator](../../../administration/packages/dependency_proxy.md).
+To use the Dependency Proxy, it must be enabled for the GitLab instance. It's enabled by default,
+but [administrators can turn it off](../../../administration/packages/dependency_proxy.md).
### Supported images and packages
@@ -33,13 +33,17 @@ The following images and packages are supported.
For a list of planned additions, view the
[direction page](https://about.gitlab.com/direction/package/#dependency-proxy).
-## Enable or disable the Dependency Proxy for a group
+## Enable or turn off the Dependency Proxy for a group
-To enable or disable the Dependency Proxy for a group:
+To enable or turn off the Dependency Proxy for a group:
1. Go to your group's **Settings > Packages & Registries**.
1. Expand the **Dependency Proxy** section.
-1. To enable the proxy, turn on **Enable Proxy**. To disable it, turn the toggle off.
+1. To enable the proxy, turn on **Enable Proxy**. To turn it off, turn the toggle off.
+
+This setting only affects the Dependency Proxy for a group. Only an administrator can
+[turn the Dependency Proxy on or off](../../../administration/packages/dependency_proxy.md)
+for the entire GitLab instance.
## View the Dependency Proxy
@@ -227,7 +231,7 @@ You can enable an automatic time-to-live (TTL) policy for the Dependency Proxy f
interface. To do this, navigate to your group's **Settings > Packages & Registries > Dependency Proxy**
and enable the setting to automatically clear items from the cache after 90 days.
-#### Enable cleanup policies with GraphQL
+#### Enable cleanup policies with GraphQL
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/294187) in GitLab 14.4.
@@ -259,7 +263,7 @@ mutation {
```
See the [Getting started with GraphQL](../../../api/graphql/getting_started.md)
-guide to learn how to make GraphQL queries.
+guide to learn how to make GraphQL queries.
When the policy is initially enabled, the default TTL setting is 90 days. Once enabled, stale
dependency proxy files are queued for deletion each day. Deletion may not occur right away due to
diff --git a/doc/user/packages/generic_packages/index.md b/doc/user/packages/generic_packages/index.md
index 5b7316a495e..7b44b5bcbb7 100644
--- a/doc/user/packages/generic_packages/index.md
+++ b/doc/user/packages/generic_packages/index.md
@@ -13,20 +13,17 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - 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).
-WARNING:
-This feature might not be available to you. Check the **version history** note above for details.
-
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.
## Authenticate to the Package Registry
-To authenticate to the Package Registry, you need either a [personal access token](../../../api/index.md#personalproject-access-tokens),
+To authenticate to the Package Registry, you need either a [personal access token](../../../api/index.md#personalprojectgroup-access-tokens),
[CI/CD job token](../../../ci/jobs/ci_job_token.md), or [deploy token](../../project/deploy_tokens/index.md).
In addition to the standard API authentication mechanisms, the generic package
API allows authentication with HTTP Basic authentication for use with tools that
do not support the other available mechanisms. The `user-id` is not checked and
-may be any value, and the `password` must be either a [personal access token](../../../api/index.md#personalproject-access-tokens),
+may be any value, and the `password` must be either a [personal access token](../../../api/index.md#personalprojectgroup-access-tokens),
a [CI/CD job token](../../../ci/jobs/ci_job_token.md), or a [deploy token](../../project/deploy_tokens/index.md).
## Publish a package file
diff --git a/doc/user/packages/helm_repository/index.md b/doc/user/packages/helm_repository/index.md
index 488345965f9..73298afc9cd 100644
--- a/doc/user/packages/helm_repository/index.md
+++ b/doc/user/packages/helm_repository/index.md
@@ -30,7 +30,7 @@ Read more in the Helm documentation about these topics:
To authenticate to the Helm repository, you need either:
-- A [personal access token](../../../api/index.md#personalproject-access-tokens) with the scope set to `api`.
+- A [personal access token](../../../api/index.md#personalprojectgroup-access-tokens) with the scope set to `api`.
- A [deploy token](../../project/deploy_tokens/index.md) with the scope set to `read_package_registry`, `write_package_registry`, or both.
- A [CI/CD job token](../../../ci/jobs/ci_job_token.md).
diff --git a/doc/user/packages/maven_repository/index.md b/doc/user/packages/maven_repository/index.md
index 6646f18e6fe..21fecc16602 100644
--- a/doc/user/packages/maven_repository/index.md
+++ b/doc/user/packages/maven_repository/index.md
@@ -6,8 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Maven packages in the Package Repository **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5811) in GitLab 11.3.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/221259) from GitLab Premium to GitLab Free in 13.3.
+> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/221259) from GitLab Premium to GitLab Free in 13.3.
Publish [Maven](https://maven.apache.org) artifacts in your project's Package Registry.
Then, install the packages whenever you need to use them as a dependency.
@@ -418,8 +417,7 @@ repositories {
### Group-level Maven endpoint
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/8798) in GitLab 11.7.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/221259) from GitLab Premium to GitLab Free in 13.3.
+> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/221259) from GitLab Premium to GitLab Free in 13.3.
If you rely on many packages, it might be inefficient to include the `repository` section
with a unique URL for each package. Instead, you can use the group-level endpoint for
@@ -476,8 +474,7 @@ repositories {
### Instance-level Maven endpoint
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/8274) in GitLab 11.7.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/221259) from GitLab Premium to GitLab Free in 13.3.
+> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/221259) from GitLab Premium to GitLab Free in 13.3.
If you rely on many packages, it might be inefficient to include the `repository` section
with a unique URL for each package. Instead, you can use the instance-level endpoint for
diff --git a/doc/user/packages/npm_registry/index.md b/doc/user/packages/npm_registry/index.md
index 1086de1fa92..5338e546625 100644
--- a/doc/user/packages/npm_registry/index.md
+++ b/doc/user/packages/npm_registry/index.md
@@ -6,8 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# npm packages in the Package Registry **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5934) in GitLab 11.7.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/221259) from GitLab Premium to GitLab Free in 13.3.
+> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/221259) from GitLab Premium to GitLab Free in 13.3.
Publish npm packages in your project's Package Registry. Then install the
packages whenever you need to use them as a dependency.
@@ -579,8 +578,6 @@ If you get this error, ensure that:
by default, it's possible to [disable it](../package_registry/#disable-the-package-registry).
- Your token is not expired and has appropriate permissions.
- A package with the same name or version doesn't already exist within the given scope.
-- Your NPM package name does not contain a dot `.`. This is a [known issue](https://gitlab.com/gitlab-org/gitlab-ee/issues/10248)
- in GitLab 11.9 and earlier.
- The scoped packages URL includes a trailing slash:
- Correct: `//gitlab.example.com/api/v4/packages/npm/`
- Incorrect: `//gitlab.example.com/api/v4/packages/npm`
diff --git a/doc/user/packages/package_registry/index.md b/doc/user/packages/package_registry/index.md
index 28e1571b4f8..3311b271126 100644
--- a/doc/user/packages/package_registry/index.md
+++ b/doc/user/packages/package_registry/index.md
@@ -32,6 +32,25 @@ When you view packages in a group:
For information on how to create and upload a package, view the GitLab documentation for your package type.
+## Authenticate with the registry
+
+Authentication depends on the package manager being used. For more information, see the docs on the
+specific package format you want to use.
+
+For most package types, the following credential types are valid:
+
+- [Personal access token](../../profile/personal_access_tokens.md):
+ authenticates with your user permissions. Good for personal and local use of the package registry.
+- [Project deploy token](../../project/deploy_tokens/index.md):
+ allows access to all packages in a project. Good for granting and revoking project access to many
+ users.
+- [Group deploy token](../../project/deploy_tokens/index.md#group-deploy-token):
+ allows access to all packages in a group and its subgroups. Good for granting and revoking access
+ to a large number of packages to sets of users.
+- [Job token](../../../ci/jobs/ci_job_token.md):
+ allows access to packages in the project running the job for the users running the pipeline.
+ Access to other external projects can be configured.
+
## 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/terraform_module_registry/index.md b/doc/user/packages/terraform_module_registry/index.md
index b8dc071fc30..bb9f32d1144 100644
--- a/doc/user/packages/terraform_module_registry/index.md
+++ b/doc/user/packages/terraform_module_registry/index.md
@@ -15,7 +15,7 @@ as a Terraform module registry.
To authenticate to the Terraform module registry, you need either:
-- A [personal access token](../../../api/index.md#personalproject-access-tokens) with at least `read_api` rights.
+- A [personal access token](../../../api/index.md#personalprojectgroup-access-tokens) with at least `read_api` rights.
- A [CI/CD job token](../../../ci/jobs/ci_job_token.md).
## Publish a Terraform Module
diff --git a/doc/user/permissions.md b/doc/user/permissions.md
index 4336c58b56c..36c49e39151 100644
--- a/doc/user/permissions.md
+++ b/doc/user/permissions.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -46,168 +46,169 @@ 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)** | | | | | ✓ |
-| [CI/CD](../ci/index.md):<br>Download and browse job artifacts | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>View a job log | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>View list of jobs | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>View [environments](../ci/environments/index.md) | | ✓ | ✓ | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Cancel and retry jobs | | | ✓ | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Create new [environments](../ci/environments/index.md) | | | ✓ | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Run CI/CD pipeline against a protected branch | | | ✓ (*5*) | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Stop [environments](../ci/environments/index.md) | | | ✓ | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>View a job with [debug logging](../ci/variables/index.md#debug-logging) | | | ✓ | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Manage CI/CD variables | | | | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Manage job triggers | | | | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Manage runners | | | | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Run Web IDE's Interactive Web Terminals **(ULTIMATE ONLY)** | | | | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Use [environment terminals](../ci/environments/index.md#web-terminals-deprecated) | | | | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Delete pipelines | | | | | ✓ |
-| [Clusters](infrastructure/clusters/index.md):<br>View [pod logs](project/clusters/kubernetes_pod_logs.md) | | | ✓ | ✓ | ✓ |
-| [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>Remove a container registry image | | | ✓ | ✓ | ✓ |
-| [Container Registry](packages/container_registry/index.md):<br>Update container registry | | | ✓ | ✓ | ✓ |
-| [GitLab Pages](project/pages/index.md):<br>View Pages protected by [access control](project/pages/introduction.md#gitlab-pages-access-control) | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [GitLab Pages](project/pages/index.md):<br>Manage | | | | ✓ | ✓ |
-| [GitLab Pages](project/pages/index.md):<br>Manage GitLab Pages domains and certificates | | | | ✓ | ✓ |
-| [GitLab Pages](project/pages/index.md):<br>Remove GitLab Pages | | | | ✓ | ✓ |
-| [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) | (*17*) | ✓ | ✓ | ✓ | ✓ |
-| [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 | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Assign | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Create | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Create [confidential issues](project/issues/confidential_issues.md) | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>View [Design Management](project/issues/design_management.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>View related issues | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Set weight | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>View [confidential issues](project/issues/confidential_issues.md) | (*2*) | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Close / reopen | | ✓ | ✓ | ✓ | ✓ |
-| [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 (*15*) | | ✓ | ✓ | ✓ | ✓ |
-| [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 (*9*) | | | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Assign | | | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Create (*18*) | | | ✓ | ✓ | ✓ |
-| [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 (*7*) | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ |
-| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>Create/edit/delete metrics dashboard annotations | | | ✓ | ✓ | ✓ |
-| [Package registry](packages/index.md):<br>Pull package | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [Package registry](packages/index.md):<br>Publish package | | | ✓ | ✓ | ✓ |
-| [Package registry](packages/index.md):<br>Delete package | | | | ✓ | ✓ |
-| [Project operations](../operations/index.md):<br>View [Error Tracking](../operations/error_tracking.md) list | | ✓ | ✓ | ✓ | ✓ |
-| [Project operations](../operations/index.md):<br>Manage [Feature Flags](../operations/feature_flags.md) **(PREMIUM)** | | | ✓ | ✓ | ✓ |
-| [Project operations](../operations/index.md):<br>Manage [Error Tracking](../operations/error_tracking.md) | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Download project | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Leave comments | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Reposition comments on images (posted by any user) | ✓ (*10*) | ✓ (*10*) | ✓ (*10*) | ✓ | ✓ |
-| [Projects](project/index.md):<br>View Insights **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View [releases](project/releases/index.md) | ✓ (*6*) | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View Requirements **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View [time tracking](project/time_tracking.md) reports | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View [wiki](project/wiki/index.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Create [snippets](snippets.md) | | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Manage labels | | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View [project 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) | | | ✓ (*13*) | ✓ (*13*) | ✓ (*13*) |
-| [Projects](project/index.md):<br>Create, edit [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Enable Review Apps | | | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View project [Audit Events](../administration/audit_events.md) | | | ✓ (*11*) | ✓ | ✓ |
-| [Projects](project/index.md):<br>Add deploy keys | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Add new team members | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Change [project features visibility](../public_access/public_access.md) level | | | | ✓ (14) | ✓ |
-| [Projects](project/index.md):<br>Configure [webhooks](project/integrations/webhooks.md) | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Delete [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Edit comments (posted by any user) | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Edit project badges | | | | ✓ | ✓ |
-| [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)** (*12*) | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Manage [Project Operations](../operations/index.md) | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Share (invite) projects with groups | | | | ✓ (*8*) | ✓ (*8*) |
-| [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>Rename project | | | | | ✓ |
-| [Projects](project/index.md):<br>Transfer project to another namespace | | | | | ✓ |
-| [Repository](project/repository/index.md):<br>Pull project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>View project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>View a commit status | | ✓ | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Add tags | | | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Create new branches | | | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Create or update commit status | | | ✓ (*5*) | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Force push to non-protected branches | | | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Push to non-protected branches | | | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Remove non-protected branches | | | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Rewrite or remove Git tags | | | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Enable or disable branch protection | | | | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Enable or disable tag protection | | | | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Manage [push rules](../push_rules/push_rules.md) | | | | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Push to protected branches (*5*) | | | | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Turn on or off protected branch push for developers | | | | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Remove fork relationship | | | | | ✓ |
-| [Repository](project/repository/index.md):<br>Force push to protected branches (*4*) | | | | | |
-| [Repository](project/repository/index.md):<br>Remove protected branches (*4*) | | | | | |
-| [Requirements Management](project/requirements/index.md):<br>Archive / reopen **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
-| [Requirements Management](project/requirements/index.md):<br>Create / edit **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
-| [Requirements Management](project/requirements/index.md):<br>Import / export **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>View Security reports **(ULTIMATE)** | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>Create issue from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>Create vulnerability from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [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 **(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)** | | | | | ✓ |
+| [CI/CD](../ci/index.md):<br>Download and browse job artifacts | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>View a job log | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>View list of jobs | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>View [environments](../ci/environments/index.md) | | ✓ | ✓ | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Cancel and retry jobs | | | ✓ | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Create new [environments](../ci/environments/index.md) | | | ✓ | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Run CI/CD pipeline against a protected branch | | | ✓ (*5*) | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Stop [environments](../ci/environments/index.md) | | | ✓ | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>View a job with [debug logging](../ci/variables/index.md#debug-logging) | | | ✓ | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Manage CI/CD variables | | | | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Manage job triggers | | | | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Manage group runners | | | | | ✓ |
+| [CI/CD](../ci/index.md):<br>Manage project runners | | | | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Run Web IDE's Interactive Web Terminals **(ULTIMATE ONLY)** | | | | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Use [environment terminals](../ci/environments/index.md#web-terminals-deprecated) | | | | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Delete pipelines | | | | | ✓ |
+| [Clusters](infrastructure/clusters/index.md):<br>View [pod logs](project/clusters/kubernetes_pod_logs.md) | | | ✓ | ✓ | ✓ |
+| [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>Remove a container registry image | | | ✓ | ✓ | ✓ |
+| [Container Registry](packages/container_registry/index.md):<br>Update container registry | | | ✓ | ✓ | ✓ |
+| [GitLab Pages](project/pages/index.md):<br>View Pages protected by [access control](project/pages/introduction.md#gitlab-pages-access-control) | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [GitLab Pages](project/pages/index.md):<br>Manage | | | | ✓ | ✓ |
+| [GitLab Pages](project/pages/index.md):<br>Manage GitLab Pages domains and certificates | | | | ✓ | ✓ |
+| [GitLab Pages](project/pages/index.md):<br>Remove GitLab Pages | | | | ✓ | ✓ |
+| [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) | (*17*) | ✓ | ✓ | ✓ | ✓ |
+| [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 | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Assign | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Create | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Create [confidential issues](project/issues/confidential_issues.md) | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>View [Design Management](project/issues/design_management.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>View related issues | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Set weight | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>View [confidential issues](project/issues/confidential_issues.md) | (*2*) | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Close / reopen | | ✓ | ✓ | ✓ | ✓ |
+| [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 (*15*) | | ✓ | ✓ | ✓ | ✓ |
+| [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 (*9*) | | | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Assign | | | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Create (*18*) | | | ✓ | ✓ | ✓ |
+| [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 (*7*) | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ |
+| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>Create/edit/delete metrics dashboard annotations | | | ✓ | ✓ | ✓ |
+| [Package registry](packages/index.md):<br>Pull package | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Package registry](packages/index.md):<br>Publish package | | | ✓ | ✓ | ✓ |
+| [Package registry](packages/index.md):<br>Delete package | | | | ✓ | ✓ |
+| [Project operations](../operations/index.md):<br>View [Error Tracking](../operations/error_tracking.md) list | | ✓ | ✓ | ✓ | ✓ |
+| [Project operations](../operations/index.md):<br>Manage [Feature Flags](../operations/feature_flags.md) **(PREMIUM)** | | | ✓ | ✓ | ✓ |
+| [Project operations](../operations/index.md):<br>Manage [Error Tracking](../operations/error_tracking.md) | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Download project | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Leave comments | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Reposition comments on images (posted by any user) | ✓ (*10*) | ✓ (*10*) | ✓ (*10*) | ✓ | ✓ |
+| [Projects](project/index.md):<br>View Insights **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View [releases](project/releases/index.md) | ✓ (*6*) | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View Requirements **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View [time tracking](project/time_tracking.md) reports | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View [wiki](project/wiki/index.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Create [snippets](snippets.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Manage labels | | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View [project 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) | | | ✓ (*13*) | ✓ (*13*) | ✓ (*13*) |
+| [Projects](project/index.md):<br>Create, edit [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Enable Review Apps | | | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View project [Audit Events](../administration/audit_events.md) | | | ✓ (*11*) | ✓ | ✓ |
+| [Projects](project/index.md):<br>Add deploy keys | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Add new team members | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Change [project features visibility](../public_access/public_access.md) level | | | | ✓ (14) | ✓ |
+| [Projects](project/index.md):<br>Configure [webhooks](project/integrations/webhooks.md) | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Delete [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Edit comments (posted by any user) | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Edit project badges | | | | ✓ | ✓ |
+| [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)** (*12*) | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Manage [Project Operations](../operations/index.md) | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Share (invite) projects with groups | | | | ✓ (*8*) | ✓ (*8*) |
+| [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>Rename project | | | | | ✓ |
+| [Projects](project/index.md):<br>Transfer project to another namespace | | | | | ✓ |
+| [Repository](project/repository/index.md):<br>Pull project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>View project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>View a commit status | | ✓ | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Add tags | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Create new branches | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Create or update commit status | | | ✓ (*5*) | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Force push to non-protected branches | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Push to non-protected branches | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Remove non-protected branches | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Rewrite or remove Git tags | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Enable or disable branch protection | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Enable or disable tag protection | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Manage [push rules](../push_rules/push_rules.md) | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Push to protected branches (*5*) | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Turn on or off protected branch push for developers | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Remove fork relationship | | | | | ✓ |
+| [Repository](project/repository/index.md):<br>Force push to protected branches (*4*) | | | | | |
+| [Repository](project/repository/index.md):<br>Remove protected branches (*4*) | | | | | |
+| [Requirements Management](project/requirements/index.md):<br>Archive / reopen **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
+| [Requirements Management](project/requirements/index.md):<br>Create / edit **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
+| [Requirements Management](project/requirements/index.md):<br>Import / export **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>View Security reports **(ULTIMATE)** | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>Create issue from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>Create vulnerability from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| [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 | | ✓ | ✓ | ✓ | ✓ |
1. On self-managed GitLab instances, guest users are able to perform this action only on
public and internal projects (not on private projects). [External users](#external-users)
@@ -512,6 +513,7 @@ instance and project.
| Change project configuration | | | ✓ | ✓ |
| Add specific runners | | | ✓ | ✓ |
| Add shared runners | | | | ✓ |
+| Clear runner caches manually | | | ✓ | ✓ |
| See events in the system | | | | ✓ |
| Admin Area | | | | ✓ |
diff --git a/doc/user/profile/account/create_accounts.md b/doc/user/profile/account/create_accounts.md
index ab0cae976d2..32b8d2b33ee 100644
--- a/doc/user/profile/account/create_accounts.md
+++ b/doc/user/profile/account/create_accounts.md
@@ -1,7 +1,7 @@
---
type: reference
stage: Manage
-group: Access
+group: Authentication & 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/user/profile/account/delete_account.md b/doc/user/profile/account/delete_account.md
index 96415279de4..365f96b48b3 100644
--- a/doc/user/profile/account/delete_account.md
+++ b/doc/user/profile/account/delete_account.md
@@ -1,7 +1,7 @@
---
type: howto
stage: Manage
-group: Access
+group: Authentication & 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/user/profile/account/two_factor_authentication.md b/doc/user/profile/account/two_factor_authentication.md
index 343f8e328ba..3af8c1c1b5a 100644
--- a/doc/user/profile/account/two_factor_authentication.md
+++ b/doc/user/profile/account/two_factor_authentication.md
@@ -1,59 +1,51 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
# Two-factor authentication **(FREE)**
-Two-factor authentication (2FA) provides an additional level of security to your
-GitLab account. After being enabled, in addition to supplying your username and
-password to sign in, you are prompted for a code generated by your one-time
-password authenticator (for example, a password manager on one of your devices).
+Two-factor authentication (2FA) provides an additional level of security to your GitLab account. For others to access
+your account, they would need your username and password _and_ access to your second factor of authentication.
-By enabling 2FA, the only way someone other than you can sign in to your account
-is to know your username and password _and_ have access to your one-time
-password secret.
+GitLab supports as a second factor of authentication:
-## Overview
+- Time-based one-time passwords ([TOTP](https://datatracker.ietf.org/doc/html/rfc6238)). When enabled, GitLab prompts
+ you for a code when you sign in. Codes are generated by your one-time password authenticator (for example, a password
+ manager on one of your devices).
+- U2F or WebAuthn devices. You're prompted to activate your U2F or WebAuthn device (usually by pressing a button on it) when
+ you supply your username and password to sign in. This performs secure authentication on your behalf.
-NOTE:
-When you enable 2FA, don't forget to back up your [recovery codes](#recovery-codes)!
+If you set up a device, also set up a TOTP so you can still access your account if you lose the device.
-In addition to time-based one time passwords (TOTP), GitLab supports WebAuthn devices as the second factor
-of authentication. After being enabled, in addition to supplying your username
-and password to sign in, you're prompted to activate your U2F / WebAuthn device
-(usually by pressing a button on it) which performs secure authentication on
-your behalf.
+## Use personal access tokens with two-factor authentication
-It's highly recommended that you set up 2FA with both a [one-time password authenticator](#one-time-password)
-or use [FortiAuthenticator](#one-time-password-via-fortiauthenticator) and a
-[U2F device](#u2f-device) or a [WebAuthn device](#webauthn-device), so you can
-still access your account if you lose your U2F / WebAuthn device.
+When 2FA is enabled, you can't use your password to authenticate with Git over HTTPS or the [GitLab API](../../../api/index.md).
+You must use a [personal access token](../personal_access_tokens.md) instead.
-## Enabling 2FA
+## Enable two-factor authentication
> - Account email confirmation requirement [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35102) in GitLab 14.3. [Deployed behind the `ensure_verified_primary_email_for_2fa` flag](../../../administration/feature_flags.md), enabled by default.
> - Account email confirmation requirement generally available and [feature flag `ensure_verified_primary_email_for_2fa` removed](https://gitlab.com/gitlab-org/gitlab/-/issues/340151) in GitLab 14.4.
-There are multiple ways to enable two-factor authentication (2FA):
+You can enable 2FA:
-- Using a one-time password authenticator.
-- Using a U2F / WebAuthn device.
+- Using a one-time password authenticator. After you enable 2FA, back up your [recovery codes](#recovery-codes).
+- Using a U2F or WebAuthn device.
-In GitLab 14.3 and later, your account email must be confirmed to enable two-factor authentication.
+In GitLab 14.3 and later, your account email must be confirmed to enable 2FA.
-### One-time password
+### Enable one-time password
-To enable 2FA:
+To enable 2FA with a one-time password:
1. **In GitLab:**
- 1. Sign in to your GitLab account.
- 1. Go to your [**User settings**](../index.md#access-your-user-settings).
- 1. Go to **Account**.
+ 1. Access your [**User settings**](../index.md#access-your-user-settings).
+ 1. Select **Account**.
1. Select **Enable Two-factor Authentication**.
1. **On your device (usually your phone):**
- 1. Install a compatible application, like:
+ 1. Install a compatible application. For example:
- [Authy](https://authy.com/)
- [Duo Mobile](https://duo.com/product/multi-factor-authentication-mfa/duo-mobile-app)
- [LastPass Authenticator](https://lastpass.com/auth/)
@@ -63,37 +55,36 @@ To enable 2FA:
- [Microsoft Authenticator](https://www.microsoft.com/en-us/security/mobile-authenticator-app)
- [SailOTP](https://openrepos.net/content/seiichiro0185/sailotp)
1. In the application, add a new entry in one of two ways:
- - Scan the code presented in GitLab with your device's camera to add the
- entry automatically.
+ - Scan the code displayed by GitLab with your device's camera to add the entry automatically.
- Enter the details provided to add the entry manually.
1. **In GitLab:**
- 1. Enter the six-digit pin number from the entry on your device into the **Pin
- code** field.
+ 1. Enter the six-digit pin number from the entry on your device into **Pin code**.
1. Enter your current password.
1. Select **Submit**.
-If the pin you entered was correct, a message displays indicating that
-two-factor authentication has been enabled, and you're shown a list
-of [recovery codes](#recovery-codes). Be sure to download them and keep them
+If you entered the correct pin, GitLab displays a list of [recovery codes](#recovery-codes). Download them and keep them
in a safe place.
-### One-time password via FortiAuthenticator
+### Enable one-time password using FortiAuthenticator
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212312) in GitLab 13.5 [with a flag](../../../administration/feature_flags.md) named `forti_authenticator`. Disabled by default.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available per user, ask an administrator to
+[enable the feature flag](../../../administration/feature_flags.md) named `forti_authenticator`. On GitLab.com, this
+feature is not available.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212312) in GitLab 13.5.
-> - It's deployed behind a feature flag, disabled by default.
-> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-fortiauthenticator-integration).
+You can use FortiAuthenticator as a one-time password (OTP) provider in GitLab. Users must:
-You can use FortiAuthenticator as a one-time password (OTP) provider in GitLab. Users must exist in
-both FortiAuthenticator and GitLab with the exact same username, and users must
-have FortiToken configured in FortiAuthenticator.
+- Exist in both FortiAuthenticator and GitLab with the same username.
+- Have FortiToken configured in FortiAuthenticator.
-You need a username and access token for FortiAuthenticator. The
-`access_token` in the code samples shown below is the FortAuthenticator access
-key. To get the token, see the `REST API Solution Guide` at
-[`Fortinet Document Library`](https://docs.fortinet.com/document/fortiauthenticator/6.2.0/rest-api-solution-guide/158294/the-fortiauthenticator-api).
+You need a username and access token for FortiAuthenticator. The `access_token` shown below is the FortAuthenticator
+access key. To get the token, see the REST API Solution Guide at
+[Fortinet Document Library](https://docs.fortinet.com/document/fortiauthenticator/6.2.0/rest-api-solution-guide/158294/the-fortiauthenticator-api).
GitLab 13.5 has been tested with FortAuthenticator version 6.2.0.
-First configure FortiAuthenticator in GitLab. On your GitLab server:
+Configure FortiAuthenticator in GitLab. On your GitLab server:
1. Open the configuration file.
@@ -134,43 +125,27 @@ First configure FortiAuthenticator in GitLab. On your GitLab server:
```
1. Save the configuration file.
-1. [Reconfigure](../../../administration/restart_gitlab.md#omnibus-gitlab-reconfigure)
- or [restart GitLab](../../../administration/restart_gitlab.md#installations-from-source)
- for the changes to take effect if you installed GitLab via Omnibus or from
- source respectively.
-
-#### Enable FortiAuthenticator integration
-
-This feature comes with the `:forti_authenticator` feature flag disabled by
-default.
-
-To enable this feature, ask a GitLab administrator with [Rails console access](../../../administration/feature_flags.md#how-to-enable-and-disable-features-behind-flags)
-to run the following command:
+1. [Reconfigure](../../../administration/restart_gitlab.md#omnibus-gitlab-reconfigure) (Omnibus GitLab) or
+ [restart](../../../administration/restart_gitlab.md#installations-from-source) (GitLab installed from source).
-```ruby
-Feature.enable(:forti_authenticator, User.find(<user ID>))
-```
+### Enable one-time password using FortiToken Cloud
-### One-time password via FortiToken Cloud
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212313) in GitLab 13.7 [with a flag](../../../administration/feature_flags.md) named `forti_token_cloud`. Disabled by default.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212313) in GitLab 13.7.
-> - It's deployed behind a feature flag, disabled by default.
-> - It's disabled on GitLab.com.
-> - It's not recommended for production use.
-> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-fortitoken-cloud-integration).
+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 `forti_token_cloud`. On GitLab.com, this
+feature is not available. The feature is not ready for production use.
-WARNING:
-This feature might not be available to you. Check the **version history** note above for details.
+You can use FortiToken Cloud as a one-time password (OTP) provider in GitLab. Users must:
-You can use FortiToken Cloud as a one-time password (OTP) provider in GitLab. Users must exist in
-both FortiToken Cloud and GitLab with the exact same username, and users must
-have FortiToken configured in FortiToken Cloud.
+- Exist in both FortiToken Cloud and GitLab with the same username.
+- Have FortiToken configured in FortiToken Cloud.
-You'll also need a `client_id` and `client_secret` to configure FortiToken Cloud.
-To get these, see the `REST API Guide` at
-[`Fortinet Document Library`](https://docs.fortinet.com/document/fortitoken-cloud/latest/rest-api).
+You need a `client_id` and `client_secret` to configure FortiToken Cloud. To get these, see the REST API Guide at
+[Fortinet Document Library](https://docs.fortinet.com/document/fortitoken-cloud/latest/rest-api/456035/overview).
-First configure FortiToken Cloud in GitLab. On your GitLab server:
+Configure FortiToken Cloud in GitLab. On your GitLab server:
1. Open the configuration file.
@@ -207,215 +182,184 @@ First configure FortiToken Cloud in GitLab. On your GitLab server:
```
1. Save the configuration file.
-1. [Reconfigure](../../../administration/restart_gitlab.md#omnibus-gitlab-reconfigure)
- or [restart GitLab](../../../administration/restart_gitlab.md#installations-from-source)
- for the changes to take effect if you installed GitLab via Omnibus or from
- source respectively.
-
-#### Enable or disable FortiToken Cloud integration
-
-FortiToken Cloud integration 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(:forti_token_cloud, User.find(<user ID>))
-```
-
-To disable it:
+1. [Reconfigure](../../../administration/restart_gitlab.md#omnibus-gitlab-reconfigure) (Omnibus GitLab) or
+ [restart](../../../administration/restart_gitlab.md#installations-from-source) (GitLab installed from source).
-```ruby
-Feature.disable(:forti_token_cloud, User.find(<user ID>))
-```
+### Set up a U2F device
-### U2F device
+GitLab officially supports [YubiKey](https://www.yubico.com/products/) U2F devices, but users have successfully used
+[SoloKeys](https://solokeys.com/) and [Google Titan Security Key](https://cloud.google.com/titan-security-key).
-GitLab officially only supports [YubiKey](https://www.yubico.com/products/)
-U2F devices, but users have successfully used [SoloKeys](https://solokeys.com/)
-or [Google Titan Security Key](https://cloud.google.com/titan-security-key).
-
-NOTE:
-2FA must be configured before U2F.
-
-The U2F workflow is [supported by](https://caniuse.com/#search=U2F) the
-following desktop browsers:
+U2F is [supported by](https://caniuse.com/#search=U2F) the following desktop browsers:
- Chrome
- Edge
-- Firefox 67+
- Opera
+- Firefox 67+. For Firefox 47-66:
-NOTE:
-For Firefox 47-66, you can enable the FIDO U2F API in
-[`about:config`](https://support.mozilla.org/en-US/kb/about-config-editor-firefox).
-Search for `security.webauth.u2f` and double click on it to toggle to `true`.
+ 1. Enable the FIDO U2F API in [`about:config`](https://support.mozilla.org/en-US/kb/about-config-editor-firefox).
+ 1. Search for `security.webauth.u2f` and select it to toggle to `true`.
To set up 2FA with a U2F device:
-1. Sign in to your GitLab account.
-1. Go to your [**User settings**](../index.md#access-your-user-settings).
-1. Go to **Account**.
-1. Click **Enable Two-Factor Authentication**.
+1. Access your [**User settings**](../index.md#access-your-user-settings).
+1. Select **Account**.
+1. Select **Enable Two-Factor Authentication**.
1. Connect your U2F device.
-1. Click on **Set up New U2F Device**.
+1. Select on **Set up New U2F Device**.
1. A light begins blinking on your device. Activate it by pressing its button.
-A message displays, indicating that your device was successfully set up.
-Click on **Register U2F Device** to complete the process.
+A message displays indicating that your device was successfully set up. Select **Register U2F Device** to complete the
+process. Recovery codes are not generated for U2F devices.
-### WebAuthn device
+### Set up a WebAuthn device
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22506) in GitLab 13.4 [with a flag](../../../administration/feature_flags.md) named `webauthn`. Disabled by default.
> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/232671) in GitLab 14.6.
FLAG:
-On self-managed GitLab, by default this feature is available. To disable the feature, ask an administrator to [disable the feature flag](../../../administration/feature_flags.md) named `webauthn`. If you disable the WebAuthn feature flag after WebAuthn devices have been registered, these devices are not usable until you re-enable this feature. On GitLab.com, this feature is available.
-
-The WebAuthn workflow is [supported by](https://caniuse.com/#search=webauthn) the
-following desktop browsers:
-
-- Chrome
-- Edge
-- Firefox
-- Opera
-- Safari
-
-and the following mobile browsers:
-
-- Chrome for Android
-- Firefox for Android
-- iOS Safari (since iOS 13.3)
-
-To set up 2FA with a WebAuthn compatible device:
-
-1. Sign in to your GitLab account.
-1. Go to your [**User settings**](../index.md#access-your-user-settings).
-1. Go to **Account**.
+On self-managed GitLab, by default this feature is available. To disable the feature, ask an administrator to
+[disable the feature flag](../../../administration/feature_flags.md) named `webauthn`. If you disable the WebAuthn
+feature flag after WebAuthn devices have been registered, these devices are not usable until you re-enable this feature.
+On GitLab.com, this feature is available.
+
+WebAuthn [supported by](https://caniuse.com/#search=webauthn):
+
+- The following desktop browsers:
+ - Chrome
+ - Edge
+ - Firefox
+ - Opera
+ - Safari
+- The following mobile browsers:
+ - Chrome for Android
+ - Firefox for Android
+ - iOS Safari (since iOS 13.3)
+
+To set up 2FA with a WebAuthn-compatible device:
+
+1. Access your [**User settings**](../index.md#access-your-user-settings).
+1. Select **Account**.
1. Select **Enable Two-Factor Authentication**.
1. Plug in your WebAuthn device.
1. Select **Set up New WebAuthn Device**.
-1. Depending on your device, you might need to press a button or touch a sensor.
+1. Depending on your device, you might have to press a button or touch a sensor.
-A message displays, indicating that your device was successfully set up.
-Recovery codes are not generated for WebAuthn devices.
+A message displays indicating that your device was successfully set up. Recovery codes are not generated for WebAuthn
+devices.
## Recovery codes
-NOTE:
-Recovery codes are not generated for U2F / WebAuthn devices.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/267730) in GitLab 13.7, **Copy codes** and **Print codes** buttons.
+
+Immediately after successfully enabling 2FA with a one-time password, you're prompted to download
+a set of generated recovery codes. If you ever lose access to your one-time password authenticator, you can use one of
+these recovery codes to sign in to your account.
WARNING:
Each code can be used only once to sign in to your account.
-Immediately after successfully enabling two-factor authentication, you're
-prompted to download a set of generated recovery codes. Should you ever lose access
-to your one-time password authenticator, you can use one of these recovery codes to sign in to
-your account. We suggest copying and printing them, or downloading them using
-the **Download codes** button for storage in a safe place. If you choose to
-download them, the file is called `gitlab-recovery-codes.txt`.
+We recommend copying and printing them, or downloading them using the **Download codes** button for storage in a safe
+place. If you choose to download them, the file is called `gitlab-recovery-codes.txt`.
+
+NOTE:
+Recovery codes are not generated for U2F or WebAuthn devices.
+
+If you lose the recovery codes, or want to generate new ones, you can use either:
+
+- The [2FA account settings](#regenerate-two-factor-authentication-recovery-codes) page.
+- [SSH](#generate-new-recovery-codes-using-ssh).
+
+### Regenerate two-factor authentication recovery codes
-The UI now includes **Copy codes** and **Print codes** buttons, for your convenience.
-[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/267730) in GitLab 13.7.
+To regenerate 2FA recovery codes, you need access to a desktop browser:
-If you lose the recovery codes or just want to generate new ones, you can do so
-from the [two-factor authentication account settings page](#regenerate-2fa-recovery-codes) or
-[using SSH](#generate-new-recovery-codes-using-ssh).
+1. Access your [**User settings**](../index.md#access-your-user-settings).
+1. Select **Account > Two-Factor Authentication (2FA)**.
+1. If you've already configured 2FA, select **Manage two-factor authentication**.
+1. In the **Register Two-Factor Authenticator** pane, enter your current password and select **Regenerate recovery codes**.
-## Signing in with 2FA Enabled
+NOTE:
+If you regenerate 2FA recovery codes, save them. You can't use any previously created 2FA codes.
+
+## Sign in with two-factor authentication enabled
-Signing in with 2FA enabled is only slightly different than the normal sign-in process.
-Enter your username and password credentials as you normally would, and you're
-presented with a second prompt, depending on which type of 2FA you've enabled.
+Signing in with 2FA enabled is only slightly different than the normal sign-in process. Enter your username and password
+and you're presented with a second prompt, depending on which type of 2FA you've enabled.
-### Sign in by using a one-time password
+### Sign in using a one-time password
-When asked, enter the pin from your one time password authenticator's application or a
-recovery code to sign in.
+When asked, enter the pin from your one time password authenticator's application or a recovery code to sign in.
-### Sign in by using a U2F device
+### Sign in using a U2F device
To sign in by using a U2F device:
-1. Click **Login via U2F Device**.
+1. Select **Login via U2F Device**.
1. A light begins blinking on your device. Activate it by touching/pressing
its button.
-A message displays, indicating that your device responded to the authentication
-request, and you're automatically signed in.
+A message displays indicating that your device responded to the authentication request, and you're automatically signed
+in.
-### Sign in by using a WebAuthn device
+### Sign in using a WebAuthn device
-In supported browsers you should be automatically prompted to activate your WebAuthn device
-(for example, by touching or pressing its button) after entering your credentials.
+In supported browsers, you should be automatically prompted to activate your WebAuthn device (for example, by touching
+or pressing its button) after entering your credentials.
-A message displays, indicating that your device responded to the authentication
-request and you're automatically signed in.
+A message displays indicating that your device responded to the authentication request and you're automatically signed
+in.
-## Disabling 2FA
+## Disable two-factor authentication
-If you ever need to disable 2FA:
+To disable 2FA:
-1. Sign in to your GitLab account.
-1. Go to your [**User settings**](../index.md#access-your-user-settings).
-1. Go to **Account**.
+1. Access your [**User settings**](../index.md#access-your-user-settings).
+1. Select **Account**.
1. Select **Manage two-factor authentication**.
-1. Under **Two-Factor Authentication**, enter your current password and select **Disable**.
-
-This clears all your two-factor authentication registrations, including mobile
-applications and U2F / WebAuthn devices.
+1. Under **Register Two-Factor Authenticator**, enter your current password and select **Disable two-factor
+ authentication**.
-Support for disabling 2FA is limited, depending on your subscription level. For more information, see the
-[Account Recovery](https://about.gitlab.com/support/#account-recovery) section of our website.
+This clears all your 2FA registrations, including mobile applications and U2F or WebAuthn devices.
-## Personal access tokens
-
-When 2FA is enabled, you can no longer use your normal account password to
-authenticate with Git over HTTPS on the command line or when using
-the [GitLab API](../../../api/index.md). You must use a
-[personal access token](../personal_access_tokens.md) instead.
+Support Team support for disabling 2FA is limited, depending on your subscription level. For more information, see the
+[Account Recovery](https://about.gitlab.com/support/#account-recovery-and-2fa-resets) section of our website.
## Recovery options
-To disable two-factor authentication on your account (for example, if you
-have lost your code generation device) you can:
+If you don't have access to your code generation device, you can recover access to your account:
-- [Use a saved recovery code](#use-a-saved-recovery-code).
-- [Generate new recovery codes using SSH](#generate-new-recovery-codes-using-ssh).
-- [Regenerate 2FA recovery codes](#regenerate-2fa-recovery-codes).
-- [Have 2FA disabled on your account](#have-2fa-disabled-on-your-account).
+- [Use a saved recovery code](#use-a-saved-recovery-code), if you saved them when you enabled two-factor
+ authentication.
+- [Generate new recovery codes using SSH](#generate-new-recovery-codes-using-ssh), if you didn't save your original
+ recovery codes but have an SSH key.
+- [Have 2FA disabled on your account](#have-two-factor-authentication-disabled-on-your-account), if you don't have your
+ recovery codes or an SSH key.
### Use a saved recovery code
-Enabling two-factor authentication for your account generated several recovery
-codes. If you saved these codes, you can use one of them to sign in.
+To use a recovery code:
-To use a recovery code, enter your username/email and password on the GitLab
-sign-in page. When prompted for a two-factor code, enter the recovery code.
+1. Enter your username or email, and password, on the GitLab sign-in page.
+1. When prompted for a two-factor code, enter the recovery code.
-After you use a recovery code, you cannot re-use it. You can still use the other
-recovery codes you saved.
+After you use a recovery code, you cannot re-use it. You can still use the other recovery codes you saved.
### Generate new recovery codes using SSH
-Users often forget to save their recovery codes when enabling two-factor
-authentication. If an SSH key is added to your GitLab account, you can generate
-a new set of recovery codes with SSH:
+Users often forget to save their recovery codes when enabling 2FA. If you added an SSH key to your
+GitLab account, you can generate a new set of recovery codes with SSH:
-1. Run:
+1. In a terminal, run:
```shell
ssh git@gitlab.com 2fa_recovery_codes
```
- NOTE:
- On self-managed instances, replace **`gitlab.com`** in the command above
- with the GitLab server hostname (`gitlab.example.com`).
+ On self-managed instances, replace **`gitlab.com`** in the command above with the GitLab server hostname (`gitlab.example.com`).
-1. You are prompted to confirm that you want to generate new codes.
- Continuing this process invalidates previously saved codes:
+1. You are prompted to confirm that you want to generate new codes. This process invalidates previously-saved codes. For
+ example:
```shell
Are you sure you want to generate new two-factor recovery codes?
@@ -441,49 +385,30 @@ a new set of recovery codes with SSH:
so you do not lose access to your account again.
```
-1. Go to the GitLab sign-in page and enter your username/email and password.
- When prompted for a two-factor code, enter one of the recovery codes obtained
- from the command-line output.
-
-After signing in, visit your **User settings > Account** immediately to set
-up two-factor authentication with a new device.
-
-### Regenerate 2FA recovery codes
-
-To regenerate 2FA recovery codes, you need access to a desktop browser:
-
-1. Navigate to GitLab.
-1. Sign in to your GitLab account.
-1. Go to your [**User settings**](../index.md#access-your-user-settings).
-1. Select **Account > Two-Factor Authentication (2FA)**.
-1. If you've already configured 2FA, click **Manage two-factor authentication**.
-1. In the **Register Two-Factor Authenticator** pane, enter your current password and select **Regenerate recovery codes**.
+1. Go to the GitLab sign-in page and enter your username or email, and password. When prompted for a two-factor code,
+ enter one of the recovery codes obtained from the command-line output.
-NOTE:
-If you regenerate 2FA recovery codes, save them. You can't use any previously created 2FA codes.
+After signing in, immediately set up 2FA with a new device.
-### Have 2FA disabled on your account
+### Have two-factor authentication disabled on your account **(PREMIUM SAAS)**
-If you can't use a saved recovery code or generate new recovery codes, submit a [support ticket](https://support.gitlab.com/hc/en-us/requests/new) to
-request a GitLab global administrator disable two-factor authentication for your account. Note that:
+If other methods are unavailable, submit a [support ticket](https://support.gitlab.com/hc/en-us/requests/new) to request
+a GitLab global administrator disable 2FA for your account:
- Only the owner of the account can make this request.
- This service is only available for accounts that have a GitLab.com subscription. For more information, see our
[blog post](https://about.gitlab.com/blog/2020/08/04/gitlab-support-no-longer-processing-mfa-resets-for-free-users/).
-- Disabling this setting temporarily leaves your account in a less secure state. You should sign in and re-enable two-factor authentication
- as soon as possible.
+- Disabling this setting temporarily leaves your account in a less secure state. You should sign in and re-enable two-factor
+ authentication as soon as possible.
-## Note to GitLab administrators
+## Information for GitLab administrators **(FREE SELF)**
-- You need to take special care to that 2FA keeps working after
- [restoring a GitLab backup](../../../raketasks/backup_restore.md).
-- To ensure 2FA authorizes correctly with time-based one time passwords (TOTP) server, you may want to ensure
- your GitLab server's time is synchronized via a service like NTP. Otherwise,
- you may have cases where authorization always fails because of time differences.
-- The GitLab U2F implementation does _not_ work when the GitLab instance is accessed from
- multiple hostnames, or FQDNs. Each U2F registration is linked to the _current hostname_ at
- the time of registration, and cannot be used for other hostnames/FQDNs. The same applies to
- WebAuthn registrations.
+- Take care that 2FA keeps working after [restoring a GitLab backup](../../../raketasks/backup_restore.md).
+- To ensure 2FA authorizes correctly with a time-based one time passwords (TOTP) server, synchronize your GitLab
+ server's time using a service like NTP. Otherwise, authorization can always fail because of time differences.
+- The GitLab U2F and WebAuthn implementation does _not_ work when the GitLab instance is accessed from multiple hostnames
+ or FQDNs. Each U2F or WebAuthn registration is linked to the _current hostname_ at the time of registration, and
+ cannot be used for other hostnames or FQDNs.
For example, if a user is trying to access a GitLab instance from `first.host.xyz` and `second.host.xyz`:
@@ -492,13 +417,13 @@ request a GitLab global administrator disable two-factor authentication for your
- The user signs out and attempts to sign in by using `second.host.xyz` - U2F authentication fails, because
the U2F key has only been registered on `first.host.xyz`.
-- To enforce 2FA at the system or group levels see [Enforce Two-factor Authentication](../../../security/two_factor_authentication.md).
+- To enforce 2FA at the system or group levels see, [Enforce two-factor authentication](../../../security/two_factor_authentication.md).
## Troubleshooting
-If you are receiving an `invalid pin code` error, this may indicate that there is a time sync issue between the authentication application and the GitLab instance itself.
-
-To avoid the time sync issue, enable time synchronization in the device that generates the codes. For example:
+If you receive an `invalid pin code` error, this can indicate that there is a time sync issue between the authentication
+application and the GitLab instance itself. To avoid the time sync issue, enable time synchronization in the device that
+generates the codes. For example:
- For Android (Google Authenticator):
1. Go to the Main Menu in Google Authenticator.
@@ -510,15 +435,3 @@ To avoid the time sync issue, enable time synchronization in the device that gen
1. Select General.
1. Select Date & Time.
1. Enable Set Automatically. If it's already enabled, disable it, wait a few seconds, and re-enable.
-
-<!-- ## Troubleshooting
-
-Include any troubleshooting steps that you can foresee. If you know beforehand what issues
-one might have when setting this up, or when something is changed, or on upgrading, it's
-important to describe those, too. Think of things that may go wrong and include them here.
-This is important to minimize requests for support, and to avoid doc comments with
-questions that you know someone might ask.
-
-Each scenario can be a third-level heading, e.g. `### Getting error message X`.
-If you have none to add when creating a doc, leave this section in place
-but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/user/profile/index.md b/doc/user/profile/index.md
index 90cb6502bbd..89e4ea6ea5b 100644
--- a/doc/user/profile/index.md
+++ b/doc/user/profile/index.md
@@ -1,7 +1,7 @@
---
type: index, howto
stage: Manage
-group: Access
+group: Authentication & 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/user/profile/personal_access_tokens.md b/doc/user/profile/personal_access_tokens.md
index ea66f3e508f..45cff326332 100644
--- a/doc/user/profile/personal_access_tokens.md
+++ b/doc/user/profile/personal_access_tokens.md
@@ -1,7 +1,7 @@
---
type: concepts, howto
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -14,7 +14,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Personal access tokens can be an alternative to [OAuth2](../../api/oauth2.md) and used to:
-- Authenticate with the [GitLab API](../../api/index.md#personalproject-access-tokens).
+- Authenticate with the [GitLab API](../../api/index.md#personalprojectgroup-access-tokens).
- Authenticate with Git using HTTP Basic Authentication.
In both cases, you authenticate with a personal access token in place of your password.
@@ -33,7 +33,7 @@ Though required, GitLab usernames are ignored when authenticating with a persona
There is an [issue for tracking](https://gitlab.com/gitlab-org/gitlab/-/issues/212953) to make GitLab
use the username.
-For examples of how you can use a personal access token to authenticate with the API, see the [API documentation](../../api/index.md#personalproject-access-tokens).
+For examples of how you can use a personal access token to authenticate with the API, see the [API documentation](../../api/index.md#personalprojectgroup-access-tokens).
Alternately, GitLab administrators can use the API to create [impersonation tokens](../../api/index.md#impersonation-tokens).
Use impersonation tokens to automate authentication as a specific user.
diff --git a/doc/user/profile/unknown_sign_in_notification.md b/doc/user/profile/unknown_sign_in_notification.md
index be86db3daf5..0ed2a11d363 100644
--- a/doc/user/profile/unknown_sign_in_notification.md
+++ b/doc/user/profile/unknown_sign_in_notification.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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/user/project/badges.md b/doc/user/project/badges.md
index 9ca11d43864..79d395d51c3 100644
--- a/doc/user/project/badges.md
+++ b/doc/user/project/badges.md
@@ -1,14 +1,11 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, howto
+info: 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
---
# Badges **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41174) in GitLab 10.7.
-
Badges are a unified way to present condensed pieces of information about your
projects. They consist of a small image and a URL that the image
points to. Examples for badges can be the [pipeline status](../../ci/pipelines/settings.md#pipeline-status-badge),
@@ -87,7 +84,7 @@ Badges directly associated with a project can be configured on the
## Placeholders
-The URL a badge points to, as well as the image URL, can contain placeholders
+Both the URL a badge points to and the image URL can contain placeholders
which are evaluated when displaying the badge. The following placeholders
are available:
diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md
index ccf90a3d3dd..cf571abbf8a 100644
--- a/doc/user/project/clusters/serverless/aws.md
+++ b/doc/user/project/clusters/serverless/aws.md
@@ -394,6 +394,8 @@ stages:
production:
stage: deploy
before_script:
+ - apt-get update
+ - apt-get install -y python3-pip
- pip3 install awscli --upgrade
- pip3 install aws-sam-cli --upgrade
script:
diff --git a/doc/user/project/code_owners.md b/doc/user/project/code_owners.md
index a95e4d2bc26..4068d8e056c 100644
--- a/doc/user/project/code_owners.md
+++ b/doc/user/project/code_owners.md
@@ -1,19 +1,12 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference
+info: 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
---
# Code Owners **(PREMIUM)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6916) in GitLab 11.3.
-> - Code Owners for merge request approvals was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4418) in GitLab Premium 11.9.
-> - Moved to GitLab Premium in 13.9.
-
-INFO:
-Get access to Code Owners and more with a
-[free 30-day trial of GitLab Ultimate](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=p-code-owners-docs).
+> Moved to GitLab Premium in 13.9.
Code Owners define who owns specific files or directories in a repository.
@@ -283,3 +276,26 @@ model/db @database
[DOCUMENTATION]
README.md @docs
```
+
+## Troubleshooting
+
+### Approvals shown as optional
+
+A Code Owner approval rule is optional if these conditions are not met:
+
+- The user or group are not a member of the project or parent group.
+- [Code Owner approval on a protected branch](protected_branches.md#require-code-owner-approval-on-a-protected-branch) has not been set up.
+- The section is [marked as optional](#make-a-code-owners-section-optional).
+
+### Approvals do not show
+
+Code Owner approval rules only update when the merge request is created.
+If you update the `CODEOWNERS` file, close the merge request and create a new one.
+
+### User not shown as possible approver
+
+A user might not show as an approver on the Code Owner merge request approval rules.
+
+This result occurs when a rule prevents the specific user from approving the merge request.
+Check the project
+[merge request approval setting](merge_requests/approvals/settings.md#edit-merge-request-approval-settings).
diff --git a/doc/user/project/deploy_keys/index.md b/doc/user/project/deploy_keys/index.md
index c5950347ae9..2e876b24b53 100644
--- a/doc/user/project/deploy_keys/index.md
+++ b/doc/user/project/deploy_keys/index.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: howto, reference
---
-# Deploy keys
+# 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.
diff --git a/doc/user/project/deploy_tokens/index.md b/doc/user/project/deploy_tokens/index.md
index c840f6c8698..f57fa5aa57d 100644
--- a/doc/user/project/deploy_tokens/index.md
+++ b/doc/user/project/deploy_tokens/index.md
@@ -4,12 +4,12 @@ group: Release
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Deploy tokens
+# Deploy tokens **(FREE)**
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/199370) from **Settings > Repository** in GitLab 12.9.
-> - [Added `write_registry` scope](https://gitlab.com/gitlab-org/gitlab/-/issues/22743) in GitLab 12.10.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29280) from **Settings > CI/CD** in GitLab 12.10.1.
-> - [Added package registry scopes](https://gitlab.com/gitlab-org/gitlab/-/issues/213566) in GitLab 13.0.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/199370) from **Settings > Repository** to **Settings > CI/CD** in GitLab 12.9.
+> - [Added](https://gitlab.com/gitlab-org/gitlab/-/issues/22743) `write_registry` scope in GitLab 12.10.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29280) from **Settings > CI/CD** to **Settings > Repository** in GitLab 12.10.1.
+> - [Added](https://gitlab.com/gitlab-org/gitlab/-/issues/213566) package registry scopes in GitLab 13.0.
Deploy tokens allow you to download (`git clone`) or push and pull packages and
container registry images of a project without having a user and a password.
diff --git a/doc/user/project/description_templates.md b/doc/user/project/description_templates.md
index 66e5931fa4c..6c17964f3a5 100644
--- a/doc/user/project/description_templates.md
+++ b/doc/user/project/description_templates.md
@@ -6,73 +6,42 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Description templates **(FREE)**
-We all know that a properly submitted issue is more likely to be addressed in
-a timely manner by the developers of a project.
+You can define templates to use as descriptions
+for your [issues](issues/index.md) and [merge requests](merge_requests/index.md).
-With description templates, you can define context-specific templates for issue and merge request
-description fields for your project, and filter out unnecessary noise from issues.
+You can define these templates in a project, group, or instance. Projects
+inherit the templates defined at a higher level.
-By using the description templates, users that create a new issue or merge
-request can select a description template to help them communicate with other
-contributors effectively.
+You might want to use these templates:
-Every GitLab project can define its own set of description templates as they
-are added to the root directory of a GitLab project's repository.
+- For different stages of your workflow, for example, feature proposal, feature improvement, or a bug report.
+- For every issue or merge request for a specific project, so the layout is consistent.
+- For a [Service Desk email template](service_desk.md#new-service-desk-issues).
-Description templates must be written in [Markdown](../markdown.md) and stored
-in your project's repository in the `.gitlab` directory. Only the
-templates of the default branch are taken into account.
+For description templates to work, they must be:
-To learn how to create templates for various file types in groups, visit
-[Group file templates](../group/index.md#group-file-templates).
-
-## Use cases
-
-These are some situations when you might find description templates useful:
-
-- You can create issues and merge request templates for different
- stages of your workflow, for example, feature proposal, feature improvement, or a bug report.
-- Add a template to be used in every issue for a specific project,
- giving instructions and guidelines, requiring for information specific to that subject.
- For example, if you have a project for tracking new blog posts, you can require the
- title, outlines, author name, and author social media information.
-- Following the previous example, you can make a template for every MR submitted
- with a new blog post, requiring information about the post date, front matter data,
- images guidelines, link to the related issue, reviewer name, and so on.
-- You can also create issues and merge request templates for different
- stages of your workflow, for example, feature proposal, feature improvement, or a bug report.
-- You can use an [issue description template](#create-an-issue-template) as a
- [Service Desk email template](service_desk.md#new-service-desk-issues).
+- Saved with the `.md` extension.
+- Stored in your project's repository in the `.gitlab/issue_templates`
+ or `.gitlab/merge_request_templates` directory.
+- Be present on the default branch.
## Create an issue template
Create a new Markdown (`.md`) file inside the `.gitlab/issue_templates/`
-directory in your repository. Commit and push to your default branch.
+directory in your repository.
-To create a Markdown file:
+To create an issue description template:
-1. In a project, go to **Repository**.
-1. Next to the default branch, select the **{plus}** button.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Repository**.
+1. Next to the default branch, select **{plus}**.
1. Select **New file**.
-1. Next to the default branch, in the **File name** field, add the name of your issue template.
- Make sure that your file has the `.md` extension, for
- example `feature_request.md` or `Feature Request.md`.
-1. Commit and push to your default branch.
-
-If you don't have a `.gitlab/issue_templates` directory in your repository, you need to create it.
-
-To create the `.gitlab/issue_templates` directory:
-
-1. In a project, go to **Repository**.
-1. Next to the default branch, select the **{plus}** button.
-1. Select **New directory**.
-1. Name this new directory `.gitlab` and commit to your default branch.
-1. Next to the default branch, select the **{plus}** button.
-1. Select **New directory**.
-1. Name your directory `issue_templates` and commit to your default branch.
+1. Next to the default branch, in the **File name** text box, enter `.gitlab/issue_templates/mytemplate.md`,
+ where `mytemplate` is the name of your issue template.
+1. Commit to your default branch.
To check if this has worked correctly, [create a new issue](issues/managing_issues.md#create-an-issue)
-and see if you can choose a description template.
+and see if you can find your description template in the **Choose a template** dropdown list.
## Create a merge request template
@@ -80,51 +49,48 @@ Similarly to issue templates, create a new Markdown (`.md`) file inside the
`.gitlab/merge_request_templates/` directory in your repository. Commit and
push to your default branch.
-## Use the templates
-
-Let's take for example that you've created the file `.gitlab/issue_templates/Bug.md`.
-This enables the `Bug` dropdown option when creating or editing issues. When
-`Bug` is selected, the content from the `Bug.md` template file is copied
-to the issue description field. The **Reset template** button discards any
-changes you made after picking the template and returns it to its initial status.
+To create a merge request description template:
-NOTE:
-You can create shortcut links to create an issue using a designated template.
-For example: `https://gitlab.com/gitlab-org/gitlab/-/issues/new?issuable_template=Feature%20proposal`.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Repository**.
+1. Next to the default branch, select **{plus}**.
+1. Select **New file**.
+1. Next to the default branch, in the **File name** text box, enter `.gitlab/merge_request_templates/mytemplate.md`,
+ where `mytemplate` is the name of your merge request template.
+1. Commit to your default branch.
-![Description templates](img/description_templates.png)
+To check if this has worked correctly, [create a new merge request](merge_requests/creating_merge_requests.md)
+and see if you can find your description template in the **Choose a template** dropdown list.
-You can set description templates at various levels:
+## Use the templates
-- The entire [instance](#set-instance-level-description-templates)
-- A specific [group or subgroup](#set-group-level-description-templates)
-- A specific [project](#set-a-default-template-for-merge-requests-and-issues)
+When you create or edit an issue or a merge request, it shows in the **Choose a template** dropdown list.
-The templates are inherited. For example, in a project, you can also access templates set for the
-instance or the project's parent groups.
+To apply a template:
-### Set instance-level description templates **(PREMIUM SELF)**
+1. Create or edit an issue or a merge request.
+1. Select the **Choose a template** dropdown list.
+1. If the **Description** text box hasn't been empty, to confirm, select **Apply template**.
+1. Select **Save changes**.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52360) in GitLab 13.9.
-> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/321247) in GitLab 14.0.
+When you select a description template, its content is copied to the description text box.
-You can set a description template at the **instance level** for issues
-and merge requests.
-As a result, these templates are available in all projects within the instance.
+To discard any changes to the description you've made after selecting the template: expand the **Choose a template** dropdown list and select **Reset template**.
-Only instance administrators can set instance-level templates.
+![Choosing a description template in an issue](img/description_templates_v14_7.png)
-To set the instance-level description template repository:
+NOTE:
+You can create shortcut links to create an issue using a designated template.
+For example: `https://gitlab.com/gitlab-org/gitlab/-/issues/new?issuable_template=Feature%20proposal`. Read more about [creating issues using a URL with prefilled values](issues/managing_issues.md#using-a-url-with-prefilled-values).
-1. On the top bar, select **Menu > Admin**.
-1. On the left sidebar, select **Settings > Templates**.
-1. Expand **Templates**
-1. From the dropdown, select your template project as the template repository at instance level.
-1. Select **Save changes**.
+### Set instance-level description templates **(PREMIUM SELF)**
-![Setting templates in the Admin Area](../admin_area/settings/img/file_template_admin_area_v14_0.png)
+You can set a description template at the **instance level** for issues
+and merge requests by using an [instance template repository](../admin_area/settings/instance_template_repository.md).
+You can also use the instance template repository for file templates.
-Learn more about [instance template repository](../admin_area/settings/instance_template_repository.md).
+You might also be interested [project templates](../admin_area/custom_project_templates.md)
+that you can use when creating a new project in the instance.
### Set group-level description templates **(PREMIUM)**
@@ -137,23 +103,27 @@ As a result, you can use the same templates in issues and merge requests in all
To re-use templates [you've created](../project/description_templates.md#create-an-issue-template):
-1. Go to the group's **Settings > General > Templates**.
-1. From the dropdown, select your template project as the template repository at group level.
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Settings > General**.
+1. Expand **Templates**.
+1. From the dropdown list, select your template project as the template repository at group level.
1. Select **Save changes**.
![Group template settings](../group/img/group_file_template_settings.png)
+You might also be interested in templates for various
+[file types in groups](../group/index.md#group-file-templates).
+
### Set a default template for merge requests and issues **(PREMIUM)**
In a project, you can choose a default description template for new issues and merge requests.
As a result, every time a new merge request or issue is created, it's pre-filled with the text you
entered in the template.
-The visibility of issues or merge requests should be set to either "Everyone
-with access" or "Only Project Members" in your project's
-**Settings / Visibility, project features, permissions** section. Otherwise, the
-template text areas don't show. This is the default behavior, so in most cases
-you should be fine.
+Prerequisites:
+
+- On your project's left sidebar, select **Settings > General** and expand **Visibility, project features, permissions**.
+ Ensure issues or merge requests are set to either **Everyone with access** or **Only Project Members**.
To set a default description template for merge requests:
@@ -170,11 +140,10 @@ To set a default description template for issues:
Because GitLab merge request and issues support [Markdown](../markdown.md), you can use it to format
headings, lists, and so on.
-[GitLab versions 13.10 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/885)
-provide `issues_template` and `merge_requests_template` attributes in the
-[Projects API](../../api/projects.md) to help you keep your templates up to date.
+You can also provide `issues_template` and `merge_requests_template` attributes in the
+[Projects REST API](../../api/projects.md) to keep your default issue and merge request templates up to date.
-## Description template example
+## Example description template
We use description templates for issues and merge requests in the
[`.gitlab` folder](https://gitlab.com/gitlab-org/gitlab/-/tree/master/.gitlab) of the
diff --git a/doc/user/project/file_lock.md b/doc/user/project/file_lock.md
index 10dcbddac17..1d06b605aa9 100644
--- a/doc/user/project/file_lock.md
+++ b/doc/user/project/file_lock.md
@@ -2,7 +2,6 @@
stage: Create
group: Source Code
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: reference, howto
---
# File Locking **(FREE)**
@@ -43,8 +42,6 @@ locked by Administrator`.
## Exclusive file locks **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/35856) in GitLab 10.5.
-
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.
diff --git a/doc/user/project/img/description_templates.png b/doc/user/project/img/description_templates.png
deleted file mode 100644
index e9d45029532..00000000000
--- a/doc/user/project/img/description_templates.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/img/description_templates_v14_7.png b/doc/user/project/img/description_templates_v14_7.png
new file mode 100644
index 00000000000..acb1b9f79d9
--- /dev/null
+++ b/doc/user/project/img/description_templates_v14_7.png
Binary files differ
diff --git a/doc/user/project/import/bitbucket_server.md b/doc/user/project/import/bitbucket_server.md
index 81e7d159a06..da47b673c29 100644
--- a/doc/user/project/import/bitbucket_server.md
+++ b/doc/user/project/import/bitbucket_server.md
@@ -33,6 +33,7 @@ created as private in GitLab as well.
and quote part of the original comment.
- Declined pull requests have unreachable commits, which prevents the GitLab importer from
generating a proper diff. These pull requests show up as empty changes.
+- Pull request approvals are not imported.
- Attachments in Markdown are not imported.
- Task lists are not imported.
- Emoji reactions are not imported.
diff --git a/doc/user/project/import/github.md b/doc/user/project/import/github.md
index 72bf0841687..d4cca723333 100644
--- a/doc/user/project/import/github.md
+++ b/doc/user/project/import/github.md
@@ -26,6 +26,7 @@ The following aspects of a project are imported:
- Regular issue and pull request comments
- [Git Large File Storage (LFS) Objects](../../../topics/git/lfs/index.md)
- Pull request comments replies in discussions ([GitLab.com & 14.5+](https://gitlab.com/gitlab-org/gitlab/-/issues/336596))
+- Diff Notes suggestions ([GitLab.com & 14.7+](https://gitlab.com/gitlab-org/gitlab/-/issues/340624)) [with a flag](../../../administration/feature_flags.md) named `github_importer_use_diff_note_with_suggestions`. Enabled by default.
References to pull requests and issues are preserved (GitLab.com & 8.7+), and
each imported repository maintains visibility level unless that [visibility
@@ -164,16 +165,16 @@ your GitHub repositories are listed.
![GitHub importer page](img/import_projects_from_github_importer_v12_3.png)
-## Mirror a repository and share pipeline status
+## Mirror a repository and share pipeline status **(PREMIUM)**
Depending on your GitLab tier, [repository mirroring](../repository/mirror/index.md) can be set up to keep
your imported repository in sync with its GitHub copy.
-Additionally, you can configure GitLab to send pipeline status updates back GitHub with the
-[GitHub Project Integration](../integrations/github.md). **(PREMIUM)**
+Additionally, you can configure GitLab to send pipeline status updates back to GitHub with the
+[GitHub Project Integration](../integrations/github.md).
If you import your project using [CI/CD for external repository](../../../ci/ci_cd_for_external_repos/index.md), then both
-of the above are automatically configured. **(PREMIUM)**
+of the above are automatically configured.
NOTE:
Mirroring does not sync any new or updated pull requests from your GitHub project.
diff --git a/doc/user/project/import/index.md b/doc/user/project/import/index.md
index 9d7ed593d41..001f0d56cc5 100644
--- a/doc/user/project/import/index.md
+++ b/doc/user/project/import/index.md
@@ -28,7 +28,7 @@ See these documents to migrate to GitLab:
You can also import any Git repository through HTTP from the **New Project** page. Note that if the
repository is too large, the import can timeout.
-You can also [connect your external repository to get CI/CD benefits](../../../ci/ci_cd_for_external_repos/index.md). **(PREMIUM)**
+You can also [connect your external repository to get CI/CD benefits](../../../ci/ci_cd_for_external_repos/index.md).
## LFS authentication
@@ -42,7 +42,10 @@ However, you can't import issues and merge requests this way. To retain all meta
merge requests, use the [import/export feature](../settings/import_export.md)
to export projects from self-managed GitLab and import those projects into GitLab.com. All GitLab
user associations (such as comment author) are changed to the user importing the project. For more
-information, see [the import notes](../settings/import_export.md#important-notes).
+information, see the prerequisites and important notes in these sections:
+
+- [Export a project and its data](../settings/import_export.md#export-a-project-and-its-data).
+- [Import the project](../settings/import_export.md#import-a-project-and-its-data).
NOTE:
When migrating to GitLab.com, you must create users manually unless [SCIM](../../../user/group/saml_sso/scim_setup.md)
@@ -56,7 +59,7 @@ Migrate the assets in this order:
1. [Projects](../../../api/projects.md)
1. [Project variables](../../../api/project_level_variables.md)
-Keep in mind the limitations of the [import/export feature](../settings/import_export.md#exported-contents).
+Keep in mind the limitations of the [import/export feature](../settings/import_export.md#items-that-are-exported).
You must still migrate your [Container Registry](../../packages/container_registry/)
over a series of Docker pulls and pushes. Re-run any CI pipelines to retrieve any build artifacts.
@@ -87,7 +90,7 @@ to migrate users.
## Project aliases **(PREMIUM SELF)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3264) in GitLab Premium 12.1.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3264) in GitLab 12.1.
GitLab repositories are usually accessed with a namespace and a project name. When migrating
frequently accessed repositories to GitLab, however, you can use project aliases to access those
diff --git a/doc/user/project/index.md b/doc/user/project/index.md
index 07e8ea1dc06..bee097cdcbe 100644
--- a/doc/user/project/index.md
+++ b/doc/user/project/index.md
@@ -1,8 +1,7 @@
---
stage: Manage
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"
-type: reference
+info: 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
---
# Organize work with projects **(FREE)**
@@ -43,9 +42,9 @@ Projects include the following [features](https://about.gitlab.com/features/):
- [Issue tracker](issues/index.md): Discuss implementations with your team.
- [Issue boards](issue_board.md): Organize and prioritize your workflow.
- [Multiple issue boards](issue_board.md#multiple-issue-boards): Create team-specific workflows (issue boards) for a project.
-- [Merge Requests](merge_requests/index.md): Apply a branching
+- [Merge requests](merge_requests/index.md): Apply a branching
strategy and get reviewed by your team.
- - [Merge Request Approvals](merge_requests/approvals/index.md): Ask for approval before
+ - [Merge request approvals](merge_requests/approvals/index.md): Ask for approval before
implementing a change.
- [Fix merge conflicts from the UI](merge_requests/conflicts.md): View Git diffs from the GitLab UI.
- [Review Apps](../../ci/review_apps/index.md): By branch, preview the results
@@ -144,7 +143,7 @@ There are numerous [APIs](../../api/index.md) to use with your projects:
- [Issue board](../../api/boards.md)
- [Labels](../../api/labels.md)
- [Markdown](../../api/markdown.md)
-- [Merge Requests](../../api/merge_requests.md)
+- [Merge requests](../../api/merge_requests.md)
- [Milestones](../../api/milestones.md)
- [Services](../../api/integrations.md)
- [Snippets](../../api/project_snippets.md)
diff --git a/doc/user/project/insights/index.md b/doc/user/project/insights/index.md
index 957290c5f20..0609b843e86 100644
--- a/doc/user/project/insights/index.md
+++ b/doc/user/project/insights/index.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Insights **(ULTIMATE)**
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/725) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.0.
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/725) in GitLab 12.0.
Configure the Insights that matter for your projects to explore data such as
triage hygiene, issues created/closed per a given period, average time for merge
@@ -297,7 +297,7 @@ you may see `created_at` in place of `merged_at`. `created_at` is used instead.
### `projects`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10904) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10904) in GitLab 12.4.
You can limit where the "issuables" can be queried from:
diff --git a/doc/user/project/integrations/discord_notifications.md b/doc/user/project/integrations/discord_notifications.md
index c9333b879f3..ad7719f0e5b 100644
--- a/doc/user/project/integrations/discord_notifications.md
+++ b/doc/user/project/integrations/discord_notifications.md
@@ -6,8 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Discord Notifications service **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/22684) in GitLab 11.6.
-
The Discord Notifications service sends event notifications from GitLab to the channel for which the webhook was created.
To send GitLab event notifications to a Discord channel, [create a webhook in Discord](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks)
@@ -17,10 +15,12 @@ and configure it in GitLab.
1. Open the Discord channel you want to receive GitLab event notifications.
1. From the channel menu, select **Edit channel**.
-1. Click on **Webhooks** menu item.
-1. Click the **Create Webhook** button and fill in the name of the bot to post the messages. Optionally, edit the avatar.
-1. Note the URL from the **WEBHOOK URL** field.
-1. Click the **Save** button.
+1. Select **Integrations**.
+1. If there are no existing webhooks, select **Create Webhook**. Otherwise, select **View Webhooks** then **New Webhook**.
+1. Enter the name of the bot to post the message.
+1. Optional. Edit the avatar.
+1. Copy the URL from the **WEBHOOK URL** field.
+1. Select **Save**.
## Configure created webhook in GitLab
diff --git a/doc/user/project/integrations/github.md b/doc/user/project/integrations/github.md
index 9f1ea3796c6..c07142d6edf 100644
--- a/doc/user/project/integrations/github.md
+++ b/doc/user/project/integrations/github.md
@@ -6,8 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitHub project integration **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3836) in GitLab 10.6.
-
You can update GitHub with pipeline status updates from GitLab.
This integration can help you if you use GitLab for CI/CD.
@@ -46,8 +44,7 @@ to configure pipelines to run for open pull requests.
### Static or dynamic status check names
-> - Introduced in GitLab 11.5 with static status check names as an opt-in option.
-> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/9931) in GitLab 12.4 to make static status check names the default behavior for new projects.
+> [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/9931) in GitLab 12.4 to make static status check names the default behavior for new projects.
A status check name can be static or dynamic:
diff --git a/doc/user/project/integrations/gitlab_slack_application.md b/doc/user/project/integrations/gitlab_slack_application.md
index 0d8ea636eba..0a685ad0efb 100644
--- a/doc/user/project/integrations/gitlab_slack_application.md
+++ b/doc/user/project/integrations/gitlab_slack_application.md
@@ -6,9 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitLab Slack application **(FREE SAAS)**
-> - Introduced in GitLab 9.4.
-> - Distributed to Slack App Directory in GitLab 10.2.
-
NOTE:
The GitLab Slack application is only configurable for GitLab.com. It will **not**
work for on-premises installations where you can configure the
diff --git a/doc/user/project/integrations/hangouts_chat.md b/doc/user/project/integrations/hangouts_chat.md
index 7a96bb74e3f..fbfa7d914a5 100644
--- a/doc/user/project/integrations/hangouts_chat.md
+++ b/doc/user/project/integrations/hangouts_chat.md
@@ -6,8 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Google Chat integration **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/43756) in GitLab 11.2.
-
Integrate your project to send notifications from GitLab to a
room of your choice in [Google Chat](https://chat.google.com/) (former Google
Hangouts).
diff --git a/doc/user/project/integrations/overview.md b/doc/user/project/integrations/overview.md
index 819c17c12fd..5b83df9b22e 100644
--- a/doc/user/project/integrations/overview.md
+++ b/doc/user/project/integrations/overview.md
@@ -51,7 +51,7 @@ Click on the service links to see further configuration instructions and details
| [Mattermost slash commands](mattermost_slash_commands.md) | Perform common tasks with slash commands. | **{dotted-circle}** No |
| [Microsoft Teams notifications](microsoft_teams.md) | Receive event notifications. | **{dotted-circle}** No |
| Packagist | Keep your PHP dependencies updated on Packagist. | **{check-circle}** Yes |
-| Pipelines emails | Send the pipeline status to a list of recipients by email. | **{dotted-circle}** No |
+| [Pipelines emails](pipeline_status_emails.md) | Send the pipeline status to a list of recipients by email. | **{dotted-circle}** No |
| [Pivotal Tracker](pivotal_tracker.md) | Add commit messages as comments to Pivotal Tracker stories. | **{dotted-circle}** No |
| [Prometheus](prometheus.md) | Monitor application metrics. | **{dotted-circle}** No |
| Pushover | Get real-time notifications on your device. | **{dotted-circle}** No |
diff --git a/doc/user/project/integrations/pipeline_status_emails.md b/doc/user/project/integrations/pipeline_status_emails.md
new file mode 100644
index 00000000000..742ab977090
--- /dev/null
+++ b/doc/user/project/integrations/pipeline_status_emails.md
@@ -0,0 +1,23 @@
+---
+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
+---
+
+# Pipeline status emails **(FREE)**
+
+You can send notifications about pipeline status changes in a group or
+project to a list of email addresses.
+
+## Enable pipeline status email notifications
+
+To enable pipeline status emails:
+
+1. In your project or group, on the left sidebar, select **Settings > Integrations**.
+1. Select **Pipeline status emails**.
+1. Ensure the **Active** checkbox is selected.
+1. In **Recipients**, enter a comma-separated list of email addresses.
+1. Optional. To receive notifications for broken pipelines only, select
+ **Notify only broken pipelines**.
+1. Select the branches to send notifications for.
+1. Select **Save changes**.
diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md
index 680f787c83c..de7ac6782d6 100644
--- a/doc/user/project/integrations/prometheus.md
+++ b/doc/user/project/integrations/prometheus.md
@@ -6,8 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Prometheus integration **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/8935) in GitLab 9.0.
-
GitLab offers powerful integration with [Prometheus](https://prometheus.io) for
monitoring key metrics of your apps, directly in GitLab.
Metrics for each environment are retrieved from Prometheus, and then displayed
@@ -41,10 +39,9 @@ See [Prometheus cluster integration](../../clusters/integrations.md#prometheus-c
Integration with Prometheus requires the following:
-1. GitLab 9.0 or higher
-1. Prometheus must be configured to collect one of the [supported metrics](prometheus_library/index.md)
-1. Each metric must be have a label to indicate the environment
-1. GitLab must have network connectivity to the Prometheus server
+- Prometheus must be configured to collect one of the [supported metrics](prometheus_library/index.md)
+- Each metric must have a label to indicate the environment
+- GitLab must have network connectivity to the Prometheus server
#### Getting started
@@ -113,9 +110,6 @@ can use only one:
## Determining the performance impact of a merge
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10408) in GitLab 9.2.
-> - GitLab 9.3 added the [numeric comparison](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/27439) of the 30 minute averages.
-
Developers can view the performance impact of their changes in the merge
request workflow. This feature requires [Kubernetes](prometheus_library/kubernetes.md) metrics.
diff --git a/doc/user/project/integrations/prometheus_library/cloudwatch.md b/doc/user/project/integrations/prometheus_library/cloudwatch.md
index b35ebacbd31..a07abf26fba 100644
--- a/doc/user/project/integrations/prometheus_library/cloudwatch.md
+++ b/doc/user/project/integrations/prometheus_library/cloudwatch.md
@@ -4,7 +4,13 @@ group: Monitor
info: 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
---
-# Monitoring AWS resources **(FREE)**
+# Monitoring AWS resources (DEPRECATED) **(FREE)**
+
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
GitLab supports automatically detecting and monitoring AWS resources, starting
with the [Elastic Load Balancer](https://aws.amazon.com/elasticloadbalancing/) (ELB).
diff --git a/doc/user/project/integrations/prometheus_library/haproxy.md b/doc/user/project/integrations/prometheus_library/haproxy.md
index 11b74c35a74..97f69d65412 100644
--- a/doc/user/project/integrations/prometheus_library/haproxy.md
+++ b/doc/user/project/integrations/prometheus_library/haproxy.md
@@ -4,9 +4,13 @@ group: Monitor
info: 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
---
-# Monitoring HAProxy **(FREE)**
+# Monitoring HAProxy (DEPRECATED) **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12621) in GitLab 9.4
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
GitLab has support for automatically detecting and monitoring HAProxy. This is provided by leveraging the [HAProxy Exporter](https://github.com/prometheus/haproxy_exporter), which translates HAProxy statistics into a Prometheus readable form.
diff --git a/doc/user/project/integrations/prometheus_library/index.md b/doc/user/project/integrations/prometheus_library/index.md
index fe74ea6834b..a5fc398e558 100644
--- a/doc/user/project/integrations/prometheus_library/index.md
+++ b/doc/user/project/integrations/prometheus_library/index.md
@@ -4,9 +4,13 @@ group: Monitor
info: 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
---
-# Prometheus Metrics library **(FREE)**
+# Prometheus Metrics library (DEPRECATED) **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/8935) in GitLab 9.0.
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
GitLab offers automatic detection of select [Prometheus exporters](https://prometheus.io/docs/instrumenting/exporters/).
diff --git a/doc/user/project/integrations/prometheus_library/kubernetes.md b/doc/user/project/integrations/prometheus_library/kubernetes.md
index 429df7f7e27..26d006adeb9 100644
--- a/doc/user/project/integrations/prometheus_library/kubernetes.md
+++ b/doc/user/project/integrations/prometheus_library/kubernetes.md
@@ -4,9 +4,13 @@ group: Monitor
info: 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
---
-# Monitoring Kubernetes **(FREE)**
+# Monitoring Kubernetes (DEPRECATED) **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/8935) in GitLab 9.0.
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
GitLab has support for automatically detecting and monitoring Kubernetes metrics.
@@ -44,8 +48,6 @@ Instead, the [Deployment](https://kubernetes.io/docs/concepts/workloads/controll
## Displaying Canary metrics **(PREMIUM)**
-> Introduced in [GitLab 10.2](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/15201).
-
GitLab also gathers Kubernetes metrics for [canary deployments](../../canary_deployments.md), allowing easy comparison between the current deployed version and the canary.
These metrics expect the [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) or [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) name to begin with `$CI_ENVIRONMENT_SLUG-canary`, to isolate the canary metrics.
diff --git a/doc/user/project/integrations/prometheus_library/nginx.md b/doc/user/project/integrations/prometheus_library/nginx.md
index 3f888a89b1b..ad89543e9a6 100644
--- a/doc/user/project/integrations/prometheus_library/nginx.md
+++ b/doc/user/project/integrations/prometheus_library/nginx.md
@@ -4,9 +4,13 @@ group: Monitor
info: 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
---
-# Monitoring NGINX **(FREE)**
+# Monitoring NGINX (DEPRECATED) **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12621) in GitLab 9.4
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
GitLab has support for automatically detecting and monitoring NGINX. This is provided by leveraging the [NGINX VTS exporter](https://github.com/hnlq715/nginx-vts-exporter), which translates [VTS statistics](https://github.com/vozlt/nginx-module-vts) into a Prometheus readable form.
diff --git a/doc/user/project/integrations/prometheus_library/nginx_ingress.md b/doc/user/project/integrations/prometheus_library/nginx_ingress.md
index 6478011b730..03bf9258659 100644
--- a/doc/user/project/integrations/prometheus_library/nginx_ingress.md
+++ b/doc/user/project/integrations/prometheus_library/nginx_ingress.md
@@ -4,9 +4,13 @@ group: Monitor
info: 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
---
-# Monitoring NGINX Ingress Controller **(FREE)**
+# Monitoring NGINX Ingress Controller (DEPRECATED) **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/22133) in GitLab 11.7.
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
GitLab has support for automatically detecting and monitoring the Kubernetes NGINX Ingress controller. This is provided by leveraging the built-in Prometheus metrics included with Kubernetes NGINX Ingress controller [version 0.16.0](https://github.com/kubernetes/ingress-nginx/blob/master/Changelog.md#0160) onward.
diff --git a/doc/user/project/integrations/prometheus_library/nginx_ingress_vts.md b/doc/user/project/integrations/prometheus_library/nginx_ingress_vts.md
index 6bdd2c64dcf..89c174f8fb9 100644
--- a/doc/user/project/integrations/prometheus_library/nginx_ingress_vts.md
+++ b/doc/user/project/integrations/prometheus_library/nginx_ingress_vts.md
@@ -4,9 +4,13 @@ group: Monitor
info: 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
---
-# Monitoring NGINX Ingress Controller with VTS metrics **(FREE)**
+# Monitoring NGINX Ingress Controller with VTS metrics (DEPRECATED) **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13438) in GitLab 9.5.
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
+for use in GitLab 14.7, and is planned for removal in GitLab 15.0.
NOTE:
[NGINX Ingress version 0.16](nginx_ingress.md) and above have built-in Prometheus metrics, which are different than the VTS based metrics.
diff --git a/doc/user/project/integrations/slack.md b/doc/user/project/integrations/slack.md
index 87f38c3482b..870554100b7 100644
--- a/doc/user/project/integrations/slack.md
+++ b/doc/user/project/integrations/slack.md
@@ -59,20 +59,20 @@ Your Slack team now starts receiving GitLab event notifications as configured.
The following triggers are available for Slack notifications:
-| Trigger name | Trigger event |
-| ------------------------ | ------------------------------------------------------ |
-| **Push** | A push to the repository. |
-| **Issue** | An issue is created, updated, or closed. |
-| **Confidential issue** | A confidential issue is created, updated, or closed. |
-| **Merge request** | A merge request is created, updated, or merged. |
-| **Note** | A comment is added. |
-| **Confidential note** | A confidential note is added. |
-| **Tag push** | A new tag is pushed to the repository. |
-| **Pipeline** | A pipeline status changed. |
-| **Wiki page** | A wiki page is created or updated. |
-| **Deployment** | A deployment starts or finishes. |
-| **Alert** | A new, unique alert is recorded. |
-| **Vulnerability** | **(ULTIMATE)** A new, unique vulnerability is recorded. |
+| Trigger name | Trigger event |
+|--------------------------------------------------------------------------|------------------------------------------------------|
+| **Push** | A push to the repository. |
+| **Issue** | An issue is created, updated, or closed. |
+| **Confidential issue** | A confidential issue is created, updated, or closed. |
+| **Merge request** | A merge request is created, updated, or merged. |
+| **Note** | A comment is added. |
+| **Confidential note** | A confidential note is added. |
+| **Tag push** | A new tag is pushed to the repository. |
+| **Pipeline** | A pipeline status changed. |
+| **Wiki page** | A wiki page is created or updated. |
+| **Deployment** | A deployment starts or finishes. |
+| **Alert** | A new, unique alert is recorded. |
+| [**Vulnerability**](../../application_security/vulnerabilities/index.md) | A new, unique vulnerability is recorded. |
## Troubleshooting
diff --git a/doc/user/project/integrations/webhooks.md b/doc/user/project/integrations/webhooks.md
index e0405955d3d..8bc2b51276a 100644
--- a/doc/user/project/integrations/webhooks.md
+++ b/doc/user/project/integrations/webhooks.md
@@ -21,11 +21,10 @@ you can use webhooks to:
every time an issue is created for a specific project or group in GitLab.
- [Automatically assign labels to merge requests](https://about.gitlab.com/blog/2016/08/19/applying-gitlab-labels-automatically/).
-You can configure your GitLab project or [group](#group-webhooks) to trigger
-a percent-encoded webhook URL when an event occurs. For example, when new code
-is pushed or a new issue is created.
-The webhook listens for specific [events](#events) and
-GitLab sends a POST request with data to the webhook URL.
+You can configure your GitLab project or [group](#group-webhooks) to trigger a
+[percent-encoded](https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding) webhook URL
+when an event occurs. For example, when new code is pushed or a new issue is created. The webhook
+listens for specific [events](#events) and GitLab sends a POST request with data to the webhook URL.
Usually, you set up your own [webhook receiver](#create-an-example-webhook-receiver)
to receive information from GitLab and send it to another app, according to your requirements.
@@ -55,7 +54,7 @@ You can configure a webhook for a group or a project.
1. In your project or group, on the left sidebar, select **Settings > Webhooks**.
1. In **URL**, enter the URL of the webhook endpoint.
- The URL must be percentage-encoded, if necessary.
+ The URL must be percent-encoded if it contains one or more special characters.
1. In **Secret token**, enter the [secret token](#validate-payloads-by-using-a-secret-token) to validate payloads.
1. In the **Trigger** section, select the [events](webhook_events.md) to trigger the webhook.
1. Optional. Clear the **Enable SSL verification** checkbox to disable [SSL verification](#verify-an-ssl-certificate).
@@ -135,8 +134,6 @@ in your GitLab projects.
## Filter push events by branch
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/20338) in GitLab 11.3.
-
Push events can be filtered by branch using a branch name or wildcard pattern
to limit which push events are sent to your webhook endpoint. By default,
all push events are sent to your webhook endpoint. You can configure branch filtering
@@ -159,8 +156,6 @@ GitLab webhooks, keep in mind the following:
## How image URLs are displayed in the webhook body
-> Introduced in GitLab 11.2.
-
Relative image references are rewritten to use an absolute URL
in the body of a webhook.
For example, if an image, merge request, comment, or wiki page includes the
diff --git a/doc/user/project/issues/img/issue_board.png b/doc/user/project/issues/img/issue_board.png
deleted file mode 100644
index dd40740aec5..00000000000
--- a/doc/user/project/issues/img/issue_board.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/issues/managing_issues.md b/doc/user/project/issues/managing_issues.md
index 1a23902514a..d120df82dbf 100644
--- a/doc/user/project/issues/managing_issues.md
+++ b/doc/user/project/issues/managing_issues.md
@@ -22,7 +22,7 @@ You can create an issue in many ways in GitLab:
- [From another issue](#from-another-issue)
- [From an issue board](#from-an-issue-board)
- [By sending an email](#by-sending-an-email)
-- Using a URL with prefilled fields
+- [Using a URL with prefilled values](#using-a-url-with-prefilled-values)
- [Using Service Desk](#using-service-desk)
### From a project
@@ -639,6 +639,9 @@ You can then see the issue's status in the issues list and the epic tree.
After an issue is closed, its health status can't be edited and the **Edit** button becomes disabled
until the issue is reopened.
+You can also set and clear health statuses using the `/health_status` and `/clear_health_status`
+[quick actions](../quick_actions.md#issues-merge-requests-and-epics).
+
## Publish an issue **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30906) in GitLab 13.1.
diff --git a/doc/user/project/labels.md b/doc/user/project/labels.md
index 8874512f9c3..7ccc39eeb8b 100644
--- a/doc/user/project/labels.md
+++ b/doc/user/project/labels.md
@@ -90,9 +90,10 @@ label section of the right sidebar of an issue or a merge request:
color value for a specific color.
1. Click **Create**.
-Once created, you can edit a label by clicking the pencil (**{pencil}**), or delete
-a label by clicking the three dots (**{ellipsis_v}**) next to the **Subscribe** button
-and selecting **Delete**.
+To edit a label after you create it, select (**{pencil}**).
+
+To delete a project label, select (**{ellipsis_v}**) next to the **Subscribe** button
+and select **Delete** or select **Delete** when you edit 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.
diff --git a/doc/user/project/members/index.md b/doc/user/project/members/index.md
index 283576fb4e9..2dc29f5d725 100644
--- a/doc/user/project/members/index.md
+++ b/doc/user/project/members/index.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -211,7 +211,7 @@ Instead of adding users one by one, you can [share a project with an entire grou
> - 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). **(FREE SELF)**
+> - 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.
diff --git a/doc/user/project/members/share_project_with_groups.md b/doc/user/project/members/share_project_with_groups.md
index 4c96c4d9f56..4e3bae2dc30 100644
--- a/doc/user/project/members/share_project_with_groups.md
+++ b/doc/user/project/members/share_project_with_groups.md
@@ -52,7 +52,7 @@ Administrators can share projects with any group in the system.
> - 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). **(FREE SELF)**
+> - 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.
diff --git a/doc/user/project/merge_requests/accessibility_testing.md b/doc/user/project/merge_requests/accessibility_testing.md
index 8f803f9207c..e67af8dc936 100644
--- a/doc/user/project/merge_requests/accessibility_testing.md
+++ b/doc/user/project/merge_requests/accessibility_testing.md
@@ -9,71 +9,69 @@ type: reference, howto
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25144) in GitLab 12.8.
-If your application offers a web interface and you are using
-[GitLab CI/CD](../../../ci/index.md), you can quickly determine the accessibility
+If your application offers a web interface, you can use
+[GitLab CI/CD](../../../ci/index.md) to determine the accessibility
impact of pending code changes.
-## Overview
-
-GitLab uses [pa11y](https://pa11y.org/), a free and open source tool for
-measuring the accessibility of web sites, and has built a simple
+[Pa11y](https://pa11y.org/) is a free and open source tool for
+measuring the accessibility of web sites. GitLab integrates Pa11y into a
[CI job template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Verify/Accessibility.gitlab-ci.yml).
-This job outputs accessibility violations, warnings, and notices for each page
-analyzed to a file called `accessibility`.
+The `a11y` job analyzes a defined set of web pages and reports
+accessibility violations, warnings, and notices in a file named
+`accessibility`.
-From [GitLab 14.5](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73309), the version of `pa11y` uses
-[WCAG 2.1 rules](https://www.w3.org/TR/WCAG21/#new-features-in-wcag-2-1), which may report more issues.
+As of [GitLab 14.5](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73309), Pa11y uses
+[WCAG 2.1 rules](https://www.w3.org/TR/WCAG21/#new-features-in-wcag-2-1).
## Accessibility merge request widget
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/39425) in GitLab 13.0 behind the disabled [feature flag](../../../administration/feature_flags.md) `:accessibility_report_view`.
> - [Feature Flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/217372) in GitLab 13.1.
-In addition to the report artifact that is created, GitLab will also show the
-Accessibility Report in the merge request widget area:
+GitLab displays an **Accessibility Report** in the merge request widget area:
![Accessibility merge request widget](img/accessibility_mr_widget_v13_0.png)
-## Configure Accessibility Testing
-
-This example shows how to run [pa11y](https://pa11y.org/)
-on your code with GitLab CI/CD using the [GitLab Accessibility Docker image](https://gitlab.com/gitlab-org/ci-cd/accessibility).
+## Configure accessibility testing
-For GitLab 12.9 and later, to define the `a11y` job, you must
-[include](../../../ci/yaml/index.md#includetemplate) the
-[`Accessibility.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Verify/Accessibility.gitlab-ci.yml)
-included with your GitLab installation, as shown below.
+You can run Pa11y with GitLab CI/CD using the
+[GitLab Accessibility Docker image](https://gitlab.com/gitlab-org/ci-cd/accessibility).
-Add the following to your `.gitlab-ci.yml` file:
+To define the `a11y` job for GitLab 12.9 and later:
-```yaml
-stages:
- - accessibility
+1. [Include](../../../ci/yaml/index.md#includetemplate) the
+ [`Accessibility.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Verify/Accessibility.gitlab-ci.yml)
+ from your GitLab installation.
+1. Add the following configuration to your `.gitlab-ci.yml` file.
-variables:
- a11y_urls: "https://about.gitlab.com https://gitlab.com/users/sign_in"
+ ```yaml
+ stages:
+ - accessibility
+
+ variables:
+ a11y_urls: "https://about.gitlab.com https://gitlab.com/users/sign_in"
+
+ include:
+ - template: "Verify/Accessibility.gitlab-ci.yml"
+ ```
-include:
- - template: "Verify/Accessibility.gitlab-ci.yml"
-```
+1. Customize the `a11y_urls` variable to list the URLs of the web pages to test with Pa11y.
-creates an `a11y` job in your CI/CD pipeline, runs
-Pa11y against the web pages defined in `a11y_urls`, and builds an HTML report for each.
+The `a11y` job in your CI/CD pipeline generates these files:
-The report for each URL is saved as an artifact that can be [viewed directly in your browser](../../../ci/pipelines/job_artifacts.md#download-job-artifacts).
+- One HTML report per URL listed in the `a11y_urls` variable.
+- One file containing the collected report data. In GitLab versions 12.11 and later, this
+ file is named `gl-accessibility.json`. In GitLab versions 12.10 and earlier, this file
+ is named [`accessibility.json`](https://gitlab.com/gitlab-org/ci-cd/accessibility/-/merge_requests/9).
-A single `gl-accessibility.json` artifact is created and saved along with the individual HTML reports.
-It includes report data for all URLs scanned.
-
-NOTE:
-For GitLab 12.10 and earlier, the [artifact generated is named `accessibility.json`](https://gitlab.com/gitlab-org/ci-cd/accessibility/-/merge_requests/9).
+You can [view job artifacts in your browser](../../../ci/pipelines/job_artifacts.md#download-job-artifacts).
NOTE:
-For GitLab versions earlier than 12.9, you can use `include:remote` and use a
+For GitLab versions earlier than 12.9, use `include:remote` and
link to the [current template in the default branch](https://gitlab.com/gitlab-org/gitlab/-/raw/master/lib/gitlab/ci/templates/Verify/Accessibility.gitlab-ci.yml)
NOTE:
-The job definition provided by the template does not support Kubernetes yet.
+The job definition provided by the template does not support Kubernetes.
-It is not yet possible to pass configurations into Pa11y via CI configuration. To change anything,
-copy the template to your CI file and make the desired edits.
+You cannot pass configurations into Pa11y via CI configuration.
+To change the configuration, edit a copy of the template in your CI file.
diff --git a/doc/user/project/merge_requests/allow_collaboration.md b/doc/user/project/merge_requests/allow_collaboration.md
index 5d1a04e1fe0..b10d6597c1e 100644
--- a/doc/user/project/merge_requests/allow_collaboration.md
+++ b/doc/user/project/merge_requests/allow_collaboration.md
@@ -2,77 +2,99 @@
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: reference, howto
---
-# Allow collaboration on merge requests across forks **(FREE)**
+# Collaborate on merge requests across forks **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17395) in GitLab 10.6.
+When you open a merge request from your fork, you can allow upstream
+members to collaborate with you on your branch.
+When you enable this option, members who have permission to merge to the target branch get
+permission to write to the merge request's source branch.
-When a user opens a merge request from a fork, they are given the option to allow
-upstream members to collaborate with them on the source branch. This allows
-the members of the upstream project to make small fixes or rebase branches
-before merging, reducing the back and forth of accepting external contributions.
+The members of the upstream project can then make small fixes or rebase branches
+before merging.
This feature is available for merge requests across forked projects that are
publicly accessible.
-When enabled for a merge request, members with merge access to the target
-branch of the project is granted write permissions to the source branch
-of the merge request.
+## Allow commits from upstream members
-## Enabling commit edits from upstream members
+> Enabled by default in [GitLab 13.7 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/23308).
-In [GitLab 13.7 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/23308),
-this setting is enabled by default. It can be changed by users with the
-Developer [role](../../permissions.md) for the source project. After it's enabled,
-upstream members can retry the pipelines and jobs of the merge request:
+As the author of a merge request, you can allow commit edits from
+upstream members of the project you're contributing to:
1. While creating or editing a merge request, scroll to **Contribution** and
- then select the **Allow commits from members who can merge to the target branch**.
+ select the **Allow commits from members who can merge to the target branch**
checkbox.
1. Finish creating your merge request.
-After you create the merge request, the merge request widget displays a message:
-**Members who can merge are allowed to add commits.**
+After you create the merge request, the merge request widget displays the message
+**Members who can merge are allowed to add commits**. Upstream members can then
+commit directly to your branch, as well as retry the pipelines and jobs of the
+merge request.
-## Pushing to the fork as the upstream member
+## Prevent commits from upstream members
-If the creator of the merge request has enabled contributions from upstream
-members, you can push directly to the branch of the forked repository.
+As the author of a merge request, you can prevent commit edits from
+upstream members of the project you're contributing to:
-Assuming that:
+1. While creating or editing a merge request, scroll to **Contribution** and
+ clear the **Allow commits from members who can merge to the target branch**
+ checkbox.
+1. Finish creating your merge request.
+
+## Push to the fork as the upstream member
-- The forked project URL is `git@gitlab.com:thedude/awesome-project.git`.
-- The branch of the merge request is `update-docs`.
+You can push directly to the branch of the forked repository if:
-To find and work with the changes from the fork:
+- The author of the merge request has enabled contributions from upstream
+ members.
+- You have at least the [Developer role](../../permissions.md) in the
+ upstream project.
+
+In the following example:
+
+- The forked repository URL is `git@gitlab.com:contributor/forked-project.git`.
+- The branch of the merge request is `fork-branch`.
+
+To change or add a commit to the contributor's merge request:
1. Open the merge request page, and select the **Overview** tab.
-1. Scroll to the merge request widget, and select **Check out branch**:
- ![Check out branch button](img/commit-button_v13_12.png)
-1. In the modal window, select **{copy-to-clipboard}** (**Copy**) for step 1
- to copy the `git fetch` and `git checkout` instructions to your clipboard.
- Paste the commands (which look like this example) into your terminal:
+1. Scroll to the merge request widget, and select **Check out branch**.
+1. In the modal window, select **Copy** (**{copy-to-clipboard}**).
+1. In your terminal, navigate to your cloned version of the repository, and
+ paste the commands. For example:
```shell
- git fetch git@gitlab.com:thedude/awesome-project.git update-docs
- git checkout -b thedude-awesome-project-update-docs FETCH_HEAD
+ git fetch "git@gitlab.com:contributor/forked-project.git" 'fork-branch'
+ git checkout -b contributor/fork-branch' FETCH_HEAD
```
- These commands fetch the branch from the forked project, and create a local branch
- based off the fetched branch.
+ Those commands fetch the branch from the forked project, and create a local branch
+ for you to work on.
+
+1. Make your changes to your local copy of the branch, and then commit them.
+1. Push your local changes to the forked project. The following command pushes
+ the local branch `contributor/fork-branch` to the `fork-branch` branch of
+ the `git@gitlab.com:contributor/forked-project.git` repository:
-1. Make your changes to the local copy of the branch, and then commit them.
-1. In your terminal, push your local changes back up to the forked project. This
- command pushes the local branch `thedude-awesome-project-update-docs` to the
- `update-docs` branch of the `git@gitlab.com:thedude/awesome-project.git` repository:
+ ```shell
+ git push git@gitlab.com:contributor/forked-project.git contributor/fork-branch:fork-branch
+ ```
+
+ If you have amended or squashed any commits, you must force push. Proceed
+ with caution as this command rewrites the commit history:
```shell
- git push git@gitlab.com:thedude/awesome-project.git thedude-awesome-project-update-docs:update-docs
+ git push --force git@gitlab.com:contributor/forked-project.git contributor/fork-branch:fork-branch
```
- Note the colon (`:`) between the two branches.
+ Note the colon (`:`) between the two branches. The general scheme is:
+
+ ```shell
+ git push <forked_repository_git_url> <local_branch>:<fork_branch>
+ ```
## Troubleshooting
@@ -89,14 +111,3 @@ going back to the original project:
1. Create a group containing all the upstream members.
1. Go to the **Project information > Members** page in the forked project and invite the newly-created
group to the forked project.
-
-<!-- ## Troubleshooting
-Include any troubleshooting steps that you can foresee. If you know beforehand what issues
-one might have when setting this up, or when something is changed, or on upgrading, it's
-important to describe those, too. Think of things that may go wrong and include them here.
-This is important to minimize requests for support, and to avoid doc comments with
-questions that you know someone might ask.
-
-Each scenario can be a third-level heading, e.g. `### Getting error message X`.
-If you have none to add when creating a doc, leave this section in place
-but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/user/project/merge_requests/approvals/rules.md b/doc/user/project/merge_requests/approvals/rules.md
index f4393b2b76d..129010010e7 100644
--- a/doc/user/project/merge_requests/approvals/rules.md
+++ b/doc/user/project/merge_requests/approvals/rules.md
@@ -1,8 +1,7 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, concepts
+info: 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
---
# Merge request approval rules **(PREMIUM)**
@@ -146,8 +145,7 @@ approve in these ways:
### Code owners as eligible approvers **(PREMIUM)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/7933) in GitLab 11.5.
-> - Moved to GitLab Premium in 13.9.
+> Moved to GitLab Premium in 13.9.
If you add [code owners](../../code_owners.md) to your repository, the owners of files
become eligible approvers in the project. To enable this merge request approval rule:
diff --git a/doc/user/project/merge_requests/approvals/settings.md b/doc/user/project/merge_requests/approvals/settings.md
index a6ca9423df0..1e1c8ccb241 100644
--- a/doc/user/project/merge_requests/approvals/settings.md
+++ b/doc/user/project/merge_requests/approvals/settings.md
@@ -1,8 +1,7 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, concepts
+info: 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
---
# Merge request approval settings **(PREMIUM)**
@@ -32,8 +31,7 @@ In this section of general settings, you can configure the following settings:
## Prevent approval by author
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3349) in GitLab 11.3.
-> - Moved to GitLab Premium in 13.9.
+> Moved to GitLab Premium in 13.9.
By default, the author of a merge request cannot approve it. To change this setting:
@@ -54,8 +52,7 @@ this setting, unless you configure one of these options:
## Prevent approvals by users who add commits
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10441) in GitLab 11.10.
-> - Moved to GitLab Premium in 13.9.
+> Moved to GitLab Premium in 13.9.
By default, users who commit to a merge request can still approve it. At both
the project level or [instance level](../../../admin_area/merge_requests_approvals.md)
diff --git a/doc/user/project/merge_requests/browser_performance_testing.md b/doc/user/project/merge_requests/browser_performance_testing.md
index e59456e5b34..6668e1736cf 100644
--- a/doc/user/project/merge_requests/browser_performance_testing.md
+++ b/doc/user/project/merge_requests/browser_performance_testing.md
@@ -63,7 +63,7 @@ on your code by using GitLab CI/CD and [sitespeed.io](https://www.sitespeed.io)
using Docker-in-Docker.
1. First, set up GitLab Runner with a
- [Docker-in-Docker build](../../../ci/docker/using_docker_build.md#use-the-docker-executor-with-the-docker-image-docker-in-docker).
+ [Docker-in-Docker build](../../../ci/docker/using_docker_build.md#use-docker-in-docker).
1. Configure the default Browser Performance Testing CI/CD job as follows in your `.gitlab-ci.yml` file:
```yaml
diff --git a/doc/user/project/merge_requests/code_quality.md b/doc/user/project/merge_requests/code_quality.md
index b791bce5749..30d463efa69 100644
--- a/doc/user/project/merge_requests/code_quality.md
+++ b/doc/user/project/merge_requests/code_quality.md
@@ -2,13 +2,11 @@
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/#assignments
-type: reference, howto
---
# Code Quality **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1984) in GitLab 9.3.
-> - Made [available in all tiers](https://gitlab.com/gitlab-org/gitlab/-/issues/212499) in 13.2.
+> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212499) to GitLab Free in 13.2.
To ensure your project's code stays simple, readable, and easy to contribute to,
you can use [GitLab CI/CD](../../../ci/index.md) to analyze your source code quality.
@@ -32,8 +30,7 @@ Code Quality:
## Code Quality Widget
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1984) in GitLab 9.3.
-> - Made [available in all tiers](https://gitlab.com/gitlab-org/gitlab/-/issues/212499) in 13.2.
+> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212499) to GitLab Free in 13.2.
Going a step further, GitLab can show the Code Quality report right
in the merge request widget area if a report from the target branch is available to compare to:
@@ -69,11 +66,8 @@ the merge request's diff view displays an indicator next to lines with new Code
## Example configuration
This example shows how to run Code Quality on your code by using GitLab CI/CD and Docker.
-It requires GitLab 11.11 or later, and GitLab Runner 11.5 or later. If you are using
-GitLab 11.4 or earlier, you can view the deprecated job definitions in the
-[documentation archive](https://docs.gitlab.com/12.10/ee/user/project/merge_requests/code_quality.html#previous-job-definitions).
-- Using shared runners, the job should be configured For the [Docker-in-Docker workflow](../../../ci/docker/using_docker_build.md#use-the-docker-executor-with-the-docker-image-docker-in-docker).
+- Using shared runners, the job should be configured For the [Docker-in-Docker workflow](../../../ci/docker/using_docker_build.md#use-docker-in-docker).
- Using private runners, there is an [alternative configuration](#set-up-a-private-runner-for-code-quality-without-docker-in-docker) recommended for running Code Quality analysis more efficiently.
In either configuration, the runner must have enough disk space to handle generated Code Quality files. For example on the [GitLab project](https://gitlab.com/gitlab-org/gitlab) the files are approximately 7 GB.
@@ -232,7 +226,7 @@ are configured with `privileged=true`, and they do not expose `docker.sock` into
the job container. As a result, socket binding cannot be used to make `docker` available
in the context of the job script.
-[Docker-in-Docker](../../../ci/docker/using_docker_build.md#use-the-docker-executor-with-the-docker-image-docker-in-docker)
+[Docker-in-Docker](../../../ci/docker/using_docker_build.md#use-docker-in-docker)
was chosen as an operational decision by the runner team, instead of exposing `docker.sock`.
### Disabling the code quality job
diff --git a/doc/user/project/merge_requests/commit_templates.md b/doc/user/project/merge_requests/commit_templates.md
index bffb66755e0..0cc18d2117b 100644
--- a/doc/user/project/merge_requests/commit_templates.md
+++ b/doc/user/project/merge_requests/commit_templates.md
@@ -67,6 +67,8 @@ GitLab creates a squash commit message with this template:
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20263) in GitLab 14.5.
> - [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.
Commit message templates support these variables:
@@ -80,8 +82,13 @@ Commit message templates support these variables:
| `%{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.` |
+| `%{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>` |
+| `%{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>` |
-Empty variables that are the only word in a line are removed, along with all newline characters preceding it.
+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.
## Related topics
diff --git a/doc/user/project/merge_requests/creating_merge_requests.md b/doc/user/project/merge_requests/creating_merge_requests.md
index 220049d9a88..6ee02238a22 100644
--- a/doc/user/project/merge_requests/creating_merge_requests.md
+++ b/doc/user/project/merge_requests/creating_merge_requests.md
@@ -2,7 +2,6 @@
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: howto
description: "How to create merge requests in GitLab."
disqus_identifier: 'https://docs.gitlab.com/ee/gitlab-basics/add-merge-request.html'
---
@@ -78,7 +77,7 @@ You can create a merge request by running Git commands on your local machine.
```plaintext
...
- remote: To create a merge request for docs-new-merge-request, visit:
+ remote: To create a merge request for my-new-branch, visit:
remote: https://gitlab.example.com/my-group/my-project/merge_requests/new?merge_request%5Bsource_branch%5D=my-new-branch
```
@@ -111,10 +110,6 @@ For more information, [see the forking workflow documentation](../repository/for
## By sending an email
-> The format of the generated email address changed in GitLab 11.7.
- The earlier format is still supported so existing aliases
- or contacts still work.
-
You can create a merge request by sending an email message to GitLab.
The merge request target branch is the project's default branch.
@@ -142,8 +137,6 @@ A merge request is created.
### Add attachments when creating a merge request by email
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/22723) in GitLab 11.5.
-
You can add commits to a merge request by adding
patches as attachments to the email. All attachments with a filename
ending in `.patch` are considered patches and are processed
diff --git a/doc/user/project/merge_requests/fail_fast_testing.md b/doc/user/project/merge_requests/fail_fast_testing.md
index 0d87a04461b..3cb50195f5a 100644
--- a/doc/user/project/merge_requests/fail_fast_testing.md
+++ b/doc/user/project/merge_requests/fail_fast_testing.md
@@ -42,7 +42,7 @@ This template requires:
- A project built in Rails that uses RSpec for testing.
- CI/CD configured to:
- Use a Docker image with Ruby available.
- - Use [Pipelines for merge requests](../../../ci/pipelines/merge_request_pipelines.md#configure-pipelines-for-merge-requests)
+ - Use [Pipelines for merge requests](../../../ci/pipelines/merge_request_pipelines.md#prerequisites)
- [Pipelines for Merged Results](../../../ci/pipelines/pipelines_for_merged_results.md#enable-pipelines-for-merged-results)
enabled in the project settings.
- A Docker image with Ruby available. The template uses `image: ruby:2.6` by default, but you [can override](../../../ci/yaml/includes.md#override-included-configuration-values) this.
diff --git a/doc/user/project/merge_requests/fast_forward_merge.md b/doc/user/project/merge_requests/fast_forward_merge.md
index 078f8048900..cd65fe20e66 100644
--- a/doc/user/project/merge_requests/fast_forward_merge.md
+++ b/doc/user/project/merge_requests/fast_forward_merge.md
@@ -38,9 +38,12 @@ Now, when you visit the merge request page, you can accept it
If a fast-forward merge is not possible but a conflict free rebase is possible,
a rebase button is offered.
+You can also rebase without running a CI/CD pipeline.
+[Introduced in](https://gitlab.com/gitlab-org/gitlab/-/issues/118825) GitLab 14.7.
+
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.png)
+![Fast forward merge request](img/ff_merge_rebase_v14_7.png)
If the target branch is ahead of the source branch and a conflict free rebase is
not possible, you need to rebase the
@@ -48,6 +51,13 @@ source branch locally before you can do a fast-forward merge.
![Fast forward merge rebase locally](img/ff_merge_rebase_locally.png)
+## Fast-forward merges prevent squashing commits
+
+If your project has enabled fast-forward merges, to merge cleanly, the code in a
+merge request cannot use [squashing during merge](squash_and_merge.md). Squashing
+is available only when accepting a merge request. Rebasing may be required before
+squashing, even though squashing can itself be considered equivalent to rebasing.
+
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
diff --git a/doc/user/project/merge_requests/getting_started.md b/doc/user/project/merge_requests/getting_started.md
index 323b7505190..ec509f58723 100644
--- a/doc/user/project/merge_requests/getting_started.md
+++ b/doc/user/project/merge_requests/getting_started.md
@@ -2,7 +2,6 @@
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: index, reference
description: "Getting started with merge requests."
---
@@ -92,8 +91,7 @@ and the merge request is added to their
#### Multiple assignees **(PREMIUM)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2004) in GitLab 11.11.
-> - Moved to GitLab Premium in 13.9
+> Moved to GitLab Premium in 13.9
Multiple people often review merge requests at the same time.
GitLab allows you to have multiple assignees for merge requests
@@ -207,7 +205,7 @@ This improvement is [tracked as a follow-up](https://gitlab.com/gitlab-org/gitla
- When working locally in your branch, add multiple commits and only push when
you're done, so GitLab runs only one pipeline for all the commits pushed
- at once. By doing so, you save pipeline minutes.
+ at once. By doing so, you save CI/CD minutes.
- Delete feature branches on merge or after merging them to keep your repository clean.
- Take one thing at a time and ship the smallest changes possible. By doing so,
reviews are faster and your changes are less prone to errors.
diff --git a/doc/user/project/merge_requests/img/commit-button_v13_12.png b/doc/user/project/merge_requests/img/commit-button_v13_12.png
deleted file mode 100644
index be154b9e60b..00000000000
--- a/doc/user/project/merge_requests/img/commit-button_v13_12.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/ff_merge_rebase.png b/doc/user/project/merge_requests/img/ff_merge_rebase.png
deleted file mode 100644
index f6139f189ce..00000000000
--- a/doc/user/project/merge_requests/img/ff_merge_rebase.png
+++ /dev/null
Binary files differ
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
new file mode 100644
index 00000000000..3c845d277e4
--- /dev/null
+++ b/doc/user/project/merge_requests/img/ff_merge_rebase_v14_7.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/squash_edit_form.png b/doc/user/project/merge_requests/img/squash_edit_form.png
deleted file mode 100644
index 326d74b68cb..00000000000
--- a/doc/user/project/merge_requests/img/squash_edit_form.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/squash_mr_commits.png b/doc/user/project/merge_requests/img/squash_mr_commits.png
deleted file mode 100644
index dfc1ee38435..00000000000
--- a/doc/user/project/merge_requests/img/squash_mr_commits.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/squash_mr_message.png b/doc/user/project/merge_requests/img/squash_mr_message.png
deleted file mode 100644
index 8c7dc7886f7..00000000000
--- a/doc/user/project/merge_requests/img/squash_mr_message.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/squash_mr_widget.png b/doc/user/project/merge_requests/img/squash_mr_widget.png
deleted file mode 100644
index 81334ca9758..00000000000
--- a/doc/user/project/merge_requests/img/squash_mr_widget.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/squash_squashed_commit.png b/doc/user/project/merge_requests/img/squash_squashed_commit.png
deleted file mode 100644
index 7def5339d8a..00000000000
--- a/doc/user/project/merge_requests/img/squash_squashed_commit.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 7b157aa94d8..40859c6b572 100644
--- a/doc/user/project/merge_requests/load_performance_testing.md
+++ b/doc/user/project/merge_requests/load_performance_testing.md
@@ -103,7 +103,7 @@ job.
An example configuration workflow:
1. Set up GitLab Runner to run Docker containers, like the
- [Docker-in-Docker workflow](../../../ci/docker/using_docker_build.md#use-the-docker-executor-with-the-docker-image-docker-in-docker).
+ [Docker-in-Docker workflow](../../../ci/docker/using_docker_build.md#use-docker-in-docker).
1. Configure the default Load Performance Testing CI/CD job in your `.gitlab-ci.yml` file.
You need to include the template and configure it with CI/CD variables:
diff --git a/doc/user/project/merge_requests/revert_changes.md b/doc/user/project/merge_requests/revert_changes.md
index e6fb619d365..6441ccb73fe 100644
--- a/doc/user/project/merge_requests/revert_changes.md
+++ b/doc/user/project/merge_requests/revert_changes.md
@@ -2,7 +2,6 @@
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: reference, concepts
---
# Revert changes **(FREE)**
@@ -13,11 +12,6 @@ by clicking the **Revert** button in merge requests and commit details.
## Revert a merge request
NOTE:
-The **Revert** button is available only for merge requests
-created in GitLab 8.5 and later. However, you can still revert a merge request
-by reverting the merge commit from the list of Commits page.
-
-NOTE:
The **Revert** button is shown only for projects that use the
merge method "Merge Commit", which can be set under the project's
**Settings > General > Merge request**. [Fast-forward commits](fast_forward_merge.md)
diff --git a/doc/user/project/merge_requests/reviews/img/suggestions_custom_commit_messages_v13_1.jpg b/doc/user/project/merge_requests/reviews/img/suggestions_custom_commit_messages_v13_1.jpg
deleted file mode 100644
index a4c9df0ebb9..00000000000
--- a/doc/user/project/merge_requests/reviews/img/suggestions_custom_commit_messages_v13_1.jpg
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/reviews/img/suggestions_custom_commit_messages_v14_7.png b/doc/user/project/merge_requests/reviews/img/suggestions_custom_commit_messages_v14_7.png
new file mode 100644
index 00000000000..2805ef19f2d
--- /dev/null
+++ b/doc/user/project/merge_requests/reviews/img/suggestions_custom_commit_messages_v14_7.png
Binary files differ
diff --git a/doc/user/project/merge_requests/reviews/suggestions.md b/doc/user/project/merge_requests/reviews/suggestions.md
index c25b9e15974..1b2a35ba139 100644
--- a/doc/user/project/merge_requests/reviews/suggestions.md
+++ b/doc/user/project/merge_requests/reviews/suggestions.md
@@ -89,7 +89,7 @@ These commit messages can be customized to follow any guidelines you might have.
To do so, expand the **Merge requests** tab within your project's **General**
settings and change the **Merge suggestions** text:
-![Custom commit message for applied suggestions](img/suggestions_custom_commit_messages_v13_1.jpg)
+![Custom commit message for applied suggestions](img/suggestions_custom_commit_messages_v14_7.png)
You can also use following variables besides static text:
diff --git a/doc/user/project/merge_requests/squash_and_merge.md b/doc/user/project/merge_requests/squash_and_merge.md
index 3fe82fb8ef3..f90296e9626 100644
--- a/doc/user/project/merge_requests/squash_and_merge.md
+++ b/doc/user/project/merge_requests/squash_and_merge.md
@@ -2,131 +2,79 @@
stage: Create
group: Source Code
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: reference, concepts
---
# Squash and merge **(FREE)**
-> - [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/18956) from GitLab Premium to GitLab Free in 11.0.
+As you work on a feature branch, you often create small, self-contained commits. These small commits
+help describe the process of building a feature, but can clutter your Git history after the feature
+is finished. As you finish features, you can combine these commits and ensure a cleaner merge history
+in your Git repository by using the _squash and merge_ strategy.
-With squash and merge you can combine all your merge request's commits into one
-and retain a clean history.
+- Small commits are joined together, making it simpler to [revert all parts of a change](revert_changes.md).
+- When the single commit merges into the target branch, it retains the full commit history.
+- Your base branch remains clean, and contains meaningful commit messages.
-Squashing lets you tidy up the commit history of a branch when accepting a merge
-request. It applies all of the changes in the merge request as a single commit,
-and then merges that commit using the merge method set for the project.
+Each time a branch merges into your base branch, up to two commits are added:
-In other words, squashing a merge request turns a long list of commits:
+- The single commit created by squashing the commits from the branch.
+- A merge commit, unless you have [enabled fast-forward merges](fast_forward_merge.md#enabling-fast-forward-merges)
+ in your project. Fast-forward merges disable both merge commits and squashing.
-![List of commits from a merge request](img/squash_mr_commits.png)
+By default, squashed commits contain the following metadata:
-Into a single commit on merge:
+- Message: Description of the squash commit, or a customized message
+- Author: User that created the merge request
+- Committer: User who initiated the squash
-![A squashed commit followed by a merge commit](img/squash_squashed_commit.png)
+Project owners can [create new default messages](commit_templates.md) for all
+squash commits and merge commits.
-NOTE:
-The squashed commit in this example is followed by a merge commit, because the merge method for this repository uses a merge commit. You can disable merge commits in
-**Project Settings > General > Merge requests > Merge method > Fast-forward merge**.
+## Set default squash options for a merge request
-The squashed commit's default commit message is taken from the merge request title.
-You can [edit the default message for squash commits](commit_templates.md).
+Users with permission to create or edit a merge request can set the default squash options
+for a merge request. To do this:
-It can also be customized before merging a merge request.
+1. Go to the merge request and select **Edit**.
+1. Select or clear the **Squash commits when merge request is accepted** checkbox.
+1. Select **Save changes**.
-![A squash commit message editor](img/squash_mr_message.png)
+## Squash commits in a merge request
-Squashing also works with the fast-forward merge strategy, see [squashing and fast-forward merge](#squash-and-fast-forward-merge) for more details.
+If your project allows you to select squashing options for merge requests, to
+squash the commits as part of the merge process:
-## Use cases
+1. Go to the merge request, and scroll to the merge request reports section that
+ contains the **Merge** button.
+1. Ensure the **Squash commits** checkbox is selected. This checkbox doesn't display
+ if the project's squashing option is set to either **Do not allow** or **Require**.
+1. Optional. To modify either the squash commit message or the merge commit message
+ (depending on your project configuration), select **Modify commit messages**.
+1. When the merge request is ready to merge, select **Merge**.
-When working on a feature branch, you sometimes want to commit your current
-progress, but don't really care about the commit messages. Those 'work in
-progress commits' don't necessarily contain important information and as such
-you'd rather not include them in your target branch.
+## Configure squash options for a project
-With squash and merge, when the merge request is ready to be merged,
-all you have to do is enable squashing before you press merge to join
-the commits in the merge request into a single commit.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/17613) in GitLab 13.2 [with a flag](../../../administration/feature_flags.md) named `squash_options`, disabled by default.
+> - [Enabled on GitLab.com and self-managed by default](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39382) in GitLab 13.3.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/232536) in GitLab 13.8. Feature flag `squash_options` removed.
-This way, the history of your base branch remains clean with
-meaningful commit messages and:
+To configure the default squashing behavior for all merge requests in your project:
-- It's simpler to [revert](revert_changes.md) if necessary.
-- The merged branch retains the full commit history.
-
-## Enable squash for a merge request
-
-Anyone who can create or edit a merge request can choose for it to be squashed
-on the merge request form. Users can select or clear the checkbox when they
-create the merge request:
-
-![Squash commits checkbox on edit form](img/squash_edit_form.png)
-
-After the merge request is submitted, Squash and Merge can still be enabled or disabled
-by editing the merge request description:
-
-1. Scroll to the top of the merge request page and click **Edit**.
-1. Scroll down to the end of the merge request form and select the checkbox
-**Squash commits when merge request is accepted**.
-
-This setting can then be overridden at the time of accepting the merge request.
-At the end of the merge request widget, next to the **Merge** button, the **Squash commits** checkbox
-can be either selected or unselected:
-
-![Squash commits checkbox on accept merge request form](img/squash_mr_widget.png)
-
-Note that Squash and Merge might not be available depending on the project's configuration
-for [Squash Commit Options](#squash-commits-options).
-
-## Commit metadata for squashed commits
-
-The squashed commit has the following metadata:
-
-- Message: the message of the squash commit, or a customized message.
-- Author: the author of the merge request.
-- Committer: the user who initiated the squash.
-
-## Squash and fast-forward merge
-
-When a project has the [fast-forward merge setting enabled](fast_forward_merge.md#enabling-fast-forward-merges), the merge
-request must be able to be fast-forwarded without squashing in order to squash
-it. This is because squashing is only available when accepting a merge request,
-so a merge request may need to be rebased before squashing, even though
-squashing can itself be considered equivalent to rebasing.
-
-## Squash commits options
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/17613) in GitLab 13.2.
-> - Deployed behind a feature flag, disabled by default.
-> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39382) in GitLab 13.3.
-> - Enabled on GitLab.com.
-> - Can be enabled per project.
-> - Recommended for production use.
-
-With Squash Commits Options you can configure the behavior of Squash and Merge for your project.
-To set it up, navigate to your project's **Settings > General** and expand **Merge requests**.
-You can choose from these options, which affect existing and new merge requests
-submitted to your project:
-
-- **Do not allow**: users cannot use Squash and Merge to squash all the commits immediately before
- merging. The checkbox to enable or disable it is unchecked and hidden from the users.
-- **Allow**: users can enable Squash and Merge on a merge request basis.
- The checkbox is unchecked (disabled) by default, but and the user is allowed to enable it.
-- **Encourage**: users can enable Squash and Merge on a merge request basis.
- The checkbox is checked (enabled) by default to encourage its use, but the user is allowed to
- disable it.
-- **Require**: Squash and Merge is enabled for all merge requests, so it is always performed.
- The checkbox to enable or disable it is checked and hidden from the users.
-
-The Squash and Merge checkbox is displayed when you create a merge request and when you edit the description of an existing one, except when Squash Commit Options is set to **Do not allow** or **Require**.
-
-NOTE:
-If your project is set to **Do not allow** Squash and Merge, the users still have the option to
-squash commits locally through the command line and force-push to their remote branch before merging.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Settings > General**.
+1. Expand **Merge requests**.
+1. In the **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.
+ - **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.
+1. Select **Save changes**.
## Related topics
-- [Commit message templates](commit_templates.md).
+- [Commit message templates](commit_templates.md)
+- [Fast-forward merges](fast_forward_merge.md)
<!-- ## Troubleshooting
diff --git a/doc/user/project/merge_requests/versions.md b/doc/user/project/merge_requests/versions.md
index 796ffc7866c..236ec64a4dc 100644
--- a/doc/user/project/merge_requests/versions.md
+++ b/doc/user/project/merge_requests/versions.md
@@ -39,8 +39,6 @@ changes appears as a system note.
## Find the merge request that introduced a change
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/2383) in GitLab 10.5.
-
When viewing the commit details page, GitLab links to the merge request (or
merge requests, if it's in more than one) containing that commit.
diff --git a/doc/user/project/pages/getting_started/pages_new_project_template.md b/doc/user/project/pages/getting_started/pages_new_project_template.md
index f52f64626ac..cee10675a62 100644
--- a/doc/user/project/pages/getting_started/pages_new_project_template.md
+++ b/doc/user/project/pages/getting_started/pages_new_project_template.md
@@ -1,5 +1,4 @@
---
-type: reference, howto
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
@@ -7,8 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Create a Pages website from a template **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/47857) in GitLab 11.8.
-
GitLab provides templates for the most popular Static Site Generators (SSGs).
You can create a new project from a template and run the CI/CD pipeline to generate a Pages website.
diff --git a/doc/user/project/pages/img/icons/lock.png b/doc/user/project/pages/img/icons/lock.png
deleted file mode 100644
index f7f32fded45..00000000000
--- a/doc/user/project/pages/img/icons/lock.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/pages/introduction.md b/doc/user/project/pages/introduction.md
index 59a2f0c2eba..10fbc57fa0b 100644
--- a/doc/user/project/pages/introduction.md
+++ b/doc/user/project/pages/introduction.md
@@ -214,8 +214,6 @@ needing to compress files on-demand.
### Resolving ambiguous URLs
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/95) in GitLab 11.8
-
GitLab Pages makes assumptions about which files to serve when receiving a
request for a URL that does not include an extension.
diff --git a/doc/user/project/pages/pages_access_control.md b/doc/user/project/pages/pages_access_control.md
index 4b4d479e3e9..002b234f561 100644
--- a/doc/user/project/pages/pages_access_control.md
+++ b/doc/user/project/pages/pages_access_control.md
@@ -1,5 +1,4 @@
---
-type: reference, howto
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
@@ -7,8 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitLab Pages access control **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/33422) in GitLab 11.5.
-> - Available on GitLab.com in GitLab 12.4.
+> Available on GitLab.com in GitLab 12.4.
You can enable Pages access control on your project
if your administrator has [enabled the access control feature](../../../administration/pages/index.md#access-control)
diff --git a/doc/user/project/protected_branches.md b/doc/user/project/protected_branches.md
index a4e94c03e86..6c18fc158f5 100644
--- a/doc/user/project/protected_branches.md
+++ b/doc/user/project/protected_branches.md
@@ -1,8 +1,7 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, howto
+info: 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
---
# Protected branches **(FREE)**
@@ -76,8 +75,6 @@ The protected branch displays in the list of protected branches.
## Create a protected branch
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53361) in GitLab 11.9.
-
Users with the Developer or higher [role](../permissions.md) can create a protected branch.
Prerequisites:
diff --git a/doc/user/project/protected_tags.md b/doc/user/project/protected_tags.md
index b4e13aebdb2..e4743c82a3b 100644
--- a/doc/user/project/protected_tags.md
+++ b/doc/user/project/protected_tags.md
@@ -1,14 +1,11 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, howto
+info: 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
---
# Protected tags **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10356) in GitLab 9.1.
-
Protected tags:
- Allow control over who has permission to create tags.
diff --git a/doc/user/project/push_options.md b/doc/user/project/push_options.md
index 15df69ee68c..846d4732533 100644
--- a/doc/user/project/push_options.md
+++ b/doc/user/project/push_options.md
@@ -1,14 +1,11 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, howto
+info: 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
---
# Push Options **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/15643) in GitLab 11.7.
-
GitLab supports using client-side [Git push options](https://git-scm.com/docs/git-push#Documentation/git-push.txt--oltoptiongt)
to perform various actions at the same time as pushing changes. Additionally, [Push Rules](../../push_rules/push_rules.md) offer server-side control and enforcement options.
diff --git a/doc/user/project/quick_actions.md b/doc/user/project/quick_actions.md
index 75a5a2a6a4f..21a080de404 100644
--- a/doc/user/project/quick_actions.md
+++ b/doc/user/project/quick_actions.md
@@ -47,76 +47,78 @@ threads. Some quick actions might not be available to all subscription tiers.
<!-- Keep this table sorted alphabetically -->
-| Command | Issue | Merge request | Epic | Action |
-|:--------------------------------------|:-----------------------|:-----------------------|:-----------------------|:-------|
-| `/add_contacts email1 email2` | **{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)). |
-| `/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_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. |
-| `/confidential` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Make confidential. |
-| `/copy_metadata <!merge_request>` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Copy labels and milestone from another merge request in the project. |
-| `/copy_metadata <#issue>` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Copy labels and milestone from another issue in the project. |
-| `/create_merge_request <branch name>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Create a new merge request starting from the current issue. |
-| `/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. |
-| `/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). |
-| `/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)). |
-| `/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. |
-| `/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)). |
-| `/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)) |
-| `/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 email1 email2` | **{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_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_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_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)). |
-| `/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). |
-| `/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)). |
-| `/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)|
-| `/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. |
-| `/unassign_reviewer` or `/remove_reviewer` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Remove all reviewers. |
-| `/unlabel ~label1 ~label2` or `/remove_label ~label1 ~label2` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Remove specified labels. |
-| `/unlabel` or `/remove_label` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Remove all labels. |
-| `/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)). |
+| Command | Issue | Merge request | Epic | Action |
+|:-------------------------------------------------------------------------------------------------|:-----------------------|:-----------------------|:-----------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `/add_contacts email1 email2` | **{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)). |
+| `/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)). |
+| `/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. |
+| `/confidential` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Make confidential. |
+| `/copy_metadata <!merge_request>` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Copy labels and milestone from another merge request in the project. |
+| `/copy_metadata <#issue>` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Copy labels and milestone from another issue in the project. |
+| `/create_merge_request <branch name>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Create a new merge request starting from the current issue. |
+| `/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. |
+| `/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)). |
+| `/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)). |
+| `/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. |
+| `/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)). |
+| `/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)) |
+| `/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 email1 email2` | **{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_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_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_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)). |
+| `/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). |
+| `/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)). |
+| `/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) |
+| `/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. |
+| `/unassign_reviewer` or `/remove_reviewer` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Remove all reviewers. |
+| `/unlabel ~label1 ~label2` or `/remove_label ~label1 ~label2` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Remove specified labels. |
+| `/unlabel` or `/remove_label` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Remove all labels. |
+| `/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)). |
## Commit messages
diff --git a/doc/user/project/releases/img/feature_count_v14_6.png b/doc/user/project/releases/img/feature_count_v14_6.png
index 0b1a0552631..f254ff4c78a 100644
--- a/doc/user/project/releases/img/feature_count_v14_6.png
+++ b/doc/user/project/releases/img/feature_count_v14_6.png
Binary files differ
diff --git a/doc/user/project/releases/index.md b/doc/user/project/releases/index.md
index 239e6c9cea8..747b41d07f2 100644
--- a/doc/user/project/releases/index.md
+++ b/doc/user/project/releases/index.md
@@ -6,8 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Releases **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41766) in GitLab 11.7.
-
In GitLab, a release enables you to create a snapshot of your project for your users, including
installation packages and release notes. You can create a GitLab release on any branch. Creating a
release also creates a [Git tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging) to mark the
@@ -134,6 +132,10 @@ release creation, the release job fails.
To create a release when you push a Git tag, or when you add a Git tag
in the UI by going to **Repository > Tags**:
+NOTE:
+Do not provide **Release notes** when you create the Git tag in the UI.
+Providing release notes creates a release, resulting in the pipeline failing.
+
```yaml
release_job:
stage: release
@@ -829,3 +831,7 @@ Make sure that the user or a service/bot account is allowed to
[create the protected tag](../protected_tags.md#configuring-protected-tags) too.
See [the release permissions](#release-permissions) for more information.
+
+### Note about storage
+
+Note that the feature is built on top of Git tags, so virtually no extra data is needed besides to create the release itself. Additional assets and the release evidence that is automatically generated consume storage.
diff --git a/doc/user/project/repository/gpg_signed_commits/index.md b/doc/user/project/repository/gpg_signed_commits/index.md
index 27767f8d325..0c5c0d5fa7c 100644
--- a/doc/user/project/repository/gpg_signed_commits/index.md
+++ b/doc/user/project/repository/gpg_signed_commits/index.md
@@ -1,15 +1,11 @@
---
stage: Create
group: Source Code
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: concepts, howto
+info: 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
---
# Signing commits with GPG **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/9546) in GitLab 9.5.
-> - Subkeys support was added in GitLab 10.1.
-
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
diff --git a/doc/user/project/repository/index.md b/doc/user/project/repository/index.md
index 54e9470892c..6ece6e3e4e0 100644
--- a/doc/user/project/repository/index.md
+++ b/doc/user/project/repository/index.md
@@ -2,7 +2,6 @@
stage: Create
group: Source Code
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: concepts, howto
---
# Repository **(FREE)**
@@ -66,8 +65,6 @@ Alternatively, you can clone directly into a code editor.
### Clone and open in Apple Xcode
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/45820) in GitLab 11.0.
-
Projects that contain a `.xcodeproj` or `.xcworkspace` directory can be cloned
into Xcode on macOS.
@@ -98,8 +95,7 @@ Visual Studio Code:
## Download the code in a repository
-> - Support for directory download was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/24704) in GitLab 11.11.
-> - Support for [including Git LFS blobs](../../../topics/git/lfs#lfs-objects-in-project-archives) was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15079) in GitLab 13.5.
+> Support for [including Git LFS blobs](../../../topics/git/lfs#lfs-objects-in-project-archives) was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15079) in GitLab 13.5.
You can download the source code that's stored in a repository.
diff --git a/doc/user/project/repository/jupyter_notebooks/index.md b/doc/user/project/repository/jupyter_notebooks/index.md
index d040cc93876..5646f478d9f 100644
--- a/doc/user/project/repository/jupyter_notebooks/index.md
+++ b/doc/user/project/repository/jupyter_notebooks/index.md
@@ -25,10 +25,10 @@ GitLab.
## Cleaner diffs
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/epics/6589) in GitLab 14.5 [with a flag](../../../../administration/feature_flags.md) named `jupyter_clean_diffs`. Disabled by default.
+> [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 not available. To make it available, ask an administrator to [enable the feature flag](../../../../administration/feature_flags.md) named `jupyter_clean_diffs`.
+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.
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 361c0902ebf..c8950d39f28 100644
--- a/doc/user/project/repository/mirror/index.md
+++ b/doc/user/project/repository/mirror/index.md
@@ -213,7 +213,7 @@ used in commits. To fix this problem, either:
### Deadline Exceeded
-When upgrading to GitLab 11.11.8 or later, a change in how usernames are represented means that you
+When upgrading GitLab, a change in how usernames are represented means that you
must update your mirroring username and password to ensure that `%40` characters are replaced with `@`.
### Connection blocked because server only allows public key authentication
diff --git a/doc/user/project/repository/mirror/push.md b/doc/user/project/repository/mirror/push.md
index 498b8d063a9..221616bd41c 100644
--- a/doc/user/project/repository/mirror/push.md
+++ b/doc/user/project/repository/mirror/push.md
@@ -79,7 +79,7 @@ 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)
with `public_repo` selected.
1. Enter a **Git repository URL** with this format:
- `https://<your_github_username>@github.com/<your_github_group>/<your_github_project>.git`.
+ `https://<your_access_token>@github.com/<github_group>/<github_project>.git`.
1. For **Password**, enter your GitHub personal access token.
1. Select **Mirror repository**.
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 0094e0b1b15..23cead7e8a7 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
@@ -127,7 +127,8 @@ To purge files from a GitLab repository:
Refer to the Git [`replace`](https://git-scm.com/book/en/v2/Git-Tools-Replace) documentation for information on how this works.
-1. Run a [repository cleanup](#repository-cleanup).
+1. Wait at least 30 minutes, because the repository cleanup process only processes object older than 30 minutes.
+1. Run [repository cleanup](#repository-cleanup).
## Repository cleanup
diff --git a/doc/user/project/repository/web_editor.md b/doc/user/project/repository/web_editor.md
index ba105a970a7..4165c1828cc 100644
--- a/doc/user/project/repository/web_editor.md
+++ b/doc/user/project/repository/web_editor.md
@@ -2,7 +2,6 @@
stage: Create
group: Editor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: howto
---
# GitLab Web Editor **(FREE)**
@@ -118,8 +117,6 @@ There are multiple ways to create a branch from the GitLab web interface.
### Create a new branch from an issue
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/2808) in GitLab 8.6.
-
If your development workflow requires an issue for every merge
request, you can create a branch directly from the issue to speed the process up.
The new branch, and later its merge request, are marked as related to this issue.
diff --git a/doc/user/project/requirements/index.md b/doc/user/project/requirements/index.md
index 294e493dfe9..5fe0e0ef3a2 100644
--- a/doc/user/project/requirements/index.md
+++ b/doc/user/project/requirements/index.md
@@ -17,10 +17,6 @@ In 14.4, Requirements was moved under **Issues**.
With requirements, you can set criteria to check your products against. They can be based on users,
stakeholders, system, software, or anything else you find important to capture.
-INFO:
-Meet your compliance needs with requirements in GitLab.
-[Try Ultimate free for 30 days](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=u-project-requirements-docs).
-
A requirement is an artifact in GitLab which describes the specific behavior of your product.
Requirements are long-lived and don't disappear unless manually cleared.
diff --git a/doc/user/project/service_desk.md b/doc/user/project/service_desk.md
index 072d685bde4..1b30f14ac90 100644
--- a/doc/user/project/service_desk.md
+++ b/doc/user/project/service_desk.md
@@ -184,9 +184,10 @@ NOTE:
On GitLab.com a custom mailbox is already configured with `contact-project+%{key}@incoming.gitlab.com` as the email address, you can still configure the
[custom suffix](#configuring-a-custom-email-address-suffix) in project settings.
-Using the `service_desk_email` configuration, 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)
+Service Desk uses the [incoming email](../../administration/incoming_email.md)
+configuration by default. However, by using the `service_desk_email` configuration,
+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'
@@ -194,10 +195,10 @@ portion of the address, before the `@`. This is used to identify the project
where the issue should be created.
NOTE:
-The `service_desk_email` and `incoming_email` configurations should
-always use separate mailboxes. This is important, because emails picked from
-`service_desk_email` mailbox are processed by a different worker and it would
-not recognize `incoming_email` emails.
+When configuring a custom mailbox, the `service_desk_email` and `incoming_email`
+configurations must always use separate mailboxes. This is important, because
+emails picked from `service_desk_email` mailbox are processed by a different
+worker and it would not recognize `incoming_email` emails.
To configure a custom mailbox for Service Desk with IMAP, add the following snippets to your configuration file in full:
diff --git a/doc/user/project/settings/img/import_export_download_export.png b/doc/user/project/settings/img/import_export_download_export.png
deleted file mode 100644
index 62292e99e8e..00000000000
--- a/doc/user/project/settings/img/import_export_download_export.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/settings/img/import_export_export_button.png b/doc/user/project/settings/img/import_export_export_button.png
deleted file mode 100644
index 6f3663d64e8..00000000000
--- a/doc/user/project/settings/img/import_export_export_button.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/settings/img/import_export_mail_link.png b/doc/user/project/settings/img/import_export_mail_link.png
deleted file mode 100644
index 1bd9a071178..00000000000
--- a/doc/user/project/settings/img/import_export_mail_link.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/settings/img/import_export_new_project.png b/doc/user/project/settings/img/import_export_new_project.png
deleted file mode 100644
index 0e2365ecb68..00000000000
--- a/doc/user/project/settings/img/import_export_new_project.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/settings/img/import_export_select_file.png b/doc/user/project/settings/img/import_export_select_file.png
deleted file mode 100644
index 90a3e8d5c4e..00000000000
--- a/doc/user/project/settings/img/import_export_select_file.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/settings/import_export.md b/doc/user/project/settings/import_export.md
index da0336d01ff..06bdf4ca14b 100644
--- a/doc/user/project/settings/import_export.md
+++ b/doc/user/project/settings/import_export.md
@@ -6,129 +6,69 @@ info: "To determine the technical writer assigned to the Stage/Group associated
# Project import/export **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/3050) in GitLab 8.9.
-> - From GitLab 10.0, administrators can disable the project export option on the GitLab instance.
+Existing projects on any self-managed GitLab instance or GitLab.com can be exported to a file and
+then imported into a new GitLab instance.
-Existing projects running on any GitLab instance or GitLab.com can be exported with all their related
-data and be moved into a new GitLab instance.
+## Set up project import/export
-The **GitLab import/export** button is displayed if the project import option is enabled.
+Before you can import or export a project and its data, you must set it up.
-See also:
+1. On the left sidebar, select **Settings > General**.
+1. Expand **Visibility and access controls**.
+1. Scroll to **Import sources**.
+1. Enable the desired **Import sources**.
-- [Project import/export API](../../../api/project_import_export.md)
-- [Project import/export administration Rake tasks](../../../administration/raketasks/project_import_export.md) **(FREE SELF)**
-- [Group import/export](../../group/settings/import_export.md)
-- [Group import/export API](../../../api/group_import_export.md)
-
-To set up a project import/export:
-
- 1. On the top bar, go to **Menu > Admin > Settings > General > Visibility and access controls**.
- 1. Scroll to **Import sources**.
- 1. Enable the desired **Import sources**.
-
-## Important notes
-
-Note the following:
-
-- Before you can import a project, you must export the data first.
- See [Export a project and its data](#export-a-project-and-its-data)
- for how you can export a project through the UI.
-- Imports from a newer version of GitLab are not supported.
- The Importing GitLab version must be greater than or equal to the Exporting GitLab version.
-- Imports fail unless the import and export GitLab instances are
- compatible as described in the [Version history](#version-history).
-- Exports are generated in your configured `shared_path`, a temporary shared directory,
- and are moved to your configured `uploads_directory`. Every 24 hours, a specific worker deletes these export files.
-- Group members are exported as project members, as long as the user has
- a maintainer or administrator role in the group where the exported project lives.
-- Project members with the [Owner role](../../permissions.md) are imported as Maintainers.
-- Imported users can be mapped by their public email on self-managed instances, if an administrative user (not an owner) does the import.
- The public email is not set by default. Users must [set it in their profiles](../../profile/index.md#set-your-public-email)
- for mapping to work correctly. Additionally, the user must be an existing member of the namespace,
- or the user can be added as a member of the project for contributions to be mapped.
- Otherwise, a supplementary comment is left to mention that the original author and
- the MRs, notes, or issues are owned by the importer.
- - For project migration imports performed over GitLab.com Groups, preserving author information is
- possible through a [professional services engagement](https://about.gitlab.com/services/migration/).
-- If an imported project contains merge requests originating from forks,
- then new branches associated with such merge requests are created
- in a project during the import/export. Thus, the number of branches
- in the exported project could be bigger than in the original project.
-- Deploy keys allowed to push to protected branches are not exported. Therefore,
- you must recreate this association by first enabling these deploy keys in your
- imported project and then updating your protected branches accordingly.
-
-## Version history
-
-### 14.0+
-
-In GitLab 14.0, the JSON format is no longer supported for project and group exports. To allow for a
-transitional period, you can still import any JSON exports. The new format for imports and exports
-is NDJSON.
+## Between CE and EE
-### 13.0+
+You can export projects from the [Community Edition to the Enterprise Edition](https://about.gitlab.com/install/ce-or-ee/)
+and vice versa. This assumes [version history](#version-history)
+requirements are met.
-Starting with GitLab 13.0, GitLab can import bundles that were exported from a different GitLab deployment.
-This ability is limited to two previous GitLab [minor](../../../policy/maintenance.md#versioning)
-releases, which is similar to our process for [Security Releases](../../../policy/maintenance.md#security-releases).
+If you're exporting a project from the Enterprise Edition to the Community Edition, you may lose
+data that is retained only in the Enterprise Edition. For more information, see
+[downgrading from EE to CE](../../../index.md).
-For example:
+## Export a project and its data
-| Current version | Can import bundles exported from |
-|-----------------|----------------------------------|
-| 13.0 | 13.0, 12.10, 12.9 |
-| 13.1 | 13.1, 13.0, 12.10 |
+Before you can import a project, you must export it.
-### 12.x
+Prerequisites:
-Prior to 13.0 this was a defined compatibility table:
+- Review the list of [data that will be exported](#items-that-are-exported).
+ Not all data is exported.
+- You must have at least the Maintainer role for the project.
-| Exporting GitLab version | Importing GitLab version |
-| -------------------------- | -------------------------- |
-| 11.7 to 12.10 | 11.7 to 12.10 |
-| 11.1 to 11.6 | 11.1 to 11.6 |
-| 10.8 to 11.0 | 10.8 to 11.0 |
-| 10.4 to 10.7 | 10.4 to 10.7 |
-| 10.3 | 10.3 |
-| 10.0 to 10.2 | 10.0 to 10.2 |
-| 9.4 to 9.6 | 9.4 to 9.6 |
-| 9.2 to 9.3 | 9.2 to 9.3 |
-| 8.17 to 9.1 | 8.17 to 9.1 |
-| 8.13 to 8.16 | 8.13 to 8.16 |
-| 8.12 | 8.12 |
-| 8.10.3 to 8.11 | 8.10.3 to 8.11 |
-| 8.10.0 to 8.10.2 | 8.10.0 to 8.10.2 |
-| 8.9.5 to 8.9.11 | 8.9.5 to 8.9.11 |
-| 8.9.0 to 8.9.4 | 8.9.0 to 8.9.4 |
-
-Projects can be exported and imported only between versions of GitLab with matching Import/Export versions.
-
-For example, 8.10.3 and 8.11 have the same Import/Export version (0.1.3)
-and the exports between them are compatible.
-
-## Between CE and EE
+To export a project and its data, follow these steps:
-You can export projects from the [Community Edition to the Enterprise Edition](https://about.gitlab.com/install/ce-or-ee/) and vice versa.
-This assumes [version history](#version-history) requirements are met.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Settings**.
+1. Expand **Advanced**.
+1. Select **Export project**.
+1. After the export is generated, you should receive an email with a link to download the file.
+1. Alternatively, you can come back to the project settings and download the file from there or
+ generate a new export. After the file is available, the page should show the **Download export**
+ button.
-If you're exporting a project from the Enterprise Edition to the Community Edition, you may lose data that is retained only in the Enterprise Edition. For more information, see [downgrading from EE to CE](../../../index.md).
+The export is generated in your configured `shared_path`, a temporary shared directory, and then
+moved to your configured `uploads_directory`. Every 24 hours, a worker deletes these export files.
-## Exported contents
+### Items that are exported
The following items are exported:
- Project and wiki repositories
- Project uploads
- Project configuration, excluding integrations
-- Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, time tracking,
- and other project entities
+- Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, time
+ tracking, and other project entities
- Design Management files and data
- LFS objects
- Issue boards
- Pipelines history
- Push Rules
- Awards
+- Group members are exported as project members, as long as the user has the Maintainer role in the
+ exported project's group, or is an administrator
The following items are **not** exported:
@@ -140,6 +80,7 @@ The following items are **not** exported:
- Any encrypted tokens
- Merge Request Approvers
- Repository size limits
+- Deploy keys allowed to push to protected branches
These content rules also apply to creating projects from templates on the
[group](../../group/custom_project_templates.md)
@@ -150,87 +91,146 @@ NOTE:
For more details on the specific data persisted in a project export, see the
[`import_export.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/import_export/project/import_export.yml) file.
-## Export a project and its data
-
-Full project export functionality is limited to project maintainers and owners.
-You can configure such functionality through [project settings](index.md):
-
-To export a project and its data, follow these steps:
+## Import a project and its data
-1. Go to your project's homepage.
+> Default maximum import file size [changed](https://gitlab.com/gitlab-org/gitlab/-/issues/251106) from 50 MB to unlimited in GitLab 13.8.
-1. Select **Settings** in the sidebar.
+WARNING:
+Only import projects from sources you trust. If you import a project from an untrusted source, it
+may be possible for an attacker to steal your sensitive data.
-1. Scroll down and expand the **Advanced** section.
+Prerequisites:
-1. Scroll down to find the **Export project** button:
+- You must have [exported the project and its data](#export-a-project-and-its-data).
+- Compare GitLab versions and ensure you are importing to a GitLab version that is the same or later
+ than the GitLab version you exported to.
+- Review the [Version history](#version-history)
+ for compatibility issues.
- ![Export button](img/import_export_export_button.png)
+To import a project:
-1. After the export is generated, you should receive an email with a link to
- download the file:
+1. When [creating a new project](../working_with_projects.md#create-a-project),
+ select **Import project**.
+1. In **Import project from**, select **GitLab export**.
+1. Enter your project name and URL. Then select the file you exported previously.
+1. Select **Import project** to begin importing. Your newly imported project page appears shortly.
- ![Email download link](img/import_export_mail_link.png)
+To get the status of an import, you can query it through the [Project import/export API](../../../api/project_import_export.md#import-status).
+As described in the API documentation, the query may return an import error or exceptions.
-1. Alternatively, you can come back to the project settings and download the
- file from there, or generate a new export. After the file is available, the page
- should show the **Download export** button:
+### Items that are imported
- ![Download export](img/import_export_download_export.png)
+The following items are imported but changed slightly:
-## Import the project
+- Project members with the [Owner role](../../permissions.md)
+ are imported as Maintainers.
+- If an imported project contains merge requests originating from forks, then new branches
+ associated with such merge requests are created in a project during the import/export. Thus, the
+ number of branches in the exported project might be bigger than in the original project.
+- If use of the `Internal` visibility level
+ [is restricted](../../../public_access/public_access.md#restrict-use-of-public-or-internal-projects),
+ all imported projects are given `Private` visibility.
-> Default maximum import file size [changed](https://gitlab.com/gitlab-org/gitlab/-/issues/251106) from 50 MB to unlimited in GitLab 13.8.
+Deploy keys aren't imported. To use deploy keys, you must enable them in your imported project and update protected branches.
-WARNING:
-Only import projects from sources you trust. If you import a project from an untrusted source, it
-may be possible for an attacker to steal your sensitive data.
+### Import large projects **(FREE SELF)**
-1. The GitLab project import feature is the first import option when creating a
- new project. Select **GitLab export**:
+If you have a larger project, consider using a Rake task as described in the [developer documentation](../../../development/import_project.md#importing-via-a-rake-task).
- ![New project](img/import_export_new_project.png)
+## Automate group and project import **(PREMIUM)**
-1. Enter your project name and URL. Then select the file you exported previously:
+For information on automating user, group, and project import API calls, see
+[Automate group and project import](../import/index.md#automate-group-and-project-import).
- ![Select file](img/import_export_select_file.png)
+## Maximum import file size
-1. Select **Import project** to begin importing. Your newly imported project
- page appears shortly.
+Administrators can set the maximum import file size one of two ways:
-NOTE:
-If use of the `Internal` visibility level
-[is restricted](../../../public_access/public_access.md#restrict-use-of-public-or-internal-projects),
-all imported projects are given the visibility of `Private`.
+- With the `max_import_size` option in the [Application settings API](../../../api/settings.md#change-application-settings).
+- In the [Admin Area UI](../../admin_area/settings/account_and_limit_settings.md#max-import-size).
-The maximum import file size can be set by the Administrator, and the default is `0` (unlimited).
-As an administrator, you can modify the maximum import file size. To do so, use the `max_import_size` option in the [Application settings API](../../../api/settings.md#change-application-settings) or the [Admin Area UI](../../admin_area/settings/account_and_limit_settings.md).
+The default is `0` (unlimited).
-### Project import status
+## Map users for import
-You can query an import through the [Project import/export API](../../../api/project_import_export.md#import-status).
-As described in the API documentation, the query may return an import error or exceptions.
+Imported users can be mapped by their public email addresses on self-managed instances, if an administrator (not an owner) does the import.
-### Import large projects **(FREE SELF)**
+- Public email addresses are not set by default. Users must
+[set it in their profiles](../../profile/index.md#set-your-public-email)
+for mapping to work correctly.
+- For contributions to be mapped correctly, users must be an existing member of the namespace,
+ or they can be added as a member of the project. Otherwise, a supplementary comment is left to mention that the original author and the MRs, notes, or issues that are owned by the importer.
-If you have a larger project, consider using a Rake task, as described in our [developer documentation](../../../development/import_project.md#importing-via-a-rake-task).
+For project migration imports performed over GitLab.com groups, preserving author information is
+possible through a [professional services engagement](https://about.gitlab.com/services/migration/).
## Rate Limits
To help avoid abuse, by default, users are rate limited to:
-| Request Type | Limit |
-| ---------------- | ---------------------------------------- |
-| Export | 6 projects per minute |
-| Download export | 1 download per group per minute |
-| Import | 6 projects per minute |
+| Request Type | Limit |
+| ---------------- | ----- |
+| Export | 6 projects per minute |
+| Download export | 1 download per group per minute |
+| Import | 6 projects per minute |
-GitLab.com may have [different settings](../../gitlab_com/index.md#importexport) from the defaults.
+GitLab.com may have [different settings](../../gitlab_com/index.md#importexport)
+from the defaults.
-## Automate group and project import **(PREMIUM)**
+## Version history
-For information on automating user, group, and project import API calls, see
-[Automate group and project import](../import/index.md#automate-group-and-project-import).
+### 14.0+
+
+In GitLab 14.0, the JSON format is no longer supported for project and group exports. To allow for a
+transitional period, you can still import any JSON exports. The new format for imports and exports
+is NDJSON.
+
+### 13.0+
+
+Starting with GitLab 13.0, GitLab can import bundles that were exported from a different GitLab deployment.
+This ability is limited to two previous GitLab [minor](../../../policy/maintenance.md#versioning)
+releases, which is similar to our process for [Security Releases](../../../policy/maintenance.md#security-releases).
+
+For example:
+
+| Current version | Can import bundles exported from |
+|-----------------|----------------------------------|
+| 13.0 | 13.0, 12.10, 12.9 |
+| 13.1 | 13.1, 13.0, 12.10 |
+
+### 12.x
+
+Prior to 13.0 this was a defined compatibility table:
+
+| Exporting GitLab version | Importing GitLab version |
+| -------------------------- | -------------------------- |
+| 11.7 to 12.10 | 11.7 to 12.10 |
+| 11.1 to 11.6 | 11.1 to 11.6 |
+| 10.8 to 11.0 | 10.8 to 11.0 |
+| 10.4 to 10.7 | 10.4 to 10.7 |
+| 10.3 | 10.3 |
+| 10.0 to 10.2 | 10.0 to 10.2 |
+| 9.4 to 9.6 | 9.4 to 9.6 |
+| 9.2 to 9.3 | 9.2 to 9.3 |
+| 8.17 to 9.1 | 8.17 to 9.1 |
+| 8.13 to 8.16 | 8.13 to 8.16 |
+| 8.12 | 8.12 |
+| 8.10.3 to 8.11 | 8.10.3 to 8.11 |
+| 8.10.0 to 8.10.2 | 8.10.0 to 8.10.2 |
+| 8.9.5 to 8.9.11 | 8.9.5 to 8.9.11 |
+| 8.9.0 to 8.9.4 | 8.9.0 to 8.9.4 |
+
+Projects can be exported and imported only between versions of GitLab with matching Import/Export versions.
+
+For example, 8.10.3 and 8.11 have the same Import/Export version (0.1.3)
+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)**
+- [Group import/export](../../group/settings/import_export.md)
+- [Group import/export API](../../../api/group_import_export.md)
## Troubleshooting
@@ -245,7 +245,7 @@ Review [issue 276930](https://gitlab.com/gitlab-org/gitlab/-/issues/276930), and
### Import workarounds for large repositories
-[Maximum import size limitations](#import-the-project)
+[Maximum import size limitations](#import-a-project-and-its-data)
can prevent an import from being successful. If changing the import limits is not possible, you can
try one of the workarounds listed here.
diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md
index c6cbd45a6ab..9df545b52ec 100644
--- a/doc/user/project/settings/index.md
+++ b/doc/user/project/settings/index.md
@@ -86,12 +86,17 @@ read-only view to discourage this behavior.
> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/300324) in GitLab 13.11.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/331231) in GitLab 14.2.
-Group owners can use compliance pipeline configuration to add additional pipeline configuration to
-projects to define compliance requirements such as scans or tests.
-
-[Compliance frameworks](#compliance-frameworks) allow group owners to specify the location of
-compliance pipeline configuration stored and managed in dedicated projects, separate from regular
-projects.
+Compliance framework pipelines allow group owners to define
+a compliance pipeline in a separate repository that gets
+executed in place of the local project's `gitlab-ci.yml` file. As part of this pipeline, an
+`include` statement can reference the local project's `gitlab-ci.yml` file. This way, the two CI
+files are merged together any time the pipeline runs. Jobs and variables defined in the compliance
+pipeline can't be changed by variables in the local project's `gitlab-ci.yml` file.
+
+When used to enforce scan execution, this feature has some overlap with [scan execution policies](../../application_security/policies/#scan-execution-policies),
+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](../../application_security/#enforce-scan-execution).
When you set up the compliance framework, use the **Compliance pipeline configuration** box to link
the compliance framework to specific CI/CD configuration. Use the
@@ -178,8 +183,6 @@ include: # Execute individual project's configuration (if project contains .git
project: '$CI_PROJECT_PATH'
file: '$CI_CONFIG_PATH'
ref: '$CI_COMMIT_REF_NAME' # Must be defined or MR pipelines always use the use default branch
- rules:
- - exists: '$CI_CONFIG_PATH'
```
##### Ensure compliance jobs are always run
@@ -265,7 +268,7 @@ Some features depend on others:
- If you disable the **Issues** option, GitLab also removes the following
features:
- - **issue boards**
+ - **Issue Boards**
- [**Service Desk**](#service-desk)
NOTE:
@@ -324,7 +327,7 @@ Enable [Service Desk](../service_desk.md) for your project to offer customer sup
### Export project
-Learn how to [export a project](import_export.md#import-the-project) in GitLab.
+Learn how to [export a project](import_export.md#import-a-project-and-its-data) in GitLab.
### Advanced settings
diff --git a/doc/user/project/settings/project_access_tokens.md b/doc/user/project/settings/project_access_tokens.md
index 44ece6cb172..3fcfe202d38 100644
--- a/doc/user/project/settings/project_access_tokens.md
+++ b/doc/user/project/settings/project_access_tokens.md
@@ -1,6 +1,6 @@
---
stage: Manage
-group: Access
+group: Authentication & 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
---
@@ -14,18 +14,19 @@ type: reference, howto
You can use a project access token to authenticate:
-- With the [GitLab API](../../../api/index.md#personalproject-access-tokens).
+- With the [GitLab API](../../../api/index.md#personalprojectgroup-access-tokens).
- With Git, when using HTTP Basic Authentication.
After you configure a project access token, you don't need a password when you authenticate.
Instead, you can enter any non-blank value.
-Project access tokens are similar to [personal access tokens](../../profile/personal_access_tokens.md),
-except they are associated with a project rather than a user.
+Project access tokens are similar to [group access tokens](../../group/settings/group_access_tokens.md)
+and [personal access tokens](../../profile/personal_access_tokens.md), except they are
+associated with a project rather than a group or user.
You can use project access tokens:
-- On GitLab SaaS if you have the Premium license tier or higher. Personal access tokens are not available with a [trial license](https://about.gitlab.com/free-trial/).
+- 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/).
- On self-managed instances of GitLab, with any license tier. If you have the Free tier:
- Review your security and compliance policies around
[user self-enrollment](../../admin_area/settings/sign_up_restrictions.md#disable-new-sign-ups).
@@ -78,83 +79,11 @@ To enable or disable project access token creation for all projects in a top-lev
1. On the top bar, select **Menu > Groups** and find your group.
1. On the left sidebar, select **Settings > General**.
-1. Expand **Permissions, LFS, 2FA**.
-1. Under **Permissions**, turn on or off **Allow project access token creation**.
+1. Expand **Permissions and group features**.
+1. Under **Permissions**, turn on or off **Allow project and group access token creation**.
Even when creation is disabled, you can still use and revoke existing project access tokens.
-## Group access tokens **(FREE SELF)**
-
-With group access tokens, you can use a single token to:
-
-- Perform actions for groups.
-- Manage the projects within the group.
-- In [GitLab 14.2](https://gitlab.com/gitlab-org/gitlab/-/issues/330718) and later, authenticate with Git over HTTPS.
-
-NOTE:
-You cannot use the UI to create a group access token. [An issue exists](https://gitlab.com/gitlab-org/gitlab/-/issues/214045)
-to add this functionality. This section describes a workaround.
-
-If you are an administrator of a self-managed GitLab instance, you can create a group access token in the
-[Rails console](../../../administration/operations/rails_console.md).
-
-<div class="video-fallback">
- For a demo of the group access token workaround, see <a href="https://www.youtube.com/watch?v=W2fg1P1xmU0">Demo: Group Level Access Tokens</a>.
-</div>
-<figure class="video-container">
- <iframe src="https://www.youtube.com/embed/W2fg1P1xmU0" frameborder="0" allowfullscreen="true"> </iframe>
-</figure>
-
-### Create a group access token
-
-To create a group access token:
-
-1. Run the following commands in a [Rails console](../../../administration/operations/rails_console.md):
-
- ```ruby
- # Set the GitLab administration user to use. If user ID 1 is not available or is not an adinistrator, use 'admin = User.admins.first' instead to select an admininistrator.
- admin = User.find(1)
-
- # Set the group group you want to create a token for. For example, group with ID 109.
- group = Group.find(109)
-
- # Create the group bot user. For further group access tokens, the username should be group_#{group.id}_bot#{bot_count}. For example, group_109_bot2 and email address group_109_bot2@example.com.
- bot = Users::CreateService.new(admin, { name: 'group_token', username: "group_#{group.id}_bot", email: "group_#{group.id}_bot@example.com", user_type: :project_bot }).execute
-
- # Confirm the group bot.
- bot.confirm
-
- # Add the bot to the group with the required role.
- group.add_user(bot, :maintainer)
-
- # Give the bot a personal access token.
- token = bot.personal_access_tokens.create(scopes:[:api, :write_repository], name: 'group_token')
-
- # Get the token value.
- gtoken = token.token
- ```
-
-1. Test if the generated group access token works:
-
- 1. Use the group access token in the `PRIVATE-TOKEN` header with GitLab REST APIs. For example:
-
- - [Create an epic](../../../api/epics.md#new-epic) in the group.
- - [Create a project pipeline](../../../api/pipelines.md#create-a-new-pipeline) in one of the group's projects.
- - [Create an issue](../../../api/issues.md#new-issue) in one of the group's projects.
-
- 1. Use the group token to [clone a group's project](../../../gitlab-basics/start-using-git.md#clone-with-https)
- using HTTPS.
-
-### Revoke a group access token
-
-To revoke a group access token, run the following command in a [Rails console](../../../administration/operations/rails_console.md):
-
-```ruby
-bot = User.find_by(username: 'group_109_bot') # the owner of the token you want to revoke
-token = bot.personal_access_tokens.last # the token you want to revoke
-token.revoke!
-```
-
## Project bot users
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/210181) in GitLab 13.0.
@@ -169,11 +98,11 @@ selected role and [scope](#scopes-for-a-project-access-token) of the project acc
- The name is set to the name of the token.
- The username is set to `project_{project_id}_bot` for the first access token. For example, `project_123_bot`.
-- The email is set to `project{project_id}_bot@example.com`. For example, `project123_bot@example.com`.
+- The email is set to `project{project_id}_bot@noreply.{Gitlab.config.gitlab.host}`. For example, `project123_bot@noreply.example.com`.
- For additional access tokens in the same project, the username is set to `project_{project_id}_bot{bot_count}`. For
example, `project_123_bot1`.
-- For additional access tokens in the same project, the email is set to `project{project_id}_bot{bot_count}@example.com`.
- For example, `project123_bot1@example.com`.
+- For additional access tokens in the same project, the email is set to `project{project_id}_bot{bot_count}@noreply.{Gitlab.config.gitlab.host}`.
+ For example, `project123_bot1@noreply.example.com`.
API calls made with a project access token are associated with the corresponding bot user.
diff --git a/doc/user/project/time_tracking.md b/doc/user/project/time_tracking.md
index b41ea30bfef..6ceb8c94934 100644
--- a/doc/user/project/time_tracking.md
+++ b/doc/user/project/time_tracking.md
@@ -76,6 +76,15 @@ For example, if you want to log 1 hour of time spent on the 31 January 2021,
you would type `/spend 1h 2021-01-31`. If you supply a date in the future, the
command fails and no time is logged.
+To add a timelog entry with a note, create a comment with a description and the quick action.
+It then shows in the timelog "Summary/Notes" column. For example:
+
+```plaintext
+Draft MR and respond to initial comments
+
+/spend 30m
+```
+
To remove all the time spent at once, use `/remove_time_spent`.
## View a time tracking report
diff --git a/doc/user/project/web_ide/index.md b/doc/user/project/web_ide/index.md
index 40c9ae8bd59..4565b5f1c91 100644
--- a/doc/user/project/web_ide/index.md
+++ b/doc/user/project/web_ide/index.md
@@ -1,17 +1,14 @@
---
stage: Create
group: Editor
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, how-to
+info: 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 IDE **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4539) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.4.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/44157) to GitLab Free in 10.7.
-
-The Web Integrated Development Environment (IDE) editor makes it faster and easier to contribute changes to your
-projects by providing an advanced editor with commit staging.
+The Web Integrated Development Environment (IDE) editor streamlines the process
+to contribute changes to your projects, by providing an advanced editor with
+commit staging.
## Open the Web IDE
@@ -36,8 +33,6 @@ and from merge requests:
## File finder
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/18323) in [GitLab Free](https://about.gitlab.com/pricing/) 10.8.
-
The file finder allows you to quickly open files in the current branch by
searching for fragments of the file path. The file finder is launched using the keyboard shortcut
<kbd>Command</kbd>+<kbd>p</kbd>, <kbd>Control</kbd>+<kbd>p</kbd>, or <kbd>t</kbd>
@@ -150,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](https://about.gitlab.com/pricing/) 13.1.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23352) in GitLab Free 13.1.
The Web IDE supports configuration of certain editor settings by using
[`.editorconfig` files](https://editorconfig.org/). When opening a file, the
@@ -169,12 +164,10 @@ The Web IDE currently supports the following `.editorconfig` settings:
## Commit changes
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4539) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.4.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/44157) to GitLab Free in 10.7.
-> - From [GitLab 12.7 onward](https://gitlab.com/gitlab-org/gitlab/-/issues/33441), files were automatically staged.
-> - From [GitLab 12.9 onward](https://gitlab.com/gitlab-org/gitlab/-/issues/196609), support for staging files was removed to prevent loss of unstaged data. All your current changes necessarily have to be committed or discarded.
+> - 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.
-After making your changes, click the **Commit** button on the bottom-left to
+After making your changes, select **Commit** on the bottom-left to
review the list of changed files.
After you have finalized your changes, you can add a commit message, commit the
@@ -182,8 +175,8 @@ changes and directly create a merge request. In case you don't have write
access to the selected branch, you see a warning, but can still create
a new branch and start a merge request.
-To discard a change in a particular file, click the **Discard changes** button on that
-file in the changes tab. To discard all the changes, click the trash icon on the
+To discard a change in a particular file, select **Discard changes** on that
+file in the changes tab. To discard all the changes, select the trash icon on the
top-right corner of the changes sidebar.
![Commit changes](img/commit_changes_v13_11.png)
@@ -198,8 +191,6 @@ shows you a preview of the merge request diff if you commit your changes.
## View CI job logs
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/19279) in [GitLab Free](https://about.gitlab.com/pricing/) 11.0.
-
You can use the Web IDE to quickly fix failing tests by opening
the branch or merge request in the Web IDE and opening the logs of the failed
job. You can access the status of all jobs for the most recent pipeline and job
@@ -211,16 +202,12 @@ left.
## Switching merge requests
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/19318) in [GitLab Free](https://about.gitlab.com/pricing/) 11.0.
-
To switch between your authored and assigned merge requests, click the
dropdown in the top of the sidebar to open a list of merge requests. You must commit or discard all your changes before switching to a different merge
request.
## Switching branches
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/20850) in [GitLab Free](https://about.gitlab.com/pricing/) 11.2.
-
To switch between branches of the current project repository, click the dropdown
in the top of the sidebar to open a list of branches.
You must commit or discard all your changes before switching to a
@@ -228,9 +215,8 @@ different branch.
## Markdown editing
-> - Markdown preview [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/18059) in [GitLab Free](https://about.gitlab.com/pricing/) 10.7.
-> - Support for pasting images [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22822) in [GitLab Free](https://about.gitlab.com/pricing/) 13.1.
-> - Side-by-side Markdown preview [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68274) in [GitLab Free](https://about.gitlab.com/pricing/) 14.3
+> - 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.
To edit Markdown files in the Web IDE:
@@ -255,8 +241,7 @@ There are two ways to preview Markdown content in the Web IDE:
## Live Preview
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/19764) in [GitLab Free](https://about.gitlab.com/pricing/) 11.2.
-> - [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/213853) from _Client Side Evaluation_ to _Live Preview_ in GitLab 13.0.
+> [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/213853) from _Client Side Evaluation_ to _Live Preview_ in GitLab 13.0.
You can use the Web IDE to preview JavaScript projects right in the browser.
This feature uses CodeSandbox to compile and bundle the JavaScript used to
@@ -301,8 +286,7 @@ An example `package.json`:
## Interactive Web Terminals for the Web IDE
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5426) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.6.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/211685) to GitLab Free in 13.1.
+> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/211685) to GitLab Free in 13.1.
WARNING:
Interactive Web Terminals for the Web IDE is currently in **Beta**.
@@ -407,8 +391,8 @@ click **Restart Terminal** to start a new terminal session.
### File syncing to web terminal
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5276) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.0.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/211686) to GitLab Free in 13.1.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5276) in GitLab Ultimate 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.
This enables users to test their code changes in a preconfigured terminal
diff --git a/doc/user/project/wiki/index.md b/doc/user/project/wiki/index.md
index 9f1670d3f4c..95ea1b4d0bc 100644
--- a/doc/user/project/wiki/index.md
+++ b/doc/user/project/wiki/index.md
@@ -1,8 +1,7 @@
---
stage: Create
group: Editor
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: reference, how-to
+info: 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
---
# Wiki **(FREE)**
@@ -87,11 +86,7 @@ Users with the [Developer role](../../permissions.md) can create new wiki pages:
[special characters](#special-characters-in-page-titles) for subdirectories and formatting,
and have [length restrictions](#length-restrictions-for-file-and-directory-names).
1. Add content to your wiki page.
-1. Optional. Attach a file, and GitLab stores it according to your installed version of GitLab:
- - *Files added in [GitLab 11.3 and later](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/33475):*
- Files are stored in the wiki's Git repository.
- - *Files added GitLab 11.2 and earlier:* Files are stored in GitLab itself. To add
- the file to the wiki's Git repository, you must re-upload the file.
+1. Optional. Attach a file, and GitLab stores it in the wiki's Git repository.
1. Add a **Commit message**. Git requires a commit message, so GitLab creates one
if you don't enter one yourself.
1. Select **Create page**.
@@ -227,9 +222,9 @@ You can see the changes made in a version of a wiki page, similar to versioned d
## Track wiki events
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14902) in **GitLab 12.10.**
-> - Git events were [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216014) in **GitLab 13.0.**
-> - [Feature flag for Git events was removed](https://gitlab.com/gitlab-org/gitlab/-/issues/258665) in **GitLab 13.5**
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14902) in GitLab 12.10.
+> - Git events were [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216014) in GitLab 13.0.
+> - [Feature flag for Git events was removed](https://gitlab.com/gitlab-org/gitlab/-/issues/258665) in GitLab 13.5.
GitLab tracks wiki creation, deletion, and update events. These events are displayed on these pages:
diff --git a/doc/user/project/working_with_projects.md b/doc/user/project/working_with_projects.md
index b5b3f2d2085..61eca19a67b 100644
--- a/doc/user/project/working_with_projects.md
+++ b/doc/user/project/working_with_projects.md
@@ -16,7 +16,7 @@ To explore projects:
1. On the top bar, select **Menu > Projects**.
1. Select **Explore projects**.
-The **Projects** page shows a list of projects, sorted by last updated date.
+The **Projects** page shows a list of projects, sorted by last updated date.
- To view projects with the most [stars](#star-a-project), select **Most stars**.
- To view projects with the largest number of comments in the past month, select **Trending**.
@@ -326,7 +326,7 @@ on the project dashboard when a project is part of a group under a
Prerequisites:
- Contact your administrator to enable the [GitLab Go Proxy](../packages/go_proxy/index.md).
-- To use a private project in a subgroup as a Go package, you must [authenticate Go requests](#authenticate-go-requests-to-private-projects). Go requests that are not authenticated cause
+- To use a private project in a subgroup as a Go package, you must [authenticate Go requests](#authenticate-go-requests-to-private-projects). Go requests that are not authenticated cause
`go get` to fail. You don't need to authenticate Go requests for projects that are not in subgroups.
To use a project as a Go package, use the `go get` and `godoc.org` discovery requests. You can use the meta tags:
diff --git a/doc/user/search/advanced_search.md b/doc/user/search/advanced_search.md
index b9c45bce43a..13fba126169 100644
--- a/doc/user/search/advanced_search.md
+++ b/doc/user/search/advanced_search.md
@@ -14,10 +14,6 @@ This is the user documentation. To configure the Advanced Search,
visit the [administrator documentation](../../integration/elasticsearch.md).
Advanced Search is enabled in GitLab.com.
-INFO:
-Get advanced search and more with a
-[free 30-day trial of GitLab Ultimate](https://about.gitlab.com/free-trial/index.html?glm_source=docs.gitlab.com&glm_content=p-advanced-search-docs).
-
GitLab Advanced Search expands on the Basic Search with an additional set of
features for faster, more advanced searches across the entire GitLab instance
when searching in:
diff --git a/doc/user/search/img/code_search.png b/doc/user/search/img/code_search.png
new file mode 100644
index 00000000000..7c62bb6921b
--- /dev/null
+++ b/doc/user/search/img/code_search.png
Binary files differ
diff --git a/doc/user/search/img/project_code_search.png b/doc/user/search/img/project_code_search.png
deleted file mode 100644
index 5412f614a74..00000000000
--- a/doc/user/search/img/project_code_search.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/search/index.md b/doc/user/search/index.md
index aa4950cfa33..0e2be455a0c 100644
--- a/doc/user/search/index.md
+++ b/doc/user/search/index.md
@@ -1,8 +1,7 @@
---
stage: Create
group: Editor
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
-type: index, reference, howto
+info: 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
---
# Searching in GitLab **(FREE)**
@@ -102,8 +101,7 @@ You can filter the **Issues** list to individual instances by their ID. For exam
### Filtering merge requests by approvers **(PREMIUM)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9468) in GitLab 11.9.
-> - Moved to GitLab Premium in 13.9.
+> 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.
@@ -143,7 +141,7 @@ you can choose from:
![Filter MRs by their environment](img/filtering_merge_requests_by_environment_v14_6.png)
-When filtering by `Deployed-before` or `Deployed-after`, the date refers to when
+When filtering by `Deployed-before` or `Deployed-after`, the date refers to when
the deployment to an environment (triggered by the merge commit) completed successfully.
You must enter the deploy date manually. Deploy dates
use the format `YYYY-MM-DD`, and must be quoted if you wish to specify
@@ -272,8 +270,10 @@ search, or choose a specific group or project.
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. [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/project_code_search.png)
+![code search results](img/code_search.png)
### SHA search
diff --git a/lib/api/api.rb b/lib/api/api.rb
index dcecaeae558..5984879413f 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -299,6 +299,7 @@ module API
mount ::API::Internal::Lfs
mount ::API::Internal::Pages
mount ::API::Internal::Kubernetes
+ mount ::API::Internal::MailRoom
version 'v3', using: :path do
# Although the following endpoints are kept behind V3 namespace,
diff --git a/lib/api/ci/helpers/runner.rb b/lib/api/ci/helpers/runner.rb
index 72c388160b4..43ed35b99fd 100644
--- a/lib/api/ci/helpers/runner.rb
+++ b/lib/api/ci/helpers/runner.rb
@@ -11,14 +11,6 @@ module API
JOB_TOKEN_HEADER = 'HTTP_JOB_TOKEN'
JOB_TOKEN_PARAM = :token
- def runner_registration_token_valid?
- ActiveSupport::SecurityUtils.secure_compare(params[: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 authenticate_runner!
forbidden! unless current_runner
diff --git a/lib/api/ci/job_artifacts.rb b/lib/api/ci/job_artifacts.rb
index 6431436b50d..ca76d2664f8 100644
--- a/lib/api/ci/job_artifacts.rb
+++ b/lib/api/ci/job_artifacts.rb
@@ -137,6 +137,17 @@ module API
status :no_content
end
+
+ desc 'Expire the artifacts files from a project'
+ delete ':id/artifacts' do
+ not_found! unless Feature.enabled?(:bulk_expire_project_artifacts, default_enabled: :yaml)
+
+ authorize_destroy_artifacts!
+
+ ::Ci::JobArtifacts::DeleteProjectArtifactsService.new(project: user_project).execute
+
+ accepted!
+ end
end
end
end
diff --git a/lib/api/ci/runner.rb b/lib/api/ci/runner.rb
index 4317789f7aa..fef6a7891c2 100644
--- a/lib/api/ci/runner.rb
+++ b/lib/api/ci/runner.rb
@@ -15,6 +15,7 @@ module API
params do
requires :token, type: String, desc: 'Registration token'
optional :description, type: String, desc: %q(Runner's description)
+ optional :maintainer_note, type: String, desc: %q(Runner's maintainer notes)
optional :info, type: Hash, desc: %q(Runner's metadata)
optional :active, type: Boolean, desc: 'Should Runner be active'
optional :locked, type: Boolean, desc: 'Should Runner be locked for current project'
@@ -25,24 +26,11 @@ module API
optional :maximum_timeout, type: Integer, desc: 'Maximum timeout set when this Runner will handle the job'
end
post '/', feature_category: :runner do
- attributes = attributes_for_keys([:description, :active, :locked, :run_untagged, :tag_list, :access_level, :maximum_timeout])
+ attributes = attributes_for_keys(%i[description maintainer_note active locked run_untagged tag_list access_level maximum_timeout])
.merge(get_runner_details_from_request)
- attributes =
- if runner_registration_token_valid?
- # Create shared runner. Requires admin access
- attributes.merge(runner_type: :instance_type)
- elsif runner_registrar_valid?('project') && @project = Project.find_by_runners_token(params[:token])
- # Create a specific runner for the project
- attributes.merge(runner_type: :project_type, projects: [@project])
- elsif runner_registrar_valid?('group') && @group = Group.find_by_runners_token(params[:token])
- # Create a specific runner for the group
- attributes.merge(runner_type: :group_type, groups: [@group])
- else
- forbidden!
- end
-
- @runner = ::Ci::Runner.create(attributes)
+ @runner = ::Ci::RegisterRunnerService.new.execute(params[:token], attributes)
+ forbidden! unless @runner
if @runner.persisted?
present @runner, with: Entities::Ci::RunnerRegistrationDetails
diff --git a/lib/api/ci/runners.rb b/lib/api/ci/runners.rb
index ef712c84804..f21782a698f 100644
--- a/lib/api/ci/runners.rb
+++ b/lib/api/ci/runners.rb
@@ -229,7 +229,12 @@ module API
use :pagination
end
get ':id/runners' do
- runners = ::Ci::Runner.belonging_to_group(user_group.id, include_ancestors: true)
+ runners = if ::Feature.enabled?(:ci_find_runners_by_ci_mirrors, user_group, default_enabled: :yaml)
+ ::Ci::Runner.belonging_to_group_and_ancestors(user_group.id)
+ else
+ ::Ci::Runner.legacy_belonging_to_group(user_group.id, include_ancestors: true)
+ end
+
runners = apply_filter(runners, params)
present paginate(runners), with: Entities::Ci::Runner
diff --git a/lib/api/ci/triggers.rb b/lib/api/ci/triggers.rb
index 6a2b16e1568..ae89b475ef8 100644
--- a/lib/api/ci/triggers.rb
+++ b/lib/api/ci/triggers.rb
@@ -5,7 +5,7 @@ module API
class Triggers < ::API::Base
include PaginationParams
- HTTP_GITLAB_EVENT_HEADER = "HTTP_#{WebHookService::GITLAB_EVENT_HEADER}".underscore.upcase
+ HTTP_GITLAB_EVENT_HEADER = "HTTP_#{::Gitlab::WebHooks::GITLAB_EVENT_HEADER}".underscore.upcase
feature_category :continuous_integration
diff --git a/lib/api/debian_project_packages.rb b/lib/api/debian_project_packages.rb
index 497ce2f4356..5fb11db8938 100644
--- a/lib/api/debian_project_packages.rb
+++ b/lib/api/debian_project_packages.rb
@@ -83,7 +83,6 @@ module API
::Packages::Debian::ProcessChangesWorker.perform_async(package_file.id, current_user.id) # rubocop:disable CodeReuse/Worker
end
- track_package_event('push_package', :debian, user: current_user, project: authorized_user_project, namespace: authorized_user_project.namespace)
created!
rescue ObjectStorage::RemoteStoreError => e
Gitlab::ErrorTracking.track_exception(e, extra: { file_name: params[:file_name], project_id: authorized_user_project.id })
diff --git a/lib/api/deployments.rb b/lib/api/deployments.rb
index 80a50ded522..486ff5d89bc 100644
--- a/lib/api/deployments.rb
+++ b/lib/api/deployments.rb
@@ -165,3 +165,5 @@ module API
end
end
end
+
+API::Deployments.prepend_mod
diff --git a/lib/api/entities/group_detail.rb b/lib/api/entities/group_detail.rb
index 5eaccbc7154..e6872709432 100644
--- a/lib/api/entities/group_detail.rb
+++ b/lib/api/entities/group_detail.rb
@@ -4,7 +4,7 @@ module API
module Entities
class GroupDetail < Group
expose :shared_with_groups do |group, options|
- SharedGroupWithGroup.represent(group.shared_with_group_links.public_or_visible_to_user(group, options[:current_user]))
+ SharedGroupWithGroup.represent(group.shared_with_group_links_visible_to_user(options[:current_user]))
end
expose :runners_token, if: lambda { |group, options| options[:user_can_admin_group] }
expose :prevent_sharing_groups_outside_hierarchy, if: ->(group) { group.root? }
diff --git a/lib/api/entities/issue_basic.rb b/lib/api/entities/issue_basic.rb
index 6125dc05a6e..20f66c026e6 100644
--- a/lib/api/entities/issue_basic.rb
+++ b/lib/api/entities/issue_basic.rb
@@ -23,7 +23,7 @@ module API
expose :issue_type,
as: :type,
format_with: :upcase,
- documentation: { type: "String", desc: "One of #{::WorkItem::Type.allowed_types_for_issues.map(&:upcase)}" }
+ documentation: { type: "String", desc: "One of #{::WorkItems::Type.allowed_types_for_issues.map(&:upcase)}" }
expose :assignee, using: ::API::Entities::UserBasic do |issue|
issue.assignees.first
diff --git a/lib/api/entities/merge_request_basic.rb b/lib/api/entities/merge_request_basic.rb
index d5cf2f653db..55d58166590 100644
--- a/lib/api/entities/merge_request_basic.rb
+++ b/lib/api/entities/merge_request_basic.rb
@@ -3,9 +3,13 @@
module API
module Entities
class MergeRequestBasic < IssuableEntity
+ # Deprecated in favour of merge_user
expose :merged_by, using: Entities::UserBasic do |merge_request, _options|
merge_request.metrics&.merged_by
end
+ expose :merge_user, using: Entities::UserBasic do |merge_request|
+ merge_request.metrics&.merged_by || merge_request.merge_user
+ end
expose :merged_at do |merge_request, _options|
merge_request.metrics&.merged_at
end
diff --git a/lib/api/entities/project.rb b/lib/api/entities/project.rb
index 1b9299ed17e..74097dc2883 100644
--- a/lib/api/entities/project.rb
+++ b/lib/api/entities/project.rb
@@ -82,6 +82,8 @@ module API
expose :forked_from_project, using: Entities::BasicProjectDetails, if: ->(project, options) do
project.forked? && Ability.allowed?(options[:current_user], :read_project, project.forked_from_project)
end
+ expose :mr_default_target_self, if: -> (project) { project.forked? }
+
expose :import_status
expose :import_error, if: lambda { |_project, options| options[:user_can_admin_project] } do |project|
@@ -130,6 +132,7 @@ module API
Ability.allowed?(options[:current_user], :change_repository_storage, project)
}
expose :keep_latest_artifacts_available?, as: :keep_latest_artifact
+ expose :runner_token_expiration_interval
# rubocop: disable CodeReuse/ActiveRecord
def self.preload_resource(project)
diff --git a/lib/api/entities/project_with_access.rb b/lib/api/entities/project_with_access.rb
index ac89cb52e43..b541ccbadcf 100644
--- a/lib/api/entities/project_with_access.rb
+++ b/lib/api/entities/project_with_access.rb
@@ -8,7 +8,7 @@ module API
if options[:project_members]
options[:project_members].find { |member| member.source_id == project.id }
else
- project.project_member(options[:current_user])
+ project.member(options[:current_user])
end
end
diff --git a/lib/api/entities/resource_access_token.rb b/lib/api/entities/resource_access_token.rb
index a1c7b28af45..569fd16f488 100644
--- a/lib/api/entities/resource_access_token.rb
+++ b/lib/api/entities/resource_access_token.rb
@@ -4,7 +4,7 @@ module API
module Entities
class ResourceAccessToken < Entities::PersonalAccessToken
expose :access_level do |token, options|
- options[:project].project_member(token.user).access_level
+ options[:resource].member(token.user).access_level
end
end
end
diff --git a/lib/api/helpers/integrations_helpers.rb b/lib/api/helpers/integrations_helpers.rb
index e7fdb6645a5..3af0dd4c532 100644
--- a/lib/api/helpers/integrations_helpers.rb
+++ b/lib/api/helpers/integrations_helpers.rb
@@ -314,25 +314,33 @@ module API
required: false,
name: :datadog_site,
type: String,
- desc: 'Choose the Datadog site to send data to. Set to "datadoghq.eu" to send data to the EU site'
+ desc: 'The Datadog site to send data to. To send data to the EU site, use datadoghq.eu'
},
{
required: false,
name: :api_url,
type: String,
- desc: '(Advanced) Define the full URL for your Datadog site directly'
+ desc: '(Advanced) The full URL for your Datadog site'
},
+ # TODO: uncomment this field once :datadog_integration_logs_collection is rolled out
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/346339
+ # {
+ # required: false,
+ # name: :archive_trace_events,
+ # type: Boolean,
+ # desc: 'When enabled, job logs will be collected by Datadog and shown along pipeline execution traces'
+ # },
{
required: false,
name: :datadog_service,
type: String,
- desc: 'Name of this GitLab instance that all data will be tagged with'
+ desc: 'Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments'
},
{
required: false,
name: :datadog_env,
type: String,
- desc: 'The environment tag that traces will be tagged with'
+ desc: 'For self-managed deployments, set the env tag for all the data sent to Datadog. How do I use tags?'
}
],
'discord' => [
diff --git a/lib/api/helpers/members_helpers.rb b/lib/api/helpers/members_helpers.rb
index c2710be6c03..6c20993431d 100644
--- a/lib/api/helpers/members_helpers.rb
+++ b/lib/api/helpers/members_helpers.rb
@@ -50,7 +50,7 @@ module API
end
def find_all_members_for_group(group)
- GroupMembersFinder.new(group).execute
+ GroupMembersFinder.new(group, current_user).execute(include_relations: [:inherited, :direct, :shared_from_groups])
end
def present_members(members)
diff --git a/lib/api/helpers/projects_helpers.rb b/lib/api/helpers/projects_helpers.rb
index d7de8bd8b8b..00f745067e7 100644
--- a/lib/api/helpers/projects_helpers.rb
+++ b/lib/api/helpers/projects_helpers.rb
@@ -71,6 +71,7 @@ module API
optional :repository_storage, type: String, desc: 'Which storage shard the repository is on. Available only to admins'
optional :packages_enabled, type: Boolean, desc: 'Enable project packages feature'
optional :squash_option, type: String, values: %w(never always default_on default_off), desc: 'Squash default for project. One of `never`, `always`, `default_on`, or `default_off`.'
+ optional :mr_default_target_self, Boolean, desc: 'Merge requests of this forked project targets itself by default'
end
params :optional_project_params_ee do
@@ -169,6 +170,7 @@ module API
:packages_enabled,
:service_desk_enabled,
:keep_latest_artifact,
+ :mr_default_target_self,
# TODO: remove in API v5, replaced by *_access_level
:issues_enabled,
diff --git a/lib/api/helpers/rate_limiter.rb b/lib/api/helpers/rate_limiter.rb
index 7d87c74097d..0ad4f089907 100644
--- a/lib/api/helpers/rate_limiter.rb
+++ b/lib/api/helpers/rate_limiter.rb
@@ -10,6 +10,7 @@ module API
# See app/controllers/concerns/check_rate_limit.rb for Rails controllers version
module RateLimiter
def check_rate_limit!(key, scope:, **options)
+ return if bypass_header_set?
return unless rate_limiter.throttled?(key, scope: scope, **options)
rate_limiter.log_request(request, "#{key}_request_limit".to_sym, current_user)
@@ -24,6 +25,10 @@ module API
def rate_limiter
::Gitlab::ApplicationRateLimiter
end
+
+ def bypass_header_set?
+ ::Gitlab::Throttle.bypass_header.present? && request.get_header(Gitlab::Throttle.bypass_header) == '1'
+ end
end
end
end
diff --git a/lib/api/integrations.rb b/lib/api/integrations.rb
index bab8e556a73..ff1d88e35f0 100644
--- a/lib/api/integrations.rb
+++ b/lib/api/integrations.rb
@@ -111,7 +111,14 @@ module API
integration = user_project.find_or_initialize_integration(params[:slug].underscore)
destroy_conditionally!(integration) do
- attrs = integration_attributes(integration).index_with { nil }.merge(active: false)
+ attrs = integration_attributes(integration).index_with do |attr|
+ column = integration.column_for_attribute(attr)
+ if column.is_a?(ActiveRecord::ConnectionAdapters::NullColumn)
+ nil
+ else
+ column.default
+ end
+ end.merge(active: false)
render_api_error!('400 Bad Request', 400) unless integration.update(attrs)
end
diff --git a/lib/api/internal/base.rb b/lib/api/internal/base.rb
index d8e39d089e4..48157a91477 100644
--- a/lib/api/internal/base.rb
+++ b/lib/api/internal/base.rb
@@ -43,6 +43,10 @@ module API
# This is a separate method so that EE can alter its behaviour more
# easily.
+ if Feature.enabled?(:rate_limit_gitlab_shell, default_enabled: :yaml)
+ check_rate_limit!(:gitlab_shell_operation, scope: [params[:action], params[:project], actor.key_or_user])
+ end
+
# Stores some Git-specific env thread-safely
env = parse_env
Gitlab::Git::HookEnv.set(gl_repository, env) if container
diff --git a/lib/api/internal/kubernetes.rb b/lib/api/internal/kubernetes.rb
index f3974236fe3..3977da4bda4 100644
--- a/lib/api/internal/kubernetes.rb
+++ b/lib/api/internal/kubernetes.rb
@@ -53,7 +53,7 @@ module API
def check_agent_token
unauthorized! unless agent_token
- agent_token.track_usage
+ Clusters::AgentTokens::TrackUsageService.new(agent_token).execute
end
end
diff --git a/lib/api/internal/mail_room.rb b/lib/api/internal/mail_room.rb
new file mode 100644
index 00000000000..6e24cf6e7c5
--- /dev/null
+++ b/lib/api/internal/mail_room.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+module API
+ # This internal endpoint receives webhooks sent from the MailRoom component.
+ # This component constantly listens to configured email accounts. When it
+ # finds any incoming email or service desk email, it makes a POST request to
+ # this endpoint. The target mailbox type is indicated in the request path.
+ # The email raw content is attached to the request body.
+ #
+ # For more information, please visit https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/644
+ module Internal
+ class MailRoom < ::API::Base
+ feature_category :service_desk
+
+ before do
+ authenticate_gitlab_mailroom_request!
+ end
+
+ helpers do
+ def authenticate_gitlab_mailroom_request!
+ unauthorized! unless Gitlab::MailRoom::Authenticator.verify_api_request(headers, params[:mailbox_type])
+ end
+ end
+
+ namespace 'internal' do
+ namespace 'mail_room' do
+ params do
+ requires :mailbox_type, type: String,
+ desc: 'The destination mailbox type configuration. Must either be incoming_email or service_desk_email'
+ end
+ post "/*mailbox_type" do
+ worker = Gitlab::MailRoom.worker_for(params[:mailbox_type])
+ raw = request.body.read
+ begin
+ worker.perform_async(raw)
+ rescue Gitlab::SidekiqMiddleware::SizeLimiter::ExceedLimitError
+ receiver = Gitlab::Email::Receiver.new(raw)
+ reason = Gitlab::Email::FailureHandler.handle(receiver, Gitlab::Email::EmailTooLarge.new)
+
+ status 400
+ break { success: false, message: reason }
+ end
+
+ status 200
+ { success: true }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index 4d67cbd1272..46124a74e9d 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -82,7 +82,7 @@ module API
desc: 'Return issues sorted in `asc` or `desc` order.'
optional :due_date, type: String, values: %w[0 overdue week month next_month_and_previous_two_weeks] << '',
desc: 'Return issues that have no due date (`0`), or whose due date is this week, this month, between two weeks ago and next month, or which are overdue. Accepts: `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`, `0`'
- optional :issue_type, type: String, values: WorkItem::Type.allowed_types_for_issues, desc: "The type of the issue. Accepts: #{WorkItem::Type.allowed_types_for_issues.join(', ')}"
+ optional :issue_type, type: String, values: WorkItems::Type.allowed_types_for_issues, desc: "The type of the issue. Accepts: #{WorkItems::Type.allowed_types_for_issues.join(', ')}"
use :issues_stats_params
use :pagination
@@ -99,7 +99,7 @@ module API
optional :due_date, type: String, desc: 'Date string in the format YEAR-MONTH-DAY'
optional :confidential, type: Boolean, desc: 'Boolean parameter if the issue should be confidential'
optional :discussion_locked, type: Boolean, desc: " Boolean parameter indicating if the issue's discussion is locked"
- optional :issue_type, type: String, values: WorkItem::Type.allowed_types_for_issues, desc: "The type of the issue. Accepts: #{WorkItem::Type.allowed_types_for_issues.join(', ')}"
+ optional :issue_type, type: String, values: WorkItems::Type.allowed_types_for_issues, desc: "The type of the issue. Accepts: #{WorkItems::Type.allowed_types_for_issues.join(', ')}"
use :optional_issue_params_ee
end
diff --git a/lib/api/package_files.rb b/lib/api/package_files.rb
index 79ebf18ff27..5e421da2c55 100644
--- a/lib/api/package_files.rb
+++ b/lib/api/package_files.rb
@@ -28,10 +28,15 @@ module API
package = ::Packages::PackageFinder
.new(user_project, params[:package_id]).execute
- files = package.package_files
- .preload_pipelines
+ package_files = if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml)
+ package.installable_package_files
+ else
+ package.package_files
+ end
- present paginate(files), with: ::API::Entities::PackageFile
+ package_files = package_files.preload_pipelines
+
+ present paginate(package_files), with: ::API::Entities::PackageFile
end
desc 'Remove a package file' do
@@ -50,7 +55,13 @@ module API
not_found! unless package
- package_file = package.package_files.find_by_id(params[:package_file_id])
+ package_files = if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml)
+ package.installable_package_files
+ else
+ package.package_files
+ end
+
+ package_file = package_files.find_by_id(params[:package_file_id])
not_found! unless package_file
diff --git a/lib/api/project_container_repositories.rb b/lib/api/project_container_repositories.rb
index 82b6082c3fe..d4efca6e8f2 100644
--- a/lib/api/project_container_repositories.rb
+++ b/lib/api/project_container_repositories.rb
@@ -123,7 +123,6 @@ module API
end
delete ':id/registry/repositories/:repository_id/tags/:tag_name', requirements: REPOSITORY_ENDPOINT_REQUIREMENTS do
authorize_destroy_container_image!
- validate_tag!
result = ::Projects::ContainerRepository::DeleteTagsService
.new(repository.project, current_user, tags: [declared_params[:tag_name]])
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 887c76941cf..d772079372c 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -363,6 +363,7 @@ module API
optional :name, type: String, desc: 'The name that will be assigned to the fork'
optional :description, type: String, desc: 'The description that will be assigned to the fork'
optional :visibility, type: String, values: Gitlab::VisibilityLevel.string_values, desc: 'The visibility of the fork'
+ optional :mr_default_target_self, Boolean, desc: 'Merge requests of this forked project targets itself by default'
end
post ':id/fork', feature_category: :source_code_management do
Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/20759')
diff --git a/lib/api/resource_access_tokens.rb b/lib/api/resource_access_tokens.rb
index f42acc6b2eb..e52f8fd9111 100644
--- a/lib/api/resource_access_tokens.rb
+++ b/lib/api/resource_access_tokens.rb
@@ -8,7 +8,7 @@ module API
feature_category :authentication_and_authorization
- %w[project].each do |source_type|
+ %w[project group].each do |source_type|
resource source_type.pluralize, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Get list of all access tokens for the specified resource' do
detail 'This feature was introduced in GitLab 13.9.'
@@ -23,8 +23,8 @@ module API
tokens = PersonalAccessTokensFinder.new({ user: resource.bots, impersonation: false }).execute.preload_users
- resource.project_members.load
- present paginate(tokens), with: Entities::ResourceAccessToken, project: resource
+ resource.members.load
+ present paginate(tokens), with: Entities::ResourceAccessToken, resource: resource
end
desc 'Revoke a resource access token' do
@@ -58,7 +58,7 @@ module API
requires :id, type: String, desc: "The #{source_type} ID"
requires :name, type: String, desc: "Resource access token name"
requires :scopes, type: Array[String], desc: "The permissions of the token"
- optional :access_level, type: Integer, desc: "The access level of the token in the project"
+ optional :access_level, type: Integer, desc: "The access level of the token in the #{source_type}"
optional :expires_at, type: Date, desc: "The expiration date of the token"
end
post ':id/access_tokens' do
@@ -71,7 +71,7 @@ module API
).execute
if token_response.success?
- present token_response.payload[:access_token], with: Entities::ResourceAccessTokenWithToken, project: resource
+ present token_response.payload[:access_token], with: Entities::ResourceAccessTokenWithToken, resource: resource
else
bad_request!(token_response.message)
end
diff --git a/lib/api/rubygem_packages.rb b/lib/api/rubygem_packages.rb
index 9ef6ec03a41..3effa370e84 100644
--- a/lib/api/rubygem_packages.rb
+++ b/lib/api/rubygem_packages.rb
@@ -66,9 +66,12 @@ module API
get "gems/:file_name", requirements: FILE_NAME_REQUIREMENTS do
authorize!(:read_package, user_project)
- package_file = ::Packages::PackageFile.for_rubygem_with_file_name(
- user_project, params[:file_name]
- ).last!
+ package_files = ::Packages::PackageFile
+ .for_rubygem_with_file_name(user_project, params[:file_name])
+
+ package_files = package_files.installable if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml)
+
+ package_file = package_files.last!
track_package_event('pull_package', :rubygems, project: user_project, namespace: user_project.namespace)
diff --git a/lib/api/search.rb b/lib/api/search.rb
index fbdbe3476db..60a7e944b43 100644
--- a/lib/api/search.rb
+++ b/lib/api/search.rb
@@ -4,7 +4,11 @@ module API
class Search < ::API::Base
include PaginationParams
- before { authenticate! }
+ before do
+ authenticate!
+
+ check_rate_limit!(:user_email_lookup, scope: [current_user]) if search_service.params.email_lookup?
+ end
feature_category :global_search
@@ -36,7 +40,7 @@ module API
}.freeze
end
- def search(additional_params = {})
+ def search_service(additional_params = {})
search_params = {
scope: params[:scope],
search: params[:search],
@@ -50,7 +54,11 @@ module API
sort: params[:sort]
}.merge(additional_params)
- results = SearchService.new(current_user, search_params).search_objects(preload_method)
+ SearchService.new(current_user, search_params)
+ end
+
+ def search(additional_params = {})
+ results = search_service(additional_params).search_objects(preload_method)
Gitlab::UsageDataCounters::SearchCounter.count(:all_searches)
diff --git a/lib/api/terraform/modules/v1/packages.rb b/lib/api/terraform/modules/v1/packages.rb
index ad5a4ae7ea6..970fdeba734 100644
--- a/lib/api/terraform/modules/v1/packages.rb
+++ b/lib/api/terraform/modules/v1/packages.rb
@@ -71,7 +71,11 @@ module API
def package_file
strong_memoize(:package_file) do
- package.package_files.first
+ if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml)
+ package.installable_package_files.first
+ else
+ package.package_files.first
+ end
end
end
end
diff --git a/lib/api/users.rb b/lib/api/users.rb
index ce0a0e9b502..eeb5244466a 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -142,11 +142,15 @@ 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)
+ check_rate_limit! :users_get_by_id, scope: current_user unless current_user.admin?
+ end
+
user = User.find_by(id: params[:id])
not_found!('User') unless user && can?(current_user, :read_user, user)
- opts = { with: current_user&.admin? ? Entities::UserDetailsWithAdmin : Entities::User, current_user: current_user }
+ opts = { with: current_user.admin? ? Entities::UserDetailsWithAdmin : Entities::User, current_user: current_user }
user, opts = with_custom_attributes(user, opts)
present user, opts
@@ -1072,7 +1076,7 @@ module API
attrs = declared_params(include_missing: false)
- service = ::Users::UpsertCreditCardValidationService.new(attrs).execute
+ service = ::Users::UpsertCreditCardValidationService.new(attrs, user).execute
if service.success?
present user.credit_card_validation, with: Entities::UserCreditCardValidations
diff --git a/lib/api/v3/github.rb b/lib/api/v3/github.rb
index d6c026963e1..c86b7785ce2 100644
--- a/lib/api/v3/github.rb
+++ b/lib/api/v3/github.rb
@@ -183,7 +183,9 @@ module API
params do
use :project_full_path
end
- get ':namespace/:project/pulls' do
+ # TODO Remove the custom Apdex SLO target `urgency: :low` when this endpoint has been optimised.
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/337269
+ get ':namespace/:project/pulls', urgency: :low do
user_project = find_project_with_access(params)
merge_requests = authorized_merge_requests_for_project(user_project)
@@ -236,7 +238,9 @@ module API
use :project_full_path
use :pagination
end
- get ':namespace/:project/branches' do
+ # TODO Remove the custom Apdex SLO target `urgency: :low` when this endpoint has been optimised.
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/337268
+ get ':namespace/:project/branches', urgency: :low do
user_project = find_project_with_access(params)
update_project_feature_usage_for(user_project)
diff --git a/lib/backup.rb b/lib/backup.rb
index 91682645a9a..95b595d885a 100644
--- a/lib/backup.rb
+++ b/lib/backup.rb
@@ -16,19 +16,6 @@ module Backup
end
end
- class RepositoryBackupError < Backup::Error
- attr_reader :container, :backup_repos_path
-
- def initialize(container, backup_repos_path)
- @container = container
- @backup_repos_path = backup_repos_path
- end
-
- def message
- "Failed to create compressed file '#{backup_repos_path}' when trying to backup the following paths: '#{container.disk_path}'"
- end
- end
-
class DatabaseBackupError < Backup::Error
attr_reader :config, :db_file_name
diff --git a/lib/backup/database.rb b/lib/backup/database.rb
index f07fd786b4b..a4ac404d245 100644
--- a/lib/backup/database.rb
+++ b/lib/backup/database.rb
@@ -61,7 +61,7 @@ module Backup
report_success(success)
progress.flush
- raise Backup::Error, 'Backup failed' unless success
+ raise DatabaseBackupError.new(config, db_file_name) unless success
end
def restore
diff --git a/lib/backup/files.rb b/lib/backup/files.rb
index 42cfff98239..4e51dcfb79e 100644
--- a/lib/backup/files.rb
+++ b/lib/backup/files.rb
@@ -37,7 +37,7 @@ module Backup
unless status == 0
puts output
- raise Backup::Error, 'Backup failed'
+ raise_custom_error
end
tar_cmd = [tar, exclude_dirs(:tar), %W[-C #{@backup_files_dir} -cf - .]].flatten
@@ -49,7 +49,7 @@ module Backup
end
unless pipeline_succeeded?(tar_status: status_list[0], gzip_status: status_list[1], output: output)
- raise Backup::Error, "Backup operation failed: #{output}"
+ raise_custom_error
end
end
@@ -143,5 +143,9 @@ module Backup
end
end
end
+
+ def raise_custom_error
+ raise FileBackupError.new(app_files_dir, backup_tarball)
+ end
end
end
diff --git a/lib/backup/gitaly_backup.rb b/lib/backup/gitaly_backup.rb
index b104beed39c..8ac09e94004 100644
--- a/lib/backup/gitaly_backup.rb
+++ b/lib/backup/gitaly_backup.rb
@@ -2,11 +2,17 @@
module Backup
# Backup and restores repositories using gitaly-backup
+ #
+ # gitaly-backup can work in parallel and accepts a list of repositories
+ # through input pipe using a specific json format for both backup and restore
class GitalyBackup
- def initialize(progress, parallel: nil, parallel_storage: nil)
+ # @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)
@progress = progress
- @parallel = parallel
- @parallel_storage = parallel_storage
+ @max_parallelism = max_parallelism
+ @storage_parallelism = storage_parallelism
end
def start(type)
@@ -22,20 +28,20 @@ module Backup
end
args = []
- args += ['-parallel', @parallel.to_s] if @parallel
- args += ['-parallel-storage', @parallel_storage.to_s] if @parallel_storage
+ args += ['-parallel', @max_parallelism.to_s] if @max_parallelism
+ args += ['-parallel-storage', @storage_parallelism.to_s] if @storage_parallelism
- @stdin, stdout, @thread = Open3.popen2(build_env, bin_path, command, '-path', backup_repos_path, *args)
+ @input_stream, stdout, @thread = Open3.popen2(build_env, bin_path, command, '-path', backup_repos_path, *args)
@out_reader = Thread.new do
IO.copy_stream(stdout, @progress)
end
end
- def wait
+ def finish!
return unless started?
- @stdin.close
+ @input_stream.close
[@thread, @out_reader].each(&:join)
status = @thread.value
@@ -49,12 +55,7 @@ module Backup
repository = repo_type.repository_for(container)
- @stdin.puts({
- storage_name: repository.storage,
- relative_path: repository.relative_path,
- gl_project_path: repository.gl_project_path,
- always_create: repo_type.project?
- }.merge(Gitlab::GitalyClient.connection_data(repository.storage)).to_json)
+ schedule_backup_job(repository, always_create: repo_type.project?)
end
def parallel_enqueue?
@@ -63,6 +64,24 @@ module Backup
private
+ # Schedule a new backup job through a non-blocking JSON based pipe protocol
+ #
+ # @see https://gitlab.com/gitlab-org/gitaly/-/blob/master/doc/gitaly-backup.md
+ def schedule_backup_job(repository, always_create:)
+ connection_params = Gitlab::GitalyClient.connection_data(repository.storage)
+
+ json_job = {
+ address: connection_params['address'],
+ token: connection_params['token'],
+ storage_name: repository.storage,
+ relative_path: repository.relative_path,
+ gl_project_path: repository.gl_project_path,
+ always_create: always_create
+ }.to_json
+
+ @input_stream.puts(json_job)
+ end
+
def build_env
{
'SSL_CERT_FILE' => OpenSSL::X509::DEFAULT_CERT_FILE,
diff --git a/lib/backup/gitaly_rpc_backup.rb b/lib/backup/gitaly_rpc_backup.rb
index baac4eb26ca..bbd83cd2157 100644
--- a/lib/backup/gitaly_rpc_backup.rb
+++ b/lib/backup/gitaly_rpc_backup.rb
@@ -23,7 +23,7 @@ module Backup
end
end
- def wait
+ def finish!
@type = nil
end
diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb
index 1bdc4965e5d..ed2e001cefc 100644
--- a/lib/backup/manager.rb
+++ b/lib/backup/manager.rb
@@ -2,7 +2,7 @@
module Backup
class Manager
- ARCHIVES_TO_BACKUP = %w[uploads builds artifacts pages lfs registry].freeze
+ 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'
diff --git a/lib/backup/packages.rb b/lib/backup/packages.rb
new file mode 100644
index 00000000000..7b6a8f086ed
--- /dev/null
+++ b/lib/backup/packages.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Backup
+ class Packages < Backup::Files
+ attr_reader :progress
+
+ def initialize(progress)
+ @progress = progress
+
+ super('packages', Settings.packages.storage_path, excludes: ['tmp'])
+ end
+ end
+end
diff --git a/lib/backup/repositories.rb b/lib/backup/repositories.rb
index 0b5a62529b4..4c39e58c87d 100644
--- a/lib/backup/repositories.rb
+++ b/lib/backup/repositories.rb
@@ -40,7 +40,7 @@ module Backup
raise errors.pop unless errors.empty?
ensure
- strategy.wait
+ strategy.finish!
end
def restore
@@ -48,7 +48,7 @@ module Backup
enqueue_consecutive
ensure
- strategy.wait
+ strategy.finish!
cleanup_snippets_without_repositories
restore_object_pools
diff --git a/lib/backup/terraform_state.rb b/lib/backup/terraform_state.rb
new file mode 100644
index 00000000000..5f71e18f1b4
--- /dev/null
+++ b/lib/backup/terraform_state.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Backup
+ class TerraformState < Backup::Files
+ attr_reader :progress
+
+ def initialize(progress)
+ @progress = progress
+
+ super('terraform_state', Settings.terraform_state.storage_path, excludes: ['tmp'])
+ end
+ end
+end
diff --git a/lib/banzai/filter/base_sanitization_filter.rb b/lib/banzai/filter/base_sanitization_filter.rb
index 7ea32c4b1e7..4e350a59fa0 100644
--- a/lib/banzai/filter/base_sanitization_filter.rb
+++ b/lib/banzai/filter/base_sanitization_filter.rb
@@ -42,7 +42,7 @@ module Banzai
# Allow any protocol in `a` elements
# and then remove links with unsafe protocols
allowlist[:protocols].delete('a')
- allowlist[:transformers].push(self.class.method(:remove_unsafe_links))
+ allowlist[:transformers].push(self.class.method(:sanitize_unsafe_links))
# Remove `rel` attribute from `a` elements
allowlist[:transformers].push(self.class.remove_rel)
diff --git a/lib/banzai/filter/footnote_filter.rb b/lib/banzai/filter/footnote_filter.rb
index 00a38f02141..537b7c80d91 100644
--- a/lib/banzai/filter/footnote_filter.rb
+++ b/lib/banzai/filter/footnote_filter.rb
@@ -7,13 +7,14 @@ module Banzai
# Footnotes are supported in CommonMark. However we were stripping
# the ids during sanitization. Those are now allowed.
#
- # Footnotes are numbered the same - the first one has `id=fn1`, the
- # second is `id=fn2`, etc. In order to allow footnotes when rendering
- # multiple markdown blocks on a page, we need to make each footnote
- # reference unique.
- #
+ # Footnotes are numbered as an increasing integer starting at `1`.
+ # The `id` associated with a footnote is based on the footnote reference
+ # string. For example, `[^foot]` will generate `id="fn-foot"`.
+ # In order to allow footnotes when rendering multiple markdown blocks
+ # on a page, we need to make each footnote reference unique.
+
# This filter adds a random number to each footnote (the same number
- # can be used for a single render). So you get `id=fn1-4335` and `id=fn2-4335`.
+ # can be used for a single render). So you get `id=fn-1-4335` and `id=fn-foot-4335`.
#
class FootnoteFilter < HTML::Pipeline::Filter
FOOTNOTE_ID_PREFIX = 'fn-'
@@ -26,53 +27,24 @@ module Banzai
CSS_FOOTNOTE = 'sup > a[data-footnote-ref]'
XPATH_FOOTNOTE = Gitlab::Utils::Nokogiri.css_to_xpath(CSS_FOOTNOTE).freeze
- # only needed when feature flag use_cmark_renderer is turned off
- INTEGER_PATTERN = /\A\d+\z/.freeze
- FOOTNOTE_ID_PREFIX_OLD = 'fn'
- FOOTNOTE_LINK_ID_PREFIX_OLD = 'fnref'
- FOOTNOTE_LI_REFERENCE_PATTERN_OLD = /\A#{FOOTNOTE_ID_PREFIX_OLD}\d+\z/.freeze
- FOOTNOTE_LINK_REFERENCE_PATTERN_OLD = /\A#{FOOTNOTE_LINK_ID_PREFIX_OLD}\d+\z/.freeze
- FOOTNOTE_START_NUMBER = 1
- CSS_SECTION_OLD = "ol > li[id=#{FOOTNOTE_ID_PREFIX_OLD}#{FOOTNOTE_START_NUMBER}]"
- XPATH_SECTION_OLD = Gitlab::Utils::Nokogiri.css_to_xpath(CSS_SECTION_OLD).freeze
-
def call
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- # Sanitization stripped off the section class - add it back in
- return doc unless section_node = doc.at_xpath(XPATH_SECTION)
+ # Sanitization stripped off the section class - add it back in
+ return doc unless section_node = doc.at_xpath(XPATH_SECTION)
- section_node.append_class('footnotes')
- else
- return doc unless first_footnote = doc.at_xpath(XPATH_SECTION_OLD)
- return doc unless first_footnote.parent
-
- first_footnote.parent.wrap('<section class="footnotes">')
- end
+ section_node.append_class('footnotes')
rand_suffix = "-#{random_number}"
modified_footnotes = {}
- xpath_footnote = if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- XPATH_FOOTNOTE
- else
- Gitlab::Utils::Nokogiri.css_to_xpath('sup > a[id]')
- end
-
- doc.xpath(xpath_footnote).each do |link_node|
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- ref_num = link_node[:id].delete_prefix(FOOTNOTE_LINK_ID_PREFIX)
- ref_num.gsub!(/[[:punct:]]/, '\\\\\&')
- else
- ref_num = link_node[:id].delete_prefix(FOOTNOTE_LINK_ID_PREFIX_OLD)
- end
+ doc.xpath(XPATH_FOOTNOTE).each do |link_node|
+ ref_num = link_node[:id].delete_prefix(FOOTNOTE_LINK_ID_PREFIX)
+ ref_num.gsub!(/[[:punct:]]/, '\\\\\&')
- css = Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml) ? "section[data-footnotes] li[id=#{fn_id(ref_num)}]" : "li[id=#{fn_id(ref_num)}]"
+ css = "section[data-footnotes] li[id=#{fn_id(ref_num)}]"
node_xpath = Gitlab::Utils::Nokogiri.css_to_xpath(css)
footnote_node = doc.at_xpath(node_xpath)
if footnote_node || modified_footnotes[ref_num]
- next if Feature.disabled?(:use_cmark_renderer, default_enabled: :yaml) && !INTEGER_PATTERN.match?(ref_num)
-
link_node[:href] += rand_suffix
link_node[:id] += rand_suffix
@@ -103,13 +75,11 @@ module Banzai
end
def fn_id(num)
- prefix = Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml) ? FOOTNOTE_ID_PREFIX : FOOTNOTE_ID_PREFIX_OLD
- "#{prefix}#{num}"
+ "#{FOOTNOTE_ID_PREFIX}#{num}"
end
def fnref_id(num)
- prefix = Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml) ? FOOTNOTE_LINK_ID_PREFIX : FOOTNOTE_LINK_ID_PREFIX_OLD
- "#{prefix}#{num}"
+ "#{FOOTNOTE_LINK_ID_PREFIX}#{num}"
end
end
end
diff --git a/lib/banzai/filter/markdown_engines/common_mark.rb b/lib/banzai/filter/markdown_engines/common_mark.rb
index dc94e3c925a..cf368e28beb 100644
--- a/lib/banzai/filter/markdown_engines/common_mark.rb
+++ b/lib/banzai/filter/markdown_engines/common_mark.rb
@@ -4,8 +4,8 @@
# This module is used in Banzai::Filter::MarkdownFilter.
# Used gem is `commonmarker` which is a ruby wrapper for libcmark (CommonMark parser)
# including GitHub's GFM extensions.
+# We now utilize the renderer built in `C`, rather than the ruby based renderer.
# Homepage: https://github.com/gjtorikian/commonmarker
-
module Banzai
module Filter
module MarkdownEngines
@@ -22,57 +22,29 @@ module Banzai
:VALIDATE_UTF8 # replace illegal sequences with the replacement character U+FFFD.
].freeze
- RENDER_OPTIONS_C = [
+ RENDER_OPTIONS = [
:GITHUB_PRE_LANG, # use GitHub-style <pre lang> for fenced code blocks.
:FOOTNOTES, # render footnotes.
:FULL_INFO_STRING, # include full info strings of code blocks in separate attribute.
:UNSAFE # allow raw/custom HTML and unsafe links.
].freeze
- # The `:GITHUB_PRE_LANG` option is not used intentionally because
- # it renders a fence block with language as `<pre lang="LANG"><code>some code\n</code></pre>`
- # while GitLab's syntax is `<pre><code lang="LANG">some code\n</code></pre>`.
- # If in the future the syntax is about to be made GitHub-compatible, please, add `:GITHUB_PRE_LANG` render option below
- # and remove `code_block` method from `lib/banzai/renderer/common_mark/html.rb`.
- RENDER_OPTIONS_RUBY = [
- # as of commonmarker 0.18.0, we need to use :UNSAFE to get the same as the original :DEFAULT
- # https://github.com/gjtorikian/commonmarker/pull/81
- :UNSAFE # allow raw/custom HTML and unsafe links.
- ].freeze
-
def initialize(context)
@context = context
- @renderer = Banzai::Renderer::CommonMark::HTML.new(options: render_options) if Feature.disabled?(:use_cmark_renderer, default_enabled: :yaml)
end
def render(text)
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- CommonMarker.render_html(text, render_options, extensions)
- else
- doc = CommonMarker.render_doc(text, PARSE_OPTIONS, extensions)
-
- @renderer.render(doc)
- end
+ CommonMarker.render_html(text, render_options, EXTENSIONS)
end
private
- def extensions
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- EXTENSIONS
- else
- EXTENSIONS + [
- :tagfilter # strips out several "unsafe" HTML tags from being used: https://github.github.com/gfm/#disallowed-raw-html-extension-
- ].freeze
- end
- end
-
def render_options
@context[:no_sourcepos] ? render_options_no_sourcepos : render_options_sourcepos
end
def render_options_no_sourcepos
- Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml) ? RENDER_OPTIONS_C : RENDER_OPTIONS_RUBY
+ RENDER_OPTIONS
end
def render_options_sourcepos
diff --git a/lib/banzai/filter/markdown_post_escape_filter.rb b/lib/banzai/filter/markdown_post_escape_filter.rb
index b979b7573ae..09ae09a22ae 100644
--- a/lib/banzai/filter/markdown_post_escape_filter.rb
+++ b/lib/banzai/filter/markdown_post_escape_filter.rb
@@ -8,8 +8,10 @@ module Banzai
NOT_LITERAL_REGEX = %r{#{LITERAL_KEYWORD}-((%5C|\\).+?)-#{LITERAL_KEYWORD}}.freeze
SPAN_REGEX = %r{<span>(.*?)</span>}.freeze
- CSS_A = 'a'
- XPATH_A = Gitlab::Utils::Nokogiri.css_to_xpath(CSS_A).freeze
+ CSS_A = 'a'
+ XPATH_A = Gitlab::Utils::Nokogiri.css_to_xpath(CSS_A).freeze
+ CSS_LANG_TAG = 'pre'
+ XPATH_LANG_TAG = Gitlab::Utils::Nokogiri.css_to_xpath(CSS_LANG_TAG).freeze
def call
return doc unless result[:escaped_literals]
@@ -32,22 +34,12 @@ module Banzai
node.attributes['title'].value = node.attributes['title'].value.gsub(SPAN_REGEX, '\1') if node.attributes['title']
end
- doc.xpath(lang_tag).each do |node|
+ doc.xpath(XPATH_LANG_TAG).each do |node|
node.attributes['lang'].value = node.attributes['lang'].value.gsub(SPAN_REGEX, '\1') if node.attributes['lang']
end
doc
end
-
- private
-
- def lang_tag
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- Gitlab::Utils::Nokogiri.css_to_xpath('pre')
- else
- Gitlab::Utils::Nokogiri.css_to_xpath('code')
- end
- end
end
end
end
diff --git a/lib/banzai/filter/plantuml_filter.rb b/lib/banzai/filter/plantuml_filter.rb
index 3f160960d23..68a99702d6f 100644
--- a/lib/banzai/filter/plantuml_filter.rb
+++ b/lib/banzai/filter/plantuml_filter.rb
@@ -25,12 +25,7 @@ module Banzai
private
def lang_tag
- @lang_tag ||=
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- Gitlab::Utils::Nokogiri.css_to_xpath('pre[lang="plantuml"] > code').freeze
- else
- Gitlab::Utils::Nokogiri.css_to_xpath('pre > code[lang="plantuml"]').freeze
- end
+ @lang_tag ||= Gitlab::Utils::Nokogiri.css_to_xpath('pre[lang="plantuml"] > code').freeze
end
def settings
diff --git a/lib/banzai/filter/references/abstract_reference_filter.rb b/lib/banzai/filter/references/abstract_reference_filter.rb
index 7a23326bafa..a34519799d5 100644
--- a/lib/banzai/filter/references/abstract_reference_filter.rb
+++ b/lib/banzai/filter/references/abstract_reference_filter.rb
@@ -216,6 +216,8 @@ module Banzai
url_for_object_cached(object, parent)
end
+ url.chomp!(matches[:format]) if matches.names.include?("format")
+
content = link_content || object_link_text(object, matches)
link = %(<a href="#{url}" #{data}
diff --git a/lib/banzai/filter/sanitization_filter.rb b/lib/banzai/filter/sanitization_filter.rb
index d5f45ff7689..fe189b1b0c9 100644
--- a/lib/banzai/filter/sanitization_filter.rb
+++ b/lib/banzai/filter/sanitization_filter.rb
@@ -28,12 +28,10 @@ module Banzai
allowlist[:attributes]['li'] = %w[id]
allowlist[:transformers].push(self.class.remove_non_footnote_ids)
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- # Allow section elements with data-footnotes attribute
- allowlist[:elements].push('section')
- allowlist[:attributes]['section'] = %w(data-footnotes)
- allowlist[:attributes]['a'].push('data-footnote-ref', 'data-footnote-backref')
- end
+ # Allow section elements with data-footnotes attribute
+ allowlist[:elements].push('section')
+ allowlist[:attributes]['section'] = %w(data-footnotes)
+ allowlist[:attributes]['a'].push('data-footnote-ref', 'data-footnote-backref')
allowlist
end
@@ -61,13 +59,8 @@ module Banzai
return unless node.name == 'a' || node.name == 'li'
return unless node.has_attribute?('id')
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- return if node.name == 'a' && node['id'] =~ Banzai::Filter::FootnoteFilter::FOOTNOTE_LINK_REFERENCE_PATTERN
- return if node.name == 'li' && node['id'] =~ Banzai::Filter::FootnoteFilter::FOOTNOTE_LI_REFERENCE_PATTERN
- else
- return if node.name == 'a' && node['id'] =~ Banzai::Filter::FootnoteFilter::FOOTNOTE_LINK_REFERENCE_PATTERN_OLD
- return if node.name == 'li' && node['id'] =~ Banzai::Filter::FootnoteFilter::FOOTNOTE_LI_REFERENCE_PATTERN_OLD
- end
+ return if node.name == 'a' && node['id'] =~ Banzai::Filter::FootnoteFilter::FOOTNOTE_LINK_REFERENCE_PATTERN
+ return if node.name == 'li' && node['id'] =~ Banzai::Filter::FootnoteFilter::FOOTNOTE_LI_REFERENCE_PATTERN
node.remove_attribute('id')
end
diff --git a/lib/banzai/filter/syntax_highlight_filter.rb b/lib/banzai/filter/syntax_highlight_filter.rb
index 9fcfcf4acc4..07f82c98666 100644
--- a/lib/banzai/filter/syntax_highlight_filter.rb
+++ b/lib/banzai/filter/syntax_highlight_filter.rb
@@ -14,7 +14,7 @@ module Banzai
LANG_PARAMS_DELIMITER = ':'
LANG_PARAMS_ATTR = 'data-lang-params'
- CSS = 'pre:not([data-math-style]):not([data-mermaid-style]):not([data-kroki-style]) > code'
+ CSS = 'pre:not([data-math-style]):not([data-mermaid-style]):not([data-kroki-style]) > code:only-child'
XPATH = Gitlab::Utils::Nokogiri.css_to_xpath(CSS).freeze
def call
@@ -70,11 +70,11 @@ module Banzai
private
def parse_lang_params(node)
- node = node.parent if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
+ node = node.parent
# Commonmarker's FULL_INFO_STRING render option works with the space delimiter.
# But the current behavior of GitLab's markdown renderer is different - it grabs everything as the single
- # line, including language and its options. To keep backward compatability, we have to parse the old format and
+ # line, including language and its options. To keep backward compatibility, we have to parse the old format and
# merge with the new one.
#
# Behaviors before separating language and its parameters:
@@ -91,11 +91,7 @@ module Banzai
return unless language
language, language_params = language.split(LANG_PARAMS_DELIMITER, 2)
-
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- language_params = [node.attr('data-meta'), language_params].compact.join(' ')
- end
-
+ language_params = [node.attr('data-meta'), language_params].compact.join(' ')
formatted_language_params = format_language_params(language_params)
[language, formatted_language_params]
@@ -110,8 +106,8 @@ module Banzai
(Rouge::Lexer.find(language) || Rouge::Lexers::PlainText).new
end
+ # Replace the parent `pre` element with the entire highlighted block
def replace_parent_pre_element(node, highlighted)
- # Replace the parent `pre` element with the entire highlighted block
node.parent.replace(highlighted)
end
diff --git a/lib/banzai/reference_parser/merge_request_parser.rb b/lib/banzai/reference_parser/merge_request_parser.rb
index 1664fa1f9ff..3e28f06b783 100644
--- a/lib/banzai/reference_parser/merge_request_parser.rb
+++ b/lib/banzai/reference_parser/merge_request_parser.rb
@@ -8,8 +8,6 @@ module Banzai
self.reference_type = :merge_request
def nodes_visible_to_user(user, nodes)
- return super if Feature.disabled?(:optimize_merge_request_parser, user, default_enabled: :yaml)
-
merge_request_nodes = nodes.select { |node| node.has_attribute?(self.class.data_attribute) }
records = projects_for_nodes(merge_request_nodes)
diff --git a/lib/banzai/renderer/common_mark/html.rb b/lib/banzai/renderer/common_mark/html.rb
deleted file mode 100644
index d9a2d9a9564..00000000000
--- a/lib/banzai/renderer/common_mark/html.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-# Remove this entire file when removing `use_cmark_renderer` feature flag and switching to the CMARK html renderer.
-# https://gitlab.com/gitlab-org/gitlab/-/issues/345744
-module Banzai
- module Renderer
- module CommonMark
- class HTML < CommonMarker::HtmlRenderer
- def code_block(node)
- block do
- out("<pre#{sourcepos(node)}><code")
- out(' lang="', node.fence_info, '"') if node.fence_info.present?
- out('>')
- out(escape_html(node.string_content))
- out('</code></pre>')
- end
- end
- end
- end
- end
-end
diff --git a/lib/bulk_imports/common/extractors/ndjson_extractor.rb b/lib/bulk_imports/common/extractors/ndjson_extractor.rb
index ecd7c08bd25..04febebff8e 100644
--- a/lib/bulk_imports/common/extractors/ndjson_extractor.rb
+++ b/lib/bulk_imports/common/extractors/ndjson_extractor.rb
@@ -4,49 +4,47 @@ module BulkImports
module Common
module Extractors
class NdjsonExtractor
- include Gitlab::ImportExport::CommandLineUtil
- include Gitlab::Utils::StrongMemoize
-
def initialize(relation:)
@relation = relation
- @tmp_dir = Dir.mktmpdir
+ @tmpdir = Dir.mktmpdir
end
def extract(context)
- download_service(tmp_dir, context).execute
- decompression_service(tmp_dir).execute
- relations = ndjson_reader(tmp_dir).consume_relation('', relation)
+ download_service(context).execute
+ decompression_service.execute
+
+ records = ndjson_reader.consume_relation('', relation)
- BulkImports::Pipeline::ExtractedData.new(data: relations)
+ BulkImports::Pipeline::ExtractedData.new(data: records)
end
- def remove_tmp_dir
- FileUtils.remove_entry(tmp_dir)
+ def remove_tmpdir
+ FileUtils.remove_entry(tmpdir) if Dir.exist?(tmpdir)
end
private
- attr_reader :relation, :tmp_dir
+ attr_reader :relation, :tmpdir
def filename
- @filename ||= "#{relation}.ndjson.gz"
+ "#{relation}.ndjson.gz"
end
- def download_service(tmp_dir, context)
+ def download_service(context)
@download_service ||= BulkImports::FileDownloadService.new(
configuration: context.configuration,
relative_url: context.entity.relation_download_url_path(relation),
- dir: tmp_dir,
+ tmpdir: tmpdir,
filename: filename
)
end
- def decompression_service(tmp_dir)
- @decompression_service ||= BulkImports::FileDecompressionService.new(dir: tmp_dir, filename: filename)
+ def decompression_service
+ @decompression_service ||= BulkImports::FileDecompressionService.new(tmpdir: tmpdir, filename: filename)
end
- def ndjson_reader(tmp_dir)
- @ndjson_reader ||= Gitlab::ImportExport::Json::NdjsonReader.new(tmp_dir)
+ def ndjson_reader
+ @ndjson_reader ||= Gitlab::ImportExport::Json::NdjsonReader.new(tmpdir)
end
end
end
diff --git a/lib/bulk_imports/common/pipelines/uploads_pipeline.rb b/lib/bulk_imports/common/pipelines/uploads_pipeline.rb
index 2ac4e533c1d..d7b9d6920ea 100644
--- a/lib/bulk_imports/common/pipelines/uploads_pipeline.rb
+++ b/lib/bulk_imports/common/pipelines/uploads_pipeline.rb
@@ -15,7 +15,7 @@ module BulkImports
decompression_service.execute
extraction_service.execute
- upload_file_paths = Dir.glob(File.join(tmp_dir, '**', '*'))
+ upload_file_paths = Dir.glob(File.join(tmpdir, '**', '*'))
BulkImports::Pipeline::ExtractedData.new(data: upload_file_paths)
end
@@ -37,7 +37,7 @@ module BulkImports
end
def after_run(_)
- FileUtils.remove_entry(tmp_dir) if Dir.exist?(tmp_dir)
+ FileUtils.remove_entry(tmpdir) if Dir.exist?(tmpdir)
end
private
@@ -46,17 +46,17 @@ module BulkImports
BulkImports::FileDownloadService.new(
configuration: context.configuration,
relative_url: context.entity.relation_download_url_path(relation),
- dir: tmp_dir,
+ tmpdir: tmpdir,
filename: targz_filename
)
end
def decompression_service
- BulkImports::FileDecompressionService.new(dir: tmp_dir, filename: targz_filename)
+ BulkImports::FileDecompressionService.new(tmpdir: tmpdir, filename: targz_filename)
end
def extraction_service
- BulkImports::ArchiveExtractionService.new(tmpdir: tmp_dir, filename: tar_filename)
+ BulkImports::ArchiveExtractionService.new(tmpdir: tmpdir, filename: tar_filename)
end
def relation
@@ -71,8 +71,8 @@ module BulkImports
"#{tar_filename}.gz"
end
- def tmp_dir
- @tmp_dir ||= Dir.mktmpdir('bulk_imports')
+ def tmpdir
+ @tmpdir ||= Dir.mktmpdir('bulk_imports')
end
def file_uploader
diff --git a/lib/bulk_imports/ndjson_pipeline.rb b/lib/bulk_imports/ndjson_pipeline.rb
index d5475a8b324..d85e51984df 100644
--- a/lib/bulk_imports/ndjson_pipeline.rb
+++ b/lib/bulk_imports/ndjson_pipeline.rb
@@ -68,7 +68,7 @@ module BulkImports
end
def after_run(_)
- extractor.remove_tmp_dir if extractor.respond_to?(:remove_tmp_dir)
+ extractor.remove_tmpdir if extractor.respond_to?(:remove_tmpdir)
end
def relation_class(relation_key)
diff --git a/lib/bulk_imports/projects/pipelines/project_attributes_pipeline.rb b/lib/bulk_imports/projects/pipelines/project_attributes_pipeline.rb
index 4d742225ff7..2492a023cbe 100644
--- a/lib/bulk_imports/projects/pipelines/project_attributes_pipeline.rb
+++ b/lib/bulk_imports/projects/pipelines/project_attributes_pipeline.rb
@@ -8,15 +8,16 @@ module BulkImports
transformer ::BulkImports::Common::Transformers::ProhibitedAttributesTransformer
- def extract(context)
- download_service(tmp_dir, context).execute
- decompression_service(tmp_dir).execute
+ def extract(_context)
+ download_service.execute
+ decompression_service.execute
+
project_attributes = json_decode(json_attributes)
BulkImports::Pipeline::ExtractedData.new(data: project_attributes)
end
- def transform(_, data)
+ def transform(_context, data)
subrelations = config.portable_relations_tree.keys.map(&:to_s)
Gitlab::ImportExport::AttributeCleaner.clean(
@@ -26,42 +27,42 @@ module BulkImports
).except(*subrelations)
end
- def load(_, data)
+ def load(_context, data)
portable.assign_attributes(data)
portable.reconcile_shared_runners_setting!
portable.drop_visibility_level!
portable.save!
end
- def after_run(_)
- FileUtils.remove_entry(tmp_dir)
+ def after_run(_context)
+ FileUtils.remove_entry(tmpdir) if Dir.exist?(tmpdir)
end
def json_attributes
- @json_attributes ||= File.read(File.join(tmp_dir, filename))
+ @json_attributes ||= File.read(File.join(tmpdir, filename))
end
private
- def tmp_dir
- @tmp_dir ||= Dir.mktmpdir
+ def tmpdir
+ @tmpdir ||= Dir.mktmpdir('bulk_imports')
end
def config
@config ||= BulkImports::FileTransfer.config_for(portable)
end
- def download_service(tmp_dir, context)
+ def download_service
@download_service ||= BulkImports::FileDownloadService.new(
configuration: context.configuration,
- relative_url: context.entity.relation_download_url_path(BulkImports::FileTransfer::BaseConfig::SELF_RELATION),
- dir: tmp_dir,
+ relative_url: context.entity.relation_download_url_path(BulkImports::FileTransfer::BaseConfig::SELF_RELATION),
+ tmpdir: tmpdir,
filename: compressed_filename
)
end
- def decompression_service(tmp_dir)
- @decompression_service ||= BulkImports::FileDecompressionService.new(dir: tmp_dir, filename: compressed_filename)
+ def decompression_service
+ @decompression_service ||= BulkImports::FileDecompressionService.new(tmpdir: tmpdir, filename: compressed_filename)
end
def compressed_filename
diff --git a/lib/feature.rb b/lib/feature.rb
index f301f206b46..12b4ef07dd6 100644
--- a/lib/feature.rb
+++ b/lib/feature.rb
@@ -29,6 +29,15 @@ class Feature
class << self
delegate :group, to: :flipper
+ def feature_flags_available?
+ # When the DBMS is not available, an exception (e.g. PG::ConnectionBad) is raised
+ active_db_connection = ActiveRecord::Base.connection.active? rescue false # rubocop:disable Database/MultipleDatabases
+
+ active_db_connection && Feature::FlipperFeature.table_exists?
+ rescue ActiveRecord::NoDatabaseError
+ false
+ end
+
def all
flipper.features.to_a
end
diff --git a/lib/gitlab.rb b/lib/gitlab.rb
index d93d7acbaad..2449554d3c0 100644
--- a/lib/gitlab.rb
+++ b/lib/gitlab.rb
@@ -1,10 +1,15 @@
# frozen_string_literal: true
require 'pathname'
+require 'forwardable'
+
+require_relative 'gitlab_edition'
module Gitlab
- def self.root
- Pathname.new(File.expand_path('..', __dir__))
+ class << self
+ extend Forwardable
+
+ def_delegators :GitlabEdition, :root, :extensions, :ee?, :ee, :jh?, :jh
end
def self.version_info
@@ -89,47 +94,6 @@ module Gitlab
Rails.env.development? || Rails.env.test?
end
- def self.extensions
- if jh?
- %w[ee jh]
- elsif ee?
- %w[ee]
- else
- %w[]
- end
- end
-
- def self.ee?
- @is_ee ||=
- # We use this method when the Rails environment is not loaded. This
- # means that checking the presence of the License class could result in
- # this method returning `false`, even for an EE installation.
- #
- # The `FOSS_ONLY` is always `string` or `nil`
- # Thus the nil or empty string will result
- # in using default value: false
- #
- # The behavior needs to be synchronised with
- # config/helpers/is_ee_env.js
- root.join('ee/app/models/license.rb').exist? &&
- !%w[true 1].include?(ENV['FOSS_ONLY'].to_s)
- end
-
- def self.jh?
- @is_jh ||=
- ee? &&
- root.join('jh').exist? &&
- !%w[true 1].include?(ENV['EE_ONLY'].to_s)
- end
-
- def self.ee
- yield if ee?
- end
-
- def self.jh
- yield if jh?
- end
-
def self.http_proxy_env?
HTTP_PROXY_ENV_VARS.any? { |name| ENV[name] }
end
diff --git a/lib/gitlab/anonymous_session.rb b/lib/gitlab/anonymous_session.rb
index e58240e16b4..6904945a755 100644
--- a/lib/gitlab/anonymous_session.rb
+++ b/lib/gitlab/anonymous_session.rb
@@ -2,14 +2,12 @@
module Gitlab
class AnonymousSession
- include ::Gitlab::Redis::SessionsStoreHelper
-
def initialize(remote_ip)
@remote_ip = remote_ip
end
def count_session_ip
- redis_store_class.with do |redis|
+ Gitlab::Redis::Sessions.with do |redis|
redis.pipelined do |pipeline|
pipeline.incr(session_lookup_name)
pipeline.expire(session_lookup_name, 24.hours)
@@ -18,13 +16,13 @@ module Gitlab
end
def session_count
- redis_store_class.with do |redis|
+ Gitlab::Redis::Sessions.with do |redis|
redis.get(session_lookup_name).to_i
end
end
def cleanup_session_per_ip_count
- redis_store_class.with do |redis|
+ Gitlab::Redis::Sessions.with do |redis|
redis.del(session_lookup_name)
end
end
diff --git a/lib/gitlab/application_rate_limiter.rb b/lib/gitlab/application_rate_limiter.rb
index fb90ad9e275..12f1b15f820 100644
--- a/lib/gitlab/application_rate_limiter.rb
+++ b/lib/gitlab/application_rate_limiter.rb
@@ -49,9 +49,15 @@ module Gitlab
group_testing_hook: { threshold: 5, interval: 1.minute },
profile_add_new_email: { threshold: 5, interval: 1.minute },
web_hook_calls: { interval: 1.minute },
+ users_get_by_id: { threshold: 10, interval: 1.minute },
+ username_exists: { threshold: 20, interval: 1.minute },
+ user_sign_up: { threshold: 20, interval: 1.minute },
profile_resend_email_confirmation: { threshold: 5, interval: 1.minute },
+ 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 }
+ auto_rollback_deployment: { threshold: 1, interval: 3.minutes },
+ user_email_lookup: { threshold: -> { application_settings.user_email_lookup_limit }, interval: 1.minute },
+ gitlab_shell_operation: { threshold: 600, interval: 1.minute }
}.freeze
end
@@ -59,7 +65,7 @@ module Gitlab
# be throttled.
#
# @param key [Symbol] Key attribute registered in `.rate_limits`
- # @param scope [Array<ActiveRecord>] Array of ActiveRecord models to scope throttling to a specific request (e.g. per user per project)
+ # @param scope [Array<ActiveRecord>] Array of ActiveRecord models, Strings or Symbols to scope throttling to a specific request (e.g. per user per project)
# @param threshold [Integer] Optional threshold value to override default one registered in `.rate_limits`
# @param users_allowlist [Array<String>] Optional list of usernames to exclude from the limit. This param will only be functional if Scope includes a current user.
# @param peek [Boolean] Optional. When true the key will not be incremented but the current throttled state will be returned.
diff --git a/lib/gitlab/asciidoc/syntax_highlighter/html_pipeline_adapter.rb b/lib/gitlab/asciidoc/syntax_highlighter/html_pipeline_adapter.rb
index 3ada3f947ee..b2e1c9e2379 100644
--- a/lib/gitlab/asciidoc/syntax_highlighter/html_pipeline_adapter.rb
+++ b/lib/gitlab/asciidoc/syntax_highlighter/html_pipeline_adapter.rb
@@ -7,11 +7,7 @@ module Gitlab
register_for 'gitlab-html-pipeline'
def format(node, lang, opts)
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- %(<pre #{lang ? %[lang="#{lang}"] : ''}><code>#{node.content}</code></pre>)
- else
- %(<pre><code #{lang ? %[ lang="#{lang}"] : ''}>#{node.content}</code></pre>)
- end
+ %(<pre #{lang ? %[lang="#{lang}"] : ''}><code>#{node.content}</code></pre>)
end
end
end
diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb
index 3e982168339..38bc50a2cb8 100644
--- a/lib/gitlab/auth.rb
+++ b/lib/gitlab/auth.rb
@@ -84,7 +84,7 @@ module Gitlab
Gitlab::Auth::UniqueIpsLimiter.limit_user! do
user = User.by_login(login)
- break if user && !can_user_login_with_non_expired_password?(user)
+ break if user && !user.can_log_in_with_non_expired_password?
authenticators = []
@@ -187,7 +187,7 @@ module Gitlab
if valid_oauth_token?(token)
user = User.id_in(token.resource_owner_id).first
- return unless user && can_user_login_with_non_expired_password?(user)
+ return unless user && user.can_log_in_with_non_expired_password?
Gitlab::Auth::Result.new(user, nil, :oauth, abilities_for_scopes(token.scopes))
end
@@ -210,7 +210,7 @@ module Gitlab
return unless token_bot_in_project?(token.user, project) || token_bot_in_group?(token.user, project)
end
- if can_user_login_with_non_expired_password?(token.user) || token.user.project_bot?
+ if token.user.can_log_in_with_non_expired_password? || token.user.project_bot?
Gitlab::Auth::Result.new(token.user, nil, :personal_access_token, abilities_for_scopes(token.scopes))
end
end
@@ -309,7 +309,7 @@ module Gitlab
return unless build.project.builds_enabled?
if build.user
- return unless can_user_login_with_non_expired_password?(build.user) || (build.user.project_bot? && build.project.bots&.include?(build.user))
+ return unless build.user.can_log_in_with_non_expired_password? || (build.user.project_bot? && build.project.bots&.include?(build.user))
# If user is assigned to build, use restricted credentials of user
Gitlab::Auth::Result.new(build.user, build.project, :build, build_authentication_abilities)
@@ -406,10 +406,6 @@ module Gitlab
user.increment_failed_attempts!
end
-
- def can_user_login_with_non_expired_password?(user)
- user.can?(:log_in) && !user.password_expired_if_applicable?
- end
end
end
end
diff --git a/lib/gitlab/auth/auth_finders.rb b/lib/gitlab/auth/auth_finders.rb
index 9c33a5fc872..ecda96af403 100644
--- a/lib/gitlab/auth/auth_finders.rb
+++ b/lib/gitlab/auth/auth_finders.rb
@@ -165,7 +165,7 @@ module Gitlab
authorization_token, _options = token_and_options(current_request)
- ::Clusters::AgentToken.find_by_token(authorization_token)
+ ::Clusters::AgentToken.active.find_by_token(authorization_token)
end
def find_runner_from_token
diff --git a/lib/gitlab/auth/ldap/config.rb b/lib/gitlab/auth/ldap/config.rb
index 7bfe776fed0..82c6411c712 100644
--- a/lib/gitlab/auth/ldap/config.rb
+++ b/lib/gitlab/auth/ldap/config.rb
@@ -206,7 +206,8 @@ module Gitlab
def base_options
{
host: options['host'],
- port: options['port']
+ port: options['port'],
+ hosts: options['hosts']
}
end
diff --git a/lib/gitlab/auth/o_auth/user.rb b/lib/gitlab/auth/o_auth/user.rb
index feb5fea4c85..9f142727ebb 100644
--- a/lib/gitlab/auth/o_auth/user.rb
+++ b/lib/gitlab/auth/o_auth/user.rb
@@ -230,8 +230,8 @@ module Gitlab
name: name.strip.presence || valid_username,
username: valid_username,
email: email,
- password: auth_hash.password,
- password_confirmation: auth_hash.password,
+ password: Gitlab::Password.test_default(21),
+ password_confirmation: Gitlab::Password.test_default(21),
password_automatically_set: true
}
end
diff --git a/lib/gitlab/background_migration/backfill_ci_namespace_mirrors.rb b/lib/gitlab/background_migration/backfill_ci_namespace_mirrors.rb
new file mode 100644
index 00000000000..2247747ba08
--- /dev/null
+++ b/lib/gitlab/background_migration/backfill_ci_namespace_mirrors.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # A job to create ci_namespace_mirrors entries in batches
+ class BackfillCiNamespaceMirrors
+ class Namespace < ActiveRecord::Base # rubocop:disable Style/Documentation
+ include ::EachBatch
+
+ self.table_name = 'namespaces'
+ self.inheritance_column = nil
+
+ scope :base_query, -> do
+ select(:id, :parent_id)
+ end
+ end
+
+ PAUSE_SECONDS = 0.1
+ SUB_BATCH_SIZE = 500
+
+ def perform(start_id, end_id)
+ batch_query = Namespace.base_query.where(id: start_id..end_id)
+ batch_query.each_batch(of: SUB_BATCH_SIZE) do |sub_batch|
+ first, last = sub_batch.pluck(Arel.sql('MIN(id), MAX(id)')).first
+ ranged_query = Namespace.unscoped.base_query.where(id: first..last)
+
+ update_sql = <<~SQL
+ INSERT INTO ci_namespace_mirrors (namespace_id, traversal_ids)
+ #{insert_values(ranged_query)}
+ ON CONFLICT (namespace_id) DO NOTHING
+ SQL
+ # We do nothing on conflict because we consider they were already filled.
+
+ Namespace.connection.execute(update_sql)
+
+ sleep PAUSE_SECONDS
+ end
+
+ mark_job_as_succeeded(start_id, end_id)
+ end
+
+ private
+
+ def insert_values(batch)
+ calculated_traversal_ids(
+ batch.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336433')
+ )
+ end
+
+ # Copied from lib/gitlab/background_migration/backfill_namespace_traversal_ids_children.rb
+ def calculated_traversal_ids(batch)
+ <<~SQL
+ WITH RECURSIVE cte(source_id, namespace_id, parent_id, height) AS (
+ (
+ SELECT batch.id, batch.id, batch.parent_id, 1
+ FROM (#{batch.to_sql}) AS batch
+ )
+ UNION ALL
+ (
+ SELECT cte.source_id, n.id, n.parent_id, cte.height+1
+ FROM namespaces n, cte
+ WHERE n.id = cte.parent_id
+ )
+ )
+ SELECT flat_hierarchy.source_id as namespace_id,
+ array_agg(flat_hierarchy.namespace_id ORDER BY flat_hierarchy.height DESC) as traversal_ids
+ FROM (SELECT * FROM cte FOR UPDATE) flat_hierarchy
+ GROUP BY flat_hierarchy.source_id
+ SQL
+ end
+
+ def mark_job_as_succeeded(*arguments)
+ Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded('BackfillCiNamespaceMirrors', arguments)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/background_migration/backfill_ci_project_mirrors.rb b/lib/gitlab/background_migration/backfill_ci_project_mirrors.rb
new file mode 100644
index 00000000000..ff6ab9928b0
--- /dev/null
+++ b/lib/gitlab/background_migration/backfill_ci_project_mirrors.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # A job to create ci_project_mirrors entries in batches
+ class BackfillCiProjectMirrors
+ class Project < ActiveRecord::Base # rubocop:disable Style/Documentation
+ include ::EachBatch
+
+ self.table_name = 'projects'
+
+ scope :base_query, -> do
+ select(:id, :namespace_id)
+ end
+ end
+
+ PAUSE_SECONDS = 0.1
+ SUB_BATCH_SIZE = 500
+
+ def perform(start_id, end_id)
+ batch_query = Project.base_query.where(id: start_id..end_id)
+ batch_query.each_batch(of: SUB_BATCH_SIZE) do |sub_batch|
+ first, last = sub_batch.pluck(Arel.sql('MIN(id), MAX(id)')).first
+ ranged_query = Project.unscoped.base_query.where(id: first..last)
+
+ update_sql = <<~SQL
+ INSERT INTO ci_project_mirrors (project_id, namespace_id)
+ #{insert_values(ranged_query)}
+ ON CONFLICT (project_id) DO NOTHING
+ SQL
+ # We do nothing on conflict because we consider they were already filled.
+
+ Project.connection.execute(update_sql)
+
+ sleep PAUSE_SECONDS
+ end
+
+ mark_job_as_succeeded(start_id, end_id)
+ end
+
+ private
+
+ def insert_values(batch)
+ batch.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336433').to_sql
+ end
+
+ def mark_job_as_succeeded(*arguments)
+ Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded('BackfillCiProjectMirrors', arguments)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/background_migration/backfill_incident_issue_escalation_statuses.rb b/lib/gitlab/background_migration/backfill_incident_issue_escalation_statuses.rb
new file mode 100644
index 00000000000..2d46ff6b933
--- /dev/null
+++ b/lib/gitlab/background_migration/backfill_incident_issue_escalation_statuses.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # BackfillIncidentIssueEscalationStatuses adds
+ # IncidentManagement::IssuableEscalationStatus records for existing Incident issues.
+ # They will be added with no policy, and escalations_started_at as nil.
+ class BackfillIncidentIssueEscalationStatuses
+ def perform(start_id, stop_id)
+ ActiveRecord::Base.connection.execute <<~SQL
+ INSERT INTO incident_management_issuable_escalation_statuses (issue_id, created_at, updated_at)
+ SELECT issues.id, current_timestamp, current_timestamp
+ FROM issues
+ WHERE issues.issue_type = 1
+ AND issues.id BETWEEN #{start_id} AND #{stop_id}
+ ON CONFLICT (issue_id) DO NOTHING;
+ SQL
+
+ mark_job_as_succeeded(start_id, stop_id)
+ end
+
+ private
+
+ def mark_job_as_succeeded(*arguments)
+ ::Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
+ self.class.name.demodulize,
+ arguments
+ )
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/background_migration/base_job.rb b/lib/gitlab/background_migration/base_job.rb
new file mode 100644
index 00000000000..e21e7e0e4a3
--- /dev/null
+++ b/lib/gitlab/background_migration/base_job.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # Simple base class for background migration job classes which are executed through the sidekiq queue.
+ #
+ # Any job class that inherits from the base class will have connection to the tracking database set on
+ # initialization.
+ class BaseJob
+ def initialize(connection:)
+ @connection = connection
+ end
+
+ def perform(*arguments)
+ raise NotImplementedError, "subclasses of #{self.class.name} must implement #{__method__}"
+ end
+
+ private
+
+ attr_reader :connection
+ end
+ end
+end
diff --git a/lib/gitlab/background_migration/cleanup_concurrent_rename.rb b/lib/gitlab/background_migration/cleanup_concurrent_rename.rb
deleted file mode 100644
index d3f366f3480..00000000000
--- a/lib/gitlab/background_migration/cleanup_concurrent_rename.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module BackgroundMigration
- # Background migration for cleaning up a concurrent column rename.
- class CleanupConcurrentRename < CleanupConcurrentSchemaChange
- RESCHEDULE_DELAY = 10.minutes
-
- def cleanup_concurrent_schema_change(table, old_column, new_column)
- cleanup_concurrent_column_rename(table, old_column, new_column)
- end
- end
- end
-end
diff --git a/lib/gitlab/background_migration/cleanup_concurrent_schema_change.rb b/lib/gitlab/background_migration/cleanup_concurrent_schema_change.rb
deleted file mode 100644
index 91b50c1a493..00000000000
--- a/lib/gitlab/background_migration/cleanup_concurrent_schema_change.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module BackgroundMigration
- # Base class for background migration for rename/type changes.
- class CleanupConcurrentSchemaChange
- include Database::MigrationHelpers
-
- # table - The name of the table the migration is performed for.
- # old_column - The name of the old (to drop) column.
- # new_column - The name of the new column.
- def perform(table, old_column, new_column)
- return unless column_exists?(table, new_column) && column_exists?(table, old_column)
-
- rows_to_migrate = define_model_for(table)
- .where(new_column => nil)
- .where
- .not(old_column => nil)
-
- if rows_to_migrate.any?
- BackgroundMigrationWorker.perform_in(
- RESCHEDULE_DELAY,
- self.class.name,
- [table, old_column, new_column]
- )
- else
- cleanup_concurrent_schema_change(table, old_column, new_column)
- end
- end
-
- def cleanup_concurrent_schema_change(_table, _old_column, _new_column)
- raise NotImplementedError
- end
-
- # These methods are necessary so we can re-use the migration helpers in
- # this class.
- def connection
- ActiveRecord::Base.connection
- end
-
- def method_missing(name, *args, &block)
- connection.__send__(name, *args, &block) # rubocop: disable GitlabSecurity/PublicSend
- end
-
- def respond_to_missing?(*args)
- connection.respond_to?(*args) || super
- end
-
- def define_model_for(table)
- Class.new(ActiveRecord::Base) do
- self.table_name = table
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/background_migration/cleanup_concurrent_type_change.rb b/lib/gitlab/background_migration/cleanup_concurrent_type_change.rb
deleted file mode 100644
index 48411095dbb..00000000000
--- a/lib/gitlab/background_migration/cleanup_concurrent_type_change.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module BackgroundMigration
- # Background migration for cleaning up a concurrent column type changeb.
- class CleanupConcurrentTypeChange < CleanupConcurrentSchemaChange
- RESCHEDULE_DELAY = 10.minutes
-
- def cleanup_concurrent_schema_change(table, old_column, new_column)
- cleanup_concurrent_column_type_change(table, old_column)
- end
- end
- end
-end
diff --git a/lib/gitlab/background_migration/copy_column.rb b/lib/gitlab/background_migration/copy_column.rb
deleted file mode 100644
index ef70f37d5eb..00000000000
--- a/lib/gitlab/background_migration/copy_column.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module BackgroundMigration
- # CopyColumn is a simple (reusable) background migration that can be used to
- # update the value of a column based on the value of another column in the
- # same table.
- #
- # For this background migration to work the table that is migrated _has_ to
- # have an `id` column as the primary key.
- class CopyColumn
- # table - The name of the table that contains the columns.
- # copy_from - The column containing the data to copy.
- # copy_to - The column to copy the data to.
- # start_id - The start ID of the range of rows to update.
- # end_id - The end ID of the range of rows to update.
- def perform(table, copy_from, copy_to, start_id, end_id)
- return unless connection.column_exists?(table, copy_to)
-
- quoted_table = connection.quote_table_name(table)
- quoted_copy_from = connection.quote_column_name(copy_from)
- quoted_copy_to = connection.quote_column_name(copy_to)
-
- # We're using raw SQL here since this job may be frequently executed. As
- # a result dynamically defining models would lead to many unnecessary
- # schema information queries.
- connection.execute <<-SQL.strip_heredoc
- UPDATE #{quoted_table}
- SET #{quoted_copy_to} = #{quoted_copy_from}
- WHERE id BETWEEN #{start_id} AND #{end_id}
- AND #{quoted_copy_from} IS NOT NULL
- AND #{quoted_copy_to} IS NULL
- SQL
- end
-
- def connection
- ActiveRecord::Base.connection
- end
- end
- end
-end
diff --git a/lib/gitlab/background_migration/encrypt_static_object_token.rb b/lib/gitlab/background_migration/encrypt_static_object_token.rb
new file mode 100644
index 00000000000..80931353e2f
--- /dev/null
+++ b/lib/gitlab/background_migration/encrypt_static_object_token.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # Populates "static_object_token_encrypted" field with encrypted versions
+ # of values from "static_object_token" field
+ class EncryptStaticObjectToken
+ # rubocop:disable Style/Documentation
+ class User < ActiveRecord::Base
+ include ::EachBatch
+ self.table_name = 'users'
+ scope :with_static_object_token, -> { where.not(static_object_token: nil) }
+ scope :without_static_object_token_encrypted, -> { where(static_object_token_encrypted: nil) }
+ end
+ # rubocop:enable Style/Documentation
+
+ BATCH_SIZE = 100
+
+ def perform(start_id, end_id)
+ ranged_query = User
+ .where(id: start_id..end_id)
+ .with_static_object_token
+ .without_static_object_token_encrypted
+
+ ranged_query.each_batch(of: BATCH_SIZE) do |sub_batch|
+ first, last = sub_batch.pluck(Arel.sql('min(id), max(id)')).first
+
+ batch_query = User.unscoped
+ .where(id: first..last)
+ .with_static_object_token
+ .without_static_object_token_encrypted
+
+ user_tokens = batch_query.pluck(:id, :static_object_token)
+
+ user_encrypted_tokens = user_tokens.map do |(id, plaintext_token)|
+ next if plaintext_token.blank?
+
+ [id, Gitlab::CryptoHelper.aes256_gcm_encrypt(plaintext_token)]
+ end
+
+ encrypted_tokens_sql = user_encrypted_tokens.compact.map { |(id, token)| "(#{id}, '#{token}')" }.join(',')
+
+ if user_encrypted_tokens.present?
+ User.connection.execute(<<~SQL)
+ WITH cte(cte_id, cte_token) AS #{::Gitlab::Database::AsWithMaterialized.materialized_if_supported} (
+ SELECT *
+ FROM (VALUES #{encrypted_tokens_sql}) AS t (id, token)
+ )
+ UPDATE #{User.table_name}
+ SET static_object_token_encrypted = cte_token
+ FROM cte
+ WHERE cte_id = id
+ SQL
+ end
+
+ mark_job_as_succeeded(start_id, end_id)
+ end
+ end
+
+ private
+
+ def mark_job_as_succeeded(*arguments)
+ Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
+ self.class.name.demodulize,
+ arguments
+ )
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/background_migration/fix_vulnerability_occurrences_with_hashes_as_raw_metadata.rb b/lib/gitlab/background_migration/fix_vulnerability_occurrences_with_hashes_as_raw_metadata.rb
new file mode 100644
index 00000000000..2b049ea2d2f
--- /dev/null
+++ b/lib/gitlab/background_migration/fix_vulnerability_occurrences_with_hashes_as_raw_metadata.rb
@@ -0,0 +1,124 @@
+# frozen_string_literal: true
+
+require 'parser/ruby27'
+
+module Gitlab
+ module BackgroundMigration
+ # This migration fixes raw_metadata entries which have incorrectly been passed a Ruby Hash instead of JSON data.
+ class FixVulnerabilityOccurrencesWithHashesAsRawMetadata
+ CLUSTER_IMAGE_SCANNING_REPORT_TYPE = 7
+ GENERIC_REPORT_TYPE = 99
+
+ # Type error is used to handle unexpected types when parsing stringified hashes.
+ class TypeError < ::StandardError
+ attr_reader :message, :type
+
+ def initialize(message, type)
+ @message = message
+ @type = type
+ end
+ end
+
+ # Migration model namespace isolated from application code.
+ class Finding < ActiveRecord::Base
+ include EachBatch
+
+ self.table_name = 'vulnerability_occurrences'
+
+ scope :by_api_report_types, -> { where(report_type: [CLUSTER_IMAGE_SCANNING_REPORT_TYPE, GENERIC_REPORT_TYPE]) }
+ end
+
+ def perform(start_id, end_id)
+ Finding.by_api_report_types.where(id: start_id..end_id).each do |finding|
+ next if valid_json?(finding.raw_metadata)
+
+ metadata = hash_from_s(finding.raw_metadata)
+
+ finding.update(raw_metadata: metadata.to_json) if metadata
+ end
+ mark_job_as_succeeded(start_id, end_id)
+ end
+
+ def hash_from_s(str_hash)
+ ast = Parser::Ruby27.parse(str_hash)
+
+ unless ast.type == :hash
+ ::Gitlab::AppLogger.error(message: "expected raw_metadata to be a hash", type: ast.type)
+ return
+ end
+
+ parse_hash(ast)
+ rescue Parser::SyntaxError => e
+ ::Gitlab::AppLogger.error(message: "error parsing raw_metadata", error: e.message)
+ nil
+ rescue TypeError => e
+ ::Gitlab::AppLogger.error(message: "error parsing raw_metadata", error: e.message, type: e.type)
+ nil
+ end
+
+ private
+
+ def mark_job_as_succeeded(*arguments)
+ Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
+ 'FixVulnerabilityOccurrencesWithHashesAsRawMetadata',
+ arguments
+ )
+ end
+
+ def valid_json?(metadata)
+ Oj.load(metadata)
+ true
+ rescue Oj::ParseError, Encoding::UndefinedConversionError
+ false
+ end
+
+ def parse_hash(hash)
+ out = {}
+ hash.children.each do |node|
+ unless node.type == :pair
+ raise TypeError.new("expected child of hash to be a `pair`", node.type)
+ end
+
+ key, value = node.children
+
+ key = parse_key(key)
+ value = parse_value(value)
+
+ out[key] = value
+ end
+
+ out
+ end
+
+ def parse_key(key)
+ case key.type
+ when :sym, :str, :int
+ key.children.first
+ else
+ raise TypeError.new("expected key to be either symbol, string, or integer", key.type)
+ end
+ end
+
+ def parse_value(value)
+ case value.type
+ when :sym, :str, :int
+ value.children.first
+ # rubocop:disable Lint/BooleanSymbol
+ when :true
+ true
+ when :false
+ false
+ # rubocop:enable Lint/BooleanSymbol
+ when :nil
+ nil
+ when :array
+ value.children.map { |c| parse_value(c) }
+ when :hash
+ parse_hash(value)
+ else
+ raise TypeError.new("value of a pair was an unexpected type", value.type)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/background_migration/job_coordinator.rb b/lib/gitlab/background_migration/job_coordinator.rb
index cfbe7167677..5dc77f935e3 100644
--- a/lib/gitlab/background_migration/job_coordinator.rb
+++ b/lib/gitlab/background_migration/job_coordinator.rb
@@ -36,6 +36,8 @@ module Gitlab
attr_reader :worker_class
+ delegate :minimum_interval, :perform_in, to: :worker_class
+
def queue
@queue ||= worker_class.sidekiq_options['queue']
end
@@ -79,7 +81,7 @@ module Gitlab
def perform(class_name, arguments)
with_shared_connection do
- migration_class_for(class_name).new.perform(*arguments)
+ migration_instance_for(class_name).perform(*arguments)
end
end
@@ -113,6 +115,16 @@ module Gitlab
enqueued_job?([retry_set], migration_class)
end
+ def migration_instance_for(class_name)
+ migration_class = migration_class_for(class_name)
+
+ if migration_class < Gitlab::BackgroundMigration::BaseJob
+ migration_class.new(connection: connection)
+ else
+ migration_class.new
+ end
+ end
+
def migration_class_for(class_name)
Gitlab::BackgroundMigration.const_get(class_name, false)
end
diff --git a/lib/gitlab/background_migration/migrate_legacy_artifacts.rb b/lib/gitlab/background_migration/migrate_legacy_artifacts.rb
deleted file mode 100644
index 23d99274232..00000000000
--- a/lib/gitlab/background_migration/migrate_legacy_artifacts.rb
+++ /dev/null
@@ -1,130 +0,0 @@
-# frozen_string_literal: true
-# rubocop:disable Metrics/ClassLength
-
-module Gitlab
- module BackgroundMigration
- ##
- # The class to migrate job artifacts from `ci_builds` to `ci_job_artifacts`
- class MigrateLegacyArtifacts
- FILE_LOCAL_STORE = 1 # equal to ObjectStorage::Store::LOCAL
- ARCHIVE_FILE_TYPE = 1 # equal to Ci::JobArtifact.file_types['archive']
- METADATA_FILE_TYPE = 2 # equal to Ci::JobArtifact.file_types['metadata']
- LEGACY_PATH_FILE_LOCATION = 1 # equal to Ci::JobArtifact.file_location['legacy_path']
-
- def perform(start_id, stop_id)
- ActiveRecord::Base.transaction do
- insert_archives(start_id, stop_id)
- insert_metadatas(start_id, stop_id)
- delete_legacy_artifacts(start_id, stop_id)
- end
- end
-
- private
-
- def insert_archives(start_id, stop_id)
- ActiveRecord::Base.connection.execute <<~SQL
- INSERT INTO
- ci_job_artifacts (
- project_id,
- job_id,
- expire_at,
- file_location,
- created_at,
- updated_at,
- file,
- size,
- file_store,
- file_type
- )
- SELECT
- project_id,
- id,
- artifacts_expire_at #{add_missing_db_timezone},
- #{LEGACY_PATH_FILE_LOCATION},
- created_at #{add_missing_db_timezone},
- created_at #{add_missing_db_timezone},
- artifacts_file,
- artifacts_size,
- COALESCE(artifacts_file_store, #{FILE_LOCAL_STORE}),
- #{ARCHIVE_FILE_TYPE}
- FROM
- ci_builds
- WHERE
- id BETWEEN #{start_id.to_i} AND #{stop_id.to_i}
- AND artifacts_file <> ''
- AND NOT EXISTS (
- SELECT
- 1
- FROM
- ci_job_artifacts
- WHERE
- ci_builds.id = ci_job_artifacts.job_id
- AND ci_job_artifacts.file_type = #{ARCHIVE_FILE_TYPE})
- SQL
- end
-
- def insert_metadatas(start_id, stop_id)
- ActiveRecord::Base.connection.execute <<~SQL
- INSERT INTO
- ci_job_artifacts (
- project_id,
- job_id,
- expire_at,
- file_location,
- created_at,
- updated_at,
- file,
- size,
- file_store,
- file_type
- )
- SELECT
- project_id,
- id,
- artifacts_expire_at #{add_missing_db_timezone},
- #{LEGACY_PATH_FILE_LOCATION},
- created_at #{add_missing_db_timezone},
- created_at #{add_missing_db_timezone},
- artifacts_metadata,
- NULL,
- COALESCE(artifacts_metadata_store, #{FILE_LOCAL_STORE}),
- #{METADATA_FILE_TYPE}
- FROM
- ci_builds
- WHERE
- id BETWEEN #{start_id.to_i} AND #{stop_id.to_i}
- AND artifacts_file <> ''
- AND artifacts_metadata <> ''
- AND NOT EXISTS (
- SELECT
- 1
- FROM
- ci_job_artifacts
- WHERE
- ci_builds.id = ci_job_artifacts.job_id
- AND ci_job_artifacts.file_type = #{METADATA_FILE_TYPE})
- SQL
- end
-
- def delete_legacy_artifacts(start_id, stop_id)
- ActiveRecord::Base.connection.execute <<~SQL
- UPDATE
- ci_builds
- SET
- artifacts_file = NULL,
- artifacts_file_store = NULL,
- artifacts_size = NULL,
- artifacts_metadata = NULL,
- artifacts_metadata_store = NULL
- WHERE
- id BETWEEN #{start_id.to_i} AND #{stop_id.to_i}
- AND artifacts_file <> ''
- SQL
- end
-
- def add_missing_db_timezone
- 'at time zone \'UTC\''
- end
- end
- end
-end
diff --git a/lib/gitlab/background_migration/populate_test_reports_issue_id.rb b/lib/gitlab/background_migration/populate_test_reports_issue_id.rb
new file mode 100644
index 00000000000..301efd0c943
--- /dev/null
+++ b/lib/gitlab/background_migration/populate_test_reports_issue_id.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+# rubocop: disable Style/Documentation
+
+module Gitlab
+ module BackgroundMigration
+ class PopulateTestReportsIssueId
+ def perform(start_id, stop_id)
+ # NO OP
+ end
+ end
+ end
+end
+
+Gitlab::BackgroundMigration::PopulateTestReportsIssueId.prepend_mod
diff --git a/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid.rb b/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid.rb
index 84ff7423254..c1b8de1f6aa 100644
--- a/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid.rb
+++ b/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
# rubocop: disable Style/Documentation
-class Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrencesUuid
+class Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrencesUuid # rubocop:disable Metrics/ClassLength
# rubocop: disable Gitlab/NamespacedClass
class VulnerabilitiesIdentifier < ActiveRecord::Base
self.table_name = "vulnerability_identifiers"
@@ -9,10 +9,14 @@ class Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrencesUuid
end
class VulnerabilitiesFinding < ActiveRecord::Base
+ include EachBatch
include ShaAttribute
self.table_name = "vulnerability_occurrences"
+
+ has_many :signatures, foreign_key: 'finding_id', class_name: 'VulnerabilityFindingSignature', inverse_of: :finding
belongs_to :primary_identifier, class_name: 'VulnerabilitiesIdentifier', inverse_of: :primary_findings, foreign_key: 'primary_identifier_id'
+
REPORT_TYPES = {
sast: 0,
dependency_scanning: 1,
@@ -20,7 +24,9 @@ class Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrencesUuid
dast: 3,
secret_detection: 4,
coverage_fuzzing: 5,
- api_fuzzing: 6
+ api_fuzzing: 6,
+ cluster_image_scanning: 7,
+ generic: 99
}.with_indifferent_access.freeze
enum report_type: REPORT_TYPES
@@ -28,6 +34,25 @@ class Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrencesUuid
sha_attribute :location_fingerprint
end
+ class VulnerabilityFindingSignature < ActiveRecord::Base
+ include ShaAttribute
+
+ self.table_name = 'vulnerability_finding_signatures'
+ belongs_to :finding, foreign_key: 'finding_id', inverse_of: :signatures, class_name: 'VulnerabilitiesFinding'
+
+ sha_attribute :signature_sha
+ end
+
+ class VulnerabilitiesFindingPipeline < ActiveRecord::Base
+ include EachBatch
+ self.table_name = "vulnerability_occurrence_pipelines"
+ end
+
+ class Vulnerability < ActiveRecord::Base
+ include EachBatch
+ self.table_name = "vulnerabilities"
+ end
+
class CalculateFindingUUID
FINDING_NAMESPACES_IDS = {
development: "a143e9e2-41b3-47bc-9a19-081d089229f4",
@@ -52,35 +77,122 @@ class Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrencesUuid
end
# rubocop: enable Gitlab/NamespacedClass
+ # rubocop: disable Metrics/AbcSize,Metrics/MethodLength,Metrics/BlockLength
def perform(start_id, end_id)
- findings = VulnerabilitiesFinding
- .joins(:primary_identifier)
- .select(:id, :report_type, :fingerprint, :location_fingerprint, :project_id)
- .where(id: start_id..end_id)
-
- mappings = findings.each_with_object({}) do |finding, hash|
- hash[finding] = { uuid: calculate_uuid_v5_for_finding(finding) }
+ unless Feature.enabled?(:migrate_vulnerability_finding_uuids, default_enabled: true)
+ return log_info('Migration is disabled by the feature flag', start_id: start_id, end_id: end_id)
end
- ::Gitlab::Database::BulkUpdate.execute(%i[uuid], mappings)
+ log_info('Migration started', start_id: start_id, end_id: end_id)
- logger.info(message: 'RecalculateVulnerabilitiesOccurrencesUuid Migration: recalculation is done for:',
- finding_ids: mappings.keys.pluck(:id))
+ VulnerabilitiesFinding
+ .joins(:primary_identifier)
+ .includes(:signatures)
+ .select(:id, :report_type, :primary_identifier_id, :fingerprint, :location_fingerprint, :project_id, :created_at, :vulnerability_id, :uuid)
+ .where(id: start_id..end_id)
+ .each_batch(of: 50) do |relation|
+ duplicates = find_duplicates(relation)
+ remove_findings(ids: duplicates) if duplicates.present?
+
+ to_update = relation.reject { |finding| duplicates.include?(finding.id) }
+
+ begin
+ known_uuids = Set.new
+ to_be_deleted = []
+
+ mappings = to_update.each_with_object({}) do |finding, hash|
+ uuid = calculate_uuid_v5_for_finding(finding)
+
+ if known_uuids.add?(uuid)
+ hash[finding] = { uuid: uuid }
+ else
+ to_be_deleted << finding.id
+ end
+ end
+
+ # It is technically still possible to have duplicate uuids
+ # if the data integrity is broken somehow and the primary identifiers of
+ # the findings are pointing to different projects with the same fingerprint values.
+ if to_be_deleted.present?
+ log_info('Conflicting UUIDs found within the batch', finding_ids: to_be_deleted)
+
+ remove_findings(ids: to_be_deleted)
+ end
+
+ ::Gitlab::Database::BulkUpdate.execute(%i[uuid], mappings) if mappings.present?
+
+ log_info('Recalculation is done', finding_ids: mappings.keys.pluck(:id))
+ rescue ActiveRecord::RecordNotUnique => error
+ log_info('RecordNotUnique error received')
+
+ match_data = /\(uuid\)=\((?<uuid>\S{36})\)/.match(error.message)
+
+ # This exception returns the **correct** UUIDv5 which probably comes from a later record
+ # and it's the one we can drop in the easiest way before retrying the UPDATE query
+ if match_data
+ uuid = match_data[:uuid]
+ log_info('Conflicting UUID found', uuid: uuid)
+
+ id = VulnerabilitiesFinding.find_by(uuid: uuid)&.id
+ remove_findings(ids: id) if id
+ retry
+ else
+ log_error('Couldnt find conflicting uuid')
+
+ Gitlab::ErrorTracking.track_and_raise_exception(error)
+ end
+ end
+ end
mark_job_as_succeeded(start_id, end_id)
rescue StandardError => error
- Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error)
+ log_error('An exception happened')
+
+ Gitlab::ErrorTracking.track_and_raise_exception(error)
end
+ # rubocop: disable Metrics/AbcSize,Metrics/MethodLength,Metrics/BlockLength
private
+ def find_duplicates(relation)
+ to_exclude = []
+ relation.flat_map do |record|
+ # Assuming we're scanning id 31 and the duplicate is id 40
+ # first we'd process 31 and add 40 to the list of ids to remove
+ # then we would process record 40 and add 31 to the list of removals
+ # so we would drop both records
+ to_exclude << record.id
+
+ VulnerabilitiesFinding.where(
+ report_type: record.report_type,
+ location_fingerprint: record.location_fingerprint,
+ primary_identifier_id: record.primary_identifier_id,
+ project_id: record.project_id
+ ).where.not(id: to_exclude).pluck(:id)
+ end
+ end
+
+ def remove_findings(ids:)
+ ids = Array(ids)
+ log_info('Removing Findings and associated records', ids: ids)
+
+ vulnerability_ids = VulnerabilitiesFinding.where(id: ids).pluck(:vulnerability_id).uniq.compact
+
+ VulnerabilitiesFindingPipeline.where(occurrence_id: ids).each_batch { |batch| batch.delete_all }
+ Vulnerability.where(id: vulnerability_ids).each_batch { |batch| batch.delete_all }
+ VulnerabilitiesFinding.where(id: ids).delete_all
+ end
+
def calculate_uuid_v5_for_finding(vulnerability_finding)
return unless vulnerability_finding
+ signatures = vulnerability_finding.signatures.sort_by { |signature| signature.algorithm_type_before_type_cast }
+ location_fingerprint = signatures.last&.signature_sha || vulnerability_finding.location_fingerprint
+
uuid_v5_name_components = {
report_type: vulnerability_finding.report_type,
primary_identifier_fingerprint: vulnerability_finding.fingerprint,
- location_fingerprint: vulnerability_finding.location_fingerprint,
+ location_fingerprint: location_fingerprint,
project_id: vulnerability_finding.project_id
}
@@ -89,6 +201,14 @@ class Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrencesUuid
CalculateFindingUUID.call(name)
end
+ def log_info(message, **extra)
+ logger.info(migrator: 'RecalculateVulnerabilitiesOccurrencesUuid', message: message, **extra)
+ end
+
+ def log_error(message, **extra)
+ logger.error(migrator: 'RecalculateVulnerabilitiesOccurrencesUuid', message: message, **extra)
+ end
+
def logger
@logger ||= Gitlab::BackgroundMigration::Logger.build
end
diff --git a/lib/gitlab/background_migration/remove_duplicate_services.rb b/lib/gitlab/background_migration/remove_duplicate_services.rb
deleted file mode 100644
index 59fb9143a72..00000000000
--- a/lib/gitlab/background_migration/remove_duplicate_services.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module BackgroundMigration
- # Remove duplicated service records with the same project and type.
- # These were created in the past for unknown reasons, and should be blocked
- # now by the uniqueness validation in the Service model.
- class RemoveDuplicateServices
- # See app/models/service
- class Service < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'services'
- self.inheritance_column = :_type_disabled
-
- scope :project_ids_with_duplicates, -> do
- select(:project_id)
- .distinct
- .where.not(project_id: nil)
- .group(:project_id, :type)
- .having('count(*) > 1')
- end
-
- scope :types_with_duplicates, -> (project_ids) do
- select(:project_id, :type)
- .where(project_id: project_ids)
- .group(:project_id, :type)
- .having('count(*) > 1')
- end
- end
-
- def perform(*project_ids)
- types_with_duplicates = Service.types_with_duplicates(project_ids).pluck(:project_id, :type)
-
- types_with_duplicates.each do |project_id, type|
- remove_duplicates(project_id, type)
- end
- end
-
- private
-
- def remove_duplicates(project_id, type)
- scope = Service.where(project_id: project_id, type: type)
-
- # Build a subquery to determine which service record is actually in use,
- # by querying for it without specifying an order.
- #
- # This should match the record returned by `Project#find_service`,
- # and the `has_one` service associations on `Project`.
- correct_service = scope.select(:id).limit(1)
-
- # Delete all other services with the same `project_id` and `type`
- duplicate_services = scope.where.not(id: correct_service)
- duplicate_services.delete_all
- end
- end
- end
-end
diff --git a/lib/gitlab/checks/changes_access.rb b/lib/gitlab/checks/changes_access.rb
index 3ce2e50c548..84c01cf4baf 100644
--- a/lib/gitlab/checks/changes_access.rb
+++ b/lib/gitlab/checks/changes_access.rb
@@ -33,18 +33,33 @@ module Gitlab
# changes. This set may also contain commits which are not referenced by
# any of the new revisions.
def commits
+ allow_quarantine = true
+
newrevs = @changes.map do |change|
+ oldrev = change[:oldrev]
newrev = change[:newrev]
- newrev unless newrev.blank? || Gitlab::Git.blank_ref?(newrev)
+
+ next if blank_rev?(newrev)
+
+ # In case any of the old revisions is blank, then we cannot reliably
+ # detect which commits are new for a given change when enumerating
+ # objects via the object quarantine directory given that the client
+ # may have pushed too many commits, and we don't know when to
+ # terminate the walk. We thus fall back to using `git rev-list --not
+ # --all`, which is a lot less efficient but at least can only ever
+ # returns commits which really are new.
+ allow_quarantine = false if allow_quarantine && blank_rev?(oldrev)
+
+ newrev
end.compact
return [] if newrevs.empty?
- @commits ||= project.repository.new_commits(newrevs, allow_quarantine: true)
+ @commits ||= project.repository.new_commits(newrevs, allow_quarantine: allow_quarantine)
end
# All commits which have been newly introduced via the given revision.
- def commits_for(newrev)
+ def commits_for(oldrev, newrev)
commits_by_id = commits.index_by(&:id)
result = []
@@ -65,9 +80,11 @@ module Gitlab
# Only add the parent ID to the pending set if we actually know its
# commit to guards us against readding an ID which we have already
- # queued up before.
+ # queued up before. Furthermore, we stop walking as soon as we hit
+ # `oldrev` such that we do not include any commits in our checks
+ # which have been "over-pushed" by the client.
commit.parent_ids.each do |parent_id|
- pending.add(parent_id) if commits_by_id.has_key?(parent_id)
+ pending.add(parent_id) if commits_by_id.has_key?(parent_id) && parent_id != oldrev
end
result << commit
@@ -80,10 +97,10 @@ module Gitlab
@single_changes_accesses ||=
changes.map do |change|
commits =
- if change[:newrev].blank? || Gitlab::Git.blank_ref?(change[:newrev])
+ if blank_rev?(change[:newrev])
[]
else
- Gitlab::Lazy.new { commits_for(change[:newrev]) }
+ Gitlab::Lazy.new { commits_for(change[:oldrev], change[:newrev]) }
end
Checks::SingleChangeAccess.new(
@@ -109,6 +126,10 @@ module Gitlab
def bulk_access_checks!
Gitlab::Checks::LfsCheck.new(self).validate!
end
+
+ def blank_rev?(rev)
+ rev.blank? || Gitlab::Git.blank_ref?(rev)
+ end
end
end
end
diff --git a/lib/gitlab/ci/build/policy/refs.rb b/lib/gitlab/ci/build/policy/refs.rb
index afe0ccb361e..7ade9ca5085 100644
--- a/lib/gitlab/ci/build/policy/refs.rb
+++ b/lib/gitlab/ci/build/policy/refs.rb
@@ -35,7 +35,10 @@ module Gitlab
# patterns can be matched only when branch or tag is used
# the pattern matching does not work for merge requests pipelines
if pipeline.branch? || pipeline.tag?
- if regexp = Gitlab::UntrustedRegexp::RubySyntax.fabricate(pattern, fallback: true)
+ regexp = Gitlab::UntrustedRegexp::RubySyntax
+ .fabricate(pattern, fallback: true, project: pipeline.project)
+
+ if regexp
regexp.match?(pipeline.ref)
else
pattern == pipeline.ref
diff --git a/lib/gitlab/ci/build/status/reason.rb b/lib/gitlab/ci/build/status/reason.rb
new file mode 100644
index 00000000000..82e07faef63
--- /dev/null
+++ b/lib/gitlab/ci/build/status/reason.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Build
+ module Status
+ class Reason
+ attr_reader :build, :failure_reason, :exit_code
+
+ def initialize(build, failure_reason, exit_code = nil)
+ @build = build
+ @failure_reason = failure_reason
+ @exit_code = exit_code
+ end
+
+ def failure_reason_enum
+ ::CommitStatus.failure_reasons[failure_reason]
+ end
+
+ def force_allow_failure?
+ return false if exit_code.nil?
+
+ !build.allow_failure? && build.allowed_to_fail_with_code?(exit_code)
+ end
+
+ def self.fabricate(build, reason)
+ if reason.is_a?(self)
+ new(build, reason.failure_reason, reason.exit_code)
+ else
+ new(build, reason)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/config.rb b/lib/gitlab/ci/config.rb
index 42b487fdf81..4c98941e032 100644
--- a/lib/gitlab/ci/config.rb
+++ b/lib/gitlab/ci/config.rb
@@ -36,7 +36,7 @@ module Gitlab
end
@root = self.logger.instrument(:config_compose) do
- Entry::Root.new(@config).tap(&:compose!)
+ Entry::Root.new(@config, project: project, user: user).tap(&:compose!)
end
rescue *rescue_errors => e
raise Config::ConfigError, e.message
diff --git a/lib/gitlab/ci/config/entry/root.rb b/lib/gitlab/ci/config/entry/root.rb
index e6290ef2479..41a3c87037b 100644
--- a/lib/gitlab/ci/config/entry/root.rb
+++ b/lib/gitlab/ci/config/entry/root.rb
@@ -59,7 +59,8 @@ module Gitlab
entry :types, Entry::Stages,
description: 'Deprecated: stages for this pipeline.',
- reserved: true
+ reserved: true,
+ deprecation: { deprecated: '9.0', warning: '14.8', removed: '15.0', documentation: 'https://docs.gitlab.com/ee/ci/yaml/#deprecated-keywords' }
entry :cache, Entry::Caches,
description: 'Configure caching between build jobs.',
@@ -122,8 +123,9 @@ module Gitlab
# Deprecated `:types` key workaround - if types are defined and
# stages are not defined we use types definition as stages.
#
- if types_defined? && !stages_defined?
- @entries[:stages] = @entries[:types]
+ if types_defined?
+ @entries[:stages] = @entries[:types] unless stages_defined?
+ log_and_warn_deprecated_entry(@entries[:types])
end
@entries.delete(:types)
diff --git a/lib/gitlab/ci/jwt_v2.rb b/lib/gitlab/ci/jwt_v2.rb
new file mode 100644
index 00000000000..278353220e4
--- /dev/null
+++ b/lib/gitlab/ci/jwt_v2.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class JwtV2 < Jwt
+ private
+
+ def reserved_claims
+ super.merge(
+ iss: Settings.gitlab.base_url,
+ sub: "project_path:#{project.full_path}:ref_type:#{ref_type}:ref:#{source_ref}",
+ aud: Settings.gitlab.base_url
+ )
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/pipeline/chain/create.rb b/lib/gitlab/ci/pipeline/chain/create.rb
index 15b0ff3c04d..54b54bd0514 100644
--- a/lib/gitlab/ci/pipeline/chain/create.rb
+++ b/lib/gitlab/ci/pipeline/chain/create.rb
@@ -9,13 +9,13 @@ module Gitlab
include Gitlab::Utils::StrongMemoize
def perform!
- logger.instrument(:pipeline_save) do
+ logger.instrument_with_sql(:pipeline_save) do
BulkInsertableAssociations.with_bulk_insert do
- tags = extract_tag_list_by_status
-
- pipeline.transaction do
- pipeline.save!
- CommitStatus.bulk_insert_tags!(statuses, tags) if bulk_insert_tags?
+ with_bulk_insert_tags do
+ pipeline.transaction do
+ pipeline.save!
+ CommitStatus.bulk_insert_tags!(statuses) if bulk_insert_tags?
+ end
end
end
end
@@ -29,32 +29,26 @@ module Gitlab
private
- def statuses
- strong_memoize(:statuses) do
- pipeline.stages.flat_map(&:statuses)
+ def bulk_insert_tags?
+ strong_memoize(:bulk_insert_tags) do
+ ::Feature.enabled?(:ci_bulk_insert_tags, project, default_enabled: :yaml)
end
end
- # We call `job.tag_list=` to assign tags to the jobs from the
- # Chain::Seed step which uses the `@tag_list` instance variable to
- # store them on the record. We remove them here because we want to
- # bulk insert them, otherwise they would be inserted and assigned one
- # by one with callbacks. We must use `remove_instance_variable`
- # because having the instance variable defined would still run the callbacks
- def extract_tag_list_by_status
- return {} unless bulk_insert_tags?
-
- statuses.each.with_object({}) do |job, acc|
- tag_list = job.clear_memoization(:tag_list)
- next unless tag_list
-
- acc[job.name] = tag_list
- end
+ def with_bulk_insert_tags
+ previous = Thread.current['ci_bulk_insert_tags']
+ Thread.current['ci_bulk_insert_tags'] = bulk_insert_tags?
+ yield
+ ensure
+ Thread.current['ci_bulk_insert_tags'] = previous
end
- def bulk_insert_tags?
- strong_memoize(:bulk_insert_tags) do
- ::Feature.enabled?(:ci_bulk_insert_tags, project, default_enabled: :yaml)
+ def statuses
+ strong_memoize(:statuses) do
+ pipeline
+ .stages
+ .flat_map(&:statuses)
+ .select { |status| status.respond_to?(:tag_list) }
end
end
end
diff --git a/lib/gitlab/ci/pipeline/chain/create_deployments.rb b/lib/gitlab/ci/pipeline/chain/create_deployments.rb
index b92aa89d62d..b913ba3c87d 100644
--- a/lib/gitlab/ci/pipeline/chain/create_deployments.rb
+++ b/lib/gitlab/ci/pipeline/chain/create_deployments.rb
@@ -5,8 +5,6 @@ module Gitlab
module Pipeline
module Chain
class CreateDeployments < Chain::Base
- DeploymentCreationError = Class.new(StandardError)
-
def perform!
return unless pipeline.create_deployment_in_separate_transaction?
@@ -24,18 +22,7 @@ module Gitlab
end
def create_deployment(build)
- return unless build.instance_of?(::Ci::Build) && build.persisted_environment.present?
-
- deployment = ::Gitlab::Ci::Pipeline::Seed::Deployment
- .new(build, build.persisted_environment).to_resource
-
- return unless deployment
-
- deployment.deployable = build
- deployment.save!
- rescue ActiveRecord::RecordInvalid => e
- Gitlab::ErrorTracking.track_and_raise_for_dev_exception(
- DeploymentCreationError.new(e.message), build_id: build.id)
+ ::Deployments::CreateForBuildService.new.execute(build)
end
end
end
diff --git a/lib/gitlab/ci/pipeline/chain/seed.rb b/lib/gitlab/ci/pipeline/chain/seed.rb
index 356eeb76908..feae123f216 100644
--- a/lib/gitlab/ci/pipeline/chain/seed.rb
+++ b/lib/gitlab/ci/pipeline/chain/seed.rb
@@ -53,13 +53,18 @@ module Gitlab
end
def context
- Gitlab::Ci::Pipeline::Seed::Context.new(pipeline, root_variables: root_variables)
+ Gitlab::Ci::Pipeline::Seed::Context.new(
+ pipeline,
+ root_variables: root_variables,
+ logger: logger
+ )
end
def root_variables
logger.instrument(:pipeline_seed_merge_variables) do
::Gitlab::Ci::Variables::Helpers.merge_variables(
- @command.yaml_processor_result.root_variables, @command.workflow_rules_result.variables
+ @command.yaml_processor_result.root_variables,
+ @command.workflow_rules_result.variables
)
end
end
diff --git a/lib/gitlab/ci/pipeline/logger.rb b/lib/gitlab/ci/pipeline/logger.rb
index 97f7dddd09a..fbba12c11a9 100644
--- a/lib/gitlab/ci/pipeline/logger.rb
+++ b/lib/gitlab/ci/pipeline/logger.rb
@@ -37,6 +37,16 @@ module Gitlab
result
end
+ def instrument_with_sql(operation, &block)
+ op_start_db_counters = current_db_counter_payload
+
+ result = instrument(operation, &block)
+
+ observe_sql_counters(operation, op_start_db_counters, current_db_counter_payload)
+
+ result
+ end
+
def observe(operation, value)
return unless enabled?
@@ -50,11 +60,20 @@ module Gitlab
class: self.class.name.to_s,
pipeline_creation_caller: caller,
project_id: project.id,
- pipeline_id: pipeline.id,
pipeline_persisted: pipeline.persisted?,
pipeline_source: pipeline.source,
pipeline_creation_service_duration_s: age
- }.stringify_keys.merge(observations_hash)
+ }
+
+ if pipeline.persisted?
+ attributes[:pipeline_builds_tags_count] = pipeline.tags_count
+ attributes[:pipeline_builds_distinct_tags_count] = pipeline.distinct_tags_count
+ attributes[:pipeline_id] = pipeline.id
+ end
+
+ attributes.compact!
+ attributes.stringify_keys!
+ attributes.merge!(observations_hash)
destination.info(attributes)
end
@@ -97,6 +116,19 @@ module Gitlab
def observations
@observations ||= Hash.new { |hash, key| hash[key] = [] }
end
+
+ def observe_sql_counters(operation, start_db_counters, end_db_counters)
+ end_db_counters.each do |key, value|
+ result = value - start_db_counters.fetch(key, 0)
+ next if result == 0
+
+ observe("#{operation}_#{key}", result)
+ end
+ end
+
+ def current_db_counter_payload
+ ::Gitlab::Metrics::Subscribers::ActiveRecord.db_counter_payload
+ end
end
end
end
diff --git a/lib/gitlab/ci/pipeline/seed/build.rb b/lib/gitlab/ci/pipeline/seed/build.rb
index 762292f0fa3..5a0ad695741 100644
--- a/lib/gitlab/ci/pipeline/seed/build.rb
+++ b/lib/gitlab/ci/pipeline/seed/build.rb
@@ -41,12 +41,14 @@ module Gitlab
def included?
strong_memoize(:inclusion) do
- if @using_rules
- rules_result.pass?
- elsif @using_only || @using_except
- all_of_only? && none_of_except?
- else
- true
+ logger.instrument(:pipeline_seed_build_inclusion) do
+ if @using_rules
+ rules_result.pass?
+ elsif @using_only || @using_except
+ all_of_only? && none_of_except?
+ else
+ true
+ end
end
end
end
@@ -122,6 +124,8 @@ module Gitlab
private
+ delegate :logger, to: :@context
+
def all_of_only?
@only.all? { |spec| spec.satisfied_by?(@pipeline, evaluate_context) }
end
diff --git a/lib/gitlab/ci/pipeline/seed/context.rb b/lib/gitlab/ci/pipeline/seed/context.rb
index 6194a78f682..c0b8ebeb833 100644
--- a/lib/gitlab/ci/pipeline/seed/context.rb
+++ b/lib/gitlab/ci/pipeline/seed/context.rb
@@ -5,11 +5,18 @@ module Gitlab
module Pipeline
module Seed
class Context
- attr_reader :pipeline, :root_variables
+ attr_reader :pipeline, :root_variables, :logger
- def initialize(pipeline, root_variables: [])
+ def initialize(pipeline, root_variables: [], logger: nil)
@pipeline = pipeline
@root_variables = root_variables
+ @logger = logger || build_logger
+ end
+
+ private
+
+ def build_logger
+ ::Gitlab::Ci::Pipeline::Logger.new(project: pipeline.project)
end
end
end
diff --git a/lib/gitlab/ci/queue/metrics.rb b/lib/gitlab/ci/queue/metrics.rb
index 7f45d626922..54fb1d19ea8 100644
--- a/lib/gitlab/ci/queue/metrics.rb
+++ b/lib/gitlab/ci/queue/metrics.rb
@@ -69,17 +69,6 @@ module Gitlab
self.class.attempt_counter.increment
end
- # rubocop: disable CodeReuse/ActiveRecord
- def jobs_running_for_project(job)
- return '+Inf' unless runner.instance_type?
-
- # excluding currently started job
- running_jobs_count = job.project.builds.running.where(runner: ::Ci::Runner.instance_type)
- .limit(JOBS_RUNNING_FOR_PROJECT_MAX_BUCKET + 1).count - 1
- running_jobs_count < JOBS_RUNNING_FOR_PROJECT_MAX_BUCKET ? running_jobs_count : "#{JOBS_RUNNING_FOR_PROJECT_MAX_BUCKET}+"
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
def increment_queue_operation(operation)
self.class.increment_queue_operation(operation)
end
@@ -242,6 +231,32 @@ module Gitlab
Gitlab::Metrics.histogram(name, comment, labels, buckets)
end
end
+
+ private
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def jobs_running_for_project(job)
+ return '+Inf' unless runner.instance_type?
+
+ # excluding currently started job
+ running_jobs_count = running_jobs_relation(job)
+ .limit(JOBS_RUNNING_FOR_PROJECT_MAX_BUCKET + 1).count - 1
+
+ if running_jobs_count < JOBS_RUNNING_FOR_PROJECT_MAX_BUCKET
+ running_jobs_count
+ else
+ "#{JOBS_RUNNING_FOR_PROJECT_MAX_BUCKET}+"
+ end
+ end
+
+ def running_jobs_relation(job)
+ if ::Feature.enabled?(:ci_pending_builds_maintain_denormalized_data, default_enabled: :yaml)
+ ::Ci::RunningBuild.instance_type.where(project_id: job.project_id)
+ else
+ job.project.builds.running.where(runner: ::Ci::Runner.instance_type)
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
end
end
end
diff --git a/lib/gitlab/ci/status/build/factory.rb b/lib/gitlab/ci/status/build/factory.rb
index 7e5afbad806..a4434e2c144 100644
--- a/lib/gitlab/ci/status/build/factory.rb
+++ b/lib/gitlab/ci/status/build/factory.rb
@@ -14,7 +14,8 @@ module Gitlab
Status::Build::WaitingForResource,
Status::Build::Preparing,
Status::Build::Pending,
- Status::Build::Skipped],
+ Status::Build::Skipped,
+ Status::Build::WaitingForApproval],
[Status::Build::Cancelable,
Status::Build::Retryable],
[Status::Build::FailedUnmetPrerequisites,
diff --git a/lib/gitlab/ci/status/build/waiting_for_approval.rb b/lib/gitlab/ci/status/build/waiting_for_approval.rb
new file mode 100644
index 00000000000..59869a947a9
--- /dev/null
+++ b/lib/gitlab/ci/status/build/waiting_for_approval.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Status
+ module Build
+ class WaitingForApproval < Status::Extended
+ def illustration
+ {
+ 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."
+ }
+ end
+
+ def self.matches?(build, user)
+ build.waiting_for_deployment_approval?
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/tags/bulk_insert.rb b/lib/gitlab/ci/tags/bulk_insert.rb
index a299df7e2d9..29f3731a9b4 100644
--- a/lib/gitlab/ci/tags/bulk_insert.rb
+++ b/lib/gitlab/ci/tags/bulk_insert.rb
@@ -4,12 +4,13 @@ module Gitlab
module Ci
module Tags
class BulkInsert
+ include Gitlab::Utils::StrongMemoize
+
TAGGINGS_BATCH_SIZE = 1000
TAGS_BATCH_SIZE = 500
- def initialize(statuses, tag_list_by_status)
+ def initialize(statuses)
@statuses = statuses
- @tag_list_by_status = tag_list_by_status
end
def insert!
@@ -20,7 +21,18 @@ module Gitlab
private
- attr_reader :statuses, :tag_list_by_status
+ attr_reader :statuses
+
+ def tag_list_by_status
+ strong_memoize(:tag_list_by_status) do
+ statuses.each.with_object({}) do |status, acc|
+ tag_list = status.tag_list
+ next unless tag_list
+
+ acc[status] = tag_list
+ end
+ end
+ end
def persist_build_tags!
all_tags = tag_list_by_status.values.flatten.uniq.reject(&:blank?)
@@ -54,7 +66,7 @@ module Gitlab
def build_taggings_attributes(tag_records_by_name)
taggings = statuses.flat_map do |status|
- tag_list = tag_list_by_status[status.name]
+ tag_list = tag_list_by_status[status]
next unless tag_list
tags = tag_records_by_name.values_at(*tag_list)
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 00b771f1e5c..6942631a97f 100644
--- a/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
@@ -7,7 +7,7 @@ code_quality:
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
- CODE_QUALITY_IMAGE: "registry.gitlab.com/gitlab-org/ci-cd/codequality:0.85.24-gitlab.1"
+ CODE_QUALITY_IMAGE: "registry.gitlab.com/gitlab-org/ci-cd/codequality:0.85.26"
needs: []
script:
- export SOURCE_CODE=$PWD
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 18f0f20203d..42487cc0c67 100644
--- a/lib/gitlab/ci/templates/Jobs/Secret-Detection.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Secret-Detection.gitlab-ci.yml
@@ -14,6 +14,8 @@ variables:
image: "$SECURE_ANALYZERS_PREFIX/secrets:$SECRETS_ANALYZER_VERSION"
services: []
allow_failure: true
+ variables:
+ GIT_DEPTH: "50"
# `rules` must be overridden explicitly by each child job
# see https://gitlab.com/gitlab-org/gitlab/-/issues/218444
artifacts:
@@ -29,8 +31,16 @@ secret_detection:
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
- - git fetch origin $CI_DEFAULT_BRANCH $CI_COMMIT_REF_NAME
- - git log --left-right --cherry-pick --pretty=format:"%H" refs/remotes/origin/$CI_DEFAULT_BRANCH...refs/remotes/origin/$CI_COMMIT_REF_NAME > "$CI_COMMIT_SHA"_commit_list.txt
- - export SECRET_DETECTION_COMMITS_FILE="$CI_COMMIT_SHA"_commit_list.txt
+ - |
+ git fetch origin $CI_DEFAULT_BRANCH $CI_COMMIT_REF_NAME
+ git log --left-right --cherry-pick --pretty=format:"%H" refs/remotes/origin/${CI_DEFAULT_BRANCH}..refs/remotes/origin/${CI_COMMIT_REF_NAME} >${CI_COMMIT_SHA}_commit_list.txt
+ if [[ $(wc -l <${CI_COMMIT_SHA}_commit_list.txt) -eq "0" ]]; then
+ # if git log produces 0 or 1 commits we should scan $CI_COMMIT_SHA only
+ export SECRET_DETECTION_COMMITS=$CI_COMMIT_SHA
+ else
+ # +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"
+ export SECRET_DETECTION_COMMITS_FILE=${CI_COMMIT_SHA}_commit_list.txt
+ fi
- /analyzer run
- rm "$CI_COMMIT_SHA"_commit_list.txt
diff --git a/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml b/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml
index 0c8b98dc1cf..1660a9250e3 100644
--- a/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml
@@ -29,7 +29,7 @@ before_script:
- ruby -v # Print out ruby version for debugging
# Uncomment next line if your rails app needs a JS runtime:
# - apt-get update -q && apt-get install nodejs -yqq
- - bundle config set path 'vendor' # Install dependencies into ./vendor/ruby
+ - bundle config set path 'vendor' # Install dependencies into ./vendor/ruby
- bundle install -j $(nproc)
# Optional - Delete if not using `rubocop`
diff --git a/lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml
index 7243f240eed..f7f016b5e57 100644
--- a/lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml
@@ -33,6 +33,7 @@ coverage_fuzzing_unlicensed:
before_script:
- export COVFUZZ_JOB_TOKEN=$CI_JOB_TOKEN
- export COVFUZZ_PRIVATE_TOKEN=$CI_PRIVATE_TOKEN
+ - export COVFUZZ_PROJECT_PATH=$CI_PROJECT_PATH
- export COVFUZZ_PROJECT_ID=$CI_PROJECT_ID
- if [ -x "$(command -v apt-get)" ] ; then apt-get update && apt-get install -y wget; fi
- wget -O gitlab-cov-fuzz "${COVFUZZ_URL_PREFIX}"/"${COVFUZZ_VERSION}"/binaries/gitlab-cov-fuzz_Linux_x86_64
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
new file mode 100644
index 00000000000..6888e955467
--- /dev/null
+++ b/lib/gitlab/ci/templates/Security/DAST-On-Demand-API-Scan.gitlab-ci.yml
@@ -0,0 +1,27 @@
+stages:
+ - build
+ - test
+ - deploy
+ - dast
+
+variables:
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+ DAST_API_VERSION: "1"
+ DAST_API_IMAGE: $SECURE_ANALYZERS_PREFIX/api-fuzzing:$DAST_API_VERSION
+
+dast:
+ stage: dast
+ image: $DAST_API_IMAGE
+ variables:
+ GIT_STRATEGY: none
+ allow_failure: true
+ script:
+ - /peach/analyzer-dast-api
+ artifacts:
+ when: always
+ paths:
+ - gl-assets
+ - gl-dast-api-report.json
+ - gl-*.log
+ reports:
+ dast: gl-dast-api-report.json
diff --git a/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml
index e554742735c..12c987a8d37 100644
--- a/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml
@@ -5,9 +5,11 @@
include:
- template: Terraform/Base.latest.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml
+ - template: Jobs/SAST-IaC.latest.gitlab-ci.yml
stages:
- validate
+ - test
- build
- deploy
diff --git a/lib/gitlab/ci/trace/remote_checksum.rb b/lib/gitlab/ci/trace/remote_checksum.rb
index d57f3888ec0..7f43d91e6d7 100644
--- a/lib/gitlab/ci/trace/remote_checksum.rb
+++ b/lib/gitlab/ci/trace/remote_checksum.rb
@@ -26,7 +26,6 @@ module Gitlab
delegate :aws?, :google?, to: :object_store_config, prefix: :provider
def fetch_md5_checksum
- return unless Feature.enabled?(:ci_archived_build_trace_checksum, trace_artifact.project, default_enabled: :yaml)
return unless object_store_config.enabled?
return if trace_artifact.local_store?
diff --git a/lib/gitlab/ci/trace/stream.rb b/lib/gitlab/ci/trace/stream.rb
index 2d31049a0c9..dd435ba05b7 100644
--- a/lib/gitlab/ci/trace/stream.rb
+++ b/lib/gitlab/ci/trace/stream.rb
@@ -11,10 +11,6 @@ module Gitlab
delegate :close, :tell, :seek, :size, :url, :truncate, to: :stream, allow_nil: true
- delegate :valid?, to: :stream, allow_nil: true
-
- alias_method :present?, :valid?
-
def initialize(metrics = Trace::Metrics.new)
@stream = yield
@stream&.binmode
@@ -24,6 +20,7 @@ module Gitlab
def valid?
self.stream.present?
end
+ alias_method :present?, :valid?
def file?
self.path.present?
diff --git a/lib/gitlab/ci/variables/builder.rb b/lib/gitlab/ci/variables/builder.rb
index 3e2c2c7fc1a..4c777527ebc 100644
--- a/lib/gitlab/ci/variables/builder.rb
+++ b/lib/gitlab/ci/variables/builder.rb
@@ -13,12 +13,76 @@ module Gitlab
def scoped_variables(job, environment:, dependencies:)
Gitlab::Ci::Variables::Collection.new.tap do |variables|
variables.concat(predefined_variables(job))
+
+ next variables unless pipeline.use_variables_builder_definitions?
+
+ 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(job.yaml_variables)
+ variables.concat(user_variables(job.user))
+ variables.concat(job.dependency_variables) if dependencies
+ variables.concat(secret_instance_variables(ref: job.git_ref))
+ variables.concat(secret_group_variables(environment: environment, ref: job.git_ref))
+ variables.concat(secret_project_variables(environment: environment, ref: job.git_ref))
+ variables.concat(job.trigger_request.user_variables) if job.trigger_request
+ variables.concat(pipeline.variables)
+ variables.concat(pipeline.pipeline_schedule.job_variables) if pipeline.pipeline_schedule
+ end
+ end
+
+ def kubernetes_variables(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
+ template = ::Ci::GenerateKubeconfigService.new(job).execute
+
+ if template.valid?
+ collection.append(key: 'KUBECONFIG', value: template.to_yaml, public: false, file: true)
+ end
end
end
+ def deployment_variables(environment:, job:)
+ return [] unless environment
+
+ project.deployment_variables(
+ environment: environment,
+ kubernetes_namespace: job.expanded_kubernetes_namespace
+ )
+ end
+
+ def user_variables(user)
+ Gitlab::Ci::Variables::Collection.new.tap do |variables|
+ break variables if user.blank?
+
+ variables.append(key: 'GITLAB_USER_ID', value: user.id.to_s)
+ variables.append(key: 'GITLAB_USER_EMAIL', value: user.email)
+ variables.append(key: 'GITLAB_USER_LOGIN', value: user.username)
+ variables.append(key: 'GITLAB_USER_NAME', value: user.name)
+ end
+ end
+
+ def secret_instance_variables(ref:)
+ project.ci_instance_variables_for(ref: ref)
+ end
+
+ def secret_group_variables(environment:, ref:)
+ return [] unless project.group
+
+ project.group.ci_variables_for(ref, project, environment: environment)
+ end
+
+ def secret_project_variables(environment:, ref:)
+ project.ci_variables_for(ref: ref, environment: environment)
+ end
+
private
attr_reader :pipeline
+ delegate :project, to: :pipeline
def predefined_variables(job)
Gitlab::Ci::Variables::Collection.new.tap do |variables|
diff --git a/lib/gitlab/ci/yaml_processor.rb b/lib/gitlab/ci/yaml_processor.rb
index 296b0cfded2..553508c8638 100644
--- a/lib/gitlab/ci/yaml_processor.rb
+++ b/lib/gitlab/ci/yaml_processor.rb
@@ -86,11 +86,19 @@ module Gitlab
def validate_job_needs!(name, job)
return unless needs = job.dig(:needs, :job)
+ validate_duplicate_needs!(name, needs)
+
needs.each do |need|
validate_job_dependency!(name, need[:name], 'need')
end
end
+ def validate_duplicate_needs!(name, needs)
+ unless needs.uniq == needs
+ error!("#{name} has duplicate entries in the needs section.")
+ end
+ end
+
def validate_job_dependency!(name, dependency, dependency_type = 'dependency')
unless @jobs[dependency.to_sym]
error!("#{name} job: undefined #{dependency_type}: #{dependency}")
diff --git a/lib/gitlab/color_schemes.rb b/lib/gitlab/color_schemes.rb
index 620b4a8aee6..3884f5f0428 100644
--- a/lib/gitlab/color_schemes.rb
+++ b/lib/gitlab/color_schemes.rb
@@ -7,21 +7,23 @@ module Gitlab
# Struct class representing a single Scheme
Scheme = Struct.new(:id, :name, :css_class)
- SCHEMES = [
- Scheme.new(1, 'White', 'white'),
- Scheme.new(2, 'Dark', 'dark'),
- Scheme.new(3, 'Solarized Light', 'solarized-light'),
- Scheme.new(4, 'Solarized Dark', 'solarized-dark'),
- Scheme.new(5, 'Monokai', 'monokai'),
- Scheme.new(6, 'None', 'none')
- ].freeze
+ def self.available_schemes
+ [
+ Scheme.new(1, s_('SynthaxHighlightingTheme|Light'), 'white'),
+ Scheme.new(2, s_('SynthaxHighlightingTheme|Dark'), 'dark'),
+ Scheme.new(3, s_('SynthaxHighlightingTheme|Solarized Light'), 'solarized-light'),
+ Scheme.new(4, s_('SynthaxHighlightingTheme|Solarized Dark'), 'solarized-dark'),
+ Scheme.new(5, s_('SynthaxHighlightingTheme|Monokai'), 'monokai'),
+ Scheme.new(6, s_('SynthaxHighlightingTheme|None'), 'none')
+ ]
+ end
# Convenience method to get a space-separated String of all the color scheme
# classes that might be applied to a code block.
#
# Returns a String
def self.body_classes
- SCHEMES.collect(&:css_class).uniq.join(' ')
+ available_schemes.collect(&:css_class).uniq.join(' ')
end
# Get a Scheme by its ID
@@ -32,12 +34,12 @@ module Gitlab
#
# Returns a Scheme
def self.by_id(id)
- SCHEMES.detect { |s| s.id == id } || default
+ available_schemes.detect { |s| s.id == id } || default
end
# Returns the number of defined Schemes
def self.count
- SCHEMES.size
+ available_schemes.size
end
# Get the default Scheme
@@ -51,7 +53,7 @@ module Gitlab
#
# Yields the Scheme object
def self.each(&block)
- SCHEMES.each(&block)
+ available_schemes.each(&block)
end
# Get the Scheme for the specified user, or the default
@@ -68,7 +70,7 @@ module Gitlab
end
def self.valid_ids
- SCHEMES.map(&:id)
+ available_schemes.map(&:id)
end
end
end
diff --git a/lib/gitlab/config/entry/configurable.rb b/lib/gitlab/config/entry/configurable.rb
index 6bf77ebaa5b..aa6c724c2a3 100644
--- a/lib/gitlab/config/entry/configurable.rb
+++ b/lib/gitlab/config/entry/configurable.rb
@@ -76,7 +76,7 @@ module Gitlab
private
# rubocop: disable CodeReuse/ActiveRecord
- def entry(key, entry, description: nil, default: nil, inherit: nil, reserved: nil, metadata: {})
+ def entry(key, entry, description: nil, default: nil, inherit: nil, reserved: nil, deprecation: nil, metadata: {})
entry_name = key.to_sym
raise ArgumentError, "Entry '#{key}' already defined in '#{name}'" if @nodes.to_h[entry_name]
@@ -85,6 +85,7 @@ module Gitlab
.with(default: default)
.with(inherit: inherit)
.with(reserved: reserved)
+ .with(deprecation: deprecation)
.metadata(metadata)
@nodes ||= {}
diff --git a/lib/gitlab/config/entry/factory.rb b/lib/gitlab/config/entry/factory.rb
index f76c98f7cbf..61f2071b62f 100644
--- a/lib/gitlab/config/entry/factory.rb
+++ b/lib/gitlab/config/entry/factory.rb
@@ -32,6 +32,10 @@ module Gitlab
self
end
+ def deprecation
+ @attributes[:deprecation]
+ end
+
def description
@attributes[:description]
end
@@ -84,6 +88,7 @@ module Gitlab
node.parent = @attributes[:parent]
node.default = @attributes[:default]
node.description = @attributes[:description]
+ node.deprecation = @attributes[:deprecation]
end
end
end
diff --git a/lib/gitlab/config/entry/node.rb b/lib/gitlab/config/entry/node.rb
index 32912cb1046..6ce7046262b 100644
--- a/lib/gitlab/config/entry/node.rb
+++ b/lib/gitlab/config/entry/node.rb
@@ -10,7 +10,7 @@ module Gitlab
InvalidError = Class.new(StandardError)
attr_reader :config, :metadata
- attr_accessor :key, :parent, :default, :description
+ attr_accessor :key, :parent, :default, :description, :deprecation
def initialize(config, **metadata)
@config = config
@@ -128,6 +128,24 @@ module Gitlab
private
attr_reader :entries
+
+ def log_and_warn_deprecated_entry(entry)
+ user = metadata[:user]
+ project = metadata[:project]
+
+ if project && user
+ Gitlab::AppJsonLogger.info(event: 'ci_used_deprecated_keyword',
+ entry: entry.key.to_s,
+ user_id: user.id,
+ project_id: project.id)
+ end
+
+ deprecation = entry.deprecation
+ add_warning(
+ "`#{entry.key}` is deprecated in " \
+ "#{deprecation[:deprecated]} and will be removed in #{deprecation[:removed]}."
+ )
+ end
end
end
end
diff --git a/lib/gitlab/content_security_policy/config_loader.rb b/lib/gitlab/content_security_policy/config_loader.rb
index 87bc2ace204..78ba0916808 100644
--- a/lib/gitlab/content_security_policy/config_loader.rb
+++ b/lib/gitlab/content_security_policy/config_loader.rb
@@ -147,7 +147,7 @@ module Gitlab
# Using 'self' in the CSP introduces several CSP bypass opportunities
# for this reason we list the URLs where GitLab frames itself instead
def self.allow_framed_gitlab_paths(directives)
- ['/admin/', '/assets/', '/-/speedscope/index.html'].map do |path|
+ ['/admin/', '/assets/', '/-/speedscope/index.html', '/-/sandbox/mermaid'].map do |path|
append_to_directive(directives, 'frame_src', Gitlab::Utils.append_path(Gitlab.config.gitlab.url, path))
end
end
diff --git a/lib/gitlab/data_builder/archive_trace.rb b/lib/gitlab/data_builder/archive_trace.rb
new file mode 100644
index 00000000000..f6dd6130104
--- /dev/null
+++ b/lib/gitlab/data_builder/archive_trace.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module DataBuilder
+ module ArchiveTrace
+ extend self
+
+ def build(job)
+ {
+ object_kind: 'archive_trace',
+ trace_url: job.job_artifacts_trace.file.url,
+ build_id: job.id,
+ pipeline_id: job.pipeline_id,
+ project: job.project.hook_attrs
+ }
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/data_builder/deployment.rb b/lib/gitlab/data_builder/deployment.rb
index 267c2d32ca9..a4508bc93c5 100644
--- a/lib/gitlab/data_builder/deployment.rb
+++ b/lib/gitlab/data_builder/deployment.rb
@@ -25,7 +25,8 @@ module Gitlab
user: deployment.deployed_by.hook_attrs,
user_url: Gitlab::UrlBuilder.build(deployment.deployed_by),
commit_url: Gitlab::UrlBuilder.build(deployment.commit),
- commit_title: deployment.commit.title
+ commit_title: deployment.commit.title,
+ ref: deployment.ref
}
end
end
diff --git a/lib/gitlab/database/background_migration/batched_job.rb b/lib/gitlab/database/background_migration/batched_job.rb
index 503172dd750..290fa51692a 100644
--- a/lib/gitlab/database/background_migration/batched_job.rb
+++ b/lib/gitlab/database/background_migration/batched_job.rb
@@ -12,17 +12,6 @@ module Gitlab
MAX_ATTEMPTS = 3
STUCK_JOBS_TIMEOUT = 1.hour.freeze
- belongs_to :batched_migration, foreign_key: :batched_background_migration_id
-
- scope :active, -> { where(status: [:pending, :running]) }
- scope :stuck, -> { active.where('updated_at <= ?', STUCK_JOBS_TIMEOUT.ago) }
- scope :retriable, -> {
- failed_jobs = where(status: :failed).where('attempts < ?', MAX_ATTEMPTS)
-
- from_union([failed_jobs, self.stuck])
- }
- scope :except_succeeded, -> { where(status: self.statuses.except(:succeeded).values) }
-
enum status: {
pending: 0,
running: 1,
@@ -30,7 +19,14 @@ module Gitlab
succeeded: 3
}
+ belongs_to :batched_migration, foreign_key: :batched_background_migration_id
+
+ scope :active, -> { where(status: [:pending, :running]) }
+ scope :stuck, -> { active.where('updated_at <= ?', STUCK_JOBS_TIMEOUT.ago) }
+ scope :retriable, -> { from_union([failed.where('attempts < ?', MAX_ATTEMPTS), self.stuck]) }
+ scope :except_succeeded, -> { where(status: self.statuses.except(:succeeded).values) }
scope :successful_in_execution_order, -> { where.not(finished_at: nil).succeeded.order(:finished_at) }
+ scope :with_preloads, -> { preload(:batched_migration) }
delegate :job_class, :table_name, :column_name, :job_arguments,
to: :batched_migration, prefix: :migration
diff --git a/lib/gitlab/database/background_migration/batched_migration.rb b/lib/gitlab/database/background_migration/batched_migration.rb
index 2844cbe4a74..2f066039874 100644
--- a/lib/gitlab/database/background_migration/batched_migration.rb
+++ b/lib/gitlab/database/background_migration/batched_migration.rb
@@ -113,7 +113,7 @@ module Gitlab
end
def smoothed_time_efficiency(number_of_jobs: 10, alpha: 0.2)
- jobs = batched_jobs.successful_in_execution_order.reverse_order.limit(number_of_jobs)
+ jobs = batched_jobs.successful_in_execution_order.reverse_order.limit(number_of_jobs).with_preloads
return if jobs.size < number_of_jobs
diff --git a/lib/gitlab/database/background_migration_job.rb b/lib/gitlab/database/background_migration_job.rb
index c046571a111..c0e3016fd3d 100644
--- a/lib/gitlab/database/background_migration_job.rb
+++ b/lib/gitlab/database/background_migration_job.rb
@@ -2,7 +2,7 @@
module Gitlab
module Database
- class BackgroundMigrationJob < ActiveRecord::Base # rubocop:disable Rails/ApplicationRecord
+ class BackgroundMigrationJob < SharedModel
include EachBatch
include BulkInsertSafe
diff --git a/lib/gitlab/database/batch_counter.rb b/lib/gitlab/database/batch_counter.rb
index 6c0ce9e481a..417511618e4 100644
--- a/lib/gitlab/database/batch_counter.rb
+++ b/lib/gitlab/database/batch_counter.rb
@@ -52,12 +52,7 @@ module Gitlab
batch_end = [batch_start + batch_size, finish].min
batch_relation = build_relation_batch(batch_start, batch_end, mode)
- op_args = @operation_args
- if @operation == :count && @operation_args.blank? && use_loose_index_scan_for_distinct_values?(mode)
- op_args = [Gitlab::Database::LooseIndexScanDistinctCount::COLUMN_ALIAS]
- end
-
- results = merge_results(results, batch_relation.send(@operation, *op_args)) # rubocop:disable GitlabSecurity/PublicSend
+ results = merge_results(results, batch_relation.send(@operation, *@operation_args)) # rubocop:disable GitlabSecurity/PublicSend
batch_start = batch_end
rescue ActiveRecord::QueryCanceled => error
# retry with a safe batch size & warmer cache
@@ -67,18 +62,6 @@ module Gitlab
log_canceled_batch_fetch(batch_start, mode, batch_relation.to_sql, error)
return FALLBACK
end
- rescue Gitlab::Database::LooseIndexScanDistinctCount::ColumnConfigurationError => error
- Gitlab::AppJsonLogger
- .error(
- event: 'batch_count',
- relation: @relation.table_name,
- operation: @operation,
- operation_args: @operation_args,
- mode: mode,
- message: "LooseIndexScanDistinctCount column error: #{error.message}"
- )
-
- return FALLBACK
end
sleep(SLEEP_TIME_IN_SECONDS)
@@ -104,11 +87,7 @@ module Gitlab
private
def build_relation_batch(start, finish, mode)
- if use_loose_index_scan_for_distinct_values?(mode)
- Gitlab::Database::LooseIndexScanDistinctCount.new(@relation, @column).build_query(from: start, to: finish)
- else
- @relation.select(@column).public_send(mode).where(between_condition(start, finish)) # rubocop:disable GitlabSecurity/PublicSend
- end
+ @relation.select(@column).public_send(mode).where(between_condition(start, finish)) # rubocop:disable GitlabSecurity/PublicSend
end
def batch_size_for_mode_and_operation(mode, operation)
@@ -151,10 +130,6 @@ module Gitlab
)
end
- def use_loose_index_scan_for_distinct_values?(mode)
- Feature.enabled?(:loose_index_scan_for_distinct_values) && not_group_by_query? && mode == :distinct
- end
-
def not_group_by_query?
!@relation.is_a?(ActiveRecord::Relation) || @relation.group_values.blank?
end
diff --git a/lib/gitlab/database/gitlab_loose_foreign_keys.yml b/lib/gitlab/database/gitlab_loose_foreign_keys.yml
index 0343c054f23..d694165574d 100644
--- a/lib/gitlab/database/gitlab_loose_foreign_keys.yml
+++ b/lib/gitlab/database/gitlab_loose_foreign_keys.yml
@@ -1,3 +1,12 @@
+---
+dast_site_profiles_pipelines:
+ - table: ci_pipelines
+ column: ci_pipeline_id
+ on_delete: async_delete
+vulnerability_feedback:
+ - table: ci_pipelines
+ column: pipeline_id
+ on_delete: async_nullify
ci_pipeline_chat_data:
- table: chat_names
column: chat_name_id
@@ -6,7 +15,7 @@ dast_scanner_profiles_builds:
- table: ci_builds
column: ci_build_id
on_delete: async_delete
-dast_scanner_profiles_builds:
+dast_site_profiles_builds:
- table: ci_builds
column: ci_build_id
on_delete: async_delete
@@ -18,10 +27,48 @@ clusters_applications_runners:
- table: ci_runners
column: runner_id
on_delete: async_nullify
+ci_job_token_project_scope_links:
+ - table: users
+ column: added_by_id
+ on_delete: async_nullify
+ci_daily_build_group_report_results:
+ - table: namespaces
+ column: group_id
+ on_delete: async_delete
+ - table: projects
+ column: project_id
+ on_delete: async_delete
+ci_freeze_periods:
+ - table: projects
+ column: project_id
+ on_delete: async_delete
+ci_pending_builds:
+ - table: namespaces
+ column: namespace_id
+ on_delete: async_delete
+ - table: projects
+ column: project_id
+ on_delete: async_delete
+ci_resource_groups:
+ - table: projects
+ column: project_id
+ on_delete: async_delete
+ci_runner_namespaces:
+ - table: namespaces
+ column: namespace_id
+ on_delete: async_delete
+ci_running_builds:
+ - table: projects
+ column: project_id
+ on_delete: async_delete
ci_namespace_mirrors:
- table: namespaces
column: namespace_id
on_delete: async_delete
+ci_build_report_results:
+ - table: projects
+ column: project_id
+ on_delete: async_delete
ci_builds:
- table: users
column: user_id
@@ -43,6 +90,22 @@ ci_project_mirrors:
- table: namespaces
column: namespace_id
on_delete: async_delete
+ci_unit_tests:
+ - table: projects
+ column: project_id
+ on_delete: async_delete
+merge_requests:
+ - table: ci_pipelines
+ column: head_pipeline_id
+ on_delete: async_nullify
+vulnerability_statistics:
+ - table: ci_pipelines
+ column: latest_pipeline_id
+ on_delete: async_nullify
+vulnerability_occurrence_pipelines:
+ - table: ci_pipelines
+ column: pipeline_id
+ on_delete: async_delete
packages_build_infos:
- table: ci_pipelines
column: pipeline_id
@@ -67,3 +130,31 @@ project_pages_metadata:
- table: ci_job_artifacts
column: artifacts_archive_id
on_delete: async_nullify
+ci_pipeline_schedules:
+ - table: users
+ column: owner_id
+ on_delete: async_nullify
+ci_group_variables:
+ - table: namespaces
+ column: group_id
+ on_delete: async_delete
+ci_minutes_additional_packs:
+ - table: namespaces
+ column: namespace_id
+ on_delete: async_delete
+requirements_management_test_reports:
+ - table: ci_builds
+ column: build_id
+ on_delete: async_nullify
+security_scans:
+ - table: ci_builds
+ column: build_id
+ on_delete: async_delete
+ci_secure_files:
+ - table: projects
+ column: project_id
+ on_delete: async_delete
+ci_pipeline_artifacts:
+ - table: projects
+ column: project_id
+ on_delete: async_delete
diff --git a/lib/gitlab/database/gitlab_schemas.yml b/lib/gitlab/database/gitlab_schemas.yml
index 24c2d634780..fb5d8cfa32f 100644
--- a/lib/gitlab/database/gitlab_schemas.yml
+++ b/lib/gitlab/database/gitlab_schemas.yml
@@ -107,6 +107,7 @@ ci_runner_projects: :gitlab_ci
ci_runners: :gitlab_ci
ci_running_builds: :gitlab_ci
ci_sources_pipelines: :gitlab_ci
+ci_secure_files: :gitlab_ci
ci_sources_projects: :gitlab_ci
ci_stages: :gitlab_ci
ci_subscriptions_projects: :gitlab_ci
@@ -200,7 +201,7 @@ experiment_subjects: :gitlab_main
experiment_users: :gitlab_main
external_approval_rules: :gitlab_main
external_approval_rules_protected_branches: :gitlab_main
-external_pull_requests: :gitlab_main
+external_pull_requests: :gitlab_ci
external_status_checks: :gitlab_main
external_status_checks_protected_branches: :gitlab_main
feature_gates: :gitlab_main
@@ -231,6 +232,7 @@ gpg_key_subkeys: :gitlab_main
gpg_signatures: :gitlab_main
grafana_integrations: :gitlab_main
group_custom_attributes: :gitlab_main
+group_crm_settings: :gitlab_main
group_deletion_schedules: :gitlab_main
group_deploy_keys: :gitlab_main
group_deploy_keys_groups: :gitlab_main
@@ -460,6 +462,8 @@ security_findings: :gitlab_main
security_orchestration_policy_configurations: :gitlab_main
security_orchestration_policy_rule_schedules: :gitlab_main
security_scans: :gitlab_main
+security_training_providers: :gitlab_main
+security_trainings: :gitlab_main
self_managed_prometheus_alert_events: :gitlab_main
sent_notifications: :gitlab_main
sentry_issues: :gitlab_main
@@ -521,13 +525,7 @@ vulnerabilities: :gitlab_main
vulnerability_exports: :gitlab_main
vulnerability_external_issue_links: :gitlab_main
vulnerability_feedback: :gitlab_main
-vulnerability_finding_evidence_assets: :gitlab_main
-vulnerability_finding_evidence_headers: :gitlab_main
-vulnerability_finding_evidence_requests: :gitlab_main
-vulnerability_finding_evidence_responses: :gitlab_main
vulnerability_finding_evidences: :gitlab_main
-vulnerability_finding_evidence_sources: :gitlab_main
-vulnerability_finding_evidence_supporting_messages: :gitlab_main
vulnerability_finding_links: :gitlab_main
vulnerability_finding_signatures: :gitlab_main
vulnerability_findings_remediations: :gitlab_main
diff --git a/lib/gitlab/database/grant.rb b/lib/gitlab/database/grant.rb
index c8a30c68bc6..0093848ee6f 100644
--- a/lib/gitlab/database/grant.rb
+++ b/lib/gitlab/database/grant.rb
@@ -10,7 +10,7 @@ module Gitlab
# We _must not_ use quote_table_name as this will produce double
# quotes on PostgreSQL and for "has_table_privilege" we need single
# quotes.
- connection = ActiveRecord::Base.connection # rubocop: disable Database/MultipleDatabases
+ connection = ApplicationRecord.connection
quoted_table = connection.quote(table)
begin
diff --git a/lib/gitlab/database/load_balancing/setup.rb b/lib/gitlab/database/load_balancing/setup.rb
index ef38f42f50b..126c8bb2aa6 100644
--- a/lib/gitlab/database/load_balancing/setup.rb
+++ b/lib/gitlab/database/load_balancing/setup.rb
@@ -104,11 +104,9 @@ module Gitlab
end
end
- # rubocop:disable Database/MultipleDatabases
def connection
- use_model_load_balancing? ? super : ActiveRecord::Base.connection
+ use_model_load_balancing? ? super : ApplicationRecord.connection
end
- # rubocop:enable Database/MultipleDatabases
end
end
end
diff --git a/lib/gitlab/database/loose_index_scan_distinct_count.rb b/lib/gitlab/database/loose_index_scan_distinct_count.rb
deleted file mode 100644
index 26be07f91c4..00000000000
--- a/lib/gitlab/database/loose_index_scan_distinct_count.rb
+++ /dev/null
@@ -1,102 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Database
- # This class builds efficient batched distinct query by using loose index scan.
- # Consider the following example:
- # > Issue.distinct(:project_id).where(project_id: (1...100)).count
- #
- # Note: there is an index on project_id
- #
- # This query will read each element in the index matching the project_id filter.
- # If for a project_id has 100_000 issues, all 100_000 elements will be read.
- #
- # A loose index scan will only read one entry from the index for each project_id to reduce the number of disk reads.
- #
- # Usage:
- #
- # Gitlab::Database::LooseIndexScanDisctinctCount.new(Issue, :project_id).count(from: 1, to: 100)
- #
- # The query will return the number of distinct projects_ids between 1 and 100
- #
- # Getting the Arel query:
- #
- # Gitlab::Database::LooseIndexScanDisctinctCount.new(Issue, :project_id).build_query(from: 1, to: 100)
- class LooseIndexScanDistinctCount
- COLUMN_ALIAS = 'distinct_count_column'
-
- ColumnConfigurationError = Class.new(StandardError)
-
- def initialize(scope, column)
- if scope.is_a?(ActiveRecord::Relation)
- @scope = scope
- @model = scope.model
- else
- @scope = scope.where({})
- @model = scope
- end
-
- @column = transform_column(column)
- end
-
- def count(from:, to:)
- build_query(from: from, to: to).count(COLUMN_ALIAS)
- end
-
- def build_query(from:, to:) # rubocop:disable Metrics/AbcSize
- cte = Gitlab::SQL::RecursiveCTE.new(:counter_cte, union_args: { remove_order: false })
- table = model.arel_table
-
- cte << @scope
- .dup
- .select(column.as(COLUMN_ALIAS))
- .where(column.gteq(from))
- .where(column.lt(to))
- .order(column)
- .limit(1)
-
- inner_query = @scope
- .dup
- .where(column.gt(cte.table[COLUMN_ALIAS]))
- .where(column.lt(to))
- .select(column.as(COLUMN_ALIAS))
- .order(column)
- .limit(1)
-
- cte << cte.table
- .project(Arel::Nodes::Grouping.new(Arel.sql(inner_query.to_sql)).as(COLUMN_ALIAS))
- .where(cte.table[COLUMN_ALIAS].lt(to))
-
- model
- .with
- .recursive(cte.to_arel)
- .from(cte.alias_to(table))
- .unscope(where: :source_type)
- .unscope(where: model.inheritance_column) # Remove STI query, not needed here
- end
-
- private
-
- attr_reader :column, :model
-
- # Transforms the column so it can be used in Arel expressions
- #
- # 'table.column' => 'table.column'
- # 'column' => 'table_name.column'
- # :column => 'table_name.column'
- # Arel::Attributes::Attribute => name of the column
- def transform_column(column)
- if column.is_a?(String) || column.is_a?(Symbol)
- column_as_string = column.to_s
- column_as_string = "#{model.table_name}.#{column_as_string}" unless column_as_string.include?('.')
-
- Arel.sql(column_as_string)
- elsif column.is_a?(Arel::Attributes::Attribute)
- column
- else
- raise ColumnConfigurationError, "Cannot transform the column: #{column.inspect}, please provide the column name as string"
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb
index 4245dd80714..aa5ac1e3486 100644
--- a/lib/gitlab/database/migration_helpers.rb
+++ b/lib/gitlab/database/migration_helpers.rb
@@ -778,186 +778,6 @@ module Gitlab
install_rename_triggers(table, old, new)
end
- # Changes the column type of a table using a background migration.
- #
- # Because this method uses a background migration it's more suitable for
- # large tables. For small tables it's better to use
- # `change_column_type_concurrently` since it can complete its work in a
- # much shorter amount of time and doesn't rely on Sidekiq.
- #
- # Example usage:
- #
- # class Issue < ActiveRecord::Base
- # self.table_name = 'issues'
- #
- # include EachBatch
- #
- # def self.to_migrate
- # where('closed_at IS NOT NULL')
- # end
- # end
- #
- # change_column_type_using_background_migration(
- # Issue.to_migrate,
- # :closed_at,
- # :datetime_with_timezone
- # )
- #
- # Reverting a migration like this is done exactly the same way, just with
- # a different type to migrate to (e.g. `:datetime` in the above example).
- #
- # relation - An ActiveRecord relation to use for scheduling jobs and
- # figuring out what table we're modifying. This relation _must_
- # have the EachBatch module included.
- #
- # column - The name of the column for which the type will be changed.
- #
- # new_type - The new type of the column.
- #
- # batch_size - The number of rows to schedule in a single background
- # migration.
- #
- # interval - The time interval between every background migration.
- def change_column_type_using_background_migration(
- relation,
- column,
- new_type,
- batch_size: 10_000,
- interval: 10.minutes
- )
-
- unless relation.model < EachBatch
- raise TypeError, 'The relation must include the EachBatch module'
- end
-
- temp_column = "#{column}_for_type_change"
- table = relation.table_name
- max_index = 0
-
- add_column(table, temp_column, new_type)
- install_rename_triggers(table, column, temp_column)
-
- # Schedule the jobs that will copy the data from the old column to the
- # new one. Rows with NULL values in our source column are skipped since
- # the target column is already NULL at this point.
- relation.where.not(column => nil).each_batch(of: batch_size) do |batch, index|
- start_id, end_id = batch.pluck('MIN(id), MAX(id)').first
- max_index = index
-
- migrate_in(
- index * interval,
- 'CopyColumn',
- [table, column, temp_column, start_id, end_id]
- )
- end
-
- # Schedule the renaming of the column to happen (initially) 1 hour after
- # the last batch finished.
- migrate_in(
- (max_index * interval) + 1.hour,
- 'CleanupConcurrentTypeChange',
- [table, column, temp_column]
- )
-
- if perform_background_migration_inline?
- # To ensure the schema is up to date immediately we perform the
- # migration inline in dev / test environments.
- Gitlab::BackgroundMigration.steal('CopyColumn')
- Gitlab::BackgroundMigration.steal('CleanupConcurrentTypeChange')
- end
- end
-
- # Renames a column using a background migration.
- #
- # Because this method uses a background migration it's more suitable for
- # large tables. For small tables it's better to use
- # `rename_column_concurrently` since it can complete its work in a much
- # shorter amount of time and doesn't rely on Sidekiq.
- #
- # Example usage:
- #
- # rename_column_using_background_migration(
- # :users,
- # :feed_token,
- # :rss_token
- # )
- #
- # table - The name of the database table containing the column.
- #
- # old - The old column name.
- #
- # new - The new column name.
- #
- # type - The type of the new column. If no type is given the old column's
- # type is used.
- #
- # batch_size - The number of rows to schedule in a single background
- # migration.
- #
- # interval - The time interval between every background migration.
- def rename_column_using_background_migration(
- table,
- old_column,
- new_column,
- type: nil,
- batch_size: 10_000,
- interval: 10.minutes
- )
-
- check_trigger_permissions!(table)
-
- old_col = column_for(table, old_column)
- new_type = type || old_col.type
- max_index = 0
-
- add_column(table, new_column, new_type,
- limit: old_col.limit,
- precision: old_col.precision,
- scale: old_col.scale)
-
- # We set the default value _after_ adding the column so we don't end up
- # updating any existing data with the default value. This isn't
- # necessary since we copy over old values further down.
- change_column_default(table, new_column, old_col.default) if old_col.default
-
- install_rename_triggers(table, old_column, new_column)
-
- model = Class.new(ActiveRecord::Base) do
- self.table_name = table
-
- include ::EachBatch
- end
-
- # Schedule the jobs that will copy the data from the old column to the
- # new one. Rows with NULL values in our source column are skipped since
- # the target column is already NULL at this point.
- model.where.not(old_column => nil).each_batch(of: batch_size) do |batch, index|
- start_id, end_id = batch.pluck('MIN(id), MAX(id)').first
- max_index = index
-
- migrate_in(
- index * interval,
- 'CopyColumn',
- [table, old_column, new_column, start_id, end_id]
- )
- end
-
- # Schedule the renaming of the column to happen (initially) 1 hour after
- # the last batch finished.
- migrate_in(
- (max_index * interval) + 1.hour,
- 'CleanupConcurrentRename',
- [table, old_column, new_column]
- )
-
- if perform_background_migration_inline?
- # To ensure the schema is up to date immediately we perform the
- # migration inline in dev / test environments.
- Gitlab::BackgroundMigration.steal('CopyColumn')
- Gitlab::BackgroundMigration.steal('CleanupConcurrentRename')
- end
- end
-
def convert_to_bigint_column(column)
"#{column}_convert_to_bigint"
end
diff --git a/lib/gitlab/database/migrations/background_migration_helpers.rb b/lib/gitlab/database/migrations/background_migration_helpers.rb
index 8c33c41ce77..4f1b490cc8f 100644
--- a/lib/gitlab/database/migrations/background_migration_helpers.rb
+++ b/lib/gitlab/database/migrations/background_migration_helpers.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-
module Gitlab
module Database
module Migrations
@@ -45,11 +44,11 @@ module Gitlab
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
+ job_coordinator = coordinator_for_tracking_database
+
# To not overload the worker too much we enforce a minimum interval both
# when scheduling and performing jobs.
- if delay_interval < BackgroundMigrationWorker.minimum_interval
- delay_interval = BackgroundMigrationWorker.minimum_interval
- end
+ delay_interval = [delay_interval, job_coordinator.minimum_interval].max
final_delay = 0
batch_counter = 0
@@ -60,14 +59,14 @@ module Gitlab
start_id, end_id = relation.pluck(min, max).first
- # `BackgroundMigrationWorker.bulk_perform_in` schedules all jobs for
+ # `SingleDatabaseWorker.bulk_perform_in` schedules all jobs for
# the same time, which is not helpful in most cases where we wish to
# spread the work over time.
final_delay = initial_delay + delay_interval * index
full_job_arguments = [start_id, end_id] + other_job_arguments
track_in_database(job_class_name, full_job_arguments) if track_jobs
- migrate_in(final_delay, job_class_name, full_job_arguments)
+ migrate_in(final_delay, job_class_name, full_job_arguments, coordinator: job_coordinator)
batch_counter += 1
end
@@ -91,9 +90,11 @@ module Gitlab
# delay_interval - The duration between each job's scheduled time
# batch_size - The maximum number of jobs to fetch to memory from the database.
def requeue_background_migration_jobs_by_range_at_intervals(job_class_name, delay_interval, batch_size: BATCH_SIZE, initial_delay: 0)
+ job_coordinator = coordinator_for_tracking_database
+
# To not overload the worker too much we enforce a minimum interval both
# when scheduling and performing jobs.
- delay_interval = [delay_interval, BackgroundMigrationWorker.minimum_interval].max
+ delay_interval = [delay_interval, job_coordinator.minimum_interval].max
final_delay = 0
job_counter = 0
@@ -103,7 +104,7 @@ module Gitlab
job_batch.each do |job|
final_delay = initial_delay + delay_interval * job_counter
- migrate_in(final_delay, job_class_name, job.arguments)
+ migrate_in(final_delay, job_class_name, job.arguments, coordinator: job_coordinator)
job_counter += 1
end
@@ -132,56 +133,33 @@ module Gitlab
# This method does not garauntee that all jobs completed successfully.
# It can only be used if the previous background migration used the queue_background_migration_jobs_by_range_at_intervals helper.
def finalize_background_migration(class_name, delete_tracking_jobs: ['succeeded'])
+ job_coordinator = coordinator_for_tracking_database
+
# Empty the sidekiq queue.
- Gitlab::BackgroundMigration.steal(class_name)
+ job_coordinator.steal(class_name)
# Process pending tracked jobs.
jobs = Gitlab::Database::BackgroundMigrationJob.pending.for_migration_class(class_name)
+
jobs.find_each do |job|
- BackgroundMigrationWorker.new.perform(job.class_name, job.arguments)
+ job_coordinator.perform(job.class_name, job.arguments)
end
# Empty the sidekiq queue.
- Gitlab::BackgroundMigration.steal(class_name)
+ job_coordinator.steal(class_name)
# Delete job tracking rows.
delete_job_tracking(class_name, status: delete_tracking_jobs) if delete_tracking_jobs
end
- def perform_background_migration_inline?
- Rails.env.test? || Rails.env.development?
- end
-
- def migrate_async(*args)
- with_migration_context do
- BackgroundMigrationWorker.perform_async(*args)
- end
- end
-
- def migrate_in(*args)
- with_migration_context do
- BackgroundMigrationWorker.perform_in(*args)
- end
- end
-
- def bulk_migrate_in(*args)
+ def migrate_in(*args, coordinator: coordinator_for_tracking_database)
with_migration_context do
- BackgroundMigrationWorker.bulk_perform_in(*args)
+ coordinator.perform_in(*args)
end
end
- def bulk_migrate_async(*args)
- with_migration_context do
- BackgroundMigrationWorker.bulk_perform_async(*args)
- end
- end
-
- def with_migration_context(&block)
- Gitlab::ApplicationContext.with_context(caller_id: self.class.to_s, &block)
- end
-
def delete_queued_jobs(class_name)
- Gitlab::BackgroundMigration.steal(class_name) do |job|
+ coordinator_for_tracking_database.steal(class_name) do |job|
job.delete
false
@@ -196,9 +174,21 @@ module Gitlab
private
+ def with_migration_context(&block)
+ Gitlab::ApplicationContext.with_context(caller_id: self.class.to_s, &block)
+ end
+
def track_in_database(class_name, arguments)
Gitlab::Database::BackgroundMigrationJob.create!(class_name: class_name, arguments: arguments)
end
+
+ def coordinator_for_tracking_database
+ Gitlab::BackgroundMigration.coordinator_for_database(tracking_database)
+ end
+
+ def tracking_database
+ Gitlab::BackgroundMigration::DEFAULT_TRACKING_DATABASE
+ end
end
end
end
diff --git a/lib/gitlab/database/partitioning/partition_manager.rb b/lib/gitlab/database/partitioning/partition_manager.rb
index aa824dfbd2f..ba6fa0cf278 100644
--- a/lib/gitlab/database/partitioning/partition_manager.rb
+++ b/lib/gitlab/database/partitioning/partition_manager.rb
@@ -64,6 +64,10 @@ module Gitlab
# with_lock_retries starts a requires_new transaction most of the time, but not on the last iteration
with_lock_retries do
connection.transaction(requires_new: false) do # so we open a transaction here if not already in progress
+ # Partitions might not get created (IF NOT EXISTS) so explicit locking will not happen.
+ # This LOCK TABLE ensures to have exclusive lock as the first step.
+ connection.execute "LOCK TABLE #{connection.quote_table_name(model.table_name)} IN ACCESS EXCLUSIVE MODE"
+
partitions.each do |partition|
connection.execute partition.to_sql
diff --git a/lib/gitlab/database/partitioning/sliding_list_strategy.rb b/lib/gitlab/database/partitioning/sliding_list_strategy.rb
index 21b86b43ae7..e9865fb91d6 100644
--- a/lib/gitlab/database/partitioning/sliding_list_strategy.rb
+++ b/lib/gitlab/database/partitioning/sliding_list_strategy.rb
@@ -44,7 +44,18 @@ module Gitlab
def extra_partitions
possibly_extra = current_partitions[0...-1] # Never consider the most recent partition
- possibly_extra.take_while { |p| detach_partition_if.call(p.value) }
+ extra = possibly_extra.take_while { |p| detach_partition_if.call(p.value) }
+
+ default_value = current_default_value
+ if extra.any? { |p| p.value == default_value }
+ Gitlab::AppLogger.error(message: "Inconsistent partition detected: partition with value #{current_default_value} should not be deleted because it's used as the default value.",
+ partition_number: current_default_value,
+ table_name: model.table_name)
+
+ extra = extra.reject { |p| p.value == default_value }
+ end
+
+ extra
end
def after_adding_partitions
@@ -64,6 +75,21 @@ module Gitlab
private
+ def current_default_value
+ column_name = model.connection.quote(partitioning_key)
+ table_name = model.connection.quote(model.table_name)
+
+ value = model.connection.select_value <<~SQL
+ SELECT columns.column_default AS default_value
+ FROM information_schema.columns columns
+ WHERE columns.column_name = #{column_name} AND columns.table_name = #{table_name}
+ SQL
+
+ raise "No default value found for the #{partitioning_key} column within #{model.name}" if value.nil?
+
+ Integer(value)
+ end
+
def ensure_partitioning_column_ignored!
unless model.ignored_columns.include?(partitioning_key.to_s)
raise "Add #{partitioning_key} to #{model.name}.ignored_columns to use it with SlidingListStrategy"
diff --git a/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table.rb b/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table.rb
index 17a42d997e6..f551fa06cad 100644
--- a/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table.rb
+++ b/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table.rb
@@ -4,7 +4,7 @@ module Gitlab
module Database
module PartitioningMigrationHelpers
# Class that will generically copy data from a given table into its corresponding partitioned table
- class BackfillPartitionedTable
+ class BackfillPartitionedTable < ::Gitlab::BackgroundMigration::BaseJob
include ::Gitlab::Database::DynamicModelHelpers
SUB_BATCH_SIZE = 2_500
@@ -21,7 +21,7 @@ module Gitlab
return
end
- bulk_copy = BulkCopy.new(source_table, partitioned_table, source_column)
+ bulk_copy = BulkCopy.new(source_table, partitioned_table, source_column, connection: connection)
parent_batch_relation = relation_scoped_to_range(source_table, source_column, start_id, stop_id)
parent_batch_relation.each_batch(of: SUB_BATCH_SIZE) do |sub_batch|
@@ -36,10 +36,6 @@ module Gitlab
private
- def connection
- ActiveRecord::Base.connection
- end
-
def transaction_open?
connection.transaction_open?
end
@@ -53,7 +49,8 @@ module Gitlab
end
def relation_scoped_to_range(source_table, source_key_column, start_id, stop_id)
- define_batchable_model(source_table).where(source_key_column => start_id..stop_id)
+ define_batchable_model(source_table)
+ .where(source_key_column => start_id..stop_id)
end
def mark_jobs_as_succeeded(*arguments)
@@ -64,12 +61,13 @@ module Gitlab
class BulkCopy
DELIMITER = ', '
- attr_reader :source_table, :destination_table, :source_column
+ attr_reader :source_table, :destination_table, :source_column, :connection
- def initialize(source_table, destination_table, source_column)
+ def initialize(source_table, destination_table, source_column, connection:)
@source_table = source_table
@destination_table = destination_table
@source_column = source_column
+ @connection = connection
end
def copy_between(start_id, stop_id)
@@ -85,10 +83,6 @@ module Gitlab
private
- def connection
- @connection ||= ActiveRecord::Base.connection
- end
-
def column_listing
@column_listing ||= connection.columns(source_table).map(&:name).join(DELIMITER)
end
diff --git a/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb b/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb
index c382d2f0715..984c708aa48 100644
--- a/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb
+++ b/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb
@@ -406,7 +406,8 @@ module Gitlab
end
def copy_missed_records(source_table_name, partitioned_table_name, source_column)
- backfill_table = BackfillPartitionedTable.new
+ backfill_table = BackfillPartitionedTable.new(connection: connection)
+
relation = ::Gitlab::Database::BackgroundMigrationJob.pending
.for_partitioning_migration(MIGRATION_CLASS_NAME, source_table_name)
diff --git a/lib/gitlab/database/reflection.rb b/lib/gitlab/database/reflection.rb
index 48a4de28541..3ea7277571f 100644
--- a/lib/gitlab/database/reflection.rb
+++ b/lib/gitlab/database/reflection.rb
@@ -105,6 +105,35 @@ module Gitlab
row['system_identifier']
end
+ def flavor
+ {
+ # Based on https://aws.amazon.com/premiumsupport/knowledge-center/aurora-version-number/
+ 'Amazon Aurora PostgreSQL' => { statement: 'SELECT AURORA_VERSION()', error: /PG::UndefinedFunction/ },
+ # Based on https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts.General.FeatureSupport.Extensions,
+ # this is also available for both Aurora and RDS, so we need to check for the former first.
+ 'PostgreSQL on Amazon RDS' => { statement: 'SHOW rds.extensions', error: /PG::UndefinedObject/ },
+ # Based on https://cloud.google.com/sql/docs/postgres/flags#postgres-c this should be specific
+ # to Cloud SQL for PostgreSQL
+ 'Cloud SQL for PostgreSQL' => { statement: 'SHOW cloudsql.iam_authentication', error: /PG::UndefinedObject/ },
+ # Based on
+ # - https://docs.microsoft.com/en-us/azure/postgresql/flexible-server/concepts-extensions
+ # - https://docs.microsoft.com/en-us/azure/postgresql/concepts-extensions
+ # this should be available only for Azure Database for PostgreSQL - Flexible Server.
+ 'Azure Database for PostgreSQL - Flexible Server' => { statement: 'SHOW azure.extensions', error: /PG::UndefinedObject/ },
+ # Based on
+ # - https://docs.microsoft.com/en-us/azure/postgresql/flexible-server/concepts-servers
+ # - https://docs.microsoft.com/en-us/azure/postgresql/concepts-servers#managing-your-server
+ # this database is present on both Flexible and Single server, so we should check the former first.
+ 'Azure Database for PostgreSQL - Single Server' => { statement: "SELECT datname FROM pg_database WHERE datname = 'azure_maintenance'" }
+ }.each do |flavor, conditions|
+ return flavor if connection.execute(conditions[:statement]).to_a.present?
+ rescue ActiveRecord::StatementInvalid => e
+ raise if conditions[:error] && !e.message.match?(conditions[:error])
+ end
+
+ nil
+ end
+
private
def connection
diff --git a/lib/gitlab/database/reindexing.rb b/lib/gitlab/database/reindexing.rb
index 6ffe14249f0..91c3fcc7d72 100644
--- a/lib/gitlab/database/reindexing.rb
+++ b/lib/gitlab/database/reindexing.rb
@@ -76,20 +76,7 @@ module Gitlab
def self.cleanup_leftovers!
PostgresIndex.reindexing_leftovers.each do |index|
- Gitlab::AppLogger.info("Removing index #{index.identifier} which is a leftover, temporary index from previous reindexing activity")
-
- retries = Gitlab::Database::WithLockRetriesOutsideTransaction.new(
- connection: index.connection,
- timing_configuration: REMOVE_INDEX_RETRY_CONFIG,
- klass: self.class,
- logger: Gitlab::AppLogger
- )
-
- retries.run(raise_on_exhaustion: false) do
- index.connection.tap do |conn|
- conn.execute("DROP INDEX CONCURRENTLY IF EXISTS #{conn.quote_table_name(index.schema)}.#{conn.quote_table_name(index.name)}")
- end
- end
+ Coordinator.new(index).drop
end
end
end
diff --git a/lib/gitlab/database/reindexing/coordinator.rb b/lib/gitlab/database/reindexing/coordinator.rb
index 3e4a83aa2e7..b4f7da999df 100644
--- a/lib/gitlab/database/reindexing/coordinator.rb
+++ b/lib/gitlab/database/reindexing/coordinator.rb
@@ -31,6 +31,25 @@ module Gitlab
end
end
+ def drop
+ try_obtain_lease do
+ Gitlab::AppLogger.info("Removing index #{index.identifier} which is a leftover, temporary index from previous reindexing activity")
+
+ retries = Gitlab::Database::WithLockRetriesOutsideTransaction.new(
+ connection: index.connection,
+ timing_configuration: REMOVE_INDEX_RETRY_CONFIG,
+ klass: self.class,
+ logger: Gitlab::AppLogger
+ )
+
+ retries.run(raise_on_exhaustion: false) do
+ index.connection.tap do |conn|
+ conn.execute("DROP INDEX CONCURRENTLY IF EXISTS #{conn.quote_table_name(index.schema)}.#{conn.quote_table_name(index.name)}")
+ end
+ end
+ end
+ end
+
private
def with_notifications(action)
diff --git a/lib/gitlab/database_importers/work_items/base_type_importer.rb b/lib/gitlab/database_importers/work_items/base_type_importer.rb
index c5acdb41de5..2d9700cb2bc 100644
--- a/lib/gitlab/database_importers/work_items/base_type_importer.rb
+++ b/lib/gitlab/database_importers/work_items/base_type_importer.rb
@@ -5,8 +5,8 @@ module Gitlab
module WorkItems
module BaseTypeImporter
def self.import
- WorkItem::Type::BASE_TYPES.each do |type, attributes|
- WorkItem::Type.create!(base_type: type, **attributes.slice(:name, :icon_name))
+ ::WorkItems::Type::BASE_TYPES.each do |type, attributes|
+ ::WorkItems::Type.create!(base_type: type, **attributes.slice(:name, :icon_name))
end
end
end
diff --git a/lib/gitlab/email.rb b/lib/gitlab/email.rb
index 5f935880764..2e8f076c5d8 100644
--- a/lib/gitlab/email.rb
+++ b/lib/gitlab/email.rb
@@ -18,5 +18,6 @@ module Gitlab
InvalidMergeRequestError = Class.new(InvalidRecordError)
UnknownIncomingEmail = Class.new(ProcessingError)
InvalidAttachment = Class.new(ProcessingError)
+ EmailTooLarge = Class.new(ProcessingError)
end
end
diff --git a/lib/gitlab/email/failure_handler.rb b/lib/gitlab/email/failure_handler.rb
new file mode 100644
index 00000000000..1079a9c2bb6
--- /dev/null
+++ b/lib/gitlab/email/failure_handler.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Email
+ module FailureHandler
+ def self.handle(receiver, error)
+ can_retry = false
+ reason =
+ case error
+ when Gitlab::Email::UnknownIncomingEmail
+ s_("EmailError|We couldn't figure out what the email is for. Please create your issue or comment through the web interface.")
+ when Gitlab::Email::SentNotificationNotFoundError
+ s_("EmailError|We couldn't figure out what the email is in reply to. Please create your comment through the web interface.")
+ when Gitlab::Email::ProjectNotFound
+ s_("EmailError|We couldn't find the project. Please check if there's any typo.")
+ when Gitlab::Email::EmptyEmailError
+ can_retry = true
+ s_("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.")
+ when Gitlab::Email::UserNotFoundError
+ s_("EmailError|We couldn't figure out what user corresponds to the email. Please create your comment through the web interface.")
+ when Gitlab::Email::UserBlockedError
+ s_("EmailError|Your account has been blocked. If you believe this is in error, contact a staff member.")
+ when Gitlab::Email::UserNotAuthorizedError
+ s_("EmailError|You are not allowed to perform this action. If you believe this is in error, contact a staff member.")
+ when Gitlab::Email::NoteableNotFoundError
+ s_("EmailError|The thread you are replying to no longer exists, perhaps it was deleted? If you believe this is in error, contact a staff member.")
+ when Gitlab::Email::InvalidAttachment
+ error.message
+ when Gitlab::Email::InvalidRecordError
+ can_retry = true
+ error.message
+ when Gitlab::Email::EmailTooLarge
+ s_("EmailError|We couldn't process your email because it is too large. Please create your issue or comment through the web interface.")
+ end
+
+ if reason
+ receiver.mail.body = nil
+
+ EmailRejectionMailer.rejection(reason, receiver.mail.encoded, can_retry).deliver_later
+ end
+
+ reason
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/error_tracking/processor/sidekiq_processor.rb b/lib/gitlab/error_tracking/processor/sidekiq_processor.rb
index 0d2f673d73c..cc8cfd827f1 100644
--- a/lib/gitlab/error_tracking/processor/sidekiq_processor.rb
+++ b/lib/gitlab/error_tracking/processor/sidekiq_processor.rb
@@ -53,6 +53,8 @@ module Gitlab
# 'args' in :job => from default error handler
job_holder = sidekiq.key?('args') ? sidekiq : sidekiq[:job]
+ return event unless job_holder
+
if job_holder['args']
job_holder['args'] = filter_arguments(job_holder['args'], job_holder['class']).to_a
end
diff --git a/lib/gitlab/event_store.rb b/lib/gitlab/event_store.rb
new file mode 100644
index 00000000000..3d7b6b27eb0
--- /dev/null
+++ b/lib/gitlab/event_store.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+# Gitlab::EventStore is a simple pub-sub mechanism that lets you publish
+# domain events and use Sidekiq workers as event handlers.
+#
+# It can be used to decouple domains from different bounded contexts
+# by publishing domain events and let any interested parties subscribe
+# to them.
+#
+module Gitlab
+ module EventStore
+ Error = Class.new(StandardError)
+ InvalidEvent = Class.new(Error)
+ InvalidSubscriber = Class.new(Error)
+
+ def self.publish(event)
+ instance.publish(event)
+ end
+
+ def self.instance
+ @instance ||= configure!
+ end
+
+ # Define all event subscriptions using:
+ #
+ # store.subscribe(DomainA::SomeWorker, to: DomainB::SomeEvent)
+ #
+ # It is possible to subscribe to a subset of events matching a condition:
+ #
+ # store.subscribe(DomainA::SomeWorker, to: DomainB::SomeEvent), if: ->(event) { event.data == :some_value }
+ #
+ def self.configure!
+ Store.new do |store|
+ ###
+ # Add subscriptions here:
+
+ store.subscribe ::MergeRequests::UpdateHeadPipelineWorker, to: ::Ci::PipelineCreatedEvent
+ end
+ end
+ private_class_method :configure!
+ end
+end
diff --git a/lib/gitlab/event_store/event.rb b/lib/gitlab/event_store/event.rb
new file mode 100644
index 00000000000..ee0c329b8e8
--- /dev/null
+++ b/lib/gitlab/event_store/event.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+# An Event object represents a domain event that occurred in a bounded context.
+# By publishing events we notify other bounded contexts about something
+# that happened, so that they can react to it.
+#
+# Define new event classes under `app/events/<namespace>/` with a name
+# representing something that happened in the past:
+#
+# class Projects::ProjectCreatedEvent < Gitlab::EventStore::Event
+# def schema
+# {
+# 'type' => 'object',
+# 'properties' => {
+# 'project_id' => { 'type' => 'integer' }
+# }
+# }
+# end
+# end
+#
+# To publish it:
+#
+# Gitlab::EventStore.publish(
+# Projects::ProjectCreatedEvent.new(data: { project_id: project.id })
+# )
+#
+module Gitlab
+ module EventStore
+ class Event
+ attr_reader :data
+
+ def initialize(data:)
+ validate_schema!(data)
+ @data = data
+ end
+
+ def schema
+ raise NotImplementedError, 'must specify schema to validate the event'
+ end
+
+ private
+
+ def validate_schema!(data)
+ unless data.is_a?(Hash)
+ raise Gitlab::EventStore::InvalidEvent, "Event data must be a Hash"
+ end
+
+ unless JSONSchemer.schema(schema).valid?(data.deep_stringify_keys)
+ raise Gitlab::EventStore::InvalidEvent, "Data for event #{self.class} does not match the defined schema: #{schema}"
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/event_store/store.rb b/lib/gitlab/event_store/store.rb
new file mode 100644
index 00000000000..ecf3cd7e562
--- /dev/null
+++ b/lib/gitlab/event_store/store.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module EventStore
+ class Store
+ attr_reader :subscriptions
+
+ def initialize
+ @subscriptions = Hash.new { |h, k| h[k] = [] }
+
+ yield(self) if block_given?
+
+ # freeze the subscriptions as safety measure to avoid further
+ # subcriptions after initialization.
+ lock!
+ end
+
+ def subscribe(worker, to:, if: nil)
+ condition = binding.local_variable_get('if')
+
+ Array(to).each do |event|
+ validate_subscription!(worker, event)
+ subscriptions[event] << Gitlab::EventStore::Subscription.new(worker, condition)
+ end
+ end
+
+ def publish(event)
+ unless event.is_a?(Event)
+ raise InvalidEvent, "Event being published is not an instance of Gitlab::EventStore::Event: got #{event.inspect}"
+ end
+
+ subscriptions[event.class].each do |subscription|
+ subscription.consume_event(event)
+ end
+ end
+
+ private
+
+ def lock!
+ @subscriptions.freeze
+ end
+
+ def validate_subscription!(subscriber, event_class)
+ unless event_class < Event
+ raise InvalidEvent, "Event being subscribed to is not a subclass of Gitlab::EventStore::Event: got #{event_class}"
+ end
+
+ unless subscriber.respond_to?(:perform_async)
+ raise InvalidSubscriber, "Subscriber is not an ApplicationWorker: got #{subscriber}"
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/event_store/subscriber.rb b/lib/gitlab/event_store/subscriber.rb
new file mode 100644
index 00000000000..cf326d1f9e4
--- /dev/null
+++ b/lib/gitlab/event_store/subscriber.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+# This module should be included in order to turn an ApplicationWorker
+# into a Subscriber.
+# This module overrides the `perform` method and provides a better and
+# safer interface for handling events via `handle_event` method.
+#
+# @example:
+# class SomeEventSubscriber
+# include ApplicationWorker
+# include Gitlab::EventStore::Subscriber
+#
+# def handle_event(event)
+# # ...
+# end
+# end
+
+module Gitlab
+ module EventStore
+ module Subscriber
+ def perform(event_type, data)
+ raise InvalidEvent, event_type unless self.class.const_defined?(event_type)
+
+ event = event_type.constantize.new(
+ data: data.with_indifferent_access
+ )
+
+ handle_event(event)
+ end
+
+ def handle_event(event)
+ raise NotImplementedError, 'you must implement this methods in order to handle events'
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/event_store/subscription.rb b/lib/gitlab/event_store/subscription.rb
new file mode 100644
index 00000000000..e5c92ab969f
--- /dev/null
+++ b/lib/gitlab/event_store/subscription.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module EventStore
+ class Subscription
+ attr_reader :worker, :condition
+
+ def initialize(worker, condition)
+ @worker = worker
+ @condition = condition
+ end
+
+ def consume_event(event)
+ return unless condition_met?(event)
+
+ worker.perform_async(event.class.name, event.data)
+ # TODO: Log dispatching of events to subscriber
+
+ # We rescue and track any exceptions here because we don't want to
+ # impact other subscribers if one is faulty.
+ # The method `condition_met?`, since it can run a block, it might encounter
+ # a bug. By raising an exception here we could interrupt the publishing
+ # process, preventing other subscribers from consuming the event.
+ rescue StandardError => e
+ Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e, event_class: event.class.name, event_data: event.data)
+ end
+
+ private
+
+ def condition_met?(event)
+ return true unless condition
+
+ condition.call(event)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/exceptions_app.rb b/lib/gitlab/exceptions_app.rb
new file mode 100644
index 00000000000..de07b788fb9
--- /dev/null
+++ b/lib/gitlab/exceptions_app.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require_relative 'utils/override'
+
+module Gitlab
+ class ExceptionsApp < ActionDispatch::PublicExceptions
+ extend ::Gitlab::Utils::Override
+
+ REQUEST_ID_PLACEHOLDER = '<!-- REQUEST_ID -->'
+ REQUEST_ID_PARAGRAPH = '<p>Request ID: <code>%s</code></p>'
+
+ override :call
+ def call(env)
+ status, headers, body = super
+
+ if html_rendered? && body.first&.include?(REQUEST_ID_PLACEHOLDER)
+ body = [insert_request_id(env, body.first)]
+ headers['X-GitLab-Custom-Error'] = '1'
+ end
+
+ [status, headers, body]
+ end
+
+ private
+
+ override :render_html
+ def render_html(status)
+ @html_rendered = true
+
+ super
+ end
+
+ def html_rendered?
+ !!@html_rendered
+ end
+
+ def insert_request_id(env, body)
+ request_id = ERB::Util.html_escape(ActionDispatch::Request.new(env).request_id)
+
+ body.gsub(REQUEST_ID_PLACEHOLDER, REQUEST_ID_PARAGRAPH % [request_id])
+ end
+ end
+end
diff --git a/lib/gitlab/experimentation.rb b/lib/gitlab/experimentation.rb
index 4cc653bec43..7edda290204 100644
--- a/lib/gitlab/experimentation.rb
+++ b/lib/gitlab/experimentation.rb
@@ -30,14 +30,6 @@
module Gitlab
module Experimentation
EXPERIMENTS = {
- remove_known_trial_form_fields_welcoming: {
- tracking_category: 'Growth::Conversion::Experiment::RemoveKnownTrialFormFieldsWelcoming',
- rollout_strategy: :user
- },
- remove_known_trial_form_fields_noneditable: {
- tracking_category: 'Growth::Conversion::Experiment::RemoveKnownTrialFormFieldsNoneditable',
- rollout_strategy: :user
- }
}.freeze
class << self
diff --git a/lib/gitlab/gon_helper.rb b/lib/gitlab/gon_helper.rb
index bb3ba1129fc..ac3b4de0988 100644
--- a/lib/gitlab/gon_helper.rb
+++ b/lib/gitlab/gon_helper.rb
@@ -57,6 +57,7 @@ module Gitlab
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)
end
# Exposes the state of a feature flag to the frontend code.
diff --git a/lib/gitlab/gpg/commit.rb b/lib/gitlab/gpg/commit.rb
index 59882e8d4f8..ab7de14b07a 100644
--- a/lib/gitlab/gpg/commit.rb
+++ b/lib/gitlab/gpg/commit.rb
@@ -102,7 +102,7 @@ module Gitlab
end
def verification_status(gpg_key)
- return :multiple_signatures if multiple_signatures? && Feature.enabled?(:multiple_gpg_signatures, @commit.project, default_enabled: :yaml)
+ return :multiple_signatures if multiple_signatures?
return :unknown_key unless gpg_key
return :unverified_key unless gpg_key.verified?
return :unverified unless verified_signature&.valid?
diff --git a/lib/gitlab/http.rb b/lib/gitlab/http.rb
index 1b860001ac0..d0918fc39bc 100644
--- a/lib/gitlab/http.rb
+++ b/lib/gitlab/http.rb
@@ -49,11 +49,12 @@ module Gitlab
return httparty_perform_request(http_method, path, options_with_timeouts, &block)
end
- start_time = Gitlab::Metrics::System.monotonic_time
+ start_time = nil
read_total_timeout = options.fetch(:timeout, DEFAULT_READ_TOTAL_TIMEOUT)
tracked_timeout_error = false
httparty_perform_request(http_method, path, options_with_timeouts) do |fragment|
+ start_time ||= Gitlab::Metrics::System.monotonic_time
elapsed = Gitlab::Metrics::System.monotonic_time - start_time
if elapsed > read_total_timeout
diff --git a/lib/gitlab/i18n.rb b/lib/gitlab/i18n.rb
index 12203cab8c8..f056381b86a 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' => 51,
+ 'da_DK' => 49,
'de' => 15,
'en' => 100,
'eo' => 0,
- 'es' => 39,
+ 'es' => 38,
'fil_PH' => 0,
- 'fr' => 12,
+ 'fr' => 11,
'gl_ES' => 0,
'id_ID' => 0,
'it' => 2,
- 'ja' => 35,
- 'ko' => 11,
- 'nb_NO' => 33,
+ 'ja' => 36,
+ 'ko' => 12,
+ 'nb_NO' => 32,
'nl_NL' => 0,
'pl_PL' => 5,
- 'pt_BR' => 49,
- 'ro_RO' => 23,
- 'ru' => 25,
- 'tr_TR' => 15,
+ 'pt_BR' => 50,
+ 'ro_RO' => 22,
+ 'ru' => 26,
+ 'tr_TR' => 14,
'uk' => 45,
- 'zh_CN' => 95,
+ 'zh_CN' => 98,
'zh_HK' => 2,
'zh_TW' => 3
}.freeze
diff --git a/lib/gitlab/import/set_async_jid.rb b/lib/gitlab/import/set_async_jid.rb
index 054fcdb433f..527d84477fe 100644
--- a/lib/gitlab/import/set_async_jid.rb
+++ b/lib/gitlab/import/set_async_jid.rb
@@ -13,7 +13,7 @@ module Gitlab
def self.set_jid(import_state)
jid = generate_jid(import_state)
- Gitlab::SidekiqStatus.set(jid, Gitlab::Import::StuckImportJob::IMPORT_JOBS_EXPIRATION, value: 2)
+ Gitlab::SidekiqStatus.set(jid, Gitlab::Import::StuckImportJob::IMPORT_JOBS_EXPIRATION)
import_state.update_column(:jid, jid)
end
diff --git a/lib/gitlab/import_export/base/relation_factory.rb b/lib/gitlab/import_export/base/relation_factory.rb
index 6749ef4e276..8a8c74c302d 100644
--- a/lib/gitlab/import_export/base/relation_factory.rb
+++ b/lib/gitlab/import_export/base/relation_factory.rb
@@ -196,7 +196,7 @@ module Gitlab
end
def use_attributes_permitter?
- Feature.enabled?(:permitted_attributes_for_import_export, default_enabled: :yaml)
+ true
end
def existing_or_new_object
diff --git a/lib/gitlab/import_export/group/relation_tree_restorer.rb b/lib/gitlab/import_export/group/relation_tree_restorer.rb
index cbc8ee9e18b..c2cbd2fdf47 100644
--- a/lib/gitlab/import_export/group/relation_tree_restorer.rb
+++ b/lib/gitlab/import_export/group/relation_tree_restorer.rb
@@ -118,7 +118,7 @@ module Gitlab
end
def filter_attributes(params)
- if use_attributes_permitter? && attributes_permitter.permitted_attributes_defined?(importable_class_sym)
+ if attributes_permitter.permitted_attributes_defined?(importable_class_sym)
attributes_permitter.permit(importable_class_sym, params)
else
Gitlab::ImportExport::AttributeCleaner.clean(
@@ -132,10 +132,6 @@ module Gitlab
@attributes_permitter ||= Gitlab::ImportExport::AttributesPermitter.new
end
- def use_attributes_permitter?
- Feature.enabled?(:permitted_attributes_for_import_export, default_enabled: :yaml)
- end
-
def present_override_params
# we filter out the empty strings from the overrides
# keeping the default values configured
@@ -264,14 +260,12 @@ module Gitlab
@relation_reader.sort_ci_pipelines_by_id
end
- # Enable logging of each top-level relation creation when Importing
- # into a Group if feature flag is enabled
+ # Enable logging of each top-level relation creation when Importing into a Group
def log_relation_creation(importable, relation_key, relation_object)
root_ancestor_group = importable.try(:root_ancestor)
return unless root_ancestor_group
return unless root_ancestor_group.instance_of?(::Group)
- return unless Feature.enabled?(:log_import_export_relation_creation, root_ancestor_group)
@shared.logger.info(
importable_type: importable.class.to_s,
diff --git a/lib/gitlab/import_export/project/import_export.yml b/lib/gitlab/import_export/project/import_export.yml
index ef146359da9..059f6bd42e3 100644
--- a/lib/gitlab/import_export/project/import_export.yml
+++ b/lib/gitlab/import_export/project/import_export.yml
@@ -120,6 +120,7 @@ included_attributes:
- :name
ci_cd_settings:
- :group_runners_enabled
+ - :runner_token_expiration_interval
metrics_setting:
- :dashboard_timezone
- :external_dashboard_url
@@ -904,6 +905,7 @@ excluded_attributes:
- :release_id
project_members:
- :source_id
+ - :member_namespace_id
- :invite_email_success
- :state
group_members:
diff --git a/lib/gitlab/jwt_authenticatable.rb b/lib/gitlab/jwt_authenticatable.rb
index 1270a148e8d..08d9f69497e 100644
--- a/lib/gitlab/jwt_authenticatable.rb
+++ b/lib/gitlab/jwt_authenticatable.rb
@@ -13,26 +13,38 @@ module Gitlab
module ClassMethods
include Gitlab::Utils::StrongMemoize
- def decode_jwt_for_issuer(issuer, encoded_message)
- JWT.decode(
- encoded_message,
- secret,
- true,
- { iss: issuer, verify_iss: true, algorithm: 'HS256' }
- )
+ def decode_jwt(encoded_message, jwt_secret = secret, issuer: nil, iat_after: nil)
+ options = { algorithm: 'HS256' }
+ options = options.merge(iss: issuer, verify_iss: true) if issuer.present?
+ options = options.merge(verify_iat: true) if iat_after.present?
+
+ decoded_message = JWT.decode(encoded_message, jwt_secret, true, options)
+ payload = decoded_message[0]
+ if iat_after.present?
+ raise JWT::DecodeError, "JWT iat claim is missing" if payload['iat'].blank?
+
+ iat = payload['iat'].to_i
+ raise JWT::ExpiredSignature, 'Token has expired' if iat < iat_after.to_i
+ end
+
+ decoded_message
end
def secret
strong_memoize(:secret) do
- Base64.strict_decode64(File.read(secret_path).chomp).tap do |bytes|
- raise "#{secret_path} does not contain #{SECRET_LENGTH} bytes" if bytes.length != SECRET_LENGTH
- end
+ read_secret(secret_path)
+ end
+ end
+
+ def read_secret(path)
+ Base64.strict_decode64(File.read(path).chomp).tap do |bytes|
+ raise "#{path} does not contain #{SECRET_LENGTH} bytes" if bytes.length != SECRET_LENGTH
end
end
- def write_secret
+ def write_secret(path = secret_path)
bytes = SecureRandom.random_bytes(SECRET_LENGTH)
- File.open(secret_path, 'w:BINARY', 0600) do |f|
+ File.open(path, 'w:BINARY', 0600) do |f|
f.chmod(0600) # If the file already existed, the '0600' passed to 'open' above was a no-op.
f.write(Base64.strict_encode64(bytes))
end
diff --git a/lib/gitlab/kas.rb b/lib/gitlab/kas.rb
index 408b3afc128..ed7787ffc49 100644
--- a/lib/gitlab/kas.rb
+++ b/lib/gitlab/kas.rb
@@ -11,7 +11,7 @@ module Gitlab
class << self
def verify_api_request(request_headers)
- decode_jwt_for_issuer(JWT_ISSUER, request_headers[INTERNAL_API_REQUEST_HEADER])
+ decode_jwt(request_headers[INTERNAL_API_REQUEST_HEADER], issuer: JWT_ISSUER)
rescue JWT::DecodeError
nil
end
diff --git a/lib/gitlab/lfs/client.rb b/lib/gitlab/lfs/client.rb
index a05e8107cad..10df9262cca 100644
--- a/lib/gitlab/lfs/client.rb
+++ b/lib/gitlab/lfs/client.rb
@@ -36,7 +36,7 @@ module Gitlab
headers: build_request_headers
)
- raise BatchSubmitError unless rsp.success?
+ raise BatchSubmitError.new(http_response: rsp) unless rsp.success?
# HTTParty provides rsp.parsed_response, but it only kicks in for the
# application/json content type in the response, which we can't rely on
@@ -53,19 +53,13 @@ module Gitlab
params = {
body_stream: file,
- headers: {
- 'Content-Length' => object.size.to_s,
- 'Content-Type' => 'application/octet-stream',
- 'User-Agent' => GIT_LFS_USER_AGENT
- }.merge(upload_action['header'] || {})
+ headers: upload_headers(object, upload_action)
}
- authenticated = true if params[:headers].key?('Authorization')
- params[:basic_auth] = basic_auth unless authenticated
-
- rsp = Gitlab::HTTP.put(upload_action['href'], params)
+ url = set_basic_auth_and_extract_lfs_url!(params, upload_action['href'])
+ rsp = Gitlab::HTTP.put(url, params)
- raise ObjectUploadError unless rsp.success?
+ raise ObjectUploadError.new(http_response: rsp) unless rsp.success?
ensure
file&.close
end
@@ -76,20 +70,51 @@ module Gitlab
headers: build_request_headers(verify_action['header'])
}
- authenticated = true if params[:headers].key?('Authorization')
- params[:basic_auth] = basic_auth unless authenticated
-
- rsp = Gitlab::HTTP.post(verify_action['href'], params)
+ url = set_basic_auth_and_extract_lfs_url!(params, verify_action['href'])
+ rsp = Gitlab::HTTP.post(url, params)
- raise ObjectVerifyError unless rsp.success?
+ raise ObjectVerifyError.new(http_response: rsp) unless rsp.success?
end
private
+ def set_basic_auth_and_extract_lfs_url!(params, raw_url)
+ authenticated = true if params[:headers].key?('Authorization')
+ params[:basic_auth] = basic_auth unless authenticated
+ strip_userinfo = authenticated || params[:basic_auth].present?
+ lfs_url(raw_url, strip_userinfo)
+ end
+
def build_request_headers(extra_headers = nil)
DEFAULT_HEADERS.merge(extra_headers || {})
end
+ def upload_headers(object, upload_action)
+ # This uses the httprb library to handle case-insensitive HTTP headers
+ headers = ::HTTP::Headers.new
+ headers.merge!(upload_action['header'])
+ transfer_encodings = Array(headers['Transfer-Encoding']&.split(',')).map(&:strip)
+
+ headers['Content-Length'] = object.size.to_s unless transfer_encodings.include?('chunked')
+ headers['Content-Type'] = 'application/octet-stream'
+ headers['User-Agent'] = GIT_LFS_USER_AGENT
+
+ headers.to_h
+ end
+
+ def lfs_url(raw_url, strip_userinfo)
+ # HTTParty will give precedence to the username/password
+ # specified in the URL. This causes problems with Azure DevOps,
+ # which includes a username in the URL. Stripping the userinfo
+ # from the URL allows the provided HTTP Basic Authentication
+ # credentials to be used.
+ if strip_userinfo
+ Gitlab::UrlSanitizer.new(raw_url).sanitized_url
+ else
+ raw_url
+ end
+ end
+
attr_reader :credentials
def batch_url
@@ -105,9 +130,21 @@ module Gitlab
{ username: credentials[:user], password: credentials[:password] }
end
- class BatchSubmitError < StandardError
+ class HttpError < StandardError
+ def initialize(http_response:)
+ super
+
+ @http_response = http_response
+ end
+
+ def http_error
+ "HTTP status #{@http_response.code}"
+ end
+ end
+
+ class BatchSubmitError < HttpError
def message
- "Failed to submit batch"
+ "Failed to submit batch: #{http_error}"
end
end
@@ -122,15 +159,15 @@ module Gitlab
end
end
- class ObjectUploadError < StandardError
+ class ObjectUploadError < HttpError
def message
- "Failed to upload object"
+ "Failed to upload object: #{http_error}"
end
end
- class ObjectVerifyError < StandardError
+ class ObjectVerifyError < HttpError
def message
- "Failed to verify object"
+ "Failed to verify object: #{http_error}"
end
end
end
diff --git a/lib/gitlab/logger.rb b/lib/gitlab/logger.rb
index 89a4e36a232..53ad0d9cb4d 100644
--- a/lib/gitlab/logger.rb
+++ b/lib/gitlab/logger.rb
@@ -33,7 +33,11 @@ module Gitlab
def self.build
Gitlab::SafeRequestStore[self.cache_key] ||=
- new(self.full_log_path, level: ::Logger::DEBUG)
+ new(self.full_log_path, level: log_level)
+ end
+
+ def self.log_level(fallback: ::Logger::DEBUG)
+ ENV.fetch('GITLAB_LOG_LEVEL', fallback)
end
def self.full_log_path
diff --git a/lib/gitlab/mail_room.rb b/lib/gitlab/mail_room.rb
index 75d27ed8cc1..e93a297cee4 100644
--- a/lib/gitlab/mail_room.rb
+++ b/lib/gitlab/mail_room.rb
@@ -25,7 +25,7 @@ module Gitlab
# Email specific configuration which is merged with configuration
# fetched from YML config file.
- ADDRESS_SPECIFIC_CONFIG = {
+ MAILBOX_SPECIFIC_CONFIGS = {
incoming_email: {
queue: 'email_receiver',
worker: 'EmailReceiverWorker'
@@ -38,7 +38,15 @@ module Gitlab
class << self
def enabled_configs
- @enabled_configs ||= configs.select { |config| enabled?(config) }
+ @enabled_configs ||= configs.select { |_key, config| enabled?(config) }
+ end
+
+ def enabled_mailbox_types
+ enabled_configs.keys.map(&:to_s)
+ end
+
+ def worker_for(mailbox_type)
+ MAILBOX_SPECIFIC_CONFIGS.try(:[], mailbox_type.to_sym).try(:[], :worker).try(:safe_constantize)
end
private
@@ -48,7 +56,7 @@ module Gitlab
end
def configs
- ADDRESS_SPECIFIC_CONFIG.keys.map { |key| fetch_config(key) }
+ MAILBOX_SPECIFIC_CONFIGS.to_h { |key, _value| [key, fetch_config(key)] }
end
def fetch_config(config_key)
@@ -63,7 +71,7 @@ module Gitlab
def merged_configs(config_key)
yml_config = load_yaml.fetch(config_key, {})
- specific_config = ADDRESS_SPECIFIC_CONFIG.fetch(config_key, {})
+ specific_config = MAILBOX_SPECIFIC_CONFIGS.fetch(config_key, {})
DEFAULT_CONFIG.merge(specific_config, yml_config) do |_key, oldval, newval|
newval.nil? ? oldval : newval
end
diff --git a/lib/gitlab/mail_room/authenticator.rb b/lib/gitlab/mail_room/authenticator.rb
new file mode 100644
index 00000000000..26ebdca8beb
--- /dev/null
+++ b/lib/gitlab/mail_room/authenticator.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module MailRoom
+ class Authenticator
+ 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
+
+ class << self
+ def verify_api_request(request_headers, mailbox_type)
+ mailbox_type = mailbox_type.to_sym
+ return false if enabled_configs[mailbox_type].blank?
+
+ decode_jwt(
+ request_headers[INTERNAL_API_REQUEST_HEADER],
+ secret(mailbox_type),
+ issuer: 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?
+
+ false
+ end
+
+ def secret(mailbox_type)
+ strong_memoize("jwt_secret_#{mailbox_type}".to_sym) do
+ secret_path = enabled_configs[mailbox_type][:secret_file]
+ raise SecretConfigurationError, "#{mailbox_type}'s secret_file configuration is missing" if secret_path.blank?
+
+ begin
+ read_secret(secret_path)
+ rescue StandardError => e
+ raise SecretConfigurationError, "Fail to read #{mailbox_type}'s secret: #{e.message}"
+ end
+ end
+ end
+
+ def enabled_configs
+ Gitlab::MailRoom.enabled_configs
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/merge_requests/commit_message_generator.rb b/lib/gitlab/merge_requests/commit_message_generator.rb
index 0e9ec6f5cb3..0515c17fe5d 100644
--- a/lib/gitlab/merge_requests/commit_message_generator.rb
+++ b/lib/gitlab/merge_requests/commit_message_generator.rb
@@ -2,8 +2,9 @@
module Gitlab
module MergeRequests
class CommitMessageGenerator
- def initialize(merge_request:)
+ def initialize(merge_request:, current_user:)
@merge_request = merge_request
+ @current_user = @merge_request.metrics&.merged_by || @merge_request.merge_user || current_user
end
def merge_message
@@ -15,57 +16,66 @@ module Gitlab
def squash_message
return unless @merge_request.target_project.squash_commit_template.present?
- replace_placeholders(@merge_request.target_project.squash_commit_template)
+ replace_placeholders(@merge_request.target_project.squash_commit_template, squash: true)
end
private
attr_reader :merge_request
+ attr_reader :current_user
PLACEHOLDERS = {
- 'source_branch' => ->(merge_request) { merge_request.source_branch.to_s },
- 'target_branch' => ->(merge_request) { merge_request.target_branch.to_s },
- 'title' => ->(merge_request) { merge_request.title },
- 'issues' => ->(merge_request) do
- return "" if merge_request.visible_closing_issues_for.blank?
+ 'source_branch' => ->(merge_request, _, _) { merge_request.source_branch.to_s },
+ 'target_branch' => ->(merge_request, _, _) { merge_request.target_branch.to_s },
+ 'title' => ->(merge_request, _, _) { merge_request.title },
+ 'issues' => ->(merge_request, _, _) do
+ return if merge_request.visible_closing_issues_for.blank?
closes_issues_references = merge_request.visible_closing_issues_for.map do |issue|
issue.to_reference(merge_request.target_project)
end
"Closes #{closes_issues_references.to_sentence}"
end,
- 'description' => ->(merge_request) { merge_request.description.presence || '' },
- 'reference' => ->(merge_request) { merge_request.to_reference(full: true) },
- 'first_commit' => -> (merge_request) { merge_request.first_commit&.safe_message&.strip.presence || '' },
- 'first_multiline_commit' => -> (merge_request) { merge_request.first_multiline_commit&.safe_message&.strip.presence || merge_request.title }
+ 'description' => ->(merge_request, _, _) { merge_request.description },
+ 'reference' => ->(merge_request, _, _) { merge_request.to_reference(full: true) },
+ 'first_commit' => -> (merge_request, _, _) { merge_request.first_commit&.safe_message&.strip },
+ 'first_multiline_commit' => -> (merge_request, _, _) { merge_request.first_multiline_commit&.safe_message&.strip.presence || merge_request.title },
+ 'url' => ->(merge_request, _, _) { Gitlab::UrlBuilder.build(merge_request) },
+ 'approved_by' => ->(merge_request, _, _) { merge_request.approved_by_users.map { |user| "Approved-by: #{user.name} <#{user.commit_email_or_default}>" }.join("\n") },
+ 'merged_by' => ->(_, user, _) { "#{user&.name} <#{user&.commit_email_or_default}>" },
+ 'co_authored_by' => ->(merge_request, merged_by, squash) do
+ commit_author = squash ? merge_request.author : merged_by
+ merge_request.recent_commits
+ .to_h { |commit| [commit.author_email, commit.author_name] }
+ .except(commit_author&.commit_email_or_default)
+ .map { |author_email, author_name| "Co-authored-by: #{author_name} <#{author_email}>" }
+ .join("\n")
+ end
}.freeze
- PLACEHOLDERS_REGEX = Regexp.union(PLACEHOLDERS.keys.map do |key|
- Regexp.new(Regexp.escape(key))
- end).freeze
-
- BLANK_PLACEHOLDERS_REGEXES = (PLACEHOLDERS.map do |key, value|
- [key, Regexp.new("[\n\r]+%{#{Regexp.escape(key)}}$")]
- end).to_h.freeze
+ PLACEHOLDERS_COMBINED_REGEX = /%{(#{Regexp.union(PLACEHOLDERS.keys)})}/.freeze
- def replace_placeholders(message)
- # convert CRLF to LF
+ def replace_placeholders(message, squash: false)
+ # Convert CRLF to LF.
message = message.delete("\r")
- # Remove placeholders that correspond to empty values and are the last word in the line
- # along with all whitespace characters preceding them.
- # This allows us to recreate previous default merge commit message behaviour - we skipped new line character
- # before empty description and before closed issues when none were present.
- PLACEHOLDERS.each do |key, value|
- unless value.call(merge_request).present?
- message = message.gsub(BLANK_PLACEHOLDERS_REGEXES[key], '')
- end
+ used_variables = message.scan(PLACEHOLDERS_COMBINED_REGEX).map { |value| value[0] }.uniq
+ values = used_variables.to_h do |variable_name|
+ ["%{#{variable_name}}", PLACEHOLDERS[variable_name].call(merge_request, current_user, squash)]
end
+ names_of_empty_variables = values.filter_map { |name, value| name if value.blank? }
- Gitlab::StringPlaceholderReplacer
- .replace_string_placeholders(message, PLACEHOLDERS_REGEX) do |key|
- PLACEHOLDERS[key].call(merge_request)
+ # Remove lines that contain empty variable placeholder and nothing else.
+ if names_of_empty_variables.present?
+ # If there is blank line or EOF after it, remove blank line before it as well.
+ message = message.gsub(/\n\n#{Regexp.union(names_of_empty_variables)}(\n\n|\Z)/, '\1')
+ # Otherwise, remove only the line it is in.
+ message = message.gsub(/^#{Regexp.union(names_of_empty_variables)}\n/, '')
end
+ # Substitute all variables with their values.
+ message = message.gsub(Regexp.union(values.keys), values) if values.present?
+
+ message
end
end
end
diff --git a/lib/gitlab/metrics/exporter/base_exporter.rb b/lib/gitlab/metrics/exporter/base_exporter.rb
index 47c862c0232..190d3d3fd2f 100644
--- a/lib/gitlab/metrics/exporter/base_exporter.rb
+++ b/lib/gitlab/metrics/exporter/base_exporter.rb
@@ -11,44 +11,41 @@ module Gitlab
attr_accessor :readiness_checks
- def initialize(settings, **options)
+ def initialize(settings, log_enabled:, log_file:, gc_requests: false, **options)
super(**options)
@settings = settings
+ @gc_requests = gc_requests
+
+ # log_enabled does not exist for all exporters
+ log_sink = log_enabled ? File.join(Rails.root, 'log', log_file) : File::NULL
+ @logger = WEBrick::Log.new(log_sink)
+ @logger.time_format = "[%Y-%m-%dT%H:%M:%S.%L%z]"
end
def enabled?
settings.enabled
end
- def log_filename
- raise NotImplementedError
- end
-
private
- attr_reader :settings
+ attr_reader :settings, :logger
def start_working
- logger = WEBrick::Log.new(log_filename)
- logger.time_format = "[%Y-%m-%dT%H:%M:%S.%L%z]"
-
access_log = [
[logger, WEBrick::AccessLog::COMBINED_LOG_FORMAT]
]
@server = ::WEBrick::HTTPServer.new(
Port: settings.port, BindAddress: settings.address,
- Logger: logger, AccessLog: access_log)
- server.mount_proc '/readiness' do |req, res|
- render_probe(readiness_probe, req, res)
- end
- server.mount_proc '/liveness' do |req, res|
- render_probe(liveness_probe, req, res)
- end
+ Logger: logger, AccessLog: access_log
+ )
server.mount '/', Rack::Handler::WEBrick, rack_app
true
+ rescue StandardError => e
+ logger.error(e)
+ false
end
def run_thread
@@ -72,8 +69,16 @@ module Gitlab
end
def rack_app
+ readiness = readiness_probe
+ liveness = liveness_probe
+ pid = thread_name
+ gc_requests = @gc_requests
+
Rack::Builder.app do
use Rack::Deflater
+ use Gitlab::Metrics::Exporter::MetricsMiddleware, pid
+ use Gitlab::Metrics::Exporter::HealthChecksMiddleware, readiness, liveness
+ use Gitlab::Metrics::Exporter::GcRequestMiddleware if gc_requests
use ::Prometheus::Client::Rack::Exporter if ::Gitlab::Metrics.metrics_folder_present?
run -> (env) { [404, {}, ['']] }
end
@@ -86,14 +91,6 @@ module Gitlab
def liveness_probe
::Gitlab::HealthChecks::Probes::Collection.new
end
-
- def render_probe(probe, req, res)
- result = probe.execute
-
- res.status = result.http_status
- res.content_type = 'application/json; charset=utf-8'
- res.body = result.json.to_json
- end
end
end
end
diff --git a/lib/gitlab/metrics/exporter/gc_request_middleware.rb b/lib/gitlab/metrics/exporter/gc_request_middleware.rb
new file mode 100644
index 00000000000..3806b0e2bd1
--- /dev/null
+++ b/lib/gitlab/metrics/exporter/gc_request_middleware.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Metrics
+ module Exporter
+ class GcRequestMiddleware
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ @app.call(env).tap do
+ GC.start
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/metrics/exporter/health_checks_middleware.rb b/lib/gitlab/metrics/exporter/health_checks_middleware.rb
new file mode 100644
index 00000000000..c43b8004b72
--- /dev/null
+++ b/lib/gitlab/metrics/exporter/health_checks_middleware.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Metrics
+ module Exporter
+ class HealthChecksMiddleware
+ def initialize(app, readiness_probe, liveness_probe)
+ @app = app
+ @readiness_probe = readiness_probe
+ @liveness_probe = liveness_probe
+ end
+
+ def call(env)
+ case env['PATH_INFO']
+ when '/readiness' then render_probe(@readiness_probe)
+ when '/liveness' then render_probe(@liveness_probe)
+ else @app.call(env)
+ end
+ end
+
+ private
+
+ def render_probe(probe)
+ result = probe.execute
+
+ [
+ result.http_status,
+ { 'Content-Type' => 'application/json; charset=utf-8' },
+ [result.json.to_json]
+ ]
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/metrics/exporter/metrics_middleware.rb b/lib/gitlab/metrics/exporter/metrics_middleware.rb
new file mode 100644
index 00000000000..e17f1c13cf0
--- /dev/null
+++ b/lib/gitlab/metrics/exporter/metrics_middleware.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Metrics
+ module Exporter
+ class MetricsMiddleware
+ def initialize(app, pid)
+ @app = app
+ default_labels = {
+ pid: pid
+ }
+ @requests_total = Gitlab::Metrics.counter(
+ :exporter_http_requests_total, 'Total number of HTTP requests', default_labels
+ )
+ @request_durations = Gitlab::Metrics.histogram(
+ :exporter_http_request_duration_seconds,
+ 'HTTP request duration histogram (seconds)',
+ default_labels,
+ [0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10]
+ )
+ end
+
+ def call(env)
+ start = Gitlab::Metrics::System.monotonic_time
+ @app.call(env).tap do |response|
+ duration = Gitlab::Metrics::System.monotonic_time - start
+
+ labels = {
+ method: env['REQUEST_METHOD'].downcase,
+ path: env['PATH_INFO'].to_s,
+ code: response.first.to_s
+ }
+
+ @requests_total.increment(labels)
+ @request_durations.observe(labels, duration)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/metrics/exporter/sidekiq_exporter.rb b/lib/gitlab/metrics/exporter/sidekiq_exporter.rb
index eea71fda6a0..afecf6546f8 100644
--- a/lib/gitlab/metrics/exporter/sidekiq_exporter.rb
+++ b/lib/gitlab/metrics/exporter/sidekiq_exporter.rb
@@ -4,12 +4,11 @@ module Gitlab
module Metrics
module Exporter
class SidekiqExporter < BaseExporter
- def log_filename
- if settings['log_enabled']
- File.join(Rails.root, 'log', 'sidekiq_exporter.log')
- else
- File::NULL
- end
+ def initialize(settings, **options)
+ super(settings,
+ log_enabled: settings['log_enabled'],
+ log_file: 'sidekiq_exporter.log',
+ **options)
end
end
end
diff --git a/lib/gitlab/metrics/exporter/web_exporter.rb b/lib/gitlab/metrics/exporter/web_exporter.rb
index d41484aaaa7..c05ad8ccf42 100644
--- a/lib/gitlab/metrics/exporter/web_exporter.rb
+++ b/lib/gitlab/metrics/exporter/web_exporter.rb
@@ -26,8 +26,8 @@ module Gitlab
attr_reader :running
# This exporter is always run on master process
- def initialize
- super(Settings.monitoring.web_exporter)
+ def initialize(**options)
+ super(Settings.monitoring.web_exporter, log_enabled: true, log_file: 'web_exporter.log', **options)
# DEPRECATED:
# these `readiness_checks` are deprecated
@@ -39,10 +39,6 @@ module Gitlab
]
end
- def log_filename
- File.join(Rails.root, 'log', 'web_exporter.log')
- end
-
def mark_as_not_running!
@running = false
end
diff --git a/lib/gitlab/metrics/samplers/action_cable_sampler.rb b/lib/gitlab/metrics/samplers/action_cable_sampler.rb
index adce3030d0d..1f50371cae9 100644
--- a/lib/gitlab/metrics/samplers/action_cable_sampler.rb
+++ b/lib/gitlab/metrics/samplers/action_cable_sampler.rb
@@ -6,8 +6,8 @@ module Gitlab
class ActionCableSampler < BaseSampler
DEFAULT_SAMPLING_INTERVAL_SECONDS = 5
- def initialize(interval = nil, action_cable: ::ActionCable.server)
- super(interval)
+ def initialize(action_cable: ::ActionCable.server, **options)
+ super(**options)
@action_cable = action_cable
end
diff --git a/lib/gitlab/metrics/samplers/base_sampler.rb b/lib/gitlab/metrics/samplers/base_sampler.rb
index 52d80c3c27e..b2a9de21145 100644
--- a/lib/gitlab/metrics/samplers/base_sampler.rb
+++ b/lib/gitlab/metrics/samplers/base_sampler.rb
@@ -9,7 +9,10 @@ module Gitlab
attr_reader :interval
# interval - The sampling interval in seconds.
- def initialize(interval = nil)
+ # warmup - When true, takes a single sample eagerly before entering the sampling loop.
+ # This can be useful to ensure that all metrics files exist after `start` returns,
+ # since prometheus-client-mmap creates them lazily upon first access.
+ def initialize(interval: nil, logger: Logger.new($stdout), warmup: false, **options)
interval ||= ENV[interval_env_key]&.to_i
interval ||= self.class::DEFAULT_SAMPLING_INTERVAL_SECONDS
interval_half = interval.to_f / 2
@@ -17,13 +20,16 @@ module Gitlab
@interval = interval
@interval_steps = (-interval_half..interval_half).step(0.1).to_a
- super()
+ @logger = logger
+ @warmup = warmup
+
+ super(**options)
end
def safe_sample
sample
rescue StandardError => e
- ::Gitlab::AppLogger.warn("#{self.class}: #{e}, stopping")
+ @logger.warn("#{self.class}: #{e}, stopping")
stop
end
@@ -63,6 +69,8 @@ module Gitlab
def start_working
@running = true
+ safe_sample if @warmup
+
true
end
diff --git a/lib/gitlab/metrics/samplers/ruby_sampler.rb b/lib/gitlab/metrics/samplers/ruby_sampler.rb
index b1c5e9800da..d71ee671b8d 100644
--- a/lib/gitlab/metrics/samplers/ruby_sampler.rb
+++ b/lib/gitlab/metrics/samplers/ruby_sampler.rb
@@ -7,12 +7,12 @@ module Gitlab
DEFAULT_SAMPLING_INTERVAL_SECONDS = 60
GC_REPORT_BUCKETS = [0.01, 0.05, 0.1, 0.2, 0.3, 0.5, 1].freeze
- def initialize(*)
+ def initialize(...)
GC::Profiler.clear
metrics[:process_start_time_seconds].set(labels, Time.now.to_i)
- super
+ super(...)
end
def metrics
diff --git a/lib/gitlab/middleware/multipart.rb b/lib/gitlab/middleware/multipart.rb
index a047015e54f..0b7b5e23b75 100644
--- a/lib/gitlab/middleware/multipart.rb
+++ b/lib/gitlab/middleware/multipart.rb
@@ -116,7 +116,7 @@ module Gitlab
jwt_token = params[param_key]
raise "Empty JWT param: #{param_key}" if jwt_token.blank?
- payload = Gitlab::Workhorse.decode_jwt(jwt_token).first
+ payload = Gitlab::Workhorse.decode_jwt_with_issuer(jwt_token).first
raise "Invalid JWT payload: not a Hash" unless payload.is_a?(Hash)
upload_params = payload.fetch(JWT_PARAM_FIXED_KEY, {})
@@ -172,7 +172,7 @@ module Gitlab
encoded_message = env.delete(RACK_ENV_KEY)
return @app.call(env) if encoded_message.blank?
- message = ::Gitlab::Workhorse.decode_jwt(encoded_message)[0]
+ message = ::Gitlab::Workhorse.decode_jwt_with_issuer(encoded_message)[0]
::Gitlab::Middleware::Multipart::Handler.new(env, message).with_open_files do
@app.call(env)
diff --git a/lib/gitlab/middleware/webhook_recursion_detection.rb b/lib/gitlab/middleware/webhook_recursion_detection.rb
new file mode 100644
index 00000000000..2677445852c
--- /dev/null
+++ b/lib/gitlab/middleware/webhook_recursion_detection.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Middleware
+ class WebhookRecursionDetection
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ headers = ActionDispatch::Request.new(env).headers
+
+ ::Gitlab::WebHooks::RecursionDetection.set_from_headers(headers)
+
+ @app.call(env)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/pages.rb b/lib/gitlab/pages.rb
index 98e87e9e915..4e0e5102bec 100644
--- a/lib/gitlab/pages.rb
+++ b/lib/gitlab/pages.rb
@@ -10,7 +10,7 @@ module Gitlab
class << self
def verify_api_request(request_headers)
- decode_jwt_for_issuer('gitlab-pages', request_headers[INTERNAL_API_REQUEST_HEADER])
+ decode_jwt(request_headers[INTERNAL_API_REQUEST_HEADER], issuer: 'gitlab-pages')
rescue JWT::DecodeError
false
end
diff --git a/lib/gitlab/pagination/keyset/column_order_definition.rb b/lib/gitlab/pagination/keyset/column_order_definition.rb
index 2b968c4253f..302e7b406b1 100644
--- a/lib/gitlab/pagination/keyset/column_order_definition.rb
+++ b/lib/gitlab/pagination/keyset/column_order_definition.rb
@@ -114,6 +114,20 @@ module Gitlab
# - When the order is a calculated expression or the column is in another table (JOIN-ed)
#
# If the add_to_projections is true, the query builder will automatically add the column to the SELECT values
+ #
+ # **sql_type**
+ #
+ # The SQL type of the column or SQL expression. This is an optional field which is only required when using the
+ # column with the InOperatorOptimization class.
+ #
+ # Example: When the order expression is a calculated SQL expression.
+ #
+ # {
+ # attribute_name: 'id_times_count',
+ # order_expression: Arel.sql('(id * count)').asc,
+ # sql_type: 'integer' # the SQL type here must match with the type of the produced data by the order_expression. Putting 'text' here would be incorrect.
+ # }
+ #
class ColumnOrderDefinition
REVERSED_ORDER_DIRECTIONS = { asc: :desc, desc: :asc }.freeze
REVERSED_NULL_POSITIONS = { nulls_first: :nulls_last, nulls_last: :nulls_first }.freeze
@@ -122,7 +136,8 @@ module Gitlab
attr_reader :attribute_name, :column_expression, :order_expression, :add_to_projections, :order_direction
- def initialize(attribute_name:, order_expression:, column_expression: nil, reversed_order_expression: nil, nullable: :not_nullable, distinct: true, order_direction: nil, add_to_projections: false)
+ # rubocop: disable Metrics/ParameterLists
+ def initialize(attribute_name:, order_expression:, column_expression: nil, reversed_order_expression: nil, nullable: :not_nullable, distinct: true, order_direction: nil, sql_type: nil, add_to_projections: false)
@attribute_name = attribute_name
@order_expression = order_expression
@column_expression = column_expression || calculate_column_expression(order_expression)
@@ -130,8 +145,10 @@ module Gitlab
@reversed_order_expression = reversed_order_expression || calculate_reversed_order(order_expression)
@nullable = parse_nullable(nullable, distinct)
@order_direction = parse_order_direction(order_expression, order_direction)
+ @sql_type = sql_type
@add_to_projections = add_to_projections
end
+ # rubocop: enable Metrics/ParameterLists
def reverse
self.class.new(
@@ -185,6 +202,12 @@ module Gitlab
sql_string
end
+ def sql_type
+ raise Gitlab::Pagination::Keyset::SqlTypeMissingError.for_column(self) if @sql_type.nil?
+
+ @sql_type
+ end
+
private
attr_reader :reversed_order_expression, :nullable, :distinct
diff --git a/lib/gitlab/pagination/keyset/in_operator_optimization/column_data.rb b/lib/gitlab/pagination/keyset/in_operator_optimization/column_data.rb
index 3f620f74eca..93b28661bb0 100644
--- a/lib/gitlab/pagination/keyset/in_operator_optimization/column_data.rb
+++ b/lib/gitlab/pagination/keyset/in_operator_optimization/column_data.rb
@@ -4,23 +4,35 @@ module Gitlab
module Pagination
module Keyset
module InOperatorOptimization
+ # This class is used for wrapping an Arel column with
+ # convenient helper methods in order to make the query
+ # building for the InOperatorOptimization a bit cleaner.
class ColumnData
attr_reader :original_column_name, :as, :arel_table
- def initialize(original_column_name, as, arel_table)
- @original_column_name = original_column_name.to_s
+ # column - name of the DB column
+ # as - custom alias for the column
+ # arel_table - relation where the column is located
+ def initialize(column, as, arel_table)
+ @original_column_name = column
@as = as.to_s
@arel_table = arel_table
end
+ # Generates: `issues.name AS my_alias`
def projection
arel_column.as(as)
end
+ # Generates: issues.name`
def arel_column
arel_table[original_column_name]
end
+ # overridden in OrderByColumnData class
+ alias_method :column_expression, :arel_column
+
+ # Generates: `issues.my_alias`
def arel_column_as
arel_table[as]
end
@@ -29,8 +41,9 @@ module Gitlab
"#{arel_table.name}_#{original_column_name}_array"
end
+ # Generates: SELECT ARRAY_AGG(...) AS issues_name_array
def array_aggregated_column
- Arel::Nodes::NamedFunction.new('ARRAY_AGG', [arel_column]).as(array_aggregated_column_name)
+ Arel::Nodes::NamedFunction.new('ARRAY_AGG', [column_expression]).as(array_aggregated_column_name)
end
end
end
diff --git a/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_column_data.rb b/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_column_data.rb
new file mode 100644
index 00000000000..9cb1ba1542d
--- /dev/null
+++ b/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_column_data.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Pagination
+ module Keyset
+ module InOperatorOptimization
+ class OrderByColumnData < ColumnData
+ extend ::Gitlab::Utils::Override
+
+ attr_reader :column
+
+ # column - a ColumnOrderDefinition object
+ # as - custom alias for the column
+ # arel_table - relation where the column is located
+ def initialize(column, as, arel_table)
+ super(column.attribute_name.to_s, as, arel_table)
+ @column = column
+ end
+
+ override :arel_column
+ def arel_column
+ column.column_expression
+ end
+
+ override :column_expression
+ def column_expression
+ arel_table[original_column_name]
+ end
+
+ def column_for_projection
+ column.column_expression.as(original_column_name)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_columns.rb b/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_columns.rb
index d8c69a74e6b..d6513114d08 100644
--- a/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_columns.rb
+++ b/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_columns.rb
@@ -9,16 +9,16 @@ module Gitlab
# This class exposes collection methods for the order by columns
#
- # Example: by modelling the `issues.created_at ASC, issues.id ASC` ORDER BY
+ # Example: by modeling the `issues.created_at ASC, issues.id ASC` ORDER BY
# SQL clause, this class will receive two ColumnOrderDefinition objects
def initialize(columns, arel_table)
@columns = columns.map do |column|
- ColumnData.new(column.attribute_name, "order_by_columns_#{column.attribute_name}", arel_table)
+ OrderByColumnData.new(column, "order_by_columns_#{column.attribute_name}", arel_table)
end
end
def arel_columns
- columns.map(&:arel_column)
+ columns.map(&:column_for_projection)
end
def array_aggregated_columns
diff --git a/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb b/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb
index 53faf8469f2..065a3a0cf20 100644
--- a/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb
+++ b/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb
@@ -120,7 +120,7 @@ module Gitlab
.from(array_cte)
.join(Arel.sql("LEFT JOIN LATERAL (#{initial_keyset_query.to_sql}) #{table_name} ON TRUE"))
- order_by_columns.each { |column| q.where(column.arel_column.not_eq(nil)) }
+ order_by_columns.each { |column| q.where(column.column_expression.not_eq(nil)) }
q.as('array_scope_lateral_query')
end
@@ -231,7 +231,7 @@ module Gitlab
order
.apply_cursor_conditions(keyset_scope, cursor_values, use_union_optimization: true)
- .reselect(*order_by_columns.arel_columns)
+ .reselect(*order_by_columns.map(&:column_for_projection))
.limit(1)
end
diff --git a/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/order_values_loader_strategy.rb b/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/order_values_loader_strategy.rb
index fc2b56048f6..932aa0c2d28 100644
--- a/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/order_values_loader_strategy.rb
+++ b/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/order_values_loader_strategy.rb
@@ -12,11 +12,7 @@ module Gitlab
end
def initializer_columns
- order_by_columns.map do |column|
- column_name = column.original_column_name.to_s
- type = model.columns_hash[column_name].sql_type
- "NULL::#{type} AS #{column_name}"
- end
+ order_by_columns.map { |column_data| null_with_type_cast(column_data) }
end
def columns
@@ -30,6 +26,15 @@ module Gitlab
private
attr_reader :model, :order_by_columns
+
+ def null_with_type_cast(column_data)
+ column_name = column_data.original_column_name.to_s
+ active_record_column = model.columns_hash[column_name]
+
+ type = active_record_column ? active_record_column.sql_type : column_data.column.sql_type
+
+ "NULL::#{type} AS #{column_name}"
+ end
end
end
end
diff --git a/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy.rb b/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy.rb
index b12c33d6e51..51f38c1da58 100644
--- a/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy.rb
+++ b/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy.rb
@@ -9,6 +9,8 @@ module Gitlab
RECORDS_COLUMN = 'records'
def initialize(finder_query, model, order_by_columns)
+ verify_order_by_attributes_on_model!(model, order_by_columns)
+
@finder_query = finder_query
@order_by_columns = order_by_columns
@table_name = model.table_name
@@ -34,6 +36,20 @@ module Gitlab
private
attr_reader :finder_query, :order_by_columns, :table_name
+
+ def verify_order_by_attributes_on_model!(model, order_by_columns)
+ order_by_columns.map(&:column).each do |column|
+ unless model.columns_hash[column.attribute_name.to_s]
+ text = <<~TEXT
+ The "RecordLoaderStrategy" does not support the following ORDER BY column because
+ it's not available on the \"#{model.table_name}\" table: #{column.attribute_name}
+
+ Omit the "finder_query" parameter to use the "OrderValuesLoaderStrategy".
+ TEXT
+ raise text
+ end
+ end
+ end
end
end
end
diff --git a/lib/gitlab/pagination/keyset/sql_type_missing_error.rb b/lib/gitlab/pagination/keyset/sql_type_missing_error.rb
new file mode 100644
index 00000000000..0525ae13e9c
--- /dev/null
+++ b/lib/gitlab/pagination/keyset/sql_type_missing_error.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+module Gitlab
+ module Pagination
+ module Keyset
+ class SqlTypeMissingError < StandardError
+ def self.for_column(column)
+ message = <<~TEXT
+ The "sql_type" attribute is not set for the following column definition:
+ #{column.attribute_name}
+
+ See the ColumnOrderDefinition class for more context.
+ TEXT
+
+ new(message)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/password.rb b/lib/gitlab/password.rb
new file mode 100644
index 00000000000..00aef8754d6
--- /dev/null
+++ b/lib/gitlab/password.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+# This module is used to return fake strong password for tests
+
+module Gitlab
+ module Password
+ DEFAULT_LENGTH = 12
+ TEST_DEFAULT = "123qweQWE!@#" + "0" * (User.password_length.max - DEFAULT_LENGTH)
+ def self.test_default(length = 12)
+ password_length = [[User.password_length.min, length].max, User.password_length.max].min
+ TEST_DEFAULT[...password_length]
+ end
+ end
+end
diff --git a/lib/gitlab/redis/multi_store.rb b/lib/gitlab/redis/multi_store.rb
deleted file mode 100644
index 500b62bf0e8..00000000000
--- a/lib/gitlab/redis/multi_store.rb
+++ /dev/null
@@ -1,229 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Redis
- class MultiStore
- include Gitlab::Utils::StrongMemoize
-
- class ReadFromPrimaryError < StandardError
- def message
- 'Value not found on the redis primary store. Read from the redis secondary store successful.'
- end
- end
- class MethodMissingError < StandardError
- def message
- 'Method missing. Falling back to execute method on the redis secondary store.'
- end
- end
-
- attr_reader :primary_store, :secondary_store, :instance_name
-
- FAILED_TO_READ_ERROR_MESSAGE = 'Failed to read from the redis primary_store.'
- FAILED_TO_WRITE_ERROR_MESSAGE = 'Failed to write to the redis primary_store.'
-
- SKIP_LOG_METHOD_MISSING_FOR_COMMANDS = %i(info).freeze
-
- READ_COMMANDS = %i(
- get
- mget
- smembers
- scard
- ).freeze
-
- WRITE_COMMANDS = %i(
- set
- setnx
- setex
- sadd
- srem
- del
- pipelined
- flushdb
- ).freeze
-
- def initialize(primary_store, secondary_store, instance_name)
- @primary_store = primary_store
- @secondary_store = secondary_store
- @instance_name = instance_name
-
- validate_stores!
- end
- # rubocop:disable GitlabSecurity/PublicSend
- READ_COMMANDS.each do |name|
- define_method(name) do |*args, &block|
- if use_primary_and_secondary_stores?
- read_command(name, *args, &block)
- else
- default_store.send(name, *args, &block)
- end
- end
- end
-
- WRITE_COMMANDS.each do |name|
- define_method(name) do |*args, &block|
- if use_primary_and_secondary_stores?
- write_command(name, *args, &block)
- else
- default_store.send(name, *args, &block)
- end
- end
- end
-
- def method_missing(...)
- return @instance.send(...) if @instance
-
- log_method_missing(...)
-
- default_store.send(...)
- end
- # rubocop:enable GitlabSecurity/PublicSend
-
- def respond_to_missing?(command_name, include_private = false)
- true
- end
-
- # This is needed because of Redis::Rack::Connection is requiring Redis::Store
- # https://github.com/redis-store/redis-rack/blob/a833086ba494083b6a384a1a4e58b36573a9165d/lib/redis/rack/connection.rb#L15
- # Done similarly in https://github.com/lsegal/yard/blob/main/lib/yard/templates/template.rb#L122
- def is_a?(klass)
- return true if klass == default_store.class
-
- super(klass)
- end
- alias_method :kind_of?, :is_a?
-
- def to_s
- use_primary_and_secondary_stores? ? primary_store.to_s : default_store.to_s
- end
-
- def use_primary_and_secondary_stores?
- feature_flags_available? &&
- Feature.enabled?("use_primary_and_secondary_stores_for_#{instance_name.underscore}", default_enabled: :yaml) &&
- !same_redis_store?
- end
-
- def use_primary_store_as_default?
- feature_flags_available? &&
- Feature.enabled?("use_primary_store_as_default_for_#{instance_name.underscore}", default_enabled: :yaml) &&
- !same_redis_store?
- end
-
- private
-
- def default_store
- use_primary_store_as_default? ? primary_store : secondary_store
- end
-
- def log_method_missing(command_name, *_args)
- return if SKIP_LOG_METHOD_MISSING_FOR_COMMANDS.include?(command_name)
-
- log_error(MethodMissingError.new, command_name)
- increment_method_missing_count(command_name)
- end
-
- def read_command(command_name, *args, &block)
- if @instance
- send_command(@instance, command_name, *args, &block)
- else
- read_one_with_fallback(command_name, *args, &block)
- end
- end
-
- def write_command(command_name, *args, &block)
- if @instance
- send_command(@instance, command_name, *args, &block)
- else
- write_both(command_name, *args, &block)
- end
- end
-
- def read_one_with_fallback(command_name, *args, &block)
- begin
- value = send_command(primary_store, command_name, *args, &block)
- rescue StandardError => e
- log_error(e, command_name,
- multi_store_error_message: FAILED_TO_READ_ERROR_MESSAGE)
- end
-
- value ||= fallback_read(command_name, *args, &block)
-
- value
- end
-
- def fallback_read(command_name, *args, &block)
- value = send_command(secondary_store, command_name, *args, &block)
-
- if value
- log_error(ReadFromPrimaryError.new, command_name)
- increment_read_fallback_count(command_name)
- end
-
- value
- end
-
- def write_both(command_name, *args, &block)
- begin
- send_command(primary_store, command_name, *args, &block)
- rescue StandardError => e
- log_error(e, command_name,
- multi_store_error_message: FAILED_TO_WRITE_ERROR_MESSAGE)
- end
-
- send_command(secondary_store, command_name, *args, &block)
- end
-
- def same_redis_store?
- strong_memoize(:same_redis_store) do
- # <Redis client v4.4.0 for redis:///path_to/redis/redis.socket/5>"
- primary_store.inspect == secondary_store.inspect
- end
- end
-
- # rubocop:disable GitlabSecurity/PublicSend
- def send_command(redis_instance, command_name, *args, &block)
- if block_given?
- # Make sure that block is wrapped and executed only on the redis instance that is executing the block
- redis_instance.send(command_name, *args) do |*params|
- with_instance(redis_instance, *params, &block)
- end
- else
- redis_instance.send(command_name, *args)
- end
- end
- # rubocop:enable GitlabSecurity/PublicSend
-
- def with_instance(instance, *params)
- @instance = instance
-
- yield(*params)
- ensure
- @instance = nil
- end
-
- def increment_read_fallback_count(command_name)
- @read_fallback_counter ||= Gitlab::Metrics.counter(:gitlab_redis_multi_store_read_fallback_total, 'Client side Redis MultiStore reading fallback')
- @read_fallback_counter.increment(command: command_name, instance_name: instance_name)
- end
-
- def increment_method_missing_count(command_name)
- @method_missing_counter ||= Gitlab::Metrics.counter(:gitlab_redis_multi_store_method_missing_total, 'Client side Redis MultiStore method missing')
- @method_missing_counter.increment(command: command_name, instance_name: instance_name)
- end
-
- def validate_stores!
- raise ArgumentError, 'primary_store is required' unless primary_store
- raise ArgumentError, 'secondary_store is required' unless secondary_store
- raise ArgumentError, 'instance_name is required' unless instance_name
- raise ArgumentError, 'invalid primary_store' unless primary_store.is_a?(::Redis)
- raise ArgumentError, 'invalid secondary_store' unless secondary_store.is_a?(::Redis)
- end
-
- def log_error(exception, command_name, extra = {})
- Gitlab::ErrorTracking.log_exception(
- exception,
- command_name: command_name,
- extra: extra.merge(instance_name: instance_name))
- end
- end
- end
-end
diff --git a/lib/gitlab/redis/sessions.rb b/lib/gitlab/redis/sessions.rb
index c547828d907..ddcfdf6e798 100644
--- a/lib/gitlab/redis/sessions.rb
+++ b/lib/gitlab/redis/sessions.rb
@@ -9,39 +9,9 @@ module Gitlab
IP_SESSIONS_LOOKUP_NAMESPACE = 'session:lookup:ip:gitlab2'
OTP_SESSIONS_NAMESPACE = 'session:otp'
- class << self
- # The data we store on Sessions used to be stored on SharedState.
- def config_fallback
- SharedState
- end
-
- private
-
- def redis
- # Don't use multistore if redis.sessions configuration is not provided
- return super if config_fallback?
-
- primary_store = ::Redis.new(params)
- secondary_store = ::Redis.new(config_fallback.params)
-
- MultiStore.new(primary_store, secondary_store, store_name)
- end
- end
-
- def store(extras = {})
- # Don't use multistore if redis.sessions configuration is not provided
- return super if self.class.config_fallback?
-
- primary_store = create_redis_store(redis_store_options, extras)
- secondary_store = create_redis_store(self.class.config_fallback.params, extras)
-
- MultiStore.new(primary_store, secondary_store, self.class.store_name)
- end
-
- private
-
- def create_redis_store(options, extras)
- ::Redis::Store.new(options.merge(extras))
+ # The data we store on Sessions used to be stored on SharedState.
+ def self.config_fallback
+ SharedState
end
end
end
diff --git a/lib/gitlab/redis/sessions_store_helper.rb b/lib/gitlab/redis/sessions_store_helper.rb
deleted file mode 100644
index c80442847f1..00000000000
--- a/lib/gitlab/redis/sessions_store_helper.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Redis
- module SessionsStoreHelper
- extend ActiveSupport::Concern
-
- module StoreMethods
- def redis_store_class
- use_redis_session_store? ? Gitlab::Redis::Sessions : Gitlab::Redis::SharedState
- end
-
- private
-
- def use_redis_session_store?
- Gitlab::Utils.to_boolean(ENV['GITLAB_USE_REDIS_SESSIONS_STORE'], default: true)
- end
- end
-
- include StoreMethods
-
- included do
- extend StoreMethods
- end
- end
- end
-end
diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb
index 8e139ae0709..b07b9c79858 100644
--- a/lib/gitlab/regex.rb
+++ b/lib/gitlab/regex.rb
@@ -79,7 +79,11 @@ module Gitlab
def nuget_version_regex
@nuget_version_regex ||= /
- \A#{_semver_major_minor_patch_regex}(\.\d*)?#{_semver_prerelease_build_regex}\z
+ \A#{_semver_major_regex}
+ \.#{_semver_minor_regex}
+ (\.#{_semver_patch_regex})?
+ (\.\d*)?
+ #{_semver_prerelease_build_regex}\z
/x.freeze
end
@@ -167,9 +171,25 @@ module Gitlab
# regexes rather than being used alone.
def _semver_major_minor_patch_regex
@_semver_major_minor_patch_regex ||= /
+ #{_semver_major_regex}\.#{_semver_minor_regex}\.#{_semver_patch_regex}
+ /x.freeze
+ end
+
+ def _semver_major_regex
+ @_semver_major_regex ||= /
(?<major>0|[1-9]\d*)
- \.(?<minor>0|[1-9]\d*)
- \.(?<patch>0|[1-9]\d*)
+ /x.freeze
+ end
+
+ def _semver_minor_regex
+ @_semver_minor_regex ||= /
+ (?<minor>0|[1-9]\d*)
+ /x.freeze
+ end
+
+ def _semver_patch_regex
+ @_semver_patch_regex ||= /
+ (?<patch>0|[1-9]\d*)
/x.freeze
end
diff --git a/lib/gitlab/repository_archive_rate_limiter.rb b/lib/gitlab/repository_archive_rate_limiter.rb
index 31a3dc34bf6..d395b1aba7f 100644
--- a/lib/gitlab/repository_archive_rate_limiter.rb
+++ b/lib/gitlab/repository_archive_rate_limiter.rb
@@ -3,7 +3,7 @@
module Gitlab
module RepositoryArchiveRateLimiter
def check_archive_rate_limit!(current_user, project, &block)
- return unless Feature.enabled?(:archive_rate_limit)
+ return unless Feature.enabled?(:archive_rate_limit, default_enabled: :yaml)
threshold = current_user ? nil : 100
diff --git a/lib/gitlab/search/params.rb b/lib/gitlab/search/params.rb
index e6a1305a82a..1ae14e5e618 100644
--- a/lib/gitlab/search/params.rb
+++ b/lib/gitlab/search/params.rb
@@ -7,6 +7,7 @@ module Gitlab
SEARCH_CHAR_LIMIT = 4096
SEARCH_TERM_LIMIT = 64
+ MIN_TERM_LENGTH = 3
# Generic validation
validates :query_string, length: { maximum: SEARCH_CHAR_LIMIT }
@@ -53,6 +54,10 @@ module Gitlab
errors[:query_string].none? { |msg| msg.include? SEARCH_TERM_LIMIT.to_s }
end
+ def email_lookup?
+ search_terms.any? { |term| term =~ URI::MailTo::EMAIL_REGEXP }
+ end
+
def validate
if detect_abuse?
abuse_detection.validate
@@ -75,8 +80,12 @@ module Gitlab
@detect_abuse
end
+ def search_terms
+ @search_terms ||= query_string.split.select { |word| word.length >= MIN_TERM_LENGTH }
+ end
+
def not_too_many_terms
- if query_string.split.count { |word| word.length >= 3 } > SEARCH_TERM_LIMIT
+ if search_terms.count > SEARCH_TERM_LIMIT
errors.add :query_string, "has too many search terms (maximum is #{SEARCH_TERM_LIMIT})"
end
end
diff --git a/lib/gitlab/sherlock.rb b/lib/gitlab/sherlock.rb
deleted file mode 100644
index a1471c9de47..00000000000
--- a/lib/gitlab/sherlock.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-require 'securerandom'
-
-module Gitlab
- module Sherlock
- @collection = Collection.new
-
- class << self
- attr_reader :collection
- end
-
- def self.enabled?
- Rails.env.development? && !!ENV['ENABLE_SHERLOCK']
- end
-
- def self.enable_line_profiler?
- RUBY_ENGINE == 'ruby'
- end
- end
-end
diff --git a/lib/gitlab/sherlock/collection.rb b/lib/gitlab/sherlock/collection.rb
deleted file mode 100644
index ce3a376cf75..00000000000
--- a/lib/gitlab/sherlock/collection.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Sherlock
- # A collection of transactions recorded by Sherlock.
- #
- # Method calls for this class are synchronized using a mutex to allow
- # sharing of a single Collection instance between threads (e.g. when using
- # Puma as a webserver).
- class Collection
- include Enumerable
-
- def initialize
- @transactions = []
- @mutex = Mutex.new
- end
-
- def add(transaction)
- synchronize { @transactions << transaction }
- end
-
- alias_method :<<, :add
-
- def each(&block)
- synchronize { @transactions.each(&block) }
- end
-
- def clear
- synchronize { @transactions.clear }
- end
-
- def empty?
- synchronize { @transactions.empty? }
- end
-
- def find_transaction(id)
- find { |trans| trans.id == id }
- end
-
- def newest_first
- sort { |a, b| b.finished_at <=> a.finished_at }
- end
-
- private
-
- def synchronize(&block)
- @mutex.synchronize(&block)
- end
- end
- end
-end
diff --git a/lib/gitlab/sherlock/file_sample.rb b/lib/gitlab/sherlock/file_sample.rb
deleted file mode 100644
index 5d10d8c4877..00000000000
--- a/lib/gitlab/sherlock/file_sample.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Sherlock
- class FileSample
- attr_reader :id, :file, :line_samples, :events, :duration
-
- # file - The full path to the file this sample belongs to.
- # line_samples - An array of LineSample objects.
- # duration - The total execution time in milliseconds.
- # events - The total amount of events.
- def initialize(file, line_samples, duration, events)
- @id = SecureRandom.uuid
- @file = file
- @line_samples = line_samples
- @duration = duration
- @events = events
- end
-
- def relative_path
- @relative_path ||= @file.gsub(%r{^#{Rails.root}/?}, '')
- end
-
- def to_param
- @id
- end
-
- def source
- @source ||= File.read(@file)
- end
- end
- end
-end
diff --git a/lib/gitlab/sherlock/line_profiler.rb b/lib/gitlab/sherlock/line_profiler.rb
deleted file mode 100644
index aa25eb5a571..00000000000
--- a/lib/gitlab/sherlock/line_profiler.rb
+++ /dev/null
@@ -1,100 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Sherlock
- # Class for profiling code on a per line basis.
- #
- # The LineProfiler class can be used to profile code on per line basis
- # without littering your code with Ruby implementation specific profiling
- # methods.
- #
- # This profiler only includes samples taking longer than a given threshold
- # and those that occur in the actual application (e.g. files from Gems are
- # ignored).
- class LineProfiler
- # The minimum amount of time that has to be spent in a file for it to be
- # included in a list of samples.
- MINIMUM_DURATION = 10.0
-
- # Profiles the given block.
- #
- # Example:
- #
- # profiler = LineProfiler.new
- #
- # retval, samples = profiler.profile do
- # "cats are amazing"
- # end
- #
- # retval # => "cats are amazing"
- # samples # => [#<Gitlab::Sherlock::FileSample ...>, ...]
- #
- # Returns an Array containing the block's return value and an Array of
- # FileSample objects.
- def profile(&block)
- if mri?
- profile_mri(&block)
- else
- raise NotImplementedError,
- 'Line profiling is not supported on this platform'
- end
- end
-
- # Profiles the given block using rblineprof (MRI only).
- def profile_mri
- require 'rblineprof'
-
- retval = nil
- samples = lineprof(/^#{Rails.root}/) { retval = yield }
-
- file_samples = aggregate_rblineprof(samples)
-
- [retval, file_samples]
- end
-
- # Returns an Array of file samples based on the output of rblineprof.
- #
- # lineprof_stats - A Hash containing rblineprof statistics on a per file
- # basis.
- #
- # Returns an Array of FileSample objects.
- def aggregate_rblineprof(lineprof_stats)
- samples = []
-
- lineprof_stats.each do |(file, stats)|
- source_lines = File.read(file).each_line.to_a
- line_samples = []
-
- total_duration = microsec_to_millisec(stats[0][0])
- total_events = stats[0][2]
-
- next if total_duration <= MINIMUM_DURATION
-
- stats[1..].each_with_index do |data, index|
- next unless source_lines[index]
-
- duration = microsec_to_millisec(data[0])
- events = data[2]
-
- line_samples << LineSample.new(duration, events)
- end
-
- samples << FileSample
- .new(file, line_samples, total_duration, total_events)
- end
-
- samples
- end
-
- private
-
- def microsec_to_millisec(microsec)
- microsec / 1000.0
- end
-
- def mri?
- RUBY_ENGINE == 'ruby'
- end
- end
- end
-end
diff --git a/lib/gitlab/sherlock/line_sample.rb b/lib/gitlab/sherlock/line_sample.rb
deleted file mode 100644
index c92fa9ea1ff..00000000000
--- a/lib/gitlab/sherlock/line_sample.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Sherlock
- class LineSample
- attr_reader :duration, :events
-
- # duration - The execution time in milliseconds.
- # events - The amount of events.
- def initialize(duration, events)
- @duration = duration
- @events = events
- end
-
- # Returns the sample duration percentage relative to the given duration.
- #
- # Example:
- #
- # sample.duration # => 150
- # sample.percentage_of(1500) # => 10.0
- #
- # total_duration - The total duration to compare with.
- #
- # Returns a float
- def percentage_of(total_duration)
- (duration.to_f / total_duration) * 100.0
- end
-
- # Returns true if the current sample takes up the majority of the given
- # duration.
- #
- # total_duration - The total duration to compare with.
- def majority_of?(total_duration)
- percentage_of(total_duration) >= 30
- end
- end
- end
-end
diff --git a/lib/gitlab/sherlock/location.rb b/lib/gitlab/sherlock/location.rb
deleted file mode 100644
index 4bba60f3490..00000000000
--- a/lib/gitlab/sherlock/location.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Sherlock
- class Location
- attr_reader :path, :line
-
- SHERLOCK_DIR = File.dirname(__FILE__)
-
- # Creates a new Location from a `Thread::Backtrace::Location`.
- def self.from_ruby_location(location)
- new(location.path, location.lineno)
- end
-
- # path - The full path of the frame as a String.
- # line - The line number of the frame as a Fixnum.
- def initialize(path, line)
- @path = path
- @line = line
- end
-
- # Returns true if the current frame originated from the application.
- def application?
- @path.start_with?(Rails.root.to_s) && !path.start_with?(SHERLOCK_DIR)
- end
- end
- end
-end
diff --git a/lib/gitlab/sherlock/middleware.rb b/lib/gitlab/sherlock/middleware.rb
deleted file mode 100644
index f7b08d58e49..00000000000
--- a/lib/gitlab/sherlock/middleware.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Sherlock
- # Rack middleware used for tracking request metrics.
- class Middleware
- CONTENT_TYPES = %r{text/html|application/json}i.freeze
-
- IGNORE_PATHS = %r{^/sherlock}.freeze
-
- def initialize(app)
- @app = app
- end
-
- # env - A Hash containing Rack environment details.
- def call(env)
- if instrument?(env)
- call_with_instrumentation(env)
- else
- @app.call(env)
- end
- end
-
- def call_with_instrumentation(env)
- trans = transaction_from_env(env)
- retval = trans.run { @app.call(env) }
-
- Sherlock.collection.add(trans)
-
- retval
- end
-
- def instrument?(env)
- !!(env['HTTP_ACCEPT'] =~ CONTENT_TYPES &&
- env['REQUEST_URI'] !~ IGNORE_PATHS)
- end
-
- def transaction_from_env(env)
- Transaction.new(env['REQUEST_METHOD'], env['REQUEST_URI'])
- end
- end
- end
-end
diff --git a/lib/gitlab/sherlock/query.rb b/lib/gitlab/sherlock/query.rb
deleted file mode 100644
index 6f1d2ad23c1..00000000000
--- a/lib/gitlab/sherlock/query.rb
+++ /dev/null
@@ -1,112 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Sherlock
- class Query
- attr_reader :id, :query, :started_at, :finished_at, :backtrace
-
- # SQL identifiers that should be prefixed with newlines.
- PREFIX_NEWLINE = %r{
- \s+(FROM
- |(LEFT|RIGHT)?INNER\s+JOIN
- |(LEFT|RIGHT)?OUTER\s+JOIN
- |WHERE
- |AND
- |GROUP\s+BY
- |ORDER\s+BY
- |LIMIT
- |OFFSET)\s+}ix.freeze # Vim indent breaks when this is on a newline :<
-
- # Creates a new Query using a String and a separate Array of bindings.
- #
- # query - A String containing a SQL query, optionally with numeric
- # placeholders (`$1`, `$2`, etc).
- #
- # bindings - An Array of ActiveRecord columns and their values.
- # started_at - The start time of the query as a Time-like object.
- # finished_at - The completion time of the query as a Time-like object.
- #
- # Returns a new Query object.
- def self.new_with_bindings(query, bindings, started_at, finished_at)
- bindings.each_with_index do |(_, value), index|
- quoted_value = ActiveRecord::Base.connection.quote(value)
-
- query = query.gsub("$#{index + 1}", quoted_value)
- end
-
- new(query, started_at, finished_at)
- end
-
- # query - The SQL query as a String (without placeholders).
- # started_at - The start time of the query as a Time-like object.
- # finished_at - The completion time of the query as a Time-like object.
- def initialize(query, started_at, finished_at)
- @id = SecureRandom.uuid
- @query = query
- @started_at = started_at
- @finished_at = finished_at
- @backtrace = caller_locations.map do |loc|
- Location.from_ruby_location(loc)
- end
-
- unless @query.end_with?(';')
- @query = "#{@query};"
- end
- end
-
- # Returns the query duration in milliseconds.
- def duration
- @duration ||= (@finished_at - @started_at) * 1000.0
- end
-
- def to_param
- @id
- end
-
- # Returns a human readable version of the query.
- def formatted_query
- @formatted_query ||= format_sql(@query)
- end
-
- # Returns the last application frame of the backtrace.
- def last_application_frame
- @last_application_frame ||= @backtrace.find(&:application?)
- end
-
- # Returns an Array of application frames (excluding Gems and the likes).
- def application_backtrace
- @application_backtrace ||= @backtrace.select(&:application?)
- end
-
- # Returns the query plan as a String.
- def explain
- unless @explain
- ActiveRecord::Base.connection.transaction do
- @explain = raw_explain(@query).values.flatten.join("\n")
-
- # Roll back any queries that mutate data so we don't mess up
- # anything when running explain on an INSERT, UPDATE, DELETE, etc.
- raise ActiveRecord::Rollback
- end
- end
-
- @explain
- end
-
- private
-
- def raw_explain(query)
- explain = "EXPLAIN ANALYZE #{query};"
-
- ActiveRecord::Base.connection.execute(explain)
- end
-
- def format_sql(query)
- query.each_line
- .map { |line| line.strip }
- .join("\n")
- .gsub(PREFIX_NEWLINE) { "\n#{Regexp.last_match(1)} " }
- end
- end
- end
-end
diff --git a/lib/gitlab/sherlock/transaction.rb b/lib/gitlab/sherlock/transaction.rb
deleted file mode 100644
index d04624977dc..00000000000
--- a/lib/gitlab/sherlock/transaction.rb
+++ /dev/null
@@ -1,140 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Sherlock
- class Transaction
- attr_reader :id, :type, :path, :queries, :file_samples, :started_at,
- :finished_at, :view_counts
-
- # type - The type of transaction (e.g. "GET", "POST", etc)
- # path - The path of the transaction (e.g. the HTTP request path)
- def initialize(type, path)
- @id = SecureRandom.uuid
- @type = type
- @path = path
- @queries = []
- @file_samples = []
- @started_at = nil
- @finished_at = nil
- @thread = Thread.current
- @view_counts = Hash.new(0)
- end
-
- # Runs the transaction and returns the block's return value.
- def run
- @started_at = Time.now
-
- retval = with_subscriptions do
- profile_lines { yield }
- end
-
- @finished_at = Time.now
-
- retval
- end
-
- # Returns the duration in seconds.
- def duration
- @duration ||= started_at && finished_at ? finished_at - started_at : 0
- end
-
- # Returns the total query duration in seconds.
- def query_duration
- @query_duration ||= @queries.map { |q| q.duration }.inject(:+) / 1000.0
- end
-
- def to_param
- @id
- end
-
- # Returns the queries sorted in descending order by their durations.
- def sorted_queries
- @queries.sort { |a, b| b.duration <=> a.duration }
- end
-
- # Returns the file samples sorted in descending order by their durations.
- def sorted_file_samples
- @file_samples.sort { |a, b| b.duration <=> a.duration }
- end
-
- # Finds a query by the given ID.
- #
- # id - The query ID as a String.
- #
- # Returns a Query object if one could be found, nil otherwise.
- def find_query(id)
- @queries.find { |query| query.id == id }
- end
-
- # Finds a file sample by the given ID.
- #
- # id - The query ID as a String.
- #
- # Returns a FileSample object if one could be found, nil otherwise.
- def find_file_sample(id)
- @file_samples.find { |sample| sample.id == id }
- end
-
- def profile_lines
- retval = nil
-
- if Sherlock.enable_line_profiler?
- retval, @file_samples = LineProfiler.new.profile { yield }
- else
- retval = yield
- end
-
- retval
- end
-
- def subscribe_to_active_record
- ActiveSupport::Notifications.subscribe('sql.active_record') do |_, start, finish, _, data|
- next unless same_thread?
-
- unless data.fetch(:cached, data[:name] == 'CACHE')
- track_query(data[:sql].strip, data[:binds], start, finish)
- end
- end
- end
-
- def subscribe_to_action_view
- regex = /render_(template|partial)\.action_view/
-
- ActiveSupport::Notifications.subscribe(regex) do |_, start, finish, _, data|
- next unless same_thread?
-
- track_view(data[:identifier])
- end
- end
-
- private
-
- def track_query(query, bindings, start, finish)
- @queries << Query.new_with_bindings(query, bindings, start, finish)
- end
-
- def track_view(path)
- @view_counts[path] += 1
- end
-
- def with_subscriptions
- ar_subscriber = subscribe_to_active_record
- av_subscriber = subscribe_to_action_view
-
- retval = yield
-
- ActiveSupport::Notifications.unsubscribe(ar_subscriber)
- ActiveSupport::Notifications.unsubscribe(av_subscriber)
-
- retval
- end
-
- # In case somebody uses a multi-threaded server locally (e.g. Puma) we
- # _only_ want to track notifications that originate from the transaction
- # thread.
- def same_thread?
- Thread.current == @thread
- end
- end
- end
-end
diff --git a/lib/gitlab/sidekiq_logging/json_formatter.rb b/lib/gitlab/sidekiq_logging/json_formatter.rb
index a6281bbdf26..dd50fef8c3d 100644
--- a/lib/gitlab/sidekiq_logging/json_formatter.rb
+++ b/lib/gitlab/sidekiq_logging/json_formatter.rb
@@ -2,6 +2,7 @@
# This is needed for sidekiq-cluster
require 'json'
+require 'sidekiq/job_retry'
module Gitlab
module SidekiqLogging
diff --git a/lib/gitlab/sidekiq_logging/structured_logger.rb b/lib/gitlab/sidekiq_logging/structured_logger.rb
index 3438bc0f3ef..a9bfcce2e0a 100644
--- a/lib/gitlab/sidekiq_logging/structured_logger.rb
+++ b/lib/gitlab/sidekiq_logging/structured_logger.rb
@@ -2,6 +2,8 @@
require 'active_record'
require 'active_record/log_subscriber'
+require 'sidekiq/job_logger'
+require 'sidekiq/job_retry'
module Gitlab
module SidekiqLogging
diff --git a/lib/gitlab/sidekiq_middleware/monitor.rb b/lib/gitlab/sidekiq_middleware/monitor.rb
index ed825dbfd60..d38fed3b768 100644
--- a/lib/gitlab/sidekiq_middleware/monitor.rb
+++ b/lib/gitlab/sidekiq_middleware/monitor.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require 'sidekiq/job_retry'
+
module Gitlab
module SidekiqMiddleware
class Monitor
diff --git a/lib/gitlab/sidekiq_status.rb b/lib/gitlab/sidekiq_status.rb
index 120d18f63f2..66417b3697e 100644
--- a/lib/gitlab/sidekiq_status.rb
+++ b/lib/gitlab/sidekiq_status.rb
@@ -29,16 +29,15 @@ module Gitlab
# for most jobs.
DEFAULT_EXPIRATION = 30.minutes.to_i
- DEFAULT_VALUE = 1
- DEFAULT_VALUE_MESSAGE = 'Keys using the default value for SidekiqStatus detected'
-
# Starts tracking of the given job.
#
# jid - The Sidekiq job ID
# expire - The expiration time of the Redis key.
- def self.set(jid, expire = DEFAULT_EXPIRATION, value: DEFAULT_VALUE)
+ def self.set(jid, expire = DEFAULT_EXPIRATION)
+ return unless expire
+
Sidekiq.redis do |redis|
- redis.set(key_for(jid), value, ex: expire)
+ redis.set(key_for(jid), 1, ex: expire)
end
end
@@ -94,17 +93,10 @@ module Gitlab
return [] if job_ids.empty?
keys = job_ids.map { |jid| key_for(jid) }
- results = Sidekiq.redis { |redis| redis.mget(*keys) }
-
- if Feature.enabled?(:log_implicit_sidekiq_status_calls, default_enabled: :yaml)
- to_log = keys.zip(results).select do |_key, result|
- result == DEFAULT_VALUE.to_s
- end.map(&:first)
-
- Sidekiq.logger.info(message: DEFAULT_VALUE_MESSAGE, keys: to_log) if to_log.any?
- end
- results.map { |result| !result.nil? }
+ Sidekiq
+ .redis { |redis| redis.mget(*keys) }
+ .map { |result| !result.nil? }
end
# Returns the JIDs that are completed
diff --git a/lib/gitlab/sidekiq_status/client_middleware.rb b/lib/gitlab/sidekiq_status/client_middleware.rb
index cee7270f2fb..8471696dcea 100644
--- a/lib/gitlab/sidekiq_status/client_middleware.rb
+++ b/lib/gitlab/sidekiq_status/client_middleware.rb
@@ -4,10 +4,8 @@ module Gitlab
module SidekiqStatus
class ClientMiddleware
def call(_, job, _, _)
- status_expiration = job['status_expiration'] || Gitlab::SidekiqStatus::DEFAULT_EXPIRATION
- value = job['status_expiration'] ? 2 : Gitlab::SidekiqStatus::DEFAULT_VALUE
+ Gitlab::SidekiqStatus.set(job['jid'], job['status_expiration'])
- Gitlab::SidekiqStatus.set(job['jid'], status_expiration, value: value)
yield
end
end
diff --git a/lib/gitlab/sourcegraph.rb b/lib/gitlab/sourcegraph.rb
index 7ef6ab32bd4..892c4468107 100644
--- a/lib/gitlab/sourcegraph.rb
+++ b/lib/gitlab/sourcegraph.rb
@@ -8,13 +8,14 @@ module Gitlab
end
def feature_available?
- # The sourcegraph_bundle feature could be conditionally applied, so check if `!off?`
- !feature.off?
+ # The sourcegraph feature could be conditionally applied, so check if `!off?`
+ # We also can't just check !off? because the ActiveRecord might not exist yet
+ self.feature_enabled? || !feature.off?
end
def feature_enabled?(actor = nil)
# Some CI jobs grep for Feature.enabled? in our codebase, so it is important this reference stays around.
- Feature.enabled?(:sourcegraph, actor)
+ Feature.enabled?(:sourcegraph, actor, default_enabled: :yaml)
end
private
diff --git a/lib/gitlab/ssh_public_key.rb b/lib/gitlab/ssh_public_key.rb
index 6df54852d02..314cc5e2db6 100644
--- a/lib/gitlab/ssh_public_key.rb
+++ b/lib/gitlab/ssh_public_key.rb
@@ -2,13 +2,15 @@
module Gitlab
class SSHPublicKey
- Technology = Struct.new(:name, :key_class, :supported_sizes)
+ Technology = Struct.new(:name, :key_class, :supported_sizes, :supported_algorithms)
+ # See https://man.openbsd.org/sshd#AUTHORIZED_KEYS_FILE_FORMAT for the list of
+ # supported algorithms.
TECHNOLOGIES = [
- Technology.new(:rsa, OpenSSL::PKey::RSA, [1024, 2048, 3072, 4096]),
- Technology.new(:dsa, OpenSSL::PKey::DSA, [1024, 2048, 3072]),
- Technology.new(:ecdsa, OpenSSL::PKey::EC, [256, 384, 521]),
- Technology.new(:ed25519, Net::SSH::Authentication::ED25519::PubKey, [256])
+ Technology.new(:rsa, OpenSSL::PKey::RSA, [1024, 2048, 3072, 4096], %w(ssh-rsa)),
+ Technology.new(:dsa, OpenSSL::PKey::DSA, [1024, 2048, 3072], %w(ssh-dss)),
+ Technology.new(:ecdsa, OpenSSL::PKey::EC, [256, 384, 521], %w(ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521)),
+ Technology.new(:ed25519, Net::SSH::Authentication::ED25519::PubKey, [256], %w(ssh-ed25519))
].freeze
def self.technology(name)
@@ -19,8 +21,20 @@ module Gitlab
TECHNOLOGIES.find { |tech| key.is_a?(tech.key_class) }
end
+ def self.supported_types
+ TECHNOLOGIES.map(&:name)
+ end
+
def self.supported_sizes(name)
- technology(name)&.supported_sizes
+ technology(name).supported_sizes
+ end
+
+ def self.supported_algorithms
+ TECHNOLOGIES.flat_map { |tech| tech.supported_algorithms }
+ end
+
+ def self.supported_algorithms_for_name(name)
+ technology(name).supported_algorithms
end
def self.sanitize(key_content)
diff --git a/lib/gitlab/themes.rb b/lib/gitlab/themes.rb
index ac1522b8a6c..228da9ee370 100644
--- a/lib/gitlab/themes.rb
+++ b/lib/gitlab/themes.rb
@@ -13,26 +13,28 @@ module Gitlab
Theme = Struct.new(:id, :name, :css_class, :css_filename, :primary_color)
# All available Themes
- THEMES = [
- Theme.new(1, 'Indigo', 'ui-indigo', 'theme_indigo', '#292961'),
- Theme.new(6, 'Light Indigo', 'ui-light-indigo', 'theme_light_indigo', '#4b4ba3'),
- Theme.new(4, 'Blue', 'ui-blue', 'theme_blue', '#1a3652'),
- Theme.new(7, 'Light Blue', 'ui-light-blue', 'theme_light_blue', '#2261a1'),
- Theme.new(5, 'Green', 'ui-green', 'theme_green', '#0d4524'),
- Theme.new(8, 'Light Green', 'ui-light-green', 'theme_light_green', '#156b39'),
- Theme.new(9, 'Red', 'ui-red', 'theme_red', '#691a16'),
- Theme.new(10, 'Light Red', 'ui-light-red', 'theme_light_red', '#a62e21'),
- Theme.new(2, 'Dark', 'ui-dark', 'theme_dark', '#303030'),
- Theme.new(3, 'Light', 'ui-light', 'theme_light', '#666'),
- Theme.new(11, 'Dark Mode (alpha)', 'gl-dark', nil, '#303030')
- ].freeze
+ def available_themes
+ [
+ Theme.new(1, s_('NavigationTheme|Indigo'), 'ui-indigo', 'theme_indigo', '#292961'),
+ Theme.new(6, s_('NavigationTheme|Light Indigo'), 'ui-light-indigo', 'theme_light_indigo', '#4b4ba3'),
+ Theme.new(4, s_('NavigationTheme|Blue'), 'ui-blue', 'theme_blue', '#1a3652'),
+ Theme.new(7, s_('NavigationTheme|Light Blue'), 'ui-light-blue', 'theme_light_blue', '#2261a1'),
+ Theme.new(5, s_('NavigationTheme|Green'), 'ui-green', 'theme_green', '#0d4524'),
+ Theme.new(8, s_('NavigationTheme|Light Green'), 'ui-light-green', 'theme_light_green', '#156b39'),
+ Theme.new(9, s_('NavigationTheme|Red'), 'ui-red', 'theme_red', '#691a16'),
+ Theme.new(10, s_('NavigationTheme|Light Red'), 'ui-light-red', 'theme_light_red', '#a62e21'),
+ Theme.new(2, s_('NavigationTheme|Dark'), 'ui-dark', 'theme_dark', '#303030'),
+ Theme.new(3, s_('NavigationTheme|Light'), 'ui-light', 'theme_light', '#666'),
+ Theme.new(11, s_('NavigationTheme|Dark Mode (alpha)'), 'gl-dark', nil, '#303030')
+ ]
+ end
# Convenience method to get a space-separated String of all the theme
# classes that might be applied to the `body` element
#
# Returns a String
def body_classes
- THEMES.collect(&:css_class).uniq.join(' ')
+ available_themes.collect(&:css_class).uniq.join(' ')
end
# Get a Theme by its ID
@@ -43,12 +45,12 @@ module Gitlab
#
# Returns a Theme
def by_id(id)
- THEMES.detect { |t| t.id == id } || default
+ available_themes.detect { |t| t.id == id } || default
end
# Returns the number of defined Themes
def count
- THEMES.size
+ available_themes.size
end
# Get the default Theme
@@ -62,7 +64,7 @@ module Gitlab
#
# Yields the Theme object
def each(&block)
- THEMES.each(&block)
+ available_themes.each(&block)
end
# Get the Theme for the specified user, or the default
@@ -79,7 +81,7 @@ module Gitlab
end
def self.valid_ids
- THEMES.map(&:id)
+ available_themes.map(&:id)
end
private
@@ -87,7 +89,7 @@ module Gitlab
def default_id
@default_id ||= begin
id = Gitlab.config.gitlab.default_theme.to_i
- theme_ids = THEMES.map(&:id)
+ theme_ids = available_themes.map(&:id)
theme_ids.include?(id) ? id : APPLICATION_DEFAULT
end
diff --git a/lib/gitlab/tracking/standard_context.rb b/lib/gitlab/tracking/standard_context.rb
index 837390b91fb..542dc476526 100644
--- a/lib/gitlab/tracking/standard_context.rb
+++ b/lib/gitlab/tracking/standard_context.rb
@@ -3,7 +3,7 @@
module Gitlab
module Tracking
class StandardContext
- GITLAB_STANDARD_SCHEMA_URL = 'iglu:com.gitlab/gitlab_standard/jsonschema/1-0-7'
+ GITLAB_STANDARD_SCHEMA_URL = 'iglu:com.gitlab/gitlab_standard/jsonschema/1-0-8'
GITLAB_RAILS_SOURCE = 'gitlab-rails'
def initialize(namespace: nil, project: nil, user: nil, **extra)
@@ -46,7 +46,8 @@ module Gitlab
extra: extra,
user_id: user&.id,
namespace_id: namespace&.id,
- project_id: project_id
+ project_id: project_id,
+ context_generated_at: Time.current
}
end
diff --git a/lib/gitlab/untrusted_regexp/ruby_syntax.rb b/lib/gitlab/untrusted_regexp/ruby_syntax.rb
index 6adf119aa75..010214cf295 100644
--- a/lib/gitlab/untrusted_regexp/ruby_syntax.rb
+++ b/lib/gitlab/untrusted_regexp/ruby_syntax.rb
@@ -20,13 +20,13 @@ module Gitlab
!!self.fabricate(pattern, fallback: fallback)
end
- def self.fabricate(pattern, fallback: false)
- self.fabricate!(pattern, fallback: fallback)
+ def self.fabricate(pattern, fallback: false, project: nil)
+ self.fabricate!(pattern, fallback: fallback, project: project)
rescue RegexpError
nil
end
- def self.fabricate!(pattern, fallback: false)
+ def self.fabricate!(pattern, fallback: false, project: nil)
raise RegexpError, 'Pattern is not string!' unless pattern.is_a?(String)
matches = pattern.match(PATTERN)
@@ -38,6 +38,16 @@ module Gitlab
raise unless fallback &&
Feature.enabled?(:allow_unsafe_ruby_regexp, default_enabled: false)
+ if Feature.enabled?(:ci_unsafe_regexp_logger, type: :ops, default_enabled: :yaml)
+ Gitlab::AppJsonLogger.info(
+ class: self.class.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
end
diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb
index 917c273d3f6..adf920d8b52 100644
--- a/lib/gitlab/usage_data.rb
+++ b/lib/gitlab/usage_data.rb
@@ -304,7 +304,8 @@ module Gitlab
# rubocop: disable UsageData/LargeTable
adapter: alt_usage_data { ApplicationRecord.database.adapter_name },
version: alt_usage_data { ApplicationRecord.database.version },
- pg_system_id: alt_usage_data { ApplicationRecord.database.system_id }
+ pg_system_id: alt_usage_data { ApplicationRecord.database.system_id },
+ flavor: alt_usage_data { ApplicationRecord.database.flavor }
# rubocop: enable UsageData/LargeTable
},
mail: {
@@ -521,11 +522,7 @@ module Gitlab
projects_with_disable_overriding_approvers_per_merge_request: count(::Project.where(time_period.merge(disable_overriding_approvers_per_merge_request: true))),
projects_without_disable_overriding_approvers_per_merge_request: count(::Project.where(time_period.merge(disable_overriding_approvers_per_merge_request: [false, nil]))),
remote_mirrors: distinct_count(::Project.with_remote_mirrors.where(time_period), :creator_id),
- snippets: distinct_count(::Snippet.where(time_period), :author_id),
- suggestions: distinct_count(::Note.with_suggestions.where(time_period),
- :author_id,
- start: minimum_id(::User),
- finish: maximum_id(::User))
+ snippets: distinct_count(::Snippet.where(time_period), :author_id)
}.tap do |h|
if time_period.present?
h[:merge_requests_users] = merge_requests_users(time_period)
@@ -552,33 +549,11 @@ module Gitlab
user_auth_by_provider: distinct_count_user_auth_by_provider(time_period),
unique_users_all_imports: unique_users_all_imports(time_period),
bulk_imports: {
- gitlab: DEPRECATED_VALUE,
gitlab_v1: count(::BulkImport.where(**time_period, source_type: :gitlab))
},
project_imports: project_imports(time_period),
issue_imports: issue_imports(time_period),
- group_imports: group_imports(time_period),
-
- # Deprecated data to be removed
- projects_imported: {
- total: DEPRECATED_VALUE,
- gitlab_project: DEPRECATED_VALUE,
- gitlab: DEPRECATED_VALUE,
- github: DEPRECATED_VALUE,
- bitbucket: DEPRECATED_VALUE,
- bitbucket_server: DEPRECATED_VALUE,
- gitea: DEPRECATED_VALUE,
- git: DEPRECATED_VALUE,
- manifest: DEPRECATED_VALUE
- },
- issues_imported: {
- jira: DEPRECATED_VALUE,
- fogbugz: DEPRECATED_VALUE,
- phabricator: DEPRECATED_VALUE,
- csv: DEPRECATED_VALUE
- },
- groups_imported: DEPRECATED_VALUE
- # End of deprecated keys
+ group_imports: group_imports(time_period)
}
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/lib/gitlab/usage_data_counters/counter_events/package_events.yml b/lib/gitlab/usage_data_counters/counter_events/package_events.yml
index 21d637e7152..a64d0ff7e24 100644
--- a/lib/gitlab/usage_data_counters/counter_events/package_events.yml
+++ b/lib/gitlab/usage_data_counters/counter_events/package_events.yml
@@ -5,12 +5,8 @@
- i_package_conan_delete_package
- i_package_conan_pull_package
- i_package_conan_push_package
-- i_package_container_delete_package
-- i_package_container_pull_package
-- i_package_container_push_package
- i_package_debian_delete_package
- i_package_debian_pull_package
-- i_package_debian_push_package
- i_package_delete_package
- i_package_delete_package_by_deploy_token
- i_package_delete_package_by_guest
@@ -56,9 +52,6 @@
- i_package_rubygems_delete_package
- i_package_rubygems_pull_package
- i_package_rubygems_push_package
-- i_package_tag_delete_package
-- i_package_tag_pull_package
-- i_package_tag_push_package
- i_package_terraform_module_delete_package
- i_package_terraform_module_pull_package
- i_package_terraform_module_push_package
diff --git a/lib/gitlab/usage_data_counters/hll_redis_counter.rb b/lib/gitlab/usage_data_counters/hll_redis_counter.rb
index 8fc8bb5d344..c6e9db6a314 100644
--- a/lib/gitlab/usage_data_counters/hll_redis_counter.rb
+++ b/lib/gitlab/usage_data_counters/hll_redis_counter.rb
@@ -104,7 +104,7 @@ module Gitlab
events_names = events_for_category(category)
event_results = events_names.each_with_object({}) do |event, hash|
- hash["#{event}_weekly"] = unique_events(**weekly_time_range.merge(event_names: [event]))
+ hash["#{event}_weekly"] = unique_events(**weekly_time_range.merge(event_names: [event])) unless event == "i_package_composer_deploy_token"
hash["#{event}_monthly"] = unique_events(**monthly_time_range.merge(event_names: [event]))
end
diff --git a/lib/gitlab/usage_data_counters/known_events/ci_templates.yml b/lib/gitlab/usage_data_counters/known_events/ci_templates.yml
index d90960b344c..55ed9a42512 100644
--- a/lib/gitlab/usage_data_counters/known_events/ci_templates.yml
+++ b/lib/gitlab/usage_data_counters/known_events/ci_templates.yml
@@ -103,6 +103,10 @@
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
+- name: p_ci_templates_security_dast_on_demand_api_scan
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
- name: p_ci_templates_security_coverage_fuzzing
category: ci_templates
redis_slot: ci_templates
@@ -539,6 +543,10 @@
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
+- name: p_ci_templates_implicit_security_dast_on_demand_api_scan
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
- name: p_ci_templates_implicit_security_coverage_fuzzing
category: ci_templates
redis_slot: ci_templates
diff --git a/lib/gitlab/usage_data_counters/known_events/common.yml b/lib/gitlab/usage_data_counters/known_events/common.yml
index bb98a0b262a..fc610f1e2d6 100644
--- a/lib/gitlab/usage_data_counters/known_events/common.yml
+++ b/lib/gitlab/usage_data_counters/known_events/common.yml
@@ -368,8 +368,18 @@
redis_slot: testing
category: testing
aggregation: weekly
+- name: users_clicking_license_testing_visiting_external_website
+ redis_slot: testing
+ category: testing
+ aggregation: weekly
# Container Security - Network Policies
- name: clusters_using_network_policies_ui
redis_slot: network_policies
category: network_policies
aggregation: weekly
+# Geo group
+- name: g_geo_proxied_requests
+ category: geo
+ redis_slot: geo
+ aggregation: daily
+ feature_flag: track_geo_proxy_events
diff --git a/lib/gitlab/usage_data_counters/known_events/package_events.yml b/lib/gitlab/usage_data_counters/known_events/package_events.yml
index e5031599dd0..debdbd8614f 100644
--- a/lib/gitlab/usage_data_counters/known_events/package_events.yml
+++ b/lib/gitlab/usage_data_counters/known_events/package_events.yml
@@ -15,22 +15,6 @@
category: user_packages
aggregation: weekly
redis_slot: package
-- name: i_package_container_deploy_token
- category: deploy_token_packages
- aggregation: weekly
- redis_slot: package
-- name: i_package_container_user
- category: user_packages
- aggregation: weekly
- redis_slot: package
-- name: i_package_debian_deploy_token
- category: deploy_token_packages
- aggregation: weekly
- redis_slot: package
-- name: i_package_debian_user
- category: user_packages
- aggregation: weekly
- redis_slot: package
- name: i_package_generic_deploy_token
category: deploy_token_packages
aggregation: weekly
@@ -39,14 +23,6 @@
category: user_packages
aggregation: weekly
redis_slot: package
-- name: i_package_golang_deploy_token
- category: deploy_token_packages
- aggregation: weekly
- redis_slot: package
-- name: i_package_golang_user
- category: user_packages
- aggregation: weekly
- redis_slot: package
- name: i_package_helm_deploy_token
category: deploy_token_packages
aggregation: weekly
@@ -95,14 +71,6 @@
category: user_packages
aggregation: weekly
redis_slot: package
-- name: i_package_tag_deploy_token
- category: deploy_token_packages
- aggregation: weekly
- redis_slot: package
-- name: i_package_tag_user
- category: user_packages
- aggregation: weekly
- redis_slot: package
- name: i_package_terraform_module_deploy_token
category: deploy_token_packages
aggregation: weekly
diff --git a/lib/gitlab/usage_data_counters/known_events/quickactions.yml b/lib/gitlab/usage_data_counters/known_events/quickactions.yml
index d831ac02dd1..44f6b42d584 100644
--- a/lib/gitlab/usage_data_counters/known_events/quickactions.yml
+++ b/lib/gitlab/usage_data_counters/known_events/quickactions.yml
@@ -39,6 +39,10 @@
category: quickactions
redis_slot: quickactions
aggregation: weekly
+- name: i_quickactions_clear_health_status
+ category: quickactions
+ redis_slot: quickactions
+ aggregation: weekly
- name: i_quickactions_clone
category: quickactions
redis_slot: quickactions
@@ -263,6 +267,10 @@
category: quickactions
redis_slot: quickactions
aggregation: weekly
+- name: i_quickactions_health_status
+ category: quickactions
+ redis_slot: quickactions
+ aggregation: weekly
- name: i_quickactions_wip
category: quickactions
redis_slot: quickactions
diff --git a/lib/gitlab/utils/sanitize_node_link.rb b/lib/gitlab/utils/sanitize_node_link.rb
index ab5d18e9c8a..b0dfa087fcf 100644
--- a/lib/gitlab/utils/sanitize_node_link.rb
+++ b/lib/gitlab/utils/sanitize_node_link.rb
@@ -8,6 +8,12 @@ module Gitlab
UNSAFE_PROTOCOLS = %w(data javascript vbscript).freeze
ATTRS_TO_SANITIZE = %w(href src data-src data-canonical-src).freeze
+ # sanitize 6.0 requires only a context argument. Do not add any default
+ # arguments to this method.
+ def sanitize_unsafe_links(env)
+ remove_unsafe_links(env)
+ end
+
def remove_unsafe_links(env, remove_invalid_links: true)
node = env[:node]
diff --git a/lib/gitlab/utils/usage_data.rb b/lib/gitlab/utils/usage_data.rb
index e347168f419..6c182f98dd0 100644
--- a/lib/gitlab/utils/usage_data.rb
+++ b/lib/gitlab/utils/usage_data.rb
@@ -169,7 +169,8 @@ module Gitlab
return -1 if args.any?(&:negative?)
args.sum
- rescue StandardError
+ rescue StandardError => error
+ Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error)
FALLBACK
end
@@ -179,7 +180,8 @@ module Gitlab
else
value
end
- rescue StandardError
+ rescue StandardError => error
+ Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error)
fallback
end
@@ -295,13 +297,15 @@ module Gitlab
def redis_usage_counter
yield
- rescue ::Redis::CommandError, Gitlab::UsageDataCounters::BaseCounter::UnknownEvent, Gitlab::UsageDataCounters::HLLRedisCounter::EventError
+ rescue ::Redis::CommandError, Gitlab::UsageDataCounters::BaseCounter::UnknownEvent, Gitlab::UsageDataCounters::HLLRedisCounter::EventError => error
+ Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error)
FALLBACK
end
def redis_usage_data_totals(counter)
counter.totals
- rescue ::Redis::CommandError, Gitlab::UsageDataCounters::BaseCounter::UnknownEvent
+ rescue ::Redis::CommandError, Gitlab::UsageDataCounters::BaseCounter::UnknownEvent => error
+ Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error)
counter.fallback_totals
end
end
diff --git a/lib/gitlab/web_hooks.rb b/lib/gitlab/web_hooks.rb
new file mode 100644
index 00000000000..349c7a020cc
--- /dev/null
+++ b/lib/gitlab/web_hooks.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module WebHooks
+ GITLAB_EVENT_HEADER = 'X-Gitlab-Event'
+ end
+end
diff --git a/lib/gitlab/web_hooks/recursion_detection.rb b/lib/gitlab/web_hooks/recursion_detection.rb
new file mode 100644
index 00000000000..1b5350d4a4e
--- /dev/null
+++ b/lib/gitlab/web_hooks/recursion_detection.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+# This module detects and blocks recursive webhook requests.
+#
+# Recursion can happen when a webhook has been configured to make a call
+# to its own GitLab instance (i.e., its API), and during the execution of
+# the call the webhook is triggered again to create an infinite loop of
+# being triggered.
+#
+# Additionally the module blocks a webhook once the number of requests to
+# the instance made by a series of webhooks triggering other webhooks reaches
+# a limit.
+#
+# Blocking recursive webhooks allows GitLab to continue to support workflows
+# that use webhooks to call the API non-recursively, or do not go on to
+# trigger an unreasonable number of other webhooks.
+module Gitlab
+ module WebHooks
+ module RecursionDetection
+ COUNT_LIMIT = 100
+ TOUCH_CACHE_TTL = 30.minutes
+
+ class << self
+ def set_from_headers(headers)
+ uuid = headers[UUID::HEADER]
+
+ return unless uuid
+
+ set_request_uuid(uuid)
+ end
+
+ def set_request_uuid(uuid)
+ UUID.instance.request_uuid = uuid
+ end
+
+ # Before a webhook is executed, `.register!` should be called.
+ # Adds the webhook ID to a cache (see `#cache_key_for_hook` for
+ # details of the cache).
+ def register!(hook)
+ cache_key = cache_key_for_hook(hook)
+
+ ::Gitlab::Redis::SharedState.with do |redis|
+ redis.multi do
+ redis.sadd(cache_key, hook.id)
+ redis.expire(cache_key, TOUCH_CACHE_TTL)
+ end
+ end
+ end
+
+ # Returns true if the webhook ID is present in the cache, or if the
+ # number of IDs in the cache exceeds the limit (see
+ # `#cache_key_for_hook` for details of the cache).
+ def block?(hook)
+ # If a request UUID has not been set then we know the request was not
+ # made by a webhook, and no recursion is possible.
+ return false unless UUID.instance.request_uuid
+
+ cache_key = cache_key_for_hook(hook)
+
+ ::Gitlab::Redis::SharedState.with do |redis|
+ redis.sismember(cache_key, hook.id) ||
+ redis.scard(cache_key) >= COUNT_LIMIT
+ end
+ end
+
+ def header(hook)
+ UUID.instance.header(hook)
+ end
+
+ def to_log(hook)
+ {
+ uuid: UUID.instance.uuid_for_hook(hook),
+ ids: ::Gitlab::Redis::SharedState.with { |redis| redis.smembers(cache_key_for_hook(hook)).map(&:to_i) }
+ }
+ end
+
+ private
+
+ # Returns a cache key scoped to a UUID.
+ #
+ # The particular UUID will be either:
+ #
+ # - A UUID that was recycled from the request headers if the request was made by a webhook.
+ # - a new UUID initialized for the webhook.
+ #
+ # This means that cycles of webhooks that are triggered from other webhooks
+ # will share the same cache, and other webhooks will use a new cache.
+ def cache_key_for_hook(hook)
+ [:webhook_recursion_detection, UUID.instance.uuid_for_hook(hook)].join(':')
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/web_hooks/recursion_detection/uuid.rb b/lib/gitlab/web_hooks/recursion_detection/uuid.rb
new file mode 100644
index 00000000000..9c52399818d
--- /dev/null
+++ b/lib/gitlab/web_hooks/recursion_detection/uuid.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module WebHooks
+ module RecursionDetection
+ class UUID
+ HEADER = "#{::Gitlab::WebHooks::GITLAB_EVENT_HEADER}-UUID"
+
+ include Singleton
+
+ attr_accessor :request_uuid
+
+ def initialize
+ self.new_uuids_for_hooks = {}
+ end
+
+ class << self
+ # Back the Singleton with RequestStore so it is isolated to this request.
+ def instance
+ Gitlab::SafeRequestStore[:web_hook_recursion_detection_uuid] ||= new
+ end
+ end
+
+ # Returns a UUID, which will be either:
+ #
+ # - The UUID that was recycled from the request headers if the request was made by a webhook.
+ # - A new UUID initialized for the webhook.
+ def uuid_for_hook(hook)
+ request_uuid || new_uuid_for_hook(hook)
+ end
+
+ def header(hook)
+ { HEADER => uuid_for_hook(hook) }
+ end
+
+ private
+
+ attr_accessor :new_uuids_for_hooks
+
+ def new_uuid_for_hook(hook)
+ new_uuids_for_hooks[hook.id] ||= SecureRandom.uuid
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/workhorse.rb b/lib/gitlab/workhorse.rb
index 3a905a2e1c5..19d30daa577 100644
--- a/lib/gitlab/workhorse.rb
+++ b/lib/gitlab/workhorse.rb
@@ -203,11 +203,11 @@ module Gitlab
end
def verify_api_request!(request_headers)
- decode_jwt(request_headers[INTERNAL_API_REQUEST_HEADER])
+ decode_jwt_with_issuer(request_headers[INTERNAL_API_REQUEST_HEADER])
end
- def decode_jwt(encoded_message)
- decode_jwt_for_issuer('gitlab-workhorse', encoded_message)
+ def decode_jwt_with_issuer(encoded_message)
+ decode_jwt(encoded_message, issuer: 'gitlab-workhorse')
end
def secret_path
diff --git a/lib/gitlab_edition.rb b/lib/gitlab_edition.rb
new file mode 100644
index 00000000000..6eb6b52c357
--- /dev/null
+++ b/lib/gitlab_edition.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require 'pathname'
+
+module GitlabEdition
+ def self.root
+ Pathname.new(File.expand_path('..', __dir__))
+ end
+
+ def self.extensions
+ if jh?
+ %w[ee jh]
+ elsif ee?
+ %w[ee]
+ else
+ %w[]
+ end
+ end
+
+ def self.ee?
+ @is_ee ||=
+ # We use this method when the Rails environment is not loaded. This
+ # means that checking the presence of the License class could result in
+ # this method returning `false`, even for an EE installation.
+ #
+ # The `FOSS_ONLY` is always `string` or `nil`
+ # Thus the nil or empty string will result
+ # in using default value: false
+ #
+ # The behavior needs to be synchronised with
+ # config/helpers/is_ee_env.js
+ root.join('ee/app/models/license.rb').exist? &&
+ !%w[true 1].include?(ENV['FOSS_ONLY'].to_s)
+ end
+
+ def self.jh?
+ @is_jh ||=
+ ee? &&
+ root.join('jh').exist? &&
+ !%w[true 1].include?(ENV['EE_ONLY'].to_s)
+ end
+
+ def self.ee
+ yield if ee?
+ end
+
+ def self.jh
+ yield if jh?
+ end
+end
diff --git a/lib/sidebars/groups/menus/ci_cd_menu.rb b/lib/sidebars/groups/menus/ci_cd_menu.rb
index f5bce57f496..a1f98b918e6 100644
--- a/lib/sidebars/groups/menus/ci_cd_menu.rb
+++ b/lib/sidebars/groups/menus/ci_cd_menu.rb
@@ -34,10 +34,8 @@ module Sidebars
)
end
- # TODO Proper policies, such as `read_group_runners`, should be implemented per
- # See https://gitlab.com/gitlab-org/gitlab/-/issues/334802
def show_runners?
- can?(context.current_user, :admin_group, context.group) &&
+ can?(context.current_user, :read_group_runners, context.group) &&
Feature.enabled?(:runner_list_group_view_vue_ui, context.group, default_enabled: :yaml)
end
end
diff --git a/lib/sidebars/groups/menus/settings_menu.rb b/lib/sidebars/groups/menus/settings_menu.rb
index f0239ca6a1a..810b467ed2d 100644
--- a/lib/sidebars/groups/menus/settings_menu.rb
+++ b/lib/sidebars/groups/menus/settings_menu.rb
@@ -10,6 +10,7 @@ module Sidebars
add_item(general_menu_item)
add_item(integrations_menu_item)
+ add_item(access_tokens_menu_item)
add_item(group_projects_menu_item)
add_item(repository_menu_item)
add_item(ci_cd_menu_item)
@@ -56,6 +57,19 @@ module Sidebars
)
end
+ def access_tokens_menu_item
+ unless can?(context.current_user, :read_resource_access_tokens, context.group)
+ return ::Sidebars::NilMenuItem.new(item_id: :access_tokens)
+ end
+
+ ::Sidebars::MenuItem.new(
+ title: _('Access Tokens'),
+ link: group_settings_access_tokens_path(context.group),
+ active_routes: { path: 'access_tokens#index' },
+ item_id: :access_tokens
+ )
+ end
+
def group_projects_menu_item
::Sidebars::MenuItem.new(
title: _('Projects'),
diff --git a/lib/sidebars/projects/menus/infrastructure_menu.rb b/lib/sidebars/projects/menus/infrastructure_menu.rb
index 1018bdd545b..060a5be5f57 100644
--- a/lib/sidebars/projects/menus/infrastructure_menu.rb
+++ b/lib/sidebars/projects/menus/infrastructure_menu.rb
@@ -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] },
+ active_routes: { controller: [:google_cloud, :service_accounts, :deployments] },
item_id: :google_cloud
)
end
diff --git a/lib/sidebars/projects/menus/issues_menu.rb b/lib/sidebars/projects/menus/issues_menu.rb
index 3774bec2f13..51eea3d850d 100644
--- a/lib/sidebars/projects/menus/issues_menu.rb
+++ b/lib/sidebars/projects/menus/issues_menu.rb
@@ -8,7 +8,7 @@ module Sidebars
override :configure_menu_items
def configure_menu_items
- return unless can?(context.current_user, :read_issue, context.project)
+ return false unless show_issues_menu_items?
add_item(list_menu_item)
add_item(boards_menu_item)
@@ -70,6 +70,10 @@ module Sidebars
private
+ def show_issues_menu_items?
+ can?(context.current_user, :read_issue, context.project)
+ end
+
def list_menu_item
::Sidebars::MenuItem.new(
title: _('List'),
diff --git a/lib/tasks/gitlab/backup.rake b/lib/tasks/gitlab/backup.rake
index cc10d73f76a..0bca63a64f5 100644
--- a/lib/tasks/gitlab/backup.rake
+++ b/lib/tasks/gitlab/backup.rake
@@ -9,14 +9,9 @@ namespace :gitlab do
task create: :gitlab_environment do
warn_user_is_not_gitlab
- Rake::Task['gitlab:backup:db:create'].invoke
- Rake::Task['gitlab:backup:repo:create'].invoke
- Rake::Task['gitlab:backup:uploads:create'].invoke
- Rake::Task['gitlab:backup:builds:create'].invoke
- Rake::Task['gitlab:backup:artifacts:create'].invoke
- Rake::Task['gitlab:backup:pages:create'].invoke
- Rake::Task['gitlab:backup:lfs:create'].invoke
- Rake::Task['gitlab:backup:registry:create'].invoke
+ %w(db repo uploads builds artifacts pages lfs terraform_state registry packages).each do |type|
+ Rake::Task["gitlab:backup:#{type}:create"].invoke
+ end
backup = Backup::Manager.new(progress)
backup.write_info
@@ -83,7 +78,9 @@ namespace :gitlab do
Rake::Task['gitlab:backup:artifacts:restore'].invoke unless backup.skipped?('artifacts')
Rake::Task['gitlab:backup:pages:restore'].invoke unless backup.skipped?('pages')
Rake::Task['gitlab:backup:lfs:restore'].invoke unless backup.skipped?('lfs')
+ Rake::Task['gitlab:backup:terraform_state:restore'].invoke unless backup.skipped?('terraform_state')
Rake::Task['gitlab:backup:registry:restore'].invoke unless backup.skipped?('registry')
+ Rake::Task['gitlab:backup:packages:restore'].invoke unless backup.skipped?('packages')
Rake::Task['gitlab:shell:setup'].invoke
Rake::Task['cache:clear'].invoke
@@ -133,8 +130,12 @@ namespace :gitlab do
if ENV["SKIP"] && ENV["SKIP"].include?("db")
puts_time "[SKIPPED]".color(:cyan)
else
- Backup::Database.new(progress).dump
- puts_time "done".color(:green)
+ begin
+ Backup::Database.new(progress).dump
+ puts_time "done".color(:green)
+ rescue Backup::DatabaseBackupError => e
+ progress.puts "#{e.message}"
+ end
end
end
@@ -166,8 +167,12 @@ namespace :gitlab do
if ENV["SKIP"] && ENV["SKIP"].include?("builds")
puts_time "[SKIPPED]".color(:cyan)
else
- Backup::Builds.new(progress).dump
- puts_time "done".color(:green)
+ begin
+ Backup::Builds.new(progress).dump
+ puts_time "done".color(:green)
+ rescue Backup::FileBackupError => e
+ progress.puts "#{e.message}"
+ end
end
end
@@ -185,8 +190,12 @@ namespace :gitlab do
if ENV["SKIP"] && ENV["SKIP"].include?("uploads")
puts_time "[SKIPPED]".color(:cyan)
else
- Backup::Uploads.new(progress).dump
- puts_time "done".color(:green)
+ begin
+ Backup::Uploads.new(progress).dump
+ puts_time "done".color(:green)
+ rescue Backup::FileBackupError => e
+ progress.puts "#{e.message}"
+ end
end
end
@@ -204,8 +213,12 @@ namespace :gitlab do
if ENV["SKIP"] && ENV["SKIP"].include?("artifacts")
puts_time "[SKIPPED]".color(:cyan)
else
- Backup::Artifacts.new(progress).dump
- puts_time "done".color(:green)
+ begin
+ Backup::Artifacts.new(progress).dump
+ puts_time "done".color(:green)
+ rescue Backup::FileBackupError => e
+ progress.puts "#{e.message}"
+ end
end
end
@@ -223,8 +236,12 @@ namespace :gitlab do
if ENV["SKIP"] && ENV["SKIP"].include?("pages")
puts_time "[SKIPPED]".color(:cyan)
else
- Backup::Pages.new(progress).dump
- puts_time "done".color(:green)
+ begin
+ Backup::Pages.new(progress).dump
+ puts_time "done".color(:green)
+ rescue Backup::FileBackupError => e
+ progress.puts "#{e.message}"
+ end
end
end
@@ -242,8 +259,12 @@ namespace :gitlab do
if ENV["SKIP"] && ENV["SKIP"].include?("lfs")
puts_time "[SKIPPED]".color(:cyan)
else
- Backup::Lfs.new(progress).dump
- puts_time "done".color(:green)
+ begin
+ Backup::Lfs.new(progress).dump
+ puts_time "done".color(:green)
+ rescue Backup::FileBackupError => e
+ progress.puts "#{e.message}"
+ end
end
end
@@ -254,6 +275,25 @@ namespace :gitlab do
end
end
+ namespace :terraform_state do
+ task create: :gitlab_environment do
+ puts_time "Dumping terraform states ... ".color(:blue)
+
+ if ENV["SKIP"] && ENV["SKIP"].include?("terraform_state")
+ puts_time "[SKIPPED]".color(:cyan)
+ else
+ Backup::TerraformState.new(progress).dump
+ puts_time "done".color(:green)
+ end
+ end
+
+ task restore: :gitlab_environment do
+ puts_time "Restoring terraform states ... ".color(:blue)
+ Backup::TerraformState.new(progress).restore
+ puts_time "done".color(:green)
+ end
+ end
+
namespace :registry do
task create: :gitlab_environment do
puts_time "Dumping container registry images ... ".color(:blue)
@@ -262,8 +302,12 @@ namespace :gitlab do
if ENV["SKIP"] && ENV["SKIP"].include?("registry")
puts_time "[SKIPPED]".color(:cyan)
else
- Backup::Registry.new(progress).dump
- puts_time "done".color(:green)
+ begin
+ Backup::Registry.new(progress).dump
+ puts_time "done".color(:green)
+ rescue Backup::FileBackupError => e
+ progress.puts "#{e.message}"
+ end
end
else
puts_time "[DISABLED]".color(:cyan)
@@ -282,6 +326,25 @@ namespace :gitlab do
end
end
+ namespace :packages do
+ task create: :gitlab_environment do
+ puts_time "Dumping packages ... ".color(:blue)
+
+ if ENV['SKIP'] && ENV['SKIP'].include?('packages')
+ puts_time "[SKIPPED]".color(:cyan)
+ else
+ Backup::Packages.new(progress).dump
+ puts_time "done".color(:green)
+ end
+ end
+
+ task restore: :gitlab_environment do
+ puts_time "Restoring packages ...".color(:blue)
+ Backup::Packages.new(progress).restore
+ puts_time "done".color(:green)
+ end
+ end
+
def puts_time(msg)
progress.puts "#{Time.now} -- #{msg}"
Gitlab::BackupLogger.info(message: "#{Rainbow.uncolor(msg)}")
@@ -302,7 +365,7 @@ namespace :gitlab do
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, parallel: max_concurrency, parallel_storage: max_storage_concurrency)
+ Backup::GitalyBackup.new(progress, max_parallelism: max_concurrency, storage_parallelism: max_storage_concurrency)
else
Backup::GitalyRpcBackup.new(progress)
end
diff --git a/lib/tasks/gitlab/cleanup.rake b/lib/tasks/gitlab/cleanup.rake
index 8f033a41e3d..f908a7606fa 100644
--- a/lib/tasks/gitlab/cleanup.rake
+++ b/lib/tasks/gitlab/cleanup.rake
@@ -100,15 +100,13 @@ namespace :gitlab do
namespace :sessions do
desc "GitLab | Cleanup | Sessions | Clean ActiveSession lookup keys"
task active_sessions_lookup_keys: :gitlab_environment do
- use_redis_session_store = Gitlab::Utils.to_boolean(ENV['GITLAB_USE_REDIS_SESSIONS_STORE'], default: true)
- redis_store_class = use_redis_session_store ? Gitlab::Redis::Sessions : Gitlab::Redis::SharedState
session_key_pattern = "#{Gitlab::Redis::Sessions::USER_SESSIONS_LOOKUP_NAMESPACE}:*"
last_save_check = Time.at(0)
wait_time = 10.seconds
cursor = 0
total_users_scanned = 0
- redis_store_class.with do |redis|
+ Gitlab::Redis::Sessions.with do |redis|
begin
cursor, keys = redis.scan(cursor, match: session_key_pattern)
total_users_scanned += keys.count
diff --git a/lib/tasks/gitlab/db.rake b/lib/tasks/gitlab/db.rake
index 9e733fc3a0f..efb0e1ef1e1 100644
--- a/lib/tasks/gitlab/db.rake
+++ b/lib/tasks/gitlab/db.rake
@@ -170,7 +170,7 @@ namespace :gitlab do
# the `ActiveRecord::Base.connection` might be switched to another one
# This is due to `if should_reconnect`:
# https://github.com/rails/rails/blob/a81aeb63a007ede2fe606c50539417dada9030c7/activerecord/lib/active_record/railties/databases.rake#L622
- ActiveRecord::Base.establish_connection :main
+ ActiveRecord::Base.establish_connection :main # rubocop: disable Database/EstablishConnection
Rake::Task['gitlab:db:create_dynamic_partitions'].invoke
end
diff --git a/lib/tasks/gitlab/docs/compile_deprecations.rake b/lib/tasks/gitlab/docs/compile_deprecations.rake
index dc9788cb0b2..4ac68a9f850 100644
--- a/lib/tasks/gitlab/docs/compile_deprecations.rake
+++ b/lib/tasks/gitlab/docs/compile_deprecations.rake
@@ -4,19 +4,19 @@ namespace :gitlab do
namespace :docs do
desc "Generate deprecation list from individual files"
task :compile_deprecations do
- require_relative '../../../../tooling/deprecations/docs'
-
- File.write(Deprecations::Docs.path, Deprecations::Docs.render)
-
- puts "Deprecations compiled to #{Deprecations::Docs.path}"
+ require_relative '../../../../tooling/docs/deprecation_handling'
+ path = Rails.root.join("doc/update/deprecations.md")
+ File.write(path, Docs::DeprecationHandling.new('deprecation').render)
+ puts "Deprecations compiled to #{path}"
end
desc "Check that the deprecation doc is up to date"
task :check_deprecations do
- require_relative '../../../../tooling/deprecations/docs'
+ require_relative '../../../../tooling/docs/deprecation_handling'
+ path = Rails.root.join("doc/update/deprecations.md")
- contents = Deprecations::Docs.render
- doc = File.read(Deprecations::Docs.path)
+ contents = Docs::DeprecationHandling.new('deprecation').render
+ doc = File.read(path)
if doc == contents
puts "Deprecations doc is up to date."
@@ -25,5 +25,28 @@ namespace :gitlab do
abort
end
end
+
+ desc "Generate removal list from individual files"
+ task :compile_removals do
+ require_relative '../../../../tooling/docs/deprecation_handling'
+ path = Rails.root.join("doc/update/removals.md")
+ File.write(path, Docs::DeprecationHandling.new('removal').render)
+ puts "Removals compiled to #{path}"
+ end
+
+ desc "Check that the removal doc is up to date"
+ task :check_removals do
+ require_relative '../../../../tooling/docs/deprecation_handling'
+ path = Rails.root.join("doc/update/removals.md")
+ contents = Docs::DeprecationHandling.new('removal').render
+ doc = File.read(path)
+
+ if doc == contents
+ puts "Removals doc is up to date."
+ else
+ format_output('Removals doc is outdated! You (or your technical writer) can update it by running `bin/rake gitlab:docs:compile_removals`.')
+ abort
+ end
+ end
end
end
diff --git a/lib/tasks/gitlab/docs/redirect.rake b/lib/tasks/gitlab/docs/redirect.rake
index 123a4775605..e7ece9e0fdd 100644
--- a/lib/tasks/gitlab/docs/redirect.rake
+++ b/lib/tasks/gitlab/docs/redirect.rake
@@ -51,7 +51,7 @@ namespace :gitlab do
post.puts "remove_date: '#{date}'"
post.puts '---'
post.puts
- post.puts "This file was moved to [another location](#{new_path})."
+ 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 -->"
diff --git a/lib/tasks/gitlab/gitaly.rake b/lib/tasks/gitlab/gitaly.rake
index b01a7902bf2..18c68615637 100644
--- a/lib/tasks/gitlab/gitaly.rake
+++ b/lib/tasks/gitlab/gitaly.rake
@@ -2,41 +2,6 @@
namespace :gitlab do
namespace :gitaly do
- desc 'Installs gitaly for running tests within gitlab-development-kit'
- task :test_install, [:dir, :storage_path, :repo] => :gitlab_environment do |t, args|
- inside_gdk = Rails.env.test? && File.exist?(Rails.root.join('../GDK_ROOT'))
-
- if ENV['FORCE_GITALY_INSTALL'] || !inside_gdk
- Rake::Task["gitlab:gitaly:install"].invoke(*args)
-
- next
- end
-
- gdk_gitaly_dir = ENV.fetch('GDK_GITALY', Rails.root.join('../gitaly'))
-
- # Our test setup expects a git repo, so clone rather than copy
- clone_repo(gdk_gitaly_dir, args.dir, clone_opts: %w[--depth 1]) unless Dir.exist?(args.dir)
-
- # We assume the GDK gitaly already compiled binaries
- build_dir = File.join(gdk_gitaly_dir, '_build')
- FileUtils.cp_r(build_dir, args.dir)
-
- # We assume the GDK gitaly already ran bundle install
- bundle_dir = File.join(gdk_gitaly_dir, 'ruby', '.bundle')
- FileUtils.cp_r(bundle_dir, File.join(args.dir, 'ruby'))
-
- # For completeness we copy this for gitaly's make target
- ruby_bundle_file = File.join(gdk_gitaly_dir, '.ruby-bundle')
- FileUtils.cp_r(ruby_bundle_file, args.dir)
-
- gitaly_binary = File.join(build_dir, 'bin', 'gitaly')
- warn_gitaly_out_of_date!(gitaly_binary, Gitlab::GitalyClient.expected_server_version)
- rescue Errno::ENOENT => e
- puts "Could not copy files, did you run `gdk update`? Error: #{e.message}"
-
- raise
- end
-
desc 'GitLab | Gitaly | Clone and checkout gitaly'
task :clone, [:dir, :storage_path, :repo] => :gitlab_environment do |t, args|
warn_user_is_not_gitlab
@@ -60,9 +25,6 @@ Usage: rake "gitlab:gitaly:install[/installation/dir,/storage/path]")
storage_paths = { 'default' => args.storage_path }
Gitlab::SetupHelper::Gitaly.create_configuration(args.dir, storage_paths)
- # In CI we run scripts/gitaly-test-build
- next if ENV['CI'].present?
-
Dir.chdir(args.dir) do
Bundler.with_original_env do
env = { "RUBYOPT" => nil, "BUNDLE_GEMFILE" => nil }
diff --git a/lib/tasks/gitlab/seed/group_seed.rake b/lib/tasks/gitlab/seed/group_seed.rake
index a9a350fb6c3..491cf782985 100644
--- a/lib/tasks/gitlab/seed/group_seed.rake
+++ b/lib/tasks/gitlab/seed/group_seed.rake
@@ -125,7 +125,7 @@ class GroupSeeder
name: FFaker::Name.name,
email: FFaker::Internet.email,
confirmed_at: DateTime.now,
- password: Devise.friendly_token
+ password: Gitlab::Password.test_default
)
end
diff --git a/lib/version_check.rb b/lib/version_check.rb
index e5a4c244c7a..2d132001f54 100644
--- a/lib/version_check.rb
+++ b/lib/version_check.rb
@@ -16,14 +16,6 @@ class VersionCheck
{ "REFERER": Gitlab.config.gitlab.url }
end
- # This is temporary and will be removed when the new UI is hooked up
- # to the version_check.json endpoint.
- def self.image_url
- encoded_data = Base64.urlsafe_encode64(data.to_json)
-
- "#{host}/check.svg?gitlab_info=#{encoded_data}"
- end
-
def self.url
encoded_data = Base64.urlsafe_encode64(data.to_json)
diff --git a/locale/am_ET/gitlab.po b/locale/am_ET/gitlab.po
index 5018225aa3a..9043877aba8 100644
--- a/locale/am_ET/gitlab.po
+++ b/locale/am_ET/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: am\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:59\n"
+"PO-Revision-Date: 2022-01-06 17:24\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
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; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/ar_SA/gitlab.po b/locale/ar_SA/gitlab.po
index c4408571f2f..4ce7194d0fd 100644
--- a/locale/ar_SA/gitlab.po
+++ b/locale/ar_SA/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ar\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:57\n"
+"PO-Revision-Date: 2022-01-06 17:21\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -871,7 +871,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -1150,6 +1150,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1387,6 +1390,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1507,6 +1516,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1582,6 +1594,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -2008,6 +2023,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -2254,6 +2272,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -2266,12 +2293,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -2329,6 +2365,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -2353,6 +2419,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -2458,7 +2527,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2884,6 +2953,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -3160,7 +3238,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -3445,6 +3523,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3835,6 +3916,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -4039,6 +4123,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -4066,9 +4153,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -4249,6 +4333,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -4258,6 +4345,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -4411,6 +4501,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4768,9 +4864,15 @@ msgstr[5] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4801,6 +4903,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4810,6 +4915,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4834,6 +4948,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4861,6 +4978,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4897,7 +5017,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -5071,9 +5191,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -5221,6 +5338,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5626,9 +5746,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5878,9 +5995,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5911,13 +6025,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5929,7 +6040,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5941,9 +6055,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -6133,7 +6253,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -6502,7 +6622,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -6511,6 +6634,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6550,6 +6676,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -7258,7 +7387,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -7528,9 +7657,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7741,6 +7867,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7759,9 +7888,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7915,12 +8050,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7933,6 +8083,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7948,9 +8104,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7996,12 +8158,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -8077,6 +8248,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -8095,12 +8269,30 @@ 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 ""
+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[4] ""
+msgstr[5] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -8110,6 +8302,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -9301,6 +9496,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9730,6 +9934,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9823,6 +10030,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -10054,12 +10264,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -10090,9 +10306,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -10432,9 +10645,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -10465,6 +10675,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -10507,9 +10720,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -10519,13 +10729,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10705,15 +10918,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10723,15 +10954,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10882,15 +11122,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11587,6 +11818,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11866,6 +12100,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11899,15 +12136,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -12052,6 +12283,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -12076,7 +12310,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -12085,6 +12319,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12919,15 +13156,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -13072,6 +13309,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -13207,7 +13447,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -13246,6 +13486,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -14191,6 +14434,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -14236,9 +14482,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -14392,9 +14635,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -14479,6 +14719,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14668,9 +14911,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14863,7 +15103,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -15583,9 +15823,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15916,6 +16153,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16777,9 +17017,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16867,6 +17104,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -17056,9 +17296,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -17185,6 +17422,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -17287,9 +17527,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -17362,6 +17611,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -17401,6 +17653,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -17434,6 +17689,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -17458,7 +17725,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -17467,7 +17734,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -17509,6 +17776,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -17536,12 +17806,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17656,6 +17932,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17710,6 +17989,9 @@ 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 ""
+
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 ""
@@ -19642,6 +19924,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19891,9 +20176,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19996,9 +20278,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -20110,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20758,7 +21034,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -21214,6 +21490,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -22003,7 +22285,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22759,10 +23041,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22861,6 +23143,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -23488,6 +23773,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -23695,6 +23983,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23908,6 +24229,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -24136,6 +24460,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -24559,6 +24886,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -24571,7 +24901,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24994,6 +25324,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -25012,12 +25348,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -25057,12 +25399,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -25087,18 +25438,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -25108,9 +25474,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -25273,6 +25636,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25816,9 +26182,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -26008,9 +26371,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -26110,6 +26479,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -26191,12 +26563,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -26428,6 +26794,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -26647,9 +27016,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26926,6 +27292,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26938,6 +27310,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -27133,9 +27508,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -27487,6 +27859,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -27544,6 +27919,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -27628,6 +28009,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27922,6 +28306,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -28048,6 +28474,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -28300,19 +28729,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -28468,6 +28894,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28852,9 +29287,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28867,9 +29299,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28894,9 +29323,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28978,6 +29404,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -29023,9 +29452,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -29068,6 +29503,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -29083,6 +29521,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -29311,6 +29752,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -29500,9 +29947,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -29545,6 +29989,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29875,10 +30367,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -30586,6 +31078,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -30595,6 +31090,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30799,9 +31300,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30823,6 +31321,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30874,19 +31378,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30940,6 +31447,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30985,6 +31495,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30994,7 +31507,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -31063,7 +31579,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -31081,6 +31597,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31342,6 +31861,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -31363,9 +31885,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -31690,6 +32209,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -31762,6 +32284,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31816,6 +32341,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31900,9 +32428,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -32101,6 +32626,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -32113,6 +32641,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -32188,6 +32719,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -32341,6 +32875,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -32692,6 +33229,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32848,6 +33391,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -33559,6 +34105,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -34003,9 +34552,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -34402,6 +34948,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34837,6 +35389,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -35113,9 +35683,33 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -35146,6 +35740,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -35158,6 +35755,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -35194,12 +35794,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -35497,6 +36106,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -35623,9 +36235,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -35635,9 +36244,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -35710,7 +36316,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35965,9 +36571,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -36313,6 +36916,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -36325,9 +36931,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -36352,6 +36955,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -36466,6 +37072,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -36631,6 +37240,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -37351,6 +37963,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -37417,6 +38032,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -37591,6 +38239,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -37717,15 +38368,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -37750,9 +38392,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -38380,9 +39019,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -39274,16 +39910,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -39325,6 +39961,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -39352,6 +39991,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -39385,6 +40027,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -39481,6 +40129,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -39562,12 +40213,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39595,6 +40258,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39664,9 +40330,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -39682,21 +40357,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -39706,6 +40393,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -39730,6 +40420,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -39853,6 +40552,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39940,6 +40642,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39976,6 +40684,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -40033,6 +40750,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -40069,6 +40795,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -40078,9 +40807,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40924,6 +41650,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -41113,6 +41845,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -41404,6 +42142,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -41656,6 +42397,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -41686,7 +42430,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -41734,8 +42478,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41833,8 +42577,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -42004,6 +42748,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42472,9 +43219,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -42838,6 +43582,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42937,9 +43684,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/as_IN/gitlab.po b/locale/as_IN/gitlab.po
index b167d8d54dc..ceb49d0e7f6 100644
--- a/locale/as_IN/gitlab.po
+++ b/locale/as_IN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: as\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 19:00\n"
+"PO-Revision-Date: 2022-01-06 17:24\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/az_AZ/gitlab.po b/locale/az_AZ/gitlab.po
index 72868deab35..82c56f0dc55 100644
--- a/locale/az_AZ/gitlab.po
+++ b/locale/az_AZ/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: az\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:57\n"
+"PO-Revision-Date: 2022-01-06 17:21\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/ba_RU/gitlab.po b/locale/ba_RU/gitlab.po
index 84e06ac64c3..a39c3bf5ce9 100644
--- a/locale/ba_RU/gitlab.po
+++ b/locale/ba_RU/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ba\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 19:00\n"
+"PO-Revision-Date: 2022-01-06 17:24\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -486,7 +486,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -760,6 +760,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -947,6 +950,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1062,6 +1071,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1127,6 +1139,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1428,6 +1443,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1674,6 +1692,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1686,12 +1713,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1749,6 +1785,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1773,6 +1839,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1878,7 +1947,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2304,6 +2373,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2580,7 +2658,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2865,6 +2943,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3255,6 +3336,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3459,6 +3543,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3486,9 +3573,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3669,6 +3753,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3678,6 +3765,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3826,6 +3916,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4148,9 +4244,15 @@ msgstr[0] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4181,6 +4283,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4190,6 +4295,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4214,6 +4328,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4241,6 +4358,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4277,7 +4397,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4446,9 +4566,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4596,6 +4713,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -4991,9 +5111,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5243,9 +5360,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5276,13 +5390,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5294,7 +5405,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5306,9 +5420,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5493,7 +5613,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5852,7 +5972,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5861,6 +5984,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -5900,6 +6026,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6603,7 +6732,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6863,9 +6992,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7076,6 +7202,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7094,9 +7223,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7250,12 +7385,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7268,6 +7418,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7283,9 +7439,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7331,12 +7493,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7412,6 +7583,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7430,12 +7604,25 @@ 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 ""
+msgid "ClusterAgents|There's no activity from the past day"
+msgid_plural "ClusterAgents|There's no activity from the past %d days"
+msgstr[0] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7445,6 +7632,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8631,6 +8821,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9050,6 +9249,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9138,6 +9340,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9369,12 +9574,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9405,9 +9616,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9747,9 +9955,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9780,6 +9985,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9822,9 +10030,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9834,13 +10039,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10020,15 +10228,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10038,15 +10264,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10197,15 +10432,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -10887,6 +11113,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11166,6 +11395,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11199,15 +11431,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11337,6 +11563,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11361,7 +11590,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11370,6 +11599,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12164,15 +12396,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12312,6 +12544,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12447,7 +12682,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12486,6 +12721,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13426,6 +13664,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13471,9 +13712,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13627,9 +13865,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13714,6 +13949,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -13898,9 +14136,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14093,7 +14328,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14798,9 +15033,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15131,6 +15363,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -15992,9 +16227,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16082,6 +16314,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16271,9 +16506,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16400,6 +16632,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16502,9 +16737,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16577,6 +16821,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16616,6 +16863,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16649,6 +16899,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16673,7 +16935,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16682,7 +16944,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16724,6 +16986,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16751,12 +17016,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -16871,6 +17142,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -16925,6 +17199,9 @@ 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 ""
+
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 ""
@@ -18827,6 +19104,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19076,9 +19356,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19181,9 +19458,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19295,9 +19569,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -19943,7 +20214,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20394,6 +20665,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21148,7 +21425,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -21904,10 +22181,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22006,6 +22283,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22623,6 +22903,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22825,6 +23108,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23038,6 +23354,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23261,6 +23580,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23679,6 +24001,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23691,7 +24016,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24094,6 +24419,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24112,12 +24443,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24157,12 +24494,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24187,18 +24533,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24208,9 +24569,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24368,6 +24726,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -24906,9 +25267,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25098,9 +25456,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25200,6 +25564,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25281,12 +25648,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25518,6 +25879,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25737,9 +26101,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26016,6 +26377,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26028,6 +26395,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26223,9 +26593,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26577,6 +26944,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26634,6 +27004,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26718,6 +27094,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27012,6 +27391,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27138,6 +27559,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27390,19 +27814,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27558,6 +27979,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -27942,9 +28372,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27957,9 +28384,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -27984,9 +28408,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28068,6 +28489,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28113,9 +28537,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28158,6 +28588,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28173,6 +28606,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28401,6 +28837,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28585,9 +29027,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28630,6 +29069,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -28955,10 +29442,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29636,6 +30123,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29645,6 +30135,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -29839,9 +30335,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -29863,6 +30356,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -29914,19 +30413,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -29980,6 +30482,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30025,6 +30530,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30034,7 +30542,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30103,7 +30614,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30121,6 +30632,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30382,6 +30896,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30403,9 +30920,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30675,6 +31189,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30747,6 +31264,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -30801,6 +31321,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -30885,9 +31408,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31086,6 +31606,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31098,6 +31621,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31173,6 +31699,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31326,6 +31855,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31677,6 +32209,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -31833,6 +32371,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32529,6 +33070,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -32973,9 +33517,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33372,6 +33913,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -33807,6 +34354,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34073,9 +34638,23 @@ msgid "Terraform|%{number} Terraform report was generated in your pipelines"
msgid_plural "Terraform|%{number} Terraform reports were generated in your pipelines"
msgstr[0] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34106,6 +34685,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34118,6 +34700,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34154,12 +34739,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34442,6 +35036,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34563,9 +35160,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34575,9 +35169,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34650,7 +35241,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -34905,9 +35496,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35253,6 +35841,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35265,9 +35856,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35292,6 +35880,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35406,6 +35997,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35571,6 +36165,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36281,6 +36878,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36347,6 +36947,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36521,6 +37154,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36642,15 +37278,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36675,9 +37302,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37305,9 +37929,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38199,16 +38820,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38250,6 +38871,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38272,6 +38896,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38300,6 +38927,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38391,6 +39024,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38472,12 +39108,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38505,6 +39153,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38574,9 +39225,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38592,21 +39252,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38616,6 +39288,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38640,6 +39315,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38763,6 +39447,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -38850,6 +39537,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -38886,6 +39579,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -38943,6 +39645,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -38979,6 +39690,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -38988,9 +39702,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -39824,6 +40535,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40013,6 +40730,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40304,6 +41027,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40541,6 +41267,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40571,7 +41300,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40619,8 +41348,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgid "ciReport|Browser performance test metrics: No changes"
@@ -40713,8 +41442,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgid "ciReport|Load performance test metrics results are being parsed"
@@ -40874,6 +41603,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41312,9 +42044,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41668,6 +42397,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -41767,9 +42499,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/bg/gitlab.po b/locale/bg/gitlab.po
index 7c9ff89c518..2ebca9f78af 100644
--- a/locale/bg/gitlab.po
+++ b/locale/bg/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: bg\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:57\n"
+"PO-Revision-Date: 2022-01-06 17:22\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "ДейноÑÑ‚"
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr "Създаване на нов…"
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,8 +12835,8 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
-msgstr "Редактиране на плана %{id} за Ñхема"
+msgid "Edit Pipeline Schedule"
+msgstr ""
msgid "Edit Release"
msgstr ""
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr "От прилагането на заÑвката за Ñливане д
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr "щракнете за качване"
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/bn_BD/gitlab.po b/locale/bn_BD/gitlab.po
index cd53038e86a..2b98bb85c85 100644
--- a/locale/bn_BD/gitlab.po
+++ b/locale/bn_BD/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: bn\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:56\n"
+"PO-Revision-Date: 2022-01-06 17:21\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/bn_IN/gitlab.po b/locale/bn_IN/gitlab.po
index 8eae0d9c6f2..835bd013af1 100644
--- a/locale/bn_IN/gitlab.po
+++ b/locale/bn_IN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: bn-IN\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:59\n"
+"PO-Revision-Date: 2022-01-06 17:24\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/br_FR/gitlab.po b/locale/br_FR/gitlab.po
index 5b8b85651d0..2572a05a0ab 100644
--- a/locale/br_FR/gitlab.po
+++ b/locale/br_FR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: br-FR\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 19:00\n"
+"PO-Revision-Date: 2022-01-06 17:25\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -794,7 +794,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -1072,6 +1072,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1299,6 +1302,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1418,6 +1427,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1491,6 +1503,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1892,6 +1907,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -2138,6 +2156,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -2150,12 +2177,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -2213,6 +2249,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -2237,6 +2303,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -2342,7 +2411,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2768,6 +2837,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -3044,7 +3122,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -3329,6 +3407,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3719,6 +3800,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3923,6 +4007,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3950,9 +4037,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -4133,6 +4217,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -4142,6 +4229,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -4294,6 +4384,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4644,9 +4740,15 @@ msgstr[4] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4677,6 +4779,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4686,6 +4791,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4710,6 +4824,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4737,6 +4854,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4773,7 +4893,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4946,9 +5066,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -5096,6 +5213,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5499,9 +5619,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5751,9 +5868,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5784,13 +5898,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr ""
-
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5802,7 +5913,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5814,9 +5928,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -6005,7 +6125,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -6372,7 +6492,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -6381,6 +6504,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6420,6 +6546,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -7127,7 +7256,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -7395,9 +7524,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7608,6 +7734,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7626,9 +7755,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7782,12 +7917,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7800,6 +7950,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7815,9 +7971,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7863,12 +8025,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7944,6 +8115,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7962,12 +8136,29 @@ 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 ""
+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[4] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7977,6 +8168,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -9167,6 +9361,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9594,6 +9797,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9686,6 +9892,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9917,12 +10126,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9953,9 +10168,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -10295,9 +10507,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -10328,6 +10537,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -10370,9 +10582,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -10382,13 +10591,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10568,15 +10780,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10586,15 +10816,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10745,15 +10984,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11447,6 +11677,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11726,6 +11959,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11759,15 +11995,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11909,6 +12139,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11933,7 +12166,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11942,6 +12175,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12768,15 +13004,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12920,6 +13156,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -13055,7 +13294,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -13094,6 +13333,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -14038,6 +14280,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -14083,9 +14328,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -14239,9 +14481,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -14326,6 +14565,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14514,9 +14756,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14709,7 +14948,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -15426,9 +15665,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15759,6 +15995,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16620,9 +16859,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16710,6 +16946,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16899,9 +17138,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -17028,6 +17264,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -17130,9 +17369,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -17205,6 +17453,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -17244,6 +17495,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -17277,6 +17531,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -17301,7 +17567,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -17310,7 +17576,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -17352,6 +17618,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -17379,12 +17648,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17499,6 +17774,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17553,6 +17831,9 @@ 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 ""
+
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 ""
@@ -19479,6 +19760,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19728,9 +20012,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19833,9 +20114,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19947,9 +20225,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20595,7 +20870,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -21050,6 +21325,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21832,7 +22113,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22588,10 +22869,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22690,6 +22971,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -23315,6 +23599,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -23521,6 +23808,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23734,6 +24054,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23961,6 +24284,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -24383,6 +24709,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -24395,7 +24724,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24814,6 +25143,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24832,12 +25167,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24877,12 +25218,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24907,18 +25257,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24928,9 +25293,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -25092,6 +25454,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25634,9 +25999,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25826,9 +26188,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25928,6 +26296,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -26009,12 +26380,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -26246,6 +26611,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -26465,9 +26833,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26744,6 +27109,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26756,6 +27127,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26951,9 +27325,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -27305,6 +27676,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -27362,6 +27736,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -27446,6 +27826,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27740,6 +28123,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27866,6 +28291,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -28118,19 +28546,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -28286,6 +28711,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28670,9 +29104,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28685,9 +29116,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28712,9 +29140,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28796,6 +29221,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28841,9 +29269,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28886,6 +29320,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28901,6 +29338,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -29129,6 +29569,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -29317,9 +29763,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -29362,6 +29805,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29691,10 +30182,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -30396,6 +30887,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -30405,6 +30899,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30607,9 +31107,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30631,6 +31128,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30682,19 +31185,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30748,6 +31254,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30793,6 +31302,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30802,7 +31314,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30871,7 +31386,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30889,6 +31404,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31150,6 +31668,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -31171,9 +31692,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -31487,6 +32005,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -31559,6 +32080,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31613,6 +32137,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31697,9 +32224,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31898,6 +32422,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31910,6 +32437,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31985,6 +32515,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -32138,6 +32671,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -32489,6 +33025,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32645,6 +33187,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -33353,6 +33898,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33797,9 +34345,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -34196,6 +34741,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34631,6 +35182,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34905,9 +35474,31 @@ msgstr[2] ""
msgstr[3] ""
msgstr[4] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34938,6 +35529,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34950,6 +35544,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34986,12 +35583,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -35286,6 +35892,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -35411,9 +36020,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -35423,9 +36029,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -35498,7 +36101,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35753,9 +36356,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -36101,6 +36701,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -36113,9 +36716,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -36140,6 +36740,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -36254,6 +36857,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -36419,6 +37025,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -37137,6 +37746,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -37203,6 +37815,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -37377,6 +38022,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -37502,15 +38150,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -37535,9 +38174,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -38165,9 +38801,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -39059,16 +39692,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -39110,6 +39743,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -39136,6 +39772,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -39168,6 +39807,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -39263,6 +39908,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -39344,12 +39992,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39377,6 +40037,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39446,9 +40109,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -39464,21 +40136,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -39488,6 +40172,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -39512,6 +40199,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -39635,6 +40331,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39722,6 +40421,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39758,6 +40463,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39815,6 +40529,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39851,6 +40574,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39860,9 +40586,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40704,6 +41427,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40893,6 +41622,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -41184,6 +41919,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -41433,6 +42171,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -41463,7 +42204,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -41511,8 +42252,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41609,8 +42350,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41778,6 +42519,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42240,9 +42984,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -42604,6 +43345,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42703,9 +43447,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/bs_BA/gitlab.po b/locale/bs_BA/gitlab.po
index 8a3068eaefc..dad23730748 100644
--- a/locale/bs_BA/gitlab.po
+++ b/locale/bs_BA/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: bs\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 19:00\n"
+"PO-Revision-Date: 2022-01-06 17:24\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -640,7 +640,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -916,6 +916,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1123,6 +1126,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1240,6 +1249,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1309,6 +1321,9 @@ msgstr ""
msgid ", or "
msgstr " ili "
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1660,6 +1675,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1906,6 +1924,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1918,12 +1945,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1981,6 +2017,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -2005,6 +2071,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -2110,7 +2179,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2536,6 +2605,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2812,7 +2890,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -3097,6 +3175,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3487,6 +3568,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3691,6 +3775,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3718,9 +3805,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3901,6 +3985,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3910,6 +3997,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -4060,6 +4150,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4396,9 +4492,15 @@ msgstr[2] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4429,6 +4531,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4438,6 +4543,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4462,6 +4576,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4489,6 +4606,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4525,7 +4645,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4696,9 +4816,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4846,6 +4963,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr "Dodaj neke zadatke ovom cilju."
@@ -5245,9 +5365,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5497,9 +5614,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5530,13 +5644,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr ""
-
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5548,7 +5659,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5560,9 +5674,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5749,7 +5869,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -6112,7 +6232,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -6121,6 +6244,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6160,6 +6286,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6865,7 +6994,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -7129,9 +7258,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7342,6 +7468,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7360,9 +7489,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7516,12 +7651,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7534,6 +7684,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7549,9 +7705,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7597,12 +7759,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7678,6 +7849,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7696,12 +7870,27 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7711,6 +7900,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8899,6 +9091,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9322,6 +9523,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9412,6 +9616,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9643,12 +9850,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9679,9 +9892,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -10021,9 +10231,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -10054,6 +10261,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -10096,9 +10306,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -10108,13 +10315,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10294,15 +10504,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10312,15 +10540,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10471,15 +10708,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11167,6 +11395,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11446,6 +11677,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11479,15 +11713,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11623,6 +11851,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11647,7 +11878,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11656,6 +11887,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12466,15 +12700,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12616,6 +12850,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12751,7 +12988,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12790,6 +13027,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13732,6 +13972,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr "Problem pri uklanjanju zadatka iz epika."
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13777,9 +14020,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13933,9 +14173,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -14020,6 +14257,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14206,9 +14446,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14401,7 +14638,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -15112,9 +15349,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15445,6 +15679,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16306,9 +16543,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16396,6 +16630,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16585,9 +16822,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16714,6 +16948,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16816,9 +17053,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16891,6 +17137,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16930,6 +17179,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16963,6 +17215,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16987,7 +17251,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16996,7 +17260,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -17038,6 +17302,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -17065,12 +17332,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17185,6 +17458,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17239,6 +17515,9 @@ 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 ""
+
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 ""
@@ -19153,6 +19432,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19402,9 +19684,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19507,9 +19786,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19621,9 +19897,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr "Tabla"
@@ -20269,7 +20542,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20722,6 +20995,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21490,7 +21769,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22246,10 +22525,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22348,6 +22627,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22969,6 +23251,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -23173,6 +23458,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23386,6 +23704,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23611,6 +23932,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -24031,6 +24355,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -24043,7 +24370,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24454,6 +24781,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24472,12 +24805,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24517,12 +24856,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24547,18 +24895,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24568,9 +24931,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24730,6 +25090,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25270,9 +25633,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25462,9 +25822,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25564,6 +25930,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25645,12 +26014,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25882,6 +26245,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -26101,9 +26467,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26380,6 +26743,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26392,6 +26761,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26587,9 +26959,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26941,6 +27310,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26998,6 +27370,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -27082,6 +27460,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27376,6 +27757,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27502,6 +27925,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27754,19 +28180,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27922,6 +28345,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28306,9 +28738,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28321,9 +28750,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28348,9 +28774,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28432,6 +28855,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28477,9 +28903,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28522,6 +28954,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28537,6 +28972,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28765,6 +29203,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28951,9 +29395,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28996,6 +29437,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29323,10 +29812,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -30016,6 +30505,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -30025,6 +30517,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30223,9 +30721,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30247,6 +30742,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30298,19 +30799,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30364,6 +30868,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30409,6 +30916,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30418,7 +30928,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30487,7 +31000,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30505,6 +31018,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30766,6 +31282,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30787,9 +31306,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -31081,6 +31597,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -31153,6 +31672,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31207,6 +31729,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31291,9 +31816,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31492,6 +32014,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31504,6 +32029,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31579,6 +32107,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31732,6 +32263,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -32083,6 +32617,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32239,6 +32779,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32941,6 +33484,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33385,9 +33931,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33784,6 +34327,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34219,6 +34768,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34489,9 +35056,27 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34522,6 +35107,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34534,6 +35122,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34570,12 +35161,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34864,6 +35464,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34987,9 +35590,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34999,9 +35599,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -35074,7 +35671,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35329,9 +35926,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35677,6 +36271,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35689,9 +36286,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35716,6 +36310,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35830,6 +36427,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35995,6 +36595,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36709,6 +37312,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36775,6 +37381,39 @@ msgstr ""
msgid "Today"
msgstr "Danas"
+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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36949,6 +37588,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -37072,15 +37714,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -37105,9 +37738,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37735,9 +38365,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38629,16 +39256,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38680,6 +39307,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38704,6 +39334,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38734,6 +39367,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38827,6 +39466,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38908,12 +39550,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38941,6 +39595,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39010,9 +39667,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -39028,21 +39694,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -39052,6 +39730,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -39076,6 +39757,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -39199,6 +39889,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39286,6 +39979,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39322,6 +40021,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39379,6 +40087,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39415,6 +40132,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39424,9 +40144,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40264,6 +40981,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40453,6 +41176,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40744,6 +41473,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40987,6 +41719,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -41017,7 +41752,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -41065,8 +41800,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41161,8 +41896,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41326,6 +42061,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41776,9 +42514,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -42136,6 +42871,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42235,9 +42973,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/ca_ES/gitlab.po b/locale/ca_ES/gitlab.po
index d2d69eec6e9..baec3c96e96 100644
--- a/locale/ca_ES/gitlab.po
+++ b/locale/ca_ES/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ca\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:57\n"
+"PO-Revision-Date: 2022-01-06 17:22\n"
msgid " %{start} to %{end}"
msgstr " Des de %{start} fins %{end}"
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr "%{placeholder} no és un esquema de colors vàlid"
msgid "%{placeholder} is not a valid theme"
msgstr "%{placeholder} no és un tema vàlid"
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr "Sessions actives"
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "Activitat"
@@ -1994,7 +2063,7 @@ msgstr "Afegeix una taula"
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr "Suprimeix l'usuari"
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr "per usuari"
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr "Taulers"
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr "Trieu un color."
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr "Crea una etiqueta nova"
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr "Crea..."
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr "Selector de data"
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr "Ajuda"
@@ -23212,6 +23529,9 @@ msgstr "Nou"
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr "Aplicació nova"
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/cs_CZ/gitlab.po b/locale/cs_CZ/gitlab.po
index 249f926d295..44b010039f0 100644
--- a/locale/cs_CZ/gitlab.po
+++ b/locale/cs_CZ/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: cs\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:57\n"
+"PO-Revision-Date: 2022-01-06 17:22\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -717,7 +717,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -994,6 +994,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1211,6 +1214,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1329,6 +1338,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1400,6 +1412,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1776,6 +1791,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -2022,6 +2040,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -2034,12 +2061,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -2097,6 +2133,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -2121,6 +2187,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -2226,7 +2295,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2652,6 +2721,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2928,7 +3006,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -3213,6 +3291,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3603,6 +3684,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3807,6 +3891,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3834,9 +3921,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -4017,6 +4101,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -4026,6 +4113,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -4177,6 +4267,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4520,9 +4616,15 @@ msgstr[3] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4553,6 +4655,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4562,6 +4667,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4586,6 +4700,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4613,6 +4730,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4649,7 +4769,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4821,9 +4941,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4971,6 +5088,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5372,9 +5492,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5624,9 +5741,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5657,13 +5771,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr ""
-
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5675,7 +5786,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5687,9 +5801,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5877,7 +5997,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -6242,7 +6362,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -6251,6 +6374,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6290,6 +6416,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6996,7 +7125,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -7262,9 +7391,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7475,6 +7601,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7493,9 +7622,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7649,12 +7784,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7667,6 +7817,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7682,9 +7838,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7730,12 +7892,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7811,6 +7982,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7829,12 +8003,28 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7844,6 +8034,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -9033,6 +9226,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9458,6 +9660,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9549,6 +9754,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9780,12 +9988,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9816,9 +10030,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -10158,9 +10369,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -10191,6 +10399,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -10233,9 +10444,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -10245,13 +10453,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10431,15 +10642,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10449,15 +10678,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10608,15 +10846,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11307,6 +11536,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11586,6 +11818,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11619,15 +11854,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11766,6 +11995,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11790,7 +12022,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11799,6 +12031,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12617,15 +12852,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12768,6 +13003,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12903,7 +13141,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12942,6 +13180,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13885,6 +14126,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13930,9 +14174,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -14086,9 +14327,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -14173,6 +14411,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14360,9 +14601,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14555,7 +14793,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -15269,9 +15507,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15602,6 +15837,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16463,9 +16701,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16553,6 +16788,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16742,9 +16980,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16871,6 +17106,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16973,9 +17211,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -17048,6 +17295,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -17087,6 +17337,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -17120,6 +17373,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -17144,7 +17409,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -17153,7 +17418,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -17195,6 +17460,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -17222,12 +17490,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17342,6 +17616,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17396,6 +17673,9 @@ 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 ""
+
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 ""
@@ -19316,6 +19596,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19565,9 +19848,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19670,9 +19950,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19784,9 +20061,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20432,7 +20706,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20886,6 +21160,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21661,7 +21941,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22417,10 +22697,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22519,6 +22799,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -23142,6 +23425,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -23347,6 +23633,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23560,6 +23879,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23786,6 +24108,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -24207,6 +24532,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -24219,7 +24547,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24634,6 +24962,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24652,12 +24986,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24697,12 +25037,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24727,18 +25076,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24748,9 +25112,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24911,6 +25272,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25452,9 +25816,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25644,9 +26005,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25746,6 +26113,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25827,12 +26197,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -26064,6 +26428,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -26283,9 +26650,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26562,6 +26926,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26574,6 +26944,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26769,9 +27142,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -27123,6 +27493,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -27180,6 +27553,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -27264,6 +27643,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27558,6 +27940,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27684,6 +28108,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27936,19 +28363,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -28104,6 +28528,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28488,9 +28921,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28503,9 +28933,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28530,9 +28957,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28614,6 +29038,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28659,9 +29086,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28704,6 +29137,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28719,6 +29155,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28947,6 +29386,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -29134,9 +29579,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -29179,6 +29621,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29507,10 +29997,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -30206,6 +30696,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -30215,6 +30708,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30415,9 +30914,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30439,6 +30935,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30490,19 +30992,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30556,6 +31061,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30601,6 +31109,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30610,7 +31121,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30679,7 +31193,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30697,6 +31211,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30958,6 +31475,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30979,9 +31499,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -31284,6 +31801,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -31356,6 +31876,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31410,6 +31933,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31494,9 +32020,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31695,6 +32218,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31707,6 +32233,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31782,6 +32311,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31935,6 +32467,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -32286,6 +32821,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32442,6 +32983,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -33147,6 +33691,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33591,9 +34138,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33990,6 +34534,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34425,6 +34975,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34697,9 +35265,29 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34730,6 +35318,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34742,6 +35333,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34778,12 +35372,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -35075,6 +35678,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -35199,9 +35805,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -35211,9 +35814,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -35286,7 +35886,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35541,9 +36141,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35889,6 +36486,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35901,9 +36501,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35928,6 +36525,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -36042,6 +36642,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -36207,6 +36810,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36923,6 +37529,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36989,6 +37598,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -37163,6 +37805,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -37287,15 +37932,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -37320,9 +37956,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37950,9 +38583,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38844,16 +39474,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38895,6 +39525,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38920,6 +39553,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38951,6 +39587,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -39045,6 +39687,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -39126,12 +39771,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39159,6 +39816,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39228,9 +39888,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -39246,21 +39915,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -39270,6 +39951,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -39294,6 +39978,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -39417,6 +40110,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39504,6 +40200,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39540,6 +40242,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39597,6 +40308,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39633,6 +40353,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39642,9 +40365,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40484,6 +41204,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40673,6 +41399,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40964,6 +41696,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -41210,6 +41945,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -41240,7 +41978,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -41288,8 +42026,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41385,8 +42123,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41552,6 +42290,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42008,9 +42749,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -42370,6 +43108,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42469,9 +43210,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/cy_GB/gitlab.po b/locale/cy_GB/gitlab.po
index 1fa0260469e..635bb93c491 100644
--- a/locale/cy_GB/gitlab.po
+++ b/locale/cy_GB/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: cy\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:59\n"
+"PO-Revision-Date: 2022-01-06 17:23\n"
msgid " %{start} to %{end}"
msgstr " %{start} i %{end}"
@@ -871,7 +871,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr "%{description}- Digwyddiad sentry: %{errorUrl}- Gwelwyd gyntaf: %{firstSeen}- Gwelwyd ddiwethaf: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -1150,6 +1150,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1387,6 +1390,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1507,6 +1516,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1582,6 +1594,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -2008,6 +2023,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -2254,6 +2272,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -2266,12 +2293,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -2329,6 +2365,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -2353,6 +2419,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -2458,7 +2527,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2884,6 +2953,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -3160,7 +3238,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -3445,6 +3523,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3835,6 +3916,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -4039,6 +4123,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -4066,9 +4153,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -4249,6 +4333,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -4258,6 +4345,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -4411,6 +4501,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4768,9 +4864,15 @@ msgstr[5] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4801,6 +4903,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4810,6 +4915,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4834,6 +4948,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4861,6 +4978,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4897,7 +5017,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -5071,9 +5191,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -5221,6 +5338,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5626,9 +5746,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5878,9 +5995,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5911,13 +6025,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5929,7 +6040,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5941,9 +6055,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -6133,7 +6253,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -6502,7 +6622,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -6511,6 +6634,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6550,6 +6676,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -7258,7 +7387,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -7528,9 +7657,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7741,6 +7867,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7759,9 +7888,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7915,12 +8050,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7933,6 +8083,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7948,9 +8104,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7996,12 +8158,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -8077,6 +8248,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -8095,12 +8269,30 @@ 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 ""
+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[4] ""
+msgstr[5] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -8110,6 +8302,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -9301,6 +9496,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9730,6 +9934,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9823,6 +10030,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -10054,12 +10264,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -10090,9 +10306,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -10432,9 +10645,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -10465,6 +10675,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -10507,9 +10720,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -10519,13 +10729,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10705,15 +10918,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10723,15 +10954,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10882,15 +11122,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11587,6 +11818,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11866,6 +12100,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11899,15 +12136,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -12052,6 +12283,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -12076,7 +12310,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -12085,6 +12319,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12919,15 +13156,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -13072,6 +13309,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -13207,7 +13447,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -13246,6 +13486,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -14191,6 +14434,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -14236,9 +14482,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -14392,9 +14635,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -14479,6 +14719,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14668,9 +14911,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14863,7 +15103,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -15583,9 +15823,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15916,6 +16153,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16777,9 +17017,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16867,6 +17104,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -17056,9 +17296,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -17185,6 +17422,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -17287,9 +17527,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -17362,6 +17611,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -17401,6 +17653,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -17434,6 +17689,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -17458,7 +17725,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -17467,7 +17734,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -17509,6 +17776,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -17536,12 +17806,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17656,6 +17932,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17710,6 +17989,9 @@ 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 ""
+
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 ""
@@ -19642,6 +19924,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19891,9 +20176,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19996,9 +20278,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -20110,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20758,7 +21034,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -21214,6 +21490,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -22003,7 +22285,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22759,10 +23041,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22861,6 +23143,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -23488,6 +23773,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -23695,6 +23983,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23908,6 +24229,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -24136,6 +24460,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -24559,6 +24886,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -24571,7 +24901,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24994,6 +25324,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -25012,12 +25348,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -25057,12 +25399,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -25087,18 +25438,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -25108,9 +25474,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -25273,6 +25636,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25816,9 +26182,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -26008,9 +26371,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -26110,6 +26479,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -26191,12 +26563,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -26428,6 +26794,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -26647,9 +27016,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26926,6 +27292,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26938,6 +27310,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -27133,9 +27508,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -27487,6 +27859,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -27544,6 +27919,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -27628,6 +28009,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27922,6 +28306,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -28048,6 +28474,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -28300,19 +28729,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -28468,6 +28894,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28852,9 +29287,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28867,9 +29299,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28894,9 +29323,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28978,6 +29404,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -29023,9 +29452,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -29068,6 +29503,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -29083,6 +29521,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -29311,6 +29752,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -29500,9 +29947,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -29545,6 +29989,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29875,10 +30367,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -30586,6 +31078,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -30595,6 +31090,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30799,9 +31300,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30823,6 +31321,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30874,19 +31378,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30940,6 +31447,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30985,6 +31495,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30994,7 +31507,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -31063,7 +31579,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -31081,6 +31597,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31342,6 +31861,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -31363,9 +31885,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -31690,6 +32209,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -31762,6 +32284,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31816,6 +32341,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31900,9 +32428,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -32101,6 +32626,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -32113,6 +32641,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -32188,6 +32719,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -32341,6 +32875,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -32692,6 +33229,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32848,6 +33391,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -33559,6 +34105,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -34003,9 +34552,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -34402,6 +34948,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34837,6 +35389,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -35113,9 +35683,33 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -35146,6 +35740,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -35158,6 +35755,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -35194,12 +35794,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -35497,6 +36106,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -35623,9 +36235,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -35635,9 +36244,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -35710,7 +36316,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35965,9 +36571,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -36313,6 +36916,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -36325,9 +36931,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -36352,6 +36955,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -36466,6 +37072,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -36631,6 +37240,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -37351,6 +37963,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -37417,6 +38032,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -37591,6 +38239,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -37717,15 +38368,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -37750,9 +38392,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -38380,9 +39019,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -39274,16 +39910,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -39325,6 +39961,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -39352,6 +39991,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -39385,6 +40027,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -39481,6 +40129,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -39562,12 +40213,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39595,6 +40258,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39664,9 +40330,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -39682,21 +40357,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -39706,6 +40393,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -39730,6 +40420,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -39853,6 +40552,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39940,6 +40642,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39976,6 +40684,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -40033,6 +40750,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -40069,6 +40795,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -40078,9 +40807,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40924,6 +41650,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -41113,6 +41845,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -41404,6 +42142,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -41656,6 +42397,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -41686,7 +42430,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -41734,8 +42478,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41833,8 +42577,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -42004,6 +42748,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42472,9 +43219,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -42838,6 +43582,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42937,9 +43684,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/da_DK/gitlab.po b/locale/da_DK/gitlab.po
index dd255fb2953..dbca2826517 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: 2021-12-06 18:57\n"
+"PO-Revision-Date: 2022-01-06 17:22\n"
msgid " %{start} to %{end}"
msgstr " %{start} til %{end}"
@@ -563,8 +563,8 @@ msgstr "%{deployLinkStart}Brug en skabelon til at udsende til ECS%{deployLinkEnd
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr "%{description}- Sentry-begivenhed: %{errorUrl}- Først set: %{firstSeen}- Sidst set: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
-msgstr "%{doc_link_start}Avanceret søgning%{doc_link_end} er deaktiveret eftersom %{ref_elem} ikke er standardgrenen, %{default_branch_link_start}søg i stedet på %{default_branch}%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
+msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
msgstr "%{doc_link_start}Avanceret søgning%{doc_link_end} er aktiveret."
@@ -838,6 +838,9 @@ msgstr "%{placeholder} er ikke et gyldigt farveskema"
msgid "%{placeholder} is not a valid theme"
msgstr "%{placeholder} er ikke et gyldigt tema"
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
@@ -1035,6 +1038,12 @@ msgstr "%{userName}s avatar"
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr "%{user_name} (%{user_username}) blev fjernet fra %{rotation} i %{schedule} i %{project}. "
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr "%{user_name}s profilside"
@@ -1151,6 +1160,9 @@ msgstr "(lad den være tom hvis du ikke vil ændre den)"
msgid "(max size 15 MB)"
msgstr "(maks. størrelse 15 MB)"
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr "(fjernet)"
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr " eller "
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr "- Tilgængelig til at køre jobs."
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr "En skabelon der er klar til brug med Android-programmer"
@@ -1790,6 +1808,15 @@ msgstr "Er du sikker? RSS- eller kalender-URL'er som er i brug i øjeblikket vil
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr "Er du sikker? Problemstillings e-mailadresser som er i brug i øjeblikket vil stoppe med at virke."
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr "Oprettet"
@@ -1802,12 +1829,21 @@ msgstr "Indgående e-mailtoken"
msgid "AccessTokens|It cannot be used to access any other data."
msgstr "Den kan ikke bruges til at få adgang til andre data."
+msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{linkStart}reset this token%{linkEnd}."
+msgstr ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr "Hold adgangstokenen hemmelig. Alle der har den kan oprette problemstillinger som var de dig. Hvis det sker, så %{link_reset_it}."
+msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{linkStart}reset this token%{linkEnd}."
+msgstr ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr "Hold adgangstokenen hemmelig. Alle der har den kan læse aktivitets- og problemstillings RSS-feeds eller din kalenderfeed som var de dig. Hvis det sker, så %{link_reset_it}."
@@ -1865,6 +1901,36 @@ msgstr "Konto:"
msgid "Account: %{account}"
msgstr "Konto: %{account}"
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr "Handling"
@@ -1889,6 +1955,9 @@ msgstr "Aktive %{type} (%{token_length})"
msgid "Active Sessions"
msgstr "Aktive sessioner"
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "Aktivitet"
@@ -1994,7 +2063,7 @@ msgstr "Tilføj en tabel"
msgid "Add a task list"
msgstr "Tilføj en opgaveliste"
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr "Du er ved at stoppe alle job. Det standser alle nuværende job som køre
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "Fejl ved indlæsning af statistikken. Prøv venligst igen"
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,8 +2774,8 @@ msgstr "Slet bruger"
msgid "AdminUsers|Delete user and contributions"
msgstr "Slet brugeren og bidrag"
-msgid "AdminUsers|Export permissions as CSV"
-msgstr "Eksportér tilladelser som CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
+msgstr ""
msgid "AdminUsers|External"
msgstr "Eksterne"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr "Alle epics"
msgid "All groups and projects"
msgstr "Alle grupper og projekter"
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr "Alle problemstillinger for milepælen er lukket."
@@ -3575,6 +3659,9 @@ msgstr "Der er opstået en fejl"
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr "Der opstod en fejl ved tilføjelse af et udkast til tråden."
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr "Der opstod en fejl ved forhåndsvisning af blob'en"
-msgid "An error occurred when removing the label."
-msgstr "Der opstod en fejl ved fjernelse af etiketten."
-
msgid "An error occurred when updating the title"
msgstr "Der opstod en fejl ved opdatering af titlen"
@@ -3785,6 +3869,9 @@ msgstr "Der opstod en fejl under indlæsning af sammenlægningsanmodninger."
msgid "An error occurred while loading projects."
msgstr "Der opstod en fejl under indlæsning af projekter."
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr "Der opstod en fejl under indlæsning af fanebladet Behov."
@@ -3794,6 +3881,9 @@ msgstr "Der opstod en fejl under indlæsning af fanebladet Testrapporter."
msgid "An error occurred while loading the access tokens form, please try again."
msgstr "Der opstod en fejl under indlæsning af formularen til adgangstokens. Prøv venligst igen."
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr "Der opstod en fejl under indlæsning af dataene. Prøv venligst igen."
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] "%{count} godkendelser kræves fra %{membersCount}"
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr "%{firstLabel} +%{numberOfAdditionalLabels} mere"
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr "Tilføj godkendere"
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr "Alle skannere"
@@ -4305,6 +4407,9 @@ msgstr "Godkendertype"
msgid "ApprovalRule|Approvers"
msgstr "Godkendere"
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr "Eksempler: kvalitetssikring, sikkerhed."
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr "Navn"
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr "Alvorlighedsniveauer"
msgid "ApprovalRule|Target branch"
msgstr "MÃ¥lgren"
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr "SÃ¥rbarheder tilladt"
@@ -4401,7 +4521,7 @@ msgstr "Der opstod en fejl under opdatering af godkendelsesindstillinger for sam
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr "Indstillingen er konfigureret på instansniveau og kan kun ændres af en administrator."
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr "Er du sikker på, at du vil sammenlægge straks?"
msgid "Are you sure you want to re-deploy this environment?"
msgstr "Er du sikker på, at du vil genudsende miljøet?"
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr "Er du sikker på, at du vil regenerere den offentlige nøgle? Du skal opdatere den offentlige nøgle på fjernserveren, før spejling fungerer igen."
-
msgid "Are you sure you want to reindex?"
msgstr "Er du sikker på, at du vil genindeksere?"
@@ -4721,6 +4838,9 @@ msgstr "Tildel kontrollant"
msgid "Assign reviewer(s)"
msgstr "Tildel kontrollanter"
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr "Tildel nogle problemstillinger til milepælen."
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr "Avatar til %{assigneeName}"
-msgid "Avatar for %{name}"
-msgstr "Avatar til %{name}"
-
msgid "Avatar will be removed. Are you sure?"
msgstr "Avataren fjernes. Er du sikker?"
@@ -5370,9 +5487,6 @@ msgstr "månedligt"
msgid "BillingPlans|per user"
msgstr "pr. bruger"
-msgid "BillingPlan|Contact sales"
-msgstr "Kontakt salgsafdelingen"
-
msgid "BillingPlan|Upgrade"
msgstr "Opgrader"
@@ -5403,15 +5517,12 @@ msgstr "Genaktivér prøveperiode"
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr "Delte runnere kan ikke aktiveres indtil et gyldigt kreditkort er blevet registreret."
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
-msgstr "Bruger valideret"
-
msgid "Billings|User validation required"
msgstr "Brugervalidering kræves"
@@ -5421,7 +5532,10 @@ msgstr "Validér konto"
msgid "Billings|Validate user account"
msgstr "Validér brugerkonto"
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr "Kan ikke fjerne brugeren"
@@ -5621,8 +5741,8 @@ msgstr "Vægt"
msgid "Boards"
msgstr "Tavler"
-msgid "Boards and Board Lists"
-msgstr "Tavler og tavlelister"
+msgid "Boards and board lists"
+msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
msgid_plural "Boards|+ %{displayedIssuablesCount} more %{issuableType}s"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr "Masseopdatering"
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr "Eksisterende grupper"
msgid "BulkImport|Filter by source group"
msgstr "Filtrér efter kildegruppe"
+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 ""
+
msgid "BulkImport|From source group"
msgstr "Fra kildegruppe"
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr "Ingen forælder"
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr "Vælg en farve."
msgid "Choose file…"
msgstr "Vælg fil …"
-msgid "Choose labels"
-msgstr "Vælg etiketter"
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr "Ryd forfaldsdato"
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr "Ryd seneste søgninger"
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr "Ryd vægt"
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr "Rydder vægt."
@@ -7383,12 +7518,27 @@ msgstr "Klyngeniveau"
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr "Adgangstokens"
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ msgstr "Der opstod en fejl under indlæsning af dine GitLab-agenter"
msgid "ClusterAgents|An error occurred while loading your agent"
msgstr "Der opstod en fejl under indlæsning af din agent"
+msgid "ClusterAgents|An error occurred while retrieving GitLab Agent activity. Reload the page to try again."
+msgstr ""
+
msgid "ClusterAgents|An unknown error occurred. Please try again."
msgstr "Der opstod en ukendt fejl. Prøv venligst igen."
+msgid "ClusterAgents|Are you sure you want to delete this agent? You cannot undo this."
+msgstr ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr "Oprettet af %{name} %{time}"
msgid "ClusterAgents|Date created"
msgstr "Dato oprettet"
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr "Beskrivelse"
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr "Registreringstoken"
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
msgstr "Agenten har ingen tokens"
+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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr "Ukendt bruger"
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr "Komponent"
@@ -9186,6 +9386,9 @@ msgstr "Endnu ikke planlagt"
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr "Udgivet %{timeInfo}"
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr "Kunne ikke finde aftryksdepotet."
@@ -9506,12 +9712,18 @@ msgstr "Kopiér miljø"
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr "Kopiér filindhold"
msgid "Copy file path"
msgstr "Kopiér filsti"
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr "Kopiér nøgle"
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr "Kopiér registreringstokenen."
-msgid "Copy this value"
-msgstr "Kopiér værdien"
-
msgid "Copy to clipboard"
msgstr "Kopiér til udklipsholder"
@@ -9884,9 +10093,6 @@ msgstr "Opret ny etiket"
msgid "Create new project"
msgstr "Opret nyt projekt"
-msgid "Create new..."
-msgstr "Opret ny(t) ..."
-
msgid "Create or import your first project"
msgstr "Opret eller importér dit første projekt"
@@ -9917,6 +10123,9 @@ msgstr "Opret emne"
msgid "Create user"
msgstr "Opret bruger"
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr "Opret jokertegn: %{searchTerm}"
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr "Opret Value Stream"
-
msgid "CreateValueStreamForm|Create from default template"
msgstr "Opret fra standardskabelon"
@@ -9971,14 +10177,17 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr "Opret ny Value Stream"
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr "Standardstadier"
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
-msgstr "Rediger Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
+msgstr ""
msgid "CreateValueStreamForm|Editing stage"
msgstr "Redigeringsstadie"
@@ -10157,15 +10366,33 @@ msgstr "Kreditkort:"
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr "Tilpas din pipelinekonfiguration og dækningsrapport."
msgid "Customize your pipeline configuration."
msgstr "Tilpas din pipelinekonfiguration."
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr "Vil du tilpasse siden?"
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr "Gå til præferencer"
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr "Siden viser som standard en liste over dine projekter men den kan ændres til at vise projekternes aktivitet, grupper, din gøremålsliste, tildelte problemstillinger, tildelte sammenlægningsanmodninger mm. Du kan ændre det under \"Indhold for startside\" i dine præferencer"
-
msgid "Cycle Time"
msgstr "Cyklustid"
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr "Dato"
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr "Datovælger"
@@ -11306,6 +11536,9 @@ msgstr "Slet brugerliste"
msgid "Delete variable"
msgstr "Slet variabel"
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr "Kunne ikke fjerne projektdepot. Prøv venligst igen eller kontakt administrator."
@@ -11339,15 +11572,9 @@ msgstr "Slet %{name}"
msgid "Deleted"
msgstr "Slettet"
-msgid "Deleted Projects"
-msgstr "Slettede projekter"
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr "Slettede chatkaldenavn: %{chat_name}!"
-msgid "Deleted projects"
-msgstr "Slettede projekter"
-
msgid "Deleted projects cannot be restored!"
msgstr "Slettede projekter kan ikke gendannes!"
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] "Afhænger af %d sammenlægningsanmodning der er ved at blive sammenlagt"
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr "GitLab vil udføre statiske og dynamiske tests på koden i dit program hvor der ledes efter kendte defekter og de rapporteres i sammenlægningsanmodningen, så du kan rette dem inden der sammenlægges."
-msgid "Discover|Give feedback for this page"
-msgstr "Giv feedback til siden"
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr "Start en gratis prøveperiode"
@@ -12464,6 +12697,9 @@ msgstr "Download (%{size})"
msgid "Download CSV"
msgstr "Download CSV"
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr "Download artefakter"
@@ -12599,8 +12835,8 @@ msgstr "Rediger milepæl"
msgid "Edit Password"
msgstr "Rediger adgangskode"
-msgid "Edit Pipeline Schedule %{id}"
-msgstr "Rediger pipelineplanlægningen %{id}"
+msgid "Edit Pipeline Schedule"
+msgstr ""
msgid "Edit Release"
msgstr "Rediger udgivelse"
@@ -12638,6 +12874,9 @@ msgstr "Rediger beskrivelse"
msgid "Edit environment"
msgstr "Rediger miljø"
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr "Rediger filer i editoren og commit ændringer her"
@@ -13579,6 +13818,9 @@ msgstr "Noget gik galt under flytning af organisering af element."
msgid "Epics|Something went wrong while removing issue from epic."
msgstr "Noget gik galt under fjernelse af problemstilling fra epic."
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr "Fejl ved oprettelse af depot for udklip med id'et %{snippet_id}"
msgid "Error creating the snippet"
msgstr "Fejl ved oprettelse af udklippet"
-msgid "Error deleting %{issuableType}"
-msgstr "Fejl ved sletning af %{issuableType}"
-
msgid "Error deleting project. Check logs for error details."
msgstr "Fejl ved sletning af projekt. Tjek loggene for fejldetaljer."
@@ -13780,9 +14019,6 @@ msgstr "Fejl ved upload af fil: %{stripped}"
msgid "Error while loading the merge request. Please try again."
msgstr "Fejl ved indlæsning af sammenlægningsanmodningen. Prøv venligst igen."
-msgid "Error while loading the project data. Please try again."
-msgstr "Fejl ved indlæsning af projektdataene. Prøv venligst igen."
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr "Fejl ved migrering af %{upload_id}: %{error_message}"
@@ -13867,6 +14103,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 "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr "Hvert år"
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr "Alle"
-
msgid "Everyone With Access"
msgstr "Alle med adgang"
@@ -14247,7 +14483,7 @@ msgstr "Eksportér projekt"
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr "Filtrér efter testsager som i øjeblikket er arkiveret."
msgid "Filter by test cases that are currently open."
msgstr "Filtrér efter testsager som i øjeblikket er åbne."
-msgid "Filter by two-factor authentication"
-msgstr "Filtrér efter totrinsgodkendelse"
-
msgid "Filter by user"
msgstr "Filtrér efter bruger"
@@ -15288,6 +15521,9 @@ msgstr "Fra sammenlægning af sammenlægningsanmodning til udsendelse til produk
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr "Fulde navn"
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr "Gå til målinger"
msgid "Go to next page"
msgstr "Gå til næste side"
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr "Gå til forælder"
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr "Gruppe-URL"
-msgid "Group Wikis"
-msgstr "Gruppewikier"
-
msgid "Group application: %{name}"
msgstr "Gruppeprogram: %{name}"
@@ -16557,6 +16790,9 @@ msgstr "Gruppen blev eksporteret"
msgid "Group was successfully updated."
msgstr "Gruppen blev opdateret."
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr "Gruppe: %{group_name}"
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
msgid "GroupSAML|Are you sure you want to remove the SAML group link?"
msgstr "Er du sikker på, at du vil fjerne SAML-gruppelinket?"
+msgid "GroupSAML|Are you sure you want to reset the SCIM token? SCIM provisioning will stop working until the new token is updated."
+msgstr ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,8 +17093,8 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr "Badges"
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
-msgstr "Vær forsigtig. Ændring af en gruppes forælder kan have utilsigtede %{side_effects_link_start}bivirkninger%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
+msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
msgstr "Kan ikke opdatere stien da der er projekter under gruppen som indeholder Docker-aftryk i deres beholderregister. Fjern venligst først aftrykkene fra dine projekter og prøv igen."
@@ -16839,7 +17102,7 @@ msgstr "Kan ikke opdatere stien da der er projekter under gruppen som indeholder
msgid "GroupSettings|Change group URL"
msgstr "Ændr gruppe-URL"
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr "Pipelineindstillinger blev opdateret for gruppen"
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr "Vælg en undergruppe som skal bruges som kilden til tilpassede projektskabeloner i gruppen."
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ msgstr "Udfyld venligst din personlige adgangstoken."
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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr "Ugyldigt styresystem"
msgid "Invalid URL"
msgstr "Ugyldig URL"
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr "Ugyldig container_name"
@@ -19239,9 +19520,6 @@ msgstr "Inviter teammedlemmer"
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr "Tilføj medlemmer til projektet og begynd at samarbejde med dit team."
-msgid "InviteMember|Invite Member"
-msgstr "Inviter medlem"
-
msgid "InviteMember|Invite Members (optional)"
msgstr "Inviter medlemmer (valgfrit)"
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr "Blokeres af"
-msgid "Is this GitLab trial for your company?"
-msgstr "Er GitLab-prøveperioden til din virksomhed?"
-
msgid "Is using license seat:"
msgstr "Bruger licenssæde:"
@@ -19458,9 +19733,6 @@ msgstr "Status"
msgid "IssueAnalytics|Weight"
msgstr "Vægt"
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr "Der opstod et problem under indstilling af underretningsstatus. Prøv venligst igen."
-
msgid "IssueBoards|Board"
msgstr "Tavle"
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr "Download"
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr "Start et udviklingsmiljø som er klar til at kode til dit projekt."
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr "Manuelt"
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr "YAML-definition for målingsbetjeningspanel er gyldig."
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr "Der findes mere information|her"
msgid "More information."
msgstr "Mere information."
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr "Naviger til projektet for at lukke milepælen."
msgid "Navigation bar"
msgstr "Navigationslinje"
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr "Hjælp"
@@ -23212,6 +23529,9 @@ msgstr "Ny"
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr "Nyt program"
@@ -23436,6 +23756,9 @@ msgstr "Næste design"
msgid "Next file in diff"
msgstr "Næste fil i diff"
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr "Næste uløste debat"
@@ -23641,7 +23964,7 @@ msgid "No matching results..."
msgstr ""
msgid "No member provided"
-msgstr ""
+msgstr "Intet medlem angivet"
msgid "No members found"
msgstr "Ingen medlemmer fundet"
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr "Bemærk: Overvej at spørge din GitLab-administrator om at konfigurere %{github_integration_link}, hvilket vil gøre det muligt at logge ind via GitHub og tillade import af depoter uden generering af en personlig adgangstoken."
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr "Er du sikker på, at du vil annullere oprettelse af kommentaren?"
msgid "Notes|Collapse replies"
msgstr "Sammenfold svar"
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr "Opret ny webstedsprofil"
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr "Beskrivelse (valgfrit)"
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr "Starttidspunkt"
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr "Brug eksisterende skannerprofil"
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr "Når den er fjernet kan forgreningsrelationen ikke gendannes. Projektet vil ikke længere være i stand til at modtage eller sende sammenlægningsanmodninger til kildeprojektet eller andre forgreninger."
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr "Når du bekræfter og trykker på \"Reducer projektets synlighed\":"
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr "Siden blev ikke fundet"
msgid "Page settings"
msgstr "Sideindstillinger"
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr "Aktiv"
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr "Afventende"
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr "Afventende kommentarer"
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr "væg"
msgid "Period in seconds"
msgstr "Periode i sekunder"
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr "Slet projekt permanent"
@@ -25463,12 +25831,6 @@ msgstr "Pipeline-URL"
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr "Ryd runnermellemlagre"
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr "Kopiér udløsertoken"
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr "Se venligst %{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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr "Vælg venligst"
@@ -26210,6 +26578,9 @@ msgstr "Vælg venligst et land"
msgid "Please select a file"
msgstr "Vælg venligst en fil"
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr "Vælg venligst en gruppe."
@@ -26405,9 +26776,6 @@ msgstr "Præferencer for tid"
msgid "Preferences|Use relative times"
msgstr "Brug relative tidspunkter"
-msgid "Press %{key}-C to copy"
-msgstr "Tryk på %{key}-C for at kopiere"
-
msgid "Prev"
msgstr "Forrige"
@@ -26759,6 +27127,9 @@ msgstr "Ugyldig adgangskode"
msgid "Profiles|Invalid username"
msgstr "Ugyldigt brugernavn"
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr "Nøgle"
@@ -26816,6 +27187,12 @@ msgstr "Private bidrag"
msgid "Profiles|Profile was successfully updated"
msgstr "Profilen blev opdateret"
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr "Offentlig avatar"
@@ -26900,6 +27277,9 @@ msgstr "Brugernavnet blev ændret"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr "Det kan være sjovt at bruge emojier i navne men prøv venligst at indstille en statusmeddelelse i stedet"
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr "Hvad er din status?"
@@ -27194,6 +27574,48 @@ msgstr "Kopiér projekt-id"
msgid "ProjectPage|Project ID: %{project_id}"
msgstr "Projekt-id: %{project_id}"
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr " eller gruppe"
@@ -27320,6 +27742,9 @@ msgstr "Udløs begivenhed når en problemstilling oprettes, opdateres eller lukk
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr "%{link_start}Hvad er beskrivelsesskabeloner?%{link_end}"
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr "Yderligere indstillinger der påvirker hvordan og hvornår sammenlægninger foretages."
@@ -27572,19 +27997,16 @@ msgstr "Squashing udføres aldrig og afkrydsningsboksen er skjult."
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr "Indsend ændringer som skal sammenlægges upstream."
-msgid "ProjectSettings|Supported variables:"
-msgstr "Understøttede variabler:"
-
msgid "ProjectSettings|Target project"
msgstr "MÃ¥lprojekt"
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr "iOS (Swift)"
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr "Projekter"
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr "Funktionen er låst."
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr "Prøv det gratis"
@@ -28139,9 +28567,6 @@ msgstr "Opgrader din plan for at aktivere avanceret søgning."
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr "Opgrader din plan for at aktivere gruppewebhooks."
@@ -28166,9 +28591,6 @@ msgstr "Vægtning af din problemstilling"
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr "Når du har mange problemstillinger, så kan det være svært at få et overblik. Ved at tilføje en vægt til dine problemstillinger kan du bedre få en ide om den indtast, omkostning, krævede tid og værdien af hver, og dermed bedre vil kunne håndtere dem."
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr "Gren"
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr "Gren:"
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr "Kodeejergodkendelse til/fra"
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr "Hvad er beskyttede grene?"
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr "%{environment_name} vil være skrivbar for udviklere. Er du sikker?"
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "Dit miljø har fået fjernet sin beskyttelse"
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr "Beskyttede mærkater"
msgid "ProtectedTag|What are protected tags?"
msgstr "Hvad er beskyttede mærkater?"
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr "Protip: %{linkStart}Auto DevOps%{linkEnd} bruger Kubernetes-klynger til at udsende din kode!"
@@ -28583,6 +29020,12 @@ msgstr "Hurtigområde"
msgid "Quickly and easily edit multiple files in your project."
msgstr "Hurtig of let redigering af flere filer i dit projekt."
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr "README"
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr "Regenerer nøgle"
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr "Tilmeld med totrinsprogram"
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr "Fjernede tidsestimat."
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr "Genoptag"
msgid "Resync"
msgstr "Synkroniser igen"
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr "Prøv igen"
@@ -29835,6 +30326,12 @@ msgstr "Prøv job igen"
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr "Prøv jobbet igen"
@@ -30031,9 +30528,6 @@ msgstr "Der er opstået en fejl under hentning af instruktioner"
msgid "Runners|Architecture"
msgstr "Arkitektur"
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr "Er du sikker på, at du vil slette runneren?"
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr "Udsend GitLab Runner i AWS"
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr "Navn"
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr "Ny registreringstoken genereret!"
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr "Runner"
msgid "Runners|Runner #%{runner_id}"
msgstr "Runner #%{runner_id}"
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr "Noget gik galt under hentning af runnerdata."
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr "Noget fik galt under hentning af mærkatforslagene"
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr "Stop runneren i at acceptere nye job."
msgid "Runners|Tags"
msgstr "Mærkater"
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr "gruppe"
msgid "Runners|locked"
msgstr "låst"
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr "delt"
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr "Kører"
@@ -30574,6 +31089,9 @@ msgstr "Søg efter teksten"
msgid "Search forks"
msgstr "Søg efter forgreninger"
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr "Søg efter gennemløb"
@@ -30595,9 +31113,6 @@ msgstr "Søg efter eller filtrér resultater ..."
msgid "Search or filter results…"
msgstr "Søg efter eller filtrér resultater …"
-msgid "Search or jump to..."
-msgstr "Søg eller hop til ..."
-
msgid "Search project"
msgstr "Søg efter projekt"
@@ -30878,6 +31393,9 @@ msgstr "Aktivér %{feature}"
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr "Aktivér Auto DevOps"
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr "Aktiveret"
@@ -30950,6 +31468,9 @@ msgstr "%{branches} %{plural}"
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr "%{branches} og %{lastBranch} %{plural}"
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr "Netværk"
msgid "SecurityOrchestration|New policy"
msgstr "Nyt regelsæt"
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr "Kun ejere kan opdatere sikkerhedsregelsætprojekt"
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr "vis resultater"
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr "+%{count} mere"
@@ -31289,6 +31810,9 @@ msgstr "Indstil status"
msgid "SecurityReports|Severity"
msgstr "Alvorlighed"
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr "Status"
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr "Din feedback er vigtig for os! Vi spørger igen om en uge."
@@ -31529,6 +32059,9 @@ msgstr "Vælg projekt og zone for at vælge maskintype"
msgid "Select project to choose zone"
msgstr "Vælg projekt for at vælge zone"
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr "Indstil forfaldsdato"
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr "Indstil gennemløb"
@@ -32036,6 +32575,9 @@ msgstr "Din status nulstilles %{date}."
msgid "Sets %{epic_ref} as parent epic."
msgstr "Indstiller %{epic_ref} som forælderepic."
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr "Noget gik galt under opdatering af et krav."
msgid "Something went wrong while updating assignees"
msgstr "Noget gik galt under opdatering af tildelere"
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr "Noget gik galt under opdatering af dine listeindstillinger"
@@ -33179,9 +33724,6 @@ msgstr "Start din gratis Ultimate-prøveperiode"
msgid "Start your free trial"
msgstr "Start din gratis prøveperiode"
-msgid "Start your trial"
-msgstr "Start din prøveperiode"
-
msgid "Started"
msgstr "Startet"
@@ -33578,6 +34120,12 @@ msgstr "Abonnement oprettet."
msgid "Subscription successfully deleted."
msgstr "Abonnement slettet."
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr "Tilføj sæder"
@@ -34013,6 +34561,24 @@ msgstr "Syntaksen er korrekt."
msgid "Syntax is incorrect."
msgstr "Syntaksen er forkert."
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr "System"
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] "%{number} Terraform-rapport blev genereret i dine pipelines"
msgstr[1] "%{number} Terraform-rapporter blev genereret i dine pipelines"
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr "%{user} opdateret %{timeAgo}"
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr "En rapport kunne ikke genereres."
@@ -34314,6 +34896,9 @@ msgstr "Detaljer"
msgid "Terraform|Download JSON"
msgstr "Download JSON"
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr "Generering af rapporten forårsagede en fejl."
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr "Jobstatus"
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr "LÃ¥s"
@@ -34362,12 +34950,21 @@ msgstr "Tilstande"
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr "Sammenligningsvisningen kan være upræcis pga. sammenlægningskonflikte
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr "Gruppeeksporten kan downloades fra:"
@@ -34787,9 +35384,6 @@ msgstr "Gruppen er allerede blevet delt med gruppen"
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr "Gruppeindstillingerne for %{group_links} kræver at du aktivere totrinsgodkendelse for din konto. Du kan %{leave_group_links}."
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr "Parameteren group_project_ids er kun tilladt til en gruppe"
@@ -34862,7 +35456,7 @@ msgstr "Den maksimale filstørrelse i megabytes for individuelle jobartefakter."
msgid "The maximum file size is %{size}."
msgstr "Den maksimale tilladte filstørrelse er %{size}."
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr "Der er ingen problemstillinger at vise"
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr "Der er endnu ingen etiketter"
-
msgid "There are no matching files"
msgstr "Der er ingen matchende filer"
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr "Handlingen er blevet udført for mange gange. Prøv igen senere."
-
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 ""
@@ -35504,6 +36095,9 @@ msgstr "Programmet blev oprettet til gruppen %{group_link}."
msgid "This application will be able to:"
msgstr "Programmet vil være i stand til at:"
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr "Vedhæftningen er blevet afkortet for ikke at overstige den maksimale tilladte vedhæftningsstørrelse på %{size_limit}. %{written_count} af %{count} %{issuables} er blevet medtaget. Overvej at eksportere igen med et mindre udvalg af %{issuables}."
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
msgstr "Gruppen"
+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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr "Jobbet kræver en manuel handling"
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ msgstr "Log ind på GitLab på %{gitlab_url} for at genaktivere din konto."
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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr "Gøremålselement mærket som færdig."
msgid "Today"
msgstr "I dag"
+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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr "GitLab Next til/fra"
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr "Overfør"
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr "Overfør ejerskab"
@@ -36857,15 +37496,6 @@ msgstr "Fornavn"
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr "GitLab Ultimate-prøveperiode (valgfrit)"
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr "Hej%{salutation}, din GitLab Ultimate-prøveperiode varer 30 dage, men du kan beholde din gratis GitLab-konto for evigt. Vi har blot brug for nogle yderligere informationer om %{company} for at aktivere din prøveperiode."
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr "Hvor mange medarbejdere kommer til at bruge Gitlab?"
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr "Efternavn"
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr "Din GitLab Ultimate-prøveperiode varer 30 dage, men du kan beholde din gratis GitLab-konto for evigt. Vi har blot brug for nogle yderligere informationer for at aktivere din prøveperiode."
-msgid "Trial|your company"
-msgstr "din virksomhed"
-
msgid "Trigger"
msgstr "Udløser"
@@ -37520,9 +38147,6 @@ msgstr "klik for at uploade"
msgid "Uploading changes to terminal"
msgstr "Uploader ændringer til terminal"
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr "Når handlingen udføres, så slettes indholdet i gruppen, dens undergrupper og projekter permanent efter %{deletion_adjourned_period} dage %{date}. Indtil da:"
-
msgid "Upstream"
msgstr "Upstream"
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr "Vis alle miljøer."
msgid "View all issues"
msgstr "Vis alle problemstillinger"
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr "Vis detaljer: %{details_url}"
msgid "View documentation"
msgstr "Vis dokumentation"
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr "Vis kvalificerede godkendere"
@@ -38517,6 +39147,12 @@ msgstr "Vis gruppe i administratorområde"
msgid "View group labels"
msgstr "Vis gruppeetiketter"
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr "Vist"
msgid "Viewing commit"
msgstr "Viser commit"
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr "Synlighed"
@@ -38690,12 +39329,24 @@ msgstr "%{statusStart}Afskediget%{statusEnd} %{timeago} af %{user}"
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr "%{statusStart}Løst%{statusEnd} %{timeago} af %{user}"
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr "Ændr status"
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+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."
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr "Yderligere information"
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr "Klasse"
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr "Kommentarer"
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr "Beskrivelse"
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr "Download"
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr "Fil"
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr "Billede"
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr "Links"
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr "Alvorlighed"
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr "Vi bruger det til at hjælpe med at fremfinde de rette funktioner og information til dig."
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr "Vi fandt ingen sårbarheder"
@@ -39068,6 +39758,12 @@ msgstr "Hændelser for udsendelse"
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr "Hændelser for funktionsflag"
@@ -39104,6 +39800,15 @@ msgstr "Hændelser for undergruppe"
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr "Udløser"
@@ -39161,6 +39866,15 @@ msgstr "URL'en skal være procentkodet hvis det er nødvendigt."
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr "Hændelser for wikiside"
@@ -39197,6 +39911,9 @@ msgstr "Velkommen til GitLab,%{br_tag}%{name}!"
msgid "Welcome, %{name}!"
msgstr "Velkommen, %{name}!"
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr "Hvad søger du?"
@@ -40044,6 +40758,12 @@ msgstr "Du har ikke tilstrækkelige tilladelser til at opdatere HTTP-integrering
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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr "Du har ingen tilladelser"
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr "Der blev logget ind på din %{host}-konto fra en ny placering"
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
msgstr "Dit abonnement udløb!"
+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 ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] "Dit abonnement vil udløbe om %{remaining_days} dag."
@@ -40764,6 +41493,9 @@ msgstr "må ikke selv blokeres"
msgid "cannot merge"
msgstr "kan ikke sammenlægge"
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr "commit %{commit_id}"
msgid "committed"
msgstr "committed"
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr "mangler"
-msgid "more information"
-msgstr "mere information"
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr "skal være et rodnavnerum"
msgid "must be a valid IPv4 or IPv6 address"
msgstr "skal være en gyldig IPv4- eller IPv6-adresse"
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr "skal være efter start"
@@ -42001,9 +42736,6 @@ msgstr "Ã¥bnet %{timeAgo}"
msgid "or"
msgstr "eller"
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/de/gitlab.po b/locale/de/gitlab.po
index a64941b8c82..ccd4eff4bf3 100644
--- a/locale/de/gitlab.po
+++ b/locale/de/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: de\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:58\n"
+"PO-Revision-Date: 2022-01-06 17:22\n"
msgid " %{start} to %{end}"
msgstr " %{start} bis %{end}"
@@ -78,13 +78,13 @@ msgstr "#allgemein, #entwicklung"
msgid "%d Alert"
msgid_plural "%d Alerts"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d Warnung"
+msgstr[1] "%d Warnungen"
msgid "%d Alert:"
msgid_plural "%d Alerts:"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d Warnung:"
+msgstr[1] "%d Warnungen:"
msgid "%d Approval"
msgid_plural "%d Approvals"
@@ -233,13 +233,13 @@ msgstr[1] "%d Dateien"
msgid "%d fixed test result"
msgid_plural "%d fixed test results"
-msgstr[0] "%d festes Testergebnis"
-msgstr[1] "%d feste Testergebnisse"
+msgstr[0] ""
+msgstr[1] ""
msgid "%d fork"
msgid_plural "%d forks"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d Fork"
+msgstr[1] "%d Forks"
msgid "%d group"
msgid_plural "%d groups"
@@ -503,8 +503,8 @@ msgstr "%{count} Zustimmungen von %{name}"
msgid "%{count} contact"
msgid_plural "%{count} contacts"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{count} Kontakt"
+msgstr[1] "%{count} Kontakte"
msgid "%{count} files touched"
msgstr "%{count} Dateien verändert"
@@ -563,8 +563,8 @@ msgstr "%{deployLinkStart}Verwende eine Vorlage für die Bereitstellung in ECS%{
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr "%{description}- Sentry-Event: %{errorUrl}- Zuerst gesehen: %{firstSeen}- Zuletzt gesehen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
-msgstr "%{doc_link_start}Erweiterte Suche%{doc_link_end} ist deaktiviert, da %{ref_elem} nicht der Standard-Branch ist. %{default_branch_link_start}Suche auf %{default_branch} statt%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
+msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
msgstr "%{doc_link_start}Erweiterte Suche%{doc_link_end} ist aktiviert."
@@ -809,19 +809,19 @@ msgid "%{number_commits_behind} commits behind %{default_branch}, %{number_commi
msgstr "%{number_commits_behind} Commits hinter %{default_branch}, %{number_commits_ahead} Commits voraus"
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 ""
+msgstr "%{openedEpics} offen, %{closedEpics} geschlossen"
msgid "%{openedIssues} open, %{closedIssues} closed"
-msgstr ""
+msgstr "%{openedIssues} offen, %{closedIssues} geschlossen"
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
@@ -853,16 +856,16 @@ msgstr[0] "%{releases} Release"
msgstr[1] "%{releases} Releases"
msgid "%{remaining_approvals} left"
-msgstr ""
+msgstr "%{remaining_approvals} übrig"
msgid "%{reportType} %{status}"
-msgstr ""
+msgstr "%{reportType} %{status}"
msgid "%{reportType} detected %{totalStart}%{total}%{totalEnd} potential %{vulnMessage}"
-msgstr ""
+msgstr "%{reportType} erkannte %{totalStart}%{total}%{totalEnd} eventuell %{vulnMessage}"
msgid "%{reportType} detected %{totalStart}no%{totalEnd} vulnerabilities."
-msgstr ""
+msgstr "%{reportType} hat %{totalStart} keine %{totalEnd} Sicherheitslücken erkannt."
msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}."
msgstr ""
@@ -874,29 +877,29 @@ msgid "%{rotation} has been recalculated with the remaining participants. Please
msgstr "%{rotation} wurde mit den verbliebenen Beteiligten neu errechnet. Bitte die neue Einrichtung für %{rotation} überprüfen. Wir empfehlen, sich mit den aktuellen Bereitschaftsverantwortlichen in Verbindung zu setzen, um eine kontinuierliche Anrufbereitschaft sicherzustellen."
msgid "%{scope} results for term '%{term}'"
-msgstr ""
+msgstr "%{scope} Ergebnisse für Suchwort '%{term}'"
msgid "%{search} %{description} %{scope}"
-msgstr ""
+msgstr "%{search} %{description} %{scope}"
msgid "%{seconds}s"
msgstr ""
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} ist für dieses Projekt nicht aktiviert. %{linkStart}Weitere Informationen%{linkEnd}"
+msgstr[1] "%{securityScanner} sind für dieses Projekt nicht aktiviert. %{linkStart}Weitere Informationen%{linkEnd}"
msgid "%{securityScanner} result is not available because a pipeline has not been run since it was enabled. %{linkStart}Run a pipeline%{linkEnd}"
msgid_plural "%{securityScanner} results are not available because a pipeline has not been run since it was enabled. %{linkStart}Run a pipeline%{linkEnd}"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Kein Ergebnis aus %{securityScanner} verfügbar, da keine Pipeline seit der Aktivierung ausgeführt wurde. %{linkStart}Eine Pipeline ausführen%{linkEnd}"
+msgstr[1] "%{securityScanner}-Ergebnisse sind nicht verfügbar, da keine Pipeline seit der Aktivierung ausgeführt wurde. %{linkStart}Eine Pipeline ausführen%{linkEnd}"
msgid "%{service_ping_link_start}What information is shared with GitLab Inc.?%{service_ping_link_end}"
-msgstr ""
+msgstr "%{service_ping_link_start}Welche Informationen werden mit GitLab Inc. geteilt.?%{service_ping_link_end}"
msgid "%{size} %{unit}"
-msgstr ""
+msgstr "%{size} %{unit}"
msgid "%{size} GiB"
msgstr "%{size} GiB"
@@ -911,25 +914,25 @@ msgid "%{size} bytes"
msgstr "%{size} Bytes"
msgid "%{sourceBranch} into %{targetBranch}"
-msgstr ""
+msgstr "%{sourceBranch} in %{targetBranch}"
msgid "%{spammable_titlecase} was submitted to Akismet successfully."
msgstr "%{spammable_titlecase} wurde erfolgreich an Akismet übermittelt."
msgid "%{spanStart}at line%{spanEnd} %{errorLine}%{errorColumn}"
-msgstr ""
+msgstr "%{spanStart}in Zeile%{spanEnd} %{errorLine}%{errorColumn}"
msgid "%{spanStart}in%{spanEnd} %{errorFn}"
-msgstr ""
+msgstr "%{spanStart}in%{spanEnd} %{errorFn}"
msgid "%{start} to %{end}"
msgstr "%{start} bis %{end}"
msgid "%{strongOpen}Warning:%{strongClose} SAML group links can cause GitLab to automatically remove members from groups."
-msgstr ""
+msgstr "%{strongOpen}Warnung:%{strongClose} SAML Gruppen-Links können GitLab dazu veranlassen, automatisch Mitglieder aus Gruppen zu entfernen."
msgid "%{strongStart}Tip:%{strongEnd} You can also checkout merge requests locally by %{linkStart}following these guidelines%{linkEnd}"
-msgstr ""
+msgstr "%{strongStart}Tipp:%{strongEnd} Du kannst Merge-Requests auch lokal auschecken, indem du %{linkStart}diese Richtlinien%{linkEnd} befolgst."
msgid "%{strong_start}%{branch_count}%{strong_end} Branch"
msgid_plural "%{strong_start}%{branch_count}%{strong_end} Branches"
@@ -1035,6 +1038,12 @@ msgstr "Avatar von %{userName}"
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr "%{user_name} (%{user_username}) wurde von %{rotation} in %{schedule} in %{project} entfernt. "
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr "Profileseite von %{user_name}"
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr "(entfernt)"
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ", oder "
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr "Ein Projekt, das Tickets für jede Prüfanfrage im HIPAA-Prüfprotokoll
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr "Sind Sie sicher? Jegliche RSS- oder Kalender-Links, die aktuell genutzt
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr "Sind Sie sicher? Jegliche betroffene E-Mail-Adressen, die aktuell genutzt werden aufhören zu funktionieren."
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr "Erstellt"
@@ -1802,12 +1829,21 @@ msgstr "Token für eingehende E-Mails"
msgid "AccessTokens|It cannot be used to access any other data."
msgstr "Es kann nicht für den Zugriff auf andere Daten verwendet werden."
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr "Konto: %{account}"
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr "Aktive Sitzungen"
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "Aktivität"
@@ -1994,7 +2063,7 @@ msgstr "Tabelle hinzufügen"
msgid "Add a task list"
msgstr "Eine Aufgabenliste hinzufügen"
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "Fehler beim Laden der Statistik. Bitte versuche es erneut"
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr "Benutzer(in) löschen"
msgid "AdminUsers|Delete user and contributions"
msgstr "Benutzer(in) und Beiträge löschen"
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr "Alle Gruppen und Projekte"
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr "Alle Tickets für diesen Meilenstein sind geschlossen."
@@ -3575,6 +3659,9 @@ msgstr "Es ist ein Fehler aufgetreten"
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr "Beim Hinzufügen eines Entwurfs zur Diskussion ist ein Fehler aufgetreten."
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr "Bei der Vorschau des Blobs ist ein Fehler aufgetreten"
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr "Beim Laden der Daten trat ein Fehler auf. Bitte versuche es erneut."
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] "%{count} Zustimmungen von %{membersCount} nötig"
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr "Genehmigungsberechtigte(r)"
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr "Name"
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr "Möchtest du den öffentlichen Schlüssel wirklich neu generieren? Du musst dann den öffentlichen Schlüssel auf dem Remote-Server aktualisieren, bevor die Spiegelung wieder funktioniert."
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr "Einige Tickets diesem Meilenstein zuordnen."
@@ -5118,9 +5238,6 @@ msgstr "Verfügbare spezifische Runner"
msgid "Avatar for %{assigneeName}"
msgstr "Avatar von %{assigneeName}"
-msgid "Avatar for %{name}"
-msgstr "Avatar von %{name}"
-
msgid "Avatar will be removed. Are you sure?"
msgstr "Avatar wird entfernt. Bist du sicher?"
@@ -5370,9 +5487,6 @@ msgstr "monatlich"
msgid "BillingPlans|per user"
msgstr "je Benutzer(in)"
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr ""
-
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr "Boards"
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr "Parallelität von Massenanfragen"
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr "Überprüfe Verfügbarkeit des Benutzernamens..."
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr "Wähle eine Farbe."
msgid "Choose file…"
msgstr "Datei auswählen…"
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr "Wählen Sie bestimmte Gruppen oder Speicherfragmente aus"
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr "Letzte Suchen löschen"
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr "Gewichtung entfernt."
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr "Neues Label erstellen"
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr "Neu erstellen..."
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr "Datumsauswahl"
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr "Gelöscht"
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr "CSV herunterladen"
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr "Artefakte herunterladen"
@@ -12599,8 +12835,8 @@ msgstr "Meilenstein bearbeiten"
msgid "Edit Password"
msgstr "Passwort ändern"
-msgid "Edit Pipeline Schedule %{id}"
-msgstr "Pipeline-Zeitplan bearbeiten %{id}"
+msgid "Edit Pipeline Schedule"
+msgstr ""
msgid "Edit Release"
msgstr "Release bearbeiten"
@@ -12638,6 +12874,9 @@ msgstr "Beschreibung bearbeiten"
msgid "Edit environment"
msgstr "Umgebung bearbeiten"
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr "Bearbeite Dateien im Editor und committe die Änderungen hier"
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr "Fehler beim Laden des Merge-Requests. Bitte versuche es erneut."
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr "Vom Umsetzen des Merge Request bis zur Bereitstellung auf dem Produktivs
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr "Gruppen-SAML muss zum Testen aktiviert sein"
msgid "Group URL"
msgstr "Gruppen-URL"
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr "Gruppe: %{group_name}"
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr "Badges"
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr "Pipeline-Einstellungen wurden für die Gruppe aktualisiert"
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr "Du kannst die Berechtigungen deiner Gruppenmitglieder und den Zugriff au
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr "Board"
@@ -20106,8 +20378,8 @@ msgstr "Komplette Rohdaten"
msgid "Job|Download"
msgstr "Herunterladen"
-msgid "Job|Erase job log"
-msgstr "Jobprotokoll löschen"
+msgid "Job|Erase job log and artifacts"
+msgstr ""
msgid "Job|Job artifacts"
msgstr "Jobartefakte"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr "Metriken und Profiling"
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr "Hilfe"
@@ -23212,6 +23529,9 @@ msgstr "Neu"
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr "Neue Anwendung"
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr "Hinweis: Ãœberlege dir, deine(n) GitLab-Administrator(in) zu bitten, ein
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr "Hinweis: Überlege dir, deine(n) GitLab Administrator(in) zu bitten, einen %{github_integration_link} zu konfigurieren. Mit diesem kannst du dich über GitHub anmelden und Repositories importieren, ohne einen persönlichen Access-Token generieren zu müssen."
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr "Bist du sicher, dass du die Erstellung dieses Kommentars abbrechen möch
msgid "Notes|Collapse replies"
msgstr "Antworten reduzieren"
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr "Operations Dashboard"
@@ -25088,9 +25450,6 @@ msgstr "Seite nicht gefunden"
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr "Wartend"
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr "Ungültiges Kennwort"
msgid "Profiles|Invalid username"
msgstr "Ungültiger Benutzername"
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr "Private Beiträge"
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr "Benutzername erfolgreich geändert"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr "Was ist dein Status?"
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr "Projekt ID: %{project_id}"
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr "Projekte"
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr "Diese Funktion ist gesperrt."
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr "%{environment_name} wird für Entwickler änderbar sein. Bist du sicher?"
@@ -28340,6 +28771,9 @@ msgstr "Deine Umgebung wurde geschützt."
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "Der Schutz deiner Umgebung wurde aufgehoben"
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr "Instanz-ID neu generieren"
-msgid "Regenerate key"
-msgstr "Schlüssel neu generieren"
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr "Fortsetzen"
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr "Wiederholen"
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr "Wiederhole diese Aufgabe"
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr "Laufend"
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr "Suche oder filtere Ergebnisse..."
msgid "Search or filter results…"
msgstr "Suchen oder Ergebnisse filtern…"
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr "Projekt suchen"
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr "Wähle ein Projekt und eine Zone, um den Maschinentyp auszuwählen"
msgid "Select project to choose zone"
msgstr "Wähle ein Projekt aus, um die Zone auszuwählen"
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr "Lege die Standardeinstellungen fest und beschränke die Sichtbarkeitsstu
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33135,7 +33680,7 @@ msgid "Start Web Terminal"
msgstr ""
msgid "Start a %{new_merge_request} with these changes"
-msgstr "Beginne einen %{new_merge_request} mit diesen Änderungen"
+msgstr "%{new_merge_request} mit diesen Änderungen"
msgid "Start a Free Ultimate Trial"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr "Testzeitraum beginnen"
-
msgid "Started"
msgstr "Begonnen"
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "Die Verbindung wird nach %{timeout} beendet. Verwende eine Clone/Push-Kombination für Repositorys, die länger brauchen."
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr "Es gibt keine Tickets die angezeigt werden können"
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr "Es gibt noch keine Labels"
-
msgid "There are no matching files"
msgstr "Es gibt keine passenden Dateien"
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr "Diese Anwendung wird in der Lage sein:"
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
msgstr "Diese Gruppe"
+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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr "Dieser Job erfordert eine manuelle Aktion"
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
msgstr "Heute"
+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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr "Zum Upload klicken"
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr "Alle Tickets anzeigen"
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr "Geeignete Genehmigungsberechtigte anzeigen"
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr "Gruppenlabels ansehen"
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr "Klasse"
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr "Beschreibung"
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr "Datei"
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr "Bezeichner"
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr "Links"
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr "Schweregrad"
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr "Du hast keine Berechtigungen"
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr "fehlt"
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr "letzte Bereitstellung"
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr "erstellt %{timeAgo}"
msgid "or"
msgstr "oder"
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/el_GR/gitlab.po b/locale/el_GR/gitlab.po
index 48c3723a4a9..5b12b90aa40 100644
--- a/locale/el_GR/gitlab.po
+++ b/locale/el_GR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: el\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:58\n"
+"PO-Revision-Date: 2022-01-06 17:22\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/eo/gitlab.po b/locale/eo/gitlab.po
index c05c47362b3..8b08938d39c 100644
--- a/locale/eo/gitlab.po
+++ b/locale/eo/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: eo\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 19:00\n"
+"PO-Revision-Date: 2022-01-06 17:24\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "Aktiveco"
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr "Krei novan…"
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,8 +12835,8 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
-msgstr "Redakti ĉenstablan planon %{id}"
+msgid "Edit Pipeline Schedule"
+msgstr ""
msgid "Edit Release"
msgstr ""
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr "De la kunfandado de la peto pri kunfando Äis la disponigado en la publi
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr "alklaku por alÅuti"
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/es/gitlab.po b/locale/es/gitlab.po
index 52565e9fd8c..5bb9c3f1ba4 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: 2021-12-06 18:57\n"
+"PO-Revision-Date: 2022-01-06 17:21\n"
msgid " %{start} to %{end}"
msgstr " %{start} hasta %{end}"
@@ -71,20 +71,20 @@ msgid "\"%{repository_name}\" size (%{repository_size}) is larger than the limit
msgstr "El tamaño de \"%{repository_name}(%{repository_size}) es mayor que el límite de %{limit}."
msgid "#%{issueIid} (closed)"
-msgstr ""
+msgstr "#%{issueIid} (cerrado)"
msgid "#general, #development"
msgstr "#general, #desarrollo"
msgid "%d Alert"
msgid_plural "%d Alerts"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d Alerta"
+msgstr[1] "%d Alertas"
msgid "%d Alert:"
msgid_plural "%d Alerts:"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d Alerta:"
+msgstr[1] "%d Alertas:"
msgid "%d Approval"
msgid_plural "%d Approvals"
@@ -93,8 +93,8 @@ msgstr[1] "%d autorizaciones"
msgid "%d Module"
msgid_plural "%d Modules"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d módulo"
+msgstr[1] "%d módulos"
msgid "%d Other"
msgid_plural "%d Others"
@@ -168,8 +168,8 @@ msgstr[1] "%d commits"
msgid "%d commit author"
msgid_plural "%d commit authors"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d autor del commit"
+msgstr[1] "%d autores del commit"
msgid "%d commit behind"
msgid_plural "%d commits behind"
@@ -503,8 +503,8 @@ msgstr "%{count} aprobaciones de %{name}"
msgid "%{count} contact"
msgid_plural "%{count} contacts"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{count} contacto"
+msgstr[1] "%{count} contactos"
msgid "%{count} files touched"
msgstr "%{count} archivos modificados"
@@ -563,7 +563,7 @@ msgstr "%{deployLinkStart}Utilice una plantilla para implementar en ECS%{deployL
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr "%{description}- Evento de Sentry: %{errorUrl}- Visto por primera vez: %{firstSeen}- Visto por última vez: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -711,7 +711,7 @@ msgid "%{learn_more_link}."
msgstr ""
msgid "%{lessThan} 1 hour"
-msgstr ""
+msgstr "%{lessThan} 1 hora"
msgid "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} is a free, automated, and open certificate authority (CA) that issues digital certificates to enable HTTPS (SSL/TLS) for sites."
msgstr "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} es una autoridad de certificación gratuita, automatizada, y abierta que genera certificados digitales para habilitar HTTPS para sitios web."
@@ -838,6 +838,9 @@ msgstr "%{placeholder} no es un esquema de color válido"
msgid "%{placeholder} is not a valid theme"
msgstr "%{placeholder} no es un tema válido"
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
@@ -874,7 +877,7 @@ msgid "%{rotation} has been recalculated with the remaining participants. Please
msgstr ""
msgid "%{scope} results for term '%{term}'"
-msgstr ""
+msgstr "%{scope} resultados para el término '%{term}'"
msgid "%{search} %{description} %{scope}"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr "Avatar de %{userName}"
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr "%{user_name} página de perfil"
@@ -1151,6 +1160,9 @@ msgstr "(Déjelo en blanco si no quiere cambiarlo)"
msgid "(max size 15 MB)"
msgstr "(tamaño máximo 15 MB)"
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr "(eliminado)"
@@ -1163,16 +1175,16 @@ msgstr[0] ""
msgstr[1] ""
msgid "(this user)"
-msgstr ""
+msgstr "(este usuario)"
msgid "(we need your current password to confirm your changes)"
msgstr "(Necesitamos su contraseña actual para confirmar sus cambios)"
msgid "* All times are in UTC unless specified"
-msgstr ""
+msgstr "* Todas las horas están en UTC a menos que se especifique"
msgid "*Required"
-msgstr ""
+msgstr "*Requerido"
msgid "+ %{amount} more"
msgstr "+ %{amount} más"
@@ -1213,11 +1225,14 @@ msgid "+%{tags} more"
msgstr "+%{tags} más"
msgid ", and "
-msgstr ""
+msgstr ", y "
msgid ", or "
msgstr ", o "
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr "- Disponible para ejecutar trabajos."
@@ -1230,7 +1245,7 @@ msgid "- Not available to run jobs."
msgstr "- No disponible para ejecutar trabajos."
msgid "- Select -"
-msgstr ""
+msgstr "- Seleccione -"
msgid "- User"
msgid_plural "- Users"
@@ -1247,7 +1262,7 @@ msgid "."
msgstr "."
msgid "/"
-msgstr ""
+msgstr "/"
msgid "0 bytes"
msgstr "0 bytes"
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr "Una plantilla lista para utilizar con aplicaciones de Android"
@@ -1790,6 +1808,15 @@ msgstr "¿Está seguro? Cualquier RSS o URLs de calendarios que esté utilizando
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr "¿Está seguro? Cualquier dirección de correo electrónico de incidencias que esté utilizando dejará de funcionar."
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr "Creado"
@@ -1802,12 +1829,21 @@ msgstr "Token de correo entrante"
msgid "AccessTokens|It cannot be used to access any other data."
msgstr "No se puede utilizar para acceder a ningún otro dato."
+msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{linkStart}reset this token%{linkEnd}."
+msgstr ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr "Mantenga este token en secreto. Cualquiera que lo tenga puede acceder a los objetos estáticos del repositorio como si fuera usted. Si eso sucede alguna vez, %{reset_link_start}reinice este token%{reset_link_end}."
+msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{linkStart}reset this token%{linkEnd}."
+msgstr ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr "Mantenga este token en secreto. Cualquiera que lo tenga puede crear incidencias como si fuera usted. Si eso sucede, %{link_reset_it}."
+msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{linkStart}reset this token%{linkEnd}."
+msgstr ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr "Mantenga este token en secreto. Cualquiera que lo tenga puede leer la actividad o crear anuncios RSS o anuncios en su calendario como si fuera usted. Si eso sucede, %{link_reset_it}."
@@ -1865,6 +1901,36 @@ msgstr "Cuenta:"
msgid "Account: %{account}"
msgstr "Cuenta: %{account}"
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr "Acción"
@@ -1878,7 +1944,7 @@ msgid "Activate Service Desk"
msgstr "Activar Service Desk"
msgid "Activated on"
-msgstr ""
+msgstr "Activado el"
msgid "Active"
msgstr "Activo"
@@ -1889,11 +1955,14 @@ msgstr "Activo %{type} (%{token_length})"
msgid "Active Sessions"
msgstr "Sesiones activas"
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "Actividad"
msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
-msgstr ""
+msgstr "Se ha producido un error al recuperar la actividad. Por favor, recargue la página para volver a intentarlo."
msgid "Add"
msgstr "Añadir"
@@ -1994,7 +2063,7 @@ msgstr "Añadir tabla"
msgid "Add a task list"
msgstr "Añadir una lista de tareas"
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "Se ha producido un error al cargar las estadísticas. Por favor, inténtalo de nuevo"
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,8 +2774,8 @@ msgstr "Eliminar usuario"
msgid "AdminUsers|Delete user and contributions"
msgstr "Eliminar el usuario y sus colaboraciones"
-msgid "AdminUsers|Export permissions as CSV"
-msgstr "Exportar permisos como CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
+msgstr ""
msgid "AdminUsers|External"
msgstr "Externos"
@@ -2790,7 +2868,7 @@ msgid "AdminUsers|The user can't access git repositories."
msgstr ""
msgid "AdminUsers|The user can't log in."
-msgstr ""
+msgstr "El usuario no puede iniciar sesión."
msgid "AdminUsers|The user will be logged out"
msgstr "El usuario será desconectado"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr "Todas las tareas épicas"
msgid "All groups and projects"
msgstr "Todos los grupos y proyectos"
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr "Todos las incidencias de este hito están cerradas."
@@ -3575,6 +3659,9 @@ msgstr "Se ha producido un error"
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr "Se ha producido un error al agregar un borrador a la discusión."
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr "Ha ocurrido un error visualizando el blob"
-msgid "An error occurred when removing the label."
-msgstr "Se ha producido un error al eliminar la etiqueta."
-
msgid "An error occurred when updating the title"
msgstr "Se ha producido un error al actualizar el título"
@@ -3785,6 +3869,9 @@ msgstr "Se ha producido un error al cargar los merge requests."
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr "Se ha producido un error al cargar el formulario de tokens de acceso. Por favor, inténtelo de nuevo."
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr "Se ha producido un error al cargar los datos. Por favor, inténtelo de nuevo."
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] "%{count} aprobaciones requeridas para %{membersCount}"
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr "Añadir aprobadores"
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr "Todos los escáneres"
@@ -4305,6 +4407,9 @@ msgstr "Tipo de aprobador"
msgid "ApprovalRule|Approvers"
msgstr "Aprobadores"
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr "Ejemplos: QA, Seguridad."
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr "Nombre"
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr "Niveles de gravedad"
msgid "ApprovalRule|Target branch"
msgstr "Branch de destino"
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr "Vulnerabilidades permitidas"
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr "¿Está seguro de que quiere hacer merge inmediatamente?"
msgid "Are you sure you want to re-deploy this environment?"
msgstr "¿Está seguro de que desea volver a desplegar este entorno?"
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr "¿Seguro que quiere regenerar la clave pública? Deberá actualizar la clave pública en el servidor remoto antes de que la duplicación funcione nuevamente."
-
msgid "Are you sure you want to reindex?"
msgstr "¿Está seguro de que desea reindexar?"
@@ -4721,6 +4838,9 @@ msgstr "Asignar revisor"
msgid "Assign reviewer(s)"
msgstr "Asignar revisores"
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr "Asignar algunas incidencias a este hito."
@@ -5118,9 +5238,6 @@ msgstr "Ejecutores dedicados disponibles"
msgid "Avatar for %{assigneeName}"
msgstr "Avatar para %{assigneeName}"
-msgid "Avatar for %{name}"
-msgstr "Avatar para %{name}"
-
msgid "Avatar will be removed. Are you sure?"
msgstr "El avatar será eliminado. ¿Está seguro?"
@@ -5370,9 +5487,6 @@ msgstr "mensual"
msgid "BillingPlans|per user"
msgstr "por usuario"
-msgid "BillingPlan|Contact sales"
-msgstr "Contactar con ventas"
-
msgid "BillingPlan|Upgrade"
msgstr "Actualizar"
@@ -5403,15 +5517,12 @@ msgstr "Reactivar el periodo de prueba"
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
-msgstr "Usuario validado correctamente"
-
msgid "Billings|User validation required"
msgstr "Es necesaria la validación del usuario"
@@ -5421,7 +5532,10 @@ msgstr "Validar la cuenta"
msgid "Billings|Validate user account"
msgstr "Validar la cuenta de usuario"
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr "Se ha producido un error al cargar la lista de miembros facturables"
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr "Se ha producido un error al eliminar un miembro facturable"
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr "No es posible eliminar al usuario"
@@ -5574,19 +5694,19 @@ msgid "BoardScope|Any assignee"
msgstr "Cualquier asignado"
msgid "BoardScope|Any label"
-msgstr ""
+msgstr "Cualquier etiqueta"
msgid "BoardScope|Assignee"
msgstr "Asignado"
msgid "BoardScope|Choose labels"
-msgstr ""
+msgstr "Elija las etiquetas"
msgid "BoardScope|Edit"
msgstr "Editar"
msgid "BoardScope|Labels"
-msgstr ""
+msgstr "Etiquetas"
msgid "BoardScope|Milestone"
msgstr "Hito"
@@ -5601,7 +5721,7 @@ msgid "BoardScope|Select assignee"
msgstr "Seleccionar asignado"
msgid "BoardScope|Select labels"
-msgstr ""
+msgstr "Seleccione las etiquetas"
msgid "BoardScope|Select milestone"
msgstr "Seleccionar hito"
@@ -5621,8 +5741,8 @@ msgstr ""
msgid "Boards"
msgstr "Tableros"
-msgid "Boards and Board Lists"
-msgstr "Tableros y listas de tableros"
+msgid "Boards and board lists"
+msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
msgid_plural "Boards|+ %{displayedIssuablesCount} more %{issuableType}s"
@@ -5695,7 +5815,7 @@ msgid "Boards|Failed to fetch blocking %{issuableType}s"
msgstr ""
msgid "Boards|New board"
-msgstr ""
+msgstr "Nuevo tablero"
msgid "Boards|New epic"
msgstr "Nueva épica"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr "Grupos existentes"
msgid "BulkImport|Filter by source group"
msgstr "Filtrar por grupo de origen"
+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 ""
+
msgid "BulkImport|From source group"
msgstr "Del grupo de origen"
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr "No hay ningún padre"
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6354,7 +6483,7 @@ msgid "CanaryIngress|%{boldStart}Stable:%{boldEnd} %{stable}"
msgstr ""
msgid "CanaryIngress|Canary"
-msgstr ""
+msgstr "Canary"
msgid "CanaryIngress|Change ratio"
msgstr "Cambiar ratio"
@@ -6462,10 +6591,10 @@ msgid "Capacity threshold"
msgstr "Límite de capacidad"
msgid "Card holder name"
-msgstr ""
+msgstr "Nombre del titular de la tarjeta"
msgid "Card number:"
-msgstr ""
+msgstr "Número de tarjeta:"
msgid "CascadingSettings|Enforce for all subgroups"
msgstr "Forzar para todos los subgrupos"
@@ -6734,7 +6863,7 @@ msgstr "Verificando la disponibilidad del nombres de usuario..."
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6761,7 +6890,7 @@ msgid "Checkout|%{name}'s storage subscription"
msgstr ""
msgid "Checkout|%{quantity} CI minutes"
-msgstr ""
+msgstr "%{quantity} minutos de CI"
msgid "Checkout|%{quantity} GB of storage"
msgstr ""
@@ -6796,7 +6925,7 @@ msgid "Checkout|CI minute packs are only used after you've used your subscriptio
msgstr ""
msgid "Checkout|CI minutes"
-msgstr ""
+msgstr "Minutos de CI"
msgid "Checkout|Checkout"
msgstr ""
@@ -6856,7 +6985,7 @@ msgid "Checkout|Failed to register credit card. Please try again."
msgstr "Se ha producido un error al registrar la tarjeta de crédito. Por favor, inténtelo de nuevo."
msgid "Checkout|GB"
-msgstr ""
+msgstr "GB"
msgid "Checkout|GitLab group"
msgstr "Grupo de GitLab"
@@ -6895,7 +7024,7 @@ msgid "Checkout|State"
msgstr "Estado"
msgid "Checkout|Storage packs"
-msgstr ""
+msgstr "Paquetes de almacenamiento"
msgid "Checkout|Street address"
msgstr "Dirección"
@@ -6919,7 +7048,7 @@ msgid "Checkout|Total minutes: %{quantity}"
msgstr "Minutos totales: %{quantity}"
msgid "Checkout|Total storage: %{quantity} GB"
-msgstr ""
+msgstr "Almacenamiento total: %{quantity} GB"
msgid "Checkout|Users"
msgstr "Usuarios"
@@ -6946,7 +7075,7 @@ msgid "Checkout|company or team"
msgstr "empresa o equipo"
msgid "Checkout|minutes"
-msgstr ""
+msgstr "minutos"
msgid "Checkout|x %{quantity} %{units} per pack"
msgstr ""
@@ -6996,9 +7125,6 @@ msgstr "Elegir cualquier color."
msgid "Choose file…"
msgstr "Seleccione un archivo…"
-msgid "Choose labels"
-msgstr "Seleccione las etiquetas"
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr "Borrar los filtros del gráfico"
msgid "Clear due date"
msgstr "Borrar fecha de vencimiento"
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr "Borrar el historial de búsquedas recientes"
@@ -7227,9 +7356,15 @@ msgstr "Borrar entrada de búsqueda de plantillas"
msgid "Clear weight"
msgstr "Limpiar peso"
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr "Limpiar peso."
@@ -7252,7 +7387,7 @@ msgid "Click to expand text"
msgstr "Haga clic para expandir el texto"
msgid "Click to hide"
-msgstr ""
+msgstr "Clic para ocultar"
msgid "Click to reveal"
msgstr "Haga clic para revelar"
@@ -7273,7 +7408,7 @@ msgid "Clients"
msgstr "Clientes"
msgid "Clientside DSN"
-msgstr ""
+msgstr "DSN del lado del cliente"
msgid "Clone"
msgstr "Clonar"
@@ -7282,7 +7417,7 @@ msgid "Clone repository"
msgstr "Clonar repositorio"
msgid "Clone this issue"
-msgstr ""
+msgstr "Clonar esta incidencia"
msgid "Clone with %{http_label}"
msgstr "Clonar con %{http_label}"
@@ -7303,7 +7438,7 @@ msgid "CloneIssue|Cannot clone issue to target project as it is pending deletion
msgstr "No se puede clonar la incidencia en el proyecto de destino ya que está pendiente de eliminación."
msgid "CloneIssue|Cannot clone issues of '%{issue_type}' type."
-msgstr ""
+msgstr "No se pueden clonar las incidencias de tipo \"%{issue_type}\"."
msgid "Cloned this issue to %{path_to_project}."
msgstr "Clonó esta incidencia en %{path_to_project}."
@@ -7318,13 +7453,13 @@ msgid "Close %{issueType}"
msgstr "Cerrar %{issueType}"
msgid "Close %{noteable}"
-msgstr ""
+msgstr "Cerrar %{noteable}"
msgid "Close %{tabname}"
msgstr "Cerrar %{tabname}"
msgid "Close design"
-msgstr ""
+msgstr "Cerrar diseño"
msgid "Close epic"
msgstr "Cerrar épica"
@@ -7383,30 +7518,51 @@ msgstr "Nivel de clúster"
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} agents"
+msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
+msgid "ClusterAgents|%{number} of %{total} agents"
+msgstr "%{number} de %{total} agentes"
+
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
+msgstr "%{number} de %{total} clústeres conectados a través de certificados de cluster"
+
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
msgstr ""
msgid "ClusterAgents|Access tokens"
msgstr "Tokens de acceso"
msgid "ClusterAgents|Actions"
-msgstr ""
+msgstr "Acciones"
msgid "ClusterAgents|Advanced installation methods"
-msgstr ""
+msgstr "Métodos de instalación avanzados"
msgid "ClusterAgents|Agent"
msgstr ""
-msgid "ClusterAgents|Agent might not be connected to GitLab"
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
msgstr ""
-msgid "ClusterAgents|Agent never connected to GitLab"
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
msgstr ""
+msgid "ClusterAgents|Agent might not be connected to GitLab"
+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|All"
msgstr ""
@@ -7416,9 +7572,15 @@ msgstr "Se ha producido un error al cargar sus agentes de GitLab"
msgid "ClusterAgents|An error occurred while loading your agent"
msgstr "Se ha producido un error al cargar su agente"
+msgid "ClusterAgents|An error occurred while retrieving GitLab Agent activity. Reload the page to try again."
+msgstr ""
+
msgid "ClusterAgents|An unknown error occurred. Please try again."
msgstr "Se ha producido un error desconocido. Por favor, inténtelo de nuevo."
+msgid "ClusterAgents|Are you sure you want to delete this agent? You cannot undo this."
+msgstr ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7444,10 +7606,10 @@ msgid "ClusterAgents|Connect your cluster through the Agent"
msgstr ""
msgid "ClusterAgents|Connected"
-msgstr ""
+msgstr "Conectado"
msgid "ClusterAgents|Connection status"
-msgstr ""
+msgstr "Estado de la conexión"
msgid "ClusterAgents|Copy token"
msgstr "Copiar token"
@@ -7464,12 +7626,21 @@ msgstr "Creado por %{name} %{time}"
msgid "ClusterAgents|Date created"
msgstr "Fecha de creación"
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr "Descripción"
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7489,19 +7660,19 @@ msgid "ClusterAgents|How to register an agent?"
msgstr ""
msgid "ClusterAgents|Install a new agent"
-msgstr ""
+msgstr "Instalar un nuevo agente"
msgid "ClusterAgents|Last connected %{timeAgo}."
-msgstr ""
+msgstr "Última conexión %{timeAgo}"
msgid "ClusterAgents|Last contact"
-msgstr ""
+msgstr "Último contacto"
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr "Aprenda cómo crear un token de acceso del agente"
msgid "ClusterAgents|Learn how to troubleshoot"
-msgstr ""
+msgstr "Aprende a solucionar problemas"
msgid "ClusterAgents|Make sure you are using a valid token."
msgstr ""
@@ -7513,7 +7684,7 @@ msgid "ClusterAgents|Never"
msgstr "Nunca"
msgid "ClusterAgents|Never connected"
-msgstr ""
+msgstr "Nunca se ha conectado"
msgid "ClusterAgents|No agents"
msgstr ""
@@ -7522,7 +7693,7 @@ msgid "ClusterAgents|No clusters connected through cluster certificates"
msgstr ""
msgid "ClusterAgents|Not connected"
-msgstr ""
+msgstr "No está conectado"
msgid "ClusterAgents|Recommended"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr "Token de registro"
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
msgstr "Este agente no tiene tokens"
+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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr "Usuario desconocido"
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -7666,7 +7857,7 @@ msgid "ClusterIntegration|An unknown error occurred while attempting to connect
msgstr ""
msgid "ClusterIntegration|Any project namespaces"
-msgstr ""
+msgstr "Cualquier espacio de nombres de proyecto"
msgid "ClusterIntegration|Apply for credit"
msgstr "Solicitar crédito"
@@ -7690,7 +7881,7 @@ msgid "ClusterIntegration|Certificate Authority bundle (PEM format)"
msgstr "paquete de certificado de autoridad (formato PEM)"
msgid "ClusterIntegration|Check your CA certificate"
-msgstr ""
+msgstr "Verifique su certificado CA"
msgid "ClusterIntegration|Check your cluster status"
msgstr "Verifique el estado de su clúster"
@@ -7717,7 +7908,7 @@ msgid "ClusterIntegration|Clear the local cache of namespace and service account
msgstr ""
msgid "ClusterIntegration|Cluster Region"
-msgstr ""
+msgstr "Región del clúster"
msgid "ClusterIntegration|Cluster management project"
msgstr "Proyecto de gestión de clúster"
@@ -7735,7 +7926,7 @@ msgid "ClusterIntegration|Connect existing cluster"
msgstr "Conectar a un clúster existente"
msgid "ClusterIntegration|Connect with a certificate"
-msgstr ""
+msgstr "Conectar con un certificado"
msgid "ClusterIntegration|Connect your cluster to GitLab through %{linkStart}cluster certificates%{linkEnd}."
msgstr ""
@@ -7810,10 +8001,10 @@ msgid "ClusterIntegration|Elastic Kubernetes Service"
msgstr "Elastic Kubernetes Service"
msgid "ClusterIntegration|Enable Cloud Run for Anthos"
-msgstr ""
+msgstr "Habilitar Cloud Run para Anthos"
msgid "ClusterIntegration|Enable Elastic Stack integration"
-msgstr ""
+msgstr "Habilitar la integración de Elastic Stack"
msgid "ClusterIntegration|Enable Prometheus integration"
msgstr ""
@@ -8170,7 +8361,7 @@ msgid "ClusterIntegration|Select an instance type"
msgstr ""
msgid "ClusterIntegration|Select key pair"
-msgstr ""
+msgstr "Seleccione un par de claves"
msgid "ClusterIntegration|Select machine type"
msgstr "Seleccione el tipo de máquina"
@@ -8185,7 +8376,7 @@ msgid "ClusterIntegration|Select project to choose zone"
msgstr "Seleccione un proyecto para elegir la zona"
msgid "ClusterIntegration|Select service role"
-msgstr ""
+msgstr "Seleccione el rol de servicio"
msgid "ClusterIntegration|Select the key pair name that will be used to create EC2 nodes. To use a new key pair name, first create one on %{linkStart}Amazon Web Services%{linkEnd}."
msgstr ""
@@ -8688,7 +8879,7 @@ msgid "Compliance framework"
msgstr "Framework de cumplimiento"
msgid "Compliance report"
-msgstr ""
+msgstr "Informe de cumplimiento"
msgid "ComplianceDashboard|created by:"
msgstr "Creado por:"
@@ -8697,10 +8888,10 @@ msgid "ComplianceFrameworks|Add framework"
msgstr "Añadir framework"
msgid "ComplianceFrameworks|Background color"
-msgstr ""
+msgstr "Color de fondo"
msgid "ComplianceFrameworks|Cancel"
-msgstr ""
+msgstr "Cancelar"
msgid "ComplianceFrameworks|Compliance framework deleted successfully"
msgstr ""
@@ -8739,13 +8930,13 @@ msgid "ComplianceFrameworks|Error fetching compliance frameworks data. Please re
msgstr ""
msgid "ComplianceFrameworks|Invalid format"
-msgstr ""
+msgstr "Formato no válido"
msgid "ComplianceFrameworks|Name"
-msgstr ""
+msgstr "Nombre"
msgid "ComplianceFrameworks|Name is required"
-msgstr ""
+msgstr "El nombre es obligatorio"
msgid "ComplianceFrameworks|No compliance frameworks are configured"
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr "Componente"
@@ -8988,7 +9188,7 @@ msgid "Contact support"
msgstr "Contactar con soporte"
msgid "Contacts"
-msgstr ""
+msgstr "Contactos"
msgid "Container Registry"
msgstr "Registro de contenedores"
@@ -9000,7 +9200,7 @@ msgid "Container does not exist"
msgstr "El contenedor no existe"
msgid "Container must be a project or a group."
-msgstr ""
+msgstr "El contenedor debe ser un proyecto o un grupo."
msgid "Container registry images"
msgstr "Imágenes del registro de contenedores"
@@ -9012,7 +9212,7 @@ msgid "Container repositories"
msgstr "Repositorios de contenedores"
msgid "Container repositories synchronization concurrency limit"
-msgstr ""
+msgstr "Límite de sincronización de repositorios de contenedores"
msgid "Container repository"
msgstr "Repositorio de contenedores"
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr "Publicado %{timeInfo}"
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr "Copiar entorno"
msgid "Copy evidence SHA"
msgstr "Copia evidencia SHA"
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr "Copia el contenido del archivo"
msgid "Copy file path"
msgstr "Copiar la ruta del archivo"
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr "Copiar clave"
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr "Copiar este token de registro."
-msgid "Copy this value"
-msgstr "Copiar este valor"
-
msgid "Copy to clipboard"
msgstr "Copiar al portapapeles"
@@ -9884,11 +10093,8 @@ msgstr "Crear nueva etiqueta"
msgid "Create new project"
msgstr "Crear nuevo proyecto"
-msgid "Create new..."
-msgstr "Crear nuevo..."
-
msgid "Create or import your first project"
-msgstr ""
+msgstr "Cree o importe su primer proyecto"
msgid "Create project"
msgstr "Crear proyecto"
@@ -9903,7 +10109,7 @@ msgid "Create requirement"
msgstr "Crear requisito"
msgid "Create service account"
-msgstr ""
+msgstr "Crear cuenta de servicio"
msgid "Create snippet"
msgstr "Crear fragmento de código"
@@ -9912,11 +10118,14 @@ msgid "Create tag %{tagName}"
msgstr "Crear etiqueta %{tagName}"
msgid "Create topic"
-msgstr ""
+msgstr "Crear tema"
msgid "Create user"
msgstr "Crear usuario"
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr "Crear comodín: %{searchTerm}"
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10152,18 +10361,36 @@ msgid "CredentialsInventory|SSH Keys"
msgstr "Claves SSH"
msgid "Credit card:"
-msgstr ""
+msgstr "Tarjeta de crédito:"
msgid "Critical vulnerabilities present"
msgstr "Vulnerabilidades críticas presentes"
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
+msgstr "Crear nuevo contacto"
+
+msgid "Crm|Create organization"
msgstr ""
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
+msgstr "Descripción (opcional)"
+
+msgid "Crm|Edit contact"
msgstr ""
msgid "Crm|Email"
@@ -10175,17 +10402,26 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
+msgstr "No se encontraron organizaciones"
+
+msgid "Crm|Organization has been added"
msgstr ""
msgid "Crm|Phone number (optional)"
-msgstr ""
+msgstr "Número de teléfono (opcional)"
msgid "Cron Timezone"
msgstr "Zona horaria del Cron"
@@ -10248,7 +10484,7 @@ msgid "CurrentUser|Buy Pipeline minutes"
msgstr ""
msgid "CurrentUser|Edit profile"
-msgstr ""
+msgstr "Editar perfil"
msgid "CurrentUser|One of your groups is running out"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr "Personalice la configuración de su pipeline."
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr "Ir a las preferencias"
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr "Tiempo del ciclo"
@@ -10543,7 +10770,7 @@ msgid "DORA4Metrics|%{startDate} - %{endDate}"
msgstr ""
msgid "DORA4Metrics|Date"
-msgstr ""
+msgstr "Fecha"
msgid "DORA4Metrics|Days from merge to deploy"
msgstr ""
@@ -10627,7 +10854,7 @@ msgid "DastProfiles|Additional request headers (Optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
-msgstr ""
+msgstr "¿Está seguro de que desea eliminar este perfil?"
msgid "DastProfiles|Authentication"
msgstr "Autentificación"
@@ -10735,19 +10962,19 @@ msgid "DastProfiles|Manage profiles"
msgstr "Administrar perfiles"
msgid "DastProfiles|Manage site profiles"
-msgstr ""
+msgstr "Administrar perfiles del sitio"
msgid "DastProfiles|Minimum = 0 (no timeout enabled), Maximum = 2880 minutes"
msgstr "Mínimo = 0 (sin tiempo de espera habilitado), Máximo = 2880 minutos"
msgid "DastProfiles|Minimum = 1 second, Maximum = 3600 seconds"
-msgstr ""
+msgstr "Mínimo = 1 segundo, Máximo = 3600 segundos"
msgid "DastProfiles|New scanner profile"
-msgstr ""
+msgstr "Nuevo perfil de escaneo"
msgid "DastProfiles|New site profile"
-msgstr ""
+msgstr "Nuevo perfil del sitio"
msgid "DastProfiles|No scanner profiles created yet"
msgstr ""
@@ -10762,7 +10989,7 @@ msgid "DastProfiles|Not Validated"
msgstr "No validado"
msgid "DastProfiles|Passive"
-msgstr ""
+msgstr "Pasivo"
msgid "DastProfiles|Password"
msgstr "Contraseña"
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr "Fecha"
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr "Selector de fecha"
@@ -11157,13 +11387,13 @@ msgid "DefaultBranchProtection|Developers cannot push new commits, but maintaine
msgstr ""
msgid "DefaultBranchProtection|Fully protected"
-msgstr ""
+msgstr "Totalmente protegido"
msgid "DefaultBranchProtection|Not protected"
-msgstr ""
+msgstr "No protegido"
msgid "DefaultBranchProtection|Partially protected"
-msgstr ""
+msgstr "Protegido parcialmente"
msgid "DefaultBranchProtection|Protected against pushes"
msgstr ""
@@ -11214,7 +11444,7 @@ msgid "Delete"
msgstr "Eliminar"
msgid "Delete %{issuableType}"
-msgstr ""
+msgstr "Eliminar %{issuableType}"
msgid "Delete %{name}"
msgstr "Eliminar %{name}"
@@ -11226,7 +11456,7 @@ msgid "Delete Key"
msgstr "Eliminar clave"
msgid "Delete Selected"
-msgstr ""
+msgstr "Eliminar seleccionado"
msgid "Delete Value Stream"
msgstr ""
@@ -11241,7 +11471,7 @@ msgid "Delete badge"
msgstr "Eliminar insignia"
msgid "Delete column"
-msgstr ""
+msgstr "Eliminar columna"
msgid "Delete comment"
msgstr "Eliminar comentario"
@@ -11274,7 +11504,7 @@ msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
msgid "Delete row"
-msgstr ""
+msgstr "Eliminar fila"
msgid "Delete self monitoring project"
msgstr ""
@@ -11292,7 +11522,7 @@ msgid "Delete subscription"
msgstr "Eliminar suscripción"
msgid "Delete table"
-msgstr ""
+msgstr "Eliminar tabla"
msgid "Delete this attachment"
msgstr "Eliminar este adjunto"
@@ -11306,6 +11536,9 @@ msgstr "Eliminar la lista de usuarios"
msgid "Delete variable"
msgstr "Eliminar variable"
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr "Se ha producido un error al eliminar el repositorio del proyecto. Por favor, inténtelo de nuevo o póngase en contacto con el administrador."
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr "Eliminado"
-msgid "Deleted Projects"
-msgstr "Proyectos eliminados"
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr "¡Eliminado el nick del chat %{chat_name}!"
-msgid "Deleted projects"
-msgstr "Proyectos eliminados"
-
msgid "Deleted projects cannot be restored!"
msgstr "¡Los proyectos eliminados no se pueden recuperar!"
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -11887,13 +12120,13 @@ msgid "DesignManagement|Deselect all"
msgstr "Deseleccionar todo"
msgid "DesignManagement|Designs"
-msgstr ""
+msgstr "Diseños"
msgid "DesignManagement|Discard comment"
msgstr "Descartar comentario"
msgid "DesignManagement|Download design"
-msgstr ""
+msgstr "Descargar diseño"
msgid "DesignManagement|Error uploading a new design. Please try again."
msgstr "Se ha producido un error al cargar un nuevo diseño. Por favor, inténtelo de nuevo."
@@ -11947,7 +12180,7 @@ msgid "DesignManagement|To upload designs, you'll need to enable LFS and have an
msgstr ""
msgid "DesignManagement|Unresolve thread"
-msgstr ""
+msgstr "Hilo sin resolver"
msgid "DesignManagement|Upload designs"
msgstr "Subir diseños"
@@ -12067,7 +12300,7 @@ msgid "DevopsAdoption|DevOps adoption tracks the use of key features across your
msgstr ""
msgid "DevopsAdoption|Edit groups"
-msgstr ""
+msgstr "Editar grupos"
msgid "DevopsAdoption|Edit subgroups"
msgstr "Editar subgrupos"
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr "Iniciar una prueba gratuita"
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr "Descargar CSV"
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr "Descargar artefactos"
@@ -12588,7 +12824,7 @@ msgid "Edit Group Hook"
msgstr "Editar hook del grupo"
msgid "Edit Identity"
-msgstr ""
+msgstr "Editar identidad"
msgid "Edit Label"
msgstr "Editar etiqueta"
@@ -12599,8 +12835,8 @@ msgstr "Editar hito"
msgid "Edit Password"
msgstr "Editar la contraseña"
-msgid "Edit Pipeline Schedule %{id}"
-msgstr "Editar Programación del Pipeline %{id}"
+msgid "Edit Pipeline Schedule"
+msgstr ""
msgid "Edit Release"
msgstr "Editar versión"
@@ -12638,6 +12874,9 @@ msgstr "Editar descripción"
msgid "Edit environment"
msgstr "Editar el entorno"
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr "Editar los archivos en el editor y confirmar los cambios aquí"
@@ -12672,10 +12911,10 @@ msgid "Edit public deploy key"
msgstr "Editar clave pública de despliegue"
msgid "Edit sidebar"
-msgstr ""
+msgstr "Editar barra lateral"
msgid "Edit table"
-msgstr ""
+msgstr "Editar tabla"
msgid "Edit this file only."
msgstr "Editar solo este archivo."
@@ -12687,10 +12926,10 @@ msgid "Edit title and description"
msgstr "Editar título y descripción"
msgid "Edit topic: %{topic_name}"
-msgstr ""
+msgstr "Editar tema: %{topic_name}"
msgid "Edit user: %{user_name}"
-msgstr ""
+msgstr "Editar usuario: %{user_name}"
msgid "Edit wiki page"
msgstr "Editar página wiki"
@@ -12717,7 +12956,7 @@ msgid "Elasticsearch HTTP client timeout value in seconds."
msgstr ""
msgid "Elasticsearch indexing"
-msgstr ""
+msgstr "Indexando Elasticsearch"
msgid "Elasticsearch indexing restrictions"
msgstr "Restricciones en la indexación de Elasticsearch"
@@ -12744,7 +12983,7 @@ msgid "Elasticsearch zero-downtime reindexing"
msgstr ""
msgid "Elasticsearch's region."
-msgstr ""
+msgstr "Región de Elasticsearch."
msgid "Elastic|None. Select namespaces to index."
msgstr "Ninguno. Seleccione los espacios de nombres a indexar."
@@ -12768,7 +13007,7 @@ msgid "Email a new %{name} to this project"
msgstr ""
msgid "Email address suffix"
-msgstr ""
+msgstr "Sufijo de la dirección de correo electrónico"
msgid "Email address to use for Support Desk"
msgstr ""
@@ -12948,7 +13187,7 @@ msgid "Enable access tokens to expire after 2 hours. If disabled, tokens do not
msgstr ""
msgid "Enable admin mode"
-msgstr ""
+msgstr "Habilitar el modo de administrador"
msgid "Enable and disable Service Desk. Some additional configuration might be required. %{link_start}Learn more%{link_end}."
msgstr ""
@@ -12963,7 +13202,7 @@ msgid "Enable authenticated web request rate limit"
msgstr ""
msgid "Enable authentication"
-msgstr ""
+msgstr "Habilitar la autenticación"
msgid "Enable automatic repository housekeeping"
msgstr ""
@@ -13026,7 +13265,7 @@ msgid "Enable or disable the Pseudonymizer data collection."
msgstr "Habilitar o deshabilitar la recolección de datos con Pseudonymizer."
msgid "Enable or disable version check and Service Ping."
-msgstr ""
+msgstr "Habilitar o deshabilitar la comprobación de la versión y el servicio Ping."
msgid "Enable rate limiting for POST requests to the specified paths"
msgstr ""
@@ -13035,7 +13274,7 @@ msgid "Enable reCAPTCHA"
msgstr "Habilitar reCAPTCHA"
msgid "Enable reCAPTCHA for login."
-msgstr ""
+msgstr "Habilitar reCAPTCHA para iniciar sesión."
msgid "Enable repository checks"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr "Se ha producido un error al ordenar el elemento."
msgid "Epics|Something went wrong while removing issue from epic."
msgstr "Se ha producido un error al eliminar la incidencia de la tarea épica."
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr "Se ha producido un error al subir el archivo: %{stripped}"
msgid "Error while loading the merge request. Please try again."
msgstr "Se ha producido un error al procesar su merge request. Por favor, inténtelo de nuevo."
-msgid "Error while loading the project data. Please try again."
-msgstr "Error al cargar los datos del proyecto. Por favor, vuelva a intentarlo."
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr "Se ha producido un error al migrar %{upload_id}: %{error_message}"
@@ -13793,7 +14029,7 @@ msgid "Error: %{error_message}"
msgstr "Error: %{error_message}"
msgid "Error: %{error}"
-msgstr ""
+msgstr "Error: %{error}"
msgid "Error: Couldn't load some or all of the changes."
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -13958,7 +14197,7 @@ msgid "EscalationPolicies|This policy has no escalation rules."
msgstr ""
msgid "EscalationPolicies|mins"
-msgstr ""
+msgstr "minutos"
msgid "Estimate"
msgstr "Estimación"
@@ -13973,7 +14212,7 @@ msgid "EventFilterBy|Filter by comments"
msgstr "Filtrar por comentarios"
msgid "EventFilterBy|Filter by designs"
-msgstr ""
+msgstr "Filtrar por diseños"
msgid "EventFilterBy|Filter by epic events"
msgstr "Filtrar por eventos épicos"
@@ -14000,16 +14239,16 @@ msgid "Every %{action} attempt has failed: %{job_error_message}. Please try agai
msgstr "Cada intento de %{action} ha fallado: %{job_error_message}. Por favor, inténtalo de nuevo."
msgid "Every 3 months"
-msgstr ""
+msgstr "Cada 3 meses"
msgid "Every 3 months on the %{day} at %{time} %{timezone}"
-msgstr ""
+msgstr "Cada 3 meses el %{day} a las %{time} %{timezone}"
msgid "Every 6 months"
-msgstr ""
+msgstr "Cada 6 meses"
msgid "Every 6 months on the %{day} at %{time} %{timezone}"
-msgstr ""
+msgstr "Cada 6 meses el %{day} a las %{time} %{timezone}"
msgid "Every day"
msgstr "Diario"
@@ -14018,7 +14257,7 @@ msgid "Every day (at %{time})"
msgstr "Todos los días (a %{time})"
msgid "Every day at %{time} %{timezone}"
-msgstr ""
+msgstr "Todos los días a las %{time} %{timezone}"
msgid "Every month"
msgstr "Cada mes"
@@ -14027,7 +14266,7 @@ msgid "Every month (Day %{day} at %{time})"
msgstr "Todos los meses (Día %{day} a %{time})"
msgid "Every month on the %{day} at %{time} %{timezone}"
-msgstr ""
+msgstr "Todos los meses los %{day} a las %{time} %{timezone}"
msgid "Every three months"
msgstr "Cada tres meses"
@@ -14044,16 +14283,13 @@ msgid "Every week (%{weekday} at %{time})"
msgstr "Todas las semanas (%{weekday} a %{time})"
msgid "Every week on %{day} at %{time} %{timezone}"
-msgstr ""
+msgstr "Todas las semanas los %{day} a las %{time} %{timezone}"
msgid "Every year"
-msgstr ""
+msgstr "Todos los años"
msgid "Every year on %{day} at %{time} %{timezone}"
-msgstr ""
-
-msgid "Everyone"
-msgstr "Todo el mundo"
+msgstr "Todos los años los %{day} a las %{time} %{timezone}"
msgid "Everyone With Access"
msgstr "Todos los usuarios con acceso"
@@ -14137,16 +14373,16 @@ msgid "Expand file"
msgstr "Expandir archivo"
msgid "Expand issues"
-msgstr ""
+msgstr "Expandir incidencias"
msgid "Expand milestones"
msgstr "Expandir hitos"
msgid "Expand panel"
-msgstr ""
+msgstr "Expandir panel"
msgid "Expand pipeline"
-msgstr ""
+msgstr "Expandir pipeline"
msgid "Expand settings section"
msgstr ""
@@ -14188,7 +14424,7 @@ msgid "Expires in %{expires_at}"
msgstr "Caduca en %{expires_at}"
msgid "Expires on"
-msgstr ""
+msgstr "Caduca el"
msgid "Expires:"
msgstr "Caduca:"
@@ -14215,16 +14451,16 @@ msgid "Explore public groups"
msgstr "Explorar grupos públicos"
msgid "Explore snippets"
-msgstr ""
+msgstr "Explorar fragmentos de código"
msgid "Explore topics"
-msgstr ""
+msgstr "Explorar temas"
msgid "Export"
msgstr "Exportar"
msgid "Export %{requirementsCount} requirements?"
-msgstr ""
+msgstr "¿Exportar los requisitos de %{requirementsCount}?"
msgid "Export as CSV"
msgstr "Exportar como CSV"
@@ -14236,7 +14472,7 @@ msgid "Export group"
msgstr "Exportar grupo"
msgid "Export issues"
-msgstr ""
+msgstr "Exportar incidencias"
msgid "Export merge requests"
msgstr ""
@@ -14245,9 +14481,9 @@ msgid "Export project"
msgstr "Exportar proyecto"
msgid "Export requirements"
-msgstr ""
+msgstr "Exportar requisitos"
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14269,7 +14505,7 @@ msgid "External URL"
msgstr "URL externa"
msgid "External User:"
-msgstr ""
+msgstr "Usuario externo"
msgid "External authentication"
msgstr "Autenticación externa"
@@ -14302,10 +14538,10 @@ msgid "ExternalIssueIntegration|This issue is synchronized with %{trackerName}"
msgstr ""
msgid "ExternalWikiService|External wiki"
-msgstr ""
+msgstr "Wiki externo"
msgid "ExternalWikiService|External wiki URL"
-msgstr ""
+msgstr "URL del wiki externo"
msgid "ExternalWikiService|Link to an external wiki from the sidebar."
msgstr ""
@@ -14887,7 +15123,7 @@ msgid "File upload error."
msgstr "Error al subir el archivo."
msgid "Filename"
-msgstr ""
+msgstr "Nombre del archivo"
msgid "Files"
msgstr "Archivos"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr "Filtrar por autenticación de dos factores"
-
msgid "Filter by user"
msgstr "Filtrar por usuario"
@@ -15019,10 +15252,10 @@ msgid "Finished"
msgstr "Finalizado"
msgid "Finished at"
-msgstr ""
+msgstr "Terminado en"
msgid "First Name"
-msgstr ""
+msgstr "Primer nombre"
msgid "First Seen"
msgstr "Visto por primera vez"
@@ -15085,13 +15318,13 @@ msgid "Folder/%{name}"
msgstr "Carpeta/%{name}"
msgid "Follow"
-msgstr ""
+msgstr "Seguir"
msgid "Followed Users' Activity"
-msgstr ""
+msgstr "Actividad de los usuarios seguidos"
msgid "Followed users"
-msgstr ""
+msgstr "Usuarios seguidos"
msgid "Font Color"
msgstr "Color de la fuente"
@@ -15121,7 +15354,7 @@ msgid "For files larger than this limit, only index the file name. The file cont
msgstr ""
msgid "For general work"
-msgstr ""
+msgstr "Para trabajo general"
msgid "For individual use, create a separate account under your personal email address, not tied to the Enterprise email domain or group."
msgstr ""
@@ -15187,7 +15420,7 @@ msgid "ForkProject|Please select a visibility level"
msgstr ""
msgid "ForkProject|Private"
-msgstr ""
+msgstr "Privado"
msgid "ForkProject|Project access must be granted explicitly to each user. If this project is part of a group, access will be granted to members of the group."
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr "Desde la integración de la solicitud de fusión hasta el despliegue a p
msgid "Full"
msgstr "Completo"
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr "Nombre completo"
@@ -15865,10 +16101,10 @@ msgid "GitLab Issue"
msgstr "Incidencia de GitLab"
msgid "GitLab Pages"
-msgstr ""
+msgstr "GitLab Pages"
msgid "GitLab Shell"
-msgstr ""
+msgstr "GitLab Shell"
msgid "GitLab Support Bot"
msgstr "Bot de soporte de GitLab"
@@ -16018,7 +16254,7 @@ msgid "GitLabPages|Removing pages will prevent them from being exposed to the ou
msgstr "Al eliminar páginas evitará que estén expuestas al mundo exterior."
msgid "GitLabPages|Save changes"
-msgstr ""
+msgstr "Guardar los cambios"
msgid "GitLabPages|Something went wrong while obtaining the Let's Encrypt certificate for %{domain}. To retry visit your %{link_start}domain details%{link_end}."
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr "Ir a métricas"
msgid "Go to next page"
msgstr "Ir a la página siguiente"
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr "Ir al principal"
@@ -16428,9 +16664,6 @@ msgstr "El grupo SAML debe estar habilitado para poder probar"
msgid "Group URL"
msgstr "URL del grupo"
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr "El grupo fue exportado"
msgid "Group was successfully updated."
msgstr "Grupo actualizado correctamente."
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr "Grupo: %{group_name}"
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr "La huella digital SHA1 del certificado de firma de tokens SAML. Puede ob
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr "El token SCIM está oculto. Para ver el valor del token de nuevo, necesita "
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,8 +17093,8 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr "Insignias"
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
-msgstr "Tenga cuidado. Cambiar el grupo principal puede tener %{side_effects_link_start}efectos secundarios no intencionados%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
+msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
msgstr "No se puede actualizar la ruta porque hay proyectos en este grupo que contienen imágenes de Docker en su registro de contenedores. Elimine primero las imágenes de sus proyectos e inténtelo de nuevo."
@@ -16839,7 +17102,7 @@ msgstr "No se puede actualizar la ruta porque hay proyectos en este grupo que co
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr "¡Se ha generado el token de registro para los nuevos ejecutores!"
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr "La configuración del pipeline se actualizó para el grupo"
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr "Puede administrar los permisos y el acceso de cada miembro del grupo a c
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr "SO no válido"
msgid "Invalid URL"
msgstr "URL no válida"
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr "Nombre del contenedor no válido"
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr "Está bloqueado por"
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr "Está usando el asiento de licencia:"
@@ -19458,9 +19733,6 @@ msgstr "Estado"
msgid "IssueAnalytics|Weight"
msgstr "Peso"
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr "Tablero"
@@ -20106,8 +20378,8 @@ msgstr "Raw completo"
msgid "Job|Download"
msgstr "Descargar"
-msgid "Job|Erase job log"
-msgstr "Borrar el registro del trabajo"
+msgid "Job|Erase job log and artifacts"
+msgstr ""
msgid "Job|Job artifacts"
msgstr "Artefactos del trabajo"
@@ -20558,6 +20830,12 @@ msgstr "Último pipeline para el commit más reciente en esta rama"
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr "No ha sido posible guardar el orden de las incidencias"
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr "Métricas e informes"
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr "Más de %{number_commits_distance} commits diferente con %{default_branch}"
@@ -22999,6 +23283,39 @@ msgstr "Desplácese hasta el proyecto para cerrar el hito."
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr "Ayuda"
@@ -23212,6 +23529,9 @@ msgstr "Nuevo"
msgid "New %{issueType}"
msgstr "Nueva %{issueType}"
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr "Nueva aplicación"
@@ -23344,7 +23664,7 @@ msgid "New label"
msgstr "Nueva etiqueta"
msgid "New list"
-msgstr ""
+msgstr "Nueva lista"
msgid "New merge request"
msgstr "Nueva solicitud de fusión"
@@ -23353,7 +23673,7 @@ msgid "New milestone"
msgstr "Nuevo hito"
msgid "New name"
-msgstr ""
+msgstr "Nuevo nombre"
msgid "New password"
msgstr "Nueva contraseña"
@@ -23371,7 +23691,7 @@ msgid "New project pages"
msgstr ""
msgid "New project/repository"
-msgstr ""
+msgstr "Nuevo proyecto/repositorio"
msgid "New public deploy key"
msgstr ""
@@ -23383,7 +23703,7 @@ msgid "New requirement"
msgstr "Nuevo requisito"
msgid "New response for issue #%{issue_iid}:"
-msgstr ""
+msgstr "Nueva respuesta para la incidencia #%{issue_iid}:"
msgid "New runners registration token has been generated!"
msgstr "¡Se ha generado el token de registro para los nuevos ejecutores!"
@@ -23407,7 +23727,7 @@ msgid "New test case"
msgstr ""
msgid "New topic"
-msgstr ""
+msgstr "Nuevo tema"
msgid "New users set to external"
msgstr "Nuevos usuarios configurados como externos"
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr "Siguiente archivo en diff"
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr "Siguiente discusión sin resolver"
@@ -23686,7 +24009,7 @@ msgid "No prioritized labels with such name or description"
msgstr "No hay etiquetas priorizadas con dicho nombre o descripción"
msgid "No profiles found"
-msgstr ""
+msgstr "No se encontraron perfiles"
msgid "No projects found"
msgstr ""
@@ -23814,7 +24137,7 @@ msgid "Not confidential"
msgstr "No es confidencial"
msgid "Not found"
-msgstr ""
+msgstr "No encontrado"
msgid "Not found."
msgstr "No encontrado."
@@ -23855,6 +24178,9 @@ msgstr "Nota: Considere preguntarle a su administrador de GitLab que configure %
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr "Nota: Considere pedirle a su administrador de GitLab que configure %{github_integration_link}, que le permitirá el inicio de sesión a través de GitHub y le permitirá la conexión de repositorios sin la necesidad de generar un token de acceso personal."
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr "Nota"
@@ -23867,7 +24193,7 @@ msgstr "¿Está seguro de que desea cancelar la creación de este comentario?"
msgid "Notes|Collapse replies"
msgstr "Contraer respuestas"
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24089,7 +24415,7 @@ msgid "OfSearchInADropdown|Filter"
msgstr "Filtrar"
msgid "Off"
-msgstr ""
+msgstr "Apagado"
msgid "Oh no!"
msgstr "¡Oh, no!"
@@ -24098,7 +24424,7 @@ msgid "Ok, let's go"
msgstr ""
msgid "Okay"
-msgstr ""
+msgstr "Aceptar"
msgid "Oldest first"
msgstr "Más antiguo primero"
@@ -24107,7 +24433,7 @@ msgid "OmniAuth"
msgstr "OmniAuth"
msgid "On"
-msgstr ""
+msgstr "En"
msgid "On track"
msgstr ""
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr "Una vez importados, los repositorios se pueden replicar vía de SSH. Par
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr "Una vez que el archivo exportado esté preparado, recibirá una notificación por correo electrónico con un enlace para su descarga, también puede descargarlo desde esta página."
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr "Operación no permitida"
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 ""
+
msgid "Operations Dashboard"
msgstr "Panel de control de operaciones"
@@ -25088,9 +25450,6 @@ msgstr "Página no encontrada"
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25269,7 +25628,7 @@ msgid "Pause Elasticsearch indexing"
msgstr ""
msgid "Paused"
-msgstr ""
+msgstr "Pausado"
msgid "Paused runners don't accept new jobs"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr "Pendiente"
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25458,17 +25826,11 @@ msgid "Pipeline Schedules"
msgstr "Programaciones de los Pipelines"
msgid "Pipeline URL"
-msgstr ""
+msgstr "URL del pipeline"
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr "Cuota de minutos del pipeline"
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25614,7 +25976,7 @@ msgid "PipelineSchedules|Variables"
msgstr "Variables"
msgid "PipelineSource|API"
-msgstr ""
+msgstr "API"
msgid "PipelineSource|Chat"
msgstr ""
@@ -25638,7 +26000,7 @@ msgid "PipelineSource|Parent Pipeline"
msgstr ""
msgid "PipelineSource|Pipeline"
-msgstr ""
+msgstr "Pipeline"
msgid "PipelineSource|Push"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25827,7 +26192,7 @@ msgid "Pipelines|To keep your codebase simple, readable, and accessible to contr
msgstr ""
msgid "Pipelines|Token"
-msgstr ""
+msgstr "Token"
msgid "Pipelines|Trigger user has insufficient permissions to project"
msgstr ""
@@ -25857,13 +26222,13 @@ msgid "Pipelines|Visualize"
msgstr ""
msgid "Pipelines|invalid"
-msgstr ""
+msgstr "no válido"
msgid "Pipelines|parent"
msgstr "padre"
msgid "Pipeline|Actions"
-msgstr ""
+msgstr "Acciones"
msgid "Pipeline|Branch name"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr "Por favor, seleccione"
@@ -26210,6 +26578,9 @@ msgstr "Por favor, seleccione un país"
msgid "Please select a file"
msgstr "Por favor, seleccione un archivo"
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr "Por favor, seleccione un grupo."
@@ -26405,9 +26776,6 @@ msgstr "Preferencias de hora"
msgid "Preferences|Use relative times"
msgstr "Utilizar tiempos relativos"
-msgid "Press %{key}-C to copy"
-msgstr "Presione %{key}-C para copiar"
-
msgid "Prev"
msgstr "Previo"
@@ -26759,6 +27127,9 @@ msgstr "Contraseña no válida"
msgid "Profiles|Invalid username"
msgstr "Nombre de usuario inválido"
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr "Clave"
@@ -26816,6 +27187,12 @@ msgstr "Contribuciones privadas"
msgid "Profiles|Profile was successfully updated"
msgstr "El perfil se actualizó correctamente"
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr "El nombre de usuario se cambió con éxito"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr "El uso de emojis en los nombres parece divertido, pero por favor, intente establecer un mensaje de estado en su lugar"
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr "¿Cuál es su estado?"
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr "ID de proyecto: %{project_id}"
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr "o grupo"
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27327,7 +27752,7 @@ msgid "ProjectSettings|All discussions must be resolved"
msgstr "Todas las discusiones deben ser resueltas"
msgid "ProjectSettings|Allow"
-msgstr ""
+msgstr "Permitir"
msgid "ProjectSettings|Always show thumbs-up and thumbs-down award emoji buttons on issues, merge requests, and snippets."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr "IOS (Swift)"
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr "Proyectos"
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr "Esta funcionalidad está bloqueada."
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr "Pruébelo gratis"
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr "Ponderar su problema"
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr "Cuando tienes muchas incidencias, puede ser difícil obtener una visión general. Al añadir un peso a tus problemas, puedes tener una mejor idea del esfuerzo, del costo, del tiempo requerido, o valor de cada uno, y por lo tanto poder manejarlos mejor."
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr "Permitido push:"
msgid "ProtectedBranch|Branch"
msgstr "Rama"
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr "%{environment_name} podrá modificarse por los desarrolladores. ¿Estás seguro de que desea continuar?"
@@ -28340,6 +28771,9 @@ msgstr "Se ha protegido su entorno."
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "Se ha desprotegido su entorno"
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr "Rango rápido"
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr "README"
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr "Regenerar el lD de la instancia"
-msgid "Regenerate key"
-msgstr "Regenerar clave"
-
msgid "Regenerate recovery codes"
msgstr "Regenerar los códigos de recuperación"
@@ -28813,6 +29253,54 @@ msgstr "Registrarse con la aplicación de dos factores"
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr "Eliminado el tiempo estimado."
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr "Reanudar"
msgid "Resync"
msgstr "Resincronizar"
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr "Reintentar"
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr "Reintentar este trabajo"
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr "grupo"
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr "En ejecución"
@@ -30574,6 +31089,9 @@ msgstr "Buscar este texto"
msgid "Search forks"
msgstr "Buscar forks"
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr "Buscar o filtrar resultados..."
msgid "Search or filter results…"
msgstr "Buscar o filtrar resultados…"
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr "Buscar proyecto"
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr "Habilitado"
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr "Gravedad"
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr "Estado"
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr "Seleccione el proyecto y la zona para elegir el tipo de máquina"
msgid "Select project to choose zone"
msgstr "Seleccione el proyecto para elegir la zona"
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31692,7 +32225,7 @@ msgid "Serve repository static objects (for example, archives and blobs) from ex
msgstr ""
msgid "Server (optional)"
-msgstr ""
+msgstr "Servidor (opcional)"
msgid "Server supports batch API only, please update your Git LFS client to version 1.0.1 and up."
msgstr "El servidor solo admite API por lotes, actualice su cliente Git LFS a la versión 1.0.1 o superior."
@@ -31851,7 +32384,7 @@ msgid "ServicePing|Turn on service ping to review instance-level analytics."
msgstr ""
msgid "Services"
-msgstr ""
+msgstr "Servicios"
msgid "Session ID"
msgstr "ID de sesión"
@@ -31880,6 +32413,12 @@ msgstr "Establecer y restringir los niveles de visibilidad por defecto. Configur
msgid "Set due date"
msgstr "Establecer fecha de finalización"
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr "Establecer iteración"
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr "Establecer %{epic_ref} cómo tarea épica principal."
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr "Establece la rama de destino a %{branch_name}."
@@ -32451,7 +32993,7 @@ msgid "Skipped deployment to"
msgstr ""
msgid "Skype:"
-msgstr ""
+msgstr "Skype:"
msgid "Slack application"
msgstr "Aplicación Slack"
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -32934,7 +33479,7 @@ msgid "SortOptions|Start soon"
msgstr "Comienza pronto"
msgid "SortOptions|Title"
-msgstr ""
+msgstr "Título"
msgid "SortOptions|Type"
msgstr "Tipo"
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr "Comience su prueba gratuita"
-msgid "Start your trial"
-msgstr "Comience su prueba gratuita"
-
msgid "Started"
msgstr "Iniciado"
@@ -33420,16 +33962,16 @@ msgid "Stay updated about the performance and health of your environment by conf
msgstr "Manténgase informado sobre el rendimiento y la salud de su entorno mediante la configuración dePrometheus para monitorizar sus despliegues."
msgid "Step 1."
-msgstr ""
+msgstr "Paso 1."
msgid "Step 2."
-msgstr ""
+msgstr "Paso 2."
msgid "Step 3."
-msgstr ""
+msgstr "Paso 3."
msgid "Step 4."
-msgstr ""
+msgstr "Paso 4."
msgid "Stop Terminal"
msgstr "Detener Terminal"
@@ -33578,6 +34120,12 @@ msgstr "Suscripción creada correctamente."
msgid "Subscription successfully deleted."
msgstr "Suscripción eliminada correctamente."
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -33741,7 +34289,7 @@ msgid "SuggestedColors|Aztec Gold"
msgstr ""
msgid "SuggestedColors|Blue"
-msgstr ""
+msgstr "Azul"
msgid "SuggestedColors|Blue-gray"
msgstr ""
@@ -33774,7 +34322,7 @@ msgid "SuggestedColors|Deep violet"
msgstr ""
msgid "SuggestedColors|Gray"
-msgstr ""
+msgstr "Gris"
msgid "SuggestedColors|Green screen"
msgstr ""
@@ -33792,7 +34340,7 @@ msgid "SuggestedColors|Medium sea green"
msgstr ""
msgid "SuggestedColors|Red"
-msgstr ""
+msgstr "Rojo"
msgid "SuggestedColors|Rose red"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr "Sistema"
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34312,6 +34894,9 @@ msgid "Terraform|Details"
msgstr ""
msgid "Terraform|Download JSON"
+msgstr "Descargar JSON"
+
+msgid "Terraform|Failed to load Terraform reports"
msgstr ""
msgid "Terraform|Generating the report caused an error."
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34339,13 +34927,13 @@ msgid "Terraform|Locking state"
msgstr ""
msgid "Terraform|Name"
-msgstr ""
+msgstr "Nombre"
msgid "Terraform|Pipeline"
-msgstr ""
+msgstr "Pipeline"
msgid "Terraform|Remove"
-msgstr ""
+msgstr "Eliminar"
msgid "Terraform|Remove state file and versions"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "La conexión terminará después de %{timeout}. Para los repositorios que tarden más tiempo, utilice una combinación de git clone y git push."
@@ -34775,9 +35375,6 @@ msgstr "El grupo y cualquier proyecto público se pueden ver sin necesidad de au
msgid "The group and its projects can only be viewed by members."
msgstr "El grupo y sus proyectos sólo se pueden ver por sus miembros."
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr "El grupo ya ha sido compartido con este grupo"
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr "La configuración de grupos para %{group_links} requiere que habilite la autenticación en dos pasos para sú cuenta. Puede %{leave_group_links}."
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr "Aún no hay incidencias que mostrar"
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr "Aún no hay etiquetas"
-
msgid "There are no matching files"
msgstr "No hay archivos coincidentes"
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ 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 has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr "Está aplicación podrá:"
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
msgstr "Este grupo"
+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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr "Este trabajo requiere una acción manual"
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36397,7 +36997,7 @@ msgid "To add the entry manually, provide the following details to the applicati
msgstr "Para agregar la entrada manualmente, proporcione los siguientes detalles a la aplicación en su teléfono."
msgid "To confirm, type %{phrase_code}"
-msgstr ""
+msgstr "Para confirmar, escriba %{phrase_code}"
msgid "To connect GitHub repositories, you can use a %{personal_access_token_link}. When you create your Personal Access Token, you will need to select the %{code_open}repo%{code_close} scope, so we can display a list of your public and private repositories which are available to connect."
msgstr ""
@@ -36495,6 +37095,9 @@ 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 "Para recibir alertas de los servicios de Prometheus configurados manualmente, agregue la siguiente URL y la clave de autorización a su archivo de configuración del webhook de Prometheus. Puede obtener más información sobre la %{linkStart}configuración de Prometheus%{linkEnd} para enviar alertas a GitLab."
+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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr "La tarea pendiente se ha marcado como realizada correctamente."
msgid "Today"
msgstr "Hoy"
+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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr "Transferir"
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr "Transferir la propiedad"
@@ -36840,10 +37479,10 @@ msgid "Trial|Company name"
msgstr "Nombre de la empresa"
msgid "Trial|Continue"
-msgstr ""
+msgstr "Continuar"
msgid "Trial|Continue using the basic features of GitLab for free."
-msgstr ""
+msgstr "Continúe utilizando las funciones básicas de GitLab de forma gratuita."
msgid "Trial|Country"
msgstr "País"
@@ -36852,20 +37491,11 @@ msgid "Trial|Dismiss"
msgstr "Descartar"
msgid "Trial|First name"
-msgstr ""
+msgstr "Primer nombre"
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr "GitLab Ultimate (opcional)"
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr "Hola%{salutation}, tu prueba de GitLab Ultimate dura 30 días, pero puedes mantener tu cuenta gratuita de GitLab para siempre. Solo necesitamos información adicional sobre %{company} para activar tu prueba."
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr "¿Cuántos empleados utilizarán Gitlab?"
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr "su empresa"
-
msgid "Trigger"
msgstr "Disparador"
@@ -36996,7 +37623,7 @@ msgid "Twitter"
msgstr "Twitter"
msgid "Twitter:"
-msgstr ""
+msgstr "Twitter:"
msgid "Two-Factor Authentication"
msgstr "Autenticación de doble factor"
@@ -37209,7 +37836,7 @@ msgid "Unassign from commenting user"
msgstr ""
msgid "Unassigned"
-msgstr ""
+msgstr "Sin asignar"
msgid "Unauthenticated API rate limit period in seconds"
msgstr ""
@@ -37236,7 +37863,7 @@ msgid "Unexpected error"
msgstr "Error inesperado"
msgid "Unfollow"
-msgstr ""
+msgstr "Dejar de seguir"
msgid "Unfortunately, your email message to GitLab could not be processed."
msgstr "Desafortunadamente, su mensaje de correo electrónico a GitLab no pudo ser procesado."
@@ -37509,7 +38136,7 @@ msgid "Upload license"
msgstr ""
msgid "Upload new file"
-msgstr ""
+msgstr "Subir nuevo archivo"
msgid "Upload object map"
msgstr "Subir un mapa de objetos"
@@ -37520,9 +38147,6 @@ msgstr "Hacer clic para subir"
msgid "Uploading changes to terminal"
msgstr "Subir los cambios al terminal"
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr "Upstream"
@@ -38028,7 +38652,7 @@ msgid "UserLists|New list"
msgstr "Nueva lista"
msgid "UserLists|New user list"
-msgstr ""
+msgstr "Nueva lista de usuarios"
msgid "UserLists|Save"
msgstr "Guardar"
@@ -38187,7 +38811,7 @@ msgid "UserProfile|made a private contribution"
msgstr "hizo una colaboración privada"
msgid "Username"
-msgstr ""
+msgstr "Nombre de usuario"
msgid "Username (optional)"
msgstr "Nombre de usuario (opcional)"
@@ -38202,7 +38826,7 @@ msgid "Username or email"
msgstr "Nombre de usuario o email"
msgid "Username:"
-msgstr ""
+msgstr "Nombre de usuario:"
msgid "Username: %{username}"
msgstr "Nombre de usuario: %{username}"
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr "Estado de la verificación"
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr "Ver todos los entornos."
msgid "View all issues"
msgstr "Ver todas las incidencias"
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr "Ver detalles: %{details_url}"
msgid "View documentation"
msgstr "Ver documentación"
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr "Ver aprobadores elegibles"
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr "Ver etiquetas de grupo"
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr "Ver incidencias."
@@ -38560,7 +39196,7 @@ msgid "View open merge request"
msgstr "Ver solicitud de fusión abierta"
msgid "View page @ "
-msgstr ""
+msgstr "Ver página @ "
msgid "View performance dashboard."
msgstr "Ver panel de control de rendimiento."
@@ -38609,6 +39245,9 @@ msgstr "Visto"
msgid "Viewing commit"
msgstr "Ver commit"
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr "Visibilidad"
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr "Cambiar estado"
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr "La respuesta recibida es la que se recibió cuando se detectó este fall
msgid "Vulnerability|Additional Info"
msgstr "Información adicional"
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr "Clase"
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr "Comentarios"
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr "Descripción"
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr "Detectada"
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr "Descargar"
msgid "Vulnerability|Evidence"
msgstr "Evidencia"
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr "Archivo"
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr "Identificador"
@@ -38834,6 +39509,9 @@ msgstr "Identificadores"
msgid "Vulnerability|Image"
msgstr "Imagen"
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr "Enlaces"
@@ -38858,6 +39536,15 @@ msgstr "Solicitud/Respuesta"
msgid "Vulnerability|Scanner Provider"
msgstr "Proveedor del escáner"
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr "Severidad"
@@ -38981,6 +39668,9 @@ msgstr "Validaremos continuamente la configuración de su pipeline. Los resultad
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr "No hemos encontrado vulnerabilidades"
@@ -39036,22 +39726,22 @@ msgid "Webhook"
msgstr "Webhook"
msgid "Webhook Logs"
-msgstr ""
+msgstr "Registros de Webhook"
msgid "Webhook Settings"
-msgstr ""
+msgstr "Ajustes Webhook"
msgid "Webhook events will be displayed here."
msgstr ""
msgid "Webhook:"
-msgstr ""
+msgstr "Webhook:"
msgid "Webhooks"
msgstr "Webhooks"
msgid "Webhooks Help"
-msgstr ""
+msgstr "Ayuda de Webhooks"
msgid "Webhooks|Comments"
msgstr "Comentarios"
@@ -39060,7 +39750,7 @@ msgid "Webhooks|Confidential comments"
msgstr "Comentarios confidenciales"
msgid "Webhooks|Confidential issues events"
-msgstr ""
+msgstr "Eventos confidenciales"
msgid "Webhooks|Deployment events"
msgstr "Eventos de despliegue"
@@ -39068,6 +39758,12 @@ msgstr "Eventos de despliegue"
msgid "Webhooks|Enable SSL verification"
msgstr "Activar la verificación SSL"
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr "Disparador"
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr "¡Bienvenido a GitLab,%{br_tag}%{name}!"
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr "¿Qué está buscando?"
@@ -39368,7 +40082,7 @@ msgid "WikiEmpty|Enable the Confluence Wiki integration"
msgstr "Activar la integración de Confluence Wiki"
msgid "WikiEmpty|Go to Confluence"
-msgstr ""
+msgstr "Ir a Confluence"
msgid "WikiEmpty|Suggest wiki improvement"
msgstr "Sugerir una mejora del wiki"
@@ -39425,7 +40139,7 @@ msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
msgstr ""
msgid "WikiPage|Cancel"
-msgstr ""
+msgstr "Cancelar"
msgid "WikiPage|Commit message"
msgstr ""
@@ -39461,7 +40175,7 @@ msgid "WikiPage|Page title"
msgstr "Título de la página"
msgid "WikiPage|Retry"
-msgstr ""
+msgstr "Reintentar"
msgid "WikiPage|Save changes"
msgstr ""
@@ -39830,10 +40544,10 @@ 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 "Ya puede cerrar esta ventana."
msgid "You can now export your security dashboard to a CSV report."
-msgstr ""
+msgstr "Ahora puede exportar su panel de seguridad a un informe CSV."
msgid "You can now submit a merge request to get this change into the original branch."
msgstr "Puede enviar un merge request para tener este cambio en la rama original."
@@ -40044,6 +40758,12 @@ msgstr ""
msgid "You have insufficient permissions to view shifts for this rotation"
msgstr "No tiene permisos suficientes para ver los turnos de esta rotación"
+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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr "No tiene permisos"
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40273,7 +40999,7 @@ msgid "Your Groups"
msgstr "Sus grupos"
msgid "Your Personal Access Token was revoked"
-msgstr ""
+msgstr "Su token de acceso personal fue revocado"
msgid "Your Projects (default)"
msgstr "Sus proyectos (por defecto)"
@@ -40303,10 +41029,10 @@ msgid "Your U2F device was registered!"
msgstr "¡Se ha registrado su dispositivo U2F!"
msgid "Your WebAuthn device did not send a valid JSON response."
-msgstr ""
+msgstr "Su dispositivo WebAuthn no envió una respuesta JSON válida."
msgid "Your WebAuthn device was registered!"
-msgstr ""
+msgstr "¡Su dispositivo WebAuthn se ha registrado correctamente!"
msgid "Your access request to the %{source_type} has been withdrawn."
msgstr "Su solicitud de acceso a %{source_type} ha sido retirada."
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
msgstr "¡Su suscripción ha caducado!"
+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 ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40613,7 +41342,7 @@ msgid "access:"
msgstr "acceso:"
msgid "added"
-msgstr ""
+msgstr "añadido"
msgid "added %{emails}"
msgstr ""
@@ -40764,6 +41493,9 @@ msgstr "no se puede bloquer"
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr "Investigue esta vulnerabilidad creando una incidencia"
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41074,7 +41806,7 @@ msgid "codeQualityWalkthrough|Troubleshoot your code quality job"
msgstr ""
msgid "codeQualityWalkthrough|View the logs"
-msgstr ""
+msgstr "Ver los registros"
msgid "codeQualityWalkthrough|Well done! You've just automated your code quality review. %{emojiStart}raised_hands%{emojiEnd}"
msgstr ""
@@ -41100,6 +41832,9 @@ msgstr "commit %{commit_id}"
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr "falta"
-msgid "more information"
-msgstr "más información"
-
msgid "most recent deployment"
msgstr "despliegue más reciente"
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr "abierto %{timeAgo}"
msgid "or"
msgstr "o"
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
@@ -42100,7 +42832,7 @@ msgid "project members"
msgstr ""
msgid "project name"
-msgstr ""
+msgstr "nombre del proyecto"
msgid "project namespace cannot be the parent of another namespace"
msgstr ""
@@ -42288,7 +43020,7 @@ msgid "the correct format."
msgstr ""
msgid "the file"
-msgstr ""
+msgstr "el archivo"
msgid "the following issue(s)"
msgstr "la siguiente incidencia(s)"
@@ -42443,7 +43175,7 @@ msgid "your settings"
msgstr "sus ajustes"
msgid "{group}"
-msgstr ""
+msgstr "{group}"
msgid "{project}"
msgstr ""
diff --git a/locale/et_EE/gitlab.po b/locale/et_EE/gitlab.po
index 78e2c60636c..7365b99ef0b 100644
--- a/locale/et_EE/gitlab.po
+++ b/locale/et_EE/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: et\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:56\n"
+"PO-Revision-Date: 2022-01-06 17:21\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/fa_IR/gitlab.po b/locale/fa_IR/gitlab.po
index 475f77d866b..8d461c0c997 100644
--- a/locale/fa_IR/gitlab.po
+++ b/locale/fa_IR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: fa\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:56\n"
+"PO-Revision-Date: 2022-01-06 17:20\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/fi_FI/gitlab.po b/locale/fi_FI/gitlab.po
index 2f64870ee83..dcf6c4f31c6 100644
--- a/locale/fi_FI/gitlab.po
+++ b/locale/fi_FI/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: fi\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:58\n"
+"PO-Revision-Date: 2022-01-06 17:22\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/fil_PH/gitlab.po b/locale/fil_PH/gitlab.po
index 88bf5ec7cdf..721b7c66fde 100644
--- a/locale/fil_PH/gitlab.po
+++ b/locale/fil_PH/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: fil\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 19:00\n"
+"PO-Revision-Date: 2022-01-06 17:25\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/fr/gitlab.po b/locale/fr/gitlab.po
index 8f46df90455..93f73123226 100644
--- a/locale/fr/gitlab.po
+++ b/locale/fr/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: fr\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:57\n"
+"PO-Revision-Date: 2022-01-06 17:21\n"
msgid " %{start} to %{end}"
msgstr " %{start} à %{end}"
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr "Profil de %{user_name}"
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ", ou "
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr "Sessions actives"
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "Activité"
@@ -1994,7 +2063,7 @@ msgstr "Ajouter un tableau"
msgid "Add a task list"
msgstr "Ajouter une liste de tâches"
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "Erreur lors du chargement des statistiques. Veuillez réessayer"
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr "Supprimer un compte utilisateur"
msgid "AdminUsers|Delete user and contributions"
msgstr "Supprimer le compte et ses contributions"
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr "Une erreur est survenue"
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr "Une erreur s’est produite lors de la prévisualisation du blob"
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr "Êtesâ€vous sûr de vouloir générer une nouvelle paire de clefs ? Vous devrez copier la nouvelle clef publique sur le serveur distant pour que la mise en miroir refonctionne."
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr "L’avatar sera supprimé. Êtesâ€vous sûr·e ?"
@@ -5370,9 +5487,6 @@ msgstr "mensuel"
msgid "BillingPlans|per user"
msgstr "par utilisateur"
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr ""
-
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr "Tableaux"
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr "Choisissez n’importe quelle couleur."
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr "Créer une nouvelle étiquette"
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr "Créer un nouveau…"
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr "Sélecteur de date"
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr "Supprimé"
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,8 +12835,8 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
-msgstr "Éditer le pipeline programmé %{id}"
+msgid "Edit Pipeline Schedule"
+msgstr ""
msgid "Edit Release"
msgstr ""
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr "Modifier les fichiers dans l’éditeur et valider les modifications ici"
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr "Erreur lors du chargement de la demande de fusion. Veuillez réessayer."
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr "Depuis la fusion de la demande de fusion jusqu’au déploiement en prod
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr "Le SAML de groupe doit être activé afin de pouvoir tester"
msgid "Group URL"
msgstr "URL du groupe"
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr "Groupe : %{group_name}"
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr "Badges numériques"
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr "Vous pouvez gérer les autorisations des membres de votre groupe et accÃ
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr "Tableau"
@@ -20106,8 +20378,8 @@ msgstr "Brut complet"
msgid "Job|Download"
msgstr "Télécharger"
-msgid "Job|Erase job log"
-msgstr "Effacer le journal de la tâche"
+msgid "Job|Erase job log and artifacts"
+msgstr ""
msgid "Job|Job artifacts"
msgstr "Artefacts de la tâche"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr "Statistiques et rapports"
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr "Aide"
@@ -23212,6 +23529,9 @@ msgstr "Nouveau"
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr "Nouvelle application"
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr "Remarque : Envisagez de demander à votre administrateur ou administrat
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr "Remarque : Envisagez de demander à votre administra·teur·trice GitLab de configurer %{github_integration_link}, ce qui vous permettra de vous connecter via GitHub et d’importer des dépôts sans générer de jeton d’accès personnel."
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr "Souhaitezâ€vous réellement annuler la création de ce commentaire ?"
msgid "Notes|Collapse replies"
msgstr "Réduire les réponses"
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr "Tableau de bord des opérations"
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr "En attente"
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr "Mot de passe incorrect"
msgid "Profiles|Invalid username"
msgstr "Nom d’utilisateur incorrect"
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr "Contributions privées"
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr "Changement de nom d’utilisateur effectué"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr "Quel est votre statut ?"
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr "Identifiant de projet : %{project_id}"
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr "Projets"
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr "Cette fonctionnalité est verrouillée."
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr "%{environment_name} sera accessible en écriture aux développeurs. Êtesâ€vous sûr de vouloir cela ?"
@@ -28340,6 +28771,9 @@ msgstr "Votre environnement a été protégé."
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "Votre environnement a été déprotégé"
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr "Régénérer la clef"
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr "Reprendre"
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr "Réessayer"
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr "Relancer cette tâche"
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr "En cours d’exécution"
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr "Rechercher ou filtrer les résultats…"
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr "Rechercher des projets"
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr "Sélectionnez le projet et la zone afin de choisir le type de machine"
msgid "Select project to choose zone"
msgstr "Sélectionnez le projet afin de choisir la zone"
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr "Définissez les valeurs par défaut et restreignez les niveaux de visibi
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr "Commencez votre essai gratuit"
-
msgid "Started"
msgstr "Démarré"
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "La connexion expirera après %{timeout}. Pour les dépôts qui nécessitent plus de temps, utilisez une combinaison de clone et push."
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr "Il n’y a aucun ticket à afficher"
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr "Il n’y a pas encore d’étiquette"
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr "Cette application sera en mesure de :"
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
msgstr "Ce groupe"
+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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr "Cette tâche nécessite une action manuelle"
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
msgstr "Aujourd’hui"
+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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr "Cliquez pour envoyer"
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr "Afficher les labels de groupe"
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr "Classe"
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr "Description"
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr "Fichier"
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr "Identifiants"
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr "Liens"
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr "Gravité"
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr "Vous n’avez pas les autorisations"
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 376b87d8432..8f5be8ace27 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -722,6 +722,9 @@ msgstr ""
msgid "%{level_name} is not allowed since the fork source project has lower visibility."
msgstr ""
+msgid "%{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "%{link_start}Learn more%{link_end} about roles."
msgstr ""
@@ -731,6 +734,9 @@ 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 ""
@@ -841,9 +847,6 @@ msgstr ""
msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
msgstr ""
-msgid "%{primary} (%{secondary})"
-msgstr ""
-
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 ""
@@ -876,6 +879,9 @@ msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
+msgid "%{runner} created %{timeago}"
+msgstr ""
+
msgid "%{scope} results for term '%{term}'"
msgstr ""
@@ -1160,6 +1166,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1829,21 +1838,12 @@ 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 ""
-msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
-msgstr ""
-
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 ""
-msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
-msgstr ""
-
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 ""
-msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
-msgstr ""
-
msgid "AccessTokens|Personal Access Tokens"
msgstr ""
@@ -1868,9 +1868,6 @@ 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 ""
-msgid "AccessTokens|reset this token"
-msgstr ""
-
msgid "AccessibilityReport|Learn more"
msgstr ""
@@ -1907,19 +1904,19 @@ msgstr ""
msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
msgstr ""
-msgid "AccountValidation|In order to use free pipeline minutes on shared runners, you'll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project."
+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 ""
msgid "AccountValidation|Learn more."
msgstr ""
-msgid "AccountValidation|Looks like you’ll need to validate your account to use free pipeline minutes"
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
msgstr ""
-msgid "AccountValidation|This is required to discourage and reduce the abuse on GitLab infrastructure. %{strong_start}GitLab will not charge or store your card, it will only be used for validation.%{strong_end} %{learn_more_link}"
+msgid "AccountValidation|Validate your account"
msgstr ""
-msgid "AccountValidation|Validate your account"
+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"
@@ -1952,6 +1949,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1973,9 +1973,6 @@ msgstr ""
msgid "Add CONTRIBUTING"
msgstr ""
-msgid "Add GitLab to Slack"
-msgstr ""
-
msgid "Add Jaeger URL"
msgstr ""
@@ -1985,7 +1982,7 @@ msgstr ""
msgid "Add LICENSE"
msgstr ""
-msgid "Add New Node"
+msgid "Add New Site"
msgstr ""
msgid "Add README"
@@ -2000,6 +1997,9 @@ msgstr ""
msgid "Add a GPG key"
msgstr ""
+msgid "Add a GPG key for secure access to GitLab. %{help_link_start}Learn more.%{help_link_end}"
+msgstr ""
+
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 ""
@@ -2066,6 +2066,9 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
+msgid "Add an SSH key for secure access to GitLab. %{help_link_start}Learn more.%{help_link_end}"
+msgstr ""
+
msgid "Add an existing issue"
msgstr ""
@@ -2183,9 +2186,6 @@ msgstr ""
msgid "Add text to the sign-in page. Markdown enabled."
msgstr ""
-msgid "Add to Slack"
-msgstr ""
-
msgid "Add to board"
msgstr ""
@@ -2483,6 +2483,12 @@ msgstr ""
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 ""
+
+msgid "AdminGeo|The URL of the secondary site that is used internally by the primary site."
+msgstr ""
+
msgid "AdminLabels|Define your default set of project labels"
msgstr ""
@@ -2639,6 +2645,9 @@ msgstr ""
msgid "AdminUsers|(Internal)"
msgstr ""
+msgid "AdminUsers|(Locked)"
+msgstr ""
+
msgid "AdminUsers|(Pending approval)"
msgstr ""
@@ -2768,7 +2777,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -3527,15 +3536,6 @@ msgstr ""
msgid "Allow public access to pipelines and job details, including output logs and artifacts."
msgstr ""
-msgid "Allow requests to the local network from hooks and services."
-msgstr ""
-
-msgid "Allow requests to the local network from system hooks"
-msgstr ""
-
-msgid "Allow requests to the local network from web hooks and services"
-msgstr ""
-
msgid "Allow subgroups to set up their own two-factor authentication rules"
msgstr ""
@@ -3875,6 +3875,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -4614,6 +4617,9 @@ msgstr ""
msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
+msgid "Are you sure you want to approve %{user}?"
+msgstr ""
+
msgid "Are you sure you want to attempt to merge?"
msgstr ""
@@ -4706,9 +4712,6 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
-msgid "Are you sure you want to reset the SCIM token? SCIM provisioning will stop working until the new token is updated."
-msgstr ""
-
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4793,7 +4796,7 @@ msgstr ""
msgid "Ask someone with write access to resolve it."
msgstr ""
-msgid "Ask your group maintainer to set up a group runner."
+msgid "Ask your group owner to set up a group runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -5367,6 +5370,9 @@ msgstr ""
msgid "Based on"
msgstr ""
+msgid "Basic information"
+msgstr ""
+
msgid "Be careful. Changing the project's namespace can have unintended side effects."
msgstr ""
@@ -5394,6 +5400,9 @@ msgstr ""
msgid "Below you will find all the groups that are public."
msgstr ""
+msgid "Beta"
+msgstr ""
+
msgid "Bi-weekly code coverage"
msgstr ""
@@ -5508,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr ""
-
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5526,12 +5532,21 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
+msgstr ""
+
+msgid "Billing|%{user} was successfully approved"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
msgstr ""
+msgid "Billing|An error occurred while approving %{user}"
+msgstr ""
+
msgid "Billing|An error occurred while getting a billable member details"
msgstr ""
@@ -5922,18 +5937,12 @@ msgstr ""
msgid "Branches|Delete protected branch"
msgstr ""
-msgid "Branches|Delete protected branch '%{branch_name}'?"
-msgstr ""
-
msgid "Branches|Delete protected branch. Are you ABSOLUTELY SURE?"
msgstr ""
msgid "Branches|Deleting the %{strongStart}%{branchName}%{strongEnd} branch cannot be undone. Are you sure?"
msgstr ""
-msgid "Branches|Deleting the '%{branch_name}' branch cannot be undone. Are you sure?"
-msgstr ""
-
msgid "Branches|Deleting the merged branches cannot be undone. Are you sure?"
msgstr ""
@@ -5949,9 +5958,6 @@ msgstr ""
msgid "Branches|No branches to show"
msgstr ""
-msgid "Branches|Once you confirm and press %{delete_protected_branch}, it cannot be undone or recovered."
-msgstr ""
-
msgid "Branches|Once you confirm and press %{strongStart}%{buttonText},%{strongEnd} it cannot be undone or recovered."
msgstr ""
@@ -6000,15 +6006,6 @@ msgstr ""
msgid "Branches|This branch hasn’t been merged into %{defaultBranchName}. To avoid data loss, consider merging this branch before deleting it."
msgstr ""
-msgid "Branches|This branch hasn’t been merged into %{default_branch}."
-msgstr ""
-
-msgid "Branches|To avoid data loss, consider merging this branch before deleting it."
-msgstr ""
-
-msgid "Branches|To confirm, type %{branch_name_confirmation}:"
-msgstr ""
-
msgid "Branches|To discard the local changes and overwrite the branch with the upstream version, delete it here and choose 'Update Now' above."
msgstr ""
@@ -6027,9 +6024,6 @@ msgstr ""
msgid "Branches|You're about to permanently delete the protected branch %{strongStart}%{branchName}.%{strongEnd}"
msgstr ""
-msgid "Branches|You’re about to permanently delete the protected branch %{branch_name}."
-msgstr ""
-
msgid "Branches|diverged from upstream"
msgstr ""
@@ -6290,9 +6284,21 @@ msgstr ""
msgid "CICDAnalytics|Releases"
msgstr ""
+msgid "CICDAnalytics|Shared Runners Usage"
+msgstr ""
+
+msgid "CICDAnalytics|Shared runner usage"
+msgstr ""
+
+msgid "CICDAnalytics|Shared runner usage is the total runtime of all jobs that ran on shared runners"
+msgstr ""
+
msgid "CICDAnalytics|Something went wrong while fetching release statistics"
msgstr ""
+msgid "CICDAnalytics|What is shared runner usage?"
+msgstr ""
+
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 ""
@@ -6906,6 +6912,9 @@ msgstr ""
msgid "Checkout|(x%{quantity})"
msgstr ""
+msgid "Checkout|An unknown error has occurred. Please try again by refreshing this page."
+msgstr ""
+
msgid "Checkout|Billing address"
msgstr ""
@@ -7326,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7344,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7374,15 +7392,6 @@ msgstr ""
msgid "Click to reveal"
msgstr ""
-msgid "Client authentication certificate"
-msgstr ""
-
-msgid "Client authentication key"
-msgstr ""
-
-msgid "Client authentication key password"
-msgstr ""
-
msgid "Client request timeout"
msgstr ""
@@ -7479,6 +7488,12 @@ msgstr ""
msgid "Closes this %{quick_action_target}."
msgstr ""
+msgid "Cloud Run"
+msgstr ""
+
+msgid "Cloud Storage"
+msgstr ""
+
msgid "Cluster"
msgstr ""
@@ -7500,6 +7515,9 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
@@ -7557,6 +7575,9 @@ msgstr ""
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7602,6 +7623,12 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
@@ -7715,7 +7742,10 @@ msgstr[1] ""
msgid "ClusterAgents|This agent has no tokens"
msgstr ""
-msgid "ClusterAgents|To install a new agent, first add the agent's configuration file to this repository. %{linkStart}What's the agent's configuration file?%{linkEnd}"
+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}"
@@ -8932,6 +8962,9 @@ msgstr ""
msgid "ComplianceReport|Less than 2 approvers"
msgstr ""
+msgid "ComplianceReport|No violations found"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9007,12 +9040,15 @@ msgstr ""
msgid "Configure a %{codeStart}.gitlab-webide.yml%{codeEnd} file in the %{codeStart}.gitlab%{codeEnd} directory to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
-msgid "Configure advanced permissions, Large File Storage, and two-factor authentication settings."
+msgid "Configure advanced permissions, Large File Storage, two-factor authentication, and customer relations settings."
msgstr ""
msgid "Configure existing installation"
msgstr ""
+msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9040,12 +9076,18 @@ msgstr ""
msgid "Configure the way a user creates a new account."
msgstr ""
+msgid "Configure via Merge Request"
+msgstr ""
+
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
msgid "Confirm"
msgstr ""
+msgid "Confirm approval"
+msgstr ""
+
msgid "Confirm new password"
msgstr ""
@@ -9353,6 +9395,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9442,6 +9487,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9598,7 +9646,7 @@ msgstr ""
msgid "Control how the GitLab Package Registry functions."
msgstr ""
-msgid "Control whether to display third-party offers in GitLab."
+msgid "Control whether to display customer experience improvement content and third-party offers in GitLab."
msgstr ""
msgid "Control which projects can be accessed by API requests authenticated with this project's CI_JOB_TOKEN CI/CD variable. It is a security risk to disable this feature, because unauthorized projects might attempt to retrieve an active token and access the API."
@@ -9673,6 +9721,9 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
@@ -9712,9 +9763,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9742,6 +9790,9 @@ msgstr ""
msgid "CorpusManagement|Corpus name"
msgstr ""
+msgid "CorpusManagement|Currently, there are no uploaded or generated corpuses."
+msgstr ""
+
msgid "CorpusManagement|Fuzz testing corpus management"
msgstr ""
@@ -9829,6 +9880,9 @@ msgstr ""
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 ""
+
msgid "Could not find design."
msgstr ""
@@ -9856,13 +9910,16 @@ msgstr ""
msgid "Could not restore the group"
msgstr ""
+msgid "Could not revoke access token %{access_token_name}."
+msgstr ""
+
msgid "Could not revoke impersonation token %{token_name}."
msgstr ""
msgid "Could not revoke personal access token %{personal_access_token_name}."
msgstr ""
-msgid "Could not revoke project access token %{project_access_token_name}."
+msgid "Could not save configuration. Please refresh the page, or try again later."
msgstr ""
msgid "Could not save group ID"
@@ -10006,6 +10063,9 @@ msgstr ""
msgid "Create iteration"
msgstr ""
+msgid "Create label"
+msgstr ""
+
msgid "Create list"
msgstr ""
@@ -10084,6 +10144,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -10126,9 +10189,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -10138,13 +10198,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10495,6 +10558,9 @@ msgstr ""
msgid "Customer Relations Organizations"
msgstr ""
+msgid "Customer experience improvement and third-party offers"
+msgstr ""
+
msgid "Customer relations"
msgstr ""
@@ -10829,12 +10895,6 @@ msgstr ""
msgid "DastProfiles|Could not create the site profile. Please try again."
msgstr ""
-msgid "DastProfiles|Could not delete saved scan. Please refresh the page, or try again later."
-msgstr ""
-
-msgid "DastProfiles|Could not delete saved scans:"
-msgstr ""
-
msgid "DastProfiles|Could not delete scanner profile. Please refresh the page, or try again later."
msgstr ""
@@ -10847,9 +10907,6 @@ msgstr ""
msgid "DastProfiles|Could not delete site profiles:"
msgstr ""
-msgid "DastProfiles|Could not fetch saved scans. Please refresh the page, or try again later."
-msgstr ""
-
msgid "DastProfiles|Could not fetch scanner profiles. Please refresh the page, or try again later."
msgstr ""
@@ -10862,9 +10919,6 @@ msgstr ""
msgid "DastProfiles|Could not update the site profile. Please try again."
msgstr ""
-msgid "DastProfiles|DAST Scan"
-msgstr ""
-
msgid "DastProfiles|Debug messages"
msgstr ""
@@ -10937,9 +10991,6 @@ msgstr ""
msgid "DastProfiles|No scanner profiles created yet"
msgstr ""
-msgid "DastProfiles|No scans saved yet"
-msgstr ""
-
msgid "DastProfiles|No site profiles created yet"
msgstr ""
@@ -10967,9 +11018,6 @@ msgstr ""
msgid "DastProfiles|Rest API"
msgstr ""
-msgid "DastProfiles|Run scan"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -10979,12 +11027,6 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
-msgid "DastProfiles|Saved Scans"
-msgstr ""
-
-msgid "DastProfiles|Scan"
-msgstr ""
-
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -10997,9 +11039,6 @@ msgstr ""
msgid "DastProfiles|Scanner name"
msgstr ""
-msgid "DastProfiles|Schedule"
-msgstr ""
-
msgid "DastProfiles|Select branch"
msgstr ""
@@ -11021,9 +11060,6 @@ msgstr ""
msgid "DastProfiles|Spider timeout"
msgstr ""
-msgid "DastProfiles|Target"
-msgstr ""
-
msgid "DastProfiles|Target URL"
msgstr ""
@@ -11293,9 +11329,6 @@ msgstr ""
msgid "Default branch protection"
msgstr ""
-msgid "Default classification label"
-msgstr ""
-
msgid "Default delayed project deletion"
msgstr ""
@@ -11722,6 +11755,9 @@ msgstr[1] ""
msgid "Deploy Keys"
msgstr ""
+msgid "Deploy container based web apps on Google managed clusters"
+msgstr ""
+
msgid "Deploy freezes"
msgstr ""
@@ -11737,6 +11773,9 @@ msgstr ""
msgid "Deploy progress not found. To see pods, ensure your environment matches %{linkStart}deploy board criteria%{linkEnd}."
msgstr ""
+msgid "Deploy static assets and resources to Google managed CDN"
+msgstr ""
+
msgid "Deploy to..."
msgstr ""
@@ -11949,9 +11988,33 @@ msgstr[1] ""
msgid "Deployment|API"
msgstr ""
+msgid "Deployment|Cancelled"
+msgstr ""
+
+msgid "Deployment|Created"
+msgstr ""
+
+msgid "Deployment|Failed"
+msgstr ""
+
+msgid "Deployment|Running"
+msgstr ""
+
+msgid "Deployment|Skipped"
+msgstr ""
+
+msgid "Deployment|Success"
+msgstr ""
+
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Waiting"
+msgstr ""
+
+msgid "Deployment|blocked"
+msgstr ""
+
msgid "Deployment|canceled"
msgstr ""
@@ -12512,9 +12575,6 @@ msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
-msgid "Discover|Send feedback"
-msgstr ""
-
msgid "Discover|Start a free trial"
msgstr ""
@@ -12580,7 +12640,7 @@ msgstr ""
msgid "Display time tracking in issues in total hours only."
msgstr ""
-msgid "Do not display offers from third parties"
+msgid "Do not display content for customer experience improvement and offers from third parties"
msgstr ""
msgid "Do not force push over diverged refs. After the mirror is created, this setting can only be modified using the API. %{mirroring_docs_link_start}Learn more about this option%{link_closing_tag} and %{mirroring_api_docs_link_start}the API.%{link_closing_tag}"
@@ -12775,7 +12835,7 @@ msgstr ""
msgid "Edit Deploy Key"
msgstr ""
-msgid "Edit Geo Node"
+msgid "Edit Geo Site"
msgstr ""
msgid "Edit Group Hook"
@@ -12832,6 +12892,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13018,6 +13081,9 @@ msgstr ""
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 ""
+
msgid "EmailError|You are not allowed to perform this action. If you believe this is in error, contact a staff member."
msgstr ""
@@ -13162,9 +13228,6 @@ msgstr ""
msgid "Enable automatic repository housekeeping"
msgstr ""
-msgid "Enable classification control using an external service"
-msgstr ""
-
msgid "Enable container expiration and retention policies for projects created earlier than GitLab 12.7."
msgstr ""
@@ -13207,6 +13270,9 @@ msgstr ""
msgid "Enable kuromoji custom analyzer: Search"
msgstr ""
+msgid "Enable logs collection"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -13234,6 +13300,12 @@ msgstr ""
msgid "Enable repository checks"
msgstr ""
+msgid "Enable security training"
+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 ""
+
msgid "Enable shared runners for all projects and subgroups in this group."
msgstr ""
@@ -13312,9 +13384,6 @@ msgstr ""
msgid "Ends: %{endsAt}"
msgstr ""
-msgid "Enforce DNS rebinding attack protection"
-msgstr ""
-
msgid "Enforce SSH key expiration"
msgstr ""
@@ -13363,6 +13432,9 @@ msgstr ""
msgid "Enter in your Phabricator Server URL and personal access token below"
msgstr ""
+msgid "Enter license key"
+msgstr ""
+
msgid "Enter merge request URLs"
msgstr ""
@@ -13773,6 +13845,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -14447,9 +14522,6 @@ msgstr ""
msgid "Exported requirements"
msgstr ""
-msgid "External Classification Policy Authorization"
-msgstr ""
-
msgid "External ID"
msgstr ""
@@ -14459,15 +14531,9 @@ msgstr ""
msgid "External User:"
msgstr ""
-msgid "External authentication"
-msgstr ""
-
msgid "External authorization denied access to this project"
msgstr ""
-msgid "External authorization request timeout"
-msgstr ""
-
msgid "External storage URL"
msgstr ""
@@ -14483,6 +14549,54 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
+msgid "ExternalAuthorization|Access to projects is validated on an external service using their classification label."
+msgstr ""
+
+msgid "ExternalAuthorization|Certificate used to authenticate with the external authorization service. If blank, the server certificate is validated when accessing over HTTPS."
+msgstr ""
+
+msgid "ExternalAuthorization|Classification label to use when requesting authorization if no specific label is defined on the project."
+msgstr ""
+
+msgid "ExternalAuthorization|Client authorization certificate"
+msgstr ""
+
+msgid "ExternalAuthorization|Client authorization key"
+msgstr ""
+
+msgid "ExternalAuthorization|Client authorization key password (optional)"
+msgstr ""
+
+msgid "ExternalAuthorization|Default classification label"
+msgstr ""
+
+msgid "ExternalAuthorization|Enable classification control using an external service"
+msgstr ""
+
+msgid "ExternalAuthorization|External authorization"
+msgstr ""
+
+msgid "ExternalAuthorization|External authorization request timeout (seconds)"
+msgstr ""
+
+msgid "ExternalAuthorization|External classification policy authorization."
+msgstr ""
+
+msgid "ExternalAuthorization|Passphrase required to decrypt the private key. Encrypted when stored."
+msgstr ""
+
+msgid "ExternalAuthorization|Period GitLab waits for a response from the external service. If there is no response, access is denied. Default: 0.5 seconds."
+msgstr ""
+
+msgid "ExternalAuthorization|Private key of client authentication certificate. Encrypted when stored."
+msgstr ""
+
+msgid "ExternalAuthorization|Service URL"
+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|Not all data may be displayed here. To view more details or make changes to this issue, go to %{linkStart}%{trackerName}%{linkEnd}."
msgstr ""
@@ -14566,7 +14680,7 @@ msgstr ""
msgid "Failed to create merge request. Please try again."
msgstr ""
-msgid "Failed to create new project access token: %{token_response_message}"
+msgid "Failed to create new access token: %{token_response_message}"
msgstr ""
msgid "Failed to create repository"
@@ -15473,6 +15587,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -15503,6 +15620,9 @@ msgstr ""
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 ""
+
msgid "Generate key"
msgstr ""
@@ -15539,15 +15659,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Nodes"
-msgstr ""
-
msgid "Geo Replication"
msgstr ""
msgid "Geo Settings"
msgstr ""
+msgid "Geo Sites"
+msgstr ""
+
msgid "Geo sites"
msgstr ""
@@ -15641,6 +15761,9 @@ msgstr ""
msgid "Geo|Does not match the primary storage configuration"
msgstr ""
+msgid "Geo|Edit %{nodeType} site"
+msgstr ""
+
msgid "Geo|Failed"
msgstr ""
@@ -15770,6 +15893,9 @@ msgstr ""
msgid "Geo|Remove"
msgstr ""
+msgid "Geo|Remove %{nodeType} site"
+msgstr ""
+
msgid "Geo|Remove entry"
msgstr ""
@@ -15959,6 +16085,9 @@ msgstr ""
msgid "Get a free instance review"
msgstr ""
+msgid "Get a free trial"
+msgstr ""
+
msgid "Get a support subscription"
msgstr ""
@@ -16082,9 +16211,6 @@ msgstr ""
msgid "GitLab export"
msgstr ""
-msgid "GitLab for Slack"
-msgstr ""
-
msgid "GitLab group: %{source_link}"
msgstr ""
@@ -16109,6 +16235,9 @@ msgstr ""
msgid "GitLab is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "GitLab logo"
+msgstr ""
+
msgid "GitLab member or Email address"
msgstr ""
@@ -16289,6 +16418,9 @@ msgstr ""
msgid "Gitpod|The URL to your Gitpod instance configured to read your GitLab projects, such as https://gitpod.example.com."
msgstr ""
+msgid "Gitpod|To use Gitpod you must first enable the feature in the integrations section of your %{linkStart}user preferences%{linkEnd}."
+msgstr ""
+
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 ""
@@ -16334,9 +16466,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16598,6 +16727,9 @@ msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group Access Tokens"
+msgstr ""
+
msgid "Group Git LFS status:"
msgstr ""
@@ -16616,6 +16748,9 @@ msgstr ""
msgid "Group URL"
msgstr ""
+msgid "Group access token creation is disabled in this group. You can still use and manage existing tokens. %{link_start}Learn more.%{link_end}"
+msgstr ""
+
msgid "Group application: %{name}"
msgstr ""
@@ -16679,9 +16814,6 @@ msgstr ""
msgid "Group jobs by"
msgstr ""
-msgid "Group maintainers can register group runners in the %{link}"
-msgstr ""
-
msgid "Group members"
msgstr ""
@@ -16706,6 +16838,9 @@ msgstr ""
msgid "Group overview content"
msgstr ""
+msgid "Group owners can register group runners in the %{link}"
+msgstr ""
+
msgid "Group path is already taken. We've suggested one that is available."
msgstr ""
@@ -16718,9 +16853,6 @@ msgstr ""
msgid "Group project URLs are prefixed with the group namespace"
msgstr ""
-msgid "Group projects"
-msgstr ""
-
msgid "Group requires separate account"
msgstr ""
@@ -16961,18 +17093,12 @@ msgstr ""
msgid "GroupSAML|SAML group link was successfully removed."
msgstr ""
-msgid "GroupSAML|SCIM API endpoint URL"
-msgstr ""
-
msgid "GroupSAML|SCIM Token"
msgstr ""
msgid "GroupSAML|SHA1 fingerprint of the SAML token signing certificate. Get this from your identity provider, where it can also be called \"Thumbprint\"."
msgstr ""
-msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
-msgstr ""
-
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
msgstr ""
@@ -16997,9 +17123,6 @@ msgstr ""
msgid "GroupSAML|With prohibit outer forks flag enabled group members will be able to fork project only inside your group."
msgstr ""
-msgid "GroupSAML|Your SCIM token"
-msgstr ""
-
msgid "GroupSAML|as %{access_level}"
msgstr ""
@@ -17030,7 +17153,10 @@ msgstr ""
msgid "GroupSelect|Select a group"
msgstr ""
-msgid "GroupSettings|Allow project access token creation"
+msgid "GroupSettings|Allow project and group access token creation"
+msgstr ""
+
+msgid "GroupSettings|Allows creating organizations and contacts and associating them with issues."
msgstr ""
msgid "GroupSettings|Applied to all subgroups unless overridden by a group owner. Groups already added to the project lose access."
@@ -17078,6 +17204,9 @@ msgstr ""
msgid "GroupSettings|Disable group mentions"
msgstr ""
+msgid "GroupSettings|Enable customer relations"
+msgstr ""
+
msgid "GroupSettings|Enable delayed project deletion"
msgstr ""
@@ -17171,7 +17300,7 @@ msgstr ""
msgid "GroupSettings|Transfer group"
msgstr ""
-msgid "GroupSettings|Users can create %{link_start}project access tokens%{link_end} for projects in this group."
+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 ""
msgid "GroupSettings|What are badges?"
@@ -17637,9 +17766,6 @@ msgstr ""
msgid "How do I use file templates?"
msgstr ""
-msgid "How it works"
-msgstr ""
-
msgid "How many days need to pass between marking entity for deletion and actual removing it."
msgstr ""
@@ -17754,6 +17880,18 @@ msgstr ""
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 ""
+
+msgid "IdentityVerification|Before you create your group, we need you to verify your identity with a valid payment method."
+msgstr ""
+
+msgid "IdentityVerification|Create a project"
+msgstr ""
+
+msgid "IdentityVerification|Verify your identity"
+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 ""
@@ -17778,9 +17916,6 @@ msgstr ""
msgid "If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "If enabled, access to projects will be validated on an external service using their classification label."
-msgstr ""
-
msgid "If enabled, only protected branches will be mirrored."
msgstr ""
@@ -18381,6 +18516,9 @@ msgstr ""
msgid "InProductMarketing|Start a GitLab Ultimate trial today in less than one minute, no credit card required."
msgstr ""
+msgid "InProductMarketing|Start a Self-Managed trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18483,6 +18621,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Want to host GitLab on your servers?"
+msgstr ""
+
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 ""
@@ -18558,6 +18699,9 @@ msgstr ""
msgid "Incident Management Limits"
msgstr ""
+msgid "Incident details"
+msgstr ""
+
msgid "Incident template (optional)."
msgstr ""
@@ -19574,9 +19718,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -20785,6 +20926,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21010,6 +21157,9 @@ msgstr ""
msgid "License file"
msgstr ""
+msgid "License key"
+msgstr ""
+
msgid "License overview"
msgstr ""
@@ -21333,9 +21483,6 @@ msgstr ""
msgid "Loading…"
msgstr ""
-msgid "Local IP addresses and domain names that hooks and services may access."
-msgstr ""
-
msgid "Localization"
msgstr ""
@@ -21351,6 +21498,9 @@ msgstr ""
msgid "Lock %{issuableDisplayName}"
msgstr ""
+msgid "Lock File?"
+msgstr ""
+
msgid "Lock memberships to LDAP synchronization"
msgstr ""
@@ -21387,6 +21537,39 @@ msgstr ""
msgid "Locks the discussion."
msgstr ""
+msgid "LoggedOutMarketingHeader|About GitLab"
+msgstr ""
+
+msgid "LoggedOutMarketingHeader|Explore GitLab"
+msgstr ""
+
+msgid "LoggedOutMarketingHeader|Get started"
+msgstr ""
+
+msgid "LoggedOutMarketingHeader|GitLab Learn"
+msgstr ""
+
+msgid "LoggedOutMarketingHeader|GitLab docs"
+msgstr ""
+
+msgid "LoggedOutMarketingHeader|GitLab: the DevOps platform"
+msgstr ""
+
+msgid "LoggedOutMarketingHeader|How GitLab compares"
+msgstr ""
+
+msgid "LoggedOutMarketingHeader|Install GitLab"
+msgstr ""
+
+msgid "LoggedOutMarketingHeader|Pricing"
+msgstr ""
+
+msgid "LoggedOutMarketingHeader|Talk to an expert"
+msgstr ""
+
+msgid "Login"
+msgstr ""
+
msgid "Login with smartcard"
msgstr ""
@@ -22302,10 +22485,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -23002,9 +23185,6 @@ msgstr ""
msgid "More Information"
msgstr ""
-msgid "More Slack commands"
-msgstr ""
-
msgid "More actions"
msgstr ""
@@ -23026,6 +23206,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -23202,10 +23385,10 @@ 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 "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}."
+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 ""
-msgid "NamespaceUserCap|View pending user approvals"
+msgid "NamespaceUserCap|View pending approvals"
msgstr ""
msgid "NamespaceUserCap|Your group has reached its billable member limit"
@@ -23229,6 +23412,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23379,9 +23595,6 @@ msgstr ""
msgid "NetworkPolicies|To enable alerts, %{installLinkStart}install an agent%{installLinkEnd} first."
msgstr ""
-msgid "NetworkPolicies|Traffic that does not match any rule will be blocked."
-msgstr ""
-
msgid "NetworkPolicies|all DNS names"
msgstr ""
@@ -23442,6 +23655,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23921,6 +24137,9 @@ msgstr ""
msgid "No profiles found"
msgstr ""
+msgid "No project subscribes to the pipelines in this project."
+msgstr ""
+
msgid "No projects found"
msgstr ""
@@ -23987,7 +24206,7 @@ msgstr ""
msgid "No webhook events"
msgstr ""
-msgid "No webhooks found, add one in the form above."
+msgid "No webhooks enabled. Select trigger events above."
msgstr ""
msgid "No worries, you can still use all the %{strong}%{plan_name}%{strong_close} features for now. You have %{remaining_days} day to renew your subscription."
@@ -24088,6 +24307,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -24507,6 +24729,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24525,12 +24753,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24573,12 +24807,18 @@ msgstr ""
msgid "OnDemandScans|Repeats"
msgstr ""
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24615,6 +24855,9 @@ msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
msgid "OnDemandScans|There are no scheduled scans."
msgstr ""
@@ -24794,6 +25037,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -24869,7 +25115,28 @@ msgstr ""
msgid "Out-of-compliance with this project's policies and should be removed"
msgstr ""
-msgid "Outbound requests"
+msgid "OutboundRequests|Allow requests to the local network from hooks and services."
+msgstr ""
+
+msgid "OutboundRequests|Allow requests to the local network from system hooks"
+msgstr ""
+
+msgid "OutboundRequests|Allow requests to the local network from web hooks and services"
+msgstr ""
+
+msgid "OutboundRequests|Enforce DNS rebinding attack protection"
+msgstr ""
+
+msgid "OutboundRequests|Local IP addresses and domain names that hooks and services may access"
+msgstr ""
+
+msgid "OutboundRequests|Outbound requests"
+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 ""
msgid "OutdatedBrowser|GitLab may not work properly, because you are using an outdated web browser."
@@ -25486,9 +25753,6 @@ msgstr ""
msgid "Paste this DSN into your Sentry SDK"
msgstr ""
-msgid "Paste your public SSH key, which is usually contained in the file '~/.ssh/id_ed25519.pub' or '~/.ssh/id_rsa.pub' and begins with 'ssh-ed25519' or 'ssh-rsa'. Do not paste your private SSH key, as that can compromise your identity."
-msgstr ""
-
msgid "Patch to apply"
msgstr ""
@@ -25627,9 +25891,15 @@ 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 ""
@@ -25642,7 +25912,7 @@ msgstr ""
msgid "Permissions Help"
msgstr ""
-msgid "Permissions, LFS, 2FA"
+msgid "Permissions and group features"
msgstr ""
msgid "Personal Access Token"
@@ -25711,12 +25981,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25930,6 +26194,9 @@ msgstr ""
msgid "Pipelines|Are you sure you want to run this pipeline?"
msgstr ""
+msgid "Pipelines|Auto DevOps"
+msgstr ""
+
msgid "Pipelines|Build with confidence"
msgstr ""
@@ -25942,12 +26209,15 @@ msgstr ""
msgid "Pipelines|CI/CD template to test and deploy your %{name} project."
msgstr ""
-msgid "Pipelines|Child pipeline"
+msgid "Pipelines|Child pipeline (%{link_start}parent%{link_end})"
msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -26104,10 +26374,25 @@ msgstr ""
msgid "Pipelines|Visualize"
msgstr ""
+msgid "Pipelines|detached"
+msgstr ""
+
+msgid "Pipelines|error"
+msgstr ""
+
msgid "Pipelines|invalid"
msgstr ""
-msgid "Pipelines|parent"
+msgid "Pipelines|latest"
+msgstr ""
+
+msgid "Pipelines|stuck"
+msgstr ""
+
+msgid "Pipelines|train"
+msgstr ""
+
+msgid "Pipelines|yaml invalid"
msgstr ""
msgid "Pipeline|Actions"
@@ -26305,6 +26590,12 @@ msgstr ""
msgid "Please %{link_to_register} or %{link_to_sign_in} to comment"
msgstr ""
+msgid "Please %{registerLinkStart}register%{registerLinkEnd} or %{signInLinkStart}sign in%{signInLinkEnd} to reply."
+msgstr ""
+
+msgid "Please %{registerLinkStart}register%{registerLinkEnd} or %{signInLinkStart}sign in%{signInLinkEnd} to start a new discussion."
+msgstr ""
+
msgid "Please %{startTagRegister}register%{endRegisterTag} or %{startTagSignIn}sign in%{endSignInTag} to reply"
msgstr ""
@@ -26461,6 +26752,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26656,7 +26950,7 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
+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 "Prev"
@@ -26884,6 +27178,9 @@ msgstr ""
msgid "Profiles|Avatar will be removed. Are you sure?"
msgstr ""
+msgid "Profiles|Begins with %{ssh_key_algorithms}."
+msgstr ""
+
msgid "Profiles|Bio"
msgstr ""
@@ -27010,6 +27307,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -27067,6 +27367,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -27124,9 +27430,6 @@ msgstr ""
msgid "Profiles|Type your %{confirmationValue} to confirm:"
msgstr ""
-msgid "Profiles|Typically starts with \"ssh-ed25519 …\" or \"ssh-rsa …\""
-msgstr ""
-
msgid "Profiles|Update profile settings"
msgstr ""
@@ -27151,6 +27454,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27613,6 +27919,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27724,6 +28033,9 @@ msgstr ""
msgid "ProjectSettings|Highlight the usage of hidden unicode characters. These have innocent uses for right-to-left languages, but can also be used in potential exploits."
msgstr ""
+msgid "ProjectSettings|If merge trains are enabled, merging is only possible if the branch can be rebased without conflicts."
+msgstr ""
+
msgid "ProjectSettings|Internal"
msgstr ""
@@ -27865,19 +28177,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -28033,6 +28342,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28534,6 +28852,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28579,6 +28900,9 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -28687,9 +29011,6 @@ msgstr ""
msgid "Public deploy keys"
msgstr ""
-msgid "Public deploy keys (%{deploy_keys_count})"
-msgstr ""
-
msgid "Public pipelines"
msgstr ""
@@ -28876,6 +29197,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28963,6 +29290,12 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
+msgid "Rebase without CI"
+msgstr ""
+
+msgid "Rebases and triggers a pipeline"
+msgstr ""
+
msgid "Recaptcha verified?"
msgstr ""
@@ -29032,6 +29365,9 @@ msgstr ""
msgid "Reduce project visibility"
msgstr ""
+msgid "Reduce risk and triage fewer vulnerabilities with security training"
+msgstr ""
+
msgid "Reduce this project’s visibility?"
msgstr ""
@@ -29106,10 +29442,19 @@ msgstr ""
msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
msgstr ""
-msgid "RegistrationFeatures|Read more about the %{linkStart}Registration Features Program%{linkEnd}."
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
msgstr ""
-msgid "RegistrationFeatures|Want to use this feature for free?"
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
msgstr ""
msgid "RegistrationVerification|Are you sure you want to skip this step?"
@@ -29938,9 +30283,6 @@ msgstr ""
msgid "Requests per period"
msgstr ""
-msgid "Requests to these domain(s)/address(es) on the local network will be allowed when local requests from hooks and services are not allowed. IP ranges such as 1:0:0:0:0:0:0:0/124 or 127.0.0.0/28 are supported. Domain wildcards are not supported currently. Use comma, semicolon, or newline to separate multiple entries. The allowlist can hold a maximum of 1000 entries. Domains should use IDNA encoding. Ex: example.com, 192.168.1.1, 127.0.0.0/28, xn--itlab-j1a.com."
-msgstr ""
-
msgid "Require additional authentication for administrative tasks."
msgstr ""
@@ -30086,9 +30428,6 @@ msgstr ""
msgid "Resolved by %{name}"
msgstr ""
-msgid "Resolves IP addresses once and uses them to submit requests"
-msgstr ""
-
msgid "Response"
msgstr ""
@@ -30155,7 +30494,7 @@ msgstr ""
msgid "Resync"
msgstr ""
-msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgid "Retrieving the compliance report failed. Refresh the page and try again."
msgstr ""
msgid "Retry"
@@ -30255,13 +30594,13 @@ msgstr ""
msgid "Revoked"
msgstr ""
-msgid "Revoked impersonation token %{token_name}!"
+msgid "Revoked access token %{access_token_name}!"
msgstr ""
-msgid "Revoked personal access token %{personal_access_token_name}!"
+msgid "Revoked impersonation token %{token_name}!"
msgstr ""
-msgid "Revoked project access token %{project_access_token_name}!"
+msgid "Revoked personal access token %{personal_access_token_name}!"
msgstr ""
msgid "RightSidebar|Copy email address"
@@ -30381,6 +30720,9 @@ msgstr ""
msgid "Runners|Can run untagged jobs"
msgstr ""
+msgid "Runners|Change to project runner"
+msgstr ""
+
msgid "Runners|Command to register runner"
msgstr ""
@@ -30447,10 +30789,13 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
msgid "Runners|No contact from this runner in over 3 months"
@@ -30462,16 +30807,16 @@ msgstr ""
msgid "Runners|Not available to run jobs"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Offline"
msgstr ""
-msgid "Runners|Offline"
+msgid "Runners|Offline runners"
msgstr ""
msgid "Runners|Online"
msgstr ""
-msgid "Runners|Online Runners"
+msgid "Runners|Online runners"
msgstr ""
msgid "Runners|Paused"
@@ -30567,6 +30912,9 @@ msgstr ""
msgid "Runners|Stale"
msgstr ""
+msgid "Runners|Stale runners"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30579,10 +30927,7 @@ 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 ""
-msgid "Runners|This runner has never connected to this instance"
-msgstr ""
-
-msgid "Runners|This runner is associated with one or more projects."
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with specific projects."
@@ -30648,7 +30993,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30867,9 +31212,6 @@ msgstr ""
msgid "Search GitLab"
msgstr ""
-msgid "Search Jira issues"
-msgstr ""
-
msgid "Search a group"
msgstr ""
@@ -30930,6 +31272,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30951,9 +31296,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -31234,6 +31576,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -31300,6 +31645,9 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
+msgid "SecurityOrchestration| or "
+msgstr ""
+
msgid "SecurityOrchestration|%{branches} %{plural}"
msgstr ""
@@ -31378,15 +31726,18 @@ msgstr ""
msgid "SecurityOrchestration|Policy editor"
msgstr ""
-msgid "SecurityOrchestration|Policy preview"
+msgid "SecurityOrchestration|Policy status"
msgstr ""
-msgid "SecurityOrchestration|Policy status"
+msgid "SecurityOrchestration|Policy summary"
msgstr ""
msgid "SecurityOrchestration|Policy type"
msgstr ""
+msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
+msgstr ""
+
msgid "SecurityOrchestration|Rule"
msgstr ""
@@ -31396,12 +31747,18 @@ msgstr ""
msgid "SecurityOrchestration|Scan Execution"
msgstr ""
+msgid "SecurityOrchestration|Scan Result"
+msgstr ""
+
msgid "SecurityOrchestration|Scan execution"
msgstr ""
msgid "SecurityOrchestration|Scan execution policies can only be created by project owners."
msgstr ""
+msgid "SecurityOrchestration|Scan result"
+msgstr ""
+
msgid "SecurityOrchestration|Scan to be performed %{cadence}"
msgstr ""
@@ -31429,6 +31786,9 @@ msgstr ""
msgid "SecurityOrchestration|Status"
msgstr ""
+msgid "SecurityOrchestration|The %{scanners} %{severities} in an open merge request targeting the %{branches}."
+msgstr ""
+
msgid "SecurityOrchestration|There was a problem creating the new security policy"
msgstr ""
@@ -31447,9 +31807,51 @@ msgstr ""
msgid "SecurityOrchestration|Update scan execution policies"
msgstr ""
+msgid "SecurityOrchestration|a"
+msgstr ""
+
+msgid "SecurityOrchestration|an"
+msgstr ""
+
+msgid "SecurityOrchestration|branch"
+msgstr ""
+
+msgid "SecurityOrchestration|branches"
+msgstr ""
+
+msgid "SecurityOrchestration|members of groups"
+msgstr ""
+
+msgid "SecurityOrchestration|members of groups with ids"
+msgstr ""
+
+msgid "SecurityOrchestration|members of the group"
+msgstr ""
+
+msgid "SecurityOrchestration|members of the group with id"
+msgstr ""
+
+msgid "SecurityOrchestration|scanner finds"
+msgstr ""
+
+msgid "SecurityOrchestration|scanners find"
+msgstr ""
+
+msgid "SecurityOrchestration|user with id"
+msgstr ""
+
+msgid "SecurityOrchestration|users with ids"
+msgstr ""
+
msgid "SecurityOrchestration|view results"
msgstr ""
+msgid "SecurityOrchestration|vulnerabilities"
+msgstr ""
+
+msgid "SecurityOrchestration|vulnerability"
+msgstr ""
+
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31459,6 +31861,9 @@ msgstr ""
msgid "SecurityPolicies|Policy type"
msgstr ""
+msgid "SecurityReports|%{count}+ projects"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -31648,6 +32053,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31777,9 +32185,6 @@ msgstr ""
msgid "Select Git revision"
msgstr ""
-msgid "Select GitLab project to link with your Slack team"
-msgstr ""
-
msgid "Select Page"
msgstr ""
@@ -31894,6 +32299,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -32164,9 +32572,6 @@ 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 URL"
-msgstr ""
-
msgid "Service account generated successfully"
msgstr ""
@@ -32182,18 +32587,12 @@ msgstr ""
msgid "ServiceDesk|Issues created from Service Desk emails will appear here. Each comment becomes part of the email conversation."
msgstr ""
-msgid "ServiceDesk|Service Desk is enabled but not yet active"
-msgstr ""
-
msgid "ServiceDesk|Service Desk is not enabled"
msgstr ""
msgid "ServiceDesk|Service Desk is not supported"
msgstr ""
-msgid "ServiceDesk|To activate Service Desk on this instance, an instance administrator must first set up incoming email."
-msgstr ""
-
msgid "ServiceDesk|To enable Service Desk on this instance, an instance administrator must first set up incoming email."
msgstr ""
@@ -32245,6 +32644,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32401,6 +32806,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32496,9 +32904,6 @@ msgstr ""
msgid "SharedRunnersMinutesSettings|Reset used pipeline minutes"
msgstr ""
-msgid "Sherlock Transactions"
-msgstr ""
-
msgid "Shimo|Go to Shimo Workspace"
msgstr ""
@@ -32722,6 +33127,9 @@ msgstr ""
msgid "Sign up"
msgstr ""
+msgid "Sign up now"
+msgstr ""
+
msgid "Sign up was successful! Please confirm your email to sign in."
msgstr ""
@@ -32824,9 +33232,27 @@ msgstr ""
msgid "Slack integration allows you to interact with GitLab via slash commands in a chat window."
msgstr ""
+msgid "Slack logo"
+msgstr ""
+
+msgid "SlackIntegration|GitLab for Slack"
+msgstr ""
+
+msgid "SlackIntegration|Project alias"
+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 ""
+msgid "SlackIntegration|Team name"
+msgstr ""
+
+msgid "SlackIntegration|To set up this integration press \"Add to Slack\""
+msgstr ""
+
msgid "SlackService|1. %{slash_command_link_start}Add a slash command%{slash_command_link_end} in your Slack team using this information:"
msgstr ""
@@ -33199,9 +33625,6 @@ msgstr ""
msgid "SortOptions|Last created"
msgstr ""
-msgid "SortOptions|Last updated"
-msgstr ""
-
msgid "SortOptions|Least popular"
msgstr ""
@@ -33547,9 +33970,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33922,6 +34342,9 @@ msgstr ""
msgid "Subscribed to this %{quick_action_target}."
msgstr ""
+msgid "Subscribed to this project"
+msgstr ""
+
msgid "Subscribes to this %{quick_action_target}."
msgstr ""
@@ -34030,9 +34453,6 @@ msgstr ""
msgid "SubscriptionTable|Trial start date"
msgstr ""
-msgid "SubscriptionTable|Upgrade"
-msgstr ""
-
msgid "SubscriptionTable|Usage"
msgstr ""
@@ -34387,6 +34807,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34630,6 +35068,9 @@ msgstr ""
msgid "Terms of Service and Privacy Policy"
msgstr ""
+msgid "Terms of service"
+msgstr ""
+
msgid "Terraform"
msgstr ""
@@ -34655,9 +35096,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34688,6 +35145,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34700,6 +35160,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34736,12 +35199,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34982,12 +35454,6 @@ msgstr ""
msgid "The Snowplow cookie domain."
msgstr ""
-msgid "The URL defined on the primary node that secondary nodes should use to contact it."
-msgstr ""
-
-msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
-msgstr ""
-
msgid "The URL of the Jenkins server."
msgstr ""
@@ -34997,9 +35463,6 @@ msgstr ""
msgid "The URLs for connecting to Elasticsearch. For clustering, add the URLs separated by commas."
msgstr ""
-msgid "The X509 Certificate to use when mutual TLS is required to communicate with the external authorization service. If left blank, the server certificate is still validated when accessing over HTTPS."
-msgstr ""
-
msgid "The application will be used where the client secret can be kept confidential. Native mobile apps and Single Page Apps are considered non-confidential."
msgstr ""
@@ -35033,7 +35496,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 same group as the issue"
+msgid "The contact does not belong to the issue group or an ancestor"
msgstr ""
msgid "The content editor may change the markdown formatting style of the document, which may not match your original markdown style."
@@ -35233,7 +35696,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35275,9 +35738,6 @@ msgstr ""
msgid "The parent epic is confidential and can only contain confidential epics and issues"
msgstr ""
-msgid "The passphrase required to decrypt the private key. This is optional and the value is encrypted at rest."
-msgstr ""
-
msgid "The password for the Jenkins server."
msgstr ""
@@ -35293,9 +35753,6 @@ msgstr ""
msgid "The pipelines schedule runs pipelines in the future, repeatedly, for specific branches or tags. Those scheduled pipelines will inherit limited project access based on their associated user."
msgstr ""
-msgid "The private key to use when a client certificate is provided. This value is encrypted at rest."
-msgstr ""
-
msgid "The project can be accessed by any logged in user except external users."
msgstr ""
@@ -35800,9 +36257,6 @@ msgstr ""
msgid "Third Party Advisory Link"
msgstr ""
-msgid "Third-party offers"
-msgstr ""
-
msgid "This %{issuableDisplayName} is locked. Only project members can comment."
msgstr ""
@@ -36007,6 +36461,9 @@ msgstr ""
msgid "This group has been scheduled for permanent removal on %{date}"
msgstr ""
+msgid "This group has no active access tokens."
+msgstr ""
+
msgid "This group is linked to a subscription"
msgstr ""
@@ -36229,6 +36686,9 @@ 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."
+msgstr ""
+
msgid "This project does not belong to a group and cannot make use of group runners."
msgstr ""
@@ -36250,6 +36710,9 @@ msgstr ""
msgid "This project is licensed under the %{strong_start}%{license_name}%{strong_end}."
msgstr ""
+msgid "This project is not subscribed to any project pipelines."
+msgstr ""
+
msgid "This project manages its dependencies using %{strong_start}%{manager_name}%{strong_end}"
msgstr ""
@@ -36289,6 +36752,9 @@ msgstr ""
msgid "This setting can be overridden in each project."
msgstr ""
+msgid "This setting is allowed for forked projects only"
+msgstr ""
+
msgid "This subscription is for"
msgstr ""
@@ -36517,9 +36983,6 @@ msgstr ""
msgid "Time in seconds"
msgstr ""
-msgid "Time in seconds GitLab will wait for a response from the external service. When the service does not respond in time, access will be denied."
-msgstr ""
-
msgid "Time of import: %{importTime}"
msgstr ""
@@ -36767,9 +37230,6 @@ msgstr ""
msgid "To add a custom suffix, set up a Service Desk email address. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
-msgid "To add an SSH key you need to %{generate_link_start}generate one%{link_end} or use an %{existing_link_start}existing key%{link_end}."
-msgstr ""
-
msgid "To add the entry manually, provide the following details to the application on your phone."
msgstr ""
@@ -36911,9 +37371,6 @@ msgstr ""
msgid "To update Snippets with multiple files, you must use the `files` parameter"
msgstr ""
-msgid "To use Gitpod you must first enable the feature in the integrations section of your %{user_prefs}."
-msgstr ""
-
msgid "To use the additional formats, you must start the required %{container_link_start}companion containers%{container_link_end}."
msgstr ""
@@ -36941,6 +37398,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -37106,9 +37596,6 @@ msgstr ""
msgid "Track time with quick actions"
msgstr ""
-msgid "Track your GitLab projects with GitLab for Slack."
-msgstr ""
-
msgid "Training mode"
msgstr ""
@@ -37219,6 +37706,9 @@ msgstr ""
msgid "Trials|Your trial ends on %{boldStart}%{trialEndDate}%{boldEnd}. We hope you’re enjoying the features of GitLab %{planName}. To keep those features after your trial ends, you’ll need to buy a subscription. (You can also choose GitLab Premium if it meets your needs.)"
msgstr ""
+msgid "Trial|Allowed characters: +, 0-9, -, and spaces."
+msgstr ""
+
msgid "Trial|Company name"
msgstr ""
@@ -37234,24 +37724,9 @@ msgstr ""
msgid "Trial|Dismiss"
msgstr ""
-msgid "Trial|First name"
-msgstr ""
-
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
-msgid "Trial|Last name"
-msgstr ""
-
msgid "Trial|Number of employees"
msgstr ""
@@ -37273,9 +37748,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37840,6 +38312,9 @@ msgstr ""
msgid "Updated %{updated_at} by %{updated_by}"
msgstr ""
+msgid "Updated date"
+msgstr ""
+
msgid "Updates"
msgstr ""
@@ -37861,6 +38336,9 @@ msgstr ""
msgid "Upload"
msgstr ""
+msgid "Upload %{file_name} file"
+msgstr ""
+
msgid "Upload CSV file"
msgstr ""
@@ -38296,6 +38774,9 @@ msgstr ""
msgid "User cap"
msgstr ""
+msgid "User cap cannot be enabled. The group or one of its subgroups or projects is shared externally."
+msgstr ""
+
msgid "User created at"
msgstr ""
@@ -38794,16 +39275,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38827,6 +39308,18 @@ msgstr ""
msgid "Version %{versionNumber} (latest)"
msgstr ""
+msgid "VersionCheck|Up to date"
+msgstr ""
+
+msgid "VersionCheck|Update ASAP"
+msgstr ""
+
+msgid "VersionCheck|Update available"
+msgstr ""
+
+msgid "VersionCheck|Your GitLab Version"
+msgstr ""
+
msgid "View Documentation"
msgstr ""
@@ -39085,6 +39578,9 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
msgid "VulnerabilityManagement|A removed or remediated vulnerability"
msgstr ""
@@ -39196,6 +39692,9 @@ msgstr ""
msgid "Vulnerability|Actual received response is the one received when this fault was detected"
msgstr ""
+msgid "Vulnerability|Add another identifier"
+msgstr ""
+
msgid "Vulnerability|Additional Info"
msgstr ""
@@ -39238,6 +39737,9 @@ msgstr ""
msgid "Vulnerability|Download"
msgstr ""
+msgid "Vulnerability|Enter the associated CVE or CWE entries for this vulnerability."
+msgstr ""
+
msgid "Vulnerability|Evidence"
msgstr ""
@@ -39256,6 +39758,12 @@ msgstr ""
msgid "Vulnerability|Identifier"
msgstr ""
+msgid "Vulnerability|Identifier URL"
+msgstr ""
+
+msgid "Vulnerability|Identifier code"
+msgstr ""
+
msgid "Vulnerability|Identifiers"
msgstr ""
@@ -39265,6 +39773,9 @@ msgstr ""
msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
msgstr ""
+msgid "Vulnerability|Learn more about this vulnerability and the best way to resolve it."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -39277,6 +39788,9 @@ msgstr ""
msgid "Vulnerability|Project"
msgstr ""
+msgid "Vulnerability|Remove identifier row"
+msgstr ""
+
msgid "Vulnerability|Reproduction Assets"
msgstr ""
@@ -39313,6 +39827,12 @@ msgstr ""
msgid "Vulnerability|Tool"
msgstr ""
+msgid "Vulnerability|Training"
+msgstr ""
+
+msgid "Vulnerability|Training not available for this vulnerability."
+msgstr ""
+
msgid "Vulnerability|Unmodified Response"
msgstr ""
@@ -39421,6 +39941,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39493,127 +40016,127 @@ msgstr ""
msgid "Webhooks Help"
msgstr ""
-msgid "Webhooks|Comments"
+msgid "Webhooks|A comment is added to a confidential issue."
msgstr ""
-msgid "Webhooks|Confidential comments"
+msgid "Webhooks|A comment is added to an issue."
msgstr ""
-msgid "Webhooks|Confidential issues events"
+msgid "Webhooks|A confidential issue is created, updated, closed, or reopened."
msgstr ""
-msgid "Webhooks|Deployment events"
+msgid "Webhooks|A deployment starts, finishes, fails, or is canceled."
msgstr ""
-msgid "Webhooks|Enable SSL verification"
+msgid "Webhooks|A feature flag is turned on or off."
msgstr ""
-msgid "Webhooks|Failed to connect"
+msgid "Webhooks|A group member is created, updated, or removed."
msgstr ""
-msgid "Webhooks|Fails to connect"
+msgid "Webhooks|A job's status changes."
msgstr ""
-msgid "Webhooks|Feature flag events"
+msgid "Webhooks|A merge request is created, updated, or merged."
msgstr ""
-msgid "Webhooks|Issues events"
+msgid "Webhooks|A new tag is pushed to the repository."
msgstr ""
-msgid "Webhooks|Job events"
+msgid "Webhooks|A pipeline's status changes."
msgstr ""
-msgid "Webhooks|Member events"
+msgid "Webhooks|A release is created or updated."
msgstr ""
-msgid "Webhooks|Merge request events"
+msgid "Webhooks|A subgroup is created or removed."
msgstr ""
-msgid "Webhooks|Pipeline events"
+msgid "Webhooks|A wiki page is created or updated."
msgstr ""
-msgid "Webhooks|Push events"
+msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
-msgid "Webhooks|Releases events"
+msgid "Webhooks|Comments"
msgstr ""
-msgid "Webhooks|SSL verification"
+msgid "Webhooks|Confidential comments"
msgstr ""
-msgid "Webhooks|Secret token"
+msgid "Webhooks|Confidential issues events"
msgstr ""
-msgid "Webhooks|Subgroup events"
+msgid "Webhooks|Deployment events"
msgstr ""
-msgid "Webhooks|Tag push events"
+msgid "Webhooks|Enable SSL verification"
msgstr ""
-msgid "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."
+msgid "Webhooks|Failed to connect"
msgstr ""
-msgid "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."
+msgid "Webhooks|Fails to connect"
msgstr ""
-msgid "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."
+msgid "Webhooks|Feature flag events"
msgstr ""
-msgid "Webhooks|Trigger"
+msgid "Webhooks|Issues events"
msgstr ""
-msgid "Webhooks|URL"
+msgid "Webhooks|Job events"
msgstr ""
-msgid "Webhooks|URL is triggered by a push to the repository"
+msgid "Webhooks|Member events"
msgstr ""
-msgid "Webhooks|URL is triggered when a confidential issue is created, updated, closed, or reopened"
+msgid "Webhooks|Merge request events"
msgstr ""
-msgid "Webhooks|URL is triggered when a deployment starts, finishes, fails, or is canceled"
+msgid "Webhooks|Pipeline events"
msgstr ""
-msgid "Webhooks|URL is triggered when a feature flag is turned on or off"
+msgid "Webhooks|Push events"
msgstr ""
-msgid "Webhooks|URL is triggered when a group member is created, updated, or removed"
+msgid "Webhooks|Push to the repository."
msgstr ""
-msgid "Webhooks|URL is triggered when a merge request is created, updated, or merged"
+msgid "Webhooks|Releases events"
msgstr ""
-msgid "Webhooks|URL is triggered when a new tag is pushed to the repository"
+msgid "Webhooks|SSL verification"
msgstr ""
-msgid "Webhooks|URL is triggered when a release is created or updated"
+msgid "Webhooks|Secret token"
msgstr ""
-msgid "Webhooks|URL is triggered when a subgroup is created or removed"
+msgid "Webhooks|Subgroup events"
msgstr ""
-msgid "Webhooks|URL is triggered when a wiki page is created or updated"
+msgid "Webhooks|Tag push events"
msgstr ""
-msgid "Webhooks|URL is triggered when an issue is created, updated, closed, or reopened"
+msgid "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."
msgstr ""
-msgid "Webhooks|URL is triggered when someone adds a comment"
+msgid "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."
msgstr ""
-msgid "Webhooks|URL is triggered when someone adds a comment on a confidential issue"
+msgid "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."
msgstr ""
-msgid "Webhooks|URL is triggered when the job status changes"
+msgid "Webhooks|Trigger"
msgstr ""
-msgid "Webhooks|URL is triggered when the pipeline status changes"
+msgid "Webhooks|URL"
msgstr ""
-msgid "Webhooks|URL must be percent-encoded if neccessary."
+msgid "Webhooks|URL must be percent-encoded if it contains one or more special characters."
msgstr ""
-msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
+msgid "Webhooks|Used to validate received payloads. Sent with the request in the %{code_start}X-Gitlab-Token HTTP%{code_end} header."
msgstr ""
msgid "Webhooks|Webhook failed to connect"
@@ -39661,6 +40184,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39670,9 +40196,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -39721,10 +40244,10 @@ msgstr ""
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 leaving the URL blank, classification labels can still be specified without disabling cross project features or performing external authorization checks."
+msgid "When inactive, an external authentication provider must be used."
msgstr ""
msgid "When merge requests and commits in the default branch close, any issues they reference also close."
@@ -40032,9 +40555,6 @@ msgstr ""
msgid "Work in progress Limit"
msgstr ""
-msgid "Work in progress- click here to find out more"
-msgstr ""
-
msgid "WorkItem|Work Items"
msgstr ""
@@ -40215,6 +40735,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use group access tokens with Git to authenticate over HTTP(S). %{link_start}Learn more.%{link_end}"
+msgstr ""
+
msgid "You can also use project access tokens with Git to authenticate over HTTP(S). %{link_start}Learn more.%{link_end}"
msgstr ""
@@ -40260,6 +40783,9 @@ msgstr ""
msgid "You can enable Registration Features because Service Ping is enabled. To continue using Registration Features in the future, you will also need to register with GitLab via a new cloud licensing service."
msgstr ""
+msgid "You can enable group access token creation in %{link_start}group settings%{link_end}."
+msgstr ""
+
msgid "You can enable project access token creation in %{link_start}group settings%{link_end}."
msgstr ""
@@ -40487,6 +41013,9 @@ msgstr ""
msgid "You have insufficient permissions to create an on-call schedule for this project"
msgstr ""
+msgid "You have insufficient permissions to manage timeline events for this incident"
+msgstr ""
+
msgid "You have insufficient permissions to remove an on-call rotation from this project"
msgstr ""
@@ -40526,7 +41055,7 @@ msgstr ""
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
-msgid "You have successfully purchased %{product}. You'll receive a receipt by email."
+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 ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
@@ -40922,7 +41451,7 @@ msgstr ""
msgid "Your new %{type}"
msgstr ""
-msgid "Your new SCIM token"
+msgid "Your new access token has been created."
msgstr ""
msgid "Your new comment"
@@ -40931,9 +41460,6 @@ msgstr ""
msgid "Your new personal access token has been created."
msgstr ""
-msgid "Your new project access token has been created."
-msgstr ""
-
msgid "Your password isn't required to view this page. If a password or any other personal details are requested, please contact your administrator to report abuse."
msgstr ""
@@ -41130,6 +41656,11 @@ msgstr ""
msgid "any-approver for the project already exists"
msgstr ""
+msgid "approval"
+msgid_plural "approvals"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "approved by: "
msgstr ""
@@ -41213,6 +41744,9 @@ msgstr ""
msgid "cannot be changed if shared runners are enabled"
msgstr ""
+msgid "cannot be enabled"
+msgstr ""
+
msgid "cannot be enabled because parent group does not allow it"
msgstr ""
@@ -41585,6 +42119,9 @@ msgstr ""
msgid "compliance violation has already been recorded"
msgstr ""
+msgid "contact with same email already exists in group hierarchy"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41612,12 +42149,6 @@ msgstr ""
msgid "created %{timeAgoString} by %{email} via %{user}"
msgstr ""
-msgid "created %{timeAgoString} by %{user}"
-msgstr ""
-
-msgid "created %{timeAgoString} by %{user} in Jira"
-msgstr ""
-
msgid "created %{timeAgo}"
msgstr ""
@@ -41745,6 +42276,9 @@ msgstr ""
msgid "failed to dismiss associated finding(id=%{finding_id}): %{message}"
msgstr ""
+msgid "failed to dismiss finding: %{message}"
+msgstr ""
+
msgid "failed to revert associated finding(id=%{finding_id}) to detected"
msgstr ""
@@ -41791,6 +42325,12 @@ msgstr ""
msgid "group"
msgstr ""
+msgid "group access token"
+msgstr ""
+
+msgid "group access tokens"
+msgstr ""
+
msgid "group members"
msgstr ""
@@ -41907,6 +42447,9 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
+msgid "is not allowed."
+msgstr ""
+
msgid "is not allowed. We do not currently support project-level iterations"
msgstr ""
@@ -42003,9 +42546,6 @@ msgstr ""
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
-msgid "log in"
-msgstr ""
-
msgid "manual"
msgstr ""
@@ -42219,6 +42759,9 @@ 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 ""
+
msgid "mrWidget|Merge failed."
msgstr ""
@@ -42327,9 +42870,6 @@ msgstr ""
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -42649,9 +43189,6 @@ msgstr ""
msgid "required"
msgstr ""
-msgid "reset it."
-msgstr ""
-
msgid "satisfied"
msgstr ""
@@ -42832,9 +43369,6 @@ msgstr ""
msgid "user namespace cannot be the parent of another namespace"
msgstr ""
-msgid "user preferences"
-msgstr ""
-
msgid "username"
msgstr ""
diff --git a/locale/gl_ES/gitlab.po b/locale/gl_ES/gitlab.po
index 2043b565c47..3c6e7a33c91 100644
--- a/locale/gl_ES/gitlab.po
+++ b/locale/gl_ES/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: gl\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:56\n"
+"PO-Revision-Date: 2022-01-06 17:20\n"
msgid " %{start} to %{end}"
msgstr " %{start} a %{end}"
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/he_IL/gitlab.po b/locale/he_IL/gitlab.po
index 220f5ce6fed..791ca7c801e 100644
--- a/locale/he_IL/gitlab.po
+++ b/locale/he_IL/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: he\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:58\n"
+"PO-Revision-Date: 2022-01-06 17:22\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -717,7 +717,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -994,6 +994,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
@@ -1211,6 +1214,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1329,6 +1338,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1400,6 +1412,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1776,6 +1791,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -2022,6 +2040,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -2034,12 +2061,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -2097,6 +2133,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -2121,6 +2187,9 @@ msgstr ""
msgid "Active Sessions"
msgstr "הפעלות פעילות"
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "פעילות"
@@ -2226,7 +2295,7 @@ msgstr "הוספת טבלה"
msgid "Add a task list"
msgstr "הוספת רשימת משימות"
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2652,6 +2721,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2928,7 +3006,7 @@ msgstr "מחיקת משתמש"
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -3213,6 +3291,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3603,6 +3684,9 @@ msgstr ""
msgid "All groups and projects"
msgstr "כל הקבוצות והמיזמי×"
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3807,6 +3891,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3834,9 +3921,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -4017,6 +4101,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -4026,6 +4113,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -4177,6 +4267,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4520,9 +4616,15 @@ msgstr[3] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4553,6 +4655,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4562,6 +4667,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4586,6 +4700,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4613,6 +4730,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4649,7 +4769,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4821,9 +4941,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4971,6 +5088,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5372,9 +5492,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5624,9 +5741,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5657,13 +5771,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr ""
-
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5675,7 +5786,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5687,9 +5801,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5877,7 +5997,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -6242,7 +6362,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -6251,6 +6374,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6290,6 +6416,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6996,7 +7125,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -7262,9 +7391,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7475,6 +7601,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7493,9 +7622,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7649,12 +7784,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7667,6 +7817,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7682,9 +7838,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7730,12 +7892,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7811,6 +7982,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7829,12 +8003,28 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7844,6 +8034,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -9033,6 +9226,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9458,6 +9660,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9549,6 +9754,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9780,12 +9988,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9816,9 +10030,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -10158,9 +10369,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -10191,6 +10399,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -10233,9 +10444,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -10245,13 +10453,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10431,15 +10642,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10449,15 +10678,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10608,15 +10846,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11307,6 +11536,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11586,6 +11818,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11619,15 +11854,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11766,6 +11995,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11790,7 +12022,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11799,6 +12031,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12617,15 +12852,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12768,6 +13003,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12903,7 +13141,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12942,6 +13180,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13885,6 +14126,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13930,9 +14174,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -14086,9 +14327,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -14173,6 +14411,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14360,9 +14601,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14555,7 +14793,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -15269,9 +15507,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15602,6 +15837,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16463,9 +16701,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16553,6 +16788,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16742,9 +16980,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16871,6 +17106,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16973,9 +17211,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -17048,6 +17295,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -17087,6 +17337,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -17120,6 +17373,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -17144,7 +17409,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -17153,7 +17418,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -17195,6 +17460,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -17222,12 +17490,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17342,6 +17616,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17396,6 +17673,9 @@ 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 ""
+
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 ""
@@ -19316,6 +19596,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19565,9 +19848,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19670,9 +19950,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19784,9 +20061,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20432,7 +20706,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20886,6 +21160,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21661,7 +21941,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22417,10 +22697,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22519,6 +22799,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -23142,6 +23425,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -23347,6 +23633,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23560,6 +23879,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23786,6 +24108,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -24207,6 +24532,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -24219,7 +24547,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24634,6 +24962,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24652,12 +24986,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24697,12 +25037,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24727,18 +25076,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24748,9 +25112,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24911,6 +25272,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25452,9 +25816,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25644,9 +26005,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25746,6 +26113,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25827,12 +26197,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -26064,6 +26428,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -26283,9 +26650,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26562,6 +26926,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26574,6 +26944,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26769,9 +27142,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -27123,6 +27493,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -27180,6 +27553,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -27264,6 +27643,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27558,6 +27940,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27684,6 +28108,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27936,19 +28363,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -28104,6 +28528,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28488,9 +28921,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28503,9 +28933,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28530,9 +28957,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28614,6 +29038,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28659,9 +29086,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28704,6 +29137,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28719,6 +29155,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28947,6 +29386,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -29134,9 +29579,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -29179,6 +29621,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29507,10 +29997,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -30206,6 +30696,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -30215,6 +30708,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30415,9 +30914,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30439,6 +30935,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30490,19 +30992,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30556,6 +31061,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30601,6 +31109,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30610,7 +31121,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30679,7 +31193,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30697,6 +31211,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30958,6 +31475,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30979,9 +31499,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -31284,6 +31801,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -31356,6 +31876,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31410,6 +31933,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31494,9 +32020,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31695,6 +32218,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31707,6 +32233,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31782,6 +32311,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31935,6 +32467,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -32286,6 +32821,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32442,6 +32983,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -33147,6 +33691,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33591,9 +34138,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33990,6 +34534,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34425,6 +34975,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34697,9 +35265,29 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34730,6 +35318,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34742,6 +35333,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34778,12 +35372,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -35075,6 +35678,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -35199,9 +35805,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -35211,9 +35814,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -35286,7 +35886,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35541,9 +36141,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35889,6 +36486,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35901,9 +36501,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35928,6 +36525,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -36042,6 +36642,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -36207,6 +36810,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36923,6 +37529,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36989,6 +37598,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -37163,6 +37805,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -37287,15 +37932,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -37320,9 +37956,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37950,9 +38583,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38844,16 +39474,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38895,6 +39525,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38920,6 +39553,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38951,6 +39587,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -39045,6 +39687,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -39126,12 +39771,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39159,6 +39816,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39228,9 +39888,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -39246,21 +39915,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -39270,6 +39951,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -39294,6 +39978,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -39417,6 +40110,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39504,6 +40200,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39540,6 +40242,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39597,6 +40308,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39633,6 +40353,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39642,9 +40365,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40484,6 +41204,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40673,6 +41399,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40964,6 +41696,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -41210,6 +41945,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -41240,7 +41978,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -41288,8 +42026,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41385,8 +42123,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41552,6 +42290,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42008,9 +42749,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -42370,6 +43108,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42469,9 +43210,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/hi_IN/gitlab.po b/locale/hi_IN/gitlab.po
index 890faef7427..31fcea58b1f 100644
--- a/locale/hi_IN/gitlab.po
+++ b/locale/hi_IN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: hi\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:57\n"
+"PO-Revision-Date: 2022-01-06 17:21\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/hr_HR/gitlab.po b/locale/hr_HR/gitlab.po
index fd845906783..186561fdfda 100644
--- a/locale/hr_HR/gitlab.po
+++ b/locale/hr_HR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: hr\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:56\n"
+"PO-Revision-Date: 2022-01-06 17:21\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -640,7 +640,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -916,6 +916,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1123,6 +1126,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1240,6 +1249,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1309,6 +1321,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1660,6 +1675,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1906,6 +1924,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1918,12 +1945,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1981,6 +2017,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -2005,6 +2071,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -2110,7 +2179,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2536,6 +2605,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2812,7 +2890,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -3097,6 +3175,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3487,6 +3568,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3691,6 +3775,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3718,9 +3805,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3901,6 +3985,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3910,6 +3997,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -4060,6 +4150,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4396,9 +4492,15 @@ msgstr[2] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4429,6 +4531,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4438,6 +4543,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4462,6 +4576,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4489,6 +4606,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4525,7 +4645,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4696,9 +4816,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4846,6 +4963,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5245,9 +5365,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5497,9 +5614,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5530,13 +5644,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr ""
-
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5548,7 +5659,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5560,9 +5674,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5749,7 +5869,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -6112,7 +6232,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -6121,6 +6244,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6160,6 +6286,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6865,7 +6994,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -7129,9 +7258,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7342,6 +7468,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7360,9 +7489,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7516,12 +7651,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7534,6 +7684,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7549,9 +7705,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7597,12 +7759,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7678,6 +7849,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7696,12 +7870,27 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7711,6 +7900,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8899,6 +9091,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9322,6 +9523,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9412,6 +9616,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9643,12 +9850,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9679,9 +9892,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -10021,9 +10231,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -10054,6 +10261,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -10096,9 +10306,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -10108,13 +10315,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10294,15 +10504,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10312,15 +10540,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10471,15 +10708,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11167,6 +11395,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11446,6 +11677,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11479,15 +11713,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11623,6 +11851,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11647,7 +11878,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11656,6 +11887,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12466,15 +12700,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12616,6 +12850,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12751,7 +12988,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12790,6 +13027,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13732,6 +13972,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13777,9 +14020,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13933,9 +14173,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -14020,6 +14257,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14206,9 +14446,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14401,7 +14638,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -15112,9 +15349,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15445,6 +15679,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16306,9 +16543,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16396,6 +16630,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16585,9 +16822,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16714,6 +16948,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16816,9 +17053,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16891,6 +17137,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16930,6 +17179,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16963,6 +17215,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16987,7 +17251,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16996,7 +17260,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -17038,6 +17302,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -17065,12 +17332,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17185,6 +17458,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17239,6 +17515,9 @@ 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 ""
+
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 ""
@@ -19153,6 +19432,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19402,9 +19684,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19507,9 +19786,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19621,9 +19897,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20269,7 +20542,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20722,6 +20995,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21490,7 +21769,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22246,10 +22525,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22348,6 +22627,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22969,6 +23251,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -23173,6 +23458,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23386,6 +23704,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23611,6 +23932,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -24031,6 +24355,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -24043,7 +24370,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24454,6 +24781,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24472,12 +24805,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24517,12 +24856,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24547,18 +24895,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24568,9 +24931,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24730,6 +25090,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25270,9 +25633,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25462,9 +25822,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25564,6 +25930,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25645,12 +26014,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25882,6 +26245,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -26101,9 +26467,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26380,6 +26743,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26392,6 +26761,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26587,9 +26959,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26941,6 +27310,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26998,6 +27370,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -27082,6 +27460,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27376,6 +27757,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27502,6 +27925,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27754,19 +28180,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27922,6 +28345,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28306,9 +28738,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28321,9 +28750,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28348,9 +28774,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28432,6 +28855,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28477,9 +28903,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28522,6 +28954,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28537,6 +28972,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28765,6 +29203,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28951,9 +29395,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28996,6 +29437,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29323,10 +29812,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -30016,6 +30505,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -30025,6 +30517,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30223,9 +30721,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30247,6 +30742,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30298,19 +30799,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30364,6 +30868,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30409,6 +30916,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30418,7 +30928,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30487,7 +31000,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30505,6 +31018,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30766,6 +31282,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30787,9 +31306,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -31081,6 +31597,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -31153,6 +31672,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31207,6 +31729,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31291,9 +31816,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31492,6 +32014,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31504,6 +32029,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31579,6 +32107,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31732,6 +32263,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -32083,6 +32617,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32239,6 +32779,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32941,6 +33484,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33385,9 +33931,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33784,6 +34327,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34219,6 +34768,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34489,9 +35056,27 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34522,6 +35107,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34534,6 +35122,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34570,12 +35161,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34864,6 +35464,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34987,9 +35590,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34999,9 +35599,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -35074,7 +35671,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35329,9 +35926,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35677,6 +36271,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35689,9 +36286,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35716,6 +36310,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35830,6 +36427,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35995,6 +36595,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36709,6 +37312,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36775,6 +37381,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36949,6 +37588,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -37072,15 +37714,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -37105,9 +37738,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37735,9 +38365,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38629,16 +39256,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38680,6 +39307,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38704,6 +39334,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38734,6 +39367,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38827,6 +39466,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38908,12 +39550,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38941,6 +39595,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39010,9 +39667,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -39028,21 +39694,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -39052,6 +39730,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -39076,6 +39757,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -39199,6 +39889,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39286,6 +39979,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39322,6 +40021,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39379,6 +40087,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39415,6 +40132,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39424,9 +40144,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40264,6 +40981,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40453,6 +41176,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40744,6 +41473,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40987,6 +41719,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -41017,7 +41752,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -41065,8 +41800,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41161,8 +41896,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41326,6 +42061,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41776,9 +42514,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -42136,6 +42871,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42235,9 +42973,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/hu_HU/gitlab.po b/locale/hu_HU/gitlab.po
index 9c3a99bbf54..bd16729ea98 100644
--- a/locale/hu_HU/gitlab.po
+++ b/locale/hu_HU/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: hu\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:57\n"
+"PO-Revision-Date: 2022-01-06 17:21\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/hy_AM/gitlab.po b/locale/hy_AM/gitlab.po
index 5176cafc52d..513a87dd770 100644
--- a/locale/hy_AM/gitlab.po
+++ b/locale/hy_AM/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: hy-AM\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:58\n"
+"PO-Revision-Date: 2022-01-06 17:22\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/id_ID/gitlab.po b/locale/id_ID/gitlab.po
index c87675567ac..c2a7fae7a62 100644
--- a/locale/id_ID/gitlab.po
+++ b/locale/id_ID/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: id\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:56\n"
+"PO-Revision-Date: 2022-01-06 17:20\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -486,7 +486,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -760,6 +760,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -947,6 +950,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1062,6 +1071,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1127,6 +1139,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1428,6 +1443,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1674,6 +1692,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1686,12 +1713,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1749,6 +1785,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1773,6 +1839,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1878,7 +1947,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2304,6 +2373,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2580,7 +2658,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2865,6 +2943,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3255,6 +3336,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3459,6 +3543,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3486,9 +3573,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3669,6 +3753,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3678,6 +3765,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3826,6 +3916,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4148,9 +4244,15 @@ msgstr[0] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4181,6 +4283,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4190,6 +4295,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4214,6 +4328,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4241,6 +4358,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4277,7 +4397,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4446,9 +4566,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4596,6 +4713,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -4991,9 +5111,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5243,9 +5360,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5276,13 +5390,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5294,7 +5405,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5306,9 +5420,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5493,7 +5613,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5852,7 +5972,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5861,6 +5984,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -5900,6 +6026,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6603,7 +6732,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6863,9 +6992,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7076,6 +7202,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7094,9 +7223,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7250,12 +7385,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7268,6 +7418,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7283,9 +7439,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7331,12 +7493,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7412,6 +7583,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7430,12 +7604,25 @@ 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 ""
+msgid "ClusterAgents|There's no activity from the past day"
+msgid_plural "ClusterAgents|There's no activity from the past %d days"
+msgstr[0] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7445,6 +7632,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8631,6 +8821,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9050,6 +9249,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9138,6 +9340,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9369,12 +9574,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9405,9 +9616,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9747,9 +9955,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9780,6 +9985,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9822,9 +10030,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9834,13 +10039,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10020,15 +10228,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10038,15 +10264,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10197,15 +10432,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -10887,6 +11113,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11166,6 +11395,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11199,15 +11431,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11337,6 +11563,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11361,7 +11590,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11370,6 +11599,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12164,15 +12396,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12312,6 +12544,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12447,7 +12682,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12486,6 +12721,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13426,6 +13664,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13471,9 +13712,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13627,9 +13865,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13714,6 +13949,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -13898,9 +14136,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14093,7 +14328,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14798,9 +15033,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15131,6 +15363,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -15992,9 +16227,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16082,6 +16314,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16271,9 +16506,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16400,6 +16632,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16502,9 +16737,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16577,6 +16821,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16616,6 +16863,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16649,6 +16899,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16673,7 +16935,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16682,7 +16944,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16724,6 +16986,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16751,12 +17016,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -16871,6 +17142,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -16925,6 +17199,9 @@ 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 ""
+
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 ""
@@ -18827,6 +19104,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19076,9 +19356,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19181,9 +19458,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19295,9 +19569,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -19943,7 +20214,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20394,6 +20665,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21148,7 +21425,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -21904,10 +22181,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22006,6 +22283,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22623,6 +22903,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22825,6 +23108,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23038,6 +23354,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23261,6 +23580,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23679,6 +24001,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23691,7 +24016,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24094,6 +24419,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24112,12 +24443,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24157,12 +24494,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24187,18 +24533,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24208,9 +24569,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24368,6 +24726,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -24906,9 +25267,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25098,9 +25456,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25200,6 +25564,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25281,12 +25648,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25518,6 +25879,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25737,9 +26101,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26016,6 +26377,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26028,6 +26395,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26223,9 +26593,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26577,6 +26944,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26634,6 +27004,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26718,6 +27094,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27012,6 +27391,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27138,6 +27559,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27390,19 +27814,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27558,6 +27979,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -27942,9 +28372,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27957,9 +28384,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -27984,9 +28408,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28068,6 +28489,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28113,9 +28537,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28158,6 +28588,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28173,6 +28606,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28401,6 +28837,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28585,9 +29027,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28630,6 +29069,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -28955,10 +29442,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29636,6 +30123,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29645,6 +30135,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -29839,9 +30335,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -29863,6 +30356,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -29914,19 +30413,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -29980,6 +30482,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30025,6 +30530,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30034,7 +30542,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30103,7 +30614,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30121,6 +30632,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30382,6 +30896,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30403,9 +30920,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30675,6 +31189,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30747,6 +31264,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -30801,6 +31321,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -30885,9 +31408,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31086,6 +31606,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31098,6 +31621,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31173,6 +31699,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31326,6 +31855,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31677,6 +32209,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -31833,6 +32371,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32529,6 +33070,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -32973,9 +33517,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33372,6 +33913,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -33807,6 +34354,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34073,9 +34638,23 @@ msgid "Terraform|%{number} Terraform report was generated in your pipelines"
msgid_plural "Terraform|%{number} Terraform reports were generated in your pipelines"
msgstr[0] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34106,6 +34685,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34118,6 +34700,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34154,12 +34739,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34442,6 +35036,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34563,9 +35160,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34575,9 +35169,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34650,7 +35241,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -34905,9 +35496,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35253,6 +35841,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35265,9 +35856,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35292,6 +35880,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35406,6 +35997,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35571,6 +36165,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36281,6 +36878,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36347,6 +36947,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36521,6 +37154,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36642,15 +37278,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36675,9 +37302,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37305,9 +37929,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38199,16 +38820,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38250,6 +38871,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38272,6 +38896,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38300,6 +38927,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38391,6 +39024,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38472,12 +39108,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38505,6 +39153,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38574,9 +39225,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38592,21 +39252,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38616,6 +39288,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38640,6 +39315,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38763,6 +39447,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -38850,6 +39537,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -38886,6 +39579,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -38943,6 +39645,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -38979,6 +39690,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -38988,9 +39702,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -39824,6 +40535,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40013,6 +40730,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40304,6 +41027,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40541,6 +41267,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40571,7 +41300,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40619,8 +41348,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgid "ciReport|Browser performance test metrics: No changes"
@@ -40713,8 +41442,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgid "ciReport|Load performance test metrics results are being parsed"
@@ -40874,6 +41603,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41312,9 +42044,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41668,6 +42397,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -41767,9 +42499,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/ig_NG/gitlab.po b/locale/ig_NG/gitlab.po
index 31ed74baa6e..0b15beddbea 100644
--- a/locale/ig_NG/gitlab.po
+++ b/locale/ig_NG/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ig\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:59\n"
+"PO-Revision-Date: 2022-01-06 17:24\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -486,7 +486,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -760,6 +760,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -947,6 +950,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1062,6 +1071,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1127,6 +1139,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1428,6 +1443,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1674,6 +1692,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1686,12 +1713,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1749,6 +1785,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1773,6 +1839,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1878,7 +1947,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2304,6 +2373,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2580,7 +2658,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2865,6 +2943,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3255,6 +3336,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3459,6 +3543,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3486,9 +3573,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3669,6 +3753,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3678,6 +3765,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3826,6 +3916,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4148,9 +4244,15 @@ msgstr[0] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4181,6 +4283,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4190,6 +4295,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4214,6 +4328,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4241,6 +4358,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4277,7 +4397,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4446,9 +4566,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4596,6 +4713,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -4991,9 +5111,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5243,9 +5360,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5276,13 +5390,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5294,7 +5405,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5306,9 +5420,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5493,7 +5613,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5852,7 +5972,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5861,6 +5984,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -5900,6 +6026,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6603,7 +6732,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6863,9 +6992,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7076,6 +7202,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7094,9 +7223,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7250,12 +7385,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7268,6 +7418,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7283,9 +7439,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7331,12 +7493,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7412,6 +7583,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7430,12 +7604,25 @@ 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 ""
+msgid "ClusterAgents|There's no activity from the past day"
+msgid_plural "ClusterAgents|There's no activity from the past %d days"
+msgstr[0] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7445,6 +7632,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8631,6 +8821,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9050,6 +9249,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9138,6 +9340,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9369,12 +9574,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9405,9 +9616,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9747,9 +9955,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9780,6 +9985,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9822,9 +10030,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9834,13 +10039,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10020,15 +10228,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10038,15 +10264,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10197,15 +10432,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -10887,6 +11113,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11166,6 +11395,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11199,15 +11431,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11337,6 +11563,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11361,7 +11590,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11370,6 +11599,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12164,15 +12396,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12312,6 +12544,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12447,7 +12682,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12486,6 +12721,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13426,6 +13664,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13471,9 +13712,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13627,9 +13865,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13714,6 +13949,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -13898,9 +14136,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14093,7 +14328,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14798,9 +15033,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15131,6 +15363,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -15992,9 +16227,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16082,6 +16314,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16271,9 +16506,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16400,6 +16632,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16502,9 +16737,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16577,6 +16821,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16616,6 +16863,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16649,6 +16899,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16673,7 +16935,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16682,7 +16944,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16724,6 +16986,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16751,12 +17016,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -16871,6 +17142,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -16925,6 +17199,9 @@ 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 ""
+
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 ""
@@ -18827,6 +19104,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19076,9 +19356,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19181,9 +19458,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19295,9 +19569,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -19943,7 +20214,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20394,6 +20665,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21148,7 +21425,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -21904,10 +22181,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22006,6 +22283,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22623,6 +22903,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22825,6 +23108,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23038,6 +23354,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23261,6 +23580,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23679,6 +24001,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23691,7 +24016,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24094,6 +24419,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24112,12 +24443,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24157,12 +24494,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24187,18 +24533,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24208,9 +24569,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24368,6 +24726,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -24906,9 +25267,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25098,9 +25456,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25200,6 +25564,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25281,12 +25648,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25518,6 +25879,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25737,9 +26101,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26016,6 +26377,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26028,6 +26395,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26223,9 +26593,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26577,6 +26944,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26634,6 +27004,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26718,6 +27094,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27012,6 +27391,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27138,6 +27559,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27390,19 +27814,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27558,6 +27979,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -27942,9 +28372,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27957,9 +28384,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -27984,9 +28408,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28068,6 +28489,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28113,9 +28537,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28158,6 +28588,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28173,6 +28606,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28401,6 +28837,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28585,9 +29027,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28630,6 +29069,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -28955,10 +29442,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29636,6 +30123,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29645,6 +30135,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -29839,9 +30335,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -29863,6 +30356,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -29914,19 +30413,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -29980,6 +30482,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30025,6 +30530,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30034,7 +30542,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30103,7 +30614,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30121,6 +30632,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30382,6 +30896,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30403,9 +30920,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30675,6 +31189,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30747,6 +31264,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -30801,6 +31321,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -30885,9 +31408,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31086,6 +31606,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31098,6 +31621,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31173,6 +31699,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31326,6 +31855,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31677,6 +32209,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -31833,6 +32371,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32529,6 +33070,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -32973,9 +33517,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33372,6 +33913,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -33807,6 +34354,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34073,9 +34638,23 @@ msgid "Terraform|%{number} Terraform report was generated in your pipelines"
msgid_plural "Terraform|%{number} Terraform reports were generated in your pipelines"
msgstr[0] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34106,6 +34685,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34118,6 +34700,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34154,12 +34739,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34442,6 +35036,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34563,9 +35160,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34575,9 +35169,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34650,7 +35241,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -34905,9 +35496,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35253,6 +35841,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35265,9 +35856,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35292,6 +35880,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35406,6 +35997,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35571,6 +36165,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36281,6 +36878,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36347,6 +36947,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36521,6 +37154,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36642,15 +37278,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36675,9 +37302,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37305,9 +37929,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38199,16 +38820,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38250,6 +38871,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38272,6 +38896,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38300,6 +38927,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38391,6 +39024,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38472,12 +39108,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38505,6 +39153,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38574,9 +39225,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38592,21 +39252,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38616,6 +39288,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38640,6 +39315,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38763,6 +39447,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -38850,6 +39537,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -38886,6 +39579,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -38943,6 +39645,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -38979,6 +39690,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -38988,9 +39702,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -39824,6 +40535,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40013,6 +40730,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40304,6 +41027,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40541,6 +41267,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40571,7 +41300,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40619,8 +41348,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgid "ciReport|Browser performance test metrics: No changes"
@@ -40713,8 +41442,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgid "ciReport|Load performance test metrics results are being parsed"
@@ -40874,6 +41603,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41312,9 +42044,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41668,6 +42397,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -41767,9 +42499,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/is_IS/gitlab.po b/locale/is_IS/gitlab.po
index db7d42a5ded..0d340987b24 100644
--- a/locale/is_IS/gitlab.po
+++ b/locale/is_IS/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: is\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:56\n"
+"PO-Revision-Date: 2022-01-06 17:20\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/it/gitlab.po b/locale/it/gitlab.po
index 7fed1e03739..d02eafd53c6 100644
--- a/locale/it/gitlab.po
+++ b/locale/it/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: it\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:58\n"
+"PO-Revision-Date: 2022-01-06 17:22\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr "Pagina profilo di %{user_name}"
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ", o "
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "Attività"
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr "Crea nuovo..."
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,8 +12835,8 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
-msgstr "Cambia programmazione della pipeline %{id}"
+msgid "Edit Pipeline Schedule"
+msgstr ""
msgid "Edit Release"
msgstr ""
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr "Dalla richiesta di merge fino effettua il merge fino al rilascio in prod
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr "Password non valida"
msgid "Profiles|Invalid username"
msgstr "Username non valido"
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr "Progetti"
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr "clicca per caricare"
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/ja/gitlab.po b/locale/ja/gitlab.po
index 04e0ff56dfc..8738f0e82b4 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: 2021-12-06 18:58\n"
+"PO-Revision-Date: 2022-01-06 17:22\n"
msgid " %{start} to %{end}"
msgstr " %{start} ã‹ã‚‰ %{end} ã¾ã§"
@@ -29,13 +29,13 @@ msgid " Please sign in."
msgstr " サインインã—ã¦ãã ã•ã„。"
msgid " Target Path"
-msgstr ""
+msgstr " 対象パス"
msgid " Try to %{action} this file again."
msgstr " ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ã‚‚ã†ä¸€åº¦ %{action} ã—ã¦ã¿ã¦ãã ã•ã„。"
msgid " Type"
-msgstr ""
+msgstr " タイプ"
msgid " You need to do this before %{grace_period_deadline}."
msgstr " %{grace_period_deadline} ã®å‰ã«ã“れを行ã†å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
@@ -62,7 +62,7 @@ msgid " or references (e.g. path/to/project!merge_request_id)"
msgstr " ã¾ãŸã¯ãƒªãƒ•ã‚¡ãƒ¬ãƒ³ã‚¹å½¢å¼ï¼ˆä¾‹: path/to/project!merge_request_id)"
msgid " reacted with :%{name}:"
-msgstr ""
+msgstr " :%{name}: ã§åå¿œã—ã¾ã—ãŸ"
msgid "\"%{path}\" did not exist on \"%{ref}\""
msgstr "「%{path}ã€ã¯ã€Œ%{ref}ã€ã«å­˜åœ¨ã—ã¾ã›ã‚“ã§ã—ãŸ"
@@ -71,18 +71,18 @@ msgid "\"%{repository_name}\" size (%{repository_size}) is larger than the limit
msgstr "\"%{repository_name}\" ã®ã‚µã‚¤ã‚º (%{repository_size}) ãŒåˆ¶é™ã® %{limit} を超ãˆã¦ã„ã¾ã™ã€‚"
msgid "#%{issueIid} (closed)"
-msgstr ""
+msgstr "#%{issueIid} (クローズ)"
msgid "#general, #development"
-msgstr ""
+msgstr "#general, #development"
msgid "%d Alert"
msgid_plural "%d Alerts"
-msgstr[0] ""
+msgstr[0] "%d 件ã®ã‚¢ãƒ©ãƒ¼ãƒˆ"
msgid "%d Alert:"
msgid_plural "%d Alerts:"
-msgstr[0] ""
+msgstr[0] "%d 件ã®ã‚¢ãƒ©ãƒ¼ãƒˆ:"
msgid "%d Approval"
msgid_plural "%d Approvals"
@@ -142,7 +142,7 @@ msgstr[0] "ã“ã®ã‚³ãƒŸãƒƒãƒˆã¸ã®%d 件ã®ã‚³ãƒ¡ãƒ³ãƒˆ"
msgid "%d commenter"
msgid_plural "%d commenters"
-msgstr[0] ""
+msgstr[0] "%d 人ã«ã‚ˆã‚‹ã‚³ãƒ¡ãƒ³ãƒˆ"
msgid "%d commit"
msgid_plural "%d commits"
@@ -150,7 +150,7 @@ msgstr[0] "%d個ã®ã‚³ãƒŸãƒƒãƒˆ"
msgid "%d commit author"
msgid_plural "%d commit authors"
-msgstr[0] ""
+msgstr[0] "%d人ã®ã‚³ãƒŸãƒƒãƒˆä½œæˆè€…"
msgid "%d commit behind"
msgid_plural "%d commits behind"
@@ -174,7 +174,7 @@ msgstr[0] "%d æ—¥"
msgid "%d epic"
msgid_plural "%d epics"
-msgstr[0] ""
+msgstr[0] "%d 件ã®ã‚¨ãƒ”ック"
msgid "%d error"
msgid_plural "%d errors"
@@ -198,7 +198,7 @@ msgstr[0] "%d 件ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ã‚¸ãƒ§ãƒ–ãŒå¤±æ•—ã—ã¾ã—ãŸ"
msgid "%d file"
msgid_plural "%d files"
-msgstr[0] ""
+msgstr[0] "%d 個ã®ãƒ•ã‚¡ã‚¤ãƒ«"
msgid "%d fixed test result"
msgid_plural "%d fixed test results"
@@ -206,7 +206,7 @@ msgstr[0] "%d 件ã®ãƒ†ã‚¹ãƒˆã§ä¿®æ­£ã•ã‚Œã¾ã—ãŸ"
msgid "%d fork"
msgid_plural "%d forks"
-msgstr[0] ""
+msgstr[0] "%d 件ã®ãƒ•ã‚©ãƒ¼ã‚¯"
msgid "%d group"
msgid_plural "%d groups"
@@ -250,7 +250,7 @@ msgstr[0] "アクセスã§ããªã„ %d 個ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆ"
msgid "%d merge requests"
msgid_plural "%d merge requests"
-msgstr[0] ""
+msgstr[0] "%d 個ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆ"
msgid "%d metric"
msgid_plural "%d metrics"
@@ -306,7 +306,7 @@ msgstr[0] "%d 件ã®ã‚·ãƒ£ãƒ¼ãƒ‰ã‚’é¸æŠžæ¸ˆã¿"
msgid "%d star"
msgid_plural "%d stars"
-msgstr[0] ""
+msgstr[0] "%d 件ã®ã‚¹ã‚¿ãƒ¼"
msgid "%d tag"
msgid_plural "%d tags"
@@ -318,7 +318,7 @@ msgstr[0] "ç”»åƒåã”ã¨ã«%d 件ã®ã‚¿ã‚°"
msgid "%d token has expired"
msgid_plural "%d tokens have expired"
-msgstr[0] ""
+msgstr[0] "%d 件ã®ãƒˆãƒ¼ã‚¯ãƒ³ã®æœ‰åŠ¹æœŸé™ãŒåˆ‡ã‚Œã¾ã—ãŸ"
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
@@ -338,7 +338,7 @@ msgstr[0] "%d 件ã®è„†å¼±æ€§ãŒç„¡è¦–ã•ã‚Œã¾ã—ãŸ"
msgid "%d vulnerability updated"
msgid_plural "%d vulnerabilities updated"
-msgstr[0] ""
+msgstr[0] "%d 件ã®è„†å¼±æ€§ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸ"
msgid "%d warning found:"
msgid_plural "%d warnings found:"
@@ -364,10 +364,10 @@ msgid "%{anchorOpen}Learn more%{anchorClose} about how you can customize / disab
msgstr "インスタンスã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ç™»éŒ²ã‚’カスタマイズ/無効化ã™ã‚‹æ–¹æ³•ã®%{anchorOpen}詳細を表示ã™ã‚‹%{anchorClose}。"
msgid "%{author_link} cloned %{original_issue} to %{new_issue}."
-msgstr ""
+msgstr "%{author_link} ㌠%{original_issue} ã‚’ %{new_issue} ã«è¤‡è£½ã—ã¾ã—ãŸã€‚"
msgid "%{author_link} cloned %{original_issue}. You don't have access to the new project."
-msgstr ""
+msgstr "%{author_link} 㯠%{original_issue}を複製ã—ã¾ã—ãŸã€‚æ–°ã—ã„プロジェクトã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。"
msgid "%{author_link} wrote:"
msgstr "%{author_link} ãŒæ›¸ãã¾ã—ãŸ:"
@@ -380,34 +380,34 @@ msgstr "%{board_target} ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "%{bold_start}%{count}%{bold_end} issue"
msgid_plural "%{bold_start}%{count}%{bold_end} issues"
-msgstr[0] ""
+msgstr[0] "%{bold_start}%{count}%{bold_end} 件ã®ã‚¤ã‚·ãƒ¥ãƒ¼"
msgid "%{bold_start}%{count}%{bold_end} member"
msgid_plural "%{bold_start}%{count}%{bold_end} members"
-msgstr[0] ""
+msgstr[0] "%{bold_start}%{count}%{bold_end} 人ã®ãƒ¡ãƒ³ãƒãƒ¼"
msgid "%{bold_start}%{count}%{bold_end} opened merge request"
msgid_plural "%{bold_start}%{count}%{bold_end} opened merge requests"
-msgstr[0] ""
+msgstr[0] "%{bold_start}%{count}%{bold_end} 件ã®ã‚ªãƒ¼ãƒ—ンã—ã¦ã„るマージリクエスト"
msgid "%{code_open}Masked:%{code_close} Hidden in job logs. Must match masking requirements."
-msgstr ""
+msgstr "%{code_open}マスク:%{code_close} ジョブログã§éžè¡¨ç¤ºã«ã—ã¾ã™ã€‚マスキングã®è¦ä»¶ã‚’満ãŸã™å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "%{code_open}Protected:%{code_close} Only exposed to protected branches or tags."
-msgstr ""
+msgstr "%{code_open}ä¿è­·:%{code_close} ä¿è­·ãƒ–ランãƒã‚„ä¿è­·ã‚¿ã‚°ã«ã®ã¿å…¬é–‹ã•ã‚Œã¾ã™ã€‚"
msgid "%{commit_author_link} authored %{commit_authored_timeago}"
-msgstr ""
+msgstr "%{commit_author_link} ㌠%{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} ㌠%{commit_authored_timeago} ã«ä½œæˆã—〠%{commit_committer_avatar} %{commit_committer_link} ㌠%{commit_committer_timeago} ã«ã‚³ãƒŸãƒƒãƒˆã—ã¾ã—ãŸ"
msgid "%{completedCount} completed weight"
msgstr "%{completedCount} ウェイトãŒå®Œäº†ã—ã¾ã—ãŸ"
msgid "%{completedCount} of %{count} task completed"
msgid_plural "%{completedCount} of %{count} tasks completed"
-msgstr[0] ""
+msgstr[0] "%{count} 件中 %{completedCount} 件ã®ã‚¿ã‚¹ã‚¯ãŒå®Œäº†ã—ã¾ã—ãŸ"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr "%{completedWeight}/%{totalWeight} ウェイトãŒå®Œäº†ã—ã¾ã—ãŸ"
@@ -430,17 +430,17 @@ msgstr "%{name} ㌠%{count} 件ã®æ‰¿èªã‚’了承ã—ã¾ã—ãŸ"
msgid "%{count} contact"
msgid_plural "%{count} contacts"
-msgstr[0] ""
+msgstr[0] "%{count}件ã®é€£çµ¡å…ˆ"
msgid "%{count} files touched"
msgstr "%{count} ファイルãŒå¤‰æ›´ã•ã‚Œã¾ã—ãŸ"
msgid "%{count} item"
msgid_plural "%{count} items"
-msgstr[0] ""
+msgstr[0] "%{count} 件ã®ã‚¢ã‚¤ãƒ†ãƒ "
msgid "%{count} items per page"
-msgstr ""
+msgstr "1ページã‚ãŸã‚Š%{count} 件"
msgid "%{count} more"
msgstr "他 %{count} 件"
@@ -466,7 +466,7 @@ msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr "%{count} 件ã®é–¢é€£ã—㟠%{pluralized_subject}: %{links}"
msgid "%{count} selected"
-msgstr ""
+msgstr "%{count} 件é¸æŠžã—ã¾ã—ãŸ"
msgid "%{count} total weight"
msgstr "åˆè¨ˆã‚¦ã‚§ã‚¤ãƒˆ %{count}"
@@ -486,20 +486,20 @@ msgstr "%{deployLinkStart}テンプレートを使用ã—ã¦ECS%{deployLinkEnd}ã
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
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; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
-msgstr "%{doc_link_start}高度ãªæ¤œç´¢%{doc_link_end} ã¯ã€ç„¡åŠ¹ã«ãªã£ã¦ã„ã¾ã™ã€‚ %{ref_elem} ãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ–ランãƒã§ã¯ãªã„ãŸã‚ã§ã™ã€‚%{default_branch_link_start} 代ã‚ã‚Šã« %{default_branch} ã§æ¤œç´¢ã—ã¾ã™%{default_branch_link_end}。"
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
+msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
msgstr "%{doc_link_start}高度ãªæ¤œç´¢%{doc_link_end} ãŒæœ‰åŠ¹ã§ã™ã€‚"
msgid "%{docs_link_start}Learn about visibility levels.%{docs_link_end}"
-msgstr ""
+msgstr "%{docs_link_start} å¯è¦–性レベルã«ã¤ã„ã¦å­¦ã³ã¾ã—ょã†ã€‚%{docs_link_end}"
msgid "%{docs_link_start}What is Large File Storage?%{docs_link_end}"
-msgstr ""
+msgstr "%{docs_link_start} Large File Storage ã¨ã¯ä½•ã§ã™ã‹? %{docs_link_end}"
msgid "%{docs_link_start}What is two-factor authentication?%{docs_link_end}"
-msgstr ""
+msgstr "%{docs_link_start}二è¦ç´ èªè¨¼ã¨ã¯ä½•ã§ã™ã‹ï¼Ÿ%{docs_link_end}"
msgid "%{due_date} (Past due)"
msgstr "%{due_date} (期é™åˆ‡ã‚Œ)"
@@ -535,16 +535,16 @@ msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
msgstr "%{firstMilestoneName} +他 %{numberOfOtherMilestones} 件"
msgid "%{gitlab_experience_text}. Don't worry, this information isn't shared outside of your self-managed GitLab instance."
-msgstr ""
+msgstr "%{gitlab_experience_text}。ã“ã®æƒ…å ±ã¯ã€ã‚»ãƒ«ãƒ•ãƒžãƒãƒ¼ã‚¸ãƒ‰ã®GitLabインスタンス以外ã¨ã¯å…±æœ‰ã•ã‚Œã¾ã›ã‚“。"
msgid "%{gitlab_experience_text}. We won't share this information with anyone."
-msgstr ""
+msgstr "%{gitlab_experience_text}。ã“ã®æƒ…å ±ã¯èª°ã¨ã‚‚共有ã—ã¾ã›ã‚“。"
msgid "%{global_id} is not a valid ID for %{expected_types}."
-msgstr ""
+msgstr "%{global_id} 㯠%{expected_types} ã«ã¨ã£ã¦æœ‰åŠ¹ãªIDã§ã¯ã‚ã‚Šã¾ã›ã‚“。"
msgid "%{group_name} activity"
-msgstr ""
+msgstr "%{group_name} アクティビティー"
msgid "%{group_name} group members"
msgstr "%{group_name} グループã®ãƒ¡ãƒ³ãƒãƒ¼"
@@ -553,7 +553,7 @@ msgid "%{group_name} uses group managed accounts. You need to create a new GitLa
msgstr "%{group_name} ã¯ã‚°ãƒ«ãƒ¼ãƒ—管ç†ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’使用ã—ã¾ã™ã€‚ %{group_name} ã«ã‚ˆã£ã¦ç®¡ç†ã•ã‚Œã‚‹æ–°ã—ã„GitLabアカウントを作æˆã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "%{group_name}&%{epic_iid} &middot; created %{epic_created} by %{author}"
-msgstr ""
+msgstr "%{group_name}&%{epic_iid} &middot; %{author} ã«ã‚ˆã‚Š %{epic_created} 作æˆã•ã‚Œã¾ã—ãŸ"
msgid "%{hook_type} was deleted"
msgstr "%{hook_type} ã¯å‰Šé™¤ã•ã‚Œã¾ã—ãŸ"
@@ -577,7 +577,7 @@ msgid "%{issuesSize} with a limit of %{maxIssueCount}"
msgstr "最大 %{maxIssueCount} 件中〠%{issuesSize} 件"
msgid "%{italic_start}What's new%{italic_end} is inactive and cannot be viewed."
-msgstr ""
+msgstr "%{italic_start}新機能%{italic_end} ã¯éžã‚¢ã‚¯ãƒ†ã‚£ãƒ–ã§ã‚ã‚Šã€è¡¨ç¤ºã§ãã¾ã›ã‚“。"
msgid "%{itemsCount} issues with a limit of %{maxIssueCount}"
msgstr ""
@@ -622,7 +622,7 @@ msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
msgstr "%{labelStart}é‡è¦åº¦:%{labelEnd} %{severity}"
msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
-msgstr ""
+msgstr "%{labelStart} ツール:%{labelEnd} %{reportType}"
msgid "%{labelStart}Unmodified response:%{labelEnd} %{headers}"
msgstr "%{labelStart}修正ã•ã‚Œã¦ã„ãªã„レスãƒãƒ³ã‚¹:%{labelEnd} %{headers}"
@@ -631,13 +631,13 @@ msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} ã¯åˆ©ç”¨ä¸å¯"
msgid "%{learn_more_link}."
-msgstr ""
+msgstr "%{learn_more_link}。"
msgid "%{lessThan} 1 hour"
-msgstr ""
+msgstr "%{lessThan} 1時間"
msgid "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} is a free, automated, and open certificate authority (CA) that issues digital certificates to enable HTTPS (SSL/TLS) for sites."
-msgstr ""
+msgstr "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} ã¯ã€ç„¡æ–™ã®è‡ªå‹•åŒ–ã•ã‚ŒãŸã‚ªãƒ¼ãƒ—ンãªèªè¨¼å±€(CA)ã§ã€Webサイトã§HTTPS(SSL/TLS)を有効ã«ã™ã‚‹ãŸã‚ã®ãƒ‡ã‚¸ã‚¿ãƒ«è¨¼æ˜Žæ›¸ã‚’発行ã§ãã¾ã™ã€‚"
msgid "%{level_name} is not allowed in a %{group_level_name} group."
msgstr "%{level_name} 㯠%{group_level_name} グループã«å«ã‚られã¾ã›ã‚“。"
@@ -646,19 +646,19 @@ msgid "%{level_name} is not allowed since the fork source project has lower visi
msgstr "%{level_name} ã¯è¨±å¯ã•ã‚Œã¾ã›ã‚“。フォークã—ãŸã‚½ãƒ¼ã‚¹ãƒ—ロジェクトã¯ã‚ˆã‚Šå¯è¦–性ãŒä½Žã„ã‹ã‚‰ã§ã™ã€‚"
msgid "%{link_start}Learn more%{link_end} about roles."
-msgstr ""
+msgstr "ロールã«ã¤ã„ã¦%{link_start}ã‚‚ã£ã¨è©³ã—ã%{link_end}。"
msgid "%{link_start}Remove the %{draft_snippet} prefix%{link_end} from the title to allow this merge request to be merged when it's ready."
-msgstr ""
+msgstr "タイトルã‹ã‚‰ %{link_start} %{draft_snippet} ã®ãƒ—レフィックス %{link_end} を削除ã—ã¦ã€æº–å‚™ãŒã§ã次第マージリクエストをマージã§ãるよã†ã«ã™ã‚‹ã€‚"
msgid "%{link_start}Start the title with %{draft_snippet}%{link_end} to prevent a merge request draft from merging before it's ready."
-msgstr ""
+msgstr "タイトルã®å…ˆé ­ã« %{link_start} %{draft_snippet} %{link_end} を書ã„ã¦ã€ä½œæ¥­ä¸­ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆãŒæº–å‚™ãŒã§ãã‚‹ã¾ã§ãƒžãƒ¼ã‚¸ã•ã‚Œãªã„よã†ã«ã—ã¾ã™ã€‚"
msgid "%{link_start}What information does GitLab Inc. collect?%{link_end}"
-msgstr ""
+msgstr "%{link_start}GitLab Inc.ã¯ã©ã®ã‚ˆã†ãªæƒ…報をåŽé›†ã—ã¦ã„ã¾ã™ã‹ï¼Ÿ%{link_end}"
msgid "%{listToShow}, and %{awardsListLength} more"
-msgstr ""
+msgstr "%{listToShow}ã€ãã—ã¦ã•ã‚‰ã« %{awardsListLength} 個。"
msgid "%{location} is missing required keys: %{keys}"
msgstr "%{location} ã«å¿…è¦ãªã‚­ãƒ¼ãŒã‚ã‚Šã¾ã›ã‚“: %{keys}"
@@ -682,19 +682,19 @@ msgid "%{milliseconds}ms"
msgstr "%{milliseconds} ミリ秒"
msgid "%{model_name} not found"
-msgstr ""
+msgstr "%{model_name} ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "%{mrText}, this issue will be closed automatically."
msgstr "%{mrText} ã€ã“ã®ã‚¤ã‚·ãƒ¥ãƒ¼ã¯è‡ªå‹•çš„ã«ã‚¯ãƒ­ãƒ¼ã‚ºã—ã¾ã™ã€‚"
msgid "%{name_with_link} namespace has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
-msgstr ""
+msgstr "åå‰ç©ºé–“ã® %{name_with_link} 㯠%{percent}ã¾ãŸã¯ãれ以下ã®å…±æœ‰ãƒ©ãƒ³ãƒŠãƒ¼ãƒ‘イプラインã®åˆ©ç”¨æ™‚é–“ãŒæ®‹ã£ã¦ã„ã¾ã™ã€‚ã“ã‚ŒãŒãªããªã‚‹ã¨ã€ãã®ãƒ—ロジェクトã®æ–°ã—ã„ジョブやパイプラインã¯å®Ÿè¡Œã•ã‚Œãªããªã‚Šã¾ã™ã€‚"
msgid "%{name_with_link} namespace has run out of Shared Runner Pipeline minutes. No new jobs or pipelines in its projects will run."
-msgstr ""
+msgstr "åå‰ç©ºé–“ã® %{name_with_link} ã«ã¯ 共有ランナーパイプラインã®åˆ©ç”¨æ™‚é–“ãŒãªããªã‚Šã¾ã—ãŸã€‚ãã®ãƒ—ロジェクトã®æ–°ã—ã„ジョブやパイプラインã¯å®Ÿè¡Œã•ã‚Œãªããªã‚Šã¾ã™ã€‚"
msgid "%{name} (Busy)"
-msgstr ""
+msgstr "%{name} (ビジー)"
msgid "%{name} contained %{resultsString}"
msgstr "%{name} ã«ã¯ %{resultsString} ãŒå«ã¾ã‚Œã¦ã„ã¾ã™"
@@ -706,7 +706,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} ã§ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ«æ¸ˆã¿ã§ã™"
@@ -715,13 +715,13 @@ msgid "%{name}'s avatar"
msgstr "%{name}ã®ã‚¢ãƒã‚¿ãƒ¼"
msgid "%{name}(%{url}) namespace has %{percent} or less Shared Runner Pipeline minutes remaining. After it runs out, no new jobs or pipelines in its projects will run."
-msgstr ""
+msgstr "åå‰ç©ºé–“ã® %{name}(%{url}) 㯠%{percent}ã¾ãŸã¯ãれ以下ã®å…±æœ‰ Runner パイプラインã®åˆ©ç”¨æ™‚é–“ãŒæ®‹ã£ã¦ã„ã¾ã™ã€‚ã“ã‚ŒãŒãªããªã‚‹ã¨ã€ãã®ãƒ—ロジェクトã®æ–°ã—ã„ジョブやパイプラインã¯å®Ÿè¡Œã•ã‚Œãªããªã‚Šã¾ã™ã€‚"
msgid "%{name}(%{url}) namespace has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
-msgstr ""
+msgstr "åå‰ç©ºé–“ã® %{name}(%{url}) ã«ã¯ 共有ランナーパイプラインã®åˆ©ç”¨æ™‚é–“ãŒãªããªã‚Šã¾ã—ãŸã€‚ãã®ãŸã‚ã€ãã®ãƒ—ロジェクトã®æ–°ã—ã„ジョブやパイプラインã¯å®Ÿè¡Œã•ã‚Œãªããªã‚Šã¾ã™ã€‚"
msgid "%{name}, confirm your email address now!"
-msgstr ""
+msgstr "%{name}ã•ã‚“ã€ä»Šã™ãメールアドレスを確èªã—ã¦ãã ã•ã„ï¼"
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
@@ -731,13 +731,13 @@ msgid "%{number_commits_behind} commits behind %{default_branch}, %{number_commi
msgstr "%{default_branch} ã‹ã‚‰ %{number_commits_behind} コミットé…ã‚Œã¦ã„ã¦ã€ %{number_commits_ahead} コミット進んã§ã„ã¾ã™ã€‚"
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 "%{openedEpics} オープン, %{closedEpics} 完了"
@@ -760,11 +760,14 @@ msgstr "%{placeholder} ã¯æœ‰åŠ¹ãªã‚«ãƒ©ãƒ¼ã‚¹ã‚­ãƒ¼ãƒ ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "%{placeholder} is not a valid theme"
msgstr "%{placeholder} 㯠有効ãªãƒ†ãƒ¼ãƒžã§ã¯ã‚ã‚Šã¾ã›ã‚“。"
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
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} ã¯ã€GitLab プロファイルã«READMEを追加ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã™ã‚‹ãƒ—ロジェクトã§ã™ã€‚開始ã™ã‚‹ã«ã¯ã€ãƒ‘ブリックプロジェクトを作æˆã—ã€README ãŒå«ã¾ã‚ŒãŸçŠ¶æ…‹ã§ãƒªãƒã‚¸ãƒˆãƒªã‚’åˆæœŸåŒ–ã—ã¾ã™ã€‚ %{help_link_start}詳細ã¯ã“ã¡ã‚‰%{help_link_end}"
msgid "%{ref} cannot be added: %{error}"
msgstr "%{ref} を追加ã™ã‚‹ãã¾ã›ã‚“ã§ã—ãŸ: %{error}"
@@ -777,28 +780,28 @@ msgid "%{remaining_approvals} left"
msgstr "残り%{remaining_approvals}"
msgid "%{reportType} %{status}"
-msgstr ""
+msgstr "%{reportType} %{status}"
msgid "%{reportType} detected %{totalStart}%{total}%{totalEnd} potential %{vulnMessage}"
-msgstr ""
+msgstr "%{reportType} ã®æ½œåœ¨çš„㪠%{vulnMessage} ã‚’ %{totalStart}%{total}%{totalEnd} 件検出ã—ã¾ã—ãŸ"
msgid "%{reportType} detected %{totalStart}no%{totalEnd} vulnerabilities."
-msgstr ""
+msgstr "%{reportType} 㮠脆弱性を%{totalStart} 0 %{totalEnd} 件検出ã—ã¾ã—ãŸ."
msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}."
msgstr "%{retryButtonStart}ã‚‚ã†ä¸€åº¦è©¦ã™%{retryButtonEnd} ã¾ãŸã¯ %{newFileButtonStart}æ–°ã—ã„ファイルを添付ã™ã‚‹%{newFileButtonEnd}。"
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation_link}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
-msgstr ""
+msgstr "残りã®å‚加者ã‹ã‚‰ %{rotation} ã‚’å†è¨ˆç®—ã—ã¾ã—ãŸã€‚ %{rotation_link}ã®æ–°ã—ã„設定を確èªã—ã¦ãã ã•ã„。 オンコールã®ã‚«ãƒãƒ¬ãƒƒã‚¸ã‚’確èªã™ã‚‹ãŸã‚ã«ã€ç¾åœ¨ã®ã‚ªãƒ³ã‚³ãƒ¼ãƒ«ã®å¯¾å¿œè€…ã«é€£çµ¡ã™ã‚‹ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚"
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 "%{scope} results for term '%{term}'"
msgstr ""
msgid "%{search} %{description} %{scope}"
-msgstr ""
+msgstr "%{search} %{description} %{scope}"
msgid "%{seconds}s"
msgstr "%{seconds} 秒"
@@ -812,7 +815,7 @@ msgid_plural "%{securityScanner} results are not available because a pipeline ha
msgstr[0] "%{securityScanner} ã®çµæžœã¯åˆ©ç”¨ã§ãã¾ã›ã‚“。パイプラインãŒæœ‰åŠ¹ã«ãªã£ã¦ã‹ã‚‰ã¾ã å®Ÿè¡Œã•ã‚Œã¦ã„ãªã„ãŸã‚ã§ã™ã€‚ %{linkStart}パイプラインを実行%{linkEnd}"
msgid "%{service_ping_link_start}What information is shared with GitLab Inc.?%{service_ping_link_end}"
-msgstr ""
+msgstr "%{service_ping_link_start}ã©ã®ã‚ˆã†ãªæƒ…å ±ãŒGitLab Inc.ã¨å…±æœ‰ã•ã‚Œã¾ã™ã‹ï¼Ÿ%{service_ping_link_end}"
msgid "%{size} %{unit}"
msgstr "%{size} %{unit}"
@@ -845,10 +848,10 @@ msgid "%{start} to %{end}"
msgstr "%{start} ã‹ã‚‰ %{end} ã¾ã§"
msgid "%{strongOpen}Warning:%{strongClose} SAML group links can cause GitLab to automatically remove members from groups."
-msgstr ""
+msgstr "%{strongOpen}警告:%{strongClose} SAML グループ リンクã«ã‚ˆã‚Šã€GitLab ã¯ã‚°ãƒ«ãƒ¼ãƒ—ã‹ã‚‰ãƒ¡ãƒ³ãƒãƒ¼ã‚’自動的ã«å‰Šé™¤ã—ã¾ã™ã€‚"
msgid "%{strongStart}Tip:%{strongEnd} You can also checkout merge requests locally by %{linkStart}following these guidelines%{linkEnd}"
-msgstr ""
+msgstr "%{strongStart}ヒント:%{strongEnd} %{linkStart}ã“れらã®ã‚¬ã‚¤ãƒ‰ãƒ©ã‚¤ãƒ³%{linkEnd}ã«å¾“ã£ã¦ãƒ­ãƒ¼ã‚«ãƒ«ã§ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’ãƒã‚§ãƒƒã‚¯ã‚¢ã‚¦ãƒˆã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™"
msgid "%{strong_start}%{branch_count}%{strong_end} Branch"
msgid_plural "%{strong_start}%{branch_count}%{strong_end} Branches"
@@ -860,15 +863,15 @@ msgstr[0] "%{strong_start}%{commit_count}%{strong_end} コミット"
msgid "%{strong_start}%{count} approval rule%{strong_end} requires eligible members to approve before merging."
msgid_plural "%{strong_start}%{count} approval rules%{strong_end} require eligible members to approve before merging."
-msgstr[0] ""
+msgstr[0] "%{strong_start}%{count} 承èªãƒ«ãƒ¼ãƒ«%{strong_end} ã¯ã€ãƒžãƒ¼ã‚¸å‰ã«é©åˆ‡ãªãƒ¡ãƒ³ãƒãƒ¼ãŒæ‰¿èªã™ã‚‹ã“ã¨ã‚’è¦æ±‚ã—ã¾ã™ã€‚"
msgid "%{strong_start}%{count} eligible member%{strong_end} must approve to merge."
msgid_plural "%{strong_start}%{count} eligible members%{strong_end} must approve to merge."
-msgstr[0] ""
+msgstr[0] "マージã™ã‚‹ãŸã‚ã«ã¯ %{strong_start}%{count} 人ã®é©åˆ‡ãªãƒ¡ãƒ³ãƒãƒ¼%{strong_end} ã®æ‰¿èªãŒå¿…è¦ã§ã™ã€‚"
msgid "%{strong_start}%{count} member%{strong_end} must approve to merge. Anyone with role Developer or higher can approve."
msgid_plural "%{strong_start}%{count} members%{strong_end} must approve to merge. Anyone with role Developer or higher can approve."
-msgstr[0] ""
+msgstr[0] "マージã™ã‚‹ãŸã‚ã« %{strong_start}%{count} 人ã®ãƒ¡ãƒ³ãƒãƒ¼%{strong_end} ã®æ‰¿èªãŒå¿…è¦ã§ã™ã€‚開発者以上ã®ãƒ­ãƒ¼ãƒ«ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯èª°ã§ã‚‚承èªã§ãã¾ã™ã€‚"
msgid "%{strong_start}%{human_size}%{strong_end} Files"
msgstr "%{strong_start}%{human_size}%{strong_end} ファイル"
@@ -918,7 +921,7 @@ msgid "%{title} changes"
msgstr "%{title} ã®å¤‰æ›´"
msgid "%{totalCpu} (%{freeSpacePercentage}%{percentSymbol} free)"
-msgstr ""
+msgstr "%{totalCpu} (%{freeSpacePercentage}%{percentSymbol} 空ã)"
msgid "%{totalMemory} (%{freeSpacePercentage}%{percentSymbol} free)"
msgstr "%{totalMemory} (%{freeSpacePercentage}%{percentSymbol} 空ã)"
@@ -945,13 +948,19 @@ msgid "%{userName}'s avatar"
msgstr "%{userName}ã®ã‚¢ãƒã‚¿ãƒ¼"
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
+msgstr "%{user_name} (%{user_username}) 㯠%{project} プロジェクト㮠%{schedule}ã®%{rotation} ã‹ã‚‰å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚ "
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
msgstr ""
msgid "%{user_name} profile page"
msgstr "%{user_name} プロフィールページ"
msgid "%{username} changed the draft status of merge request %{mr_link}"
-msgstr ""
+msgstr "%{username} ãŒãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆ %{mr_link} ã®ãƒ‰ãƒ©ãƒ•ãƒˆã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’変更ã—ã¾ã—ãŸ"
msgid "%{username} has asked for a GitLab account on your instance %{host}:"
msgstr "%{username} ãŒã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ %{host} ã® GitLab アカウントをリクエストã—ã¾ã—ãŸã€‚"
@@ -960,16 +969,16 @@ msgid "%{username}'s avatar"
msgstr "%{username}ã®ã‚¢ãƒã‚¿ãƒ¼"
msgid "%{user} created a merge request: %{mr_link}"
-msgstr ""
+msgstr "%{user} ãŒãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’作æˆã—ã¾ã—ãŸ: %{mr_link}"
msgid "%{user} created an epic: %{epic_link}"
-msgstr ""
+msgstr "%{user} ãŒã‚¨ãƒ”ックを作æˆã—ã¾ã—ãŸ: %{epic_link}"
msgid "%{user} created an issue: %{issue_link}"
-msgstr ""
+msgstr "%{user} ãŒã‚¤ã‚·ãƒ¥ãƒ¼ã‚’作æˆã—ã¾ã—ãŸ: %{issue_link}"
msgid "%{value} is not included in the list"
-msgstr ""
+msgstr "%{value} ã¯ãƒªã‚¹ãƒˆã«å«ã¾ã‚Œã¦ã„ã¾ã›ã‚“。"
msgid "%{value} s"
msgstr "%{value} 秒"
@@ -981,13 +990,13 @@ msgid "%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notif
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 ""
+msgstr "%{webhooks_link_start}%{webhook_type}%{link_end} ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—ã¾ãŸã¯ãƒ—ロジェクトã®ã‚¤ãƒ™ãƒ³ãƒˆã«å¿œç­”ã—ã¦Webアプリケーションã¸é€šçŸ¥ã‚’é€ä¿¡ã§ãるよã†ã«ã—ã¾ã™ã€‚ Webhookよりも %{integrations_link_start}インテグレーション%{link_end} を使用ã™ã‚‹ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚"
msgid "%{widget} options"
-msgstr ""
+msgstr "%{widget} オプション"
msgid "%{wildcards_link_start}Wildcards%{wildcards_link_end} such as %{code_tag_start}v*%{code_tag_end} or %{code_tag_start}*-release%{code_tag_end} are supported."
-msgstr ""
+msgstr "%{code_tag_start}v*%{code_tag_end} ã‚„ %{code_tag_start}*-release%{code_tag_end} ã®ã‚ˆã†ãª%{wildcards_link_start}ワイルドカード%{wildcards_link_end} をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã™ã€‚"
msgid "'%{data}' at %{location} does not match format: %{format}"
msgstr "%{location} ã«ã‚ã‚‹ '%{data}' ㌠%{format} フォーマットã¨ä¸€è‡´ã—ã¾ã›ã‚“。"
@@ -1017,7 +1026,7 @@ msgid "'%{name}' Value Stream deleted"
msgstr "'%{name}' ãƒãƒªãƒ¥ãƒ¼ã‚¹ãƒˆãƒªãƒ¼ãƒ ãŒå‰Šé™¤ã•ã‚Œã¾ã—ãŸ"
msgid "'%{name}' Value Stream saved"
-msgstr ""
+msgstr "'%{name}' ãƒãƒªãƒ¥ãƒ¼ã‚¹ãƒˆãƒªãƒ¼ãƒ ã‚’ä¿å­˜ã—ã¾ã—ãŸ"
msgid "'%{source}' is not a import source"
msgstr "'%{source}' ã¯ã‚¤ãƒ³ãƒãƒ¼ãƒˆã‚½ãƒ¼ã‚¹ã§ã¯ã‚ã‚Šã¾ã›ã‚“。"
@@ -1036,16 +1045,16 @@ msgid "(%{value}) has already been taken"
msgstr "(%{value})ã¯æ—¢ã«ä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™"
msgid "(+%{count}&nbsp;rules)"
-msgstr ""
+msgstr "(+%{count}&nbsp;ルール)"
msgid "(Group Managed Account)"
-msgstr ""
+msgstr "(グループ管ç†ã‚¢ã‚«ã‚¦ãƒ³ãƒˆ)"
msgid "(No changes)"
msgstr "(変更ãªã—)"
msgid "(UTC %{offset}) %{timezone}"
-msgstr ""
+msgstr "(UTC %{offset}) %{timezone}"
msgid "(check progress)"
msgstr "(進行状æ³ã‚’確èªã™ã‚‹)"
@@ -1054,14 +1063,17 @@ msgid "(deleted)"
msgstr "(削除済ã¿)"
msgid "(expired)"
-msgstr ""
+msgstr "(有効期é™åˆ‡ã‚Œ)"
msgid "(leave blank if you don't want to change it)"
-msgstr ""
+msgstr "(変更ã—ãŸããªã„å ´åˆã€ç©ºç™½ã®ã¾ã¾ã«ã—ã¦ãã ã•ã„)"
msgid "(max size 15 MB)"
msgstr "(最大サイズ 15MB)"
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr "(除去ã—ã¾ã—ãŸ)"
@@ -1073,16 +1085,16 @@ msgid_plural "(squashes %d commits)"
msgstr[0] ""
msgid "(this user)"
-msgstr ""
+msgstr "(ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼)"
msgid "(we need your current password to confirm your changes)"
-msgstr ""
+msgstr "(変更を確èªã™ã‚‹ãŸã‚ã«ç¾åœ¨ã®ãƒ‘スワードãŒå¿…è¦ã§ã™)"
msgid "* All times are in UTC unless specified"
-msgstr ""
+msgstr "* 指定ãŒãªã„é™ã‚Šã€ã™ã¹ã¦ã®æ™‚é–“ã¯UTCã§ã™ã€‚"
msgid "*Required"
-msgstr ""
+msgstr "*å¿…é ˆ"
msgid "+ %{amount} more"
msgstr "+ %{amount} 件以上"
@@ -1104,7 +1116,7 @@ msgid "+%{approvers} more approvers"
msgstr "%{approvers} 人以上ã®æ‰¿èªè€…"
msgid "+%{extra} more"
-msgstr ""
+msgstr "+%{extra} 件以上"
msgid "+%{more_assignees_count}"
msgstr "+%{more_assignees_count}"
@@ -1122,23 +1134,26 @@ msgid "+%{tags} more"
msgstr "+%{tags} 以上"
msgid ", and "
-msgstr ""
+msgstr ", 㨠"
msgid ", or "
msgstr "ã€ã¾ãŸã¯"
-msgid "- Available to run jobs."
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
msgstr ""
+msgid "- Available to run jobs."
+msgstr "- ジョブを実行ã§ãã¾ã™ã€‚"
+
msgid "- Event"
msgid_plural "- Events"
msgstr[0] "- イベント"
msgid "- Not available to run jobs."
-msgstr ""
+msgstr "- ジョブを実行ã§ãã¾ã›ã‚“。"
msgid "- Select -"
-msgstr ""
+msgstr "- é¸æŠž -"
msgid "- User"
msgid_plural "- Users"
@@ -1154,7 +1169,7 @@ msgid "."
msgstr "."
msgid "/"
-msgstr ""
+msgstr "/"
msgid "0 bytes"
msgstr "0 ãƒã‚¤ãƒˆ"
@@ -1184,11 +1199,11 @@ msgstr[0] "%d æ—¥"
msgid "1 day remaining"
msgid_plural "%d days remaining"
-msgstr[0] ""
+msgstr[0] "残り %d 日"
msgid "1 day selected"
msgid_plural "%d days selected"
-msgstr[0] ""
+msgstr[0] "%d æ—¥é¸æŠžæ¸ˆã¿"
msgid "1 deploy key"
msgid_plural "%d deploy keys"
@@ -1196,7 +1211,7 @@ msgstr[0] "%d 個ã®ãƒ‡ãƒ—ロイキー"
msgid "1 follower"
msgid_plural "%{count} followers"
-msgstr[0] ""
+msgstr[0] "%{count} フォロワー"
msgid "1 group"
msgid_plural "%d groups"
@@ -1208,7 +1223,7 @@ msgstr[0] "%d 時間"
msgid "1 issue selected"
msgid_plural "%d issues selected"
-msgstr[0] ""
+msgstr[0] "%d 件ã®ã‚¤ã‚·ãƒ¥ãƒ¼ã‚’é¸æŠžæ¸ˆã¿"
msgid "1 merge request selected"
msgid_plural "%d merge requests selected"
@@ -1224,7 +1239,7 @@ msgstr[0] "%d 分"
msgid "1 month remaining"
msgid_plural "%d months remaining"
-msgstr[0] ""
+msgstr[0] "残り %d ヶ月"
msgid "1 open issue"
msgid_plural "%{issues} open issues"
@@ -1248,11 +1263,11 @@ msgstr[0] "%{num}ユーザー"
msgid "1 week remaining"
msgid_plural "%d weeks remaining"
-msgstr[0] ""
+msgstr[0] "残り %d 週間"
msgid "1 year remaining"
msgid_plural "%d years remaining"
-msgstr[0] ""
+msgstr[0] "残り %d 年"
msgid "1-9 contributions"
msgstr "貢献 1-9 件"
@@ -1264,7 +1279,7 @@ msgid "1000+"
msgstr "1000 以上"
msgid "192.168.0.0/24"
-msgstr ""
+msgstr "192.168.0.0/24"
msgid "1st contribution!"
msgstr "最åˆã®è²¢çŒ®!"
@@ -1318,7 +1333,7 @@ msgid ":%{startLine} to %{endLine}"
msgstr ":%{startLine} 行目ã‹ã‚‰ %{endLine} 行目"
msgid "A %{incident_docs_start}modified issue%{incident_docs_end} to guide the resolution of incidents."
-msgstr ""
+msgstr "インシデントã®è§£æ±ºã‚’ガイドã™ã‚‹ãŸã‚ã® %{incident_docs_start}修正ã•ã‚ŒãŸã‚¤ã‚·ãƒ¥ãƒ¼%{incident_docs_end}"
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr "ä»»æ„ã®.NET Coreプロジェクト用ã«ã‚«ã‚¹ã‚¿ãƒžã‚¤ã‚ºå¯èƒ½ãªã€.NET Coreコンソールアプリケーションテンプレート"
@@ -1327,31 +1342,31 @@ msgid "A CI/CD pipeline must run and be successful before merge."
msgstr "マージå‰ã«CI/CDパイプラインãŒå®Ÿè¡Œãƒ»æˆåŠŸã—ã¦ã„ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。"
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "GitBookã®ã‚µã‚¤ãƒˆã§GitLabã®ä»£ã‚ã‚Šã«Netlifyã‚’CI/CDã§ä½¿ç”¨ã—ã¦ã„ãŸã¨ã—ã¦ã‚‚ã€GitLabã«ã¯ã»ã‹ã«ã‚‚素晴らã—ã„機能ãŒãŸãã•ã‚“ã‚ã‚Šã¾ã™ã€‚"
msgid "A Gitpod configured Webapplication in Spring and Java"
msgstr "Springã¨Javaã§æ§‹æˆã•ã‚ŒãŸã‚¦ã‚§ãƒ–アプリケーションã®Gitpod"
msgid "A Hexo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Hexoã®ã‚µã‚¤ãƒˆã§GitLabã®ä»£ã‚ã‚Šã«Netlifyã‚’CI/CDã§ä½¿ç”¨ã—ã¦ã„ãŸã¨ã—ã¦ã‚‚ã€GitLabã«ã¯ã»ã‹ã«ã‚‚素晴らã—ã„機能ãŒãŸãã•ã‚“ã‚ã‚Šã¾ã™ã€‚"
msgid "A Hugo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Hugoã®ã‚µã‚¤ãƒˆã§GitLabã®ä»£ã‚ã‚Šã«Netlifyã‚’CI/CDã§ä½¿ç”¨ã—ã¦ã„ãŸã¨ã—ã¦ã‚‚ã€GitLabã«ã¯ã»ã‹ã«ã‚‚素晴らã—ã„機能ãŒãŸãã•ã‚“ã‚ã‚Šã¾ã™ã€‚"
msgid "A Jekyll site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Jekyllã®ã‚µã‚¤ãƒˆã§GitLabã®ä»£ã‚ã‚Šã«Netlifyã‚’CI/CDã§ä½¿ç”¨ã—ã¦ã„ãŸã¨ã—ã¦ã‚‚ã€GitLabã«ã¯ã»ã‹ã«ã‚‚素晴らã—ã„機能ãŒãŸãã•ã‚“ã‚ã‚Šã¾ã™ã€‚"
msgid "A Let's Encrypt SSL certificate can not be obtained until your domain is verified."
msgstr "Let's Encrypt ã®SSL証明書ã¯ã€ã‚ãªãŸã®ãƒ‰ãƒ¡ã‚¤ãƒ³ãŒç¢ºèªã•ã‚Œã‚‹ã¾ã§å–å¾—ã§ãã¾ã›ã‚“。"
msgid "A Metrics Dashboard menu item appears in the Monitoring section of the Admin Area."
-msgstr ""
+msgstr "管ç†è€…エリア㮠モニタリングセクションã«ãƒ¡ãƒˆãƒªã‚¯ã‚¹ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰ã®ãƒ¡ãƒ‹ãƒ¥ãƒ¼é …ç›®ãŒè¡¨ç¤ºã•ã‚Œã¾ã™ã€‚"
msgid "A basic page and serverless function that uses AWS Lambda, AWS API Gateway, and GitLab Pages"
msgstr "AWS Lambdaã€AWS API Gatewayã€ãŠã‚ˆã³GitLab Pagesを使用ã™ã‚‹åŸºæœ¬çš„ãªãƒšãƒ¼ã‚¸ã¨ã‚µãƒ¼ãƒãƒ¼ãƒ¬ã‚¹é–¢æ•°"
msgid "A basic template for developing Linux programs using Kotlin Native"
-msgstr ""
+msgstr "Kotlin Native を使用ã—㦠Linux プログラムを開発ã™ã‚‹ãŸã‚ã®åŸºæœ¬çš„ãªãƒ†ãƒ³ãƒ—レート"
msgid "A complete DevOps platform"
msgstr "完全㪠DevOps ã®ãƒ—ラットフォーム"
@@ -1363,7 +1378,7 @@ msgid "A deleted user"
msgstr "削除ã•ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼"
msgid "A different reason"
-msgstr ""
+msgstr "別ã®ç†ç”±"
msgid "A file has been changed."
msgstr "ファイルãŒå¤‰æ›´ã•ã‚Œã¾ã—ãŸã€‚"
@@ -1381,13 +1396,13 @@ msgid "A group represents your organization in GitLab. Groups allow you to manag
msgstr "グループã§ã‚ãªãŸã®çµ„織を表ç¾ã§ãã¾ã™ã€‚グループå˜ä½ã§ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’管ç†ã—ã€è¤‡æ•°ã®ãƒ—ロジェクトã«ã‚ãŸã£ã¦ã‚³ãƒ©ãƒœãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã‚’è¡Œã†ã“ã¨ãŒã§ãã¾ã™ã€‚"
msgid "A job artifact is an archive of files and directories saved by a job when it finishes."
-msgstr ""
+msgstr "ジョブアーティファクトã¯ã€ã‚¸ãƒ§ãƒ–ãŒçµ‚了ã—ãŸã¨ãã«ä¿å­˜ã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã¨ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã§ã™ã€‚"
msgid "A limit of %{ci_project_subscriptions_limit} subscriptions to or from a project applies."
-msgstr ""
+msgstr "プロジェクトã¸ã®ã‚µãƒ–スクリプションã€ã¾ãŸã¯ãƒ—ロジェクトã‹ã‚‰ã®ã‚µãƒ–スクリプション㯠%{ci_project_subscriptions_limit} 件ã«åˆ¶é™ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "A management, operational, or technical control (that is, safeguard or countermeasure) employed by an organization that provides equivalent or comparable protection for an information system."
-msgstr ""
+msgstr "通常ã®æƒ…報システムã«ç›¸å½“ã¾ãŸã¯åŒç­‰ã®ä¿è­·ã‚’æä¾›ã™ã‚‹çµ„ç¹”ãŒä½¿ç”¨ã™ã‚‹ç®¡ç†ã€é‹ç”¨ã€ã¾ãŸã¯æŠ€è¡“çš„ãªåˆ¶å¾¡(ã™ãªã‚ã¡ã€ä¿è­·ã¾ãŸã¯å¯¾ç­–)。"
msgid "A member of the abuse team will review your report as soon as possible."
msgstr "ãŸã ã¡ã«ä¸æ­£åˆ©ç”¨å¯¾å¿œãƒãƒ¼ãƒ ãƒ¡ãƒ³ãƒãƒ¼ã§ã„ãŸã ã„ãŸãƒ¬ãƒãƒ¼ãƒˆã‚’æ‹èª­ã—å‚考ã«ã•ã›ã¦ã„ãŸã ãã¾ã™ã€‚"
@@ -1396,7 +1411,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 "æ–°ã—ã„Auto DevOps パイプラインãŒä½œæˆã•ã‚Œã¾ã—ãŸã€‚詳細ã«ã¤ã„ã¦ã¯ã€ パイプラインページ ã‚’å‚ç…§ã—ã¦ãã ã•ã„。"
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 "%{name} ã®æ–°ã—ã„リリース %{tag} ãŒå…¬é–‹ã•ã‚Œã¾ã—ãŸã€‚ 詳細ã«ã¤ã„ã¦ã¯ã€ %{release_link_start} リリースページ %{release_link_end} ã‚’ã”覧ãã ã•ã„。"
@@ -1411,31 +1426,34 @@ msgid "A non-confidential epic cannot be assigned to a confidential parent epic"
msgstr "公開エピックã®è¦ªã‚¨ãƒ”ックã«éžå…¬é–‹ã‚¨ãƒ”ックã«å‰²ã‚Šå½“ã¦ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
msgid "A plain HTML site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "プレーンHTMLã®ã‚µã‚¤ãƒˆã§GitLabã®ä»£ã‚ã‚Šã«Netlifyã‚’CI/CDã§ä½¿ç”¨ã—ã¦ã„ãŸã¨ã—ã¦ã‚‚ã€GitLabã«ã¯ã»ã‹ã«ã‚‚素晴らã—ã„機能ãŒãŸãã•ã‚“ã‚ã‚Šã¾ã™ã€‚"
msgid "A platform value can be web, mob or app."
msgstr "プラットフォームã®å€¤ã¯ã€ã‚¦ã‚§ãƒ–ã€ãƒ¢ãƒã‚¤ãƒ«ã€ã¾ãŸã¯ã‚¢ãƒ—リã§ã™ã€‚"
msgid "A project boilerplate for Salesforce App development with Salesforce Developer tools"
-msgstr ""
+msgstr "Salesforce Developerツールを使用ã—ãŸSalesforceアプリケーション開発用ã®ãƒ—ロジェクトテンプレート"
msgid "A project boilerplate for Tencent Serverless Framework that uses Next.js SSR"
-msgstr ""
+msgstr "Next.js SSRを使用ã—ãŸTencent Serverless Frameworkã®ãƒ—ロジェクトテンプレート"
msgid "A project containing issues for each audit inquiry in the HIPAA Audit Protocol published by the U.S. Department of Health & Human Services"
msgstr "アメリカåˆè¡†å›½ä¿å¥ç¦ç¥‰çœãŒç™ºè¡Œã—ãŸHIPAA監査プロトコルã®å„監査照会ã®ã‚¤ã‚·ãƒ¥ãƒ¼ã‚’å«ã‚€ãƒ—ロジェクト"
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
+msgstr "プロジェクトã®ãƒªãƒã‚¸ãƒˆãƒªåã¯ã€ãã®URL(ブラウザーを介ã—ã¦ãƒ—ロジェクトã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã™ã‚‹ã‚‚ã®ï¼‰ã¨GitLabãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã¦ã„るファイルディスク上ã®å ´æ‰€ã‚’定義ã—ã¾ã™ã€‚ %{link_start}詳細ã¯ã“ã¡ã‚‰ã€‚%{link_end}"
+
+msgid "A quarterly reconciliation is due on %{date}"
msgstr ""
msgid "A ready-to-go template for use with Android apps"
-msgstr ""
+msgstr "Android アプリã§ã™ãã«ä½¿ãˆã‚‹ãƒ†ãƒ³ãƒ—レート。"
msgid "A ready-to-go template for use with iOS Swift apps"
-msgstr ""
+msgstr "iOS Swift アプリã§ã™ãã«ä½¿ãˆã‚‹ãƒ†ãƒ³ãƒ—レート。"
msgid "A rebase is already in progress."
-msgstr ""
+msgstr "rebase を実行ã—ã¦ã„ã¾ã™ã€‚"
msgid "A sign-in to your account has been made from the following IP address: %{ip}"
msgstr "次ã®IPアドレスã‹ã‚‰ã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¸ã®ã‚µã‚¤ãƒ³ã‚¤ãƒ³ãŒè¡Œã‚ã‚Œã¾ã—ãŸ: %{ip}"
@@ -1450,13 +1468,13 @@ msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt c
msgstr "アクションãŒå¿…è¦ï¼šGitLab Pagesã®ãƒ‰ãƒ¡ã‚¤ãƒ³ '%{domain}'ã¸ã®Let's Encrypt証明書ã®å–得中ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "API"
-msgstr ""
+msgstr "API"
msgid "API Fuzzing"
msgstr "APIファジング"
msgid "API Fuzzing Configuration"
-msgstr ""
+msgstr "API Fuzzing ã®è¨­å®š"
msgid "API Help"
msgstr "API ヘルプ"
@@ -1468,118 +1486,118 @@ msgid "API key"
msgstr "APIキー"
msgid "API?"
-msgstr ""
+msgstr "API?"
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 ""
+msgstr "API Fuzzing 設定"
msgid "APIFuzzing|Base URL of API testing target. For example, http://www.example.com."
-msgstr ""
+msgstr "APIテストターゲットã®ãƒ™ãƒ¼ã‚¹URL。例ãˆã°ã€http://www.example.com"
msgid "APIFuzzing|Choose a method"
-msgstr ""
+msgstr "メソッドをé¸æŠž"
msgid "APIFuzzing|Choose a profile"
-msgstr ""
+msgstr "プロファイルをé¸æŠž"
msgid "APIFuzzing|Configure HTTP basic authentication values. Other authentication methods are supported. %{linkStart}Learn more%{linkEnd}."
-msgstr ""
+msgstr "HTTPã®åŸºæœ¬èªè¨¼ã‚’設定ã—ã¾ã™ã€‚ä»–ã®èªè¨¼æ–¹æ³•ãŒã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã™ã€‚ 詳ã—ãã¯%{linkStart}ã“ã¡ã‚‰%{linkEnd} ã‚’ã”覧ãã ã•ã„。"
msgid "APIFuzzing|Customize 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 fuzzing ã®è¨­å®šã‚ªãƒ—ションをカスタマイズã—ã€ã‚³ãƒ¼ãƒ‰ã‚¹ãƒ‹ãƒšãƒƒãƒˆã‚’.gitlab-ci.yml ファイルã«ã‚³ãƒ”ーã—ã¦ã€å¤‰æ›´ã‚’é©ç”¨ã—ã¾ã™ã€‚ã“ã®ãƒ„ールã¯è‡ªå‹•çš„ã« .gitlab-ci.yml を変更ã¾ãŸã¯æ›´æ–°ã—ãªã„ã“ã¨ã«æ³¨æ„ã—ã¦ãã ã•ã„。より高度ãªè¨­å®šã‚ªãƒ—ションã®è©³ç´°ã«ã¤ã„ã¦ã¯ã€ %{docsLinkStart}GitLab API Fuzzing ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆ%{docsLinkEnd} ã‚’å‚ç…§ã—ã¦ãã ã•ã„。"
msgid "APIFuzzing|Enable authentication"
-msgstr ""
+msgstr "èªè¨¼ã‚’有効化"
msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
-msgstr ""
+msgstr "パスワードをå«ã‚€ CI変数ã®åå‰ã‚’入力ã—ã¾ã™ã€‚例: $VARIABLE_WITH_PASSWORD。"
msgid "APIFuzzing|Enter the name of the CI variable containing the username. For example, $VARIABLE_WITH_USERNAME."
-msgstr ""
+msgstr "ユーザーåã‚’å«ã‚€CI変数ã®åå‰ã‚’入力ã—ã¾ã™ã€‚例: $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 "テスト対象ã®API ã®ãƒ•ã‚¡ã‚¤ãƒ«ãƒ‘スã¾ãŸã¯API ã®URL。例ãˆã°ã€folder/example_fuzz.har 。HAR ファイルã«ã¯ã€èªè¨¼ãƒˆãƒ¼ã‚¯ãƒ³ã€API キーã€ã‚»ãƒƒã‚·ãƒ§ãƒ³ã‚¯ãƒƒã‚­ãƒ¼ãªã©ã®æ©Ÿå¯†æƒ…å ±ãŒå«ã¾ã‚Œã¦ã„ã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚ HAR ファイルã®å†…容をリãƒã‚¸ãƒˆãƒªã«è¿½åŠ ã™ã‚‹å‰ã«ãƒ¬ãƒ“ューã™ã‚‹ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚"
msgid "APIFuzzing|File path or URL to OpenAPI specification. For example, folder/openapi.json or http://www.example.com/openapi.json."
-msgstr ""
+msgstr "OpenAPI仕様ã®ãƒ•ã‚¡ã‚¤ãƒ«ãƒ‘スã¾ãŸã¯URL。例ãˆã°ã€folder/openapi.json ã¾ãŸã¯ http://www.example.com/openapi.json。"
msgid "APIFuzzing|File path or URL to requests to be tested. For example, folder/example.postman_collection.json."
-msgstr ""
+msgstr "テスト対象ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã¸ã®ãƒ•ã‚¡ã‚¤ãƒ«ãƒ‘スã¾ãŸã¯URL。例ãˆã°ã€folder/example.postman_collection.json 。"
msgid "APIFuzzing|Generate code snippet"
-msgstr ""
+msgstr "コードスニペットã®ç”Ÿæˆ"
msgid "APIFuzzing|Make sure your credentials are secured"
-msgstr ""
+msgstr "èªè¨¼æƒ…å ±ãŒå®‰å…¨ã§ã‚ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„"
msgid "APIFuzzing|Password for basic authentication"
-msgstr ""
+msgstr "ベーシックèªè¨¼ã®ãƒ‘スワード"
msgid "APIFuzzing|Predefined profiles"
-msgstr ""
+msgstr "事å‰å®šç¾©ã•ã‚ŒãŸãƒ—ロファイル"
msgid "APIFuzzing|Scan mode"
msgstr "スキャンモード"
msgid "APIFuzzing|Scan profile"
-msgstr ""
+msgstr "スキャンプロファイル"
msgid "APIFuzzing|Show code snippet for the profile"
-msgstr ""
+msgstr "プロファイルã®ã‚³ãƒ¼ãƒ‰ã‚¹ãƒ‹ãƒšãƒƒãƒˆã‚’表示"
msgid "APIFuzzing|Target URL"
-msgstr ""
+msgstr "ターゲットURL"
msgid "APIFuzzing|There are three ways to perform scans."
-msgstr ""
+msgstr "スキャンを実行ã™ã‚‹æ–¹æ³•ã¯3ã¤ã‚ã‚Šã¾ã™ã€‚"
msgid "APIFuzzing|Tip: Insert the following variables anywhere below stages and include"
-msgstr ""
+msgstr "ヒント: stages 㨠include ã®ä¸‹ã®ä»»æ„ã®å ´æ‰€ã«æ¬¡ã®å¤‰æ•°ã‚’挿入ã—ã¾ã™"
msgid "APIFuzzing|Tip: Insert this part below all include"
-msgstr ""
+msgstr "ヒント: ã“ã®éƒ¨åˆ†ã‚’ã™ã¹ã¦ã® include ã®ä¸‹ã«æŒ¿å…¥ã—ã¾ã™"
msgid "APIFuzzing|Tip: Insert this part below all stages"
-msgstr ""
+msgstr "ヒント: ã“ã®éƒ¨åˆ†ã‚’ã™ã¹ã¦ã® stage ã®ä¸‹ã«æŒ¿å…¥ã—ã¾ã™"
msgid "APIFuzzing|To prevent a security leak, authentication info must be added as a %{ciVariablesLinkStart}CI variable%{ciVariablesLinkEnd}. A user with maintainer access rights can manage CI variables in the %{ciSettingsLinkStart}Settings%{ciSettingsLinkEnd} area. We detected that you are not a maintainer. Commit your changes and assign them to a maintainer to update the credentials before merging."
-msgstr ""
+msgstr "情報æ¼æ´©ã‚’防ããŸã‚ã«ã€èªè¨¼æƒ…報を%{ciVariablesLinkStart}CI変数%{ciVariablesLinkEnd}ã«è¿½åŠ ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ 。メンテナーã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©ã‚’æŒã¤ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ã€ %{ciSettingsLinkStart}設定%{ciSettingsLinkEnd} ã§CI変数を管ç†ã§ãã¾ã™ã€‚ã‚ãªãŸãŒãƒ¡ãƒ³ãƒ†ãƒŠãƒ¼ã§ã¯ãªã„ã“ã¨ãŒæ¤œå‡ºã•ã‚Œã¾ã—ãŸã€‚変更をコミットã—ã€ãれらをメンテナーã«å‰²ã‚Šå½“ã¦ã¦ã€ãƒžãƒ¼ã‚¸ã™ã‚‹å‰ã«èªè¨¼æƒ…報を更新ã—ã¦ãã ã•ã„。"
msgid "APIFuzzing|To prevent a security leak, authentication info must be added as a %{ciVariablesLinkStart}CI variable%{ciVariablesLinkEnd}. As a user with maintainer access rights, you can manage CI variables in the %{ciSettingsLinkStart}Settings%{ciSettingsLinkEnd} area."
-msgstr ""
+msgstr "情報æ¼æ´©ã‚’防ããŸã‚ã«ã€èªè¨¼æƒ…報を%{ciVariablesLinkStart}CI変数%{ciVariablesLinkEnd}ã«è¿½åŠ ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ 。メンテナーã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©ã‚’æŒã¤ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¨ã—ã¦ã€ %{ciSettingsLinkStart}設定%{ciSettingsLinkEnd} ã§CI変数を管ç†ã§ãã¾ã™ã€‚"
msgid "APIFuzzing|Username for basic authentication"
-msgstr ""
+msgstr "ベーシックèªè¨¼ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼å"
msgid "APIFuzzing|You may need a maintainer's help to secure your credentials."
-msgstr ""
+msgstr "èªè¨¼æƒ…報をä¿è­·ã™ã‚‹ã«ã¯ãƒ¡ãƒ³ãƒ†ãƒŠãƒ¼ã®åŠ©ã‘ãŒå¿…è¦ã‹ã‚‚ã—ã‚Œã¾ã›ã‚“。"
msgid "APIFuzzing|folder/example.postman_collection.json"
-msgstr ""
+msgstr "folder/example.postman_collection.json"
msgid "APIFuzzing|folder/example_fuzz.har"
-msgstr ""
+msgstr "folder/example_fuzz.har"
msgid "APIFuzzing|folder/openapi.json"
-msgstr ""
+msgstr "folder/openapi.json"
msgid "AWS Access Key"
msgstr "AWS アクセスキー"
msgid "AWS Access Key. Only required if not using role instance credentials"
-msgstr ""
+msgstr "AWSアクセスキー。ロールインスタンスã®è³‡æ ¼æƒ…報を使用ã—ãªã„å ´åˆã«ã®ã¿å¿…è¦"
msgid "AWS Secret Access Key"
msgstr "AWS 秘密アクセスキー"
msgid "AWS Secret Access Key. Only required if not using role instance credentials"
-msgstr ""
+msgstr "AWSã®ã‚·ãƒ¼ã‚¯ãƒ¬ãƒƒãƒˆã‚¢ã‚¯ã‚»ã‚¹ã‚­ãƒ¼ã€‚ロールインスタンスã®è³‡æ ¼æƒ…報を使用ã—ãªã„å ´åˆã«ã®ã¿å¿…è¦"
msgid "AWS service error: %{error}"
msgstr "AWS サービスエラー: %{error}"
@@ -1603,7 +1621,7 @@ msgid "Abuse reports"
msgstr "ä¸æ­£åˆ©ç”¨ãƒ¬ãƒãƒ¼ãƒˆ"
msgid "Abuse reports notification email"
-msgstr ""
+msgstr "ä¸æ­£åˆ©ç”¨ãƒ¬ãƒãƒ¼ãƒˆé€šçŸ¥ãƒ¡ãƒ¼ãƒ«"
msgid "Accept invitation"
msgstr "招待をå—ã‘入れる"
@@ -1615,7 +1633,7 @@ msgid "Acceptable for use in this project"
msgstr "ã“ã®ãƒ—ロジェクトã¯ä½¿ç”¨å¯èƒ½"
msgid "Access Git repositories or the API."
-msgstr ""
+msgstr "Git リãƒã‚¸ãƒˆãƒªã¾ãŸã¯ API ã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã¾ã™ã€‚"
msgid "Access Tokens"
msgstr "アクセス トークン"
@@ -1624,13 +1642,13 @@ msgid "Access denied for your LDAP account."
msgstr "ã‚ãªãŸã® LDAP アカウントã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•ã‚Œã¾ã—ãŸã€‚"
msgid "Access denied: %{error}"
-msgstr ""
+msgstr "アクセス拒å¦: %{error}"
msgid "Access expiration date"
msgstr "アクセス有効期é™"
msgid "Access expires"
-msgstr ""
+msgstr "アクセスã®æœ‰åŠ¹æœŸé™ãŒåˆ‡ã‚Œã¾ã™"
msgid "Access forbidden. Check your access level."
msgstr "アクセスã¯ç¦æ­¢ã•ã‚Œã¦ã„ã¾ã™ã€‚アクセスレベルを確èªã—ã¦ãã ã•ã„。"
@@ -1639,7 +1657,7 @@ msgid "Access granted"
msgstr "アクセスãŒè¨±å¯ã•ã‚Œã¾ã—ãŸ"
msgid "Access key ID"
-msgstr ""
+msgstr "アクセスキーID"
msgid "Access requests"
msgstr "アクセスリクエスト"
@@ -1648,7 +1666,7 @@ msgid "Access to '%{classification_label}' not allowed"
msgstr "'%{classification_label}'ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
msgid "Access tokens expire after 2 hours. A refresh token may be used at any time to generate a new access token. Non-expiring access tokens are deprecated. Clear this setting to enable backward compatibility."
-msgstr ""
+msgstr "アクセストークンã¯2時間後ã«æœŸé™åˆ‡ã‚Œã«ãªã‚Šã¾ã™ã€‚リフレッシュトークンã¯ã„ã¤ã§ã‚‚æ–°ã—ã„アクセストークンを生æˆã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã§ãã¾ã™ã€‚ 無期é™ã®ã‚¢ã‚¯ã‚»ã‚¹ãƒˆãƒ¼ã‚¯ãƒ³ã¯æŽ¨å¥¨ã•ã‚Œã¾ã›ã‚“。後方互æ›æ€§ã‚’有効ã«ã™ã‚‹ã«ã¯ã€ã“ã®è¨­å®šã‚’クリアã—ã¦ãã ã•ã„。"
msgid "AccessDropdown|Deploy Keys"
msgstr "デプロイキー"
@@ -1674,6 +1692,15 @@ msgstr "本当ã«ã‚ˆã‚ã—ã„ã§ã™ã‹ï¼Ÿç¾åœ¨ä½¿ç”¨ã—ã¦ã„ã‚‹RSSã¾ãŸã¯ã‚«
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr "本当ã«ã‚ˆã‚ã—ã„ã§ã™ã‹ï¼Ÿç¾åœ¨ä½¿ç”¨ã—ã¦ã„るメールアドレスã¯æ©Ÿèƒ½ã—ãªããªã‚Šã¾ã™ã€‚"
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr "作æˆæ¸ˆã¿"
@@ -1686,14 +1713,23 @@ msgstr "å—信メールトークン"
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
+msgstr "ã“ã®ãƒˆãƒ¼ã‚¯ãƒ³ã‚’外部ã«æ¼ã‚‰ã•ãªã„ã§ãã ã•ã„。ã“れをæŒã£ã¦ã„る人ã¯èª°ã§ã‚‚ã‚ãªãŸã«ãªã‚Šã™ã¾ã—ã¦ãƒªãƒã‚¸ãƒˆãƒªã®ã‚¹ã‚¿ãƒ†ã‚£ãƒƒã‚¯ã‚ªãƒ–ジェクトã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã™ã€‚ã‚‚ã—ã‚‚æ¼æ´©ã—ãŸå ´åˆã€ %{reset_link_start} ã“ã®ãƒˆãƒ¼ã‚¯ãƒ³ã‚’リセット %{reset_link_end}ã™ã¹ãã§ã™ã€‚"
+
+msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{linkStart}reset this token%{linkEnd}."
msgstr ""
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
+msgstr "ã“ã®ãƒˆãƒ¼ã‚¯ãƒ³ã¯ç§˜å¯†ã«ã—ã¦ãŠã„ã¦ãã ã•ã„。ã“れをæŒã£ã¦ã„る人ã¯èª°ã§ã‚‚ã‚ãªãŸã¨åŒã˜ã‚ˆã†ã«ã‚¤ã‚·ãƒ¥ãƒ¼ã‚’作æˆã§ãã¾ã™ã€‚ã‚‚ã—æ¼æ´©ã—ãŸå ´åˆã€ %{link_reset_it}。"
+
+msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{linkStart}reset this token%{linkEnd}."
msgstr ""
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
-msgstr ""
+msgstr "ã“ã®ãƒˆãƒ¼ã‚¯ãƒ³ã‚’外部ã«æ¼ã‚‰ã•ãªã„ã§ãã ã•ã„。ã“れをæŒã£ã¦ã„る人ã¯èª°ã§ã‚‚ã‚ãªãŸã®ã‚ˆã†ã«ã‚¢ã‚¯ãƒ†ã‚£ãƒ“ティを読ã‚ã€ã‚ãªãŸã¨ã—ã¦RSSフィードやカレンダーã®ãƒ•ã‚£ãƒ¼ãƒ‰ã‚’発行ã§ãã¾ã™ã€‚æ¼æ´©ã—ãŸå ´åˆã¯ã€%{link_reset_it} ã™ã¹ãã§ã™ã€‚"
msgid "AccessTokens|Personal Access Tokens"
msgstr "パーソナルアクセストークン"
@@ -1711,16 +1747,16 @@ msgid "AccessTokens|You can generate a personal access token for each applicatio
msgstr "GitLab APIã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹å¿…è¦ãŒã‚るアプリケーションã”ã¨ã«ã€ãƒ‘ーソナルアクセストークンを生æˆã§ãã¾ã™ã€‚"
msgid "AccessTokens|Your feed token authenticates you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar. It is visible in those feed URLs."
-msgstr ""
+msgstr "RSS リーダーãŒå€‹äººç”¨RSS フィードを読ã¿è¾¼ã‚€ã¨ãã€ã¾ãŸã¯ã‚«ãƒ¬ãƒ³ãƒ€ãƒ¼ã‚¢ãƒ—リケーションãŒå€‹äººç”¨ã‚«ãƒ¬ãƒ³ãƒ€ãƒ¼ã‚’読ã¿è¾¼ã‚€ã¨ãã«ã€ãƒ•ã‚£ãƒ¼ãƒ‰ãƒˆãƒ¼ã‚¯ãƒ³ã‚’使用ã—ã¦ã‚ãªãŸã‚’èªè¨¼ã—ã¾ã™ã€‚トークンã¯ãƒ•ã‚£ãƒ¼ãƒ‰ URL ã«è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚"
msgid "AccessTokens|Your incoming email token authenticates you when you create a new issue by email, and is included in your personal project-specific email addresses."
-msgstr ""
+msgstr "ã‚ãªãŸãŒãƒ¡ãƒ¼ãƒ«ã§æ–°ã—ã„イシューを作æˆã™ã‚‹ã¨ãã€ã‚ãªãŸã®å—信メールトークンã¯ã‚ãªãŸã‚’èªè¨¼ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã—ã¾ã™ã€‚ã¾ãŸã€ã‚ãªãŸã®å—信メールトークンã¯ã‚ãªãŸã®å€‹äººçš„ãªãƒ—ロジェクト特有ã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã«å«ã¾ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "AccessTokens|Your static object token authenticates you when repository static objects (such as archives or blobs) are served from an external storage."
-msgstr ""
+msgstr "(アーカイブã€ãƒ–ロブãªã©ã®) リãƒã‚¸ãƒˆãƒªã®é™çš„オブジェクトãŒå¤–部ストレージã‹ã‚‰æä¾›ã•ã‚Œã¦ã„ã‚‹å ´åˆã€é™çš„オブジェクトトークンã§ã‚ãªãŸã‚’èªè¨¼ã—ã¾ã™ã€‚"
msgid "AccessTokens|reset this token"
-msgstr ""
+msgstr "トークンをリセット"
msgid "AccessibilityReport|Learn more"
msgstr "詳細を表示"
@@ -1744,11 +1780,41 @@ msgid "Account and limit"
msgstr "アカウントã¨åˆ¶é™"
msgid "Account:"
-msgstr ""
+msgstr "アカウント:"
msgid "Account: %{account}"
msgstr "アカウント: %{account}"
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr "アクション"
@@ -1773,11 +1839,14 @@ msgstr "有効 %{type} (%{token_length})"
msgid "Active Sessions"
msgstr "アクティブ セッション"
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "アクティビティー"
msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
-msgstr ""
+msgstr "アクティビティã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ページをå†èª­ã¿è¾¼ã¿ã—ã¦å†è©¦è¡Œã—ã¦ãã ã•ã„。"
msgid "Add"
msgstr "追加"
@@ -1822,25 +1891,25 @@ msgid "Add a GPG key"
msgstr "GPGキーを追加"
msgid "Add a Jaeger URL to replace this page with a link to your Jaeger server. You first need to %{link_start_tag}install Jaeger%{link_end_tag}."
-msgstr ""
+msgstr "Jaeger URL を追加ã—ã¦ã€ã“ã®ãƒšãƒ¼ã‚¸ã‚’ Jaeger サーãƒãƒ¼ã¸ã®ãƒªãƒ³ã‚¯ã«ç½®ãæ›ãˆã¾ã™ã€‚ã¾ãš %{link_start_tag}Jaeger をインストール%{link_end_tag}ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "Add a Terms of Service agreement and Privacy Policy for users of this GitLab instance."
-msgstr ""
+msgstr "ã“ã® GitLab インスタンスã®ãƒ¦ãƒ¼ã‚¶ã«å¯¾ã—ã¦ã€åˆ©ç”¨è¦ç´„ã¨ãƒ—ライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼ã‚’追加ã—ã¾ã™ã€‚"
msgid "Add a bullet list"
msgstr "箇æ¡æ›¸ãリストを追加"
msgid "Add a collapsible section"
-msgstr ""
+msgstr "折りãŸãŸã¿å¯èƒ½ãªã‚»ã‚¯ã‚·ãƒ§ãƒ³ã‚’追加"
msgid "Add a comment to this line"
msgstr "ã“ã®è¡Œã«ã‚³ãƒ¡ãƒ³ãƒˆã‚’追加"
msgid "Add a comment to this line or drag for multiple lines"
-msgstr ""
+msgstr "ã“ã®è¡Œã«ã‚³ãƒ¡ãƒ³ãƒˆã‚’追加ã™ã‚‹ã‹ã€è¤‡æ•°è¡Œã‚’ドラッグã—ã¦ãã ã•ã„"
msgid "Add a custom message with details about the instance's shared runners. The message is visible in group and project CI/CD settings, in the Runners section. Markdown is supported."
-msgstr ""
+msgstr "インスタンスã®å…±æœ‰ãƒ©ãƒ³ãƒŠãƒ¼ã«ã¤ã„ã¦ã®è©³ç´°ã‚’記載ã—ãŸã‚«ã‚¹ã‚¿ãƒ ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’追加ã—ã¾ã™ã€‚ ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—ãŠã‚ˆã³ãƒ—ロジェクト CI/CD ã®è¨­å®šã‚„ Runner セクションã§è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚Markdown ãŒã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr "ã“ã® %{noteableDisplayName} ã¸ä¸€èˆ¬çš„ãªã‚³ãƒ¡ãƒ³ãƒˆã‚’追加。"
@@ -1849,7 +1918,7 @@ msgid "Add a homepage to your wiki that contains information about your project
msgstr "ã‚ãªãŸã® Wiki ã«ãƒ—ロジェクトã«é–¢ã™ã‚‹æƒ…報をå«ã‚€ãƒ›ãƒ¼ãƒ ãƒšãƒ¼ã‚¸ã‚’追加ã™ã‚‹ã¨ã€GitLab ã¯ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®ä»£ã‚ã‚Šã«ãれをã“ã“ã«è¡¨ç¤ºã—ã¾ã™ã€‚"
msgid "Add a horizontal rule"
-msgstr ""
+msgstr "横線を追加"
msgid "Add a line"
msgstr "行を追加"
@@ -1858,7 +1927,7 @@ msgid "Add a link"
msgstr "リンクを追加"
msgid "Add a link to Grafana"
-msgstr ""
+msgstr "Grafanaã¸ã®ãƒªãƒ³ã‚¯ã‚’追加"
msgid "Add a new issue"
msgstr "æ–°ã—ã„イシューを作æˆã™ã‚‹"
@@ -1870,7 +1939,7 @@ 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 "テーブルを追加ã™ã‚‹"
@@ -1878,7 +1947,7 @@ msgstr "テーブルを追加ã™ã‚‹"
msgid "Add a task list"
msgstr "タスクリストを追加"
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -1906,7 +1975,7 @@ msgid "Add bold text"
msgstr "太字ã®ãƒ†ã‚­ã‚¹ãƒˆã‚’追加"
msgid "Add broadcast message"
-msgstr ""
+msgstr "ブロードキャストメッセージを追加"
msgid "Add child epic to an epic"
msgstr "エピックã«å­ã‚¨ãƒ”ックを追加"
@@ -1918,10 +1987,10 @@ msgid "Add comment to design"
msgstr "デザインã«ã‚³ãƒ¡ãƒ³ãƒˆã‚’追加"
msgid "Add commit messages as comments to Asana tasks. %{docs_link}"
-msgstr ""
+msgstr "コミットメッセージをコメントã¨ã—ã¦Asana タスクã«è¿½åŠ ã—ã¾ã™ã€‚ %{docs_link}"
msgid "Add commit messages as comments to Pivotal Tracker stories. %{docs_link}"
-msgstr ""
+msgstr "Pivotal Tracker ストーリーã«ã‚³ãƒ¡ãƒ³ãƒˆã¨ã—ã¦ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’追加ã—ã¾ã™ã€‚ %{docs_link}"
msgid "Add customer relation contact(s)."
msgstr ""
@@ -1933,13 +2002,13 @@ msgid "Add deploy freeze"
msgstr "デプロイフリーズを追加"
msgid "Add deploy keys to grant read/write access to this repository. %{link_start}What are deploy keys?%{link_end}"
-msgstr ""
+msgstr "ã“ã®ãƒªãƒã‚¸ãƒˆãƒªã¸ã®èª­ã¿å–ã‚Š/書ãè¾¼ã¿ã‚¢ã‚¯ã‚»ã‚¹ã‚’許å¯ã™ã‚‹ãŸã‚ã®ãƒ‡ãƒ—ロイキーを追加ã—ã¾ã™ã€‚ %{link_start}デプロイキーã¨ã¯ä½•ã§ã™ã‹ï¼Ÿ%{link_end}"
msgid "Add email address"
msgstr "メールアドレス追加"
msgid "Add email participant(s)"
-msgstr ""
+msgstr "メールå‚加者を追加"
msgid "Add environment"
msgstr "環境ã®è¿½åŠ "
@@ -1981,7 +2050,7 @@ msgid "Add previously merged commits"
msgstr "以å‰ã«ãƒžãƒ¼ã‚¸ã—ãŸã‚³ãƒŸãƒƒãƒˆã‚’追加"
msgid "Add project"
-msgstr ""
+msgstr "プロジェクトを追加"
msgid "Add projects"
msgstr "プロジェクトを追加"
@@ -2002,7 +2071,7 @@ msgid "Add system hook"
msgstr "システムフックã®è¿½åŠ "
msgid "Add text to the sign-in page. Markdown enabled."
-msgstr ""
+msgstr "サインインページã«ãƒ†ã‚­ã‚¹ãƒˆã‚’追加ã—ã¾ã™ã€‚ マークダウンãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ã¾ã™ã€‚"
msgid "Add to Slack"
msgstr "Slackã«è¿½åŠ "
@@ -2026,10 +2095,10 @@ msgid "Add to tree"
msgstr "ツリーã«è¿½åŠ "
msgid "Add topics to projects to help users find them."
-msgstr ""
+msgstr "プロジェクトã«ãƒˆãƒ”ックを追加ã—ã¦ã€ãƒ¦ãƒ¼ã‚¶ãŒãƒ—ロジェクトを見ã¤ã‘ã‚„ã™ãã—ã¾ã™ã€‚"
msgid "Add trigger"
-msgstr ""
+msgstr "トリガーを追加"
msgid "Add user(s) to the group:"
msgstr "グループã«ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’追加:"
@@ -2041,7 +2110,7 @@ msgid "Add variable"
msgstr "変数ã®è¿½åŠ "
msgid "Add vulnerability finding"
-msgstr ""
+msgstr "発見ã—ãŸè„†å¼±æ€§ã‚’追加ã™ã‚‹"
msgid "Add webhook"
msgstr "Webhook ã®è¿½åŠ "
@@ -2056,16 +2125,16 @@ msgid "AddContextCommits|Add/remove"
msgstr "追加/削除"
msgid "AddMember|Emails cannot be blank"
-msgstr ""
+msgstr "メールを空白ã«ã§ãã¾ã›ã‚“"
msgid "AddMember|Invite email is invalid"
-msgstr ""
+msgstr "招待メールãŒç„¡åŠ¹ã§ã™"
msgid "AddMember|Invite limit of %{daily_invites} per day exceeded"
-msgstr ""
+msgstr "1æ—¥ã‚ãŸã‚Šã®æ‹›å¾…制é™æ•° %{daily_invites} を超ãˆã¾ã—ãŸ"
msgid "AddMember|No invite source provided."
-msgstr ""
+msgstr "招待元ãŒæä¾›ã•ã‚Œã¦ã„ã¾ã›ã‚“。"
msgid "AddMember|No users specified."
msgstr "ユーザーãŒæŒ‡å®šã•ã‚Œã¦ã„ã¾ã›ã‚“。"
@@ -2104,22 +2173,22 @@ msgid "Additional minutes"
msgstr "追加分数"
msgid "Additional minutes:"
-msgstr ""
+msgstr "追加時間(分):"
msgid "Additional text"
msgstr "追加テキスト"
msgid "Additional text for the sign-in and Help page."
-msgstr ""
+msgstr "サインインã¨ãƒ˜ãƒ«ãƒ—ページã®è¿½åŠ ãƒ†ã‚­ã‚¹ãƒˆã§ã™ã€‚"
msgid "Additional text to show on the Help page"
-msgstr ""
+msgstr "ヘルプページã«è¡¨ç¤ºã™ã‚‹è¿½åŠ ãƒ†ã‚­ã‚¹ãƒˆ"
msgid "Additional text to show on the sign-in page"
-msgstr ""
+msgstr "サインインページã«è¡¨ç¤ºã™ã‚‹è¿½åŠ ãƒ†ã‚­ã‚¹ãƒˆ"
msgid "Address"
-msgstr ""
+msgstr "アドレス"
msgid "Adds"
msgstr "追加"
@@ -2131,7 +2200,7 @@ msgid "Adds %{labels} %{label_text}."
msgstr "%{labels} %{label_text} を追加。"
msgid "Adds a Zoom meeting."
-msgstr ""
+msgstr "Zoom ミーティングを追加。"
msgid "Adds a to do."
msgstr "Todoを追加ã—ã¾ã™ã€‚"
@@ -2140,16 +2209,16 @@ msgid "Adds an issue to an epic."
msgstr "イシューをエピックã«è¿½åŠ ã€‚"
msgid "Adds email participant(s)."
-msgstr ""
+msgstr "メールå‚加者を追加。"
msgid "Adjust how frequently the GitLab UI polls for updates."
-msgstr ""
+msgstr "GitLab UI ã®æ›´æ–°é »åº¦ã‚’調整ã—ã¾ã™ã€‚"
msgid "Adjust your filters/search criteria above. If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
msgstr "上記ã®ãƒ•ã‚£ãƒ«ã‚¿ãƒ¼/検索æ¡ä»¶ã‚’調整ã—ã¦ãã ã•ã„。ã“ã‚ŒãŒã‚¨ãƒ©ãƒ¼ã¨è€ƒãˆã‚‰ã‚Œã‚‹å ´åˆã¯ã€ %{linkStart}Geo Troubleshooting%{linkEnd} ドキュメントをå‚ç…§ã—ã¦ãã ã•ã„。"
msgid "Admin"
-msgstr ""
+msgstr "管ç†è€…"
msgid "Admin Area"
msgstr "管ç†è€…エリア"
@@ -2179,13 +2248,13 @@ msgid "Admin mode enabled"
msgstr "管ç†ãƒ¢ãƒ¼ãƒ‰ã¯æœ‰åŠ¹ã§ã™"
msgid "Admin navigation"
-msgstr ""
+msgstr "管ç†è€…用ナビゲーション"
msgid "Admin notes"
msgstr "管ç†è€…メモ"
msgid "AdminArea|%{billable_users_link_start}Learn more%{billable_users_link_end} about what defines a billable user"
-msgstr ""
+msgstr "課金対象ユーザーã®å®šç¾©ã«ã¤ã„ã¦%{billable_users_link_start}詳細を表示%{billable_users_link_end}"
msgid "AdminArea|Active users"
msgstr " アクティブãªãƒ¦ãƒ¼ã‚¶ãƒ¼"
@@ -2212,10 +2281,10 @@ msgid "AdminArea|Features"
msgstr "機能"
msgid "AdminArea|Get security updates from GitLab and stay up to date"
-msgstr ""
+msgstr "GitLab ã‹ã‚‰ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ã‚¢ãƒƒãƒ—デートをå–å¾—ã—ã€æœ€æ–°ã®çŠ¶æ…‹ã‚’維æŒ"
msgid "AdminArea|Groups"
-msgstr ""
+msgstr "グループ"
msgid "AdminArea|Guest"
msgstr "ゲスト"
@@ -2236,7 +2305,7 @@ msgid "AdminArea|Maintainer"
msgstr "メンテナー"
msgid "AdminArea|Minimal access"
-msgstr ""
+msgstr "最å°ã‚¢ã‚¯ã‚»ã‚¹"
msgid "AdminArea|New group"
msgstr "æ–°è¦ã‚°ãƒ«ãƒ¼ãƒ—"
@@ -2251,16 +2320,16 @@ msgid "AdminArea|Owner"
msgstr "オーナー"
msgid "AdminArea|Projects"
-msgstr ""
+msgstr "プロジェクト"
msgid "AdminArea|Reporter"
msgstr "レãƒãƒ¼ã‚¿ãƒ¼"
msgid "AdminArea|Sign up for the GitLab Security Newsletter to get notified for security updates."
-msgstr ""
+msgstr "GitLab セキュリティニュースレターã«ç™»éŒ²ã—ã¦ã€ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£æ›´æ–°ã®é€šçŸ¥ã‚’å—ã‘å–る。"
msgid "AdminArea|Sign up for the GitLab newsletter"
-msgstr ""
+msgstr "GitLabニュースレターã«ç™»éŒ²"
msgid "AdminArea|Stop all jobs"
msgstr "å…¨ã¦ã®ã‚¸ãƒ§ãƒ–ã‚’åœæ­¢"
@@ -2278,7 +2347,7 @@ msgid "AdminArea|Total users"
msgstr "全ユーザー"
msgid "AdminArea|Users"
-msgstr ""
+msgstr "ユーザー"
msgid "AdminArea|Users statistics"
msgstr "ユーザー統計"
@@ -2304,6 +2373,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "統計ã®èª­ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2580,7 +2658,7 @@ msgstr "ユーザーã®å‰Šé™¤"
msgid "AdminUsers|Delete user and contributions"
msgstr "ユーザーã¨è²¢çŒ®åº¦ã®å‰Šé™¤"
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2865,6 +2943,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3010,7 +3091,7 @@ msgid "AlertManagement|This assignee cannot be assigned to this alert."
msgstr "ã“ã®æ‹…当者ã¯ã“ã®ã‚¢ãƒ©ãƒ¼ãƒˆã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã›ã‚“。"
msgid "AlertManagement|Tool"
-msgstr ""
+msgstr "ツール"
msgid "AlertManagement|Triggered"
msgstr ""
@@ -3106,7 +3187,7 @@ msgid "AlertSettings|Proceed with editing"
msgstr ""
msgid "AlertSettings|Prometheus"
-msgstr ""
+msgstr "Prometheus"
msgid "AlertSettings|Prometheus API base URL"
msgstr ""
@@ -3172,7 +3253,7 @@ msgid "AlertSettings|You can now set up alert endpoints for manually configured
msgstr ""
msgid "AlertSettings|{ \"events\": [{ \"application\": \"Name of application\" }] }"
-msgstr ""
+msgstr "{ \"events\": [{ \"application\": \"アプリケーションã®åå‰\" }] }"
msgid "Alerts"
msgstr "アラート"
@@ -3255,6 +3336,9 @@ msgstr ""
msgid "All groups and projects"
msgstr "全グループã¨ãƒ—ロジェクト"
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr "ã“ã®ãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³ã®ã™ã¹ã¦ã®ã‚¤ã‚·ãƒ¥ãƒ¼ã‚’完了ã—ã¾ã—ãŸã€‚"
@@ -3316,10 +3400,10 @@ msgid "Allow owners to manually add users outside of LDAP"
msgstr "オーナーãŒLDAPã¨é–¢ä¿‚ãªãユーザーを手動ã§è¿½åŠ ã§ãるよã†ã«ã™ã‚‹"
msgid "Allow password authentication for Git over HTTP(S)"
-msgstr ""
+msgstr "Git over HTTP(S)ã®ãƒ‘スワードèªè¨¼ã‚’許å¯ã™ã‚‹"
msgid "Allow password authentication for the web interface"
-msgstr ""
+msgstr "Webインターフェイスã®ãƒ‘スワードèªè¨¼ã‚’許å¯ã™ã‚‹"
msgid "Allow project maintainers to configure repository mirroring"
msgstr ""
@@ -3424,7 +3508,7 @@ msgid "Amazon EKS integration allows you to provision EKS clusters from GitLab."
msgstr "Amazon EKSçµ±åˆã«ã‚ˆã‚Šã€GitLabã‹ã‚‰EKSクラスターをプロビジョニングã§ãã¾ã™ã€‚"
msgid "Amazon Web Services Logo"
-msgstr ""
+msgstr "Amazon Web Services ã®ãƒ­ã‚´"
msgid "Amazon authentication is not %{link_start}correctly configured%{link_end}. Ask your GitLab administrator if you want to use this service."
msgstr "Amazon èªè¨¼ã¯ %{link_start} æ­£ã—ã設定 %{link_end} ã§ãã¦ã„ã¾ã›ã‚“。ã“ã®ã‚µãƒ¼ãƒ“スを使用ã—ãŸã„å ´åˆã€ GitLab ã®ç®¡ç†è€…ã«å•ã„åˆã‚ã›ã¦ãã ã•ã„。"
@@ -3433,7 +3517,7 @@ msgid "An %{link_start}alert%{link_end} with the same fingerprint is already ope
msgstr ""
msgid "An Enterprise User GitLab account has been created for you by your organization:"
-msgstr ""
+msgstr "エンタープライズユーザーGitLabアカウントãŒã‚ãªãŸã®çµ„ç¹”ã«ã‚ˆã£ã¦ä½œæˆã•ã‚Œã¾ã—ãŸã€‚"
msgid "An administrator changed the password for your GitLab account on %{link_to}."
msgstr ""
@@ -3459,6 +3543,9 @@ msgstr "エラーãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr "ã“ã®ã‚¹ãƒ¬ãƒƒãƒ‰ã«ä¸‹æ›¸ãを追加ã™ã‚‹éš›ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
@@ -3486,9 +3573,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr "Blobã®ãƒ—レビュー中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3669,6 +3753,9 @@ msgstr "マージリクエストã®ãƒ­ãƒ¼ãƒ‰ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3678,6 +3765,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr "データ読ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
@@ -3694,7 +3784,7 @@ msgid "An error occurred while loading the file. Please try again later."
msgstr "ファイルã®èª­ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "An error occurred while loading the file. Please try again."
-msgstr ""
+msgstr "ファイルã®ãƒ­ãƒ¼ãƒ‰ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "An error occurred while loading the merge request changes."
msgstr "マージリクエストã®å¤‰æ›´ã‚’読込中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
@@ -3761,7 +3851,7 @@ msgstr ""
msgid "An error occurred while saving the setting"
msgid_plural "An error occurred while saving the settings"
-msgstr[0] ""
+msgstr[0] "設定ã®ä¿å­˜ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "An error occurred while subscribing to notifications."
msgstr "通知ã®è³¼èª­ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
@@ -3800,7 +3890,7 @@ msgid "An error occurred while updating the notification settings. Please try ag
msgstr ""
msgid "An error occurred while uploading the file. Please try again."
-msgstr ""
+msgstr "ファイルã®ã‚¢ãƒƒãƒ—ロード中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "An error occurred while uploading the image. Please try again."
msgstr ""
@@ -3826,6 +3916,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -3866,7 +3962,7 @@ msgid "Analyze a review version of your web application."
msgstr "Webアプリケーションã®ãƒ¬ãƒ“ューãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’分æžã—ã¾ã™ã€‚"
msgid "Analyze your dependencies for known vulnerabilities."
-msgstr ""
+msgstr "ä¾å­˜é–¢ä¿‚ã«å«ã¾ã‚Œã¦ã„る既知ã®è„†å¼±æ€§ã‚’分æžã—ã¾ã™ã€‚"
msgid "Analyze your infrastructure as code configuration files for known vulnerabilities."
msgstr ""
@@ -3902,7 +3998,7 @@ msgid "Any"
msgstr "ä»»æ„ã®"
msgid "Any %{header}"
-msgstr ""
+msgstr "ä»»æ„ã® %{header}"
msgid "Any Author"
msgstr "ä»»æ„ã®ä½œæˆè€…"
@@ -3988,7 +4084,7 @@ msgstr ""
msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
-msgstr[0] ""
+msgstr[0] "ã“ã®å¤‰æ›´ã‚’è¡Œã†ã“ã¨ã«ã‚ˆã‚Šã€ä¿ç•™ä¸­ã®æ‰¿èªã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’æŒã¤%dユーザーを自動的ã«æ‰¿èªã—ã¾ã™ã€‚"
msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
msgstr ""
@@ -4127,7 +4223,7 @@ msgid "Approval rules reset to project defaults"
msgstr "承èªãƒ«ãƒ¼ãƒ«ã¯ãƒ—ロジェクトã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã«ãƒªã‚»ãƒƒãƒˆã•ã‚Œã¾ã—ãŸ"
msgid "Approval settings"
-msgstr ""
+msgstr "承èªã®è¨­å®š"
msgid "ApprovalRuleRemove|%d member"
msgid_plural "ApprovalRuleRemove|%d members"
@@ -4148,7 +4244,13 @@ msgstr[0] "%{membersCount} åã®ã†ã¡ %{count} åã‹ã‚‰ã®æ‰¿èªãŒå¿…è¦"
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
+msgstr "承èªè€…を追加"
+
+msgid "ApprovalRule|Add required approvers to improve your code review process"
msgstr ""
msgid "ApprovalRule|All scanners"
@@ -4181,6 +4283,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr "承èªè€…"
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4190,6 +4295,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr "åå‰"
@@ -4214,6 +4328,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4241,6 +4358,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr "ターゲットブランãƒ"
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4277,7 +4397,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4305,7 +4425,7 @@ msgid "Approve the current merge request."
msgstr "ç¾åœ¨ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’承èªã™ã‚‹ã€‚"
msgid "Approved"
-msgstr ""
+msgstr "承èªæ¸ˆã¿"
msgid "Approved MRs"
msgstr "承èªã•ã‚ŒãŸãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆ"
@@ -4353,7 +4473,7 @@ msgid "Archived (%{movedToStart}moved%{movedToEnd})"
msgstr ""
msgid "Archived in this version"
-msgstr ""
+msgstr "ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–"
msgid "Archived project! Repository and other project resources are read-only"
msgstr "ã“ã®ãƒ—ロジェクトã¯ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã•ã‚Œã¦ã„ã¾ã™ã€‚リãƒã‚¸ãƒˆãƒªãŠã‚ˆã³ãã®ä»–ã®ãƒ—ロジェクトリソースã¯èª­ã¿å–り専用ã§ã™"
@@ -4429,10 +4549,10 @@ msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
msgid "Are you sure you want to lock %{path}?"
-msgstr ""
+msgstr "%{path} をロックã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
msgid "Are you sure you want to lock this directory?"
-msgstr ""
+msgstr "ã“ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’ロックã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
msgid "Are you sure you want to lose unsaved changes?"
msgstr "変更ãŒä¿å­˜ã•ã‚Œã¦ã„ã¾ã›ã‚“ãŒç ´æ£„ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
@@ -4446,9 +4566,6 @@ msgstr "本当ã«ã™ãã«ãƒžãƒ¼ã‚¸ã—ã¾ã™ã‹ï¼Ÿ"
msgid "Are you sure you want to re-deploy this environment?"
msgstr "ã“ã®ç’°å¢ƒã‚’å†ãƒ‡ãƒ—ロイã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr "公開éµã‚’å†ç”Ÿæˆã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹? ミラーリングを行ã†å‰ã«ãƒªãƒ¢ãƒ¼ãƒˆã‚µãƒ¼ãƒãƒ¼ã®å…¬é–‹éµã‚’æ›´æ–°ã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。"
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4462,7 +4579,7 @@ msgid "Are you sure you want to remove the attachment?"
msgstr "添付ファイルを削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
msgid "Are you sure you want to remove the license?"
-msgstr ""
+msgstr "ライセンスを消去ã—ã¦æœ¬å½“ã«ã‚ˆã‚ã—ã„ã§ã™ã‹?"
msgid "Are you sure you want to remove this deploy key? If anything is still using this key, it will stop working."
msgstr ""
@@ -4501,10 +4618,10 @@ msgid "Are you sure you want to unlock %{path_lock_path}?"
msgstr "%{path_lock_path} ã®ãƒ­ãƒƒã‚¯ã‚’解除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
msgid "Are you sure you want to unlock %{path}?"
-msgstr ""
+msgstr "%{path} ã®ãƒ­ãƒƒã‚¯ã‚’解除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
msgid "Are you sure you want to unlock this directory?"
-msgstr ""
+msgstr "ã“ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®ãƒ­ãƒƒã‚¯ã‚’解除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
msgid "Are you sure you want to unsubscribe from the %{type}: %{link_to_noteable_text}?"
msgstr "%{type}: %{link_to_noteable_text} ã®è³¼èª­ã‚’解除ã—ã¦ã‚ˆã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
@@ -4596,6 +4713,9 @@ msgstr "レビュアーを割り当ã¦ã‚‹"
msgid "Assign reviewer(s)"
msgstr "レビュアーを割り当ã¦ã‚‹"
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr "ã“ã®ãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³ã«ã„ãã¤ã‹ã®ã‚¤ã‚·ãƒ¥ãƒ¼ã‚’割り当ã¦ã¾ã™ã€‚"
@@ -4725,13 +4845,13 @@ msgid "AuditLogs|Failed to find %{type}. Please try again."
msgstr ""
msgid "AuditLogs|Group Events"
-msgstr ""
+msgstr "グループイベント"
msgid "AuditLogs|IP Address"
msgstr "IPアドレス"
msgid "AuditLogs|Member Events"
-msgstr ""
+msgstr "メンãƒãƒ¼ã‚¤ãƒ™ãƒ³ãƒˆ"
msgid "AuditLogs|No matching %{type} found."
msgstr ""
@@ -4740,7 +4860,7 @@ msgid "AuditLogs|Object"
msgstr ""
msgid "AuditLogs|Project Events"
-msgstr ""
+msgstr "プロジェクトイベント"
msgid "AuditLogs|Target"
msgstr ""
@@ -4749,7 +4869,7 @@ msgid "AuditLogs|This month"
msgstr ""
msgid "AuditLogs|User Events"
-msgstr ""
+msgstr "ユーザーイベント"
msgid "Aug"
msgstr "8月"
@@ -4991,9 +5111,6 @@ msgstr "利用å¯èƒ½ãª Specific Runner"
msgid "Avatar for %{assigneeName}"
msgstr "%{assigneeName} ã®ã‚¢ãƒã‚¿ãƒ¼"
-msgid "Avatar for %{name}"
-msgstr "%{name} ã®ã‚¢ãƒã‚¿ãƒ¼"
-
msgid "Avatar will be removed. Are you sure?"
msgstr "ã‚¢ãƒã‚¿ãƒ¼ã‚’削除ã—ã¾ã™ã€‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
@@ -5184,7 +5301,7 @@ msgid "BillingPlans|End of availability for the Bronze Plan"
msgstr ""
msgid "BillingPlans|Free upgrade!"
-msgstr ""
+msgstr "無料アップグレードï¼"
msgid "BillingPlans|If you would like to downgrade your plan please contact %{support_link_start}Customer Support%{support_link_end}."
msgstr "プランをダウングレードを希望ã™ã‚‹å ´åˆã€ %{support_link_start} カスタマーサãƒãƒ¼ãƒˆ%{support_link_end} ã¾ã§ã”連絡ãã ã•ã„。"
@@ -5243,9 +5360,6 @@ msgstr "月é¡"
msgid "BillingPlans|per user"
msgstr "1ユーザーã«ã¤ã"
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr "アップグレード"
@@ -5276,13 +5390,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5294,7 +5405,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5306,9 +5420,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5493,7 +5613,7 @@ msgstr ""
msgid "Boards"
msgstr "ボード"
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5852,7 +5972,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5861,6 +5984,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -5900,6 +6026,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -5988,7 +6117,7 @@ msgid "CI configuration validated, including all configuration added with the %{
msgstr ""
msgid "CI settings"
-msgstr ""
+msgstr "CI設定"
msgid "CI variables"
msgstr "CI 変数"
@@ -6235,7 +6364,7 @@ msgid "CanaryIngress|Doing so will set a deployment change in progress. This tem
msgstr ""
msgid "CanaryIngress|Stable"
-msgstr ""
+msgstr "安定版"
msgid "CanaryIngress|You are changing the ratio of the canary rollout for %{environment} compared to the stable deployment to:"
msgstr ""
@@ -6334,7 +6463,7 @@ msgid "Card holder name"
msgstr ""
msgid "Card number:"
-msgstr ""
+msgstr "カード番å·:"
msgid "CascadingSettings|Enforce for all subgroups"
msgstr ""
@@ -6603,7 +6732,7 @@ msgstr "ユーザーåãŒåˆ©ç”¨å¯èƒ½ã‹ç¢ºèªã—ã¦ã„ã¾ã™..."
msgid "Checkout"
msgstr "Checkout"
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6765,7 +6894,7 @@ msgid "Checkout|Storage packs"
msgstr ""
msgid "Checkout|Street address"
-msgstr ""
+msgstr "市区町æ‘以下ã®ä½æ‰€"
msgid "Checkout|Submitting the credit card form failed with code %{errorCode}: %{errorMessage}"
msgstr "クレジットカードã®ãƒ•ã‚©ãƒ¼ãƒ ã®ã‚³ãƒ¼ãƒ‰ %{errorCode} ã®é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸã€‚: %{errorMessage}"
@@ -6863,9 +6992,6 @@ msgstr "カラーをé¸æŠžã—ã¦ãã ã•ã„。"
msgid "Choose file…"
msgstr "ファイルをé¸æŠž..."
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7076,6 +7202,9 @@ msgstr "ãƒãƒ£ãƒ¼ãƒˆãƒ•ã‚£ãƒ«ã‚¿ãƒ¼ã‚’解除"
msgid "Clear due date"
msgstr "期日を消去"
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr "最近検索をクリアー"
@@ -7094,9 +7223,15 @@ msgstr "テンプレート検索入力をクリア"
msgid "Clear weight"
msgstr "ウェイトをクリア"
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr "ウェイトをクリア"
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr "ウェイトをクリアã—ã¾ã™ã€‚"
@@ -7250,12 +7385,27 @@ msgstr "クラスターã®ãƒ¬ãƒ™ãƒ«"
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7268,6 +7418,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7283,9 +7439,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7331,12 +7493,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7412,6 +7583,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7430,12 +7604,25 @@ 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 ""
+msgid "ClusterAgents|There's no activity from the past day"
+msgid_plural "ClusterAgents|There's no activity from the past %d days"
+msgstr[0] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7445,6 +7632,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8226,7 +8416,7 @@ msgid "Code Coverage|Couldn't fetch the code coverage data"
msgstr ""
msgid "Code Owner"
-msgstr ""
+msgstr "コードオーナー"
msgid "Code Owners"
msgstr "コードオーナー"
@@ -8464,7 +8654,7 @@ msgid "Company"
msgstr ""
msgid "Company Name"
-msgstr ""
+msgstr "会社å"
msgid "Compare"
msgstr "比較"
@@ -8554,7 +8744,7 @@ msgid "Compliance framework"
msgstr ""
msgid "Compliance report"
-msgstr ""
+msgstr "コンプライアンスレãƒãƒ¼ãƒˆ"
msgid "ComplianceDashboard|created by:"
msgstr ""
@@ -8631,6 +8821,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -8779,16 +8978,16 @@ msgid "Conflict: This file was modified in the source branch, but removed in the
msgstr ""
msgid "Conflict: This file was removed in the source branch, but modified in the target branch."
-msgstr ""
+msgstr "競åˆï¼šã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯ã‚½ãƒ¼ã‚¹ãƒ–ランãƒã§å‰Šé™¤ã•ã‚Œã¾ã—ãŸãŒã€ã‚¿ãƒ¼ã‚²ãƒƒãƒˆãƒ–ランãƒã§å¤‰æ›´ã•ã‚Œã¾ã—ãŸã€‚"
msgid "Conflict: This file was removed in the source branch, but renamed in the target branch."
-msgstr ""
+msgstr "競åˆï¼šã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯ã‚½ãƒ¼ã‚¹ãƒ–ランãƒã§å‰Šé™¤ã•ã‚Œã¾ã—ãŸãŒã€ã‚¿ãƒ¼ã‚²ãƒƒãƒˆãƒ–ランãƒã§åå‰ãŒå¤‰æ›´ã•ã‚Œã¾ã—ãŸã€‚"
msgid "Conflict: This file was renamed differently in the source and target branches."
-msgstr ""
+msgstr "競åˆï¼šã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯ã€ã‚½ãƒ¼ã‚¹ãƒ–ランãƒã¨ã‚¿ãƒ¼ã‚²ãƒƒãƒˆãƒ–ランãƒã§ç•°ãªã‚‹åå‰ã«å¤‰æ›´ã•ã‚Œã¾ã—ãŸã€‚"
msgid "Conflict: This file was renamed in the source branch, but removed in the target branch."
-msgstr ""
+msgstr "競åˆï¼šã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯ã‚½ãƒ¼ã‚¹ãƒ–ランãƒã§åå‰ãŒå¤‰æ›´ã•ã‚Œã¾ã—ãŸãŒã€ã‚¿ãƒ¼ã‚²ãƒƒãƒˆãƒ–ランãƒã§å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚"
msgid "Confluence"
msgstr ""
@@ -8866,7 +9065,7 @@ msgid "Container does not exist"
msgstr "コンテナãŒã‚ã‚Šã¾ã›ã‚“"
msgid "Container must be a project or a group."
-msgstr ""
+msgstr "コンテナã¯ãƒ—ロジェクトã¾ãŸã¯ã‚°ãƒ«ãƒ¼ãƒ—ã§ã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "Container registry images"
msgstr "コンテナレジストリã®ã‚¤ãƒ¡ãƒ¼ã‚¸"
@@ -8907,10 +9106,10 @@ msgid "ContainerRegistry|-- tags"
msgstr ""
msgid "ContainerRegistry|Build an image"
-msgstr ""
+msgstr "イメージをビルド"
msgid "ContainerRegistry|CLI Commands"
-msgstr ""
+msgstr "CLI コマンド"
msgid "ContainerRegistry|Cleanup disabled"
msgstr ""
@@ -8973,7 +9172,7 @@ msgid "ContainerRegistry|Copy push command"
msgstr "プッシュコマンドをコピー"
msgid "ContainerRegistry|Delete image repository?"
-msgstr ""
+msgstr "イメージリãƒã‚¸ãƒˆãƒªã‚’削除ã—ã¾ã™ã‹?"
msgid "ContainerRegistry|Delete selected tags"
msgstr ""
@@ -8991,7 +9190,7 @@ msgid "ContainerRegistry|Docker connection error"
msgstr "Docker接続エラー"
msgid "ContainerRegistry|Enable expiration policy"
-msgstr ""
+msgstr "有効期é™ãƒãƒªã‚·ãƒ¼ã‚’有効ã«ã™ã‚‹"
msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
@@ -9030,7 +9229,7 @@ msgid "ContainerRegistry|Keep these tags"
msgstr ""
msgid "ContainerRegistry|Last updated %{time}"
-msgstr ""
+msgstr "最終更新 %{time}"
msgid "ContainerRegistry|Login"
msgstr "ログイン"
@@ -9042,14 +9241,17 @@ msgid "ContainerRegistry|Missing or insufficient permission, delete button disab
msgstr ""
msgid "ContainerRegistry|Next cleanup scheduled to run on:"
-msgstr ""
+msgstr "次ã®ã‚¯ãƒªãƒ¼ãƒ³ã‚¢ãƒƒãƒ—ã®å®Ÿè¡Œäºˆå®šæ—¥æ™‚:"
msgid "ContainerRegistry|Not yet scheduled"
-msgstr ""
+msgstr "スケジュールã•ã‚Œã¦ã„ã¾ã›ã‚“"
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9138,6 +9340,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9369,12 +9574,18 @@ msgstr "環境をコピー"
msgid "Copy evidence SHA"
msgstr "証拠 SHA をコピー"
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr "ファイルã®å†…容をコピー"
msgid "Copy file path"
msgstr "ファイルã®ãƒ‘スをコピー"
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr "キーをコピー"
@@ -9405,9 +9616,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9634,7 +9842,7 @@ msgid "Create a new issue"
msgstr "イシューã®æ–°è¦ä½œæˆ"
msgid "Create a new project"
-msgstr ""
+msgstr "æ–°è¦ãƒ—ロジェクトを作æˆ"
msgid "Create a new repository"
msgstr "æ–°ã—ã„リãƒã‚¸ãƒˆãƒªã‚’作æˆ"
@@ -9747,9 +9955,6 @@ msgstr "ラベルã®æ–°è¦ä½œæˆ"
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr "æ–°è¦ä½œæˆ"
-
msgid "Create or import your first project"
msgstr ""
@@ -9780,6 +9985,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9790,7 +9998,7 @@ msgid "Create your group"
msgstr "グループを作æˆ"
msgid "Create/import your first project"
-msgstr ""
+msgstr "最åˆã®ãƒ—ロジェクトを作æˆ/インãƒãƒ¼ãƒˆ"
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr "ã‚ãªãŸã¯ã€ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«ã‚µãƒ–グループを作æˆã™ã‚‹æ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“。"
@@ -9822,9 +10030,6 @@ msgstr "ã™ã¹ã¦ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã‚¹ãƒ†ãƒ¼ã‚¸ã¯ç¾åœ¨è¡¨ç¤ºã•ã‚Œã¦ã„ã¾ã™
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9834,13 +10039,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr "デフォルトステージ"
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -9955,7 +10163,7 @@ msgid "Created by me"
msgstr "自分ãŒä½œæˆ"
msgid "Created by:"
-msgstr ""
+msgstr "作æˆè€…:"
msgid "Created date"
msgstr ""
@@ -10020,15 +10228,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr "é‡å¤§ãªè„†å¼±æ€§ã®å­˜åœ¨"
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10038,15 +10264,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10102,7 +10337,7 @@ msgid "Current sign-in at:"
msgstr ""
msgid "Current sign-in ip"
-msgstr ""
+msgstr "ç¾åœ¨ã®ãƒ­ã‚°ã‚¤ãƒ³IPアドレス"
msgid "Current vulnerabilities count"
msgstr "ç¾åœ¨ã®è„†å¼±æ€§ã‚«ã‚¦ãƒ³ãƒˆ"
@@ -10197,15 +10432,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr "パイプライン設定をカスタマイズ"
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -10443,7 +10669,7 @@ msgid "Dashboard"
msgstr "ダッシュボード"
msgid "Dashboard uid not found"
-msgstr ""
+msgstr "ダッシュボード uid ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "DashboardProjects|All"
msgstr "ã™ã¹ã¦"
@@ -10887,6 +11113,9 @@ msgstr ""
msgid "Date"
msgstr "日付"
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr "日付é¸æŠž"
@@ -10996,7 +11225,7 @@ msgid "Default projects limit"
msgstr ""
msgid "Default timeout"
-msgstr ""
+msgstr "デフォルトã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆ"
msgid "Default: Map a FogBugz account ID to a full name"
msgstr "デフォルト:FogBugz ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆIDをフルãƒãƒ¼ãƒ ã«ãƒžãƒƒãƒ—ã™ã‚‹"
@@ -11119,7 +11348,7 @@ msgid "Delete image repository"
msgstr ""
msgid "Delete label"
-msgstr ""
+msgstr "ラベルを削除"
msgid "Delete label: %{labelName}"
msgstr ""
@@ -11166,6 +11395,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr "プロジェクトã®ãƒªãƒã‚¸ãƒˆãƒªã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã™ã‹ã€ç®¡ç†è€…ã«é€£çµ¡ã—ã¦ãã ã•ã„。"
@@ -11199,15 +11431,9 @@ msgstr ""
msgid "Deleted"
msgstr "削除完了"
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr "ãƒãƒ£ãƒƒãƒˆãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ ã‚’削除ã—ã¾ã—ãŸï¼š %{chat_name}ï¼"
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11337,6 +11563,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11361,7 +11590,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11370,6 +11599,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -11817,7 +12049,7 @@ msgid "Destroy"
msgstr "破棄"
msgid "Detail"
-msgstr ""
+msgstr "詳細"
msgid "Details"
msgstr "詳細"
@@ -12164,15 +12396,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr "無料トライアルを始ã‚ã‚‹"
@@ -12312,6 +12544,9 @@ msgstr ""
msgid "Download CSV"
msgstr "CSV をダウンロード"
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr "アーティファクトã®ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰"
@@ -12447,8 +12682,8 @@ msgstr "マイルストーンを編集"
msgid "Edit Password"
msgstr "パスワードを編集"
-msgid "Edit Pipeline Schedule %{id}"
-msgstr "パイプラインスケジュール %{id} を編集"
+msgid "Edit Pipeline Schedule"
+msgstr ""
msgid "Edit Release"
msgstr "リリースを編集"
@@ -12486,6 +12721,9 @@ msgstr "説明を編集"
msgid "Edit environment"
msgstr "環境を編集"
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr "エディターã§ãƒ•ã‚¡ã‚¤ãƒ«ã‚’編集ã—ã€ã“ã“ã§å¤‰æ›´ã‚’コミットã—ã¾ã™"
@@ -13426,6 +13664,9 @@ msgstr "アイテムを並ã¹ã¦ã„ã‚‹é–“ã«ä½•ã‹å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚
msgid "Epics|Something went wrong while removing issue from epic."
msgstr "エピックã‹ã‚‰ã‚¤ã‚·ãƒ¥ãƒ¼ã‚’削除ã—ã¦ã‚‹é–“ã«ä½•ã‹å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
+msgid "Epics|Something went wrong while updating epics."
+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 "ã“ã®ã‚¨ãƒ”ックã¨ã“ã‚Œå«ã¾ã‚Œã¦ã„ã‚‹å­ã‚¨ãƒ”ックã¯éžå…¬é–‹ã§ã‚ã‚Šã€å°‘ãªãã¨ã‚‚Reporterアクセス権é™ã®ã‚ã‚‹ãƒãƒ¼ãƒ ãƒ¡ãƒ³ãƒãƒ¼ã«ã®ã¿è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚"
@@ -13471,9 +13712,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr "プロジェクトã®å‰Šé™¤ã§ã‚¨ãƒ©ãƒ¼ãŒã‚ã‚Šã¾ã™ã€‚エラーã®è©³ç´°ã«ã¤ã„ã¦ã¯ãƒ­ã‚°ã‚’確èªã—ã¦ãã ã•ã„。"
@@ -13627,9 +13865,6 @@ msgstr "ファイルã®ã‚¢ãƒƒãƒ—ロードã«å¤±æ•—ã—ã¾ã—ãŸ: %{stripped} "
msgid "Error while loading the merge request. Please try again."
msgstr "マージリクエストã®èª­ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
-msgid "Error while loading the project data. Please try again."
-msgstr "プロジェクトデータã®èª­ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚å†è©¦è¡Œã—ã¦ãã ã•ã„。"
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr "%{upload_id} ã®ç§»è¡Œä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %{error_message}"
@@ -13714,6 +13949,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -13898,9 +14136,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr "全員"
-
msgid "Everyone With Access"
msgstr "アクセスã§ãる人ã™ã¹ã¦"
@@ -13929,7 +14164,7 @@ msgid "Everything you need to create a GitLab Pages site using plain HTML"
msgstr ""
msgid "Evidence collection"
-msgstr "証拠集ã‚"
+msgstr "エビデンス一覧"
msgid "Exactly one of %{attributes} is required"
msgstr ""
@@ -14093,7 +14328,7 @@ msgstr "プロジェクトã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ"
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14302,7 +14537,7 @@ msgid "Failed to load labels. Please try again."
msgstr ""
msgid "Failed to load milestones."
-msgstr ""
+msgstr "マイルストーンã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
msgid "Failed to load milestones. Please try again."
msgstr "マイルストーンã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
@@ -14798,9 +15033,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr "2è¦ç´ èªè¨¼ã§çµžã‚Šè¾¼ã¿"
-
msgid "Filter by user"
msgstr "ユーザーã§ãƒ•ã‚£ãƒ«ã‚¿ãƒ¼"
@@ -15131,6 +15363,9 @@ msgstr "マージリクエストãŒãƒžãƒ¼ã‚¸ã•ã‚Œã¦ã‹ã‚‰ãƒ—ロダクション
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr "æ°å"
@@ -15992,9 +16227,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16082,6 +16314,9 @@ msgstr "メトリクスã¸"
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr "親ã«ç§»å‹•"
@@ -16271,9 +16506,6 @@ msgstr "グループ SAML を有効ã«ã—ã¦ãƒ†ã‚¹ãƒˆã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™
msgid "Group URL"
msgstr "グループ URL"
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16400,6 +16632,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr "グループã¯æ­£å¸¸ã«æ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚"
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr "グループ:%{group_name}"
@@ -16502,9 +16737,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16577,6 +16821,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr "ã“ã® SAML グループã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’割り当ã¦ã‚‹ãƒ­ãƒ¼ãƒ«ã€‚"
@@ -16616,6 +16863,9 @@ msgstr "SAML トークン㮠SHA1 フィンガープリントã§è¨¼æ˜Žæ›¸ã«ç½²å
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr "SCIMトークンã¯éžè¡¨ç¤ºã«ãªã£ã¦ã„ã¾ã™ã€‚トークンã®å€¤ã‚’ã‚‚ã†ä¸€åº¦ç¢ºèªã™ã‚‹ã«ã¯ã€æ¬¡ã®æ‰‹é †ã‚’実行ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚ "
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16649,6 +16899,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16673,8 +16935,8 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr "ãƒãƒƒã‚¸"
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
-msgstr "注æ„ã—ã¦ãã ã•ã„。グループã®è¦ªã‚’変更ã™ã‚‹ã¨ã€æ„図ã—ã¦ã„ãªã‹ã£ãŸ %{side_effects_link_start} 副作用 %{side_effects_link_end}ãŒç™ºç”Ÿã™ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚"
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
+msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
msgstr "コンテナレジストリã«Dockerイメージをå«ã‚€ãƒ—ロジェクトãŒã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã®ä¸‹ã«ã‚ã‚‹ãŸã‚ã€ãƒ‘スを更新ã§ãã¾ã›ã‚“。 最åˆã«ãƒ—ロジェクトã‹ã‚‰ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’削除ã—ã¦ã€ã‚‚ã†ä¸€åº¦è©¦ã—ã¦ãã ã•ã„。"
@@ -16682,7 +16944,7 @@ msgstr "コンテナレジストリã«Dockerイメージをå«ã‚€ãƒ—ロジェク
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16724,6 +16986,9 @@ msgstr "æ–°ã—ã„ランナー登録トークンを生æˆã—ã¾ã—ãŸï¼"
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr "グループã®ãƒ‘イプライン設定ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸ"
@@ -16751,12 +17016,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -16871,6 +17142,9 @@ msgstr "グループメンãƒãƒ¼ã®æ¨©é™ç®¡ç†ã€ãŠã‚ˆã³ã‚°ãƒ«ãƒ¼ãƒ—内ã®å„
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -16896,7 +17170,7 @@ msgid "GroupsNew|Groups can also be nested by creating %{linkStart}subgroups%{li
msgstr ""
msgid "GroupsNew|Import group"
-msgstr ""
+msgstr "グループをインãƒãƒ¼ãƒˆ"
msgid "GroupsNew|Import groups from another instance of GitLab"
msgstr ""
@@ -16925,6 +17199,9 @@ 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 ""
+
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 ""
@@ -17180,7 +17457,7 @@ msgid "Home page URL"
msgstr ""
msgid "Homepage"
-msgstr ""
+msgstr "ホームページ"
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr "フックã®å®Ÿè¡Œã«å¤±æ•—ã—ã¾ã—ãŸã€‚グループã«ã‚³ãƒŸãƒƒãƒˆã®ã‚るプロジェクトãŒã‚ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。"
@@ -17294,7 +17571,7 @@ msgid "ID:"
msgstr "ID:"
msgid "IDE"
-msgstr ""
+msgstr "IDE"
msgid "IDE|Back"
msgstr "戻る"
@@ -18827,6 +19104,9 @@ msgstr ""
msgid "Invalid URL"
msgstr "無効㪠URL"
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19076,9 +19356,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19181,9 +19458,6 @@ msgstr ""
msgid "Is blocked by"
msgstr "ブロックã•ã‚Œã¦ã„ã¾ã™ï¼š"
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr "ライセンスシートã®ä½¿ç”¨:"
@@ -19295,9 +19569,6 @@ msgstr "ステータス"
msgid "IssueAnalytics|Weight"
msgstr "ウェイト"
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr "ボード"
@@ -19943,8 +20214,8 @@ msgstr "完全㪠Raw"
msgid "Job|Download"
msgstr "ダウンロード"
-msgid "Job|Erase job log"
-msgstr "ジョブログã®æ¶ˆåŽ»"
+msgid "Job|Erase job log and artifacts"
+msgstr ""
msgid "Job|Job artifacts"
msgstr "ジョブã®ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ã‚¡ã‚¯ãƒˆ"
@@ -20394,6 +20665,12 @@ msgstr "ã“ã®ãƒ–ランãƒã§ã®ç›´è¿‘ã®ã‚³ãƒŸãƒƒãƒˆã®æœ€æ–°ã®ãƒ‘イプライ
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21148,7 +21425,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr "ã“ã®ã‚¤ã‚·ãƒ¥ãƒ¼ã®é †åºã‚’ä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸ"
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -21904,10 +22181,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22006,6 +22283,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr "メトリクスã¨ãƒ—ロファイリング"
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22623,6 +22903,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr "%{default_branch} ã‹ã‚‰%{number_commits_distance} コミット以上異ãªã£ã¦ã„ã¾ã™ã€‚"
@@ -22825,6 +23108,39 @@ msgstr "プロジェクトã«ç§»å‹•ã—ã¦ã€ãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³ã‚’é–‰ã˜ã‚‹ã€‚
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr "ヘルプ"
@@ -23038,6 +23354,9 @@ msgstr "æ–°è¦ä½œæˆ"
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr "æ–°ã—ã„アプリケーション"
@@ -23100,7 +23419,7 @@ msgid "New Test Case"
msgstr ""
msgid "New User"
-msgstr ""
+msgstr "æ–°è¦ãƒ¦ãƒ¼ã‚¶ãƒ¼"
msgid "New application"
msgstr ""
@@ -23261,6 +23580,9 @@ msgstr ""
msgid "Next file in diff"
msgstr "差分ã®ã‚る次ã®ãƒ•ã‚¡ã‚¤ãƒ«"
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr "次ã®æœªè§£æ±ºã®ãƒ‡ã‚£ã‚¹ã‚«ãƒƒã‚·ãƒ§ãƒ³ã¸ã‚¸ãƒ£ãƒ³ãƒ—"
@@ -23679,6 +24001,9 @@ msgstr "注: GitLab ã®ç®¡ç†è€…ã«%{github_integration_link} を設定ã—ã¦ã€
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr "注: GitLab ã®ç®¡ç†è€…ã«%{github_integration_link} を設定ã—ã¦ã€GitHub 経由ã®ãƒ­ã‚°ã‚¤ãƒ³ãŒè¨±å¯ã—ã€å€‹äººç”¨ã®ã‚¢ã‚¯ã‚»ã‚¹ãƒˆãƒ¼ã‚¯ãƒ³ã‚’生æˆã›ãšã«ãƒªãƒã‚¸ãƒˆãƒªã‚’インãƒãƒ¼ãƒˆã§ããªã„ã‹å•ã„åˆã‚ã›ãã ã•ã„。"
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr "メモ"
@@ -23691,7 +24016,7 @@ msgstr "本当ã«ã“ã®ã‚³ãƒ¡ãƒ³ãƒˆã®ä½œæˆã‚’キャンセルã—ã¾ã™ã‹ï¼Ÿ"
msgid "Notes|Collapse replies"
msgstr "返信を折りãŸãŸã‚€"
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -23930,7 +24255,7 @@ msgid "On"
msgstr ""
msgid "On track"
-msgstr ""
+msgstr "順調"
msgid "On-call Schedules"
msgstr ""
@@ -24094,6 +24419,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24112,12 +24443,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr "オンデマンドDASTスキャンを編集"
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24157,12 +24494,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr "オンデマンドスキャン㯠DevOps ã®ã‚µã‚¤ã‚¯ãƒ«å¤–ã§å®Ÿè¡Œã•ã‚Œã€ãƒ—ロジェクトã®è„†å¼±æ€§ã‚’見ã¤ã‘ã¾ã™ã€‚%{learnMoreLinkStart}詳細を表示%{learnMoreLinkEnd}"
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24187,18 +24533,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24208,9 +24569,6 @@ msgstr "インãƒãƒ¼ãƒˆã™ã‚‹ã¨ã€ãƒªãƒã‚¸ãƒˆãƒªã¯SSHã«ã‚ˆã‚ŠãƒŸãƒ©ãƒ¼ãƒªãƒ³
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr "エクスãƒãƒ¼ãƒˆã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã®æº–å‚™ãŒã§ããŸã‚‰ã€ã‚ãªãŸã¯ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ãƒªãƒ³ã‚¯ä»˜ãã®é€šçŸ¥ãƒ¡ãƒ¼ãƒ«ã‚’å—ã‘å–ã‚Œã¾ã™ã€‚ã¾ãŸã¯ã“ã®ãƒšãƒ¼ã‚¸ã‹ã‚‰ãれをダウンロードã§ãã¾ã™ã€‚"
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24368,6 +24726,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr "æ“作ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸã€‚ pod log ã® %{pod_name} ã§è©³ç´°ã‚’確èªã—ã¦ãã ã•ã„。"
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr "オペレーションダッシュボード"
@@ -24811,7 +25172,7 @@ msgid "PackageRegistry|Required Python: %{pythonVersion}"
msgstr ""
msgid "PackageRegistry|RubyGems"
-msgstr ""
+msgstr "RubyGems"
msgid "PackageRegistry|Settings for Generic packages"
msgstr ""
@@ -24906,9 +25267,6 @@ msgstr "ページãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25098,9 +25456,15 @@ msgstr ""
msgid "Pending"
msgstr "ä¿ç•™ä¸­"
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25200,6 +25564,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25281,12 +25648,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr "パイプラインクォータ(分)"
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25518,6 +25879,9 @@ msgstr "å­ãƒ‘イプライン"
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25737,9 +26101,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr "マージçµæžœãƒ‘イプライン"
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -25861,7 +26222,7 @@ msgid "Plan"
msgstr ""
msgid "Plan:"
-msgstr ""
+msgstr "プラン:"
msgid "PlantUML"
msgstr "PlantUML"
@@ -26016,6 +26377,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr "é¸æŠžã—ã¦ãã ã•ã„"
@@ -26028,6 +26395,9 @@ msgstr "国をé¸æŠžã—ã¦ãã ã•ã„"
msgid "Please select a file"
msgstr "ファイルをé¸æŠžã—ã¦ãã ã•ã„"
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr "グループをé¸æŠžã—ã¦ä¸‹ã•ã„。"
@@ -26223,9 +26593,6 @@ msgstr "時間設定"
msgid "Preferences|Use relative times"
msgstr "相対時間を使用"
-msgid "Press %{key}-C to copy"
-msgstr "%{key} + C を押ã—ã¦ã‚³ãƒ”ーã™ã‚‹"
-
msgid "Prev"
msgstr ""
@@ -26577,6 +26944,9 @@ msgstr "パスワードãŒæ­£ã—ãã‚ã‚Šã¾ã›ã‚“"
msgid "Profiles|Invalid username"
msgstr "ユーザーåãŒæ­£ã—ãã‚ã‚Šã¾ã›ã‚“"
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr "キー"
@@ -26634,6 +27004,12 @@ msgstr "éžå…¬é–‹ã®è²¢çŒ®"
msgid "Profiles|Profile was successfully updated"
msgstr "ã‚ãªãŸã®ãƒ—ロファイルを正常ã«æ›´æ–°ã§ãã¾ã—ãŸã€‚"
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26718,6 +27094,9 @@ msgstr "ユーザーåã¯æ­£å¸¸ã«å¤‰æ›´ã•ã‚Œã¾ã—ãŸ"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr "åå‰ã«çµµæ–‡å­—を使ã†ã®ã¯æ¥½ã—ãã†ã§ã™ãŒã€ä»£ã‚ã‚Šã«ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’設定ã—ã¦ã¿ã¦ãã ã•ã„"
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr "ã‚ãªãŸã¯ã©ã‚“ãªã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã§ã™ã‹ï¼Ÿ"
@@ -26995,7 +27374,7 @@ msgid "ProjectOverview|Starrers"
msgstr ""
msgid "ProjectOverview|Unstar"
-msgstr "ãŠæ°—ã«ã„ã‚Šã‹ã‚‰å¤–ã™"
+msgstr "スターを外ã™"
msgid "ProjectOverview|You don't have permission to fork this project"
msgstr ""
@@ -27012,6 +27391,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr "プロジェクトID: %{project_id}"
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr "ã¾ãŸã¯ã‚°ãƒ«ãƒ¼ãƒ—"
@@ -27138,6 +27559,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27390,19 +27814,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27558,6 +27979,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr "iOS (Swift)"
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr "プロジェクト"
@@ -27664,7 +28094,7 @@ msgid "ProjectsNew|Create from template"
msgstr "テンプレートã‹ã‚‰ä½œæˆ"
msgid "ProjectsNew|Create new project"
-msgstr ""
+msgstr "æ–°ã—ã„プロジェクトを作æˆ"
msgid "ProjectsNew|Description format"
msgstr "説明フォーマット"
@@ -27942,9 +28372,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr "ã“ã®æ©Ÿèƒ½ã¯ãƒ­ãƒƒã‚¯ã•ã‚Œã¦ã„ã¾ã™ã€‚"
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr "貢献度分æžã§ã‚¢ã‚¯ãƒ†ã‚£ãƒ“ティーを追跡ã™ã‚‹ã€‚"
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27957,9 +28384,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr "プランをアップグレードã—ã¦è²¢çŒ®åº¦åˆ†æžã‚’有効化ã™ã‚‹ã€‚"
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -27984,9 +28408,6 @@ msgstr "イシューã«ã‚¦ã‚§ã‚¤ãƒˆã‚’付ã‘ã‚‹"
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr "多ãã®ã‚¤ã‚·ãƒ¥ãƒ¼ãŒã‚ã‚‹å ´åˆã€å…¨ä½“を把æ¡ã™ã‚‹ã®ã¯å›°é›£ã§ã™ã€‚ イシューã«ã‚¦ã‚§ã‚¤ãƒˆã‚’付ã‘ã‚‹ã“ã¨ã§ã€ãã‚Œãžã‚Œã®åŠ´åŠ›ã€ã‚³ã‚¹ãƒˆã€å¿…è¦ãªæ™‚é–“ã€ã¾ãŸã¯ä¾¡å€¤ã‚’よりよã把æ¡ã§ãã€ãれらをよりé©åˆ‡ã«ç®¡ç†ã§ãã¾ã™ã€‚"
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr "貢献度分æžã‚’使用ã™ã‚‹ã¨ã€çµ„ç¹”ã¨ãã®ãƒ¡ãƒ³ãƒãƒ¼ã®ã‚¤ã‚·ãƒ¥ãƒ¼ã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã€ãƒ—ッシュイベントã®æ´»å‹•ã®æ¦‚è¦ã‚’知るã“ã¨ãŒã§ãã¾ã™ã€‚"
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28068,6 +28489,9 @@ msgstr "プッシュを許å¯:"
msgid "ProtectedBranch|Branch"
msgstr "ブランãƒ"
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28113,9 +28537,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr "コード所有者ã®æ‰¿èªã®åˆ‡ã‚Šæ›¿ãˆ"
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr "%{environment_name} ã¯é–‹ç™ºè€…権é™ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒæ›¸ãè¾¼ã¿å¯èƒ½ã«ãªã‚Šã¾ã™ã€‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
@@ -28158,6 +28588,9 @@ msgstr "ã‚ãªãŸã®ç’°å¢ƒã¯ä¿è­·ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "ã‚ãªãŸã®ç’°å¢ƒã¯ä¿è­·ã•ã‚Œã¦ã„ã¾ã›ã‚“。ã¾ãŸã¯ä¿è­·ãŒè§£é™¤ã•ã‚Œã¦ã„ã¾ã™ã€‚"
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28173,6 +28606,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28401,6 +28837,12 @@ msgstr "クイックレンジ"
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr "README"
@@ -28549,7 +28991,7 @@ msgid "Redirecting"
msgstr ""
msgid "Redis"
-msgstr ""
+msgstr "Redis"
msgid "Reduce incident management alert volume (for example, if too many issues are being created)."
msgstr ""
@@ -28585,9 +29027,6 @@ msgstr "エクスãƒãƒ¼ãƒˆã‚’å†ç”Ÿæˆ"
msgid "Regenerate instance ID"
msgstr "インスタンスIDã‚’å†ç”Ÿæˆ"
-msgid "Regenerate key"
-msgstr "éµã‚’å†ç”Ÿæˆã™ã‚‹"
-
msgid "Regenerate recovery codes"
msgstr "リカãƒãƒªãƒ¼ã‚³ãƒ¼ãƒ‰ã®å†ç™ºè¡Œ"
@@ -28630,6 +29069,54 @@ msgstr "2è¦ç´ èªè¨¼ã‚¢ãƒ—リã§ç™»éŒ²"
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -28955,10 +29442,10 @@ msgstr "見ç©æ™‚間を削除ã—ã¾ã—ãŸã€‚"
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29245,7 +29732,7 @@ msgid "RepositoriesAnalytics|Download historic test coverage data (.csv)"
msgstr ""
msgid "RepositoriesAnalytics|Download test coverage data (.csv)"
-msgstr ""
+msgstr "テストカãƒãƒ¬ãƒƒã‚¸ãƒ‡ãƒ¼ã‚¿ã‚’CSVå½¢å¼ã§ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰"
msgid "RepositoriesAnalytics|Historic Test Coverage Data is available in raw format (.csv) for further analysis."
msgstr ""
@@ -29278,7 +29765,7 @@ msgid "RepositoriesAnalytics|Projects with Coverage: %{projectCount}"
msgstr ""
msgid "RepositoriesAnalytics|Test Code Coverage"
-msgstr ""
+msgstr "テストコードカãƒãƒ¬ãƒƒã‚¸"
msgid "RepositoriesAnalytics|There was an error fetching the projects."
msgstr ""
@@ -29636,6 +30123,9 @@ msgstr "å†é–‹"
msgid "Resync"
msgstr "å†åŒæœŸ"
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr "å†è©¦è¡Œ"
@@ -29645,6 +30135,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr "ジョブをå†è©¦è¡Œã—ã¦ãã ã•ã„"
@@ -29839,9 +30335,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -29863,6 +30356,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -29914,19 +30413,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -29980,6 +30482,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30025,6 +30530,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30034,7 +30542,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30103,7 +30614,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30121,6 +30632,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr "稼åƒä¸­"
@@ -30323,7 +30837,7 @@ msgid "Search Jira issues"
msgstr ""
msgid "Search a group"
-msgstr ""
+msgstr "グループã®æ¤œç´¢"
msgid "Search an environment spec"
msgstr "環境スペックを検索"
@@ -30382,6 +30896,9 @@ msgstr "ã“ã®ãƒ†ã‚­ã‚¹ãƒˆã‚’検索"
msgid "Search forks"
msgstr "フォークを検索ã™ã‚‹"
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30403,9 +30920,6 @@ msgstr "çµæžœã‚’検索ã¾ãŸã¯ãƒ•ã‚£ãƒ«ã‚¿ã™ã‚‹..."
msgid "Search or filter results…"
msgstr "çµæžœã‚’検索ã¾ãŸã¯ãƒ•ã‚£ãƒ«ã‚¿ã™ã‚‹..."
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr "プロジェクトを検索"
@@ -30675,6 +31189,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr "有効"
@@ -30747,6 +31264,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -30801,6 +31321,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -30885,9 +31408,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31086,6 +31606,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31098,6 +31621,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31173,6 +31699,9 @@ msgstr "ã“ã®ãƒ¬ãƒãƒ¼ãƒˆã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹æ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“"
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr "ã“ã®ãƒ¬ãƒãƒ¼ãƒˆã‚’表示ã™ã‚‹ã«ã¯ã€æ‰¿èªã•ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ã¨ã—ã¦ã‚µã‚¤ãƒ³ã‚¤ãƒ³ã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。"
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31231,7 +31760,7 @@ msgid "Select a label"
msgstr "ラベルをé¸æŠž"
msgid "Select a milestone"
-msgstr ""
+msgstr "マイルストーンをé¸æŠž"
msgid "Select a new namespace"
msgstr "æ–°ã—ã„åå‰ç©ºé–“ã‚’é¸æŠž"
@@ -31326,6 +31855,9 @@ msgstr "マシンタイプをé¸æŠžã™ã‚‹ãŸã‚ã«ã€ãƒ—ロジェクトã¨ã‚¾ãƒ¼
msgid "Select project to choose zone"
msgstr "プロジェクトをé¸æŠžã—ã¦ã‚¾ãƒ¼ãƒ³ã‚’é¸æŠž"
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31450,7 +31982,7 @@ msgid "Send emails to users upon account deactivation."
msgstr ""
msgid "Send message"
-msgstr ""
+msgstr "メッセージé€ä¿¡"
msgid "Send notifications about project events to Mattermost channels."
msgstr ""
@@ -31677,6 +32209,12 @@ msgstr "デフォルトを設定ã—ã€å¯è¦–性レベルを制é™ã—ã¾ã™ã€‚イ
msgid "Set due date"
msgstr "期é™ã®è¨­å®š"
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr "イテレーションを設定"
@@ -31833,6 +32371,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr "%{epic_ref} を親エピックã¨ã—ã¦è¨­å®šã—ã¾ã™ 。"
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr "ターゲットブランãƒã‚’ %{branch_name} ã«è¨­å®šã€‚"
@@ -32529,6 +33070,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr "担当者ã®æ›´æ–°ä¸­ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr "リスト設定を更新ã™ã‚‹é–“ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸ"
@@ -32973,9 +33517,6 @@ msgstr ""
msgid "Start your free trial"
msgstr "無料トライアルを開始"
-msgid "Start your trial"
-msgstr "試用を開始"
-
msgid "Started"
msgstr "開始済ã¿"
@@ -33372,6 +33913,12 @@ msgstr "サブスクリプションã®ä½œæˆã«æˆåŠŸã—ã¾ã—ãŸã€‚"
msgid "Subscription successfully deleted."
msgstr "サブスクリプションã®å‰Šé™¤ã«æˆåŠŸã—ã¾ã—ãŸã€‚"
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -33807,6 +34354,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr "システム"
@@ -34073,9 +34638,23 @@ msgid "Terraform|%{number} Terraform report was generated in your pipelines"
msgid_plural "Terraform|%{number} Terraform reports were generated in your pipelines"
msgstr[0] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34106,6 +34685,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34118,6 +34700,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34154,12 +34739,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34442,6 +35036,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "コãƒã‚¯ã‚·ãƒ§ãƒ³ã¯ %{timeout} ã§ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã™ã€‚タイムアウトã™ã‚‹ãƒªãƒã‚¸ãƒˆãƒªã§ã¯ã€clone/push を組ã¿åˆã‚ã›ã¦ä½¿ç”¨ã—ã¦ãã ã•ã„。"
@@ -34563,9 +35160,6 @@ msgstr "グループãŠã‚ˆã³å…¬é–‹ãƒ—ロジェクトã¯èªè¨¼ç„¡ã—ã§é–²è¦§ã™
msgid "The group and its projects can only be viewed by members."
msgstr "グループã¨ãã®ãƒ—ロジェクトã¯ãƒ¡ãƒ³ãƒãƒ¼ã®ã¿ãŒé–²è¦§ã§ãã¾ã™"
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34575,9 +35169,6 @@ msgstr "対象ã®ã‚°ãƒ«ãƒ¼ãƒ—ã¯æ—¢ã«ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã¨å…±æœ‰ã•ã‚Œã¦ã„ã¾
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr "%{group_links} ã®ã‚°ãƒ«ãƒ¼ãƒ—設定ã§ã¯ã€ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«å¯¾ã—ã¦2è¦ç´ èªè¨¼ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚ ã‚ãªãŸã¯%{leave_group_links} ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34650,7 +35241,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -34905,9 +35496,6 @@ msgstr "表示ã™ã‚‹ã‚¤ã‚·ãƒ¥ãƒ¼ãŒã‚ã‚Šã¾ã›ã‚“"
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr "ã¾ã ãƒ©ãƒ™ãƒ«ãŒã‚ã‚Šã¾ã›ã‚“"
-
msgid "There are no matching files"
msgstr "一致ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ãŒã‚ã‚Šã¾ã›ã‚“。"
@@ -35253,6 +35841,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35265,9 +35856,6 @@ msgstr "ã“ã®å‹•ä½œã«ã‚ˆã£ã¦ãƒ‡ãƒ¼ã‚¿ãŒå¤±ã‚れるå¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35292,6 +35880,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr "ã“ã®ã‚¢ãƒ—リケーションã¯æ¬¡ã®ã“ã¨ãŒã§ãã¾ã™:"
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35406,6 +35997,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35571,6 +36165,9 @@ msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã¯æ‰‹å‹•ã«ã‚ˆã‚‹å®Ÿè¡Œã‚’求ã‚ã¦ã„ã¾ã™"
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr "ã“ã®ã‚¸ãƒ§ãƒ–を開始ã™ã‚‹ã«ã¯ã€æ‰‹å‹•ã«ã‚ˆã‚‹ä»‹å…¥ãŒå¿…è¦ã§ã™ã€‚ ã“ã®ã‚¸ãƒ§ãƒ–を開始ã™ã‚‹å‰ã«ã€ç›´å‰ã®æ§‹æˆå¤‰æ›´ã®ãŸã‚ã«ä»¥ä¸‹ã®å¤‰æ•°ã‚’追加ã§ãã¾ã™ã€‚"
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã¯ã‚¿ã‚¤ãƒžãƒ¼çµ‚了後ã«è‡ªå‹•çš„ã«å®Ÿè¡Œã•ã‚Œã¾ã™ã€‚多ãã®å ´åˆæœ¬ç•ªç’°å¢ƒã¸ã®æ®µéšŽçš„ãªãƒ­ãƒ¼ãƒ«ã‚¢ã‚¦ãƒˆãƒ‡ãƒ—ロイã«ä½¿ç”¨ã•ã‚Œã¾ã™ã€‚スケジュールã•ã‚Œã¦ã„ãªã„ã¨ãã¯æ‰‹å‹•ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã«å¤‰æ›ã•ã‚Œã¾ã™ã€‚"
@@ -36281,6 +36878,9 @@ 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 "手動ã§è¨­å®šã•ã‚ŒãŸPrometheus サービスã‹ã‚‰ã‚¢ãƒ©ãƒ¼ãƒˆã‚’å—ä¿¡ã™ã‚‹ã«ã¯ã€æ¬¡ã®URLã¨èªè¨¼ã‚­ãƒ¼ã‚’ Prometheus webhook ã®è¨­å®šãƒ•ã‚¡ã‚¤ãƒ«ã«è¿½åŠ ã—ã¦ãã ã•ã„。GitLab ã«ã‚¢ãƒ©ãƒ¼ãƒˆã‚’é€ä¿¡ã™ã‚‹ãŸã‚ã® %{linkEnd} Prometheusã®è¨­å®š %{linkStart} ã®è©³ç´°ã‚’ã”覧ãã ã•ã„。"
+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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36347,6 +36947,39 @@ msgstr "Todo ã‚’ 完了ã¨ãƒžãƒ¼ã‚¯ã—ã¾ã—ãŸã€‚"
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36521,6 +37154,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36642,15 +37278,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36675,9 +37302,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr "トリガー"
@@ -37305,9 +37929,6 @@ msgstr "クリックã—ã¦ã‚¢ãƒƒãƒ—ロード"
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr "Upstream"
@@ -38199,16 +38820,16 @@ msgstr ""
msgid "Verification status"
msgstr "検証ステータス"
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38250,6 +38871,9 @@ msgstr ""
msgid "View all issues"
msgstr "ã™ã¹ã¦ã®ã‚¤ã‚·ãƒ¥ãƒ¼ã‚’表示"
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr "ã“ã®å¤‰æ›´å‰ã® blame を表示"
@@ -38272,6 +38896,9 @@ msgstr "詳細を見る: %{details_url}"
msgid "View documentation"
msgstr "ドキュメントã®è¡¨ç¤º"
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr "資格ã®ã‚る承èªè€…を表示"
@@ -38300,6 +38927,12 @@ msgstr ""
msgid "View group labels"
msgstr "グループラベルを表示"
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38391,6 +39024,9 @@ msgstr ""
msgid "Viewing commit"
msgstr "コミットを表示中"
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr "公開範囲"
@@ -38472,12 +39108,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38505,6 +39153,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38574,9 +39225,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr "クラス"
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38592,21 +39252,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr "説明"
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr "ファイル"
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38616,6 +39288,9 @@ msgstr "識別å­"
msgid "Vulnerability|Image"
msgstr "イメージ"
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr "リンク"
@@ -38640,6 +39315,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr "スキャナープロãƒã‚¤ãƒ€ãƒ¼"
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr "é‡è¦åº¦"
@@ -38763,6 +39447,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr "脆弱性ã¯ç™ºè¦‹ã•ã‚Œã¾ã›ã‚“ã§ã—ãŸ"
@@ -38850,6 +39537,12 @@ msgstr "デプロイイベント"
msgid "Webhooks|Enable SSL verification"
msgstr "SSL証明書検証ã®æœ‰åŠ¹åŒ–"
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -38886,6 +39579,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr "タグプッシュイベント"
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr "トリガー"
@@ -38943,6 +39645,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -38971,7 +39682,7 @@ msgid "Welcome to GitLab"
msgstr "GitLab ã¸ã‚ˆã†ã“ã"
msgid "Welcome to GitLab, %{first_name}!"
-msgstr ""
+msgstr "%{first_name} ã•ã‚“ã€GitLab ã¸ã‚ˆã†ã“ãï¼"
msgid "Welcome to GitLab,%{br_tag}%{name}!"
msgstr ""
@@ -38979,6 +39690,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -38988,9 +39702,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr "何を探ã—ã¾ã™ã‹?"
@@ -39824,6 +40535,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr "権é™ãŒã‚ã‚Šã¾ã›ã‚“"
@@ -40013,6 +40730,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40304,6 +41027,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40541,6 +41267,9 @@ msgstr "ãれ自体をブロックã§ãã¾ã›ã‚“"
msgid "cannot merge"
msgstr "マージã§ãã¾ã›ã‚“"
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40571,7 +41300,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40619,8 +41348,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgid "ciReport|Browser performance test metrics: No changes"
@@ -40713,8 +41442,8 @@ msgstr "イシューを作æˆã—ã¦ã€ã“ã®è„†å¼±æ€§ã‚’調査ã—ã¾ã™"
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgid "ciReport|Load performance test metrics results are being parsed"
@@ -40874,6 +41603,9 @@ msgstr "コミット %{commit_id}"
msgid "committed"
msgstr "コミット済ã¿"
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41000,7 +41732,7 @@ msgid "environment_id parameter is required when type is container_policy"
msgstr ""
msgid "epic"
-msgstr ""
+msgstr "エピック"
msgid "error"
msgstr "エラー"
@@ -41312,9 +42044,6 @@ msgstr "metric_id ã¯ãƒ—ロジェクト全体ã§ä¸€æ„ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã
msgid "missing"
msgstr "見ã¤ã‹ã‚Šã¾ã›ã‚“"
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr "最新ã®ãƒ‡ãƒ—ロイ"
@@ -41668,6 +42397,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -41767,9 +42499,6 @@ msgstr "%{timeAgo}ã«ã‚ªãƒ¼ãƒ—ン"
msgid "or"
msgstr "ã¾ãŸã¯"
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/ka_GE/gitlab.po b/locale/ka_GE/gitlab.po
index a749e37c803..df58416397a 100644
--- a/locale/ka_GE/gitlab.po
+++ b/locale/ka_GE/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ka\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:58\n"
+"PO-Revision-Date: 2022-01-06 17:23\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/kab/gitlab.po b/locale/kab/gitlab.po
index 6fe12248f54..f650053d008 100644
--- a/locale/kab/gitlab.po
+++ b/locale/kab/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: kab\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 19:00\n"
+"PO-Revision-Date: 2022-01-06 17:25\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/ko/gitlab.po b/locale/ko/gitlab.po
index f06c5745fd4..0e77ef6cc52 100644
--- a/locale/ko/gitlab.po
+++ b/locale/ko/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ko\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:58\n"
+"PO-Revision-Date: 2022-01-06 17:23\n"
msgid " %{start} to %{end}"
msgstr " %{start}부터 %{end}까지"
@@ -29,13 +29,13 @@ msgid " Please sign in."
msgstr " ë¡œê·¸ì¸ í•´ì£¼ì„¸ìš”."
msgid " Target Path"
-msgstr ""
+msgstr " 타겟 경로"
msgid " Try to %{action} this file again."
msgstr " ì´ íŒŒì¼ì— 대해 %{action} ë™ìž‘ì„ ë‹¤ì‹œ ì‹œë„하세요."
msgid " Type"
-msgstr ""
+msgstr " 유형"
msgid " You need to do this before %{grace_period_deadline}."
msgstr " %{grace_period_deadline} ì´ì „ì— ì´ ìž‘ì—…ì„ ìˆ˜í–‰ 하셔야 합니다."
@@ -62,7 +62,7 @@ msgid " or references (e.g. path/to/project!merge_request_id)"
msgstr " ë˜ëŠ” 참조 (예: path/to/project!merge_request_id)"
msgid " reacted with :%{name}:"
-msgstr ""
+msgstr " :%{name}: ë¡œ ë°˜ì‘했습니다."
msgid "\"%{path}\" did not exist on \"%{ref}\""
msgstr "\"%{path}\"는 \"%{ref}\"ì— ì¡´ìž¬í•˜ì§€ 않습니다"
@@ -78,7 +78,7 @@ msgstr ""
msgid "%d Alert"
msgid_plural "%d Alerts"
-msgstr[0] ""
+msgstr[0] "%dê±´ì˜ ê²½ê³ "
msgid "%d Alert:"
msgid_plural "%d Alerts:"
@@ -86,7 +86,7 @@ msgstr[0] ""
msgid "%d Approval"
msgid_plural "%d Approvals"
-msgstr[0] ""
+msgstr[0] "%dê±´ì˜ ìŠ¹ì¸"
msgid "%d Module"
msgid_plural "%d Modules"
@@ -94,7 +94,7 @@ msgstr[0] ""
msgid "%d Other"
msgid_plural "%d Others"
-msgstr[0] ""
+msgstr[0] "ì´ì™¸ %d ê±´"
msgid "%d Package"
msgid_plural "%d Packages"
@@ -102,7 +102,7 @@ msgstr[0] ""
msgid "%d Scanned URL"
msgid_plural "%d Scanned URLs"
-msgstr[0] ""
+msgstr[0] "%dê°œì˜ ìŠ¤ìº”ëœ URL"
msgid "%d URL scanned"
msgid_plural "%d URLs scanned"
@@ -110,11 +110,11 @@ msgstr[0] "%dê°œì˜ URL 검사ë¨"
msgid "%d approver"
msgid_plural "%d approvers"
-msgstr[0] ""
+msgstr[0] "%dëª…ì˜ ìŠ¹ì¸ìž"
msgid "%d approver (you've approved)"
msgid_plural "%d approvers (you've approved)"
-msgstr[0] ""
+msgstr[0] "%dëª…ì˜ ìŠ¹ì¸ìž (ë‚´ê°€ 승ì¸í•¨)"
msgid "%d changed file"
msgid_plural "%d changed files"
@@ -122,15 +122,15 @@ msgstr[0] "%dê°œì˜ ë³€ê²½ëœ íŒŒì¼"
msgid "%d character remaining"
msgid_plural "%d characters remaining"
-msgstr[0] ""
+msgstr[0] "%dê¸€ìž ë‚¨ìŒ"
msgid "%d child epic"
msgid_plural "%d child epics"
-msgstr[0] ""
+msgstr[0] "%d 하위 ì—픽"
msgid "%d code quality issue"
msgid_plural "%d code quality issues"
-msgstr[0] ""
+msgstr[0] "%dê°œì˜ ì½”ë“œ 품질 문제"
msgid "%d comment"
msgid_plural "%d comments"
@@ -138,11 +138,11 @@ msgstr[0] "%dê°œì˜ ëŒ“ê¸€"
msgid "%d comment on this commit"
msgid_plural "%d comments on this commit"
-msgstr[0] ""
+msgstr[0] "ì´ ì»¤ë°‹ì— ëŒ€í•œ %dê°œì˜ ëŒ“ê¸€"
msgid "%d commenter"
msgid_plural "%d commenters"
-msgstr[0] ""
+msgstr[0] "%dëª…ì˜ ëŒ“ê¸€ 작성ìž"
msgid "%d commit"
msgid_plural "%d commits"
@@ -150,7 +150,7 @@ msgstr[0] "%dê°œì˜ ì»¤ë°‹"
msgid "%d commit author"
msgid_plural "%d commit authors"
-msgstr[0] ""
+msgstr[0] "%dëª…ì˜ ì»¤ë°‹ 작성ìž"
msgid "%d commit behind"
msgid_plural "%d commits behind"
@@ -162,7 +162,7 @@ msgstr[0] "%dê°œì˜ ì»¤ë°‹,"
msgid "%d completed issue"
msgid_plural "%d completed issues"
-msgstr[0] ""
+msgstr[0] "%dê±´ì˜ ì™„ë£Œëœ ì´ìŠˆ"
msgid "%d contribution"
msgid_plural "%d contributions"
@@ -174,7 +174,7 @@ msgstr[0] "%dì¼"
msgid "%d epic"
msgid_plural "%d epics"
-msgstr[0] ""
+msgstr[0] "%dê°œì˜ ì—픽"
msgid "%d error"
msgid_plural "%d errors"
@@ -182,7 +182,7 @@ msgstr[0] "%dê°œì˜ ì˜¤ë¥˜"
msgid "%d error found:"
msgid_plural "%d errors found:"
-msgstr[0] ""
+msgstr[0] "%d ê±´ì˜ ì˜¤ë¥˜ë¥¼ 발견했습니다:"
msgid "%d exporter"
msgid_plural "%d exporters"
@@ -194,11 +194,11 @@ msgstr[0] "%dê°œì˜ ì‹¤íŒ¨"
msgid "%d failed security job"
msgid_plural "%d failed security jobs"
-msgstr[0] ""
+msgstr[0] "실패한 보안 작업 %d 개"
msgid "%d file"
msgid_plural "%d files"
-msgstr[0] ""
+msgstr[0] "%dê°œì˜ íŒŒì¼"
msgid "%d fixed test result"
msgid_plural "%d fixed test results"
@@ -206,11 +206,11 @@ msgstr[0] "%dê±´ì˜ í…ŒìŠ¤íŠ¸ 결과를 고쳤습니다."
msgid "%d fork"
msgid_plural "%d forks"
-msgstr[0] ""
+msgstr[0] "%d번 í¬í¬ ë¨"
msgid "%d group"
msgid_plural "%d groups"
-msgstr[0] ""
+msgstr[0] "%dê°œì˜ ê·¸ë£¹"
msgid "%d group selected"
msgid_plural "%d groups selected"
@@ -230,11 +230,11 @@ msgstr[0] "%d ì´ìŠˆ"
msgid "%d issue in this group"
msgid_plural "%d issues in this group"
-msgstr[0] ""
+msgstr[0] "ì´ ê·¸ë£¹ì˜ %dê°œì˜ ì´ìŠˆ"
msgid "%d issue successfully imported with the label"
msgid_plural "%d issues successfully imported with the label"
-msgstr[0] ""
+msgstr[0] "%dê±´ì˜ ì´ìŠˆë¥¼ ë¼ë²¨ì„ 통해 성공ì ìœ¼ë¡œ 가져왔습니다"
msgid "%d layer"
msgid_plural "%d layers"
@@ -250,7 +250,7 @@ msgstr[0] "%d 머지 ìš”ì²­ì„ í•  ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤."
msgid "%d merge requests"
msgid_plural "%d merge requests"
-msgstr[0] ""
+msgstr[0] "%dê°œì˜ ë¨¸ì§€ 리퀘스트(MR)"
msgid "%d metric"
msgid_plural "%d metrics"
@@ -270,11 +270,11 @@ msgstr[0] "%d 댓글 ë” ë³´ê¸°"
msgid "%d open issue"
msgid_plural "%d open issues"
-msgstr[0] ""
+msgstr[0] "%dê±´ì˜ ì—´ë¦° ì´ìŠˆ"
msgid "%d pending comment"
msgid_plural "%d pending comments"
-msgstr[0] ""
+msgstr[0] "%dê°œì˜ ëŒ€ê¸° ì¤‘ì¸ ëŒ“ê¸€"
msgid "%d personal project will be removed and cannot be restored."
msgid_plural "%d personal projects will be removed and cannot be restored."
@@ -282,7 +282,7 @@ msgstr[0] "%dê°œì˜ ê°œì¸ í”„ë¡œì íŠ¸ê°€ 제거ë˜ê³ , ë³µì›í•  수 없게 ë
msgid "%d previously merged commit"
msgid_plural "%d previously merged commits"
-msgstr[0] ""
+msgstr[0] "%dê°œì˜ ì´ì „ì— ë¨¸ì§€ëœ ì»¤ë°‹"
msgid "%d project"
msgid_plural "%d projects"
@@ -290,7 +290,7 @@ msgstr[0] "%d 프로ì íŠ¸"
msgid "%d project selected"
msgid_plural "%d projects selected"
-msgstr[0] ""
+msgstr[0] "%dê°œì˜ í”„ë¡œì íŠ¸ê°€ ì„ íƒë¨"
msgid "%d request with warnings"
msgid_plural "%d requests with warnings"
@@ -302,11 +302,11 @@ msgstr[0] "%d ì´ˆ"
msgid "%d shard selected"
msgid_plural "%d shards selected"
-msgstr[0] ""
+msgstr[0] "%dê°œì˜ ì¡°ê°ì´ ì„ íƒë¨"
msgid "%d star"
msgid_plural "%d stars"
-msgstr[0] ""
+msgstr[0] "%dê°œì˜ ìŠ¤íƒ€"
msgid "%d tag"
msgid_plural "%d tags"
@@ -314,11 +314,11 @@ msgstr[0] "%dê°œì˜ íƒœê·¸"
msgid "%d tag per image name"
msgid_plural "%d tags per image name"
-msgstr[0] ""
+msgstr[0] "ì´ë¯¸ì§€ ì´ë¦„ 당 %dê°œì˜ íƒœê·¸"
msgid "%d token has expired"
msgid_plural "%d tokens have expired"
-msgstr[0] ""
+msgstr[0] "%dê°œì˜ í† í°ì´ 만료ë˜ì—ˆìŠµë‹ˆë‹¤"
msgid "%d unassigned issue"
msgid_plural "%d unassigned issues"
@@ -326,7 +326,7 @@ msgstr[0] ""
msgid "%d unresolved thread"
msgid_plural "%d unresolved threads"
-msgstr[0] ""
+msgstr[0] "%dê°œì˜ í•´ê²°ë˜ì§€ ì•Šì€ ìŠ¤ë ˆë“œ"
msgid "%d vulnerability"
msgid_plural "%d vulnerabilities"
@@ -338,11 +338,11 @@ msgstr[0] "%dê°œì˜ ì·¨ì•½ì  ë¬´ì‹œë¨"
msgid "%d vulnerability updated"
msgid_plural "%d vulnerabilities updated"
-msgstr[0] ""
+msgstr[0] "%dê°œì˜ ì·¨ì•½ì ì´ ì—…ë°ì´íŠ¸ë¨"
msgid "%d warning found:"
msgid_plural "%d warnings found:"
-msgstr[0] ""
+msgstr[0] "%dê°œì˜ ê²½ê³  발견:"
msgid "%s additional commit has been omitted to prevent performance issues."
msgid_plural "%s additional commits have been omitted to prevent performance issues."
@@ -370,17 +370,17 @@ 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 "%{authorsName} ì˜ ìŠ¤ë ˆë“œ"
msgid "%{board_target} not found"
-msgstr ""
+msgstr "%{board_target} ì°¾ì„ ìˆ˜ ì—†ìŒ"
msgid "%{bold_start}%{count}%{bold_end} issue"
msgid_plural "%{bold_start}%{count}%{bold_end} issues"
-msgstr[0] ""
+msgstr[0] "%{bold_start}%{count}%{bold_end} ì´ìŠˆ"
msgid "%{bold_start}%{count}%{bold_end} member"
msgid_plural "%{bold_start}%{count}%{bold_end} members"
@@ -394,10 +394,10 @@ msgid "%{code_open}Masked:%{code_close} Hidden in job logs. Must match masking r
msgstr ""
msgid "%{code_open}Protected:%{code_close} Only exposed to protected branches or tags."
-msgstr ""
+msgstr "%{code_open}보호ëœ%{code_close} 정보는 ë³´í˜¸ëœ ë¸Œë Œì¹˜ë‚˜ 태그ì—만 보입니다."
msgid "%{commit_author_link} authored %{commit_authored_timeago}"
-msgstr ""
+msgstr "%{commit_authored_timeago} ì— %{commit_author_link} ë‹˜ì´ ì»¤ë°‹í–ˆìŠµë‹ˆë‹¤."
msgid "%{commit_author_link} authored %{commit_authored_timeago} and %{commit_committer_avatar} %{commit_committer_link} committed %{commit_committer_timeago}"
msgstr ""
@@ -437,7 +437,7 @@ msgstr "%{count} 파ì¼ì´ 변경ë˜ì—ˆìŠµë‹ˆë‹¤"
msgid "%{count} item"
msgid_plural "%{count} items"
-msgstr[0] ""
+msgstr[0] "%{count}ê°œì˜ í•­ëª©"
msgid "%{count} items per page"
msgstr ""
@@ -466,7 +466,7 @@ msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr "%{count} ê±´ê³¼ ê´€ë ¨ëœ %{pluralized_subject}: %{links}"
msgid "%{count} selected"
-msgstr ""
+msgstr "%{count}ê°œ ì„ íƒë¨"
msgid "%{count} total weight"
msgstr ""
@@ -486,7 +486,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
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; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -502,7 +502,7 @@ msgid "%{docs_link_start}What is two-factor authentication?%{docs_link_end}"
msgstr ""
msgid "%{due_date} (Past due)"
-msgstr ""
+msgstr "%{due_date} (기한 지남)"
msgid "%{duration}ms"
msgstr "%{duration}ms"
@@ -520,7 +520,7 @@ msgid "%{edit_in_new_fork_notice} Try to upload a file again."
msgstr "%{edit_in_new_fork_notice} 파ì¼ì„ 다시 업로드하십시오."
msgid "%{emailPrefix}@company.com"
-msgstr ""
+msgstr "%{emailPrefix}@company.com"
msgid "%{extra} more downstream pipelines"
msgstr ""
@@ -535,19 +535,19 @@ msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
msgstr "%{firstMilestoneName} + %{numberOfOtherMilestones}ê°œ ë” ìžˆìŒ"
msgid "%{gitlab_experience_text}. Don't worry, this information isn't shared outside of your self-managed GitLab instance."
-msgstr ""
+msgstr "%{gitlab_experience_text}. 걱정하지 마세요. ì´ ì •ë³´ëŠ” ì§ì ‘ 관리하는 깃랩 ì¸ìŠ¤í„´ìŠ¤ ì™¸ë¶€ì— ê³µìœ í•˜ì§€ 않습니다."
msgid "%{gitlab_experience_text}. We won't share this information with anyone."
-msgstr ""
+msgstr "%{gitlab_experience_text}. ì´ ì •ë³´ë¥¼ ëˆ„êµ¬ì™€ë„ ê³µìœ í•˜ì§€ ì•Šì„ ê²ƒìž…ë‹ˆë‹¤."
msgid "%{global_id} is not a valid ID for %{expected_types}."
-msgstr ""
+msgstr "%{global_id}ì€(는) %{expected_types}ì˜ ìœ íš¨í•œ IDê°€ 아닙니다."
msgid "%{group_name} activity"
-msgstr ""
+msgstr "%{group_name} 활ë™"
msgid "%{group_name} group members"
-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}ì€ ê·¸ë£¹ 관리 ê³„ì •ì„ ì‚¬ìš© 합니다. %{group_name}를 관리 í•  새 GitLab ê³„ì •ì„ ë§Œë“¤ì–´ì•¼ 합니다."
@@ -556,7 +556,7 @@ msgid "%{group_name}&%{epic_iid} &middot; created %{epic_created} by %{author}"
msgstr ""
msgid "%{hook_type} was deleted"
-msgstr ""
+msgstr "%{hook_type} ì‚­ì œë¨"
msgid "%{hook_type} was scheduled for deletion"
msgstr ""
@@ -571,7 +571,7 @@ msgid "%{issuableType} will be removed! Are you sure?"
msgstr "%{issuableType}ì´ ì‚­ì œë©ë‹ˆë‹¤! 확실합니까?"
msgid "%{issueType} actions"
-msgstr ""
+msgstr "%{issueType} ì•¡ì…˜"
msgid "%{issuesSize} with a limit of %{maxIssueCount}"
msgstr ""
@@ -589,7 +589,7 @@ msgid "%{labelStart}Assert:%{labelEnd} %{assertion}"
msgstr ""
msgid "%{labelStart}Class:%{labelEnd} %{class}"
-msgstr ""
+msgstr "%{labelStart}í´ëž˜ìŠ¤:%{labelEnd} %{class}"
msgid "%{labelStart}Crash Address:%{labelEnd} %{crash_address}"
msgstr ""
@@ -601,25 +601,25 @@ msgid "%{labelStart}Evidence:%{labelEnd} %{evidence}"
msgstr ""
msgid "%{labelStart}File:%{labelEnd} %{file}"
-msgstr ""
+msgstr "%{labelStart}íŒŒì¼ :%{labelEnd} %{file}"
msgid "%{labelStart}Image:%{labelEnd} %{image}"
-msgstr ""
+msgstr "%{labelStart}ì´ë¯¸ì§€ :%{labelEnd} %{image}"
msgid "%{labelStart}Method:%{labelEnd} %{method}"
-msgstr ""
+msgstr "%{labelStart}메소드:%{labelEnd} %{method}"
msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
-msgstr ""
+msgstr "%{labelStart}네임 스페ì´ìŠ¤ :%{labelEnd} %{namespace}"
msgid "%{labelStart}Scanner:%{labelEnd} %{scanner}"
-msgstr ""
+msgstr "%{labelStart}스ìºë„ˆ:%{labelEnd} %{scanner}"
msgid "%{labelStart}Sent request:%{labelEnd} %{headers}"
msgstr ""
msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
-msgstr ""
+msgstr "%{labelStart}심ê°ì„±:%{labelEnd} %{severity}"
msgid "%{labelStart}Tool:%{labelEnd} %{reportType}"
msgstr ""
@@ -631,13 +631,13 @@ msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} 사용할 수 ì—†ìŒ"
msgid "%{learn_more_link}."
-msgstr ""
+msgstr "%{learn_more_link}."
msgid "%{lessThan} 1 hour"
-msgstr ""
+msgstr "%{lessThan} 1시간"
msgid "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} is a free, automated, and open certificate authority (CA) that issues digital certificates to enable HTTPS (SSL/TLS) for sites."
-msgstr ""
+msgstr "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end}는 웹사ì´íŠ¸ì— HTTPS (SSL/TLS) ì—°ê²°ìš© 디지털 ì¸ì¦ì„œë¥¼ 제공하는 무료, ìžë™í™”, 개방형 ì¸ì¦ 기관(CA)입니다."
msgid "%{level_name} is not allowed in a %{group_level_name} group."
msgstr "%{group_level_name} 그룹ì—는 %{level_name} ì´ í—ˆìš©ë˜ì§€ 않습니다."
@@ -646,7 +646,7 @@ msgid "%{level_name} is not allowed since the fork source project has lower visi
msgstr "Forkí•œ ì›ë³¸ 프로ì íŠ¸ê°€ ë” ë‚®ì€ ê³µê°œ 수준으로 설정ë˜ì–´ 있으므로 %{level_name} ìˆ˜ì¤€ì´ í—ˆìš©ë˜ì§€ 않습니다."
msgid "%{link_start}Learn more%{link_end} about roles."
-msgstr ""
+msgstr "ì—­í• ì— ëŒ€í•´ %{link_start}ìžì„¸ížˆ 알아보기%{link_end}."
msgid "%{link_start}Remove the %{draft_snippet} prefix%{link_end} from the title to allow this merge request to be merged when it's ready."
msgstr ""
@@ -661,19 +661,19 @@ msgid "%{listToShow}, and %{awardsListLength} more"
msgstr ""
msgid "%{location} is missing required keys: %{keys}"
-msgstr ""
+msgstr "%{location}ì— í•„ìˆ˜ 키가 없습니다: %{keys}"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} 경로는 GitLab User %{lock_user_id} ì— ì˜í•´ 잠겼습니다."
msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
-msgstr ""
+msgstr "%{markdownDocsLinkStart}마í¬ë‹¤ìš´%{markdownDocsLinkEnd}ê³¼ %{quickActionsDocsLinkStart}빠른 ì•¡ì…˜%{quickActionsDocsLinkEnd}ì´ ì§€ì›ë©ë‹ˆë‹¤."
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr "%{mergeLength}/%{usersLength} 머지 가능"
msgid "%{message} showing first %{warnings_displayed}"
-msgstr ""
+msgstr "%{message} 첫 번째 %{warnings_displayed} 보기"
msgid "%{milestone} (expired)"
msgstr ""
@@ -694,7 +694,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 "%{name} í¬í•¨ë¨ %{resultsString}"
@@ -715,7 +715,7 @@ msgid "%{name}'s avatar"
msgstr "%{name} ì˜ ì•„ë°”íƒ€"
msgid "%{name}(%{url}) namespace has %{percent} or less Shared Runner Pipeline minutes remaining. After it runs out, no new jobs or pipelines in its projects will run."
-msgstr ""
+msgstr "%{name}(%{url}) 네임스페ì´ìŠ¤ì— ë‚¨ì€ ê³µìœ  러너 파ì´í”„ë¼ì¸ 시간(분)ì´ %{percent} ì´í•˜ìž…니다. 소진ë˜ë©´ 프로ì íŠ¸ì˜ 새 ìž‘ì—…ì´ë‚˜ 파ì´í”„ë¼ì¸ì´ 실행ë˜ì§€ 않습니다."
msgid "%{name}(%{url}) namespace has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
msgstr ""
@@ -760,6 +760,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr "%{primary}(%{secondary})"
@@ -777,7 +780,7 @@ msgid "%{remaining_approvals} left"
msgstr ""
msgid "%{reportType} %{status}"
-msgstr ""
+msgstr "%{reportType} %{status}"
msgid "%{reportType} detected %{totalStart}%{total}%{totalEnd} potential %{vulnMessage}"
msgstr ""
@@ -801,7 +804,7 @@ msgid "%{search} %{description} %{scope}"
msgstr ""
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}"
@@ -815,7 +818,7 @@ 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 "%{size} GiB"
@@ -830,7 +833,7 @@ msgid "%{size} bytes"
msgstr "%{size} bytes"
msgid "%{sourceBranch} into %{targetBranch}"
-msgstr ""
+msgstr "%{sourceBranch} ì—ì„œ %{targetBranch}"
msgid "%{spammable_titlecase} was submitted to Akismet successfully."
msgstr "%{spammable_titlecase} (ì´)ê°€ Akismetì— ì„±ê³µì ìœ¼ë¡œ 제출ë˜ì—ˆìŠµë‹ˆë‹¤."
@@ -845,7 +848,7 @@ msgid "%{start} to %{end}"
msgstr "%{start}부터 %{end}까지"
msgid "%{strongOpen}Warning:%{strongClose} SAML group links can cause GitLab to automatically remove members from groups."
-msgstr ""
+msgstr "%{strongOpen}경고:%{strongClose} SAML 그룹 ë§í¬ë¡œ ì¸í•´ GitLabì´ ê·¸ë£¹ì—ì„œ 구성ì›ì„ ìžë™ìœ¼ë¡œ 제거할 수 있습니다."
msgid "%{strongStart}Tip:%{strongEnd} You can also checkout merge requests locally by %{linkStart}following these guidelines%{linkEnd}"
msgstr ""
@@ -894,7 +897,7 @@ msgid "%{tags} tags per image name"
msgstr "ê° ì´ë¯¸ì§€ ì´ë¦„마다 %{tags} 태그"
msgid "%{tag}-%{evidence}-%{filename}"
-msgstr ""
+msgstr "%{tag}-%{evidence}-%{filename}"
msgid "%{template_project_id} is unknown or invalid"
msgstr "%{template_project_id}(ì€)는 ì•Œ 수 없거나 잘못ë˜ì—ˆìŠµë‹ˆë‹¤."
@@ -909,7 +912,7 @@ msgid "%{timebox_type} does not support burnup charts"
msgstr ""
msgid "%{timebox_type} must have a start and due date"
-msgstr ""
+msgstr "%{timebox_type} ì€(는) 시작날짜와 종료날짜가 있어야합니다."
msgid "%{title} %{operator} %{threshold}"
msgstr "%{title} %{operator} %{threshold}"
@@ -927,7 +930,7 @@ msgid "%{totalWeight} total weight"
msgstr ""
msgid "%{total_warnings} warning(s) found:"
-msgstr ""
+msgstr "%{total_warnings}ê°œì˜ ê²½ê³  발견ë¨:"
msgid "%{total} open issue weight"
msgstr ""
@@ -947,6 +950,12 @@ msgstr "%{userName}ì˜ ì•„ë°”íƒ€"
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr "%{user_name} 프로필 페ì´ì§€"
@@ -969,10 +978,10 @@ msgid "%{user} created an issue: %{issue_link}"
msgstr ""
msgid "%{value} is not included in the list"
-msgstr ""
+msgstr "%{value} ì€(는) 목ë¡ì— í¬í•¨ë˜ì§€ 않습니다"
msgid "%{value} s"
-msgstr ""
+msgstr "%{value}ì´ˆ"
msgid "%{verb} %{time_spent_value} spent time."
msgstr "%{verb} %{time_spent_value} ì‹œê°„ì´ ì§€ë‚¬ìŠµë‹ˆë‹¤."
@@ -987,7 +996,7 @@ msgid "%{widget} options"
msgstr ""
msgid "%{wildcards_link_start}Wildcards%{wildcards_link_end} such as %{code_tag_start}v*%{code_tag_end} or %{code_tag_start}*-release%{code_tag_end} are supported."
-msgstr ""
+msgstr "%{code_tag_start}v*%{code_tag_end}나, %{code_tag_start}*-릴리스%{code_tag_end}ê°™ì€ %{wildcards_link_start}와ì¼ë“œì¹´ë“œ%{wildcards_link_end}는 지ì›ë©ë‹ˆë‹¤."
msgid "'%{data}' at %{location} does not match format: %{format}"
msgstr ""
@@ -1036,7 +1045,7 @@ msgid "(%{value}) has already been taken"
msgstr ""
msgid "(+%{count}&nbsp;rules)"
-msgstr ""
+msgstr "(+%{count}&nbsp;규칙)"
msgid "(Group Managed Account)"
msgstr ""
@@ -1051,15 +1060,18 @@ msgid "(check progress)"
msgstr "(진행 ìƒí™© 확ì¸)"
msgid "(deleted)"
-msgstr ""
+msgstr "(ì‚­ì œë¨)"
msgid "(expired)"
-msgstr ""
+msgstr "(만료ë¨)"
msgid "(leave blank if you don't want to change it)"
msgstr ""
msgid "(max size 15 MB)"
+msgstr "(최대 사ì´ì¦ˆ 15MB)"
+
+msgid "(optional)"
msgstr ""
msgid "(removed)"
@@ -1082,7 +1094,7 @@ msgid "* All times are in UTC unless specified"
msgstr ""
msgid "*Required"
-msgstr ""
+msgstr "*필수"
msgid "+ %{amount} more"
msgstr "+ %{amount}ê°œ ë” ìžˆìŒ"
@@ -1113,20 +1125,23 @@ msgid "+%{more_assignees_count} more assignees"
msgstr ""
msgid "+%{more_reviewers_count}"
-msgstr ""
+msgstr "+%{more_reviewers_count}"
msgid "+%{more_reviewers_count} more reviewers"
-msgstr ""
+msgstr "+%{more_reviewers_count} ëª…ì˜ ë¦¬ë·°ì–´"
msgid "+%{tags} more"
msgstr "+%{tags}개"
msgid ", and "
-msgstr ""
+msgstr ", 그리고 "
msgid ", or "
msgstr ", ë˜ëŠ” "
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1160,7 +1175,7 @@ msgid "0 bytes"
msgstr ""
msgid "0t1DgySidms"
-msgstr ""
+msgstr "0t1DgySidms"
msgid "1 Day"
msgid_plural "%d Days"
@@ -1168,7 +1183,7 @@ msgstr[0] "%dì¼"
msgid "1 Issue"
msgid_plural "%d Issues"
-msgstr[0] ""
+msgstr[0] "%dê°œì˜ ì´ìŠˆ"
msgid "1 closed issue"
msgid_plural "%{issues} closed issues"
@@ -1184,7 +1199,7 @@ msgstr[0] "%dì¼"
msgid "1 day remaining"
msgid_plural "%d days remaining"
-msgstr[0] ""
+msgstr[0] "%dì¼ ë‚¨ìŒ"
msgid "1 day selected"
msgid_plural "%d days selected"
@@ -1261,10 +1276,10 @@ msgid "10-19 contributions"
msgstr "10 ê°œ ì´ìƒ 참여"
msgid "1000+"
-msgstr ""
+msgstr "1000+"
msgid "192.168.0.0/24"
-msgstr ""
+msgstr "192.168.0.0/24"
msgid "1st contribution!"
msgstr "첫번째 기여!"
@@ -1285,7 +1300,7 @@ msgid "3 hours"
msgstr "3 시간"
msgid "30 days"
-msgstr ""
+msgstr "30ì¼"
msgid "30 minutes"
msgstr "30 분"
@@ -1309,13 +1324,13 @@ msgid "404|Please contact your GitLab administrator if you think this is a mista
msgstr "ì´ê²ƒì´ ì‹¤ìˆ˜ì— ì˜í•œ 것ì´ë¼ê³  ìƒê°í•œë‹¤ë©´ GitLab 관리ìžì—게 문ì˜í•˜ì„¸ìš”."
msgid "7 days"
-msgstr ""
+msgstr "7ì¼"
msgid "8 hours"
msgstr "8 시간"
msgid ":%{startLine} to %{endLine}"
-msgstr ""
+msgstr ":%{startLine} ì—ì„œ %{endLine}"
msgid "A %{incident_docs_start}modified issue%{incident_docs_end} to guide the resolution of incidents."
msgstr ""
@@ -1402,7 +1417,7 @@ msgid "A new Release %{tag} for %{name} was published. Visit the %{release_link_
msgstr "새 릴리즈 %{tag}ê°€ %{name}으로 공개ë˜ì—ˆìŠµë‹ˆë‹¤. %{release_link_start}릴리즈 페ì´ì§€%{release_link_end}를 방문하여 ë” ìžì„¸ížˆ 알아보세요."
msgid "A new Release %{tag} for %{name} was published. Visit the Releases page to read more about it:"
-msgstr ""
+msgstr "새 릴리스 %{tag}(ì´)ê°€ %{name}(으)ë¡œ 공개ë˜ì—ˆìŠµë‹ˆë‹¤. 릴리스 페ì´ì§€ë¥¼ 방문해 ìžì„¸ížˆ 알아보세요."
msgid "A new impersonation token has been created."
msgstr ""
@@ -1428,6 +1443,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1438,7 +1456,7 @@ msgid "A rebase is already in progress."
msgstr ""
msgid "A sign-in to your account has been made from the following IP address: %{ip}"
-msgstr ""
+msgstr "ë‹¤ìŒ IP 주소ì—ì„œ ê³„ì •ì— ë¡œê·¸ì¸í–ˆìŠµë‹ˆë‹¤ : %{ip}"
msgid "A title is required"
msgstr ""
@@ -1450,7 +1468,7 @@ msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt c
msgstr ""
msgid "API"
-msgstr ""
+msgstr "API"
msgid "API Fuzzing"
msgstr ""
@@ -1465,10 +1483,10 @@ msgid "API Token"
msgstr "API 토í°"
msgid "API key"
-msgstr ""
+msgstr "API 키"
msgid "API?"
-msgstr ""
+msgstr "API?"
msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
msgstr ""
@@ -1513,28 +1531,28 @@ msgid "APIFuzzing|File path or URL to requests to be tested. For example, folder
msgstr ""
msgid "APIFuzzing|Generate code snippet"
-msgstr ""
+msgstr "코드 스니펫 ìƒì„±"
msgid "APIFuzzing|Make sure your credentials are secured"
msgstr ""
msgid "APIFuzzing|Password for basic authentication"
-msgstr ""
+msgstr "기본 ì¸ì¦ì„ 위한 비밀번호"
msgid "APIFuzzing|Predefined profiles"
msgstr ""
msgid "APIFuzzing|Scan mode"
-msgstr ""
+msgstr "모드 스캔"
msgid "APIFuzzing|Scan profile"
-msgstr ""
+msgstr "프로필 스캔"
msgid "APIFuzzing|Show code snippet for the profile"
msgstr ""
msgid "APIFuzzing|Target URL"
-msgstr ""
+msgstr "타겟 URL"
msgid "APIFuzzing|There are three ways to perform scans."
msgstr ""
@@ -1573,16 +1591,16 @@ msgid "AWS Access Key"
msgstr "AWS 엑세스 키"
msgid "AWS Access Key. Only required if not using role instance credentials"
-msgstr ""
+msgstr "AWS 액세스 키. ì—­í•  ì¸ìŠ¤í„´ìŠ¤ ìžê²© ì¦ëª…ì„ ì‚¬ìš©í•˜ì§€ 않는 경우ì—만 í•„ìš”"
msgid "AWS Secret Access Key"
msgstr "AWS 비밀 액세스 키"
msgid "AWS Secret Access Key. Only required if not using role instance credentials"
-msgstr ""
+msgstr "AWS 비밀 액세스 키. ì—­í•  ì¸ìŠ¤í„´ìŠ¤ ìžê²© ì¦ëª…ì„ ì‚¬ìš©í•˜ì§€ 않는 경우ì—만 í•„ìš”"
msgid "AWS service error: %{error}"
-msgstr ""
+msgstr "AWS 서비스 ì—러 : %{error}"
msgid "Abort"
msgstr "중지"
@@ -1612,10 +1630,10 @@ msgid "Accept terms"
msgstr "약관ë™ì˜"
msgid "Acceptable for use in this project"
-msgstr ""
+msgstr "ì´ í”„ë¡œì íŠ¸ì—ì„œ 사용 가능"
msgid "Access Git repositories or the API."
-msgstr ""
+msgstr "Git 저장소 ë˜ëŠ” APIì— ì•¡ì„¸ìŠ¤í•©ë‹ˆë‹¤."
msgid "Access Tokens"
msgstr "액세스 토í°"
@@ -1674,6 +1692,15 @@ msgstr "확실한가요? 모든 RSS ë˜ëŠ” ìº˜ë¦°ë” URLì´ ìž‘ë™ì„ 멈추게
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr "확실한가요? 현재 ì‚¬ìš©ì¤‘ì¸ ì´ìŠˆ ì´ë©”ì¼ ì£¼ì†Œê°€ ìž‘ë™í•˜ì§€ 않게 ë©ë‹ˆë‹¤."
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1686,12 +1713,21 @@ msgstr "수신 ì´ë©”ì¼ í† í°"
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1723,7 +1759,7 @@ msgid "AccessTokens|reset this token"
msgstr ""
msgid "AccessibilityReport|Learn more"
-msgstr ""
+msgstr "ë” ì•Œì•„ë³´ê¸°"
msgid "AccessibilityReport|Message: %{message}"
msgstr "메시지: %{message}"
@@ -1749,6 +1785,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr "계정: %{account}"
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1773,6 +1839,9 @@ msgstr "%{type} 활성화 (%{token_length})"
msgid "Active Sessions"
msgstr "í™œì„±í™”ëœ ì„¸ì…˜"
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "활ë™"
@@ -1783,7 +1852,7 @@ msgid "Add"
msgstr "추가"
msgid "Add \"%{value}\""
-msgstr ""
+msgstr "\"%{value}\" 추가"
msgid "Add %{linkStart}assets%{linkEnd} to your Release. GitLab automatically includes read-only assets, like source code and release evidence."
msgstr "%{linkStart}ì—ì…‹%{linkEnd}ì„ ë¦´ë¦¬ì¦ˆì— ì¶”ê°€í•˜ì„¸ìš”. GitLabì´ ìžë™ìœ¼ë¡œ 소스 코드나 릴리즈 ì¦ê±°ì²˜ëŸ¼ ìžë™ìœ¼ë¡œ í¬í•¨í•©ë‹ˆë‹¤."
@@ -1813,7 +1882,7 @@ msgid "Add README"
msgstr "README 추가"
msgid "Add Zoom meeting"
-msgstr ""
+msgstr "Zoom 미팅 추가"
msgid "Add a %{type}"
msgstr ""
@@ -1822,7 +1891,7 @@ msgid "Add a GPG key"
msgstr "GPG 키 추가"
msgid "Add a Jaeger URL to replace this page with a link to your Jaeger server. You first need to %{link_start_tag}install Jaeger%{link_end_tag}."
-msgstr ""
+msgstr "ì´ íŽ˜ì´ì§€ë¥¼ Jaeger ì„œë²„ì— ëŒ€í•œ ë§í¬ë¡œ 바꾸려면 Jaeger URLì„ ì¶”ê°€í•˜ì‹­ì‹œì˜¤. 먼저 %{link_start_tag}Jaeger를 설치%{link_end_tag}해야 합니다."
msgid "Add a Terms of Service agreement and Privacy Policy for users of this GitLab instance."
msgstr ""
@@ -1834,7 +1903,7 @@ msgid "Add a collapsible section"
msgstr ""
msgid "Add a comment to this line"
-msgstr ""
+msgstr "ì´ ë¼ì¸ì— 댓글 추가"
msgid "Add a comment to this line or drag for multiple lines"
msgstr ""
@@ -1878,7 +1947,7 @@ msgstr "í…Œì´ë¸” 추가"
msgid "Add a task list"
msgstr "ìž‘ì—… ëª©ë¡ ì¶”ê°€"
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -1888,19 +1957,19 @@ msgid "Add an SSH key"
msgstr "SSH 키 추가"
msgid "Add an existing issue"
-msgstr ""
+msgstr "기존 ì´ìŠˆ 추가"
msgid "Add an impersonation token"
msgstr ""
msgid "Add another link"
-msgstr ""
+msgstr "다른 ë§í¬ 추가"
msgid "Add approval rule"
-msgstr ""
+msgstr "ìŠ¹ì¸ ê·œì¹™ 추가"
msgid "Add approvers"
-msgstr ""
+msgstr "승ì¸ìž 추가"
msgid "Add bold text"
msgstr "êµµì€ ë¬¸ìžì—´ 추가"
@@ -1933,7 +2002,7 @@ msgid "Add deploy freeze"
msgstr ""
msgid "Add deploy keys to grant read/write access to this repository. %{link_start}What are deploy keys?%{link_end}"
-msgstr ""
+msgstr "ì´ ì €ìž¥ì†Œì— ëŒ€í•œ ì½ê¸°/쓰기 액세스 ê¶Œí•œì„ ë¶€ì—¬í•˜ë ¤ë©´ ë°°í¬ í‚¤ë¥¼ 추가하세요. %{link_start}ë°°í¬ í‚¤ëž€ ​​무엇입니까?%{link_end}"
msgid "Add email address"
msgstr "ì´ë©”ì¼ ì£¼ì†Œ 추가"
@@ -1957,7 +2026,7 @@ msgid "Add italic text"
msgstr "기울임 í…스트 추가"
msgid "Add key"
-msgstr ""
+msgstr "키 추가"
msgid "Add label(s)"
msgstr "ë ˆì´ë¸” 추가"
@@ -1981,10 +2050,10 @@ msgid "Add previously merged commits"
msgstr ""
msgid "Add project"
-msgstr ""
+msgstr "프로ì íŠ¸ 추가"
msgid "Add projects"
-msgstr ""
+msgstr "프로ì íŠ¸ 추가"
msgid "Add reaction"
msgstr "ë°˜ì‘ ì¶”ê°€"
@@ -1999,7 +2068,7 @@ msgid "Add suggestion to batch"
msgstr ""
msgid "Add system hook"
-msgstr ""
+msgstr "시스템 í›„í¬ ì¶”ê°€"
msgid "Add text to the sign-in page. Markdown enabled."
msgstr ""
@@ -2008,16 +2077,16 @@ msgid "Add to Slack"
msgstr "ìŠ¬ëž™ì— ì¶”ê°€"
msgid "Add to board"
-msgstr ""
+msgstr "ë³´ë“œì— ì¶”ê°€"
msgid "Add to epic"
-msgstr ""
+msgstr "ì—í”½ì— ì¶”ê°€"
msgid "Add to merge train"
-msgstr ""
+msgstr "머지 트레ì¸ì— 추가"
msgid "Add to merge train when pipeline succeeds"
-msgstr ""
+msgstr "파ì´í”„ë¼ì¸ì´ 성공하면 머지 트레ì¸ì— 추가"
msgid "Add to review"
msgstr "리뷰 추가"
@@ -2038,34 +2107,34 @@ msgid "Add users to group"
msgstr "ê·¸ë£¹ì— ì‚¬ìš©ìž ì¶”ê°€"
msgid "Add variable"
-msgstr ""
+msgstr "변수 추가"
msgid "Add vulnerability finding"
msgstr ""
msgid "Add webhook"
-msgstr ""
+msgstr "웹훅 추가"
msgid "Add/remove"
-msgstr ""
+msgstr "추가/제거"
msgid "AddContextCommits|Add previously merged commits"
-msgstr ""
+msgstr "ì´ì „ì— ë¨¸ì§€ëœ ì»¤ë°‹ 추가"
msgid "AddContextCommits|Add/remove"
-msgstr ""
+msgstr "추가/제거"
msgid "AddMember|Emails cannot be blank"
msgstr ""
msgid "AddMember|Invite email is invalid"
-msgstr ""
+msgstr "초대 ì´ë©”ì¼ì´ 유효하지 않습니다"
msgid "AddMember|Invite limit of %{daily_invites} per day exceeded"
-msgstr ""
+msgstr "ì¼ì¼ 초대 í•œë„ %{daily_invites} 초과"
msgid "AddMember|No invite source provided."
-msgstr ""
+msgstr "초대 소스가 제공ë˜ì§€ 않았습니다."
msgid "AddMember|No users specified."
msgstr "사용ìžë¥¼ 지정하지 않았습니다."
@@ -2086,13 +2155,13 @@ msgid "Added a to do."
msgstr ""
msgid "Added an issue to an epic."
-msgstr ""
+msgstr "ì´ìŠˆë¥¼ ì—í”½ì— ì¶”ê°€í–ˆìŠµë‹ˆë‹¤."
msgid "Added for this merge request"
msgstr ""
msgid "Added in this version"
-msgstr ""
+msgstr "ì´ ë²„ì „ì— ì¶”ê°€ë¨"
msgid "Adding new applications is disabled in your GitLab instance. Please contact your GitLab administrator to get the permission"
msgstr "GitLab ì¸ìŠ¤í„´ìŠ¤ì— 새 애플리케ì´ì…˜ì„ 추가 í•  수 없습니다. ê¶Œí•œì„ ì–»ìœ¼ë ¤ë©´ GitLab 관리ìžì—게 문ì˜í•˜ì‹­ì‹œì˜¤."
@@ -2128,7 +2197,7 @@ msgid "Adds %{epic_ref} as child epic."
msgstr ""
msgid "Adds %{labels} %{label_text}."
-msgstr ""
+msgstr "%{labels} %{label_text} 추가"
msgid "Adds a Zoom meeting."
msgstr ""
@@ -2215,7 +2284,7 @@ msgid "AdminArea|Get security updates from GitLab and stay up to date"
msgstr ""
msgid "AdminArea|Groups"
-msgstr ""
+msgstr "그룹"
msgid "AdminArea|Guest"
msgstr ""
@@ -2224,7 +2293,7 @@ msgid "AdminArea|Included Free in license"
msgstr ""
msgid "AdminArea|Latest groups"
-msgstr ""
+msgstr "최근 그룹"
msgid "AdminArea|Latest projects"
msgstr ""
@@ -2239,28 +2308,28 @@ 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 ""
msgid "AdminArea|Sign up for the GitLab Security Newsletter to get notified for security updates."
-msgstr ""
+msgstr "보안 ì—…ë°ì´íŠ¸ì— 대한 ì•Œë¦¼ì„ ë°›ìœ¼ë ¤ë©´ GitLab 보안 ë‰´ìŠ¤ë ˆí„°ì— ê°€ìž…í•˜ì„¸ìš”."
msgid "AdminArea|Sign up for the GitLab newsletter"
-msgstr ""
+msgstr "GitLab 뉴스레터 신청"
msgid "AdminArea|Stop all jobs"
msgstr "모든 작업 중지"
@@ -2278,7 +2347,7 @@ msgid "AdminArea|Total users"
msgstr "ì´ ì‚¬ìš©ìž"
msgid "AdminArea|Users"
-msgstr ""
+msgstr "사용ìž"
msgid "AdminArea|Users statistics"
msgstr "ì‚¬ìš©ìž í†µê³„"
@@ -2287,16 +2356,16 @@ msgid "AdminArea|Users with highest role"
msgstr ""
msgid "AdminArea|Users without a Group and Project"
-msgstr ""
+msgstr "그룹 ë° í”„ë¡œì íŠ¸ê°€ 없는 사용ìž"
msgid "AdminArea|View latest groups"
-msgstr ""
+msgstr "최근 그룹 보기"
msgid "AdminArea|View latest projects"
-msgstr ""
+msgstr "최신 프로ì íŠ¸ 보기"
msgid "AdminArea|View latest users"
-msgstr ""
+msgstr "최신 유저 보기"
msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
@@ -2304,6 +2373,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2323,10 +2401,10 @@ msgid "AdminSettings|Auto DevOps domain"
msgstr "Auto DevOps ë„ë©”ì¸"
msgid "AdminSettings|Configure Let's Encrypt"
-msgstr ""
+msgstr "Let's Encrypt 설정"
msgid "AdminSettings|Disable feed token"
-msgstr ""
+msgstr "피드 í† í° ë¹„í™œì„±í™”"
msgid "AdminSettings|Disable public access to Pages sites"
msgstr ""
@@ -2344,7 +2422,7 @@ msgid "AdminSettings|Enable shared runners for new projects"
msgstr "새 프로ì íŠ¸ì— 공유 러너 활성화"
msgid "AdminSettings|Feed token"
-msgstr ""
+msgstr "피드 토í°"
msgid "AdminSettings|I have read and agree to the Let's Encrypt %{link_start}Terms of Service%{link_end} (PDF)."
msgstr ""
@@ -2356,13 +2434,13 @@ msgid "AdminSettings|Keep the latest artifacts for all jobs in the latest succes
msgstr ""
msgid "AdminSettings|Let's Encrypt email"
-msgstr ""
+msgstr "Let's Encrypt ì´ë©”ì¼"
msgid "AdminSettings|Maximum duration of a session for Git operations when 2FA is enabled."
msgstr ""
msgid "AdminSettings|New CI/CD variables in projects and groups default to protected."
-msgstr ""
+msgstr "프로ì íŠ¸ ë° ê·¸ë£¹ì˜ ìƒˆ CI/CD 변수는 기본ì ìœ¼ë¡œ 보호ë¨ìœ¼ë¡œ 설정ë©ë‹ˆë‹¤."
msgid "AdminSettings|No required pipeline"
msgstr ""
@@ -2416,25 +2494,25 @@ msgid "AdminStatistics|Active Users"
msgstr ""
msgid "AdminStatistics|Forks"
-msgstr ""
+msgstr "í¬í¬"
msgid "AdminStatistics|Issues"
-msgstr ""
+msgstr "ì´ìŠˆ"
msgid "AdminStatistics|Merge requests"
-msgstr ""
+msgstr "머지 리퀘스트"
msgid "AdminStatistics|Milestones"
-msgstr ""
+msgstr "마ì¼ìŠ¤í†¤"
msgid "AdminStatistics|Notes"
msgstr ""
msgid "AdminStatistics|SSH Keys"
-msgstr ""
+msgstr "SSH 키"
msgid "AdminStatistics|Snippets"
-msgstr ""
+msgstr "스니펫"
msgid "AdminUsers|(Admin)"
msgstr ""
@@ -2443,10 +2521,10 @@ msgid "AdminUsers|(Banned)"
msgstr ""
msgid "AdminUsers|(Blocked)"
-msgstr ""
+msgstr "(차단ë¨)"
msgid "AdminUsers|(Deactivated)"
-msgstr ""
+msgstr "(비활성화ë¨)"
msgid "AdminUsers|(Internal)"
msgstr ""
@@ -2524,7 +2602,7 @@ msgid "AdminUsers|Be added to groups and projects"
msgstr ""
msgid "AdminUsers|Block"
-msgstr ""
+msgstr "차단"
msgid "AdminUsers|Block user"
msgstr "ì‚¬ìš©ìž ì°¨ë‹¨"
@@ -2580,7 +2658,7 @@ msgstr "ì‚¬ìš©ìž ì‚­ì œ"
msgid "AdminUsers|Delete user and contributions"
msgstr "사용ìžì™€ 기여 ì‚­ì œ"
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2614,7 +2692,7 @@ msgid "AdminUsers|Learn more about %{link_start}banned users.%{link_end}"
msgstr ""
msgid "AdminUsers|Log in"
-msgstr ""
+msgstr "로그ì¸"
msgid "AdminUsers|Manage (accept/reject) pending user sign ups"
msgstr ""
@@ -2704,7 +2782,7 @@ msgid "AdminUsers|Unban user %{username}?"
msgstr ""
msgid "AdminUsers|Unblock"
-msgstr ""
+msgstr "차단 해제"
msgid "AdminUsers|Unblock user %{username}?"
msgstr ""
@@ -2725,7 +2803,7 @@ msgid "AdminUsers|User will not be able to login"
msgstr ""
msgid "AdminUsers|Users"
-msgstr ""
+msgstr "사용ìž"
msgid "AdminUsers|Users can still be invited to your instance and/or add themselves if permitted based on your settings. They will not have access to your instance, nor count towards your subscribed seat count until you %{approve_link}."
msgstr ""
@@ -2865,6 +2943,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -2920,7 +3001,7 @@ msgid "AlertManagement|Display alerts from all your monitoring tools directly wi
msgstr ""
msgid "AlertManagement|Edit"
-msgstr ""
+msgstr "편집"
msgid "AlertManagement|Environment"
msgstr ""
@@ -2932,7 +3013,7 @@ msgid "AlertManagement|Incident"
msgstr ""
msgid "AlertManagement|Key"
-msgstr ""
+msgstr "키"
msgid "AlertManagement|Metrics"
msgstr ""
@@ -3250,11 +3331,14 @@ msgid "All environments"
msgstr ""
msgid "All epics"
-msgstr ""
+msgstr "모든 ì—픽"
msgid "All groups and projects"
msgstr "모든 그룹과 프로ì íŠ¸"
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr "ì´ ë§ˆì¼ìŠ¤í†¤ì— 대한 모든 ì´ìŠˆê°€ 닫혔습니다."
@@ -3277,7 +3361,7 @@ msgid "All projects selected"
msgstr ""
msgid "All threads resolved"
-msgstr ""
+msgstr "모든 스레드가 í•´ê²°ë¨"
msgid "All users must accept the Terms of Service and Privacy Policy to access GitLab"
msgstr ""
@@ -3301,7 +3385,7 @@ msgid "Allow commits from members who can merge to the target branch."
msgstr "ëŒ€ìƒ ë¸Œëžœì¹˜ì— ë¨¸ì§€í•  수 있는 ë©¤ë²„ì˜ ì»¤ë°‹ì„ í—ˆìš©í•©ë‹ˆë‹¤."
msgid "Allow group owners to manage LDAP-related settings"
-msgstr ""
+msgstr "그룹 소유ìžê°€ LDAP 관련 ì„¤ì •ì„ ê´€ë¦¬í•˜ë„ë¡ í—ˆìš©"
msgid "Allow non-administrators access to the performance bar"
msgstr ""
@@ -3343,7 +3427,7 @@ msgid "Allow requests to the local network from web hooks and services"
msgstr ""
msgid "Allow subgroups to set up their own two-factor authentication rules"
-msgstr ""
+msgstr "하위 ê·¸ë£¹ì´ ìžì²´ 2단계 ì¸ì¦ ê·œì¹™ì„ ì„¤ì •í•˜ë„ë¡ í—ˆìš©í•©ë‹ˆë‹¤."
msgid "Allow this key to push to this repository"
msgstr ""
@@ -3382,7 +3466,7 @@ msgid "Allowed to fail"
msgstr "실패 허용ë¨"
msgid "Allows projects or subgroups in this group to override the global setting."
-msgstr ""
+msgstr "ì´ ê·¸ë£¹ì˜ í”„ë¡œì íŠ¸ ë˜ëŠ” 하위 ê·¸ë£¹ì´ ì „ì—­ ì„¤ì •ì„ ìž¬ì •ì˜ í•  수 있습니다."
msgid "Allows you to add and manage Kubernetes clusters."
msgstr "Kubernetes í´ëŸ¬ìŠ¤í„°ë¥¼ 추가하고 관리 í•  수 ​​있습니다."
@@ -3394,7 +3478,7 @@ msgid "Almost there..."
msgstr ""
msgid "Already blocked"
-msgstr ""
+msgstr "ì´ë¯¸ 차단ë¨"
msgid "Already have login and password?"
msgstr ""
@@ -3459,6 +3543,9 @@ msgstr "ì—러가 ë°œìƒí–ˆìŠµë‹ˆë‹¤."
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3486,9 +3573,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr "BLOB 미리보기 ì¤‘ì— ì˜¤ë¥˜ê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤."
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3589,7 +3673,7 @@ msgid "An error occurred while fetching reference"
msgstr ""
msgid "An error occurred while fetching tags. Retry the search."
-msgstr ""
+msgstr "태그를 가져오는 ë™ì•ˆ 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤. 다시 검색해 보세요."
msgid "An error occurred while fetching terraform reports."
msgstr ""
@@ -3669,6 +3753,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3678,6 +3765,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3800,10 +3890,10 @@ msgid "An error occurred while updating the notification settings. Please try ag
msgstr ""
msgid "An error occurred while uploading the file. Please try again."
-msgstr ""
+msgstr "파ì¼ì„ 업로드하는 ë™ì•ˆ 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤. 다시 ì‹œë„í•´ 주세요."
msgid "An error occurred while uploading the image. Please try again."
-msgstr ""
+msgstr "ì´ë¯¸ì§€ë¥¼ 업로드하는 ë™ì•ˆ 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤. 다시 ì‹œë„í•´ 주세요."
msgid "An error occurred while validating group path"
msgstr ""
@@ -3826,6 +3916,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -3857,7 +3953,7 @@ msgid "An unknown error occurred while loading this graph."
msgstr ""
msgid "An unknown error occurred."
-msgstr ""
+msgstr "ì•Œ 수 없는 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤."
msgid "Analytics"
msgstr "분ì„"
@@ -3914,7 +4010,7 @@ msgid "Any encrypted tokens"
msgstr ""
msgid "Any label"
-msgstr ""
+msgstr "모든 ë¼ë²¨"
msgid "Any member with at least Developer permissions on the project."
msgstr ""
@@ -4072,7 +4168,7 @@ msgid "Applications"
msgstr "어플리케ì´ì…˜"
msgid "Applied"
-msgstr "ì ìš©ëœ"
+msgstr "ì ìš©ë¨"
msgid "Apply"
msgstr "ì ìš©"
@@ -4112,10 +4208,10 @@ msgid "Applying multiple commands"
msgstr ""
msgid "Applying suggestion..."
-msgstr ""
+msgstr "제안 ì ìš© 중..."
msgid "Applying suggestions..."
-msgstr ""
+msgstr "제안 ì ìš© 중..."
msgid "Approval Status"
msgstr ""
@@ -4148,9 +4244,15 @@ msgstr[0] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4181,6 +4283,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4190,6 +4295,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4214,6 +4328,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4241,6 +4358,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4277,7 +4397,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4305,13 +4425,13 @@ msgid "Approve the current merge request."
msgstr ""
msgid "Approved"
-msgstr ""
+msgstr "승ì¸ë¨"
msgid "Approved MRs"
msgstr ""
msgid "Approved the current merge request."
-msgstr ""
+msgstr "ì´ ë¨¸ì§€ 리퀘스트를 승ì¸í–ˆìŠµë‹ˆë‹¤."
msgid "Approved-By"
msgstr ""
@@ -4446,9 +4566,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr "공개키를 재ìƒì„±í•˜ì‹œê² ìŠµë‹ˆê¹Œ? 미러ë§ì´ 다시 ë™ìž‘하기 위해서 remote ì„œë²„ì˜ ê³µê°œí‚¤ë¥¼ ì—…ë°ì´íŠ¸í•´ì•¼ í•  것입니다."
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4591,9 +4708,12 @@ msgid "Assign milestone"
msgstr "마ì¼ìŠ¤í†¤ 지정"
msgid "Assign reviewer"
-msgstr ""
+msgstr "리뷰어 지정하기"
msgid "Assign reviewer(s)"
+msgstr "리뷰어 지정하기"
+
+msgid "Assign severity"
msgstr ""
msgid "Assign some issues to this milestone."
@@ -4821,13 +4941,13 @@ msgid "Author"
msgstr "작성ìž"
msgid "Author: %{author_name}"
-msgstr ""
+msgstr "작성ìž: %{author_name}"
msgid "Authored %{timeago}"
-msgstr ""
+msgstr "%{timeago} ì „ 작성ë¨"
msgid "Authored %{timeago} by %{author}"
-msgstr ""
+msgstr "%{timeago} ì „ %{author}ì— ì˜í•´ 작성ë¨"
msgid "Authorization code:"
msgstr "ì¸ì¦ 코드:"
@@ -4974,7 +5094,7 @@ msgid "Available"
msgstr "ì´ìš© 가능"
msgid "Available ID"
-msgstr ""
+msgstr "사용 가능한 ID"
msgid "Available group runners: %{runners}"
msgstr ""
@@ -4991,9 +5111,6 @@ msgstr "사용 가능한 지정 러너"
msgid "Avatar for %{assigneeName}"
msgstr "%{assigneeName} ì˜ ì•„ë°”íƒ€"
-msgid "Avatar for %{name}"
-msgstr "%{name} ì˜ ì•„ë°”íƒ€"
-
msgid "Avatar will be removed. Are you sure?"
msgstr "아바타가 ì‚­ì œë©ë‹ˆë‹¤. 확실합니까?"
@@ -5172,7 +5289,7 @@ msgid "BillingPlans|%{group_name} is currently using the %{plan_name}."
msgstr ""
msgid "BillingPlans|@%{user_name} you are currently using the %{plan_name}."
-msgstr ""
+msgstr "@%{user_name}ë‹˜ì€ í˜„ìž¬ %{plan_name} í”Œëžœì„ ì‚¬ìš©í•˜ê³  있습니다."
msgid "BillingPlans|Compare all plans"
msgstr ""
@@ -5243,9 +5360,6 @@ msgstr "ì›”"
msgid "BillingPlans|per user"
msgstr "ì‚¬ìš©ìž ë‹¹"
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr "업그레ì´ë“œ"
@@ -5276,13 +5390,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5294,7 +5405,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5306,9 +5420,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5493,7 +5613,7 @@ msgstr ""
msgid "Boards"
msgstr "보드"
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5556,7 +5676,7 @@ msgid "Boards|Collapse"
msgstr "접기"
msgid "Boards|Edit board"
-msgstr ""
+msgstr "보드 편집"
msgid "Boards|Expand"
msgstr ""
@@ -5592,16 +5712,16 @@ msgid "Board|Create board"
msgstr ""
msgid "Board|Create new board"
-msgstr ""
+msgstr "새 ë³´ë“œ ìƒì„±"
msgid "Board|Delete board"
-msgstr ""
+msgstr "보드 삭제"
msgid "Board|Edit board"
-msgstr ""
+msgstr "보드 편집"
msgid "Board|Enter board name"
-msgstr ""
+msgstr "ë³´ë“œ ì´ë¦„ ìž…ë ¥"
msgid "Board|Failed to delete board. Please try again."
msgstr ""
@@ -5852,7 +5972,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5861,6 +5984,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -5900,6 +6026,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6106,7 +6235,7 @@ msgid "CONTRIBUTING"
msgstr "CONTRIBUTING"
msgid "CPU"
-msgstr ""
+msgstr "CPU"
msgid "CSV is being generated and will be emailed to you upon completion."
msgstr ""
@@ -6169,7 +6298,7 @@ msgid "Can be overridden in each project."
msgstr ""
msgid "Can create groups:"
-msgstr ""
+msgstr "그룹 ìƒì„± 가능:"
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6184,7 +6313,7 @@ msgid "Can't apply this suggestion."
msgstr ""
msgid "Can't be empty"
-msgstr ""
+msgstr "비워둘 수 없습니다"
msgid "Can't create snippet: %{err}"
msgstr ""
@@ -6301,7 +6430,7 @@ msgid "Cannot make the epic confidential if it contains non-confidential issues"
msgstr ""
msgid "Cannot merge"
-msgstr ""
+msgstr "머지할 수 ì—†ìŒ"
msgid "Cannot modify %{profile_name} referenced in security policy"
msgstr ""
@@ -6331,10 +6460,10 @@ msgid "Capacity threshold"
msgstr ""
msgid "Card holder name"
-msgstr ""
+msgstr "ì¹´ë“œ ì†Œì§€ìž ì´ë¦„"
msgid "Card number:"
-msgstr ""
+msgstr "카드번호:"
msgid "CascadingSettings|Enforce for all subgroups"
msgstr ""
@@ -6385,7 +6514,7 @@ msgid "Change branches"
msgstr ""
msgid "Change label"
-msgstr ""
+msgstr "ë¼ë²¨ 변경"
msgid "Change made by"
msgstr ""
@@ -6397,10 +6526,10 @@ msgid "Change path"
msgstr "경로 변경"
msgid "Change reviewer(s)"
-msgstr ""
+msgstr "리뷰어 변경하기"
msgid "Change reviewer(s)."
-msgstr ""
+msgstr "리뷰어 변경하기"
msgid "Change role"
msgstr ""
@@ -6424,10 +6553,10 @@ msgid "Change your password or recover your current one"
msgstr "비밀번호 변경 ë˜ëŠ” 비밀번호 복구"
msgid "ChangeReviewer|Reviewer changed from %{old} to %{new}"
-msgstr ""
+msgstr "리뷰어가 %{old} ì—ì„œ %{new}ë¡œ 변경 ë˜ì—ˆìŠµë‹ˆë‹¤."
msgid "ChangeReviewer|Reviewer changed to %{new}"
-msgstr ""
+msgstr "리뷰어가 %{new} ë¡œ 변경 ë˜ì—ˆìŠµë‹ˆë‹¤."
msgid "ChangeReviewer|Unassigned"
msgstr ""
@@ -6603,7 +6732,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6828,25 +6957,25 @@ msgid "Cherry-pick this merge request"
msgstr "ì´ ë¨¸ì§€ 리퀘스트(MR)를 Cherry-pick"
msgid "Child"
-msgstr ""
+msgstr "하위"
msgid "Child epic does not exist."
-msgstr ""
+msgstr "하위 ì—í”½ì´ ì¡´ìž¬í•˜ì§€ 않습니다."
msgid "Child epic doesn't exist."
-msgstr ""
+msgstr "하위 ì—í”½ì´ ì¡´ìž¬í•˜ì§€ 않습니다."
msgid "Chinese language support using"
msgstr ""
msgid "Choose File..."
-msgstr ""
+msgstr "íŒŒì¼ ì„ íƒ..."
msgid "Choose a file"
msgstr "íŒŒì¼ ì„ íƒ"
msgid "Choose a group"
-msgstr ""
+msgstr "그룹 ì„ íƒ"
msgid "Choose a template"
msgstr "템플릿 ì„ íƒ"
@@ -6863,9 +6992,6 @@ msgstr "아무 색ìƒì„ ì„ íƒí•´ 주세요."
msgid "Choose file…"
msgstr "íŒŒì¼ ì„ íƒâ€¦"
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -6888,7 +7014,7 @@ msgid "Choose which repositories you want to connect and run CI/CD pipelines."
msgstr "Ci/CD 파ì´í”„ë¼ì¸ì´ ì—°ê²°ë˜ê³  실행할 저장소를 ì„ íƒí•´ 주세요."
msgid "Choose your framework"
-msgstr ""
+msgstr "프레임워í¬ë¥¼ ì„ íƒí•˜ì„¸ìš”"
msgid "CiCdAnalytics|Date range: %{range}"
msgstr ""
@@ -7076,6 +7202,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr "최근 검색 지우기"
@@ -7094,9 +7223,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7134,7 +7269,7 @@ msgid "Client authentication key password"
msgstr "í´ë¼ì´ì–¸íŠ¸ ì¸ì¦ 키 비밀번호"
msgid "Client request timeout"
-msgstr ""
+msgstr "í´ë¼ì´ì–¸íŠ¸ 요청 시간 초과"
msgid "Clients"
msgstr "í´ë¼ì´ì–¸íŠ¸"
@@ -7250,12 +7385,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7268,6 +7418,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7283,9 +7439,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7331,12 +7493,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7412,6 +7583,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7430,12 +7604,25 @@ 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 ""
+msgid "ClusterAgents|There's no activity from the past day"
+msgid_plural "ClusterAgents|There's no activity from the past %d days"
+msgstr[0] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7445,6 +7632,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8250,7 +8440,7 @@ msgid "Code owners"
msgstr "코드 소유ìž"
msgid "Code review"
-msgstr ""
+msgstr "코드 리뷰"
msgid "Code snippet"
msgstr ""
@@ -8265,7 +8455,7 @@ msgid "CodeNavigation|No references found"
msgstr ""
msgid "CodeOwner|Pattern"
-msgstr ""
+msgstr "패턴"
msgid "CodeQuality|New code quality degradations on this line"
msgstr ""
@@ -8346,7 +8536,7 @@ msgid "Commands did not apply"
msgstr ""
msgid "Comment"
-msgstr "코멘트"
+msgstr "댓글 달기"
msgid "Comment & resolve thread"
msgstr ""
@@ -8376,7 +8566,7 @@ msgid "Commenting on symbolic links that replace or are replaced by files is cur
msgstr ""
msgid "Comments"
-msgstr "코멘트"
+msgstr "댓글"
msgid "Commit"
msgid_plural "Commits"
@@ -8458,13 +8648,13 @@ msgid "Commit…"
msgstr "커밋..."
msgid "Community forum"
-msgstr ""
+msgstr "커뮤니티 í¬ëŸ¼"
msgid "Company"
-msgstr ""
+msgstr "회사"
msgid "Company Name"
-msgstr ""
+msgstr "회사 ì´ë¦„"
msgid "Compare"
msgstr "비êµ"
@@ -8631,6 +8821,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -8851,7 +9050,7 @@ msgid "Consistency guarantee method"
msgstr ""
msgid "Contact support"
-msgstr ""
+msgstr "ê³ ê° ì§€ì› ë¬¸ì˜"
msgid "Contacts"
msgstr ""
@@ -9050,6 +9249,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9133,11 +9335,14 @@ msgid "ContainerRegistry|Tags with names that match this regex pattern are kept.
msgstr ""
msgid "ContainerRegistry|Tags with names that match this regex pattern are removed. %{linkStart}View regex examples.%{linkEnd}"
-msgstr ""
+msgstr "ì´ ì •ê·œì‹ íŒ¨í„´ê³¼ ê°™ì€ ì´ë¦„ì„ ê°€ì§„ 태그는 제거ë©ë‹ˆë‹¤. %{linkStart}ì •ê·œì‹ ì˜ˆì œ 보기%{linkEnd}"
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9283,10 +9488,10 @@ msgid "Contributions per group member"
msgstr "그룹 구성ì›ë³„ 기여"
msgid "Contributor"
-msgstr ""
+msgstr "기여ìž"
msgid "Contributors"
-msgstr "기여해 주신 분들"
+msgstr "기여ìž"
msgid "Control emails linked to your account"
msgstr ""
@@ -9334,7 +9539,7 @@ msgid "Copy ID"
msgstr "ID 복사"
msgid "Copy IP Address"
-msgstr ""
+msgstr "IP 주소 복사"
msgid "Copy KRB5 clone URL"
msgstr "KRB5 í´ë¡  URL 복사"
@@ -9369,14 +9574,20 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
-msgid "Copy file contents"
+msgid "Copy failed. Please manually copy the value."
msgstr ""
+msgid "Copy file contents"
+msgstr "íŒŒì¼ ë‚´ìš© 복사"
+
msgid "Copy file path"
+msgstr "íŒŒì¼ ê²½ë¡œ 복사"
+
+msgid "Copy issue URL to clipboard"
msgstr ""
msgid "Copy key"
-msgstr ""
+msgstr "키 복사"
msgid "Copy labels and milestone from %{source_issuable_reference}."
msgstr ""
@@ -9397,7 +9608,7 @@ msgid "Copy secret"
msgstr ""
msgid "Copy source branch name"
-msgstr ""
+msgstr "소스 브랜치 ì´ë¦„ 복사"
msgid "Copy the code below to implement tracking in your application:"
msgstr ""
@@ -9405,14 +9616,11 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
msgid "Copy token"
-msgstr ""
+msgstr "í† í° ë³µì‚¬"
msgid "Copy trigger token"
msgstr ""
@@ -9580,7 +9788,7 @@ msgid "Couldn't assign policy to project"
msgstr ""
msgid "Country"
-msgstr ""
+msgstr "êµ­ê°€"
msgid "Coverage"
msgstr ""
@@ -9747,9 +9955,6 @@ msgstr "새 ë¼ë²¨ 만들기"
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr "새로 만들기 ..."
-
msgid "Create or import your first project"
msgstr ""
@@ -9780,6 +9985,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9822,9 +10030,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9834,13 +10039,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10020,15 +10228,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10038,15 +10264,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10111,13 +10346,13 @@ msgid "CurrentUser|Buy Pipeline minutes"
msgstr ""
msgid "CurrentUser|Edit profile"
-msgstr ""
+msgstr "프로필 편집"
msgid "CurrentUser|One of your groups is running out"
msgstr ""
msgid "CurrentUser|Preferences"
-msgstr ""
+msgstr "환경설정"
msgid "CurrentUser|Start an Ultimate trial"
msgstr ""
@@ -10197,15 +10432,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr "설정으로 ì´ë™"
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -10887,6 +11113,9 @@ msgstr ""
msgid "Date"
msgstr "날짜"
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr "날짜 ì„ íƒ"
@@ -11119,7 +11348,7 @@ msgid "Delete image repository"
msgstr ""
msgid "Delete label"
-msgstr ""
+msgstr "ë¼ë²¨ ì‚­ì œ"
msgid "Delete label: %{labelName}"
msgstr ""
@@ -11166,6 +11395,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11199,15 +11431,9 @@ msgstr ""
msgid "Deleted"
msgstr "ì‚­ì œë¨"
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11337,6 +11563,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11361,7 +11590,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11370,6 +11599,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -11642,7 +11874,7 @@ msgid "Descending"
msgstr "내림차순"
msgid "Describe the goal of the changes and what reviewers should be aware of."
-msgstr ""
+msgstr "ë³€ê²½ì˜ ëª©í‘œì™€ 리뷰어가 알아야 í•  ì‚¬í•­ì„ ì„¤ëª…í•©ë‹ˆë‹¤."
msgid "Description"
msgstr "설명"
@@ -11700,10 +11932,10 @@ msgid "DesignManagement|Are you sure you want to archive the selected designs?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
-msgstr ""
+msgstr "ì´ ëŒ“ê¸€ì˜ ë³€ê²½ ì‚¬í•­ì„ ì·¨ì†Œí•˜ì‹œê² ìŠµë‹ˆê¹Œ?"
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
-msgstr ""
+msgstr "ì´ ëŒ“ê¸€ ìž‘ì„±ì„ ì·¨ì†Œí•˜ì‹œê² ìŠµë‹ˆê¹Œ?"
msgid "DesignManagement|Cancel changes"
msgstr ""
@@ -11718,7 +11950,7 @@ msgid "DesignManagement|Click the image where you'd like to start a new discussi
msgstr ""
msgid "DesignManagement|Comment"
-msgstr ""
+msgstr "댓글"
msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
msgstr ""
@@ -12150,7 +12382,7 @@ msgid "Discover"
msgstr ""
msgid "Discover GitLab Geo"
-msgstr ""
+msgstr "GitLab Geo 알아보기"
msgid "Discover projects, groups and snippets. Share your projects with others"
msgstr "프로ì íŠ¸, 그룹 그리고 ìŠ¤ë‹ˆíŽ«ì„ ë°œê²¬í•˜ê³  ë‹¹ì‹ ì˜ í”„ë¡œì íŠ¸ë¥¼ 다른 사람과 공유합니다."
@@ -12164,15 +12396,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12312,6 +12544,9 @@ msgstr ""
msgid "Download CSV"
msgstr "CSV 다운로드"
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12430,7 +12665,7 @@ msgid "Edit Deploy Key"
msgstr "ë°°í¬ í‚¤ 편집"
msgid "Edit Geo Node"
-msgstr ""
+msgstr "ì´ ë…¸ë“œ 편집"
msgid "Edit Group Hook"
msgstr ""
@@ -12447,8 +12682,8 @@ msgstr "마ì¼ìŠ¤í†¤ 편집"
msgid "Edit Password"
msgstr "비밀번호 수정"
-msgid "Edit Pipeline Schedule %{id}"
-msgstr "파ì´í”„ë¼ì¸ 스케줄 편집 %{id}"
+msgid "Edit Pipeline Schedule"
+msgstr ""
msgid "Edit Release"
msgstr ""
@@ -12486,6 +12721,9 @@ msgstr "설명 편집"
msgid "Edit environment"
msgstr "환경 편집"
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr "ì—디터ì—ì„œ 파ì¼ì„ 편집하고 여기서 ë³€ê²½ì‚¬í•­ì„ ì»¤ë°‹í•˜ì„¸ìš”."
@@ -12550,7 +12788,7 @@ msgid "Edited"
msgstr ""
msgid "Edited %{timeago}"
-msgstr ""
+msgstr "%{timeago} ì „ 수정ë¨"
msgid "Editing"
msgstr ""
@@ -13426,6 +13664,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13471,9 +13712,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13553,7 +13791,7 @@ msgid "Error occurred when saving assignees"
msgstr ""
msgid "Error occurred when saving reviewers"
-msgstr ""
+msgstr "리뷰어를 저장하는 ë™ì•ˆ 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤."
msgid "Error occurred while updating the %{issuableType} status"
msgstr ""
@@ -13616,10 +13854,10 @@ msgid "Error updating the snippet"
msgstr ""
msgid "Error uploading file"
-msgstr ""
+msgstr "íŒŒì¼ ì—…ë¡œë“œ 오류"
msgid "Error uploading file. Please try again."
-msgstr ""
+msgstr "íŒŒì¼ ì—…ë¡œë“œì— ì‹¤íŒ¨í•˜ì˜€ìŠµë‹ˆë‹¤. 다시 ì‹œë„í•´ 주세요."
msgid "Error uploading file: %{stripped}"
msgstr ""
@@ -13627,9 +13865,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr "머지 리퀘스트(MR) 요청 중 오류 ë°œìƒ. 다시 ì‹œë„하십시오."
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13714,6 +13949,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -13898,9 +14136,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr "모ë‘"
-
msgid "Everyone With Access"
msgstr ""
@@ -14007,7 +14242,7 @@ msgid "ExperimentSubject|Must have exactly one of User, Namespace, or Project."
msgstr ""
msgid "Expiration"
-msgstr ""
+msgstr "만료"
msgid "Expiration date"
msgstr "만료ì¼"
@@ -14064,7 +14299,7 @@ msgid "Explore snippets"
msgstr ""
msgid "Explore topics"
-msgstr ""
+msgstr "주제별 둘러보기"
msgid "Export"
msgstr ""
@@ -14093,7 +14328,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14182,7 +14417,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgid "Failed to assign a reviewer because no user was found."
-msgstr ""
+msgstr "사용ìžë¥¼ ì°¾ì„ ìˆ˜ 없기 ë•Œë¬¸ì— ë¦¬ë·°ì–´ë¥¼ 지정하지 못했습니다."
msgid "Failed to assign a user because no user was found."
msgstr ""
@@ -14489,7 +14724,7 @@ msgid "FeatureFlags|All Users"
msgstr ""
msgid "FeatureFlags|All users"
-msgstr ""
+msgstr "모든 사용ìž"
msgid "FeatureFlags|Configure"
msgstr "구성"
@@ -14555,7 +14790,7 @@ msgid "FeatureFlags|Get started with feature flags"
msgstr ""
msgid "FeatureFlags|ID"
-msgstr ""
+msgstr "ID"
msgid "FeatureFlags|Inactive"
msgstr "비활성화"
@@ -14798,9 +15033,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15131,6 +15363,9 @@ msgstr "머지 리퀘스트(MR) 머지ì—ì„œ 프로ë•ì…˜ í™˜ê²½ì— ë°°í¬ê¹Œì§€
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -15201,13 +15436,13 @@ msgid "Geo Nodes"
msgstr "Geo 노드"
msgid "Geo Replication"
-msgstr ""
+msgstr "Geo 레플리케ì´ì…˜"
msgid "Geo Settings"
-msgstr ""
+msgstr "Geo 설정"
msgid "Geo sites"
-msgstr ""
+msgstr "Geo 사ì´íŠ¸"
msgid "Geo|%{component} synced"
msgstr ""
@@ -15231,16 +15466,16 @@ msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
msgid "Geo|%{timeAgoStr} (%{pendingEvents} events)"
-msgstr ""
+msgstr "%{timeAgoStr} (%{pendingEvents} ì´ë²¤íŠ¸)"
msgid "Geo|%{title} checksum progress"
msgstr ""
msgid "Geo|(%{timeAgo})"
-msgstr ""
+msgstr "(%{timeAgo})"
msgid "Geo|Add site"
-msgstr ""
+msgstr "사ì´íŠ¸ 추가"
msgid "Geo|Adjust your filters/search criteria above. If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
msgstr ""
@@ -15252,7 +15487,7 @@ msgid "Geo|All projects"
msgstr "모든 프로ì íŠ¸"
msgid "Geo|All projects are being scheduled for resync"
-msgstr ""
+msgstr "모든 프로ì íŠ¸ì˜ 재ë™ê¸°í™”ê°€ 예약ë˜ì—ˆìŠµë‹ˆë‹¤."
msgid "Geo|All projects are being scheduled for reverify"
msgstr ""
@@ -15279,7 +15514,7 @@ msgid "Geo|Connection timeout should be between 1-120"
msgstr ""
msgid "Geo|Consult Geo troubleshooting information"
-msgstr ""
+msgstr "Geo 문제 í•´ê²° 문서 확ì¸í•˜ê¸°"
msgid "Geo|Could not remove tracking entry for an existing project."
msgstr ""
@@ -15288,13 +15523,13 @@ msgid "Geo|Data replication lag"
msgstr ""
msgid "Geo|Data type"
-msgstr ""
+msgstr "ë°ì´í„° 타입"
msgid "Geo|Disabled"
msgstr ""
msgid "Geo|Discover GitLab Geo"
-msgstr ""
+msgstr "GitLab Geo 알아보기"
msgid "Geo|Does not match the primary storage configuration"
msgstr ""
@@ -15312,7 +15547,7 @@ msgid "Geo|Geo Status"
msgstr ""
msgid "Geo|Geo sites"
-msgstr ""
+msgstr "Geo 사ì´íŠ¸"
msgid "Geo|Geo sites are paused using a command run on the site"
msgstr ""
@@ -15501,7 +15736,7 @@ msgid "Geo|Selective (%{syncLabel})"
msgstr ""
msgid "Geo|Site's status was updated %{timeAgo}."
-msgstr ""
+msgstr "사ì´íŠ¸ì˜ ìƒíƒœê°€ %{timeAgo} ì „ ì—…ë°ì´íŠ¸ ë˜ì—ˆìŠµë‹ˆë‹¤."
msgid "Geo|Status"
msgstr "ìƒíƒœ"
@@ -15576,7 +15811,7 @@ msgid "Geo|Unknown state"
msgstr "ì•Œ 수 없는 ìƒíƒœ"
msgid "Geo|Updated %{timeAgo}"
-msgstr ""
+msgstr "%{timeAgo} ì „ ì—…ë°ì´íŠ¸ ë¨"
msgid "Geo|Verification"
msgstr ""
@@ -15954,7 +16189,7 @@ msgid "Gitpod|https://gitpod.example.com"
msgstr ""
msgid "Given access %{time_ago}"
-msgstr ""
+msgstr "%{time_ago} ì „ 엑세스 권한 부여ë¨"
msgid "Given epic is already related to this epic."
msgstr ""
@@ -15992,9 +16227,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16082,6 +16314,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16155,7 +16390,7 @@ msgid "Go to your snippets"
msgstr ""
msgid "Goal of the changes and what reviewers should be aware of"
-msgstr ""
+msgstr "ì´ ë³€ê²½ì˜ ëª©í‘œì™€ ë° ë¦¬ë·°ì–´ê°€ 알아야 í•  사항"
msgid "Google Cloud"
msgstr ""
@@ -16271,9 +16506,6 @@ msgstr ""
msgid "Group URL"
msgstr "그룹 URL"
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16344,10 +16576,10 @@ msgid "Group members"
msgstr ""
msgid "Group membership expiration date changed"
-msgstr ""
+msgstr "그룹 멤버십 만료ì¼ì´ 변경ë¨"
msgid "Group membership expiration date removed"
-msgstr ""
+msgstr "그룹 멤버십 만료ì¼ì´ ì‚­ì œë¨"
msgid "Group milestone"
msgstr ""
@@ -16400,6 +16632,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr "ê·¸ë£¹ì´ ì„±ê³µì ìœ¼ë¡œ ì—…ë°ì´íŠ¸ ë˜ì—ˆìŠµë‹ˆë‹¤."
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr "그룹: %{group_name}"
@@ -16502,9 +16737,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16554,7 +16798,7 @@ msgid "GroupSAML|Make sure you save this token — you won't be able to access i
msgstr ""
msgid "GroupSAML|Manage your group’s membership while adding another level of security with SAML."
-msgstr ""
+msgstr "ê·¸ë£¹ì˜ íšŒì›ì„ 관리합니다. SAMLë¡œ 다른 ìˆ˜ì¤€ì˜ ë³´ì•ˆì„ ì¶”ê°€í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤."
msgid "GroupSAML|Members"
msgstr ""
@@ -16577,6 +16821,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16616,6 +16863,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16649,6 +16899,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16673,7 +16935,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr "배지"
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16682,7 +16944,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16724,6 +16986,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16751,12 +17016,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -16821,13 +17092,13 @@ msgid "GroupSettings|remove the share with group lock from %{ancestor_group_name
msgstr "%{ancestor_group_name} ì—ì„œ 그룹 lock 공유 제거"
msgid "Groups"
-msgstr ""
+msgstr "그룹"
msgid "Groups (%{count})"
msgstr ""
msgid "Groups and projects"
-msgstr ""
+msgstr "그룹 ë° í”„ë¡œì íŠ¸"
msgid "Groups and subgroups"
msgstr ""
@@ -16871,6 +17142,9 @@ msgstr "그룹 구성ì›ì˜ 사용 ê¶Œí•œì„ ê´€ë¦¬í•˜ê³  ê·¸ë£¹ì˜ ê° í”„ë¡œì 
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -16925,11 +17199,14 @@ 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 ""
+
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 ""
msgid "GroupsNew|Upload file"
-msgstr ""
+msgstr "íŒŒì¼ ì—…ë¡œë“œ"
msgid "GroupsNew|e.g. h8d3f016698e..."
msgstr ""
@@ -18827,6 +19104,9 @@ msgstr ""
msgid "Invalid URL"
msgstr "유효하지 ì•Šì€ URL"
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19044,7 +19324,7 @@ msgid "InviteMembersModal|Select a group to invite"
msgstr ""
msgid "InviteMembersModal|Select a role"
-msgstr ""
+msgstr "ì—­í•  ì„ íƒ"
msgid "InviteMembersModal|Select members or type email addresses"
msgstr ""
@@ -19076,9 +19356,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19181,9 +19458,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19245,7 +19519,7 @@ msgid "Issue has been promoted to incident"
msgstr ""
msgid "Issue label"
-msgstr ""
+msgstr "ì´ìŠˆ ë¼ë²¨"
msgid "Issue or merge request ID is required"
msgstr ""
@@ -19295,9 +19569,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr "보드"
@@ -19383,7 +19654,7 @@ msgid "Issues Rate Limits"
msgstr ""
msgid "Issues and merge requests"
-msgstr ""
+msgstr "ì´ìŠˆì™€ 머지 리퀘스트"
msgid "Issues are being rebalanced at the moment, so manual reordering is disabled."
msgstr ""
@@ -19464,7 +19735,7 @@ msgid "Italic text"
msgstr ""
msgid "Iteration"
-msgstr ""
+msgstr "ì´í„°ë ˆì´ì…˜"
msgid "Iteration changed to"
msgstr ""
@@ -19479,7 +19750,7 @@ msgid "Iteration updated"
msgstr ""
msgid "Iterations"
-msgstr ""
+msgstr "ì´í„°ë ˆì´ì…˜"
msgid "Iterations|Add iteration"
msgstr ""
@@ -19943,8 +20214,8 @@ msgstr ""
msgid "Job|Download"
msgstr "다운로드"
-msgid "Job|Erase job log"
-msgstr "작업 로그 지우기"
+msgid "Job|Erase job log and artifacts"
+msgstr ""
msgid "Job|Job artifacts"
msgstr ""
@@ -20220,10 +20491,10 @@ msgid "LabelSelect|%{labelsString}, and %{remainingLabelCount} more"
msgstr "%{labelsString}, 그리고 %{remainingLabelCount} ì´ìƒ"
msgid "LabelSelect|Labels"
-msgstr ""
+msgstr "ë¼ë²¨"
msgid "Labels"
-msgstr "ë ˆì´ë¸”"
+msgstr "ë¼ë²¨"
msgid "Labels can be applied to %{features}. Group labels are available for any project within the group."
msgstr "%{features} ì— ë ˆì´ë¸”ì„ ì ìš©í•  수 있습니다. 그룹 ë ˆì´ë¸”ì€ ê·¸ë£¹ë‚´ì˜ ëª¨ë“  프로ì íŠ¸ì— 사용할 수 있습니다."
@@ -20394,6 +20665,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21148,7 +21425,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -21668,7 +21945,7 @@ msgid "Member|Remove member"
msgstr ""
msgid "Member|Revoke invite"
-msgstr ""
+msgstr "초대 취소"
msgid "Memory Usage"
msgstr ""
@@ -21695,7 +21972,7 @@ msgid "Merge Requests created"
msgstr "머지 리퀘스트(MR) ìƒì„±ë¨"
msgid "Merge Requests in Review"
-msgstr ""
+msgstr "검토 ì¤‘ì¸ ë¨¸ì§€ 리퀘스트"
msgid "Merge Requests merged"
msgstr ""
@@ -21854,7 +22131,7 @@ msgid "MergeRequests|Failed to squash. Should be done manually."
msgstr ""
msgid "MergeRequests|Saving the comment failed"
-msgstr "코멘트 저장 실패"
+msgstr "댓글 저장 실패"
msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
msgstr ""
@@ -21904,10 +22181,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22006,6 +22283,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22623,6 +22903,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22825,6 +23108,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr "ë„움ë§"
@@ -23038,6 +23354,9 @@ msgstr "신규"
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr "새로운 애플리케ì´ì…˜"
@@ -23261,6 +23580,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23439,7 +23761,7 @@ msgid "No jobs to show"
msgstr ""
msgid "No label"
-msgstr ""
+msgstr "ë¼ë²¨ ì—†ìŒ"
msgid "No labels with such name or description"
msgstr "그런 ì´ë¦„ ë˜ëŠ” 설명ì´ìžˆëŠ” ë ˆì´ë¸”ì´ ì—†ìŠµë‹ˆë‹¤."
@@ -23679,6 +24001,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr "참고: 관리ìžì—게 %{github_integration_link} (ì„) 를 설정하여, GitHub를 통한 로그ì¸ì„ 허용하고 ê°œì¸ ì•¡ì„¸ìŠ¤ 토í°ì„ ìƒì„±í•˜ì§€ ì•Šê³  저장소를 가져올 수 있ë„ë¡ í—ˆìš©í•  수 있는지 문ì˜í•˜ì‹­ì‹œì˜¤."
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23691,7 +24016,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -23740,7 +24065,7 @@ msgstr[0] ""
msgid "NotificationEmail|Reviewer"
msgid_plural "NotificationEmail|Reviewers"
-msgstr[0] ""
+msgstr[0] "리뷰어"
msgid "NotificationEmail|Reviewer: %{users}"
msgid_plural "NotificationEmail|Reviewers: %{users}"
@@ -24094,6 +24419,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24112,12 +24443,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24157,12 +24494,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24187,18 +24533,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24208,9 +24569,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24318,13 +24676,13 @@ msgid "Open errors"
msgstr ""
msgid "Open in Web IDE"
-msgstr ""
+msgstr "웹 IDEì—ì„œ 열기"
msgid "Open in file view"
msgstr ""
msgid "Open in your IDE"
-msgstr ""
+msgstr "IDEì—ì„œ 열기"
msgid "Open raw"
msgstr ""
@@ -24368,6 +24726,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr "작업 대시보드"
@@ -24906,9 +25267,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25098,9 +25456,15 @@ msgstr ""
msgid "Pending"
msgstr "대기중"
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25200,6 +25564,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25281,12 +25648,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25518,6 +25879,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25737,9 +26101,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26016,6 +26377,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26028,6 +26395,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26122,7 +26492,7 @@ msgid "Pre-defined push rules."
msgstr ""
msgid "Preferences"
-msgstr "환경 설정"
+msgstr "환경설정"
msgid "Preferences saved."
msgstr "ì„¤ì •ì„ ì €ìž¥í–ˆìŠµë‹ˆë‹¤."
@@ -26164,7 +26534,7 @@ msgid "Preferences|For example: 30 minutes ago."
msgstr ""
msgid "Preferences|Gitpod"
-msgstr ""
+msgstr "Gitpod"
msgid "Preferences|Homepage content"
msgstr ""
@@ -26223,9 +26593,6 @@ msgstr "시간 설정"
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26577,6 +26944,9 @@ msgstr "ìž˜ëª»ëœ íŒ¨ìŠ¤ì›Œë“œ"
msgid "Profiles|Invalid username"
msgstr "ìž˜ëª»ëœ ì‚¬ìš©ìžì´ë¦„"
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr "키"
@@ -26634,6 +27004,12 @@ msgstr "비밀 기여"
msgid "Profiles|Profile was successfully updated"
msgstr "í”„ë¡œí•„ì´ ì„±ê³µì ìœ¼ë¡œ ì—…ë°ì´íŠ¸ë˜ì—ˆìŠµë‹ˆë‹¤."
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26718,6 +27094,9 @@ msgstr "ì‚¬ìš©ìž ì´ë¦„ì„ ì„±ê³µì ìœ¼ë¡œ 바꿨습니다"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr "ìƒíƒœëŠ” 어떤가요?"
@@ -26746,7 +27125,7 @@ msgid "Profiles|You must transfer ownership or delete groups you are an owner of
msgstr ""
msgid "Profiles|You must transfer ownership or delete these groups before you can delete your account."
-msgstr ""
+msgstr "ê³„ì •ì„ ì‚­ì œí•˜ê¸° ì „ì— ê·¸ë£¹ì˜ ì†Œìœ ê¶Œì„ ì´ì „하거나 삭제해야 합니다."
msgid "Profiles|Your LinkedIn profile name from linkedin.com/in/profilename"
msgstr "linkedin.com/in/profilenameì˜ í”„ë¡œí•„ ì´ë¦„"
@@ -26905,7 +27284,7 @@ msgid "Project info:"
msgstr ""
msgid "Project information"
-msgstr ""
+msgstr "프로ì íŠ¸ ì •ë³´"
msgid "Project is required when cluster_type is :project"
msgstr ""
@@ -26938,7 +27317,7 @@ msgid "Project slug"
msgstr "프로ì íŠ¸ 슬러그"
msgid "Project uploads"
-msgstr ""
+msgstr "프로ì íŠ¸ 업로드"
msgid "Project visibility level will be changed to match namespace rules when transferring to a group."
msgstr ""
@@ -27012,6 +27391,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr "프로ì íŠ¸ ID: %{project_id}"
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27138,6 +27559,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27390,19 +27814,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27558,6 +27979,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr "프로ì íŠ¸"
@@ -27942,9 +28372,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr "ì´ ê¸°ëŠ¥ì€ ìž ê²¨ìžˆìŠµë‹ˆë‹¤."
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27957,9 +28384,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -27984,9 +28408,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28068,6 +28489,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28113,9 +28537,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28158,6 +28588,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28173,6 +28606,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28401,6 +28837,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr "README"
@@ -28585,9 +29027,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr "키 재ìƒì„±"
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28630,6 +29069,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -28776,7 +29263,7 @@ msgid "Remove all or specific label(s)"
msgstr ""
msgid "Remove all or specific reviewer(s)"
-msgstr ""
+msgstr "ì „ì²´ ë˜ëŠ” 특정 리뷰어 제거"
msgid "Remove approver"
msgstr ""
@@ -28785,7 +29272,7 @@ msgid "Remove approvers"
msgstr ""
msgid "Remove approvers?"
-msgstr ""
+msgstr "승ì¸ìžë¥¼ 삭제하시겠습니까?"
msgid "Remove asset link"
msgstr ""
@@ -28878,7 +29365,7 @@ msgid "Remove report"
msgstr ""
msgid "Remove reviewer"
-msgstr ""
+msgstr "리뷰어 제거"
msgid "Remove runner"
msgstr ""
@@ -28955,10 +29442,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29636,6 +30123,9 @@ msgstr "재개"
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr "재시ë„"
@@ -29645,6 +30135,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr "ì´ ìž‘ì—… 재시ë„"
@@ -29705,13 +30201,13 @@ msgstr ""
msgid "Reviewer"
msgid_plural "%d Reviewers"
-msgstr[0] ""
+msgstr[0] "%dëª…ì˜ ë¦¬ë·°ì–´"
msgid "Reviewer(s)"
-msgstr ""
+msgstr "리뷰어"
msgid "Reviewers"
-msgstr ""
+msgstr "리뷰어"
msgid "Reviewing"
msgstr "검토중"
@@ -29839,9 +30335,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -29863,6 +30356,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -29914,19 +30413,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -29980,6 +30482,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30025,6 +30530,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30034,7 +30542,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30103,7 +30614,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30121,6 +30632,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr "실행중"
@@ -30382,11 +30896,14 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
msgid "Search labels"
-msgstr ""
+msgstr "ë¼ë²¨ 검색"
msgid "Search merge requests"
msgstr "머지 리퀘스트(MR) 검색"
@@ -30403,9 +30920,6 @@ msgstr "검색 ë˜ëŠ” ê²°ê³¼ í•„í„°..."
msgid "Search or filter results…"
msgstr "검색 ë˜ëŠ” ê²°ê³¼ í•„í„°..."
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr "프로ì íŠ¸ 검색"
@@ -30452,7 +30966,7 @@ msgid "SearchAutocomplete|Merge requests assigned to me"
msgstr ""
msgid "SearchAutocomplete|Merge requests that I'm a reviewer"
-msgstr ""
+msgstr "내가 리뷰 해야 할 머지 리퀘스트"
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
@@ -30675,6 +31189,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30747,6 +31264,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -30801,6 +31321,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -30885,9 +31408,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31086,6 +31606,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31098,6 +31621,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31173,6 +31699,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31228,7 +31757,7 @@ msgid "Select a group to invite"
msgstr "초대 í•  그룹 ì„ íƒ"
msgid "Select a label"
-msgstr ""
+msgstr "ë¼ë²¨ ì„ íƒ"
msgid "Select a milestone"
msgstr ""
@@ -31326,6 +31855,9 @@ msgstr "머신 타입 ì„¤ì •ì„ ìœ„í•´ 프로ì íŠ¸ì™€ ì¡´ì„ ì„ íƒí•˜ì„¸ìš”."
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31333,7 +31865,7 @@ msgid "Select projects"
msgstr "프로ì íŠ¸ ì„ íƒ"
msgid "Select reviewer(s)"
-msgstr ""
+msgstr "리뷰어 ì„ íƒí•˜ê¸°"
msgid "Select shards to replicate"
msgstr ""
@@ -31677,6 +32209,12 @@ msgstr "ê¸°ë³¸ê°’ì„ ì„¤ì •í•˜ê³  공개 ìˆ˜ì¤€ì„ ì œí•œí•˜ì‹­ì‹œì˜¤. 소스 ê°
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -31833,6 +32371,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32529,6 +33070,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -32938,13 +33482,13 @@ msgid "Start a new discussion…"
msgstr ""
msgid "Start a new merge request"
-msgstr ""
+msgstr "새 머지 리퀘스트 만들기"
msgid "Start a new merge request with these changes"
msgstr ""
msgid "Start a review"
-msgstr ""
+msgstr "리뷰 시작"
msgid "Start by choosing a group to start exploring the merge requests in that group. You can then proceed to filter by projects, labels, milestones and authors."
msgstr ""
@@ -32973,9 +33517,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr "시작ë¨"
@@ -33372,6 +33913,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -33520,7 +34067,7 @@ msgid "Successfully unlocked"
msgstr ""
msgid "Successfully updated %{last_updated_timeago}."
-msgstr ""
+msgstr "성공ì ìœ¼ë¡œ %{last_updated_timeago}ì— ì—…ë°ì´íŠ¸í–ˆìŠµë‹ˆë‹¤."
msgid "Successfully updated the environment."
msgstr ""
@@ -33807,6 +34354,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -33880,7 +34445,7 @@ msgid "Tagged this commit to %{tag_name}."
msgstr ""
msgid "Tags"
-msgstr ""
+msgstr "태그 "
msgid "Tags are deleted until the timeout is reached. Any remaining tags are included the next time the policy runs. To remove the time limit, set it to 0."
msgstr ""
@@ -34073,9 +34638,23 @@ msgid "Terraform|%{number} Terraform report was generated in your pipelines"
msgid_plural "Terraform|%{number} Terraform reports were generated in your pipelines"
msgstr[0] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34106,6 +34685,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34118,6 +34700,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34154,12 +34739,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34442,6 +35036,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34563,9 +35160,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34575,9 +35169,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34650,7 +35241,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -34905,9 +35496,6 @@ msgstr "표시할 ì´ìŠˆê°€ 없습니다"
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr "ì•„ì§ ë¼ë²¨ì´ 없습니다."
-
msgid "There are no matching files"
msgstr "ì¼ì¹˜í•˜ëŠ” 파ì¼ì´ 없습니다"
@@ -34984,13 +35572,13 @@ msgid "There was a problem fetching epics."
msgstr ""
msgid "There was a problem fetching groups."
-msgstr ""
+msgstr "ê·¸ë£¹ì„ ê°€ì ¸ì˜¤ëŠ” ì¤‘ì— ë¬¸ì œê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤."
msgid "There was a problem fetching iterations."
msgstr ""
msgid "There was a problem fetching labels."
-msgstr ""
+msgstr "ë¼ë²¨ì„ 가져오는 ì¤‘ì— ë¬¸ì œê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤."
msgid "There was a problem fetching linked pipelines."
msgstr ""
@@ -35253,6 +35841,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35265,9 +35856,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35292,6 +35880,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr "ì´ ì‘ìš© í”„ë¡œê·¸ëž¨ì€ ë‹¤ìŒì„ 수행 í•  수 있습니다."
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35406,6 +35997,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35571,6 +36165,9 @@ msgstr "ì´ ìž‘ì—…ì—는 ìˆ˜ë™ ìž‘ì—…ì´ í•„ìš”í•©ë‹ˆë‹¤."
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -35956,7 +36553,7 @@ msgid "Time until first merge request"
msgstr "첫 번째 머지 리퀘스트(MR)ê¹Œì§€ì˜ ì‹œê°„"
msgid "Time zone"
-msgstr ""
+msgstr "시간대"
msgid "TimeTrackingEstimated|Est"
msgstr "Est"
@@ -36281,6 +36878,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36347,6 +36947,39 @@ msgstr "í•  ì¼ í•­ëª©ì´ ì„±ê³µì ìœ¼ë¡œ 완료로 표시ë˜ì—ˆìŠµë‹ˆë‹¤."
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36521,6 +37154,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36642,15 +37278,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36675,9 +37302,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37261,16 +37885,16 @@ msgid "Upgrade your plan"
msgstr ""
msgid "Upload"
-msgstr ""
+msgstr "업로드"
msgid "Upload CSV file"
msgstr "CSV íŒŒì¼ ì—…ë¡œë“œ"
msgid "Upload File"
-msgstr ""
+msgstr "íŒŒì¼ ì—…ë¡œë“œ"
msgid "Upload License"
-msgstr ""
+msgstr "ë¼ì´ì„ ìŠ¤ 업로드"
msgid "Upload New File"
msgstr "새 íŒŒì¼ ì—…ë¡œë“œ"
@@ -37282,19 +37906,19 @@ msgid "Upload a private key for your certificate"
msgstr ""
msgid "Upload an image"
-msgstr ""
+msgstr "ì´ë¯¸ì§€ 업로드"
msgid "Upload file"
msgstr "íŒŒì¼ ì—…ë¡œë“œ"
msgid "Upload image"
-msgstr ""
+msgstr "ì´ë¯¸ì§€ 업로드"
msgid "Upload license"
-msgstr ""
+msgstr "ë¼ì´ì„ ìŠ¤ 업로드"
msgid "Upload new file"
-msgstr ""
+msgstr "새 íŒŒì¼ ì—…ë¡œë“œ"
msgid "Upload object map"
msgstr ""
@@ -37305,9 +37929,6 @@ msgstr "업로드하려면 í´ë¦­í•˜ì‹­ì‹œì˜¤."
msgid "Uploading changes to terminal"
msgstr "터미ë„ì— ë³€ê²½ 사항 업로드 중"
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -37840,7 +38461,7 @@ msgid "UserList|Delete %{name}?"
msgstr ""
msgid "UserList|created %{timeago}"
-msgstr ""
+msgstr "%{timeago} ì „ ìƒì„±ë¨"
msgid "UserProfile|(Busy)"
msgstr ""
@@ -38199,16 +38820,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38250,6 +38871,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38272,6 +38896,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38300,6 +38927,12 @@ msgstr ""
msgid "View group labels"
msgstr "그룹 ë¼ë²¨ 보기"
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38391,6 +39024,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38472,12 +39108,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38505,6 +39153,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38574,9 +39225,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38592,21 +39252,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr "설명"
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38616,6 +39288,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38640,6 +39315,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38763,6 +39447,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -38850,6 +39537,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -38886,6 +39579,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -38896,7 +39598,7 @@ msgid "Webhooks|URL is triggered by a push to the repository"
msgstr ""
msgid "Webhooks|URL is triggered when a confidential issue is created, updated, closed, or reopened"
-msgstr ""
+msgstr "기밀 ì´ìŠˆê°€ ìƒì„±, ì—…ë°ì´íŠ¸, 종료 ë˜ëŠ” 다시 열릴 ë•Œ URLì´ íŠ¸ë¦¬ê±°ë©ë‹ˆë‹¤."
msgid "Webhooks|URL is triggered when a deployment starts, finishes, fails, or is canceled"
msgstr ""
@@ -38923,7 +39625,7 @@ msgid "Webhooks|URL is triggered when a wiki page is created or updated"
msgstr ""
msgid "Webhooks|URL is triggered when an issue is created, updated, closed, or reopened"
-msgstr ""
+msgstr "ì´ìŠˆê°€ ìƒì„±, ì—…ë°ì´íŠ¸, 종료 ë˜ëŠ” 다시 열릴 ë•Œ URLì´ íŠ¸ë¦¬ê±°ë©ë‹ˆë‹¤."
msgid "Webhooks|URL is triggered when someone adds a comment"
msgstr ""
@@ -38943,6 +39645,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -38974,11 +39685,14 @@ msgid "Welcome to GitLab, %{first_name}!"
msgstr ""
msgid "Welcome to GitLab,%{br_tag}%{name}!"
-msgstr ""
+msgstr "GitLabì— ì˜¤ì‹  ê²ƒì„ í™˜ì˜í•©ë‹ˆë‹¤, %{br_tag}%{name}!"
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -38988,9 +39702,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -39155,10 +39866,10 @@ msgid "WikiEmpty|Suggest wiki improvement"
msgstr ""
msgid "WikiEmpty|The wiki lets you write documentation for your group"
-msgstr ""
+msgstr "위키를 사용하면 ê·¸ë£¹ì— ëŒ€í•œ 문서를 작성할 수 있습니다."
msgid "WikiEmpty|The wiki lets you write documentation for your project"
-msgstr ""
+msgstr "위키를 사용하면 프로ì íŠ¸ì— 대한 문서를 작성할 수 있습니다."
msgid "WikiEmpty|This group has no wiki pages"
msgstr ""
@@ -39263,7 +39974,7 @@ msgid "WikiPage|Tip: You can move this page by adding the path to the beginning
msgstr ""
msgid "WikiPage|Tip: You can specify the full path for the new file. We will automatically create any missing directories."
-msgstr ""
+msgstr "íŒ: 새 파ì¼ì˜ ì „ì²´ 경로를 지정할 수 있습니다. 누ë½ëœ 디렉토리는 ìžë™ìœ¼ë¡œ ìƒì„±ë©ë‹ˆë‹¤."
msgid "WikiPage|Title"
msgstr ""
@@ -39284,7 +39995,7 @@ msgid "WikiPage|Use the new editor"
msgstr ""
msgid "WikiPage|Write your content or drag files here…"
-msgstr ""
+msgstr "ì—¬ê¸°ì— ë‚´ìš©ì„ ìž‘ì„±í•˜ê±°ë‚˜ 파ì¼ì„ 드래그하세요…"
msgid "Wikis"
msgstr ""
@@ -39362,13 +40073,13 @@ 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 ""
@@ -39446,7 +40157,7 @@ msgid "You are going to delete %{project_full_name}. Deleted projects CANNOT be
msgstr ""
msgid "You are going to remove %{group_name}. This will also delete all of its subgroups and projects. Removed groups CANNOT be restored! Are you ABSOLUTELY sure?"
-msgstr ""
+msgstr "%{group_name}ì„ ì œê±°í•©ë‹ˆë‹¤. ì´ì— ë”°ë¼ ëª¨ë“  하위 그룹과 프로ì íŠ¸ë„ ì‚­ì œë©ë‹ˆë‹¤. ì œê±°ëœ ê·¸ë£¹ì€ ë³µì›í•  수 없습니다! ì •ë§ë¡œ 제거하시겠습니까?"
msgid "You are going to remove the fork relationship from %{project_full_name}. Are you ABSOLUTELY sure?"
msgstr ""
@@ -39596,10 +40307,10 @@ msgid "You can invite a new member to %{project_name} or invite another group."
msgstr ""
msgid "You can invite a new member to %{project_name}."
-msgstr ""
+msgstr "%{project_name} ì— ìƒˆ 회ì›ì„ 초대할 수 있습니다."
msgid "You can invite a new member to %{strong_start}%{group_name}%{strong_end}."
-msgstr ""
+msgstr "%{strong_start}%{group_name}%{strong_end} ì— ìƒˆ 회ì›ì„ 초대할 수 있습니다."
msgid "You can invite another group to %{project_name}."
msgstr ""
@@ -39752,7 +40463,7 @@ msgid "You don't have sufficient permission to perform this action."
msgstr ""
msgid "You don't have write access to the source branch."
-msgstr ""
+msgstr "ì´ ì†ŒìŠ¤ ë¸Œëžœì¹˜ì— ì“°ê¸° ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤."
msgid "You don’t have access to Productivity Analytics in this group"
msgstr ""
@@ -39824,6 +40535,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr "ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤."
@@ -39945,7 +40662,7 @@ msgid "You will receive notifications for any activity"
msgstr "모든 활ë™ì— 대한 ì•Œë¦¼ì„ ë°›ê²Œë©ë‹ˆë‹¤."
msgid "You will receive notifications only for comments in which you were @mentioned"
-msgstr "ë‹¹ì‹ ì€ ë‹¹ì‹ ì´ @mentioned í•œ ì½”ë©˜íŠ¸ì— ëŒ€í•´ì„œë§Œ 통지를 받게ë©ë‹ˆë‹¤."
+msgstr "ë‹¹ì‹ ì´ @멘션 ëœ ëŒ“ê¸€ì— ëŒ€í•´ì„œë§Œ 알림를 받게ë©ë‹ˆë‹¤."
msgid "You won't be able to create new projects because you have reached your project limit."
msgstr ""
@@ -40013,6 +40730,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40304,6 +41027,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40427,7 +41153,7 @@ msgid "any-approver for the merge request already exists"
msgstr ""
msgid "any-approver for the project already exists"
-msgstr ""
+msgstr "ì´ë¯¸ 프로ì íŠ¸ 승ì¸ìžê°€ 존재합니다."
msgid "approved by: "
msgstr ""
@@ -40541,6 +41267,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40571,7 +41300,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40619,8 +41348,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgid "ciReport|Browser performance test metrics: No changes"
@@ -40713,8 +41442,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgid "ciReport|Load performance test metrics results are being parsed"
@@ -40866,7 +41595,7 @@ msgid "comment"
msgstr ""
msgid "commented on %{link_to_project}"
-msgstr ""
+msgstr "%{link_to_project}ì— ëŒ“ê¸€ì„ ë‹¬ì•˜ìŠµë‹ˆë‹¤."
msgid "commit %{commit_id}"
msgstr ""
@@ -40874,6 +41603,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -40887,7 +41619,7 @@ msgid "contains invalid URLs (%{urls})"
msgstr ""
msgid "contribute to this project."
-msgstr ""
+msgstr "ì´ í”„ë¡œì íŠ¸ì— 기여하기"
msgid "could not read private key, is the passphrase correct?"
msgstr "ê°œì¸ í‚¤ë¥¼ ì½ì„ 수 없습니다. 암호가 맞습니까?"
@@ -40908,10 +41640,10 @@ msgid "created %{timeAgoString} by %{user} in Jira"
msgstr ""
msgid "created %{timeAgo}"
-msgstr ""
+msgstr "%{timeAgo} ì „ ìƒì„±ë¨"
msgid "created %{timeAgo} by %{author}"
-msgstr ""
+msgstr "%{timeAgo} ì „ %{author}ì— ì˜í•´ ìƒì„±ë¨"
msgid "created by"
msgstr ""
@@ -41083,7 +41815,7 @@ msgid "group's CI/CD settings."
msgstr ""
msgid "groups"
-msgstr ""
+msgstr "그룹"
msgid "has already been linked to another vulnerability"
msgstr ""
@@ -41304,7 +42036,7 @@ msgid_plural "merge requests"
msgstr[0] "머지 리퀘스트(MR)"
msgid "merged %{timeAgo}"
-msgstr ""
+msgstr "%{timeAgo} ì „ 머지ë¨"
msgid "metric_id must be unique across a project"
msgstr ""
@@ -41312,9 +42044,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41492,7 +42221,7 @@ msgid "mrWidget|Merge blocked: denied licenses must be removed."
msgstr ""
msgid "mrWidget|Merge blocked: fast-forward merge is not possible. To merge this request, first rebase locally."
-msgstr ""
+msgstr "머지 차단ë¨: 패스트-í¬ì›Œë“œ 머지가 불가능합니다. ì´ ìš”ì²­ì„ ë¨¸ì§€í•˜ë ¤ë©´ 먼저 로컬ì—ì„œ 리베ì´ìŠ¤í•˜ì‹­ì‹œì˜¤."
msgid "mrWidget|Merge blocked: merge conflicts must be resolved."
msgstr ""
@@ -41549,7 +42278,7 @@ msgid "mrWidget|More information"
msgstr ""
msgid "mrWidget|Open in Gitpod"
-msgstr ""
+msgstr "Gitpot 으로 열기"
msgid "mrWidget|Open in Web IDE"
msgstr "Web IDEì—ì„œ 열기"
@@ -41591,13 +42320,13 @@ msgid "mrWidget|SAST and Secret Detection is not enabled."
msgstr ""
msgid "mrWidget|Set by %{merge_author} to be added to the merge train when the pipeline succeeds"
-msgstr ""
+msgstr "파ì´í”„ë¼ì¸ì´ 성공하면 머지 트레ì¸ì— 추가ë˜ë„ë¡ %{merge_author}ì— ì˜í•´ 설정ë©ë‹ˆë‹¤"
msgid "mrWidget|Set by %{merge_author} to be merged automatically when the pipeline succeeds"
-msgstr ""
+msgstr "파ì´í”„ë¼ì¸ì´ 성공하면 ìžë™ìœ¼ë¡œ 머지ë˜ë„ë¡ %{merge_author}ì— ì˜í•´ 설정ë©ë‹ˆë‹¤"
msgid "mrWidget|Set by %{merge_author} to start a merge train when the pipeline succeeds"
-msgstr ""
+msgstr "파ì´í”„ë¼ì¸ì´ 성공할 ë•Œ 머지 트레ì¸ì„ 시작하ë„ë¡ %{merge_author}ì— ì˜í•´ 설정ë©ë‹ˆë‹¤"
msgid "mrWidget|Show %{widget} details"
msgstr ""
@@ -41609,10 +42338,10 @@ 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 ""
+msgstr "ì´ ë¨¸ì§€ ë¦¬í€˜ìŠ¤íŠ¸ì— ëŒ€í•œ 파ì´í”„ë¼ì¸ì´ 완료ë˜ì§€ 않았습니다. 새 ì»¤ë°‹ì„ í‘¸ì‹œí•˜ì—¬ 오류를 수정하거나 %{linkStart}문제 í•´ê²° 문서%{linkEnd}를 확ì¸í•˜ì—¬ 가능한 다른 ìž‘ì—…ì„ í™•ì¸í•˜ì„¸ìš”."
msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure."
-msgstr ""
+msgstr "ì´ ë¨¸ì§€ ë¦¬í€˜ìŠ¤íŠ¸ì— ëŒ€í•œ 파ì´í”„ë¼ì¸ì´ 완료ë˜ì§€ 않았습니다. 새 ì»¤ë°‹ì„ í‘¸ì‰¬í•˜ì—¬ 오류를 수정하세요."
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -41627,7 +42356,7 @@ msgid "mrWidget|This merge request failed to be merged automatically"
msgstr "ì´ ë¨¸ì§€ 리퀘스트(MR)를 ìžë™ìœ¼ë¡œ ë¨¸ì§€í•˜ëŠ”ë° ì‹¤íŒ¨í•˜ì˜€ìŠµë‹ˆë‹¤."
msgid "mrWidget|To approve this merge request, please enter your password. This project requires all approvals to be authenticated."
-msgstr ""
+msgstr "ì´ ë¨¸ì§€ 리퀘스트를 승ì¸í•˜ë ¤ë©´ 비밀번호를 입력하세요. ì´ í”„ë¡œì íŠ¸ëŠ” ì¸ì¦ëœ ìƒíƒœì—서만 모든 승ì¸ì´ 가능합니다."
msgid "mrWidget|To change these default messages, edit the templates for both the merge and squash commit messages. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
@@ -41668,6 +42397,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -41756,10 +42488,10 @@ msgid "on track"
msgstr ""
msgid "only available on top-level groups."
-msgstr ""
+msgstr "최ìƒìœ„ 그룹ì—서만 사용 가능합니다."
msgid "open issue"
-msgstr ""
+msgstr "ì´ìŠˆ 열기"
msgid "opened %{timeAgo}"
msgstr "%{timeAgo}ì— ì—´ë¦¼"
@@ -41767,9 +42499,6 @@ msgstr "%{timeAgo}ì— ì—´ë¦¼"
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
@@ -41853,7 +42582,7 @@ msgid "project avatar"
msgstr ""
msgid "project bots cannot be added to other groups / projects"
-msgstr ""
+msgstr "프로ì íŠ¸ ë´‡ì€ ë‹¤ë¥¸ 그룹 / 프로ì íŠ¸ì— 추가할 수 없습니다."
msgid "project is read-only"
msgstr ""
@@ -41941,7 +42670,7 @@ msgid "scan-execution-policy: policy not applied, %{policy_path} file is missing
msgstr ""
msgid "security Reports|There was an error creating the merge request"
-msgstr ""
+msgstr "머지 리퀘스트를 ìƒì„±í•˜ëŠ” ë™ì•ˆ 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤."
msgid "severity|Blocker"
msgstr ""
@@ -42097,13 +42826,13 @@ msgid "updated"
msgstr ""
msgid "updated %{timeAgo}"
-msgstr ""
+msgstr "%{timeAgo} ì „ ì—…ë°ì´íŠ¸ ë¨"
msgid "updated %{time_ago}"
msgstr ""
msgid "uploads"
-msgstr ""
+msgstr "업로드"
msgid "user avatar"
msgstr "ì‚¬ìš©ìž ì•„ë°”íƒ€"
@@ -42118,7 +42847,7 @@ msgid "username"
msgstr "사용ìžëª…"
msgid "v%{version} published %{timeAgo}"
-msgstr ""
+msgstr "%{timeAgo} ì „ v%{version} 공개ë¨"
msgid "value for '%{storage}' must be an integer"
msgstr ""
@@ -42136,7 +42865,7 @@ msgid "via %{closed_via}"
msgstr ""
msgid "via merge request %{link}"
-msgstr ""
+msgstr "%{link}ì— ì˜í•œ 머지 리퀘스트"
msgid "view it on GitLab"
msgstr "GitLabì—ì„œ 보기"
diff --git a/locale/ku_TR/gitlab.po b/locale/ku_TR/gitlab.po
index ba6f667ede6..369003ca62e 100644
--- a/locale/ku_TR/gitlab.po
+++ b/locale/ku_TR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ku\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:58\n"
+"PO-Revision-Date: 2022-01-06 17:23\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/ky_KG/gitlab.po b/locale/ky_KG/gitlab.po
index 60ea5763e73..4230c6d6bf3 100644
--- a/locale/ky_KG/gitlab.po
+++ b/locale/ky_KG/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ky\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:59\n"
+"PO-Revision-Date: 2022-01-06 17:23\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/lt_LT/gitlab.po b/locale/lt_LT/gitlab.po
index a947780e8ca..49a136f8582 100644
--- a/locale/lt_LT/gitlab.po
+++ b/locale/lt_LT/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: lt\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:58\n"
+"PO-Revision-Date: 2022-01-06 17:23\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -717,7 +717,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -994,6 +994,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1211,6 +1214,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1329,6 +1338,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1400,6 +1412,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1776,6 +1791,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -2022,6 +2040,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -2034,12 +2061,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -2097,6 +2133,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -2121,6 +2187,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -2226,7 +2295,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2652,6 +2721,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2928,7 +3006,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -3213,6 +3291,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3603,6 +3684,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3807,6 +3891,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3834,9 +3921,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -4017,6 +4101,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -4026,6 +4113,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -4177,6 +4267,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4520,9 +4616,15 @@ msgstr[3] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4553,6 +4655,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4562,6 +4667,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4586,6 +4700,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4613,6 +4730,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4649,7 +4769,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4821,9 +4941,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4971,6 +5088,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5372,9 +5492,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5624,9 +5741,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5657,13 +5771,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr ""
-
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5675,7 +5786,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5687,9 +5801,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5877,7 +5997,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -6242,7 +6362,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -6251,6 +6374,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6290,6 +6416,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6996,7 +7125,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -7262,9 +7391,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7475,6 +7601,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7493,9 +7622,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7649,12 +7784,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7667,6 +7817,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7682,9 +7838,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7730,12 +7892,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7811,6 +7982,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7829,12 +8003,28 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7844,6 +8034,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -9033,6 +9226,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9458,6 +9660,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9549,6 +9754,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9780,12 +9988,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9816,9 +10030,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -10158,9 +10369,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -10191,6 +10399,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -10233,9 +10444,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -10245,13 +10453,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10431,15 +10642,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10449,15 +10678,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10608,15 +10846,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11307,6 +11536,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11586,6 +11818,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11619,15 +11854,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11766,6 +11995,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11790,7 +12022,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11799,6 +12031,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12617,15 +12852,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12768,6 +13003,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12903,7 +13141,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12942,6 +13180,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13885,6 +14126,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13930,9 +14174,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -14086,9 +14327,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -14173,6 +14411,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14360,9 +14601,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14555,7 +14793,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -15269,9 +15507,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15602,6 +15837,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16463,9 +16701,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16553,6 +16788,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16742,9 +16980,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16871,6 +17106,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16973,9 +17211,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -17048,6 +17295,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -17087,6 +17337,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -17120,6 +17373,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -17144,7 +17409,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -17153,7 +17418,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -17195,6 +17460,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -17222,12 +17490,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17342,6 +17616,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17396,6 +17673,9 @@ 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 ""
+
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 ""
@@ -19316,6 +19596,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19565,9 +19848,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19670,9 +19950,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19784,9 +20061,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20432,7 +20706,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20886,6 +21160,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21661,7 +21941,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22417,10 +22697,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22519,6 +22799,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -23142,6 +23425,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -23347,6 +23633,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23560,6 +23879,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23786,6 +24108,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -24207,6 +24532,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -24219,7 +24547,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24634,6 +24962,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24652,12 +24986,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24697,12 +25037,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24727,18 +25076,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24748,9 +25112,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24911,6 +25272,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25452,9 +25816,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25644,9 +26005,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25746,6 +26113,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25827,12 +26197,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -26064,6 +26428,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -26283,9 +26650,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26562,6 +26926,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26574,6 +26944,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26769,9 +27142,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -27123,6 +27493,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -27180,6 +27553,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -27264,6 +27643,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27558,6 +27940,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27684,6 +28108,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27936,19 +28363,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -28104,6 +28528,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28488,9 +28921,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28503,9 +28933,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28530,9 +28957,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28614,6 +29038,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28659,9 +29086,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28704,6 +29137,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28719,6 +29155,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28947,6 +29386,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -29134,9 +29579,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -29179,6 +29621,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29507,10 +29997,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -30206,6 +30696,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -30215,6 +30708,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30415,9 +30914,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30439,6 +30935,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30490,19 +30992,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30556,6 +31061,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30601,6 +31109,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30610,7 +31121,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30679,7 +31193,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30697,6 +31211,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30958,6 +31475,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30979,9 +31499,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -31284,6 +31801,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -31356,6 +31876,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31410,6 +31933,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31494,9 +32020,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31695,6 +32218,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31707,6 +32233,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31782,6 +32311,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31935,6 +32467,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -32286,6 +32821,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32442,6 +32983,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -33147,6 +33691,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33591,9 +34138,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33990,6 +34534,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34425,6 +34975,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34697,9 +35265,29 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34730,6 +35318,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34742,6 +35333,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34778,12 +35372,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -35075,6 +35678,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -35199,9 +35805,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -35211,9 +35814,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -35286,7 +35886,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35541,9 +36141,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35889,6 +36486,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35901,9 +36501,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35928,6 +36525,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -36042,6 +36642,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -36207,6 +36810,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36923,6 +37529,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36989,6 +37598,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -37163,6 +37805,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -37287,15 +37932,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -37320,9 +37956,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37950,9 +38583,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38844,16 +39474,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38895,6 +39525,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38920,6 +39553,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38951,6 +39587,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -39045,6 +39687,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -39126,12 +39771,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39159,6 +39816,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39228,9 +39888,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -39246,21 +39915,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -39270,6 +39951,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -39294,6 +39978,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -39417,6 +40110,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39504,6 +40200,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39540,6 +40242,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39597,6 +40308,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39633,6 +40353,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39642,9 +40365,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40484,6 +41204,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40673,6 +41399,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40964,6 +41696,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -41210,6 +41945,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -41240,7 +41978,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -41288,8 +42026,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41385,8 +42123,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41552,6 +42290,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42008,9 +42749,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -42370,6 +43108,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42469,9 +43210,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/mk_MK/gitlab.po b/locale/mk_MK/gitlab.po
index 18d95943eea..43a30dde9c1 100644
--- a/locale/mk_MK/gitlab.po
+++ b/locale/mk_MK/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: mk\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:58\n"
+"PO-Revision-Date: 2022-01-06 17:23\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/mn_MN/gitlab.po b/locale/mn_MN/gitlab.po
index da613f2d5cf..4f3ea7851de 100644
--- a/locale/mn_MN/gitlab.po
+++ b/locale/mn_MN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: mn\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:59\n"
+"PO-Revision-Date: 2022-01-06 17:23\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/nb_NO/gitlab.po b/locale/nb_NO/gitlab.po
index fd88c15a78d..c2a65db27ba 100644
--- a/locale/nb_NO/gitlab.po
+++ b/locale/nb_NO/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: nb\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 19:00\n"
+"PO-Revision-Date: 2022-01-06 17:24\n"
msgid " %{start} to %{end}"
msgstr " %{start} til %{end}"
@@ -563,8 +563,8 @@ msgstr "%{deployLinkStart}Bruke en mal for å distribuere til ECS%{deployLinkEnd
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr "%{description}- Sentry-hendelse: %{errorUrl}- Først sett: %{firstSeen}- Senest sett: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
-msgstr "%{doc_link_start}Avansert søk%{doc_link_end} er deaktivert siden %{ref_elem} ikke er standardgrenen; %{default_branch_link_start}søk på %{default_branch} stedet for%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
+msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
msgstr "%{doc_link_start}Avansert søk%{doc_link_end} er aktivert."
@@ -838,6 +838,9 @@ msgstr "%{placeholder} er ikke en gyldig fargepalett"
msgid "%{placeholder} is not a valid theme"
msgstr "%{placeholder} er ikke et gyldig tema"
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
@@ -1035,6 +1038,12 @@ msgstr "%{userName} sin avatar"
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr "%{user_name} sin profilside"
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr "(maks størrelse 15 MB)"
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr "(fjernet)"
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ", eller "
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr "Er du sikker? Eventuelle nettadresser til RSS eller kalendre som er i br
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr "Opprettet"
@@ -1802,12 +1829,21 @@ msgstr "Innkommende E-postsjetong"
msgid "AccessTokens|It cannot be used to access any other data."
msgstr "Den kan ikke brukes til å få tilgang til noen andre data."
+msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{linkStart}reset this token%{linkEnd}."
+msgstr ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr "Konto:"
msgid "Account: %{account}"
msgstr "Konto: %{account}"
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr "Handling"
@@ -1889,6 +1955,9 @@ msgstr "Aktiv %{type} (%{token_length})"
msgid "Active Sessions"
msgstr "Aktive økter"
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "Aktivitet"
@@ -1994,7 +2063,7 @@ msgstr "Legg til ny tabell"
msgid "Add a task list"
msgstr "Legg til en oppgaveliste"
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "Feil under innlasting av statistikken. Vennligst prøv igjen"
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,8 +2774,8 @@ msgstr "Slett brukere"
msgid "AdminUsers|Delete user and contributions"
msgstr "Slette brukeren og bidragene"
-msgid "AdminUsers|Export permissions as CSV"
-msgstr "Eksporter tillatelser som CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
+msgstr ""
msgid "AdminUsers|External"
msgstr "Ekstern"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr "Alle eposer"
msgid "All groups and projects"
msgstr "Alle grupper og prosjekter"
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr "Alle saker for denne milepælen er lukket."
@@ -3575,6 +3659,9 @@ msgstr "En feil har oppstått"
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr "En feil oppstod under tillegging av et utkast til tråden."
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr "En feil oppstod under forhåndsvisning av blobben"
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr "Det oppstod en feil under innlasting av fletteforespørsler."
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr "En feil oppstod under innlasting av dataene. Vennligst prøv igjen."
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] "%{count} godkjenninger kreves fra %{membersCount}"
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr "%{firstLabel} +%{numberOfAdditionalLabels} til"
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr "Legg til godkjennere"
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr "Alle skannere"
@@ -4305,6 +4407,9 @@ msgstr "Godkjennertype"
msgid "ApprovalRule|Approvers"
msgstr "Godkjennere"
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr "Navn"
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr "Alvorlighetsgrader"
msgid "ApprovalRule|Target branch"
msgstr "MÃ¥lgren"
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr "Er du sikker på at du vil innflette umiddelbart?"
msgid "Are you sure you want to re-deploy this environment?"
msgstr "Er du sikker på at du vil distribuere dette miljøet på nytt?"
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr "Er du sikker på at du vil regenerere den offentlige nøkkelen? Du vil måtte oppdatere den offentlige nøkkelen på fjerntjeneren før speiling vil fungere igjen."
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr "Tilordne godkjenner"
msgid "Assign reviewer(s)"
msgstr "Tilordne godkjenner(e)"
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr "Tildel noen saker til denne milepælen."
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr "Avatar for %{assigneeName}"
-msgid "Avatar for %{name}"
-msgstr "Avatar for %{name}"
-
msgid "Avatar will be removed. Are you sure?"
msgstr "Avataren vil bli fjernet. Er du sikker?"
@@ -5370,9 +5487,6 @@ msgstr "månedlig"
msgid "BillingPlans|per user"
msgstr "per bruker"
-msgid "BillingPlan|Contact sales"
-msgstr "Kontakt salgsavdelingen"
-
msgid "BillingPlan|Upgrade"
msgstr "Oppgrader"
@@ -5403,15 +5517,12 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
-msgstr "Brukeren ble vellykket validert"
-
msgid "Billings|User validation required"
msgstr ""
@@ -5421,7 +5532,10 @@ msgstr "Valider konto"
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr "Kan ikke fjerne brukeren"
@@ -5621,7 +5741,7 @@ msgstr "Vektlegging"
msgid "Boards"
msgstr "Bord"
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr "Eksisterende grupper"
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 ""
+
msgid "BulkImport|From source group"
msgstr "Fra kildegruppe"
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr "Sjekker brukernavnets tilgjengelighet …"
msgid "Checkout"
msgstr "Kasse"
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr "Velg hvilken som helst farge."
msgid "Choose file…"
msgstr "Velg fil …"
-msgid "Choose labels"
-msgstr "Velg stempler"
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr "Tøm måldato"
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr "Tøm nylige søk"
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr "Tøm vektlegging"
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr "Tømte vektleggingen."
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr "Tømmer vektleggingen."
@@ -7383,12 +7518,27 @@ msgstr "Klynge-nivå"
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr "Tilgangssjetonger"
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
msgid "ClusterAgents|An unknown error occurred. Please try again."
msgstr "En ukjent feil oppstod. Vennligst prøv igjen."
+msgid "ClusterAgents|Are you sure you want to delete this agent? You cannot undo this."
+msgstr ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr "Opprettet av %{name} den %{time}"
msgid "ClusterAgents|Date created"
msgstr "Dato opprettet"
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr "Beskrivelse"
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr "Ukjent bruker"
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr "Komponent"
@@ -9186,6 +9386,9 @@ msgstr "Ikke planlagt ennå"
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr "Publisert den %{timeInfo}"
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr "Kopier miljø"
msgid "Copy evidence SHA"
msgstr "Kopier bevis-SHA"
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr "Kopier filinnhold"
msgid "Copy file path"
msgstr "Kopier filbanen"
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr "Kopier nøkkel"
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr "Kopier denne verdien"
-
msgid "Copy to clipboard"
msgstr "Kopier til utklippstavle"
@@ -9884,9 +10093,6 @@ msgstr "Opprett ny stempel"
msgid "Create new project"
msgstr "Opprett et nytt prosjekt"
-msgid "Create new..."
-msgstr "Opprett ny..."
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr "Opprett bruker"
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr "Opprett jokertegn: %{searchTerm}"
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr "Opprett verdistrøm"
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr "Kritiske sårbarheter til stede"
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr "Vil du tilpasse denne siden?"
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr "GÃ¥ til preferansene"
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr "Denne siden viser en liste over prosjektene dine som standard, men den kan endres til å vise prosjektenes aktivitet, grupper, din oppgaveliste, tilordnede saker, tilordnede flettforespørsler og mer. Du kan endre dette under «Hjemmesideinnhold» i dine preferanser"
-
msgid "Cycle Time"
msgstr "Syklustid"
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr "Dato"
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr "Datovelger"
@@ -11306,6 +11536,9 @@ msgstr "Slett brukerliste"
msgid "Delete variable"
msgstr "Slett variabel"
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr "Slett %{name}"
msgid "Deleted"
msgstr "Slettet"
-msgid "Deleted Projects"
-msgstr "Slettede prosjekter"
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr "Slettede prosjekter"
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr "Gi tilbakemelding på denne siden"
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr "Begynn en gratis prøveperiode"
@@ -12464,6 +12697,9 @@ msgstr "Last ned (%{size})"
msgid "Download CSV"
msgstr "Last ned CSV"
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr "Last ned artefakter"
@@ -12599,7 +12835,7 @@ msgstr "Rediger milepæl"
msgid "Edit Password"
msgstr "Rediger passord"
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr "Rediger beskrivelse"
msgid "Edit environment"
msgstr "Rediger miljø"
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr "Noe gikk galt under sortering av gjenstand."
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr "Feil under opprettelse av utdrag"
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr "Feil under opplasting av fil: %{stripped}"
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr "Alle"
-
msgid "Everyone With Access"
msgstr "Alle med tilgang"
@@ -14247,7 +14483,7 @@ msgstr "Eksporter prosjekt"
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr "Filtrer etter 2-trinnsautentisering"
-
msgid "Filter by user"
msgstr "Filtrer etter user"
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr "Full"
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr "Fullt navn"
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr "Gå til målinger"
msgid "Go to next page"
msgstr "GÃ¥ til neste side"
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr "Gruppe-URL"
-msgid "Group Wikis"
-msgstr "Gruppe-wikier"
-
msgid "Group application: %{name}"
msgstr "Gruppeprogram: %{name}"
@@ -16557,6 +16790,9 @@ msgstr "Gruppen ble eksportert"
msgid "Group was successfully updated."
msgstr "Gruppen ble vellykket oppdatert."
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr "Gruppe: %{group_name}"
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr "Ingen samsvarende resultater"
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr "Merker"
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,8 +17102,8 @@ msgstr "Kan ikke oppdatere filbanen fordi det er prosjekter innenfor denne grupp
msgid "GroupSettings|Change group URL"
msgstr "Endre gruppe-URL"
-msgid "GroupSettings|Changing group URL can have unintended side effects."
-msgstr "Endring av gruppe-URL-en kan ha utilsiktede bivirkninger."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
+msgstr ""
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr "Ugyldig OS"
msgid "Invalid URL"
msgstr "Ugyldig URL"
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr "Inviter teammedlemmer"
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr "Inviter medlem"
-
msgid "InviteMember|Invite Members (optional)"
msgstr "Inviter medlemmer (valgfritt)"
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr "Er blokkert av"
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr "Bruker lisenssetet:"
@@ -19458,9 +19733,6 @@ msgstr "Status"
msgid "IssueAnalytics|Weight"
msgstr "Vektlegging"
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr "Bord"
@@ -20106,8 +20378,8 @@ msgstr ""
msgid "Job|Download"
msgstr "Last ned"
-msgid "Job|Erase job log"
-msgstr "Slett jobblogg"
+msgid "Job|Erase job log and artifacts"
+msgstr ""
msgid "Job|Job artifacts"
msgstr "Jobb-artefakter"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr "Ledetid"
@@ -21319,7 +21597,7 @@ msgstr "Manuell"
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr "Mere informasjon."
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr "Mer enn %{number_commits_distance} commiter er annerledes fra %{default_branch}"
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr "Navigasjonslinje"
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr "Hjelp"
@@ -23212,6 +23529,9 @@ msgstr "Ny"
msgid "New %{issueType}"
msgstr "Ny %{issueType}"
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr "Ny applikasjon"
@@ -23436,6 +23756,9 @@ msgstr "Neste design"
msgid "Next file in diff"
msgstr "Neste fil i diff"
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr "Bemerk: Vurder å spørre din GitLab-administrator om å konfigurere %{g
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr "Bemerk: Vurder å spørre din GitLab-administrator om å konfigurere %{github_integration_link}, som vil tillate innlogging via GitHub og tillate å importere til kodelagre uten å generere en personlig tilgangssjetong."
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr "Notis"
@@ -23867,7 +24193,7 @@ msgstr "Er du sikker på at du vil avbryte opprettelsen av denne kommentaren?"
msgid "Notes|Collapse replies"
msgstr "Klapp sammen svar"
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr "Beskrivelse (valgfritt)"
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr "Lagre skanning"
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr "Bruk eksisterende sideprofil"
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr "Handlingen er ikke tillatt"
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr "Siden ble ikke funnet"
msgid "Page settings"
msgstr "Sideinnstillinger"
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr "Aktiv"
@@ -25280,9 +25639,15 @@ msgstr "Fagfellevurdering av"
msgid "Pending"
msgstr "I kø"
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr "Avventende kommentarer"
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr "Periode i sekunder"
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr "Rørlednings-URL"
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr "Bestått"
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr "Vennligst velg"
@@ -26210,6 +26578,9 @@ msgstr "Vennligst velg et land"
msgid "Please select a file"
msgstr "Vennligst velg en fil"
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr "Vennligst velg en gruppe."
@@ -26405,9 +26776,6 @@ msgstr "Tidspreferanser"
msgid "Preferences|Use relative times"
msgstr "Bruk relative tidspunkter"
-msgid "Press %{key}-C to copy"
-msgstr "Trykk %{key}-C for å kopiere"
-
msgid "Prev"
msgstr "Forrige"
@@ -26759,6 +27127,9 @@ msgstr "Ugyldig passord"
msgid "Profiles|Invalid username"
msgstr "Ugyldig brukernavn"
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr "Nøkkel"
@@ -26816,6 +27187,12 @@ msgstr "Private bidrag"
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr "Offentlig avatar"
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr "Hva er statusen din?"
@@ -27194,6 +27574,48 @@ msgstr "Kopier prosjekt-ID"
msgid "ProjectPage|Project ID: %{project_id}"
msgstr "Prosjekt-ID: %{project_id}"
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr "eller gruppe"
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr "iOS (Swift)"
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr "Prosjekt"
@@ -28124,9 +28555,6 @@ msgstr "Det avansert søket i GitLab er en kraftig søketjeneste som sparer deg
msgid "Promotions|This feature is locked."
msgstr "Denne funksjonen er låst."
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr "Prøv det gratis"
@@ -28139,9 +28567,6 @@ msgstr "Oppgrader planen din for å skru på avansert søking."
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr "Når du har mange saker, kan det være vanskelig å få oversikt. Ved å vektlegge dine problemstillinger, kan du få en bedre idé om innsatsen, kostnaden, nødvendig tid eller deres verdier, og så å kunne behandle dem bedre."
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr "Gren"
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr "Gren:"
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr "%{environment_name} vil være skrivbar for utviklere. Er du sikker?"
@@ -28340,6 +28771,9 @@ msgstr "Miljøet ditt er beskyttet."
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "Miljøet ditt er blitt ubeskyttet"
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr "Beskyttede etiketter"
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr "README"
@@ -28768,9 +29211,6 @@ msgstr "Regenerer eksport"
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr "Registrer med 2-trinnsapp"
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr "Kasse"
@@ -29139,11 +29627,11 @@ msgstr "Fjernet tidsestimat."
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
-msgstr "Du har ikke fjernet noen prosjekter."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
+msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
msgstr "Fjerner %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr "Fortsett"
msgid "Resync"
msgstr "Re-synk"
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr "Forsøk igjen"
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr "Prøv denne jobben på nytt"
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr "Arkitektur"
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,10 +30606,16 @@ msgstr ""
msgid "Runners|Name"
msgstr "Navn"
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
+msgstr ""
+
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
@@ -30118,9 +30624,6 @@ msgstr ""
msgid "Runners|Not available to run jobs"
msgstr ""
-msgid "Runners|Not connected"
-msgstr "Ikke tilkoblet"
-
msgid "Runners|Offline"
msgstr "Frakoblet"
@@ -30172,6 +30675,9 @@ msgstr "Runner"
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr "Etiketter"
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr "gruppe"
msgid "Runners|locked"
msgstr "låst"
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr "delt"
msgid "Runners|specific"
msgstr "spesifikk"
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr "Kjører"
@@ -30574,6 +31089,9 @@ msgstr "Søk etter denne teksten"
msgid "Search forks"
msgstr "Velg utgreininger"
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr "Søk blant iterasjoner"
@@ -30595,9 +31113,6 @@ msgstr "Søk eller filtrer resultater …"
msgid "Search or filter results…"
msgstr "Søk blant eller filtrer resultater …"
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr "Søk i prosjekt"
@@ -30878,6 +31393,9 @@ msgstr "Skru på %{feature}"
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr "Aktiver Auto DevOps"
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr "Skrudd på"
@@ -30950,6 +31468,9 @@ msgstr "%{branches} %{plural}"
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr "%{branches} og %{lastBranch} %{plural}"
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr "Handling"
@@ -31004,6 +31525,9 @@ msgstr "Nettverk"
msgid "SecurityOrchestration|New policy"
msgstr "Ny retningslinje"
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr "vis resultater"
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr "+%{count} til"
@@ -31289,6 +31810,9 @@ msgstr "Sett status"
msgid "SecurityReports|Severity"
msgstr "Alvorlighet"
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr "Status"
msgid "SecurityReports|Take survey"
msgstr "Ta undersøkelse"
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr "Velg prosjekt og sone for å velge maskintype"
msgid "Select project to choose zone"
msgstr "Velg prosjekt for å velge sone"
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr "Bestem måldato"
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr "Velg iterasjon"
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr "Noe gikk galt under oppdatering av et krav."
msgid "Something went wrong while updating assignees"
msgstr "Noe gikk galt under oppdatering av tilordnede"
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr "Noe gikk galt under oppdatering av listeinnstillingene dine"
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr "Begynn din gratis prøveperiode"
-msgid "Start your trial"
-msgstr "Begynn prøveperioden din"
-
msgid "Started"
msgstr "Startet"
@@ -33578,6 +34120,12 @@ msgstr "Abonnementet ble vellykket opprettet."
msgid "Subscription successfully deleted."
msgstr "Abonnementet ble vellykket slettet."
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr "Legg til seter"
@@ -34013,6 +34561,24 @@ msgstr "Syntaksen er korrekt."
msgid "Syntax is incorrect."
msgstr "Syntaksen er feil."
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr "System"
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr "%{user} oppdaterte for %{timeAgo}"
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr "Detaljer"
msgid "Terraform|Download JSON"
msgstr "Last ned JSON"
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr "Genereringen av prosjektet forårsaket en feil."
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr "Jobbstatus"
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr "LÃ¥s"
@@ -34362,12 +34950,21 @@ msgstr "Tilstander"
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr "Gruppen kan bli fullt gjenopprettet"
-
msgid "The group export can be downloaded from:"
msgstr "Gruppeeksporteringen kan lastes ned fra:"
@@ -34787,9 +35384,6 @@ msgstr "Gruppen har allerede blitt delt med denne gruppen"
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr "Den maks tillatte filstørrelsen er %{size}."
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr "Det er ingen saker å vise"
msgid "There are no issues with the selected labels"
msgstr "Det er ingen saker med de valgte stemplene"
-msgid "There are no labels yet"
-msgstr "Det er ingen stempler ennå"
-
msgid "There are no matching files"
msgstr "Det er ingen samsvarende filer"
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr "Dette programmet vil kunne:"
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
msgstr "Denne gruppen"
+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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr "Denne jobben krever en manuell handling"
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ msgstr "For å aktivere kontoen din på nytt, logg på GitLab på %{gitlab_url}.
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 "For å motta alarmer fra manuelt konfigurerte Prometheus-tjenester, legg til den følgende URL-en og autorisasjonsnøkkelen til din Prometeus-webhook-oppsettsfil. Lær mer om %{linkStart}å sette opp Prometheus%{linkEnd} til å sende varsler til GitLab."
+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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr "For å oppklare dette, forsøk å:"
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
msgstr "I dag"
+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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr "Overfør"
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr "Overfør eierskap"
@@ -36857,15 +37496,6 @@ msgstr "Fornavn"
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr "Etternavn"
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr "bedriften din"
-
msgid "Trigger"
msgstr "Utløser"
@@ -37520,9 +38147,6 @@ msgstr "klikk for å laste opp"
msgid "Uploading changes to terminal"
msgstr "Laster opp endringer til terminalen"
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr "Oppstrøms"
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr "Verifiseringsstatus"
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr "Vis alle saker"
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr "Vis dokumentasjon"
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr "Vis kvalifiserte godkjennere"
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr "Vis gruppeetiketter"
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr "Vist"
msgid "Viewing commit"
msgstr "Viser commit"
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr "Synlighet"
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr "Endre status"
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+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."
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr "Ytterligere info"
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr "Klasse"
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr "Kommentarer"
@@ -38810,21 +39473,33 @@ msgstr "Krasjtype"
msgid "Vulnerability|Description"
msgstr "Beskrivelse"
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr "Oppdaget"
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr "Last ned"
msgid "Vulnerability|Evidence"
msgstr "Bevis"
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr "File"
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr "Identifikator"
@@ -38834,6 +39509,9 @@ msgstr "identifikatorer"
msgid "Vulnerability|Image"
msgstr "Bilde"
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr "Lenker"
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr "Skannerleverandør"
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr "Alvorlighetsgrad"
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr "Vi fant ingen sårbarheter"
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr "Skru på SSL-verifisering"
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr "Undergruppehendelser"
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr "Trigger"
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr "Wiki-sidehendelser"
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr "Velkommen, %{name}!"
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr "Hva leter du etter?"
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr "Du har ingen tillatelser"
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
msgstr "Abonnementet ditt har utløpt!"
+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 ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr "kan ikke selv bli blokkert"
msgid "cannot merge"
msgstr "kan ikke flette"
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr "%{degradedNum} degradert"
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr "Undersøk dette sikkerhetsproblemet ved å opprette en sak"
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr "commit %{commit_id}"
msgid "committed"
msgstr "forpliktet"
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr "mangler"
-msgid "more information"
-msgstr "mere informasjon"
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr "må være etter starten"
@@ -42001,9 +42736,6 @@ msgstr "Ã¥pnet %{timeAgo}"
msgid "or"
msgstr "eller"
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/nl_NL/gitlab.po b/locale/nl_NL/gitlab.po
index 44b2aee9359..4057a8d0ea8 100644
--- a/locale/nl_NL/gitlab.po
+++ b/locale/nl_NL/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: nl\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:59\n"
+"PO-Revision-Date: 2022-01-06 17:23\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "Activiteit"
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/pa_IN/gitlab.po b/locale/pa_IN/gitlab.po
index f02427c7b8b..13e17a72b29 100644
--- a/locale/pa_IN/gitlab.po
+++ b/locale/pa_IN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: pa-IN\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:59\n"
+"PO-Revision-Date: 2022-01-06 17:23\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/pl_PL/gitlab.po b/locale/pl_PL/gitlab.po
index 390d681acc5..4c8ab4554a4 100644
--- a/locale/pl_PL/gitlab.po
+++ b/locale/pl_PL/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: pl\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:58\n"
+"PO-Revision-Date: 2022-01-06 17:22\n"
msgid " %{start} to %{end}"
msgstr " %{start} do %{end}"
@@ -717,8 +717,8 @@ msgstr "%{deployLinkStart}Użyj szablonu by wdrożyć w ECS%{deployLinkEnd}, lub
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr "%{description}- Wydarzenie Sentry: %{errorUrl}- Pierwsze wystÄ…pienie: %{firstSeen}- Ostatnie wystÄ…pienie: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
-msgstr "%{doc_link_start}Zaawansowane wyszukiwanie%{doc_link_end} jest wyłączone, bo %{ref_elem} nie jest domyślnym branchem; %{default_branch_link_start}szukaj %{default_branch} zamiast%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
+msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
msgstr "%{doc_link_start}Zaawansowane wyszukiwanie%{doc_link_end} jest włączone."
@@ -994,6 +994,9 @@ msgstr "%{placeholder} nie jest prawidłowym schematem kolorów"
msgid "%{placeholder} is not a valid theme"
msgstr "%{placeholder} nie jest prawidłowym motywem"
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
@@ -1211,6 +1214,12 @@ msgstr "awatar użytkownika %{userName}"
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr "Strona profilowa %{user_name}"
@@ -1329,6 +1338,9 @@ msgstr "(pozostaw puste, jeśli nie chcesz tego zmieniać)"
msgid "(max size 15 MB)"
msgstr "(maksymalny rozmiar 15 MB)"
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr "(usunięto)"
@@ -1400,6 +1412,9 @@ msgstr ""
msgid ", or "
msgstr ", lub "
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr "- Dostępne do uruchamiania zadań."
@@ -1776,6 +1791,9 @@ msgstr "Projekt zawierający kwestie dotyczące każdego audytu w protokole kont
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr "Nazwa repozytorium projektu definiuje jego adres URL (ten, którego używasz do uzyskiwania dostępu do projektu za pośrednictwem przeglądarki) i jego miejsce na dysku plików, na którym zainstalowano GitLab. %{link_start} Dowiedz się więcej. %{link_end}"
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr "Gotowy do użycia szablon dla aplikacji Androida"
@@ -2022,6 +2040,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -2034,12 +2061,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -2097,6 +2133,36 @@ msgstr "Konto:"
msgid "Account: %{account}"
msgstr "Konto: %{account}"
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr "Akcja"
@@ -2121,6 +2187,9 @@ msgstr "Aktywne %{type} (%{token_length})"
msgid "Active Sessions"
msgstr "Aktywne Sesje"
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "Aktywność"
@@ -2226,7 +2295,7 @@ msgstr "Dodaj tabelÄ™"
msgid "Add a task list"
msgstr "Dodaj listę zadań"
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2652,6 +2721,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2928,7 +3006,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -3213,6 +3291,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3603,6 +3684,9 @@ msgstr ""
msgid "All groups and projects"
msgstr "Wszystkie grupy i projekty"
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3807,6 +3891,9 @@ msgstr "Wystapił błąd"
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr "Wystąpił błąd podczas dodawania szkicu do wątku."
@@ -3834,9 +3921,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr "Wystąpił błąd podczas usuwania etykiety."
-
msgid "An error occurred when updating the title"
msgstr "Wystąpił błąd podczas aktualizacji tytułu"
@@ -4017,6 +4101,9 @@ msgstr "Wystąpił błąd podczas ładowania merge requestów."
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -4026,6 +4113,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr "Wystąpił błąd podczas ładowania formularza tokenów dostępu, proszę, spróbuj ponownie."
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr "Wystąpił błąd podczas ładowania danych. Proszę, spróbuj ponownie."
@@ -4177,6 +4267,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4520,9 +4616,15 @@ msgstr[3] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4553,6 +4655,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4562,6 +4667,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4586,6 +4700,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4613,6 +4730,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4649,7 +4769,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4821,9 +4941,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4971,6 +5088,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5372,9 +5492,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5624,9 +5741,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5657,13 +5771,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr ""
-
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5675,7 +5786,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5687,9 +5801,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5877,7 +5997,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -6242,7 +6362,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -6251,6 +6374,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6290,6 +6416,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6996,7 +7125,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -7262,9 +7391,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7475,6 +7601,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7493,9 +7622,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7649,12 +7784,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7667,6 +7817,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7682,9 +7838,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7730,12 +7892,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7811,6 +7982,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7829,12 +8003,28 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7844,6 +8034,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -9033,6 +9226,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9458,6 +9660,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9549,6 +9754,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9780,12 +9988,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9816,9 +10030,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -10158,9 +10369,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -10191,6 +10399,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -10233,9 +10444,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -10245,13 +10453,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10431,15 +10642,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10449,15 +10678,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10608,15 +10846,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11307,6 +11536,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11586,6 +11818,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11619,15 +11854,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11766,6 +11995,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11790,7 +12022,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11799,6 +12031,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12617,15 +12852,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12768,6 +13003,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12903,7 +13141,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12942,6 +13180,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13885,6 +14126,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13930,9 +14174,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -14086,9 +14327,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -14173,6 +14411,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14360,9 +14601,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14555,7 +14793,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -15269,9 +15507,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15602,6 +15837,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16463,9 +16701,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16553,6 +16788,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16742,9 +16980,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16871,6 +17106,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16973,9 +17211,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -17048,6 +17295,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -17087,6 +17337,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -17120,6 +17373,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -17144,7 +17409,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -17153,7 +17418,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -17195,6 +17460,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -17222,12 +17490,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17342,6 +17616,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17396,6 +17673,9 @@ 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 ""
+
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 ""
@@ -19316,6 +19596,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19565,9 +19848,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19670,9 +19950,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19784,9 +20061,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20432,7 +20706,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20886,6 +21160,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21661,7 +21941,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22417,10 +22697,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22519,6 +22799,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -23142,6 +23425,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -23347,6 +23633,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23560,6 +23879,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23786,6 +24108,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -24207,6 +24532,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -24219,7 +24547,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24634,6 +24962,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24652,12 +24986,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24697,12 +25037,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24727,18 +25076,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24748,9 +25112,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24911,6 +25272,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25452,9 +25816,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25644,9 +26005,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25746,6 +26113,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25827,12 +26197,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -26064,6 +26428,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -26283,9 +26650,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26562,6 +26926,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26574,6 +26944,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26769,9 +27142,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -27123,6 +27493,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -27180,6 +27553,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -27264,6 +27643,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27558,6 +27940,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27684,6 +28108,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27936,19 +28363,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -28104,6 +28528,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28488,9 +28921,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28503,9 +28933,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28530,9 +28957,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28614,6 +29038,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28659,9 +29086,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28704,6 +29137,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28719,6 +29155,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28947,6 +29386,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -29134,9 +29579,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -29179,6 +29621,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29507,10 +29997,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -30206,6 +30696,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -30215,6 +30708,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30415,9 +30914,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30439,6 +30935,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30490,19 +30992,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30556,6 +31061,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30601,6 +31109,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30610,7 +31121,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30679,7 +31193,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30697,6 +31211,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30958,6 +31475,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30979,9 +31499,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -31284,6 +31801,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -31356,6 +31876,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31410,6 +31933,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31494,9 +32020,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31695,6 +32218,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31707,6 +32233,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31782,6 +32311,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31935,6 +32467,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -32286,6 +32821,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32442,6 +32983,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -33147,6 +33691,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33591,9 +34138,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33990,6 +34534,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34425,6 +34975,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34697,9 +35265,29 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34730,6 +35318,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34742,6 +35333,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34778,12 +35372,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -35075,6 +35678,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "Połączenie upłynie po %{timeout}. W przypadku repozytoriów, którym zajmuje to dłużej, użyj kombinacji klonuj/pchnij."
@@ -35199,9 +35805,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -35211,9 +35814,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -35286,7 +35886,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35541,9 +36141,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35889,6 +36486,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35901,9 +36501,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35928,6 +36525,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -36042,6 +36642,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -36207,6 +36810,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36923,6 +37529,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36989,6 +37598,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -37163,6 +37805,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -37287,15 +37932,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -37320,9 +37956,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37950,9 +38583,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38844,16 +39474,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38895,6 +39525,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38920,6 +39553,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38951,6 +39587,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -39045,6 +39687,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -39126,12 +39771,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39159,6 +39816,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39228,9 +39888,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -39246,21 +39915,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -39270,6 +39951,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -39294,6 +39978,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -39417,6 +40110,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39504,6 +40200,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39540,6 +40242,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39597,6 +40308,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39633,6 +40353,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39642,9 +40365,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40484,6 +41204,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40673,6 +41399,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40964,6 +41696,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -41210,6 +41945,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -41240,7 +41978,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -41288,8 +42026,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41385,8 +42123,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41552,6 +42290,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42008,9 +42749,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -42370,6 +43108,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42469,9 +43210,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/pt_BR/gitlab.po b/locale/pt_BR/gitlab.po
index e9b8494fabd..e372d5b55a4 100644
--- a/locale/pt_BR/gitlab.po
+++ b/locale/pt_BR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: pt-BR\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:56\n"
+"PO-Revision-Date: 2022-01-06 17:20\n"
msgid " %{start} to %{end}"
msgstr " %{start} até %{end}"
@@ -563,8 +563,8 @@ msgstr "%{deployLinkStart}Use um modelo para fazer deploy em ECS%{deployLinkEnd}
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr "%{description}- Evento Sentry: %{errorUrl}- Visto pela primeira vez: %{firstSeen}- Visto pela última vez: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
-msgstr "%{doc_link_start}A pesquisa avançada%{doc_link_end} está desativada porque %{ref_elem} não é o branch padrão; %{default_branch_link_start}pesquise em %{default_branch} em vez de%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
+msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
msgstr "%{doc_link_start}A pesquisa avançada%{doc_link_end} está ativada."
@@ -729,7 +729,7 @@ msgid "%{link_start}Remove the %{draft_snippet} prefix%{link_end} from the title
msgstr ""
msgid "%{link_start}Start the title with %{draft_snippet}%{link_end} to prevent a merge request draft from merging before it's ready."
-msgstr ""
+msgstr "%{link_start}Inicie o título com %{draft_snippet}%{link_end} para evitar que uma solicitação de mesclagem de código de um trabalho em andamento seja executada antes de estar pronta."
msgid "%{link_start}What information does GitLab Inc. collect?%{link_end}"
msgstr ""
@@ -838,6 +838,9 @@ msgstr "%{placeholder} não é um esquema de cores válido"
msgid "%{placeholder} is not a valid theme"
msgstr "%{placeholder} não é um tema válido"
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
@@ -1035,6 +1038,12 @@ msgstr "Avatar de %{userName}"
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr "Página de perfil de %{user_name}"
@@ -1151,6 +1160,9 @@ msgstr "(Deixe em branco se não quiser alterá-lo)"
msgid "(max size 15 MB)"
msgstr "(tamanho máximo de 15MB)"
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr "(removido)"
@@ -1172,7 +1184,7 @@ msgid "* All times are in UTC unless specified"
msgstr ""
msgid "*Required"
-msgstr ""
+msgstr "*Obrigatório"
msgid "+ %{amount} more"
msgstr "+ %{amount} mais"
@@ -1213,11 +1225,14 @@ msgid "+%{tags} more"
msgstr "+%{tags} mais"
msgid ", and "
-msgstr ""
+msgstr ", e "
msgid ", or "
msgstr ", ou "
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr "- Disponível para executar tarefas."
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr "O nome do repositório de um projeto define sua URL (aquele que você usa para acessar o projeto através de um navegador) e seu lugar no disco de arquivos onde o GitLab está instalado. %{link_start}Saber mais.%{link_end}"
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr "Um modelo pronto para uso com aplicativos do Android"
@@ -1790,6 +1808,15 @@ msgstr "Tem certeza? Todos os URLs de RSS ou de calendário atualmente em uso de
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr "Tem certeza? Todos os endereços de e-mail de issue atualmente em uso deixarão de funcionar."
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr "Copiar token de e-mail recebido"
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr "Criado"
@@ -1802,12 +1829,21 @@ msgstr "Token de e-mail recebido"
msgid "AccessTokens|It cannot be used to access any other data."
msgstr "Ele não pode ser usado para acessar outros dados."
+msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{linkStart}reset this token%{linkEnd}."
+msgstr "Mantenha este token em segredo. Qualquer pessoa que o tiver poderá acessar objetos estáticos do repositório como se fosse você. Se isso acontecer,%{linkStart} reinicie este token%{linkEnd}."
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr "Mantenha este token em segredo. Qualquer pessoa que o tiver poderá acessar objetos estáticos do repositório como se fosse você. Se isso acontecer,%{reset_link_start} reinicie este token%{reset_link_end}."
+msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{linkStart}reset this token%{linkEnd}."
+msgstr "AccessTokens|Mantenha este token em segredo. Qualquer pessoa que o tiver poderá criar issues como se fosse você. Se isso acontecer, %{linkStart}redefina o token%{linkEnd}."
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr "Mantenha este token em segredo. Qualquer pessoa que o tiver poderá criar issues como se fosse você. Se isso acontecer %{link_reset_it}."
+msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{linkStart}reset this token%{linkEnd}."
+msgstr "Mantenha este token em segredo. Qualquer pessoa que o tenha pode ler a atividade e emitir feeds RSS ou o feed do seu calendário como se fosse você. Se isso acontecer, %{linkStart}redefina o token%{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, %{link_reset_it}."
msgstr "Mantenha este token em segredo. Qualquer pessoa que o tenha pode ler a atividade e emitir feeds RSS ou o feed do seu calendário como se fosse você. Se isso acontecer, %{link_reset_it}."
@@ -1827,7 +1863,7 @@ msgid "AccessTokens|You can generate a personal access token for each applicatio
msgstr "Você pode gerar um token de acesso pessoal para cada aplicativo usado que precisa de acesso à API do GitLab."
msgid "AccessTokens|Your feed token authenticates you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar. It is visible in those feed URLs."
-msgstr ""
+msgstr "Seu token de feed o autentica quando o leitor RSS carrega um feed RSS personalizado ou quando o aplicativo de calendário carrega um calendário personalizado. É visível nesses URLs de feed."
msgid "AccessTokens|Your incoming email token authenticates you when you create a new issue by email, and is included in your personal project-specific email addresses."
msgstr "Seu token de e-mail de entrada autentica você quando você cria um novo problema por e-mail e é incluído em seus endereços de e-mail pessoais específicos do projeto."
@@ -1865,6 +1901,36 @@ msgstr "Conta:"
msgid "Account: %{account}"
msgstr "Conta: %{account}"
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr "Saiba mais."
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+msgstr "Validar sua conta"
+
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr "Ação"
@@ -1889,6 +1955,9 @@ msgstr "Ativo %{type} (%{token_length})"
msgid "Active Sessions"
msgstr "Sessões ativas"
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "Atividade"
@@ -1986,7 +2055,7 @@ msgid "Add a related issue"
msgstr "Adicionar um issue relacionada"
msgid "Add a suffix to Service Desk email address. %{linkStart}Learn more.%{linkEnd}"
-msgstr ""
+msgstr "Adicione um sufixo ao endereço de e-mail da Central de serviços. %{linkStart}Saiba mais.%{linkEnd}"
msgid "Add a table"
msgstr "Adicionar uma tabela"
@@ -1994,8 +2063,8 @@ msgstr "Adicionar uma tabela"
msgid "Add a task list"
msgstr "Adicionar uma lista de tarefas"
-msgid "Add a title…"
-msgstr ""
+msgid "Add a title..."
+msgstr "Adicionar um título..."
msgid "Add a to do"
msgstr "Adicionar uma tarefa pendente"
@@ -2352,7 +2421,7 @@ msgid "AdminArea|Maintainer"
msgstr "Mantenedor"
msgid "AdminArea|Minimal access"
-msgstr ""
+msgstr "Acesso mínimo"
msgid "AdminArea|New group"
msgstr "Novo grupo"
@@ -2420,6 +2489,15 @@ msgstr "Você parará todas as tarefas. Os processos em execução serão abrupt
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "Erro ao carregar as estatísticas. Por favor, tente novamente"
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,8 +2774,8 @@ msgstr "Apagar usuário"
msgid "AdminUsers|Delete user and contributions"
msgstr "Excluir o usuário e suas contribuições"
-msgid "AdminUsers|Export permissions as CSV"
-msgstr "Exportar permissões como CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
+msgstr ""
msgid "AdminUsers|External"
msgstr "Externo"
@@ -2961,10 +3039,10 @@ 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 ""
+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 ""
+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."
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 "Depois que a exportação for concluída, baixe o arquivo de dados do e-mail de notificação ou desta página. Você pode então importar o arquivo de dados na página %{strong_text_start}Criar novo grupo%{strong_text_end} de outra instância do GitLab."
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr "Todos os épicos"
msgid "All groups and projects"
msgstr "Todos os grupos e projetos"
+msgid "All issues"
+msgstr "Todas as issues"
+
msgid "All issues for this milestone are closed."
msgstr "Todas as issues para este marco estão fechadas."
@@ -3575,6 +3659,9 @@ msgstr "Ocorreu um erro"
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr "Ocorreu um erro ao buscar as tarefas de pipelines."
+
msgid "An error occurred adding a draft to the thread."
msgstr "Ocorreu um erro ao adicionar um rascunho à discussão."
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr "Erro ao pré-visualizar o blob"
-msgid "An error occurred when removing the label."
-msgstr "Ocorreu um erro ao remover a etiqueta."
-
msgid "An error occurred when updating the title"
msgstr "Ocorreu um erro ao atualizar o título"
@@ -3785,6 +3869,9 @@ msgstr "Ocorreu um erro ao carregar as solicitações de mesclagem"
msgid "An error occurred while loading projects."
msgstr "Um erro ocorreu durante o carregamento de projetos."
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr "Ocorreu um erro ao carregar os dados. Por favor, tente novamente."
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -3986,7 +4082,7 @@ msgid "Analyze your dependencies for known vulnerabilities."
msgstr "Analise suas dependências em busca de vulnerabilidades conhecidas."
msgid "Analyze your infrastructure as code configuration files for known vulnerabilities."
-msgstr ""
+msgstr "Analise sua infraestrutura como arquivos de configuração de código para vulnerabilidades conhecidas."
msgid "Analyze your source code and git history for secrets."
msgstr "Analise seu código-fonte e histórico git para segredos."
@@ -4099,7 +4195,7 @@ msgstr[0] "Aprovar %d usuário"
msgstr[1] "Aprovar %d usuários"
msgid "ApplicationSettings|Approve users"
-msgstr ""
+msgstr "Aprovar usuários"
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
@@ -4256,8 +4352,8 @@ msgstr[1] "%d membros"
msgid "ApprovalRuleRemove|You are about to remove the %{name} approver group which has %{strongStart}%{count} member%{strongEnd}. Approvals from this member are not revoked."
msgid_plural "ApprovalRuleRemove|You are about to remove the %{name} approver group which has %{strongStart}%{count} members%{strongEnd}. Approvals from these members are not revoked."
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Você está prestes a remover o %{name} grupo de aprovadores no qual tem %{strongStart}%{count} membro%{strongEnd}. Aprovações deste membro não estão revogadas."
+msgstr[1] "Você está prestes a remover o %{name} grupo de aprovadores no qual tem %{strongStart}%{count} membros%{strongEnd}. Aprovações destes membros não estão revogadas."
msgid "ApprovalRuleSummary|%d member"
msgid_plural "ApprovalRuleSummary|%d members"
@@ -4272,9 +4368,15 @@ msgstr[1] "%{count} aprovações obrigatórias de %{membersCount}"
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr "Adicionar aprovadores"
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr "Todas as verificações"
@@ -4305,6 +4407,9 @@ msgstr "Tipo de aprovador"
msgid "ApprovalRule|Approvers"
msgstr "Aprovadores"
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr "Confirmado"
@@ -4314,6 +4419,15 @@ msgstr "Dispensado"
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr "Nome"
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr "Detectado anteriormente"
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr "Resolvido"
@@ -4365,6 +4482,9 @@ msgstr "Níveis de severidade"
msgid "ApprovalRule|Target branch"
msgstr "Ramificação de destino"
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr "Vulnerabilidades permitidas"
@@ -4387,7 +4507,7 @@ msgid "ApprovalSettings|Prevent editing approval rules in projects and merge req
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 "Remove todas as aprovações quando commits forem adicionados a ramificação de origem."
+msgstr "Remover todas as aprovações quando commits forem adicionados a ramificação de origem."
msgid "ApprovalSettings|Require user password to approve."
msgstr "Exigir senha do usuário para aprovar."
@@ -4401,8 +4521,8 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr "Esta configuração está caracterizada no nível de instância e pode ser somente alterada por um administrador."
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
-msgstr "Essa configuração está configurada em %{groupName} e só pode ser alterada por um administrador ou proprietário do grupo."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
+msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
msgstr ""
@@ -4571,9 +4691,6 @@ msgstr "Tem certeza de que deseja fazer merge imediatamente?"
msgid "Are you sure you want to re-deploy this environment?"
msgstr "Tem certeza de que deseja fazer novo deploy deste ambiente?"
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr "Tem certeza de que deseja regenerar a chave pública? Você precisará atualizar a chave pública no servidor remote antes que o espelhamento funcione novamente."
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4671,10 +4788,10 @@ msgid "AsanaService|Add commit messages as comments to Asana tasks."
msgstr "Adicione mensagens de commit como comentários às tarefas Asana."
msgid "AsanaService|Comma-separated list of branches to be automatically inspected. Leave blank to include all branches."
-msgstr ""
+msgstr "Lista de ramificações separadas por vírgulas para serem automaticamente inspecionadas. Deixe em branco para incluir todas as ramificações."
msgid "AsanaService|User Personal Access Token. User must have access to the task. All comments are attributed to this user."
-msgstr ""
+msgstr "Token de acesso pessoal do usuário. O usuário deve ter acesso à tarefa. Todos os comentários são atribuídos a este usuário."
msgid "Ascending"
msgstr "Ascendente"
@@ -4721,6 +4838,9 @@ msgstr "Atribuir revisor"
msgid "Assign reviewer(s)"
msgstr "Atribuir revisor(es)"
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr "Atribua alguns issues a este marco."
@@ -4731,7 +4851,7 @@ msgid "Assign to commenting user"
msgstr "Atribuir ao usuário que comentou"
msgid "Assign to me"
-msgstr ""
+msgstr "Atribuir a mim"
msgid "Assign yourself to these issues"
msgstr "Atribuir-se a essas issues"
@@ -4831,7 +4951,7 @@ msgid "Audit Events"
msgstr "Eventos de auditoria"
msgid "Audit events"
-msgstr ""
+msgstr "Eventos de auditoria"
msgid "AuditLogs|(removed)"
msgstr "(removido)"
@@ -4924,13 +5044,13 @@ msgid "Authentication Failure"
msgstr "Falha de autenticação"
msgid "Authentication Log"
-msgstr "Log de autenticação"
+msgstr "Registro de autenticação"
msgid "Authentication failed: %{error_message}"
msgstr "Autenticação falhou: %{error_message}"
msgid "Authentication log"
-msgstr "Log de autenticação"
+msgstr "Registro de autenticação"
msgid "Authentication method"
msgstr "Método de autenticação"
@@ -5035,7 +5155,7 @@ msgid "AutoDevopsAlert|Security testing tools enabled with %{linkStart}Auto DevO
msgstr ""
msgid "AutoRemediation| 1 Merge Request"
-msgstr ""
+msgstr "1 solicitação de mesclagem"
msgid "AutoRemediation|%{mrsCount} ready for review"
msgstr "%{mrsCount} pronto para revisão"
@@ -5118,9 +5238,6 @@ msgstr "Executores específicos disponíveis"
msgid "Avatar for %{assigneeName}"
msgstr "Imagem de perfil para %{assigneeName}"
-msgid "Avatar for %{name}"
-msgstr "Imagem de perfil para %{name}"
-
msgid "Avatar will be removed. Are you sure?"
msgstr "Foto de perfil será removida. Tem certeza?"
@@ -5370,9 +5487,6 @@ msgstr "mensalmente"
msgid "BillingPlans|per user"
msgstr "por usuário"
-msgid "BillingPlan|Contact sales"
-msgstr "Contatar vendas"
-
msgid "BillingPlan|Upgrade"
msgstr "Atualizar"
@@ -5403,15 +5517,12 @@ msgstr "Reativar avaliação"
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr "Executores compartilhados não podem ser ativados até que um cartão de crédito válido seja registrado."
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
-msgstr "Usuário validado com sucesso"
-
msgid "Billings|User validation required"
msgstr "Validação de usuário necessária"
@@ -5421,8 +5532,11 @@ msgstr "Validar conta"
msgid "Billings|Validate user account"
msgstr "Validar conta de usuário"
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
-msgstr "Sua conta de usuário foi validada com sucesso. Agora você pode usar minutos de pipeline gratuitos."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
+msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
msgstr ""
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr "Não é possível remover usuário"
@@ -5482,10 +5602,10 @@ msgid "Billing|Users occupying seats in"
msgstr "Usuários que ocupam assentos em"
msgid "Billing|View pending approvals"
-msgstr ""
+msgstr "Ver aprovações pendentes"
msgid "Billing|You are about to remove user %{username} from your subscription. If you continue, the user will be removed from the %{namespace} group and all its subgroups and projects. This action can't be undone."
-msgstr ""
+msgstr "Você está prestes a remover o usuário %{username} de sua assinatura. Se você continuar, o usuário será removido do %{namespace} grupo e de todos os seus subgrupos e projetos. Esta ação não pode ser desfeita."
msgid "Bitbucket Server Import"
msgstr "Importação de Servidores Bitbucket"
@@ -5574,19 +5694,19 @@ msgid "BoardScope|Any assignee"
msgstr "Qualquer responsável"
msgid "BoardScope|Any label"
-msgstr ""
+msgstr "Qualquer etiqueta"
msgid "BoardScope|Assignee"
msgstr "Responsável"
msgid "BoardScope|Choose labels"
-msgstr ""
+msgstr "Escolher etiqueta"
msgid "BoardScope|Edit"
msgstr "Editar"
msgid "BoardScope|Labels"
-msgstr ""
+msgstr "Etiqueta"
msgid "BoardScope|Milestone"
msgstr "Marco"
@@ -5601,7 +5721,7 @@ msgid "BoardScope|Select assignee"
msgstr "Selecionar responsável"
msgid "BoardScope|Select labels"
-msgstr ""
+msgstr "Selecionar etiquetas"
msgid "BoardScope|Select milestone"
msgstr "Selecionar marco"
@@ -5621,8 +5741,8 @@ msgstr "Peso"
msgid "Boards"
msgstr "Painéis"
-msgid "Boards and Board Lists"
-msgstr "Painéis e listas de painéis"
+msgid "Boards and board lists"
+msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
msgid_plural "Boards|+ %{displayedIssuablesCount} more %{issuableType}s"
@@ -5695,7 +5815,7 @@ msgid "Boards|Failed to fetch blocking %{issuableType}s"
msgstr ""
msgid "Boards|New board"
-msgstr ""
+msgstr "Novo painel"
msgid "Boards|New epic"
msgstr "Novo épico"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
msgid "BulkImport|Filter by source group"
msgstr "Filtrar por grupo de fonte"
+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 ""
+
msgid "BulkImport|From source group"
msgstr "Do grupo de origem"
@@ -6030,6 +6156,9 @@ msgstr "Nenhum histórico disponível"
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6282,10 +6411,10 @@ msgid "Campfire token"
msgstr "Token do Campfire"
msgid "CampfireService|API authentication token from Campfire."
-msgstr ""
+msgstr "Token de autenticação de API do Campfire."
msgid "CampfireService|From the end of the room URL."
-msgstr ""
+msgstr "Do final da URL da sala."
msgid "CampfireService|Send notifications about push events to Campfire chat rooms. %{docs_link}"
msgstr ""
@@ -6734,8 +6863,8 @@ msgstr "Verificando disponibilidade do nome de usuário..."
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
-msgstr "$%{selectedPlanPrice} por 10 GB de armazenamento por pacote"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
+msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr ""
@@ -6761,7 +6890,7 @@ msgid "Checkout|%{name}'s storage subscription"
msgstr "Assinatura de armazenamento de %{name}"
msgid "Checkout|%{quantity} CI minutes"
-msgstr ""
+msgstr "%{quantity} minutos de CI"
msgid "Checkout|%{quantity} GB of storage"
msgstr "%{quantity} GB de armazenamento"
@@ -6996,9 +7125,6 @@ msgstr "Escolha qualquer cor."
msgid "Choose file…"
msgstr "Escolher arquivo…"
-msgid "Choose labels"
-msgstr "Escolha etiquetas"
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7009,7 +7135,7 @@ msgid "Choose the top-level group for your repository imports."
msgstr "Escolha o grupo principal para importar seus repositórios."
msgid "Choose visibility level, enable/disable project features and their permissions, disable email notifications, and show default award emoji."
-msgstr ""
+msgstr "Escolha o nível de visibilidade, ative/desabilite recursos do projeto e suas permissões, desabilite notificações por e-mail e mostre emoji de prêmio padrão"
msgid "Choose what content you want to see on a group’s overview page."
msgstr "Escolha o conteúdo que você deseja ver na página de visão geral de um grupo."
@@ -7209,6 +7335,9 @@ msgstr "Limpar filtros do gráfico"
msgid "Clear due date"
msgstr "Limpar validade"
+msgid "Clear health status"
+msgstr "Limpar estado de saúde"
+
msgid "Clear recent searches"
msgstr "Limpar pesquisas recentes"
@@ -7227,9 +7356,15 @@ msgstr "Limpar entrada de pesquisa de modelos"
msgid "Clear weight"
msgstr "Limpar peso"
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr "Limpa o peso."
@@ -7318,7 +7453,7 @@ msgid "Close %{issueType}"
msgstr "Fechar %{issueType}"
msgid "Close %{noteable}"
-msgstr ""
+msgstr "Fechar %{noteable}"
msgid "Close %{tabname}"
msgstr "Fechar %{tabname}"
@@ -7383,12 +7518,27 @@ msgstr "Nível de cluster"
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} agents"
+msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
+msgid "ClusterAgents|%{number} of %{total} agents"
+msgstr "%{number} de %{total} agentes"
+
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr "Tokens de acesso"
@@ -7399,16 +7549,22 @@ msgid "ClusterAgents|Advanced installation methods"
msgstr ""
msgid "ClusterAgents|Agent"
+msgstr "Agente"
+
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
msgstr ""
-msgid "ClusterAgents|Agent might not be connected to GitLab"
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
msgstr ""
+msgid "ClusterAgents|Agent might not be connected to GitLab"
+msgstr "O agente pode não estar conectado ao GitLab"
+
msgid "ClusterAgents|Agent never connected to GitLab"
-msgstr ""
+msgstr "Agente nunca conectado ao GitLab"
msgid "ClusterAgents|All"
-msgstr ""
+msgstr "Todos"
msgid "ClusterAgents|An error occurred while loading your GitLab Agents"
msgstr "Ocorreu um erro ao carregar seu GitLab Agents"
@@ -7416,9 +7572,15 @@ msgstr "Ocorreu um erro ao carregar seu GitLab Agents"
msgid "ClusterAgents|An error occurred while loading your agent"
msgstr "Ocorreu um erro ao carregar seu agente."
+msgid "ClusterAgents|An error occurred while retrieving GitLab Agent activity. Reload the page to try again."
+msgstr ""
+
msgid "ClusterAgents|An unknown error occurred. Please try again."
msgstr "Ocorreu um erro desconhecido. Por favor, tente novamente."
+msgid "ClusterAgents|Are you sure you want to delete this agent? You cannot undo this."
+msgstr ""
+
msgid "ClusterAgents|Certificate"
msgstr "Certificado"
@@ -7432,13 +7594,13 @@ msgid "ClusterAgents|Connect existing cluster"
msgstr "Conectar um cluster existente"
msgid "ClusterAgents|Connect with a certificate"
-msgstr ""
+msgstr "Conectar com o certificado"
msgid "ClusterAgents|Connect with the Agent"
-msgstr ""
+msgstr "Conectar com o Agente"
msgid "ClusterAgents|Connect with the GitLab Agent"
-msgstr ""
+msgstr "Conectar com o GitLab Agent"
msgid "ClusterAgents|Connect your cluster through the Agent"
msgstr ""
@@ -7453,7 +7615,7 @@ msgid "ClusterAgents|Copy token"
msgstr "Copiar token"
msgid "ClusterAgents|Create a new cluster"
-msgstr ""
+msgstr "Criar um novo cluster"
msgid "ClusterAgents|Created by"
msgstr "Criado por"
@@ -7464,12 +7626,21 @@ msgstr "Criado por %{name} %{time}"
msgid "ClusterAgents|Date created"
msgstr "Data de criação"
+msgid "ClusterAgents|Delete"
+msgstr "Excluir"
+
+msgid "ClusterAgents|Delete agent"
+msgstr "Excluir agente"
+
msgid "ClusterAgents|Deprecated"
msgstr "Obsoleto"
msgid "ClusterAgents|Description"
msgstr "Descrição"
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7477,19 +7648,19 @@ msgid "ClusterAgents|For the advanced installation method %{linkStart}see the do
msgstr ""
msgid "ClusterAgents|GitLab Agent"
-msgstr ""
+msgstr "GitLab Agent"
msgid "ClusterAgents|GitLab Agent for Kubernetes"
-msgstr ""
+msgstr "GitLab Agent para Kubernetes"
msgid "ClusterAgents|Go to the repository files"
-msgstr ""
+msgstr "Ir para o repositório de arquivos"
msgid "ClusterAgents|How to register an agent?"
-msgstr ""
+msgstr "Como registrar um agente?"
msgid "ClusterAgents|Install a new agent"
-msgstr ""
+msgstr "Instalar um novo agente"
msgid "ClusterAgents|Last connected %{timeAgo}."
msgstr "Última conexão %{timeAgo}."
@@ -7501,7 +7672,7 @@ msgid "ClusterAgents|Learn how to create an agent access token"
msgstr "Aprenda a criar um token de acesso do agente"
msgid "ClusterAgents|Learn how to troubleshoot"
-msgstr ""
+msgstr "Saiba como solucionar problemas"
msgid "ClusterAgents|Make sure you are using a valid token."
msgstr "Certifique-se de estar usando um token válido."
@@ -7525,13 +7696,13 @@ msgid "ClusterAgents|Not connected"
msgstr "Não conectado"
msgid "ClusterAgents|Recommended"
-msgstr ""
+msgstr "Recomendado"
msgid "ClusterAgents|Recommended installation method"
msgstr "Método de instalação recomendado"
msgid "ClusterAgents|Register"
-msgstr ""
+msgstr "Registrar"
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 ""
@@ -7543,10 +7714,13 @@ msgid "ClusterAgents|Registration token"
msgstr "Token de registro"
msgid "ClusterAgents|Security"
+msgstr "Segurança"
+
+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 ""
+msgstr "Selecione um agente"
msgid "ClusterAgents|Select an agent to register with GitLab"
msgstr ""
@@ -7563,10 +7737,24 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
msgstr "Este agente não tem tokens"
+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}What's the agent's configuration file?%{linkEnd}"
+msgstr "Para instalar um novo agente, primeiro inclua o arquivo de configuração do agente neste repositório. %{linkStart}Qual é o arquivo de configuração do agente?%{linkEnd}"
+
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
msgstr ""
msgid "ClusterAgents|Unknown user"
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -7693,7 +7884,7 @@ msgid "ClusterIntegration|Check your CA certificate"
msgstr ""
msgid "ClusterIntegration|Check your cluster status"
-msgstr ""
+msgstr "Verifique o estado de seu cluster"
msgid "ClusterIntegration|Check your token"
msgstr "Verifique seu token"
@@ -7735,7 +7926,7 @@ msgid "ClusterIntegration|Connect existing cluster"
msgstr "Conectar um cluster existente"
msgid "ClusterIntegration|Connect with a certificate"
-msgstr ""
+msgstr "Conecte-se com um certificado"
msgid "ClusterIntegration|Connect your cluster to GitLab through %{linkStart}cluster certificates%{linkEnd}."
msgstr "Conecte seu cluster ao GitLab por meio de %{linkStart}certificados de cluster%{linkEnd}."
@@ -8290,7 +8481,7 @@ msgid "ClusterIntegration|Unknown Error"
msgstr "Erro desconhecido"
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 ""
+msgstr "Use o %{linkStart}GitLab Agent%{linkEnd} para conectar com segurança seus clusters deKubernetes ao GitLab. Você pode implantar seus aplicativos, executar seus pipelines, usar aplicativos de revisão e muito mais."
msgid "ClusterIntegration|Uses the Cloud Run, Istio, and HTTP Load Balancing addons for this cluster."
msgstr "Usa os complementos Cloud Run, Istio, e Balanceamento de Carga HTTP para este cluster."
@@ -8712,7 +8903,7 @@ msgid "ComplianceFrameworks|Configuration not found"
msgstr "Configuração não encontrada"
msgid "ComplianceFrameworks|Configured compliance frameworks appear here."
-msgstr ""
+msgstr "As estruturas de conformidade configuradas aparecem aqui."
msgid "ComplianceFrameworks|Delete compliance framework %{framework}"
msgstr "Excluir framework de conformidade %{framework}"
@@ -8748,7 +8939,7 @@ msgid "ComplianceFrameworks|Name is required"
msgstr "O nome é necessário"
msgid "ComplianceFrameworks|No compliance frameworks are configured"
-msgstr ""
+msgstr "Nenhuma estrutura de conformidade configurada"
msgid "ComplianceFrameworks|Required format: %{codeStart}path/file.y[a]ml@group-name/project-name%{codeEnd}. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr "Componente"
@@ -9186,6 +9386,9 @@ msgstr "Ainda não agendado"
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr "Nota: Qualquer atualização de política resultará em mudança na data e hora de execução programada"
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr "Publicado em %{timeInfo}"
@@ -9275,6 +9478,9 @@ msgstr "Tags com o nome que correspondem a este padrão de regex serão removida
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9312,7 +9518,7 @@ msgid "ContainerRegistry|This project's cleanup policy for tags is not enabled."
msgstr "A política de limpeza deste projeto para tags não está ativada."
msgid "ContainerRegistry|To widen your search, change or remove the filters above."
-msgstr ""
+msgstr "Para ampliar a sua pesquisa, altere ou remova os filtros acima."
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 ""
@@ -9506,12 +9712,18 @@ msgstr "Copiar ambiente"
msgid "Copy evidence SHA"
msgstr "Copiar evidencia SHA"
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr "Copiar conteúdo do arquivo"
msgid "Copy file path"
msgstr "Copiar caminho do arquivo"
+msgid "Copy issue URL to clipboard"
+msgstr "Copiar a URL da issue para a área de transferência"
+
msgid "Copy key"
msgstr "Copiar chave"
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr "Copiar esse token de registro"
-msgid "Copy this value"
-msgstr "Copiar este valor"
-
msgid "Copy to clipboard"
msgstr "Copiar para área de transferência"
@@ -9741,7 +9950,7 @@ msgid "Create %{workspace} label"
msgstr "Criar etiqueta para %{workspace}"
msgid "Create Google Cloud project"
-msgstr ""
+msgstr "Criar projeto no Google Cloud"
msgid "Create New Directory"
msgstr "Criar Novo Diretório"
@@ -9756,7 +9965,7 @@ msgid "Create a Mattermost team for this group"
msgstr ""
msgid "Create a merge request"
-msgstr "Criar um merge request"
+msgstr ""
msgid "Create a new %{codeStart}.gitlab-ci.yml%{codeEnd} file at the root of the repository to get started."
msgstr "Crie um novo arquivo %{codeStart}.gitlab-ci.yml%{codeEnd} na raiz do repositório para começar."
@@ -9884,9 +10093,6 @@ msgstr "Criar nova etiqueta"
msgid "Create new project"
msgstr "Criar novo projeto"
-msgid "Create new..."
-msgstr "Criar novo..."
-
msgid "Create or import your first project"
msgstr "Criar ou importar seu primeiro projeto"
@@ -9903,7 +10109,7 @@ msgid "Create requirement"
msgstr "Criar requisito"
msgid "Create service account"
-msgstr ""
+msgstr "Criar nova conta de serviço"
msgid "Create snippet"
msgstr "Criar snippet"
@@ -9917,6 +10123,9 @@ msgstr "Criar tópico"
msgid "Create user"
msgstr "Criar usuário"
+msgid "Create via merge request"
+msgstr "Criar via solicitação de mesclagem"
+
msgid "Create wildcard: %{searchTerm}"
msgstr "Criar curinga: %{searchTerm}"
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr "Início da fase de código"
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr "Criar fluxo de valor"
-
msgid "CreateValueStreamForm|Create from default template"
msgstr "Criar a partir do modelo padrão"
@@ -9971,13 +10177,16 @@ msgstr "Criar a partir do modelo"
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr "Criar novo fluxo de valor"
+msgid "CreateValueStreamForm|Create value stream"
+msgstr "Criar fluxo de valor"
+
msgid "CreateValueStreamForm|Default stages"
msgstr "Estágios padrão"
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr "Estágios padrão só podem ser ocultados ou reordenados"
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr "Editar fluxo de valor"
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,35 +10366,62 @@ msgstr "Cartão de crédito:"
msgid "Critical vulnerabilities present"
msgstr "Vulnerabilidades críticas presentes"
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
+msgstr "Criar nova conta"
+
+msgid "Crm|Create organization"
msgstr ""
msgid "Crm|Customer Relations Contacts"
msgstr ""
-msgid "Crm|Description (optional)"
+msgid "Crm|Customer Relations Organizations"
msgstr ""
-msgid "Crm|Email"
+msgid "Crm|Default rate (optional)"
msgstr ""
+msgid "Crm|Description (optional)"
+msgstr "Descrição (opcional)"
+
+msgid "Crm|Edit contact"
+msgstr "Editar contato"
+
+msgid "Crm|Email"
+msgstr "E-mail"
+
msgid "Crm|First name"
-msgstr ""
+msgstr "Primeiro nome"
msgid "Crm|Last name"
+msgstr "Sobrenome"
+
+msgid "Crm|New Organization"
msgstr ""
msgid "Crm|New contact"
+msgstr "Novo contato"
+
+msgid "Crm|New organization"
msgstr ""
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
+msgstr "Nenhuma organização encontrada"
+
+msgid "Crm|Organization has been added"
msgstr ""
msgid "Crm|Phone number (optional)"
-msgstr ""
+msgstr "Número de telefone (opcional)"
msgid "Cron Timezone"
msgstr "Fuso horário do cron"
@@ -10334,15 +10570,6 @@ msgstr "Personalize a sua configuração de pipeline e relatório de cobertura."
msgid "Customize your pipeline configuration."
msgstr "Personalize a configuração de pipeline."
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr "Você quer personalizar esta página?"
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr "Vá para preferências"
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr "Essa página mostra uma lista de seus projetos por padrão, mas pode ser alterada para mostrar atividade de projetos, grupos, sua lista de tarefas pendentes, issues atribuídas, solicitações de mesclagem atribuídas, e muito mais. Você pode alterar isso em \"Conteúdo da página inicial\" nas suas preferências."
-
msgid "Cycle Time"
msgstr "Tempo de ciclo"
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr "Data"
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr "Seletor de data"
@@ -11145,13 +11375,13 @@ msgid "DefaultBranchLabel|default"
msgstr "padrão"
msgid "DefaultBranchProtection|Both developers and maintainers can push new commits, but cannot force push."
-msgstr ""
+msgstr "Tanto os desenvolvedores quanto os mantenedores podem enviar novos commits, mas não podem forçar o push."
msgid "DefaultBranchProtection|Both developers and maintainers can push new commits, force push, or delete the branch."
-msgstr ""
+msgstr "Tanto os desenvolvedores e mantenedores podem enviar novos commits, forçar push ou excluir a ramificação."
msgid "DefaultBranchProtection|Developers cannot push new commits, but are allowed to accept merge requests to the branch. Maintainers can push to the branch."
-msgstr ""
+msgstr "Os desenvolvedores não podem enviar novos commits, mas podem aceitar solicitações de mesclagem para a ramificação. Os mantenedores podem fazer push para a ramificação."
msgid "DefaultBranchProtection|Developers cannot push new commits, but maintainers can. No one can force push."
msgstr ""
@@ -11226,7 +11456,7 @@ msgid "Delete Key"
msgstr "Excluir chave"
msgid "Delete Selected"
-msgstr ""
+msgstr "Excluir selecionado"
msgid "Delete Value Stream"
msgstr "Excluir fluxo de valor"
@@ -11250,7 +11480,7 @@ msgid "Delete corpus"
msgstr "Excluir corpus"
msgid "Delete deploy key"
-msgstr ""
+msgstr "Excluir chave de implantação"
msgid "Delete file"
msgstr "Excluir arquivo"
@@ -11306,6 +11536,9 @@ msgstr "Excluir lista de usuário"
msgid "Delete variable"
msgstr "Excluir a variável"
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
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."
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr "Excluído"
-msgid "Deleted Projects"
-msgstr "Projetos excluídos"
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr "Apelido de bate-papo excluído: %{chat_name}!"
-msgid "Deleted projects"
-msgstr "Projeto excluídos"
-
msgid "Deleted projects cannot be restored!"
msgstr "Projetos excluídos não podem ser restaurados!"
@@ -11430,7 +11657,7 @@ msgid "Dependencies|Job failed to generate the dependency list"
msgstr "A tarefa falhou em gerar a lista de dependências"
msgid "Dependencies|Learn more about dependency paths"
-msgstr ""
+msgstr "Saiba mais sobre caminhos de dependência"
msgid "Dependencies|License"
msgstr "Licença"
@@ -11439,7 +11666,7 @@ msgid "Dependencies|Location"
msgstr "Localização"
msgid "Dependencies|Location and dependency path"
-msgstr ""
+msgstr "Localização e caminho de dependência"
msgid "Dependencies|Packager"
msgstr "Empacotador"
@@ -11475,11 +11702,14 @@ msgid "Dependency Scanning"
msgstr "Verificação de dependência"
msgid "Dependency list"
-msgstr ""
+msgstr "Lista de dependências"
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr "Limpar o cache do proxy de dependência automaticamente"
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr "Contém %{count} blobs de imagens (%{size})"
@@ -11496,22 +11726,25 @@ msgid "DependencyProxy|Dependency Proxy feature is limited to public groups for
msgstr ""
msgid "DependencyProxy|Dependency Proxy image prefix"
-msgstr ""
+msgstr "Prefixo da imagem do proxy de dependência"
msgid "DependencyProxy|Enable Dependency Proxy"
-msgstr ""
+msgstr "Ativar proxy de dependências"
msgid "DependencyProxy|Image list"
-msgstr ""
+msgstr "Lista de imagens"
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
-msgstr ""
+msgid "DependencyProxy|Storage settings"
+msgstr "Configurações de armazenamento"
msgid "DependencyProxy|There are no images in the cache"
-msgstr ""
+msgstr "Não há imagens no cache"
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
-msgstr ""
+msgstr "Para ver o prefixo da imagem e o que está no cache, visite o %{linkStart}proxy de dependências%{linkEnd}"
+
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr "Quando ativado, as imagens com mais de 90 dias serão removidas do cache."
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
@@ -11634,19 +11867,19 @@ 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 ""
+msgstr "Permite acesso de leitura e gravação às imagens de registro."
msgid "DeployTokens|Allows read and write access to the package registry."
-msgstr ""
+msgstr "Permite acesso de leitura e gravação ao registro do pacote."
msgid "DeployTokens|Allows read-only access to registry images."
-msgstr ""
+msgstr "Permite acesso somente-leitura às imagens do registro."
msgid "DeployTokens|Allows read-only access to the package registry."
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
-msgstr ""
+msgstr "Permite acesso somente-leitura ao repositório."
msgid "DeployTokens|Copy deploy token"
msgstr "Copiar token de implantação"
@@ -11706,16 +11939,16 @@ msgid "DeployTokens|This action cannot be undone."
msgstr "Esta ação não pode ser desfeita."
msgid "DeployTokens|This username supports access. %{link_start}What kind of access?%{link_end}"
-msgstr ""
+msgstr "Este nome de usuário suporta acesso. %{link_start}Que tipo de acesso?%{link_end}"
msgid "DeployTokens|Use this token as a password. Save it. This password can %{i_start}not%{i_end} be recovered."
-msgstr ""
+msgstr "Use este token como uma senha. Salve isso. Esta senha não pode ser recuperada %{i_start}%{i_end}"
msgid "DeployTokens|Username"
msgstr "Nome de usuário"
msgid "DeployTokens|Your new Deploy Token username"
-msgstr ""
+msgstr "Seu novo nome de usuário do token de implantação"
msgid "DeployTokens|Your new group deploy token has been created."
msgstr "Seu novo token de inplantação de grupo foi criado."
@@ -12315,15 +12548,15 @@ msgstr "Para código que já está em produção, nossos painéis oferecem uma m
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr "GitLab executará testes estáticos e dinâmicos no código do seu aplicativo, procurando falhas conhecidas e relatando-as na solicitação de mesclagem para que você possa corrigi-las antes da mesclagem."
-msgid "Discover|Give feedback for this page"
-msgstr "Dê sua opinião sobre esta página"
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr "Recursos de segurança, integrados ao seu ciclo de vida de desenvolvimento"
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr "Veja os outros recursos do %{linkStart}plano ultimate%{linkEnd}"
+msgid "Discover|Send feedback"
+msgstr "Enviar feedback"
+
msgid "Discover|Start a free trial"
msgstr "Testar"
@@ -12464,6 +12697,9 @@ msgstr "Baixar (%{size})"
msgid "Download CSV"
msgstr "Baixar CSV"
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr "Baixar artefatos"
@@ -12599,8 +12835,8 @@ msgstr "Editar marco"
msgid "Edit Password"
msgstr "Editar senha"
-msgid "Edit Pipeline Schedule %{id}"
-msgstr "Alterar Agendamento do Pipeline %{id}"
+msgid "Edit Pipeline Schedule"
+msgstr ""
msgid "Edit Release"
msgstr "Editar versão"
@@ -12624,13 +12860,13 @@ msgid "Edit comment"
msgstr "Editar comentário"
msgid "Edit commit message"
-msgstr ""
+msgstr "Editar mensagem de commit"
msgid "Edit deploy freeze"
msgstr ""
msgid "Edit deploy key"
-msgstr ""
+msgstr "Editar chave de implantação"
msgid "Edit description"
msgstr "Editar descrição"
@@ -12638,6 +12874,9 @@ msgstr "Editar descrição"
msgid "Edit environment"
msgstr "Editar ambiente"
+msgid "Edit epics"
+msgstr "Editar épicos"
+
msgid "Edit files in the editor and commit changes here"
msgstr "Alterar arquivos no editor e fazer commit das alterações aqui"
@@ -12768,7 +13007,7 @@ msgid "Email a new %{name} to this project"
msgstr "Enviar um novo %{name} para este projeto"
msgid "Email address suffix"
-msgstr ""
+msgstr "Sufixo do endereço de email"
msgid "Email address to use for Support Desk"
msgstr "Endereço de e-mail para usar na central de serviços"
@@ -12843,7 +13082,7 @@ msgid "Emails"
msgstr "E-mails"
msgid "Emails sent from Service Desk have this name."
-msgstr "OS e-mails enviados pela central de serviços tem esse nome."
+msgstr "Os e-mails enviados pela central de serviços tem esse nome."
msgid "Emails sent to %{email} are also supported."
msgstr "E-mails enviados para %{email} também são suportados."
@@ -13041,7 +13280,7 @@ msgid "Enable repository checks"
msgstr "Ativar as verificações de repositório"
msgid "Enable shared runners for all projects and subgroups in this group."
-msgstr ""
+msgstr "Ativar executores compartilhados para todos os projetos e subgrupos neste grupo."
msgid "Enable shared runners for this group"
msgstr "Ativar executores compartilhados para este grupo"
@@ -13553,7 +13792,7 @@ msgid "Epics|Show more"
msgstr "Mostrar mais"
msgid "Epics|Something went wrong while assigning issue to epic."
-msgstr ""
+msgstr "Algo deu errado ao atribuir a issue para épico."
msgid "Epics|Something went wrong while creating child epics."
msgstr "Algo deu errado ao criar épicos filhos."
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+msgstr "Algo deu errado ao atualizar épicos filhos."
+
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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr "Erro ao criar o snippet"
-msgid "Error deleting %{issuableType}"
-msgstr "Erro ao excluir %{issuableType}"
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr "Erro ao enviar o arquivo: %{stripped}"
msgid "Error while loading the merge request. Please try again."
msgstr "Erro ao carregar a solicitação de mesclagem. Por favor, tente novamente."
-msgid "Error while loading the project data. Please try again."
-msgstr "Ocorreu um erro ao carregar os dados do projeto. Por favor, tente novamente."
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr "Ocorreu um erro ao migrar %{upload_id}: %{error_message}"
@@ -13867,6 +14103,9 @@ 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:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr "Todos os anos"
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr "Todos os anos em %{day} às %{time} %{timezone}"
-msgid "Everyone"
-msgstr "Todos"
-
msgid "Everyone With Access"
msgstr "Todos com acesso"
@@ -14218,7 +14454,7 @@ msgid "Explore snippets"
msgstr ""
msgid "Explore topics"
-msgstr ""
+msgstr "Explorar tópicos"
msgid "Export"
msgstr "Exportar"
@@ -14247,7 +14483,7 @@ msgstr "Exportar projeto"
msgid "Export requirements"
msgstr "Exportar requisitos"
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14941,7 +15177,7 @@ msgid "Filter by merge requests that are currently merged."
msgstr ""
msgid "Filter by milestone"
-msgstr ""
+msgstr "Filtrar por marco"
msgid "Filter by milestone name"
msgstr "Filtrar por nome de marco"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr "Filtrar por autenticação de dois fatores"
-
msgid "Filter by user"
msgstr "Filtrar por usuário"
@@ -15112,13 +15345,13 @@ msgid "For each job, clone the repository."
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 ""
+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 files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
-msgstr ""
+msgstr "Para arquivos maiores que este limite indexam apenas o nome do arquivo. O conteúdo do arquivo não é indexado nem pesquisável."
msgid "For general work"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr "Da solicitação de mesclagem até a implantação em produção"
msgid "Full"
msgstr "Cheio"
+msgid "Full log"
+msgstr "Registro completo"
+
msgid "Full name"
msgstr "Nome completo"
@@ -16129,31 +16365,28 @@ msgid "GlobalSearch|%{count} default results provided. Use the up and down arrow
msgstr ""
msgid "GlobalSearch|Issues I've created"
-msgstr ""
+msgstr "Issues que eu criei"
msgid "GlobalSearch|Issues assigned to me"
-msgstr ""
+msgstr "Issues atribuídas a mim"
msgid "GlobalSearch|Merge requests I've created"
-msgstr ""
+msgstr "Solicitações de mesclagem que criei"
msgid "GlobalSearch|Merge requests assigned to me"
-msgstr ""
+msgstr "Solicitações de mesclagem atribuídas a mim"
msgid "GlobalSearch|Merge requests that I'm a reviewer"
-msgstr ""
+msgstr "Solicitações de mesclagem que eu seja um revisor"
msgid "GlobalSearch|Results updated. %{count} results available. Use the up and down arrow keys to navigate search results list, or ENTER to submit."
msgstr ""
msgid "GlobalSearch|Search GitLab"
-msgstr ""
-
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
+msgstr "Pesquisar no GitLab"
msgid "GlobalSearch|Search results are loading"
-msgstr ""
+msgstr "Os resultados da pesquisa estão sendo carregados"
msgid "GlobalSearch|Type and press the enter key to submit search."
msgstr ""
@@ -16162,13 +16395,13 @@ msgid "GlobalSearch|Type for new suggestions to appear below."
msgstr ""
msgid "GlobalSearch|in all GitLab"
-msgstr ""
+msgstr "em todo o GitLab"
msgid "GlobalSearch|in group"
-msgstr ""
+msgstr "no grupo"
msgid "GlobalSearch|in project"
-msgstr ""
+msgstr "no projeto"
msgid "Go Back"
msgstr "Voltar"
@@ -16239,6 +16472,9 @@ msgstr "Ir para métricas"
msgid "Go to next page"
msgstr "Ir para a próxima página"
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr "O grupo SAML deve ser habilitado para testar"
msgid "Group URL"
msgstr "URL do grupo"
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16468,7 +16701,7 @@ msgid "Group export requests"
msgstr "Requisições de exportação de grupo"
msgid "Group export started. A download link will be sent by email and made available on this page."
-msgstr ""
+msgstr "Exportação do grupo iniciada. Um link para baixar será enviado por e-mail e disponibilizado nesta página."
msgid "Group has been already marked for deletion"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr "O grupo foi exportado"
msgid "Group was successfully updated."
msgstr "O grupo foi atualizado com sucesso."
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr "Grupo: %{group_name}"
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr "Impressão digital SHA1 do certificado de assinatura de token SAML. Obte
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr "O token SCIM agora está oculto. Para ver o valor do token novamente, você precisa "
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr "Nenhum resultado correspondente"
@@ -16825,13 +17088,13 @@ msgid "GroupSettings|Auto DevOps pipeline was updated for the group"
msgstr "Pipeline de Auto DevOps foi atualizado para o grupo"
msgid "GroupSettings|Available only on the top-level group. Applies to all subgroups. Groups already shared with a group outside %{group} are still shared unless removed manually."
-msgstr ""
+msgstr "Disponível apenas no grupo de nível superior. Aplica-se a todos os subgrupos. Grupos já compartilhados com um grupo fora de %{group} ainda são compartilhados, a menos que sejam removidos manualmente."
msgid "GroupSettings|Badges"
msgstr "Selos"
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
-msgstr ""
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
+msgstr "Tenha cuidado. Mudar o pai de um grupo pode ter efeitos colaterais indesejados. %{learn_more_link_start}Saiba mais.%{learn_more_link_end}"
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
msgstr ""
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr "Alterar URL do grupo"
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+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|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr "Um novo token de registro de executores foi gerado!"
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr "Substitui as preferências de notificação do usuário para todos os membros do grupo, subgrupos e projetos."
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr "Os projetos serão excluídos permanentemente após um %{waiting_period}
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr "Os projetos serão excluídos permanentemente após um %{waiting_period}-atraso de dia(s). Este atraso pode ser %{link_start}personalizado por um administrador%{link_end} nas configurações de instância. Herdado por subgrupos."
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr "Selecione um projeto com o arquivo %{code_start}.gitlab/insights.yml%{code_end}"
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr "Selecione um subgrupo para usar como fonte para modelos de projeto personalizados para este grupo."
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr "Selecione o projeto que contém seu arquivo personalizado do Insights."
@@ -17028,6 +17300,9 @@ msgstr "Você pode gerenciar permissões de membros e acesso do seu grupo para c
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr "Peça ao seu administrador para ativar a %{enable_link_start}migração de grupo.%{enable_link_end}"
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr "Reúne projetos relacionados e concede aos membros acesso a vários projetos ao mesmo tempo."
@@ -17068,7 +17343,7 @@ msgid "GroupsNew|No import options available"
msgstr ""
msgid "GroupsNew|Not all related objects are migrated. %{docs_link_start}More info%{docs_link_end}."
-msgstr ""
+msgstr "Nem todos os objetos relacionados são migrados. %{docs_link_start}Mais informações%{docs_link_end}."
msgid "GroupsNew|Personal access token"
msgstr "Token de acesso pessoal"
@@ -17082,6 +17357,9 @@ msgstr "Por favor preencha o seu token de acesso pessoal"
msgid "GroupsNew|Provide credentials for another instance of GitLab to import your groups directly."
msgstr "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 "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 ""
@@ -17155,10 +17433,10 @@ msgid "Header message"
msgstr "Mensagem de cabeçalho"
msgid "HeaderAction|incident"
-msgstr ""
+msgstr "incidente"
msgid "HeaderAction|issue"
-msgstr ""
+msgstr "issue"
msgid "Headers"
msgstr "Cabeçalhos\t"
@@ -17257,7 +17535,7 @@ msgid "Hi %{username}!"
msgstr "Olá %{username}!"
msgid "Hidden"
-msgstr ""
+msgstr "Oculto"
msgid "Hide"
msgstr "Ocultar"
@@ -18575,7 +18853,7 @@ msgid "Infrastructure Registry"
msgstr "Registro de infraestrutura"
msgid "Infrastructure as Code (IaC) Scanning"
-msgstr ""
+msgstr "Verificação de Infraestrutura como Código (IaC)"
msgid "InfrastructureRegistry|Copy Terraform Command"
msgstr "Copiar comando do Terraform"
@@ -18793,7 +19071,7 @@ msgid "Integrations|Default settings are inherited from the instance level."
msgstr ""
msgid "Integrations|Edit project alias"
-msgstr ""
+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."
@@ -18802,7 +19080,7 @@ msgid "Integrations|Enable comments"
msgstr "Ativar comentários"
msgid "Integrations|Enter your alias"
-msgstr ""
+msgstr "Digite seu alias"
msgid "Integrations|Failed to link namespace. Please try again."
msgstr ""
@@ -18990,6 +19268,9 @@ msgstr "SO inválido"
msgid "Invalid URL"
msgstr "URL inválida"
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr "Adicione membros para esse projeto e inicie a colaboração com a sua equipe"
-msgid "InviteMember|Invite Member"
-msgstr "Convidar membro"
-
msgid "InviteMember|Invite Members (optional)"
msgstr "Convidar membros (opcional)"
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr "Está bloqueado por"
-msgid "Is this GitLab trial for your company?"
-msgstr "Este é uma avaliação do GitLab para sua empresa?"
-
msgid "Is using license seat:"
msgstr "Está usando o assento de licença:"
@@ -19458,9 +19733,6 @@ msgstr "Status"
msgid "IssueAnalytics|Weight"
msgstr "Peso"
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr "Painel"
@@ -19489,19 +19761,19 @@ msgid "IssueTracker|Custom issue tracker"
msgstr "Rastreador de issues personalizado"
msgid "IssueTracker|Issue URL"
-msgstr "URL do issue"
+msgstr "URL da issue"
msgid "IssueTracker|New issue URL"
msgstr "Novo URL da issue"
msgid "IssueTracker|The URL to create an issue in the external issue tracker."
-msgstr ""
+msgstr "O URL para criar uma issue no rastreador de problemas externo."
msgid "IssueTracker|The URL to the project in YouTrack."
msgstr ""
msgid "IssueTracker|The URL to the project in the external issue tracker."
-msgstr ""
+msgstr "O URL do projeto no rastreador de problemas externo."
msgid "IssueTracker|The URL to view an issue in the YouTrack project. Must contain %{colon_id}."
msgstr ""
@@ -19921,7 +20193,7 @@ msgid "JiraService|IDs must be a list of numbers that can be split with , or ;"
msgstr ""
msgid "JiraService|If different from Web URL."
-msgstr ""
+msgstr "Se diferente do URL da Web."
msgid "JiraService|Issues created from vulnerabilities in this project will be Jira issues, even if GitLab issues are enabled."
msgstr ""
@@ -19981,10 +20253,10 @@ msgid "JiraService|This is an Ultimate feature"
msgstr "Este é um recurso Ultimate"
msgid "JiraService|Transition Jira issues to their final state:"
-msgstr ""
+msgstr "Transição das issues do Jira para o estado final:"
msgid "JiraService|Upgrade your plan to enable this feature of the Jira Integration."
-msgstr ""
+msgstr "Melhore de seu plano para ativar esse recurso de Integração do Jira."
msgid "JiraService|Use Jira as this project's issue tracker."
msgstr "Use o Jira como rastreador de issue deste projeto."
@@ -19993,7 +20265,7 @@ msgid "JiraService|Use a password for server version and an API token for cloud
msgstr ""
msgid "JiraService|Use a username for server version and an email for cloud version."
-msgstr ""
+msgstr "Use um nome de usuário para versão de servidor e um e-mail para versão de nuvem."
msgid "JiraService|Use custom transitions"
msgstr "Usar transições personalizadas"
@@ -20106,8 +20378,8 @@ msgstr "Raw completo"
msgid "Job|Download"
msgstr "Baixar"
-msgid "Job|Erase job log"
-msgstr "Apagar log da tarefa"
+msgid "Job|Erase job log and artifacts"
+msgstr ""
msgid "Job|Job artifacts"
msgstr "Artefatos da tarefa"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr "Inicie um ambiente de desenvolvimento pronto para o seu projeto."
+msgid "Layout|Fixed"
+msgstr "Fixado"
+
+msgid "Layout|Fluid"
+msgstr "Fluido"
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr "Manual"
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -21839,7 +22117,7 @@ msgid "Member|Remove member"
msgstr ""
msgid "Member|Revoke invite"
-msgstr ""
+msgstr "Revogar convite"
msgid "Memory Usage"
msgstr "Uso da memória"
@@ -22004,10 +22282,10 @@ msgid "MergeRequestApprovals|Define approval rules and settings to ensure %{link
msgstr ""
msgid "MergeRequestApprovals|Enforce %{link_start}separation of duties%{link_end} for all projects."
-msgstr ""
+msgstr "Aplicar %{link_start}separação de tarefas%{link_end} para todos os projetos."
msgid "MergeRequestApprovals|Enforce %{separationLinkStart}separation of duties%{separationLinkEnd} for all projects. %{learnLinkStart}Learn more.%{learnLinkEnd}"
-msgstr ""
+msgstr "Aplicar %{separationLinkStart}separação de tarefas%{separationLinkEnd} para todos os projetos. %{learnLinkStart}Saiba mais.%{learnLinkEnd}"
msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
msgstr ""
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr "Métricas e perfis"
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22539,7 +22820,7 @@ msgid "MilestoneCombobox|Select milestone"
msgstr "Selecionar marco"
msgid "MilestoneSidebar|Closed:"
-msgstr "Fechado:"
+msgstr "Fechada:"
msgid "MilestoneSidebar|Copy reference"
msgstr "Copiar referência"
@@ -22557,10 +22838,10 @@ msgid "MilestoneSidebar|Issues"
msgstr "Issues"
msgid "MilestoneSidebar|Merge requests"
-msgstr "Merge request"
+msgstr "Solicitações de mesclagem"
msgid "MilestoneSidebar|Merged:"
-msgstr "Mesclado:"
+msgstr "Mesclada:"
msgid "MilestoneSidebar|New Issue"
msgstr "Nova issue"
@@ -22578,7 +22859,7 @@ msgid "MilestoneSidebar|None"
msgstr "Nenhum"
msgid "MilestoneSidebar|Open:"
-msgstr "Abrir:"
+msgstr "Aberta:"
msgid "MilestoneSidebar|Reference:"
msgstr "Referência:"
@@ -22626,7 +22907,7 @@ msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr "Marco %{milestoneTitle} não foi encontrado"
msgid "Milestones|Ongoing Issues (open and assigned)"
-msgstr ""
+msgstr "Issues em andamento (abertas e atribuídas)"
msgid "Milestones|Project Milestone"
msgstr "Marco do projeto"
@@ -22650,7 +22931,7 @@ msgid "Milestones|This action cannot be reversed."
msgstr "Essa ação não pode ser revertida."
msgid "Milestones|Unstarted Issues (open and unassigned)"
-msgstr ""
+msgstr "Issues não iniciadas (abertas e não atribuídas)"
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr "Capacidade mínima para estar disponível antes de agendar mais espelhos preventivamente."
@@ -22796,6 +23077,9 @@ msgstr "Mais informações disponíveis|aqui"
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr "Mais opções"
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr "Mais de %{number_commits_distance} diferentes commits com %{default_branch}"
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr "Barra de navegação"
+msgid "NavigationTheme|Blue"
+msgstr "Azul"
+
+msgid "NavigationTheme|Dark"
+msgstr "Escuro"
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr "Verde"
+
+msgid "NavigationTheme|Indigo"
+msgstr "Anil"
+
+msgid "NavigationTheme|Light"
+msgstr "Claro"
+
+msgid "NavigationTheme|Light Blue"
+msgstr "Azul claro"
+
+msgid "NavigationTheme|Light Green"
+msgstr "Verde claro"
+
+msgid "NavigationTheme|Light Indigo"
+msgstr "Anil claro"
+
+msgid "NavigationTheme|Light Red"
+msgstr "Vermelho claro"
+
+msgid "NavigationTheme|Red"
+msgstr "Vermelho"
+
msgid "Nav|Help"
msgstr "Ajuda"
@@ -23212,6 +23529,9 @@ msgstr "Novo"
msgid "New %{issueType}"
msgstr "Nova %{issueType}"
+msgid "New %{type} in %{project}"
+msgstr "Novo %{type} em %{project}"
+
msgid "New Application"
msgstr "Novo aplicativo"
@@ -23353,7 +23673,7 @@ msgid "New milestone"
msgstr "Novo marco"
msgid "New name"
-msgstr ""
+msgstr "Novo nome"
msgid "New password"
msgstr "Nova senha"
@@ -23365,10 +23685,10 @@ msgid "New project"
msgstr "Novo projeto"
msgid "New project page"
-msgstr ""
+msgstr "Nova página do projeto"
msgid "New project pages"
-msgstr ""
+msgstr "Novas páginas do projeto"
msgid "New project/repository"
msgstr "Novo projeto/repositório"
@@ -23436,6 +23756,9 @@ msgstr "Próximo design"
msgid "Next file in diff"
msgstr "Próximo arquivo em diff"
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr "Próxima discussão não resolvida"
@@ -23641,7 +23964,7 @@ msgid "No matching results..."
msgstr "Nenhum resultado correspondente..."
msgid "No member provided"
-msgstr ""
+msgstr "Nenhum membro fornecido"
msgid "No members found"
msgstr "Nenhum membro encontrado"
@@ -23814,7 +24137,7 @@ msgid "Not confidential"
msgstr "Não confidencial"
msgid "Not found"
-msgstr ""
+msgstr "Não encontrado"
msgid "Not found."
msgstr "Não encontrado."
@@ -23855,6 +24178,9 @@ msgstr "Nota: Considere pedir ao seu administrador do GitLab para configurar %{g
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr "Nota: Considere pedir ao seu administrador do GitLab para configurar %{github_integration_link}, o que permitirá a entrada via GitHub e permitir a importação de repositórios sem gerar um token de acesso pessoal."
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr "Nota"
@@ -23867,7 +24193,7 @@ msgstr "Você tem certeza que quer cancelar a criação deste comentário?"
msgid "Notes|Collapse replies"
msgstr "Recolher respostas"
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr "Criar novo perfil de verificação"
msgid "OnDemandScans|Create new site profile"
msgstr "Criar novo perfil de site"
+msgid "OnDemandScans|Delete profile"
+msgstr "Excluir perfil"
+
msgid "OnDemandScans|Description (optional)"
msgstr "Descrição (opcional)"
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr "Editar perfil"
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr "Por exemplo: testa a página de login para injeções de SQL"
@@ -24317,7 +24655,7 @@ msgid "OnDemandScans|New DAST scan"
msgstr "Nova verificação de DAST"
msgid "OnDemandScans|New on-demand DAST scan"
-msgstr ""
+msgstr "Nova verificação DAST sob demanda"
msgid "OnDemandScans|No profile yet. In order to create a new scan, you need to have at least one completed scanner profile."
msgstr "Não há nenhum perfil ainda. Para criar uma nova verificação, você precisa ter pelo menos um perfil completo de verificação."
@@ -24332,17 +24670,26 @@ msgid "OnDemandScans|On-demand scans"
msgstr "Verificação sob demanda"
msgid "OnDemandScans|On-demand scans run outside of DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}."
-msgstr ""
+msgstr "Verificações sob demanda são executadas fora do ciclo DevOps e encontram vulnerabilidades em seus projetos. %{learnMoreLinkStart}Saiba mais%{learnMoreLinkEnd}."
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
+msgstr "Verificações sob demanda são executadas fora do ciclo DevOps e encontram vulnerabilidades em seus projetos. %{learnMoreLinkStart}Saiba mais%{learnMoreLinkEnd}"
+
+msgid "OnDemandScans|Repeats"
msgstr ""
+msgid "OnDemandScans|Run scan"
+msgstr "Executar verificação"
+
msgid "OnDemandScans|Save and run scan"
msgstr "Salvar verificação e executar"
msgid "OnDemandScans|Save scan"
msgstr "Salvar verificação"
+msgid "OnDemandScans|Scan library"
+msgstr "Verificar"
+
msgid "OnDemandScans|Scan name"
msgstr "Nome da verificação"
@@ -24367,18 +24714,33 @@ msgstr "Hora de início"
msgid "OnDemandScans|Target"
msgstr "Destino"
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr "Uma vez importados, os repositórios podem ser espelhados por SSH. Leia
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr "Uma vez removido. o relacionamento do fork não pode ser restaurado. Esse projeto não poderá mais receber ou enviar solicitações de mesclagem para o projeto original ou outros forks."
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr "Quando o arquivo exportado estiver pronto, você receberá um e-mail de notificação com um link para download ou poderá fazer o download a partir desta página."
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24472,10 +24831,10 @@ msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
msgid "Only users from the specified IP address ranges are able to reach this group, including all subgroups, projects, and Git repositories."
-msgstr ""
+msgstr "Apenas usuários dos intervalos de endereços IP especificados podem alcançar este grupo, incluindo todos os subgrupos, projetos e repositórios Git."
msgid "Only verified users with an email address in any of these domains can be added to the group."
-msgstr ""
+msgstr "Apenas usuários verificados com um endereço de e-mail em qualquer um desses domínios podem ser adicionados ao grupo."
msgid "Only ‘Reporter’ roles and above on tiers Premium and above can see Productivity Analytics."
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr "Operação não permitida"
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr "A operação expirou. Verifique os registros do pod para %{pod_name} para mais detalhes."
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr "Painel de operações"
@@ -24742,7 +25104,7 @@ msgid "Package type must be RubyGems"
msgstr ""
msgid "PackageRegistry|%{boldStart}Allow duplicates%{boldEnd} - Accept packages with the same name and version."
-msgstr ""
+msgstr "%{boldStart}Permitir duplicatas%{boldEnd} - Aceitar pacotes com o mesmo nome e versão."
msgid "PackageRegistry|%{boldStart}Do not allow duplicates%{boldEnd} - Reject packages with the same name and version."
msgstr ""
@@ -24996,10 +25358,10 @@ msgid "PackageRegistry|RubyGems"
msgstr "RubyGems"
msgid "PackageRegistry|Settings for Generic packages"
-msgstr ""
+msgstr "Configurações para pacotes genéricos"
msgid "PackageRegistry|Settings for Maven packages"
-msgstr ""
+msgstr "Configurações para pacotes Maven"
msgid "PackageRegistry|Show Composer commands"
msgstr ""
@@ -25047,7 +25409,7 @@ msgid "PackageRegistry|This NuGet package has no dependencies."
msgstr ""
msgid "PackageRegistry|To widen your search, change or remove the filters above."
-msgstr ""
+msgstr "Para ampliar a sua pesquisa, altere ou remova os filtros acima."
msgid "PackageRegistry|Type"
msgstr ""
@@ -25059,7 +25421,7 @@ msgid "PackageRegistry|Unable to load package"
msgstr ""
msgid "PackageRegistry|Use GitLab as a private registry for common package formats. %{linkStart}Learn more.%{linkEnd}"
-msgstr ""
+msgstr "Use o GitLab como um registro privado para formatos de pacote comuns. %{linkStart}Saiba mais.%{linkEnd}"
msgid "PackageRegistry|You are about to delete %{filename}. This is a destructive action that may render your package unusable. Are you sure?"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr "Página não encontrada"
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr "Ativo"
@@ -25245,7 +25604,7 @@ msgid "Paste this DSN into your Sentry SDK"
msgstr ""
msgid "Paste your public SSH key, which is usually contained in the file '~/.ssh/id_ed25519.pub' or '~/.ssh/id_rsa.pub' and begins with 'ssh-ed25519' or 'ssh-rsa'. Do not paste your private SSH key, as that can compromise your identity."
-msgstr ""
+msgstr "Cole a sua chave SSH pública, que geralmente é encontrada no arquivo '~/.ssh/id_ed25519.pub' ou '~/.ssh/id_rsa.pub' e começa com 'ssh-ed25519' ou 'ssh-rsa'. Não cole sua chave SSH privada, pois isso pode comprometer sua identidade."
msgid "Patch to apply"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr "Revisão por pares por"
msgid "Pending"
msgstr "Pendente"
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr "parede"
msgid "Period in seconds"
msgstr "Período em segundos"
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr "Excluir projeto permanentemente"
@@ -25440,7 +25808,7 @@ msgid "Pipeline %{label} for \"%{dataTitle}\""
msgstr "Pipeline %{label} para \"%{dataTitle}\""
msgid "Pipeline Editor"
-msgstr ""
+msgstr "Editor de pipeline"
msgid "Pipeline Editor|Are you sure you want to reset the file to its last committed version?"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr "URL do pipeline"
msgid "Pipeline durations for the last 30 commits"
msgstr "Durações de pipeline dos últimos 30 commits"
-msgid "Pipeline minutes quota"
-msgstr "Quota de minutos de pipeline"
-
-msgid "Pipeline minutes quota:"
-msgstr "Quota de minutos de pipeline:"
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr "Pipeline filho"
msgid "Pipelines|Clear runner caches"
msgstr "Limpar cache dos executores"
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr "Copiar token de gatilho"
@@ -25806,10 +26171,10 @@ msgid "Pipelines|This GitLab CI configuration is invalid."
msgstr "Essa configuração do GitLab CI é invalida."
msgid "Pipelines|This GitLab CI configuration is invalid:"
-msgstr ""
+msgstr "Essa configuração do GitLab CI é invalida:"
msgid "Pipelines|This GitLab CI configuration is invalid: %{reason}."
-msgstr ""
+msgstr "Essa configuração do GitLab CI é invalida: %{reason}"
msgid "Pipelines|This GitLab CI configuration is valid."
msgstr "Essa configuração do GitLab CI é válida."
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr "Pipeline de resultado mesclado"
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr "Passou"
@@ -26001,7 +26363,7 @@ msgid "Pipeline|Variables"
msgstr "Variáveis"
msgid "Pipeline|View commit"
-msgstr ""
+msgstr "Ver commit"
msgid "Pipeline|View pipeline"
msgstr "Ver pipeline"
@@ -26198,6 +26560,12 @@ msgstr "Por favor, entre em contato se você tiver alguma dúvida, e nós ficare
msgid "Please refer to %{docs_url}"
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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr "Por favor selecione"
@@ -26210,6 +26578,9 @@ msgstr "Por favor selecione um país"
msgid "Please select a file"
msgstr "Por favor, selecione um arquivo"
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr "Por favor, selecione um grupo."
@@ -26405,14 +26776,11 @@ msgstr "Preferências de hora"
msgid "Preferences|Use relative times"
msgstr "Usar tempos relativos"
-msgid "Press %{key}-C to copy"
-msgstr "Pressione %{key}-C para copiar"
-
msgid "Prev"
msgstr ""
msgid "Prevent adding new members to projects within this group"
-msgstr ""
+msgstr "Evitar adicionar novos membros a projetos dentro deste grupo"
msgid "Prevent auto-stopping"
msgstr "Evitar a parada automática"
@@ -26427,10 +26795,10 @@ msgid "Prevent project forking outside current group"
msgstr "Evitar o fork do projeto fora do grupo atual"
msgid "Prevent users from changing their profile name"
-msgstr ""
+msgstr "Evitar que os usuários alterem seus nomes de perfil"
msgid "Prevent users from performing write operations while GitLab maintenance is in progress."
-msgstr ""
+msgstr "Evitar que os usuários realizem operações de gravação enquanto a manutenção do Gitlab está em andamento."
msgid "Preview"
msgstr "Pré-visualizar"
@@ -26694,7 +27062,7 @@ msgid "Profiles|Do not show on profile"
msgstr "Não mostrar no perfil"
msgid "Profiles|Don't display activity-related personal information on your profile"
-msgstr ""
+msgstr "Não exibir informações pessoais relacionadas à atividade em seu perfil"
msgid "Profiles|Edit Profile"
msgstr "Editar perfil"
@@ -26712,10 +27080,10 @@ msgid "Profiles|Enter your password to confirm the email change"
msgstr "Digite sua senha para confirmar a alteração do e-mail"
msgid "Profiles|Enter your pronouns to let people know how to refer to you"
-msgstr "Digite seu pronome para que as pessoas sabiam como preferir a você"
+msgstr "Preencha seu pronome para que as pessoas saibam como se referir a você"
msgid "Profiles|Expiration date"
-msgstr ""
+msgstr "Data de expiração"
msgid "Profiles|Expired key is not valid."
msgstr "A chave expirada não é válida."
@@ -26759,11 +27127,14 @@ msgstr "Senha inválida"
msgid "Profiles|Invalid username"
msgstr "Nome de usuário inválido"
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr "Chave"
msgid "Profiles|Key becomes invalid on this date."
-msgstr ""
+msgstr "A chave torna-se inválida nesta data."
msgid "Profiles|Key becomes invalid on this date. Maximum lifetime for SSH keys is %{max_ssh_key_lifetime} days"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr "Contribuições privadas"
msgid "Profiles|Profile was successfully updated"
msgstr "O perfil foi atualizado com sucesso"
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr "Avatar público"
@@ -26900,6 +27277,9 @@ msgstr "Alteração de nome de usuário realizada com sucesso"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr "Usar emojis em nomes parece divertido, mas tente definir uma mensagem de status"
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr "Qual é o seu status?"
@@ -27111,7 +27491,7 @@ msgid "Project path"
msgstr "Caminho do projeto"
msgid "Project security status"
-msgstr ""
+msgstr "Status de segurança do projeto"
msgid "Project security status help page"
msgstr ""
@@ -27180,7 +27560,7 @@ msgid "ProjectOverview|Unstar"
msgstr "Desmarcar como favorito"
msgid "ProjectOverview|You don't have permission to fork this project"
-msgstr ""
+msgstr "Você não tem permissão para fazer fork desse projeto"
msgid "ProjectOverview|You have reached your project limit"
msgstr "Você atingiu seu limite de projetos"
@@ -27194,6 +27574,48 @@ msgstr "Copiar ID do projeto"
msgid "ProjectPage|Project ID: %{project_id}"
msgstr "ID do Projeto: %{project_id}"
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr " ou grupo"
@@ -27288,7 +27710,7 @@ msgid "ProjectService|Trigger event for new tags pushed to the repository."
msgstr ""
msgid "ProjectService|Trigger event for pushes to the repository."
-msgstr ""
+msgstr "Evento de gatilho para envios para o repositório."
msgid "ProjectService|Trigger event when a commit is created or updated."
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr "Configurações adicionais que influenciam como e onde as mesclagem são feitas."
@@ -27387,7 +27812,7 @@ msgid "ProjectSettings|Enable merged results pipelines"
msgstr "Ativar pipelines de resultados mesclados"
msgid "ProjectSettings|Encourage"
-msgstr ""
+msgstr "Incentivar"
msgid "ProjectSettings|Every merge creates a merge commit."
msgstr "Cada merge cria um commit de mesclagem."
@@ -27402,7 +27827,7 @@ msgid "ProjectSettings|Everyone"
msgstr "Todos"
msgid "ProjectSettings|Existing merge requests and protected branches are not affected."
-msgstr ""
+msgstr "Solicitações de mesclagem existentes e ramificações protegidas não são afetadas."
msgid "ProjectSettings|Failed to protect the tag"
msgstr "Falha ao proteger a tag"
@@ -27423,7 +27848,7 @@ msgid "ProjectSettings|Forks"
msgstr "Forks"
msgid "ProjectSettings|Git Large File Storage (LFS)"
-msgstr ""
+msgstr "Git Large File Storage (LFS)"
msgid "ProjectSettings|Global"
msgstr "Global"
@@ -27450,7 +27875,7 @@ msgid "ProjectSettings|Manages large files such as audio, video, and graphics fi
msgstr "Gerencia arquivos grandes, como arquivos de áudio, vídeo e gráficos."
msgid "ProjectSettings|Maximum 500 characters."
-msgstr ""
+msgstr "Máximo de 500 caracteres."
msgid "ProjectSettings|Merge checks"
msgstr "Verificações de mesclagem"
@@ -27459,7 +27884,7 @@ msgid "ProjectSettings|Merge commit"
msgstr "Commit de mesclagem"
msgid "ProjectSettings|Merge commit message template"
-msgstr ""
+msgstr "Modelo de mensagem de commit de mesclagem"
msgid "ProjectSettings|Merge commit with semi-linear history"
msgstr "Commit de mesclagem com uma história semilinear"
@@ -27519,10 +27944,10 @@ msgid "ProjectSettings|Repository"
msgstr "Repositório"
msgid "ProjectSettings|Require"
-msgstr ""
+msgstr "Exigir"
msgid "ProjectSettings|Require an associated issue from Jira"
-msgstr ""
+msgstr "Exigir uma issue associada ao Jira"
msgid "ProjectSettings|Requirements"
msgstr "Requisitos"
@@ -27531,7 +27956,7 @@ msgid "ProjectSettings|Requirements management system."
msgstr "Sistema de gerenciamento de requisitos."
msgid "ProjectSettings|Search for topic"
-msgstr ""
+msgstr "Pesquisar tópico"
msgid "ProjectSettings|Security & Compliance"
msgstr "Segurança e conformidade"
@@ -27549,7 +27974,7 @@ msgid "ProjectSettings|Show default award emojis"
msgstr ""
msgid "ProjectSettings|Show link to create or view a merge request when pushing from the command line"
-msgstr ""
+msgstr "Mostrar link para criar ou ver uma solicitação de mesclagem ao fazer push da linha de comando"
msgid "ProjectSettings|Skipped pipelines are considered successful"
msgstr "Pipelines ignorados são considerados bem-sucedidos"
@@ -27572,19 +27997,16 @@ msgstr "Squashing nunca é executado e a caixa de seleção está oculta."
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr "Enviar alterações para serem mescladas no upstream."
-msgid "ProjectSettings|Supported variables:"
-msgstr "Variáveis suportadas"
-
msgid "ProjectSettings|Target project"
msgstr "Projeto alvo"
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27609,7 +28031,7 @@ msgid "ProjectSettings|To enable this feature, configure pipelines. %{link_start
msgstr "Para ativar este recurso, configure pipelines. %{link_start}Como configurar pipelines para solicitações de mesclagem?%{link_end}"
msgid "ProjectSettings|Transfer project"
-msgstr ""
+msgstr "Transferir projeto"
msgid "ProjectSettings|Upstream project"
msgstr ""
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr "iOS (Swift)"
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr "Projetos"
@@ -27750,7 +28181,7 @@ msgid "Projects Successfully Retrieved"
msgstr "Projetos obtidos com sucesso"
msgid "Projects are graded based on the highest severity vulnerability present"
-msgstr ""
+msgstr "Os projetos são classificados com base na vulnerabilidade de maior severidade presente"
msgid "Projects are organized into groups"
msgstr "Os projetos são organizados em grupos"
@@ -27792,7 +28223,7 @@ msgid "Projects with no vulnerabilities and security scanning enabled"
msgstr ""
msgid "Projects with this topic"
-msgstr ""
+msgstr "Projetos com este tópico"
msgid "Projects with write access"
msgstr "Projetos com acesso de gravação"
@@ -27852,7 +28283,7 @@ msgid "ProjectsNew|Description format"
msgstr "Formato de descrição"
msgid "ProjectsNew|Enable Static Application Security Testing (SAST)"
-msgstr ""
+msgstr "Ativar teste de segurança de aplicativo estático (SAST)"
msgid "ProjectsNew|Import"
msgstr "Importar"
@@ -28002,7 +28433,7 @@ msgid "Promote issue to an epic"
msgstr "Promover issue para um épico"
msgid "Promote issue to incident"
-msgstr ""
+msgstr "Promover issue para incidente"
msgid "Promote to epic"
msgstr ""
@@ -28023,13 +28454,13 @@ msgid "Promoted issue to an epic."
msgstr "Issue promovida para um épico."
msgid "Promotes issue to incident"
-msgstr ""
+msgstr "Promove issue para incidente"
msgid "Promotion is not supported."
msgstr ""
msgid "Promotions|Add %{link_start} description templates %{link_end} to help your contributors to communicate effectively!"
-msgstr ""
+msgstr "Adicione %{link_start}modelos de descrição %{link_end} para ajudar seus colaboradores a se comunicarem de maneira eficaz!"
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr "Adicione webhooks de grupo e GitLab Enterprise Edition."
@@ -28038,7 +28469,7 @@ msgid "Promotions|Better Protected Branches"
msgstr "Ramificações protegidas com a melhor proteção"
msgid "Promotions|Burndown Charts are visual representations of the progress of completing a milestone. At a glance, you see the current state for the completion a given milestone. Without them, you would have to organize the data from the milestone and plot it yourself to have the same sense of progress."
-msgstr ""
+msgstr "Gráficos de burndown são representações visuais do progresso de conclusão de um marco. De relance, você vê o estado atual para a conclusão de um determinado marco. Sem eles, você teria que organizar os dados do marco e traçá-los você mesmo para ter a mesma sensação de progresso."
msgid "Promotions|Buy EE"
msgstr "Comprar EE"
@@ -28119,14 +28550,11 @@ msgid "Promotions|Start GitLab Ultimate trial"
msgstr "Iniciar avaliação do GitLab Ultimate"
msgid "Promotions|The Advanced Search in GitLab is a powerful search service that saves you time. Instead of creating duplicate code and wasting time, you can now search for code within other teams that can help your own project."
-msgstr ""
+msgstr "A pesquisa avançada no GitLab é um serviço de pesquisa poderoso que economiza seu tempo. Ao invés de criar códigos duplicados e perder seu tempo, você pode agora pesquisar códigos de outros times que podem ajudar em seu projeto."
msgid "Promotions|This feature is locked."
msgstr "Esse recurso está bloqueado."
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr "Acompanhe atividades com a análises de contribuição."
-
msgid "Promotions|Try it for free"
msgstr "Experimente grátis"
@@ -28139,11 +28567,8 @@ msgstr "Aprimore seu plano para ativar a pesquisa avançada"
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr "Aprimore o seu plano para ativar os eventos de auditoria."
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr "Aprimore seu plano para ativar a análise de contribuição."
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
-msgstr ""
+msgstr "Atualize seu plano para ativar Webhooks do grupo."
msgid "Promotions|Upgrade your plan to improve merge requests."
msgstr "Aprimore seu plano para melhorar as solicitações de mesclagem."
@@ -28155,7 +28580,7 @@ msgid "Promotions|Upgrade your plan to improve repositories."
msgstr "Aprimore seu plano para melhorar os repositórios."
msgid "Promotions|Webhooks allow you to trigger a URL if, for example, new code is pushed or a new issue is created. You can configure webhooks to listen for specific events like pushes, issues or merge requests. Group webhooks will apply to all projects in a group, allowing you to standardize webhook functionality across your entire group."
-msgstr ""
+msgstr "Webhooks permitem que você acione uma URL se, por exemplo, um novo código for feito push ou uma nova issue criada. Você pode configurar os webhooks para escutar eventos específicos como push, issue ou merge request. Webhooks de grupo aplicarão para todos os projetos no grupo, permitindo você padronizar o funcionamento em todo o grupo."
msgid "Promotions|Weight"
msgstr "Peso"
@@ -28166,9 +28591,6 @@ msgstr "Ponderar sua issue"
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr "Com as análises de contribuição você pode ter uma visão geral da atividade de issues, solicitação de mesclagem e eventos de push para sua organização e seus membros."
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr "Você pode restringir o acesso a ramificações protegidas escolhendo um cargo (Mantenedores, Desenvolveres) e também determinados usuários."
@@ -28250,6 +28672,9 @@ msgstr "Permitido para push:"
msgid "ProtectedBranch|Branch"
msgstr "Ramificação"
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr "Ramificação:"
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr "O que são ramificações protegidas?"
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr "%{environment_name} poderá ser editado por desenvolvedores. Tem certeza disso?"
@@ -28340,6 +28771,9 @@ msgstr "Seu ambiente foi protegido."
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "Seu ambiente foi desprotegido"
+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."
@@ -28355,6 +28789,9 @@ msgstr "Tags protegidas"
msgid "ProtectedTag|What are protected tags?"
msgstr "O que são tags protegidas?"
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28392,7 +28829,7 @@ msgid "Public Access Help"
msgstr ""
msgid "Public deploy keys"
-msgstr ""
+msgstr "Chaves públicas de implantação"
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr "Chaves de implantação públicas (%{deploy_keys_count})"
@@ -28473,7 +28910,7 @@ msgid "PushRules|All commit author's email must match this %{wiki_syntax_link_st
msgstr ""
msgid "PushRules|All commit messages must match this %{wiki_syntax_link_start}regular expression%{wiki_syntax_link_end}. If empty, commit messages are not required to match any expression."
-msgstr ""
+msgstr "Todas as mensagens de commit devem corresponder a esta %{wiki_syntax_link_start}expressão regular%{wiki_syntax_link_end}. Se estiver vazio, as mensagens de confirmação não precisam corresponder a nenhuma expressão."
msgid "PushRules|All committed filenames cannot match this %{wiki_syntax_link_start}regular expression%{wiki_syntax_link_end}. If empty, any filename is allowed."
msgstr ""
@@ -28485,7 +28922,7 @@ msgid "PushRules|Do not allow users to remove Git tags with %{code_block_start}g
msgstr "Não permitir que os usuários removam tags do Git com %{code_block_start}git push%{code_block_end}"
msgid "PushRules|Reject any files likely to contain secrets. %{secret_files_link_start}What secret files are rejected?%{secret_files_link_end}"
-msgstr ""
+msgstr "Rejeita quaisquer arquivos que provavelmente contenham segredos. %{secret_files_link_start}Quais arquivos secretos são rejeitados?%{secret_files_link_end}"
msgid "PushRules|Reject file sizes equal to or greater than this size. If set to 0, files of any size are allowed. This rule does not apply to files tracked by Git LFS."
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr "Edite rapidamente e facilmente vários arquivos em seu projeto."
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr "README"
@@ -28768,9 +29211,6 @@ msgstr "Regenerar exportação"
msgid "Regenerate instance ID"
msgstr "Regenerar ID de instância"
-msgid "Regenerate key"
-msgstr "Gerar uma nova chave"
-
msgid "Regenerate recovery codes"
msgstr "Regenerar códigos de recuperação"
@@ -28813,6 +29253,54 @@ msgstr "Registre-se com aplicativo de dois fatores"
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
-msgstr "Projetos que foram removidos e ainda não foram removidos permanentemente estão visíveis aqui."
+msgid "RemovedProjects|No projects pending deletion found"
+msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr "Continuar"
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr "Tentar novamente"
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr "Refazer tarefa"
@@ -29915,7 +30412,7 @@ msgid "Revoke"
msgstr "Revogar"
msgid "Revoked"
-msgstr ""
+msgstr "Revogado"
msgid "Revoked impersonation token %{token_name}!"
msgstr "Revogado o token de representação %{token_name}!"
@@ -30017,7 +30514,7 @@ msgid "Runners|Active"
msgstr "Ativo"
msgid "Runners|All"
-msgstr ""
+msgstr "Todos"
msgid "Runners|Amazon Linux 2 Docker HA with manual scaling and optional scheduling. %{percentage} spot."
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr "Arquitetura"
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr "Copiar instruções"
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30074,7 +30574,7 @@ msgid "Runners|For each solution, you will choose a capacity. 1 enables warm HA
msgstr ""
msgid "Runners|Group"
-msgstr ""
+msgstr "Grupo"
msgid "Runners|Group Runners"
msgstr "Executores de grupo"
@@ -30089,7 +30589,7 @@ msgid "Runners|Install a runner"
msgstr "Instalar um executor"
msgid "Runners|Instance"
-msgstr ""
+msgstr "Instância"
msgid "Runners|Last contact"
msgstr "Último contato"
@@ -30106,10 +30606,16 @@ msgstr ""
msgid "Runners|Name"
msgstr "Nome"
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr "Novo token de registro gerado!"
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
+msgstr ""
+
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
@@ -30118,9 +30624,6 @@ msgstr ""
msgid "Runners|Not available to run jobs"
msgstr ""
-msgid "Runners|Not connected"
-msgstr "Não conectado"
-
msgid "Runners|Offline"
msgstr ""
@@ -30137,7 +30640,7 @@ msgid "Runners|Platform"
msgstr "Plataforma"
msgid "Runners|Project"
-msgstr ""
+msgstr "Projeto"
msgid "Runners|Property Name"
msgstr "Nome da propriedade"
@@ -30172,6 +30675,9 @@ msgstr "Executor"
msgid "Runners|Runner #%{runner_id}"
msgstr "Executor #%{runner_id}"
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr "Tags"
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr "grupo"
msgid "Runners|locked"
msgstr "bloqueado"
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr "compartilhado"
msgid "Runners|specific"
msgstr "específicos"
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr "Executando"
@@ -30482,7 +30997,7 @@ msgid "Scopes (select at least one)"
msgstr "Escopos (selecione pelo menos um)"
msgid "Scopes can't be blank"
-msgstr ""
+msgstr "Os escopos não podem ficar em branco"
msgid "Scopes: %{scope_list}"
msgstr "Escopos: %{scope_list}"
@@ -30574,6 +31089,9 @@ msgstr "Pesquisar por este texto"
msgid "Search forks"
msgstr "Pesquisar forks"
+msgid "Search groups"
+msgstr "Pesquisar grupos"
+
msgid "Search iterations"
msgstr "Pesquisar iteração"
@@ -30595,9 +31113,6 @@ msgstr "Pesquisar ou filtrar resultados..."
msgid "Search or filter results…"
msgstr "Pesquisar ou filtrar resultados…"
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr "Procurar projeto"
@@ -30638,22 +31153,22 @@ msgid "SearchAutocomplete|Issues assigned to me"
msgstr "Issues atribuídas a mim"
msgid "SearchAutocomplete|Merge requests I've created"
-msgstr "Merge requests que eu criei"
+msgstr "Solicitações de mesclagem que eu criei"
msgid "SearchAutocomplete|Merge requests assigned to me"
-msgstr "Merge requests atribuídas a mim"
+msgstr "Solicitações de mesclagem atribuídas a mim"
msgid "SearchAutocomplete|Merge requests that I'm a reviewer"
-msgstr "Merge requests que eu sou revisor"
+msgstr "Solicitações de mesclagem que eu sou revisor"
msgid "SearchAutocomplete|in all GitLab"
msgstr "em todo o GitLab"
msgid "SearchAutocomplete|in group %{groupName}"
-msgstr ""
+msgstr "no grupo %{groupName}"
msgid "SearchAutocomplete|in project %{projectName}"
-msgstr ""
+msgstr "no projeto %{projectName}"
msgid "SearchCodeResults|of %{link_to_project}"
msgstr "de %{link_to_project}"
@@ -30816,7 +31331,7 @@ msgid "SecurityApprovals|License-Check"
msgstr "Verificação de licença"
msgid "SecurityApprovals|Requires approval for Denied licenses. %{linkStart}More information%{linkEnd}"
-msgstr ""
+msgstr "Requer aprovação para licenças negadas. %{linkStart}Mais informações%{linkEnd}"
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}Learn more.%{linkEnd}"
msgstr "Requer aprovação para reduções de cobertura de teste. %{linkStart}Saiba mais%{linkEnd}"
@@ -30840,7 +31355,7 @@ msgid "SecurityConfiguration|Available with Ultimate"
msgstr "Disponível com Ultimate"
msgid "SecurityConfiguration|By default, all analyzers are applied in order to cover all languages across your project, and only run if the language is detected in the merge request."
-msgstr ""
+msgstr "Por padrão, todos os analisadores são aplicados para cobrir todos os idiomas em seu projeto e só são executados se o idioma for detectado na solicitação de mesclagem."
msgid "SecurityConfiguration|Compliance"
msgstr "Conformidade"
@@ -30852,10 +31367,10 @@ msgid "SecurityConfiguration|Configuration history"
msgstr "Histórico de configuração"
msgid "SecurityConfiguration|Configure %{feature}"
-msgstr ""
+msgstr "Configurar%{feature}"
msgid "SecurityConfiguration|Configure with a merge request"
-msgstr ""
+msgstr "Configurar com uma solicitação de mesclagem"
msgid "SecurityConfiguration|Copy code and open .gitlab-ci.yml file"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr "Ativar %{feature}"
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr "Ativar Auto DevOps"
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr "Ativado"
@@ -30885,7 +31403,7 @@ msgid "SecurityConfiguration|High-level vulnerability statistics across projects
msgstr "Estatísticas de vulnerabilidade de alto nível em projetos e grupos"
msgid "SecurityConfiguration|Immediately begin risk analysis and remediation with application security features. Start with SAST and Secret Detection, available to all plans. Upgrade to Ultimate to get all features, including:"
-msgstr ""
+msgstr "Comece imediatamente a análise de risco e remediação com recursos de segurança da aplicação. Comece com SAST e detecção secreta, disponível para todos os planos. Atualize para o Ultimate para obter todos os recursos, incluindo:"
msgid "SecurityConfiguration|Manage corpus"
msgstr "Gerenciar corpus"
@@ -30906,7 +31424,7 @@ msgid "SecurityConfiguration|Not enabled"
msgstr "Não ativado"
msgid "SecurityConfiguration|Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
+msgstr "Depois de ativar uma verificação para a ramificação padrão, qualquer ramificação de recurso subsequente que você criar incluirá a verificação."
msgid "SecurityConfiguration|Quickly enable all continuous testing and compliance tools by enabling %{linkStart}Auto DevOps%{linkEnd}"
msgstr "Ative rapidamente todos os testes contínuos e ferramentas de conformidade ativando %{linkStart}Auto DevOps%{linkEnd}"
@@ -30939,7 +31457,7 @@ msgid "SecurityConfiguration|Using custom settings. You won't receive automatic
msgstr ""
msgid "SecurityConfiguration|Vulnerability Management"
-msgstr ""
+msgstr "Gerenciamento de vulnerabilidades"
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr "Detalhes de vulnerabilidade e estatísticas na solicitação de mesclagem"
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr "Ação"
@@ -31004,6 +31525,9 @@ msgstr "Rede"
msgid "SecurityOrchestration|New policy"
msgstr "Nova política"
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31032,10 +31556,10 @@ msgid "SecurityOrchestration|Rules"
msgstr "Regras"
msgid "SecurityOrchestration|Scan Execution"
-msgstr ""
+msgstr "Execução de verificação"
msgid "SecurityOrchestration|Scan execution"
-msgstr ""
+msgstr "Execução de verificação"
msgid "SecurityOrchestration|Scan execution policies can only be created by project owners."
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr "ver resultados"
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr "+%{count} mais"
@@ -31289,6 +31810,9 @@ msgstr "Definir status"
msgid "SecurityReports|Severity"
msgstr "Severidade"
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr "Status"
msgid "SecurityReports|Take survey"
msgstr "Responder pesquisa"
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31338,7 +31865,7 @@ msgid "SecurityReports|These vulnerabilities were detected in external sources.
msgstr ""
msgid "SecurityReports|To widen your search, change or remove filters above"
-msgstr ""
+msgstr "Para ampliar sua pesquisa, altere ou remova os filtros acima"
msgid "SecurityReports|Tool"
msgstr "Ferramenta"
@@ -31376,6 +31903,9 @@ msgstr "Você não tem permissões suficientes para acessar esse relatório"
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31395,7 +31925,7 @@ msgid "See the affected projects in the GitLab admin panel"
msgstr "Veja os projetos afetados no painel de administração do GitLab"
msgid "See the list of available commands in Slack after setting up this service by entering"
-msgstr ""
+msgstr "Veja a lista de comandos disponíveis no Slack após configurar este serviço, digitando"
msgid "See vulnerability %{vulnerability_link} for any Remediation details."
msgstr ""
@@ -31476,7 +32006,7 @@ msgid "Select assignee"
msgstr "Selecionar responsável"
msgid "Select assignee(s)"
-msgstr ""
+msgstr "Selecionar responsável"
msgid "Select branch"
msgstr "Selecionar ramificação"
@@ -31529,6 +32059,9 @@ msgstr "Selecione projeto e zona para escolher o tipo de máquina"
msgid "Select project to choose zone"
msgstr "Selecione o projeto para escolher a zona"
+msgid "Select project to create %{type}"
+msgstr "Selecione o projeto para criar %{type}"
+
msgid "Select project to create issue"
msgstr ""
@@ -31782,13 +32315,13 @@ msgid "Service"
msgstr "Serviço"
msgid "Service Account"
-msgstr ""
+msgstr "Conta de serviço"
msgid "Service Account Key"
-msgstr ""
+msgstr "Chave de conta de serviço"
msgid "Service Accounts"
-msgstr ""
+msgstr "Contas de serviço"
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -31851,7 +32384,7 @@ msgid "ServicePing|Turn on service ping to review instance-level analytics."
msgstr ""
msgid "Services"
-msgstr ""
+msgstr "Serviços"
msgid "Session ID"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr "Definir padrão e restringir os níveis de visibilidade. Configurar font
msgid "Set due date"
msgstr "Definir validade"
+msgid "Set health status"
+msgstr "Definir status de saúde"
+
+msgid "Set health status to %{health_status}."
+msgstr "Defina o status de saúde como %{health_status}."
+
msgid "Set iteration"
msgstr ""
@@ -31977,7 +32516,7 @@ msgid "Set up new password"
msgstr "Definir uma nova senha"
msgid "Set up shared runner availability"
-msgstr ""
+msgstr "Configurar disponibilidade de executor compartilhado"
msgid "Set up your project to automatically push and/or pull changes to/from another repository. Branches, tags, and commits will be synced automatically."
msgstr "Configure seu projeto para fazer push e/ou pull de um repositório para outro automaticamente. Branches, tags e commits serão sincronizados automaticamente."
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr "Definir %{epic_ref} como épico pai."
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr "Definir ramificação de destino à %{branch_name}."
@@ -32553,7 +33095,7 @@ msgid "Some child epics may be hidden due to applied filters"
msgstr ""
msgid "Some common domains are not allowed. %{learn_more_link}."
-msgstr ""
+msgstr "Alguns domínios comuns não são permitidos. %{learn_more_link}"
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 "Alguém editou a issue ao mesmo tempo que você. Por favor, verifique %{linkStart}a issue%{linkEnd} e tenha certeza de que suas alterações não irão intencionalmente remover as alterações da outra pessoa."
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr "Algo deu errado ao atualizar os responsáveis"
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr "Comece sua avaliação Ultimate gratuita"
msgid "Start your free trial"
msgstr "Inicie o seu teste gratuito"
-msgid "Start your trial"
-msgstr "Iniciar sua avaliação"
-
msgid "Started"
msgstr "Iniciado"
@@ -33321,7 +33863,7 @@ msgid "StatusCheck|Apply this status check to all branches or a specific protect
msgstr ""
msgid "StatusCheck|Check for a status response in merge requests. Failures do not block merges. %{link_start}Learn more%{link_end}."
-msgstr ""
+msgstr "Verifique se há uma resposta de status nas solicitações de mesclagem. As falhas não bloqueiam as mesclagens. %{link_start}Saiba mais%{link_end}"
msgid "StatusCheck|Examples: QA, Security."
msgstr ""
@@ -33396,7 +33938,7 @@ msgid "StatusPage|Bucket %{docsLink}"
msgstr ""
msgid "StatusPage|Configure file storage settings to link issues in this project to an external status page."
-msgstr ""
+msgstr "Defina as configurações de armazenamento de arquivo para vincular issues neste projeto a uma página de status externa."
msgid "StatusPage|S3 Bucket name"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr "Adicionar lugares"
@@ -34013,6 +34561,24 @@ msgstr "A sintaxe está correta."
msgid "Syntax is incorrect."
msgstr "A sintaxe está incorreta."
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr "Escuro"
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr "Claro"
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr "Nenhum"
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr "Sistema"
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr "Detalhes"
msgid "Terraform|Download JSON"
msgstr "Baixar JSON"
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr "Como usar o Terraform State gerenciado pelo GitLab?"
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr "Estados"
msgid "Terraform|Terraform init command"
msgstr "Comando init do Terraform"
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr "O relatório de conformidade captura mudanças mescladas que violam as melhores práticas de conformidade."
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "A conexão expirará após %{timeout}. Para repositórios que demoram mais tempo, use a combinação clone/push."
@@ -34775,9 +35375,6 @@ msgstr "O grupo e quaisquer projetos públicos podem ser visualizados por todos
msgid "The group and its projects can only be viewed by members."
msgstr "O grupo e seus projetos só podem ser visualizados por seus membros."
-msgid "The group can be fully restored"
-msgstr "O grupo pode ser totalmente restaurado"
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr "As configurações de grupo para %{group_links} exigem que você habilite a autenticação de dois fatores para sua conta. Você pode %{leave_group_links}."
-msgid "The group will be placed in 'pending deletion' state"
-msgstr "O grupo será colocado no estado de 'exclusão pendente'"
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr "O tamanho máximo de arquivo é %{size}."
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr "Não há issues para mostrar"
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr "Ainda não há etiquetas"
-
msgid "There are no matching files"
msgstr "Não há arquivos correspondentes"
@@ -35418,13 +36009,13 @@ msgid "These runners are shared across projects in this group."
msgstr "Esses executores são compartilhados entre projetos neste grupo."
msgid "These runners are shared across this GitLab instance."
-msgstr ""
+msgstr "Esses executores são compartilhados nesta instância do GitLab."
msgid "These runners are specific to this project."
msgstr "Esses executores são específicos para este projeto."
msgid "These variables are inherited from the parent group."
-msgstr ""
+msgstr "Essas variáveis são herdadas do grupo pai."
msgid "These will be sent to %{email} in an attachment once finished."
msgstr "Estes serão enviados para %{email} em um anexo quando terminado."
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ 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 has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr "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."
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr "Esse aplicativo será capaz de:"
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,11 +36212,14 @@ msgstr "Este formulário está desativado na pré-visualização"
msgid "This group"
msgstr "Esse grupo"
-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."
+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 ""
+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 ""
+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 cannot be invited to a project inside a group with enforced SSO"
msgstr ""
@@ -35783,6 +36380,9 @@ msgstr "Essa tarefa exige uma ação manual"
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -35865,7 +36465,7 @@ msgid "This project has no active access tokens."
msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
-msgstr ""
+msgstr "Este projeto %{strongStart}NÃO%{strongEnd} tem um fork e tem o seguinte:"
msgid "This project is archived and cannot be commented on."
msgstr "Este projeto está arquivado e não pode ser comentado."
@@ -35928,13 +36528,13 @@ msgid "This user has an unconfirmed email address. You may force a confirmation.
msgstr ""
msgid "This user has no active %{type}."
-msgstr ""
+msgstr "Este usuário não tem %{type} ativo."
msgid "This user has no identities"
msgstr "Esse usuário não tem identidades"
msgid "This user has no personal projects."
-msgstr ""
+msgstr "Este usuário não tem projetos pessoais."
msgid "This user has previously committed to the %{name} project."
msgstr ""
@@ -35967,7 +36567,7 @@ msgid "Thread to reply to cannot be found"
msgstr ""
msgid "Threat monitoring"
-msgstr ""
+msgstr "Monitoramento de ameaças"
msgid "ThreatMonitoring|Alert Details"
msgstr "Detalhes de alerta"
@@ -36072,7 +36672,7 @@ msgid "ThreatMonitoring|Time"
msgstr "Tempo"
msgid "ThreatMonitoring|To view this data, ensure you have configured an environment for this project and that at least one threat monitoring feature is enabled. %{linkStart}More information%{linkEnd}"
-msgstr ""
+msgstr "Para visualizar esses dados, verifique se você configurou um ambiente para este projeto e se pelo menos um recurso de monitoramento de ameaças está habilitado. %{linkStart}Mais informações%{linkEnd}"
msgid "ThreatMonitoring|Total Packets"
msgstr "Total de pacotes"
@@ -36495,6 +37095,9 @@ 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 "Para receber alertas de serviços Prometheus configurados manualmente, adicione o URL e chaves de autorização a seguir ao seu arquivo de configuração de webhook do Prometheus. Saiba mais sobre %{linkStart}configuração do Prometheus%{linkEnd} para enviar alertas para o GitLab."
+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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36544,10 +37147,10 @@ msgid "To view all %{scannedResourcesCount} scanned URLs, %{linkStart}please dow
msgstr ""
msgid "To widen your search, change or remove filters above"
-msgstr ""
+msgstr "Para ampliar sua pesquisa, altere ou remova os filtros acima"
msgid "To widen your search, change or remove filters above."
-msgstr ""
+msgstr "Para ampliar sua pesquisa, altere ou remova os filtros acima."
msgid "To widen your search, change or remove filters."
msgstr "Para ampliar sua pesquisa, alterar ou remover filtros."
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
msgstr "Hoje"
+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 ""
+
+msgid "Todos|Filter by author"
+msgstr "Filtrar por autor"
+
+msgid "Todos|Filter by group"
+msgstr "Filtrar por grupo"
+
+msgid "Todos|Filter by project"
+msgstr "Filtrar por projeto"
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr "Alternar para o GitLab Next"
@@ -36730,11 +37366,14 @@ msgid "Track your GitLab projects with GitLab for Slack."
msgstr ""
msgid "Training mode"
-msgstr ""
+msgstr "Modo de treinamento"
msgid "Transfer"
msgstr "Transferir"
+msgid "Transfer group to another parent group."
+msgstr "Transfira o grupo para outro grupo pai."
+
msgid "Transfer ownership"
msgstr "Transferir a propriedade"
@@ -36803,8 +37442,8 @@ msgstr "Mais populares"
msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Teste %{planName} %{enDash} %{num} dia restante"
+msgstr[1] "Teste %{planName} %{enDash} %{num} dias restantes"
msgid "Trials|Compare all plans"
msgstr "Comparar todos os planos"
@@ -36857,15 +37496,6 @@ msgstr "Nome"
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr "Avaliação do GitLab Ultimate (opcional)"
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr "Quantos usuários estarão avaliando o teste?"
-
msgid "Trial|Last name"
msgstr "Sobrenome"
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr "Sua avaliação do GitLab Ultimate dura 30 dias, mas você pode manter sua conta GitLab gratuita para sempre. Precisamos apenas de algumas informações adicionais para ativar sua avaliação."
-msgid "Trial|your company"
-msgstr "sua empresa"
-
msgid "Trigger"
msgstr ""
@@ -37509,7 +38136,7 @@ msgid "Upload license"
msgstr "Enviar licença"
msgid "Upload new file"
-msgstr ""
+msgstr "Enviar novo arquivo"
msgid "Upload object map"
msgstr "Enviar mapa de objetos"
@@ -37520,9 +38147,6 @@ msgstr "clique para fazer upload"
msgid "Uploading changes to terminal"
msgstr "Enviando mudanças ao terminal"
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr "Ao realizar esta ação, o conteúdo deste grupo seu subgrupo e projetos serão excluídos permanentemente após %{deletion_adjourned_period} dias em %{date}. Até aquele momento:"
-
msgid "Upstream"
msgstr "Upstream"
@@ -37596,13 +38220,13 @@ msgid "UsageQuota|Learn more about usage quotas"
msgstr "Saiba mais sobre as cotas de uso"
msgid "UsageQuota|No CI minutes usage data available."
-msgstr ""
+msgstr "Não há dados de uso de minutos de CI disponíveis."
msgid "UsageQuota|Packages"
msgstr "Pacotes"
msgid "UsageQuota|Pending Members"
-msgstr ""
+msgstr "Membros pendentes"
msgid "UsageQuota|Pipeline artifacts and job artifacts, created with CI/CD."
msgstr "Artefatos de pipeline e artefatos de tarefa, criados com CI/CD."
@@ -37917,7 +38541,7 @@ msgid "User cap"
msgstr ""
msgid "User created at"
-msgstr ""
+msgstr "Usuário criado em"
msgid "User does not have a pending request"
msgstr "Usuário não tem uma solicitação pendente"
@@ -38115,7 +38739,7 @@ msgid "UserProfile|Report abuse"
msgstr "Denunciar abuso"
msgid "UserProfile|Retry"
-msgstr ""
+msgstr "Tentar novamente"
msgid "UserProfile|Snippets"
msgstr "Snippets"
@@ -38295,7 +38919,7 @@ msgid "Value"
msgstr "Valor"
msgid "Value Stream Analytics"
-msgstr ""
+msgstr "Análise do fluxo de valor"
msgid "Value Stream Analytics can help you determine your team’s velocity"
msgstr ""
@@ -38394,10 +39018,10 @@ msgid "Variables can be:"
msgstr "As variáveis podem ser:"
msgid "Variables store information, like passwords and secret keys, that you can use in job scripts."
-msgstr ""
+msgstr "As variáveis armazenam informações, como senhas e chaves secretas, que podem ser usadas em scripts de tarefa."
msgid "Variables store information, like passwords and secret keys, that you can use in job scripts. All projects on the instance can use these variables."
-msgstr ""
+msgstr "As variáveis armazenam informações, como senhas e chaves secretas, que podem ser usadas em scripts de tarefa. Todos os projetos na instância podem usar essas variáveis."
msgid "Various container registry settings."
msgstr "Várias configurações de registro de contêiner."
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr "Status de verificação"
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38451,7 +39075,7 @@ msgid "View Documentation"
msgstr "Ver documentação"
msgid "View Stage: %{title}"
-msgstr ""
+msgstr "Ver estágio: %{title}"
msgid "View alert details at"
msgstr "Veja os detalhes do alerta em"
@@ -38465,6 +39089,9 @@ msgstr "Ver todos os ambientes."
msgid "View all issues"
msgstr "Ver todas as issues"
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr "Ver detalhes: %{details_url}"
msgid "View documentation"
msgstr "Ver documentação"
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr "Visualizar aprovadores elegíveis"
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr "Visualizar etiquetas de grupo"
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr "Ver as issues do incidente."
@@ -38551,7 +39187,7 @@ msgid "View merge request"
msgstr "Ver solicitação de mesclagem"
msgid "View milestones"
-msgstr ""
+msgstr "Ver marcos"
msgid "View on %{url}"
msgstr "Ver em %{url}"
@@ -38609,6 +39245,9 @@ msgstr "Visto"
msgid "Viewing commit"
msgstr "Vendo commit"
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr "Visibilidade"
@@ -38664,7 +39303,7 @@ msgid "Vulnerability remediated. Review before resolving."
msgstr ""
msgid "Vulnerability report"
-msgstr ""
+msgstr "Relatório de vulnerabilidade"
msgid "Vulnerability resolved in %{branch}"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr "%{statusStart}Dispensado%{statusEnd} %{timeago} por %{user}"
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr "%{statusStart}Resolvido%{statusEnd} %{timeago} por %{user}"
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr "Informações adicionais"
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr "Classe"
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr "Descrição"
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr "Baixar"
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr "Arquivo"
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr "Identificadores"
msgid "Vulnerability|Image"
msgstr "Imagem"
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr "Links"
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr "Gravidade"
@@ -38883,7 +39570,7 @@ msgid "Wait for the file to load to copy its contents"
msgstr ""
msgid "Waiting for merge (open and assigned)"
-msgstr ""
+msgstr "Aguardando a mesclagem (aberta e atribuída)"
msgid "Waiting for performance data"
msgstr "Aguardando dados de desempenho"
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr "Vamos usar isso para ajudar a supervisionar os recursos e informações certos para você."
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr "Nenhuma vulnerabilidade encontrada"
@@ -39068,6 +39758,12 @@ msgstr "Eventos de implantação"
msgid "Webhooks|Enable SSL verification"
msgstr "Ativar verificação SSL"
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr "Eventos de feature flag"
@@ -39104,6 +39800,15 @@ msgstr "Eventos de subgrupo"
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr "Gatilho"
@@ -39161,6 +39866,15 @@ msgstr "O URL deve ser codificado em porcentagem, se necessário."
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr "Use este token para validar as cargas recebidas. Ele é enviado com a solicitação no cabeçalho Gitlab-Token HTTP."
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr "Eventos da página Wiki"
@@ -39197,6 +39911,9 @@ msgstr "Bem-vindo ao GitLab,%{br_tag}%{name}!"
msgid "Welcome, %{name}!"
msgstr "Bem-vindo, %{name}!"
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr "O que são eventos de auditoria em grupo?"
@@ -39206,9 +39923,6 @@ msgstr "O que são eventos de auditoria de instância?"
msgid "What are project audit events?"
msgstr "O que são eventos de auditoria de projetos?"
-msgid "What are shared runner pipeline minutes?"
-msgstr "O que são os minutos de pipeline do executor compartilhado?"
-
msgid "What are you searching for?"
msgstr "O que você esta pesquisando?"
@@ -39374,7 +40088,7 @@ msgid "WikiEmpty|Suggest wiki improvement"
msgstr "Sugerir melhoria da wiki"
msgid "WikiEmpty|The wiki lets you write documentation for your group"
-msgstr "O wiki permite que você escreva documentação para seu grupo."
+msgstr "A wiki permite que você escreva documentação para seu grupo."
msgid "WikiEmpty|The wiki lets you write documentation for your project"
msgstr "A wiki permite que você escreva documentação para seu projeto"
@@ -39443,7 +40157,7 @@ msgid "WikiPage|Edit rich text"
msgstr ""
msgid "WikiPage|Edit source"
-msgstr ""
+msgstr "Editar fonte"
msgid "WikiPage|Format"
msgstr "Formato"
@@ -39455,7 +40169,7 @@ msgid "WikiPage|Keep editing"
msgstr "Manter edição"
msgid "WikiPage|Learn more."
-msgstr ""
+msgstr "Saiba mais."
msgid "WikiPage|Page title"
msgstr "Título da página"
@@ -39542,7 +40256,7 @@ msgid "Wiki|Wiki Pages"
msgstr "Páginas Wiki"
msgid "Will be created"
-msgstr ""
+msgstr "Será criado"
msgid "Will be mapped to"
msgstr ""
@@ -39563,7 +40277,7 @@ msgid "Won't fix / Accept risk"
msgstr ""
msgid "Work in progress (open and unassigned)"
-msgstr ""
+msgstr "Trabalho em andamento (aberto e não atribuído)"
msgid "Work in progress Limit"
msgstr ""
@@ -40044,6 +40758,12 @@ msgstr ""
msgid "You have insufficient permissions to view shifts for this rotation"
msgstr "Você não tem permissões suficientes para ver turnos para esta rotação"
+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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr "Você não tem permissão"
@@ -40174,7 +40894,7 @@ msgid "You'll be charged for %{true_up_link_start}users over license%{link_end}
msgstr ""
msgid "You'll be signed out from your current account automatically."
-msgstr ""
+msgstr "Você será desconectado da sua conta atual automaticamente."
msgid "You'll need to use different branch names to get a valid comparison."
msgstr "Você precisará usar nomes de branch diferentes para obter uma comparação válida."
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr "Sua conta %{host} foi conectada a partir de um novo local"
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40273,7 +40999,7 @@ msgid "Your Groups"
msgstr "Seus Grupos"
msgid "Your Personal Access Token was revoked"
-msgstr ""
+msgstr "Seu token de acesso pessoal foi revogado"
msgid "Your Projects (default)"
msgstr "Seus projetos (padrão)"
@@ -40480,7 +41206,7 @@ msgid "Your project limit is %{limit} projects! Please contact your administrato
msgstr ""
msgid "Your project will be created at:"
-msgstr ""
+msgstr "Seu projeto será criado em:"
msgid "Your projects"
msgstr "Seus projetos"
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr "não é possível bloquear a si próprio"
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr "commit %{commit_id}"
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41750,7 +42482,7 @@ msgid "mrWidget|Merged by"
msgstr "Mesclado por"
msgid "mrWidget|Merges changes into"
-msgstr ""
+msgstr "Mescla as alterações em"
msgid "mrWidget|Merging! Changes are being shipped…"
msgstr ""
@@ -41777,7 +42509,7 @@ msgid "mrWidget|Merging! This is going to be great…"
msgstr ""
msgid "mrWidget|Merging! We're almost there…"
-msgstr ""
+msgstr "Mesclando! Estamos quase lá…"
msgid "mrWidget|More information"
msgstr "Mais informações"
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr "deve ser um endereço IPv4 ou IPv6 válido"
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr "deve ser depois do início"
@@ -42001,9 +42736,6 @@ msgstr "aberto em %{timeAgo}"
msgid "or"
msgstr "ou"
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/pt_PT/gitlab.po b/locale/pt_PT/gitlab.po
index 01ee3e121f1..5c130c4c7ad 100644
--- a/locale/pt_PT/gitlab.po
+++ b/locale/pt_PT/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: pt-PT\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:57\n"
+"PO-Revision-Date: 2022-01-06 17:21\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr "Página de perfil de %{user_name}"
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ", ou "
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr "Tens a certeza? Qualquer RSS ou URL do calendário atualmente em uso irÃ
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr "Tens a certeza? Qualquer problema de endereços de email em uso, irá parar de funcionar."
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr "Criado"
@@ -1802,12 +1829,21 @@ msgstr "Token de email recebido"
msgid "AccessTokens|It cannot be used to access any other data."
msgstr "Não pode ser usado para acessar nenhum outro dado."
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr "Conta: %{account}"
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr "Sessões Ativas"
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "Atividade"
@@ -1994,7 +2063,7 @@ msgstr "Adicionar uma tabela"
msgid "Add a task list"
msgstr "Adicionar uma lista de tarefas"
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr "Apagar utilizador"
msgid "AdminUsers|Delete user and contributions"
msgstr "Apagar utilizador e as suas contribuições"
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr "Todos os grupos e projetos"
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr "Ocorreu um erro"
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr "Ocorreu um erro ao pré-visualizar o blob"
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] "%{count} aprovações obrigatórias de %{membersCount}"
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr "Nome"
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr "Tens a certeza de que pretendes gerar novamente a chave pública? Terás que atualizar a chave pública no servidor remoto para que a sincronização fique novamente a funcionar."
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr "Atribuir alguns problemas para este objetivo."
@@ -5118,9 +5238,6 @@ msgstr "Executadores específicos disponíveis"
msgid "Avatar for %{assigneeName}"
msgstr "Avatar para %{assigneeName}"
-msgid "Avatar for %{name}"
-msgstr "Avatar para %{name}"
-
msgid "Avatar will be removed. Are you sure?"
msgstr "O avatar será removido. Tens a certeza?"
@@ -5370,9 +5487,6 @@ msgstr "mensalmente"
msgid "BillingPlans|per user"
msgstr "por utilizador"
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr "Painéis"
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr "A verificar a disponibilidade do nome de utilizador..."
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr "Escolhe qualquer cor."
msgid "Choose file…"
msgstr "Escolher um ficheiro…"
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr "Limpar entrada de pesquisa de modelos"
msgid "Clear weight"
msgstr "Limpar peso"
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr "Limpa peso."
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr "Editar Objetivo"
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr "Não foi possível guardar a ordem dos problemas"
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr "Ainda não há etiquetas"
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr "clica para enviar"
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/ro_RO/gitlab.po b/locale/ro_RO/gitlab.po
index 603121c34b9..a680cd102d2 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: 2021-12-06 18:55\n"
+"PO-Revision-Date: 2022-01-06 17:19\n"
msgid " %{start} to %{end}"
msgstr " de la %{start} până la %{end}"
@@ -640,8 +640,8 @@ msgstr "%{deployLinkStart}Folosește un șablon pentru a implementa în ECS%{dep
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr "%{description}- Eveniment Sentry: %{errorUrl}- Prima dată când a fost văzut: %{firstSeen}- Ultima dată când a fost văzut: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
-msgstr "%{doc_link_start}Căutarea avansată%{doc_link_end} este dezactivată deoarece %{ref_elem} nu este ramura implicită; %{default_branch_link_start}căutați pe %{default_branch} în schimb%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
+msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
msgstr "%{doc_link_start}Căutarea avansată%{doc_link_end} este activată."
@@ -916,6 +916,9 @@ msgstr "%{placeholder} nu este o schemă de culori validă"
msgid "%{placeholder} is not a valid theme"
msgstr "%{placeholder} nu este o temă validă"
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
@@ -1123,6 +1126,12 @@ msgstr "Avatarul lui %{userName}"
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr "%{user_name} (%{user_username}) a fost îndepărtat de la %{rotation} la %{schedule} la %{project}. "
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr "%{user_name} pagină profil"
@@ -1240,6 +1249,9 @@ msgstr "(lăsați necompletat dacă nu doriți să o modificați)"
msgid "(max size 15 MB)"
msgstr "(dimensiunea maximă 15 MB)"
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr "(eliminat)"
@@ -1309,6 +1321,9 @@ msgstr ""
msgid ", or "
msgstr ", sau "
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr "- Disponibil pentru a executa joburi."
@@ -1660,6 +1675,9 @@ msgstr "Un proiect care să conțină aspecte pentru fiecare anchetă de audit d
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr "Numele de repozitoriu al unui proiect îi definește URL-ul (cel pe care îl folosiți pentru a accesa proiectul via un browser) și locul său pe discul de fișier unde este instalat GitLab. %{link_start}Aflați mai multe.%{link_end}"
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr "Un șablon gata de utilizare pentru utilizare cu aplicații Android"
@@ -1906,6 +1924,15 @@ msgstr "Sunteți sigur? Orice URL RSS sau calendar utilizat în prezent nu va ma
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr "Sunteți sigur? Orice adresă de e-mail folosită în prezent nu va mai funcționa."
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr "Create"
@@ -1918,12 +1945,21 @@ msgstr "Token e-mail primit"
msgid "AccessTokens|It cannot be used to access any other data."
msgstr "Nu poate fi utilizat pentru a accesa alte date."
+msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{linkStart}reset this token%{linkEnd}."
+msgstr ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr "Păstrați acest token secret. Oricine îl are poate accesa obiectele statice ale depozitului ca și cum ar fi în locul dvs. Dacă se întâmplă asta vreodată, %{reset_link_start}resetați acest token%{reset_link_end}."
+msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{linkStart}reset this token%{linkEnd}."
+msgstr ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr "Păstrați acest simbol secret. Oricine îl are poate crea probleme ca și cum ar fi în locul dvs. Dacă se întâmplă acest lucru, %{link_reset_it}."
+msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{linkStart}reset this token%{linkEnd}."
+msgstr ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr "Păstrați acest simbol secret. Oricine îl are poate citi fluxurile RSS de activități și de probleme sau fluxul de calendar ca și cum ar fi în locul dvs. Dacă se întâmplă acest lucru, %{link_reset_it}."
@@ -1981,6 +2017,36 @@ msgstr "Cont:"
msgid "Account: %{account}"
msgstr "Cont: %{account}"
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr "Acțiune"
@@ -2005,6 +2071,9 @@ msgstr "Activ %{type} (%{token_length})"
msgid "Active Sessions"
msgstr "Sesiuni active"
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "Activitate"
@@ -2110,7 +2179,7 @@ msgstr "Adăugați un tabel"
msgid "Add a task list"
msgstr "Adăugați o listă de sarcini"
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2536,6 +2605,15 @@ msgstr "Sunteți pe cale de a opri toate joburile. Acest lucru va opri toate job
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "Eroare la încărcarea statisticilor. Vă rugăm încercați din nou"
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2812,8 +2890,8 @@ msgstr "Ștergeți utilizatorul"
msgid "AdminUsers|Delete user and contributions"
msgstr "Ștergeți utilizatorul și contribuțiile"
-msgid "AdminUsers|Export permissions as CSV"
-msgstr "Exportați permisiunile ca CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
+msgstr ""
msgid "AdminUsers|External"
msgstr "Extern"
@@ -3097,6 +3175,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr "După ce ați examinat aceste reguli privind contribuțiile, veți fi gata să"
@@ -3487,6 +3568,9 @@ msgstr "Toate epicele"
msgid "All groups and projects"
msgstr "Toate grupurile și proiectele"
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr "Toate problemele pentru acest obiectiv sunt închise."
@@ -3691,6 +3775,9 @@ msgstr "A apărut o eroare"
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr "O eroare de raportare în care rezultatul unui test indică incorect prezența unei vulnerabilități într-un sistem, când vulnerabilitatea nu este prezentă."
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr "A apărut o eroare adăugând o schiță la subiect."
@@ -3718,9 +3805,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr "A apărut o eroare de previzualizare a blobului"
-msgid "An error occurred when removing the label."
-msgstr "A apărut o eroare la îndepărtarea etichetei."
-
msgid "An error occurred when updating the title"
msgstr "A apărut o eroare la actualizarea titlului"
@@ -3901,6 +3985,9 @@ msgstr "S-a produs o eroare în timpul încărcării merge request-urilor."
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr "A apărut o eroare la încărcarea filei Necesități."
@@ -3910,6 +3997,9 @@ msgstr "A apărut o eroare la încărcarea filei Rapoarte test."
msgid "An error occurred while loading the access tokens form, please try again."
msgstr "A apărut o eroare în timpul încărcării formularului cu token-uri de acces, vă rugăm să încercați din nou."
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr "S-a produs o eroare în timpul încărcării datelor. Vă rugăm să încercați din nou."
@@ -4060,6 +4150,12 @@ msgstr "Un proiect de exemplu care prezintă cele mai bune practici pentru confi
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr "Un exemplu care arată cum să utilizați Jsonnet cu conducte dinamice copii ale GitLab"
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4396,9 +4492,15 @@ msgstr[2] "%{count} de aprobări necesare de la %{membersCount}"
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr "%{firstLabel} + încă %{numberOfAdditionalLabels}"
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr "Adăugați aprobatori"
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr "Toate scanerele"
@@ -4429,6 +4531,9 @@ msgstr "Tip aprobator"
msgid "ApprovalRule|Approvers"
msgstr "Aprobatori"
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4438,6 +4543,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr "Exemple: QA, Securitate."
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr "Nume"
@@ -4462,6 +4576,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4489,6 +4606,9 @@ msgstr "Nivele severitate"
msgid "ApprovalRule|Target branch"
msgstr "Ramura țintă"
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr "Vulnerabilități permise"
@@ -4525,7 +4645,7 @@ msgstr "S-a întâmplat o eroare actualizând setările de aprobare a cererilor
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr "Această setare este configurată la nivel de instanță și poate fi schimbată doar de un administrator."
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4696,9 +4816,6 @@ msgstr "Sunteți sigur că vreți să îmbinați imediat?"
msgid "Are you sure you want to re-deploy this environment?"
msgstr "Sunteți sigur că doriți să implementați din nou acest mediu?"
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr "Sunteți sigur că doriți să regenerați cheia publică? Va trebui să actualizați cheia publică pe serverul la distanță înainte ca replicarea să funcționeze din nou."
-
msgid "Are you sure you want to reindex?"
msgstr "Sunteți sigur că doriți să reindexați?"
@@ -4846,6 +4963,9 @@ msgstr "Atribuiți un evaluator"
msgid "Assign reviewer(s)"
msgstr "Atribuiți evaluator(i)"
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr "Atribuiți câteva probleme acestui obiectiv."
@@ -5245,9 +5365,6 @@ msgstr "Executori specifici disponibili"
msgid "Avatar for %{assigneeName}"
msgstr "Avatar pentru %{assigneeName}"
-msgid "Avatar for %{name}"
-msgstr "Avatar pentru %{name}"
-
msgid "Avatar will be removed. Are you sure?"
msgstr "Avatarul va fi eliminat. Sunteți sigur?"
@@ -5497,9 +5614,6 @@ msgstr "lunar"
msgid "BillingPlans|per user"
msgstr "per utilizator"
-msgid "BillingPlan|Contact sales"
-msgstr "Contact vânzări"
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5530,15 +5644,12 @@ msgstr "Reactivați perioada de încercare"
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
-msgstr "Utilizator validat cu succes"
-
msgid "Billings|User validation required"
msgstr "Este necesară validarea utilizatorului"
@@ -5548,8 +5659,11 @@ msgstr "Validați contul"
msgid "Billings|Validate user account"
msgstr "Validați contul de utilizator"
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
-msgstr "Contul dvs. de utilizator a fost validat cu succes. Acum puteți folosi minute gratuite pentru conducte."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
+msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
msgstr "O adresă de e-mail este vizibilă doar pentru utilizatorii cu e-mailuri publice."
@@ -5560,9 +5674,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr "Nu se poate elimina utilizatorul"
@@ -5749,7 +5869,7 @@ msgstr "Greutate"
msgid "Boards"
msgstr "Panouri"
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -6112,7 +6232,10 @@ msgstr ""
msgid "Bulk update"
msgstr "Actualizare în bloc"
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -6121,6 +6244,9 @@ msgstr "Grupuri existente"
msgid "BulkImport|Filter by source group"
msgstr "Filtrați după grupul sursă"
+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 ""
+
msgid "BulkImport|From source group"
msgstr "Din grupul sursă"
@@ -6160,6 +6286,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr "Se afișează %{start}-%{end} din %{total}"
@@ -6865,7 +6994,7 @@ msgstr "Se verifică disponibilitatea numelui de utilizator..."
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -7129,9 +7258,6 @@ msgstr "Alegeți orice culoare."
msgid "Choose file…"
msgstr "Alegeți fișierul…"
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7342,6 +7468,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7360,9 +7489,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7516,12 +7651,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr "Tipul de cluster trebuie să fie specificat pentru Stages::ClusterEndpointInserter"
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7534,6 +7684,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7549,9 +7705,15 @@ msgstr ""
msgid "ClusterAgents|An error occurred while loading your agent"
msgstr "A apărut o eroare la încărcarea agentului dumneavoastră"
+msgid "ClusterAgents|An error occurred while retrieving GitLab Agent activity. Reload the page to try again."
+msgstr ""
+
msgid "ClusterAgents|An unknown error occurred. Please try again."
msgstr "A apărut o eroare necunoscută. Vă rugăm să încercați din nou."
+msgid "ClusterAgents|Are you sure you want to delete this agent? You cannot undo this."
+msgstr ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7597,12 +7759,21 @@ msgstr "Creat de %{name} %{time}"
msgid "ClusterAgents|Date created"
msgstr "Data creării"
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr "Descriere"
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7678,6 +7849,9 @@ msgstr "Token de înregistrare"
msgid "ClusterAgents|Security"
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 ""
@@ -7696,12 +7870,27 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr "Utilizator necunoscut"
@@ -7711,6 +7900,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8899,6 +9091,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr "Component"
@@ -9322,6 +9523,9 @@ msgstr " Nu este încă programat"
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr "Notă: Orice actualizare a politicii va avea ca rezultat o modificare a datei și orei de execuție programate"
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr " Publicat %{timeInfo}"
@@ -9412,6 +9616,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9643,12 +9850,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9679,9 +9892,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -10021,9 +10231,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -10054,6 +10261,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -10096,9 +10306,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -10108,13 +10315,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10294,15 +10504,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10312,15 +10540,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10471,15 +10708,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11167,6 +11395,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11446,6 +11677,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11479,15 +11713,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11623,6 +11851,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11647,7 +11878,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11656,6 +11887,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12466,15 +12700,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12616,6 +12850,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12751,8 +12988,8 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
-msgstr "Editați programarea pipeline-ului %{id}"
+msgid "Edit Pipeline Schedule"
+msgstr ""
msgid "Edit Release"
msgstr ""
@@ -12790,6 +13027,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13732,6 +13972,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13777,9 +14020,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13933,9 +14173,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr "Eroare la migrarea %{upload_id}: %{error_message}"
@@ -14020,6 +14257,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 "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14206,9 +14446,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14401,7 +14638,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -15112,9 +15349,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15445,6 +15679,9 @@ msgstr ""
msgid "Full"
msgstr "Complet"
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16306,9 +16543,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16396,6 +16630,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16585,9 +16822,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16714,6 +16948,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16816,9 +17053,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16891,6 +17137,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16930,6 +17179,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr "Token-ul SCIM este ascuns. Pentru a vedea din nou valoarea tokenului, trebuie să "
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16963,6 +17215,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16987,7 +17251,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr "Insigne"
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16996,7 +17260,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -17038,6 +17302,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -17065,12 +17332,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr "Selectați un subgrup de utilizat ca sursă pentru șabloane de proiect personalizate pentru acest grup."
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17185,6 +17458,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17239,6 +17515,9 @@ 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 ""
+
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 ""
@@ -19153,6 +19432,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19402,9 +19684,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19507,9 +19786,6 @@ msgstr "port daemon irker (valoarea implicită este 6659)."
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19621,9 +19897,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20269,7 +20542,7 @@ msgstr "Brut complet"
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20722,6 +20995,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21490,7 +21769,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22246,10 +22525,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22348,6 +22627,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22969,6 +23251,9 @@ msgstr "Mai multe informații sunt disponibile|aici"
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -23173,6 +23458,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23386,6 +23704,9 @@ msgstr "Nou"
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23611,6 +23932,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -24031,6 +24355,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -24043,7 +24370,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24454,6 +24781,12 @@ msgstr "Programul dvs. a fost creat cu succes. Pentru a adăuga utilizatori indi
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24472,12 +24805,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24517,12 +24856,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24547,18 +24895,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24568,9 +24931,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24730,6 +25090,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25270,9 +25633,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25462,9 +25822,15 @@ msgstr "Recenzie peer de"
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25564,6 +25930,9 @@ msgstr "perete"
msgid "Period in seconds"
msgstr "Perioadă în secunde"
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25645,12 +26014,6 @@ msgstr "URL conductă"
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25882,6 +26245,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -26101,9 +26467,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26380,6 +26743,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26392,6 +26761,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26587,9 +26959,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26941,6 +27310,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26998,6 +27370,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -27082,6 +27460,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27376,6 +27757,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27502,6 +27925,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27754,19 +28180,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
-msgstr "Mesajul commit utilizat atunci când se aplică sugestii merge request. %{link_start}Aflați mai multe despre sugestii.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
+msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27922,6 +28345,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28306,9 +28738,6 @@ msgstr "Căutarea Avansată în GitLab este un serviciu puternic de căutare car
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28321,9 +28750,6 @@ msgstr "Actualizați-vă planul pentru a activa Căutarea Avansată."
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr "Actualizați-vă planul pentru a activa Evenimentele Audit."
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr "Actualizați-vă planul pentru a activa webhook-uri grup."
@@ -28348,9 +28774,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr "Puteți restricționa accesul la ramuri protejate alegând un rol (Întreținători, Dezvoltatori) sau utilizatori individuali."
@@ -28432,6 +28855,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28477,9 +28903,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28522,6 +28954,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28537,6 +28972,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28765,6 +29203,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28951,9 +29395,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28996,6 +29437,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29323,10 +29812,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -30016,6 +30505,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -30025,6 +30517,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30223,9 +30721,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30247,6 +30742,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30298,19 +30799,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30364,6 +30868,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30409,6 +30916,9 @@ msgstr "Ceva nu a mers bine în timpul preluării datelor executorilor."
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30418,7 +30928,10 @@ msgstr "Opriți executorul din a accepta noi joburi."
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30487,7 +31000,7 @@ msgstr ""
msgid "Runners|locked"
msgstr "blocat"
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30505,6 +31018,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30766,6 +31282,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30787,9 +31306,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -31081,6 +31597,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr "Activați Auto DevOps"
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -31153,6 +31672,9 @@ msgstr "%{branches}%{plural}"
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr "%{branches} și %{lastBranch}%{plural}"
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr "Acțiune"
@@ -31207,6 +31729,9 @@ msgstr "Rețea"
msgid "SecurityOrchestration|New policy"
msgstr "Politică nouă"
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr "Doar proprietarii pot actualiza Proiectul Politicii de Securitate"
@@ -31291,9 +31816,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr "+%{count} mai mult"
@@ -31492,6 +32014,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31504,6 +32029,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31579,6 +32107,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31732,6 +32263,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -32083,6 +32617,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32239,6 +32779,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32941,6 +33484,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33385,9 +33931,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33784,6 +34327,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34219,6 +34768,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34489,9 +35056,27 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34522,6 +35107,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34534,6 +35122,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34570,12 +35161,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34864,6 +35464,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34987,9 +35590,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34999,9 +35599,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -35074,7 +35671,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35329,9 +35926,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr "Nu există fișiere potrivite"
@@ -35677,6 +36271,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35689,9 +36286,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr "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."
@@ -35716,6 +36310,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35830,6 +36427,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35995,6 +36595,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36709,6 +37312,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr "Pentru a rezolva asta, încercați:"
@@ -36775,6 +37381,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36949,6 +37588,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -37072,15 +37714,6 @@ msgstr "Prenume"
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr "Bună ziua%{salutation}, perioada dvs. de încercare GitLab Ultimate ține 30 de zile, dar vă puteți păstra contul gratuit GitLab pentru totdeauna. Doar avem nevoie de câteva informații suplimentare despre %{company} pentru a vă activa perioada de încercare."
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr "Nume"
@@ -37105,9 +37738,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr "compania dvs."
-
msgid "Trigger"
msgstr ""
@@ -37735,9 +38365,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr "După efectuarea acestei acțiuni, conținutul acestui grup, al subgrupului său și proiectele vor fi șterse permanent după %{deletion_adjourned_period} zile pe %{date}. Până atunci:"
-
msgid "Upstream"
msgstr ""
@@ -38629,16 +39256,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38680,6 +39307,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38704,6 +39334,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38734,6 +39367,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38827,6 +39466,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38908,12 +39550,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38941,6 +39595,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39010,9 +39667,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -39028,21 +39694,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -39052,6 +39730,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -39076,6 +39757,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -39199,6 +39889,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39286,6 +39979,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39322,6 +40021,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39379,6 +40087,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39415,6 +40132,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39424,9 +40144,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr "Ce sunt minutele de conducte executori partajați?"
-
msgid "What are you searching for?"
msgstr ""
@@ -40264,6 +40981,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40453,6 +41176,12 @@ msgstr "Abonamentul dvs. %{group} va expira acum în %{days}."
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40744,6 +41473,9 @@ msgstr ""
msgid "Your subscription expired!"
msgstr "Abonamentul dvs. a expirat!"
+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 ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40987,6 +41719,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr "%{degradedNum} degradat"
@@ -41017,7 +41752,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -41065,8 +41800,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41161,8 +41896,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41326,6 +42061,9 @@ msgstr "commit %{commit_id}"
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+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"
@@ -41776,9 +42514,6 @@ msgstr "metric_id trebuie să fie unic în cadrul unui proiect"
msgid "missing"
msgstr "lipsește"
-msgid "more information"
-msgstr "mai multe informații"
-
msgid "most recent deployment"
msgstr ""
@@ -42136,6 +42871,9 @@ msgstr "trebuie să fie un spațiu de nume rădăcină"
msgid "must be a valid IPv4 or IPv6 address"
msgstr "trebuie să fie o adresă IPv4 sau IPv6 validă"
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr "trebuie să fie după start"
@@ -42235,9 +42973,6 @@ msgstr "deschis %{timeAgo}"
msgid "or"
msgstr "sau"
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
@@ -42596,7 +43331,7 @@ msgid "username"
msgstr "utilizator"
msgid "v%{version} published %{timeAgo}"
-msgstr ""
+msgstr "v%{version} publicată %{timeAgo}"
msgid "value for '%{storage}' must be an integer"
msgstr "valoarea pentru '%{storage}' trebuie să fie un număr întreg"
diff --git a/locale/ru/gitlab.po b/locale/ru/gitlab.po
index 9c0f666314f..242e89881a0 100644
--- a/locale/ru/gitlab.po
+++ b/locale/ru/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ru\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:56\n"
+"PO-Revision-Date: 2022-01-06 17:20\n"
msgid " %{start} to %{end}"
msgstr " %{start} по %{end}"
@@ -571,7 +571,7 @@ msgid "%{author_link} cloned %{original_issue} to %{new_issue}."
msgstr ""
msgid "%{author_link} cloned %{original_issue}. You don't have access to the new project."
-msgstr ""
+msgstr "%{author_link} клонировал %{original_issue}. У Ð²Ð°Ñ Ð½ÐµÑ‚ доÑтупа к новому проекту."
msgid "%{author_link} wrote:"
msgstr "%{author_link} напиÑал:"
@@ -620,10 +620,10 @@ msgstr ""
msgid "%{completedCount} of %{count} task completed"
msgid_plural "%{completedCount} of %{count} tasks completed"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%{completedCount} из %{count} задачи выполнено"
+msgstr[1] "%{completedCount} из %{count} задач выполнено"
+msgstr[2] "%{completedCount} из %{count} задач выполнено"
+msgstr[3] "%{completedCount} из %{count} задач выполнено"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr "Завершено %{completedWeight} из %{totalWeight} приоритета"
@@ -717,7 +717,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
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; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -808,7 +808,7 @@ msgid "%{issuesSize} with a limit of %{maxIssueCount}"
msgstr ""
msgid "%{italic_start}What's new%{italic_end} is inactive and cannot be viewed."
-msgstr ""
+msgstr "Раздел %{italic_start}Что нового%{italic_end} неактивен и недоÑтупен Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра."
msgid "%{itemsCount} issues with a limit of %{maxIssueCount}"
msgstr ""
@@ -994,6 +994,9 @@ msgstr "%{placeholder} не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимой цветово
msgid "%{placeholder} is not a valid theme"
msgstr "%{placeholder} не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимой темой"
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
@@ -1211,6 +1214,12 @@ msgstr "Ðватар %{userName}"
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr "Ñтраница Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ %{user_name}"
@@ -1329,6 +1338,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr "(макÑ. размер 15 Мбайт)"
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr "(удалено)"
@@ -1400,6 +1412,9 @@ msgstr ""
msgid ", or "
msgstr ", или "
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1776,6 +1791,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -2022,6 +2040,15 @@ msgstr "Ð’Ñ‹ уверены? Любые RSS или URL-адреÑа календ
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr "Ð’Ñ‹ уверены? Любое Ð¸Ð¼Ñ Ñлектронной почты, которое в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð¸ÑпользуетÑÑ, переÑтанет работать."
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr "Создано"
@@ -2034,12 +2061,21 @@ msgstr "Токен входÑщей Ñлектронной почты"
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -2097,6 +2133,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr "Ðккаунт: %{account}"
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -2121,6 +2187,9 @@ msgstr ""
msgid "Active Sessions"
msgstr "Ðктивные ÑеÑÑии"
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "ÐктивноÑÑ‚ÑŒ"
@@ -2226,7 +2295,7 @@ msgstr "Добавить таблицу"
msgid "Add a task list"
msgstr "Добавить ÑпиÑок задач"
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2551,19 +2620,19 @@ msgid "AdminArea|Bots"
msgstr "Боты"
msgid "AdminArea|Components"
-msgstr ""
+msgstr "Компоненты"
msgid "AdminArea|Developer"
msgstr "Developer"
msgid "AdminArea|Features"
-msgstr ""
+msgstr "ВозможноÑти"
msgid "AdminArea|Get security updates from GitLab and stay up to date"
-msgstr ""
+msgstr "Получайте Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð±ÐµÐ·Ð¾Ð¿Ð°ÑноÑти от GitLab и будьте в курÑе Ñобытий"
msgid "AdminArea|Groups"
-msgstr ""
+msgstr "Группы"
msgid "AdminArea|Guest"
msgstr "Guest"
@@ -2572,13 +2641,13 @@ msgid "AdminArea|Included Free in license"
msgstr "Включены в лицензию беÑплатно"
msgid "AdminArea|Latest groups"
-msgstr "ПоÑледние группы"
+msgstr "Ðедавние группы"
msgid "AdminArea|Latest projects"
-msgstr ""
+msgstr "Ðедавние проекты"
msgid "AdminArea|Latest users"
-msgstr ""
+msgstr "Ðедавние пользователи"
msgid "AdminArea|Maintainer"
msgstr "Maintainer"
@@ -2593,19 +2662,19 @@ msgid "AdminArea|New project"
msgstr "Ðовый проект"
msgid "AdminArea|New user"
-msgstr ""
+msgstr "Ðовый пользователь"
msgid "AdminArea|Owner"
msgstr "Owner"
msgid "AdminArea|Projects"
-msgstr ""
+msgstr "Проекты"
msgid "AdminArea|Reporter"
msgstr "Reporter"
msgid "AdminArea|Sign up for the GitLab Security Newsletter to get notified for security updates."
-msgstr ""
+msgstr "ПодпишитеÑÑŒ на раÑÑылку новоÑтей по безопаÑноÑти GitLab, чтобы получать ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¾Ð± обновлениÑÑ… безопаÑноÑти."
msgid "AdminArea|Sign up for the GitLab newsletter"
msgstr ""
@@ -2626,7 +2695,7 @@ msgid "AdminArea|Total users"
msgstr "Ð’Ñего пользователей"
msgid "AdminArea|Users"
-msgstr ""
+msgstr "Пользователи"
msgid "AdminArea|Users statistics"
msgstr "СтатиÑтика пользователей"
@@ -2638,13 +2707,13 @@ msgid "AdminArea|Users without a Group and Project"
msgstr "Пользователи без группы и проекта"
msgid "AdminArea|View latest groups"
-msgstr ""
+msgstr "ПоÑмотреть недавние группы"
msgid "AdminArea|View latest projects"
-msgstr ""
+msgstr "ПоÑмотреть недавние проекты"
msgid "AdminArea|View latest users"
-msgstr ""
+msgstr "ПоÑмотреть недавних пользователей"
msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
msgstr ""
@@ -2652,6 +2721,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "Ошибка загрузки ÑтатиÑтики. ПожалуйÑта, попробуйте еще раз"
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2665,7 +2743,7 @@ msgid "AdminSettings|A Let's Encrypt account will be configured for this GitLab
msgstr ""
msgid "AdminSettings|All new projects can use the instance's shared runners by default."
-msgstr ""
+msgstr "Ð’Ñе новые проекты могут иÑпользовать общие runner'Ñ‹ ÑкземплÑра по умолчанию."
msgid "AdminSettings|Auto DevOps domain"
msgstr "Домен Auto DevOps"
@@ -2701,7 +2779,7 @@ msgid "AdminSettings|If not specified at the group or instance level, the defaul
msgstr ""
msgid "AdminSettings|Keep the latest artifacts for all jobs in the latest successful pipelines"
-msgstr ""
+msgstr "СохранÑÑ‚ÑŒ поÑледние артефакты Ð´Ð»Ñ Ð²Ñех заданий в поÑледних уÑпешных Ñборочных линиÑÑ…"
msgid "AdminSettings|Let's Encrypt email"
msgstr ""
@@ -2752,7 +2830,7 @@ msgid "AdminSettings|The default name for the initial branch of new repositories
msgstr ""
msgid "AdminSettings|The latest artifacts for all jobs in the most recent successful pipelines in each project are stored and do not expire."
-msgstr ""
+msgstr "ПоÑледние артефакты Ð´Ð»Ñ Ð²Ñех заданий в недавних уÑпешных Ñборочных линиÑÑ… каждого проекта ÑохранÑÑŽÑ‚ÑÑ Ð±ÐµÑÑрочно."
msgid "AdminSettings|The projects in this group can be selected as templates for new projects created on the instance. %{link_start}Learn more.%{link_end} "
msgstr "Проекты в Ñтой группе могут быть выбраны в качеÑтве шаблонов Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… проектов, Ñозданных в ÑкземплÑре. %{link_start}Подробнее.%{link_end} "
@@ -2928,7 +3006,7 @@ msgstr "Удалить пользователÑ"
msgid "AdminUsers|Delete user and contributions"
msgstr "Удалить Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸ внеÑённые им изменениÑ"
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -3073,7 +3151,7 @@ msgid "AdminUsers|User will not be able to login"
msgstr "Пользователь не Ñможет войти"
msgid "AdminUsers|Users"
-msgstr ""
+msgstr "Пользователи"
msgid "AdminUsers|Users can still be invited to your instance and/or add themselves if permitted based on your settings. They will not have access to your instance, nor count towards your subscribed seat count until you %{approve_link}."
msgstr ""
@@ -3181,7 +3259,7 @@ msgid "Advanced"
msgstr "РаÑширенные"
msgid "Advanced Search"
-msgstr ""
+msgstr "РаÑширенный поиÑк"
msgid "Advanced Settings"
msgstr "Дополнительные наÑтройки"
@@ -3213,6 +3291,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3603,6 +3684,9 @@ msgstr ""
msgid "All groups and projects"
msgstr "Ð’Ñе группы и проекты"
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr "Ð’Ñе обÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð¿Ð¾ Ñтому Ñтапу закрыты."
@@ -3807,6 +3891,9 @@ msgstr "Произошла ошибка"
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr "Произошла ошибка при добавлении черновика в тему."
@@ -3834,9 +3921,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr "Произошла ошибка при предварительном проÑмотре объекта"
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3937,7 +4021,7 @@ msgid "An error occurred while fetching reference"
msgstr ""
msgid "An error occurred while fetching tags. Retry the search."
-msgstr ""
+msgstr "Произошла ошибка при получении тегов. Повторите поиÑк."
msgid "An error occurred while fetching terraform reports."
msgstr "Произошла ошибка при получении отчётов Terraform."
@@ -4017,6 +4101,9 @@ msgstr "Произошла ошибка при загрузке запроÑов
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -4026,6 +4113,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr "Произошла ошибка при загрузке данных. ПожалуйÑта, повторите попытку."
@@ -4177,6 +4267,12 @@ msgstr ""
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 ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4520,9 +4616,15 @@ msgstr[3] "Ðеобходимо %{count} одобрений из %{membersCount}
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4553,6 +4655,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr "Утверждающие"
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4562,6 +4667,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr "ИмÑ"
@@ -4586,6 +4700,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4613,6 +4730,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr "Ð¦ÐµÐ»ÐµÐ²Ð°Ñ Ð²ÐµÑ‚ÐºÐ°"
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4649,7 +4769,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4821,9 +4941,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr "Ð’Ñ‹ уверены, что вы хотите заново Ñгенерировать публичный ключ? Вам нужно будет обновить публичный ключ на удаленном Ñервере, прежде чем зеркалирование Ñнова будет работать."
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4971,6 +5088,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr "Ðазначить какие-либо задачи Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ Ñтапа."
@@ -5017,7 +5137,7 @@ msgid "Assigned to me"
msgstr "Ðазначить мне"
msgid "Assigned to you"
-msgstr ""
+msgstr "Ðазначено вам"
msgid "Assignee"
msgid_plural "%d Assignees"
@@ -5372,9 +5492,6 @@ msgstr "ДоÑтупные ÑпецифичеÑкие runner'Ñ‹"
msgid "Avatar for %{assigneeName}"
msgstr "Ðватар Ð´Ð»Ñ %{assigneeName}"
-msgid "Avatar for %{name}"
-msgstr "Ðватар Ð´Ð»Ñ %{name}"
-
msgid "Avatar will be removed. Are you sure?"
msgstr "Ðватар будет удален. Ð’Ñ‹ уверены?"
@@ -5624,9 +5741,6 @@ msgstr "ежемеÑÑчно"
msgid "BillingPlans|per user"
msgstr "на одного пользователÑ"
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr "Улучшить"
@@ -5657,13 +5771,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr "Чтобы иÑпользовать беÑплатные минуты Ñборочной линии на общих runner'ах, вам нужно подтвердить Ñчёт кредитной или дебетовой картой. ЕÑли предпочитаете не предоÑтавлÑÑ‚ÑŒ данные карт, можете запуÑкать Ñборочные линии на ÑобÑтвенных runner'ах, отключив общие runner'Ñ‹ Ñвоего проекта. Это необходимо Ð´Ð»Ñ ÑƒÐ¼ÐµÐ½ÑŒÑˆÐµÐ½Ð¸Ñ Ð½ÐµÑ†ÐµÐ»ÐµÐ²Ð¾Ð³Ð¾ иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð½Ñ„Ñ€Ð°Ñтруктуры GitLab. %{strongStart}GitLab не ÑпиÑывает ÑредÑтва и не хранит данные карт, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¸Ñ… только Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ.%{strongEnd} %{linkStart}Узнать подробнее%{linkEnd}."
-
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr "Чтобы иÑпользовать беÑплатные минуты Ñборочной линии на общих runner'ах, вам нужно подтвердить Ñчёт кредитной или дебетовой картой. Это необходимо Ð´Ð»Ñ ÑƒÐ¼ÐµÐ½ÑŒÑˆÐµÐ½Ð¸Ñ Ð½ÐµÑ†ÐµÐ»ÐµÐ²Ð¾Ð³Ð¾ иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð½Ñ„Ñ€Ð°Ñтруктуры GitLab. %{strongStart}GitLab не ÑпиÑывает ÑредÑтва и не хранит данные карт, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¸Ñ… только Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5675,7 +5786,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5687,9 +5801,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5709,7 +5829,7 @@ msgid "Billing|Group invite"
msgstr ""
msgid "Billing|Members who were invited via a group invitation cannot be removed. You can either remove the entire group, or ask an Owner of the invited group to remove the member."
-msgstr ""
+msgstr "УчаÑтники, приглашённые Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ группового приглашениÑ, не могут быть удалены. Ð’Ñ‹ можете либо удалить вÑÑŽ группу, либо попроÑить владельца приглашённой группы удалить учаÑтника."
msgid "Billing|No users to display."
msgstr ""
@@ -5806,13 +5926,13 @@ msgid "BoardNewIssue|No matching results"
msgstr ""
msgid "BoardNewIssue|Projects"
-msgstr ""
+msgstr "Проекты"
msgid "BoardNewIssue|Search projects"
-msgstr ""
+msgstr "ПоиÑк проектов"
msgid "BoardNewIssue|Select a project"
-msgstr ""
+msgstr "Выбрать проект"
msgid "BoardScope|An error occurred while getting milestones, please try again."
msgstr ""
@@ -5877,7 +5997,7 @@ msgstr ""
msgid "Boards"
msgstr "ДоÑки"
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -6242,7 +6362,10 @@ msgstr "РаÑпараллеливание маÑÑовых запроÑов"
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -6251,6 +6374,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6290,6 +6416,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6996,7 +7125,7 @@ msgstr "Проверка доÑтупноÑти имени пользоватеÐ
msgid "Checkout"
msgstr "Оформление заказа"
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -7262,9 +7391,6 @@ msgstr "Выберите любой цвет."
msgid "Choose file…"
msgstr "Выберите файл…"
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7475,6 +7601,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr "ОчиÑтить поÑледние запроÑÑ‹"
@@ -7493,9 +7622,15 @@ msgstr "ОчиÑтить шаблоны ввода данных Ð´Ð»Ñ Ð¿Ð¾Ð¸ÑÐ
msgid "Clear weight"
msgstr "ОчиÑтить приоритет"
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr "Приоритет очищен."
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr "Очищает приоритет."
@@ -7649,12 +7784,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7667,6 +7817,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7682,9 +7838,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7730,12 +7892,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7811,6 +7982,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7829,12 +8003,28 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7844,6 +8034,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8541,7 +8734,7 @@ msgid "ClusterIntegration|To remove your integration, type %{clusterName} to con
msgstr ""
msgid "ClusterIntegration|To use a new project, first create one on %{docsLinkStart}Google Cloud Platform%{docsLinkEnd}."
-msgstr ""
+msgstr "Чтобы иÑпользовать новый проект, Ñначала Ñоздайте его на %{docsLinkStart}Google Cloud Platform%{docsLinkEnd}."
msgid "ClusterIntegration|Troubleshooting tips:"
msgstr ""
@@ -8860,7 +9053,7 @@ msgid "Commit…"
msgstr "Коммит…"
msgid "Community forum"
-msgstr ""
+msgstr "Форум ÑообщеÑтва"
msgid "Company"
msgstr ""
@@ -8920,7 +9113,7 @@ msgid "CompareRevisions|Select Git revision"
msgstr ""
msgid "CompareRevisions|Select branch/tag"
-msgstr ""
+msgstr "Выбрать ветку/тег"
msgid "CompareRevisions|Select target project"
msgstr ""
@@ -8929,16 +9122,16 @@ 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 ""
+msgstr "Ошибка при загрузке ÑпиÑка веток/тегов. ПожалуйÑта, попробуйте ещё раз."
msgid "CompareRevisions|There was an error while searching the branch/tag list. Please try again."
-msgstr ""
+msgstr "Ошибка при поиÑке ÑпиÑка веток/тегов. ПожалуйÑта, попробуйте ещё раз."
msgid "CompareRevisions|There was an error while updating the branch/tag list. Please try again."
-msgstr ""
+msgstr "Ошибка при обновлении ÑпиÑка веток/тегов. ПожалуйÑта, попробуйте ещё раз."
msgid "CompareRevisions|View open merge request"
msgstr ""
@@ -9033,6 +9226,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9052,7 +9254,7 @@ msgid "Configuration help"
msgstr ""
msgid "Configure %{italic_start}What's new%{italic_end} drawer and content."
-msgstr ""
+msgstr "ÐаÑтроить меню и Ñодержимое раздела %{italic_start}Что нового%{italic_end}."
msgid "Configure %{link} to track events. %{link_start}Learn more.%{link_end}"
msgstr ""
@@ -9297,10 +9499,10 @@ msgstr[3] ""
msgid "ContainerRegistry|%{count} Tag"
msgid_plural "ContainerRegistry|%{count} Tags"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%{count} Тег"
+msgstr[1] "%{count} Тега"
+msgstr[2] "%{count} Тегов"
+msgstr[3] "%{count} Тегов"
msgid "ContainerRegistry|%{strongStart}Disabled%{strongEnd} - Tags will not be automatically deleted."
msgstr ""
@@ -9458,6 +9660,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9535,7 +9740,7 @@ msgid "ContainerRegistry|Tags successfully marked for deletion."
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 ""
+msgstr "Теги, которые ÑоответÑтвуют Ñтим правилам будут %{strongStart}Ñохранены%{strongEnd}, даже, еÑли они ÑоответÑтвуют правилам ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð½Ð¸Ð¶Ðµ. %{secondStrongStart}ПоÑледний%{secondStrongEnd} тег вÑегда ÑохранÑетÑÑ."
msgid "ContainerRegistry|Tags that match these rules are %{strongStart}removed%{strongEnd}, unless a rule above says to keep them."
msgstr ""
@@ -9549,6 +9754,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9780,12 +9988,18 @@ msgstr "Скопировать окружение"
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr "Скопировать ключ"
@@ -9816,9 +10030,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -10045,7 +10256,7 @@ msgid "Create a new issue"
msgstr "Создать новое обÑуждение"
msgid "Create a new project"
-msgstr ""
+msgstr "Создать новый проект"
msgid "Create a new repository"
msgstr "Создать новый репозиторий"
@@ -10156,10 +10367,7 @@ msgid "Create new label"
msgstr "Создать новую метку"
msgid "Create new project"
-msgstr ""
-
-msgid "Create new..."
-msgstr "Создать новый..."
+msgstr "Создать новый проект"
msgid "Create or import your first project"
msgstr ""
@@ -10191,6 +10399,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -10222,19 +10433,16 @@ msgid "CreateValueStreamForm|'%{name}' Value Stream saved"
msgstr ""
msgid "CreateValueStreamForm|Add another stage"
-msgstr ""
+msgstr "Добавить другой Ñтап"
msgid "CreateValueStreamForm|Add stage"
-msgstr ""
+msgstr "Добавить Ñтап"
msgid "CreateValueStreamForm|All default stages are currently visible"
-msgstr ""
+msgstr "Видны вÑе Ñтапы по умолчанию"
msgid "CreateValueStreamForm|Code stage start"
-msgstr ""
-
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
+msgstr "Ðачало Ñтапа кода"
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -10245,13 +10453,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
-msgid "CreateValueStreamForm|Default stages"
+msgid "CreateValueStreamForm|Create value stream"
msgstr ""
+msgid "CreateValueStreamForm|Default stages"
+msgstr "Этапы по умолчанию"
+
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
-msgstr ""
+msgstr "Этапы по умолчанию могут быть только Ñкрыты или переупорÑдочены"
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10267,7 +10478,7 @@ msgid "CreateValueStreamForm|End event: "
msgstr ""
msgid "CreateValueStreamForm|Enter stage name"
-msgstr ""
+msgstr "Введите название Ñтапа"
msgid "CreateValueStreamForm|Enter value stream name"
msgstr ""
@@ -10285,7 +10496,7 @@ msgid "CreateValueStreamForm|New stage"
msgstr ""
msgid "CreateValueStreamForm|Plan stage start"
-msgstr ""
+msgstr "Ðачало Ñтапа планированиÑ"
msgid "CreateValueStreamForm|Please select a start event first"
msgstr ""
@@ -10294,13 +10505,13 @@ msgid "CreateValueStreamForm|Please select an end event"
msgstr ""
msgid "CreateValueStreamForm|Recover hidden stage"
-msgstr ""
+msgstr "ВоÑÑтановление Ñкрытого Ñтапа"
msgid "CreateValueStreamForm|Restore defaults"
msgstr ""
msgid "CreateValueStreamForm|Restore stage"
-msgstr ""
+msgstr "ВоÑÑтановить Ñтап"
msgid "CreateValueStreamForm|Save value stream"
msgstr ""
@@ -10312,13 +10523,13 @@ msgid "CreateValueStreamForm|Select start event"
msgstr ""
msgid "CreateValueStreamForm|Stage %{index}"
-msgstr ""
+msgstr "Этап %{index}"
msgid "CreateValueStreamForm|Stage name already exists"
-msgstr ""
+msgstr "Ðазвание Ñтапа уже ÑущеÑтвует"
msgid "CreateValueStreamForm|Stage name is required"
-msgstr ""
+msgstr "ТребуетÑÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ Ñтапа"
msgid "CreateValueStreamForm|Start event"
msgstr ""
@@ -10333,7 +10544,7 @@ msgid "CreateValueStreamForm|Start event: "
msgstr ""
msgid "CreateValueStreamForm|Update stage"
-msgstr ""
+msgstr "Обновить Ñтап"
msgid "CreateValueStreamForm|Value Stream name"
msgstr ""
@@ -10431,15 +10642,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10449,15 +10678,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10522,13 +10760,13 @@ msgid "CurrentUser|Buy Pipeline minutes"
msgstr ""
msgid "CurrentUser|Edit profile"
-msgstr ""
+msgstr "Редактировать профиль"
msgid "CurrentUser|One of your groups is running out"
msgstr ""
msgid "CurrentUser|Preferences"
-msgstr ""
+msgstr "ÐаÑтройки"
msgid "CurrentUser|Start an Ultimate trial"
msgstr ""
@@ -10608,15 +10846,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr "Хотите наÑтроить Ñту Ñтраницу?"
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr "Перейти к предпочтениÑм"
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr "Ðа Ñтой Ñтранице по умолчанию отображаетÑÑ ÑпиÑок ваших проектов, но её можно изменить, чтобы отображать активноÑÑ‚ÑŒ проектов, группы, ÑпиÑок дел, назначенные обÑуждениÑ, назначенные запроÑÑ‹ на ÑлиÑние и многое другое. Ð’Ñ‹ можете изменить Ñто в разделе «Содержание главной Ñтраницы» в Ñвоих предпочтениÑÑ…."
-
msgid "Cycle Time"
msgstr ""
@@ -10974,7 +11203,7 @@ msgid "DastProfiles|Do you want to discard your changes?"
msgstr ""
msgid "DastProfiles|Edit profile"
-msgstr ""
+msgstr "Редактировать профиль"
msgid "DastProfiles|Edit scanner profile"
msgstr ""
@@ -11307,6 +11536,9 @@ msgstr ""
msgid "Date"
msgstr "Дата"
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11586,6 +11818,9 @@ msgstr ""
msgid "Delete variable"
msgstr "Удалить переменную"
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11619,15 +11854,9 @@ msgstr ""
msgid "Deleted"
msgstr "Удалено"
-msgid "Deleted Projects"
-msgstr "Удалённые проекты"
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr "Удалённый никнейм чата: %{chat_name}!"
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr "Удаленные проекты не могут воÑÑтановлены!"
@@ -11766,6 +11995,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11790,7 +12022,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11799,6 +12031,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] "Ð’ завиÑимоÑти от того был ли удовлетворен %d Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние"
@@ -12213,7 +12448,7 @@ msgid "DesignManagement|Learn more about resolving comments"
msgstr ""
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
-msgstr ""
+msgstr "Ð—Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Ð´Ð¸Ð·Ð°Ð¹Ð½Ð° не ÑущеÑтвует. ВмеÑто неё показана поÑледнÑÑ Ð²ÐµÑ€ÑиÑ"
msgid "DesignManagement|Resolve thread"
msgstr ""
@@ -12555,7 +12790,7 @@ msgid "Disable Two-factor Authentication"
msgstr ""
msgid "Disable What's new"
-msgstr ""
+msgstr "Отключить \"Что нового\""
msgid "Disable for this project"
msgstr "Отключить Ð´Ð»Ñ Ñтого проекта"
@@ -12617,15 +12852,15 @@ msgstr "Ð”Ð»Ñ ÐºÐ¾Ð´Ð°, который уже находитÑÑ Ð² произÐ
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr "GitLab выполнит ÑтатичеÑкие и динамичеÑкие теÑÑ‚Ñ‹ в коде вашего Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð² поиÑке извеÑтных дефектов и Ñообщит о них в запроÑе на ÑлиÑние, так чтобы вы могли иÑправить их перед завершением запроÑа."
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr "СредÑтва безопаÑноÑти, интегрированные в жизненный цикл вашей разработки"
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr "Ðачать беÑплатный пробный период"
@@ -12768,6 +13003,9 @@ msgstr ""
msgid "Download CSV"
msgstr "Скачать CSV"
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12903,8 +13141,8 @@ msgstr "Изменить Ñтап"
msgid "Edit Password"
msgstr "Изменить пароль"
-msgid "Edit Pipeline Schedule %{id}"
-msgstr "Изменить раÑпиÑание Ñборочной линии %{id}"
+msgid "Edit Pipeline Schedule"
+msgstr ""
msgid "Edit Release"
msgstr ""
@@ -12942,6 +13180,9 @@ msgstr "Изменить опиÑание"
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr "Редактируйте файлы в редакторе и зафикÑируйте Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð·Ð´ÐµÑÑŒ"
@@ -13237,10 +13478,10 @@ msgid "Enable Spam Check via external API endpoint"
msgstr ""
msgid "Enable What's new: All tiers"
-msgstr ""
+msgstr "Включить \"Что нового\": вÑе уровни"
msgid "Enable What's new: Current tier only"
-msgstr ""
+msgstr "Включить \"Что нового\": только текущий уровень"
msgid "Enable a Prometheus endpoint that exposes health and performance statistics. The Health Check menu item appears in the Monitoring section of the Admin Area. Restart required."
msgstr ""
@@ -13279,7 +13520,7 @@ msgid "Enable container expiration and retention policies for projects created e
msgstr ""
msgid "Enable delayed project deletion by default for newly-created groups."
-msgstr ""
+msgstr "Включить отложенное удаление проектов Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… групп по умолчанию."
msgid "Enable email notification"
msgstr ""
@@ -13562,7 +13803,7 @@ msgid "EnvironmentDashboard|You are looking at the last updated environment"
msgstr "Ð’Ñ‹ проÑматриваете поÑледнее обновленное окружение"
msgid "Environments"
-msgstr "Среды"
+msgstr "ОкружениÑ"
msgid "Environments Dashboard"
msgstr "Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñми"
@@ -13885,6 +14126,9 @@ msgstr "Что-то пошло не так при заказе товара."
msgid "Epics|Something went wrong while removing issue from epic."
msgstr "Что-то пошло не так при удалении обÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð¸Ð· цели."
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13930,9 +14174,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr "Ошибка при удалении проекта. Проверьте журналы Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð¾Ñтей об ошибке."
@@ -14086,9 +14327,6 @@ msgstr "Ошибка при загрузке файла: %{stripped}"
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr "Ошибка при загрузке данных проекта. ПожалуйÑта, попробуйте Ñнова."
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr "Ошибка при переноÑе %{upload_id}: %{error_message}"
@@ -14173,6 +14411,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14360,9 +14601,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr "Ð’Ñе"
-
msgid "Everyone With Access"
msgstr "Ð’Ñе, имеющие доÑтуп"
@@ -14555,7 +14793,7 @@ msgstr "ЭкÑпорт проекта"
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14689,7 +14927,7 @@ msgid "Failed to create merge request. Please try again."
msgstr ""
msgid "Failed to create new project access token: %{token_response_message}"
-msgstr ""
+msgstr "Ðе удалоÑÑŒ Ñоздать новый токен доÑтупа к проекту: %{token_response_message}"
msgid "Failed to create repository"
msgstr ""
@@ -14842,10 +15080,10 @@ msgid "Failed to save new settings"
msgstr ""
msgid "Failed to save preferences (%{error_message})."
-msgstr ""
+msgstr "Ðе удалоÑÑŒ Ñохранить наÑтройки (%{error_message})."
msgid "Failed to save preferences."
-msgstr ""
+msgstr "Ðе удалоÑÑŒ Ñохранить наÑтройки."
msgid "Failed to set due date because the date format is invalid."
msgstr ""
@@ -15110,7 +15348,7 @@ msgid "FeatureFlags|View user lists"
msgstr ""
msgid "FeatureFlag|Percentage"
-msgstr ""
+msgstr "Процент"
msgid "FeatureFlag|Select a user list"
msgstr ""
@@ -15269,9 +15507,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr "Фильтр по двухфакторной аутентификации"
-
msgid "Filter by user"
msgstr "Фильтр по пользователю"
@@ -15602,6 +15837,9 @@ msgstr "От запроÑа на ÑлиÑние до развертываниÑ
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr "Полное имÑ"
@@ -16461,10 +16699,7 @@ msgid "GlobalSearch|Results updated. %{count} results available. Use the up and
msgstr ""
msgid "GlobalSearch|Search GitLab"
-msgstr ""
-
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
+msgstr "ПоиÑк в GitLab"
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16553,6 +16788,9 @@ msgstr "Перейти к метрикам"
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16742,9 +16980,6 @@ msgstr ""
msgid "Group URL"
msgstr "URL группы"
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16871,6 +17106,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr "Группа была уÑпешно обновлена."
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr "Группа: %{group_name}"
@@ -16973,9 +17211,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -17048,6 +17295,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -17087,6 +17337,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -17120,6 +17373,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -17144,8 +17409,8 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr "Значки"
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
-msgstr "Будьте оÑторожны. Смена Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ñ‹ может привеÑти к непреднамеренным %{side_effects_link_start}побочным Ñффектам%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
+msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
msgstr ""
@@ -17153,7 +17418,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -17193,6 +17458,9 @@ msgid "GroupSettings|New runners registration token has been generated!"
msgstr "Ðовый региÑтрационный токен обработчика заданий Ñгенерирован!"
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
+msgstr "ПереопределÑет пользовательÑкие наÑтройки уведомлений Ð´Ð»Ñ Ð²Ñех учаÑтников Ñтой группы, подгрупп и проектов."
+
+msgid "GroupSettings|Parent Group"
msgstr ""
msgid "GroupSettings|Pipeline settings was updated for the group"
@@ -17222,12 +17490,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17262,7 +17536,7 @@ msgid "GroupSettings|Transfer group"
msgstr "ПеренеÑти группу"
msgid "GroupSettings|Users can create %{link_start}project access tokens%{link_end} for projects in this group."
-msgstr ""
+msgstr "Пользователи могут Ñоздавать %{link_start}токены доÑтупа%{link_end} к проектам в Ñтой группе."
msgid "GroupSettings|What are badges?"
msgstr ""
@@ -17342,6 +17616,9 @@ msgstr "Ð’Ñ‹ можете управлÑÑ‚ÑŒ правами и доÑтупом
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17396,6 +17673,9 @@ 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 ""
+
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 ""
@@ -18635,7 +18915,7 @@ msgid "InProductMarketing|unsubscribe"
msgstr ""
msgid "InProductMarketing|update your preferences"
-msgstr ""
+msgstr "обновите наÑтройки"
msgid "InProductMarketing|using a CI/CD template"
msgstr ""
@@ -18887,7 +19167,7 @@ msgid "Index deletion is canceled"
msgstr ""
msgid "Indicates whether this runner can pick jobs without tags"
-msgstr "Указывает, может ли Ñтот обработчик заданий выбирать Ð·Ð°Ð´Ð°Ð½Ð¸Ñ Ð±ÐµÐ· меток"
+msgstr "Указывает, может ли Ñтот обработчик заданий выбирать Ð·Ð°Ð´Ð°Ð½Ð¸Ñ Ð±ÐµÐ· тегов"
msgid "Inform users without uploaded SSH keys that they can't push over SSH until one is added"
msgstr "Сообщать пользователÑм без загруженных SSH ключей, что они не могут отправлÑÑ‚ÑŒ через SSH до тех пор, пока Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один не будет добавлен"
@@ -19041,7 +19321,7 @@ msgid "Instance audit events"
msgstr ""
msgid "Instance overview"
-msgstr ""
+msgstr "Обзор ÑкземплÑра"
msgid "Insufficient permissions"
msgstr ""
@@ -19316,6 +19596,9 @@ msgstr ""
msgid "Invalid URL"
msgstr "ÐедопуÑÑ‚Ð¸Ð¼Ð°Ñ ÑÑылка"
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19419,7 +19702,7 @@ msgid "Invite \"%{trimmed}\" by email"
msgstr "ПриглаÑить \"%{trimmed}\" по Ñлектронной почте"
msgid "Invite Members"
-msgstr ""
+msgstr "ПриглаÑить УчаÑтников"
msgid "Invite a group"
msgstr ""
@@ -19434,19 +19717,19 @@ msgid "Invite member"
msgstr "ПриглаÑить учаÑтников"
msgid "Invite members"
-msgstr ""
+msgstr "ПриглаÑить учаÑтников"
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
msgstr ""
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 ""
+msgstr "%{inviter} приглаÑил Ð²Ð°Ñ Ð¿Ñ€Ð¸ÑоединитьÑÑ Ðº %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} в роли %{role}"
msgid "InviteEmail|%{project_or_group} details"
msgstr ""
msgid "InviteEmail|Groups assemble related projects together and grant members access to several projects at once."
-msgstr ""
+msgstr "Группы объединÑÑŽÑ‚ проекты и предоÑтавлÑÑŽÑ‚ учаÑтникам доÑтуп к неÑкольким проектам одновременно."
msgid "InviteEmail|Join now"
msgstr ""
@@ -19464,7 +19747,7 @@ msgid "InviteEmail|What's it about?"
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 ""
@@ -19485,97 +19768,94 @@ msgid "InviteMembersBanner|We noticed that you haven't invited anyone to this gr
msgstr "Мы заметили, что вы никого не приглаÑили в Ñту группу. ПриглаÑите коллег, чтобы вы могли учаÑтвовать в обÑуждениÑÑ…, вмеÑте работать над запроÑами на ÑлиÑние и делитьÑÑ Ð·Ð½Ð°Ð½Ð¸Ñми."
msgid "InviteMembersModal|%{linkStart}Read more%{linkEnd} about role permissions"
-msgstr ""
+msgstr "%{linkStart}Подробнее%{linkEnd} о разрешениÑÑ… ролей"
msgid "InviteMembersModal|Access expiration date (optional)"
-msgstr ""
+msgstr "Дата Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ Ð´Ð¾Ñтупа (опционально)"
msgid "InviteMembersModal|Cancel"
-msgstr ""
+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 ""
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 ""
+msgstr "ПриглаÑить"
msgid "InviteMembersModal|Invite a group"
-msgstr ""
+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 ""
+msgstr "Выберите группу Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð³Ð»Ð°ÑˆÐµÐ½Ð¸Ñ"
msgid "InviteMembersModal|Select a role"
-msgstr ""
+msgstr "Выберите роль"
msgid "InviteMembersModal|Select members or type email addresses"
-msgstr ""
+msgstr "Выберите учаÑтников или введите адреÑа Ñлектронной почты"
msgid "InviteMembersModal|Something went wrong"
-msgstr ""
+msgstr "Что-то пошло не так"
msgid "InviteMembersModal|To assign issues to a new team member, you need a project for the issues. %{linkStart}Create a project to get started.%{linkEnd}"
-msgstr ""
+msgstr "Чтобы назначить обÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð¼Ñƒ учаÑтнику команды, нужен проект Ð´Ð»Ñ Ñтих обÑуждений. %{linkStart}Создайте проект.%{linkEnd}"
msgid "InviteMembersModal|You're inviting a group to the %{strongStart}%{name}%{strongEnd} group."
-msgstr ""
+msgstr "Вы приглашаете группу в группу %{strongStart}%{name}%{strongEnd}."
msgid "InviteMembersModal|You're inviting a group to the %{strongStart}%{name}%{strongEnd} project."
-msgstr ""
+msgstr "Вы приглашаете группу в проект %{strongStart}%{name}%{strongEnd}."
msgid "InviteMembersModal|You're inviting members to the %{strongStart}%{name}%{strongEnd} group."
-msgstr ""
+msgstr "Ð’Ñ‹ приглашаете учаÑтников в группу %{strongStart}%{name}%{strongEnd}."
msgid "InviteMembersModal|You're inviting members to the %{strongStart}%{name}%{strongEnd} project."
-msgstr ""
+msgstr "Ð’Ñ‹ приглашаете учаÑтников в проект %{strongStart}%{name}%{strongEnd}."
msgid "InviteMembers|Invite a group"
-msgstr ""
+msgstr "ПриглаÑить группу"
msgid "InviteMembers|Invite team members"
-msgstr ""
+msgstr "ПриглаÑить учаÑтников команды"
msgid "InviteMember|Add members to this project and start collaborating with your team."
-msgstr ""
-
-msgid "InviteMember|Invite Member"
-msgstr ""
+msgstr "Добавить учаÑтников в проект и начать ÑотрудничеÑтво Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹."
msgid "InviteMember|Invite Members (optional)"
-msgstr ""
+msgstr "ПриглаÑить учаÑтников (необÑзательно)"
msgid "InviteMember|Invite another member"
msgstr ""
msgid "InviteMember|Invite members"
-msgstr ""
+msgstr "ПриглаÑить учаÑтников"
msgid "InviteMember|Invite your team"
msgstr ""
@@ -19670,9 +19950,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr "Это пробный период GitLab Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ компании?"
-
msgid "Is using license seat:"
msgstr ""
@@ -19784,9 +20061,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr "ДоÑка"
@@ -20432,8 +20706,8 @@ msgstr ""
msgid "Job|Download"
msgstr "Скачать"
-msgid "Job|Erase job log"
-msgstr "ОчиÑтить журнал заданиÑ"
+msgid "Job|Erase job log and artifacts"
+msgstr ""
msgid "Job|Job artifacts"
msgstr "Ðртефакты заданиÑ"
@@ -20886,6 +21160,12 @@ msgstr "ПоÑледнÑÑ ÑÐ±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Ð´Ð»Ñ Ñамого ÑÐ
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21058,7 +21338,7 @@ msgid "LearnGitLab|Use your new GitLab workflow to deploy your application, moni
msgstr ""
msgid "LearnGitLab|Your team is growing! You've successfully invited new team members to the %{projectName} project."
-msgstr ""
+msgstr "Ваша команда раÑÑ‚Ñ‘Ñ‚! Ð’Ñ‹ уÑпешно приглаÑили новых учаÑтников в проект %{projectName}."
msgid "LearnGitlab|Creating your onboarding experience..."
msgstr ""
@@ -21250,7 +21530,7 @@ msgid "Licenses|Component"
msgstr ""
msgid "Licenses|Components"
-msgstr ""
+msgstr "Компоненты"
msgid "Licenses|Detected in Project"
msgstr ""
@@ -21661,7 +21941,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22115,7 +22395,7 @@ 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 ""
@@ -22172,7 +22452,7 @@ msgid "Members|Search groups"
msgstr ""
msgid "Members|Search invited"
-msgstr ""
+msgstr "ПоиÑк приглашённых"
msgid "Member|Deny access"
msgstr ""
@@ -22187,7 +22467,7 @@ msgid "Memory Usage"
msgstr ""
msgid "Menu"
-msgstr ""
+msgstr "Меню"
msgid "Merge"
msgstr "СлиÑние"
@@ -22417,10 +22697,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22519,6 +22799,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr "Метрики и профилирование"
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -23142,6 +23425,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr "Более %{number_commits_distance} коммитов отличаетÑÑ Ð¾Ñ‚ %{default_branch}"
@@ -23347,6 +23633,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr "Помощь"
@@ -23560,6 +23879,9 @@ msgstr "Ðовый"
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr "Ðовое Приложение"
@@ -23786,6 +24108,9 @@ msgstr ""
msgid "Next file in diff"
msgstr "Следующий файл в отличиÑÑ… (diff)"
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr "Следующее нерешённое обÑуждение"
@@ -24084,7 +24409,7 @@ msgid "No start date"
msgstr ""
msgid "No tag selected"
-msgstr ""
+msgstr "Тег не выбран"
msgid "No template"
msgstr ""
@@ -24207,6 +24532,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr "Примечание"
@@ -24219,7 +24547,7 @@ msgstr "Ð’Ñ‹ уверены, что вы хотите отменить ÑоздÐ
msgid "Notes|Collapse replies"
msgstr "Свернуть ответы"
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24634,6 +24962,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24652,12 +24986,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24697,12 +25037,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24727,18 +25076,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24748,9 +25112,6 @@ msgstr "ПоÑле импорта, репозитории могут зеркаÐ
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr "ПоÑле того, как ÑкÑпортируемый файл будет готов, вы получите уведомление по Ñлектронной почте Ñ ÑÑылкой Ð´Ð»Ñ ÑкачиваниÑ, или вы Ñможете Ñкачать его Ñ Ñтой Ñтраницы."
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24911,6 +25272,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¸ иÑтекло. Проверьте журналы пода %{pod_name} Ð´Ð»Ñ Ð±Ð¾Ð»ÐµÐµ подробной информации."
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25452,9 +25816,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25644,9 +26005,15 @@ msgstr ""
msgid "Pending"
msgstr "В ожидании"
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25746,6 +26113,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25827,12 +26197,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr "Квота иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ CI в минутах"
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -26064,6 +26428,9 @@ msgstr "ДочернÑÑ ÑÐ±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ"
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -26083,7 +26450,7 @@ msgid "Pipelines|Editor"
msgstr "Редактор"
msgid "Pipelines|Get familiar with GitLab CI/CD syntax by starting with a basic 3 stage CI/CD pipeline."
-msgstr ""
+msgstr "ОзнакомьтеÑÑŒ Ñ ÑинтакÑиÑом GitLab CI/CD, начав Ñ Ð±Ð°Ð·Ð¾Ð²Ð¾Ð¹ трёхÑтапной Ñборочной линии."
msgid "Pipelines|Get started with GitLab CI/CD"
msgstr ""
@@ -26233,7 +26600,7 @@ msgid "Pipeline|Branch name"
msgstr ""
msgid "Pipeline|Branches or tags could not be loaded."
-msgstr ""
+msgstr "Ðе удалоÑÑŒ загрузить ветки или теги."
msgid "Pipeline|Canceled"
msgstr ""
@@ -26283,9 +26650,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26341,7 +26705,7 @@ msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr "ОÑтановить Ñборочную линию #%{pipelineId}?"
msgid "Pipeline|Tag name"
-msgstr ""
+msgstr "Ðазвание тега"
msgid "Pipeline|Test coverage"
msgstr ""
@@ -26562,6 +26926,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr "ПожалуйÑта, выберите"
@@ -26574,6 +26944,9 @@ msgstr "ПожалуйÑта, выберите Ñтрану"
msgid "Please select a file"
msgstr "ПожалуйÑта, выберите файл"
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr "ПожалуйÑта, выберите группу."
@@ -26686,10 +27059,10 @@ msgid "Preferences|Choose what content you want to see on your homepage."
msgstr "Выберите Ñодержимое, которое вы хотите видеть на вашей главной Ñтранице."
msgid "Preferences|Configure how dates and times display for you."
-msgstr ""
+msgstr "ÐаÑтройте Ð´Ð»Ñ ÑÐµÐ±Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ðµ даты и времени"
msgid "Preferences|Customize integrations with third party services."
-msgstr ""
+msgstr "ÐаÑтройте интеграцию Ñо Ñторонними ÑервиÑами."
msgid "Preferences|Customize the appearance of the application header and navigation sidebar."
msgstr "ÐаÑтройте внешний вид верхней и боковой панели навигации."
@@ -26698,19 +27071,19 @@ msgid "Preferences|Display time in 24-hour format"
msgstr "Отображать Ð²Ñ€ÐµÐ¼Ñ Ð² 24-чаÑовом формате"
msgid "Preferences|Enable Gitpod integration"
-msgstr ""
+msgstr "Включить интеграцию Ñ Gitpod"
msgid "Preferences|Enable integrated code intelligence on code views"
msgstr ""
msgid "Preferences|Failed to save preferences."
-msgstr ""
+msgstr "Ðе удалоÑÑŒ Ñохранить наÑтройки."
msgid "Preferences|For example: 30 minutes ago."
-msgstr ""
+msgstr "Ðапример: 30 минут назад."
msgid "Preferences|Gitpod"
-msgstr ""
+msgstr "Gitpod"
msgid "Preferences|Homepage content"
msgstr "Содержимое главной Ñтраницы"
@@ -26719,13 +27092,13 @@ msgid "Preferences|Instead of all the files changed, show only one file at a tim
msgstr "ВмеÑто того чтобы показывать вÑе изменённые файлы, показывать только один файл. Чтобы переключатьÑÑ Ð¼ÐµÐ¶Ð´Ñƒ файлами, нужно будет иÑпользовать браузер файлов."
msgid "Preferences|Integrations"
-msgstr ""
+msgstr "Интеграции"
msgid "Preferences|Layout width"
msgstr "Ширина макета"
msgid "Preferences|Must be a number between %{min} and %{max}"
-msgstr ""
+msgstr "Должно быть чиÑлом между %{min} и %{max}"
msgid "Preferences|Navigation theme"
msgstr "Дизайн верхней панели"
@@ -26743,10 +27116,10 @@ msgid "Preferences|Show whitespace changes in diffs"
msgstr "Показывать Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð±ÐµÐ»Ð¾Ð² в отличиÑÑ…"
msgid "Preferences|Sourcegraph"
-msgstr ""
+msgstr "Sourcegraph"
msgid "Preferences|Surround text selection when typing quotes or brackets"
-msgstr ""
+msgstr "Заключить выделенный текÑÑ‚ в кавычки или Ñкобки при вводе ÑоответÑтвующих Ñимволов"
msgid "Preferences|Syntax highlighting theme"
msgstr "Тема подÑветки ÑинтакÑиÑа"
@@ -26769,9 +27142,6 @@ msgstr "ÐаÑтройки времени"
msgid "Preferences|Use relative times"
msgstr "ИÑпользовать отноÑительное времÑ"
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr "Пред."
@@ -27123,6 +27493,9 @@ msgstr "Ðеверный пароль"
msgid "Profiles|Invalid username"
msgstr "Ðеверное Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ"
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr "Ключ"
@@ -27180,6 +27553,12 @@ msgstr "Приватный вклад"
msgid "Profiles|Profile was successfully updated"
msgstr "Профиль уÑпешно обновлен"
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -27264,6 +27643,9 @@ msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ ÑƒÑпешно изменено"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr "ИÑпользовать Ñмайлы в имени - веÑьма ÐºÑ€ÐµÐ°Ñ‚Ð¸Ð²Ð½Ð°Ñ Ð¼Ñ‹Ñль, но лучше попробуйте изменить ÑÑ‚Ð°Ñ‚ÑƒÑ Ð² профиле"
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr "Как у Ð²Ð°Ñ Ð´ÐµÐ»Ð°?"
@@ -27558,6 +27940,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr "ID проекта: %{project_id}"
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr "Процент уÑпешных, проваленных и пропущенных теÑтов."
+
msgid "ProjectSelect| or group"
msgstr "или группа"
@@ -27682,22 +28106,25 @@ msgid "ProjectService|Trigger event when an issue is created, updated, or closed
msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
+msgstr "%{link_start}Что такое шаблоны опиÑаниÑ?%{link_end}"
+
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
msgstr ""
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
-msgstr ""
+msgstr "Дополнительные параметры, влиÑющие на то, как и когда проиÑходит ÑлиÑние,"
msgid "ProjectSettings|All discussions must be resolved"
msgstr "Ð’Ñе обÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ‹ быть разрешены"
msgid "ProjectSettings|Allow"
-msgstr ""
+msgstr "Разрешать"
msgid "ProjectSettings|Always show thumbs-up and thumbs-down award emoji buttons on issues, merge requests, and snippets."
-msgstr ""
+msgstr "Ð’Ñегда показывать большой палец вверх или вниз в обÑуждениÑÑ…, запроÑах на ÑлиÑние и Ñниппетах."
msgid "ProjectSettings|Analytics"
-msgstr ""
+msgstr "Ðналитика"
msgid "ProjectSettings|Automatically resolve merge request diff discussions when they become outdated"
msgstr "ÐвтоматичеÑки разрешать обÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ по запроÑу на ÑлиÑние, когда они ÑтановÑÑ‚ÑÑ Ð½ÐµÐ°ÐºÑ‚ÑƒÐ°Ð»ÑŒÐ½Ñ‹Ð¼Ð¸"
@@ -27706,13 +28133,13 @@ msgid "ProjectSettings|Badges"
msgstr "Значки"
msgid "ProjectSettings|Build, test, and deploy your changes."
-msgstr ""
+msgstr "Сборка, теÑтирование и разворачивание изменений."
msgid "ProjectSettings|Checkbox is visible and selected by default."
-msgstr ""
+msgstr "Флажок отображаетÑÑ Ð¸ выбран по умолчанию"
msgid "ProjectSettings|Checkbox is visible and unselected by default."
-msgstr ""
+msgstr "Флажок отображаетÑÑ Ð¸ ÑнÑÑ‚ по умолчанию."
msgid "ProjectSettings|Choose your merge method, merge options, merge checks, and merge suggestions."
msgstr "Выберите ваш метод, наÑтройки, проверки и Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÑлиÑниÑ."
@@ -27721,19 +28148,19 @@ msgid "ProjectSettings|Choose your merge method, merge options, merge checks, me
msgstr "Выберите метод ÑлиÑниÑ, параметры ÑлиÑниÑ, проверки ÑлиÑниÑ, Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ ÑлиÑнию и наÑтройте шаблон опиÑÐ°Ð½Ð¸Ñ Ð¿Ð¾ умолчанию Ð´Ð»Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñов на ÑлиÑние."
msgid "ProjectSettings|Configure your project resources and monitor their health."
-msgstr ""
+msgstr "ÐаÑтройка реÑурÑов проекта и мониторинг их здоровьÑ."
msgid "ProjectSettings|Contact an admin to change this setting."
-msgstr ""
+msgstr "ОбратитеÑÑŒ к админиÑтратору Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñтой наÑтройки."
msgid "ProjectSettings|Container registry"
msgstr "РееÑÑ‚Ñ€ контейнеров"
msgid "ProjectSettings|Customize this project's badges."
-msgstr ""
+msgstr "ÐаÑтройте значки Ñтого проекта."
msgid "ProjectSettings|Determine what happens to the commit history when you merge a merge request."
-msgstr ""
+msgstr "Определите, что произойдёт Ñ Ð¸Ñторией коммитов при выполнении запроÑа на ÑлиÑние."
msgid "ProjectSettings|Disable email notifications"
msgstr "Отключить ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾ Ñлектронной почте"
@@ -27742,58 +28169,58 @@ msgid "ProjectSettings|Do not allow"
msgstr "Ðе разрешать"
msgid "ProjectSettings|Enable \"Delete source branch\" option by default"
-msgstr ""
+msgstr "Включить опцию \"Удалить ветку иÑточника\" по умолчанию."
msgid "ProjectSettings|Enable merge trains"
-msgstr ""
+msgstr "Разрешить цепочки ÑлиÑний"
msgid "ProjectSettings|Enable merged results pipelines"
-msgstr ""
+msgstr "Включить Ñборочные линии Ð´Ð»Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ð¾Ð² ÑлиÑний"
msgid "ProjectSettings|Encourage"
-msgstr ""
+msgstr "ПоощрÑÑ‚ÑŒ"
msgid "ProjectSettings|Every merge creates a merge commit."
-msgstr ""
+msgstr "Каждое ÑлиÑние Ñоздает коммит ÑлиÑниÑ."
msgid "ProjectSettings|Every project can have its own space to store its Docker images"
msgstr "Каждый проект может иметь Ñвоё ÑобÑтвенное проÑтранÑтво Ð´Ð»Ñ Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¾Ð±Ñ€Ð°Ð·Ð¾Ð² Docker"
msgid "ProjectSettings|Every project can have its own space to store its packages."
-msgstr ""
+msgstr "Каждый проект может иметь ÑобÑтвенное проÑтранÑтво Ð´Ð»Ñ Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñвоих пакетов."
msgid "ProjectSettings|Everyone"
msgstr "Каждый"
msgid "ProjectSettings|Existing merge requests and protected branches are not affected."
-msgstr ""
+msgstr "СущеÑтвующие запроÑÑ‹ на ÑлиÑние и защищённые ветки не затрагиваютÑÑ."
msgid "ProjectSettings|Failed to protect the tag"
-msgstr "Ðе удалоÑÑŒ защитить метку"
+msgstr "Ðе удалоÑÑŒ защитить тег"
msgid "ProjectSettings|Failed to update tag!"
-msgstr "Ðе удалоÑÑŒ обновить метку!"
+msgstr "Ðе удалоÑÑŒ обновить тег!"
msgid "ProjectSettings|Fast-forward merge"
msgstr "БыÑтрое ÑлиÑние"
msgid "ProjectSettings|Fast-forward merges only."
-msgstr ""
+msgstr "Только быÑтрые ÑлиÑниÑ."
msgid "ProjectSettings|Flexible tool to collaboratively develop ideas and plan work in this project."
-msgstr ""
+msgstr "Гибкий инÑтрумент Ð´Ð»Ñ ÑовмеÑтной разработки идей и Ð¿Ð»Ð°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ в Ñтом проекте."
msgid "ProjectSettings|Forks"
msgstr "ОтветвлениÑ"
msgid "ProjectSettings|Git Large File Storage (LFS)"
-msgstr ""
+msgstr "Хранилище больших файлов Git (LFS)"
msgid "ProjectSettings|Global"
msgstr ""
msgid "ProjectSettings|Highlight the usage of hidden unicode characters. These have innocent uses for right-to-left languages, but can also be used in potential exploits."
-msgstr ""
+msgstr "ПодÑветить иÑпользование Ñкрытых Ñимволов unicode. Они приÑутÑтвуют в Ñзыках Ñ Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸ÐµÐ¼ пиÑьма Ñправа налево, но также могут иÑпользоватьÑÑ Ð² потенциальных ÑкÑплойтах."
msgid "ProjectSettings|Internal"
msgstr "ВнутреннÑÑ"
@@ -27811,22 +28238,22 @@ msgid "ProjectSettings|Manage who can see the project in the public access direc
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
-msgstr ""
+msgstr "УправлÑет большими файлами, такими как аудио, видео и графичеÑкие."
msgid "ProjectSettings|Maximum 500 characters."
-msgstr ""
+msgstr "МакÑимум 500 Ñимволов."
msgid "ProjectSettings|Merge checks"
msgstr "Проверки ÑлиÑниÑ"
msgid "ProjectSettings|Merge commit"
-msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние"
+msgstr "Коммит ÑлиÑниÑ"
msgid "ProjectSettings|Merge commit message template"
msgstr ""
msgid "ProjectSettings|Merge commit with semi-linear history"
-msgstr "Объединить коммит Ñ Ð¿Ð¾Ð»ÑƒÐ»Ð¸Ð½ÐµÐ¹Ð½Ð¾Ð¹ иÑторией"
+msgstr "Коммит ÑлиÑÐ½Ð¸Ñ Ñ Ð¿Ð¾Ð»ÑƒÐ»Ð¸Ð½ÐµÐ¹Ð½Ð¾Ð¹ иÑторией"
msgid "ProjectSettings|Merge method"
msgstr "Метод ÑлиÑниÑ"
@@ -27844,19 +28271,19 @@ msgid "ProjectSettings|Merge suggestions"
msgstr "ÐŸÑ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ ÑлиÑнию"
msgid "ProjectSettings|No merge commits are created."
-msgstr ""
+msgstr "Коммиты ÑлиÑÐ½Ð¸Ñ Ð½Ðµ ÑоздаютÑÑ."
msgid "ProjectSettings|Note: The container registry is always visible when a project is public and the container registry is set to '%{access_level_description}'"
msgstr ""
msgid "ProjectSettings|Only signed commits can be pushed to this repository."
-msgstr ""
+msgstr "Только подпиÑанные коммиты могут быть отправлены в Ñтот репозиторий."
msgid "ProjectSettings|Operations"
-msgstr ""
+msgstr "Операции"
msgid "ProjectSettings|Override user notification preferences for all project members."
-msgstr ""
+msgstr "Переопределить наÑтройки уведомлений Ð´Ð»Ñ Ð²Ñех учаÑтников проекта."
msgid "ProjectSettings|Packages"
msgstr "Пакеты"
@@ -27865,7 +28292,7 @@ msgid "ProjectSettings|Pages"
msgstr "Pages"
msgid "ProjectSettings|Pages for project documentation."
-msgstr ""
+msgstr "Страницы Ð´Ð»Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ð¸ проекта."
msgid "ProjectSettings|Pipelines must succeed"
msgstr "Сборочные линии должны уÑпешно выполнитьÑÑ"
@@ -27883,13 +28310,13 @@ msgid "ProjectSettings|Repository"
msgstr "Репозиторий"
msgid "ProjectSettings|Require"
-msgstr ""
+msgstr "Требовать"
msgid "ProjectSettings|Require an associated issue from Jira"
msgstr ""
msgid "ProjectSettings|Requirements"
-msgstr ""
+msgstr "ТребованиÑ"
msgid "ProjectSettings|Requirements management system."
msgstr ""
@@ -27904,7 +28331,7 @@ msgid "ProjectSettings|Security & Compliance for this project"
msgstr ""
msgid "ProjectSettings|Set the default behavior of this option in merge requests. Changes to this are also applied to existing merge requests."
-msgstr ""
+msgstr "Задайте поведение по умолчанию в запроÑах на ÑлиÑние. Изменение Ñтого параметра также затронет ÑущеÑтвующие запроÑÑ‹ на ÑлиÑние."
msgid "ProjectSettings|Share code with others outside the project."
msgstr ""
@@ -27922,33 +28349,30 @@ msgid "ProjectSettings|Snippets"
msgstr "Сниппеты"
msgid "ProjectSettings|Squash commit message template"
-msgstr ""
+msgstr "Шаблон ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ðº Ñжатому коммиту"
msgid "ProjectSettings|Squash commits when merging"
-msgstr ""
+msgstr "Сжатие коммитов при ÑлиÑнии"
msgid "ProjectSettings|Squashing is always performed. Checkbox is visible and selected, and users cannot change it."
-msgstr ""
+msgstr "Сжатие выполнÑетÑÑ Ð²Ñегда. Флажок отображаетÑÑ, выбран, и пользователи не могут его ÑнÑÑ‚ÑŒ."
msgid "ProjectSettings|Squashing is never performed and the checkbox is hidden."
-msgstr ""
+msgstr "Сжатие никогда не выполнÑетÑÑ, а флажок Ñкрыт."
msgid "ProjectSettings|Submit changes to be merged upstream."
-msgstr ""
-
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
+msgstr "Отправка изменений Ð´Ð»Ñ ÑлиÑÐ½Ð¸Ñ Ð² upstream."
msgid "ProjectSettings|Target project"
-msgstr ""
+msgstr "Целевой проект"
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27958,7 +28382,7 @@ msgid "ProjectSettings|These checks must pass before merge requests can be merge
msgstr ""
msgid "ProjectSettings|This project"
-msgstr ""
+msgstr "Этот проект"
msgid "ProjectSettings|This setting is applied on the server level and can be overridden by an admin."
msgstr "Эта наÑтройка применÑетÑÑ Ð½Ð° уровне Ñервера и может быть переопределена админиÑтратором."
@@ -27973,28 +28397,28 @@ msgid "ProjectSettings|To enable this feature, configure pipelines. %{link_start
msgstr ""
msgid "ProjectSettings|Transfer project"
-msgstr ""
+msgstr "ПеренеÑти проект"
msgid "ProjectSettings|Upstream project"
-msgstr ""
+msgstr "Upstream-проект"
msgid "ProjectSettings|Used for every new merge request."
msgstr ""
msgid "ProjectSettings|Users can copy the repository to a new project."
-msgstr ""
+msgstr "Пользователи могут копировать репозиторий в новый проект."
msgid "ProjectSettings|Users can only push commits to this repository that were committed with one of their own verified emails."
msgstr "Пользователи могут отправлÑÑ‚ÑŒ коммиты в данный репозиторий, только в Ñлучае еÑли коммит подпиÑан одним из подтвержденных адреÑов почты."
msgid "ProjectSettings|Users can request access"
-msgstr ""
+msgstr "Пользователи могут запрашивать доÑтуп"
msgid "ProjectSettings|View and edit files in this project."
-msgstr ""
+msgstr "ПроÑмотр и редактирование файлов в Ñтом проекте."
msgid "ProjectSettings|View and edit files in this project. Non-project members will only have read access."
-msgstr ""
+msgstr "ПроÑмотр и редактирование файлов в Ñтом проекте. Ðе-учаÑтники не Ñмогут вноÑить изменениÑ.."
msgid "ProjectSettings|View project analytics."
msgstr ""
@@ -28003,19 +28427,19 @@ msgid "ProjectSettings|Visibility options for this fork are limited by the curre
msgstr ""
msgid "ProjectSettings|Visualize the project's performance metrics."
-msgstr ""
+msgstr "Ð’Ð¸Ð·ÑƒÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿Ð¾ÐºÐ°Ð·Ð°Ñ‚ÐµÐ»ÐµÐ¹ производительноÑти проекта."
msgid "ProjectSettings|Warn about Potentially Unwanted Characters"
-msgstr ""
+msgstr "Предупреждать о потенциально нежелательных Ñимволах"
msgid "ProjectSettings|What are badges?"
-msgstr ""
+msgstr "Что такое значки?"
msgid "ProjectSettings|When pipelines for merge requests are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure pipelines for merge requests?%{link_end}"
msgstr ""
msgid "ProjectSettings|When there is a merge conflict, the user is given the option to rebase."
-msgstr ""
+msgstr "При возникновении конфликтов ÑлиÑÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŽ предоÑтавлÑетÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ÑŒ выбрать перебазирование."
msgid "ProjectSettings|Wiki"
msgstr "Wiki"
@@ -28104,6 +28528,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr "iOS (Swift)"
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr "Проекты"
@@ -28189,13 +28622,13 @@ msgid "ProjectsNew|Analyze your source code for known security vulnerabilities."
msgstr ""
msgid "ProjectsNew|Connect your external repository to GitLab CI/CD."
-msgstr ""
+msgstr "Подключить внешний репозиторий к GitLab CI/CD."
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr "СвÑжитеÑÑŒ Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтратором, чтобы включить параметры импорта вашего проекта."
msgid "ProjectsNew|Create"
-msgstr ""
+msgstr "Создать"
msgid "ProjectsNew|Create a blank project to house your files, plan your work, and collaborate on code, among other things."
msgstr ""
@@ -28204,7 +28637,7 @@ msgid "ProjectsNew|Create a project pre-populated with the necessary files to ge
msgstr ""
msgid "ProjectsNew|Create blank project"
-msgstr ""
+msgstr "Создать пуÑтой проект"
msgid "ProjectsNew|Create from template"
msgstr "Создать из шаблона"
@@ -28240,7 +28673,7 @@ msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr "ОпиÑание проекта %{tag_start}(необÑзательно)%{tag_end}"
msgid "ProjectsNew|Run CI/CD for external repository"
-msgstr ""
+msgstr "ЗапуÑтить CI/CD Ð´Ð»Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ репозиториÑ"
msgid "ProjectsNew|Visibility Level"
msgstr "Уровень доÑтупа"
@@ -28488,9 +28921,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28503,9 +28933,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28530,9 +28957,6 @@ msgstr "Обозначить приоритет обÑуждениÑ"
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr "При большом количеÑтве обÑуждений Ñложно оценить общую картину. Добавив приоритет к вашим обÑуждениÑм, вы можете получить лучшее предÑтавление о затрачиваемых уÑилиÑÑ…, времени, ÑтоимоÑти или значимоÑти каждого из них и, таким образом, лучше ими управлÑÑ‚ÑŒ."
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28549,7 +28973,7 @@ msgid "Protect"
msgstr ""
msgid "Protect a tag"
-msgstr ""
+msgstr "Защитить тег"
msgid "Protect variable"
msgstr "Защитить переменную"
@@ -28570,10 +28994,10 @@ msgid "Protected Paths: requests"
msgstr ""
msgid "Protected Tag"
-msgstr "Ð—Ð°Ñ‰Ð¸Ñ‰ÐµÐ½Ð½Ð°Ñ Ð¼ÐµÑ‚ÐºÐ°"
+msgstr "Защищенный тег"
msgid "Protected Tags"
-msgstr ""
+msgstr "Защищённые теги"
msgid "Protected branches"
msgstr "Защищённые ветви"
@@ -28585,7 +29009,7 @@ msgid "Protected paths"
msgstr ""
msgid "ProtectedBranch|%{wildcards_link_start}Wildcards%{wildcards_link_end} such as %{code_tag_start}*-stable%{code_tag_end} or %{code_tag_start}production/*%{code_tag_end} are supported."
-msgstr ""
+msgstr "ПоддерживаютÑÑ %{wildcards_link_start}подÑтановки%{wildcards_link_end}, такие как %{code_tag_start}*-stable%{code_tag_end} или %{code_tag_start}production/*%{code_tag_end}."
msgid "ProtectedBranch|Allow all users with push access to %{tag_start}force push%{tag_end}."
msgstr ""
@@ -28614,6 +29038,9 @@ msgstr "Отправка разрешена:"
msgid "ProtectedBranch|Branch"
msgstr "Ветка"
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28659,9 +29086,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr "Переключить утверждение владельцами кода"
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr "%{environment_name} будет доÑтупно Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ°Ð¼Ð¸. Ð’Ñ‹ уверены?"
@@ -28704,6 +29137,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28719,6 +29155,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28947,6 +29386,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr "README"
@@ -29134,9 +29579,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr "Создать ключ заново"
-
msgid "Regenerate recovery codes"
msgstr "Обновить коды воÑÑтановлениÑ"
@@ -29179,6 +29621,54 @@ msgstr "РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¸ помощи приложениÑ"
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29507,10 +29997,10 @@ msgstr "Удалено оценочное времÑ."
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29625,7 +30115,7 @@ msgid "Replication"
msgstr ""
msgid "Reply by email"
-msgstr ""
+msgstr "Ответ по Ñлектронной почте"
msgid "Reply to comment"
msgstr "Ответить на комментарий"
@@ -30206,6 +30696,9 @@ msgstr "Продолжить"
msgid "Resync"
msgstr "РеÑинхронизировать"
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr "Повторить"
@@ -30215,6 +30708,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr "Повторить Ñто фоновое задание"
@@ -30247,16 +30746,16 @@ msgid "Review App|View app"
msgstr ""
msgid "Review App|View latest app"
-msgstr ""
+msgstr "ПроÑмотр поÑледнего приложениÑ"
msgid "Review changes"
msgstr ""
msgid "Review requested from %{name}"
-msgstr ""
+msgstr "%{name} запроÑил рецензию"
msgid "Review requests for you"
-msgstr ""
+msgstr "ЗапроÑÑ‹ рецензий Ð´Ð»Ñ Ð²Ð°Ñ"
msgid "Review the changes locally"
msgstr ""
@@ -30368,7 +30867,7 @@ msgid "Run tests against your code live using the Web Terminal"
msgstr "ЗапуÑкайте теÑÑ‚Ñ‹ Ð´Ð»Ñ Ñвоего кода в реальном времени Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ веб-терминала"
msgid "Run untagged jobs"
-msgstr ""
+msgstr "ЗапуÑк заданий без тегов"
msgid "Runner API"
msgstr ""
@@ -30415,9 +30914,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30439,6 +30935,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30490,19 +30992,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30556,6 +31061,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30601,6 +31109,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30610,7 +31121,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30679,7 +31193,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30697,6 +31211,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr "ВыполнÑетÑÑ"
@@ -30893,7 +31410,7 @@ msgid "Search"
msgstr "ПоиÑк"
msgid "Search GitLab"
-msgstr ""
+msgstr "ПоиÑк в GitLab"
msgid "Search Jira issues"
msgstr ""
@@ -30917,7 +31434,7 @@ msgid "Search branches and tags"
msgstr "Ðайти ветки и теги"
msgid "Search branches, tags, and commits"
-msgstr ""
+msgstr "ПоиÑк по веткам, тегам и коммитам"
msgid "Search by Git revision"
msgstr ""
@@ -30958,6 +31475,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30979,9 +31499,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr "ПоиÑк проекта"
@@ -31284,6 +31801,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -31356,6 +31876,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31410,6 +31933,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31494,9 +32020,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31695,6 +32218,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31707,6 +32233,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31782,6 +32311,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31935,6 +32467,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -32286,6 +32821,12 @@ msgstr ""
msgid "Set due date"
msgstr "УÑтановить дату завершениÑ"
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr "Задать итерацию"
@@ -32442,6 +32983,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr "УÑтанавливает %{epic_ref} как родительÑкую цель."
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32686,7 +33230,7 @@ msgid "Showing last %{size} of log -"
msgstr ""
msgid "Showing latest version"
-msgstr ""
+msgstr "Показана поÑледнÑÑ Ð²ÐµÑ€ÑиÑ"
msgid "Showing version #%{versionNumber}"
msgstr ""
@@ -33147,6 +33691,9 @@ msgstr "Что-то пошло не так при обновлении требÐ
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33591,9 +34138,6 @@ msgstr ""
msgid "Start your free trial"
msgstr "Ðачать беÑплатный пробный период"
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr "Запущен"
@@ -33925,7 +34469,7 @@ msgid "Submit changes..."
msgstr ""
msgid "Submit feedback"
-msgstr ""
+msgstr "Отправить отзыв"
msgid "Submit review"
msgstr ""
@@ -33990,6 +34534,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34425,6 +34975,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr "СиÑтема"
@@ -34477,7 +35045,7 @@ msgid "Tag list:"
msgstr "СпиÑок тегов:"
msgid "Tag name"
-msgstr ""
+msgstr "Ðазвание тега"
msgid "Tag name is required"
msgstr ""
@@ -34504,7 +35072,7 @@ msgid "Tags are deleted until the timeout is reached. Any remaining tags are inc
msgstr ""
msgid "Tags feed"
-msgstr "Лента меток"
+msgstr "Лента тегов"
msgid "Tags this commit to %{tag_name} with \"%{message}\"."
msgstr ""
@@ -34582,7 +35150,7 @@ msgid "TagsPage|Write your release notes or drag files here…"
msgstr "Ðапишите заметки к релизу или перетащите Ñюда файлы…"
msgid "TagsPage|protected"
-msgstr "защищеннаÑ"
+msgstr "защищенный"
msgid "Target Branch"
msgstr "Ветка"
@@ -34697,9 +35265,29 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34730,6 +35318,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34742,6 +35333,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34778,12 +35372,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -35058,7 +35661,7 @@ msgid "The branch for this project has no active pipeline configuration."
msgstr "Ветка Ð´Ð»Ñ Ñтого проекта не имеет активной конфигурации Ñборочной линии."
msgid "The branch or tag does not exist"
-msgstr ""
+msgstr "Ветка или тег не ÑущеÑтвует"
msgid "The character highlighter helps you keep the subject line to %{titleLength} characters and wrap the body at %{bodyLength} so they are readable in git."
msgstr ""
@@ -35075,6 +35678,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "Соединение будет отключено через %{timeout}. Ð”Ð»Ñ Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸ÐµÐ², требующих больше времени, иÑпользуйте комбинацию clone/push."
@@ -35199,9 +35805,6 @@ msgstr "Группу и любые публичные проекты можно
msgid "The group and its projects can only be viewed by members."
msgstr "Группу и ее проекты могут проÑматривать только учаÑтники."
-msgid "The group can be fully restored"
-msgstr "Эта группа может быть полноÑтью воÑÑтановлена"
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -35211,9 +35814,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr "ÐаÑтройки группы %{group_links} требуют, чтобы вы включили двухфакторную аутентификацию Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ учетной запиÑи. Ð’Ñ‹ можете %{leave_group_links}."
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -35286,7 +35886,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35344,7 +35944,7 @@ msgid "The pipeline has been deleted"
msgstr ""
msgid "The pipelines schedule runs pipelines in the future, repeatedly, for specific branches or tags. Those scheduled pipelines will inherit limited project access based on their associated user."
-msgstr "РаÑпиÑание Ñборочных линий запуÑкает Ñборочные линии в будущем, неоднократно, Ð´Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð½Ñ‹Ñ… веток или меток. Эти запланированные Ñборочные линии будут наÑледовать ограниченный доÑтуп к проекту на оÑнове их аÑÑоциированного пользователÑ."
+msgstr "РаÑпиÑание Ñборочных линий может многократно запуÑкать Ñборочные линии Ð´Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð½Ñ‹Ñ… веток или тегов в будущем. Эти запланированные Ñборочные линии будут наÑледовать Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ñтупа к проектам от аÑÑоциированного пользователÑ."
msgid "The private key to use when a client certificate is provided. This value is encrypted at rest."
msgstr "Закрытый ключ, иÑпользуемый при предоÑтавлении клиентÑкого Ñертификата. Он будет зашифрован в ÑоÑтоÑнии покоÑ."
@@ -35541,9 +36141,6 @@ msgstr "Ðет обÑуждений, которые можно показать"
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr "Пока нет ни одной метки"
-
msgid "There are no matching files"
msgstr ""
@@ -35889,6 +36486,9 @@ msgstr "Этот ÑкземплÑÑ€ GitLab лицензирован на уроÐ
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35901,9 +36501,6 @@ msgstr "Это дейÑтвие может привеÑти к потере да
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35928,6 +36525,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -36042,6 +36642,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -36207,6 +36810,9 @@ msgstr "Это фоновое задание требует ручных дейÑ
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36885,10 +37491,10 @@ msgid "To import an SVN repository, check out %{svn_link}."
msgstr ""
msgid "To keep this project going, create a new issue"
-msgstr ""
+msgstr "Чтобы поддержать проект, Ñоздайте новое обÑуждение"
msgid "To keep this project going, create a new merge request"
-msgstr ""
+msgstr "Чтобы поддержать проект, Ñоздайте Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние"
msgid "To learn more about this project, read %{link_to_wiki}"
msgstr ""
@@ -36923,6 +37529,9 @@ 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 "Чтобы получать ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¾Ñ‚ наÑтроенных вручную Ñлужб Prometheus, добавьте Ñледующий URL и ключ авторизации в файл конфигурации веб-обработчика Prometheus. Узнайте подробнее о %{linkStart}наÑтройке Prometheus%{linkEnd} Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ уведомлений в GitLab."
+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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36989,6 +37598,39 @@ msgstr "Задача отмечена как выполненнаÑ."
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -37163,6 +37805,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -37287,15 +37932,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -37320,9 +37956,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr "СобытиÑ"
@@ -37950,9 +38583,6 @@ msgstr "кликните Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸"
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38227,7 +38857,7 @@ msgid "UsageTrends|Total projects & groups"
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 "ИÑпользуйте %{code_start}::%{code_end}, чтобы Ñоздать %{link_start}набор Ñелективных меток%{link_end} (например, %{code_start}priority::1%{code_end})"
@@ -38740,7 +39370,7 @@ msgid "ValueStreamAnalyticsStage|We don't have enough data to show this stage."
msgstr "У Ð½Ð°Ñ Ð½ÐµÐ´Ð¾Ñтаточно данных Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñтого Ñтапа."
msgid "ValueStreamAnalytics|%{stageCount}+ items"
-msgstr ""
+msgstr "%{stageCount}+ Ñлементов"
msgid "ValueStreamAnalytics|%{value}M"
msgstr ""
@@ -38797,7 +39427,7 @@ msgid "ValueStreamEvent|Items in stage"
msgstr ""
msgid "ValueStreamEvent|Stage time (median)"
-msgstr ""
+msgstr "Ð’Ñ€ÐµÐ¼Ñ Ñтапа (медиана)"
msgid "ValueStreamEvent|Start"
msgstr ""
@@ -38844,16 +39474,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38875,7 +39505,7 @@ msgid "Version %{versionNumber}"
msgstr ""
msgid "Version %{versionNumber} (latest)"
-msgstr ""
+msgstr "ВерÑÐ¸Ñ %{versionNumber} (поÑледнÑÑ)"
msgid "View Documentation"
msgstr ""
@@ -38895,6 +39525,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38920,6 +39553,9 @@ msgstr "Подробнее: %{details_url}"
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr "Увидеть подходÑщих утверждающих"
@@ -38951,6 +39587,12 @@ msgstr ""
msgid "View group labels"
msgstr "ПроÑмотр меток группы"
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr "Показать обÑуждениÑ-инциденты"
@@ -39045,6 +39687,9 @@ msgstr ""
msgid "Viewing commit"
msgstr "ПроÑмотр коммита"
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr "ВидимоÑÑ‚ÑŒ"
@@ -39126,12 +39771,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39159,6 +39816,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39228,9 +39888,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -39246,21 +39915,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr "ОпиÑание"
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -39270,6 +39951,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr "Образ"
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -39294,6 +39978,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -39417,6 +40110,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39504,6 +40200,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39540,6 +40242,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39597,6 +40308,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39633,6 +40353,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39642,9 +40365,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -39661,7 +40381,7 @@ msgid "What is repository mirroring?"
msgstr ""
msgid "What is squashing?"
-msgstr ""
+msgstr "Что такое Ñжатие?"
msgid "What is time tracking?"
msgstr ""
@@ -39679,7 +40399,7 @@ msgid "What would you like to do?"
msgstr ""
msgid "What's new"
-msgstr ""
+msgstr "Что нового?"
msgid "When a deployment job is successful, skip older deployment jobs that are still pending."
msgstr ""
@@ -40202,7 +40922,7 @@ msgid "You can create a new %{link}."
msgstr ""
msgid "You can create a new %{name} inside this project by sending an email to the following email address:"
-msgstr ""
+msgstr "Ð’Ñ‹ можете Ñоздать %{name} в Ñтом проекте, отправив пиÑьмо на Ñледующий Ð°Ð´Ñ€ÐµÑ Ñлектронной почты:"
msgid "You can create a new Personal Access Token by visiting %{link}"
msgstr ""
@@ -40250,7 +40970,7 @@ msgid "You can group test cases using labels. To learn about the future directio
msgstr ""
msgid "You can invite a new member to %{project_name} or invite another group."
-msgstr ""
+msgstr "Ð’Ñ‹ можете приглаÑить нового учаÑтника в %{project_name} или приглаÑить другую группу."
msgid "You can invite a new member to %{project_name}."
msgstr ""
@@ -40484,6 +41204,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40632,7 +41358,7 @@ msgid "You're at the last commit"
msgstr ""
msgid "You're not allowed to %{tag_start}edit%{tag_end} files in this project directly. Please fork this project, make your changes there, and submit a merge request."
-msgstr ""
+msgstr "Ð’Ñ‹ не можете %{tag_start}редактировать%{tag_end} файлы в Ñтом проекте напрÑмую. ПожалуйÑта, Ñделайте ответвление Ñтого проекта, внеÑите Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¸ отправьте Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние."
msgid "You're not allowed to make changes to this project directly. A fork of this project has been created that you can make changes in, so you can submit a merge request."
msgstr ""
@@ -40673,6 +41399,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40827,7 +41559,7 @@ msgid "Your dashboard has been updated. You can %{web_ide_link_start}edit it her
msgstr "Ваша панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð±Ñ‹Ð»Ð° обновлена. Ð’Ñ‹ можете %{web_ide_link_start}отредактировать её здеÑÑŒ%{web_ide_link_end}."
msgid "Your default notification email is used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set."
-msgstr ""
+msgstr "Ð”Ð»Ñ ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ð¹ будет иÑпользоватьÑÑ Ð²Ð°Ñˆ Ð°Ð´Ñ€ÐµÑ Ñлектронной почты по умолчанию, еÑли не задан %{openingTag}групповой адреÑ%{closingTag}."
msgid "Your deployment services will be broken, you will need to manually fix the services after renaming."
msgstr "Ваши Ñлужбы Ñ€Ð°Ð·Ð²Ñ‘Ñ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ ÑломаютÑÑ, и вам нужно будет вручную иÑправить Ñлужбы поÑле переименованиÑ."
@@ -40896,7 +41628,7 @@ msgid "Your new personal access token has been created."
msgstr "Ваш новый перÑональный токен доÑтупа был Ñоздан."
msgid "Your new project access token has been created."
-msgstr ""
+msgstr "Токен доÑтупа к проекту Ñоздан."
msgid "Your password isn't required to view this page. If a password or any other personal details are requested, please contact your administrator to report abuse."
msgstr "Ваш пароль не требуетÑÑ Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра Ñтой Ñтраницы. ЕÑли запрашиваетÑÑ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ или Ð»ÑŽÐ±Ð°Ñ Ð´Ñ€ÑƒÐ³Ð°Ñ Ð»Ð¸Ñ‡Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ, обратитеÑÑŒ к админиÑтратору, чтобы Ñообщить о нарушении."
@@ -40911,7 +41643,7 @@ msgid "Your personal access tokens will expire in %{days_to_expire} days or less
msgstr ""
msgid "Your primary email is used for avatar detection. You can change it in your %{openingTag}profile settings%{closingTag}."
-msgstr ""
+msgstr "Ваш оÑновной Ð°Ð´Ñ€ÐµÑ Ñлектронной почты иÑпользуетÑÑ Ð´Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð°Ð²Ð°Ñ‚Ð°Ñ€Ð°. Ð’Ñ‹ можете изменить его в %{openingTag}наÑтройках профилÑ%{closingTag}."
msgid "Your profile"
msgstr ""
@@ -40964,6 +41696,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -41210,6 +41945,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -41220,19 +41958,19 @@ msgid "ciReport|%{linkStartTag}Learn more about API Fuzzing%{linkEndTag}"
msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about Container Scanning %{linkEndTag}"
-msgstr ""
+msgstr "%{linkStartTag}Узнайте больше о Сканировании Контейнеров %{linkEndTag}"
msgid "ciReport|%{linkStartTag}Learn more about Coverage Fuzzing %{linkEndTag}"
msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about DAST %{linkEndTag}"
-msgstr ""
+msgstr "%{linkStartTag}Узнайте больше о DAST %{linkEndTag}"
msgid "ciReport|%{linkStartTag}Learn more about Dependency Scanning %{linkEndTag}"
-msgstr ""
+msgstr "%{linkStartTag}Подробнее о Сканировании ЗавиÑимоÑтей %{linkEndTag}"
msgid "ciReport|%{linkStartTag}Learn more about SAST %{linkEndTag}"
-msgstr ""
+msgstr "%{linkStartTag}Подробней о SAST%{linkEndTag}"
msgid "ciReport|%{linkStartTag}Learn more about Secret Detection %{linkEndTag}"
msgstr ""
@@ -41240,7 +41978,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -41288,8 +42026,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41385,8 +42123,8 @@ msgstr "РаÑÑледуйте Ñту уÑзвимоÑÑ‚ÑŒ, вынеÑÑ Ð½Ð° о
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41552,6 +42290,9 @@ msgstr "коммит %{commit_id}"
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41678,7 +42419,7 @@ msgid "entries cannot be nil"
msgstr ""
msgid "entries cannot contain HTML tags"
-msgstr ""
+msgstr "запиÑи не могут Ñодержать HTML-теги"
msgid "environment_id parameter is required when type is container_policy"
msgstr ""
@@ -41773,7 +42514,7 @@ msgid "group's CI/CD settings."
msgstr ""
msgid "groups"
-msgstr ""
+msgstr "группы"
msgid "has already been linked to another vulnerability"
msgstr ""
@@ -42008,9 +42749,6 @@ msgstr ""
msgid "missing"
msgstr "отÑутÑтвует"
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr "наиболее недавнее развёртывание"
@@ -42329,7 +43067,7 @@ msgid "mrWidget|This merge request failed to be merged automatically"
msgstr "Этот Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние не может быть выполнен автоматичеÑки"
msgid "mrWidget|To approve this merge request, please enter your password. This project requires all approvals to be authenticated."
-msgstr "Чтобы ÑоглаÑовать Ñтот запроÑ, пожалуйÑта, введите ваш пароль. Этот проект требует Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ€Ð¾Ð»ÐµÐ¼."
+msgstr "Чтобы ÑоглаÑовать Ñтот запроÑ, пожалуйÑта, введите ваш пароль. Этот проект требует Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ€Ð¾Ð»ÐµÐ¼."
msgid "mrWidget|To change these default messages, edit the templates for both the merge and squash commit messages. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
@@ -42370,6 +43108,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42469,9 +43210,6 @@ msgstr ""
msgid "or"
msgstr "или"
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
@@ -42829,7 +43567,7 @@ msgid "user namespace cannot be the parent of another namespace"
msgstr ""
msgid "user preferences"
-msgstr ""
+msgstr "наÑтройки пользователÑ"
msgid "username"
msgstr "Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ"
diff --git a/locale/si_LK/gitlab.po b/locale/si_LK/gitlab.po
index bbf9386fbd7..5f40265460b 100644
--- a/locale/si_LK/gitlab.po
+++ b/locale/si_LK/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: si-LK\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 19:00\n"
+"PO-Revision-Date: 2022-01-06 17:24\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/sk_SK/gitlab.po b/locale/sk_SK/gitlab.po
index c9b755cc49a..77bdd802774 100644
--- a/locale/sk_SK/gitlab.po
+++ b/locale/sk_SK/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sk\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:57\n"
+"PO-Revision-Date: 2022-01-06 17:21\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -717,7 +717,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -994,6 +994,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1211,6 +1214,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1329,6 +1338,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1400,6 +1412,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1776,6 +1791,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -2022,6 +2040,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -2034,12 +2061,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -2097,6 +2133,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -2121,6 +2187,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -2226,7 +2295,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2652,6 +2721,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2928,7 +3006,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -3213,6 +3291,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3603,6 +3684,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3807,6 +3891,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3834,9 +3921,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -4017,6 +4101,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -4026,6 +4113,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -4177,6 +4267,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4520,9 +4616,15 @@ msgstr[3] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4553,6 +4655,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4562,6 +4667,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4586,6 +4700,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4613,6 +4730,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4649,7 +4769,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4821,9 +4941,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4971,6 +5088,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5372,9 +5492,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5624,9 +5741,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5657,13 +5771,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr ""
-
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5675,7 +5786,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5687,9 +5801,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5877,7 +5997,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -6242,7 +6362,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -6251,6 +6374,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6290,6 +6416,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6996,7 +7125,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -7262,9 +7391,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7475,6 +7601,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7493,9 +7622,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7649,12 +7784,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7667,6 +7817,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7682,9 +7838,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7730,12 +7892,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7811,6 +7982,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7829,12 +8003,28 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7844,6 +8034,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -9033,6 +9226,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9458,6 +9660,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9549,6 +9754,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9780,12 +9988,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9816,9 +10030,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -10158,9 +10369,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -10191,6 +10399,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -10233,9 +10444,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -10245,13 +10453,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10431,15 +10642,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10449,15 +10678,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10608,15 +10846,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11307,6 +11536,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11586,6 +11818,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11619,15 +11854,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11766,6 +11995,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11790,7 +12022,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11799,6 +12031,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12617,15 +12852,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12768,6 +13003,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12903,7 +13141,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12942,6 +13180,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13885,6 +14126,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13930,9 +14174,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -14086,9 +14327,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -14173,6 +14411,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14360,9 +14601,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14555,7 +14793,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -15269,9 +15507,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15602,6 +15837,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16463,9 +16701,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16553,6 +16788,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16742,9 +16980,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16871,6 +17106,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16973,9 +17211,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -17048,6 +17295,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -17087,6 +17337,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -17120,6 +17373,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -17144,7 +17409,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -17153,7 +17418,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -17195,6 +17460,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -17222,12 +17490,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17342,6 +17616,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17396,6 +17673,9 @@ 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 ""
+
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 ""
@@ -19316,6 +19596,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19565,9 +19848,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19670,9 +19950,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19784,9 +20061,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20432,7 +20706,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20886,6 +21160,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21661,7 +21941,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22417,10 +22697,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22519,6 +22799,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -23142,6 +23425,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -23347,6 +23633,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23560,6 +23879,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23786,6 +24108,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -24207,6 +24532,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -24219,7 +24547,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24634,6 +24962,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24652,12 +24986,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24697,12 +25037,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24727,18 +25076,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24748,9 +25112,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24911,6 +25272,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25452,9 +25816,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25644,9 +26005,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25746,6 +26113,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25827,12 +26197,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -26064,6 +26428,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -26283,9 +26650,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26562,6 +26926,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26574,6 +26944,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26769,9 +27142,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -27123,6 +27493,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -27180,6 +27553,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -27264,6 +27643,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27558,6 +27940,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27684,6 +28108,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27936,19 +28363,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -28104,6 +28528,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28488,9 +28921,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28503,9 +28933,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28530,9 +28957,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28614,6 +29038,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28659,9 +29086,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28704,6 +29137,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28719,6 +29155,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28947,6 +29386,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -29134,9 +29579,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -29179,6 +29621,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29507,10 +29997,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -30206,6 +30696,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -30215,6 +30708,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30415,9 +30914,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30439,6 +30935,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30490,19 +30992,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30556,6 +31061,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30601,6 +31109,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30610,7 +31121,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30679,7 +31193,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30697,6 +31211,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30958,6 +31475,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30979,9 +31499,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -31284,6 +31801,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -31356,6 +31876,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31410,6 +31933,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31494,9 +32020,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31695,6 +32218,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31707,6 +32233,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31782,6 +32311,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31935,6 +32467,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -32286,6 +32821,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32442,6 +32983,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -33147,6 +33691,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33591,9 +34138,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33990,6 +34534,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34425,6 +34975,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34697,9 +35265,29 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34730,6 +35318,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34742,6 +35333,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34778,12 +35372,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -35075,6 +35678,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -35199,9 +35805,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -35211,9 +35814,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -35286,7 +35886,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35541,9 +36141,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35889,6 +36486,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35901,9 +36501,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35928,6 +36525,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -36042,6 +36642,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -36207,6 +36810,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36923,6 +37529,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36989,6 +37598,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -37163,6 +37805,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -37287,15 +37932,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -37320,9 +37956,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37950,9 +38583,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38844,16 +39474,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38895,6 +39525,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38920,6 +39553,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38951,6 +39587,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -39045,6 +39687,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -39126,12 +39771,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39159,6 +39816,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39228,9 +39888,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -39246,21 +39915,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -39270,6 +39951,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -39294,6 +39978,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -39417,6 +40110,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39504,6 +40200,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39540,6 +40242,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39597,6 +40308,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39633,6 +40353,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39642,9 +40365,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40484,6 +41204,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40673,6 +41399,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40964,6 +41696,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -41210,6 +41945,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -41240,7 +41978,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -41288,8 +42026,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41385,8 +42123,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41552,6 +42290,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42008,9 +42749,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -42370,6 +43108,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42469,9 +43210,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/sl_SI/gitlab.po b/locale/sl_SI/gitlab.po
index 84518212370..b8062074e34 100644
--- a/locale/sl_SI/gitlab.po
+++ b/locale/sl_SI/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sl\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:55\n"
+"PO-Revision-Date: 2022-01-06 17:19\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -717,7 +717,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -994,6 +994,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1211,6 +1214,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1329,6 +1338,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1400,6 +1412,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1776,6 +1791,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -2022,6 +2040,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -2034,12 +2061,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -2097,6 +2133,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -2121,6 +2187,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -2226,7 +2295,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2652,6 +2721,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2928,7 +3006,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -3213,6 +3291,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3603,6 +3684,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3807,6 +3891,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3834,9 +3921,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -4017,6 +4101,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -4026,6 +4113,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -4177,6 +4267,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4520,9 +4616,15 @@ msgstr[3] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4553,6 +4655,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4562,6 +4667,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4586,6 +4700,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4613,6 +4730,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4649,7 +4769,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4821,9 +4941,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4971,6 +5088,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5372,9 +5492,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5624,9 +5741,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5657,13 +5771,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr ""
-
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5675,7 +5786,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5687,9 +5801,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5877,7 +5997,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -6242,7 +6362,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -6251,6 +6374,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6290,6 +6416,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6996,7 +7125,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -7262,9 +7391,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7475,6 +7601,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7493,9 +7622,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7649,12 +7784,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7667,6 +7817,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7682,9 +7838,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7730,12 +7892,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7811,6 +7982,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7829,12 +8003,28 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7844,6 +8034,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -9033,6 +9226,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9458,6 +9660,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9549,6 +9754,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9780,12 +9988,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9816,9 +10030,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -10158,9 +10369,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -10191,6 +10399,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -10233,9 +10444,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -10245,13 +10453,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10431,15 +10642,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10449,15 +10678,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10608,15 +10846,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11307,6 +11536,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11586,6 +11818,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11619,15 +11854,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11766,6 +11995,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11790,7 +12022,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11799,6 +12031,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12617,15 +12852,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12768,6 +13003,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12903,7 +13141,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12942,6 +13180,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13885,6 +14126,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13930,9 +14174,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -14086,9 +14327,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -14173,6 +14411,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14360,9 +14601,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14555,7 +14793,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -15269,9 +15507,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15602,6 +15837,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16463,9 +16701,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16553,6 +16788,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16742,9 +16980,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16871,6 +17106,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16973,9 +17211,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -17048,6 +17295,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -17087,6 +17337,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -17120,6 +17373,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -17144,7 +17409,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -17153,7 +17418,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -17195,6 +17460,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -17222,12 +17490,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17342,6 +17616,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17396,6 +17673,9 @@ 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 ""
+
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 ""
@@ -19316,6 +19596,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19565,9 +19848,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19670,9 +19950,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19784,9 +20061,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20432,7 +20706,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20886,6 +21160,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21661,7 +21941,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22417,10 +22697,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22519,6 +22799,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -23142,6 +23425,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -23347,6 +23633,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23560,6 +23879,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23786,6 +24108,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -24207,6 +24532,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -24219,7 +24547,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24634,6 +24962,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24652,12 +24986,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24697,12 +25037,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24727,18 +25076,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24748,9 +25112,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24911,6 +25272,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25452,9 +25816,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25644,9 +26005,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25746,6 +26113,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25827,12 +26197,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -26064,6 +26428,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -26283,9 +26650,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26562,6 +26926,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26574,6 +26944,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26769,9 +27142,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -27123,6 +27493,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -27180,6 +27553,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -27264,6 +27643,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27558,6 +27940,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27684,6 +28108,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27936,19 +28363,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -28104,6 +28528,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28488,9 +28921,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28503,9 +28933,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28530,9 +28957,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28614,6 +29038,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28659,9 +29086,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28704,6 +29137,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28719,6 +29155,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28947,6 +29386,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -29134,9 +29579,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -29179,6 +29621,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29507,10 +29997,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -30206,6 +30696,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -30215,6 +30708,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30415,9 +30914,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30439,6 +30935,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30490,19 +30992,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30556,6 +31061,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30601,6 +31109,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30610,7 +31121,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30679,7 +31193,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30697,6 +31211,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30958,6 +31475,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30979,9 +31499,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -31284,6 +31801,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -31356,6 +31876,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31410,6 +31933,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31494,9 +32020,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31695,6 +32218,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31707,6 +32233,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31782,6 +32311,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31935,6 +32467,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -32286,6 +32821,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32442,6 +32983,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -33147,6 +33691,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33591,9 +34138,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33990,6 +34534,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34425,6 +34975,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34697,9 +35265,29 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34730,6 +35318,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34742,6 +35333,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34778,12 +35372,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -35075,6 +35678,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -35199,9 +35805,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -35211,9 +35814,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -35286,7 +35886,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35541,9 +36141,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35889,6 +36486,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35901,9 +36501,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35928,6 +36525,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -36042,6 +36642,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -36207,6 +36810,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36923,6 +37529,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36989,6 +37598,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -37163,6 +37805,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -37287,15 +37932,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -37320,9 +37956,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37950,9 +38583,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38844,16 +39474,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38895,6 +39525,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38920,6 +39553,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38951,6 +39587,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -39045,6 +39687,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -39126,12 +39771,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39159,6 +39816,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39228,9 +39888,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -39246,21 +39915,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -39270,6 +39951,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -39294,6 +39978,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -39417,6 +40110,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39504,6 +40200,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39540,6 +40242,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39597,6 +40308,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39633,6 +40353,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39642,9 +40365,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40484,6 +41204,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40673,6 +41399,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40964,6 +41696,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -41210,6 +41945,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -41240,7 +41978,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -41288,8 +42026,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41385,8 +42123,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41552,6 +42290,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42008,9 +42749,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -42370,6 +43108,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42469,9 +43210,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/sq_AL/gitlab.po b/locale/sq_AL/gitlab.po
index 7d014a31b58..570240d8699 100644
--- a/locale/sq_AL/gitlab.po
+++ b/locale/sq_AL/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sq\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:55\n"
+"PO-Revision-Date: 2022-01-06 17:19\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/sr_CS/gitlab.po b/locale/sr_CS/gitlab.po
index f00e16c3550..47a5d0f30ce 100644
--- a/locale/sr_CS/gitlab.po
+++ b/locale/sr_CS/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sr-CS\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:59\n"
+"PO-Revision-Date: 2022-01-06 17:24\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -640,7 +640,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -916,6 +916,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1123,6 +1126,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1240,6 +1249,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1309,6 +1321,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1660,6 +1675,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1906,6 +1924,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1918,12 +1945,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1981,6 +2017,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -2005,6 +2071,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -2110,7 +2179,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2536,6 +2605,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2812,7 +2890,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -3097,6 +3175,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3487,6 +3568,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3691,6 +3775,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3718,9 +3805,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3901,6 +3985,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3910,6 +3997,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -4060,6 +4150,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4396,9 +4492,15 @@ msgstr[2] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4429,6 +4531,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4438,6 +4543,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4462,6 +4576,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4489,6 +4606,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4525,7 +4645,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4696,9 +4816,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4846,6 +4963,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5245,9 +5365,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5497,9 +5614,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5530,13 +5644,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr ""
-
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5548,7 +5659,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5560,9 +5674,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5749,7 +5869,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -6112,7 +6232,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -6121,6 +6244,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6160,6 +6286,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6865,7 +6994,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -7129,9 +7258,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7342,6 +7468,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7360,9 +7489,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7516,12 +7651,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7534,6 +7684,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7549,9 +7705,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7597,12 +7759,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7678,6 +7849,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7696,12 +7870,27 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7711,6 +7900,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8899,6 +9091,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9322,6 +9523,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9412,6 +9616,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9643,12 +9850,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9679,9 +9892,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -10021,9 +10231,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -10054,6 +10261,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -10096,9 +10306,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -10108,13 +10315,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10294,15 +10504,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10312,15 +10540,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10471,15 +10708,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11167,6 +11395,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11446,6 +11677,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11479,15 +11713,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11623,6 +11851,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11647,7 +11878,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11656,6 +11887,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12466,15 +12700,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12616,6 +12850,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12751,7 +12988,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12790,6 +13027,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13732,6 +13972,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13777,9 +14020,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13933,9 +14173,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -14020,6 +14257,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14206,9 +14446,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14401,7 +14638,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -15112,9 +15349,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15445,6 +15679,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16306,9 +16543,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16396,6 +16630,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16585,9 +16822,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16714,6 +16948,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16816,9 +17053,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16891,6 +17137,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16930,6 +17179,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16963,6 +17215,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16987,7 +17251,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16996,7 +17260,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -17038,6 +17302,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -17065,12 +17332,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17185,6 +17458,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17239,6 +17515,9 @@ 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 ""
+
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 ""
@@ -19153,6 +19432,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19402,9 +19684,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19507,9 +19786,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19621,9 +19897,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20269,7 +20542,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20722,6 +20995,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21490,7 +21769,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22246,10 +22525,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22348,6 +22627,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22969,6 +23251,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -23173,6 +23458,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23386,6 +23704,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23611,6 +23932,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -24031,6 +24355,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -24043,7 +24370,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24454,6 +24781,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24472,12 +24805,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24517,12 +24856,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24547,18 +24895,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24568,9 +24931,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24730,6 +25090,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25270,9 +25633,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25462,9 +25822,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25564,6 +25930,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25645,12 +26014,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25882,6 +26245,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -26101,9 +26467,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26380,6 +26743,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26392,6 +26761,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26587,9 +26959,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26941,6 +27310,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26998,6 +27370,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -27082,6 +27460,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27376,6 +27757,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27502,6 +27925,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27754,19 +28180,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27922,6 +28345,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28306,9 +28738,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28321,9 +28750,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28348,9 +28774,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28432,6 +28855,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28477,9 +28903,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28522,6 +28954,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28537,6 +28972,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28765,6 +29203,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28951,9 +29395,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28996,6 +29437,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29323,10 +29812,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -30016,6 +30505,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -30025,6 +30517,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30223,9 +30721,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30247,6 +30742,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30298,19 +30799,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30364,6 +30868,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30409,6 +30916,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30418,7 +30928,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30487,7 +31000,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30505,6 +31018,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30766,6 +31282,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30787,9 +31306,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -31081,6 +31597,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -31153,6 +31672,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31207,6 +31729,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31291,9 +31816,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31492,6 +32014,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31504,6 +32029,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31579,6 +32107,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31732,6 +32263,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -32083,6 +32617,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32239,6 +32779,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32941,6 +33484,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33385,9 +33931,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33784,6 +34327,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34219,6 +34768,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34489,9 +35056,27 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34522,6 +35107,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34534,6 +35122,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34570,12 +35161,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34864,6 +35464,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34987,9 +35590,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34999,9 +35599,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -35074,7 +35671,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35329,9 +35926,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35677,6 +36271,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35689,9 +36286,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35716,6 +36310,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35830,6 +36427,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35995,6 +36595,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36709,6 +37312,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36775,6 +37381,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36949,6 +37588,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -37072,15 +37714,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -37105,9 +37738,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37735,9 +38365,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38629,16 +39256,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38680,6 +39307,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38704,6 +39334,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38734,6 +39367,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38827,6 +39466,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38908,12 +39550,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38941,6 +39595,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39010,9 +39667,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -39028,21 +39694,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -39052,6 +39730,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -39076,6 +39757,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -39199,6 +39889,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39286,6 +39979,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39322,6 +40021,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39379,6 +40087,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39415,6 +40132,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39424,9 +40144,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40264,6 +40981,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40453,6 +41176,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40744,6 +41473,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40987,6 +41719,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -41017,7 +41752,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -41065,8 +41800,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41161,8 +41896,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41326,6 +42061,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41776,9 +42514,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -42136,6 +42871,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42235,9 +42973,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/sr_SP/gitlab.po b/locale/sr_SP/gitlab.po
index 60ab8b71748..bdcfd213a9a 100644
--- a/locale/sr_SP/gitlab.po
+++ b/locale/sr_SP/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sr\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:55\n"
+"PO-Revision-Date: 2022-01-06 17:19\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -640,7 +640,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -916,6 +916,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1123,6 +1126,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1240,6 +1249,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1309,6 +1321,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1660,6 +1675,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1906,6 +1924,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1918,12 +1945,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1981,6 +2017,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -2005,6 +2071,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -2110,7 +2179,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2536,6 +2605,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2812,7 +2890,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -3097,6 +3175,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3487,6 +3568,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3691,6 +3775,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3718,9 +3805,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3901,6 +3985,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3910,6 +3997,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -4060,6 +4150,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4396,9 +4492,15 @@ msgstr[2] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4429,6 +4531,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4438,6 +4543,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4462,6 +4576,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4489,6 +4606,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4525,7 +4645,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4696,9 +4816,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4846,6 +4963,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5245,9 +5365,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5497,9 +5614,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5530,13 +5644,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr ""
-
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5548,7 +5659,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5560,9 +5674,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5749,7 +5869,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -6112,7 +6232,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -6121,6 +6244,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6160,6 +6286,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6865,7 +6994,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -7129,9 +7258,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7342,6 +7468,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7360,9 +7489,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7516,12 +7651,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7534,6 +7684,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7549,9 +7705,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7597,12 +7759,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7678,6 +7849,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7696,12 +7870,27 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7711,6 +7900,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8899,6 +9091,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9322,6 +9523,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9412,6 +9616,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9643,12 +9850,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9679,9 +9892,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -10021,9 +10231,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -10054,6 +10261,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -10096,9 +10306,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -10108,13 +10315,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10294,15 +10504,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10312,15 +10540,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10471,15 +10708,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11167,6 +11395,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11446,6 +11677,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11479,15 +11713,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11623,6 +11851,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11647,7 +11878,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11656,6 +11887,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12466,15 +12700,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12616,6 +12850,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12751,7 +12988,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12790,6 +13027,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13732,6 +13972,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13777,9 +14020,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13933,9 +14173,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -14020,6 +14257,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14206,9 +14446,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14401,7 +14638,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -15112,9 +15349,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15445,6 +15679,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16306,9 +16543,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16396,6 +16630,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16585,9 +16822,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16714,6 +16948,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16816,9 +17053,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16891,6 +17137,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16930,6 +17179,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16963,6 +17215,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16987,7 +17251,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16996,7 +17260,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -17038,6 +17302,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -17065,12 +17332,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17185,6 +17458,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17239,6 +17515,9 @@ 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 ""
+
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 ""
@@ -19153,6 +19432,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19402,9 +19684,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19507,9 +19786,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19621,9 +19897,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20269,7 +20542,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20722,6 +20995,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21490,7 +21769,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22246,10 +22525,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22348,6 +22627,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22969,6 +23251,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -23173,6 +23458,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23386,6 +23704,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23611,6 +23932,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -24031,6 +24355,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -24043,7 +24370,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24454,6 +24781,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24472,12 +24805,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24517,12 +24856,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24547,18 +24895,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24568,9 +24931,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24730,6 +25090,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25270,9 +25633,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25462,9 +25822,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25564,6 +25930,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25645,12 +26014,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25882,6 +26245,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -26101,9 +26467,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26380,6 +26743,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26392,6 +26761,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26587,9 +26959,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26941,6 +27310,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26998,6 +27370,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -27082,6 +27460,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27376,6 +27757,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27502,6 +27925,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27754,19 +28180,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27922,6 +28345,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28306,9 +28738,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28321,9 +28750,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28348,9 +28774,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28432,6 +28855,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28477,9 +28903,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28522,6 +28954,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28537,6 +28972,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28765,6 +29203,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28951,9 +29395,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28996,6 +29437,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29323,10 +29812,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -30016,6 +30505,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -30025,6 +30517,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30223,9 +30721,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30247,6 +30742,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30298,19 +30799,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30364,6 +30868,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30409,6 +30916,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30418,7 +30928,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30487,7 +31000,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30505,6 +31018,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30766,6 +31282,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30787,9 +31306,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -31081,6 +31597,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -31153,6 +31672,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31207,6 +31729,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31291,9 +31816,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31492,6 +32014,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31504,6 +32029,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31579,6 +32107,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31732,6 +32263,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -32083,6 +32617,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32239,6 +32779,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32941,6 +33484,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33385,9 +33931,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33784,6 +34327,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34219,6 +34768,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34489,9 +35056,27 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34522,6 +35107,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34534,6 +35122,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34570,12 +35161,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34864,6 +35464,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34987,9 +35590,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34999,9 +35599,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -35074,7 +35671,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35329,9 +35926,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35677,6 +36271,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35689,9 +36286,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35716,6 +36310,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35830,6 +36427,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35995,6 +36595,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36709,6 +37312,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36775,6 +37381,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36949,6 +37588,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -37072,15 +37714,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -37105,9 +37738,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37735,9 +38365,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38629,16 +39256,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38680,6 +39307,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38704,6 +39334,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38734,6 +39367,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38827,6 +39466,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38908,12 +39550,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38941,6 +39595,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39010,9 +39667,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -39028,21 +39694,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -39052,6 +39730,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -39076,6 +39757,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -39199,6 +39889,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39286,6 +39979,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39322,6 +40021,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39379,6 +40087,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39415,6 +40132,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39424,9 +40144,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40264,6 +40981,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40453,6 +41176,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40744,6 +41473,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40987,6 +41719,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -41017,7 +41752,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -41065,8 +41800,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41161,8 +41896,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41326,6 +42061,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41776,9 +42514,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -42136,6 +42871,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42235,9 +42973,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/sv_SE/gitlab.po b/locale/sv_SE/gitlab.po
index b6c64aee221..675ffd8220c 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: 2021-12-06 18:55\n"
+"PO-Revision-Date: 2022-01-06 17:19\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr "%{placeholder} är inte ett giltigt färgschema"
msgid "%{placeholder} is not a valid theme"
msgstr "%{placeholder} är ett ogiltigt tema"
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
@@ -1035,6 +1038,12 @@ msgstr "%{userName}s avatar"
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr "(max storlek 15 MB)"
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr "(borttagen)"
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr "Lägg till en tabell"
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr "Avatar för %{assigneeName}"
-msgid "Avatar for %{name}"
-msgstr "Avatar för %{name}"
-
msgid "Avatar will be removed. Are you sure?"
msgstr "Avataren kommer att tas bort! Är du säker?"
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr ""
-
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/sw_KE/gitlab.po b/locale/sw_KE/gitlab.po
index 99df1ffb531..17807b99862 100644
--- a/locale/sw_KE/gitlab.po
+++ b/locale/sw_KE/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sw\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:59\n"
+"PO-Revision-Date: 2022-01-06 17:24\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/ta_IN/gitlab.po b/locale/ta_IN/gitlab.po
index d6d77fd0152..610216894c5 100644
--- a/locale/ta_IN/gitlab.po
+++ b/locale/ta_IN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ta\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:56\n"
+"PO-Revision-Date: 2022-01-06 17:20\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/tr_TR/gitlab.po b/locale/tr_TR/gitlab.po
index e87132e2a30..172d63943bd 100644
--- a/locale/tr_TR/gitlab.po
+++ b/locale/tr_TR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: tr\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:55\n"
+"PO-Revision-Date: 2022-01-06 17:19\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr "%{placeholder} geçerli bir renk düzeni değil"
msgid "%{placeholder} is not a valid theme"
msgstr "%{placeholder} geçerli bir tema değil"
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
@@ -1035,6 +1038,12 @@ msgstr "%{userName} kullanıcısının profil resmi"
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr "%{user_name} profil sayfası"
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr "(en yüksek boyut 15 MB)"
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr "(silindi)"
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ", veya "
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr "Emin misiniz? Åžu anda kullanımda olan RSS veya takvim URL'leri çalıÅ
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr "OluÅŸturulan"
@@ -1802,12 +1829,21 @@ msgstr "Gelen e-posta erişim anahtarı"
msgid "AccessTokens|It cannot be used to access any other data."
msgstr "Başka hiçbir veriye erişmek için kullanılamaz."
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr "Hesap:"
msgid "Account: %{account}"
msgstr "Hesap: %{account}"
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr "Etkin Oturumlar"
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr "Tablo ekle"
msgid "Add a task list"
msgstr "Görev listesi ekle"
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "İstatistikler yüklenirken hata oluştu. Lütfen tekrar deneyin"
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr "Kullanıcıyı sil"
msgid "AdminUsers|Delete user and contributions"
msgstr "Kullanıcıyı ve katkılarını sil"
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr "Tüm epikler"
msgid "All groups and projects"
msgstr "Tüm gruplar ve projeler"
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr "Bu dönüm noktası için tüm sorunlar kapatıldı."
@@ -3575,6 +3659,9 @@ msgstr "Bir hata oluÅŸtu"
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr "Konuya taslak eklenirken bir hata oluÅŸtu."
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr "Blob datanın öngösteriminde, bir hata meydana geldi"
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr "Birleştirme istekleri yüklenirken bir hata oluştu."
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr "Veriler yüklenirken bir hata oluştu. Lütfen tekrar deneyin."
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] "%{membersCount} tarafından %{count} onay gerekli"
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr "Onaylayanlar"
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr "Ä°sim"
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr "Hedef dal"
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr "Bu ortamı yeniden dağıtmak istediğinizden emin misiniz?"
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr "Genel anahtarı yeniden oluşturmak istediğinizden emin misiniz? Yansıtma işleminin tekrar çalışması için önce uzak sunucudaki ortak anahtarı güncellemeniz gerekecektir."
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr "Bu dönüm noktasına bazı sorunları atayın."
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr "%{assigneeName} için profil resmi"
-msgid "Avatar for %{name}"
-msgstr "%{name} için profil resmi"
-
msgid "Avatar will be removed. Are you sure?"
msgstr "Profil resmi kaldırılacak. Emin misiniz?"
@@ -5370,9 +5487,6 @@ msgstr "aylık"
msgid "BillingPlans|per user"
msgstr "kullanıcı başına"
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr "Yükselt"
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr ""
-
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr "Panolar"
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
msgid "BulkImport|Filter by source group"
msgstr "Kaynak gruba göre filtrele"
+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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr "Kullanıcı adının geçerliliği denetleniyor..."
msgid "Checkout"
msgstr "Ödeme"
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr "Herhangi bir renk seçin."
msgid "Choose file…"
msgstr "Dosya seçin…"
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr "BitiÅŸ tarihini temizle"
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr "Son aramaları temizle"
@@ -7227,9 +7356,15 @@ msgstr "Şablonları arama girişini temizle"
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr "Dosya içeriğini kopyala"
msgid "Copy file path"
msgstr "Dosya yolunu kopyala"
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr "Anahtarı kopyala"
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr "Yeni etiket oluÅŸtur"
msgid "Create new project"
msgstr "Yeni proje oluÅŸtur"
-msgid "Create new..."
-msgstr "Yeni oluÅŸtur..."
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr "Bu sayfayı özelleştirmek istiyor musunuz?"
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr "Tercihlere git"
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr "Bu sayfada varsayılan olarak projelerinizin listesi gösterilir. Ancak burası, projelerin etkinliklerini, grupları, yapılacaklar listenizi, atanmış sorunları, atanmış birleştirme isteklerini ve daha fazlasını gösterecek şekilde değiştirilebilir. Bunu tercihlerinizdeki \"Ana sayfa içeriği\" bölümünden değiştirebilirsiniz"
-
msgid "Cycle Time"
msgstr "Döngü Süresi"
@@ -11027,6 +11254,9 @@ msgstr "Veri kaynağı adı bulunamadı"
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr "Tarih seçici"
@@ -11306,6 +11536,9 @@ msgstr "Kullanıcı listesini sil"
msgid "Delete variable"
msgstr "DeÄŸiÅŸkeni sil"
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr "Silindi"
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr "Silinen sohbet takma adı: %{chat_name}!"
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr "Zaten üretimde canlı olan kod için, gösterge panomuz size bulunan so
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr "Bu sayfa için geri bildirim bırakın"
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr "Geliştirme sürecinize entegre güvenlik özellikleri"
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr "Ücretsiz deneme sürümü başlatın"
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr "CSV olarak indir"
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr "Şifreyi Düzenle"
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr "Açıklamayı düzenle"
msgid "Edit environment"
msgstr "Ortamı düzenle"
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr "Öge sıralanırken bir şeyler ters gitti."
msgid "Epics|Something went wrong while removing issue from epic."
msgstr "Epikten sorun kaldırılırken bir şeyler ters gitti."
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr "Birleştirme isteğini yüklerken hata oluştu. Lütfen tekrar deneyin."
-msgid "Error while loading the project data. Please try again."
-msgstr "Proje verileri yüklenirken hata oluştu. Lütfen tekrar deneyin."
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr "Projeyi dışa aktar"
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr "İki adımlı kimlik doğrulamasına göre süz"
-
msgid "Filter by user"
msgstr "Kullanıcıya göre filtrele"
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr "Tam isim"
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr "Metriklere git"
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr "Grup başarıyla güncellendi."
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr "Rozetler"
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr "Pano"
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr "Ä°ndir"
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr "Yardım"
@@ -23212,6 +23529,9 @@ msgstr "Yeni"
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr "Yeni Uygulama"
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr "Bu yorumu oluşturmayı iptal etmek istediğinizden emin misiniz?"
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr "Dışa aktarılan dosya hazır olduğunda, indirme bağlantısına sahip bir bildirim e-postası alacaksınız veya bu sayfadan indirebilirsiniz."
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr "Ä°ÅŸlemler Panosu"
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr "İş hattı dakika kotası"
-
-msgid "Pipeline minutes quota:"
-msgstr "İş hattı dakika kotası:"
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr "Lütfen bir ülke seçin"
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr "Zaman tercihleri"
msgid "Preferences|Use relative times"
msgstr "Göreceli zamanları kullan"
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr "Önceki"
@@ -26759,6 +27127,9 @@ msgstr "Geçersiz şifre"
msgid "Profiles|Invalid username"
msgstr "Geçersiz kullanıcı adı"
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr "Anahtar"
@@ -26816,6 +27187,12 @@ msgstr "Özel katkılar"
msgid "Profiles|Profile was successfully updated"
msgstr "Profil başarıyla güncellendi"
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr "Genel profil resmi"
@@ -26900,6 +27277,9 @@ msgstr "Kullanıcı adı başarıyla değiştirildi"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr "İsimlerdeki ifadeleri kullanmak eğlenceli görünüyor. Ancak bunun yerine durum mesajı ayarlamayı deneyin"
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr "Durumunuz nedir?"
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr "Proje KimliÄŸi: %{project_id}"
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr " veya grup"
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr "Projeler"
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr "%{environment_name} geliştiriciler için yazılabilir olacak. Emin misiniz?"
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr "BENÄ°OKU"
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr "Çalışıyor"
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr "Çatalları ara"
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr "Ara veya sonuçları filtrele..."
msgid "Search or filter results…"
msgstr "Sonuçları ara ya da filtrele…"
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr "Proje ara"
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr "Makine tipini seçmek için proje ve bölge seçin"
msgid "Select project to choose zone"
msgstr "Bölge seçmek için proje seçin"
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr "Varsayılanı ayarlayın ve görünürlük seviyelerini sınırlayın. Ä
msgid "Set due date"
msgstr "Bitiş tarihi ayarlayın"
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr "%{epic_ref} epiğini üst epik olarak ayarlar."
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr "Ücretsiz denemenizi başlatın"
-msgid "Start your trial"
-msgstr "Denemenizi başlatın"
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr "Abonelik başarıyla oluşturuldu."
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr "Sistem"
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr "%{user} %{timeAgo} güncelledi"
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr "Gösterilecek bir sorun yok"
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr "Henüz etiket yok"
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ 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 has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
msgstr "Bu grup"
+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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr "Görev için manuel işlem gerekiyor"
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr "Yapılacaklar öğesi başarıyla bitti olarak işaretlendi."
msgid "Today"
msgstr "Bugün"
+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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr "SahipliÄŸi aktar"
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr "yüklemek için tıklayın"
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr "DoÄŸrulama durumu"
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr "Grup etiketlerini görüntüle"
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr "%{user} tarafından %{timeago} %{statusStart}reddedildi%{statusEnd}"
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr "%{user} tarafından %{timeago} %{statusStart}çözümlendi%{statusEnd}"
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr "Açıklama"
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr "Dosya"
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr "Ä°zinleriniz yok"
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr "%{host} hesabınıza yeni bir konumdan giriş yapıldı"
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
msgstr "AboneliÄŸiniz sona erdi!"
+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 ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr "birleÅŸtirilemez"
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr "eksik"
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr "en son dağıtım"
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr "%{timeAgo} açıldı"
msgid "or"
msgstr "veya"
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/uk/gitlab.po b/locale/uk/gitlab.po
index 76a89125371..2a89f199ae8 100644
--- a/locale/uk/gitlab.po
+++ b/locale/uk/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: uk\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:56\n"
+"PO-Revision-Date: 2022-01-06 17:20\n"
msgid " %{start} to %{end}"
msgstr " %{start} до %{end}"
@@ -302,10 +302,10 @@ msgstr[3] "%d виправлених результатів теÑту"
msgid "%d fork"
msgid_plural "%d forks"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%d форк"
+msgstr[1] "%d форки"
+msgstr[2] "%d форків"
+msgstr[3] "%d форків"
msgid "%d group"
msgid_plural "%d groups"
@@ -379,10 +379,10 @@ msgstr[3] "%d запитів на злиттÑ, до Ñких ви не маєт
msgid "%d merge requests"
msgid_plural "%d merge requests"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%d запит на злиттÑ"
+msgstr[1] "%d запита на злиттÑ"
+msgstr[2] "%d запитів на злиттÑ"
+msgstr[3] "%d запитів на злиттÑ"
msgid "%d metric"
msgid_plural "%d metrics"
@@ -556,7 +556,7 @@ msgid "%{actionText} & %{openOrClose} %{noteable}"
msgstr "%{actionText} Ñ– %{openOrClose} %{noteable}"
msgid "%{actionText} & close %{noteable}"
-msgstr ""
+msgstr "%{actionText} та закрити %{noteable}"
msgid "%{actionText} & reopen %{noteable}"
msgstr ""
@@ -610,7 +610,7 @@ msgid "%{code_open}Protected:%{code_close} Only exposed to protected branches or
msgstr "%{code_open}Захищений:%{code_close} Відкритий лише захищеними гілками або тегами."
msgid "%{commit_author_link} authored %{commit_authored_timeago}"
-msgstr "%{commit_author_link} автор%{commit_authored_timeago}"
+msgstr "%{commit_author_link} автор %{commit_authored_timeago}"
msgid "%{commit_author_link} authored %{commit_authored_timeago} and %{commit_committer_avatar} %{commit_committer_link} committed %{commit_committer_timeago}"
msgstr "%{commit_author_link} автор %{commit_authored_timeago} та %{commit_committer_avatar} %{commit_committer_link} коміт %{commit_committer_timeago}"
@@ -717,8 +717,8 @@ msgstr "%{deployLinkStart}ВикориÑтовуйте шаблон Ð´Ð»Ñ Ñ€Ð¾Ð
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
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; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
-msgstr "%{doc_link_start}Розширений пошук%{doc_link_end} вимкнено, оÑкільки %{ref_elem} не Ñ” гілкою за замовчуваннÑм; %{default_branch_link_start}пошук на %{default_branch} заміÑÑ‚ÑŒ%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
+msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
msgstr "%{doc_link_start}Розширений пошук%{doc_link_end} увімкнено."
@@ -994,6 +994,9 @@ msgstr "%{placeholder} не Ñ” дійÑною кольоровою Ñхемою"
msgid "%{placeholder} is not a valid theme"
msgstr "%{placeholder} не є коректною темою"
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
@@ -1035,7 +1038,7 @@ msgid "%{scope} results for term '%{term}'"
msgstr "%{scope} результати Ð´Ð»Ñ Ñ‚ÐµÑ€Ð¼Ñ–Ð½Ñƒ \"%{term}\""
msgid "%{search} %{description} %{scope}"
-msgstr ""
+msgstr "%{search} %{description} %{scope}"
msgid "%{seconds}s"
msgstr "%{seconds}Ñ"
@@ -1211,6 +1214,12 @@ msgstr "%{userName} аватар"
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr "%{user_name} (%{user_username}) було видалено з %{rotation} в %{schedule} в %{project}. "
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr "%{user_name} Ñторінка профілю"
@@ -1329,6 +1338,9 @@ msgstr "(залишіть порожнім, Ñкщо ви не хочете зм
msgid "(max size 15 MB)"
msgstr "(макÑимальний розмір 15 Мб)"
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr "(видалено)"
@@ -1352,7 +1364,7 @@ msgid "* All times are in UTC unless specified"
msgstr "* УÑÑ– чаÑи викориÑтовуютьÑÑ Ð² UTC, Ñкщо не вказано"
msgid "*Required"
-msgstr ""
+msgstr "*Обов'Ñзково"
msgid "+ %{amount} more"
msgstr "+ %{amount} більше"
@@ -1395,11 +1407,14 @@ msgid "+%{tags} more"
msgstr "+%{tags} більше"
msgid ", and "
-msgstr ""
+msgstr ", Ñ– "
msgid ", or "
msgstr ", або "
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr "- ДоÑтупний Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑку завдань."
@@ -1776,6 +1791,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr "Ім'Ñ Ñховища проєкту визначає його URL-адреÑу (ту, Ñку ви викориÑтовуєте Ð´Ð»Ñ Ð´Ð¾Ñтупу до проєкту через браузер) та його міÑце на файловому диÑку, де вÑтановлено GitLab. %{link_start}ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ.%{link_end}"
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr "Готовий шаблон Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð· Android заÑтоÑунками"
@@ -2022,6 +2040,15 @@ msgstr "Ви впевнені? Будь-Ñкі поточні RSS або URL-аÐ
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr "Ви впевнені? Будь-Ñкі поточні адреÑи електронної пошти Ð´Ð»Ñ Ð·Ð°Ð´Ð°Ñ‡ переÑтануть працювати."
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr "Створено"
@@ -2034,12 +2061,21 @@ msgstr "Токен Ð´Ð»Ñ Ð²Ñ…Ñ–Ð´Ð½Ð¸Ñ… повідомлень електрон
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr "Зберігайте цей токен в Ñекреті. Будь-хто, хто отримає до нього доÑтуп зможе читати RSS-канал активноÑÑ‚Ñ– та задач, а також канал вашого ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñ Ð²Ñ–Ð´ вашого імені. Ви повинні %{link_reset_it} Ñкщо це трапитьÑÑ."
@@ -2097,6 +2133,36 @@ msgstr "Обліковий запиÑ:"
msgid "Account: %{account}"
msgstr "Обліковий запиÑ: %{account}"
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr "ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ."
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr "ДіÑ"
@@ -2121,6 +2187,9 @@ msgstr "Ðктивні %{type} (%{token_length})"
msgid "Active Sessions"
msgstr "Ðктивні ÑеÑÑ–Ñ—"
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "ÐктивніÑÑ‚ÑŒ"
@@ -2226,7 +2295,7 @@ msgstr "Додати таблицю"
msgid "Add a task list"
msgstr "Додати ÑпиÑок завдань"
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2389,7 +2458,7 @@ msgid "Add variable"
msgstr "Додати змінну"
msgid "Add vulnerability finding"
-msgstr ""
+msgstr "Додати пошук вразливоÑтей"
msgid "Add webhook"
msgstr "Додати вебхук"
@@ -2479,7 +2548,7 @@ msgid "Adds %{labels} %{label_text}."
msgstr "Додає %{labels} %{label_text}."
msgid "Adds a Zoom meeting."
-msgstr ""
+msgstr "Додає Zoom-зуÑтріч."
msgid "Adds a to do."
msgstr "Додати нагадуваннÑ."
@@ -2488,7 +2557,7 @@ msgid "Adds an issue to an epic."
msgstr "Додає задачу до епіку."
msgid "Adds email participant(s)."
-msgstr ""
+msgstr "Додає учаÑника(ів)."
msgid "Adjust how frequently the GitLab UI polls for updates."
msgstr ""
@@ -2584,7 +2653,7 @@ msgid "AdminArea|Maintainer"
msgstr "Керівник"
msgid "AdminArea|Minimal access"
-msgstr ""
+msgstr "Мінімальний доÑтуп"
msgid "AdminArea|New group"
msgstr "Ðова група"
@@ -2652,6 +2721,15 @@ msgstr "Ви збираєтеÑÑ Ð·ÑƒÐ¿Ð¸Ð½Ð¸Ñ‚Ð¸ вÑÑ– завданнÑ. Ви
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "Помилка при завантаженні ÑтатиÑтики. Будь лаÑка, Ñпробуйте знову"
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2928,7 +3006,7 @@ msgstr "Видалити кориÑтувача"
msgid "AdminUsers|Delete user and contributions"
msgstr "Видалити кориÑтувача Ñ– його внеÑки"
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -3022,7 +3100,7 @@ msgid "AdminUsers|The user can't access git repositories."
msgstr ""
msgid "AdminUsers|The user can't log in."
-msgstr ""
+msgstr "КориÑтувач не може увійти."
msgid "AdminUsers|The user will be logged out"
msgstr "КориÑтувач вийде із ÑиÑтеми"
@@ -3172,7 +3250,7 @@ msgid "Admin|The number of max users in your instance exceeds the number of user
msgstr ""
msgid "Admin|View pending user approvals"
-msgstr ""
+msgstr "ПереглÑнути очікуючі Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувача"
msgid "Admin|Your instance has reached its user cap"
msgstr "Ваш інÑÑ‚Ð°Ð½Ñ Ð´Ð¾ÑÑг макÑимальної кількоÑÑ‚Ñ– кориÑтувачів"
@@ -3213,6 +3291,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3394,7 +3475,7 @@ msgid "AlertSettings|Add new integration"
msgstr "Додати нову інтеграцію"
msgid "AlertSettings|Alert settings"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½ÑŒ"
+msgstr "Ðалаштувати попередженнÑ"
msgid "AlertSettings|Authorization key"
msgstr "Ключ авторизації"
@@ -3603,6 +3684,9 @@ msgstr "Ð’ÑÑ– епіки"
msgid "All groups and projects"
msgstr "Ð’ÑÑ– групи та проєкти"
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr "Ð’ÑÑ– задачі в цьому етапі закриті."
@@ -3807,6 +3891,9 @@ msgstr "ТрапилаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°"
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr "Помилка у звіті, в Ñкому результат теÑту вказує на наÑвніÑÑ‚ÑŒ вразливоÑÑ‚Ñ– в ÑиÑтемі, коли не приÑутні вразливоÑÑ‚Ñ–."
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr "Помилка при додаванні чернетки до обговореннÑ."
@@ -3834,9 +3921,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð½ÑŒÐ¾Ð³Ð¾ переглÑду об'єкта"
-msgid "An error occurred when removing the label."
-msgstr "Виникла помилка при видаленні мітки."
-
msgid "An error occurred when updating the title"
msgstr "ВідбулаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ°"
@@ -4017,6 +4101,9 @@ msgstr "Помилка при завантаженні результатів з
msgid "An error occurred while loading projects."
msgstr "Під Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñ–Ð² ÑталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°."
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -4026,6 +4113,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr "Виникла помилка під Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ð¾Ñ€Ð¼Ð¸ токенів доÑтупу. Повторіть Ñпробу."
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr "Під Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… ÑталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°. Будь лаÑка, Ñпробуйте ще раз."
@@ -4177,6 +4267,12 @@ msgstr "Приклад проєкту, Ñкий показує найкращиÐ
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 ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4335,7 +4431,7 @@ msgstr[2] ""
msgstr[3] ""
msgid "ApplicationSettings|Approve users"
-msgstr ""
+msgstr "Схвалити кориÑтувачів"
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr "Затвердити кориÑтувачів у ÑтатуÑÑ– очікуваного затвердженнÑ?"
@@ -4520,9 +4616,15 @@ msgstr[3] "Потрібно %{count} затверджень від %{membersCoun
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr "%{firstLabel} + ще %{numberOfAdditionalLabels}"
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr "Додати затверджувачів"
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr "Ð’ÑÑ– Ñканери"
@@ -4553,6 +4655,9 @@ msgstr "Тип оÑоби, що затверджує"
msgid "ApprovalRule|Approvers"
msgstr "Затверджуючі оÑоби"
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr "Підтверджено"
@@ -4562,6 +4667,15 @@ msgstr "Відхилено"
msgid "ApprovalRule|Examples: QA, Security."
msgstr "Приклади: QA, Security."
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr "Ім'Ñ"
@@ -4586,6 +4700,9 @@ msgstr "Будь лаÑка, оберіть принаймні один Ñтан
msgid "ApprovalRule|Previously detected"
msgstr "Раніше виÑвлений"
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr "Вирішений"
@@ -4613,6 +4730,9 @@ msgstr "Рівні ÑерйозноÑÑ‚Ñ–"
msgid "ApprovalRule|Target branch"
msgstr "Цільова гілка"
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr "Дозволені вразливоÑÑ‚Ñ–"
@@ -4649,8 +4769,8 @@ msgstr "Під Ñ‡Ð°Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½ÑŒ Ñхваленн
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr "Цей параметр налаштований на рівні інÑтанÑу Ñ– може бути змінений тільки адмініÑтратором."
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
-msgstr "Цей параметр налаштований у %{groupName} Ñ– може бути змінений тільки адмініÑтратором або влаÑником групи."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
+msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
msgstr "ДотримуєтьÑÑ Ñ€Ð¾Ð·Ð¿Ð¾Ð´Ñ–Ð»Ñƒ обов'Ñзків"
@@ -4773,7 +4893,7 @@ msgid "Are you sure you want to delete this SSH key?"
msgstr "Ви впевнені, що хочете видалити цей SSH-ключ?"
msgid "Are you sure you want to delete this deploy key?"
-msgstr ""
+msgstr "Ви впевнені, що хочете видалити цей ключ розгортаннÑ?"
msgid "Are you sure you want to delete this device? This action cannot be undone."
msgstr "Ви впевнені, що хочете видалити цей приÑтрій? Цю дію неможливо ÑкаÑувати."
@@ -4821,9 +4941,6 @@ msgstr "Ви впевнені, що хочете об'єднати негайнÐ
msgid "Are you sure you want to re-deploy this environment?"
msgstr "Ви впевнені, що хочете повторно розгорнути це Ñередовище?"
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr "Ви впевнені, що хочете повторно згенерувати відкритий ключ? Вам доведетьÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ відкритий ключ на віддаленому Ñервері, перш ніж Ð´Ð·ÐµÑ€ÐºÐ°Ð»ÑŽÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð¿Ñ€Ð°Ñ†ÑŽÑ” знову."
-
msgid "Are you sure you want to reindex?"
msgstr "Ви впевнені, що хочете переіндекÑувати?"
@@ -4971,6 +5088,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr "Призначити деÑкі задачі до цього етапу."
@@ -4981,7 +5101,7 @@ msgid "Assign to commenting user"
msgstr ""
msgid "Assign to me"
-msgstr ""
+msgstr "Призначити Ñобі"
msgid "Assign yourself to these issues"
msgstr "Призначити ці задачі Ñобі"
@@ -5372,9 +5492,6 @@ msgstr "ДоÑтупні Ñпеціальні Runner’и"
msgid "Avatar for %{assigneeName}"
msgstr "Ðватар Ð´Ð»Ñ %{assigneeName}"
-msgid "Avatar for %{name}"
-msgstr "Ðватар Ð´Ð»Ñ %{name}"
-
msgid "Avatar will be removed. Are you sure?"
msgstr "Ðватар буде видалено. Ви впевнені?"
@@ -5624,9 +5741,6 @@ msgstr "щоміÑÑцÑ"
msgid "BillingPlans|per user"
msgstr "За кориÑтувача"
-msgid "BillingPlan|Contact sales"
-msgstr "Зв'ÑзатиÑÑ Ð· відділом продажів"
-
msgid "BillingPlan|Upgrade"
msgstr "Підвищити"
@@ -5657,14 +5771,11 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr "Ð”Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð±ÐµÐ·ÐºÐ¾ÑˆÑ‚Ð¾Ð²Ð½Ð¸Ñ… хвилин запуÑку на доÑтупних Runner'ах, необхідно додати кредитну або дебетову картку. Це необхідно Ð´Ð»Ñ Ð·Ð¼ÐµÐ½ÑˆÐµÐ½Ð½Ñ Ð·Ð»Ð¾Ð²Ð¶Ð¸Ð²Ð°Ð½Ð½Ñ Ñ–Ð½Ñ„Ñ€Ð°Ñтруктурою GitLab. %{strongStart}GitLab не розповÑюджує та не зберігає дані вашої картки, вони будуть викориÑтані лише Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸.%{strongEnd}"
-
-msgid "Billings|User successfully validated"
-msgstr "КориÑтувача уÑпішно перевірено."
+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 ""
msgid "Billings|User validation required"
msgstr ""
@@ -5675,8 +5786,11 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
-msgstr "Ваш обліковий Ð·Ð°Ð¿Ð¸Ñ Ð¿Ñ€Ð¾Ð¹ÑˆÐ¾Ð² перевірку. Ви можете викориÑтовувати безкоштовні хвилини Ð´Ð»Ñ ÐºÐ¾Ð½Ð²ÐµÑ”Ñ€Ñ–Ð²."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
+msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
msgstr ""
@@ -5687,9 +5801,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5830,19 +5950,19 @@ msgid "BoardScope|Any assignee"
msgstr "Будь-Ñкий виконавець"
msgid "BoardScope|Any label"
-msgstr ""
+msgstr "Будь-Ñка мітка"
msgid "BoardScope|Assignee"
msgstr "Виконавець"
msgid "BoardScope|Choose labels"
-msgstr ""
+msgstr "Вибрати мітки"
msgid "BoardScope|Edit"
msgstr "Редагувати"
msgid "BoardScope|Labels"
-msgstr ""
+msgstr "Мітки"
msgid "BoardScope|Milestone"
msgstr "Етап"
@@ -5857,7 +5977,7 @@ msgid "BoardScope|Select assignee"
msgstr "Обрати виконавцÑ"
msgid "BoardScope|Select labels"
-msgstr ""
+msgstr "Вибрати мітку"
msgid "BoardScope|Select milestone"
msgstr "Вибрати етап"
@@ -5877,7 +5997,7 @@ msgstr "Вага"
msgid "Boards"
msgstr "Дошки"
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5955,7 +6075,7 @@ msgid "Boards|Failed to fetch blocking %{issuableType}s"
msgstr ""
msgid "Boards|New board"
-msgstr ""
+msgstr "Ðова дошка"
msgid "Boards|New epic"
msgstr "Ðовий епік"
@@ -6242,8 +6362,11 @@ msgstr ""
msgid "Bulk update"
msgstr "МаÑове оновленнÑ"
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
-msgstr "Повторний імпорт Ñтворює нову групу. Він не ÑинхронізуєтьÑÑ Ð· наÑвною групою."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
+msgstr ""
msgid "BulkImport|Existing groups"
msgstr "ІÑнуючі групи"
@@ -6251,6 +6374,9 @@ msgstr "ІÑнуючі групи"
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 ""
+
msgid "BulkImport|From source group"
msgstr "З групи джерел"
@@ -6270,7 +6396,7 @@ msgid "BulkImport|Import selected"
msgstr ""
msgid "BulkImport|Importing the group failed."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ñ‚Ð¸ групу."
msgid "BulkImport|Last imported to %{link}"
msgstr ""
@@ -6290,6 +6416,9 @@ msgstr "ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð½ÐµÐ´Ð¾Ñтупна"
msgid "BulkImport|No parent"
msgstr "Ðемає батьківÑького елемента"
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr "Показано %{start}-%{end} із %{total}"
@@ -6393,16 +6522,16 @@ msgid "CI/CD Analytics"
msgstr "Ðналітика CI/CD"
msgid "CI/CD Settings"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ CI/CD"
+msgstr "Ðалаштувати CI/CD"
msgid "CI/CD configuration"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ CI/CD"
+msgstr "Ðалаштувати CI/CD"
msgid "CI/CD configuration file"
msgstr "Файл конфігурації CI/CD"
msgid "CI/CD|No projects have been added to the scope"
-msgstr ""
+msgstr "Ðемає проєктів в облаÑÑ‚ÑŒ видимоÑÑ‚Ñ–"
msgid "CICDAnalytics|%{percent}%{percentSymbol}"
msgstr "%{percent}%{percentSymbol}"
@@ -6664,7 +6793,7 @@ msgid "Cancelling Preview"
msgstr "СкаÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð½ÑŒÐ¾Ð³Ð¾ переглÑду"
msgid "Cannot assign a confidential epic to a non-confidential issue. Make the issue confidential and try again"
-msgstr ""
+msgstr "Ðеможливо призначати конфіденційний епік до неконфіденційної задачі. Зробіть задачу конфіденційною та Ñпробуйте ще раз"
msgid "Cannot be merged automatically"
msgstr "Ðеможливо злити автоматично"
@@ -6996,7 +7125,7 @@ msgstr "Перевірка доÑтупноÑÑ‚Ñ– імені кориÑтуваÑ
msgid "Checkout"
msgstr "ÐžÑ„Ð¾Ñ€Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ð¼Ð¾Ð²Ð»ÐµÐ½Ð½Ñ"
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -7025,7 +7154,7 @@ msgid "Checkout|%{name}'s storage subscription"
msgstr ""
msgid "Checkout|%{quantity} CI minutes"
-msgstr ""
+msgstr "%{quantity} СІ хвилин"
msgid "Checkout|%{quantity} GB of storage"
msgstr ""
@@ -7262,9 +7391,6 @@ msgstr "Вибрати будь-Ñкий колір."
msgid "Choose file…"
msgstr "Виберіть файл…"
-msgid "Choose labels"
-msgstr "Оберіть мітки"
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7475,6 +7601,9 @@ msgstr "ОчиÑтити фільтри графіків"
msgid "Clear due date"
msgstr "ОчиÑтити дату завершеннÑ"
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr "ОчиÑтити недавні пошуки"
@@ -7493,9 +7622,15 @@ msgstr "ОчиÑтити поле вводу Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ шаблоніÐ
msgid "Clear weight"
msgstr "ОчиÑтити вагу"
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr "Вагу очищено."
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr "Очищає вагу."
@@ -7584,7 +7719,7 @@ msgid "Close %{issueType}"
msgstr "Закрити %{issueType}"
msgid "Close %{noteable}"
-msgstr ""
+msgstr "Закрити %{noteable}"
msgid "Close %{tabname}"
msgstr "Закрити %{tabname}"
@@ -7649,24 +7784,45 @@ msgstr "Рівень клаÑтера"
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr "Токени доÑтупу"
msgid "ClusterAgents|Actions"
-msgstr ""
+msgstr "Дії"
msgid "ClusterAgents|Advanced installation methods"
-msgstr ""
+msgstr "Додаткові методи вÑтановленнÑ"
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7674,7 +7830,7 @@ msgid "ClusterAgents|Agent never connected to GitLab"
msgstr "Agent ніколи не підключаєтьÑÑ Ð´Ð¾ GitLab"
msgid "ClusterAgents|All"
-msgstr ""
+msgstr "Ð’ÑÑ–"
msgid "ClusterAgents|An error occurred while loading your GitLab Agents"
msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð²Ð°ÑˆÐ¸Ñ… GitLab Agents"
@@ -7682,12 +7838,18 @@ 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 ""
+
msgid "ClusterAgents|An unknown error occurred. Please try again."
msgstr "СталаÑÑ Ð½ÐµÐ²Ñ–Ð´Ð¾Ð¼Ð° помилка, Ñпробуйте ще раз."
-msgid "ClusterAgents|Certificate"
+msgid "ClusterAgents|Are you sure you want to delete this agent? You cannot undo this."
msgstr ""
+msgid "ClusterAgents|Certificate"
+msgstr "Сертифікат"
+
msgid "ClusterAgents|Configuration"
msgstr "КонфігураціÑ"
@@ -7719,7 +7881,7 @@ msgid "ClusterAgents|Copy token"
msgstr "Копіювати токен"
msgid "ClusterAgents|Create a new cluster"
-msgstr ""
+msgstr "Створити новий клаÑтер"
msgid "ClusterAgents|Created by"
msgstr "Створено"
@@ -7730,12 +7892,21 @@ msgstr "Створено %{name} %{time}"
msgid "ClusterAgents|Date created"
msgstr "Дата ÑтвореннÑ"
-msgid "ClusterAgents|Deprecated"
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
msgstr ""
+msgid "ClusterAgents|Deprecated"
+msgstr "Ðе підтримуєтьÑÑ"
+
msgid "ClusterAgents|Description"
msgstr "ОпиÑ"
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7755,7 +7926,7 @@ msgid "ClusterAgents|How to register an agent?"
msgstr ""
msgid "ClusterAgents|Install a new agent"
-msgstr ""
+msgstr "Ð’Ñтановити новий агент"
msgid "ClusterAgents|Last connected %{timeAgo}."
msgstr "ОÑтаннє Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ %{timeAgo}."
@@ -7782,7 +7953,7 @@ msgid "ClusterAgents|Never connected"
msgstr "Ðіколи не підключавÑÑ"
msgid "ClusterAgents|No agents"
-msgstr ""
+msgstr "Ðемає агентів"
msgid "ClusterAgents|No clusters connected through cluster certificates"
msgstr ""
@@ -7791,13 +7962,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 ""
@@ -7809,10 +7980,13 @@ msgid "ClusterAgents|Registration token"
msgstr "РеєÑÑ‚Ñ€Ð°Ñ†Ñ–Ñ Ñ‚Ð¾ÐºÐµÐ½Ð°"
msgid "ClusterAgents|Security"
+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 ""
+msgstr "Вибрати агента"
msgid "ClusterAgents|Select an agent to register with GitLab"
msgstr ""
@@ -7829,12 +8003,28 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr "Ðевідомий кориÑтувач"
@@ -7844,6 +8034,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -7863,7 +8056,7 @@ msgid "ClusterAgent|You have insufficient permissions to delete this cluster age
msgstr "У Ð²Ð°Ñ Ð½ÐµÐ´Ð¾Ñтатньо прав Ð´Ð»Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ клаÑтерного агента"
msgid "ClusterApplicationsRemoved|One-click application management was removed in GitLab 14.0. Your applications are still installed in your cluster, and integrations continue working."
-msgstr ""
+msgstr "У GitLab 14.0 видалено ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°ÑтоÑунками в один клік. Ваші заÑтоÑунки вÑе ще уÑтановлені у вашому клаÑтері та інтеграції продовжують працювати."
msgid "ClusterIntegration|%{linkStart}More information%{linkEnd}"
msgstr "%{linkStart}Детальніше%{linkEnd}"
@@ -7971,7 +8164,7 @@ msgid "ClusterIntegration|Choose the %{linkStart}subnets %{linkEnd} in your VPC
msgstr "Оберіть %{linkStart}підмережі%{linkEnd} вашої VPC де будуть запуÑкатиÑÑ Ð²Ð°ÑˆÑ– робочі вузли."
msgid "ClusterIntegration|Choose the worker node %{linkStart}instance type%{linkEnd}."
-msgstr ""
+msgstr "Виберіть вузол Ð²Ð¸ÐºÐ¾Ð½Ð°Ð²Ñ†Ñ %{linkStart}типу інÑтанÑу%{linkEnd}."
msgid "ClusterIntegration|Choose which of your environments will use this cluster."
msgstr "Виберіть, Ñке із ваших Ñередовищ буде викориÑтовувати цей клаÑтер."
@@ -8103,7 +8296,7 @@ msgid "ClusterIntegration|Environment scope"
msgstr "ДоÑтупніÑÑ‚ÑŒ Ð´Ð»Ñ Ñередовищ"
msgid "ClusterIntegration|Environment scope is required."
-msgstr ""
+msgstr "Потрібна облаÑÑ‚ÑŒ дії Ñередовища."
msgid "ClusterIntegration|Every new Google Cloud Platform (GCP) account receives $300 in credit upon %{sign_up_link}. In partnership with Google, GitLab is able to offer an additional $200 for both new and existing GCP accounts to get started with GitLab's Google Kubernetes Engine Integration."
msgstr "Кожен новий обліковий Ð·Ð°Ð¿Ð¸Ñ Ð² Google Cloud Platform (GCP) отримує $300 на Ñвій рахунок при %{sign_up_link}. GitLab (у партнерÑтві із Google) пропонує додаткові $200 Ð´Ð»Ñ Ð½Ð¾Ð²Ð¸Ñ… облікових запиÑів GCP, Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ–Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ñ–Ñ”ÑŽ GitLab з Google Kubernetes Engine."
@@ -9033,6 +9226,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr "Ðова оболонка Ð´Ð»Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ð½Ð¾ÑÑ‚Ñ–"
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr "Компонент"
@@ -9076,7 +9278,7 @@ msgid "Configure Gitaly timeouts."
msgstr "Ðалаштувати таймаути Gitaly."
msgid "Configure Integrations"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ–Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ñ–Ñ—"
+msgstr "Ðалаштувати інтеграції"
msgid "Configure Prometheus"
msgstr "Ðалаштувати Prometheus"
@@ -9393,7 +9595,7 @@ msgid "ContainerRegistry|Deleting the image repository will delete all images an
msgstr ""
msgid "ContainerRegistry|Digest: %{imageId}"
-msgstr ""
+msgstr "ДайджеÑÑ‚: %{imageId}"
msgid "ContainerRegistry|Docker connection error"
msgstr "Помилка Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Docker"
@@ -9411,10 +9613,10 @@ msgid "ContainerRegistry|If you are not already logged in, you need to authentic
msgstr "Якщо ви ще не виконали вхід вам необхідно автентифікуватиÑÑ Ð² РеєÑтрі Контейнерів за допомогою імені кориÑтувача та Ð¿Ð°Ñ€Ð¾Ð»Ñ GitLab. Якщо у Ð²Ð°Ñ Ð²Ð²Ñ–Ð¼ÐºÐ½ÐµÐ½Ð° %{twofaDocLinkStart}Двофакторна автентифікаціÑ%{twofaDocLinkEnd}, викориÑтовуйте %{personalAccessTokensDocLinkStart}ПерÑональний Токен ДоÑтупу%{personalAccessTokensDocLinkEnd} заміÑÑ‚ÑŒ паролю."
msgid "ContainerRegistry|Image repository deletion failed"
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ репозиторій образів"
msgid "ContainerRegistry|Image repository not found"
-msgstr ""
+msgstr "Репозиторій образів не знайдено"
msgid "ContainerRegistry|Image repository will be deleted"
msgstr ""
@@ -9458,6 +9660,9 @@ msgstr "Ще не заплановано"
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr "Примітка: Будь-Ñке Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾Ð»Ñ–Ñ‚Ð¸ÐºÐ¸ призведе до зміни запланованої та чаÑу"
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr "Опубліковано %{timeInfo}"
@@ -9549,6 +9754,9 @@ msgstr "Теги з іменами, Ñкі відповідають цьому Ñ
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr "Ð§Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð»Ñ–Ñ‚Ð¸ÐºÐ¸ Ð¾Ñ‡Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡Ð¸Ð²ÑÑ, перш ніж вона могла видалити вÑÑ– теги. ÐдмініÑтратор може %{adminLinkStart}вручну запуÑтити Ð¾Ñ‡Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð·Ð°Ñ€Ð°Ð·%{adminLinkEnd} або ви можете зачекати, поки політика Ð¾Ñ‡Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð·Ð½Ð¾Ð²Ñƒ запуÑтитьÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾. %{docLinkStart}Додаткова інформаціÑ%{docLinkEnd}"
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr "Репозиторій образів не знайдено."
@@ -9780,12 +9988,18 @@ msgstr "Копіювати Ñередовище"
msgid "Copy evidence SHA"
msgstr "Скопіювати SHA даних"
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr "Скопіювати вміÑÑ‚ файлу"
msgid "Copy file path"
msgstr "Скопіювати шлÑÑ… до файлу"
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr "Копіювати ключ"
@@ -9816,9 +10030,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr "Скопіювати цей токен реєÑтрації."
-msgid "Copy this value"
-msgstr "Копіювати це значеннÑ"
-
msgid "Copy to clipboard"
msgstr "Копіювати в буфер обміну"
@@ -10015,7 +10226,7 @@ msgid "Create %{workspace} label"
msgstr "Створити мітку %{workspace}"
msgid "Create Google Cloud project"
-msgstr ""
+msgstr "Створити проєкт Google Cloud"
msgid "Create New Directory"
msgstr "Створити новий каталог"
@@ -10158,9 +10369,6 @@ msgstr "Створити нову мітку"
msgid "Create new project"
msgstr "Створити новий проєкт"
-msgid "Create new..."
-msgstr "Створити..."
-
msgid "Create or import your first project"
msgstr "Створіть або імпортуйте Ñвій перший проєкт"
@@ -10191,6 +10399,9 @@ msgstr "Створити тему"
msgid "Create user"
msgstr "Створити кориÑтувача"
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr "Створити шаблон: %{searchTerm}"
@@ -10233,9 +10444,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -10245,13 +10453,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10431,25 +10642,49 @@ msgstr "Кредитна картка:"
msgid "Critical vulnerabilities present"
msgstr "ПриÑутні критичні вразливоÑÑ‚Ñ–"
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
-msgid "Crm|Email"
+msgid "Crm|Edit contact"
msgstr ""
+msgid "Crm|Email"
+msgstr "Електронна пошта"
+
msgid "Crm|First name"
-msgstr ""
+msgstr "Ім'Ñ"
msgid "Crm|Last name"
+msgstr "Прізвище"
+
+msgid "Crm|New Organization"
msgstr ""
msgid "Crm|New contact"
+msgstr "Ðовий контакт"
+
+msgid "Crm|New organization"
msgstr ""
msgid "Crm|No contacts found"
@@ -10458,6 +10693,9 @@ msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10608,15 +10846,6 @@ msgstr "Ðалаштуйте конфігурацію конвеєра Ñ– зві
msgid "Customize your pipeline configuration."
msgstr "Ðалаштувати конфігурацію конвеєра."
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr "Хочете налаштувати цю Ñторінку?"
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr "Перейти до налаштувань"
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr "За замовчуваннÑм на цій Ñторінці показано ÑпиÑок ваших проєктів, але це можна змінити, щоб показувати діÑльніÑÑ‚ÑŒ проєктів, групи, ваш ÑпиÑок Ñправ, призначені задачі, запити на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ñ‚Ð° багато іншого. Ви можете налаштувати це в розділі \"ВміÑÑ‚ домашньої Ñторінки\" у Ñвоїх параметрах."
-
msgid "Cycle Time"
msgstr "Ð§Ð°Ñ Ñ†Ð¸ÐºÐ»Ñƒ"
@@ -11190,7 +11419,7 @@ msgid "DastSiteValidation|Meta tag validation"
msgstr ""
msgid "DastSiteValidation|Retry validation"
-msgstr ""
+msgstr "Повторити перевірку"
msgid "DastSiteValidation|Revoke validation"
msgstr ""
@@ -11307,6 +11536,9 @@ msgstr "Ім'Ñ Ð´Ð¶ÐµÑ€ÐµÐ»Ð° даних не знайдено"
msgid "Date"
msgstr "Дата"
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr "Вибір дати"
@@ -11416,7 +11648,7 @@ msgid "Default projects limit"
msgstr "Ліміт проєктів за замовчуваннÑм"
msgid "Default timeout"
-msgstr ""
+msgstr "Тайм-аут за замовчуваннÑм"
msgid "Default: Map a FogBugz account ID to a full name"
msgstr "По замовчуванню: викориÑтовувати ідентифікатор облікового запиÑу FogBugz Ñк повне ім'Ñ"
@@ -11470,13 +11702,13 @@ 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 ""
+msgstr "Ви впевнені, що ви хочете запуÑтити %{jobName} відразу? Ð’ іншому випадку це Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ виконано автоматично по завершенню таймера."
msgid "DelayedJobs|Are you sure you want to run %{job_name} immediately? This job will run automatically after it's timer finishes."
msgstr "Ви впевнені, що ви хочете запуÑтити %{job_name} відразу? Це Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ виконано автоматично по завершенню таймера."
msgid "DelayedJobs|Are you sure you want to run %{job_name} immediately? This job will run automatically after its timer finishes."
-msgstr ""
+msgstr "Ви впевнені, що ви хочете запуÑтити %{job_name} відразу? Це Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ виконано автоматично по завершенню таймера."
msgid "DelayedJobs|Run the delayed job now?"
msgstr ""
@@ -11506,7 +11738,7 @@ msgid "Delete Key"
msgstr "Видалити ключ"
msgid "Delete Selected"
-msgstr ""
+msgstr "Видалити вибране"
msgid "Delete Value Stream"
msgstr ""
@@ -11586,6 +11818,9 @@ msgstr "Видалити ÑпиÑок кориÑтувачів"
msgid "Delete variable"
msgstr "Видалити змінну"
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr "Помилка при видаленні репозиторію проєкту. Будь лаÑка, Ñпробуйте знову, або зв'ÑжітьÑÑ Ñ–Ð· адмініÑтратором."
@@ -11619,15 +11854,9 @@ msgstr "Видалити %{name}"
msgid "Deleted"
msgstr "Видалено"
-msgid "Deleted Projects"
-msgstr "Видалені проєкти"
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr "Видалено пÑевдонім Ð´Ð»Ñ Ñ‡Ð°Ñ‚Ñƒ: %{chat_name}!"
-msgid "Deleted projects"
-msgstr "Видалені проєкти"
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11761,16 +11990,19 @@ msgid "Dependency Scanning"
msgstr "Ð¡ÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð»ÐµÐ¶Ð½Ð¾Ñтей"
msgid "Dependency list"
-msgstr ""
+msgstr "СпиÑок залежноÑтей"
msgid "DependencyProxy|Cached %{time}"
msgstr "Кешовано %{time}"
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
msgid "DependencyProxy|Copy prefix"
-msgstr ""
+msgstr "Копіювати префікÑ"
msgid "DependencyProxy|Create a local proxy for storing frequently used upstream images. %{docLinkStart}Learn more%{docLinkEnd} about dependency proxies."
msgstr ""
@@ -11790,7 +12022,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11799,6 +12031,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] "Залежить від Ð·Ð»Ð¸Ñ‚Ñ‚Ñ %d запиту на злиттÑ"
@@ -11959,7 +12194,7 @@ msgid "DeployTokens|Deploy tokens"
msgstr "Токени розгортаннÑ"
msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
-msgstr ""
+msgstr "Токени Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð½Ð°Ð´Ð°ÑŽÑ‚ÑŒ доÑтуп до пакетів, вашого репозиторію та образів реєÑтру."
msgid "DeployTokens|Enter a unique name for your deploy token."
msgstr "Введіть унікальне ім'Ñ Ð´Ð»Ñ Ñ‚Ð¾ÐºÐµÐ½Ð° вашого розгортаннÑ."
@@ -11974,7 +12209,7 @@ msgid "DeployTokens|Expires"
msgstr "Термін дії"
msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
-msgstr ""
+msgstr "Токени групового Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð½Ð°Ð´Ð°ÑŽÑ‚ÑŒ доÑтуп до пакетів, репозиторіїв та образів реєÑтру."
msgid "DeployTokens|Name"
msgstr "Ðазва"
@@ -12496,17 +12731,17 @@ msgstr "(базова)"
msgid "Diffs|%d addition"
msgid_plural "Diffs|%d additions"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%d додаваннÑ"
+msgstr[1] "%d додаваннÑ"
+msgstr[2] "%d додавань"
+msgstr[3] "%d додавань"
msgid "Diffs|%d deletion"
msgid_plural "Diffs|%d deletions"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%d видаленнÑ"
+msgstr[1] "%d видаленнÑ"
+msgstr[2] "%d видалень"
+msgstr[3] "%d видалень"
msgid "Diffs|No file name available"
msgstr "Ім'Ñ Ñ„Ð°Ð¹Ð»Ñƒ не доÑтупне"
@@ -12617,15 +12852,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr "Розпочати безкоштовну пробну верÑÑ–ÑŽ"
@@ -12768,6 +13003,9 @@ msgstr ""
msgid "Download CSV"
msgstr "Завантажити CSV"
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr "Завантажити артефакти"
@@ -12903,8 +13141,8 @@ msgstr "Редагувати етап"
msgid "Edit Password"
msgstr "Редагувати пароль"
-msgid "Edit Pipeline Schedule %{id}"
-msgstr "Редагувати Розклад Конвеєра %{id}"
+msgid "Edit Pipeline Schedule"
+msgstr ""
msgid "Edit Release"
msgstr "Редагувати Реліз"
@@ -12934,7 +13172,7 @@ msgid "Edit deploy freeze"
msgstr ""
msgid "Edit deploy key"
-msgstr ""
+msgstr "Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ»ÑŽÑ‡ Ð´Ð»Ñ Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ"
msgid "Edit description"
msgstr "Редагувати опиÑ"
@@ -12942,6 +13180,9 @@ msgstr "Редагувати опиÑ"
msgid "Edit environment"
msgstr "Редагувати Ñередовище"
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr "Редагуйте файли в редакторі і закомітьте зміни тут"
@@ -13885,6 +14126,9 @@ msgstr "Помилка при вÑтановленні порÑдку елеме
msgid "Epics|Something went wrong while removing issue from epic."
msgstr "Помилка при видаленні задачі із епіка."
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13930,9 +14174,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr "Помилка при видаленні проєкту. Перевірте журнали Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð¸Ñ†ÑŒ про помилку."
@@ -14086,9 +14327,6 @@ msgstr "Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ: %{stripped}"
msgid "Error while loading the merge request. Please try again."
msgstr "Помилка при завантаженні запита на злиттÑ. Будь лаÑка, Ñпробуйте знову."
-msgid "Error while loading the project data. Please try again."
-msgstr "Помилка при завантаженні даних проєкту. Будь лаÑка, Ñпробуйте знову."
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr "Помилка при міграції %{upload_id}: %{error_message}"
@@ -14173,6 +14411,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14180,7 +14421,7 @@ msgid "EscalationPolicies|%{notificationIcon} THEN %{doAction} %{forScheduleOrUs
msgstr ""
msgid "EscalationPolicies|+ Add an additional rule"
-msgstr ""
+msgstr "+ Додати додаткове правило"
msgid "EscalationPolicies|A schedule is required for adding an escalation policy."
msgstr ""
@@ -14360,9 +14601,6 @@ msgstr "Щороку"
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr "Будь-хто"
-
msgid "Everyone With Access"
msgstr "Кожен, хто має доÑтуп"
@@ -14523,10 +14761,10 @@ msgid "Explore public groups"
msgstr "ПереглÑнути публічні групи"
msgid "Explore snippets"
-msgstr ""
+msgstr "ОглÑд Ñніпетів"
msgid "Explore topics"
-msgstr ""
+msgstr "ОглÑд тем"
msgid "Export"
msgstr "ЕкÑпорт"
@@ -14555,8 +14793,8 @@ msgstr "ЕкÑпорт проєкту"
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
-msgstr "ЕкÑпортуйте цю групу з уÑіма відповідними даними в новий екземплÑÑ€ GitLab. ПіÑÐ»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ð²Ð¸ зможете імпортувати файл даних зі Ñторінки \"Ðова Група\"."
+msgid "Export this group with all related data."
+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 ""
@@ -14869,7 +15107,7 @@ msgid "Failed to update framework"
msgstr ""
msgid "Failed to update issue status"
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑ Ð·Ð°Ð´Ð°Ñ‡Ñ–"
msgid "Failed to update the Canary Ingress."
msgstr "Ðе вдалоÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ Canary Ingress."
@@ -14899,7 +15137,7 @@ msgid "Faster releases. Better code. Less pain."
msgstr "Швидші релізи. Кращий код. Менше болю."
msgid "Favicon"
-msgstr ""
+msgstr "Фавікон"
msgid "Favicon was successfully removed."
msgstr "Фавікон був уÑпішно видалений."
@@ -15255,7 +15493,7 @@ msgid "Filter by merge requests that are currently merged."
msgstr ""
msgid "Filter by milestone"
-msgstr ""
+msgstr "Фільтр по етапу"
msgid "Filter by milestone name"
msgstr "Фільтрувати за назвою етапу"
@@ -15269,9 +15507,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr "Фільтрувати за двофакторною автентифікацією"
-
msgid "Filter by user"
msgstr "Сортувати по кориÑтувачах"
@@ -15405,7 +15640,7 @@ msgid "Followed Users' Activity"
msgstr "ÐктивніÑÑ‚ÑŒ підпиÑаних кориÑтувачів"
msgid "Followed users"
-msgstr ""
+msgstr "ПідпиÑки"
msgid "Font Color"
msgstr "Колір шрифту"
@@ -15522,7 +15757,7 @@ msgid "ForkProject|The project can be accessed without any authentication."
msgstr ""
msgid "ForkProject|Visibility level"
-msgstr ""
+msgstr "Рівень видимоÑÑ‚Ñ–"
msgid "ForkProject|Want to house several dependent projects under the same namespace?"
msgstr ""
@@ -15531,7 +15766,7 @@ msgid "ForkSuggestion|Cancel"
msgstr "СкаÑувати"
msgid "ForkSuggestion|Fork"
-msgstr ""
+msgstr "Форк"
msgid "ForkSuggestion|You can’t %{edit_start}edit%{edit_end} files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -15602,6 +15837,9 @@ msgstr "Від Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñƒ на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð´Ð¾ розго
msgid "Full"
msgstr "Повний"
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr "Повне ім'Ñ"
@@ -15627,7 +15865,7 @@ msgid "General pipelines"
msgstr "Загальні конвеєри"
msgid "General settings"
-msgstr ""
+msgstr "Загальні налаштуваннÑ"
msgid "Generate a default set of labels"
msgstr "Створити Ñтандартний набір міток"
@@ -15657,13 +15895,13 @@ msgid "Generic package file size in bytes"
msgstr ""
msgid "GenericReport|After"
-msgstr ""
+msgstr "ПіÑлÑ"
msgid "GenericReport|Before"
-msgstr ""
+msgstr "До"
msgid "GenericReport|Diff"
-msgstr ""
+msgstr "РізницÑ"
msgid "Geo"
msgstr "Geo"
@@ -15930,7 +16168,7 @@ msgid "Geo|Replication slots"
msgstr ""
msgid "Geo|Replication status"
-msgstr ""
+msgstr "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ñ€ÐµÐ¿Ð»Ñ–ÐºÐ°Ñ†Ñ–Ñ—"
msgid "Geo|Replication summary"
msgstr ""
@@ -16041,7 +16279,7 @@ msgid "Geo|Unhealthy"
msgstr ""
msgid "Geo|Unknown"
-msgstr ""
+msgstr "Ðевідомий"
msgid "Geo|Unknown state"
msgstr "Ðевідомий Ñтан"
@@ -16140,7 +16378,7 @@ msgid "Git shallow clone"
msgstr "ЧаÑтковий (shallow) клон Git"
msgid "Git strategy"
-msgstr ""
+msgstr "Git ÑтратегіÑ"
msgid "Git transfer in progress"
msgstr "Триває перенеÑÐµÐ½Ð½Ñ Git"
@@ -16176,7 +16414,7 @@ msgid "GitLab Import"
msgstr "Імпорт з GitLab"
msgid "GitLab Issue"
-msgstr ""
+msgstr "Задача GitLab"
msgid "GitLab Pages"
msgstr "Gitlab Pages"
@@ -16461,10 +16699,7 @@ msgid "GlobalSearch|Results updated. %{count} results available. Use the up and
msgstr ""
msgid "GlobalSearch|Search GitLab"
-msgstr ""
-
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
+msgstr "Пошук в GitLab"
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16476,13 +16711,13 @@ msgid "GlobalSearch|Type for new suggestions to appear below."
msgstr ""
msgid "GlobalSearch|in all GitLab"
-msgstr ""
+msgstr "У вÑьому GitLab"
msgid "GlobalSearch|in group"
msgstr ""
msgid "GlobalSearch|in project"
-msgstr ""
+msgstr "В проєкті"
msgid "Go Back"
msgstr "ПовернутиÑÑ"
@@ -16553,6 +16788,9 @@ msgstr "Перейти до метрик"
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr "Перейти на рівень вище"
@@ -16742,9 +16980,6 @@ msgstr "SAML Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¸ повинна бути включена Ð´Ð»Ñ Ñ
msgid "Group URL"
msgstr "URL-адреÑа групи"
-msgid "Group Wikis"
-msgstr "Wiki-Ñторінки груп"
-
msgid "Group application: %{name}"
msgstr ""
@@ -16806,7 +17041,7 @@ msgid "Group is required when cluster_type is :group"
msgstr ""
msgid "Group jobs by"
-msgstr ""
+msgstr "Групувати Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð·Ð°"
msgid "Group maintainers can register group runners in the %{link}"
msgstr "Керівники групи можуть зареєÑтрувати групові runner'и через %{link}"
@@ -16871,6 +17106,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr "Групу уÑпішно оновлено."
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr "Група: %{group_name}"
@@ -16911,7 +17149,7 @@ msgid "GroupImport|Unable to process group import file"
msgstr ""
msgid "GroupPage|Copy group ID"
-msgstr ""
+msgstr "Копіювати ID групи"
msgid "GroupPage|Group ID: %{group_id}"
msgstr ""
@@ -16923,7 +17161,7 @@ msgid "GroupRoadmap|%{startDateInWords} – %{endDateInWords}"
msgstr "%{startDateInWords} – %{endDateInWords}"
msgid "GroupRoadmap|Loading epics"
-msgstr ""
+msgstr "Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ ÐµÐ¿Ñ–ÐºÑ–Ð²"
msgid "GroupRoadmap|No start and end date"
msgstr ""
@@ -16973,9 +17211,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -17048,6 +17295,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -17087,6 +17337,9 @@ msgstr "SHA1-відбиток Ñертифікату Ð´Ð»Ñ Ð¿Ñ–Ð´Ð¿Ð¸Ñу SAML
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr "Токен SCIM зараз приховоно. Щоб знову побачити Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ‚Ð¾ÐºÐµÐ½Ð° вам потрібно "
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -17120,6 +17373,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -17144,8 +17409,8 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr "Значки"
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
-msgstr "Будьте обережні. Зміна батьківÑької групи може мати %{side_effects_link_start}небажані наÑлідки%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
+msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
msgstr "Ðе вдалоÑÑ Ð·Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸ шлÑÑ… тому що в цій групі Ñ” проєкти із образами Docker у Ñвоїх РеєÑтрах контейнерів. Будь лаÑка, Ñпочатку видаліть ці образи з ваших проєктів Ñ– Ñпробуйте знову."
@@ -17153,7 +17418,7 @@ msgstr "Ðе вдалоÑÑ Ð·Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸ шлÑÑ… тому що в цій гр
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -17195,6 +17460,9 @@ msgstr "Згенеровано новий токен Ð´Ð»Ñ Ñ€ÐµÑ”Ñтрації
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr "БатьківÑька група"
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ð½Ð²ÐµÑ”Ñ€Ñ–Ð² були оновлені Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— групи"
@@ -17222,12 +17490,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr "Пошук груп"
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr "Вибери батьківÑьку групу"
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17342,6 +17616,9 @@ msgstr "Ви можете керувати правами доÑтупу члеÐ
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17396,6 +17673,9 @@ 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 ""
+
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 ""
@@ -17475,7 +17755,7 @@ msgid "HeaderAction|issue"
msgstr ""
msgid "Headers"
-msgstr ""
+msgstr "Заголовки"
msgid "Heading 1"
msgstr "Заголовок 1"
@@ -17487,7 +17767,7 @@ msgid "Heading 3"
msgstr "Заголовок 3"
msgid "Heading 4"
-msgstr ""
+msgstr "Заголовок 4"
msgid "Headings"
msgstr "Заголовки"
@@ -17571,7 +17851,7 @@ msgid "Hi %{username}!"
msgstr "Привіт %{username}!"
msgid "Hidden"
-msgstr ""
+msgstr "Прихований"
msgid "Hide"
msgstr "Приховати"
@@ -18479,7 +18759,7 @@ msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit ca
msgstr ""
msgid "InProductMarketing|Start a trial"
-msgstr ""
+msgstr "Розпочати пробну верÑÑ–ÑŽ"
msgid "InProductMarketing|Start by %{performance_link}"
msgstr ""
@@ -18593,7 +18873,7 @@ msgid "InProductMarketing|Working in GitLab = more efficient"
msgstr ""
msgid "InProductMarketing|YouTube"
-msgstr ""
+msgstr "YouTube"
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18644,7 +18924,7 @@ msgid "InProductMarketing|you may %{unsubscribe_link} at any time."
msgstr ""
msgid "Inactive"
-msgstr ""
+msgstr "Ðеактивний"
msgid "Incident"
msgstr "Інцидент"
@@ -18683,7 +18963,7 @@ msgid "IncidentManagement|Create incident"
msgstr ""
msgid "IncidentManagement|Critical - S1"
-msgstr ""
+msgstr "Критичні - S1"
msgid "IncidentManagement|Date created"
msgstr ""
@@ -18692,19 +18972,19 @@ msgid "IncidentManagement|Display your incidents in a dedicated view"
msgstr ""
msgid "IncidentManagement|High - S2"
-msgstr ""
+msgstr "ВиÑокі - S2"
msgid "IncidentManagement|Incident"
-msgstr ""
+msgstr "Інцидент"
msgid "IncidentManagement|Incidents"
-msgstr ""
+msgstr "Інциденти"
msgid "IncidentManagement|Low - S4"
-msgstr ""
+msgstr "Ðизькі - S4"
msgid "IncidentManagement|Medium - S3"
-msgstr ""
+msgstr "Середні - S3"
msgid "IncidentManagement|Missed SLA"
msgstr ""
@@ -18755,7 +19035,7 @@ msgid "IncidentSettings|Incident settings"
msgstr ""
msgid "IncidentSettings|Incidents"
-msgstr ""
+msgstr "Інциденти"
msgid "IncidentSettings|Introduce a countdown timer in incident issues to better track Service Level Agreements (SLAs). The timer starts automatically when the incident is created, and sets a time limit for resolving the incident. When activated, the time to SLA countdown appears on all new incidents."
msgstr ""
@@ -18821,7 +19101,7 @@ msgid "Incident|Metrics"
msgstr "Метрики"
msgid "Incident|Summary"
-msgstr ""
+msgstr "ПідÑумок"
msgid "Incident|There was an issue loading alert data. Please try again."
msgstr ""
@@ -18878,7 +19158,7 @@ msgid "Indent"
msgstr "ВідÑтуп"
msgid "Index"
-msgstr ""
+msgstr "ІндекÑ"
msgid "Index all projects"
msgstr "ІндекÑувати вÑÑ– проєкти"
@@ -19316,6 +19596,9 @@ msgstr "ÐеприпуÑтима ОС"
msgid "Invalid URL"
msgstr "ÐедійÑна URL адреÑа"
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr "ÐеприпуÑтиме ім'Ñ ÐºÐ¾Ð½Ñ‚ÐµÐ¹Ð½ÐµÑ€Ð°"
@@ -19410,7 +19693,7 @@ msgid "Invitation declined"
msgstr ""
msgid "Invite"
-msgstr "ЗапрошеннÑ"
+msgstr "ЗапроÑити"
msgid "Invite \"%{email}\" by email"
msgstr ""
@@ -19422,7 +19705,7 @@ msgid "Invite Members"
msgstr "ЗапроÑити учаÑників"
msgid "Invite a group"
-msgstr ""
+msgstr "ЗапроÑити групу"
msgid "Invite email has already been taken"
msgstr ""
@@ -19449,7 +19732,7 @@ msgid "InviteEmail|Groups assemble related projects together and grant members a
msgstr ""
msgid "InviteEmail|Join now"
-msgstr ""
+msgstr "ПриєднатиÑÑ Ð·Ð°Ñ€Ð°Ð·"
msgid "InviteEmail|Join your team on GitLab! %{inviter} invited you to %{project_or_group_name}"
msgstr ""
@@ -19530,16 +19813,16 @@ msgid "InviteMembersModal|Search for a group to invite"
msgstr ""
msgid "InviteMembersModal|Select a group to invite"
-msgstr ""
+msgstr "Вибрати групу Ð´Ð»Ñ Ð·Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ñ"
msgid "InviteMembersModal|Select a role"
-msgstr ""
+msgstr "Вибрати роль"
msgid "InviteMembersModal|Select members or type email addresses"
msgstr ""
msgid "InviteMembersModal|Something went wrong"
-msgstr ""
+msgstr "ЩоÑÑŒ пішло не так"
msgid "InviteMembersModal|To assign issues to a new team member, you need a project for the issues. %{linkStart}Create a project to get started.%{linkEnd}"
msgstr ""
@@ -19565,9 +19848,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr "ЗапроÑити учаÑника"
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19611,7 +19891,7 @@ msgid "InviteReminderEmail|Hey there %{wave_emoji}"
msgstr ""
msgid "InviteReminderEmail|Hey there!"
-msgstr ""
+msgstr "Привіт!"
msgid "InviteReminderEmail|In case you missed it..."
msgstr ""
@@ -19670,9 +19950,6 @@ msgstr ""
msgid "Is blocked by"
msgstr "Заблоковано кориÑтувачем"
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr "ВикориÑтовує міÑце в ліцензії:"
@@ -19784,9 +20061,6 @@ msgstr "СтатуÑ"
msgid "IssueAnalytics|Weight"
msgstr "Вага"
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr "Дошка"
@@ -19992,7 +20266,7 @@ msgid "Iterations|Create cadence and start iteration"
msgstr ""
msgid "Iterations|Create iteration"
-msgstr ""
+msgstr "Створити ітерацію"
msgid "Iterations|Delete cadence"
msgstr ""
@@ -20432,8 +20706,8 @@ msgstr "Повний неформатований"
msgid "Job|Download"
msgstr "Завантажити"
-msgid "Job|Erase job log"
-msgstr "Видалити лог завданнÑ"
+msgid "Job|Erase job log and artifacts"
+msgstr ""
msgid "Job|Job artifacts"
msgstr "Ðртефакти завдань"
@@ -20779,7 +21053,7 @@ msgid "Last Seen"
msgstr ""
msgid "Last Sync"
-msgstr ""
+msgstr "ОÑÑ‚Ð°Ð½Ð½Ñ ÑинхронізаціÑ"
msgid "Last Used"
msgstr "ОÑтаннє викориÑтаннÑ"
@@ -20866,7 +21140,7 @@ msgid "Last week"
msgstr "ОÑтанній тиждень"
msgid "Last year"
-msgstr ""
+msgstr "Минулий рік"
msgid "LastCommit|authored"
msgstr "автор"
@@ -20886,11 +21160,17 @@ msgstr "ОÑтанній конвеєр Ð´Ð»Ñ Ð¾Ñтаннього коміту
msgid "Launch a ready-to-code development environment for your project."
msgstr "ЗапуÑÑ‚Ñ–Ñ‚ÑŒ Ñередовище Ð´Ð»Ñ Ñ€Ð¾Ð·Ñ€Ð¾Ð±ÐºÐ¸ вашого проєкту."
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
msgid "Lead time"
-msgstr ""
+msgstr "Ð§Ð°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ"
msgid "Learn GitLab"
msgstr "ДізнатиÑÑ Ð¿Ñ€Ð¾ GitLab"
@@ -20917,10 +21197,10 @@ msgid "Learn more"
msgstr "ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ"
msgid "Learn more about %{link_start_tag}Jaeger configuration%{link_end_tag}."
-msgstr ""
+msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про %{link_start_tag}Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Jaeger%{link_end_tag}."
msgid "Learn more about %{username}"
-msgstr ""
+msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про %{username}"
msgid "Learn more about Auto DevOps"
msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про Auto DevOps"
@@ -20932,7 +21212,7 @@ msgid "Learn more about Web Terminal"
msgstr "ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про Веб-термінал"
msgid "Learn more about X.509 signed commits"
-msgstr ""
+msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про підпиÑані коміти X.509"
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr "ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ñертифікатів до проєкту перейшовши до %{docs_link_start}документації по GitLab Pages%{docs_link_end}."
@@ -20950,7 +21230,7 @@ msgid "Learn more about group-level project templates"
msgstr "Докладніше про шаблони проєктів на рівні групи"
msgid "Learn more about groups."
-msgstr ""
+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 ""
@@ -21043,7 +21323,7 @@ msgid "LearnGitLab|Start a free Ultimate trial"
msgstr ""
msgid "LearnGitLab|Submit a merge request"
-msgstr ""
+msgstr "ÐадіÑлати запит на злиттÑ"
msgid "LearnGitLab|Submit a merge request (MR)"
msgstr ""
@@ -21323,7 +21603,7 @@ msgstr[2] "Показ обмежено тільки %d подіÑми"
msgstr[3] "Показ обмежено тільки %d подіÑми"
msgid "Limiting mode"
-msgstr ""
+msgstr "Режим обмеженнÑ"
msgid "Line changes"
msgstr "Зміни Ñ€Ñдка"
@@ -21661,7 +21941,7 @@ msgstr "Вручну"
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr "Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ порÑдок задач"
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -21758,7 +22038,7 @@ msgid "Marks to do as done."
msgstr ""
msgid "Mask variable"
-msgstr ""
+msgstr "Приховати змінну"
msgid "Match not found; try refining your search query."
msgstr "Збігів не знайдено, Ñпробуйте уточнити ваш пошуковий запит."
@@ -22157,7 +22437,7 @@ msgid "Members|Remove \"%{groupName}\""
msgstr "Видалити \"%{groupName}\""
msgid "Members|Remove group"
-msgstr ""
+msgstr "Видалити групу"
msgid "Members|Revert to LDAP group sync settings"
msgstr ""
@@ -22238,7 +22518,7 @@ msgid "Merge commit message"
msgstr "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð´Ð»Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñƒ-злиттÑ"
msgid "Merge details"
-msgstr ""
+msgstr "Деталі об’єднаннÑ"
msgid "Merge events"
msgstr "Події злиттÑ"
@@ -22334,7 +22614,7 @@ msgid "MergeRequestAnalytics|Merge Request"
msgstr ""
msgid "MergeRequestAnalytics|Milestone"
-msgstr ""
+msgstr "Етап"
msgid "MergeRequestAnalytics|Pipelines"
msgstr "Конвеєри"
@@ -22417,10 +22697,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22519,6 +22799,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr "Метрики та профілюваннÑ"
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -23142,6 +23425,9 @@ msgstr ""
msgid "More information."
msgstr "Докладніше."
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr "Ð Ñ–Ð·Ð½Ð¸Ñ†Ñ Ñ–Ð· %{default_branch} Ñкладає більше %{number_commits_distance} комітів"
@@ -23206,7 +23492,7 @@ msgid "Moves this issue to %{path_to_project}."
msgstr "Переміщує задачі до %{path_to_project}."
msgid "MrDeploymentActions|Deploy"
-msgstr ""
+msgstr "Розгортати"
msgid "MrDeploymentActions|Re-deploy"
msgstr "Повторно розгорнути"
@@ -23254,7 +23540,7 @@ msgid "My company or team"
msgstr "ÐœÐ¾Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ñ–Ñ Ð°Ð±Ð¾ команда"
msgid "My topic"
-msgstr ""
+msgstr "ÐœÐ¾Ñ Ñ‚ÐµÐ¼Ð°"
msgid "My-Reaction"
msgstr ""
@@ -23347,6 +23633,39 @@ msgstr "Перейдіть до проєкту, щоб закрити етап."
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr "Допомога"
@@ -23560,6 +23879,9 @@ msgstr "Ðовий"
msgid "New %{issueType}"
msgstr "Ðовий %{issueType}"
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr "Ðовий додаток"
@@ -23703,7 +24025,7 @@ msgid "New milestone"
msgstr "Ðовий етап"
msgid "New name"
-msgstr ""
+msgstr "Ðова назва"
msgid "New password"
msgstr "Ðовий пароль"
@@ -23757,7 +24079,7 @@ msgid "New test case"
msgstr ""
msgid "New topic"
-msgstr ""
+msgstr "Ðова тема"
msgid "New users set to external"
msgstr "Ðові кориÑтувачі Ñ” \"зовнішні по замовчанню\""
@@ -23786,6 +24108,9 @@ msgstr "ÐаÑтупний дизайн"
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23991,7 +24316,7 @@ msgid "No matching results..."
msgstr ""
msgid "No member provided"
-msgstr ""
+msgstr "Ðемає учаÑника"
msgid "No members found"
msgstr ""
@@ -24006,7 +24331,7 @@ msgid "No messages were logged"
msgstr "Ðемає повідомлень у журналі"
msgid "No milestone"
-msgstr ""
+msgstr "Етап відÑутній"
msgid "No milestones to show"
msgstr "Ðемає етапів Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ñƒ"
@@ -24102,7 +24427,7 @@ msgid "No vulnerabilities present"
msgstr "ВразливоÑÑ‚Ñ– відÑутні"
msgid "No webhook events"
-msgstr ""
+msgstr "Ðемає подій вебхука"
msgid "No webhooks found, add one in the form above."
msgstr "Ðе знайдено жодного вебхука, додайте його у формі вище."
@@ -24139,7 +24464,7 @@ msgid "None of the group milestones have the same project as the release"
msgstr ""
msgid "Normal text"
-msgstr ""
+msgstr "Звичайний текÑÑ‚"
msgid "Not Implemented"
msgstr "Ðе реалізовано"
@@ -24207,6 +24532,9 @@ msgstr "Примітка: звернітьÑÑ Ð´Ð¾ вашого адмініÑÑ
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr "Примітка: звернітьÑÑ Ð´Ð¾ вашого адмініÑтратора GitLab, щоб налаштувати %{github_integration_link}, Ñкий дозволить входити за допомогою GitHub та імпортувати репозиторії без генерації перÑонального токена доÑтупу."
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr "Примітка"
@@ -24219,7 +24547,7 @@ msgstr "Ви впевнені, що хочете ÑкаÑувати цей коÐ
msgid "Notes|Collapse replies"
msgstr "Згорнути відповіді"
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24458,7 +24786,7 @@ msgid "Ok, let's go"
msgstr ""
msgid "Okay"
-msgstr ""
+msgstr "Гаразд"
msgid "Oldest first"
msgstr "Спочатку Ñтарі"
@@ -24634,6 +24962,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24652,12 +24986,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24697,12 +25037,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24725,6 +25074,12 @@ msgid "OnDemandScans|Start time"
msgstr ""
msgid "OnDemandScans|Target"
+msgstr "Ціль"
+
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
msgstr ""
msgid "OnDemandScans|There are no finished scans."
@@ -24733,12 +25088,21 @@ msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24748,9 +25112,6 @@ msgstr "ПіÑÐ»Ñ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚Ñƒ, репозиторії можуть бути
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr "ПіÑÐ»Ñ Ñ‚Ð¾Ð³Ð¾, Ñк екÑпортований файл буде готовий, ви отримаєте ÑÐ¿Ð¾Ð²Ñ–Ñ‰ÐµÐ½Ð½Ñ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾ÑŽ поштою із поÑиланнÑм Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð°Ð±Ð¾ можете завантажити його з цієї Ñторінки."
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr "ПіÑÐ»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ñ‚Ð° натиÑÐ½ÐµÐ½Ð½Ñ \"Зменшити видиміÑÑ‚ÑŒ проєкту\":"
@@ -24846,7 +25207,7 @@ msgid "Oops, are you sure?"
msgstr "Ой, а ви впевнені?"
msgid "Open"
-msgstr "Відкриті"
+msgstr "Відкрито"
msgid "Open Selection"
msgstr "Відкрити виділеннÑ"
@@ -24911,6 +25272,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr "ÐžÐ¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð¿ÐµÑ€ÐµÐ²Ð¸Ñ‰Ð¸Ð»Ð° ліміт очікуваннÑ. Перевірте журнал pod'а %{pod_name} Ð´Ð»Ñ Ð±Ñ–Ð»ÑŒÑˆ детальної інформації."
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr "Панель ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñми"
@@ -24951,7 +25315,7 @@ msgid "Or you can choose one of the suggested colors below"
msgstr "Ðбо ви можете вибрати один із запропонованих нижче кольорів"
msgid "Organizations"
-msgstr ""
+msgstr "ОрганізаціÑ"
msgid "Orphaned member"
msgstr ""
@@ -25452,9 +25816,6 @@ msgstr "Сторінку не знайдено"
msgid "Page settings"
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñторінки"
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25644,9 +26005,15 @@ msgstr ""
msgid "Pending"
msgstr "В очікуванні"
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr "Коментарі в очікуванні"
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25746,6 +26113,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25827,12 +26197,6 @@ msgstr "URL Конвеєра"
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr "Квота хвилин Ð´Ð»Ñ ÐºÐ¾Ð½Ð²ÐµÑ”Ñ€Ñ–Ð²"
-
-msgid "Pipeline minutes quota:"
-msgstr "Квота хвилин Ð´Ð»Ñ ÐºÐ¾Ð½Ð²ÐµÑ”Ñ€Ñ–Ð²:"
-
msgid "Pipeline ran in fork of project"
msgstr "Конвеєр запущений у форку проєкту"
@@ -26064,6 +26428,9 @@ msgstr "Дочірній конвеєр"
msgid "Pipelines|Clear runner caches"
msgstr "ОчиÑтити кеш runner"
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr "Скопіювати токен тригера"
@@ -26283,9 +26650,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr "Конвеєр результату злиттÑ"
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr "Виконано"
@@ -26562,6 +26926,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr "Будь лаÑка, виберіть"
@@ -26574,6 +26944,9 @@ msgstr "Будь лаÑка, виберіть країну"
msgid "Please select a file"
msgstr "Будь лаÑка, виберіть файл"
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr "Будь лаÑка, оберіть групу."
@@ -26769,9 +27142,6 @@ msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‡Ð°Ñу"
msgid "Preferences|Use relative times"
msgstr "ВикориÑтовувати відноÑний чаÑ"
-msgid "Press %{key}-C to copy"
-msgstr "ÐатиÑніть %{key}-C, щоб Ñкопіювати"
-
msgid "Prev"
msgstr "Ðазад"
@@ -27123,6 +27493,9 @@ msgstr "Ðеправильний пароль"
msgid "Profiles|Invalid username"
msgstr "Ðеправильне ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача"
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr "Ключ"
@@ -27180,6 +27553,12 @@ msgstr "Приватні внеÑки"
msgid "Profiles|Profile was successfully updated"
msgstr "Профіль було уÑпішно оновлено"
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr "Публічний аватар"
@@ -27264,6 +27643,9 @@ msgstr "Ð†Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача уÑпішно збережено"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr "ВикориÑÑ‚Ð°Ð½Ð½Ñ Ñмайликів в іменах виглÑдає дотепно, але, будь лаÑка, краще викориÑтовуйте Ñ—Ñ… в повідомленнÑÑ… про ÑтатуÑ"
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr "Який ваш ÑтатуÑ?"
@@ -27558,6 +27940,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr "ID проєкту: %{project_id}"
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про Ð¿Ð¾ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ‚ÐµÑтами"
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr "або групу"
@@ -27684,6 +28108,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27936,19 +28363,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -28104,6 +28528,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr "iOS (Swift)"
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr "Проєкти"
@@ -28488,9 +28921,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr "Ð¦Ñ Ñ„ÑƒÐ½ÐºÑ†Ñ–Ñ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ð°."
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28503,9 +28933,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28530,9 +28957,6 @@ msgstr "ÐÐ°Ð´Ð°Ð½Ð½Ñ Ð²Ð°Ð³Ð¸ вашій задачі"
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr "Якщо у Ð²Ð°Ñ Ð±Ð°Ð³Ð°Ñ‚Ð¾ задач, важко зрозуміти загальну картину. Додаючи вагу до Ñвоїх задач, ви матимете краще уÑÐ²Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ цінніÑÑ‚ÑŒ кожної з них а також необхідні зуÑиллÑ, кошти та чаÑ. Таким чином ними краще керувати."
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28614,6 +29038,9 @@ msgstr "Дозволена відправка:"
msgid "ProtectedBranch|Branch"
msgstr "Гілка"
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28630,7 +29057,7 @@ msgid "ProtectedBranch|Keep stable branches secure and force developers to use m
msgstr ""
msgid "ProtectedBranch|Learn more."
-msgstr ""
+msgstr "ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ."
msgid "ProtectedBranch|Protect"
msgstr "ЗахиÑтити"
@@ -28659,9 +29086,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr "Увімкнути/вимкнути Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð²Ð»Ð°Ñниками коду"
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr "%{environment_name} буде доÑупне Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу Ð´Ð»Ñ Ñ€Ð¾Ð·Ñ€Ð¾Ð±Ð½Ð¸ÐºÑ–Ð². Ви впевнені?"
@@ -28704,11 +29137,14 @@ msgstr "Ваше Ñередовище було захищено."
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "ЗахиÑÑ‚ із вашого Ñередовища було знÑто"
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
-msgstr ""
+msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ."
msgid "ProtectedTag|Limit access to creating and updating tags."
msgstr ""
@@ -28719,6 +29155,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28947,6 +29386,12 @@ msgstr "Швидкий діапазон"
msgid "Quickly and easily edit multiple files in your project."
msgstr "Швидко і легко редагувати декілька файлів у вашому проєкті."
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr "ІнÑÑ‚Ñ€ÑƒÐºÑ†Ñ–Ñ (README)"
@@ -29134,9 +29579,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr "Перегенерувати ідентифікатор інÑтанÑу"
-msgid "Regenerate key"
-msgstr "Створити ключ заново"
-
msgid "Regenerate recovery codes"
msgstr "Перегенерувати коди відновленнÑ"
@@ -29179,6 +29621,54 @@ msgstr "ЗареєÑтрувати за допомогою двофакторнÐ
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29507,10 +29997,10 @@ msgstr "Видалено оцінку чаÑу."
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29577,7 +30067,7 @@ msgid "Reopen %{issueType}"
msgstr "Повторно відкрити %{issueType}"
msgid "Reopen %{noteable}"
-msgstr ""
+msgstr "Повторно відкрити %{noteable}"
msgid "Reopen epic"
msgstr "Повторне Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ ÐµÐ¿Ñ–ÐºÑƒ"
@@ -30206,6 +30696,9 @@ msgstr "Продовжити"
msgid "Resync"
msgstr "Повторна ÑинхронізаціÑ"
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr "Спробувати знову"
@@ -30215,6 +30708,12 @@ msgstr "Повторити завданнÑ"
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr "Повторити це завданнÑ"
@@ -30401,7 +30900,7 @@ msgid "Runners|Active"
msgstr "Ðктивні"
msgid "Runners|All"
-msgstr ""
+msgstr "Ð’ÑÑ–"
msgid "Runners|Amazon Linux 2 Docker HA with manual scaling and optional scheduling. %{percentage} spot."
msgstr ""
@@ -30415,9 +30914,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr "Ðрхітектура"
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30437,6 +30933,12 @@ msgid "Runners|Copy instructions"
msgstr ""
msgid "Runners|Copy registration token"
+msgstr "Скопіювати токен Ð´Ð»Ñ Ñ€ÐµÑ”Ñтрації"
+
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
msgstr ""
msgid "Runners|Deploy GitLab Runner in AWS"
@@ -30458,7 +30960,7 @@ msgid "Runners|For each solution, you will choose a capacity. 1 enables warm HA
msgstr ""
msgid "Runners|Group"
-msgstr ""
+msgstr "Група"
msgid "Runners|Group Runners"
msgstr "Групові Runner'и"
@@ -30473,7 +30975,7 @@ msgid "Runners|Install a runner"
msgstr "Ð’Ñтановити runner"
msgid "Runners|Instance"
-msgstr ""
+msgstr "ІнÑтанÑ"
msgid "Runners|Last contact"
msgstr "ОÑтанній контакт"
@@ -30490,19 +30992,22 @@ msgstr ""
msgid "Runners|Name"
msgstr "Ім'Ñ"
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30521,7 +31026,7 @@ msgid "Runners|Platform"
msgstr "Платформа"
msgid "Runners|Project"
-msgstr ""
+msgstr "Проєкт"
msgid "Runners|Property Name"
msgstr ""
@@ -30556,6 +31061,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30593,7 +31101,7 @@ msgid "Runners|Show Runner installation instructions"
msgstr ""
msgid "Runners|Show runner installation and registration instructions"
-msgstr ""
+msgstr "Показати інÑтрукції Ð´Ð»Ñ Ð²ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñ‚Ð° реєÑтрації runner"
msgid "Runners|Something went wrong while fetching runner data."
msgstr ""
@@ -30601,16 +31109,22 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
-msgid "Runners|Status"
+msgid "Runners|Stale"
msgstr ""
+msgid "Runners|Status"
+msgstr "СтатуÑ"
+
msgid "Runners|Stop the runner from accepting new jobs."
msgstr ""
msgid "Runners|Tags"
msgstr "Теги"
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30671,7 +31185,7 @@ msgid "Runners|You have used %{quotaUsed} out of %{quotaLimit} of your shared Ru
msgstr "Ви викориÑтали %{quotaUsed} із ваших %{quotaLimit} хвилин Ð´Ð»Ñ ÐºÐ¾Ð½Ð²ÐµÑ”Ñ€Ñ–Ð² загальних runner'ів."
msgid "Runners|active"
-msgstr ""
+msgstr "активні"
msgid "Runners|group"
msgstr "Група"
@@ -30679,14 +31193,14 @@ msgstr "Група"
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
-msgstr ""
+msgstr "офлайн"
msgid "Runners|online"
-msgstr ""
+msgstr "онлайн"
msgid "Runners|paused"
msgstr ""
@@ -30697,6 +31211,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr "ВиконуєтьÑÑ"
@@ -30958,6 +31475,9 @@ msgstr "Шукати цей текÑÑ‚"
msgid "Search forks"
msgstr "Пошук форків"
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30979,9 +31499,6 @@ msgstr "Шукати чи фільтрувати результати..."
msgid "Search or filter results…"
msgstr "Шукати чи фільтрувати результати…"
-msgid "Search or jump to..."
-msgstr "Шукати чи перейти до..."
-
msgid "Search project"
msgstr "Пошук в проєкті"
@@ -31210,13 +31727,13 @@ msgid "SecurityApprovals|Coverage-Check"
msgstr ""
msgid "SecurityApprovals|Learn more about Coverage-Check"
-msgstr ""
+msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про Coverage-Check"
msgid "SecurityApprovals|Learn more about License-Check"
-msgstr ""
+msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про License-Check"
msgid "SecurityApprovals|Learn more about Vulnerability-Check"
-msgstr ""
+msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про Vulnerity-Check"
msgid "SecurityApprovals|License-Check"
msgstr ""
@@ -31284,6 +31801,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -31356,6 +31876,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31410,6 +31933,9 @@ msgstr "Мережа"
msgid "SecurityOrchestration|New policy"
msgstr "Ðова політика"
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31494,9 +32020,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31695,6 +32218,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr "Рівень"
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31707,6 +32233,9 @@ msgstr "СтатуÑ"
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31782,6 +32311,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31935,6 +32467,9 @@ msgstr "Вибрати проєкт та зону Ð´Ð»Ñ Ð²Ð¸Ð±Ð¾Ñ€Ñƒ типу Ð
msgid "Select project to choose zone"
msgstr "Вибрати проєкт Ð´Ð»Ñ Ð²Ð¸Ð±Ð¾Ñ€Ñƒ зони"
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31963,7 +32498,7 @@ msgid "Select strategy activation method"
msgstr ""
msgid "Select subgroup"
-msgstr ""
+msgstr "Вибрати підгрупи"
msgid "Select subscription"
msgstr "Виберіть підпиÑку"
@@ -32257,7 +32792,7 @@ msgid "ServicePing|Turn on service ping to review instance-level analytics."
msgstr ""
msgid "Services"
-msgstr ""
+msgstr "СервіÑи"
msgid "Session ID"
msgstr ""
@@ -32286,6 +32821,12 @@ msgstr "Ð’Ñтановіть Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð° замовчуваннÑм Ñ–
msgid "Set due date"
msgstr "Ð’Ñтановити дату завершеннÑ"
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr "Ð’Ñтановити ітерацію"
@@ -32442,6 +32983,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr "Ð’Ñтановлює %{epic_ref} Ñк батьківÑький епік."
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr "Ð’Ñтановлює цільову гілку %{branch_name}."
@@ -32842,7 +33386,7 @@ msgid "Site profile not found for given parameters"
msgstr ""
msgid "Sites"
-msgstr ""
+msgstr "Сайти"
msgid "Size"
msgstr "Розмір"
@@ -33147,6 +33691,9 @@ msgstr "ЩоÑÑŒ пішо не так під Ñ‡Ð°Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð²Ð¸Ð¼Ð¾Ð
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr "ЩоÑÑŒ пішло не так під Ñ‡Ð°Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÑпиÑків"
@@ -33591,9 +34138,6 @@ msgstr ""
msgid "Start your free trial"
msgstr "Розпочати безкоштовний випробувальний період"
-msgid "Start your trial"
-msgstr "Розпочати пробний період"
-
msgid "Started"
msgstr "Запущений"
@@ -33877,7 +34421,7 @@ msgid "Subgroup information"
msgstr "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ підгрупу"
msgid "Subgroup milestone"
-msgstr ""
+msgstr "Етап підгрупи"
msgid "Subgroup navigation"
msgstr ""
@@ -33990,6 +34534,12 @@ msgstr "ПідпиÑку уÑпішно Ñтворено."
msgid "Subscription successfully deleted."
msgstr "ПідпиÑку уÑпішно видалено."
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34425,6 +34975,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr "СиÑтемні"
@@ -34697,9 +35265,29 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr "Ðе вдалоÑÑ Ñтворити звіт."
@@ -34730,6 +35318,9 @@ msgstr "Деталі"
msgid "Terraform|Download JSON"
msgstr "Завантажити JSON"
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34742,6 +35333,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr "Стан завданнÑ"
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr "БлокуваннÑ"
@@ -34778,12 +35372,21 @@ msgstr "Стан"
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -35075,6 +35678,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "Ð—â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ припинено піÑÐ»Ñ %{timeout}. Ð”Ð»Ñ Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ñ–Ñ—Ð², Ñким потрібно більше чаÑу, викориÑтовуйте комбінацію clone/push."
@@ -35199,9 +35805,6 @@ msgstr "Ð¦Ñ Ð³Ñ€ÑƒÐ¿Ð° та будь-Ñкі проєкти можуть перÐ
msgid "The group and its projects can only be viewed by members."
msgstr "Ð¦Ñ Ð³Ñ€ÑƒÐ¿Ð° та Ñ—Ñ— проєкти видимі тільки Ð´Ð»Ñ ÑƒÑ‡Ð°Ñників."
-msgid "The group can be fully restored"
-msgstr "Цю групу можна повніÑÑ‚ÑŽ відновити"
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -35211,9 +35814,6 @@ msgstr "Група вже Ñ–Ñнує в цій групі"
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr "Групові Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ %{group_links} вимагають, щоб ви увімкнули двофакторну автентифікацію Ð´Ð»Ñ Ñвого облікового запиÑу. Ви можете %{leave_group_links}."
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -35286,7 +35886,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35541,9 +36141,6 @@ msgstr "Ðемає задач Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ"
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr "Тут ще немає міток"
-
msgid "There are no matching files"
msgstr "Ðемає відповідних файлів"
@@ -35889,6 +36486,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35901,9 +36501,6 @@ msgstr "Ð¦Ñ Ð´Ñ–Ñ Ð¼Ð¾Ð¶Ðµ призвеÑти до втрати даних. Щ
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35928,6 +36525,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr "Ð¦Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð° зможе:"
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -36042,6 +36642,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -36207,6 +36810,9 @@ msgstr "Ð—Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð²Ð¸Ð¼Ð°Ð³Ð°Ñ” ручних дій"
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr "Ð”Ð»Ñ Ð·Ð°Ð¿ÑƒÑку цього Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð½ÐµÐ¾Ð±Ñ…Ñ–Ð´Ð½Ðµ ручне втручаннÑ. Перед його запуÑком можна додати змінні нижче Ð´Ð»Ñ Ð¾Ñтанніх змін у конфігурації."
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr "Ð—Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ запущено автоматично піÑÐ»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ‚Ð°Ð¹Ð¼ÐµÑ€Ð°. Зазвичай вони викориÑтовуютьÑÑ Ð´Ð»Ñ Ñ–Ð½ÐºÑ€ÐµÐ¼ÐµÐ½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð² production Ñередовище. У разі ÑкаÑÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð²Ð¾Ð½Ð¾ перетворитьÑÑ Ð½Ð° ручну операцію."
@@ -36923,6 +37529,9 @@ 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 "Ð”Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½ÑŒ від ÑервіÑів Prometheus, Ñкі Ñконфігуровані вручну, додайте наÑтупний URL та ключ авторизаціх до вашого конфігураційного файлу веб-хуків Prometheus. ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про %{linkStart}ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€ÑƒÐ²Ð°Ð½Ñ Prometheus%{linkEnd} Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб відправлÑти Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½Ð½Ñ Ñ–Ð· Gitlab."
+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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36989,6 +37598,39 @@ msgstr "ÐÐ°Ð³Ð°Ð´ÑƒÐ²Ð°Ð½Ð½Ñ ÑƒÑпішно позначене Ñк викон
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -37163,6 +37805,9 @@ msgstr ""
msgid "Transfer"
msgstr "Передача"
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr "Змінити відповідального"
@@ -37287,15 +37932,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -37320,9 +37956,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr "Тригер"
@@ -37939,7 +38572,7 @@ msgid "Upload license"
msgstr ""
msgid "Upload new file"
-msgstr ""
+msgstr "Завантажити новий файл"
msgid "Upload object map"
msgstr "Завантажити файл відповідноÑÑ‚Ñ– об’єктів"
@@ -37950,9 +38583,6 @@ msgstr "ÐатиÑніть, щоб надіÑлати"
msgid "Uploading changes to terminal"
msgstr "Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð¼Ñ–Ð½ до терміналу"
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr "Попередній"
@@ -38023,7 +38653,7 @@ msgid "UsageQuota|Learn more about excess storage usage"
msgstr ""
msgid "UsageQuota|Learn more about usage quotas"
-msgstr ""
+msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про викориÑÑ‚Ð°Ð½Ð½Ñ ÐºÐ²Ð¾Ñ‚"
msgid "UsageQuota|No CI minutes usage data available."
msgstr ""
@@ -38632,7 +39262,7 @@ msgid "Username or email"
msgstr "Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача або електронна пошта"
msgid "Username:"
-msgstr ""
+msgstr "Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача:"
msgid "Username: %{username}"
msgstr "Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача: %{username}"
@@ -38844,16 +39474,16 @@ msgstr ""
msgid "Verification status"
msgstr "Стан перевірки"
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38895,6 +39525,9 @@ msgstr ""
msgid "View all issues"
msgstr "ПроглÑнути вÑÑ– задачі"
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38920,6 +39553,9 @@ msgstr "ПереглÑнути деталі: %{details_url}"
msgid "View documentation"
msgstr "ПереглÑнути документацію"
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr "ПереглÑнути доÑтупних оÑіб Ð´Ð»Ñ Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ"
@@ -38951,6 +39587,12 @@ msgstr ""
msgid "View group labels"
msgstr "ПереглÑнути мітки групи"
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -39045,6 +39687,9 @@ msgstr ""
msgid "Viewing commit"
msgstr "ПереглÑд коміту"
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr "ВидиміÑÑ‚ÑŒ"
@@ -39126,12 +39771,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr "Змінити ÑтатуÑ"
@@ -39159,6 +39816,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39228,9 +39888,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr "Додаткова інформаціÑ"
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr "КлаÑ"
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -39246,21 +39915,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr "ОпиÑ"
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr "Дані"
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr "Файл"
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -39270,6 +39951,9 @@ msgstr "Ідентифікатори"
msgid "Vulnerability|Image"
msgstr "Образ"
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr "ПоÑиланнÑ"
@@ -39294,6 +39978,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr "Рівень"
@@ -39417,6 +40110,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr "Це допоможе нам предÑтавити вам перÑоналізовані функції та інформацію."
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr "Ми не виÑвили вразливоÑтей"
@@ -39436,10 +40132,10 @@ msgid "WebAuthn only works with HTTPS-enabled websites. Contact your administrat
msgstr ""
msgid "WebIDE|Fork project"
-msgstr ""
+msgstr "Форк проєкту"
msgid "WebIDE|Go to fork"
-msgstr ""
+msgstr "Перейти до форку"
msgid "WebIDE|Merge request"
msgstr "Запит на злиттÑ"
@@ -39504,6 +40200,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39540,6 +40242,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39597,11 +40308,20 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
msgid "Website:"
-msgstr ""
+msgstr "Сайт:"
msgid "Wednesday"
msgstr "Середа"
@@ -39633,6 +40353,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39642,9 +40365,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr "Що ви шукаєте?"
@@ -39673,7 +40393,7 @@ 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 ""
@@ -39884,7 +40604,7 @@ msgid "WikiPage|Edit source"
msgstr ""
msgid "WikiPage|Format"
-msgstr ""
+msgstr "Формат"
msgid "WikiPage|Get a richer editing experience"
msgstr ""
@@ -39893,7 +40613,7 @@ msgid "WikiPage|Keep editing"
msgstr "Продовжити редагуваннÑ"
msgid "WikiPage|Learn more."
-msgstr ""
+msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ."
msgid "WikiPage|Page title"
msgstr ""
@@ -40484,6 +41204,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr "У Ð²Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” прав доÑтупу"
@@ -40673,6 +41399,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40964,6 +41696,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -41210,6 +41945,9 @@ msgstr "не може блокувати Ñам Ñебе"
msgid "cannot merge"
msgstr "не може виконувати злиттÑ"
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -41240,7 +41978,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr "%{linkStartTag}ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про звіти про ÑкіÑÑ‚ÑŒ коду %{linkEndTag}"
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -41288,8 +42026,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41385,8 +42123,8 @@ msgstr "ДоÑлідити цю вразливіÑÑ‚ÑŒ, Ñтворивши заÐ
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -41552,6 +42290,9 @@ msgstr "коміт %{commit_id}"
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41608,7 +42349,7 @@ msgstr[2] "днів"
msgstr[3] "днів"
msgid "days"
-msgstr ""
+msgstr "дні"
msgid "default branch"
msgstr "гілка за замовчуваннÑм"
@@ -42008,9 +42749,6 @@ msgstr ""
msgid "missing"
msgstr "відÑутні"
-msgid "more information"
-msgstr "детальніше"
-
msgid "most recent deployment"
msgstr "оÑтаннє розгортаннÑ"
@@ -42185,7 +42923,7 @@ msgstr[2] ""
msgstr[3] ""
msgid "mrWidget|Merge"
-msgstr "ЗлиттÑ"
+msgstr "Об'єднати"
msgid "mrWidget|Merge blocked: all threads must be resolved."
msgstr ""
@@ -42370,6 +43108,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42469,9 +43210,6 @@ msgstr "відкрито %{timeAgo}"
msgid "or"
msgstr "або"
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/ur_PK/gitlab.po b/locale/ur_PK/gitlab.po
index d90a7070de2..dcc18474ef3 100644
--- a/locale/ur_PK/gitlab.po
+++ b/locale/ur_PK/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ur-PK\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:56\n"
+"PO-Revision-Date: 2022-01-06 17:20\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/uz_UZ/gitlab.po b/locale/uz_UZ/gitlab.po
index c46180fed00..d4cdc3f7fd4 100644
--- a/locale/uz_UZ/gitlab.po
+++ b/locale/uz_UZ/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: uz\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 19:00\n"
+"PO-Revision-Date: 2022-01-06 17:24\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -838,6 +838,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -1035,6 +1038,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1151,6 +1160,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1218,6 +1230,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1544,6 +1559,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1790,6 +1808,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1802,12 +1829,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1865,6 +1901,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1889,6 +1955,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1994,7 +2063,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2420,6 +2489,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2696,7 +2774,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2981,6 +3059,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3371,6 +3452,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3575,6 +3659,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3602,9 +3689,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3785,6 +3869,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3794,6 +3881,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3943,6 +4033,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4272,9 +4368,15 @@ msgstr[1] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4305,6 +4407,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4314,6 +4419,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4338,6 +4452,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4365,6 +4482,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4401,7 +4521,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4571,9 +4691,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4721,6 +4838,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -5118,9 +5238,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5370,9 +5487,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5403,13 +5517,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5421,7 +5532,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5433,9 +5547,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5621,7 +5741,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5982,7 +6102,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5991,6 +6114,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -6030,6 +6156,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6734,7 +6863,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6996,9 +7125,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7209,6 +7335,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7227,9 +7356,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7383,12 +7518,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7401,6 +7551,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7416,9 +7572,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7464,12 +7626,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7545,6 +7716,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7563,12 +7737,26 @@ 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 ""
+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] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7578,6 +7766,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8765,6 +8956,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9186,6 +9386,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9275,6 +9478,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9506,12 +9712,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9542,9 +9754,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9884,9 +10093,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9917,6 +10123,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9959,9 +10168,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9971,13 +10177,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10157,15 +10366,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10175,15 +10402,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10334,15 +10570,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -11027,6 +11254,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11306,6 +11536,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11339,15 +11572,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11480,6 +11707,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11504,7 +11734,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11513,6 +11743,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12315,15 +12548,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12464,6 +12697,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12599,7 +12835,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12638,6 +12874,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13579,6 +13818,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13624,9 +13866,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13780,9 +14019,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13867,6 +14103,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14052,9 +14291,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14247,7 +14483,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14955,9 +15191,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15288,6 +15521,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -16149,9 +16385,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16239,6 +16472,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16428,9 +16664,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16557,6 +16790,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16659,9 +16895,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16734,6 +16979,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16773,6 +17021,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16806,6 +17057,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16830,7 +17093,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16839,7 +17102,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16881,6 +17144,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16908,12 +17174,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -17028,6 +17300,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -17082,6 +17357,9 @@ 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 ""
+
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 ""
@@ -18990,6 +19268,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19239,9 +19520,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19344,9 +19622,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19458,9 +19733,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -20106,7 +20378,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20558,6 +20830,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21319,7 +21597,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -22075,10 +22353,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22177,6 +22455,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22796,6 +23077,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22999,6 +23283,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23212,6 +23529,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23436,6 +23756,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23855,6 +24178,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23867,7 +24193,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24274,6 +24600,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24292,12 +24624,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24337,12 +24675,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24367,18 +24714,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24388,9 +24750,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24549,6 +24908,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -25088,9 +25450,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25280,9 +25639,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25382,6 +25747,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25463,12 +25831,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25700,6 +26062,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25919,9 +26284,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26198,6 +26560,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26210,6 +26578,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26405,9 +26776,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26759,6 +27127,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26816,6 +27187,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26900,6 +27277,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27194,6 +27574,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27320,6 +27742,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27572,19 +27997,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27740,6 +28162,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -28124,9 +28555,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -28139,9 +28567,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -28166,9 +28591,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28250,6 +28672,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28295,9 +28720,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28340,6 +28771,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28355,6 +28789,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28583,6 +29020,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28768,9 +29211,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28813,6 +29253,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -29139,10 +29627,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29826,6 +30314,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29835,6 +30326,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -30031,9 +30528,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30055,6 +30549,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -30106,19 +30606,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -30172,6 +30675,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30217,6 +30723,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30226,7 +30735,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30295,7 +30807,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30313,6 +30825,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30574,6 +31089,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30595,9 +31113,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30878,6 +31393,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30950,6 +31468,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -31004,6 +31525,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -31088,9 +31612,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31289,6 +31810,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31301,6 +31825,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31376,6 +31903,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31529,6 +32059,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31880,6 +32413,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -32036,6 +32575,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32735,6 +33277,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -33179,9 +33724,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33578,6 +34120,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -34013,6 +34561,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34281,9 +34847,25 @@ msgid_plural "Terraform|%{number} Terraform reports were generated in your pipel
msgstr[0] ""
msgstr[1] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34314,6 +34896,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34326,6 +34911,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34362,12 +34950,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34653,6 +35250,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34775,9 +35375,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34787,9 +35384,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34862,7 +35456,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -35117,9 +35711,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35465,6 +36056,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35477,9 +36071,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35504,6 +36095,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35618,6 +36212,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35783,6 +36380,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36495,6 +37095,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36561,6 +37164,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36735,6 +37371,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36857,15 +37496,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36890,9 +37520,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37520,9 +38147,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38414,16 +39038,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38465,6 +39089,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38488,6 +39115,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38517,6 +39147,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38609,6 +39245,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38690,12 +39329,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38723,6 +39374,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38792,9 +39446,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38810,21 +39473,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38834,6 +39509,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38858,6 +39536,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38981,6 +39668,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -39068,6 +39758,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -39104,6 +39800,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -39161,6 +39866,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -39197,6 +39911,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -39206,9 +39923,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -40044,6 +40758,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40233,6 +40953,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40524,6 +41250,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40764,6 +41493,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40794,7 +41526,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40842,8 +41574,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -40937,8 +41669,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41100,6 +41832,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41544,9 +42279,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41902,6 +42634,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -42001,9 +42736,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/vi_VN/gitlab.po b/locale/vi_VN/gitlab.po
index 7f2bda8478a..3fc58c5a26d 100644
--- a/locale/vi_VN/gitlab.po
+++ b/locale/vi_VN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: vi\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:55\n"
+"PO-Revision-Date: 2022-01-06 17:19\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -486,7 +486,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -760,6 +760,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -947,6 +950,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1062,6 +1071,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1127,6 +1139,9 @@ msgstr ""
msgid ", or "
msgstr ""
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1428,6 +1443,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1674,6 +1692,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1686,12 +1713,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1749,6 +1785,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1773,6 +1839,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1878,7 +1947,7 @@ msgstr ""
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2304,6 +2373,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2580,7 +2658,7 @@ msgstr ""
msgid "AdminUsers|Delete user and contributions"
msgstr ""
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2865,6 +2943,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3255,6 +3336,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3459,6 +3543,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3486,9 +3573,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr ""
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3669,6 +3753,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3678,6 +3765,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3826,6 +3916,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4148,9 +4244,15 @@ msgstr[0] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4181,6 +4283,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4190,6 +4295,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4214,6 +4328,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4241,6 +4358,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4277,7 +4397,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4446,9 +4566,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4596,6 +4713,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -4991,9 +5111,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5243,9 +5360,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5276,13 +5390,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5294,7 +5405,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5306,9 +5420,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5493,7 +5613,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5852,7 +5972,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5861,6 +5984,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -5900,6 +6026,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6603,7 +6732,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6863,9 +6992,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7076,6 +7202,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7094,9 +7223,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7250,12 +7385,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7268,6 +7418,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7283,9 +7439,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7331,12 +7493,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7412,6 +7583,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7430,12 +7604,25 @@ 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 ""
+msgid "ClusterAgents|There's no activity from the past day"
+msgid_plural "ClusterAgents|There's no activity from the past %d days"
+msgstr[0] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7445,6 +7632,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8631,6 +8821,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9050,6 +9249,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9138,6 +9340,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9369,12 +9574,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9405,9 +9616,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9747,9 +9955,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9780,6 +9985,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9822,9 +10030,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9834,13 +10039,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10020,15 +10228,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10038,15 +10264,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10197,15 +10432,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -10887,6 +11113,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11166,6 +11395,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11199,15 +11431,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11337,6 +11563,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11361,7 +11590,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11370,6 +11599,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12164,15 +12396,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12312,6 +12544,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12447,7 +12682,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12486,6 +12721,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13426,6 +13664,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13471,9 +13712,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13627,9 +13865,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13714,6 +13949,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -13898,9 +14136,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14093,7 +14328,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14798,9 +15033,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15131,6 +15363,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -15992,9 +16227,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16082,6 +16314,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16271,9 +16506,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16400,6 +16632,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16502,9 +16737,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16577,6 +16821,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16616,6 +16863,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16649,6 +16899,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16673,7 +16935,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16682,7 +16944,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16724,6 +16986,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16751,12 +17016,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -16871,6 +17142,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -16925,6 +17199,9 @@ 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 ""
+
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 ""
@@ -18827,6 +19104,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19076,9 +19356,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19181,9 +19458,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19295,9 +19569,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -19943,7 +20214,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20394,6 +20665,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21148,7 +21425,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -21904,10 +22181,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22006,6 +22283,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22623,6 +22903,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22825,6 +23108,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23038,6 +23354,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23261,6 +23580,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23679,6 +24001,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23691,7 +24016,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24094,6 +24419,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24112,12 +24443,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24157,12 +24494,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24187,18 +24533,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24208,9 +24569,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24368,6 +24726,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -24906,9 +25267,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25098,9 +25456,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25200,6 +25564,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25281,12 +25648,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25518,6 +25879,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25737,9 +26101,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26016,6 +26377,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26028,6 +26395,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26223,9 +26593,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26577,6 +26944,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26634,6 +27004,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26718,6 +27094,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27012,6 +27391,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27138,6 +27559,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27390,19 +27814,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27558,6 +27979,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -27942,9 +28372,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27957,9 +28384,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -27984,9 +28408,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28068,6 +28489,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28113,9 +28537,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28158,6 +28588,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28173,6 +28606,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28401,6 +28837,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28585,9 +29027,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28630,6 +29069,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -28955,10 +29442,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29636,6 +30123,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29645,6 +30135,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -29839,9 +30335,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -29863,6 +30356,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -29914,19 +30413,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -29980,6 +30482,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30025,6 +30530,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30034,7 +30542,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30103,7 +30614,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30121,6 +30632,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30382,6 +30896,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30403,9 +30920,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30675,6 +31189,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30747,6 +31264,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -30801,6 +31321,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -30885,9 +31408,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31086,6 +31606,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31098,6 +31621,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31173,6 +31699,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31326,6 +31855,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31677,6 +32209,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -31833,6 +32371,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32529,6 +33070,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -32973,9 +33517,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33372,6 +33913,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -33807,6 +34354,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34073,9 +34638,23 @@ msgid "Terraform|%{number} Terraform report was generated in your pipelines"
msgid_plural "Terraform|%{number} Terraform reports were generated in your pipelines"
msgstr[0] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34106,6 +34685,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34118,6 +34700,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34154,12 +34739,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34442,6 +35036,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34563,9 +35160,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34575,9 +35169,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34650,7 +35241,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -34905,9 +35496,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35253,6 +35841,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35265,9 +35856,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35292,6 +35880,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35406,6 +35997,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35571,6 +36165,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36281,6 +36878,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36347,6 +36947,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36521,6 +37154,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36642,15 +37278,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36675,9 +37302,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37305,9 +37929,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38199,16 +38820,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38250,6 +38871,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38272,6 +38896,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38300,6 +38927,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38391,6 +39024,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38472,12 +39108,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38505,6 +39153,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38574,9 +39225,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38592,21 +39252,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38616,6 +39288,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38640,6 +39315,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38763,6 +39447,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -38850,6 +39537,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -38886,6 +39579,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -38943,6 +39645,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -38979,6 +39690,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -38988,9 +39702,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -39824,6 +40535,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40013,6 +40730,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40304,6 +41027,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40541,6 +41267,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40571,7 +41300,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40619,8 +41348,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgid "ciReport|Browser performance test metrics: No changes"
@@ -40713,8 +41442,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgid "ciReport|Load performance test metrics results are being parsed"
@@ -40874,6 +41603,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41312,9 +42044,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41668,6 +42397,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -41767,9 +42499,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/zh_CN/gitlab.po b/locale/zh_CN/gitlab.po
index 26dfbd221d9..25d863b5e63 100644
--- a/locale/zh_CN/gitlab.po
+++ b/locale/zh_CN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: zh-CN\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:56\n"
+"PO-Revision-Date: 2022-01-06 17:20\n"
msgid " %{start} to %{end}"
msgstr "从%{start}到%{end}"
@@ -206,7 +206,7 @@ msgstr[0] "%d个修å¤çš„测试结果"
msgid "%d fork"
msgid_plural "%d forks"
-msgstr[0] ""
+msgstr[0] "%d 个派生"
msgid "%d group"
msgid_plural "%d groups"
@@ -250,7 +250,7 @@ msgstr[0] "%d个您无法访问的åˆå¹¶è¯·æ±‚。"
msgid "%d merge requests"
msgid_plural "%d merge requests"
-msgstr[0] ""
+msgstr[0] "%d 个åˆå¹¶è¯·æ±‚"
msgid "%d metric"
msgid_plural "%d metrics"
@@ -306,7 +306,7 @@ msgstr[0] "选中了%d个分片"
msgid "%d star"
msgid_plural "%d stars"
-msgstr[0] ""
+msgstr[0] "%d 个星标"
msgid "%d tag"
msgid_plural "%d tags"
@@ -352,10 +352,10 @@ msgid "%{actionText} & %{openOrClose} %{noteable}"
msgstr "%{actionText} 和 %{openOrClose} %{noteable}"
msgid "%{actionText} & close %{noteable}"
-msgstr ""
+msgstr "%{actionText} & 关闭 %{noteable}"
msgid "%{actionText} & reopen %{noteable}"
-msgstr ""
+msgstr "%{actionText} & é‡æ–°æ‰“å¼€ %{noteable}"
msgid "%{address} is an invalid IP address range"
msgstr "%{address}为无效的IP地å€èŒƒå›´"
@@ -430,7 +430,7 @@ msgstr "æ¥è‡ª%{name}çš„%{count}个核准"
msgid "%{count} contact"
msgid_plural "%{count} contacts"
-msgstr[0] ""
+msgstr[0] "%{count} 个è”系人"
msgid "%{count} files touched"
msgstr "已选择 %{count} 个文件"
@@ -486,8 +486,8 @@ msgstr "%{deployLinkStart}使用模æ¿éƒ¨ç½²åˆ°ECS%{deployLinkEnd},或使用do
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
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; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
-msgstr "%{doc_link_start}高级æœç´¢%{doc_link_end} 被ç¦ç”¨ï¼Œå› ä¸º %{ref_elem} ä¸æ˜¯é»˜è®¤åˆ†æ”¯ï¼› %{default_branch_link_start}æœç´¢ %{default_branch} %{default_branch_link_end}。"
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
+msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
msgstr "%{doc_link_start}高级æœç´¢%{doc_link_end} å·²å¯ç”¨ã€‚"
@@ -652,7 +652,7 @@ 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}What information does GitLab Inc. collect?%{link_end}"
msgstr "%{link_start}GitLab Inc. 收集哪些信æ¯ï¼Ÿ%{link_end}"
@@ -706,7 +706,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}"
@@ -760,11 +760,14 @@ msgstr "%{placeholder}ä¸æ˜¯æœ‰æ•ˆçš„é…色主题"
msgid "%{placeholder} is not a valid theme"
msgstr "%{placeholder}ä¸æ˜¯æœ‰æ•ˆçš„主题"
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr "%{policy_link} (在 %{elapsed_time} 分钟åŽå‘出通知, 除éžçŠ¶æ€ä¸º %{status})"
+
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
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} 是一个项目,您å¯ä»¥ä½¿ç”¨è¯¥é¡¹ç›®å°†è‡ªè¿°æ–‡ä»¶æ·»åŠ åˆ°æ‚¨çš„ GitLab é…置文件中,创建一个公共项目并使用 README åˆå§‹åŒ–仓库以开始使用。 %{help_link_start}了解更多。%{help_link_end}"
msgid "%{ref} cannot be added: %{error}"
msgstr "无法添加%{ref}:%{error}"
@@ -798,7 +801,7 @@ msgid "%{scope} results for term '%{term}'"
msgstr "'%{term}' 的结果 %{scope} "
msgid "%{search} %{description} %{scope}"
-msgstr ""
+msgstr "%{search} %{description} %{scope}"
msgid "%{seconds}s"
msgstr "%{seconds}秒"
@@ -936,7 +939,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} (æ— æƒåˆå¹¶)"
@@ -947,6 +950,12 @@ msgstr "%{userName} 的头åƒ"
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr "%{user_name}(%{user_username})已从%{project}项目中的%{schedule}计划中的%{rotation} è½®æ¢ä¸­åˆ é™¤ 。 "
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr "%{user_name} (%{user_username}) 已从 %{project_link} 的以下å‡çº§ç­–略中删除: "
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr "%{user_name} (%{user_username}) 已从 %{project} 的以下å‡çº§ç­–略中删除:"
+
msgid "%{user_name} profile page"
msgstr "%{user_name}的个人资料"
@@ -1062,6 +1071,9 @@ msgstr "(如果您ä¸æƒ³æ›´æ”¹ï¼Œè¯·ç•™ç©º)"
msgid "(max size 15 MB)"
msgstr "(最大 15 MB)"
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr "(已删除)"
@@ -1070,7 +1082,7 @@ msgstr "(已撤销)"
msgid "(squashes %d commit)"
msgid_plural "(squashes %d commits)"
-msgstr[0] ""
+msgstr[0] "(压缩 %d 个æ交)"
msgid "(this user)"
msgstr "(此用户)"
@@ -1082,7 +1094,7 @@ msgid "* All times are in UTC unless specified"
msgstr "* 除éžå¦æœ‰è¯´æ˜Žï¼Œå¦åˆ™æ‰€æœ‰æ—¶é—´å‡ä¸º UTC"
msgid "*Required"
-msgstr ""
+msgstr "*å¿…å¡«"
msgid "+ %{amount} more"
msgstr "+ 其余 %{amount} 项"
@@ -1122,11 +1134,14 @@ msgid "+%{tags} more"
msgstr "+其余%{tags}个"
msgid ", and "
-msgstr ""
+msgstr ", 和 "
msgid ", or "
msgstr ",或"
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr "- %{policy_name} (在 %{elapsed_time} 分钟åŽå‘出通知, 除éžçŠ¶æ€ä¸º %{status})"
+
msgid "- Available to run jobs."
msgstr "å¯ç”¨äºŽè¿è¡Œä½œä¸šã€‚"
@@ -1428,6 +1443,9 @@ msgstr "项目包å«ç¾Žå›½å«ç”Ÿä¸Žå…¬å…±æœåŠ¡éƒ¨å‘布的HIPAA审计å议中æ
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr "一个项目的仓库å称定义了它的URL(用æ¥é€šè¿‡æµè§ˆå™¨è®¿é—®é¡¹ç›®ï¼‰ä»¥åŠå®ƒåœ¨å®‰è£…GitLab 的文件ç£ç›˜ä¸Šçš„ä½ç½®ã€‚ %{link_start}了解更多。%{link_end}"
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr "季度对账在 %{date}"
+
msgid "A ready-to-go template for use with Android apps"
msgstr "适用于 Android 应用的éšæ—¶å¯ç”¨çš„模æ¿"
@@ -1674,6 +1692,15 @@ msgstr "您确定é‡ç½®Feed令牌å—?当å‰æ­£åœ¨ä½¿ç”¨çš„所有RSS或日历UR
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr "你确定è¦é‡ç½®è¿›å…¥ç”µå­é‚®ä»¶ä»¤ç‰Œä¹ˆï¼Ÿæ‰€ä»¥ä½¿ç”¨å½“å‰ä»¤ç‰Œçš„议题邮件地å€éƒ½å°†åœæ­¢å·¥ä½œã€‚"
+msgid "AccessTokens|Copy feed token"
+msgstr "å¤åˆ¶ Feed 令牌"
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr "å¤åˆ¶æŽ¥æ”¶ç”µå­é‚®ä»¶ä»¤ç‰Œ"
+
+msgid "AccessTokens|Copy static object token"
+msgstr "å¤åˆ¶é™æ€å¯¹è±¡ä»¤ç‰Œ"
+
msgid "AccessTokens|Created"
msgstr "创建于"
@@ -1686,12 +1713,21 @@ msgstr "接收电å­é‚®ä»¶ä»¤ç‰Œ"
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 "将此令牌ä¿å¯†ã€‚任何拥有它的人都å¯ä»¥åƒæ‚¨ä¸€æ ·è®¿é—®ä»“库é™æ€å¯¹è±¡ã€‚如果å‘生,%{linkStart}é‡ç½®æ­¤ä»¤ç‰Œ%{linkEnd}。"
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr "请确ä¿è¯¥ä»¤ç‰Œçš„安全。任何æŒæœ‰è¯¥ä»¤ç‰Œçš„人,都å¯ä»¥ä»¥æ‚¨çš„身份æ¥åˆ›å»ºè®®é¢˜ã€‚如果令牌泄露,您应该%{reset_link_start}é‡ç½®ä»¤ç‰Œ %{reset_link_end} 。"
+msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{linkStart}reset this token%{linkEnd}."
+msgstr "将此令牌ä¿å¯†ã€‚任何拥有它的人都å¯ä»¥åƒæ‚¨ä¸€æ ·åˆ›å»ºè®®é¢˜ã€‚如果å‘生,%{linkStart}é‡ç½®æ­¤ä»¤ç‰Œ%{linkEnd}。"
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr "将此令牌ä¿å¯†ã€‚任何拥有它的人都å¯ä»¥åƒæ‚¨ä¸€æ ·åˆ›å»ºè®®é¢˜ã€‚如果å‘生这ç§æƒ…况, %{link_reset_it}。"
+msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{linkStart}reset this token%{linkEnd}."
+msgstr "将此令牌ä¿å¯†ã€‚任何拥有它的人都å¯ä»¥åƒæ‚¨ä¸€æ ·è¯»å–动æ€å¹¶å‘布 RSS feeds 或您的日历 feed。如果å‘生,%{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, %{link_reset_it}."
msgstr "将此令牌ä¿å¯†ã€‚任何拥有它的人都å¯ä»¥åƒæ‚¨ä¸€æ ·åˆ›å»ºè®®é¢˜ã€‚如果å‘生这ç§æƒ…况,访问%{link_reset_it}。"
@@ -1749,6 +1785,36 @@ msgstr "账户:"
msgid "Account: %{account}"
msgstr "å¸æˆ·ï¼š%{account}"
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr "通过验è¯æ‚¨çš„å¸æˆ·æ¥ä¿®å¤æ‚¨çš„æµæ°´çº¿"
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr "我è¦ä½¿ç”¨è‡ªå·±çš„ runner"
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr "了解更多。"
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 "å–消订阅"
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr "您å¯ä»¥éšæ—¶ %{unsubscribe_link}。"
+
msgid "Action"
msgstr "æ“作"
@@ -1773,6 +1839,9 @@ msgstr "有效的%{type}(%{token_length})"
msgid "Active Sessions"
msgstr "活动会è¯"
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "动æ€"
@@ -1870,7 +1939,7 @@ 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 "添加表格"
@@ -1878,8 +1947,8 @@ msgstr "添加表格"
msgid "Add a task list"
msgstr "添加任务列表"
-msgid "Add a title…"
-msgstr ""
+msgid "Add a title..."
+msgstr "添加标题..."
msgid "Add a to do"
msgstr "添加一个待办事项"
@@ -1924,16 +1993,16 @@ msgid "Add commit messages as comments to Pivotal Tracker stories. %{docs_link}"
msgstr "å°†æ交消æ¯ä½œä¸ºè¯„论添加到 Pivotal Tracker 故事。 %{docs_link}"
msgid "Add customer relation contact(s)."
-msgstr ""
+msgstr "添加客户关系è”系人。"
msgid "Add customer relation contacts"
-msgstr ""
+msgstr "添加客户关系è”系人"
msgid "Add deploy freeze"
msgstr "添加部署冻结"
msgid "Add deploy keys to grant read/write access to this repository. %{link_start}What are deploy keys?%{link_end}"
-msgstr "添加部署密钥以授予对此存储库的读/写访问æƒé™ã€‚ %{link_start}什么是部署密钥?%{link_end}"
+msgstr "添加部署密钥以授予对此仓库的读/写访问æƒé™ã€‚ %{link_start}什么是部署密钥?%{link_end}"
msgid "Add email address"
msgstr "添加电å­é‚®ä»¶åœ°å€"
@@ -2041,7 +2110,7 @@ msgid "Add variable"
msgstr "添加å˜é‡"
msgid "Add vulnerability finding"
-msgstr ""
+msgstr "添加æ¼æ´žå‘现"
msgid "Add webhook"
msgstr "添加webhook"
@@ -2131,7 +2200,7 @@ msgid "Adds %{labels} %{label_text}."
msgstr "添加%{labels}%{label_text}。"
msgid "Adds a Zoom meeting."
-msgstr ""
+msgstr "添加 Zoom 会议。"
msgid "Adds a to do."
msgstr "添加一个待办事项."
@@ -2140,7 +2209,7 @@ msgid "Adds an issue to an epic."
msgstr "将议题添加到å²è¯—。"
msgid "Adds email participant(s)."
-msgstr ""
+msgstr "添加电å­é‚®ä»¶å‚与者。"
msgid "Adjust how frequently the GitLab UI polls for updates."
msgstr "调整 GitLab UI 轮询更新的频率。"
@@ -2236,7 +2305,7 @@ msgid "AdminArea|Maintainer"
msgstr "维护者"
msgid "AdminArea|Minimal access"
-msgstr ""
+msgstr "最å°è®¿é—®æƒé™"
msgid "AdminArea|New group"
msgstr "新建群组"
@@ -2304,8 +2373,17 @@ msgstr "您å³å°†åœæ­¢æ‰€æœ‰ä½œä¸šï¼Œè¿™ä¼šä¸­æ–­å¹¶ç»“æŸæ‰€æœ‰æ­£åœ¨è¿è¡Œçš„
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "加载统计数æ®æ—¶å‡ºé”™ã€‚请å†è¯•ä¸€æ¬¡"
+msgid "AdminLabels|Define your default set of project labels"
+msgstr "定义项目标记的默认集"
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr "在此处创建的标记将自动添加到新的项目。"
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
+msgstr "您将è¦æ°¸ä¹…删除项目 %{projectName}〠其仓库以åŠæ‰€æœ‰ç›¸å…³çš„资æºï¼ŒåŒ…括议题和åˆå¹¶è¯·æ±‚。 当您确认并按 %{strong_start}删除项目%{strong_end} 之åŽï¼Œä¸èƒ½æ’¤æ¶ˆæˆ–æ¢å¤ã€‚"
msgid "AdminProjects|Delete"
msgstr "删除"
@@ -2580,8 +2658,8 @@ msgstr "删除用户"
msgid "AdminUsers|Delete user and contributions"
msgstr "删除用户åŠç›¸å…³è´¡çŒ®"
-msgid "AdminUsers|Export permissions as CSV"
-msgstr "导出æƒé™åˆ—表为CSVæ ¼å¼"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
+msgstr ""
msgid "AdminUsers|External"
msgstr "外部"
@@ -2842,13 +2920,13 @@ msgid "Advanced export options"
msgstr "高级导出选项"
msgid "AdvancedSearch|Reindex required"
-msgstr ""
+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 ""
+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 ""
+msgstr "项目永久删除åŽï¼Œå°† %{strongStart}无法æ¢å¤%{strongEnd},您将丢失此项目的仓库和%{strongStart}所有相关资æº%{strongEnd},包括议题和åˆå¹¶è¯·æ±‚。"
msgid "After a successful password update you will be redirected to login screen."
msgstr "密ç æ›´æ–°æˆåŠŸåŽï¼Œæ‚¨å°†è¢«é‡å®šå‘到登录页é¢ã€‚"
@@ -2857,13 +2935,16 @@ msgid "After a successful password update, you will be redirected to the login p
msgstr "密ç æ›´æ–°æˆåŠŸåŽï¼Œæ‚¨å°†è¢«é‡å®šå‘到登录页é¢ï¼Œæ‚¨å¯ä»¥ä½¿ç”¨æ–°å¯†ç é‡æ–°ç™»å½•ã€‚"
msgid "After it expires, you can't use merge approvals, code quality, or many other features."
-msgstr ""
+msgstr "过期åŽï¼Œæ‚¨å°†æ— æ³•ä½¿ç”¨åˆå¹¶æ‰¹å‡†ã€ä»£ç è´¨é‡æˆ–许多其他功能。"
msgid "After it expires, you can't use merge approvals, epics, or many other features."
-msgstr ""
+msgstr "到期åŽï¼Œæ‚¨å°†æ— æ³•ä½¿ç”¨åˆå¹¶æ‰¹å‡†ã€å²è¯—或许多其他功能。"
msgid "After it expires, you can't use merge approvals, epics, or many security features."
-msgstr ""
+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 "导出完æˆåŽï¼Œä»Žé€šçŸ¥ç”µå­é‚®ä»¶æˆ–此页é¢ä¸‹è½½æ•°æ®æ–‡ä»¶ã€‚ 然åŽæ‚¨å¯ä»¥ä»Žå¦ä¸€ä¸ª GitLab 实例的 %{strong_text_start}创建新群组%{strong_text_end} 页é¢å¯¼å…¥æ•°æ®æ–‡ä»¶ã€‚"
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr "在阅读这些贡献指å—åŽï¼Œæ‚¨å°†å‡†å¤‡å¥½"
@@ -3255,6 +3336,9 @@ msgstr "所有å²è¯—"
msgid "All groups and projects"
msgstr "所有群组和项目"
+msgid "All issues"
+msgstr "所有议题"
+
msgid "All issues for this milestone are closed."
msgstr "此里程碑的所有议题å‡å·²å…³é—­ã€‚"
@@ -3459,6 +3543,9 @@ msgstr "å‘生错误"
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr "在报告测试结果时出现的错误,错误地表明在没有æ¼æ´žçš„情况下系统中存在æ¼æ´žã€‚"
+msgid "An error occured while fetching the pipelines jobs."
+msgstr "获å–æµæ°´çº¿ä½œä¸šæ—¶å‡ºé”™ã€‚"
+
msgid "An error occurred adding a draft to the thread."
msgstr "å‘主题添加è‰ç¨¿æ—¶å‡ºé”™ã€‚"
@@ -3481,14 +3568,11 @@ msgid "An error occurred fetching the project authors."
msgstr "获å–项目作者时出错。"
msgid "An error occurred fetching the public deploy keys. Please try again."
-msgstr ""
+msgstr "获å–公共部署密钥时出错。请é‡è¯•ã€‚"
msgid "An error occurred previewing the blob"
msgstr "预览 blob 时出错"
-msgid "An error occurred when removing the label."
-msgstr "删除标签时出错。"
-
msgid "An error occurred when updating the title"
msgstr "更新标题时出现错误"
@@ -3643,7 +3727,7 @@ msgid "An error occurred while loading chart data"
msgstr "加载图表数æ®æ—¶å‘生错误"
msgid "An error occurred while loading code owners."
-msgstr ""
+msgstr "加载代ç æ‰€æœ‰è€…时出错。"
msgid "An error occurred while loading commit signatures"
msgstr "加载æ交签åæ—¶å‘生错误"
@@ -3669,6 +3753,9 @@ msgstr "加载åˆå¹¶è¯·æ±‚æ—¶å‘生错误。"
msgid "An error occurred while loading projects."
msgstr "加载项目时出错。"
+msgid "An error occurred while loading the Jobs tab."
+msgstr "加载作业选项å¡æ—¶å‡ºé”™ã€‚"
+
msgid "An error occurred while loading the Needs tab."
msgstr "加载Needs选项å¡æ—¶å‡ºé”™ã€‚"
@@ -3678,6 +3765,9 @@ msgstr "加载测试报告选项å¡æ—¶å‘生错误。"
msgid "An error occurred while loading the access tokens form, please try again."
msgstr "加载访问令牌表å•æ—¶å‘生错误,请é‡è¯•ã€‚"
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr "加载数æ®æ—¶å‡ºé”™ã€‚请é‡è¯•ã€‚"
@@ -3826,8 +3916,14 @@ msgstr "一个示例项目,展示了为你自己的组织设置GitLab的最佳
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr "显示如何在GitLab动æ€å­æµæ°´çº¿ä¸­ä½¿ç”¨Jsonnet的示例"
+msgid "An incident has been resolved in %{project_path}."
+msgstr "事件已在 %{project_path} 中解决。"
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr "在 %{project_path} 中触å‘了一个事件。"
+
msgid "An integer value is required for seconds"
-msgstr ""
+msgstr "秒数必须是整数"
msgid "An issue already exists"
msgstr "议题已ç»å­˜åœ¨"
@@ -3869,7 +3965,7 @@ msgid "Analyze your dependencies for known vulnerabilities."
msgstr "分æžä¾èµ–项查找已知æ¼æ´ž."
msgid "Analyze your infrastructure as code configuration files for known vulnerabilities."
-msgstr ""
+msgstr "将您的基础设施作为已知æ¼æ´žçš„代ç é…置文件进行分æžã€‚"
msgid "Analyze your source code and git history for secrets."
msgstr "分æžä½ çš„æºä»£ç å’Œgit历å²ä¸­çš„密ç ."
@@ -3981,7 +4077,7 @@ msgid_plural "ApplicationSettings|Approve %d users"
msgstr[0] "批准 %d ä½ç”¨æˆ·"
msgid "ApplicationSettings|Approve users"
-msgstr ""
+msgstr "批准用户"
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr "批准处于待批准状æ€çš„用户?"
@@ -3991,7 +4087,7 @@ msgid_plural "ApplicationSettings|By making this change, you will automatically
msgstr[0] "通过进行此更改,您将自动批准 %d å处于待批准状æ€çš„用户。"
msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
-msgstr ""
+msgstr "通过åšæ­¤æ›´æ”¹ï¼Œæ‚¨å°†è‡ªåŠ¨æ‰¹å‡†æ‰€æœ‰ç­‰å¾…批准状æ€çš„用户。"
msgid "ApplicationSettings|Denied domains for sign-ups"
msgstr "æ‹’ç»æ³¨å†Œçš„域"
@@ -4148,9 +4244,15 @@ msgstr[0] "%{membersCount} éœ€è¦ %{count} 个核准"
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr "%{firstLabel} +%{numberOfAdditionalLabels} 更多"
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr "与åˆå¹¶è¯·æ±‚核准人åˆä½œçš„åˆå¹¶è¯·æ±‚作者"
+
msgid "ApprovalRule|Add approvers"
msgstr "添加核准人"
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr "添加所需的核准人æ¥æ”¹è¿›æ‚¨çš„代ç å®¡æŸ¥æµç¨‹"
+
msgid "ApprovalRule|All scanners"
msgstr "所有扫æ工具"
@@ -4181,6 +4283,9 @@ msgstr "核准人类型"
msgid "ApprovalRule|Approvers"
msgstr "核准人"
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr "按专业领域分é…核准人。"
+
msgid "ApprovalRule|Confirmed"
msgstr "已确认"
@@ -4190,6 +4295,15 @@ msgstr "已忽略"
msgid "ApprovalRule|Examples: QA, Security."
msgstr "示例:QAã€å®‰å…¨ã€‚"
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr "æ高组织的代ç è´¨é‡ã€‚"
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr "了解有关åˆå¹¶è¯·æ±‚批准的更多信æ¯ã€‚"
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr "让系统根æ®æ›´æ”¹çš„文件指定åˆæ ¼çš„核准人。"
+
msgid "ApprovalRule|Name"
msgstr "å称"
@@ -4214,6 +4328,9 @@ msgstr "请至少选择一ç§æ¼æ´žçŠ¶æ€"
msgid "ApprovalRule|Previously detected"
msgstr "以å‰æ£€æµ‹åˆ°"
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr "å‡å°‘åˆå¹¶çš„总时间。"
+
msgid "ApprovalRule|Resolved"
msgstr "已解决"
@@ -4241,6 +4358,9 @@ msgstr "严é‡çº§åˆ«"
msgid "ApprovalRule|Target branch"
msgstr "目标分支"
+msgid "ApprovalRule|Try it for free"
+msgstr "å…费试用"
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr "å…许的æ¼æ´ž"
@@ -4277,7 +4397,7 @@ msgstr "æ›´æ–°åˆå¹¶è¯·æ±‚审批设置时出错。"
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr "此设置在实例级别é…置,åªèƒ½ç”±ç®¡ç†å‘˜æ›´æ”¹ã€‚"
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr "此设置在 %{groupName} 中é…置,åªèƒ½ç”±ç®¡ç†å‘˜æˆ–群组所有者更改。"
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4401,7 +4521,7 @@ msgid "Are you sure you want to delete this SSH key?"
msgstr "您确定è¦åˆ é™¤æ­¤SSH密钥å—?"
msgid "Are you sure you want to delete this deploy key?"
-msgstr ""
+msgstr "您确定è¦åˆ é™¤æ­¤éƒ¨ç½²å¯†é’¥å—?"
msgid "Are you sure you want to delete this device? This action cannot be undone."
msgstr "您确定è¦åˆ é™¤æ­¤è®¾å¤‡å—?此æ“作无法撤销。"
@@ -4446,9 +4566,6 @@ msgstr "您确定è¦ç«‹å³åˆå¹¶å—?"
msgid "Are you sure you want to re-deploy this environment?"
msgstr "您确定è¦é‡æ–°éƒ¨ç½²æ­¤çŽ¯å¢ƒå—?"
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr "您确定è¦é‡æ–°ç”Ÿæˆå…¬é’¥å—?在镜åƒå†æ¬¡è¿è¡Œä¹‹å‰ï¼Œæ‚¨å¿…须更新远程æœåŠ¡å™¨ä¸Šçš„公钥。"
-
msgid "Are you sure you want to reindex?"
msgstr "您确定è¦é‡å»ºç´¢å¼•å—?"
@@ -4596,6 +4713,9 @@ msgstr "指派审核者"
msgid "Assign reviewer(s)"
msgstr "指派审核者"
+msgid "Assign severity"
+msgstr "分é…严é‡ç¨‹åº¦"
+
msgid "Assign some issues to this milestone."
msgstr "为此里程碑分é…一些议题。"
@@ -4606,7 +4726,7 @@ msgid "Assign to commenting user"
msgstr "分é…给评论用户"
msgid "Assign to me"
-msgstr ""
+msgstr "分é…给我"
msgid "Assign yourself to these issues"
msgstr "将这些议题分é…给自己"
@@ -4646,7 +4766,7 @@ msgstr "分é…给您的"
msgid "Assignee"
msgid_plural "%d Assignees"
-msgstr[0] ""
+msgstr[0] "%dä½æŒ‡æ´¾äºº"
msgid "Assignee has no permissions"
msgstr "å—让人没有æƒé™"
@@ -4704,7 +4824,7 @@ msgid "Audit Events"
msgstr "审计事件"
msgid "Audit events"
-msgstr ""
+msgstr "审计事件"
msgid "AuditLogs|(removed)"
msgstr "(已删除)"
@@ -4991,9 +5111,6 @@ msgstr "å¯ç”¨çš„指定Runner"
msgid "Avatar for %{assigneeName}"
msgstr "%{assigneeName} 头åƒ"
-msgid "Avatar for %{name}"
-msgstr "%{name} 头åƒ"
-
msgid "Avatar will be removed. Are you sure?"
msgstr "å³å°†åˆ é™¤å¤´åƒã€‚确定继续å—?"
@@ -5243,9 +5360,6 @@ msgstr "æ¯æœˆ"
msgid "BillingPlans|per user"
msgstr "æ¯ç”¨æˆ·"
-msgid "BillingPlan|Contact sales"
-msgstr "è”系销售人员"
-
msgid "BillingPlan|Upgrade"
msgstr "å‡çº§"
@@ -5276,14 +5390,11 @@ msgstr "é‡æ–°æ¿€æ´»è¯•ç”¨"
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr "Shared runners 无法å¯ç”¨ï¼Œç›´åˆ°æœ‰æ•ˆçš„信用å¡åœ¨æ¡£ã€‚"
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr "è¦åœ¨shared runners上使用å…è´¹æµæ°´çº¿æ—¶é•¿ï¼Œæ‚¨éœ€è¦ä½¿ç”¨ä¿¡ç”¨å¡æˆ–借记å¡éªŒè¯æ‚¨çš„å¸æˆ·ã€‚如果您ä¸æƒ³æ供,您å¯ä»¥é€šè¿‡ä¸ºæ‚¨çš„项目带æ¥è‡ªå·±çš„runner并ç¦ç”¨shared runnersæ¥è¿è¡Œæµæ°´çº¿ã€‚这是阻止和å‡å°‘对 GitLab 基础设施的滥用所必需的。 %{strongStart}GitLab ä¸ä¼šæ”¶è´¹æˆ–存储您的银行å¡ä¿¡æ¯ï¼Œå®ƒåªä¼šç”¨äºŽéªŒè¯æ‚¨çš„身份。%{strongEnd} %{linkStart}了解更多%{linkEnd}"
-
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr "è¦åœ¨shared runners上使用å…费的æµæ°´çº¿æ—¶é—´ï¼Œæ‚¨éœ€è¦ä½¿ç”¨ä¿¡ç”¨å¡æˆ–借记å¡éªŒè¯æ‚¨çš„è´¦å·ã€‚这样åšçš„目的是为了阻止和å‡å°‘GitLab 基础设施的滥用。 %{strongStart}GitLab ä¸ä¼šæ”¶è´¹æˆ–存储您的å¡å·ï¼Œå®ƒä»…用于验è¯ã€‚%{strongEnd}"
+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 ""
-msgid "Billings|User successfully validated"
-msgstr "用户验è¯æˆåŠŸ"
+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 ""
msgid "Billings|User validation required"
msgstr "需è¦ç”¨æˆ·éªŒè¯"
@@ -5294,8 +5405,11 @@ msgstr "验è¯å¸æˆ·"
msgid "Billings|Validate user account"
msgstr "验è¯ç”¨æˆ·å¸æˆ·"
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
-msgstr "用户账户已验è¯æˆåŠŸã€‚您现在å¯ä»¥ä½¿ç”¨å…费的æµæ°´çº¿åˆ†é’Ÿæ•°ã€‚"
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
+msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
msgstr "åªæœ‰ç”¨æˆ·è®¾ç½®äº†å…¬å¼€ç”µå­é‚®ä»¶ï¼Œä»–们的邮件æ‰å¯¹å¤–å¯è§ã€‚"
@@ -5306,9 +5420,15 @@ msgstr "获å–计费会员详细信æ¯æ—¶å‘生错误"
msgid "Billing|An error occurred while loading billable members list"
msgstr "加载收费æˆå‘˜åˆ—表时å‘生错误"
+msgid "Billing|An error occurred while loading pending members list"
+msgstr "加载待处ç†æˆå‘˜åˆ—表时出错"
+
msgid "Billing|An error occurred while removing a billable member"
msgstr "移除计费æˆå‘˜æ—¶å‡ºé”™"
+msgid "Billing|Awaiting member signup"
+msgstr "等待æˆå‘˜æ³¨å†Œ"
+
msgid "Billing|Cannot remove user"
msgstr "无法删除用户"
@@ -5355,7 +5475,7 @@ msgid "Billing|Users occupying seats in"
msgstr "å ç”¨å¸­ä½çš„用户于"
msgid "Billing|View pending approvals"
-msgstr ""
+msgstr "查看待审批"
msgid "Billing|You are about to remove user %{username} from your subscription. If you continue, the user will be removed from the %{namespace} group and all its subgroups and projects. This action can't be undone."
msgstr "您将è¦ä»Žè®¢é˜…中删除用户%{username}。如果继续,该用户将从 %{namespace} 群组åŠå…¶æ‰€æœ‰å­ç»„和项目中删除。此æ“作无法撤消。"
@@ -5434,7 +5554,7 @@ msgid "BoardScope|An error occurred while getting milestones, please try again."
msgstr "获å–里程碑时å‘生错误,请é‡è¯•ã€‚"
msgid "BoardScope|An error occurred while searching for labels, please try again."
-msgstr ""
+msgstr "æœç´¢æ ‡è®°æ—¶å‘生错误,请é‡è¯•ã€‚"
msgid "BoardScope|An error occurred while searching for users, please try again."
msgstr "æœç´¢ç”¨æˆ·æ—¶å‘生错误,请é‡è¯•ã€‚"
@@ -5446,19 +5566,19 @@ msgid "BoardScope|Any assignee"
msgstr "任何指派人"
msgid "BoardScope|Any label"
-msgstr ""
+msgstr "任何标记"
msgid "BoardScope|Assignee"
msgstr "指派人"
msgid "BoardScope|Choose labels"
-msgstr ""
+msgstr "选择标记"
msgid "BoardScope|Edit"
msgstr "编辑"
msgid "BoardScope|Labels"
-msgstr ""
+msgstr "标记"
msgid "BoardScope|Milestone"
msgstr "里程碑"
@@ -5473,7 +5593,7 @@ msgid "BoardScope|Select assignee"
msgstr "选择指派人"
msgid "BoardScope|Select labels"
-msgstr ""
+msgstr "选择标记"
msgid "BoardScope|Select milestone"
msgstr "选择里程碑"
@@ -5493,7 +5613,7 @@ msgstr "æƒé‡"
msgid "Boards"
msgstr "看æ¿"
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr "看æ¿å’Œçœ‹æ¿åˆ—表"
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5565,7 +5685,7 @@ msgid "Boards|Failed to fetch blocking %{issuableType}s"
msgstr "无法获å–ç¦ç”¨çš„ %{issuableType}"
msgid "Boards|New board"
-msgstr ""
+msgstr "新建看æ¿"
msgid "Boards|New epic"
msgstr "新建å²è¯—"
@@ -5580,7 +5700,7 @@ msgid "Boards|View scope"
msgstr "查看范围"
msgid "Board|An error occurred while fetching the board, please try again."
-msgstr ""
+msgstr "获å–看æ¿æ—¶å‘生错误,请é‡è¯•ã€‚"
msgid "Board|Are you sure you want to delete this board?"
msgstr "确定è¦åˆ é™¤æ­¤çœ‹æ¿å—?"
@@ -5852,8 +5972,11 @@ msgstr "并å‘批é‡è¯·æ±‚"
msgid "Bulk update"
msgstr "批é‡æ›´æ–°"
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
-msgstr "é‡æ–°å¯¼å…¥æ–°ç¾¤ç»„。它ä¸ä¼šä¸ŽçŽ°æœ‰ç¾¤ç»„åŒæ­¥ã€‚"
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr "%{host} 正在è¿è¡Œè¿‡æ—¶çš„ GitLab 版本(v%{version})"
+
+msgid "BulkImport|%{feature} (require v%{version})"
+msgstr "%{feature}ï¼ˆéœ€è¦ v%{version})"
msgid "BulkImport|Existing groups"
msgstr "现有群组"
@@ -5861,6 +5984,9 @@ msgstr "现有群组"
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 "以下数æ®å°†ä¸ä¼šè¢«è¿ç§»ï¼š%{bullets} 如果您在è¿ç§»ä¸­éœ€è¦æ­¤æ•°æ®ï¼Œè¯· %{host} 系统管ç†å‘˜å‡çº§ GitLab"
+
msgid "BulkImport|From source group"
msgstr "从æºç¾¤ç»„"
@@ -5874,13 +6000,13 @@ msgid "BulkImport|Import groups from GitLab"
msgstr "从GitLab导入群组"
msgid "BulkImport|Import is finished. Pick another name for re-import"
-msgstr ""
+msgstr "导入已完æˆï¼Œè¯·é€‰æ‹©å¦ä¸€ä¸ªå称å†å¯¼å…¥"
msgid "BulkImport|Import selected"
msgstr "导入已选择项"
msgid "BulkImport|Importing the group failed."
-msgstr ""
+msgstr "导入群组失败。"
msgid "BulkImport|Last imported to %{link}"
msgstr "上次导入到 %{link}"
@@ -5889,7 +6015,7 @@ msgid "BulkImport|Name already exists."
msgstr "å称已存在。"
msgid "BulkImport|Name already used as a target for another group."
-msgstr ""
+msgstr "å称已用作å¦ä¸€ç»„的目标。"
msgid "BulkImport|New group"
msgstr "新建群组"
@@ -5900,6 +6026,9 @@ msgstr "没有历å²è®°å½•"
msgid "BulkImport|No parent"
msgstr "没有父级"
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr "é‡æ–°å¯¼å…¥ä¼šåˆ›å»ºä¸€ä¸ªæ–°ç¾¤ç»„。它ä¸ä¸ŽçŽ°æœ‰ç¾¤ç»„åŒæ­¥ã€‚"
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr "显示 %{start}-%{end} / %{total}"
@@ -6136,7 +6265,7 @@ msgid "Cadence is not automated"
msgstr "Cadence ä¸æ˜¯è‡ªåŠ¨åŒ–çš„"
msgid "Calculate the number of slices during reindexing. The multiplier is applied to the number of shards per index. Learn more about %{slice_multiplier_link_start}slice multiplier configuration%{slice_multiplier_link_end}."
-msgstr ""
+msgstr "计算é‡å»ºæ—¶åˆ†ç‰‡çš„æ•°é‡ï¼Œå€æ•°é€‚用于æ¯ä¸ªç´¢å¼•çš„分片数é‡ã€‚ 了解更多关于 %{slice_multiplier_link_start}分片å€æ•°é…ç½®%{slice_multiplier_link_end}。"
msgid "Callback URL"
msgstr "回调 URL"
@@ -6436,7 +6565,7 @@ msgid "ChangeTypeAction|Cherry-pick"
msgstr "优选"
msgid "ChangeTypeAction|GitLab will create a branch in your fork and start a merge request."
-msgstr ""
+msgstr "GitLab 将在您的派生项目中创建分支并开始åˆå¹¶è¯·æ±‚。"
msgid "ChangeTypeAction|Pick into branch"
msgstr "选择分支"
@@ -6499,7 +6628,7 @@ msgid "Changes to the title have not been saved"
msgstr "标题更改尚未ä¿å­˜"
msgid "Changing any setting here requires an application restart"
-msgstr ""
+msgstr "更改此处的任何设置都需è¦é‡æ–°å¯åŠ¨åº”用程åº"
msgid "Changing group URL can have unintended side effects."
msgstr "更改群组URLå¯èƒ½ä¼šæœ‰éžé¢„期的副作用。"
@@ -6565,7 +6694,7 @@ msgid "Check out, review, and merge locally"
msgstr "在本地检出ã€å®¡æ ¸å’Œåˆå¹¶"
msgid "Check the %{code_open}elasticsearch.log%{code_close} file to debug why the migration halted and make any changes before retrying the migration. When you fix the cause of the failure, select %{strong_open}Retry migration%{strong_close}, and the migration is scheduled to retry in the background."
-msgstr ""
+msgstr "检查 %{code_open}elasticsearch.log%{code_close} 文件,debug è¿ç§»åœæ­¢çš„原因并在é‡è¯•è¿ç§»ä¹‹å‰è¿›è¡Œä»»ä½•æ›´æ”¹ï¼Œä¿®å¤å¤±è´¥åŽŸå› åŽï¼Œé€‰æ‹© %{strong_open}é‡è¯•è¿ç§»%{strong_close},è¿ç§»è®¡åˆ’在åŽå°é‡è¯•ã€‚"
msgid "Check the current instance configuration "
msgstr "检查当å‰å®žä¾‹é…ç½® "
@@ -6603,8 +6732,8 @@ msgstr "检查用户å是å¦å¯ç”¨..."
msgid "Checkout"
msgstr "支付"
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
-msgstr "æ¯ä¸ªåŒ…æ¯10 GB存储 %{selectedPlanPrice} 美元"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
+msgstr "æ¯ 10 GB 存储包æ¯å¹´ %{selectedPlanPrice} 美元"
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr "$%{selectedPlanPrice} æ¯åŒ… 1,000 分钟"
@@ -6629,7 +6758,7 @@ msgid "Checkout|%{name}'s storage subscription"
msgstr "%{name}的存储订阅"
msgid "Checkout|%{quantity} CI minutes"
-msgstr ""
+msgstr "%{quantity} CI 分钟"
msgid "Checkout|%{quantity} GB of storage"
msgstr "%{quantity} GB 存储"
@@ -6863,9 +6992,6 @@ msgstr "选择任何颜色。"
msgid "Choose file…"
msgstr "选择文件…"
-msgid "Choose labels"
-msgstr "选择标记"
-
msgid "Choose specific groups or storage shards"
msgstr "选择指定群组或存储片"
@@ -7076,6 +7202,9 @@ msgstr "清除图表筛选器"
msgid "Clear due date"
msgstr "清除截止日期"
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr "清除最近的æœç´¢"
@@ -7094,9 +7223,15 @@ msgstr "清除模æ¿æœç´¢è¾“å…¥"
msgid "Clear weight"
msgstr "清除æƒé‡"
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr "å·²é‡ç½®çš„æƒé‡"
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr "清除æƒé‡"
@@ -7140,7 +7275,7 @@ msgid "Clients"
msgstr "客户端"
msgid "Clientside DSN"
-msgstr ""
+msgstr "客户端DSN"
msgid "Clone"
msgstr "克隆"
@@ -7185,7 +7320,7 @@ msgid "Close %{issueType}"
msgstr "关闭%{issueType}"
msgid "Close %{noteable}"
-msgstr ""
+msgstr "关闭 %{noteable}"
msgid "Close %{tabname}"
msgstr "关闭%{tabname}"
@@ -7250,23 +7385,44 @@ msgstr "集群级别"
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr "Stages::ClusterEndpointInserter需è¦é›†ç¾¤ç±»åž‹"
-msgid "ClusterAgents|%{number} of %{total} agents"
+msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
+msgid "ClusterAgents|%{number} of %{total} agents"
+msgstr "%{number} 个代ç†ï¼Œå…± %{total} 个"
+
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
-msgstr ""
+msgstr "%{total}个集群中的%{number}个通过集群è¯ä¹¦è¿žæŽ¥"
+
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr "%{titleIcon}已连接"
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr "%{titleIcon}未连接"
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr "%{tokenName} 已创建"
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr "%{tokenName} 已撤销"
msgid "ClusterAgents|Access tokens"
msgstr "访问令牌"
msgid "ClusterAgents|Actions"
-msgstr ""
+msgstr "æ“作"
msgid "ClusterAgents|Advanced installation methods"
-msgstr ""
+msgstr "高级安装方法"
msgid "ClusterAgents|Agent"
-msgstr ""
+msgstr "代ç†"
+
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr "代ç†%{strongStart}已连接%{strongEnd}"
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr "代ç†%{strongStart}未连接%{strongEnd}"
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr "代ç†å¯èƒ½æ— æ³•è¿žæŽ¥åˆ° GitLab"
@@ -7275,7 +7431,7 @@ msgid "ClusterAgents|Agent never connected to GitLab"
msgstr "代ç†ä»Žæœªè¿žæŽ¥åˆ° GitLab"
msgid "ClusterAgents|All"
-msgstr ""
+msgstr "全部"
msgid "ClusterAgents|An error occurred while loading your GitLab Agents"
msgstr "加载您的GitLab Agentæ—¶å‘生错误"
@@ -7283,32 +7439,38 @@ msgstr "加载您的GitLab Agentæ—¶å‘生错误"
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 "检索 GitLab 代ç†åŠ¨æ€æ—¶å‡ºé”™ã€‚é‡æ–°åŠ è½½é¡µé¢ä»¥é‡è¯•ã€‚"
+
msgid "ClusterAgents|An unknown error occurred. Please try again."
msgstr "å‘生未知错误。请é‡è¯•ã€‚"
-msgid "ClusterAgents|Certificate"
+msgid "ClusterAgents|Are you sure you want to delete this agent? You cannot undo this."
msgstr ""
+msgid "ClusterAgents|Certificate"
+msgstr "è¯ä¹¦"
+
msgid "ClusterAgents|Configuration"
msgstr "é…ç½®"
msgid "ClusterAgents|Connect a cluster through the Agent"
-msgstr ""
+msgstr "通过代ç†è¿žæŽ¥é›†ç¾¤"
msgid "ClusterAgents|Connect existing cluster"
-msgstr ""
+msgstr "连接现有集群"
msgid "ClusterAgents|Connect with a certificate"
-msgstr ""
+msgstr "使用è¯ä¹¦è¿žæŽ¥"
msgid "ClusterAgents|Connect with the Agent"
-msgstr ""
+msgstr "与代ç†è¿žæŽ¥"
msgid "ClusterAgents|Connect with the GitLab Agent"
-msgstr ""
+msgstr "与 GitLab 代ç†è¿žæŽ¥"
msgid "ClusterAgents|Connect your cluster through the Agent"
-msgstr ""
+msgstr "通过代ç†è¿žæŽ¥æ‚¨çš„集群"
msgid "ClusterAgents|Connected"
msgstr "已连接"
@@ -7320,7 +7482,7 @@ msgid "ClusterAgents|Copy token"
msgstr "å¤åˆ¶ä»¤ç‰Œ"
msgid "ClusterAgents|Create a new cluster"
-msgstr ""
+msgstr "创建新集群"
msgid "ClusterAgents|Created by"
msgstr "创建人"
@@ -7331,32 +7493,41 @@ msgstr "由 %{name} %{time} 创建"
msgid "ClusterAgents|Date created"
msgstr "创建日期"
-msgid "ClusterAgents|Deprecated"
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
msgstr ""
+msgid "ClusterAgents|Deprecated"
+msgstr "已弃用"
+
msgid "ClusterAgents|Description"
msgstr "æè¿°"
+msgid "ClusterAgents|Event occurred"
+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 "适用于 Kubernetes çš„ GitLab 代ç†"
msgid "ClusterAgents|Go to the repository files"
-msgstr ""
+msgstr "转到仓库文件"
msgid "ClusterAgents|How to register an agent?"
-msgstr ""
+msgstr "如何注册代ç†ï¼Ÿ"
msgid "ClusterAgents|Install a new agent"
-msgstr ""
+msgstr "安装新代ç†"
msgid "ClusterAgents|Last connected %{timeAgo}."
msgstr "上次连接在 %{timeAgo}。"
@@ -7368,7 +7539,7 @@ msgid "ClusterAgents|Learn how to create an agent access token"
msgstr "了解如何创建一个 agent 访问令牌"
msgid "ClusterAgents|Learn how to troubleshoot"
-msgstr ""
+msgstr "了解如何排除故障"
msgid "ClusterAgents|Make sure you are using a valid token."
msgstr "请确ä¿æ‚¨æ­£åœ¨ä½¿ç”¨ä¸€ä¸ªæœ‰æ•ˆçš„令牌。"
@@ -7383,25 +7554,25 @@ msgid "ClusterAgents|Never connected"
msgstr "从未连接"
msgid "ClusterAgents|No agents"
-msgstr ""
+msgstr "无代ç†"
msgid "ClusterAgents|No clusters connected through cluster certificates"
-msgstr ""
+msgstr "没有通过集群è¯ä¹¦è¿žæŽ¥çš„集群"
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 ""
+msgstr "注册代ç†ä»¥ç”Ÿæˆä¸€ä¸ªä»¤ç‰Œï¼Œç”¨äºŽåœ¨ä¸‹ä¸€æ­¥å°†ä»£ç†å®‰è£…到您的集群中。"
msgid "ClusterAgents|Registering Agent"
msgstr "注册代ç†"
@@ -7410,49 +7581,68 @@ msgid "ClusterAgents|Registration token"
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 "查看代ç†åŠ¨æ€æ›´æ–°ï¼Œä¾‹å¦‚已创建或已撤销的令牌,以åŠå·²è¿žæŽ¥æˆ–未连接的集群。"
msgid "ClusterAgents|Select an agent"
-msgstr ""
+msgstr "选择代ç†"
msgid "ClusterAgents|Select an agent to register with GitLab"
-msgstr ""
+msgstr "选择è¦æ³¨å†Œåˆ° GitLab 的代ç†"
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 "当将 Kubernetes 集群连接到 GitLab 时,GitLab 代ç†æ供更高级别的安全性。 %{linkStart}了解有关 GitLab 代ç†çš„更多信æ¯ã€‚%{linkEnd}"
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
-msgstr ""
+msgstr "代ç†é•¿æ—¶é—´æœªè¿žæŽ¥ï¼Œå¯èƒ½æœ‰è¿žæŽ¥é—®é¢˜ï¼Œæœ€åŽè¿žæŽ¥æ—¶é—´æ˜¯ %{timeAgo}。"
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] "过去 %d 天里没有动æ€"
msgid "ClusterAgents|This agent has no tokens"
msgstr "此代ç†æ²¡æœ‰ä»¤ç‰Œ"
-msgid "ClusterAgents|To install a new agent, first add the agent's configuration file to this repository. %{linkStart}What's the agent's configuration file?%{linkEnd}"
+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}What's the agent's configuration file?%{linkEnd}"
+msgstr "è¦å®‰è£…新代ç†ï¼Œé¦–先将代ç†çš„é…置文件添加到此仓库中。 %{linkStart}代ç†çš„é…置文件是什么?%{linkEnd}"
+
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr "由 %{userName} 创建的令牌"
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr "由 %{userName} 撤销的令牌"
+
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|What is GitLab Agent activity?"
+msgstr "什么是 GitLab 代ç†åŠ¨æ€ï¼Ÿ"
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."
-msgstr ""
+msgstr "您的实例没有设置 %{linkStart}GitLab 代ç†æœåŠ¡å™¨ (KAS)%{linkEnd} 。è¦æ±‚ GitLab 管ç†å‘˜å®‰è£…它。"
msgid "ClusterAgent|User has insufficient permissions to create a token for this project"
msgstr "用户æƒé™ä¸è¶³ï¼Œæ— æ³•ä¸ºæ­¤é¡¹ç›®åˆ›å»ºä»¤ç‰Œ"
@@ -7602,10 +7792,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 "通过 %{linkStart}集群è¯ä¹¦%{linkEnd} 将您的集群连接到 GitLab 。"
msgid "ClusterIntegration|Connection Error"
msgstr "连接错误"
@@ -8100,7 +8290,7 @@ msgid "ClusterIntegration|The URL used to access the Kubernetes API."
msgstr "用于访问 Kubernetes API 的 URL。"
msgid "ClusterIntegration|The certificate-based method to connect clusters to GitLab was %{linkStart}deprecated%{linkEnd} in GitLab 14.5."
-msgstr ""
+msgstr "将集群连接到 GitLab 的基于è¯ä¹¦çš„方法%{linkStart}弃用%{linkEnd}于 14.5 版本。"
msgid "ClusterIntegration|The namespace associated with your project. This will be used for deploy boards, logs, and Web terminals."
msgstr "与当å‰é¡¹ç›®ç›¸å…³è”的命å空间。用于部署看æ¿ã€pod日志和Web terminal。"
@@ -8157,7 +8347,7 @@ msgid "ClusterIntegration|Unknown Error"
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 ""
+msgstr "使用 %{linkStart}GitLab 代ç†%{linkEnd} 将您的 Kubernetes 集群安全地连接到 GitLab。您å¯ä»¥éƒ¨ç½²æ‚¨çš„应用程åºã€è¿è¡Œæ‚¨çš„æµæ°´çº¿ã€ä½¿ç”¨ Review Apps 等等。"
msgid "ClusterIntegration|Uses the Cloud Run, Istio, and HTTP Load Balancing addons for this cluster."
msgstr "为此集群使用Cloud Run,Istioå’ŒHTTP负载平衡æ’件。"
@@ -8253,7 +8443,7 @@ msgid "Code review"
msgstr "代ç å®¡æ ¸"
msgid "Code snippet"
-msgstr ""
+msgstr "代ç ç‰‡æ®µ"
msgid "Code snippet copied. Insert it in the correct location in the YAML file."
msgstr "代ç ç‰‡æ®µå·²å¤åˆ¶ã€‚将其æ’å…¥ YAML 文件中的正确ä½ç½®ã€‚"
@@ -8631,6 +8821,15 @@ msgstr "编辑åˆè§„框架"
msgid "ComplianceFramework|New compliance framework"
msgstr "新建åˆè§„框架"
+msgid "ComplianceReport|Approved by author"
+msgstr "由作者批准"
+
+msgid "ComplianceReport|Approved by committer"
+msgstr "ç”±æ交者批准"
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr "少于 2 个核准人"
+
msgid "Component"
msgstr "组件"
@@ -8680,10 +8879,10 @@ msgid "Configure Prometheus"
msgstr "é…ç½®Promethes"
msgid "Configure SAST IaC 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 IaC settings."
-msgstr ""
+msgstr "使用 GitLab 托管模æ¿åœ¨â€œ.gitlab-ci.ymlâ€ä¸­é…ç½® SAST IaC。您å¯ä»¥[添加å˜é‡è¦†ç›–](https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings) æ¥è‡ªå®šä¹‰ SAST IaC 设置。"
msgid "Configure SAST IaC in `.gitlab-ci.yml`, creating this file if it does not already exist"
-msgstr ""
+msgstr "在 `.gitlab-ci.yml` 中é…ç½® SAST IaC,如果该文件ä¸å­˜åœ¨åˆ™åˆ›å»ºè¯¥æ–‡ä»¶"
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 "使用 GitLab 托管模æ¿åœ¨ `.gitlab-ci.yml` 中é…ç½® SAST。您å¯ä»¥[添加å˜é‡é‡å†™](https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings) æ¥è‡ªå®šä¹‰ SAST 设置。"
@@ -8698,7 +8897,7 @@ msgid "Configure Secret Detection in `.gitlab-ci.yml`, creating this file if it
msgstr "在 `.gitlab-ci.yml` 中é…ç½® Secret Detection,如果该文件ä¸å­˜åœ¨åˆ™åˆ›å»ºæ­¤æ–‡ä»¶"
msgid "Configure Sentry integration for error tracking"
-msgstr ""
+msgstr "é…ç½® Sentry 集æˆä»¥è¿›è¡Œé”™è¯¯è·Ÿè¸ª"
msgid "Configure Tracing"
msgstr "é…置跟踪"
@@ -9050,6 +9249,9 @@ msgstr "尚未安排"
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr "注æ„:任何策略更新都会导致对预定è¿è¡Œæ—¥æœŸå’Œæ—¶é—´çš„更改"
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr "å‘布于%{timeInfo}"
@@ -9112,7 +9314,7 @@ msgid "ContainerRegistry|Something went wrong while scheduling the image for del
msgstr "安排删除镜åƒæ—¶å‡ºé”™ã€‚"
msgid "ContainerRegistry|Something went wrong while updating the cleanup policy."
-msgstr "更新清ç†æ”¿ç­–时出了错。"
+msgstr "更新清ç†ç­–略时出错。"
msgid "ContainerRegistry|Sorry, your filter produced no results."
msgstr "对ä¸èµ·ï¼Œæ²¡æœ‰ç¬¦åˆç­›é€‰å™¨çš„任何结果."
@@ -9138,6 +9340,9 @@ msgstr "符åˆæ­¤æ­£åˆ™è¡¨è¾¾å¼çš„å称的标签将会被移除。 %{linkStart
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr "清ç†ç­–略在删除所有标签之å‰è¶…时。 管ç†å‘˜å¯ä»¥%{adminLinkStart}ç«‹å³æ‰§è¡Œæ‰‹åŠ¨æ¸…ç†%{adminLinkEnd}或者等待清ç†ç­–略下次自动è¿è¡Œã€‚%{docLinkStart}更多信æ¯%{docLinkEnd}"
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr "找ä¸åˆ°é•œåƒä»“库。"
@@ -9369,12 +9574,18 @@ msgstr "å¤åˆ¶çŽ¯å¢ƒ"
msgid "Copy evidence SHA"
msgstr "å¤åˆ¶è¯æ®SHA"
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr "å¤åˆ¶æ–‡ä»¶å†…容"
msgid "Copy file path"
msgstr "å¤åˆ¶æ–‡ä»¶è·¯å¾„"
+msgid "Copy issue URL to clipboard"
+msgstr "å¤åˆ¶è®®é¢˜ URL 到剪贴æ¿"
+
msgid "Copy key"
msgstr "å¤åˆ¶å¯†é’¥"
@@ -9405,9 +9616,6 @@ msgstr "å¤åˆ¶ä¸‹é¢çš„代ç æ¥å®žçŽ°æ‚¨çš„应用程åºä¸­çš„跟踪:"
msgid "Copy this registration token."
msgstr "å¤åˆ¶æ­¤æ³¨å†Œä»¤ç‰Œ."
-msgid "Copy this value"
-msgstr "å¤åˆ¶æ­¤å€¼"
-
msgid "Copy to clipboard"
msgstr "å¤åˆ¶åˆ°å‰ªè´´æ¿"
@@ -9448,7 +9656,7 @@ msgid "CorpusManagement|Latest Job:"
msgstr "最新作业:"
msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 5GB"
-msgstr ""
+msgstr "新语料库需è¦ä¸Šä¼ *.zip æ ¼å¼ã€‚最大 5GB"
msgid "CorpusManagement|New upload"
msgstr "新上传"
@@ -9604,7 +9812,7 @@ msgid "Create %{workspace} label"
msgstr "创建 %{workspace} 标记"
msgid "Create Google Cloud project"
-msgstr ""
+msgstr "创建 Google Cloud 项目"
msgid "Create New Directory"
msgstr "创建新目录"
@@ -9747,9 +9955,6 @@ msgstr "创建新标记"
msgid "Create new project"
msgstr "新建项目"
-msgid "Create new..."
-msgstr "创建..."
-
msgid "Create or import your first project"
msgstr "创建或导入您的第一个项目"
@@ -9766,7 +9971,7 @@ msgid "Create requirement"
msgstr "创建需求"
msgid "Create service account"
-msgstr ""
+msgstr "创建æœåŠ¡å¸æˆ·"
msgid "Create snippet"
msgstr "创建代ç ç‰‡æ–­"
@@ -9780,6 +9985,9 @@ msgstr "创建主题"
msgid "Create user"
msgstr "创建用户"
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr "创建通é…符: %{searchTerm}"
@@ -9822,9 +10030,6 @@ msgstr "所有默认阶段目å‰éƒ½å¯è§"
msgid "CreateValueStreamForm|Code stage start"
msgstr "代ç é˜¶æ®µå¼€å§‹"
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr "创建价值æµ"
-
msgid "CreateValueStreamForm|Create from default template"
msgstr "从默认模æ¿åˆ›å»º"
@@ -9834,14 +10039,17 @@ msgstr "从无模æ¿åˆ›å»º"
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr "创建新的价值æµ"
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr "默认阶段"
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr "默认阶段åªèƒ½è¢«éšè—或é‡æ–°æŽ’åº"
-msgid "CreateValueStreamForm|Edit Value Stream"
-msgstr "编辑价值æµ"
+msgid "CreateValueStreamForm|Edit value stream"
+msgstr ""
msgid "CreateValueStreamForm|Editing stage"
msgstr "编辑阶段"
@@ -10020,35 +10228,62 @@ msgstr "信用å¡ï¼š"
msgid "Critical vulnerabilities present"
msgstr "存在严é‡æ¼æ´ž"
+msgid "Crm|Contact has been added"
+msgstr "è”系人已添加"
+
+msgid "Crm|Contact has been updated"
+msgstr "è”系人已更新"
+
msgid "Crm|Create new contact"
-msgstr ""
+msgstr "创建新è”系人"
+
+msgid "Crm|Create organization"
+msgstr "创建组织"
msgid "Crm|Customer Relations Contacts"
-msgstr ""
+msgstr "客户关系è”系人"
+
+msgid "Crm|Customer Relations Organizations"
+msgstr "客户关系组织"
+
+msgid "Crm|Default rate (optional)"
+msgstr "默认速率(å¯é€‰ï¼‰"
msgid "Crm|Description (optional)"
-msgstr ""
+msgstr "æè¿° (å¯é€‰)"
+
+msgid "Crm|Edit contact"
+msgstr "编辑è”系人"
msgid "Crm|Email"
-msgstr ""
+msgstr "电å­é‚®ä»¶"
msgid "Crm|First name"
-msgstr ""
+msgstr "åå­—"
msgid "Crm|Last name"
-msgstr ""
+msgstr "姓æ°"
+
+msgid "Crm|New Organization"
+msgstr "新建组织"
msgid "Crm|New contact"
-msgstr ""
+msgstr "新建è”系人"
+
+msgid "Crm|New organization"
+msgstr "新建组织"
msgid "Crm|No contacts found"
-msgstr ""
+msgstr "找ä¸åˆ°è”系人"
msgid "Crm|No organizations found"
-msgstr ""
+msgstr "未找到组织"
+
+msgid "Crm|Organization has been added"
+msgstr "组织已添加"
msgid "Crm|Phone number (optional)"
-msgstr ""
+msgstr "电è¯å·ç  (å¯é€‰)"
msgid "Cron Timezone"
msgstr "Cron 时区"
@@ -10197,15 +10432,6 @@ msgstr "自定义您的æµæ°´çº¿é…置和覆盖率报告。"
msgid "Customize your pipeline configuration."
msgstr "自定义您的æµæ°´çº¿é…置。"
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr "您需è¦å®šåˆ¶æ­¤é¡µé¢å—?"
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr "转到å好设置"
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr "此页é¢é»˜è®¤æ˜¾ç¤ºæ‚¨çš„项目列表,但也å¯ä»¥æ”¹ä¸ºæ˜¾ç¤ºé¡¹ç›®çš„动æ€ï¼Œç¾¤ç»„,待办事项,分é…的议题,分é…çš„åˆå¹¶è¯·æ±‚等等。 您å¯ä»¥åœ¨â€œä¸»é¡µå†…容â€ä¸‹æ›´æ”¹æ­¤é€‰é¡¹"
-
msgid "Cycle Time"
msgstr "周期时间"
@@ -10437,7 +10663,7 @@ msgid "DORA4Metrics|The chart displays the median time between a merge request b
msgstr "该图表显示åˆå¹¶è¯·æ±‚被åˆå¹¶å’Œéƒ¨ç½²åˆ°ç”Ÿäº§çŽ¯å¢ƒä¹‹é—´çš„中间值时间,这些时间基于 %{linkStart}deployment_tier%{linkEnd} 值。"
msgid "DSN"
-msgstr ""
+msgstr "DSN"
msgid "Dashboard"
msgstr "仪表æ¿"
@@ -10887,6 +11113,9 @@ msgstr "找ä¸åˆ°æ•°æ®æºå称"
msgid "Date"
msgstr "日期"
+msgid "Date merged"
+msgstr "åˆå¹¶æ—¥æœŸ"
+
msgid "Date picker"
msgstr "日期选择器"
@@ -11086,7 +11315,7 @@ msgid "Delete Key"
msgstr "删除密钥"
msgid "Delete Selected"
-msgstr ""
+msgstr "删除选中项"
msgid "Delete Value Stream"
msgstr "删除值æµ"
@@ -11110,7 +11339,7 @@ msgid "Delete corpus"
msgstr "删除语料库"
msgid "Delete deploy key"
-msgstr ""
+msgstr "删除部署密钥"
msgid "Delete file"
msgstr "删除文件"
@@ -11166,6 +11395,9 @@ msgstr "删除用户列表"
msgid "Delete variable"
msgstr "删除å˜é‡"
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr "删除事件失败。请é‡è¯•æˆ–è”系管ç†å‘˜ã€‚"
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr "删除项目仓库失败。请é‡è¯•æˆ–è”系管ç†å‘˜ã€‚"
@@ -11199,23 +11431,17 @@ msgstr "删除 %{name}"
msgid "Deleted"
msgstr "已删除"
-msgid "Deleted Projects"
-msgstr "已删除的项目"
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr "已删除èŠå¤©çš„昵称: %{chat_name}!"
-msgid "Deleted projects"
-msgstr "已删除的项目"
-
msgid "Deleted projects cannot be restored!"
msgstr "已删除的项目无法æ¢å¤!"
msgid "Deletes the source branch"
-msgstr ""
+msgstr "删除æºåˆ†æ”¯"
msgid "Deletes the source branch."
-msgstr ""
+msgstr "删除æºåˆ†æ”¯ã€‚"
msgid "Deleting"
msgstr "删除中"
@@ -11332,11 +11558,14 @@ msgid "Dependency Scanning"
msgstr "ä¾èµ–项扫æ"
msgid "Dependency list"
-msgstr ""
+msgstr "ä¾èµ–列表"
msgid "DependencyProxy|Cached %{time}"
msgstr "已缓存 %{time}"
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr "自动清除ä¾èµ–代ç†ç¼“å­˜"
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr "åŒ…å« %{count} 个镜åƒå—(%{size})"
@@ -11356,19 +11585,22 @@ msgid "DependencyProxy|Dependency Proxy image prefix"
msgstr "ä¾èµ–代ç†é•œåƒå‰ç¼€"
msgid "DependencyProxy|Enable Dependency Proxy"
-msgstr ""
+msgstr "å¯ç”¨ä¾èµ–代ç†"
msgid "DependencyProxy|Image list"
-msgstr ""
+msgstr "é•œåƒåˆ—表"
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
-msgstr ""
+msgid "DependencyProxy|Storage settings"
+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}Dependency Proxy%{linkEnd}"
+
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr "å¯ç”¨åŽï¼Œè¶…过 90 天的镜åƒå°†ä»Žç¼“存中删除。"
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
@@ -11832,7 +12064,7 @@ msgid "DevOps Adoption"
msgstr "DevOps Adoption"
msgid "DevOps Reports"
-msgstr ""
+msgstr "DevOps 报告"
msgid "DevOps adoption"
msgstr "DevOps adoption"
@@ -12096,7 +12328,7 @@ msgid "Disable"
msgstr "ç¦ç”¨"
msgid "Disable Elasticsearch until indexing completes."
-msgstr ""
+msgstr "在索引完æˆä¹‹å‰ç¦ç”¨Elasticsearch。"
msgid "Disable Two-factor Authentication"
msgstr "ç¦ç”¨åŒé‡è®¤è¯"
@@ -12164,15 +12396,15 @@ msgstr "对于已ç»å‘布到生产环境中的代ç ï¼Œæˆ‘们的仪表æ¿ä¸ºæ‚¨
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr "GitLab将对您的应用程åºä»£ç æ‰§è¡Œé™æ€å’ŒåŠ¨æ€æµ‹è¯•ï¼ŒæŸ¥æ‰¾å·²çŸ¥ç¼ºé™·å¹¶åœ¨åˆå¹¶è¯·æ±‚中报告这些缺陷,以便您å¯ä»¥åœ¨åˆå¹¶ä¹‹å‰ä¿®å¤å®ƒä»¬ã€‚"
-msgid "Discover|Give feedback for this page"
-msgstr "æ供此页é¢çš„å馈"
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr "安全能力,整åˆåˆ°æ‚¨çš„å¼€å‘生命周期中"
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr "查看 %{linkStart}旗舰版方案%{linkEnd} 的其它功能"
+msgid "Discover|Send feedback"
+msgstr "å‘é€å馈"
+
msgid "Discover|Start a free trial"
msgstr "开始å…费试用"
@@ -12265,7 +12497,7 @@ msgid "Does not apply to projects in personal namespaces, which are deleted imme
msgstr "ä¸é€‚用于个人命å空间中的项目,这些项目会根æ®è¦æ±‚ç«‹å³åˆ é™¤ã€‚"
msgid "Does not delete the source branch."
-msgstr ""
+msgstr "ä¸åˆ é™¤æºåˆ†æ”¯ã€‚"
msgid "Domain"
msgstr "域å"
@@ -12312,6 +12544,9 @@ msgstr "下载(%{size})"
msgid "Download CSV"
msgstr "下载CSV"
+msgid "Download PDF"
+msgstr "下载 PDF"
+
msgid "Download artifacts"
msgstr "下载产物"
@@ -12391,7 +12626,7 @@ msgid "DropdownWidget|No %{issuableAttribute} found"
msgstr "未找到 %{issuableAttribute}"
msgid "DropdownWidget|No open %{issuableAttribute} found"
-msgstr ""
+msgstr "找ä¸åˆ°å¼€æ”¾çš„ %{issuableAttribute}"
msgid "Due Date"
msgstr "截止日期"
@@ -12447,8 +12682,8 @@ msgstr "编辑里程碑"
msgid "Edit Password"
msgstr "编辑密ç "
-msgid "Edit Pipeline Schedule %{id}"
-msgstr "编辑 %{id} æµæ°´çº¿è®¡åˆ’"
+msgid "Edit Pipeline Schedule"
+msgstr "编辑æµæ°´çº¿è®¡åˆ’"
msgid "Edit Release"
msgstr "编辑å‘布"
@@ -12472,13 +12707,13 @@ msgid "Edit comment"
msgstr "编辑评论"
msgid "Edit commit message"
-msgstr ""
+msgstr "编辑æ交消æ¯"
msgid "Edit deploy freeze"
msgstr "编辑部署冻结"
msgid "Edit deploy key"
-msgstr ""
+msgstr "编辑部署密钥"
msgid "Edit description"
msgstr "编辑æè¿°ä¿¡æ¯"
@@ -12486,6 +12721,9 @@ msgstr "编辑æè¿°ä¿¡æ¯"
msgid "Edit environment"
msgstr "编辑环境"
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr "在编辑器中编辑文件并在这里​​æ交å˜æ›´å†…容"
@@ -12574,7 +12812,7 @@ msgid "Elasticsearch indexing started"
msgstr "Elasticsearch索引已å¯åŠ¨"
msgid "Elasticsearch migration halted"
-msgstr ""
+msgstr "Elasticsearch è¿ç§»å·²åœæ­¢"
msgid "Elasticsearch reindexing is already in progress"
msgstr "Elasticsearché‡å»ºç´¢å¼•æ­£åœ¨è¿›è¡Œä¸­"
@@ -12592,7 +12830,7 @@ msgid "Elasticsearch zero-downtime reindexing"
msgstr "Elasticsearchä¸åœæœºé‡å»ºç´¢å¼•"
msgid "Elasticsearch's region."
-msgstr ""
+msgstr "Elasticsearch 的区域。"
msgid "Elastic|None. Select namespaces to index."
msgstr "无。请选择è¦å»ºç«‹ç´¢å¼•çš„命å空间。"
@@ -12616,7 +12854,7 @@ msgid "Email a new %{name} to this project"
msgstr "通过电å­é‚®ä»¶å‘该项目å‘é€ %{name}"
msgid "Email address suffix"
-msgstr ""
+msgstr "电å­é‚®ä»¶åœ°å€åŽç¼€"
msgid "Email address to use for Support Desk"
msgstr "用于技术支æŒçš„电å­é‚®ä»¶åœ°å€"
@@ -12769,7 +13007,7 @@ msgid "Enable SSL verification"
msgstr "å¯ç”¨ SSL 验è¯"
msgid "Enable Sentry error tracking"
-msgstr ""
+msgstr "å¯ç”¨ Sentry 错误跟踪"
msgid "Enable Service Ping"
msgstr "å¯ç”¨æœåŠ¡Ping"
@@ -12793,7 +13031,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 "å¯ç”¨è®¿é—®ä»¤ç‰Œåœ¨ 2 å°æ—¶åŽè¿‡æœŸï¼Œå¦‚æžœç¦ç”¨ï¼Œä»¤ç‰Œä¸ä¼šè¿‡æœŸã€‚"
msgid "Enable admin mode"
msgstr "å¯ç”¨ç®¡ç†æ¨¡å¼"
@@ -13045,10 +13283,10 @@ msgid "Enter the number of seconds, or other human-readable input, like \"1 hour
msgstr "输入秒数或其它å¯è¯»çš„输入,如“1 å°æ—¶â€ã€‚此超时优先于为项目设置的较低超时。"
msgid "Enter the password for password-protected Elasticsearch servers."
-msgstr ""
+msgstr "输入å—密ç ä¿æŠ¤çš„ Elasticsearch æœåŠ¡å™¨çš„密ç ã€‚"
msgid "Enter the username for password-protected Elasticsearch servers."
-msgstr ""
+msgstr "输入å—密ç ä¿æŠ¤çš„ Elasticsearch æœåŠ¡å™¨çš„用户å。"
msgid "Enter your Packagist server. Defaults to https://packagist.org."
msgstr "输入您的 Packagist æœåŠ¡å™¨ã€‚默认为 https://packagist.org。"
@@ -13139,7 +13377,7 @@ msgid "EnvironmentsDashboard|The environments dashboard provides a summary of ea
msgstr "环境仪表æ¿æä¾›æ¯ä¸ªé¡¹ç›®çŽ¯å¢ƒçŠ¶æ€çš„摘è¦ï¼ŒåŒ…括æµæ°´çº¿å’Œè­¦æŠ¥çŠ¶æ€ã€‚"
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 ""
+msgstr "此仪表æ¿æ˜¾ç¤ºæ¯ä¸ªé¡¹ç›®çš„ 3 个环境,并链接到æ“作仪表æ¿ï¼Œå½“您从一个仪表æ¿æ·»åŠ æˆ–删除项目时,GitLab 会从å¦ä¸€ä¸ªä»ªè¡¨æ¿æ·»åŠ æˆ–删除项目。 %{linkStart}更多信æ¯%{linkEnd}"
msgid "Environments|An error occurred while canceling the auto stop, please try again"
msgstr "å–消自动终止时å‘生错误,请é‡è¯•"
@@ -13426,6 +13664,9 @@ msgstr "排åºæ—¶å‡ºé”™ã€‚"
msgid "Epics|Something went wrong while removing issue from epic."
msgstr "从å²è¯—中删除议题时出错。"
+msgid "Epics|Something went wrong while updating epics."
+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 "这个å²è¯—和任何包å«å­å²è¯—çš„ä¿¡æ¯å‡ä¸ºç§å¯†ï¼Œåªèƒ½å¯¹æ‹¥æœ‰è‡³å°‘报告者访问æƒé™çš„团队æˆå‘˜å¯è§ã€‚"
@@ -13471,9 +13712,6 @@ msgstr "创建代ç ç‰‡æ®µ%{snippet_id}的代ç åº“时出错"
msgid "Error creating the snippet"
msgstr "创建代ç ç‰‡æ®µå‡ºé”™"
-msgid "Error deleting %{issuableType}"
-msgstr "删除%{issuableType}时出错"
-
msgid "Error deleting project. Check logs for error details."
msgstr "删除项目时出错。请检查错误详细信æ¯ã€‚"
@@ -13627,9 +13865,6 @@ msgstr "上传文件时出错: %{stripped}"
msgid "Error while loading the merge request. Please try again."
msgstr "加载åˆå¹¶è¯·æ±‚时出错。请å†è¯•ä¸€æ¬¡ã€‚"
-msgid "Error while loading the project data. Please try again."
-msgstr "加载项目数æ®æ—¶å‡ºé”™ã€‚请é‡è¯•ã€‚"
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr "è¿ç§» %{upload_id} 时出错 : %{error_message}"
@@ -13714,6 +13949,9 @@ msgstr "å‡çº§ç­–ç•¥ä¸èƒ½è¶…过 %{rule_count} 个规则"
msgid "Escalation policies must have at least one rule"
msgstr "å‡çº§ç­–略必须至少有一个规则"
+msgid "Escalation policy:"
+msgstr "å‡çº§ç­–略:"
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr "%{clockIcon}如果警报在%{minutes}分钟内ä¸æ˜¯%{alertStatus}"
@@ -13763,7 +14001,7 @@ msgid "EscalationPolicies|Escalation policies"
msgstr "å‡çº§ç­–ç•¥"
msgid "EscalationPolicies|Escalation policy %{obstacle} in project %{project}"
-msgstr ""
+msgstr "项目 %{project} çš„å‡çº§ç­–ç•¥ %{obstacle}"
msgid "EscalationPolicies|Escalation rules"
msgstr "å‡çº§è§„则"
@@ -13898,9 +14136,6 @@ msgstr "æ¯å¹´"
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr "æ¯å¹´åœ¨ %{day} çš„ %{time} %{timezone}"
-msgid "Everyone"
-msgstr "所有人"
-
msgid "Everyone With Access"
msgstr "具有访问æƒé™çš„任何人"
@@ -14061,10 +14296,10 @@ msgid "Explore public groups"
msgstr "æµè§ˆå…¬å¼€ç¾¤ç»„"
msgid "Explore snippets"
-msgstr ""
+msgstr "æµè§ˆä»£ç ç‰‡æ®µ"
msgid "Explore topics"
-msgstr ""
+msgstr "æµè§ˆä¸»é¢˜"
msgid "Export"
msgstr "导出"
@@ -14093,8 +14328,8 @@ msgstr "导出项目"
msgid "Export requirements"
msgstr "导出需求"
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
-msgstr "将所有相关数æ®å¯¼å‡ºåˆ°æ–°çš„GitLab实例。完æˆåŽï¼Œæ‚¨å¯ä»¥ä»Ž\"创建新群组\"页é¢å¯¼å…¥æ•°æ®æ–‡ä»¶ã€‚"
+msgid "Export this group with all related data."
+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 "导出此项目åŠå…¶æ‰€æœ‰ç›¸å…³æ•°æ®ï¼Œä»¥ä¾¿å°†å…¶ç§»åŠ¨åˆ°æ–°çš„ GitLab 实例。导出的文件准备就绪åŽï¼Œæ‚¨å¯ä»¥ä»Žæ­¤é¡µé¢æˆ–从您将收到的电å­é‚®ä»¶é€šçŸ¥ä¸­çš„下载链接下载它。然åŽï¼Œæ‚¨å¯ä»¥åœ¨åˆ›å»ºæ–°é¡¹ç›®æ—¶å°†å…¶å¯¼å…¥ã€‚ %{link_start}了解更多。%{link_end}"
@@ -14142,10 +14377,10 @@ msgid "ExternalAuthorizationService|When no classification label is set the defa
msgstr "未设置分类标签的时候,将使用默认的分类标签`%{default_label}`。"
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 ""
+msgstr "此处å¯èƒ½ä¸ä¼šæ˜¾ç¤ºæ‰€æœ‰æ•°æ®ï¼Œè¦æŸ¥çœ‹æ›´å¤šè¯¦ç»†ä¿¡æ¯æˆ–对此议题进行更改,请转到 %{linkStart}%{trackerName}%{linkEnd}。"
msgid "ExternalIssueIntegration|This issue is synchronized with %{trackerName}"
-msgstr ""
+msgstr "此问题已与 %{trackerName} åŒæ­¥"
msgid "ExternalWikiService|External wiki"
msgstr "外部Wiki"
@@ -14263,7 +14498,7 @@ msgid "Failed to install."
msgstr "安装失败。"
msgid "Failed to load"
-msgstr ""
+msgstr "加载失败"
msgid "Failed to load assignees."
msgstr "加载指派人失败。"
@@ -14332,7 +14567,7 @@ msgid "Failed to move this issue because target project doesn't exist."
msgstr "无法移动此议题,因为目标项目ä¸å­˜åœ¨ã€‚"
msgid "Failed to promote issue to incident"
-msgstr ""
+msgstr "æå‡è®®é¢˜åˆ°äº‹ä»¶å¤±è´¥"
msgid "Failed to promote label due to internal error. Please contact administrators."
msgstr "由于内部错误而无法å‡çº§æ ‡è®°ã€‚请è”系管ç†å‘˜ã€‚"
@@ -14784,7 +15019,7 @@ msgid "Filter by merge requests that are currently merged."
msgstr "按当å‰å·²åˆå¹¶çš„åˆå¹¶è¯·æ±‚筛选。"
msgid "Filter by milestone"
-msgstr ""
+msgstr "按里程碑筛选"
msgid "Filter by milestone name"
msgstr "按里程碑å称筛选"
@@ -14798,9 +15033,6 @@ msgstr "按当å‰å·²å½’档的测试用例筛选。"
msgid "Filter by test cases that are currently open."
msgstr "按当å‰å¼€æ”¾çš„测试用例进行过滤。"
-msgid "Filter by two-factor authentication"
-msgstr "按åŒé‡è®¤è¯ç­›é€‰"
-
msgid "Filter by user"
msgstr "按用户筛选"
@@ -14961,7 +15193,7 @@ msgid "For example, the application using the token or the purpose of the token.
msgstr "例如,应用程åºä½¿ç”¨ä»¤ç‰Œæˆ–令牌的用途。"
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
-msgstr ""
+msgstr "对于大于此é™åˆ¶çš„文件,仅索引文件å,文件内容既ä¸ç¼–入索引也ä¸å¯æœç´¢ã€‚"
msgid "For general work"
msgstr "关于一般性工作"
@@ -15131,6 +15363,9 @@ msgstr "从åˆå¹¶è¯·æ±‚被åˆå¹¶åŽåˆ°éƒ¨ç½²è‡³ç”Ÿäº§çŽ¯å¢ƒ"
msgid "Full"
msgstr "全部"
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr "å…¨å"
@@ -15177,7 +15412,7 @@ msgid "Generate site and private keys at"
msgstr "生æˆç«™ç‚¹å’Œç§é’¥åœ¨"
msgid "Generated service account is linked to the selected environment"
-msgstr ""
+msgstr "生æˆçš„æœåŠ¡å¸æˆ·ä¸Žæ‰€é€‰çŽ¯å¢ƒç›¸å…³è”"
msgid "Generic"
msgstr "通用"
@@ -15729,7 +15964,7 @@ msgid "GitLab account request rejected"
msgstr "GitLabå¸æˆ·è¯·æ±‚被拒ç»"
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æ交"
@@ -15795,7 +16030,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"
@@ -15969,49 +16204,46 @@ 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 ""
+msgstr "结果已更新, %{count} 个结果å¯ç”¨ï¼Œä½¿ç”¨ä¸Šä¸‹ç®­å¤´é”®æµè§ˆæœç´¢ç»“果列表,或使用 ENTER é”®æ交。"
msgid "GlobalSearch|Search GitLab"
-msgstr ""
-
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
+msgstr "æœç´¢ GitLab"
msgid "GlobalSearch|Search results are loading"
-msgstr ""
+msgstr "æœç´¢ç»“果正在加载中"
msgid "GlobalSearch|Type and press the enter key to submit search."
-msgstr ""
+msgstr "输入并按回车键æ交æœç´¢ã€‚"
msgid "GlobalSearch|Type for new suggestions to appear below."
-msgstr ""
+msgstr "新建议在下é¢æ˜¾ç¤ºã€‚"
msgid "GlobalSearch|in all GitLab"
-msgstr ""
+msgstr "在整个 GitLab 实例中"
msgid "GlobalSearch|in group"
-msgstr ""
+msgstr "在群组中"
msgid "GlobalSearch|in project"
-msgstr ""
+msgstr "在项目中"
msgid "Go Back"
msgstr "返回"
@@ -16082,6 +16314,9 @@ msgstr "转到指标"
msgid "Go to next page"
msgstr "转到下一页"
+msgid "Go to page %{page}"
+msgstr "å‰å¾€ %{page} 页"
+
msgid "Go to parent"
msgstr "转到上一级"
@@ -16161,19 +16396,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 "谷歌的身份验è¯æœª%{link_start}正确é…ç½®%{link_end}。如需使用这项æœåŠ¡ï¼Œè¯·è”ç³»GitLab管ç†å‘˜ã€‚"
@@ -16230,7 +16465,7 @@ msgid "GraphViewType|Stage"
msgstr "阶段"
msgid "Graphs"
-msgstr ""
+msgstr "图表"
msgid "Gravatar"
msgstr "Gravatar"
@@ -16271,9 +16506,6 @@ msgstr "å¿…é¡»å¯ç”¨ç¾¤ç»„SAMLæ‰èƒ½è¿›è¡Œæµ‹è¯•"
msgid "Group URL"
msgstr "群组URL"
-msgid "Group Wikis"
-msgstr "群组 Wiki"
-
msgid "Group application: %{name}"
msgstr "群组应用程åºï¼š%{name}"
@@ -16400,6 +16632,9 @@ msgstr "群组已导出"
msgid "Group was successfully updated."
msgstr "群组已æˆåŠŸæ›´æ–°ã€‚"
+msgid "Group wikis"
+msgstr "群组 Wiki"
+
msgid "Group: %{group_name}"
msgstr "群组:%{group_name}"
@@ -16497,14 +16732,23 @@ msgid "GroupSAML|\"persistent\" recommended"
msgstr "推è“æŒä¹…化â€"
msgid "GroupSAML|%{strongOpen}Warning%{strongClose} - Enable %{linkStart}SSO enforcement%{linkEnd} to reduce security risks."
-msgstr ""
+msgstr "%{strongOpen}警告%{strongClose} - å¯ç”¨ %{linkStart}SSO 实施%{linkEnd} 以é™ä½Žå®‰å…¨é£Žé™©ã€‚"
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr "å¯ç”¨çš„SAML群组链接(%{count})"
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr "生æˆæ‚¨çš„ SCIM 令牌时出错。请å†è¯•ä¸€æ¬¡ã€‚"
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr "é‡ç½®æ‚¨çš„ SCIM 令牌时出错。请å†è¯•ä¸€æ¬¡ã€‚"
+
msgid "GroupSAML|Are you sure you want to remove the SAML group link?"
msgstr "您确定è¦åˆ é™¤SAML群组链接å—?"
+msgid "GroupSAML|Are you sure you want to reset the SCIM token? SCIM provisioning will stop working until the new token is updated."
+msgstr "您确定è¦é‡ç½® SCIM 令牌å—?在更新新令牌之å‰ï¼ŒSCIM é…置将åœæ­¢å·¥ä½œã€‚"
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr "在执行SSO之å‰ï¼Œå¯ç”¨SAML身份验è¯ã€‚"
@@ -16577,6 +16821,9 @@ msgstr "没有å¯ç”¨çš„SAML群组链接"
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr "ç¦æ­¢ä»Žæ­¤ç¾¤ç»„å‘外派生。"
+msgid "GroupSAML|Reset SCIM token"
+msgstr "é‡ç½® SCIM 令牌"
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr "指定此SAML群组æˆå‘˜çš„角色。"
@@ -16616,6 +16863,9 @@ msgstr "SAML令牌签åè¯ä¹¦çš„SHA1指纹。请从身份验è¯æ供商处获å
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr "SCIM 令牌现在已éšè—。è¦å†æ¬¡æŸ¥çœ‹ä»¤ç‰Œçš„å€¼ï¼Œæ‚¨éœ€è¦ "
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr "SCIM 令牌现已éšè—。è¦å†æ¬¡æŸ¥çœ‹ä»¤ç‰Œçš„值,您需è¦%{linkStart}将其é‡ç½®%{linkEnd}。"
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr "将由 SAML 身份æ供商å‘é€çš„群组å称,区分大å°å†™ã€‚"
@@ -16649,6 +16899,18 @@ msgstr "必须匹é…存储的“%{extern_uid}â€çš„ NameID 以识别用户并å…
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr "建议使用æŒä¹…性 ID 而ä¸æ˜¯ç”µå­é‚®ä»¶"
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr "å¤åˆ¶ SCIM API 端点 URL"
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr "å¤åˆ¶ SCIM 令牌"
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr "SCIM API 端点 URL"
+
+msgid "GroupSaml|Your SCIM token"
+msgstr "您的 SCIM 令牌"
+
msgid "GroupSelect|No matching results"
msgstr "没有匹é…的结果"
@@ -16673,8 +16935,8 @@ msgstr "仅在顶级群组中å¯ç”¨ã€‚适用于所有å­ç»„。除éžæ‰‹åŠ¨åˆ é™¤
msgid "GroupSettings|Badges"
msgstr "徽章"
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
-msgstr "请注æ„。更改群组的父级å¯èƒ½ä¼šæœ‰%{side_effects_link_start}æ„外副作用%{side_effects_link_end}。"
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
+msgstr "注æ„,更改群组的父级å¯èƒ½ä¼šäº§ç”Ÿæ„想ä¸åˆ°çš„副作用。%{learn_more_link_start}了解更多。%{learn_more_link_end}"
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
msgstr "无法更新路径。因为此群组下的项目包å«äº†å®¹å™¨é•œåƒåº“çš„Dockeré•œåƒã€‚请先从您的项目中删除镜åƒåŽé‡è¯•ã€‚"
@@ -16682,8 +16944,8 @@ msgstr "无法更新路径。因为此群组下的项目包å«äº†å®¹å™¨é•œåƒåº“
msgid "GroupSettings|Change group URL"
msgstr "更改群组URL"
-msgid "GroupSettings|Changing group URL can have unintended side effects."
-msgstr "更改群组URLå¯èƒ½ä¼šæœ‰éžé¢„期的副作用。"
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
+msgstr "更改群组 URL å¯èƒ½ä¼šäº§ç”Ÿæ„外的副作用。"
msgid "GroupSettings|Compliance frameworks"
msgstr "åˆè§„框架"
@@ -16724,6 +16986,9 @@ msgstr "已生æˆæ–°çš„Runner注册令牌ï¼"
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr "覆盖群组ã€å­ç»„和项目所有æˆå‘˜çš„用户通知å好设置。"
+msgid "GroupSettings|Parent Group"
+msgstr "父组"
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr "群组æµæ°´çº¿è®¾ç½®å·²æ›´æ–°"
@@ -16751,12 +17016,18 @@ msgstr "项目将在 %{waiting_period}天延迟åŽæ°¸ä¹…删除,由å­ç»„继承
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr "项目将在%{waiting_period}天延迟åŽæ°¸ä¹…删除,此延迟在实例设置中%{link_start}å¯ä»¥ç”±ç®¡ç†å‘˜å®šä¹‰%{link_end} ,由å­ç¾¤ç»„继承。"
+msgid "GroupSettings|Search groups"
+msgstr "æœç´¢ç¾¤ç»„"
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr "选择 %{code_start}.gitlab/insights.yml%{code_end} 文件的项目"
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr "选择一个å­ç»„用作该组的自定义项目模æ¿çš„æºã€‚"
+msgid "GroupSettings|Select parent group"
+msgstr "选择父组"
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr "选择包å«è‡ªå®šä¹‰Insight文件的项目。"
@@ -16797,10 +17068,10 @@ msgid "GroupSettings|What are badges?"
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 ""
+msgstr "当活跃用户数é‡è¶…过这个数字时,é¢å¤–的用户必须由 %{user_cap_docs_link_start}所有者%{user_cap_docs_link_end}批准,如果您ä¸æƒ³å¼ºåˆ¶æ‰§è¡Œæ‰¹å‡†ï¼Œè¯·ç•™ç©ºã€‚"
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. Increasing the user cap will not automatically approve pending users."
-msgstr ""
+msgstr "当活跃用户数超过这个数时,é¢å¤–的用户必须是 %{user_cap_docs_link_start}由所有者%{user_cap_docs_link_end}批准。如果您ä¸æƒ³å¼ºåˆ¶æ‰§è¡Œå®¡æ‰¹ï¼Œè¯·ç•™ç©ºã€‚增加用户上é™ä¸ä¼šè‡ªåŠ¨æ‰¹å‡†å¾…定用户。"
msgid "GroupSettings|You can only transfer the group to a group you manage."
msgstr "您åªèƒ½å°†å½“å‰ç¾¤ç»„转移到您管ç†ä¸‹çš„群组。"
@@ -16871,6 +17142,9 @@ msgstr "您å¯ä»¥ç®¡ç†ç¾¤ç»„æˆå‘˜çš„æƒé™å¹¶è®¿é—®ç¾¤ç»„中的æ¯ä¸ªé¡¹ç›®ã€‚
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr "%{linkStart}群组%{linkEnd}å…许您在多个项目之间进行管ç†ä¸Žå作。群组的æˆå‘˜æ‹¥æœ‰è®¿é—®å…¶ä¸­æ‰€æœ‰é¡¹ç›®çš„æƒé™ã€‚"
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr "询问您的管ç†å‘˜ %{enable_link_start}å¯ç”¨%{enable_link_end} 群组è¿ç§»ã€‚"
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr "将相关项目组åˆåœ¨ä¸€èµ·å¹¶ä¸€æ¬¡æŽˆäºˆæˆå‘˜è®¿é—®å¤šä¸ªé¡¹ç›®çš„æƒé™ã€‚"
@@ -16925,6 +17199,9 @@ msgstr "请填写个人访问令牌。"
msgid "GroupsNew|Provide credentials for another instance of GitLab to import your groups directly."
msgstr "为å¦ä¸€ä¸ª GitLab 实例æ供凭æ®ä»¥ç›´æŽ¥å¯¼å…¥æ‚¨çš„群组。"
+msgid "GroupsNew|This feature is deprecated and replaced by %{docs_link_start}Group Migration%{docs_link_end}."
+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 "è¦å¯¼å…¥ç¾¤ç»„,请导航到 GitLab æºå®žä¾‹çš„群组设置, %{link_start}生æˆå¯¼å‡ºæ–‡ä»¶%{link_end},然åŽåœ¨æ­¤å¤„上传。"
@@ -16980,10 +17257,10 @@ msgid "Hashed storage can't be disabled anymore for new projects"
msgstr "新项目ä¸èƒ½å†ç¦ç”¨å“ˆå¸Œå­˜å‚¨"
msgid "Have a quick chat with us about your experience."
-msgstr ""
+msgstr "与我们快速èŠèŠæ‚¨çš„体验。"
msgid "Have more to say about GitLab?"
-msgstr ""
+msgstr "有更多关于GitLab的内容?"
msgid "Header logo"
msgstr "Header logo"
@@ -16998,10 +17275,10 @@ msgid "Header message"
msgstr "页头消æ¯"
msgid "HeaderAction|incident"
-msgstr ""
+msgstr "事件"
msgid "HeaderAction|issue"
-msgstr ""
+msgstr "议题"
msgid "Headers"
msgstr "Headers"
@@ -17100,7 +17377,7 @@ msgid "Hi %{username}!"
msgstr "%{username},您好!"
msgid "Hidden"
-msgstr ""
+msgstr "éšè—"
msgid "Hide"
msgstr "éšè—"
@@ -17366,7 +17643,7 @@ msgid "Identities"
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 ""
+msgstr "如果任何索引字段超过此é™åˆ¶ï¼Œåˆ™å°†å…¶æˆªæ–­ä¸ºæ­¤å­—符数。其余内容既ä¸ç¼–入索引也ä¸å¯æœç´¢ã€‚è¿™ä¸é€‚用于仓库和 wiki 索引。对于无é™å­—符,将此设置为 0。"
msgid "If blank, defaults to %{code_open}Retry later%{code_close}."
msgstr "如果为空,默认为 %{code_open}ç¨åŽé‡è¯•%{code_close}。"
@@ -17405,7 +17682,7 @@ msgid "If the number of active users exceeds the user limit, you will be charged
msgstr "如果活跃用户数é‡è¶…过了用户é™åˆ¶ï¼Œæ‚¨ä¸‹æ¬¡çš„许å¯è¯å¯¹è´¦æ—¶å°†ä¼šæ”¶å–%{users_over_license_link}个席ä½çš„费用。"
msgid "If there isn't any existing index, GitLab creates one."
-msgstr ""
+msgstr "如果没有任何现有索引,GitLab 会创建一个。"
msgid "If this email was added in error, you can remove it here:"
msgstr "如果此电å­é‚®ä»¶è¢«é”™è¯¯æ·»åŠ ï¼Œæ‚¨å¯ä»¥åœ¨è¿™é‡Œåˆ é™¤ï¼š"
@@ -18182,10 +18459,10 @@ msgid "IncidentManagement|All"
msgstr "全部"
msgid "IncidentManagement|All alerts promoted to incidents are automatically displayed within the list."
-msgstr ""
+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 "指派人"
@@ -18413,7 +18690,7 @@ msgid "Infrastructure Registry"
msgstr "基础设施库"
msgid "Infrastructure as Code (IaC) Scanning"
-msgstr ""
+msgstr "基础设施å³ä»£ç  (IaC) 扫æ"
msgid "InfrastructureRegistry|Copy Terraform Command"
msgstr "å¤åˆ¶ Terraform 命令"
@@ -18630,7 +18907,7 @@ msgid "Integrations|Default settings are inherited from the instance level."
msgstr "默认设置继承自实例级别。"
msgid "Integrations|Edit project alias"
-msgstr ""
+msgstr "编辑项目别å"
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr "在 Slack 工作区中å¯ç”¨ GitLab.com æ–œæ å‘½ä»¤ã€‚"
@@ -18639,7 +18916,7 @@ msgid "Integrations|Enable comments"
msgstr "å¯ç”¨è¯„论"
msgid "Integrations|Enter your alias"
-msgstr ""
+msgstr "输入您的别å"
msgid "Integrations|Failed to link namespace. Please try again."
msgstr "无法链接命å空间,请é‡è¯•ã€‚"
@@ -18759,7 +19036,7 @@ msgid "Integrations|You can now close this window and return to the GitLab for J
msgstr "您现在å¯ä»¥å…³é—­æ­¤çª—å£å¹¶è¿”回GitLab for Jira应用。"
msgid "Integrations|You can use this alias in your Slack commands"
-msgstr ""
+msgstr "您å¯ä»¥åœ¨ Slack 命令中使用此别å"
msgid "Integrations|You haven't activated any integrations yet."
msgstr "您尚未激活任何集æˆã€‚"
@@ -18777,10 +19054,10 @@ msgid "Integrations|ZenTao issues display here when you create issues in your pr
msgstr "当您在禅é“中创建项目的议题时,禅é“议题会显示在此处。"
msgid "Integrations|can't exceed %{recipients_limit}"
-msgstr ""
+msgstr "ä¸èƒ½è¶…过 %{recipients_limit}"
msgid "Interactive developer security education."
-msgstr ""
+msgstr "互动å¼å¼€å‘者安全教育。"
msgid "Interactive mode"
msgstr "交互模å¼"
@@ -18816,7 +19093,7 @@ msgid "Introduced in GitLab 13.1, before using %{reindexing_link_start}zero-down
msgstr ""
msgid "Introducing Your DevOps Reports"
-msgstr ""
+msgstr "介ç»æ‚¨çš„ DevOps 报告"
msgid "Invalid Insights config file detected"
msgstr "检测到无效的 Insights é…置文件"
@@ -18827,6 +19104,9 @@ msgstr "无效的æ“作系统"
msgid "Invalid URL"
msgstr "无效的网å€"
+msgid "Invalid URL: %{url}"
+msgstr "无效 URL:%{url}"
+
msgid "Invalid container_name"
msgstr "无效的container_name"
@@ -18873,7 +19153,7 @@ msgid "Invalid period"
msgstr "无效的周期"
msgid "Invalid pin code."
-msgstr ""
+msgstr "无效的 pin ç ã€‚"
msgid "Invalid pod_name"
msgstr "无效的pod_name"
@@ -19011,19 +19291,19 @@ msgid "InviteMembersModal|Close invite team members"
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 "为您的新团队æˆå‘˜åˆ›å»ºè®®é¢˜ (å¯é€‰)"
msgid "InviteMembersModal|GitLab is better with colleagues!"
-msgstr ""
+msgstr "GitLab 与åŒäº‹å…±å¤„æ›´ä½³ï¼"
msgid "InviteMembersModal|GitLab member or email address"
msgstr "GitLab用户或电å­é‚®ä»¶åœ°å€"
msgid "InviteMembersModal|How about inviting a colleague or two to join you?"
-msgstr ""
+msgstr "邀请一两个åŒäº‹åŠ å…¥ä½ æ€Žä¹ˆæ ·ï¼Ÿ"
msgid "InviteMembersModal|Invite"
msgstr "邀请"
@@ -19076,9 +19356,6 @@ msgstr "邀请团队æˆå‘˜"
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr "添加æˆå‘˜åˆ°æ­¤é¡¹ç›®å¹¶å¼€å§‹ä¸Žæ‚¨çš„团队åˆä½œã€‚"
-msgid "InviteMember|Invite Member"
-msgstr "邀请æˆå‘˜"
-
msgid "InviteMember|Invite Members (optional)"
msgstr "邀请æˆå‘˜ï¼ˆå¯é€‰ï¼‰"
@@ -19181,9 +19458,6 @@ msgstr "irker 守护进程端å£ï¼ˆé»˜è®¤ä¸º 6659)。"
msgid "Is blocked by"
msgstr "已被阻止。阻止项为"
-msgid "Is this GitLab trial for your company?"
-msgstr "是为您的公å¸è¯•ç”¨GitLabå—?"
-
msgid "Is using license seat:"
msgstr "正在使用许å¯è¯ï¼š"
@@ -19242,7 +19516,7 @@ msgid "Issue first deployed to production"
msgstr "议题首次部署到生产环境"
msgid "Issue has been promoted to incident"
-msgstr ""
+msgstr "议题已å‡çº§ä¸ºäº‹ä»¶"
msgid "Issue label"
msgstr "议题标记"
@@ -19295,9 +19569,6 @@ msgstr "状æ€"
msgid "IssueAnalytics|Weight"
msgstr "æƒé‡"
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr "设置通知状æ€æ—¶å‡ºé”™ã€‚请é‡è¯•ã€‚"
-
msgid "IssueBoards|Board"
msgstr "看æ¿"
@@ -19320,7 +19591,7 @@ msgid "IssueBoards|Switch board"
msgstr "切æ¢çœ‹æ¿"
msgid "IssueList|created %{timeAgoString} by %{user}"
-msgstr ""
+msgstr "ç”± %{user} 创建于 %{timeAgoString} å‰"
msgid "IssueTracker|Custom issue tracker"
msgstr "自定义议题跟踪器"
@@ -19386,7 +19657,7 @@ msgid "Issues and merge requests"
msgstr "议题和åˆå¹¶è¯·æ±‚"
msgid "Issues are being rebalanced at the moment, so manual reordering is disabled."
-msgstr ""
+msgstr "正在é‡æ–°æƒè¡¡è®®é¢˜ï¼Œå› æ­¤æ‰‹åŠ¨é‡æ–°æŽ’åºå·²è¢«ç¦ç”¨ã€‚"
msgid "Issues can be bugs, tasks or ideas to be discussed. Also, issues are searchable and filterable."
msgstr "议题å¯ä»¥æ˜¯ç¼ºé™·ï¼Œä»»åŠ¡æˆ–è¦è®¨è®ºçš„想法。此外,å¯ä»¥é€šè¿‡æœç´¢å’Œç­›é€‰æ¥æŸ¥æ‰¾è®®é¢˜ã€‚"
@@ -19488,7 +19759,7 @@ msgid "Iterations|Automated scheduling"
msgstr "自动调度计划"
msgid "Iterations|Cadence configuration is invalid."
-msgstr ""
+msgstr "周期é…置无效。"
msgid "Iterations|Cadence name"
msgstr "周期å称"
@@ -19500,7 +19771,7 @@ msgid "Iterations|Create cadence"
msgstr "创建周期"
msgid "Iterations|Create cadence and start iteration"
-msgstr ""
+msgstr "创建周期并开始迭代"
msgid "Iterations|Create iteration"
msgstr "创建迭代"
@@ -19599,13 +19870,13 @@ msgid "Iterations|Title"
msgstr "标题"
msgid "Iterations|Unable to find iteration cadence."
-msgstr ""
+msgstr "无法找到迭代周期。"
msgid "Iterations|Unable to find iteration."
msgstr "无法找到迭代。"
msgid "Iterations|Unable to save cadence. Please try again."
-msgstr ""
+msgstr "无法ä¿å­˜å‘¨æœŸï¼Œè¯·é‡è¯•ã€‚"
msgid "Iteration|Dates cannot overlap with other existing Iterations within this group"
msgstr "日期ä¸èƒ½ä¸Žè¯¥ç¾¤ç»„内的其它现有迭代é‡å "
@@ -19776,7 +20047,7 @@ msgid "JiraService|Jira issue type"
msgstr "Jira 议题类型"
msgid "JiraService|Jira issues"
-msgstr ""
+msgstr "Jira议题"
msgid "JiraService|Jira project key"
msgstr "Jira project key"
@@ -19943,8 +20214,8 @@ msgstr "完整原始日志"
msgid "Job|Download"
msgstr "下载"
-msgid "Job|Erase job log"
-msgstr "删除作业日志"
+msgid "Job|Erase job log and artifacts"
+msgstr "擦除作业日志和产物"
msgid "Job|Job artifacts"
msgstr "作业产物"
@@ -20115,7 +20386,7 @@ msgid "Ki"
msgstr "Ki"
msgid "Kontra"
-msgstr ""
+msgstr "Kontra"
msgid "Kroki"
msgstr "Kroki"
@@ -20394,6 +20665,12 @@ msgstr "此分支上最近æ交的最新æµæ°´çº¿"
msgid "Launch a ready-to-code development environment for your project."
msgstr "为您的项目å¯åŠ¨ä¸€ä¸ªçŽ°æˆçš„代ç å¼€å‘环境。"
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr "交付时间"
@@ -20461,7 +20738,7 @@ msgid "Learn more about groups."
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 ""
+msgstr "在 %{configuration_link_start}高级æœç´¢é…ç½®%{configuration_link_end} 中了解更多关于切片和副本的信æ¯ï¼Œç›´åˆ°æ‚¨ %{recreated_link_start}é‡æ–°åˆ›å»º%{recreated_link_end} 索引,æ‰èƒ½è¿›è¡Œæ›´æ”¹ã€‚"
msgid "Learn more about signing commits"
msgstr "了解更多有关签åæ交的详细信æ¯"
@@ -20566,7 +20843,7 @@ msgid "LearnGitLab|Use your new GitLab workflow to deploy your application, moni
msgstr "使用您的新 GitLab 工作æµç¨‹éƒ¨ç½²æ‚¨çš„应用程åºã€ç›‘控其è¿è¡ŒçŠ¶å†µå¹¶ç¡®ä¿å…¶å®‰å…¨ï¼š"
msgid "LearnGitLab|Your team is growing! You've successfully invited new team members to the %{projectName} project."
-msgstr ""
+msgstr "您的团队正在æˆé•¿ï¼æ‚¨å·²æˆåŠŸåœ°é‚€è¯·äº†æ–°çš„团队æˆå‘˜åˆ° %{projectName} 项目。"
msgid "LearnGitlab|Creating your onboarding experience..."
msgstr "正在创建您的入门体验..."
@@ -20614,7 +20891,7 @@ msgid "License Compliance"
msgstr "许å¯è¯åˆè§„"
msgid "License compliance"
-msgstr ""
+msgstr "许å¯è¯åˆè§„"
msgid "License file"
msgstr "许å¯è¯æ–‡ä»¶"
@@ -20776,7 +21053,7 @@ msgid "Licenses|The license list details information about the licenses used wit
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 "查看您项目的许å¯è¯è¯¦ç»†ä¿¡æ¯"
@@ -20800,7 +21077,7 @@ msgid "Limit the number of issues and epics per minute a user can create through
msgstr "é™åˆ¶ç”¨æˆ·æ¯åˆ†é’Ÿå¯ä»¥é€šè¿‡ Web å’Œ API 请求创建的议题和å²è¯—çš„æ•°é‡ã€‚"
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 "é™åˆ¶å­˜å‚¨åœ¨Redis中的Sidekiq作业的大å°ã€‚"
@@ -21017,7 +21294,7 @@ msgid "MERGED"
msgstr "å·²åˆå¹¶"
msgid "MR widget|Back to the merge request"
-msgstr ""
+msgstr "返回åˆå¹¶è¯·æ±‚"
msgid "MR widget|See your pipeline in action"
msgstr "查看您实际的æµæ°´çº¿"
@@ -21098,7 +21375,7 @@ msgid "Manage applications that can use GitLab as an OAuth provider, and applica
msgstr "管ç†å¯ä»¥å°†GitLab用作OAuthæ供程åºçš„应用程åºï¼Œä»¥åŠæ‚¨å·²æŽˆæƒä½¿ç”¨æ‚¨çš„å¸æˆ·çš„应用程åºã€‚"
msgid "Manage applications that use GitLab as an OAuth provider."
-msgstr ""
+msgstr "管ç†ä½¿ç”¨ GitLab 作为 OAuth æ供程åºçš„应用程åºã€‚"
msgid "Manage applications that you've authorized to use your account."
msgstr "管ç†æ‚¨æŽˆæƒä½¿ç”¨å¸æˆ·çš„应用程åºã€‚"
@@ -21148,8 +21425,8 @@ msgstr "手动"
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr "无法ä¿å­˜è®®é¢˜çš„顺åº"
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
-msgstr "手动链接此议题,方法是将其添加到%{originating_vulnerability}的链接议题部分。"
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
+msgstr "è¦æ‰‹åŠ¨é“¾æŽ¥æ­¤è®®é¢˜ï¼Œå°†å…¶æ·»åŠ åˆ°%{linkStart}原始æ¼æ´ž%{linkEnd}的链接议题部分。"
msgid "Map a FogBugz account ID to a GitLab user"
msgstr "å°†FogBugzå¸æˆ·ID映射为GitLab用户"
@@ -21311,7 +21588,7 @@ msgid "Maximum Conan package file size in bytes"
msgstr "最大Conan文件包大å°ï¼ˆå­—节)"
msgid "Maximum Helm chart file size in bytes"
-msgstr ""
+msgstr "最大 Helm chart 文件大å°ï¼ˆä»¥å­—节为å•ä½ï¼‰"
msgid "Maximum Maven package file size in bytes"
msgstr "最大Maven文件包大å°ï¼ˆå­—节)"
@@ -21332,7 +21609,7 @@ msgid "Maximum allowable lifetime for personal access token (days)"
msgstr "个人访问令牌的最长有效期(天)"
msgid "Maximum allowed lifetime for SSH keys (in days)"
-msgstr ""
+msgstr "SSH 密钥的最长å…许生命周期(以天为å•ä½ï¼‰"
msgid "Maximum artifacts size"
msgstr "最大工件大å°"
@@ -21704,10 +21981,10 @@ msgid "Merge automatically (%{strategy})"
msgstr "自动åˆå¹¶(%{strategy})"
msgid "Merge blocked: all merge request dependencies must be merged or closed."
-msgstr ""
+msgstr "åˆå¹¶è¢«é˜»æ­¢ï¼šå¿…é¡»åˆå¹¶æˆ–关闭所有åˆå¹¶è¯·æ±‚ä¾èµ–项。"
msgid "Merge blocked: merge request must be marked as ready. It's still marked as draft."
-msgstr ""
+msgstr "åˆå¹¶è¢«é˜»æ­¢ï¼šåˆå¹¶è¯·æ±‚必须标记为就绪。它ä»ç„¶è¢«æ ‡è®°ä¸ºè‰ç¨¿ã€‚"
msgid "Merge blocked: new changes were just added."
msgstr "åˆå¹¶è¢«é˜»æ­¢ï¼šåˆšåˆšæ·»åŠ äº†æ–°çš„更改。"
@@ -21725,7 +22002,7 @@ msgid "Merge commit message"
msgstr "åˆå¹¶æ交消æ¯"
msgid "Merge details"
-msgstr ""
+msgstr "åˆå¹¶è¯¦æƒ…"
msgid "Merge events"
msgstr "åˆå¹¶äº‹ä»¶"
@@ -21779,7 +22056,7 @@ msgid "Merge the branch and fix any conflicts that come up"
msgstr "åˆå¹¶åˆ†æ”¯å¹¶è§£å†³å‡ºçŽ°çš„任何冲çª"
msgid "Merge unavailable: merge requests are read-only in a secondary Geo node."
-msgstr ""
+msgstr "åˆå¹¶ä¸å¯ç”¨ï¼šåˆå¹¶è¯·æ±‚åœ¨æ¬¡è¦ Geo 节点中是åªè¯»çš„。"
msgid "Merge when pipeline succeeds"
msgstr "当æµæ°´çº¿æˆåŠŸæ—¶åˆå¹¶"
@@ -21899,15 +22176,15 @@ msgid "MergeRequest|Approved by @%{username}"
msgstr "由 @%{username} 批准"
msgid "MergeRequest|Can't show this merge request because of an internal error. Contact your administrator."
-msgstr ""
+msgstr "由于内部错误,无法显示此åˆå¹¶è¯·æ±‚。请è”系您的管ç†å‘˜ã€‚"
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
-msgstr ""
+msgstr "无法显示此åˆå¹¶è¯·æ±‚,因为派生项目已被删除。"
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22006,6 +22283,9 @@ msgstr "指标仪表æ¿YAML定义有效。"
msgid "Metrics and profiling"
msgstr "指标与分æž"
+msgid "Metrics:"
+msgstr "指标:"
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr "标注ä¸èƒ½åŒæ—¶å±žäºŽä¸€ä¸ªé›†ç¾¤å’Œä¸€ä¸ªçŽ¯å¢ƒ"
@@ -22546,7 +22826,7 @@ 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 "在您的个人资料中添加SSH密钥之å‰ï¼Œæ‚¨ä¸èƒ½é€šè¿‡SSHæ¥æ‹‰å–或推é€ä»“库。"
@@ -22623,6 +22903,9 @@ msgstr "这里"
msgid "More information."
msgstr "更多信æ¯ã€‚"
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr "è¶…å‰ %{number_commits_distance} 个æ交与 %{default_branch} ä¸åŒ"
@@ -22825,6 +23108,39 @@ msgstr "å‰å¾€è¯¥é¡¹ç›®ä»¥å…³é—­é‡Œç¨‹ç¢‘。"
msgid "Navigation bar"
msgstr "导航æ "
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr "帮助"
@@ -22973,7 +23289,7 @@ msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
msgstr "出现错误,无法获å–ç­–ç•¥"
msgid "NetworkPolicies|To enable alerts, %{installLinkStart}install an agent%{installLinkEnd} first."
-msgstr ""
+msgstr "è¦å¯ç”¨è­¦æŠ¥ï¼Œè¯·å…ˆ%{installLinkStart}安装代ç†%{installLinkEnd}。"
msgid "NetworkPolicies|Traffic that does not match any rule will be blocked."
msgstr "ä¸åŒ¹é…任何规则的æµé‡å°†è¢«é˜»æ­¢ã€‚"
@@ -23038,6 +23354,9 @@ msgstr "新增"
msgid "New %{issueType}"
msgstr "新建%{issueType}"
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr "新建应用"
@@ -23178,7 +23497,7 @@ msgid "New milestone"
msgstr "新里程碑"
msgid "New name"
-msgstr ""
+msgstr "新建å称"
msgid "New password"
msgstr "新密ç "
@@ -23217,7 +23536,7 @@ msgid "New schedule"
msgstr "新建计划"
msgid "New service account is generated for the selected Google Cloud project"
-msgstr ""
+msgstr "为选定的 Google Cloud 项目生æˆæ–°çš„æœåŠ¡å¸æˆ·"
msgid "New snippet"
msgstr "新建代ç ç‰‡æ®µ"
@@ -23261,6 +23580,9 @@ msgstr "下一个设计"
msgid "Next file in diff"
msgstr "差异中的下一个文件"
+msgid "Next scan"
+msgstr "下一次扫æ"
+
msgid "Next unresolved discussion"
msgstr "下一个未解决的讨论"
@@ -23415,7 +23737,7 @@ msgid "No forks are available to you."
msgstr "没有您å¯ç”¨çš„派生。"
msgid "No group provided"
-msgstr ""
+msgstr "没有æ供群组"
msgid "No grouping"
msgstr "无分组"
@@ -23466,13 +23788,13 @@ msgid "No matching results..."
msgstr "无匹é…结果..."
msgid "No member provided"
-msgstr ""
+msgstr "没有æä¾›æˆå‘˜"
msgid "No members found"
msgstr "未找到æˆå‘˜"
msgid "No memberships found"
-msgstr ""
+msgstr "未找到æˆå‘˜"
msgid "No merge requests found"
msgstr "找ä¸åˆ°åˆå¹¶è¯·æ±‚"
@@ -23517,7 +23839,7 @@ msgid "No projects found"
msgstr "未找到项目"
msgid "No public deploy keys"
-msgstr ""
+msgstr "没有公共部署密钥"
msgid "No public groups"
msgstr "无公开群组"
@@ -23541,7 +23863,7 @@ msgid "No schedules"
msgstr "无计划"
msgid "No service accounts"
-msgstr ""
+msgstr "没有æœåŠ¡å¸æˆ·"
msgid "No severity matches the provided parameter"
msgstr "没有与æ供的å‚数匹é…的严é‡ç¨‹åº¦"
@@ -23638,7 +23960,7 @@ msgid "Not confidential"
msgstr "éžç§å¯†"
msgid "Not found"
-msgstr ""
+msgstr "未找到"
msgid "Not found."
msgstr "未找到。"
@@ -23679,6 +24001,9 @@ msgstr "æ示:如GitLab管ç†å‘˜é…ç½® %{github_integration_link},将å…许
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr "æ示:如GitLab管ç†å‘˜é…ç½® %{github_integration_link},将å…许通过GitHub登录并å…许导入Github代ç ä»“库而ä¸éœ€è¦ä¸ªäººè®¿é—®ä»¤ç‰Œã€‚"
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr "注æ„"
@@ -23691,8 +24016,8 @@ msgstr "确定è¦å–消此评论å—?"
msgid "Notes|Collapse replies"
msgstr "收起回å¤"
-msgid "Notes|Confidential comments are only visible to project members"
-msgstr "ç§å¯†è¯„论åªå¯¹é¡¹ç›®æˆå‘˜å¯è§"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
+msgstr "机密评论åªå¯¹å…·æœ‰æŠ¥å‘Šäººæˆ–更高角色的æˆå‘˜å¯è§"
msgid "Notes|Make this comment confidential"
msgstr "将此评论ä¿å¯†"
@@ -23852,7 +24177,7 @@ msgid "Nuget metadatum must have at least license_url, project_url or icon_url s
msgstr "Nuget元数æ®å¿…须至少设置了license_url,project_url或icon_url"
msgid "Number of Elasticsearch shards and replicas per index:"
-msgstr ""
+msgstr "æ¯ä¸ªç´¢å¼•çš„ Elasticsearch 碎片和副本数:"
msgid "Number of Git pushes after which %{code_start}git gc%{code_end} is run."
msgstr "%{code_start}git gc%{code_end} 之åŽçš„ Git 推é€æ¬¡æ•°ã€‚"
@@ -24008,7 +24333,7 @@ msgid "OnCallSchedules|For this rotation, on-call will be:"
msgstr "对于这个循环,待命计划将是:"
msgid "OnCallSchedules|On-call schedule %{obstacle} in project %{project}"
-msgstr ""
+msgstr "项目 %{project} 中的调用计划 %{obstacle}"
msgid "OnCallSchedules|On-call schedules"
msgstr "待命计划"
@@ -24092,11 +24417,17 @@ msgid "OnCallSchedules|Your schedule has been successfully created. To add indiv
msgstr "您的日程已æˆåŠŸåˆ›å»ºã€‚è¦å°†å•ä¸ªç”¨æˆ·æ·»åŠ åˆ°æ­¤è®¡åˆ’,请使用添加轮æ¢æŒ‰é’®ã€‚è¦ä¸ºæ­¤è®¡åˆ’å¯ç”¨é€šçŸ¥ï¼Œæ‚¨è¿˜å¿…须创建 %{linkStart}å‡çº§ç­–ç•¥%{linkEnd}。"
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
+msgstr "%{learnMoreLinkStart}了解有关按需扫æ的更多信æ¯%{learnMoreLinkEnd}。"
+
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
msgstr ""
-msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
msgstr ""
+msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
+msgstr "无法获å–按需扫æ。请刷新页é¢ï¼Œæˆ–ç¨åŽé‡è¯•ã€‚"
+
msgid "OnDemandScans|Could not fetch scanner profiles. Please refresh the page, or try again later."
msgstr "无法获å–扫æ工具é…置文件。请刷新页é¢æˆ–ç¨åŽå†è¯•ã€‚"
@@ -24112,12 +24443,18 @@ msgstr "创建新的扫æ工具é…置文件"
msgid "OnDemandScans|Create new site profile"
msgstr "创建新的站点é…置文件"
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr "æè¿° (å¯é€‰)"
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr "编辑按需扫æDAST"
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr "例如:测试SQL注入的登录页é¢"
@@ -24157,12 +24494,21 @@ msgstr "按需扫æ在DevOps周期之外è¿è¡Œï¼Œå¹¶åœ¨æ‚¨çš„项目中å‘现æ¼
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr "按需扫æ在DevOps周期之外è¿è¡Œï¼Œå¹¶åœ¨æ‚¨çš„项目中å‘现æ¼æ´žã€‚%{learnMoreLinkStart}了解更多%{learnMoreLinkEnd}"
+msgid "OnDemandScans|Repeats"
+msgstr "é‡å¤"
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr "ä¿å­˜å¹¶è¿è¡Œæ‰«æ"
msgid "OnDemandScans|Save scan"
msgstr "ä¿å­˜æ‰«æ"
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr "扫æå称"
@@ -24187,18 +24533,33 @@ msgstr "开始时间"
msgid "OnDemandScans|Target"
msgstr "目标"
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr "无法å–消扫æ。"
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr "无法é‡è¯•æ‰«æ。"
+
msgid "OnDemandScans|There are no finished scans."
-msgstr ""
+msgstr "没有完æˆçš„扫æ。"
msgid "OnDemandScans|There are no running scans."
+msgstr "没有è¿è¡Œä¸­çš„扫æ。"
+
+msgid "OnDemandScans|There are no saved scans."
msgstr ""
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr "没有计划中的扫æ。"
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr "使用现有的站点é…ç½®"
msgid "OnDemandScans|Use existing site profile"
msgstr "使用现有的站点é…置文件"
+msgid "OnDemandScans|View results"
+msgstr "查看结果"
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr "您必须在项目中创建仓库æ‰èƒ½è¿è¡ŒæŒ‰éœ€æ‰«æ。"
@@ -24208,9 +24569,6 @@ msgstr "仓库导入åŽï¼Œå¯ä»¥é€šè¿‡SSH进行镜åƒã€‚点击%{link_start}æ­¤å¤
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr "删除åŽå°†æ— æ³•æ¢å¤æ´¾ç”Ÿå…³ç³»ã€‚此项目将无法å†å‘æºé¡¹ç›®æˆ–其他派生å‘é€æˆ–接收åˆå¹¶è¯·æ±‚。"
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr "导出的文件准备就绪åŽï¼Œæ‚¨å°†æ”¶åˆ°å¸¦æœ‰ä¸‹è½½é“¾æŽ¥çš„通知电å­é‚®ä»¶ï¼Œæˆ–者您å¯ä»¥ä»Žæ­¤é¡µé¢ä¸‹è½½ã€‚"
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr "一旦您确认并点击\"é™ä½Žé¡¹ç›®å¯è§æ€§\":"
@@ -24219,10 +24577,10 @@ msgid_plural "%d more items"
msgstr[0] "其余%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 "您无æƒè®¿é—®çš„一个或多个群组。"
@@ -24264,7 +24622,7 @@ msgid "Only effective when remote storage is enabled. Set to 0 for no size limit
msgstr "仅在å¯ç”¨è¿œç¨‹å­˜å‚¨æ—¶æœ‰æ•ˆã€‚设置为 0 表示没有大å°é™åˆ¶ã€‚"
msgid "Only enable search after installing the plugin, enabling indexing, and recreating the index."
-msgstr ""
+msgstr "åªæœ‰åœ¨å®‰è£…æ’件ã€å¯ç”¨ç´¢å¼•å’Œé‡æ–°åˆ›å»ºç´¢å¼•åŽæ‰å¯ç”¨æœç´¢ã€‚"
msgid "Only include features new to your current subscription tier."
msgstr "仅包括您当å‰è®¢é˜…级别的新功能。"
@@ -24288,7 +24646,7 @@ msgid "Only reCAPTCHA v2 is supported:"
msgstr "仅支æŒreCAPTCHA v2:"
msgid "Only use lowercase letters, numbers, and underscores."
-msgstr ""
+msgstr "仅使用å°å†™å­—æ¯ã€æ•°å­—和下划线。"
msgid "Only users from the specified IP address ranges are able to reach this group, including all subgroups, projects, and Git repositories."
msgstr "åªæœ‰æ¥è‡ªæŒ‡å®š IP 地å€èŒƒå›´çš„用户æ‰èƒ½è®¿é—®æ­¤ç¾¤ç»„,包括所有å­ç»„ã€é¡¹ç›®å’Œ Git 仓库。"
@@ -24309,7 +24667,7 @@ msgid "Open Selection"
msgstr "打开所选项"
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
-msgstr ""
+msgstr "打开 CLI 并连接到您想è¦å®‰è£…代ç†çš„集群。 使用此安装方法æ¥æœ€å°åŒ–任何手动步骤。令牌已ç»åŒ…å«åœ¨å‘½ä»¤ä¸­ã€‚"
msgid "Open epics"
msgstr "打开å²è¯—"
@@ -24368,6 +24726,9 @@ msgstr "ä¸å…许此æ“作"
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr "æ“作超时。请检查 Pod 日志 %{pod_name} 了解更多信æ¯ã€‚"
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr "è¿ç»´ä»ªè¡¨æ¿"
@@ -24480,7 +24841,7 @@ msgid "Owner"
msgstr "所有者"
msgid "PQL|An error occurred while sending hand raise lead."
-msgstr ""
+msgstr "å‘é€é‚®ä»¶æ—¶å‘生错误。"
msgid "PQL|By providing my contact information, I agree GitLab may contact me via email about its product, services and events. You may opt-out at any time by unsubscribing in emails or visiting our communication preference center."
msgstr "通过æ供我的è”系信æ¯ï¼Œæˆ‘åŒæ„ GitLab å¯ä»¥é€šè¿‡ç”µå­é‚®ä»¶è”系我有关它的产å“ã€æœåŠ¡å’Œäº‹ä»¶ã€‚ 您å¯ä»¥é€šè¿‡ç”µå­é‚®ä»¶æˆ–访问我们的通讯首选项中心éšæ—¶å–消订阅。"
@@ -24510,7 +24871,7 @@ msgid "PQL|Thank you for reaching out! Our sales team will get back to you soon.
msgstr "感谢您的è”ç³»ï¼æˆ‘们的销售团队将很快与您è”系。"
msgid "Package Registry"
-msgstr "软件包注册表"
+msgstr "软件包库"
msgid "Package Registry: authenticated API requests"
msgstr "软件包库:ç»è¿‡èº«ä»½éªŒè¯çš„ API 请求"
@@ -24549,7 +24910,7 @@ msgid "Package type must be Maven"
msgstr "包类型必须是Maven"
msgid "Package type must be NPM"
-msgstr ""
+msgstr "包类型必须是 NPM"
msgid "Package type must be NuGet"
msgstr "包类型必须是Nuget"
@@ -24906,9 +25267,6 @@ msgstr "找ä¸åˆ°é¡µé¢"
msgid "Page settings"
msgstr "页é¢è®¾ç½®"
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr "å¯ç”¨"
@@ -25098,9 +25456,15 @@ msgstr "åŒè¡Œè¯„审"
msgid "Pending"
msgstr "等待中"
+msgid "Pending Deletion"
+msgstr "等待删除"
+
msgid "Pending comments"
msgstr "待处ç†çš„评论"
+msgid "Pending deletion"
+msgstr "等待删除"
+
msgid "Pending owner approval"
msgstr "等待所有者批准"
@@ -25200,6 +25564,9 @@ msgstr "墙"
msgid "Period in seconds"
msgstr "周期(秒)"
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr "永久删除项目"
@@ -25258,10 +25625,10 @@ msgid "Pipeline %{label} for \"%{dataTitle}\""
msgstr "“%{dataTitle}â€çš„æµæ°´çº¿%{label}"
msgid "Pipeline Editor"
-msgstr ""
+msgstr "æµæ°´çº¿ç¼–辑器"
msgid "Pipeline Editor|Are you sure you want to reset the file to its last committed version?"
-msgstr ""
+msgstr "您确定è¦å°†æ–‡ä»¶é‡ç½®ä¸ºä¸Šæ¬¡æ交的版本å—?"
msgid "Pipeline ID"
msgstr "æµæ°´çº¿ID"
@@ -25281,12 +25648,6 @@ msgstr "æµæ°´çº¿ URL"
msgid "Pipeline durations for the last 30 commits"
msgstr "最近 30 次æ交的æµæ°´çº¿æŒç»­æ—¶é—´"
-msgid "Pipeline minutes quota"
-msgstr "æµæ°´çº¿åˆ†é’Ÿæ•°é…é¢"
-
-msgid "Pipeline minutes quota:"
-msgstr "æµæ°´çº¿åˆ†é’Ÿæ•°é…é¢ï¼š"
-
msgid "Pipeline ran in fork of project"
msgstr "æµæ°´çº¿è¿è¡Œåœ¨é¡¹ç›®æ´¾ç”Ÿä¸­"
@@ -25518,6 +25879,9 @@ msgstr "å­æµæ°´çº¿"
msgid "Pipelines|Clear runner caches"
msgstr "清除Runner缓存"
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr "å¤åˆ¶è§¦å‘令牌"
@@ -25708,7 +26072,7 @@ msgid "Pipeline|Created"
msgstr "已创建"
msgid "Pipeline|Creating pipeline."
-msgstr ""
+msgstr "正在创建æµæ°´çº¿ã€‚"
msgid "Pipeline|Date"
msgstr "日期"
@@ -25737,9 +26101,6 @@ msgstr "åˆå¹¶é˜Ÿåˆ—æµæ°´çº¿ä½œä¸šæ— æ³•é‡è¯•"
msgid "Pipeline|Merged result pipeline"
msgstr "åˆå¹¶ç»“æžœæµæ°´çº¿"
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr "由于当å‰çš„ CI/CD é…置,没有触å‘任何æµæ°´çº¿å¯¼è‡´æœ€è¿‘çš„å˜åŒ–。"
-
msgid "Pipeline|Passed"
msgstr "已通过"
@@ -25819,7 +26180,7 @@ msgid "Pipeline|Variables"
msgstr "å˜é‡"
msgid "Pipeline|View commit"
-msgstr ""
+msgstr "查看æ交"
msgid "Pipeline|View pipeline"
msgstr "查看æµæ°´çº¿"
@@ -25960,7 +26321,7 @@ msgid "Please enter a valid number"
msgstr "请输入有效的数字"
msgid "Please enter a valid time interval"
-msgstr ""
+msgstr "请输入有效的时间间隔"
msgid "Please enter or upload a valid license."
msgstr "请输入或上传有效的许å¯è¯ã€‚"
@@ -26016,6 +26377,12 @@ msgstr "如果您有任何疑问,请è”系我们,我们将竭诚为您æœåŠ¡
msgid "Please refer to %{docs_url}"
msgstr "请å‚考%{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 "请审核 %{project_link} çš„æ›´æ–°å‡çº§ç­–略。建议您è”系当å‰çš„ on-call å“åº”è€…ï¼Œä»¥ç¡®ä¿ on-call 覆盖的连续性。"
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr "请审核 %{project} çš„æ›´æ–°å‡çº§ç­–略。建议您è”系当å‰çš„ on-call å“åº”è€…ï¼Œä»¥ç¡®ä¿ on-call 覆盖的连续性。"
+
msgid "Please select"
msgstr "请选择"
@@ -26028,6 +26395,9 @@ msgstr "请选择国家/地区"
msgid "Please select a file"
msgstr "请选择一个文件"
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr "请选择一个群组。"
@@ -26223,14 +26593,11 @@ msgstr "时间å好"
msgid "Preferences|Use relative times"
msgstr "使用相对时间"
-msgid "Press %{key}-C to copy"
-msgstr "按 %{key}-C å¤åˆ¶"
-
msgid "Prev"
msgstr "上一页"
msgid "Prevent adding new members to projects within this group"
-msgstr ""
+msgstr "ç¦æ­¢å‘该群组内的项目添加新æˆå‘˜"
msgid "Prevent auto-stopping"
msgstr "防止自动åœæ­¢"
@@ -26512,7 +26879,7 @@ msgid "Profiles|Do not show on profile"
msgstr "ä¸åœ¨ä¸ªäººèµ„料中显示"
msgid "Profiles|Don't display activity-related personal information on your profile"
-msgstr ""
+msgstr "ä¸è¦åœ¨æ‚¨çš„个人资料中显示与活动相关的个人信æ¯"
msgid "Profiles|Edit Profile"
msgstr "编辑个人资料"
@@ -26533,7 +26900,7 @@ msgid "Profiles|Enter your pronouns to let people know how to refer to you"
msgstr "输入您的代è¯ï¼Œè®©äººä»¬çŸ¥é“如何称呼您"
msgid "Profiles|Expiration date"
-msgstr ""
+msgstr "到期日期"
msgid "Profiles|Expired key is not valid."
msgstr "过期的密钥无效。"
@@ -26577,14 +26944,17 @@ msgstr "密ç æ— æ•ˆ"
msgid "Profiles|Invalid username"
msgstr "用户å无效"
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr "密钥"
msgid "Profiles|Key becomes invalid on this date."
-msgstr ""
+msgstr "密钥在此日期无效。"
msgid "Profiles|Key becomes invalid on this date. Maximum lifetime for SSH keys is %{max_ssh_key_lifetime} days"
-msgstr ""
+msgstr "密钥在此日期无效,SSH 密钥的最大有效期为 %{max_ssh_key_lifetime} 天"
msgid "Profiles|Key can still be used after expiration."
msgstr "密钥到期åŽä»å¯ä½¿ç”¨ã€‚"
@@ -26634,6 +27004,12 @@ msgstr "éžå…¬å¼€è´¡çŒ®"
msgid "Profiles|Profile was successfully updated"
msgstr "个人资料已æˆåŠŸæ›´æ–°"
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr "公开头åƒ"
@@ -26718,6 +27094,9 @@ msgstr "用户å更改æˆåŠŸ"
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr "姓å中使用表情符å·è™½ç„¶æœ‰è¶£ï¼Œä½†è¯·è½¬åˆ°çŠ¶æ€ä¿¡æ¯é‡Œä½¿ç”¨å®ƒ"
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr "您当å‰çš„状æ€ï¼Ÿ"
@@ -26998,7 +27377,7 @@ msgid "ProjectOverview|Unstar"
msgstr "å–消星标"
msgid "ProjectOverview|You don't have permission to fork this project"
-msgstr ""
+msgstr "您没有æƒé™æ´¾ç”Ÿæ­¤é¡¹ç›®"
msgid "ProjectOverview|You have reached your project limit"
msgstr "您已达到项目数é‡é™åˆ¶"
@@ -27012,6 +27391,48 @@ msgstr "å¤åˆ¶é¡¹ç›®ID"
msgid "ProjectPage|Project ID: %{project_id}"
msgstr "项目ID: %{project_id}"
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr "å°è¯•èŽ·å–项目质é‡ç»Ÿè®¡ä¿¡æ¯æ—¶å‡ºé”™"
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr "覆盖率"
+
+msgid "ProjectQualitySummary|Failure"
+msgstr "失败"
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr "最新æµæ°´çº¿ç»“æžœ"
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr "了解有关测试覆盖率的更多信æ¯"
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr "了解有关测试报告的更多信æ¯"
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr "测é‡æ‚¨çš„代ç æœ‰å¤šå°‘被测试覆盖。"
+
+msgid "ProjectQualitySummary|See full report"
+msgstr "查看完整报告"
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr "查看项目代ç è¦†ç›–率统计"
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr "跳过"
+
+msgid "ProjectQualitySummary|Success"
+msgstr "æˆåŠŸ"
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr "测试覆盖率"
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr "测试è¿è¡Œ"
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr "测试æˆåŠŸã€å¤±è´¥æˆ–被跳过的百分比。"
+
msgid "ProjectSelect| or group"
msgstr "或群组"
@@ -27138,6 +27559,9 @@ msgstr "在创建ã€æ›´æ–°æˆ–关闭议题时触å‘事件。"
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr "%{link_start}什么是æ述模æ¿ï¼Ÿ%{link_end}"
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr "å½±å“åˆå¹¶å®Œæˆçš„æ–¹å¼å’Œæ—¶é—´çš„其他设置。"
@@ -27253,7 +27677,7 @@ msgid "ProjectSettings|Internal"
msgstr "内部"
msgid "ProjectSettings|Introduces the risk of merging changes that do not pass the pipeline."
-msgstr "介ç»åˆå¹¶æœªé€šè¿‡æµæ°´çº¿çš„更改的风险。"
+msgstr "åˆå¹¶æµæ°´çº¿æœªé€šè¿‡çš„更改å¯èƒ½ä¼šå¼•å…¥é£Žé™©ã€‚"
msgid "ProjectSettings|Issues"
msgstr "议题"
@@ -27268,7 +27692,7 @@ msgid "ProjectSettings|Manages large files such as audio, video, and graphics fi
msgstr "管ç†å¤§åž‹æ–‡ä»¶ï¼Œä¾‹å¦‚音频ã€è§†é¢‘和图形文件。"
msgid "ProjectSettings|Maximum 500 characters."
-msgstr ""
+msgstr "最多500个字符。"
msgid "ProjectSettings|Merge checks"
msgstr "åˆå¹¶æ£€æŸ¥"
@@ -27277,7 +27701,7 @@ msgid "ProjectSettings|Merge commit"
msgstr "åˆå¹¶æ交"
msgid "ProjectSettings|Merge commit message template"
-msgstr ""
+msgstr "åˆå¹¶æ交消æ¯æ¨¡æ¿"
msgid "ProjectSettings|Merge commit with semi-linear history"
msgstr "åˆå¹¶æ交与åŠçº¿æ€§åŽ†å²è®°å½•"
@@ -27349,7 +27773,7 @@ msgid "ProjectSettings|Requirements management system."
msgstr "需求管ç†ç³»ç»Ÿã€‚"
msgid "ProjectSettings|Search for topic"
-msgstr ""
+msgstr "æœç´¢ä¸»é¢˜"
msgid "ProjectSettings|Security & Compliance"
msgstr "安全与åˆè§„"
@@ -27376,7 +27800,7 @@ msgid "ProjectSettings|Snippets"
msgstr "代ç ç‰‡æ®µ"
msgid "ProjectSettings|Squash commit message template"
-msgstr ""
+msgstr "压缩æ交消æ¯æ¨¡æ¿"
msgid "ProjectSettings|Squash commits when merging"
msgstr "åˆå¹¶æ—¶åŽ‹ç¼©æ交"
@@ -27390,19 +27814,16 @@ msgstr "永远ä¸ä¼šæ‰§è¡ŒåŽ‹ç¼©ï¼Œå¹¶ä¸”该å¤é€‰æ¡†æ˜¯éšè—的。"
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr "æ交è¦åˆå¹¶åˆ°ä¸Šæ¸¸çš„更改。"
-msgid "ProjectSettings|Supported variables:"
-msgstr "支æŒçš„å˜é‡ï¼š"
-
msgid "ProjectSettings|Target project"
msgstr "目标项目"
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
-msgstr "应用åˆå¹¶è¯·æ±‚建议时使用的æ交消æ¯ã€‚ %{link_start}了解有关建议的更多信æ¯ã€‚%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
+msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27558,6 +27979,15 @@ msgstr "Tencent Serverless 框架/NextjsSSR"
msgid "ProjectTemplates|iOS (Swift)"
msgstr "iOS (Swift)"
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr "项目"
@@ -27610,7 +28040,7 @@ msgid "Projects with no vulnerabilities and security scanning enabled"
msgstr "未å¯ç”¨æ¼æ´žå’Œå®‰å…¨æ‰«æ的项目"
msgid "Projects with this topic"
-msgstr ""
+msgstr "与此主题相关的项目"
msgid "Projects with write access"
msgstr "具有写入æƒé™çš„项目"
@@ -27820,7 +28250,7 @@ msgid "Promote issue to an epic"
msgstr "将议题å‡çº§ä¸ºå²è¯—"
msgid "Promote issue to incident"
-msgstr ""
+msgstr "将议题æå‡ä¸ºäº‹ä»¶"
msgid "Promote to epic"
msgstr "æå‡åˆ°å²è¯—"
@@ -27841,13 +28271,13 @@ msgid "Promoted issue to an epic."
msgstr "将议题å‡çº§ä¸ºå²è¯—."
msgid "Promotes issue to incident"
-msgstr ""
+msgstr "将议题æå‡ä¸ºäº‹ä»¶"
msgid "Promotion is not supported."
msgstr "ä¸æ”¯æŒå‡çº§ã€‚"
msgid "Promotions|Add %{link_start} description templates %{link_end} to help your contributors to communicate effectively!"
-msgstr ""
+msgstr "添加 %{link_start} æè¿°æ¨¡æ¿ %{link_end} 以帮助您的贡献者有效地交æµï¼"
msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition."
msgstr "添加群组 Webhooks å’Œ GitLab ä¼ä¸šç‰ˆã€‚"
@@ -27942,9 +28372,6 @@ msgstr "高级æœç´¢æ˜¯ä¸€é¡¹åŠŸèƒ½å¼ºå¤§çš„æœç´¢æœåŠ¡ï¼Œå¯ä»¥èŠ‚çœæ‚¨çš„æ—¶
msgid "Promotions|This feature is locked."
msgstr "此功能已é”定"
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr "使用贡献分æžè·Ÿè¸ªæ´»åŠ¨ã€‚"
-
msgid "Promotions|Try it for free"
msgstr "å…费试用"
@@ -27957,9 +28384,6 @@ msgstr "å‡çº§æ‚¨çš„方案以激活高级æœç´¢ã€‚"
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr "å‡çº§æ‚¨çš„方案以激活审计事件。"
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr "å‡çº§æ‚¨çš„订阅计划以å¯ç”¨è´¡çŒ®åº¦åˆ†æžã€‚"
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr "å‡çº§æ‚¨çš„方案以激活群组Webhooks。"
@@ -27984,9 +28408,6 @@ msgstr "使您的议题分出轻é‡"
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr "当议题数目很多时,很难得到一个整体情况。 通过给议题添加æƒé‡ï¼Œå¯ä»¥æ›´å¥½åœ°äº†è§£å·¥ä½œé‡ã€ æˆæœ¬ã€æ‰€éœ€æ—¶é—´æˆ–æ¯ä¸ªè®®é¢˜çš„价值,从而更好地进行管ç†ã€‚"
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr "通过贡献度分æžï¼Œæ‚¨å¯ä»¥ä»Žæ€»ä½“上了解您的组织åŠå…¶æˆå‘˜çš„议题〠åˆå¹¶è¯·æ±‚和推é€æ´»åŠ¨çš„情况。"
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr "您å¯ä»¥é€šè¿‡é€‰æ‹©è§’色(维护者ã€å¼€å‘者)以åŠæŸäº›ç”¨æˆ·æ¥é™åˆ¶å¯¹å—ä¿æŠ¤åˆ†æ”¯çš„访问。"
@@ -28068,6 +28489,9 @@ msgstr "å…许推é€ï¼š"
msgid "ProtectedBranch|Branch"
msgstr "分支"
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr "分支:"
@@ -28113,9 +28537,15 @@ msgstr "切æ¢å…许强制推é€"
msgid "ProtectedBranch|Toggle code owner approval"
msgstr "切æ¢ä»£ç æ‰€æœ‰è€…的批准"
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr "什么是å—ä¿æŠ¤çš„分支?"
+msgid "ProtectedBranch|default"
+msgstr "默认"
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr "%{environment_name} 将对开å‘人员å¯å†™ã€‚确定继续å—?"
@@ -28158,6 +28588,9 @@ msgstr "您的环境已å—到ä¿æŠ¤ã€‚"
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "环境已ç»ä¸è¢«ä¿æŠ¤"
+msgid "ProtectedTags|default"
+msgstr "默认"
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr "默认情况下,å—ä¿æŠ¤çš„分支会é™åˆ¶è°å¯ä»¥ä¿®æ”¹æ ‡ç­¾ã€‚"
@@ -28173,6 +28606,9 @@ msgstr "å—ä¿æŠ¤çš„标签"
msgid "ProtectedTag|What are protected tags?"
msgstr "什么是å—ä¿æŠ¤çš„标签?"
+msgid "ProtectedTag|default"
+msgstr "默认"
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr "æ示:%{linkStart}Auto DevOps%{linkEnd} 使用 Kubernetes 集群æ¥éƒ¨ç½²æ‚¨çš„代ç ï¼"
@@ -28210,7 +28646,7 @@ msgid "Public Access Help"
msgstr "公开访问帮助"
msgid "Public deploy keys"
-msgstr ""
+msgstr "公共部署密钥"
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr "公共部署密钥(%{deploy_keys_count})"
@@ -28375,7 +28811,7 @@ msgid "PushoverService|Total commits count: %{total_commits_count}"
msgstr "总æ交次数:%{total_commits_count}"
msgid "QualitySummary|Project quality"
-msgstr ""
+msgstr "项目质é‡"
msgid "Quarters"
msgstr "季度"
@@ -28401,6 +28837,12 @@ msgstr "å¿«æ·èŒƒå›´"
msgid "Quickly and easily edit multiple files in your project."
msgstr "快速轻æ¾åœ°ç¼–辑您项目中的多个文件。"
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr "自述文件"
@@ -28492,10 +28934,10 @@ msgid "Recaptcha verified?"
msgstr "é‡æ–°éªŒè¯ï¼Ÿ"
msgid "Receive a $50 gift card as a thank you for your time."
-msgstr ""
+msgstr "收到一张 50 美元的礼å“å¡ä½œä¸ºå¯¹æ‚¨æ—¶é—´çš„感谢。"
msgid "Receive a %{strongOpen}$50 gift card%{strongClose} as a thank you for your time."
-msgstr ""
+msgstr "收到一张 %{strongOpen}美元 50 美元的礼å“å¡%{strongClose} 作为对您时间的感谢。"
msgid "Receive alerts from manually configured Prometheus servers."
msgstr "从手动é…置的 Prometheus æœåŠ¡å™¨æŽ¥æ”¶è­¦æŠ¥ã€‚"
@@ -28585,9 +29027,6 @@ msgstr "é‡æ–°ç”Ÿæˆå¯¼å‡º"
msgid "Regenerate instance ID"
msgstr "é‡æ–°ç”Ÿæˆå®žä¾‹ID"
-msgid "Regenerate key"
-msgstr "é‡æ–°ç”Ÿæˆå¯†é’¥"
-
msgid "Regenerate recovery codes"
msgstr "é‡æ–°ç”Ÿæˆæ¢å¤ç "
@@ -28630,6 +29069,54 @@ msgstr "使用åŒé‡è®¤è¯åº”用注册"
msgid "Registration Features include:"
msgstr "注册功能包括:"
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr "å¯ç”¨æœåŠ¡ Ping 并注册此功能。"
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr "您确定è¦è·³è¿‡è¿™ä¸€æ­¥å—?"
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr "å¯ç”¨å…è´¹ CI/CD 分钟"
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr "GitLab ä¸ä¼šä»Žæ‚¨çš„å¡ä¸­æ‰£æ¬¾ï¼Œå®ƒåªä¼šç”¨äºŽéªŒè¯ã€‚"
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr "使用 GitLab 共享 runner çš„æµæ°´çº¿å°†å¤±è´¥ï¼Œç›´åˆ°æ‚¨éªŒè¯æ‚¨çš„å¸æˆ·ã€‚"
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr "暂时跳过"
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr "为了防止 GitLab 垃圾邮件和滥用,我们è¦æ±‚您使用有效的付款方å¼ï¼ˆä¾‹å¦‚借记å¡æˆ–信用å¡ï¼‰éªŒè¯æ‚¨çš„身份。在此之å‰ï¼Œæ‚¨æ— æ³•ä½¿ç”¨å…费的 CI/CD 分钟æ¥æž„建您的应用程åºã€‚"
+
+msgid "RegistrationVerification|Validate account"
+msgstr "验è¯å¸æˆ·"
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr "验è¯æ‚¨çš„身份"
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr "是的,我想跳过"
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr "您å¯ä»¥ç¨åŽéªŒè¯æ‚¨çš„å¸æˆ·ã€‚"
+
msgid "Registration|Checkout"
msgstr "支付"
@@ -28764,7 +29251,7 @@ msgid "Remove Zoom meeting"
msgstr "删除Zoom会议"
msgid "Remove Zoom meeting."
-msgstr ""
+msgstr "删除 Zoom 会议。"
msgid "Remove access"
msgstr "移除访问æƒé™"
@@ -28794,7 +29281,7 @@ msgid "Remove assignee"
msgstr "删除指派人"
msgid "Remove attention request"
-msgstr ""
+msgstr "删除关注请求"
msgid "Remove avatar"
msgstr "删除头åƒ"
@@ -28806,10 +29293,10 @@ msgid "Remove child epic from an epic"
msgstr "从å²è¯—中删除å­å²è¯—"
msgid "Remove customer relation contact(s)."
-msgstr ""
+msgstr "删除客户关系è”系人。"
msgid "Remove customer relation contacts"
-msgstr ""
+msgstr "删除客户关系è”系人"
msgid "Remove deploy key"
msgstr "删除部署密钥"
@@ -28935,7 +29422,7 @@ msgid "Removed an issue from an epic."
msgstr "从å²è¯—中移除了一个议题。"
msgid "Removed attention request from @%{username}"
-msgstr ""
+msgstr "已从 @%{username} 移除关注请求"
msgid "Removed group can not be restored!"
msgstr "已删除的群组无法æ¢å¤ï¼"
@@ -28953,13 +29440,13 @@ msgid "Removed time estimate."
msgstr "已删除时间估计。"
msgid "Removed upload with id %{id}"
-msgstr ""
+msgstr "已删除id为 %{id} 的上传"
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
-msgstr "已删除但尚未永久删除的项目在此处å¯è§ã€‚"
+msgid "RemovedProjects|No projects pending deletion found"
+msgstr "找ä¸åˆ°ç­‰å¾…删除的项目"
-msgid "RemovedProjects|You haven’t removed any projects."
-msgstr "您还没有删除任何项目。"
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
+msgstr "此处列出了您有æƒè®¿é—®çš„待删除项目。"
msgid "Removes %{assignee_text} %{assignee_references}."
msgstr "移除%{assignee_text} %{assignee_references}。"
@@ -29025,7 +29512,7 @@ msgid "Reopen %{issueType}"
msgstr "é‡æ–°å¼€å¯%{issueType}"
msgid "Reopen %{noteable}"
-msgstr ""
+msgstr "é‡æ–°æ‰“å¼€ %{noteable}"
msgid "Reopen epic"
msgstr "é‡æ–°å¼€å¯å²è¯—"
@@ -29052,7 +29539,7 @@ msgid "Replace"
msgstr "替æ¢"
msgid "Replace %{blob_name}"
-msgstr ""
+msgstr "æ›¿æ¢ %{blob_name}"
msgid "Replace %{name}"
msgstr "æ›¿æ¢ %{name}"
@@ -29230,7 +29717,7 @@ msgid "RepositoriesAnalytics|Average test coverage last 30 days"
msgstr "过去 30 天的平å‡æµ‹è¯•è¦†ç›–率"
msgid "RepositoriesAnalytics|Code Coverage: %{averageCoverage}"
-msgstr ""
+msgstr "代ç è¦†ç›–范围: %{averageCoverage}"
msgid "RepositoriesAnalytics|Coverage"
msgstr "覆盖率"
@@ -29254,7 +29741,7 @@ msgid "RepositoriesAnalytics|Jobs with Coverage"
msgstr "覆盖范围内的作业"
msgid "RepositoriesAnalytics|Jobs with Coverage: %{coverageCount}"
-msgstr ""
+msgstr "覆盖范围的作业: %{coverageCount}"
msgid "RepositoriesAnalytics|Last Update"
msgstr "最新更新"
@@ -29275,7 +29762,7 @@ msgid "RepositoriesAnalytics|Projects with Coverage"
msgstr "覆盖范围内的项目"
msgid "RepositoriesAnalytics|Projects with Coverage: %{projectCount}"
-msgstr ""
+msgstr "覆盖范围的项目: %{projectCount}"
msgid "RepositoriesAnalytics|Test Code Coverage"
msgstr "测试代ç è¦†ç›–率"
@@ -29356,7 +29843,7 @@ msgid "Repository update events"
msgstr "仓库更新事件"
msgid "Repository: %{counter_repositories} / Wikis: %{counter_wikis} / Build Artifacts: %{counter_build_artifacts} / Pipeline Artifacts: %{counter_pipeline_artifacts} / LFS: %{counter_lfs_objects} / Snippets: %{counter_snippets} / Packages: %{counter_packages} / Uploads: %{counter_uploads}"
-msgstr ""
+msgstr "仓库: %{counter_repositories} / Wikis: %{counter_wikis} / 构建产物: %{counter_build_artifacts} / æµæ°´çº¿äº§ç‰©ï¼š%{counter_pipeline_artifacts} / LFS: %{counter_lfs_objects} / 代ç ç‰‡æ®µ: %{counter_snippets} / 软件包: %{counter_packages} / 上传文件: %{counter_uploads}"
msgid "RepositorySettingsAccessLevel|Select"
msgstr "选择"
@@ -29371,10 +29858,10 @@ msgid "Request a new one"
msgstr "请求一个新的"
msgid "Request attention"
-msgstr ""
+msgstr "请求关注"
msgid "Request attention to review"
-msgstr ""
+msgstr "请求关注审核"
msgid "Request details"
msgstr "请求详情"
@@ -29398,7 +29885,7 @@ msgid "Requested %{time_ago}"
msgstr "请求的 %{time_ago}"
msgid "Requested attention from @%{username}"
-msgstr ""
+msgstr "请求æ¥è‡ª @%{username} 的注æ„事项"
msgid "Requested design version does not exist."
msgstr "请求的设计版本ä¸å­˜åœ¨."
@@ -29440,7 +29927,7 @@ msgid "Required in this project."
msgstr "在此项目为必须。"
msgid "Required only if you are not using role instance credentials."
-msgstr ""
+msgstr "仅当您没有使用角色实例凭æ®æ—¶æ‰éœ€è¦ã€‚"
msgid "Requirement %{reference} has been added"
msgstr "需求%{reference}已添加"
@@ -29508,7 +29995,7 @@ msgid "Reset authorization key?"
msgstr "é‡ç½®æŽˆæƒå¯†é’¥ï¼Ÿ"
msgid "Reset file"
-msgstr ""
+msgstr "é‡ç½®æ–‡ä»¶"
msgid "Reset filters"
msgstr "é‡ç½®ç­›é€‰å™¨"
@@ -29636,6 +30123,9 @@ msgstr "æ¢å¤"
msgid "Resync"
msgstr "é‡æ–°åŒæ­¥"
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr "检索åˆè§„性报告失败。请刷新页é¢å¹¶é‡è¯•ã€‚"
+
msgid "Retry"
msgstr "é‡è¯•"
@@ -29645,6 +30135,12 @@ msgstr "é‡è¯•ä½œä¸š"
msgid "Retry migration"
msgstr "é‡è¯•è¿ç§»"
+msgid "Retry the downstream pipeline"
+msgstr "é‡è¯•ä¸‹æ¸¸æµæ°´çº¿"
+
+msgid "Retry the trigger job"
+msgstr "é‡è¯•è§¦å‘器作业"
+
msgid "Retry this job"
msgstr "é‡è¯•å½“å‰ä½œä¸š"
@@ -29705,7 +30201,7 @@ msgstr "å¯ç”¨å®¡é˜…应用"
msgid "Reviewer"
msgid_plural "%d Reviewers"
-msgstr[0] ""
+msgstr[0] "%dä½å®¡æ ¸è€…"
msgid "Reviewer(s)"
msgstr "审核者"
@@ -29825,7 +30321,7 @@ msgid "Runners|Active"
msgstr "å¯ç”¨"
msgid "Runners|All"
-msgstr ""
+msgstr "全部"
msgid "Runners|Amazon Linux 2 Docker HA with manual scaling and optional scheduling. %{percentage} spot."
msgstr "Amazon Linux 2 Docker HA,具有手动扩展和å¯é€‰è°ƒåº¦åŠŸèƒ½ã€‚ %{percentage} 点。"
@@ -29839,9 +30335,6 @@ msgstr "获å–指令时å‘生错误"
msgid "Runners|Architecture"
msgstr "架构"
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr "确定è¦åˆ é™¤æ­¤runnerå—?"
-
msgid "Runners|Associated with one or more projects"
msgstr "与一个或多个项目关è”"
@@ -29863,6 +30356,12 @@ msgstr "å¤åˆ¶è¯´æ˜Ž"
msgid "Runners|Copy registration token"
msgstr "å¤åˆ¶æ³¨å†Œä»¤ç‰Œ"
+msgid "Runners|Delete runner"
+msgstr "删除 runner"
+
+msgid "Runners|Delete runner %{name}?"
+msgstr "删除 runner %{name}?"
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr "在 AWS 中部署 GitLab Runner"
@@ -29882,7 +30381,7 @@ msgid "Runners|For each solution, you will choose a capacity. 1 enables warm HA
msgstr "对于æ¯ä¸ªè§£å†³æ–¹æ¡ˆï¼Œæ‚¨å°†é€‰æ‹©ä¸€ä¸ªå®¹é‡ã€‚ 1 通过自动扩展组é‡æ–°ç”Ÿæˆå¯ç”¨æš– HA。 2 å¯ç”¨çƒ­ HA,因为å³ä½¿èŠ‚点丢失,该æœåŠ¡ä¹Ÿå¯ç”¨ã€‚ 3 个或更多å¯ç”¨çƒ­ HA 和手动扩展runner组。"
msgid "Runners|Group"
-msgstr ""
+msgstr "群组"
msgid "Runners|Group Runners"
msgstr "群组Runner"
@@ -29897,7 +30396,7 @@ msgid "Runners|Install a runner"
msgstr "安装Runner"
msgid "Runners|Instance"
-msgstr ""
+msgstr "实例"
msgid "Runners|Last contact"
msgstr "最åŽè”ç³»"
@@ -29914,21 +30413,24 @@ msgstr "%{type}çš„æˆå‘˜å¯ä»¥æ³¨å†ŒRunner"
msgid "Runners|Name"
msgstr "å称"
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr "已生æˆæ–°çš„注册令牌ï¼"
-msgid "Runners|New runner, has not connected yet"
-msgstr "新的Runner,尚未连接"
+msgid "Runners|New runner, has not contacted yet"
+msgstr ""
+
+msgid "Runners|No contact from this runner in over 3 months"
+msgstr "超过 3 个月没有è”系此 runner"
msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
-msgstr ""
+msgstr "æ­¤ runner 最近没有è”系;最åŽä¸€æ¬¡è”系是 %{timeAgo}"
msgid "Runners|Not available to run jobs"
msgstr "ä¸å¯ç”¨äºŽè¿è¡Œä½œä¸š"
-msgid "Runners|Not connected"
-msgstr "未连接"
-
msgid "Runners|Offline"
msgstr "离线"
@@ -29936,7 +30438,7 @@ msgid "Runners|Online"
msgstr "在线"
msgid "Runners|Online Runners"
-msgstr ""
+msgstr "在线 runner"
msgid "Runners|Paused"
msgstr "已暂åœ"
@@ -29945,7 +30447,7 @@ msgid "Runners|Platform"
msgstr "å¹³å°"
msgid "Runners|Project"
-msgstr ""
+msgstr "项目"
msgid "Runners|Property Name"
msgstr "属性å称"
@@ -29980,8 +30482,11 @@ msgstr "Runner"
msgid "Runners|Runner #%{runner_id}"
msgstr "Runner #%{runner_id}"
+msgid "Runners|Runner %{name} was deleted"
+msgstr "Runner %{name} 已删除"
+
msgid "Runners|Runner ID"
-msgstr ""
+msgstr "Runner ID"
msgid "Runners|Runner assigned to project."
msgstr "分é…给项目的runner"
@@ -29993,7 +30498,7 @@ msgid "Runners|Runner is online, last contact was %{runner_contact} ago"
msgstr "Runner 处于在线状æ€ï¼Œæœ€åŽè¿žæŽ¥æ˜¯åœ¨%{runner_contact}å‰"
msgid "Runners|Runner is online; last contact was %{timeAgo}"
-msgstr ""
+msgstr "Runner 处于在线状æ€ï¼›æœ€åŽè¿žæŽ¥æ˜¯åœ¨%{timeAgo}å‰"
msgid "Runners|Runner is paused, last contact was %{runner_contact} ago"
msgstr "Runner 处于已暂åœçŠ¶æ€ï¼Œæœ€åŽè¿žæŽ¥æ˜¯åœ¨%{runner_contact}å‰"
@@ -30025,8 +30530,11 @@ msgstr "获å–Runneræ•°æ®æ—¶å‡ºé”™ã€‚"
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr "获å–标签建议时出现问题"
+msgid "Runners|Stale"
+msgstr "Stale"
+
msgid "Runners|Status"
-msgstr ""
+msgstr "状æ€"
msgid "Runners|Stop the runner from accepting new jobs."
msgstr "åœæ­¢ Runner 接收新的作业。"
@@ -30034,7 +30542,10 @@ msgstr "åœæ­¢ Runner 接收新的作业。"
msgid "Runners|Tags"
msgstr "标签"
-msgid "Runners|This runner has never connected to this instance"
+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 "Runner 将被永久删除,ä¸å†é€‚用于项目或群组。您确定è¦ç»§ç»­å—?"
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30095,7 +30606,7 @@ msgid "Runners|You have used %{quotaUsed} out of %{quotaLimit} of your shared Ru
msgstr "您已使用了%{quotaUsed},超出了共享æµæ°´çº¿æ—¶é—´é…é¢é™åˆ¶ï¼ˆ%{quotaLimit} )。"
msgid "Runners|active"
-msgstr ""
+msgstr "å¯ç”¨"
msgid "Runners|group"
msgstr "群组"
@@ -30103,14 +30614,14 @@ msgstr "群组"
msgid "Runners|locked"
msgstr "å·²é”定"
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
-msgstr ""
+msgstr "离线"
msgid "Runners|online"
-msgstr ""
+msgstr "在线"
msgid "Runners|paused"
msgstr "已暂åœ"
@@ -30121,6 +30632,9 @@ msgstr "共享"
msgid "Runners|specific"
msgstr "特定"
+msgid "Runners|stale"
+msgstr "stale"
+
msgid "Running"
msgstr "è¿è¡Œä¸­"
@@ -30382,6 +30896,9 @@ msgstr "æœç´¢æ­¤æ–‡æœ¬"
msgid "Search forks"
msgstr "æœç´¢æ´¾ç”Ÿ"
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr "æœç´¢è¿­ä»£"
@@ -30403,9 +30920,6 @@ msgstr "æœç´¢æˆ–筛选结果......"
msgid "Search or filter results…"
msgstr "æœç´¢æˆ–筛选结果…"
-msgid "Search or jump to..."
-msgstr "æœç´¢æˆ–跳转到..."
-
msgid "Search project"
msgstr "æœç´¢é¡¹ç›®"
@@ -30559,7 +31073,7 @@ msgid "Secure token that identifies an external storage request."
msgstr "识别外部存储请求的安全令牌。"
msgid "SecureCodeWarrior"
-msgstr ""
+msgstr "SecureCodeWarrior"
msgid "Security"
msgstr "安全"
@@ -30586,7 +31100,7 @@ msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline
msgstr "安全报告已过时。请在目标分支(%{targetBranchName})上è¿è¡Œ%{newPipelineLinkStart}æ–°çš„æµæ°´çº¿%{newPipelineLinkEnd}"
msgid "Security training with guide and learning pathways."
-msgstr ""
+msgstr "具有指导和学习途径的安全培训。"
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr "当安全报告包å«æ–°æ¼æ´žæ—¶éœ€è¦åˆå¹¶è¯·æ±‚审批。"
@@ -30637,7 +31151,7 @@ msgid "SecurityConfiguration|Available with Ultimate"
msgstr "适用于旗舰版"
msgid "SecurityConfiguration|By default, all analyzers are applied in order to cover all languages across your project, and only run if the language is detected in the merge request."
-msgstr ""
+msgstr "默认情况下,所有分æžå™¨éƒ½è¢«åº”用æ¥è¦†ç›–您项目的所有语言,并且åªåœ¨åˆå¹¶è¯·æ±‚中检测到该语言时æ‰è¿è¡Œã€‚"
msgid "SecurityConfiguration|Compliance"
msgstr "åˆè§„性"
@@ -30652,7 +31166,7 @@ msgid "SecurityConfiguration|Configure %{feature}"
msgstr "é…ç½® %{feature}"
msgid "SecurityConfiguration|Configure with a merge request"
-msgstr ""
+msgstr "使用åˆå¹¶è¯·æ±‚é…ç½®"
msgid "SecurityConfiguration|Copy code and open .gitlab-ci.yml file"
msgstr "å¤åˆ¶ä»£ç å¹¶æ‰“å¼€ .gitlab-ci.yml 文件"
@@ -30664,7 +31178,7 @@ msgid "SecurityConfiguration|Could not retrieve configuration data. Please refre
msgstr "无法获å–é…置数æ®ã€‚请刷新页é¢æˆ–ç¨åŽå†è¯•ã€‚"
msgid "SecurityConfiguration|Create merge request"
-msgstr ""
+msgstr "创建åˆå¹¶è¯·æ±‚"
msgid "SecurityConfiguration|Customize common SAST settings to suit your requirements. Configuration changes made here override those provided by GitLab and are excluded from updates. For details of more advanced configuration options, see the %{linkStart}GitLab SAST documentation%{linkEnd}."
msgstr "自定义常è§çš„SAST设置以满足您的需求。此处所åšçš„é…置更改会覆盖GitLabæ供的é…置,并且ä¸ä¼šåŒ…å«åœ¨æ›´æ–°ä¸­ã€‚有关更多高级é…置选项的详细信æ¯ï¼Œè¯·å‚è§%{linkStart}GitLab SAST文档%{linkEnd}。"
@@ -30675,6 +31189,9 @@ msgstr "å¯ç”¨ %{feature}"
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr "å¯ç”¨Auto DevOps"
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr "å¯ç”¨"
@@ -30724,7 +31241,7 @@ msgid "SecurityConfiguration|Security testing"
msgstr "安全测试"
msgid "SecurityConfiguration|Security training"
-msgstr ""
+msgstr "安全培训"
msgid "SecurityConfiguration|The status of the tools only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}."
msgstr "工具的状æ€ä»…适用于默认分支,并基于 %{linkStart}最新æµæ°´çº¿%{linkEnd}。"
@@ -30736,7 +31253,7 @@ msgid "SecurityConfiguration|Using custom settings. You won't receive automatic
msgstr "使用自定义设置。您ä¸ä¼šæ”¶åˆ°æ­¤å˜é‡çš„自动更新。 %{anchorStart}还原到默认%{anchorEnd}"
msgid "SecurityConfiguration|Vulnerability Management"
-msgstr ""
+msgstr "æ¼æ´žç®¡ç†"
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr "åˆå¹¶è¯·æ±‚中的æ¼æ´žè¯¦ç»†ä¿¡æ¯å’Œç»Ÿè®¡"
@@ -30747,6 +31264,9 @@ msgstr "%{branches} %{plural}"
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr "%{branches} 和 %{lastBranch} %{plural}"
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ".yaml 预览"
+
msgid "SecurityOrchestration|Action"
msgstr "行动"
@@ -30763,10 +31283,10 @@ msgid "SecurityOrchestration|An error occurred assigning your security policy pr
msgstr "分é…您的安全策略项目时出错"
msgid "SecurityOrchestration|An error occurred unassigning your security policy project"
-msgstr ""
+msgstr "å–消分é…您的安全策略项目时出错"
msgid "SecurityOrchestration|Choose a project"
-msgstr ""
+msgstr "选择项目"
msgid "SecurityOrchestration|Description"
msgstr "æè¿°"
@@ -30801,6 +31321,9 @@ msgstr "网络"
msgid "SecurityOrchestration|New policy"
msgstr "æ–°ç­–ç•¥"
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr "未定义规则 - 策略无法è¿è¡Œã€‚"
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr "åªæœ‰æ‰€æœ‰è€…å¯ä»¥æ›´æ–°å®‰å…¨ç­–略项目"
@@ -30838,10 +31361,10 @@ msgid "SecurityOrchestration|Scan execution policies can only be created by proj
msgstr "扫æ执行策略åªèƒ½ç”±é¡¹ç›®æ‰€æœ‰è€…创建。"
msgid "SecurityOrchestration|Scan to be performed %{cadence}"
-msgstr ""
+msgstr "è¦æ‰§è¡Œçš„扫æ %{cadence}"
msgid "SecurityOrchestration|Scan to be performed %{cadence} on the %{branches}"
-msgstr ""
+msgstr "扫æ %{cadence} 在 %{branches} 上执行"
msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
msgstr "在%{branches}上扫ææ¯ä¸ªæµæ°´çº¿"
@@ -30850,7 +31373,7 @@ msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr "安全策略项目已æˆåŠŸè¿žæŽ¥"
msgid "SecurityOrchestration|Security policy project was unlinked successfully"
-msgstr ""
+msgstr "安全策略项目已æˆåŠŸå–消关è”"
msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr "选择一个项目æ¥å­˜å‚¨æ‚¨çš„安全策略。 %{linkStart}更多信æ¯ã€‚%{linkEnd}"
@@ -30874,10 +31397,10 @@ msgid "SecurityOrchestration|To widen your search, change filters above or selec
msgstr "è¦æ‰©å¤§æ‚¨çš„æœç´¢èŒƒå›´ï¼Œè¯·åœ¨ä¸Šé¢æ›´æ”¹è¿‡æ»¤è§„则或选择ä¸åŒçš„安全策略项目。"
msgid "SecurityOrchestration|Unlink project"
-msgstr ""
+msgstr "å–消项目关è”"
msgid "SecurityOrchestration|Unlinking a security project removes all policies stored in the linked security project. Save to confirm this action."
-msgstr ""
+msgstr "å–消链接安全项目会移除在链接的安全项目中存储的所有策略。ä¿å­˜ä»¥ç¡®è®¤æ­¤æ“作。"
msgid "SecurityOrchestration|Update scan execution policies"
msgstr "更新扫æ执行策略"
@@ -30885,9 +31408,6 @@ msgstr "更新扫æ执行策略"
msgid "SecurityOrchestration|view results"
msgstr "查看结果"
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr "未定义规则 - 策略无法è¿è¡Œã€‚"
-
msgid "SecurityPolicies|+%{count} more"
msgstr "+%{count} 更多"
@@ -31086,6 +31606,9 @@ msgstr "设置状æ€"
msgid "SecurityReports|Severity"
msgstr "严é‡ç¨‹åº¦"
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr "有时扫æ工具无法确定调查结果的严é‡æ€§ï¼Œè¿™äº›ç»“æžœå¯èƒ½ä»ç„¶æ˜¯æ½œåœ¨çš„风险æ¥æºï¼Œè¯·æ‰‹åŠ¨æŸ¥çœ‹"
@@ -31098,9 +31621,12 @@ msgstr "状æ€"
msgid "SecurityReports|Take survey"
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}"
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
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 "æ¼æ´žæŠ¥å‘Šæ˜¾ç¤ºé¡¹ç›®é»˜è®¤åˆ†æ”¯ä¸Šæœ€æ–°æˆåŠŸæµæ°´çº¿çš„结果,以åŠæœ€æ–°å®¹å™¨æ‰«æçš„æ¼æ´žã€‚ %{linkStart}了解更多。%{linkEnd}"
+
msgid "SecurityReports|The security reports below contain one or more vulnerability findings that could not be parsed and were not recorded. Download the artifacts in the job output to investigate. Ensure any security report created conforms to the relevant %{helpPageLinkStart}JSON schema%{helpPageLinkEnd}."
msgstr "下é¢çš„安全报告包å«ä¸€ä¸ªæˆ–多个无法解æžä¸”未记录的æ¼æ´žå‘现。下载作业输出中的产物以进行调查。确ä¿åˆ›å»ºçš„任何安全报告都符åˆç›¸å…³çš„ %{helpPageLinkStart}JSON schema%{helpPageLinkEnd}。"
@@ -31132,7 +31658,7 @@ msgid "SecurityReports|There was an error while generating the report."
msgstr "生æˆæŠ¥å‘Šæ—¶å‡ºé”™ã€‚"
msgid "SecurityReports|These vulnerabilities were detected in external sources. They are not necessarily tied to your GitLab project. For example, running containers, URLs, and so on."
-msgstr ""
+msgstr "这些æ¼æ´žæ˜¯åœ¨å¤–部æ¥æºä¸­æ£€æµ‹åˆ°çš„,它们ä¸ä¸€å®šä¸Žæ‚¨çš„项目相关è”。例如,è¿è¡Œå®¹å™¨ã€URL 等。"
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr "è¦æ‰©å¤§æœç´¢èŒƒå›´ï¼Œè¯·æ›´æ”¹æˆ–删除上é¢çš„筛选器。"
@@ -31173,6 +31699,9 @@ msgstr "您没有足够的æƒé™è®¿é—®æ­¤æŠ¥å‘Š"
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr "您必须以授æƒç”¨æˆ·èº«ä»½ç™»å½•æ‰èƒ½æŸ¥çœ‹æ­¤æŠ¥å‘Š"
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr "您的å馈对我们很é‡è¦ï¼æˆ‘们将在7天内å†æ¬¡è¯¢é—®ã€‚"
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr "您的å馈对我们很é‡è¦ï¼æˆ‘们将在一周内å†æ¬¡è¯¢é—®ã€‚"
@@ -31273,7 +31802,7 @@ msgid "Select assignee"
msgstr "选择指派人"
msgid "Select assignee(s)"
-msgstr ""
+msgstr "选择指派人"
msgid "Select branch"
msgstr "选择分支"
@@ -31326,6 +31855,9 @@ msgstr "按项目和地域选择实例类型"
msgid "Select project to choose zone"
msgstr "按项目选择地域"
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr "选择è¦åˆ›å»ºè®®é¢˜çš„项目"
@@ -31579,16 +32111,16 @@ msgid "Service"
msgstr "æœåŠ¡"
msgid "Service Account"
-msgstr ""
+msgstr "æœåŠ¡å¸æˆ·"
msgid "Service Account Key"
-msgstr ""
+msgstr "æœåŠ¡å¸æˆ·å¯†é’¥"
msgid "Service Accounts"
-msgstr ""
+msgstr "æœåŠ¡å¸æˆ·"
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
-msgstr ""
+msgstr "æœåŠ¡å¸æˆ·å¯†é’¥æŽˆæƒ GitLab 部署您的 Google Cloud 项目"
msgid "Service Desk"
msgstr "æœåŠ¡å°"
@@ -31600,7 +32132,7 @@ msgid "Service URL"
msgstr "æœåŠ¡ URL"
msgid "Service account generated successfully"
-msgstr ""
+msgstr "æœåŠ¡å¸æˆ·ç”ŸæˆæˆåŠŸ"
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
msgstr "æœåŠ¡ ping 在您的é…置文件中被ç¦ç”¨ï¼Œå¹¶ä¸”无法通过此表å•å¯ç”¨ã€‚"
@@ -31648,7 +32180,7 @@ msgid "ServicePing|Turn on service ping to review instance-level analytics."
msgstr "打开æœåŠ¡ping以查看实例级分æžã€‚"
msgid "Services"
-msgstr ""
+msgstr "æœåŠ¡"
msgid "Session ID"
msgstr "ä¼šè¯ ID"
@@ -31677,6 +32209,12 @@ msgstr "设定缺çœåŠå—é™å¯è§æ€§çº§åˆ«ã€‚é…置导入æ¥æºåŠgit访问å
msgid "Set due date"
msgstr "设置截止日期"
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr "设置迭代"
@@ -31732,7 +32270,7 @@ msgid "Set the iteration to %{iteration_reference}."
msgstr "将迭代设置为%{iteration_reference}。"
msgid "Set the maximum number of slices allowed to run concurrently during Elasticsearch reindexing. Learn more about %{max_slices_running_link_start}maximum running slices configuration%{max_slices_link_end}."
-msgstr ""
+msgstr "设置 Elasticsearch é‡å»ºæœŸé—´å…许åŒæ—¶è¿è¡Œçš„碎片的最大数é‡ã€‚了解更多关于 %{max_slices_running_link_start}最大è¿è¡Œç¢Žç‰‡é…ç½®%{max_slices_link_end}。"
msgid "Set the maximum session time for a web terminal."
msgstr "设置 Web 终端的最长会è¯æ—¶é—´ã€‚"
@@ -31833,6 +32371,9 @@ msgstr "您的状æ€åœ¨ %{date} æ—¶é‡ç½®ã€‚"
msgid "Sets %{epic_ref} as parent epic."
msgstr "å°†%{epic_ref}设置为父å²è¯—。"
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr "设置目标分支为%{branch_name}。"
@@ -31931,25 +32472,25 @@ msgid "Sherlock Transactions"
msgstr "Sherlock事务"
msgid "Shimo|Go to Shimo Workspace"
-msgstr ""
+msgstr "转到石墨工作区"
msgid "Shimo|Link to a Shimo Workspace from the sidebar."
-msgstr ""
+msgstr "从侧边æ é“¾æŽ¥åˆ°çŸ³å¢¨å·¥ä½œåŒºã€‚"
msgid "Shimo|Shimo"
-msgstr ""
+msgstr "石墨"
msgid "Shimo|Shimo Workspace"
-msgstr ""
+msgstr "石墨工作区"
msgid "Shimo|Shimo Workspace URL"
-msgstr ""
+msgstr "石墨工作区 URL"
msgid "Shimo|Shimo Workspace integration is enabled"
-msgstr ""
+msgstr "石墨工作区集æˆå·²å¯ç”¨"
msgid "Shimo|You've enabled the Shimo Workspace integration. You can view your wiki directly in Shimo."
-msgstr ""
+msgstr "您已å¯ç”¨çŸ³å¢¨å·¥ä½œåŒºé›†æˆã€‚您å¯ä»¥ç›´æŽ¥åœ¨çŸ³å¢¨æŸ¥çœ‹æ‚¨çš„wiki。"
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{boldStart}will%{boldEnd} lose access to your account."
msgstr "如果您丢失手机或访问一次性密ç ï¼Œæ¯ä¸ªæ¢å¤ç éƒ½å¯ä»¥ä½¿ç”¨ä¸€æ¬¡ï¼Œä»¥é‡æ–°èŽ·å¾—您的å¸æˆ·è®¿é—®æƒé™ã€‚请将它们ä¿å­˜åœ¨å®‰å…¨çš„地方,å¦åˆ™æ‚¨%{boldStart}å°†%{boldEnd}无法访问您的å¸æˆ·ã€‚"
@@ -31967,7 +32508,7 @@ msgid "Show all activity"
msgstr "显示所有活动"
msgid "Show all breadcrumbs"
-msgstr ""
+msgstr "显示所有é¢åŒ…屑导航"
msgid "Show all issues."
msgstr "显示所有议题。"
@@ -32383,10 +32924,10 @@ msgid "Something went wrong trying to change the locked state of this %{issuable
msgstr "è¯•å›¾æ”¹å˜ %{issuableDisplayName} çš„é”定状æ€æ—¶å‡ºé”™äº†"
msgid "Something went wrong trying to load issue contacts."
-msgstr ""
+msgstr "å°è¯•åŠ è½½è®®é¢˜è”系人时出错。"
msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
+msgstr "创建工作项时出错,请é‡è¯•"
msgid "Something went wrong when reordering designs. Please try again"
msgstr "é‡æ–°æŽ’åºè®¾è®¡æ—¶å‡ºäº†ç‚¹é—®é¢˜ã€‚请å†è¯•ä¸€æ¬¡"
@@ -32529,6 +33070,9 @@ msgstr "更新需求时出了错。"
msgid "Something went wrong while updating assignees"
msgstr "更新指派人时出错"
+msgid "Something went wrong while updating work item. Please try again"
+msgstr "更新工作项时出错。请å†è¯•ä¸€æ¬¡"
+
msgid "Something went wrong while updating your list settings"
msgstr "更新列表设置时出现错误"
@@ -32767,31 +33311,31 @@ msgid "Source project cannot be found."
msgstr "找ä¸åˆ°æºé¡¹ç›®ã€‚"
msgid "SourceEditor|\"el\" parameter is required for createInstance()"
-msgstr ""
+msgstr "createInstance() éœ€è¦ \"el\" å‚æ•°"
msgid "SourceEditor|%{name} is not registered."
-msgstr ""
+msgstr "%{name} 未注册。"
msgid "SourceEditor|Extension definition should be either a class or a function"
-msgstr ""
+msgstr "扩展定义应该是一个类或一个函数"
msgid "SourceEditor|Extension definition should be either class, function, or an Array of definitions."
-msgstr ""
+msgstr "扩展定义应该是类别ã€å‡½æ•°æˆ–定义数组。"
msgid "SourceEditor|Extensions Store is required to check for an extension."
-msgstr ""
+msgstr "扩展存储需è¦æ£€æŸ¥æ‰©å±•ã€‚"
msgid "SourceEditor|Name conflict for \"%{prop}()\" method."
-msgstr ""
+msgstr "\"%{prop}()\"方法å称冲çªã€‚"
msgid "SourceEditor|No extension for unuse has been specified."
-msgstr ""
+msgstr "未指定未使用的扩展å。"
msgid "SourceEditor|Source Editor instance is required to set up an extension."
-msgstr ""
+msgstr "éœ€è¦ Source Editor 实例æ¥è®¾ç½®æ‰©å±•ã€‚"
msgid "SourceEditor|`definition` property is expected on the extension."
-msgstr ""
+msgstr "`definition` 属性应该在扩展上。"
msgid "Sourcegraph"
msgstr "Sourcegraph"
@@ -32973,9 +33517,6 @@ msgstr "开始您的å…费试用"
msgid "Start your free trial"
msgstr "开始å…费试用"
-msgid "Start your trial"
-msgstr "开始试用"
-
msgid "Started"
msgstr "å·²å¯åŠ¨"
@@ -33091,7 +33632,7 @@ msgid "Status: %{title}"
msgstr "状æ€: %{title}"
msgid "StatusCheck|%{failed} failed"
-msgstr ""
+msgstr "%{failed} 个失败"
msgid "StatusCheck|%{pending} pending"
msgstr "%{pending} 等待"
@@ -33115,7 +33656,7 @@ msgid "StatusCheck|Apply this status check to all branches or a specific protect
msgstr "将此状æ€æ£€æŸ¥åº”用于所有分支或特定的å—ä¿æŠ¤åˆ†æ”¯ã€‚"
msgid "StatusCheck|Check for a status response in merge requests. Failures do not block merges. %{link_start}Learn more%{link_end}."
-msgstr ""
+msgstr "在åˆå¹¶è¯·æ±‚中检查状æ€å“应,失败ä¸ä¼šé˜»æ­¢åˆå¹¶ã€‚ %{link_start}了解更多%{link_end}"
msgid "StatusCheck|Examples: QA, Security."
msgstr "示例:QAã€å®‰å…¨ã€‚"
@@ -33124,7 +33665,7 @@ msgid "StatusCheck|External API is already in use by another status check."
msgstr "外部 API 已被å¦ä¸€ä¸ªçŠ¶æ€æ£€æŸ¥ä½¿ç”¨ã€‚"
msgid "StatusCheck|Failed to load status checks"
-msgstr ""
+msgstr "加载状æ€æ£€æŸ¥å¤±è´¥"
msgid "StatusCheck|Failed to load status checks."
msgstr "无法加载状æ€æ£€æŸ¥ã€‚"
@@ -33148,10 +33689,10 @@ msgid "StatusCheck|Status checks"
msgstr "状æ€æ£€æŸ¥"
msgid "StatusCheck|Status checks all passed"
-msgstr ""
+msgstr "状æ€æ£€æŸ¥å…¨éƒ¨é€šè¿‡"
msgid "StatusCheck|Status checks are being fetched"
-msgstr ""
+msgstr "正在获å–状æ€æ£€æŸ¥"
msgid "StatusCheck|Status to check"
msgstr "è¦æ£€æŸ¥çš„状æ€"
@@ -33169,7 +33710,7 @@ msgid "StatusCheck|You are about to remove the %{name} status check."
msgstr "您将è¦åˆ é™¤ %{name} 状æ€æ£€æŸ¥ã€‚"
msgid "StatusCheck|status checks"
-msgstr ""
+msgstr "状æ€æ£€æŸ¥"
msgid "StatusPage|AWS %{docsLink}"
msgstr "AWS %{docsLink}"
@@ -33372,6 +33913,12 @@ msgstr "订阅已æˆåŠŸåˆ›å»ºã€‚"
msgid "Subscription successfully deleted."
msgstr "订阅已æˆåŠŸåˆ é™¤ã€‚"
+msgid "SubscriptionBanner|Export license usage file"
+msgstr "导出许å¯è¯ä½¿ç”¨æ–‡ä»¶"
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr "上传新许å¯è¯"
+
msgid "SubscriptionTable|Add seats"
msgstr "添加席ä½"
@@ -33807,6 +34354,24 @@ msgstr "语法正确。"
msgid "Syntax is incorrect."
msgstr "语法ä¸æ­£ç¡®ã€‚"
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr "系统"
@@ -34073,9 +34638,23 @@ msgid "Terraform|%{number} Terraform report was generated in your pipelines"
msgid_plural "Terraform|%{number} Terraform reports were generated in your pipelines"
msgstr[0] "您的æµæ°´çº¿ç”Ÿæˆäº†%{number}个Terraform报告"
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr "%{user}更新于%{timeAgo}"
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr "无法生æˆæŠ¥å‘Šã€‚"
@@ -34106,6 +34685,9 @@ msgstr "详细信æ¯"
msgid "Terraform|Download JSON"
msgstr "下载JSON"
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr "生æˆæŠ¥å‘Šæ—¶å‘生错误。"
@@ -34118,6 +34700,9 @@ msgstr "如何使用 GitLab 管ç†çš„ Terraform State?"
msgid "Terraform|Job status"
msgstr "作业状æ€"
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr "é”定"
@@ -34154,10 +34739,19 @@ msgstr "状æ€"
msgid "Terraform|Terraform init command"
msgstr "Terraform init 命令"
-msgid "Terraform|The job %{name} failed to generate a report."
+msgid "Terraform|Terraform reports"
msgstr ""
+msgid "Terraform|The job %{name} failed to generate a report."
+msgstr "作业 %{name} 生æˆæŠ¥å‘Šå¤±è´¥ã€‚"
+
msgid "Terraform|The job %{name} generated a report."
+msgstr "作业 %{name} 生æˆäº†ä¸€ä¸ªæŠ¥å‘Šã€‚"
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
msgstr ""
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
@@ -34410,7 +35004,7 @@ msgid "The URL should start with http:// or https://"
msgstr "URL 应该以 http:// 或 https:// 开头"
msgid "The URLs for connecting to Elasticsearch. For clustering, add the URLs separated by commas."
-msgstr ""
+msgstr "连接到Elasticsearchçš„URL。对于集群,请添加用逗å·åˆ†éš”çš„URL。"
msgid "The X509 Certificate to use when mutual TLS is required to communicate with the external authorization service. If left blank, the server certificate is still validated when accessing over HTTPS."
msgstr "在需è¦ç›¸äº’ TLS 与外部授æƒæœåŠ¡é€šä¿¡æ—¶ä½¿ç”¨çš„ X509 è¯ä¹¦ã€‚如果ä¿ç•™ä¸ºç©º, 则在访问 HTTPS æ—¶ä»ç„¶éªŒè¯æœåŠ¡å™¨è¯ä¹¦ã€‚"
@@ -34442,14 +35036,17 @@ msgstr "由于存在åˆå¹¶å†²çªï¼Œå¯¹æ¯”视图å¯èƒ½ä¸å‡†ç¡®ã€‚"
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr "åˆè§„报告æ•èŽ·è¿ååˆè§„最佳实践的åˆå¹¶æ›´æ”¹ã€‚"
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr "åˆè§„报告显示åˆå¹¶è¯·æ±‚在å—ä¿æŠ¤çš„环境中åˆå¹¶ã€‚"
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "该连接将在 %{timeout}åŽè¶…时。如仓库导入耗时超过该时间,请使用克隆/推é€ç»„åˆã€‚"
msgid "The contact does not belong to the same group as the issue"
-msgstr ""
+msgstr "è”系人ä¸å±žäºŽè®®é¢˜æ‰€åœ¨çš„相åŒç¾¤ç»„"
msgid "The content editor may change the markdown formatting style of the document, which may not match your original markdown style."
-msgstr ""
+msgstr "内容编辑器å¯èƒ½ä¼šæ›´æ”¹æ–‡æ¡£çš„ Markdown æ ¼å¼æ ·å¼ï¼Œè¿™å¯èƒ½ä¸Žæ‚¨åŽŸæ¥çš„ Markdown æ ·å¼ä¸åŒ¹é…。"
msgid "The content of this page is not encoded in UTF-8. Edits can only be made via the Git repository."
msgstr "此页é¢çš„内容未以UTF-8ç¼–ç ã€‚编辑åªèƒ½é€šè¿‡Git仓库进行。"
@@ -34563,9 +35160,6 @@ msgstr "群组和任何公共项目å¯ä»¥åœ¨æ²¡æœ‰ä»»ä½•èº«ä»½éªŒè¯çš„情况下
msgid "The group and its projects can only be viewed by members."
msgstr "群组åŠå…¶é¡¹ç›®åªèƒ½ç”±æˆå‘˜æŸ¥çœ‹ã€‚"
-msgid "The group can be fully restored"
-msgstr "群组å¯ä»¥å®Œå…¨æ¢å¤"
-
msgid "The group export can be downloaded from:"
msgstr "群组导出å¯ä»¥ä»Žä»¥ä¸‹ä½ç½®ä¸‹è½½ï¼š"
@@ -34575,9 +35169,6 @@ msgstr "该群组已与此群组共享"
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr "%{group_links} 的群组设置è¦æ±‚您为å¸æˆ·å¯ç”¨åŒé‡è®¤è¯ã€‚你也å¯ä»¥ %{leave_group_links}。"
-msgid "The group will be placed in 'pending deletion' state"
-msgstr "该群组将处于“待删除â€çŠ¶æ€"
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr "group_project_ids å‚æ•°åªå…许用于一个群组"
@@ -34650,8 +35241,8 @@ msgstr "个别作业产物的最大文件大å°ï¼Œä»¥å…†å­—节(MB)计算。"
msgid "The maximum file size is %{size}."
msgstr "最大文件大å°ä¸º %{size}。"
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
-msgstr "一个群组æ¯æœˆå¯ä»¥åœ¨å…±äº«runner上使用的最大æµæ°´çº¿åˆ†é’Ÿæ•°ã€‚ 0 表示无é™åˆ¶ã€‚"
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
+msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
msgstr "å•ä¸ªworker接å—清ç†çš„最大标签数。如果标签数é‡è¶…过此é™åˆ¶ï¼Œåˆ™è¦åˆ é™¤çš„标签列表将被截断为该数é‡ã€‚è¦å–消此é™åˆ¶ï¼Œè¯·å°†å…¶è®¾ç½®ä¸º 0。"
@@ -34840,7 +35431,7 @@ msgid "The vulnerability is no longer detected. Verify the vulnerability has bee
msgstr "æ¼æ´žå·²ä¸å†è¢«æ£€æµ‹åˆ°ã€‚请在更改其状æ€å‰ç¡®ä¿æ¼æ´žå·²ä¿®è¡¥ã€‚"
msgid "There are Advanced Search migrations pending that require indexing to pause. Indexing must remain paused until GitLab completes the migrations."
-msgstr ""
+msgstr "有需è¦æš‚åœç´¢å¼•çš„高级æœç´¢è¿ç§»å¾…处ç†ã€‚索引必须ä¿æŒæš‚åœï¼Œç›´åˆ° GitLab 完æˆè¿ç§»ã€‚"
msgid "There are currently no events."
msgstr "当å‰æ²¡æœ‰äº‹ä»¶ã€‚"
@@ -34905,9 +35496,6 @@ msgstr "当å‰æ— è®®é¢˜"
msgid "There are no issues with the selected labels"
msgstr "所选标记没有问题"
-msgid "There are no labels yet"
-msgstr "ç›®å‰æ— æ ‡è®°"
-
msgid "There are no matching files"
msgstr "没有匹é…的文件"
@@ -35253,6 +35841,9 @@ msgstr "该GitLab实例的许å¯ä¸º%{insufficient_license}级别。拥有高级ç
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr "æ­¤GitLab实例正在维护中,并以åªè¯»æ¨¡å¼è¿è¡Œã€‚"
+msgid "This PDF is too large to display. Please download to view."
+msgstr "此 PDF 太大而无法显示。请下载查看。"
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr "此项目目å‰å·²å­˜æ¡£å¹¶åªè¯»ã€‚如果您想è¦æ¢å¤æ‹‰å–é•œåƒï¼Œè¯·å…ˆå–消归档。"
@@ -35265,9 +35856,6 @@ msgstr "æ­¤æ“作å¯èƒ½å¯¼è‡´æ•°æ®ä¸¢å¤±ã€‚为防止æ„外,我们会è¦æ±‚您
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr "æ­¤æ“作无法撤消,它将永久删除%{key}SSH密钥"
-msgid "This action has been performed too many times. Try again later."
-msgstr "æ­¤æ“作已执行太多次。ç¨åŽå†è¯•ã€‚"
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr "æ­¤æ“作将 %{strongOpen}ç«‹å³%{strongClose}%{strongOpen}永久删除%{strongClose} %{codeOpen}%{project}%{codeClose} ,包括其仓库和所有相关资æºï¼ŒåŒ…括议题和åˆå¹¶è¯·æ±‚。"
@@ -35292,6 +35880,9 @@ msgstr "此应用程åºæ˜¯ä¸º%{group_link}群组创建的。"
msgid "This application will be able to:"
msgstr "此应用程åºå°†å¯ä»¥ï¼š"
+msgid "This archive has been requested too many times. Try again later."
+msgstr "请求此存档的次数过多。ç¨åŽå†è¯•ã€‚"
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr "此附件已被截断,以é¿å…超过最大å…è®¸çš„é™„ä»¶å¤§å° %{size_limit}。 其中包括%{count} 个%{issuables} 中的%{written_count}个。考虑缩å°é€‰æ‹©çš„ %{issuables} å†å¯¼å‡ºã€‚"
@@ -35326,7 +35917,7 @@ msgid "This commit is part of merge request %{link_to_merge_request}. Comments c
msgstr "æ­¤æ交是åˆå¹¶è¯·æ±‚ %{link_to_merge_request} 的一部分。此处创建的评论将在该åˆå¹¶è¯·æ±‚的上下文中创建。"
msgid "This commit was signed with %{strong_open}multiple%{strong_close} signatures."
-msgstr ""
+msgstr "æ­¤æ交使用 %{strong_open}多个%{strong_close} ç­¾å进行签署。"
msgid "This commit was signed with a %{strong_open}verified%{strong_close} signature and the committer email is verified to belong to the same user."
msgstr "æ­¤æ交使用%{strong_open}已验è¯çš„%{strong_close}ç­¾å进行签署,并且已验è¯æ交者的电å­é‚®ä»¶å±žäºŽåŒä¸€ç”¨æˆ·ã€‚"
@@ -35395,10 +35986,10 @@ msgid "This field is required."
msgstr "该字段是必填字段。"
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
-msgstr ""
+msgstr "此文件已被修改以æ高å¯è¯»æ€§ï¼Œä¸èƒ½æŽ¥å—建议,请直接编辑。"
msgid "This forked project has the following:"
-msgstr ""
+msgstr "这个派生项目有以下几点:"
msgid "This form is disabled in preview"
msgstr "此表å•åœ¨é¢„览中被ç¦ç”¨"
@@ -35406,6 +35997,9 @@ msgstr "此表å•åœ¨é¢„览中被ç¦ç”¨"
msgid "This group"
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 ""
+
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} 链接到å¦ä¸€ä¸ªç¾¤ç»„。"
@@ -35455,13 +36049,13 @@ msgid "This is a private email address %{helpIcon} generated just for you. Anyon
msgstr "这是专为您生æˆçš„ç§äººç”µå­é‚®ä»¶åœ°å€ %{helpIcon} 任何拥有它的人都å¯ä»¥åƒæ‚¨ä¸€æ ·åˆ›å»ºé—®é¢˜æˆ–åˆå¹¶è¯·æ±‚。如果å‘生这ç§æƒ…况, %{resetLinkStart}é‡ç½®è¿™ä¸ªä»¤ç‰Œ%{resetLinkEnd}。"
msgid "This is a security log of authentication events involving your account."
-msgstr ""
+msgstr "这是涉åŠæ‚¨å¸æˆ·çš„身份验è¯äº‹ä»¶çš„安全日志。"
msgid "This is a self-managed instance of GitLab."
msgstr "这是GitLab的自管ç†å®žä¾‹ã€‚"
msgid "This is an experimental feature developed by GitLab Incubation Engineering."
-msgstr ""
+msgstr "这是 GitLab Incubation Engineering å¼€å‘的一项实验性功能。"
msgid "This is the highest peak of users on your installation since the license started."
msgstr "此数字为自许å¯è¯å¯åŠ¨ä»¥æ¥ç”¨æˆ·æ•°ç›®çš„最高值。"
@@ -35473,7 +36067,7 @@ msgid "This is your current session"
msgstr "这是您当å‰çš„会è¯"
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
-msgstr ""
+msgstr "此议题是ä¿å¯†çš„,åªèƒ½æ˜¾ç¤ºç»™æ‹¥æœ‰è‡³å°‘“报告人â€è®¿é—®æƒé™çš„团队æˆå‘˜ã€‚"
msgid "This issue is currently blocked by the following issues:"
msgstr "此问题目å‰è¢«ä»¥ä¸‹é—®é¢˜é˜»æ­¢ï¼š"
@@ -35571,6 +36165,9 @@ msgstr "作业需手动æ“作"
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr "此作业需è¦æ‰‹åŠ¨å¹²é¢„æ‰èƒ½å¼€å§‹ã€‚在å¯åŠ¨æ¬¡ä½œä¸šä¹‹å‰ï¼Œæ‚¨å¯ä»¥åœ¨ä¸‹é¢æ·»åŠ å˜é‡ï¼Œè¿›è¡Œæœ€åŽæ—¶åˆ»çš„é…置更改。"
+msgid "This job triggers a downstream pipeline"
+msgstr "此作业触å‘下游æµæ°´çº¿"
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr "该作业将在计时器完æˆåŽè‡ªåŠ¨è¿è¡Œã€‚它们通常用于生产环境的增é‡éƒ¨ç½²ã€‚未计划时,它会转æ¢ä¸ºæ‰‹åŠ¨æ“作。"
@@ -35653,7 +36250,7 @@ msgid "This project has no active access tokens."
msgstr "此项目没有有效的访问令牌。"
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
-msgstr ""
+msgstr "这个项目 %{strongStart}ä¸æ˜¯%{strongEnd} 一个派生项目,并具有以下内容:"
msgid "This project is archived and cannot be commented on."
msgstr "此项目已存档,无法添加评论。"
@@ -35755,7 +36352,7 @@ msgid "Thread to reply to cannot be found"
msgstr "找ä¸åˆ°è¦å›žå¤çš„主题"
msgid "Threat monitoring"
-msgstr ""
+msgstr "å¨èƒç›‘控"
msgid "ThreatMonitoring|Alert Details"
msgstr "警报详细信æ¯"
@@ -36281,6 +36878,9 @@ msgstr "è¦é‡æ–°æ¿€æ´»æ‚¨çš„å¸æˆ·ï¼Œè¯·åœ¨ %{gitlab_url}登录 GitLab。"
msgid "To receive alerts from manually configured Prometheus services, add the following URL and Authorization key to your Prometheus webhook config file. Learn more about %{linkStart}configuring Prometheus%{linkEnd} to send alerts to GitLab."
msgstr "è¦ä»Žæ‰‹åŠ¨é…置的PrometheusæœåŠ¡æŽ¥æ”¶è­¦æŠ¥ï¼Œè¯·å°†ä»¥ä¸‹URL和授æƒå¯†é’¥æ·»åŠ åˆ°Prometheus webhooké…置文件中。了解更多关于 %{linkStart}é…ç½®Prometheus%{linkEnd} 将警报å‘é€åˆ°GitLab。"
+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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr "è¦è§£å†³æ­¤é—®é¢˜ï¼Œè¯·å°è¯•ï¼š"
@@ -36297,7 +36897,7 @@ msgid "To see this project's operational details, contact an owner of group %{gr
msgstr "è¦æŸ¥çœ‹è¯¥é¡¹ç›®çš„è¿ç»´è¯¦ç»†ä¿¡æ¯ï¼Œè¯·ä¸Ž%{groupName}群组的所有者è”系以å‡çº§è®¢é˜…计划。或者您也å¯ä»¥ä»Žä»ªè¡¨æ¿ä¸Šåˆ é™¤æ­¤é¡¹ç›®ã€‚"
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 ""
+msgstr "è¦æŸ¥çœ‹æ›´æ”¹çš„内容或创建åˆå¹¶è¯·æ±‚,请选择分支或标签(如 %{branch}),或输入æ交(如 %{sha})。"
msgid "To set up SAML authentication for your group through an identity provider like Azure, Okta, Onelogin, Ping Identity, or your custom SAML 2.0 provider:"
msgstr "通过Azure,Okta,Onelogin,Ping Identity或自定义SAML 2.0等身份验è¯ç¨‹åºä¸ºæ‚¨çš„群组设置SAML身份验è¯ï¼š"
@@ -36324,7 +36924,7 @@ msgid "To use the additional formats, you must start the required %{container_li
msgstr "è¦ä½¿ç”¨å…¶å®ƒæ ¼å¼ï¼Œæ‚¨å¿…é¡»å¯åŠ¨æ‰€éœ€çš„ %{container_link_start}ä¼´éšå®¹å™¨%{container_link_end}。"
msgid "To use the system's default, set this value to 0."
-msgstr ""
+msgstr "è¦ä½¿ç”¨ç³»ç»Ÿé»˜è®¤å€¼ï¼Œè¯·å°†æ­¤å€¼è®¾ç½®ä¸º 0。"
msgid "To view all %{scannedResourcesCount} scanned URLs, %{linkStart}please download the CSV file%{linkEnd}"
msgstr "如需查看所有%{scannedResourcesCount}已扫æ网å€ï¼Œ%{linkStart}请下载CSV文件%{linkEnd}"
@@ -36347,6 +36947,39 @@ msgstr "待办事项已æˆåŠŸæ ‡è®°ä¸ºå·²å®Œæˆã€‚"
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr "切æ¢GitLab Next"
@@ -36432,10 +37065,10 @@ msgid "Too many changes to show."
msgstr "è¦æ˜¾ç¤ºçš„å˜æ›´å¤ªå¤šã€‚"
msgid "Too many namespaces enabled. Manage them through the console or the API."
-msgstr ""
+msgstr "å¯ç”¨äº†å¤ªå¤šçš„命å空间,通过控制å°æˆ–API管ç†å®ƒä»¬ã€‚"
msgid "Too many projects enabled. Manage them through the console or the API."
-msgstr ""
+msgstr "å¯ç”¨äº†å¤ªå¤šçš„项目,通过控制å°æˆ– API 管ç†å®ƒä»¬ã€‚"
msgid "TopNav|Go back"
msgstr "返回"
@@ -36516,11 +37149,14 @@ msgid "Track your GitLab projects with GitLab for Slack."
msgstr "使用GitLab for Slack跟踪您的GitLab项目。"
msgid "Training mode"
-msgstr ""
+msgstr "训练模å¼"
msgid "Transfer"
msgstr "转移"
+msgid "Transfer group to another parent group."
+msgstr "将群组转移到å¦ä¸€ä¸ªçˆ¶ç»„。"
+
msgid "Transfer ownership"
msgstr "转移所有æƒ"
@@ -36642,15 +37278,6 @@ msgstr "åå­—"
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr "GitLab Ultimate 试用版(å¯é€‰ï¼‰"
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr "å—¨%{salutation},您的 GitLab Ultimate 试用期为 30 天,但您å¯ä»¥æ°¸ä¹…ä¿ç•™å…费的 GitLab è´¦å·ã€‚我们åªéœ€è¦ä¸€äº›å…³äºŽ %{company} 附加信æ¯å³å¯æ¿€æ´»æ‚¨çš„试用版。"
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr "有多少员工会使用Gitlab?"
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr "有多少用户会评价试用版?"
-
msgid "Trial|Last name"
msgstr "姓æ°"
@@ -36675,9 +37302,6 @@ msgstr "在您完æˆæ­¤æ­¥éª¤åŽï¼Œæˆ‘们将在您的群组中激活您的试用
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr "您的 GitLab Ultimate 试用期为 30 天,但您å¯ä»¥æ°¸ä¹…ä¿ç•™å…费的 GitLab å¸æˆ·ã€‚我们åªéœ€è¦ä¸€äº›é¢å¤–çš„ä¿¡æ¯æ¥æ¿€æ´»æ‚¨çš„试用版。"
-msgid "Trial|your company"
-msgstr "您的公å¸"
-
msgid "Trigger"
msgstr "触å‘器"
@@ -36688,7 +37312,7 @@ msgid "Trigger cluster reindexing"
msgstr "触å‘集群é‡å»ºç´¢å¼•"
msgid "Trigger cluster reindexing. Only use this with an index that was created in GitLab 13.0 or later."
-msgstr ""
+msgstr "触å‘集群é‡å»ºã€‚仅使用 13.0 或更高版本创建的索引。"
msgid "Trigger manual job"
msgstr "触å‘手动作业"
@@ -36745,10 +37369,10 @@ msgid "Try grouping with different labels"
msgstr "å°è¯•ä½¿ç”¨ä¸åŒçš„标记分组"
msgid "Try out GitLab Pipelines"
-msgstr ""
+msgstr "试用 GitLab æµæ°´çº¿"
msgid "Try the troubleshooting steps here."
-msgstr ""
+msgstr "å°è¯•æ­¤å¤„的故障排除步骤。"
msgid "Try to fork again"
msgstr "å°è¯•å†æ¬¡æ´¾ç”Ÿ"
@@ -37054,7 +37678,7 @@ msgid "Unknown response text"
msgstr "未知的å“应文本"
msgid "Unknown screen"
-msgstr ""
+msgstr "未知å±å¹•"
msgid "Unknown user"
msgstr "未知用户"
@@ -37249,7 +37873,7 @@ msgid "Updating"
msgstr "更新中"
msgid "Updating the attention request for %{username} failed."
-msgstr ""
+msgstr "更新 %{username} 关注请求失败。"
msgid "Updating…"
msgstr "正在更新…"
@@ -37294,7 +37918,7 @@ msgid "Upload license"
msgstr "上传许å¯è¯"
msgid "Upload new file"
-msgstr ""
+msgstr "上传新文件"
msgid "Upload object map"
msgstr "上传对象图"
@@ -37305,9 +37929,6 @@ msgstr "点击上传"
msgid "Uploading changes to terminal"
msgstr "正在将å˜æ›´å†…容上传到终端"
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr "执行此æ“作åŽï¼Œè¯¥ç¾¤ç»„ã€å…¶å­ç»„和项目的内容将%{deletion_adjourned_period} 天åŽåœ¨ %{date} 永久删除。到那时之å‰ï¼š"
-
msgid "Upstream"
msgstr "上游"
@@ -37381,13 +38002,13 @@ msgid "UsageQuota|Learn more about usage quotas"
msgstr "了解有关使用é…é¢çš„更多信æ¯"
msgid "UsageQuota|No CI minutes usage data available."
-msgstr ""
+msgstr "æ— å¯ç”¨çš„ CI 分钟使用数æ®ã€‚"
msgid "UsageQuota|Packages"
msgstr "软件包"
msgid "UsageQuota|Pending Members"
-msgstr ""
+msgstr "待定æˆå‘˜"
msgid "UsageQuota|Pipeline artifacts and job artifacts, created with CI/CD."
msgstr "用 CI/CD 创建的æµæ°´çº¿åˆ¶å“和作业制å“。"
@@ -38199,16 +38820,16 @@ msgstr "验è¯å¹¶å‘é™åˆ¶"
msgid "Verification status"
msgstr "验è¯çŠ¶æ€"
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38236,7 +38857,7 @@ msgid "View Documentation"
msgstr "查看文档"
msgid "View Stage: %{title}"
-msgstr ""
+msgstr "查看阶段: %{title}"
msgid "View alert details at"
msgstr "查看警报详细信æ¯äºŽ"
@@ -38250,6 +38871,9 @@ msgstr "查看所有环境。"
msgid "View all issues"
msgstr "查看所有议题"
+msgid "View blame"
+msgstr "查看 blame"
+
msgid "View blame prior to this change"
msgstr "查看此å˜æ›´å‰çš„blame模å¼"
@@ -38272,6 +38896,9 @@ msgstr "查看详细信æ¯: %{details_url}"
msgid "View documentation"
msgstr "查看文档"
+msgid "View downstream pipeline"
+msgstr "查看下游æµæ°´çº¿"
+
msgid "View eligible approvers"
msgstr "查看具备相关资格的核准人"
@@ -38280,7 +38907,7 @@ msgstr "查看å²è¯—列表"
msgid "View exposed artifact"
msgid_plural "View %d exposed artifacts"
-msgstr[0] ""
+msgstr[0] "查看%d项已展示产物"
msgid "View file @ "
msgstr "æµè§ˆæ–‡ä»¶ @ "
@@ -38300,6 +38927,12 @@ msgstr "在管ç†ä¸­å¿ƒæŸ¥çœ‹ç¾¤ç»„"
msgid "View group labels"
msgstr "查看群组标记"
+msgid "View incident details at"
+msgstr "查看事件详细信æ¯äºŽ"
+
+msgid "View incident details."
+msgstr "查看事件详情。"
+
msgid "View incident issues."
msgstr "查看事件议题。"
@@ -38334,7 +38967,7 @@ msgid "View merge request"
msgstr "查看åˆå¹¶è¯·æ±‚"
msgid "View milestones"
-msgstr ""
+msgstr "查看里程碑"
msgid "View on %{url}"
msgstr "在 %{url} 上查看"
@@ -38391,6 +39024,9 @@ msgstr "已查看"
msgid "Viewing commit"
msgstr "查看æ交"
+msgid "Violation"
+msgstr "è¿è§„"
+
msgid "Visibility"
msgstr "å¯è§æ€§"
@@ -38428,10 +39064,10 @@ msgid "Visit settings page"
msgstr "访问设置页é¢"
msgid "Visual Studio Code (HTTPS)"
-msgstr "Visual Studio ä»£ç  (HTTPS)"
+msgstr "Visual Studio Code (HTTPS)"
msgid "Visual Studio Code (SSH)"
-msgstr "Visual Studio ä»£ç  (SSH)"
+msgstr "Visual Studio Code (SSH)"
msgid "Vulnerabilities"
msgstr "æ¼æ´ž"
@@ -38446,7 +39082,7 @@ msgid "Vulnerability remediated. Review before resolving."
msgstr "æ¼æ´žå·²ä¿®è¡¥ã€‚置为解决之å‰è¯·å…ˆè¿›è¡Œå®¡æ ¸ã€‚"
msgid "Vulnerability report"
-msgstr ""
+msgstr "æ¼æ´žæŠ¥å‘Š"
msgid "Vulnerability resolved in %{branch}"
msgstr "æ¼æ´žå·²åœ¨%{branch}分支上解决"
@@ -38472,11 +39108,23 @@ msgstr "由%{user}于%{timeago}%{statusStart}忽略%{statusEnd}"
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr "由%{user}于%{timeago}%{statusStart}解决%{statusEnd}"
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr "已删除或已补救的æ¼æ´ž"
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr "真实æ¼æ´žå¹¶å°†ä¿®å¤"
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr "ç»è¯å®žçš„真实æ¼æ´ž"
+
msgid "VulnerabilityManagement|Add vulnerability finding"
-msgstr ""
+msgstr "添加æ¼æ´žå‘现"
+
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr "未è¯å®žçš„未确认å‘现"
msgid "VulnerabilityManagement|Change status"
msgstr "更改状æ€"
@@ -38488,10 +39136,10 @@ msgid "VulnerabilityManagement|Create Jira issue"
msgstr "创建 Jira 议题"
msgid "VulnerabilityManagement|Fetching linked Jira issues"
-msgstr ""
+msgstr "获å–å…³è”çš„ Jira 议题"
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
-msgstr ""
+msgstr "在æ¼æ´žæŠ¥å‘Šä¸­æ‰‹åŠ¨æ·»åŠ æ¼æ´žæ¡ç›®ã€‚"
msgid "VulnerabilityManagement|Needs triage"
msgstr "需è¦åˆ†ç±»"
@@ -38503,7 +39151,10 @@ msgid "VulnerabilityManagement|Related Jira issues"
msgstr "相关 Jira 问题"
msgid "VulnerabilityManagement|Requires assessment"
-msgstr ""
+msgstr "需è¦è¯„ä¼°"
+
+msgid "VulnerabilityManagement|Select a method"
+msgstr "选择方法"
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr "试图删除评论时出错。请ç¨åŽå†è¯•ã€‚"
@@ -38530,13 +39181,13 @@ msgid "VulnerabilityManagement|Something went wrong, could not update vulnerabil
msgstr "出错了,无法更新æ¼æ´žçŠ¶æ€ã€‚"
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
-msgstr ""
+msgstr "总结ã€è¯¦ç»†è¯´æ˜Žã€é‡çŽ°æ­¥éª¤ç­‰"
msgid "VulnerabilityManagement|Verified as fixed or mitigated"
msgstr "已验è¯ä¸ºä¿®å¤æˆ–缓解"
msgid "VulnerabilityManagement|Vulnerability name or type. Ex: Cross-site scripting"
-msgstr ""
+msgstr "æ¼æ´žå称或类型。例如:跨站脚本"
msgid "VulnerabilityManagement|Will not fix or a false-positive"
msgstr "å°†ä¸ä¿®å¤æˆ–为误报"
@@ -38554,7 +39205,7 @@ msgid "VulnerabilityStatusTypes|Dismissed"
msgstr "已忽略"
msgid "VulnerabilityStatusTypes|Needs triage"
-msgstr ""
+msgstr "需è¦åˆ†ç±»"
msgid "VulnerabilityStatusTypes|Resolved"
msgstr "已解决"
@@ -38574,9 +39225,18 @@ msgstr "实际收到的å“应是检测到此故障时收到的å“应"
msgid "Vulnerability|Additional Info"
msgstr "其它信æ¯"
+msgid "Vulnerability|Bug Bounty"
+msgstr "Bug Bounty"
+
+msgid "Vulnerability|CVSS v3"
+msgstr "CVSS v3"
+
msgid "Vulnerability|Class"
msgstr "类型"
+msgid "Vulnerability|Code Review"
+msgstr "代ç å®¡æŸ¥"
+
msgid "Vulnerability|Comments"
msgstr "注释"
@@ -38592,21 +39252,33 @@ msgstr "崩溃类型"
msgid "Vulnerability|Description"
msgstr "说明"
+msgid "Vulnerability|Details"
+msgstr "详情"
+
msgid "Vulnerability|Detected"
msgstr "检测到"
+msgid "Vulnerability|Detection method"
+msgstr "检测方法"
+
msgid "Vulnerability|Download"
msgstr "下载"
msgid "Vulnerability|Evidence"
msgstr "è¯æ®"
+msgid "Vulnerability|External Security Report"
+msgstr "外部安全报告"
+
msgid "Vulnerability|False positive detected"
msgstr "检测到误报"
msgid "Vulnerability|File"
msgstr "文件"
+msgid "Vulnerability|GitLab Security Report"
+msgstr "GitLab 安全报告"
+
msgid "Vulnerability|Identifier"
msgstr "标识"
@@ -38616,6 +39288,9 @@ msgstr "标识"
msgid "Vulnerability|Image"
msgstr "é•œåƒ"
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr "关于如何å‘现æ¼æ´žåŠå…¶å¯¹ç³»ç»Ÿçš„å½±å“çš„ä¿¡æ¯ã€‚"
+
msgid "Vulnerability|Links"
msgstr "链接"
@@ -38640,6 +39315,15 @@ msgstr "请求/å“应"
msgid "Vulnerability|Scanner Provider"
msgstr "扫æ工具æ供者"
+msgid "Vulnerability|Security Audit"
+msgstr "安全审计"
+
+msgid "Vulnerability|Select a severity"
+msgstr "选择严é‡ç¨‹åº¦"
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr "æ ¹æ®æ‚¨å¯ä»¥èŽ·å¾—çš„ä¿¡æ¯è®¾ç½®æ¼æ´žå‘现的状æ€ã€‚"
+
msgid "Vulnerability|Severity"
msgstr "严é‡çº§åˆ«"
@@ -38728,7 +39412,7 @@ msgid "We heard back from your device. You have been authenticated."
msgstr "我们收到了您设备的å“应。您已通过身份验è¯ã€‚"
msgid "We invite you to %{featureLinkStart}request a feature%{featureLinkEnd}, %{bugLinkStart}report a bug%{bugLinkEnd} or %{feedbackLinkStart}share feedback%{feedbackLinkEnd}"
-msgstr ""
+msgstr "我们邀请您加入 %{featureLinkStart}请求功能%{featureLinkEnd}, %{bugLinkStart}报告错误%{bugLinkEnd} 或 %{feedbackLinkStart}分享å馈%{feedbackLinkEnd}"
msgid "We recommend cloud-based mobile authenticator apps such as Authy, Duo Mobile, and LastPass. They can restore access if you lose your hardware device."
msgstr "我们推è基于云端的移动身份验è¯å™¨åº”用,例如Authyã€Duo Mobileå’ŒLastPas。如果您丢失了硬件设备,他们å¯ä»¥æ¢å¤è®¿é—®ã€‚"
@@ -38763,6 +39447,9 @@ msgstr "我们将ä¸æ–­éªŒè¯æ‚¨çš„æµæ°´çº¿é…置。验è¯ç»“果将显示在此
msgid "We'll use this to help surface the right features and information to you."
msgstr "我们将使用它æ¥å¸®åŠ©å‘您展示正确的功能和信æ¯ã€‚"
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr "未å‘现安全æ¼æ´ž"
@@ -38850,6 +39537,12 @@ msgstr "部署事件"
msgid "Webhooks|Enable SSL verification"
msgstr "å¯ç”¨SSL验è¯"
+msgid "Webhooks|Failed to connect"
+msgstr "连接失败"
+
+msgid "Webhooks|Fails to connect"
+msgstr "连接失败"
+
msgid "Webhooks|Feature flag events"
msgstr "功能标志事件"
@@ -38886,6 +39579,15 @@ msgstr "å­ç¾¤ç»„事件"
msgid "Webhooks|Tag push events"
msgstr "标签推é€äº‹ä»¶"
+msgid "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."
+msgstr "Webhook %{help_link_start}连接失败%{help_link_end},将在 %{retry_time} 内é‡è¯•ã€‚è‹¥è¦é‡æ–°å¯ç”¨ï¼Œè¯·æ£€æŸ¥ %{strong_start}最近事件%{strong_end} 获å–错误详情,然åŽåœ¨ä¸‹æ–¹æµ‹è¯•æ‚¨çš„设置。"
+
+msgid "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."
+msgstr "Webhook 连接失败,已ç¦ç”¨ã€‚è¦é‡æ–°å¯ç”¨å®ƒï¼Œè¯·æ£€æŸ¥ %{strong_start}最近的事件%{strong_end} 以获å–错误详细信æ¯ï¼Œç„¶åŽåœ¨ä¸‹é¢æµ‹è¯•æ‚¨çš„设置。"
+
+msgid "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."
+msgstr "Webhook æ¯åˆ†é’Ÿå·²è¢«è§¦å‘超过 %{limit} 次,现在已被ç¦ç”¨ã€‚è‹¥è¦é‡æ–°å¯ç”¨æ­¤ Webhook,请修å¤åœ¨ %{strong_start}最近事件%{strong_end} 中显示的问题,然åŽé‡æ–°æµ‹è¯•æ‚¨çš„设置。如果您需è¦å¸®åŠ©é‡æ–°å¯ç”¨æ‚¨çš„ Webhook,%{support_link_start}请è”系技术支æŒ%{support_link_end}。"
+
msgid "Webhooks|Trigger"
msgstr "触å‘æ¥æº"
@@ -38943,6 +39645,15 @@ msgstr "如有必è¦ï¼ŒURL 必须进行百分比编ç ã€‚"
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr "使用此令牌æ¥éªŒè¯æ”¶åˆ°çš„有效负载。它与 X-Gitlab-Token HTTP 标头中的请求一起å‘é€ã€‚"
+msgid "Webhooks|Webhook failed to connect"
+msgstr "Webhook 连接失败"
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr "Webhook 连接失败"
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr "Webhook 被自动ç¦ç”¨"
+
msgid "Webhooks|Wiki page events"
msgstr "Wiki页é¢äº‹ä»¶"
@@ -38979,6 +39690,9 @@ msgstr "欢迎使用 GitLab,%{br_tag}%{name}ï¼"
msgid "Welcome, %{name}!"
msgstr "欢迎, %{name}ï¼"
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr "什么是群组审计事件?"
@@ -38988,9 +39702,6 @@ msgstr "什么是实例审计事件?"
msgid "What are project audit events?"
msgstr "什么是项目审计事件?"
-msgid "What are shared runner pipeline minutes?"
-msgstr "什么是共享Runneræµæ°´çº¿åˆ†é’Ÿï¼Ÿ"
-
msgid "What are you searching for?"
msgstr "您è¦æœç´¢ä»€ä¹ˆï¼Ÿ"
@@ -39034,7 +39745,7 @@ msgid "When a runner is locked, it cannot be assigned to other projects"
msgstr "当Runner被é”定时,ä¸èƒ½å°†å…¶åˆ†é…给其他项目"
msgid "When enabled, SSH keys with no expiry date or an invalid expiration date are no longer accepted. Leave blank for no limit."
-msgstr ""
+msgstr "如果å¯ç”¨ï¼Œåˆ™ä¸å†æŽ¥å—无过期日期或无效过期日期的 SSH 密钥。留空为无é™åˆ¶ã€‚"
msgid "When enabled, existing personal access tokens may be revoked. Leave blank for no limit."
msgstr "å¯ç”¨åŽï¼ŒçŽ°æœ‰çš„个人访问令牌å¯èƒ½ä¼šè¢«æ’¤é”€ã€‚留空表示没有é™åˆ¶ã€‚"
@@ -39049,7 +39760,7 @@ msgid "When merge requests and commits in the default branch close, any issues t
msgstr "当默认分支中的åˆå¹¶è¯·æ±‚å’Œæ交关闭时,它们引用的任何议题也会关闭。"
msgid "When paused, GitLab still tracks the changes. This is useful for cluster/index migrations."
-msgstr ""
+msgstr "æš‚åœæ—¶ï¼ŒGitLab ä»ä¼šè·Ÿè¸ªæ›´æ”¹ï¼Œè¿™å¯¹äºŽé›†ç¾¤/索引è¿ç§»å¾ˆæœ‰ç”¨ã€‚"
msgid "When this merge request is accepted"
msgid_plural "When these merge requests are accepted"
@@ -39221,10 +39932,10 @@ msgid "WikiPage|Create page"
msgstr "创建页é¢"
msgid "WikiPage|Edit rich text"
-msgstr ""
+msgstr "编辑富文本"
msgid "WikiPage|Edit source"
-msgstr ""
+msgstr "编辑æ¥æº"
msgid "WikiPage|Format"
msgstr "æ ¼å¼"
@@ -39236,7 +39947,7 @@ msgid "WikiPage|Keep editing"
msgstr "继续编辑"
msgid "WikiPage|Learn more."
-msgstr ""
+msgstr "了解更多。"
msgid "WikiPage|Page title"
msgstr "页é¢æ ‡é¢˜"
@@ -39350,7 +40061,7 @@ msgid "Work in progress Limit"
msgstr "“进行中â€é™åˆ¶"
msgid "Work in progress- click here to find out more"
-msgstr ""
+msgstr "正在进行中 - å•å‡»æ­¤å¤„了解更多信æ¯"
msgid "WorkItem|Work Items"
msgstr "工作事项"
@@ -39626,7 +40337,7 @@ msgid "You can only %{action} files when you are on a branch"
msgstr "当处于分支时,您åªèƒ½ %{action} 文件"
msgid "You can only add up to %{max_contacts} contacts at one time"
-msgstr ""
+msgstr "您一次最多åªèƒ½æ·»åŠ  %{max_contacts} 个è”系人"
msgid "You can only edit files when you are on a branch"
msgstr "åªèƒ½åœ¨åˆ†æ”¯ä¸Šç¼–辑文件"
@@ -39665,7 +40376,7 @@ msgid "You cannot access the raw file. Please wait a minute."
msgstr "您ä¸èƒ½è®¿é—®åŽŸå§‹æ–‡ä»¶ã€‚请ç¨å€™ã€‚"
msgid "You cannot combine replace_ids with add_ids or remove_ids"
-msgstr ""
+msgstr "您ä¸èƒ½å°† replace_ids 与 add_ids 或 remove_ids 结åˆä½¿ç”¨"
msgid "You cannot impersonate a blocked user"
msgstr "您无法使用被ç¦ç”¨ç”¨æˆ·çš„身份"
@@ -39698,7 +40409,7 @@ msgid "You could not create a new trigger."
msgstr "您无法创建新的触å‘器。"
msgid "You do not have any Google Cloud projects. Please create a Google Cloud project and then reload this page."
-msgstr ""
+msgstr "您没有任何 Google Cloud 项目。请创建一个 Google Cloud 项目,然åŽé‡æ–°åŠ è½½æ­¤é¡µé¢ã€‚"
msgid "You do not have any subscriptions yet"
msgstr "您当å‰å°šæœªè®¢é˜…任何计划"
@@ -39707,7 +40418,7 @@ msgid "You do not have permission to access dora metrics."
msgstr "您无æƒè®¿é—® dora 指标。"
msgid "You do not have permission to approve a member"
-msgstr ""
+msgstr "您没有æƒé™æ‰¹å‡†æˆå‘˜"
msgid "You do not have permission to leave this %{namespaceType}."
msgstr "您没有æƒé™é€€å‡º%{namespaceType}。"
@@ -39762,7 +40473,7 @@ msgstr "您没有访问此群组价值æµåˆ†æžçš„æƒé™"
msgid "You have %{pendingMembersCount} pending member that needs approval."
msgid_plural "You have %{pendingMembersCount} pending members that need approval."
-msgstr[0] ""
+msgstr[0] "您有 %{pendingMembersCount} 个待处ç†æˆå‘˜éœ€è¦æ‰¹å‡†ã€‚"
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr "你已被授予 %{access_level} 访问 %{source_link} %{source_type} çš„æƒé™ã€‚"
@@ -39813,7 +40524,7 @@ msgid "You have insufficient permissions to remove this HTTP integration"
msgstr "您没有足够的æƒé™åˆ é™¤æ­¤HTTP集æˆ"
msgid "You have insufficient permissions to set customer relations contacts for this issue"
-msgstr ""
+msgstr "您没有足够的æƒé™ä¸ºæ­¤è®®é¢˜è®¾ç½®å®¢æˆ·å…³ç³»è”系人"
msgid "You have insufficient permissions to update an on-call schedule for this project"
msgstr "您没有足够的æƒé™æ¥æ›´æ–°æ­¤é¡¹ç›®çš„on-call计划"
@@ -39824,6 +40535,12 @@ msgstr "您没有足够的æƒé™æ¥æ›´æ–°æ­¤HTTP集æˆ"
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."
+msgstr "您的活跃用户数超过了您的许å¯è¯æ‰€å…许的数é‡ã€‚在 %{date} 之å‰å¿…须调节您的订阅。è¦å®Œæˆæ­¤è¿‡ç¨‹ï¼Œè¯·å¯¼å‡ºæ‚¨çš„许å¯è¯ä½¿ç”¨æ–‡ä»¶å¹¶å°†å…¶é€šè¿‡ç”µå­é‚®ä»¶å‘é€è‡³ %{renewal_service_email}。新的许å¯è¯å°†é€šè¿‡ç”µå­é‚®ä»¶å‘é€åˆ° %{customers_dot} 注册的电å­é‚®ä»¶åœ°å€ã€‚您å¯ä»¥å°†æ­¤è®¸å¯è¯ä¸Šä¼ åˆ°æ‚¨çš„实例。"
+
+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."
+msgstr "您的活跃用户数超过了您的许å¯è¯æ‰€å…许的数é‡ï¼Œå¿…须调节您的订阅。è¦å®Œæˆæ­¤è¿‡ç¨‹ï¼Œè¯·å¯¼å‡ºæ‚¨çš„许å¯è¯ä½¿ç”¨æ–‡ä»¶å¹¶å°†å…¶é€šè¿‡ç”µå­é‚®ä»¶å‘é€è‡³ %{renewal_service_email}。新的许å¯è¯å°†é€šè¿‡ç”µå­é‚®ä»¶å‘é€åˆ° %{customers_dot} 注册的电å­é‚®ä»¶åœ°å€ã€‚您å¯ä»¥å°†æ­¤è®¸å¯è¯ä¸Šä¼ åˆ°æ‚¨çš„实例。"
+
msgid "You have no permissions"
msgstr "没有æƒé™"
@@ -40013,6 +40730,12 @@ msgstr "您的%{group}æˆå‘˜èµ„格将在%{days}天内到期。"
msgid "Your %{host} account was signed in to from a new location"
msgstr "您在%{host}上的å¸æˆ·å·²ä»Žä¸€ä¸ªæ–°çš„ä½ç½®ç™»å½•"
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr "您的 %{plan} 订阅已于 %{expiry_date} 到期"
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+msgstr "您的 %{plan} 订阅于 %{expiry_date} 到期"
+
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 "您的%{strong}%{plan_name}%{strong_close}订阅将于%{strong}%{expires_on}%{strong_close}到期。此åŽï¼Œæ‚¨å°†æ— æ³•åˆ›å»ºè®®é¢˜æˆ–åˆå¹¶è¯·æ±‚,åŒæ—¶ä¹Ÿæ— æ³•è®¿é—®å…¶ä»–众多功能。"
@@ -40035,7 +40758,7 @@ msgid "Your CSV import for project"
msgstr "您的项目CSV导入"
msgid "Your DevOps Reports give an overview of how you are using GitLab from a feature perspective. Use them to view how you compare with other organizations, and how your teams compare against each other."
-msgstr ""
+msgstr "您的 DevOps 报告从功能角度概述了您如何使用 GitLab。使用它们æ¥æŸ¥çœ‹æ‚¨ä¸Žå…¶ä»–组织的比较情况,以åŠæ‚¨çš„团队之间的比较情况。"
msgid "Your GPG keys (%{count})"
msgstr "您的GPG密钥 (%{count})"
@@ -40101,10 +40824,10 @@ msgid "Your account has been deactivated. You will not be able to: "
msgstr "您的账å·å·²è¢«åœç”¨ã€‚您将无法: "
msgid "Your account is authenticated with SSO or SAML. To %{push_pull_link_start}push and pull%{link_end} over %{protocol} with Git using this account, you must %{set_password_link_start}set a password%{link_end} or %{set_up_pat_link_start}set up a Personal Access Token%{link_end} to use instead of a password. For more information, see %{clone_with_https_link_start}Clone with HTTPS%{link_end}."
-msgstr ""
+msgstr "您的å¸æˆ·å·²é€šè¿‡ SSO 或 SAML 进行身份验è¯ã€‚ è¦ä½¿ç”¨æ­¤å¸æˆ·æ¥ %{push_pull_link_start}推é€å’Œæ‹‰å–%{link_end} çš„ %{protocol} ,您必须设置 %{set_password_link_start}密ç %{link_end} 或 %{set_up_pat_link_start}设置个人访问令牌%{link_end} 以代替密ç ã€‚ 欲了解更多信æ¯ï¼Œè¯·è®¿é—® %{clone_with_https_link_start}使用 HTTPS 克隆%{link_end}。"
msgid "Your account is authenticated with SSO or SAML. To %{push_pull_link_start}push and pull%{link_end} over %{protocol} with Git using this account, you must %{set_up_pat_link_start}set up a Personal Access Token%{link_end} to use instead of a password. For more information, see %{clone_with_https_link_start}Clone with HTTPS%{link_end}."
-msgstr ""
+msgstr "您的å¸æˆ·å·²é€šè¿‡ SSO 或 SAML 进行身份验è¯ã€‚è¦ä½¿ç”¨æ­¤å¸æˆ·æ¥ %{push_pull_link_start}推é€å’Œæ‹‰å–%{link_end} 超过 %{protocol} %{set_up_pat_link_start}设置个人访问令牌%{link_end} 以代替密ç ä½¿ç”¨ã€‚有关详细信æ¯ï¼Œè¯·å‚阅 %{clone_with_https_link_start}使用 HTTPS 进行克隆%{link_end}。"
msgid "Your account is locked."
msgstr "您的å¸å·å·²è¢«é”定。"
@@ -40299,11 +41022,14 @@ msgid "Your sign-in page is %{url}."
msgstr "您的登录页é¢ä¸º%{url}。"
msgid "Your snippets"
-msgstr ""
+msgstr "您的代ç ç‰‡æ®µ"
msgid "Your subscription expired!"
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."
+msgstr "您的订阅现在已过期。若è¦æ›´æ–°ï¼Œè¯·å°†æ‚¨çš„许å¯è¯ä½¿ç”¨æ–‡ä»¶å¯¼å‡ºå¹¶å‘é€ç”µå­é‚®ä»¶è‡³ %{renewal_service_email}。新的许å¯è¯å°†å‘é€ç”µå­é‚®ä»¶åˆ°åœ¨ %{customers_dot} 注册的电å­é‚®ä»¶åœ°å€ã€‚ 您å¯ä»¥ä¸Šä¼ æ­¤è®¸å¯è¯åˆ°æ‚¨çš„实例。è¦ä½¿ç”¨æ ‡å‡†ç‰ˆï¼Œè¯·åˆ é™¤æ‚¨å½“å‰çš„许å¯è¯ã€‚"
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] "您的订阅将在 %{remaining_days} 天åŽåˆ°æœŸã€‚"
@@ -40327,7 +41053,7 @@ msgid "ZentaoIntegration|Base URL of the ZenTao instance."
msgstr "禅é“实例的基础 URL。"
msgid "ZentaoIntegration|Before you enable this integration, you must configure ZenTao. For more details, read the %{link_start}ZenTao integration documentation%{link_end}."
-msgstr ""
+msgstr "在您å¯ç”¨æ­¤é›†æˆä¹‹å‰ï¼Œæ‚¨å¿…é¡»é…置禅é“。欲了解更多详情,请访问 %{link_start}Zentao 集æˆæ–‡æ¡£%{link_end}。"
msgid "ZentaoIntegration|Enter new ZenTao API token"
msgstr "è¾“å…¥æ–°çš„ç¦…é“ API 令牌"
@@ -40488,7 +41214,7 @@ msgid "can't be nil"
msgstr "ä¸èƒ½ä¸º nil"
msgid "can't be solely blank"
-msgstr ""
+msgstr "ä¸èƒ½å®Œå…¨ä¸ºç©º"
msgid "can't be the same as the source project"
msgstr "ä¸èƒ½å’Œæºé¡¹ç›®ç›¸åŒ"
@@ -40541,6 +41267,9 @@ msgstr "本身ä¸èƒ½è¢«é˜»å¡ž"
msgid "cannot merge"
msgstr "无法åˆå¹¶"
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr "%{danger_start}%{degradedNum} é™ä½Ž%{danger_end}ã€%{same_start}%{sameNum} 相åŒ%{same_end} å’Œ %{success_start}%{improvedNum} 改善%{success_end}"
+
msgid "ciReport|%{degradedNum} degraded"
msgstr "å·²é™ä½Ž%{degradedNum}"
@@ -40571,8 +41300,8 @@ msgstr "%{linkStartTag}了解更多关于密ç æ£€æµ‹çš„ä¿¡æ¯%{linkEndTag}"
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr "%{linkStartTag}了解有关代ç è´¨é‡æŠ¥å‘Šçš„更多信æ¯%{linkEndTag}"
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
-msgstr "%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} 于 %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
+msgstr "%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} 于 %{path}"
msgid "ciReport|%{remainingPackagesCount} more"
msgstr "还有%{remainingPackagesCount} 个"
@@ -40619,9 +41348,9 @@ msgstr "正在解æžæµè§ˆå™¨æ€§èƒ½æµ‹è¯•æŒ‡æ ‡ç»“æžœ"
msgid "ciReport|Browser performance test metrics: "
msgstr "æµè§ˆå™¨æ€§èƒ½æµ‹è¯•æŒ‡æ ‡: "
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
-msgstr[0] "æµè§ˆå™¨æ€§èƒ½æµ‹è¯•æŒ‡æ ‡ï¼š%{strongStart}%{changesFound}%{strongEnd} 个更改"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
+msgstr[0] "æµè§ˆå™¨æ€§èƒ½æµ‹è¯•æŒ‡æ ‡ï¼š%{strong_start}%{changesFound}%{strong_end} 个更改"
msgid "ciReport|Browser performance test metrics: No changes"
msgstr "æµè§ˆå™¨æ€§èƒ½æµ‹è¯•æŒ‡æ ‡ï¼šæ— å˜åŒ–"
@@ -40693,7 +41422,7 @@ msgid "ciReport|Failed to load %{reportName} report"
msgstr "无法加载 %{reportName} 报告"
msgid "ciReport|Failed to load Code Quality report"
-msgstr ""
+msgstr "加载代ç è´¨é‡æŠ¥å‘Šå¤±è´¥"
msgid "ciReport|Fixed"
msgstr "已修å¤"
@@ -40705,7 +41434,7 @@ msgid "ciReport|Found %{issuesWithCount}"
msgstr "找到%{issuesWithCount}"
msgid "ciReport|IaC Scanning"
-msgstr ""
+msgstr "IaC 扫æ"
msgid "ciReport|Investigate this vulnerability by creating an issue"
msgstr "通过创建议题æ¥è°ƒæŸ¥æ­¤æ¼æ´ž"
@@ -40713,9 +41442,9 @@ msgstr "通过创建议题æ¥è°ƒæŸ¥æ­¤æ¼æ´ž"
msgid "ciReport|Load Performance"
msgstr "负载性能"
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
-msgstr[0] "负载性能测试指标检测到 %{strongStart}%{changesFound}%{strongEnd} 个å˜åŒ–"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
+msgstr[0] "负载性能测试指标检测到 %{strong_start}%{changesFound}%{strong_end} 个更改"
msgid "ciReport|Load performance test metrics results are being parsed"
msgstr "正在解æžæ€§èƒ½æµ‹è¯•æŒ‡æ ‡ç»“æžœ"
@@ -40730,7 +41459,7 @@ msgid "ciReport|Loading %{reportName} report"
msgstr "载入%{reportName} 报告"
msgid "ciReport|Loading Code Quality report"
-msgstr ""
+msgstr "加载代ç è´¨é‡æŠ¥å‘Š"
msgid "ciReport|Manage licenses"
msgstr "管ç†è®¸å¯è¯"
@@ -40769,7 +41498,7 @@ msgid "ciReport|Security scanning failed loading any results"
msgstr "安全扫æ无法加载任何结果"
msgid "ciReport|Showing %{fetchedItems} of %{totalItems} items"
-msgstr ""
+msgstr "显示 %{fetchedItems} 项,共 %{totalItems}项"
msgid "ciReport|Solution"
msgstr "解决方案"
@@ -40874,6 +41603,9 @@ msgstr "æ交 %{commit_id}"
msgid "committed"
msgstr "å·²æ交"
+msgid "compliance violation has already been recorded"
+msgstr "è¿è§„行为已被记录"
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr "container_nameåªèƒ½åŒ…å«å°å†™å­—æ¯ï¼Œæ•°å­—,'-'å’Œ'.',并且必须以字æ¯å’Œæ•°å­—字符开头和结尾"
@@ -41312,9 +42044,6 @@ msgstr "metric_id必须是整个项目唯一的"
msgid "missing"
msgstr "丢失"
-msgid "more information"
-msgstr "更多信æ¯"
-
msgid "most recent deployment"
msgstr "最近的部署"
@@ -41322,10 +42051,10 @@ msgid "mrWidgetCommitsAdded|1 merge commit"
msgstr "1个åˆå¹¶æ交"
msgid "mrWidgetCommitsAdded|Adds %{commitCount} and %{mergeCommitCount} to %{targetBranch}%{squashedCommits}."
-msgstr ""
+msgstr "将 %{commitCount} 和 %{mergeCommitCount} 添加到 %{targetBranch}%{squashedCommits}。"
msgid "mrWidgetCommitsAdded|Adds %{commitCount} to %{targetBranch}."
-msgstr ""
+msgstr "将 %{commitCount} 添加到 %{targetBranch}。"
msgid "mrWidgetNothingToMerge|This merge request contains no changes."
msgstr "æ­¤åˆå¹¶è¯·æ±‚ä¸åŒ…å«ä»»ä½•æ›´æ”¹ã€‚"
@@ -41337,7 +42066,7 @@ msgid "mrWidget| Please restore it or use a different %{missingBranchName} branc
msgstr "请æ¢å¤æ­¤åˆ†æ”¯æˆ–使用其他的 %{missingBranchName} 分支"
msgid "mrWidget|%{boldHeaderStart}Looks like there's no pipeline here.%{boldHeaderEnd}"
-msgstr ""
+msgstr "%{boldHeaderStart}此处没有æµæ°´çº¿ã€‚%{boldHeaderEnd}"
msgid "mrWidget|%{linkStart}Set up now%{linkEnd} to analyze your source code for known security vulnerabilities."
msgstr "mrWidget|%{linkStart}现在设置%{linkEnd} æ¥åˆ†æžæ‚¨çš„æºä»£ç ä¸­å·²çŸ¥çš„安全æ¼æ´žã€‚"
@@ -41431,7 +42160,7 @@ msgid "mrWidget|Delete source branch"
msgstr "删除æºåˆ†æ”¯"
msgid "mrWidget|Deletes the source branch"
-msgstr ""
+msgstr "删除æºåˆ†æ”¯"
msgid "mrWidget|Deployment statistics are not available currently"
msgstr "部署统计信æ¯å½“å‰ä¸å¯ç”¨"
@@ -41443,7 +42172,7 @@ msgid "mrWidget|Dismiss"
msgstr "关闭"
msgid "mrWidget|Does not delete the source branch"
-msgstr ""
+msgstr "ä¸åˆ é™¤æºåˆ†æ”¯"
msgid "mrWidget|Email patches"
msgstr "通过电å­é‚®ä»¶å‘出补ä¸"
@@ -41452,7 +42181,7 @@ msgid "mrWidget|Failed to load deployment statistics"
msgstr "无法加载部署统计信æ¯"
msgid "mrWidget|GitLab %{linkStart}CI/CD can automatically build, test, and deploy your application.%{linkEnd} It only takes a few minutes to get started, and we can help you create a pipeline configuration file."
-msgstr ""
+msgstr "GitLab %{linkStart}CI/CD å¯ä»¥è‡ªåŠ¨æž„建ã€æµ‹è¯•å’Œéƒ¨ç½²æ‚¨çš„应用程åºã€‚%{linkEnd} åªéœ€å‡ åˆ†é’Ÿå³å¯ä¸Šæ‰‹ï¼Œæˆ‘们å¯ä»¥å¸®åŠ©æ‚¨åˆ›å»ºæµæ°´çº¿é…置文件。"
msgid "mrWidget|Hide %{widget} details"
msgstr "éšè— %{widget} 的详细信æ¯"
@@ -41489,19 +42218,19 @@ msgid "mrWidget|Merge blocked: all threads must be resolved."
msgstr "åˆå¹¶è¢«é˜»æ­¢ï¼šå¿…须解决所有主题。"
msgid "mrWidget|Merge blocked: denied licenses must be removed."
-msgstr ""
+msgstr "åˆå¹¶è¢«é˜»æ­¢ï¼šå¿…须删除被拒ç»çš„许å¯è¯ã€‚"
msgid "mrWidget|Merge blocked: fast-forward merge is not possible. To merge this request, first rebase locally."
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."
-msgstr ""
+msgstr "åˆå¹¶è¢«é˜»æ­¢ï¼šå¿…须批准此åˆå¹¶è¯·æ±‚。"
msgid "mrWidget|Merge failed."
msgstr "åˆå¹¶å¤±è´¥ã€‚"
@@ -41510,13 +42239,13 @@ 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 "åˆå¹¶ä¸­ï¼æ­£åœ¨å‘é€æ›´æ”¹â€¦"
@@ -41531,13 +42260,13 @@ msgid "mrWidget|Merging! Everything's good…"
msgstr "正在åˆå¹¶ï¼ä¸€åˆ‡éƒ½å¾ˆå¥½â€¦"
msgid "mrWidget|Merging! Lift-off in 5… 4… 3…"
-msgstr ""
+msgstr "正在åˆå¹¶ï¼"
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 "åˆå¹¶ä¸­ï¼è¯·ç¨åŽâ€¦"
@@ -41630,19 +42359,19 @@ msgid "mrWidget|To approve this merge request, please enter your password. This
msgstr "è¦æ‰¹å‡†æ­¤åˆå¹¶è¯·æ±‚,请输入您的密ç ã€‚此项目需è¦æ‰€æœ‰æ‰¹å‡†æ‰èƒ½è®¤è¯ã€‚"
msgid "mrWidget|To change these default messages, edit the templates for both the merge and squash commit messages. %{linkStart}Learn more.%{linkEnd}"
-msgstr ""
+msgstr "è¦æ›´æ”¹æ­¤é»˜è®¤æ¶ˆæ¯ï¼Œè¯·ç¼–辑压缩和åˆå¹¶æ交消æ¯çš„模æ¿ã€‚%{linkStart}了解更多信æ¯ã€‚%{linkEnd}"
msgid "mrWidget|To change this default message, edit the template for merge commit messages. %{linkStart}Learn more.%{linkEnd}"
-msgstr ""
+msgstr "è¦æ›´æ”¹æ­¤é»˜è®¤æ¶ˆæ¯ï¼Œè¯·ç¼–辑åˆå¹¶æ交消æ¯çš„模æ¿ã€‚ %{linkStart}了解更多信æ¯ã€‚%{linkEnd}"
msgid "mrWidget|To change this default message, edit the template for squash commit messages. %{linkStart}Learn more.%{linkEnd}"
-msgstr ""
+msgstr "è¦æ›´æ”¹æ­¤é»˜è®¤æ¶ˆæ¯ï¼Œè¯·ç¼–辑压缩æ交消æ¯çš„模æ¿ã€‚ %{linkStart}了解更多信æ¯ã€‚%{linkEnd}"
msgid "mrWidget|To merge, a Jira issue key must be mentioned in the title or description."
msgstr "è¦åˆå¹¶ï¼Œå¿…须在标题或æ述中æ到Jira议题的key。"
msgid "mrWidget|Users who can write to the source or target branches can resolve the conflicts."
-msgstr ""
+msgstr "å¯ä»¥å†™å…¥æºæˆ–目标分支的用户å¯ä»¥è§£å†³å†²çªã€‚"
msgid "mrWidget|What is a merge train?"
msgstr "什么是åˆå¹¶é˜Ÿåˆ—?"
@@ -41668,6 +42397,9 @@ msgstr "必须是根命å空间"
msgid "must be a valid IPv4 or IPv6 address"
msgstr "必须是有效的IPv4或IPv6地å€"
+msgid "must be a valid json schema"
+msgstr "必须是有效的 json schema"
+
msgid "must be after start"
msgstr "必须在开始之åŽ"
@@ -41767,9 +42499,6 @@ msgstr "å¼€å¯äºŽ%{timeAgo}"
msgid "or"
msgstr "或"
-msgid "originating vulnerability"
-msgstr "åˆå§‹æ¼æ´ž"
-
msgid "other card matches"
msgstr "其他å¡ç‰‡åŒ¹é…"
@@ -41806,16 +42535,16 @@ msgid "pipeline schedules documentation"
msgstr "æµæ°´çº¿è®¡åˆ’文件"
msgid "pipelineEditorWalkthrough|Let's do this!"
-msgstr ""
+msgstr "让我们这样åšï¼"
msgid "pipelineEditorWalkthrough|See how GitLab pipelines work"
-msgstr ""
+msgstr "了解 GitLab æµæ°´çº¿çš„工作原ç†"
msgid "pipelineEditorWalkthrough|This %{codeStart}.gitlab-ci.yml%{codeEnd} file creates a simple test pipeline."
-msgstr ""
+msgstr "这个 %{codeStart}.gitlab-ci.yml%{codeEnd} 文件创建了一个简å•çš„测试æµæ°´çº¿ã€‚"
msgid "pipelineEditorWalkthrough|Use the %{boldStart}commit changes%{boldEnd} button at the bottom of the page to run the pipeline."
-msgstr ""
+msgstr "使用页é¢åº•éƒ¨çš„ %{boldStart}æ交修改%{boldEnd} 按钮æ¥è¿è¡Œæµæ°´çº¿ã€‚"
msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr "pod_nameåªèƒ½åŒ…å«å°å†™å­—æ¯ï¼Œæ•°å­—,'-'å’Œ'.',并且必须以字æ¯å’Œæ•°å­—字符开头和结尾"
@@ -42019,7 +42748,7 @@ msgid "starts on %{timebox_start_date}"
msgstr "开始于%{timebox_start_date}"
msgid "structure is too large"
-msgstr ""
+msgstr "结构过大"
msgid "stuck"
msgstr "阻塞"
diff --git a/locale/zh_HK/gitlab.po b/locale/zh_HK/gitlab.po
index 502826a5b76..426e6cb5463 100644
--- a/locale/zh_HK/gitlab.po
+++ b/locale/zh_HK/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: zh-HK\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 19:00\n"
+"PO-Revision-Date: 2022-01-06 17:25\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -486,7 +486,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
-msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -760,6 +760,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr ""
@@ -947,6 +950,12 @@ msgstr ""
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr ""
@@ -1062,6 +1071,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr ""
@@ -1127,6 +1139,9 @@ msgstr ""
msgid ", or "
msgstr "或"
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1428,6 +1443,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1674,6 +1692,15 @@ msgstr ""
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr ""
@@ -1686,12 +1713,21 @@ msgstr ""
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1749,6 +1785,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr ""
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1773,6 +1839,9 @@ msgstr ""
msgid "Active Sessions"
msgstr ""
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "活動"
@@ -1878,7 +1947,7 @@ msgstr "新增表格"
msgid "Add a task list"
msgstr ""
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2304,6 +2373,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2580,7 +2658,7 @@ msgstr "刪除使用者"
msgid "AdminUsers|Delete user and contributions"
msgstr "刪除使用者åŠå…¶è²¢ç»"
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2865,6 +2943,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3255,6 +3336,9 @@ msgstr ""
msgid "All groups and projects"
msgstr ""
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr ""
@@ -3459,6 +3543,9 @@ msgstr ""
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr ""
@@ -3486,9 +3573,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr "é è¦½ blob 檔案時發生錯誤"
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3669,6 +3753,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3678,6 +3765,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr ""
@@ -3826,6 +3916,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4148,9 +4244,15 @@ msgstr[0] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4181,6 +4283,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4190,6 +4295,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4214,6 +4328,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4241,6 +4358,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4277,7 +4397,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4446,9 +4566,6 @@ msgstr ""
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4596,6 +4713,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr "分é…一些議題到這個里程碑。"
@@ -4991,9 +5111,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr "%{assigneeName} çš„é ­åƒ"
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5243,9 +5360,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5276,13 +5390,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5294,7 +5405,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5306,9 +5420,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5493,7 +5613,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5852,7 +5972,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5861,6 +5984,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -5900,6 +6026,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6603,7 +6732,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6863,9 +6992,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7076,6 +7202,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7094,9 +7223,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7250,12 +7385,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7268,6 +7418,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7283,9 +7439,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7331,12 +7493,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7412,6 +7583,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7430,12 +7604,25 @@ 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 ""
+msgid "ClusterAgents|There's no activity from the past day"
+msgid_plural "ClusterAgents|There's no activity from the past %d days"
+msgstr[0] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7445,6 +7632,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8631,6 +8821,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9050,6 +9249,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9138,6 +9340,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9369,12 +9574,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9405,9 +9616,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9747,9 +9955,6 @@ msgstr "建立新標籤"
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr "創建..."
-
msgid "Create or import your first project"
msgstr ""
@@ -9780,6 +9985,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9822,9 +10030,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9834,13 +10039,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10020,15 +10228,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10038,15 +10264,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10197,15 +10432,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -10887,6 +11113,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11166,6 +11395,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11199,15 +11431,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11337,6 +11563,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11361,7 +11590,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11370,6 +11599,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12164,15 +12396,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12312,6 +12544,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12447,8 +12682,8 @@ msgstr "編輯里程碑"
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
-msgstr "編輯 %{id} æµæ°´ç·šè¨ˆåŠƒ"
+msgid "Edit Pipeline Schedule"
+msgstr ""
msgid "Edit Release"
msgstr ""
@@ -12486,6 +12721,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13426,6 +13664,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13471,9 +13712,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13627,9 +13865,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13714,6 +13949,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -13898,9 +14136,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14093,7 +14328,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14798,9 +15033,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15131,6 +15363,9 @@ msgstr "從åˆä½µè«‹æ±‚çš„åˆä½µåˆ°éƒ¨ç½²è‡³ç”Ÿç”¢ç’°å¢ƒ"
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -15992,9 +16227,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16082,6 +16314,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16271,9 +16506,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16400,6 +16632,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16502,9 +16737,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16577,6 +16821,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16616,6 +16863,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16649,6 +16899,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16673,7 +16935,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16682,7 +16944,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16724,6 +16986,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16751,12 +17016,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -16871,6 +17142,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -16925,6 +17199,9 @@ 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 ""
+
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 ""
@@ -18827,6 +19104,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19076,9 +19356,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19181,9 +19458,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19295,9 +19569,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr "看æ¿"
@@ -19943,7 +20214,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20394,6 +20665,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21148,7 +21425,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -21904,10 +22181,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22006,6 +22283,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22623,6 +22903,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22825,6 +23108,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23038,6 +23354,9 @@ msgstr ""
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23261,6 +23580,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23679,6 +24001,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23691,7 +24016,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24094,6 +24419,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24112,12 +24443,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24157,12 +24494,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24187,18 +24533,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24208,9 +24569,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24368,6 +24726,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -24906,9 +25267,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25098,9 +25456,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25200,6 +25564,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25281,12 +25648,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25518,6 +25879,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25737,9 +26101,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26016,6 +26377,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26028,6 +26395,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26223,9 +26593,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26577,6 +26944,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26634,6 +27004,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26718,6 +27094,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27012,6 +27391,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27138,6 +27559,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27390,19 +27814,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27558,6 +27979,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr "專案"
@@ -27942,9 +28372,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27957,9 +28384,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -27984,9 +28408,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28068,6 +28489,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28113,9 +28537,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28158,6 +28588,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28173,6 +28606,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28401,6 +28837,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28585,9 +29027,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28630,6 +29069,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -28955,10 +29442,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29636,6 +30123,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29645,6 +30135,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -29839,9 +30335,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -29863,6 +30356,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -29914,19 +30413,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -29980,6 +30482,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30025,6 +30530,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30034,7 +30542,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30103,7 +30614,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30121,6 +30632,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30382,6 +30896,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30403,9 +30920,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30675,6 +31189,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30747,6 +31264,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -30801,6 +31321,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -30885,9 +31408,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31086,6 +31606,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31098,6 +31621,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31173,6 +31699,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31326,6 +31855,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31677,6 +32209,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -31833,6 +32371,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32529,6 +33070,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -32973,9 +33517,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33372,6 +33913,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -33807,6 +34354,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34073,9 +34638,23 @@ msgid "Terraform|%{number} Terraform report was generated in your pipelines"
msgid_plural "Terraform|%{number} Terraform reports were generated in your pipelines"
msgstr[0] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34106,6 +34685,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34118,6 +34700,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34154,12 +34739,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34442,6 +35036,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34563,9 +35160,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34575,9 +35169,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34650,7 +35241,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -34905,9 +35496,6 @@ msgstr "沒有å¯ä»¥é¡¯ç¤ºçš„è­°é¡Œ"
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35253,6 +35841,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35265,9 +35856,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35292,6 +35880,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35406,6 +35997,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35571,6 +36165,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36281,6 +36878,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36347,6 +36947,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36521,6 +37154,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36642,15 +37278,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36675,9 +37302,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37305,9 +37929,6 @@ msgstr "點擊上傳"
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38199,16 +38820,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38250,6 +38871,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38272,6 +38896,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38300,6 +38927,12 @@ msgstr ""
msgid "View group labels"
msgstr "查看群組標籤"
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38391,6 +39024,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38472,12 +39108,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38505,6 +39153,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38574,9 +39225,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38592,21 +39252,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38616,6 +39288,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38640,6 +39315,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38763,6 +39447,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -38850,6 +39537,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -38886,6 +39579,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -38943,6 +39645,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -38979,6 +39690,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -38988,9 +39702,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -39824,6 +40535,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40013,6 +40730,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40304,6 +41027,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40541,6 +41267,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40571,7 +41300,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40619,8 +41348,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgid "ciReport|Browser performance test metrics: No changes"
@@ -40713,8 +41442,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgid "ciReport|Load performance test metrics results are being parsed"
@@ -40874,6 +41603,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41312,9 +42044,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41668,6 +42397,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -41767,9 +42499,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/locale/zh_TW/gitlab.po b/locale/zh_TW/gitlab.po
index 8e2bcc9a252..b8ad0cdb67d 100644
--- a/locale/zh_TW/gitlab.po
+++ b/locale/zh_TW/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: zh-TW\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2021-12-06 18:56\n"
+"PO-Revision-Date: 2022-01-06 17:20\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -486,7 +486,7 @@ msgstr ""
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
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; %{default_branch_link_start}search on %{default_branch} instead%{default_branch_link_end}."
+msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
msgstr ""
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
@@ -760,6 +760,9 @@ msgstr ""
msgid "%{placeholder} is not a valid theme"
msgstr ""
+msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
@@ -947,6 +950,12 @@ msgstr "%{userName} 的大頭貼"
msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedule} in %{project}. "
msgstr ""
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
+msgstr ""
+
+msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
+msgstr ""
+
msgid "%{user_name} profile page"
msgstr "%{user_name} 的個人資料"
@@ -1062,6 +1071,9 @@ msgstr ""
msgid "(max size 15 MB)"
msgstr ""
+msgid "(optional)"
+msgstr ""
+
msgid "(removed)"
msgstr "(已刪除)"
@@ -1127,6 +1139,9 @@ msgstr ""
msgid ", or "
msgstr "ã€æˆ– "
+msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
+msgstr ""
+
msgid "- Available to run jobs."
msgstr ""
@@ -1428,6 +1443,9 @@ msgstr ""
msgid "A project’s repository name defines its URL (the one you use to access the project via a browser) and its place on the file disk where GitLab is installed. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "A quarterly reconciliation is due on %{date}"
+msgstr ""
+
msgid "A ready-to-go template for use with Android apps"
msgstr ""
@@ -1674,6 +1692,15 @@ msgstr "你確定嗎?目å‰æ­£åœ¨ä½¿ç”¨çš„所有 RSS 或日曆 URL 都將åœæ­
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr "你確定嗎?目å‰æ­£åœ¨ä½¿ç”¨çš„所有議題電å­éƒµä»¶ä½å€éƒ½å°‡åœæ­¢é‹ä½œã€‚"
+msgid "AccessTokens|Copy feed token"
+msgstr ""
+
+msgid "AccessTokens|Copy incoming email token"
+msgstr ""
+
+msgid "AccessTokens|Copy static object token"
+msgstr ""
+
msgid "AccessTokens|Created"
msgstr "已建立"
@@ -1686,12 +1713,21 @@ msgstr "傳入電å­éƒµä»¶æ¬Šæ–"
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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
+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 ""
+
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
@@ -1749,6 +1785,36 @@ msgstr ""
msgid "Account: %{account}"
msgstr "帳戶:%{account}"
+msgid "AccountValidation|Fix your pipelines by validating your account"
+msgstr ""
+
+msgid "AccountValidation|I'll bring my own runners"
+msgstr ""
+
+msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
+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 ""
+
+msgid "AccountValidation|Learn more."
+msgstr ""
+
+msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
+msgstr ""
+
+msgid "AccountValidation|Validate your account"
+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 ""
+
+msgid "AccountValidation|you may %{unsubscribe_link} at any time."
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -1773,6 +1839,9 @@ msgstr ""
msgid "Active Sessions"
msgstr "使用中的工作階段"
+msgid "Active chat names (%{count})"
+msgstr ""
+
msgid "Activity"
msgstr "å‹•æ…‹"
@@ -1878,7 +1947,7 @@ msgstr "加入表格"
msgid "Add a task list"
msgstr "加入作業列表"
-msgid "Add a title…"
+msgid "Add a title..."
msgstr ""
msgid "Add a to do"
@@ -2304,6 +2373,15 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "載入統計資料時發生錯誤。請å†è©¦ä¸€æ¬¡"
+msgid "AdminLabels|Define your default set of project labels"
+msgstr ""
+
+msgid "AdminLabels|Labels created here will be automatically added to new projects."
+msgstr ""
+
+msgid "AdminLabels|They can be used to categorize issues and merge requests."
+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 ""
@@ -2580,7 +2658,7 @@ msgstr "刪除使用者"
msgid "AdminUsers|Delete user and contributions"
msgstr "刪除使用者åŠç›¸é—œè²¢ç»"
-msgid "AdminUsers|Export permissions as CSV"
+msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
@@ -2865,6 +2943,9 @@ msgstr ""
msgid "After it expires, you can't use merge approvals, epics, or many security features."
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 ""
+
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3255,6 +3336,9 @@ msgstr ""
msgid "All groups and projects"
msgstr "所有群組和專案"
+msgid "All issues"
+msgstr ""
+
msgid "All issues for this milestone are closed."
msgstr "此里程碑的所有議題å‡å·²é—œé–‰ã€‚"
@@ -3459,6 +3543,9 @@ msgstr "發生錯誤"
msgid "An error in reporting in which a test result incorrectly indicates the presence of a vulnerability in a system when the vulnerability is not present."
msgstr ""
+msgid "An error occured while fetching the pipelines jobs."
+msgstr ""
+
msgid "An error occurred adding a draft to the thread."
msgstr "å‘話題加入è‰ç¨¿æ™‚發生錯誤。"
@@ -3486,9 +3573,6 @@ msgstr ""
msgid "An error occurred previewing the blob"
msgstr "é è¦½ blob 時發生錯誤"
-msgid "An error occurred when removing the label."
-msgstr ""
-
msgid "An error occurred when updating the title"
msgstr ""
@@ -3669,6 +3753,9 @@ msgstr ""
msgid "An error occurred while loading projects."
msgstr ""
+msgid "An error occurred while loading the Jobs tab."
+msgstr ""
+
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -3678,6 +3765,9 @@ msgstr ""
msgid "An error occurred while loading the access tokens form, please try again."
msgstr ""
+msgid "An error occurred while loading the blob controls."
+msgstr ""
+
msgid "An error occurred while loading the data. Please try again."
msgstr "載入資料時發生錯誤。請é‡è©¦ã€‚"
@@ -3826,6 +3916,12 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
+msgid "An incident has been resolved in %{project_path}."
+msgstr ""
+
+msgid "An incident has been triggered in %{project_path}."
+msgstr ""
+
msgid "An integer value is required for seconds"
msgstr ""
@@ -4148,9 +4244,15 @@ msgstr[0] ""
msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr ""
+msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
+msgstr ""
+
msgid "ApprovalRule|Add approvers"
msgstr ""
+msgid "ApprovalRule|Add required approvers to improve your code review process"
+msgstr ""
+
msgid "ApprovalRule|All scanners"
msgstr ""
@@ -4181,6 +4283,9 @@ msgstr ""
msgid "ApprovalRule|Approvers"
msgstr ""
+msgid "ApprovalRule|Assign approvers by area of expertise."
+msgstr ""
+
msgid "ApprovalRule|Confirmed"
msgstr ""
@@ -4190,6 +4295,15 @@ msgstr ""
msgid "ApprovalRule|Examples: QA, Security."
msgstr ""
+msgid "ApprovalRule|Increase your organization’s code quality."
+msgstr ""
+
+msgid "ApprovalRule|Learn more about merge request approval."
+msgstr ""
+
+msgid "ApprovalRule|Let GitLab designate eligible approvers based on the files changed."
+msgstr ""
+
msgid "ApprovalRule|Name"
msgstr ""
@@ -4214,6 +4328,9 @@ msgstr ""
msgid "ApprovalRule|Previously detected"
msgstr ""
+msgid "ApprovalRule|Reduce the overall time to merge."
+msgstr ""
+
msgid "ApprovalRule|Resolved"
msgstr ""
@@ -4241,6 +4358,9 @@ msgstr ""
msgid "ApprovalRule|Target branch"
msgstr ""
+msgid "ApprovalRule|Try it for free"
+msgstr ""
+
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr ""
@@ -4277,7 +4397,7 @@ msgstr ""
msgid "ApprovalSettings|This setting is configured at the instance level and can only be changed by an administrator."
msgstr ""
-msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed by an administrator or group owner."
+msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
msgstr ""
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
@@ -4446,9 +4566,6 @@ msgstr "您確定è¦ç«‹å³åˆä½µå—Žï¼Ÿ"
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
-msgid "Are you sure you want to regenerate the public key? You will have to update the public key on the remote server before mirroring will work again."
-msgstr ""
-
msgid "Are you sure you want to reindex?"
msgstr ""
@@ -4596,6 +4713,9 @@ msgstr ""
msgid "Assign reviewer(s)"
msgstr ""
+msgid "Assign severity"
+msgstr ""
+
msgid "Assign some issues to this milestone."
msgstr ""
@@ -4991,9 +5111,6 @@ msgstr ""
msgid "Avatar for %{assigneeName}"
msgstr ""
-msgid "Avatar for %{name}"
-msgstr ""
-
msgid "Avatar will be removed. Are you sure?"
msgstr ""
@@ -5243,9 +5360,6 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
-msgid "BillingPlan|Contact sales"
-msgstr ""
-
msgid "BillingPlan|Upgrade"
msgstr ""
@@ -5276,13 +5390,10 @@ msgstr ""
msgid "Billings|Shared runners cannot be enabled until a valid credit card is on file."
msgstr ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
+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 ""
-msgid "Billings|To use free pipeline minutes on shared runners, you’ll need to validate your account with a credit or debit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
-
-msgid "Billings|User successfully validated"
+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 ""
msgid "Billings|User validation required"
@@ -5294,7 +5405,10 @@ msgstr ""
msgid "Billings|Validate user account"
msgstr ""
-msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
+msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
+msgstr ""
+
+msgid "Billings|Your account has been validated"
msgstr ""
msgid "Billing|An email address is only visible for users with public emails."
@@ -5306,9 +5420,15 @@ msgstr ""
msgid "Billing|An error occurred while loading billable members list"
msgstr ""
+msgid "Billing|An error occurred while loading pending members list"
+msgstr ""
+
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
+msgid "Billing|Awaiting member signup"
+msgstr ""
+
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5493,7 +5613,7 @@ msgstr ""
msgid "Boards"
msgstr ""
-msgid "Boards and Board Lists"
+msgid "Boards and board lists"
msgstr ""
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
@@ -5852,7 +5972,10 @@ msgstr ""
msgid "Bulk update"
msgstr ""
-msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
+msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
+msgstr ""
+
+msgid "BulkImport|%{feature} (require v%{version})"
msgstr ""
msgid "BulkImport|Existing groups"
@@ -5861,6 +5984,9 @@ msgstr ""
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 ""
+
msgid "BulkImport|From source group"
msgstr ""
@@ -5900,6 +6026,9 @@ msgstr ""
msgid "BulkImport|No parent"
msgstr ""
+msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
+msgstr ""
+
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr ""
@@ -6603,7 +6732,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
-msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
+msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
@@ -6863,9 +6992,6 @@ msgstr ""
msgid "Choose file…"
msgstr ""
-msgid "Choose labels"
-msgstr ""
-
msgid "Choose specific groups or storage shards"
msgstr ""
@@ -7076,6 +7202,9 @@ msgstr ""
msgid "Clear due date"
msgstr ""
+msgid "Clear health status"
+msgstr ""
+
msgid "Clear recent searches"
msgstr ""
@@ -7094,9 +7223,15 @@ msgstr ""
msgid "Clear weight"
msgstr ""
+msgid "Cleared health status."
+msgstr ""
+
msgid "Cleared weight."
msgstr ""
+msgid "Clears health status."
+msgstr ""
+
msgid "Clears weight."
msgstr ""
@@ -7250,12 +7385,27 @@ msgstr ""
msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
msgstr ""
+msgid "ClusterAgents|%{name} successfully deleted"
+msgstr ""
+
msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
msgstr ""
+msgid "ClusterAgents|%{titleIcon}Connected"
+msgstr ""
+
+msgid "ClusterAgents|%{titleIcon}Not connected"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} created"
+msgstr ""
+
+msgid "ClusterAgents|%{tokenName} revoked"
+msgstr ""
+
msgid "ClusterAgents|Access tokens"
msgstr ""
@@ -7268,6 +7418,12 @@ msgstr ""
msgid "ClusterAgents|Agent"
msgstr ""
+msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
+msgstr ""
+
+msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
+msgstr ""
+
msgid "ClusterAgents|Agent might not be connected to GitLab"
msgstr ""
@@ -7283,9 +7439,15 @@ 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 ""
+
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 ""
+
msgid "ClusterAgents|Certificate"
msgstr ""
@@ -7331,12 +7493,21 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Delete"
+msgstr ""
+
+msgid "ClusterAgents|Delete agent"
+msgstr ""
+
msgid "ClusterAgents|Deprecated"
msgstr ""
msgid "ClusterAgents|Description"
msgstr ""
+msgid "ClusterAgents|Event occurred"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7412,6 +7583,9 @@ msgstr ""
msgid "ClusterAgents|Security"
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 ""
@@ -7430,12 +7604,25 @@ 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 ""
+msgid "ClusterAgents|There's no activity from the past day"
+msgid_plural "ClusterAgents|There's no activity from the past %d days"
+msgstr[0] ""
+
msgid "ClusterAgents|This agent has no tokens"
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}What's the agent's configuration file?%{linkEnd}"
msgstr ""
+msgid "ClusterAgents|Token created by %{userName}"
+msgstr ""
+
+msgid "ClusterAgents|Token revoked by %{userName}"
+msgstr ""
+
msgid "ClusterAgents|Unknown user"
msgstr ""
@@ -7445,6 +7632,9 @@ msgstr ""
msgid "ClusterAgents|View all %{number} clusters"
msgstr ""
+msgid "ClusterAgents|What is GitLab Agent activity?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
@@ -8631,6 +8821,15 @@ msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceReport|Approved by author"
+msgstr ""
+
+msgid "ComplianceReport|Approved by committer"
+msgstr ""
+
+msgid "ComplianceReport|Less than 2 approvers"
+msgstr ""
+
msgid "Component"
msgstr ""
@@ -9050,6 +9249,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9138,6 +9340,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -9369,12 +9574,18 @@ msgstr ""
msgid "Copy evidence SHA"
msgstr ""
+msgid "Copy failed. Please manually copy the value."
+msgstr ""
+
msgid "Copy file contents"
msgstr ""
msgid "Copy file path"
msgstr ""
+msgid "Copy issue URL to clipboard"
+msgstr ""
+
msgid "Copy key"
msgstr ""
@@ -9405,9 +9616,6 @@ msgstr ""
msgid "Copy this registration token."
msgstr ""
-msgid "Copy this value"
-msgstr ""
-
msgid "Copy to clipboard"
msgstr ""
@@ -9747,9 +9955,6 @@ msgstr ""
msgid "Create new project"
msgstr ""
-msgid "Create new..."
-msgstr ""
-
msgid "Create or import your first project"
msgstr ""
@@ -9780,6 +9985,9 @@ msgstr ""
msgid "Create user"
msgstr ""
+msgid "Create via merge request"
+msgstr ""
+
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -9822,9 +10030,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
-msgid "CreateValueStreamForm|Create Value Stream"
-msgstr ""
-
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
@@ -9834,13 +10039,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
+msgid "CreateValueStreamForm|Create value stream"
+msgstr ""
+
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
-msgid "CreateValueStreamForm|Edit Value Stream"
+msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
@@ -10020,15 +10228,33 @@ msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
+msgid "Crm|Contact has been added"
+msgstr ""
+
+msgid "Crm|Contact has been updated"
+msgstr ""
+
msgid "Crm|Create new contact"
msgstr ""
+msgid "Crm|Create organization"
+msgstr ""
+
msgid "Crm|Customer Relations Contacts"
msgstr ""
+msgid "Crm|Customer Relations Organizations"
+msgstr ""
+
+msgid "Crm|Default rate (optional)"
+msgstr ""
+
msgid "Crm|Description (optional)"
msgstr ""
+msgid "Crm|Edit contact"
+msgstr ""
+
msgid "Crm|Email"
msgstr ""
@@ -10038,15 +10264,24 @@ msgstr ""
msgid "Crm|Last name"
msgstr ""
+msgid "Crm|New Organization"
+msgstr ""
+
msgid "Crm|New contact"
msgstr ""
+msgid "Crm|New organization"
+msgstr ""
+
msgid "Crm|No contacts found"
msgstr ""
msgid "Crm|No organizations found"
msgstr ""
+msgid "Crm|Organization has been added"
+msgstr ""
+
msgid "Crm|Phone number (optional)"
msgstr ""
@@ -10197,15 +10432,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CustomizeHomepageBanner|Do you want to customize this page?"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|Go to preferences"
-msgstr ""
-
-msgid "CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under \"Homepage content\" in your preferences"
-msgstr ""
-
msgid "Cycle Time"
msgstr ""
@@ -10887,6 +11113,9 @@ msgstr ""
msgid "Date"
msgstr ""
+msgid "Date merged"
+msgstr ""
+
msgid "Date picker"
msgstr ""
@@ -11166,6 +11395,9 @@ msgstr ""
msgid "Delete variable"
msgstr ""
+msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
+msgstr ""
+
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -11199,15 +11431,9 @@ msgstr ""
msgid "Deleted"
msgstr ""
-msgid "Deleted Projects"
-msgstr ""
-
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
-msgid "Deleted projects"
-msgstr ""
-
msgid "Deleted projects cannot be restored!"
msgstr ""
@@ -11337,6 +11563,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}"
msgstr ""
+msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
+msgstr ""
+
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -11361,7 +11590,7 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
-msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
+msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|There are no images in the cache"
@@ -11370,6 +11599,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr ""
+msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
+msgstr ""
+
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
msgstr[0] ""
@@ -12164,15 +12396,15 @@ msgstr ""
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
msgstr ""
-msgid "Discover|Give feedback for this page"
-msgstr ""
-
msgid "Discover|Security capabilities, integrated into your development lifecycle"
msgstr ""
msgid "Discover|See the other features of the %{linkStart}ultimate plan%{linkEnd}"
msgstr ""
+msgid "Discover|Send feedback"
+msgstr ""
+
msgid "Discover|Start a free trial"
msgstr ""
@@ -12312,6 +12544,9 @@ msgstr ""
msgid "Download CSV"
msgstr ""
+msgid "Download PDF"
+msgstr ""
+
msgid "Download artifacts"
msgstr ""
@@ -12447,7 +12682,7 @@ msgstr ""
msgid "Edit Password"
msgstr ""
-msgid "Edit Pipeline Schedule %{id}"
+msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Release"
@@ -12486,6 +12721,9 @@ msgstr ""
msgid "Edit environment"
msgstr ""
+msgid "Edit epics"
+msgstr ""
+
msgid "Edit files in the editor and commit changes here"
msgstr ""
@@ -13426,6 +13664,9 @@ msgstr ""
msgid "Epics|Something went wrong while removing issue from epic."
msgstr ""
+msgid "Epics|Something went wrong while updating epics."
+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 ""
@@ -13471,9 +13712,6 @@ msgstr ""
msgid "Error creating the snippet"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr ""
-
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -13627,9 +13865,6 @@ msgstr ""
msgid "Error while loading the merge request. Please try again."
msgstr ""
-msgid "Error while loading the project data. Please try again."
-msgstr ""
-
msgid "Error while migrating %{upload_id}: %{error_message}"
msgstr ""
@@ -13714,6 +13949,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy:"
+msgstr ""
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -13898,9 +14136,6 @@ msgstr ""
msgid "Every year on %{day} at %{time} %{timezone}"
msgstr ""
-msgid "Everyone"
-msgstr ""
-
msgid "Everyone With Access"
msgstr ""
@@ -14093,7 +14328,7 @@ msgstr ""
msgid "Export requirements"
msgstr ""
-msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgid "Export this group with all related data."
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}"
@@ -14798,9 +15033,6 @@ msgstr ""
msgid "Filter by test cases that are currently open."
msgstr ""
-msgid "Filter by two-factor authentication"
-msgstr ""
-
msgid "Filter by user"
msgstr ""
@@ -15131,6 +15363,9 @@ msgstr ""
msgid "Full"
msgstr ""
+msgid "Full log"
+msgstr ""
+
msgid "Full name"
msgstr ""
@@ -15992,9 +16227,6 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
-msgid "GlobalSearch|Search or jump to..."
-msgstr ""
-
msgid "GlobalSearch|Search results are loading"
msgstr ""
@@ -16082,6 +16314,9 @@ msgstr ""
msgid "Go to next page"
msgstr ""
+msgid "Go to page %{page}"
+msgstr ""
+
msgid "Go to parent"
msgstr ""
@@ -16271,9 +16506,6 @@ msgstr ""
msgid "Group URL"
msgstr ""
-msgid "Group Wikis"
-msgstr ""
-
msgid "Group application: %{name}"
msgstr ""
@@ -16400,6 +16632,9 @@ msgstr ""
msgid "Group was successfully updated."
msgstr ""
+msgid "Group wikis"
+msgstr ""
+
msgid "Group: %{group_name}"
msgstr ""
@@ -16502,9 +16737,18 @@ msgstr ""
msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
+msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
+msgstr ""
+
+msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
+msgstr ""
+
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 ""
+
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -16577,6 +16821,9 @@ msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
+msgid "GroupSAML|Reset SCIM token"
+msgstr ""
+
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -16616,6 +16863,9 @@ msgstr ""
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
msgstr ""
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
+msgstr ""
+
msgid "GroupSAML|The case-sensitive group name that will be sent by the SAML identity provider."
msgstr ""
@@ -16649,6 +16899,18 @@ msgstr ""
msgid "GroupSAML|recommend persistent ID instead of email"
msgstr ""
+msgid "GroupSaml|Copy SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Copy SCIM token"
+msgstr ""
+
+msgid "GroupSaml|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSaml|Your SCIM token"
+msgstr ""
+
msgid "GroupSelect|No matching results"
msgstr ""
@@ -16673,7 +16935,7 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
-msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended side effects. %{learn_more_link_start}Learn more.%{learn_more_link_end}"
msgstr ""
msgid "GroupSettings|Cannot update the path because there are projects under this group that contain Docker images in their Container Registry. Please remove the images from your projects first and try again."
@@ -16682,7 +16944,7 @@ msgstr ""
msgid "GroupSettings|Change group URL"
msgstr ""
-msgid "GroupSettings|Changing group URL can have unintended side effects."
+msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
msgid "GroupSettings|Compliance frameworks"
@@ -16724,6 +16986,9 @@ msgstr ""
msgid "GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Parent Group"
+msgstr ""
+
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
@@ -16751,12 +17016,18 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
+msgid "GroupSettings|Search groups"
+msgstr ""
+
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
+msgid "GroupSettings|Select parent group"
+msgstr ""
+
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
@@ -16871,6 +17142,9 @@ msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
+msgid "GroupsNew|Ask your administrator to %{enable_link_start}enable%{enable_link_end} Group Migration."
+msgstr ""
+
msgid "GroupsNew|Assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -16925,6 +17199,9 @@ 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 ""
+
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 ""
@@ -18827,6 +19104,9 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid URL: %{url}"
+msgstr ""
+
msgid "Invalid container_name"
msgstr ""
@@ -19076,9 +19356,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
-msgid "InviteMember|Invite Member"
-msgstr ""
-
msgid "InviteMember|Invite Members (optional)"
msgstr ""
@@ -19181,9 +19458,6 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
-msgid "Is this GitLab trial for your company?"
-msgstr ""
-
msgid "Is using license seat:"
msgstr ""
@@ -19295,9 +19569,6 @@ msgstr ""
msgid "IssueAnalytics|Weight"
msgstr ""
-msgid "IssueBoards|An error occurred while setting notifications status. Please try again."
-msgstr ""
-
msgid "IssueBoards|Board"
msgstr ""
@@ -19943,7 +20214,7 @@ msgstr ""
msgid "Job|Download"
msgstr ""
-msgid "Job|Erase job log"
+msgid "Job|Erase job log and artifacts"
msgstr ""
msgid "Job|Job artifacts"
@@ -20394,6 +20665,12 @@ msgstr ""
msgid "Launch a ready-to-code development environment for your project."
msgstr ""
+msgid "Layout|Fixed"
+msgstr ""
+
+msgid "Layout|Fluid"
+msgstr ""
+
msgid "Lead Time"
msgstr ""
@@ -21148,7 +21425,7 @@ msgstr ""
msgid "ManualOrdering|Couldn't save the order of the issues"
msgstr ""
-msgid "Manually link this issue by adding it to the linked issue section of the %{originating_vulnerability}."
+msgid "Manually link this issue by adding it to the linked issue section of the %{linkStart}originating vulnerability%{linkEnd}."
msgstr ""
msgid "Map a FogBugz account ID to a GitLab user"
@@ -21904,10 +22181,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -22006,6 +22283,9 @@ msgstr ""
msgid "Metrics and profiling"
msgstr ""
+msgid "Metrics:"
+msgstr ""
+
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -22623,6 +22903,9 @@ msgstr ""
msgid "More information."
msgstr ""
+msgid "More options"
+msgstr ""
+
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@@ -22825,6 +23108,39 @@ msgstr ""
msgid "Navigation bar"
msgstr ""
+msgid "NavigationTheme|Blue"
+msgstr ""
+
+msgid "NavigationTheme|Dark"
+msgstr ""
+
+msgid "NavigationTheme|Dark Mode (alpha)"
+msgstr ""
+
+msgid "NavigationTheme|Green"
+msgstr ""
+
+msgid "NavigationTheme|Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light"
+msgstr ""
+
+msgid "NavigationTheme|Light Blue"
+msgstr ""
+
+msgid "NavigationTheme|Light Green"
+msgstr ""
+
+msgid "NavigationTheme|Light Indigo"
+msgstr ""
+
+msgid "NavigationTheme|Light Red"
+msgstr ""
+
+msgid "NavigationTheme|Red"
+msgstr ""
+
msgid "Nav|Help"
msgstr ""
@@ -23038,6 +23354,9 @@ msgstr "新增"
msgid "New %{issueType}"
msgstr ""
+msgid "New %{type} in %{project}"
+msgstr ""
+
msgid "New Application"
msgstr ""
@@ -23261,6 +23580,9 @@ msgstr ""
msgid "Next file in diff"
msgstr ""
+msgid "Next scan"
+msgstr ""
+
msgid "Next unresolved discussion"
msgstr ""
@@ -23679,6 +24001,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr ""
+msgid "Note: current forks will keep their visibility level."
+msgstr ""
+
msgid "NoteForm|Note"
msgstr ""
@@ -23691,7 +24016,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24094,6 +24419,12 @@ msgstr ""
msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}."
msgstr ""
+msgid "OnDemandScans|Are you sure you want to delete this scan?"
+msgstr ""
+
+msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later."
+msgstr ""
+
msgid "OnDemandScans|Could not fetch on-demand scans. Please refresh the page, or try again later."
msgstr ""
@@ -24112,12 +24443,18 @@ msgstr ""
msgid "OnDemandScans|Create new site profile"
msgstr ""
+msgid "OnDemandScans|Delete profile"
+msgstr ""
+
msgid "OnDemandScans|Description (optional)"
msgstr ""
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
+msgid "OnDemandScans|Edit profile"
+msgstr ""
+
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -24157,12 +24494,21 @@ msgstr ""
msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
msgstr ""
+msgid "OnDemandScans|Repeats"
+msgstr ""
+
+msgid "OnDemandScans|Run scan"
+msgstr ""
+
msgid "OnDemandScans|Save and run scan"
msgstr ""
msgid "OnDemandScans|Save scan"
msgstr ""
+msgid "OnDemandScans|Scan library"
+msgstr ""
+
msgid "OnDemandScans|Scan name"
msgstr ""
@@ -24187,18 +24533,33 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
+msgid "OnDemandScans|The scan could not be retried."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
msgid "OnDemandScans|There are no running scans."
msgstr ""
+msgid "OnDemandScans|There are no saved scans."
+msgstr ""
+
+msgid "OnDemandScans|There are no scheduled scans."
+msgstr ""
+
msgid "OnDemandScans|Use existing scanner profile"
msgstr ""
msgid "OnDemandScans|Use existing site profile"
msgstr ""
+msgid "OnDemandScans|View results"
+msgstr ""
+
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -24208,9 +24569,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored. This project will no longer be able to receive or send merge requests to the source project or other forks."
msgstr ""
-msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
-msgstr ""
-
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
@@ -24368,6 +24726,9 @@ msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operations"
+msgstr ""
+
msgid "Operations Dashboard"
msgstr ""
@@ -24906,9 +25267,6 @@ msgstr ""
msgid "Page settings"
msgstr ""
-msgid "Page size"
-msgstr ""
-
msgid "PagerDutySettings|Active"
msgstr ""
@@ -25098,9 +25456,15 @@ msgstr ""
msgid "Pending"
msgstr ""
+msgid "Pending Deletion"
+msgstr ""
+
msgid "Pending comments"
msgstr ""
+msgid "Pending deletion"
+msgstr ""
+
msgid "Pending owner approval"
msgstr ""
@@ -25200,6 +25564,9 @@ msgstr ""
msgid "Period in seconds"
msgstr ""
+msgid "Permalink"
+msgstr ""
+
msgid "Permanently delete project"
msgstr ""
@@ -25281,12 +25648,6 @@ msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
-msgid "Pipeline minutes quota"
-msgstr ""
-
-msgid "Pipeline minutes quota:"
-msgstr ""
-
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -25518,6 +25879,9 @@ msgstr ""
msgid "Pipelines|Clear runner caches"
msgstr ""
+msgid "Pipelines|Configuration validation currently not available."
+msgstr ""
+
msgid "Pipelines|Copy trigger token"
msgstr ""
@@ -25737,9 +26101,6 @@ msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
-msgid "Pipeline|No pipeline was triggered for the latest changes due to the current CI/CD configuration."
-msgstr ""
-
msgid "Pipeline|Passed"
msgstr ""
@@ -26016,6 +26377,12 @@ msgstr ""
msgid "Please refer to %{docs_url}"
msgstr ""
+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 ""
+
+msgid "Please review the updated escalation policies for %{project}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
+msgstr ""
+
msgid "Please select"
msgstr ""
@@ -26028,6 +26395,9 @@ msgstr ""
msgid "Please select a file"
msgstr ""
+msgid "Please select a group"
+msgstr ""
+
msgid "Please select a group."
msgstr ""
@@ -26223,9 +26593,6 @@ msgstr ""
msgid "Preferences|Use relative times"
msgstr ""
-msgid "Press %{key}-C to copy"
-msgstr ""
-
msgid "Prev"
msgstr ""
@@ -26577,6 +26944,9 @@ msgstr ""
msgid "Profiles|Invalid username"
msgstr ""
+msgid "Profiles|Job title"
+msgstr ""
+
msgid "Profiles|Key"
msgstr ""
@@ -26634,6 +27004,12 @@ msgstr ""
msgid "Profiles|Profile was successfully updated"
msgstr ""
+msgid "Profiles|Pronouns"
+msgstr ""
+
+msgid "Profiles|Pronunciation"
+msgstr ""
+
msgid "Profiles|Public avatar"
msgstr ""
@@ -26718,6 +27094,9 @@ msgstr ""
msgid "Profiles|Using emojis in names seems fun, but please try to set a status message instead"
msgstr ""
+msgid "Profiles|Website url"
+msgstr ""
+
msgid "Profiles|What's your status?"
msgstr ""
@@ -27012,6 +27391,48 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Failure"
+msgstr ""
+
+msgid "ProjectQualitySummary|Latest pipeline results"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Learn more about test reports"
+msgstr ""
+
+msgid "ProjectQualitySummary|Measure of how much of your code is covered by tests."
+msgstr ""
+
+msgid "ProjectQualitySummary|See full report"
+msgstr ""
+
+msgid "ProjectQualitySummary|See project Code Coverage Statistics"
+msgstr ""
+
+msgid "ProjectQualitySummary|Skipped"
+msgstr ""
+
+msgid "ProjectQualitySummary|Success"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test coverage"
+msgstr ""
+
+msgid "ProjectQualitySummary|Test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|The percentage of tests that succeed, fail, or are skipped."
+msgstr ""
+
msgid "ProjectSelect| or group"
msgstr ""
@@ -27138,6 +27559,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27390,19 +27814,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
@@ -27558,6 +27979,15 @@ msgstr ""
msgid "ProjectTemplates|iOS (Swift)"
msgstr ""
+msgid "ProjectView|Activity"
+msgstr ""
+
+msgid "ProjectView|Files and Readme (default)"
+msgstr ""
+
+msgid "ProjectView|Readme"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -27942,9 +28372,6 @@ msgstr ""
msgid "Promotions|This feature is locked."
msgstr ""
-msgid "Promotions|Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Try it for free"
msgstr ""
@@ -27957,9 +28384,6 @@ msgstr ""
msgid "Promotions|Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Promotions|Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -27984,9 +28408,6 @@ msgstr ""
msgid "Promotions|When you have a lot of issues, it can be hard to get an overview. By adding a weight to your issues, you can get a better idea of the effort, cost, required time, or value of each, and so better manage them."
msgstr ""
-msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members."
-msgstr ""
-
msgid "Promotions|You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users."
msgstr ""
@@ -28068,6 +28489,9 @@ msgstr ""
msgid "ProtectedBranch|Branch"
msgstr ""
+msgid "ProtectedBranch|Branch will be writable for developers. Are you sure?"
+msgstr ""
+
msgid "ProtectedBranch|Branch:"
msgstr ""
@@ -28113,9 +28537,15 @@ msgstr ""
msgid "ProtectedBranch|Toggle code owner approval"
msgstr ""
+msgid "ProtectedBranch|Unprotect"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
+msgid "ProtectedBranch|default"
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
@@ -28158,6 +28588,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|default"
+msgstr ""
+
msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
msgstr ""
@@ -28173,6 +28606,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -28401,6 +28837,12 @@ msgstr ""
msgid "Quickly and easily edit multiple files in your project."
msgstr ""
+msgid "Quota of CI/CD minutes"
+msgstr ""
+
+msgid "Quota of CI/CD minutes:"
+msgstr ""
+
msgid "README"
msgstr ""
@@ -28585,9 +29027,6 @@ msgstr ""
msgid "Regenerate instance ID"
msgstr ""
-msgid "Regenerate key"
-msgstr ""
-
msgid "Regenerate recovery codes"
msgstr ""
@@ -28630,6 +29069,54 @@ msgstr ""
msgid "Registration Features include:"
msgstr ""
+msgid "RegistrationFeatures|Enable Service Ping and register for this feature."
+msgstr ""
+
+msgid "RegistrationFeatures|Read more about the %{linkStart}%{label}%{linkEnd}."
+msgstr ""
+
+msgid "RegistrationFeatures|Registration Features Program"
+msgstr ""
+
+msgid "RegistrationFeatures|Want to %{feature_title} for free?"
+msgstr ""
+
+msgid "RegistrationFeatures|send emails to users"
+msgstr ""
+
+msgid "RegistrationFeatures|use this feature"
+msgstr ""
+
+msgid "RegistrationVerification|Are you sure you want to skip this step?"
+msgstr ""
+
+msgid "RegistrationVerification|Enable free CI/CD minutes"
+msgstr ""
+
+msgid "RegistrationVerification|GitLab will not charge your card, it will only be used for validation."
+msgstr ""
+
+msgid "RegistrationVerification|Pipelines using shared GitLab runners will fail until you validate your account."
+msgstr ""
+
+msgid "RegistrationVerification|Skip this for now"
+msgstr ""
+
+msgid "RegistrationVerification|To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method, such as a debit or credit card. Until then, you can't use free CI/CD minutes to build your application."
+msgstr ""
+
+msgid "RegistrationVerification|Validate account"
+msgstr ""
+
+msgid "RegistrationVerification|Verify your identity"
+msgstr ""
+
+msgid "RegistrationVerification|Yes, I'd like to skip"
+msgstr ""
+
+msgid "RegistrationVerification|You can alway verify your account at a later time."
+msgstr ""
+
msgid "Registration|Checkout"
msgstr ""
@@ -28955,10 +29442,10 @@ msgstr ""
msgid "Removed upload with id %{id}"
msgstr ""
-msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here."
+msgid "RemovedProjects|No projects pending deletion found"
msgstr ""
-msgid "RemovedProjects|You haven’t removed any projects."
+msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
@@ -29636,6 +30123,9 @@ msgstr ""
msgid "Resync"
msgstr ""
+msgid "Retrieving the compliance report failed. Please refresh the page and try again."
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -29645,6 +30135,12 @@ msgstr ""
msgid "Retry migration"
msgstr ""
+msgid "Retry the downstream pipeline"
+msgstr ""
+
+msgid "Retry the trigger job"
+msgstr ""
+
msgid "Retry this job"
msgstr ""
@@ -29839,9 +30335,6 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
-msgid "Runners|Are you sure you want to delete this runner?"
-msgstr ""
-
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -29863,6 +30356,12 @@ msgstr ""
msgid "Runners|Copy registration token"
msgstr ""
+msgid "Runners|Delete runner"
+msgstr ""
+
+msgid "Runners|Delete runner %{name}?"
+msgstr ""
+
msgid "Runners|Deploy GitLab Runner in AWS"
msgstr ""
@@ -29914,19 +30413,22 @@ msgstr ""
msgid "Runners|Name"
msgstr ""
+msgid "Runners|Never contacted"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
-msgid "Runners|New runner, has not connected yet"
+msgid "Runners|New runner, has not contacted yet"
msgstr ""
-msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
+msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not connected"
+msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Offline"
@@ -29980,6 +30482,9 @@ msgstr ""
msgid "Runners|Runner #%{runner_id}"
msgstr ""
+msgid "Runners|Runner %{name} was deleted"
+msgstr ""
+
msgid "Runners|Runner ID"
msgstr ""
@@ -30025,6 +30530,9 @@ msgstr ""
msgid "Runners|Something went wrong while fetching the tags suggestions"
msgstr ""
+msgid "Runners|Stale"
+msgstr ""
+
msgid "Runners|Status"
msgstr ""
@@ -30034,7 +30542,10 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
-msgid "Runners|This runner has never connected to this instance"
+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 ""
+
+msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
@@ -30103,7 +30614,7 @@ msgstr ""
msgid "Runners|locked"
msgstr ""
-msgid "Runners|not connected"
+msgid "Runners|never contacted"
msgstr ""
msgid "Runners|offline"
@@ -30121,6 +30632,9 @@ msgstr ""
msgid "Runners|specific"
msgstr ""
+msgid "Runners|stale"
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -30382,6 +30896,9 @@ msgstr ""
msgid "Search forks"
msgstr ""
+msgid "Search groups"
+msgstr ""
+
msgid "Search iterations"
msgstr ""
@@ -30403,9 +30920,6 @@ msgstr ""
msgid "Search or filter results…"
msgstr ""
-msgid "Search or jump to..."
-msgstr ""
-
msgid "Search project"
msgstr ""
@@ -30675,6 +31189,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
+msgid "SecurityConfiguration|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 ""
+
msgid "SecurityConfiguration|Enabled"
msgstr ""
@@ -30747,6 +31264,9 @@ msgstr ""
msgid "SecurityOrchestration|%{branches} and %{lastBranch} %{plural}"
msgstr ""
+msgid "SecurityOrchestration|.yaml preview"
+msgstr ""
+
msgid "SecurityOrchestration|Action"
msgstr ""
@@ -30801,6 +31321,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No rules defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@@ -30885,9 +31408,6 @@ msgstr ""
msgid "SecurityOrchestration|view results"
msgstr ""
-msgid "SecurityOrhestration|No rules defined - policy will not run."
-msgstr ""
-
msgid "SecurityPolicies|+%{count} more"
msgstr ""
@@ -31086,6 +31606,9 @@ msgstr ""
msgid "SecurityReports|Severity"
msgstr ""
+msgid "SecurityReports|Software and container dependency survey"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
@@ -31098,6 +31621,9 @@ msgstr ""
msgid "SecurityReports|Take survey"
msgstr ""
+msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs."
+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 ""
@@ -31173,6 +31699,9 @@ msgstr ""
msgid "SecurityReports|You must sign in as an authorized user to see this report"
msgstr ""
+msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days."
+msgstr ""
+
msgid "SecurityReports|Your feedback is important to us! We will ask again in a week."
msgstr ""
@@ -31326,6 +31855,9 @@ msgstr ""
msgid "Select project to choose zone"
msgstr ""
+msgid "Select project to create %{type}"
+msgstr ""
+
msgid "Select project to create issue"
msgstr ""
@@ -31677,6 +32209,12 @@ msgstr ""
msgid "Set due date"
msgstr ""
+msgid "Set health status"
+msgstr ""
+
+msgid "Set health status to %{health_status}."
+msgstr ""
+
msgid "Set iteration"
msgstr ""
@@ -31833,6 +32371,9 @@ msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
+msgid "Sets health status to %{health_status}."
+msgstr ""
+
msgid "Sets target branch to %{branch_name}."
msgstr ""
@@ -32529,6 +33070,9 @@ msgstr ""
msgid "Something went wrong while updating assignees"
msgstr ""
+msgid "Something went wrong while updating work item. Please try again"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -32973,9 +33517,6 @@ msgstr ""
msgid "Start your free trial"
msgstr ""
-msgid "Start your trial"
-msgstr ""
-
msgid "Started"
msgstr ""
@@ -33372,6 +33913,12 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
+msgid "SubscriptionBanner|Export license usage file"
+msgstr ""
+
+msgid "SubscriptionBanner|Upload new license"
+msgstr ""
+
msgid "SubscriptionTable|Add seats"
msgstr ""
@@ -33807,6 +34354,24 @@ msgstr ""
msgid "Syntax is incorrect."
msgstr ""
+msgid "SynthaxHighlightingTheme|Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Light"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Monokai"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|None"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Dark"
+msgstr ""
+
+msgid "SynthaxHighlightingTheme|Solarized Light"
+msgstr ""
+
msgid "System"
msgstr ""
@@ -34073,9 +34638,23 @@ msgid "Terraform|%{number} Terraform report was generated in your pipelines"
msgid_plural "Terraform|%{number} Terraform reports were generated in your pipelines"
msgstr[0] ""
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report failed to generate"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports failed to generate"
+msgstr[0] ""
+
+msgid "Terraform|%{strong_start}%{number}%{strong_end} Terraform report was generated in your pipelines"
+msgid_plural "Terraform|%{strong_start}%{number}%{strong_end} Terraform reports were generated in your pipelines"
+msgstr[0] ""
+
msgid "Terraform|%{user} updated %{timeAgo}"
msgstr ""
+msgid "Terraform|A Terraform report failed to generate."
+msgstr ""
+
+msgid "Terraform|A Terraform report was generated in your pipelines."
+msgstr ""
+
msgid "Terraform|A report failed to generate."
msgstr ""
@@ -34106,6 +34685,9 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
+msgid "Terraform|Failed to load Terraform reports"
+msgstr ""
+
msgid "Terraform|Generating the report caused an error."
msgstr ""
@@ -34118,6 +34700,9 @@ msgstr ""
msgid "Terraform|Job status"
msgstr ""
+msgid "Terraform|Loading Terraform reports..."
+msgstr ""
+
msgid "Terraform|Lock"
msgstr ""
@@ -34154,12 +34739,21 @@ msgstr ""
msgid "Terraform|Terraform init command"
msgstr ""
+msgid "Terraform|Terraform reports"
+msgstr ""
+
msgid "Terraform|The job %{name} failed to generate a report."
msgstr ""
msgid "Terraform|The job %{name} generated a report."
msgstr ""
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} failed to generate a report."
+msgstr ""
+
+msgid "Terraform|The job %{strong_start}%{name}%{strong_end} generated a report."
+msgstr ""
+
msgid "Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}."
msgstr ""
@@ -34442,6 +35036,9 @@ msgstr ""
msgid "The compliance report captures merged changes that violate compliance best practices."
msgstr ""
+msgid "The compliance report shows the merge request violations merged in protected environments."
+msgstr ""
+
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -34563,9 +35160,6 @@ msgstr ""
msgid "The group and its projects can only be viewed by members."
msgstr ""
-msgid "The group can be fully restored"
-msgstr ""
-
msgid "The group export can be downloaded from:"
msgstr ""
@@ -34575,9 +35169,6 @@ msgstr ""
msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
msgstr ""
-msgid "The group will be placed in 'pending deletion' state"
-msgstr ""
-
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
@@ -34650,7 +35241,7 @@ msgstr ""
msgid "The maximum file size is %{size}."
msgstr ""
-msgid "The maximum number of pipeline minutes that a group can use on shared runners per month. 0 for unlimited."
+msgid "The maximum number of CI/CD minutes on shared runners that a group can use each month. 0 for unlimited."
msgstr ""
msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0."
@@ -34905,9 +35496,6 @@ msgstr ""
msgid "There are no issues with the selected labels"
msgstr ""
-msgid "There are no labels yet"
-msgstr ""
-
msgid "There are no matching files"
msgstr ""
@@ -35253,6 +35841,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr ""
+msgid "This PDF is too large to display. Please download to view."
+msgstr ""
+
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -35265,9 +35856,6 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action has been performed too many times. Try again later."
-msgstr ""
-
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
msgstr ""
@@ -35292,6 +35880,9 @@ msgstr ""
msgid "This application will be able to:"
msgstr ""
+msgid "This archive has been requested too many times. Try again later."
+msgstr ""
+
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of %{size_limit}. %{written_count} of %{count} %{issuables} have been included. Consider re-exporting with a narrower selection of %{issuables}."
msgstr ""
@@ -35406,6 +35997,9 @@ msgstr ""
msgid "This group"
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 ""
+
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 ""
@@ -35571,6 +36165,9 @@ msgstr ""
msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
msgstr ""
+msgid "This job triggers a downstream pipeline"
+msgstr ""
+
msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
msgstr ""
@@ -36281,6 +36878,9 @@ 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."
+msgstr ""
+
msgid "To resolve this, try to:"
msgstr ""
@@ -36347,6 +36947,39 @@ msgstr ""
msgid "Today"
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 ""
+
+msgid "Todos|Filter by author"
+msgstr ""
+
+msgid "Todos|Filter by group"
+msgstr ""
+
+msgid "Todos|Filter by project"
+msgstr ""
+
+msgid "Todos|It's how you always know what to work on next."
+msgstr ""
+
+msgid "Todos|Mark all as done"
+msgstr ""
+
+msgid "Todos|Nothing is on your to-do list. Nice work!"
+msgstr ""
+
+msgid "Todos|Undo mark all as done"
+msgstr ""
+
+msgid "Todos|When an issue or merge request is assigned to you, or when you receive a %{strongStart}@mention%{strongEnd} in a comment, this automatically triggers a new item in your To-Do List."
+msgstr ""
+
+msgid "Todos|You're all done!"
+msgstr ""
+
+msgid "Todos|Your To-Do List shows what to work on next"
+msgstr ""
+
msgid "Toggle GitLab Next"
msgstr ""
@@ -36521,6 +37154,9 @@ msgstr ""
msgid "Transfer"
msgstr ""
+msgid "Transfer group to another parent group."
+msgstr ""
+
msgid "Transfer ownership"
msgstr ""
@@ -36642,15 +37278,6 @@ msgstr ""
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
-msgid "Trial|Hi%{salutation}, your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information about %{company} to activate your trial."
-msgstr ""
-
-msgid "Trial|How many employees will use Gitlab?"
-msgstr ""
-
-msgid "Trial|How many users will be evaluating the trial?"
-msgstr ""
-
msgid "Trial|Last name"
msgstr ""
@@ -36675,9 +37302,6 @@ msgstr ""
msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial."
msgstr ""
-msgid "Trial|your company"
-msgstr ""
-
msgid "Trigger"
msgstr ""
@@ -37305,9 +37929,6 @@ msgstr ""
msgid "Uploading changes to terminal"
msgstr ""
-msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:"
-msgstr ""
-
msgid "Upstream"
msgstr ""
@@ -38199,16 +38820,16 @@ msgstr ""
msgid "Verification status"
msgstr ""
-msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity with a valid payment method."
+msgid "VerificationReminder|Pipeline failing? To keep GitLab spam and abuse free we ask that you verify your identity."
msgstr ""
-msgid "VerificationReminder|Until then, free pipeline minutes on shared runners are unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
+msgid "VerificationReminder|Until then, shared runners will be unavailable. %{validateLinkStart}Validate your account%{validateLinkEnd} or %{docsLinkStart}use your own runners%{docsLinkEnd}."
msgstr ""
-msgid "VerificationReminder|Your account has been validated."
+msgid "VerificationReminder|Your account has been validated"
msgstr ""
-msgid "VerificationReminder|You’ll now be able to take advantage of free pipeline minutes on shared runners."
+msgid "VerificationReminder|You’ll now be able to take advantage of free CI/CD minutes on shared runners."
msgstr ""
msgid "Verified"
@@ -38250,6 +38871,9 @@ msgstr ""
msgid "View all issues"
msgstr ""
+msgid "View blame"
+msgstr ""
+
msgid "View blame prior to this change"
msgstr ""
@@ -38272,6 +38896,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View downstream pipeline"
+msgstr ""
+
msgid "View eligible approvers"
msgstr ""
@@ -38300,6 +38927,12 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View incident details at"
+msgstr ""
+
+msgid "View incident details."
+msgstr ""
+
msgid "View incident issues."
msgstr ""
@@ -38391,6 +39024,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Violation"
+msgstr ""
+
msgid "Visibility"
msgstr ""
@@ -38472,12 +39108,24 @@ msgstr ""
msgid "VulnerabilityManagement|%{statusStart}Resolved%{statusEnd} %{timeago} by %{user}"
msgstr ""
+msgid "VulnerabilityManagement|(optional) Include the solution to the vulnerability if available."
+msgstr ""
+
+msgid "VulnerabilityManagement|A removed or remediated vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
+msgid "VulnerabilityManagement|A verified true-positive vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Add vulnerability finding"
msgstr ""
+msgid "VulnerabilityManagement|An unverified non-confirmed finding"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -38505,6 +39153,9 @@ msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
+msgid "VulnerabilityManagement|Select a method"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -38574,9 +39225,18 @@ msgstr ""
msgid "Vulnerability|Additional Info"
msgstr ""
+msgid "Vulnerability|Bug Bounty"
+msgstr ""
+
+msgid "Vulnerability|CVSS v3"
+msgstr ""
+
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Code Review"
+msgstr ""
+
msgid "Vulnerability|Comments"
msgstr ""
@@ -38592,21 +39252,33 @@ msgstr ""
msgid "Vulnerability|Description"
msgstr ""
+msgid "Vulnerability|Details"
+msgstr ""
+
msgid "Vulnerability|Detected"
msgstr ""
+msgid "Vulnerability|Detection method"
+msgstr ""
+
msgid "Vulnerability|Download"
msgstr ""
msgid "Vulnerability|Evidence"
msgstr ""
+msgid "Vulnerability|External Security Report"
+msgstr ""
+
msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
+msgid "Vulnerability|GitLab Security Report"
+msgstr ""
+
msgid "Vulnerability|Identifier"
msgstr ""
@@ -38616,6 +39288,9 @@ msgstr ""
msgid "Vulnerability|Image"
msgstr ""
+msgid "Vulnerability|Information related how the vulnerability was discovered and its impact to the system."
+msgstr ""
+
msgid "Vulnerability|Links"
msgstr ""
@@ -38640,6 +39315,15 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
+msgid "Vulnerability|Security Audit"
+msgstr ""
+
+msgid "Vulnerability|Select a severity"
+msgstr ""
+
+msgid "Vulnerability|Set the status of the vulnerability finding based on the information available to you."
+msgstr ""
+
msgid "Vulnerability|Severity"
msgstr ""
@@ -38763,6 +39447,9 @@ msgstr ""
msgid "We'll use this to help surface the right features and information to you."
msgstr ""
+msgid "We're experiencing difficulties and this tab content is currently unavailable."
+msgstr ""
+
msgid "We've found no vulnerabilities"
msgstr ""
@@ -38850,6 +39537,12 @@ msgstr ""
msgid "Webhooks|Enable SSL verification"
msgstr ""
+msgid "Webhooks|Failed to connect"
+msgstr ""
+
+msgid "Webhooks|Fails to connect"
+msgstr ""
+
msgid "Webhooks|Feature flag events"
msgstr ""
@@ -38886,6 +39579,15 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
+msgid "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."
+msgstr ""
+
msgid "Webhooks|Trigger"
msgstr ""
@@ -38943,6 +39645,15 @@ msgstr ""
msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header."
msgstr ""
+msgid "Webhooks|Webhook failed to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook fails to connect"
+msgstr ""
+
+msgid "Webhooks|Webhook was automatically disabled"
+msgstr ""
+
msgid "Webhooks|Wiki page events"
msgstr ""
@@ -38979,6 +39690,9 @@ msgstr ""
msgid "Welcome, %{name}!"
msgstr ""
+msgid "What are CI/CD minutes?"
+msgstr ""
+
msgid "What are group audit events?"
msgstr ""
@@ -38988,9 +39702,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are shared runner pipeline minutes?"
-msgstr ""
-
msgid "What are you searching for?"
msgstr ""
@@ -39824,6 +40535,12 @@ 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."
+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."
+msgstr ""
+
msgid "You have no permissions"
msgstr ""
@@ -40013,6 +40730,12 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
+msgid "Your %{plan} subscription expired on %{expiry_date}"
+msgstr ""
+
+msgid "Your %{plan} subscription expires on %{expiry_date}"
+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 ""
@@ -40304,6 +41027,9 @@ msgstr ""
msgid "Your subscription expired!"
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."
+msgstr ""
+
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
@@ -40541,6 +41267,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -40571,7 +41300,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -40619,8 +41348,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgid "ciReport|Browser performance test metrics: No changes"
@@ -40713,8 +41442,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgid "ciReport|Load performance test metrics results are being parsed"
@@ -40874,6 +41603,9 @@ msgstr ""
msgid "committed"
msgstr ""
+msgid "compliance violation has already been recorded"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -41312,9 +42044,6 @@ msgstr ""
msgid "missing"
msgstr ""
-msgid "more information"
-msgstr ""
-
msgid "most recent deployment"
msgstr ""
@@ -41668,6 +42397,9 @@ msgstr ""
msgid "must be a valid IPv4 or IPv6 address"
msgstr ""
+msgid "must be a valid json schema"
+msgstr ""
+
msgid "must be after start"
msgstr ""
@@ -41767,9 +42499,6 @@ msgstr ""
msgid "or"
msgstr ""
-msgid "originating vulnerability"
-msgstr ""
-
msgid "other card matches"
msgstr ""
diff --git a/metrics_server/dependencies.rb b/metrics_server/dependencies.rb
index a459efef1ad..5615cef42ce 100644
--- a/metrics_server/dependencies.rb
+++ b/metrics_server/dependencies.rb
@@ -6,6 +6,7 @@ require 'fileutils'
require 'active_support/concern'
require 'active_support/inflector'
+require 'active_support/core_ext/numeric/bytes'
require 'prometheus/client'
require 'rack'
@@ -18,8 +19,14 @@ require_relative '../lib/gitlab/utils/strong_memoize'
require_relative '../lib/prometheus/cleanup_multiproc_dir_service'
require_relative '../lib/gitlab/metrics/prometheus'
require_relative '../lib/gitlab/metrics'
+require_relative '../lib/gitlab/metrics/system'
+require_relative '../lib/gitlab/metrics/samplers/base_sampler'
+require_relative '../lib/gitlab/metrics/samplers/ruby_sampler'
require_relative '../lib/gitlab/metrics/exporter/base_exporter'
require_relative '../lib/gitlab/metrics/exporter/sidekiq_exporter'
+require_relative '../lib/gitlab/metrics/exporter/metrics_middleware'
+require_relative '../lib/gitlab/metrics/exporter/health_checks_middleware'
+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'
diff --git a/metrics_server/metrics_server.rb b/metrics_server/metrics_server.rb
index 56fc20dcc9d..122a4e4fc1e 100644
--- a/metrics_server/metrics_server.rb
+++ b/metrics_server/metrics_server.rb
@@ -40,15 +40,21 @@ class MetricsServer # rubocop:disable Gitlab/NamespacedClass
def start
::Prometheus::Client.configure do |config|
config.multiprocess_files_dir = @metrics_dir
+ config.pid_provider = proc { "#{@target}_exporter" }
end
FileUtils.mkdir_p(@metrics_dir, mode: 0700)
::Prometheus::CleanupMultiprocDirService.new.execute if @wipe_metrics_dir
- settings = Settings.new(Settings.monitoring[name])
+ # We need to `warmup: true` since otherwise the sampler and exporter threads enter
+ # a race where not all Prometheus db files will be visible to the exporter, resulting
+ # in missing metrics.
+ # Warming up ensures that these files exist prior to the exporter starting up.
+ Gitlab::Metrics::Samplers::RubySampler.initialize_instance(warmup: true).start
exporter_class = "Gitlab::Metrics::Exporter::#{@target.camelize}Exporter".constantize
- server = exporter_class.instance(settings, synchronous: true)
+ settings = Settings.new(Settings.monitoring[name])
+ server = exporter_class.instance(settings, gc_requests: true, synchronous: true)
server.start
end
diff --git a/metrics_server/override_gitlab_current_settings.rb b/metrics_server/override_gitlab_current_settings.rb
new file mode 100644
index 00000000000..1dc19b5da23
--- /dev/null
+++ b/metrics_server/override_gitlab_current_settings.rb
@@ -0,0 +1,21 @@
+# rubocop:disable Naming/FileName
+# frozen_string_literal: true
+
+# We need to supply this outside of Rails because:
+# RubySampler needs Gitlab::Metrics needs Gitlab::Metrics::Prometheus needs Gitlab::CurrentSettings needs ::Settings
+# to check for `prometheus_metrics_enabled`. We therefore simply redirect it to our own Settings type.
+module Gitlab
+ module CurrentSettings
+ class << self
+ def prometheus_metrics_enabled
+ # We make the simplified assumption that when the metrics-server runs,
+ # Prometheus metrics are enabled. Since the latter is a setting stored
+ # in the application database, we have no access to it here, so we need
+ # to hard-code it.
+ true
+ end
+ end
+ end
+end
+
+# rubocop:enable Naming/FileName
diff --git a/metrics_server/settings_overrides.rb b/metrics_server/settings_overrides.rb
index 8572b4f86b0..b3fd39229d5 100644
--- a/metrics_server/settings_overrides.rb
+++ b/metrics_server/settings_overrides.rb
@@ -9,6 +9,11 @@
# Here we make the necessary constants available conditionally.
require_relative 'override_rails_constants' unless Object.const_defined?('Rails')
+# We need to supply this outside of Rails because:
+# RubySampler needs Gitlab::Metrics needs Gitlab::Metrics::Prometheus needs Gitlab::CurrentSettings needs ::Settings
+# to check for `prometheus_metrics_enabled`. We therefore simply redirect it to our own Settings type.
+require_relative 'override_gitlab_current_settings' unless Object.const_defined?('Gitlab::CurrentSettings')
+
require_relative '../config/settings'
# rubocop:enable Naming/FileName
diff --git a/package.json b/package.json
index 4310081acf6..94221488036 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,8 @@
"stylelint-create-utility-map": "node scripts/frontend/stylelint/stylelint-utility-map.js",
"webpack": "NODE_OPTIONS=\"--max-old-space-size=3584\" webpack --config config/webpack.config.js",
"webpack-vendor": "NODE_OPTIONS=\"--max-old-space-size=3584\" webpack --config config/webpack.vendor.config.js",
- "webpack-prod": "NODE_OPTIONS=\"--max-old-space-size=3584\" NODE_ENV=production webpack --config config/webpack.config.js"
+ "webpack-prod": "NODE_OPTIONS=\"--max-old-space-size=3584\" NODE_ENV=production webpack --config config/webpack.config.js",
+ "webpack-prod-node-latest": "NODE_OPTIONS=\"--max-old-space-size=3584 --openssl-legacy-provider\" NODE_ENV=production webpack --config config/webpack.config.js"
},
"dependencies": {
"@babel/core": "^7.10.1",
@@ -55,44 +56,44 @@
"@babel/preset-env": "^7.10.1",
"@gitlab/at.js": "1.5.7",
"@gitlab/favicon-overlay": "2.0.0",
- "@gitlab/svgs": "2.0.0",
+ "@gitlab/svgs": "2.2.0",
"@gitlab/tributejs": "1.0.0",
- "@gitlab/ui": "32.50.0",
+ "@gitlab/ui": "32.68.0",
"@gitlab/visual-review-tools": "1.6.1",
"@rails/actioncable": "6.1.4-1",
"@rails/ujs": "6.1.4-1",
"@sentry/browser": "5.30.0",
"@sourcegraph/code-host-integration": "0.0.60",
- "@tiptap/core": "^2.0.0-beta.143",
- "@tiptap/extension-blockquote": "^2.0.0-beta.25",
- "@tiptap/extension-bold": "^2.0.0-beta.24",
- "@tiptap/extension-bullet-list": "^2.0.0-beta.23",
- "@tiptap/extension-code": "^2.0.0-beta.25",
- "@tiptap/extension-code-block-lowlight": "2.0.0-beta.57",
+ "@tiptap/core": "^2.0.0-beta.160",
+ "@tiptap/extension-blockquote": "^2.0.0-beta.26",
+ "@tiptap/extension-bold": "^2.0.0-beta.25",
+ "@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.63",
"@tiptap/extension-document": "^2.0.0-beta.15",
"@tiptap/extension-dropcursor": "^2.0.0-beta.25",
- "@tiptap/extension-gapcursor": "^2.0.0-beta.33",
+ "@tiptap/extension-gapcursor": "^2.0.0-beta.34",
"@tiptap/extension-hard-break": "^2.0.0-beta.30",
- "@tiptap/extension-heading": "^2.0.0-beta.23",
+ "@tiptap/extension-heading": "^2.0.0-beta.24",
"@tiptap/extension-history": "^2.0.0-beta.21",
"@tiptap/extension-horizontal-rule": "^2.0.0-beta.30",
"@tiptap/extension-image": "^2.0.0-beta.24",
- "@tiptap/extension-italic": "^2.0.0-beta.24",
- "@tiptap/extension-link": "^2.0.0-beta.28",
- "@tiptap/extension-list-item": "^2.0.0-beta.19",
- "@tiptap/extension-ordered-list": "^2.0.0-beta.24",
- "@tiptap/extension-paragraph": "^2.0.0-beta.22",
- "@tiptap/extension-strike": "^2.0.0-beta.26",
- "@tiptap/extension-subscript": "^2.0.0-beta.9",
- "@tiptap/extension-superscript": "^2.0.0-beta.9",
- "@tiptap/extension-table": "^2.0.0-beta.43",
+ "@tiptap/extension-italic": "^2.0.0-beta.25",
+ "@tiptap/extension-link": "^2.0.0-beta.34",
+ "@tiptap/extension-list-item": "^2.0.0-beta.20",
+ "@tiptap/extension-ordered-list": "^2.0.0-beta.27",
+ "@tiptap/extension-paragraph": "^2.0.0-beta.23",
+ "@tiptap/extension-strike": "^2.0.0-beta.27",
+ "@tiptap/extension-subscript": "^2.0.0-beta.10",
+ "@tiptap/extension-superscript": "^2.0.0-beta.10",
+ "@tiptap/extension-table": "^2.0.0-beta.46",
"@tiptap/extension-table-cell": "^2.0.0-beta.20",
"@tiptap/extension-table-header": "^2.0.0-beta.22",
"@tiptap/extension-table-row": "^2.0.0-beta.19",
- "@tiptap/extension-task-item": "^2.0.0-beta.29",
- "@tiptap/extension-task-list": "^2.0.0-beta.23",
+ "@tiptap/extension-task-item": "^2.0.0-beta.30",
+ "@tiptap/extension-task-list": "^2.0.0-beta.26",
"@tiptap/extension-text": "^2.0.0-beta.15",
- "@tiptap/vue-2": "^2.0.0-beta.69",
+ "@tiptap/vue-2": "^2.0.0-beta.74",
"@toast-ui/editor": "^2.5.2",
"@toast-ui/vue-editor": "^2.5.2",
"apollo-cache-inmemory": "^1.6.6",
@@ -110,12 +111,12 @@
"bootstrap": "4.5.3",
"cache-loader": "^4.1.0",
"canvas-confetti": "^1.4.0",
- "clipboard": "^1.7.1",
+ "clipboard": "^2.0.8",
"codemirror": "^5.48.4",
"codesandbox-api": "0.0.23",
"compression-webpack-plugin": "^5.0.2",
"copy-webpack-plugin": "^6.4.1",
- "core-js": "^3.20.0",
+ "core-js": "^3.20.2",
"cron-validator": "^1.1.1",
"cronstrue": "^1.122.0",
"cropper": "^2.3.0",
@@ -133,7 +134,7 @@
"fast-mersenne-twister": "1.0.2",
"file-loader": "^6.2.0",
"fuzzaldrin-plus": "^0.6.0",
- "graphql": "^15.4.0",
+ "graphql": "^15.7.2",
"graphql-tag": "^2.11.0",
"highlight.js": "^11.3.1",
"immer": "^7.0.7",
@@ -150,7 +151,7 @@
"lowlight": "^1.20.0",
"marked": "^0.3.12",
"mathjax": "3",
- "mermaid": "^8.13.4",
+ "mermaid": "^8.13.8",
"minimatch": "^3.0.4",
"monaco-editor": "^0.25.2",
"monaco-editor-webpack-plugin": "^4.0.0",
@@ -162,11 +163,11 @@
"popper.js": "^1.16.1",
"portal-vue": "^2.1.7",
"prismjs": "^1.21.0",
- "prosemirror-markdown": "^1.6.0",
- "prosemirror-model": "^1.15.0",
+ "prosemirror-markdown": "1.6.0",
+ "prosemirror-model": "^1.16.1",
"prosemirror-state": "^1.3.4",
"prosemirror-tables": "^1.1.1",
- "prosemirror-view": "^1.23.3",
+ "prosemirror-view": "^1.23.5",
"raphael": "^2.2.7",
"raw-loader": "^4.0.2",
"scrollparent": "^2.0.1",
@@ -209,9 +210,9 @@
"@babel/plugin-transform-modules-commonjs": "^7.10.1",
"@gitlab/eslint-plugin": "10.0.0",
"@gitlab/stylelint-config": "2.6.0",
- "@graphql-eslint/eslint-plugin": "2.3.0",
+ "@graphql-eslint/eslint-plugin": "3.0.0",
"@testing-library/dom": "^7.16.2",
- "@vue/test-utils": "1.2.0",
+ "@vue/test-utils": "1.3.0",
"acorn": "^6.3.0",
"axios-mock-adapter": "^1.15.0",
"babel-jest": "^26.5.2",
@@ -234,6 +235,7 @@
"istanbul-reports": "^3.0.0",
"jest": "^26.5.2",
"jest-canvas-mock": "^2.1.2",
+ "jest-diff": "^27.4.6",
"jest-environment-jsdom": "^26.5.2",
"jest-junit": "^12.0.0",
"jest-raw-loader": "^1.0.1",
diff --git a/public/500.html b/public/500.html
index df7b22dc9ef..16d72353bdb 100644
--- a/public/500.html
+++ b/public/500.html
@@ -76,6 +76,7 @@
<div class="container">
<h3>Whoops, something went wrong on our end.</h3>
<hr />
+ <!-- REQUEST_ID -->
<p>Try refreshing the page, or going back and attempting the action again.</p>
<p>Please contact your GitLab administrator if this problem persists.</p>
<a href="javascript:history.back()" class="js-go-back go-back">Go back</a>
diff --git a/qa/.confiner/quarantine.yml b/qa/.confiner/quarantine.yml
new file mode 100644
index 00000000000..6534d72525d
--- /dev/null
+++ b/qa/.confiner/quarantine.yml
@@ -0,0 +1,15 @@
+- name: Quarantine E2E tests that fail consistently
+ plugin:
+ name: gitlab # https://gitlab.com/gitlab-org/quality/confiner/-/blob/main/doc/plugins/gitlab.md
+ args:
+ threshold: 3 # 3 failures
+ private_token: $QA_GITLAB_CI_TOKEN
+ project_id: gitlab-org/gitlab-qa-mirror # https://gitlab.com/gitlab-org/gitlab-qa-mirror/
+ target_project: gitlab-org/gitlab
+ failure_issue_labels: QA,Quality
+ failure_issue_prefix: "Failure in "
+ pwd: qa # E2E specs reside in the qa subdirectory
+ timeout: 30
+ ref: master
+ actions:
+ - quarantine
diff --git a/qa/Dockerfile b/qa/Dockerfile
index 13213c7c8c8..54de6509518 100644
--- a/qa/Dockerfile
+++ b/qa/Dockerfile
@@ -77,7 +77,7 @@ COPY ./config/initializers/0_inject_enterprise_edition_module.rb /home/gitlab/co
# The [b] part makes ./ee/app/models/license.r[b] a pattern that is allowed to return no files (which is the case in FOSS)
COPY VERSION ./ee/app/models/license.r[b] /home/gitlab/ee/app/models/
COPY ./config/bundler_setup.rb /home/gitlab/config/
-COPY ./lib/gitlab.rb /home/gitlab/lib/
+COPY ./lib/gitlab_edition.rb /home/gitlab/lib/
COPY ./lib/gitlab/utils.rb /home/gitlab/lib/gitlab/
COPY ./INSTALLATION_TYPE ./VERSION /home/gitlab/
diff --git a/qa/Gemfile b/qa/Gemfile
index 576b58f9844..c07f9dc96a7 100644
--- a/qa/Gemfile
+++ b/qa/Gemfile
@@ -25,10 +25,12 @@ gem 'octokit', '~> 4.21'
gem 'webdrivers', '~> 5.0'
gem 'zeitwerk', '~> 2.4'
gem 'influxdb-client', '~> 1.17'
-gem 'terminal-table', '~> 1.8', require: false
+gem 'terminal-table', '~> 3.0.0', require: false
gem 'slack-notifier', '~> 2.4', require: false
gem 'fog-google', '~> 1.17', require: false
+gem 'confiner', '~> 0.2'
+
gem 'chemlab', '~> 0.9'
gem 'chemlab-library-www-gitlab-com', '~> 0.1'
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock
index 14f10d2b047..3e85a33f2a2 100644
--- a/qa/Gemfile.lock
+++ b/qa/Gemfile.lock
@@ -57,6 +57,9 @@ GEM
adamantium (~> 0.2.0)
equalizer (~> 0.0.9)
concurrent-ruby (1.1.9)
+ confiner (0.2.1)
+ gitlab (>= 4.17)
+ zeitwerk (~> 2.5.1)
declarative (0.0.20)
deprecation_toolkit (1.5.1)
activesupport (>= 4.2)
@@ -112,12 +115,12 @@ GEM
fog-core
nokogiri (>= 1.5.11, < 2.0.0)
formatador (0.3.0)
- gitlab (4.16.1)
- httparty (~> 0.14, >= 0.14.0)
- terminal-table (~> 1.5, >= 1.5.1)
- gitlab-qa (7.14.0)
+ gitlab (4.18.0)
+ httparty (~> 0.18)
+ terminal-table (>= 1.5.1)
+ gitlab-qa (7.17.1)
activesupport (~> 6.1)
- gitlab (~> 4.16.1)
+ gitlab (~> 4.18.0)
http (~> 5.0)
nokogiri (~> 1.10)
table_print (= 1.5.7)
@@ -184,12 +187,12 @@ GEM
memoizable (0.4.2)
thread_safe (~> 0.3, >= 0.3.1)
method_source (0.9.0)
- mime-types (3.4.0)
+ mime-types (3.4.1)
mime-types-data (~> 3.2015)
- mime-types-data (3.2021.1115)
+ mime-types-data (3.2022.0105)
mini_mime (1.1.0)
mini_portile2 (2.6.1)
- minitest (5.14.4)
+ minitest (5.15.0)
multi_json (1.15.0)
multi_xml (0.6.0)
multipart-post (2.1.1)
@@ -280,8 +283,8 @@ GEM
slack-notifier (2.4.0)
systemu (2.6.5)
table_print (1.5.7)
- terminal-table (1.8.0)
- unicode-display_width (~> 1.1, >= 1.1.1)
+ terminal-table (3.0.2)
+ unicode-display_width (>= 1.1.1, < 3)
thread_safe (0.3.6)
timecop (0.9.1)
trailblazer-option (0.1.2)
@@ -291,7 +294,7 @@ GEM
unf (0.1.4)
unf_ext
unf_ext (0.0.8)
- unicode-display_width (1.8.0)
+ unicode-display_width (2.1.0)
unparser (0.4.7)
abstract_type (~> 0.0.7)
adamantium (~> 0.2.0)
@@ -312,7 +315,7 @@ GEM
webrick (1.7.0)
xpath (3.2.0)
nokogiri (~> 1.8)
- zeitwerk (2.5.1)
+ zeitwerk (2.5.3)
PLATFORMS
ruby
@@ -325,6 +328,7 @@ DEPENDENCIES
capybara-screenshot (~> 1.0.23)
chemlab (~> 0.9)
chemlab-library-www-gitlab-com (~> 0.1)
+ confiner (~> 0.2)
deprecation_toolkit (~> 1.5.1)
faker (~> 2.19, >= 2.19.0)
fog-google (~> 1.17)
@@ -345,10 +349,10 @@ DEPENDENCIES
ruby-debug-ide (~> 0.7.0)
selenium-webdriver (~> 4.0)
slack-notifier (~> 2.4)
- terminal-table (~> 1.8)
+ terminal-table (~> 3.0.0)
timecop (~> 0.9.1)
webdrivers (~> 5.0)
zeitwerk (~> 2.4)
BUNDLED WITH
- 2.2.30
+ 2.2.33
diff --git a/qa/Rakefile b/qa/Rakefile
index e865b972b4e..5d8c49a399b 100644
--- a/qa/Rakefile
+++ b/qa/Rakefile
@@ -1,14 +1,9 @@
# frozen_string_literal: true
# rubocop:disable Rails/RakeEnvironment
-Dir['tasks/*.rake'].each { |file| load file }
+require_relative "qa"
-require_relative 'qa/tools/revoke_all_personal_access_tokens'
-require_relative 'qa/tools/delete_subgroups'
-require_relative 'qa/tools/generate_perf_testdata'
-require_relative 'qa/tools/delete_test_ssh_keys'
-require_relative 'qa/tools/initialize_gitlab_auth'
-require_relative 'qa/tools/delete_projects'
+Dir['tasks/*.rake'].each { |file| load file }
desc "Revokes all personal access tokens"
task :revoke_personal_access_tokens do
@@ -64,4 +59,9 @@ desc "Deletes projects directly under the provided group"
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
+end
# rubocop:enable Rails/RakeEnvironment
diff --git a/qa/knapsack/.gitignore b/qa/knapsack/.gitignore
new file mode 100644
index 00000000000..d91d3e8efdd
--- /dev/null
+++ b/qa/knapsack/.gitignore
@@ -0,0 +1,4 @@
+**
+
+!.gitignore
+!master_report.json
diff --git a/qa/knapsack/gcs/.gitignore b/qa/knapsack/gcs/.gitignore
deleted file mode 100644
index e7c1de7e0f2..00000000000
--- a/qa/knapsack/gcs/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-**
-
-!.gitignore
diff --git a/qa/knapsack/master_report.json b/qa/knapsack/master_report.json
index 152b17a0577..0e9f67fa967 100644
--- a/qa/knapsack/master_report.json
+++ b/qa/knapsack/master_report.json
@@ -1,209 +1,199 @@
{
- "qa/specs/features/ee/api/2_plan/epics_milestone_dates_spec.rb": 4.835599899291992,
- "qa/specs/features/ee/browser_ui/3_create/repository/code_owners_spec.rb": 26.39240026473999,
- "qa/specs/features/ee/browser_ui/secure/create_project_with_secure_spec.rb": 46.76790499687195,
- "qa/specs/features/api/1_manage/users_spec.rb": 0.6089541912078857,
- "qa/specs/features/browser_ui/1_manage/login/login_via_oauth_spec.rb": 20.58603596687317,
- "qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb": 31.49540114402771,
- "qa/specs/features/browser_ui/3_create/repository/add_ssh_key_spec.rb": 16.18057894706726,
- "qa/specs/features/browser_ui/3_create/repository/create_edit_delete_file_via_web_spec.rb": 18.047621726989746,
- "qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb": 19.459370374679565,
- "qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb": 22.800872802734375,
- "qa/specs/features/browser_ui/3_create/snippet/create_snippet_spec.rb": 5.812374591827393,
- "qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb": 17.273863554000854,
- "qa/specs/features/browser_ui/4_verify/ci_variable/add_ci_variable_spec.rb": 8.31815505027771,
- "qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb": 51.81568956375122,
- "qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb": 30.373554468154907,
- "qa/specs/features/sanity/version_spec.rb": 0.0004665851593017578,
- "qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb": 22.993898630142212,
- "qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb": 36.358747243881226,
- "qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb": 9.079580068588257,
- "qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb": 39.412545919418335,
- "qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb": 27.905837297439575,
- "qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb": 99.71209812164307,
- "qa/specs/features/ee/browser_ui/2_plan/epic/promote_issue_to_epic_spec.rb": 25.72262978553772,
- "qa/specs/features/ee/browser_ui/2_plan/issue_boards/project_issue_boards_spec.rb": 44.536749839782715,
- "qa/specs/features/browser_ui/2_plan/milestone/create_group_milestone_spec.rb": 18.482256174087524,
- "qa/specs/features/browser_ui/2_plan/issue/comment_issue_spec.rb": 16.314701795578003,
- "qa/specs/features/ee/browser_ui/2_plan/issue_boards/read_only_board_configuration_spec.rb": 36.934654235839844,
- "qa/specs/features/ee/browser_ui/2_plan/iterations/create_group_iteration_spec.rb": 17.103047847747803,
- "qa/specs/features/browser_ui/2_plan/milestone/create_project_milestone_spec.rb": 28.352823495864868,
- "qa/specs/features/ee/browser_ui/2_plan/issue_boards/configure_issue_board_by_label_spec.rb": 20.208287954330444,
- "qa/specs/features/ee/browser_ui/2_plan/burndown_chart/burndown_chart_spec.rb": 13.733941793441772,
- "qa/specs/features/browser_ui/2_plan/issue/collapse_comments_in_discussions_spec.rb": 16.376311540603638,
- "qa/specs/features/ee/browser_ui/2_plan/epic/epics_management_spec.rb": 98.71593880653381,
- "qa/specs/features/browser_ui/2_plan/related_issues/related_issues_spec.rb": 21.307689666748047,
- "qa/specs/features/ee/browser_ui/2_plan/multiple_assignees_for_issues/more_than_four_assignees_spec.rb": 39.39231467247009,
- "qa/specs/features/ee/browser_ui/2_plan/issue_boards/create_group_issue_board_spec.rb": 18.50350284576416,
- "qa/specs/features/ee/browser_ui/2_plan/issues_analytics/issues_analytics_spec.rb": 30.67392325401306,
- "qa/specs/features/ee/browser_ui/2_plan/custom_email/custom_email_spec.rb": 16.17888569831848,
- "qa/specs/features/ee/browser_ui/2_plan/scoped_labels/editing_scoped_labels_spec.rb": 45.47245216369629,
- "qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb": 38.93913507461548,
- "qa/specs/features/ee/browser_ui/2_plan/epic/roadmap_spec.rb": 12.087258100509644,
- "qa/specs/features/ee/browser_ui/2_plan/issue_boards/group_issue_boards_spec.rb": 17.309232473373413,
- "qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb": 70.75156497955322,
- "qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb": 22.20275855064392,
- "qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb": 24.21539831161499,
- "qa/specs/features/ee/browser_ui/2_plan/issues_weight/issue_weight_visualization_spec.rb": 20.22646951675415,
- "qa/specs/features/ee/browser_ui/2_plan/iterations/assign_group_iteration_spec.rb": 31.00749373435974,
- "qa/specs/features/ee/browser_ui/2_plan/issue/default_issue_template_spec.rb": 18.430193424224854,
- "qa/specs/features/browser_ui/3_create/wiki/project_based_page_deletion_spec.rb": 13.615312337875366,
- "qa/specs/features/browser_ui/1_manage/project/protected_tags_spec.rb": 94.04865074157715,
- "qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb": 59.575963258743286,
- "qa/specs/features/ee/browser_ui/1_manage/group/share_group_with_group_spec.rb": 25.6483793258667,
- "qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb": 26.07162046432495,
- "qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb": 8.41316819190979,
- "qa/specs/features/ee/browser_ui/secure/merge_request_license_widget_spec.rb": 73.56247329711914,
- "qa/specs/features/api/3_create/repository/files_spec.rb": 6.235261917114258,
- "qa/specs/features/browser_ui/5_package/container_registry_spec.rb": 7.263134717941284,
- "qa/specs/features/api/3_create/repository/default_branch_name_setting_spec.rb": 10.079012870788574,
- "qa/specs/features/browser_ui/3_create/repository/file/delete_file_via_web_spec.rb": 16.52791404724121,
- "qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb": 10.684799909591675,
- "qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb": 72.14465713500977,
- "qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb": 15.664107322692871,
- "qa/specs/features/browser_ui/3_create/snippet/add_file_to_snippet_spec.rb": 34.32576060295105,
- "qa/specs/features/browser_ui/3_create/design_management/archive_design_content_spec.rb": 31.586787939071655,
- "qa/specs/features/ee/browser_ui/secure/project_security_dashboard_spec.rb": 27.6742160320282,
- "qa/specs/features/api/1_manage/rate_limits_spec.rb": 11.836639165878296,
- "qa/specs/features/ee/browser_ui/1_manage/user/minimal_access_user_spec.rb": 15.691015005111694,
- "qa/specs/features/api/3_create/merge_request/push_options_mwps_spec.rb": 38.80854368209839,
- "qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb": 15.07186245918274,
- "qa/specs/features/ee/browser_ui/3_create/repository/pull_mirroring_over_http_spec.rb": 41.58929800987244,
- "qa/specs/features/api/3_create/repository/push_postreceive_idempotent_spec.rb": 13.438591957092285,
- "qa/specs/features/ee/browser_ui/3_create/merge_request/default_merge_request_template_spec.rb": 30.66688632965088,
- "qa/specs/features/browser_ui/1_manage/user/user_access_termination_spec.rb": 25.137597799301147,
- "qa/specs/features/browser_ui/3_create/repository/clone_spec.rb": 8.731743574142456,
- "qa/specs/features/browser_ui/7_configure/auto_devops/auto_devops_templates_spec.rb": 0.0008337497711181641,
- "qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb": 40.60329842567444,
- "qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb": 39.090237617492676,
- "qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb": 22.633376359939575,
- "qa/specs/features/browser_ui/3_create/design_management/modify_design_content_spec.rb": 18.457061767578125,
- "qa/specs/features/browser_ui/3_create/wiki/project_based_content_creation_spec.rb": 49.273433685302734,
- "qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb": 14.6923348903656,
- "qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb": 38.44519090652466,
- "qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb": 46.04780888557434,
- "qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb": 27.77385425567627,
- "qa/specs/features/ee/browser_ui/1_manage/insights/default_insights_spec.rb": 28.850987195968628,
- "qa/specs/features/browser_ui/3_create/repository/file/edit_file_via_web_spec.rb": 19.598198413848877,
- "qa/specs/features/browser_ui/3_create/repository/file/file_with_unusual_name_spec.rb": 15.17819595336914,
- "qa/specs/features/api/1_manage/user_access_termination_spec.rb": 6.3396782875061035,
- "qa/specs/features/ee/browser_ui/secure/create_merge_request_with_secure_spec.rb": 71.55253982543945,
- "qa/specs/features/browser_ui/4_verify/testing/view_code_coverage_spec.rb": 42.83795666694641,
- "qa/specs/features/api/3_create/merge_request/push_options_remove_source_branch_spec.rb": 17.03721809387207,
- "qa/specs/features/browser_ui/3_create/wiki/project_based_content_manipulation_spec.rb": 25.14606213569641,
- "qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb": 70.44876503944397,
- "qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb": 52.93111038208008,
- "qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb": 48.3312201499939,
- "qa/specs/features/ee/browser_ui/1_manage/group/group_audit_logs_2_spec.rb": 100.1787781715393,
- "qa/specs/features/browser_ui/3_create/repository/user_views_commit_diff_patch_spec.rb": 22.37237572669983,
- "qa/specs/features/ee/browser_ui/1_manage/group/group_file_template_spec.rb": 69.36870694160461,
- "qa/specs/features/api/3_create/merge_request/push_options_target_branch_spec.rb": 13.524356126785278,
- "qa/specs/features/ee/browser_ui/1_manage/group/prevent_forking_outside_group_spec.rb": 37.17233395576477,
- "qa/specs/features/api/2_plan/closes_issue_via_pushing_a_commit_spec.rb": 6.892294406890869,
- "qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb": 12.628767013549805,
- "qa/specs/features/ee/browser_ui/secure/enable_sast_from_configuration_spec.rb": 86.38991785049438,
- "qa/specs/features/ee/browser_ui/4_verify/pipeline_for_project_mirror_github_spec.rb": 12.684113502502441,
- "qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb": 35.340261459350586,
- "qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb": 19.719850540161133,
- "qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb": 38.779794216156006,
- "qa/specs/features/api/4_verify/cancel_pipeline_when_block_user_spec.rb": 6.86094856262207,
- "qa/specs/features/browser_ui/3_create/snippet/delete_file_from_snippet_spec.rb": 51.54451298713684,
- "qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb": 18.586050033569336,
- "qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb": 35.587294578552246,
- "qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb": 14.01547122001648,
- "qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb": 20.370421409606934,
- "qa/specs/features/browser_ui/3_create/wiki/project_based_directory_management_spec.rb": 15.297787427902222,
- "qa/specs/features/browser_ui/3_create/snippet/add_comment_to_snippet_spec.rb": 42.507469177246094,
- "qa/specs/features/ee/browser_ui/4_verify/pipeline_status_on_operation_dashboard_spec.rb": 46.77937316894531,
- "qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb": 20.96509575843811,
- "qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb": 12.62861156463623,
- "qa/specs/features/browser_ui/3_create/merge_request/revert/reverting_merge_request_spec.rb": 49.85329723358154,
- "qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb": 84.63548684120178,
- "qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb": 15.584527254104614,
- "qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb": 30.72457480430603,
- "qa/specs/features/api/3_create/merge_request/push_options_title_description_spec.rb": 10.70707631111145,
- "qa/specs/features/ee/api/1_manage/user/minimal_access_user_spec.rb": 4.82462477684021,
- "qa/specs/features/browser_ui/3_create/snippet/share_snippet_spec.rb": 32.49313712120056,
- "qa/specs/features/browser_ui/3_create/wiki/project_based_list_spec.rb": 32.37481236457825,
- "qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb": 16.573434114456177,
- "qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb": 43.15674066543579,
- "qa/specs/features/ee/browser_ui/secure/license_compliance_spec.rb": 31.000027179718018,
- "qa/specs/features/ee/browser_ui/1_manage/project/project_audit_logs_spec.rb": 149.64519357681274,
- "qa/specs/features/ee/browser_ui/1_manage/group/restrict_by_ip_address_spec.rb": 116.07316851615906,
- "qa/specs/features/browser_ui/1_manage/login/register_spec.rb": 145.5431580543518,
- "qa/specs/features/browser_ui/3_create/repository/file/create_file_via_web_spec.rb": 19.418848514556885,
- "qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb": 18.54582905769348,
- "qa/specs/features/api/5_package/container_registry_spec.rb": 3.93778920173645,
- "qa/specs/features/ee/browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb": 148.70570707321167,
- "qa/specs/features/ee/browser_ui/6_release/multi-project_pipelines_spec.rb": 52.770936250686646,
- "qa/specs/features/ee/browser_ui/3_create/contribution_analytics_spec.rb": 45.81806302070618,
- "qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb": 20.386794805526733,
- "qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb": 21.968912363052368,
- "qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb": 71.7951602935791,
- "qa/specs/features/api/1_manage/bulk_import_group_spec.rb": 50.21021842956543,
- "qa/specs/features/ee/browser_ui/2_plan/issue_boards/configurable_issue_board_spec.rb": 16.42144775390625,
- "qa/specs/features/ee/browser_ui/3_create/repository/merge_with_code_owner_in_root_group_spec.rb": 173.84056043624878,
- "qa/specs/features/ee/browser_ui/1_manage/project/project_templates_spec.rb": 86.48439168930054,
- "qa/specs/features/ee/browser_ui/3_create/repository/pull_mirroring_over_ssh_with_key_spec.rb": 56.275856018066406,
- "qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb": 87.7243127822876,
- "qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_a_project_spec.rb": 98.70601177215576,
- "qa/specs/features/ee/browser_ui/secure/vulnerability_management_spec.rb": 91.42165040969849,
- "qa/specs/features/ee/browser_ui/3_create/repository/merge_with_code_owner_in_subgroup_spec.rb": 176.7654173374176,
- "qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb": 17.273313283920288,
- "qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb": 15.879833459854126,
- "qa/specs/features/ee/browser_ui/2_plan/issue_boards/sum_of_issues_weights_spec.rb": 16.24162793159485,
- "qa/specs/features/browser_ui/1_manage/group/bulk_import_group_spec.rb": 55.61779570579529,
- "qa/specs/features/ee/browser_ui/2_plan/multiple_assignees_for_issues/four_assignees_spec.rb": 15.482072830200195,
- "qa/specs/features/browser_ui/4_verify/pipeline/pass_dotenv_variables_to_downstream_via_bridge_spec.rb": 54.22519111633301,
- "qa/specs/features/ee/browser_ui/3_create/repository/push_rules_spec.rb": 85.68487024307251,
- "qa/specs/features/ee/browser_ui/3_create/web_ide/web_terminal_spec.rb": 63.027522802352905,
- "qa/specs/features/ee/browser_ui/3_create/wiki/create_group_wiki_page_spec.rb": 26.17377734184265,
- "qa/specs/features/browser_ui/3_create/design_management/add_design_content_spec.rb": 16.853343725204468,
- "qa/specs/features/api/1_manage/project_access_token_spec.rb": 2.8215739727020264,
- "qa/specs/features/ee/browser_ui/1_manage/instance/instance_audit_logs_spec.rb": 109.0079870223999,
- "qa/specs/features/browser_ui/6_release/pages/pages_pipeline_spec.rb": 73.78986692428589,
- "qa/specs/features/browser_ui/4_verify/pipeline/locked_artifacts_spec.rb": 34.84124970436096,
- "qa/specs/features/api/1_manage/import_github_repo_spec.rb": 11.330891609191895,
- "qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb": 36.70389533042908,
- "qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb": 25.407151699066162,
- "qa/specs/features/browser_ui/7_configure/kubernetes/kubernetes_integration_spec.rb": 109.88336181640625,
- "qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb": 24.014917373657227,
- "qa/specs/features/ee/browser_ui/3_create/repository/code_owners_with_protected_branch_and_squashed_commits_spec.rb": 42.596492767333984,
- "qa/specs/features/browser_ui/3_create/snippet/snippet_index_page_spec.rb": 60.067442893981934,
- "qa/specs/features/ee/browser_ui/3_create/repository/file_locking_spec.rb": 185.41551113128662,
- "qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb": 30.03315234184265,
- "qa/specs/features/browser_ui/2_plan/milestone/assign_milestone_spec.rb": 76.58771228790283,
- "qa/specs/features/browser_ui/3_create/snippet/copy_snippet_file_contents_spec.rb": 28.64104723930359,
- "qa/specs/features/browser_ui/4_verify/ci_variable/pipeline_with_protected_variable_spec.rb": 198.37600350379944,
- "qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb": 35.098846435546875,
- "qa/specs/features/browser_ui/4_verify/pipeline/trigger_matrix_spec.rb": 51.25122785568237,
- "qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb": 61.072656869888306,
- "qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb": 135.90494751930237,
- "qa/specs/features/ee/browser_ui/4_verify/cancelling_merge_request_in_merge_train_spec.rb": 59.57308530807495,
- "qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb": 32.462252140045166,
- "qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb": 53.246745586395264,
- "qa/specs/features/browser_ui/4_verify/pipeline/mr_event_rule_pipeline_spec.rb": 79.99787259101868,
- "qa/specs/features/browser_ui/1_manage/login/2fa_ssh_recovery_spec.rb": 57.00465273857117,
- "qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb": 77.2134940624237,
- "qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb": 48.472514390945435,
- "qa/specs/features/api/3_create/merge_request/push_options_labels_spec.rb": 17.153425455093384,
- "qa/specs/features/ee/browser_ui/1_manage/group/group_audit_logs_1_spec.rb": 96.45902276039124,
- "qa/specs/features/browser_ui/4_verify/pipeline/merge_mr_when_pipline_is_blocked_spec.rb": 64.81094217300415,
- "qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb": 27.902702569961548,
- "qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_branch_switcher_spec.rb": 23.476325750350952,
- "qa/specs/features/ee/browser_ui/10_protect/policy_list_spec.rb": 14.327334642410278,
- "qa/specs/features/ee/browser_ui/secure/security_reports_spec.rb": 26.599382877349854,
- "qa/specs/features/browser_ui/4_verify/pipeline/trigger_child_pipeline_with_manual_spec.rb": 39.33750772476196,
- "qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb": 50.194467306137085,
- "qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_a_merge_spec.rb": 59.395915508270264,
- "qa/specs/features/ee/browser_ui/4_verify/pipelines_for_merged_results_and_merge_trains_spec.rb": 203.04975271224976,
- "qa/specs/features/ee/browser_ui/3_create/repository/assign_code_owners_spec.rb": 42.03165292739868,
- "qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb": 18.495836973190308,
- "qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb": 17.1261248588562,
- "qa/specs/features/ee/browser_ui/4_verify/pipeline_subscription_with_group_owned_project_spec.rb": 53.17536449432373,
- "qa/specs/features/ee/browser_ui/3_create/merge_request/add_batch_comments_in_merge_request_spec.rb": 62.42040038108826,
- "qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb": 90.16095304489136,
- "qa/specs/features/ee/browser_ui/4_verify/new_discussion_not_dropping_merge_trains_mr_spec.rb": 91.91785287857056,
- "qa/specs/features/browser_ui/5_package/maven_repository_spec.rb": 687.8482820987701,
- "qa/specs/features/browser_ui/5_package/npm_registry_spec.rb": 225.33412504196167
+ "qa/specs/features/api/1_manage/users_spec.rb": 0.38025754499994946,
+ "qa/specs/features/ee/browser_ui/11_fulfillment/license/license_spec.rb": 6.1726223529999515,
+ "qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb": 6.837727864000044,
+ "qa/specs/features/api/3_create/repository/files_spec.rb": 6.9398801430002095,
+ "qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb": 7.072401565999826,
+ "qa/specs/features/browser_ui/3_create/repository/clone_spec.rb": 8.430185218000133,
+ "qa/specs/features/ee/browser_ui/2_plan/epic/roadmap_spec.rb": 9.21629216500014,
+ "qa/specs/features/browser_ui/14_non_devops/service_ping_default_enabled_spec.rb": 9.460245247999865,
+ "qa/specs/features/api/3_create/repository/default_branch_name_setting_spec.rb": 9.749626129999797,
+ "qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb": 9.997606156000074,
+ "qa/specs/features/api/3_create/repository/push_postreceive_idempotent_spec.rb": 10.100938496999788,
+ "qa/specs/features/api/3_create/merge_request/push_options_target_branch_spec.rb": 10.435720339999989,
+ "qa/specs/features/api/3_create/merge_request/push_options_remove_source_branch_spec.rb": 10.664103456999783,
+ "qa/specs/features/browser_ui/3_create/wiki/project_based_page_deletion_spec.rb": 11.010621653000044,
+ "qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb": 11.080987325000024,
+ "qa/specs/features/api/3_create/merge_request/push_options_title_description_spec.rb": 11.289408692999814,
+ "qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb": 11.388780440000119,
+ "qa/specs/features/ee/browser_ui/2_plan/burndown_chart/burndown_chart_spec.rb": 11.812601945000097,
+ "qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb": 11.884903447000397,
+ "qa/specs/features/ee/browser_ui/2_plan/custom_email/custom_email_spec.rb": 11.973681912000075,
+ "qa/specs/features/browser_ui/3_create/wiki/project_based_directory_management_spec.rb": 11.982320482999967,
+ "qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb": 12.454461346999778,
+ "qa/specs/features/api/2_plan/closes_issue_via_pushing_a_commit_spec.rb": 12.595205497999814,
+ "qa/specs/features/api/3_create/merge_request/push_options_labels_spec.rb": 12.696943737999845,
+ "qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb": 12.821059261999835,
+ "qa/specs/features/browser_ui/2_plan/milestone/create_group_milestone_spec.rb": 13.493086933000086,
+ "qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb": 13.522706569999855,
+ "qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb": 13.611114558000281,
+ "qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb": 13.662936730000183,
+ "qa/specs/features/ee/browser_ui/2_plan/issue_boards/sum_of_issues_weights_spec.rb": 13.997128957999848,
+ "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,
+ "qa/specs/features/browser_ui/3_create/design_management/add_design_content_spec.rb": 14.869172961000004,
+ "qa/specs/features/ee/browser_ui/2_plan/iterations/assign_group_iteration_spec.rb": 15.069100258000162,
+ "qa/specs/features/ee/browser_ui/2_plan/issue_boards/configurable_issue_board_spec.rb": 15.071375434999936,
+ "qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb": 15.238976046000062,
+ "qa/specs/features/ee/browser_ui/2_plan/scoped_labels/editing_scoped_labels_spec.rb": 15.25893454900006,
+ "qa/specs/features/browser_ui/2_plan/issue/collapse_comments_in_discussions_spec.rb": 15.62486792799973,
+ "qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb": 15.73652188899996,
+ "qa/specs/features/ee/browser_ui/2_plan/issues_analytics/issues_analytics_spec.rb": 16.175388279000117,
+ "qa/specs/features/ee/browser_ui/2_plan/issues_weight/issue_weight_visualization_spec.rb": 16.21438098999988,
+ "qa/specs/features/ee/browser_ui/2_plan/issue_boards/configure_issue_board_by_label_spec.rb": 16.22156817799987,
+ "qa/specs/features/ee/browser_ui/2_plan/issue_boards/group_issue_boards_spec.rb": 16.28064358199981,
+ "qa/specs/features/browser_ui/3_create/repository/file/delete_file_via_web_spec.rb": 16.526415993999763,
+ "qa/specs/features/browser_ui/3_create/wiki/content_editor_spec.rb": 16.635663933999695,
+ "qa/specs/features/api/1_manage/import_github_repo_spec.rb": 16.75859540500005,
+ "qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb": 16.85444325000026,
+ "qa/specs/features/ee/browser_ui/2_plan/epic/promote_issue_to_epic_spec.rb": 17.065811306999876,
+ "qa/specs/features/ee/browser_ui/11_fulfillment/purchase/user_registration_billing_spec.rb": 17.17362991999994,
+ "qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb": 17.35990919599999,
+ "qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb": 17.4036377489997,
+ "qa/specs/features/ee/browser_ui/2_plan/issue_boards/create_group_issue_board_spec.rb": 17.53151273000003,
+ "qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb": 18.336858511999708,
+ "qa/specs/features/browser_ui/3_create/design_management/modify_design_content_spec.rb": 18.827946458000042,
+ "qa/specs/features/browser_ui/2_plan/issue/comment_issue_spec.rb": 19.011096268000074,
+ "qa/specs/features/ee/browser_ui/2_plan/issue/default_issue_template_spec.rb": 19.273840846999974,
+ "qa/specs/features/api/4_verify/cancel_pipeline_when_block_user_spec.rb": 19.779615910000075,
+ "qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb": 19.787533178000103,
+ "qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb": 20.357167043000118,
+ "qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb": 20.58807039300018,
+ "qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb": 20.604954283000097,
+ "qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb": 20.84536794700034,
+ "qa/specs/features/ee/browser_ui/3_create/wiki/create_group_wiki_page_spec.rb": 21.285323852000147,
+ "qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb": 21.324911325999892,
+ "qa/specs/features/api/1_manage/user_access_termination_spec.rb": 21.359333020000122,
+ "qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb": 21.53934234799999,
+ "qa/specs/features/browser_ui/3_create/repository/file/file_with_unusual_name_spec.rb": 21.623363159999826,
+ "qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_branch_switcher_spec.rb": 21.639708403999975,
+ "qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb": 22.508069357000295,
+ "qa/specs/features/browser_ui/3_create/wiki/project_based_content_manipulation_spec.rb": 22.67048247999992,
+ "qa/specs/features/ee/browser_ui/1_manage/insights/default_insights_spec.rb": 22.707359102999817,
+ "qa/specs/features/browser_ui/3_create/repository/file/create_file_via_web_spec.rb": 23.914098683999782,
+ "qa/specs/features/ee/browser_ui/1_manage/group/share_group_with_group_spec.rb": 24.228926759999922,
+ "qa/specs/features/browser_ui/2_plan/milestone/create_project_milestone_spec.rb": 24.320835930999692,
+ "qa/specs/features/browser_ui/4_verify/pipeline/mr_event_rule_pipeline_spec.rb": 24.421617836999985,
+ "qa/specs/features/ee/api/1_manage/user/minimal_access_user_spec.rb": 24.568071621999934,
+ "qa/specs/features/ee/browser_ui/2_plan/iterations/create_group_iteration_spec.rb": 25.105601008999656,
+ "qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb": 25.670671182000206,
+ "qa/specs/features/ee/browser_ui/3_create/merge_request/default_merge_request_template_spec.rb": 26.588750723999965,
+ "qa/specs/features/browser_ui/3_create/snippet/copy_snippet_file_contents_spec.rb": 26.957921672999873,
+ "qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb": 27.038084878000063,
+ "qa/specs/features/ee/browser_ui/1_manage/user/minimal_access_user_spec.rb": 27.164655879999827,
+ "qa/specs/features/browser_ui/3_create/repository/user_views_commit_diff_patch_spec.rb": 27.958475461000035,
+ "qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb": 29.15091494699982,
+ "qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb": 29.63945763499987,
+ "qa/specs/features/browser_ui/3_create/wiki/project_based_list_spec.rb": 30.055674564000128,
+ "qa/specs/features/browser_ui/3_create/snippet/share_snippet_spec.rb": 30.36701765900034,
+ "qa/specs/features/browser_ui/3_create/repository/file/edit_file_via_web_spec.rb": 31.11626907400023,
+ "qa/specs/features/browser_ui/4_verify/pipeline/locked_artifacts_spec.rb": 31.399775493000107,
+ "qa/specs/features/ee/browser_ui/10_protect/policies_list_spec.rb": 31.579298365999875,
+ "qa/specs/features/ee/browser_ui/2_plan/multiple_assignees_for_issues/more_than_four_assignees_spec.rb": 31.699020851000114,
+ "qa/specs/features/ee/browser_ui/2_plan/issue_boards/read_only_board_configuration_spec.rb": 32.22923225600016,
+ "qa/specs/features/browser_ui/4_verify/testing/view_code_coverage_spec.rb": 32.390305334999994,
+ "qa/specs/features/browser_ui/3_create/snippet/add_file_to_snippet_spec.rb": 32.4001524549999,
+ "qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb": 32.588556773000164,
+ "qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb": 32.655282309000086,
+ "qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb": 32.67606646000013,
+ "qa/specs/features/ee/browser_ui/3_create/repository/code_owners_with_protected_branch_and_squashed_commits_spec.rb": 32.86781491000011,
+ "qa/specs/features/browser_ui/3_create/design_management/archive_design_content_spec.rb": 33.592668581,
+ "qa/specs/features/browser_ui/14_non_devops/performance_bar_spec.rb": 33.844586084000184,
+ "qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb": 34.22076284800005,
+ "qa/specs/features/api/3_create/merge_request/push_options_mwps_spec.rb": 34.69707643500033,
+ "qa/specs/features/browser_ui/3_create/snippet/add_comment_to_snippet_spec.rb": 35.48510294100015,
+ "qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb": 35.60547228999985,
+ "qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb": 35.720513429999755,
+ "qa/specs/features/ee/browser_ui/3_create/repository/assign_code_owners_spec.rb": 36.74466744499978,
+ "qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb": 36.86498900599986,
+ "qa/specs/features/browser_ui/4_verify/pipeline/trigger_matrix_spec.rb": 36.88383336300012,
+ "qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb": 36.91027954099991,
+ "qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb": 38.008783447999576,
+ "qa/specs/features/browser_ui/4_verify/pipeline/trigger_child_pipeline_with_manual_spec.rb": 38.2163332099999,
+ "qa/specs/features/browser_ui/1_manage/user/user_access_termination_spec.rb": 38.41997747000005,
+ "qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb": 38.798842664000176,
+ "qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb": 38.86858395499985,
+ "qa/specs/features/ee/browser_ui/3_create/repository/code_owners_spec.rb": 39.11634360200014,
+ "qa/specs/features/ee/browser_ui/1_manage/group/prevent_forking_outside_group_spec.rb": 39.33498874499992,
+ "qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb": 39.408525157999975,
+ "qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb": 39.66159539199998,
+ "qa/specs/features/ee/browser_ui/4_verify/pipeline_status_on_operation_dashboard_spec.rb": 39.74350435799988,
+ "qa/specs/features/ee/browser_ui/4_verify/pipeline_subscription_with_group_owned_project_spec.rb": 39.873689517,
+ "qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_a_project_spec.rb": 41.68991280600039,
+ "qa/specs/features/ee/browser_ui/3_create/repository/pull_mirroring_over_http_spec.rb": 42.34842452200019,
+ "qa/specs/features/ee/browser_ui/2_plan/issue_boards/project_issue_boards_spec.rb": 42.87835724299998,
+ "qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb": 43.00558933000002,
+ "qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb": 45.002151569000034,
+ "qa/specs/features/browser_ui/3_create/wiki/project_based_content_creation_spec.rb": 45.135388796999905,
+ "qa/specs/features/ee/browser_ui/3_create/merge_request/add_batch_comments_in_merge_request_spec.rb": 45.27653511099993,
+ "qa/specs/features/browser_ui/3_create/snippet/snippet_index_page_spec.rb": 45.49861126799988,
+ "qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb": 45.95718983799998,
+ "qa/specs/features/browser_ui/4_verify/pipeline/pass_dotenv_variables_to_downstream_via_bridge_spec.rb": 46.274925919,
+ "qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb": 47.46850344200038,
+ "qa/specs/features/browser_ui/1_manage/login/2fa_ssh_recovery_spec.rb": 47.98207172000002,
+ "qa/specs/features/browser_ui/4_verify/pipeline/merge_mr_when_pipline_is_blocked_spec.rb": 48.11739431199976,
+ "qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb": 48.333632795000085,
+ "qa/specs/features/ee/browser_ui/6_release/multi-project_pipelines_spec.rb": 49.07156694399987,
+ "qa/specs/features/browser_ui/3_create/snippet/delete_file_from_snippet_spec.rb": 49.98554557300031,
+ "qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb": 50.13713323600041,
+ "qa/specs/features/ee/api/1_manage/bulk_import_group_spec.rb": 50.35492376299999,
+ "qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb": 50.79862357000002,
+ "qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb": 51.18897452500005,
+ "qa/specs/features/ee/browser_ui/3_create/contribution_analytics_spec.rb": 51.5182317230001,
+ "qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb": 52.09437633100015,
+ "qa/specs/features/ee/browser_ui/13_secure/license_compliance_spec.rb": 53.78650449299994,
+ "qa/specs/features/browser_ui/3_create/merge_request/suggestions/batch_suggestion_spec.rb": 53.991341565000084,
+ "qa/specs/features/ee/browser_ui/13_secure/create_merge_request_with_secure_spec.rb": 56.61833271799969,
+ "qa/specs/features/ee/browser_ui/3_create/repository/pull_mirroring_over_ssh_with_key_spec.rb": 58.94148023099979,
+ "qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_a_merge_spec.rb": 59.88873274600019,
+ "qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb": 61.892666940000254,
+ "qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb": 64.76709299799995,
+ "qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb": 65.38459789100034,
+ "qa/specs/features/ee/browser_ui/13_secure/merge_request_license_widget_spec.rb": 65.64657268999963,
+ "qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb": 66.96891640700005,
+ "qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb": 68.11150705099999,
+ "qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb": 70.67798023099999,
+ "qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb": 71.9568110780001,
+ "qa/specs/features/browser_ui/6_release/pages/pages_pipeline_spec.rb": 73.23625617499965,
+ "qa/specs/features/ee/browser_ui/1_manage/group/group_file_template_spec.rb": 74.34492043599994,
+ "qa/specs/features/browser_ui/1_manage/group/bulk_import_group_spec.rb": 75.80247018900013,
+ "qa/specs/features/browser_ui/2_plan/milestone/assign_milestone_spec.rb": 75.8654343979997,
+ "qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb": 76.87336582600028,
+ "qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb": 82.25273063899976,
+ "qa/specs/features/ee/browser_ui/2_plan/epic/epics_management_spec.rb": 82.48331730200016,
+ "qa/specs/features/browser_ui/1_manage/project/protected_tags_spec.rb": 84.2234556809999,
+ "qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb": 86.64432922500009,
+ "qa/specs/features/ee/browser_ui/1_manage/project/project_templates_spec.rb": 89.27986745599992,
+ "qa/specs/features/ee/browser_ui/4_verify/new_discussion_not_dropping_merge_trains_mr_spec.rb": 90.51838889500004,
+ "qa/specs/features/ee/browser_ui/4_verify/cancelling_merge_request_in_merge_train_spec.rb": 99.40036980900004,
+ "qa/specs/features/ee/browser_ui/1_manage/group/group_audit_logs_1_spec.rb": 99.88996194999982,
+ "qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb": 100.75571312800002,
+ "qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb": 102.73961456400002,
+ "qa/specs/features/ee/browser_ui/4_verify/pipelines_for_merged_results_and_merge_trains_spec.rb": 108.17952484600005,
+ "qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb": 108.78527251000014,
+ "qa/specs/features/ee/browser_ui/1_manage/group/restrict_by_ip_address_spec.rb": 108.98986279500014,
+ "qa/specs/features/ee/browser_ui/3_create/repository/merge_with_code_owner_in_root_group_spec.rb": 109.23582328299972,
+ "qa/specs/features/browser_ui/4_verify/pipeline/update_ci_file_with_pipeline_editor_spec.rb": 117.43055826199998,
+ "qa/specs/features/ee/browser_ui/3_create/repository/push_rules_spec.rb": 120.7805862900002,
+ "qa/specs/features/ee/browser_ui/13_secure/security_reports_spec.rb": 121.40739863099998,
+ "qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb": 121.93682936799996,
+ "qa/specs/features/ee/browser_ui/1_manage/group/group_audit_logs_2_spec.rb": 124.35619795699995,
+ "qa/specs/features/ee/browser_ui/1_manage/instance/instance_audit_logs_spec.rb": 129.314630158,
+ "qa/specs/features/ee/browser_ui/13_secure/vulnerability_management_spec.rb": 132.3623656059999,
+ "qa/specs/features/ee/browser_ui/13_secure/enable_scanning_from_configuration_spec.rb": 135.19990866599983,
+ "qa/specs/features/browser_ui/4_verify/ci_variable/pipeline_with_protected_variable_spec.rb": 136.47575045699978,
+ "qa/specs/features/ee/browser_ui/13_secure/project_security_dashboard_spec.rb": 137.37273152800026,
+ "qa/specs/features/ee/browser_ui/1_manage/project/project_audit_logs_spec.rb": 154.7787124900001,
+ "qa/specs/features/ee/browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb": 161.17543870600002,
+ "qa/specs/features/api/1_manage/bulk_import_group_spec.rb": 167.9717091839998,
+ "qa/specs/features/ee/browser_ui/3_create/repository/merge_with_code_owner_in_subgroup_spec.rb": 192.326786567,
+ "qa/specs/features/browser_ui/1_manage/login/register_spec.rb": 412.09824056499974,
+ "qa/specs/features/ee/browser_ui/3_create/repository/file_locking_spec.rb": 428.72626845000013,
+ "qa/specs/features/api/1_manage/bulk_import_project_spec.rb": 686.55653471,
+ "qa/specs/features/api/1_manage/rate_limits_spec.rb": 923.7095398920001
}
diff --git a/qa/lib/gitlab/page/main/welcome.rb b/qa/lib/gitlab/page/main/welcome.rb
deleted file mode 100644
index a2df1da61c9..00000000000
--- a/qa/lib/gitlab/page/main/welcome.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Page
- module Main
- class Welcome < Chemlab::Page
- path '/users/sign_up/welcome'
-
- button :get_started_button
- end
- end
- end
-end
diff --git a/qa/lib/gitlab/page/main/welcome.stub.rb b/qa/lib/gitlab/page/main/welcome.stub.rb
deleted file mode 100644
index a10e697bcbf..00000000000
--- a/qa/lib/gitlab/page/main/welcome.stub.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Page
- module Main
- module Welcome
- # @note Defined as +button :get_started_button+
- # Clicks +get_started_button+
- def get_started_button
- # This is a stub, used for indexing. The method is dynamically generated.
- end
-
- # @example
- # Gitlab::Page::Main::Welcome.perform do |welcome|
- # expect(welcome.get_started_button_element).to exist
- # end
- # @return [Watir::Button] The raw +Button+ element
- def get_started_button_element
- # This is a stub, used for indexing. The method is dynamically generated.
- end
-
- # @example
- # Gitlab::Page::Main::Welcome.perform do |welcome|
- # expect(welcome).to be_get_started_button
- # end
- # @return [Boolean] true if the +get_started_button+ element is present on the page
- def get_started_button?
- # This is a stub, used for indexing. The method is dynamically generated.
- end
- end
- end
- end
-end
diff --git a/qa/qa.rb b/qa/qa.rb
index 1cdf6bc89ca..703ed4ffe1d 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -2,7 +2,7 @@
Encoding.default_external = 'UTF-8'
-require_relative '../lib/gitlab'
+require_relative '../lib/gitlab_edition'
require_relative '../lib/gitlab/utils'
require_relative '../config/initializers/0_inject_enterprise_edition_module'
diff --git a/qa/qa/fixtures/metrics_dashboards/templating.yml b/qa/qa/fixtures/metrics_dashboards/templating.yml
index e06e7cc1247..847eba59bd2 100644
--- a/qa/qa/fixtures/metrics_dashboards/templating.yml
+++ b/qa/qa/fixtures/metrics_dashboards/templating.yml
@@ -40,4 +40,4 @@ panel_groups:
- id: pod_memory_working_set1
query_range: 'container_memory_working_set_bytes{pod_name=~"{{pod_name2}}"}/1024/1024'
unit: "MiB"
- label: pod_name
+ label: pod_name \ No newline at end of file
diff --git a/qa/qa/flow/login.rb b/qa/qa/flow/login.rb
index 5f7e0227ac5..b60f74fe9bf 100644
--- a/qa/qa/flow/login.rb
+++ b/qa/qa/flow/login.rb
@@ -6,8 +6,6 @@ module QA
module_function
def while_signed_in(as: nil, address: :gitlab, admin: false)
- Page::Main::Menu.perform(&:sign_out_if_signed_in)
-
sign_in(as: as, address: address, admin: admin)
result = yield
@@ -23,9 +21,10 @@ module QA
end
def sign_in(as: nil, address: :gitlab, skip_page_validation: false, admin: false)
+ Page::Main::Login.perform { |p| p.redirect_to_login_page(address) }
+
unless Page::Main::Login.perform(&:on_login_page?)
Page::Main::Menu.perform(&:sign_out) if Page::Main::Menu.perform(&:signed_in?)
- Runtime::Browser.visit(address, Page::Main::Login)
end
Page::Main::Login.perform do |login|
diff --git a/qa/qa/flow/sign_up.rb b/qa/qa/flow/sign_up.rb
index a2a62371092..ec7886ef969 100644
--- a/qa/qa/flow/sign_up.rb
+++ b/qa/qa/flow/sign_up.rb
@@ -26,9 +26,12 @@ module QA
sign_up.click_new_user_register_button
end
- Page::Registration::Welcome.perform(&:click_get_started_button_if_available)
+ Flow::UserOnboarding.onboard_user
success = if user.expect_fabrication_success
+ # In development env and .com the user is asked to create a group and a project which can be skipped for
+ # the purpose of signing up
+ Runtime::Browser.visit(:gitlab, Page::Dashboard::Welcome)
Page::Main::Menu.perform(&:has_personal_area?)
else
Page::Main::Menu.perform(&:not_signed_in?)
diff --git a/qa/qa/flow/user_onboarding.rb b/qa/qa/flow/user_onboarding.rb
new file mode 100644
index 00000000000..066e1878869
--- /dev/null
+++ b/qa/qa/flow/user_onboarding.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module QA
+ module Flow
+ module UserOnboarding
+ module_function
+
+ def onboard_user
+ Page::Registration::Welcome.perform do |welcome_page|
+ if welcome_page.has_get_started_button?
+ welcome_page.select_role('Other')
+ welcome_page.choose_setup_for_company_if_available
+ welcome_page.click_get_started_button
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb
index 69f58dcb8a5..526dd25ccc9 100644
--- a/qa/qa/page/base.rb
+++ b/qa/qa/page/base.rb
@@ -386,6 +386,10 @@ module QA
end
end
+ def current_host
+ URI(page.current_url).host
+ end
+
def self.path
raise NotImplementedError
end
diff --git a/qa/qa/page/component/confirm_modal.rb b/qa/qa/page/component/confirm_modal.rb
index 25eea8e0d93..a90be76c879 100644
--- a/qa/qa/page/component/confirm_modal.rb
+++ b/qa/qa/page/component/confirm_modal.rb
@@ -8,12 +8,6 @@ module QA
def self.included(base)
super
-
- base.view 'app/views/shared/_confirm_modal.html.haml' do
- element :confirm_modal
- element :confirm_input
- element :confirm_button
- end
end
def fill_confirmation_text(text)
diff --git a/qa/qa/page/component/invite_members_modal.rb b/qa/qa/page/component/invite_members_modal.rb
index fecd61fb410..ca6862ccb02 100644
--- a/qa/qa/page/component/invite_members_modal.rb
+++ b/qa/qa/page/component/invite_members_modal.rb
@@ -47,37 +47,43 @@ module QA
fill_element :members_token_select_input, username
Support::WaitForRequests.wait_for_requests
click_button username
-
- # Guest option is selected by default, skipping these steps if desired option is 'Guest'
- unless access_level == 'Guest'
- click_element :access_level_dropdown
- click_button access_level
- end
-
- click_element :invite_button
+ set_access_level(access_level)
end
- Support::WaitForRequests.wait_for_requests
-
- page.refresh
+ send_invite
end
- def invite_group(group_name, group_access = Resource::Members::AccessLevel::GUEST)
+ def invite_group(group_name, access_level = 'Guest')
open_invite_group_modal
- fill_element :access_level_dropdown, with: group_access
+ within_element(:invite_members_modal_content) do
+ click_button 'Select a group'
- click_button 'Select a group'
- fill_element :group_select_dropdown_search_field, group_name
+ # Helps stabilize race condition with concurrent group API calls while searching
+ # TODO: Replace with `fill_element :group_select_dropdown_search_field, group_name` when this bug is resolved: https://gitlab.com/gitlab-org/gitlab/-/issues/349379
+ send_keys_to_element(:group_select_dropdown_search_field, group_name)
- Support::WaitForRequests.wait_for_requests
+ Support::WaitForRequests.wait_for_requests
+ click_button group_name
+ set_access_level(access_level)
+ end
- click_button group_name
+ send_invite
+ end
- click_element :invite_button
+ private
- Support::WaitForRequests.wait_for_requests
+ def set_access_level(access_level)
+ # Guest option is selected by default, skipping these steps if desired option is 'Guest'
+ unless access_level == 'Guest'
+ click_element :access_level_dropdown
+ click_button access_level
+ end
+ end
+ def send_invite
+ click_element :invite_button
+ Support::WaitForRequests.wait_for_requests
page.refresh
end
end
diff --git a/qa/qa/page/dashboard/welcome.rb b/qa/qa/page/dashboard/welcome.rb
index b54205780d9..6f645e168c7 100644
--- a/qa/qa/page/dashboard/welcome.rb
+++ b/qa/qa/page/dashboard/welcome.rb
@@ -11,6 +11,10 @@ module QA
def has_welcome_title?(text)
has_element?(:welcome_title_content, text: text)
end
+
+ def self.path
+ '/'
+ end
end
end
end
diff --git a/qa/qa/page/file/show.rb b/qa/qa/page/file/show.rb
index 730c5a88515..e54c3e0cd07 100644
--- a/qa/qa/page/file/show.rb
+++ b/qa/qa/page/file/show.rb
@@ -23,8 +23,26 @@ module QA
element :delete_file_button, "button_tag 'Delete file'" # rubocop:disable QA/ElementWithPattern
end
+ view 'app/assets/javascripts/vue_shared/components/web_ide_link.vue' do
+ element :edit_button
+ end
+
+ view 'app/assets/javascripts/vue_shared/components/actions_button.vue' do
+ element :action_dropdown
+ element :edit_menu_item, ':data-qa-selector="`${action.key}_menu_item`"' # rubocop:disable QA/ElementWithPattern
+ end
+
def click_edit
- click_on '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'
+ end
end
def click_delete
diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb
index 5cba9d4bce4..f004107d7bd 100644
--- a/qa/qa/page/main/login.rb
+++ b/qa/qa/page/main/login.rb
@@ -156,6 +156,11 @@ module QA
sign_in_using_credentials(user: user)
end
+ def redirect_to_login_page(address)
+ desired_host = URI(Runtime::Scenario.send("#{address}_address")).host
+ Runtime::Browser.visit(address, Page::Main::Login) if desired_host != current_host
+ end
+
private
def sign_in_using_gitlab_credentials(user:, skip_page_validation: false)
diff --git a/qa/qa/page/project/branches/show.rb b/qa/qa/page/project/branches/show.rb
index afec0e27a0b..a19fcf8ec6e 100644
--- a/qa/qa/page/project/branches/show.rb
+++ b/qa/qa/page/project/branches/show.rb
@@ -14,7 +14,6 @@ module QA
end
view 'app/views/projects/branches/_branch.html.haml' do
- element :remove_btn
element :branch_name
end
diff --git a/qa/qa/page/project/members.rb b/qa/qa/page/project/members.rb
index eeb589d6ca8..1102abd6646 100644
--- a/qa/qa/page/project/members.rb
+++ b/qa/qa/page/project/members.rb
@@ -41,6 +41,11 @@ module QA
click_button 'Remove group'
end
end
+
+ def has_group?(group_name)
+ click_element :groups_list_tab
+ has_element?(:group_row, text: group_name)
+ end
end
end
end
diff --git a/qa/qa/page/project/new.rb b/qa/qa/page/project/new.rb
index 5ff52527774..42baf1f3f87 100644
--- a/qa/qa/page/project/new.rb
+++ b/qa/qa/page/project/new.rb
@@ -14,7 +14,6 @@ module QA
view 'app/views/projects/_new_project_fields.html.haml' do
element :initialize_with_readme_checkbox
element :initialize_with_sast_checkbox
- element :project_namespace_field, 'namespaces_options' # rubocop:disable QA/ElementWithPattern
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
diff --git a/qa/qa/page/project/packages/show.rb b/qa/qa/page/project/packages/show.rb
index 4872c0bc705..5ba9ad7df40 100644
--- a/qa/qa/page/project/packages/show.rb
+++ b/qa/qa/page/project/packages/show.rb
@@ -5,7 +5,7 @@ module QA
module Project
module Packages
class Show < QA::Page::Base
- view 'app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue' do
+ view 'app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue' do
element :delete_button
element :delete_modal_button
element :package_information_content
diff --git a/qa/qa/page/project/pipeline_editor/show.rb b/qa/qa/page/project/pipeline_editor/show.rb
index e430884ea08..8289039d4c5 100644
--- a/qa/qa/page/project/pipeline_editor/show.rb
+++ b/qa/qa/page/project/pipeline_editor/show.rb
@@ -24,6 +24,27 @@ module QA
element :source_editor_container, require: true
end
+ view 'app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue' do
+ element :pipeline_id_content
+ end
+
+ view 'app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue' do
+ element :commit_changes_button
+ end
+
+ view 'app/assets/javascripts/pipeline_editor/components/header/validation_segment.vue' do
+ element :validation_message_content
+ end
+
+ view 'app/assets/javascripts/pipelines/components/pipeline_graph/pipeline_graph.vue' do
+ element :stage_container
+ element :job_container
+ end
+
+ view 'app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue' do
+ element :file_editor_container
+ end
+
def initialize
super
@@ -50,8 +71,70 @@ module QA
find_element(:source_editor_container).text
end
+ def write_to_editor(text)
+ find_element(:source_editor_container).fill_in(with: text)
+ end
+
+ def submit_changes
+ click_element(:commit_changes_button)
+
+ wait_for_requests
+ end
+
+ def set_target_branch(name)
+ find_element(:target_branch_field).fill_in(with: name)
+ end
+
+ def current_branch
+ find_element(:branch_selector_button).text
+ end
+
+ def pipeline_id
+ find_element(:pipeline_id_content).text.delete!('#').to_i
+ end
+
+ def ci_syntax_validate_message
+ find_element(:validation_message_content).text
+ end
+
+ def go_to_visualize_tab
+ go_to_tab('Visualize')
+ end
+
+ def go_to_lint_tab
+ go_to_tab('Lint')
+ end
+
+ def go_to_view_merged_yaml_tab
+ go_to_tab('View merged YAML')
+ end
+
+ def has_source_editor?
+ has_element?(:source_editor_container)
+ end
+
+ def has_stage?(name)
+ all_elements(:stage_container, minimum: 1).any? { |item| item.text.match(/#{name}/i) }
+ end
+
+ def has_job?(name)
+ all_elements(:job_container, minimum: 1).any? { |item| item.text.match(/#{name}/i) }
+ end
+
+ def tab_alert_message
+ within_element(:file_editor_container) do
+ find('.gl-alert-body').text
+ end
+ end
+
private
+ def go_to_tab(name)
+ within_element(:file_editor_container) do
+ find('.nav-item', text: name).click
+ end
+ end
+
# If the page thinks user has never opened pipeline editor before
# It will expand pipeline editor sidebar by default
# Collapse the sidebar if it is expanded
diff --git a/qa/qa/page/project/secure/configuration_form.rb b/qa/qa/page/project/secure/configuration_form.rb
index 3e89a57e870..fa1fad44273 100644
--- a/qa/qa/page/project/secure/configuration_form.rb
+++ b/qa/qa/page/project/secure/configuration_form.rb
@@ -8,6 +8,10 @@ module QA
include QA::Page::Component::Select2
include QA::Page::Settings::Common
+ view 'app/assets/javascripts/security_configuration/components/app.vue' do
+ element :security_configuration_history_link
+ end
+
view 'app/assets/javascripts/security_configuration/components/feature_card.vue' do
element :dependency_scanning_status, "`${feature.type}_status`" # rubocop:disable QA/ElementWithPattern
element :sast_status, "`${feature.type}_status`" # rubocop:disable QA/ElementWithPattern
@@ -15,6 +19,22 @@ module QA
element :dependency_scanning_mr_button, "`${feature.type}_mr_button`" # rubocop:disable QA/ElementWithPattern
end
+ view 'app/assets/javascripts/security_configuration/components/auto_dev_ops_alert.vue' do
+ element :autodevops_container
+ end
+
+ def has_security_configuration_history_link?
+ has_element?(:security_configuration_history_link)
+ end
+
+ def has_no_security_configuration_history_link?
+ has_no_element?(:security_configuration_history_link)
+ end
+
+ def click_security_configuration_history_link
+ click_element(:security_configuration_history_link)
+ end
+
def click_sast_enable_button
click_element(:sast_enable_button)
end
@@ -29,11 +49,37 @@ module QA
end
end
+ def has_no_sast_status?(status_text)
+ within_element(:sast_status) do
+ has_no_text?(status_text)
+ end
+ end
+
def has_dependency_scanning_status?(status_text)
within_element(:dependency_scanning_status) do
has_text?(status_text)
end
end
+
+ def has_no_dependency_scanning_status?(status_text)
+ within_element(:dependency_scanning_status) do
+ has_no_text?(status_text)
+ end
+ end
+
+ def has_auto_devops_container?
+ has_element?(:autodevops_container)
+ end
+
+ def has_no_auto_devops_container?
+ has_no_element?(:autodevops_container)
+ end
+
+ def has_auto_devops_container_description?
+ within_element(:autodevops_container) do
+ has_text?('Quickly enable all continuous testing and compliance tools by enabling Auto DevOps')
+ end
+ end
end
end
end
diff --git a/qa/qa/page/project/settings/visibility_features_permissions.rb b/qa/qa/page/project/settings/visibility_features_permissions.rb
index 1d6686ae360..60cea6de7f5 100644
--- a/qa/qa/page/project/settings/visibility_features_permissions.rb
+++ b/qa/qa/page/project/settings/visibility_features_permissions.rb
@@ -5,14 +5,9 @@ module QA
module Project
module Settings
class VisibilityFeaturesPermissions < Page::Base
- include QA::Page::Component::Select2
-
- view 'app/views/projects/edit.html.haml' do
- element :visibility_features_permissions_save_button
- end
-
view 'app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue' do
element :project_visibility_dropdown
+ element :visibility_features_permissions_save_button
end
def set_project_visibility(visibility)
diff --git a/qa/qa/page/registration/sign_up.rb b/qa/qa/page/registration/sign_up.rb
index 6d1b9cb3615..4fedc05c702 100644
--- a/qa/qa/page/registration/sign_up.rb
+++ b/qa/qa/page/registration/sign_up.rb
@@ -16,10 +16,6 @@ module QA
element :new_user_username_field
end
- view 'app/views/registrations/welcome/show.html.haml' do
- element :get_started_button
- end
-
def fill_new_user_first_name_field(first_name)
fill_element :new_user_first_name_field, first_name
end
diff --git a/qa/qa/page/registration/welcome.rb b/qa/qa/page/registration/welcome.rb
index ff22e62b63e..660b33b4f5b 100644
--- a/qa/qa/page/registration/welcome.rb
+++ b/qa/qa/page/registration/welcome.rb
@@ -6,14 +6,25 @@ module QA
class Welcome < Page::Base
view 'app/views/registrations/welcome/show.html.haml' do
element :get_started_button
+ element :role_dropdown
end
- def click_get_started_button_if_available
- if has_element?(:get_started_button)
- Support::Retrier.retry_until do
- click_element :get_started_button
- has_no_element?(:get_started_button)
- end
+ def has_get_started_button?
+ has_element?(:get_started_button)
+ end
+
+ def select_role(role)
+ select_element(:role_dropdown, role)
+ end
+
+ def choose_setup_for_company_if_available
+ # Only implemented in EE
+ end
+
+ def click_get_started_button
+ Support::Retrier.retry_until do
+ click_element :get_started_button
+ has_no_element?(:get_started_button)
end
end
end
diff --git a/qa/qa/page/trials/new.rb b/qa/qa/page/trials/new.rb
index 268f3b71717..6e9d7fce688 100644
--- a/qa/qa/page/trials/new.rb
+++ b/qa/qa/page/trials/new.rb
@@ -6,17 +6,13 @@ module QA
class New < Chemlab::Page
path '/-/trials/new'
- # TODO: Supplant with data-qa-selectors
- text_field :first_name, id: 'first_name'
- text_field :last_name, id: 'last_name'
- text_field :company_name, id: 'company_name'
- select :number_of_employees, id: 'company_size'
- text_field :telephone_number, id: 'phone_number'
- text_field :number_of_users, id: 'number_of_users'
-
- select :country, id: 'country_select'
-
- button :continue, value: 'Continue'
+ text_field :first_name
+ text_field :last_name
+ text_field :company_name
+ select :number_of_employees
+ text_field :telephone_number
+ select :country
+ button :continue
end
end
end
diff --git a/qa/qa/resource/api_fabricator.rb b/qa/qa/resource/api_fabricator.rb
index 6315ef0bd22..4c77c515cfd 100644
--- a/qa/qa/resource/api_fabricator.rb
+++ b/qa/qa/resource/api_fabricator.rb
@@ -63,6 +63,10 @@ module QA
process_api_response(parse_body(response))
end
+ def api_fabrication_http_method
+ @api_fabrication_http_method ||= :post
+ end
+
private
def resource_web_url(resource)
@@ -85,6 +89,8 @@ module QA
raise ResourceNotFoundError, "Resource at #{request.mask_url} could not be found (#{response.code}): `#{response}`."
end
+ @api_fabrication_http_method = :get # rubocop:disable Gitlab/ModuleWithInstanceVariables
+
response
end
diff --git a/qa/qa/resource/base.rb b/qa/qa/resource/base.rb
index 640d2a8f06e..0112e766cf0 100644
--- a/qa/qa/resource/base.rb
+++ b/qa/qa/resource/base.rb
@@ -71,34 +71,49 @@ module QA
resource_web_url = yield
resource.web_url = resource_web_url
+ QA::Tools::TestResourceDataProcessor.collect(resource, resource_identifier(resource))
+
resource
end
+ def resource_identifier(resource)
+ if resource.respond_to?(:username) && resource.username
+ "with username '#{resource.username}'"
+ elsif resource.respond_to?(:full_path) && resource.full_path
+ "with full_path '#{resource.full_path}'"
+ elsif resource.respond_to?(:name) && resource.name
+ "with name '#{resource.name}'"
+ elsif resource.respond_to?(:id) && resource.id
+ "with id '#{resource.id}'"
+ elsif resource.respond_to?(:iid) && resource.iid
+ "with iid '#{resource.iid}'"
+ end
+ rescue QA::Resource::Base::NoValueError
+ nil
+ end
+
def log_fabrication(method, resource, parents, args)
start = Time.now
Support::FabricationTracker.start_fabrication
result = yield.tap do
fabrication_time = Time.now - start
- resource_identifier = begin
- if resource.respond_to?(:username) && resource.username
- "with username '#{resource.username}'"
- elsif resource.respond_to?(:full_path) && resource.full_path
- "with full_path '#{resource.full_path}'"
- elsif resource.respond_to?(:name) && resource.name
- "with name '#{resource.name}'"
- elsif resource.respond_to?(:id) && resource.id
- "with id '#{resource.id}'"
- end
- rescue QA::Resource::Base::NoValueError
- nil
- end
+
+ fabrication_http_method = if resource.api_fabrication_http_method == :get
+ if self.include?(Reusable)
+ "Retrieved for reuse"
+ else
+ "Retrieved"
+ end
+ else
+ "Built"
+ end
Support::FabricationTracker.save_fabrication(:"#{method}_fabrication", fabrication_time)
Runtime::Logger.debug do
msg = ["==#{'=' * parents.size}>"]
- msg << "Built a #{name}"
- msg << resource_identifier if resource_identifier
+ msg << "#{fabrication_http_method} a #{name}"
+ msg << resource_identifier(resource) if resource_identifier(resource)
msg << "as a dependency of #{parents.last}" if parents.any?
msg << "via #{method}"
msg << "in #{fabrication_time} seconds"
@@ -156,11 +171,11 @@ module QA
raise NotImplementedError
end
- def visit!
+ def visit!(skip_resp_code_check: false)
Runtime::Logger.debug(%(Visiting #{self.class.name} at "#{web_url}"))
# Just in case an async action is not yet complete
- Support::WaitForRequests.wait_for_requests
+ Support::WaitForRequests.wait_for_requests(skip_resp_code_check: skip_resp_code_check)
Support::Retrier.retry_until do
visit(web_url)
@@ -168,7 +183,7 @@ module QA
end
# Wait until the new page is ready for us to interact with it
- Support::WaitForRequests.wait_for_requests
+ Support::WaitForRequests.wait_for_requests(skip_resp_code_check: skip_resp_code_check)
end
def populate(*attribute_names)
@@ -179,6 +194,30 @@ module QA
QA::Support::Waiter.wait_until(max_duration: max_duration, sleep_interval: sleep_interval, &block)
end
+ # Object comparison
+ #
+ # @param [QA::Resource::Base] other
+ # @return [Boolean]
+ def ==(other)
+ other.is_a?(self.class) && comparable == other.comparable
+ end
+
+ # Override inspect for a better rspec failure diff output
+ #
+ # @return [String]
+ def inspect
+ JSON.pretty_generate(comparable)
+ end
+
+ protected
+
+ # Custom resource comparison logic using resource attributes from api_resource
+ #
+ # @return [Hash]
+ def comparable
+ raise("comparable method needs to be implemented in order to compare resources via '=='")
+ end
+
private
def attribute_value(name, block)
diff --git a/qa/qa/resource/bulk_import_group.rb b/qa/qa/resource/bulk_import_group.rb
index e8dc2d291b8..a22529152e1 100644
--- a/qa/qa/resource/bulk_import_group.rb
+++ b/qa/qa/resource/bulk_import_group.rb
@@ -3,18 +3,21 @@
module QA
module Resource
class BulkImportGroup < Group
- attributes :source_group_path,
+ attributes :source_group,
+ :destination_group,
:import_id
- attribute :destination_group_path do
- source_group_path
- end
-
attribute :access_token do
api_client.personal_access_token
end
- alias_method :path, :source_group_path
+ # In most cases we will want to set path the same as source group
+ # but it can be set to a custom name as well when imported via API
+ attribute :destination_group_path do
+ source_group.path
+ end
+ # Can't define path as attribue since @path is set in base class initializer
+ alias_method :path, :destination_group_path
delegate :gitlab_address, to: 'QA::Runtime::Scenario'
@@ -51,9 +54,9 @@ module QA
entities: [
{
source_type: 'group_entity',
- source_full_path: source_group_path,
+ source_full_path: source_group.full_path,
destination_name: destination_group_path,
- destination_namespace: sandbox.path
+ destination_namespace: sandbox.full_path
}
]
}
diff --git a/qa/qa/resource/group_badge.rb b/qa/qa/resource/group_badge.rb
index fd76f066e8b..3719b502b93 100644
--- a/qa/qa/resource/group_badge.rb
+++ b/qa/qa/resource/group_badge.rb
@@ -39,27 +39,12 @@ module QA
# @return [String]
def resource_web_url(_resource); end
- # Object comparison
- #
- # @param [QA::Resource::GroupBadge] other
- # @return [Boolean]
- def ==(other)
- other.is_a?(GroupBadge) && comparable_badge == other.comparable_badge
- end
-
- # Override inspect for a better rspec failure diff output
- #
- # @return [String]
- def inspect
- JSON.pretty_generate(comparable_badge)
- end
-
protected
# Return subset of fields for comparing badges
#
# @return [Hash]
- def comparable_badge
+ def comparable
reload! unless api_response
api_response.slice(
diff --git a/qa/qa/resource/group_base.rb b/qa/qa/resource/group_base.rb
index 19bb5ea00d7..9f492a046db 100644
--- a/qa/qa/resource/group_base.rb
+++ b/qa/qa/resource/group_base.rb
@@ -123,18 +123,12 @@ module QA
end
# Object comparison
+ # Override to make sure we are comparing descendands of GroupBase
#
# @param [QA::Resource::GroupBase] other
# @return [Boolean]
def ==(other)
- other.is_a?(GroupBase) && comparable_group == other.comparable_group
- end
-
- # Override inspect for a better rspec failure diff output
- #
- # @return [String]
- def inspect
- JSON.pretty_generate(comparable_group)
+ other.is_a?(GroupBase) && comparable == other.comparable
end
protected
@@ -142,7 +136,7 @@ module QA
# Return subset of fields for comparing groups
#
# @return [Hash]
- def comparable_group
+ def comparable
reload! if api_response.nil?
api_resource.slice(
diff --git a/qa/qa/resource/group_milestone.rb b/qa/qa/resource/group_milestone.rb
index 880ca2b9721..b9ec53e929c 100644
--- a/qa/qa/resource/group_milestone.rb
+++ b/qa/qa/resource/group_milestone.rb
@@ -56,27 +56,12 @@ module QA
end
end
- # Object comparison
- #
- # @param [QA::Resource::GroupMilestone] other
- # @return [Boolean]
- def ==(other)
- other.is_a?(GroupMilestone) && comparable_milestone == other.comparable_milestone
- end
-
- # Override inspect for a better rspec failure diff output
- #
- # @return [String]
- def inspect
- JSON.pretty_generate(comparable_milestone)
- end
-
protected
# Return subset of fields for comparing milestones
#
# @return [Hash]
- def comparable_milestone
+ def comparable
reload! unless api_response
api_response.slice(
diff --git a/qa/qa/resource/issue.rb b/qa/qa/resource/issue.rb
index 344f177932f..1e38de97c1e 100644
--- a/qa/qa/resource/issue.rb
+++ b/qa/qa/resource/issue.rb
@@ -3,7 +3,7 @@
module QA
module Resource
class Issue < Base
- attr_writer :description, :milestone, :template, :weight
+ attr_writer :milestone, :template, :weight
attribute :project do
Project.fabricate! do |resource|
@@ -95,19 +95,13 @@ module QA
)
end
- # Object comparison
+ # Create a new comment
#
- # @param [QA::Resource::Issue] other
- # @return [Boolean]
- def ==(other)
- other.is_a?(Issue) && comparable_issue == other.comparable_issue
- end
-
- # Override inspect for a better rspec failure diff output
- #
- # @return [String]
- def inspect
- JSON.pretty_generate(comparable_issue)
+ # @param [String] body
+ # @param [Boolean] confidential
+ # @return [Hash]
+ def add_comment(body:, confidential: false)
+ api_post_to(api_comments_path, body: body, confidential: confidential)
end
protected
@@ -115,7 +109,7 @@ module QA
# Return subset of fields for comparing issues
#
# @return [Hash]
- def comparable_issue
+ def comparable
reload! if api_response.nil?
api_resource.slice(
diff --git a/qa/qa/resource/label_base.rb b/qa/qa/resource/label_base.rb
index b1af0e23561..855e41af8bb 100644
--- a/qa/qa/resource/label_base.rb
+++ b/qa/qa/resource/label_base.rb
@@ -49,27 +49,12 @@ module QA
}
end
- # Object comparison
- #
- # @param [QA::Resource::GroupBase] other
- # @return [Boolean]
- def ==(other)
- other.is_a?(LabelBase) && comparable_label == other.comparable_label
- end
-
- # Override inspect for a better rspec failure diff output
- #
- # @return [String]
- def inspect
- JSON.pretty_generate(comparable_label)
- end
-
protected
# Return subset of fields for comparing labels
#
# @return [Hash]
- def comparable_label
+ def comparable
reload! unless api_response
api_response.slice(
diff --git a/qa/qa/resource/merge_request.rb b/qa/qa/resource/merge_request.rb
index ba63e0823f0..685cccea02d 100644
--- a/qa/qa/resource/merge_request.rb
+++ b/qa/qa/resource/merge_request.rb
@@ -6,11 +6,13 @@ module QA
attr_accessor :approval_rules,
:source_branch,
:target_new_branch,
+ :update_existing_file,
:assignee,
:milestone,
:labels,
:file_name,
:file_content
+
attr_writer :no_preparation,
:wait_for_merge,
:template
@@ -25,6 +27,8 @@ module QA
attribute :project do
Project.fabricate_via_api! do |resource|
resource.name = 'project-with-merge-request'
+ resource.initialize_with_readme = true
+ resource.api_client = api_client
end
end
@@ -33,22 +37,27 @@ module QA
end
attribute :target do
- Repository::ProjectPush.fabricate! do |resource|
+ Repository::Commit.fabricate_via_api! do |resource|
resource.project = project
- resource.branch_name = target_branch
- resource.new_branch = target_new_branch
- resource.remote_branch = target_branch
+ resource.api_client = api_client
+ resource.commit_message = 'This is a test commit'
+ resource.add_files([{ 'file_path': "file-#{SecureRandom.hex(8)}.txt", 'content': 'MR init' }])
+ resource.branch = target_branch
+
+ resource.start_branch = project.default_branch if target_branch != project.default_branch
end
end
attribute :source do
- Repository::ProjectPush.fabricate! do |resource|
+ Repository::Commit.fabricate_via_api! do |resource|
resource.project = project
- resource.branch_name = target_branch
- resource.remote_branch = source_branch
- resource.new_branch = false
- resource.file_name = file_name
- resource.file_content = file_content
+ resource.api_client = api_client
+ resource.commit_message = 'This is a test commit'
+ resource.branch = source_branch
+ resource.start_branch = target_branch
+
+ files = [{ 'file_path': file_name, 'content': file_content }]
+ update_existing_file ? resource.update_files(files) : resource.add_files(files)
end
end
@@ -63,6 +72,7 @@ module QA
@file_name = "added_file-#{SecureRandom.hex(8)}.txt"
@file_content = "File Added"
@target_new_branch = true
+ @update_existing_file = false
@no_preparation = false
@wait_for_merge = true
end
@@ -168,27 +178,18 @@ module QA
)
end
- # Object comparison
- #
- # @param [QA::Resource::MergeRequest] other
- # @return [Boolean]
- def ==(other)
- other.is_a?(MergeRequest) && comparable_mr == other.comparable_mr
- end
-
- # Override inspect for a better rspec failure diff output
+ # Add mr comment
#
- # @return [String]
- def inspect
- JSON.pretty_generate(comparable_mr)
+ # @param [String] body
+ # @return [Hash]
+ def add_comment(body)
+ api_post_to(api_comments_path, body: body)
end
- protected
-
# Return subset of fields for comparing merge requests
#
# @return [Hash]
- def comparable_mr
+ def comparable
reload! if api_response.nil?
api_resource.except(
@@ -197,7 +198,9 @@ module QA
:project_id,
:source_project_id,
:target_project_id,
+ :merge_status,
# these can differ depending on user fetching mr
+ :user,
:subscribed,
:first_contribution
).merge({ references: api_resource[:references].except(:full) })
@@ -211,8 +214,24 @@ module QA
super(api_resource)
end
+ # Create source and target and commits if necessary
+ #
+ # @return [void]
def populate_target_and_source_if_required
- populate(:target, :source) unless @no_preparation
+ return if @no_preparation
+
+ populate(:target) if create_target?
+ populate(:source)
+ end
+
+ # Check if target needs to be created
+ #
+ # Return false if project was already initialized and mr target is default branch
+ # Return false if target_new_branch is explicitly set to false
+ #
+ # @return [Boolean]
+ def create_target?
+ !(project.initialize_with_readme && target_branch == project.default_branch) && target_new_branch
end
end
end
diff --git a/qa/qa/resource/project.rb b/qa/qa/resource/project.rb
index d3c1e91f358..0750ea49224 100644
--- a/qa/qa/resource/project.rb
+++ b/qa/qa/resource/project.rb
@@ -107,32 +107,6 @@ module QA
super
end
- def has_file?(file_path)
- response = repository_tree
-
- raise ResourceNotFoundError, (response[:message]).to_s if response.is_a?(Hash) && response.has_key?(:message)
-
- response.any? { |file| file[:path] == file_path }
- end
-
- def has_branch?(branch)
- has_branches?(Array(branch))
- end
-
- def has_branches?(branches)
- branches.all? do |branch|
- response = get(request_url("#{api_repository_branches_path}/#{branch}"))
- response.code == HTTP_STATUS_OK
- end
- end
-
- def has_tags?(tags)
- tags.all? do |tag|
- response = get(request_url("#{api_repository_tags_path}/#{tag}"))
- response.code == HTTP_STATUS_OK
- end
- end
-
def api_get_path
"/projects/#{CGI.escape(path_with_namespace)}"
end
@@ -237,6 +211,32 @@ module QA
post_body
end
+ def has_file?(file_path)
+ response = repository_tree
+
+ raise ResourceNotFoundError, (response[:message]).to_s if response.is_a?(Hash) && response.has_key?(:message)
+
+ response.any? { |file| file[:path] == file_path }
+ end
+
+ def has_branch?(branch)
+ has_branches?(Array(branch))
+ end
+
+ def has_branches?(branches)
+ branches.all? do |branch|
+ response = get(request_url("#{api_repository_branches_path}/#{branch}"))
+ response.code == HTTP_STATUS_OK
+ end
+ end
+
+ def has_tags?(tags)
+ tags.all? do |tag|
+ response = get(request_url("#{api_repository_tags_path}/#{tag}"))
+ response.code == HTTP_STATUS_OK
+ end
+ end
+
def change_repository_storage(new_storage)
response = put(request_url(api_put_path), repository_storage: new_storage)
@@ -372,27 +372,12 @@ module QA
api_post_to(api_wikis_path, title: title, content: content)
end
- # Object comparison
- #
- # @param [QA::Resource::Project] other
- # @return [Boolean]
- def ==(other)
- other.is_a?(Project) && comparable_project == other.comparable_project
- end
-
- # Override inspect for a better rspec failure diff output
- #
- # @return [String]
- def inspect
- JSON.pretty_generate(comparable_project)
- end
-
protected
# Return subset of fields for comparing projects
#
# @return [Hash]
- def comparable_project
+ def comparable
reload! if api_response.nil?
api_resource.slice(
diff --git a/qa/qa/resource/repository/commit.rb b/qa/qa/resource/repository/commit.rb
index f5dba164de6..54093a5c195 100644
--- a/qa/qa/resource/repository/commit.rb
+++ b/qa/qa/resource/repository/commit.rb
@@ -22,42 +22,7 @@ module QA
def initialize
@commit_message = 'QA Test - Commit message'
- end
-
- def add_files(files)
- validate_files!(files)
-
- @add_files = files
- end
-
- def add_directory(dir)
- raise "Must set directory as a Pathname" unless dir.is_a?(Pathname)
-
- files_to_add = []
-
- dir.each_child do |child|
- case child.ftype?
- when "file"
- files_to_add.append({
- file_path: child.to_s,
- content: child.read
- })
- when "directory"
- add_directory(child)
- else
- continue
- end
- end
-
- validate_files!(files_to_add)
-
- @add_files.merge(files_to_add)
- end
-
- def update_files(files)
- validate_files!(files)
-
- @update_files = files
+ @actions = []
end
# If `actions` are specified, it performs the actions to create,
@@ -72,32 +37,74 @@ module QA
end
def api_get_path
- api_post_path
+ "/projects/#{CGI.escape(project.path_with_namespace)}/repository/commits"
end
def api_post_path
- "/projects/#{CGI.escape(project.path_with_namespace)}/repository/commits"
+ api_get_path
end
def api_post_body
{
- branch: @branch || project.default_branch,
- author_email: @author_email || Runtime::User.default_email,
- author_name: @author_name || Runtime::User.username,
+ branch: branch || project.default_branch,
+ author_email: author_email || api_client.user&.email || Runtime::User.default_email,
+ author_name: author_name || api_client.user&.name || Runtime::User.username,
commit_message: commit_message,
actions: actions
}.merge(new_branch)
end
- def actions
- pending_actions = []
- pending_actions << @add_files.map { |file| file.merge({ action: "create" }) } if @add_files
- pending_actions << @update_files.map { |file| file.merge({ action: "update" }) } if @update_files
- pending_actions.flatten
+ # Add files
+ # Pass in array of new files like, example:
+ # [{ "file_path": "foo/bar", "content": "some content" }]
+ #
+ # @param [Array<Hash>] files
+ # @return [void]
+ def add_files(files)
+ validate_files!(files)
+
+ actions.push(*files.map { |file| file.merge({ action: "create" }) })
+ end
+
+ # Update files
+ # Pass in array of files and it's contents, example:
+ # [{ "file_path": "foo/bar", "content": "some content" }]
+ #
+ # @param [Array<Hash>] files
+ # @return [void]
+ def update_files(files)
+ validate_files!(files)
+
+ actions.push(*files.map { |file| file.merge({ action: "update" }) })
+ end
+
+ # Add all files from directory
+ #
+ # @param [Pathname] dir
+ # @return [void]
+ def add_directory(dir)
+ raise "Must set directory as a Pathname" unless dir.is_a?(Pathname)
+
+ files_to_add = []
+
+ dir.each_child do |child|
+ case child.ftype
+ when "directory"
+ add_directory(child)
+ when "file"
+ files_to_add.push({ file_path: child.basename, content: child.read })
+ else
+ continue
+ end
+ end
+
+ add_files(files_to_add)
end
private
+ attr_reader :actions
+
def validate_files!(files)
if !files.is_a?(Array) ||
files.empty? ||
diff --git a/qa/qa/resource/reusable_group.rb b/qa/qa/resource/reusable_group.rb
new file mode 100644
index 00000000000..a4bd799e85c
--- /dev/null
+++ b/qa/qa/resource/reusable_group.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module QA
+ module Resource
+ class ReusableGroup < Group
+ prepend Reusable
+
+ def initialize
+ super
+
+ @path = "reusable_group"
+ @description = "QA reusable group"
+ @reuse_as = :default_group
+ end
+
+ # Confirms that the group can be reused
+ #
+ # @return [nil] returns nil unless an error is raised
+ def validate_reuse_preconditions
+ unless reused_path_unique?
+ raise ResourceReuseError,
+ "Reusable groups must have the same name. The group reused as #{reuse_as} has the path '#{path}' but it should be '#{self.class.resources[reuse_as].path}'"
+ end
+ end
+
+ # Confirms that reuse of the resource did not change it in a way that breaks later reuse. This raises an error if
+ # the current group path doesn't match the original path.
+ def validate_reuse
+ reload!
+
+ if api_resource[:path] != @path
+ raise ResourceReuseError, "The group now has the path '#{api_resource[:path]}' but it should be '#{path}'"
+ end
+ end
+
+ # Checks if the group is being reused with the same path.
+ #
+ # @return [Boolean] true if the group's path is different from another group with the same reuse symbol (reuse_as)
+ def reused_path_unique?
+ return true unless self.class.resources.key?(reuse_as)
+
+ self.class.resources[reuse_as].path == path
+ end
+
+ # Overrides QA::Resource::Group#remove_via_api! to log a debug message stating that removal will happen after
+ # the suite completes rather than now.
+ #
+ # @return [nil]
+ def remove_via_api!
+ QA::Runtime::Logger.debug("#{self.class.name} - deferring removal until after suite")
+ end
+ end
+ end
+end
diff --git a/qa/qa/resource/reusable_project.rb b/qa/qa/resource/reusable_project.rb
index 6b33bb9d65d..d2dfff8ad56 100644
--- a/qa/qa/resource/reusable_project.rb
+++ b/qa/qa/resource/reusable_project.rb
@@ -5,6 +5,12 @@ module QA
class ReusableProject < Project
prepend Reusable
+ attribute :group do
+ ReusableGroup.fabricate_via_api! do |resource|
+ resource.api_client = api_client
+ end
+ end
+
def initialize
super
diff --git a/qa/qa/resource/user.rb b/qa/qa/resource/user.rb
index ed4ea057484..eab428a61e7 100644
--- a/qa/qa/resource/user.rb
+++ b/qa/qa/resource/user.rb
@@ -98,6 +98,12 @@ module QA
super
end
+ def exists?
+ api_get
+ rescue ResourceNotFoundError
+ false
+ end
+
def api_delete
super
@@ -181,6 +187,15 @@ module QA
)
end
+ protected
+
+ # Compare users by username and password
+ #
+ # @return [Array]
+ def comparable
+ [username, password]
+ end
+
private
def ldap_post_body
diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb
index b73199f1fdd..1679698a9c0 100644
--- a/qa/qa/runtime/env.rb
+++ b/qa/qa/runtime/env.rb
@@ -9,6 +9,7 @@ module QA
extend self
attr_writer :personal_access_token, :admin_personal_access_token
+ attr_accessor :dry_run
ENV_VARIABLES = Gitlab::QA::Runtime::Env::ENV_VARIABLES
@@ -89,6 +90,20 @@ module QA
enabled?(ENV['ACCEPT_INSECURE_CERTS'])
end
+ def running_on_dot_com?
+ uri = URI.parse(Runtime::Scenario.gitlab_address)
+ uri.host.include?('.com')
+ end
+
+ def running_on_dev?
+ uri = URI.parse(Runtime::Scenario.gitlab_address)
+ uri.port != 80 && uri.port != 443
+ end
+
+ def running_on_dev_or_dot_com?
+ running_on_dev? || running_on_dot_com?
+ end
+
def running_in_ci?
ENV['CI'] || ENV['CI_SERVER']
end
@@ -281,9 +296,7 @@ module QA
end
def knapsack?
- return false unless ENV['CI_NODE_TOTAL'].to_i > 1
-
- !!(ENV['KNAPSACK_GENERATE_REPORT'] || ENV['KNAPSACK_REPORT_PATH'] || ENV['KNAPSACK_TEST_FILE_PATTERN'])
+ ENV['CI_NODE_TOTAL'].to_i > 1 && ENV['NO_KNAPSACK'] != "true"
end
def ldap_username
@@ -401,7 +414,7 @@ module QA
end
def gitlab_agentk_version
- ENV.fetch('GITLAB_AGENTK_VERSION', 'v14.4.0')
+ ENV.fetch('GITLAB_AGENTK_VERSION', 'v14.5.0')
end
def transient_trials
@@ -416,6 +429,11 @@ 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
+
private
def remote_grid_credentials
diff --git a/qa/qa/scenario/bootable.rb b/qa/qa/scenario/bootable.rb
index ae180ffce1c..2a9bbbc9fdb 100644
--- a/qa/qa/scenario/bootable.rb
+++ b/qa/qa/scenario/bootable.rb
@@ -31,6 +31,13 @@ module QA
end
next
+ elsif opt.name == :count_examples_only
+ parser.on(opt.arg, opt.desc) do |value|
+ QA::Runtime::Env.dry_run = true
+ Runtime::Scenario.define(opt.name, value)
+ end
+
+ next
end
parser.on(opt.arg, opt.desc) do |value|
diff --git a/qa/qa/scenario/shared_attributes.rb b/qa/qa/scenario/shared_attributes.rb
index ddbe28f05d9..d5d7aedb47f 100644
--- a/qa/qa/scenario/shared_attributes.rb
+++ b/qa/qa/scenario/shared_attributes.rb
@@ -13,6 +13,7 @@ module QA
'Specify FEATURE_FLAGS as comma-separated flag=state pairs, e.g., "flag1=enabled,flag2=disabled"'
attribute :parallel, '--parallel', 'Execute tests in parallel'
attribute :loop, '--loop', 'Execute test repeatedly'
+ attribute :count_examples_only, '--count-examples-only', 'Return the number of examples without running them'
end
end
end
diff --git a/qa/qa/scenario/template.rb b/qa/qa/scenario/template.rb
index 50bb952f1fd..ef634d3ccda 100644
--- a/qa/qa/scenario/template.rb
+++ b/qa/qa/scenario/template.rb
@@ -33,9 +33,15 @@ module QA
Runtime::Scenario.define(:about_address, URI(-> { gitlab_address.host = "about.#{gitlab_address.host}"; gitlab_address }.call).to_s) # rubocop:disable Style/Semicolon
##
+ # Setup knapsack and download latest report
+ #
+ Tools::KnapsackReport.configure! if Runtime::Env.knapsack?
+
+ ##
# Perform before hooks, which are different for CE and EE
#
- Runtime::Release.perform_before_hooks
+
+ Runtime::Release.perform_before_hooks unless Runtime::Env.dry_run
Runtime::Feature.enable(options[:enable_feature]) if options.key?(:enable_feature)
Runtime::Feature.disable(options[:disable_feature]) if options.key?(:disable_feature) && (@feature_enabled = Runtime::Feature.enabled?(options[:disable_feature]))
diff --git a/qa/qa/service/praefect_manager.rb b/qa/qa/service/praefect_manager.rb
index dd4cce5d0b0..7e47049d446 100644
--- a/qa/qa/service/praefect_manager.rb
+++ b/qa/qa/service/praefect_manager.rb
@@ -19,7 +19,7 @@ module QA
@virtual_storage = 'default'
end
- attr_reader :primary_node, :secondary_node, :tertiary_node
+ attr_reader :primary_node, :secondary_node, :tertiary_node, :postgres
# Executes the praefect `dataloss` command.
#
@@ -83,19 +83,19 @@ module QA
def start_node(name)
shell "docker start #{name}"
+ end
+
+ def stop_node(name)
+ shell "docker stop #{name}"
wait_until_shell_command_matches(
"docker inspect -f {{.State.Running}} #{name}",
- /true/,
+ /false/,
sleep_interval: 3,
max_duration: 180,
retry_on_exception: true
)
end
- def stop_node(name)
- shell "docker stop #{name}"
- end
-
def clear_replication_queue
QA::Runtime::Logger.info("Clearing the replication queue")
shell sql_to_docker_exec_cmd(
@@ -174,13 +174,13 @@ module QA
end
def start_all_nodes
+ start_node(@postgres)
start_node(@primary_node)
start_node(@secondary_node)
start_node(@tertiary_node)
start_node(@praefect)
wait_for_health_check_all_nodes
- wait_for_reliable_connection
end
def verify_storage_move(source_storage, destination_storage, repo_type: :project)
@@ -192,21 +192,23 @@ module QA
end
def wait_for_praefect
- wait_until_shell_command_matches(
- "docker inspect -f {{.State.Running}} #{@praefect}",
- /true/,
- sleep_interval: 3,
- max_duration: 180,
- retry_on_exception: true
- )
+ QA::Runtime::Logger.info("Waiting for health check on praefect")
+ Support::Waiter.wait_until(max_duration: 120, sleep_interval: 1, raise_on_failure: true) do
+ # praefect runs a grpc server on port 2305, which will return an error 'Connection refused' until such time it is ready
+ wait_until_shell_command("docker exec #{@gitaly_cluster} bash -c 'curl #{@praefect}:2305'") do |line|
+ break if line.include?('curl: (1) Received HTTP/0.9 when not allowed')
- QA::Runtime::Logger.info('Wait until Praefect starts and is listening')
- wait_until_shell_command_matches(
- "docker exec #{@praefect} bash -c 'cat /var/log/gitlab/praefect/current'",
- /listening at tcp address/
- )
+ QA::Runtime::Logger.debug(line.chomp)
+ end
+ end
+ end
- wait_for_gitaly_check
+ def praefect_sql_ping_healthy?
+ cmd = "docker exec #{@praefect} bash -c '/opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-ping'"
+ wait_until_shell_command(cmd) do |line|
+ QA::Runtime::Logger.debug(line.chomp)
+ break line.include?('praefect sql-ping: OK')
+ end
end
def wait_for_sql_ping
@@ -220,32 +222,7 @@ module QA
['error when pinging healthcheck', 'failed checking node health'].include?(msg)
end
- def wait_for_no_praefect_storage_error
- # If a healthcheck error was the last message to be logged, we'll keep seeing that message even if it's no longer a problem
- # That is, there's no message shown in the Praefect logs when the healthcheck succeeds
- # To work around that we perform the gitaly check rake task, wait a few seconds, and then we confirm that no healthcheck errors appear
-
- QA::Runtime::Logger.info("Checking that Praefect does not report healthcheck errors with its gitaly nodes")
-
- Support::Waiter.wait_until(max_duration: 120) do
- wait_for_gitaly_check
-
- sleep 5
-
- shell "docker exec #{@praefect} bash -c 'tail -n 1 /var/log/gitlab/praefect/current'" do |line|
- QA::Runtime::Logger.debug(line.chomp)
- log = JSON.parse(line)
-
- break true unless health_check_failure_message?(log['msg'])
- rescue JSON::ParserError
- # Ignore lines that can't be parsed as JSON
- end
- end
- end
-
- def wait_for_storage_nodes
- wait_for_no_praefect_storage_error
-
+ def wait_for_dial_nodes_successful
Support::Waiter.repeat_until(max_attempts: 3, max_duration: 120, sleep_interval: 1) do
nodes_confirmed = {
@primary_node => false,
@@ -253,39 +230,55 @@ module QA
@tertiary_node => false
}
- wait_until_shell_command("docker exec #{@praefect} bash -c '/opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dial-nodes'") do |line|
- QA::Runtime::Logger.debug(line.chomp)
+ nodes_confirmed.each_key do |node|
+ nodes_confirmed[node] = true if praefect_dial_nodes_status?(node)
+ end
- nodes_confirmed.each_key do |node|
- nodes_confirmed[node] = true if line =~ /SUCCESS: confirmed Gitaly storage "#{node}" in virtual storages \[#{@virtual_storage}\] is served/
- end
+ nodes_confirmed.values.all?
+ end
+ end
- nodes_confirmed.values.all?
+ def praefect_dial_nodes_status?(node, expect_healthy = true)
+ cmd = "docker exec #{@praefect} bash -c '/opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dial-nodes -timeout 1s'"
+ if expect_healthy
+ wait_until_shell_command_matches(cmd, /SUCCESS: confirmed Gitaly storage "#{node}" in virtual storages \[#{@virtual_storage}\] is served/)
+ else
+ wait_until_shell_command(cmd, raise_on_failure: false) do |line|
+ QA::Runtime::Logger.debug(line.chomp)
+ break true if line.include?('the following nodes are not healthy') && line.include?(node)
end
end
end
def wait_for_health_check_all_nodes
- wait_for_health_check(@primary_node)
- wait_for_health_check(@secondary_node)
- wait_for_health_check(@tertiary_node)
+ wait_for_gitaly_health_check(@primary_node)
+ wait_for_gitaly_health_check(@secondary_node)
+ wait_for_gitaly_health_check(@tertiary_node)
end
- def wait_for_health_check(node)
+ def wait_for_gitaly_health_check(node)
QA::Runtime::Logger.info("Waiting for health check on #{node}")
+ Support::Waiter.wait_until(max_duration: 120, sleep_interval: 1, raise_on_failure: true) do
+ # gitaly runs a grpc server on port 8075, which will return an error 'Connection refused' until such time it is ready
+ wait_until_shell_command("docker exec #{@praefect} bash -c 'curl #{node}:8075'") do |line|
+ break if line.include?('curl: (1) Received HTTP/0.9 when not allowed')
+
+ QA::Runtime::Logger.debug(line.chomp)
+ end
+ end
wait_until_node_is_marked_as_healthy_storage(node)
end
def wait_for_primary_node_health_check
- wait_for_health_check(@primary_node)
+ wait_for_gitaly_health_check(@primary_node)
end
def wait_for_secondary_node_health_check
- wait_for_health_check(@secondary_node)
+ wait_for_gitaly_health_check(@secondary_node)
end
def wait_for_tertiary_node_health_check
- wait_for_health_check(@tertiary_node)
+ wait_for_gitaly_health_check(@tertiary_node)
end
def wait_for_health_check_failure(node)
@@ -311,7 +304,6 @@ module QA
shell sql_to_docker_exec_cmd("SELECT count(*) FROM healthy_storages WHERE storage = '#{node}';") do |line|
result << line
end
- QA::Runtime::Logger.debug("result is ---#{result}")
result[2].to_i == 0
end
end
@@ -322,21 +314,10 @@ module QA
shell sql_to_docker_exec_cmd("SELECT count(*) FROM healthy_storages WHERE storage = '#{node}';") do |line|
result << line
end
-
- QA::Runtime::Logger.debug("result is ---#{result}")
result[2].to_i == 1
end
end
- def wait_for_gitaly_check
- Support::Waiter.wait_until(max_duration: 120, sleep_interval: 1, raise_on_failure: true) do
- wait_until_shell_command("docker exec #{@gitlab} bash -c 'gitlab-rake gitlab:git:fsck'") do |line|
- QA::Runtime::Logger.debug(line.chomp)
- line.include?('Done')
- end
- end
- end
-
# Waits until there is an increase in the number of reads for
# any node compared to the number of reads provided. If a node
# has no pre-read data, consider it to have had zero reads.
@@ -354,12 +335,6 @@ module QA
data.find(-> {{ value: 0 }}) { |item| item[:node] == node }[:value]
end
- def wait_for_reliable_connection
- QA::Runtime::Logger.info('Wait until GitLab and Praefect can communicate reliably')
- wait_for_sql_ping
- wait_for_storage_nodes
- end
-
def wait_for_replication(project_id)
Support::Waiter.wait_until(sleep_interval: 1) { replication_queue_incomplete_count == 0 && replicated?(project_id) }
end
@@ -414,10 +389,34 @@ module QA
end
def remove_tracked_praefect_repository(relative_path, virtual_storage)
- cmd = "gitlab-ctl praefect remove-repository --repository-relative-path #{relative_path} --virtual-storage-name #{virtual_storage}"
+ cmd = "gitlab-ctl praefect remove-repository --repository-relative-path #{relative_path} --virtual-storage-name #{virtual_storage} --apply"
shell "docker exec #{@praefect} bash -c '#{cmd}'"
end
+ # set_replication_factor assigns or unassigns random storage nodes as necessary to reach the desired replication factor for a repository
+ def set_replication_factor(relative_path, virtual_storage, factor)
+ cmd = "/opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml set-replication-factor -repository #{relative_path} -virtual-storage #{virtual_storage} -replication-factor #{factor}"
+ shell "docker exec #{@praefect} bash -c '#{cmd}'"
+ end
+
+ # get_replication_storages retrieves a list of currently assigned storages for a repository
+ def get_replication_storages(relative_path, virtual_storage)
+ storage_repositories = []
+ query = "SELECT storage FROM repository_assignments WHERE relative_path='#{relative_path}' AND virtual_storage='#{virtual_storage}';"
+ shell(sql_to_docker_exec_cmd(query)) { |line| storage_repositories << line.strip }
+ # Returned data from query will be in format
+ # storage
+ # --------
+ # gitaly1
+ # gitaly3
+ # gitaly2
+ # (3 rows)
+ #
+
+ # remove 2 header rows and last 2 rows from query response (including blank line)
+ storage_repositories[2..-3]
+ end
+
def add_repo_to_disk(node, repo_path)
cmd = "GIT_DIR=. git init --initial-branch=main /var/opt/gitlab/git-data/repositories/#{repo_path}"
shell "docker exec --user git #{node} bash -c '#{cmd}'"
@@ -452,7 +451,7 @@ module QA
end
def repository_replicated_to_disk?(node, relative_path)
- Support::Waiter.wait_until(max_duration: 300, sleep_interval: 3, raise_on_failure: false) do
+ Support::Waiter.wait_until(max_duration: 300, sleep_interval: 1, raise_on_failure: false) do
result = []
shell sql_to_docker_exec_cmd("SELECT count(*) FROM storage_repositories where relative_path='#{relative_path}';") do |line|
result << line
diff --git a/qa/qa/specs/features/api/1_manage/bulk_import_group_spec.rb b/qa/qa/specs/features/api/1_manage/bulk_import_group_spec.rb
deleted file mode 100644
index 799a5f7eaf2..00000000000
--- a/qa/qa/specs/features/api/1_manage/bulk_import_group_spec.rb
+++ /dev/null
@@ -1,179 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- # run only base UI validation on staging because test requires top level group creation which is problematic
- # on staging environment
- RSpec.describe 'Manage', :requires_admin, except: { subdomain: :staging } do
- describe 'Gitlab migration' do
- let(:import_wait_duration) { { max_duration: 300, sleep_interval: 2 } }
- let(:admin_api_client) { Runtime::API::Client.as_admin }
- let(:user) do
- Resource::User.fabricate_via_api! do |usr|
- usr.api_client = admin_api_client
- usr.hard_delete_on_api_removal = true
- end
- end
-
- let(:api_client) { Runtime::API::Client.new(user: user) }
-
- let(:sandbox) do
- Resource::Sandbox.fabricate_via_api! do |group|
- group.api_client = admin_api_client
- end
- end
-
- let(:source_group) do
- Resource::Sandbox.fabricate_via_api! do |group|
- group.api_client = api_client
- group.path = "source-group-for-import-#{SecureRandom.hex(4)}"
- group.avatar = File.new('qa/fixtures/designs/tanuki.jpg', 'r')
- end
- end
-
- let(:imported_group) do
- Resource::BulkImportGroup.fabricate_via_api! do |group|
- group.api_client = api_client
- group.sandbox = sandbox
- group.source_group_path = source_group.path
- end
- end
-
- let(:import_failures) do
- imported_group.import_details.sum([]) { |details| details[:failures] }
- end
-
- before do
- sandbox.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
- end
-
- 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?
- user.remove_via_api!
- end
-
- context 'with subgroups and labels' do
- let(:subgroup) do
- Resource::Group.fabricate_via_api! do |group|
- group.api_client = api_client
- group.sandbox = source_group
- group.path = "subgroup-for-import-#{SecureRandom.hex(4)}"
- end
- end
-
- let(:imported_subgroup) do
- Resource::Group.init do |group|
- group.api_client = api_client
- group.sandbox = imported_group
- group.path = subgroup.path
- end
- end
-
- before do
- Resource::GroupLabel.fabricate_via_api! do |label|
- label.api_client = api_client
- label.group = source_group
- label.title = "source-group-#{SecureRandom.hex(4)}"
- end
- Resource::GroupLabel.fabricate_via_api! do |label|
- label.api_client = api_client
- label.group = subgroup
- label.title = "subgroup-#{SecureRandom.hex(4)}"
- end
-
- imported_group # trigger import
- end
-
- it(
- 'successfully imports groups and labels',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347674'
- ) do
- expect { imported_group.import_status }.to eventually_eq('finished').within(import_wait_duration)
-
- aggregate_failures do
- expect(imported_group.reload!).to eq(source_group)
- expect(imported_group.labels).to include(*source_group.labels)
-
- expect(imported_subgroup.reload!).to eq(subgroup)
- expect(imported_subgroup.labels).to include(*subgroup.labels)
- end
- end
- end
-
- context 'with milestones and badges' do
- let(:source_milestone) do
- Resource::GroupMilestone.fabricate_via_api! do |milestone|
- milestone.api_client = api_client
- milestone.group = source_group
- end
- end
-
- before do
- source_milestone
-
- Resource::GroupBadge.fabricate_via_api! do |badge|
- badge.api_client = api_client
- badge.group = source_group
- badge.link_url = "http://example.com/badge"
- badge.image_url = "http://shields.io/badge"
- end
-
- imported_group # trigger import
- end
-
- it(
- 'successfully imports group milestones and badges',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347628'
- ) do
- expect { imported_group.import_status }.to eventually_eq('finished').within(import_wait_duration)
-
- imported_milestone = imported_group.reload!.milestones.find { |ml| ml.title == source_milestone.title }
- aggregate_failures do
- expect(imported_milestone).to eq(source_milestone)
- expect(imported_milestone.iid).to eq(source_milestone.iid)
- expect(imported_milestone.created_at).to eq(source_milestone.created_at)
- expect(imported_milestone.updated_at).to eq(source_milestone.updated_at)
-
- expect(imported_group.badges).to eq(source_group.badges)
- 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_group_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb
new file mode 100644
index 00000000000..a6655471591
--- /dev/null
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb
@@ -0,0 +1,185 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Manage', :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 }
+ let(:user) do
+ Resource::User.fabricate_via_api! do |usr|
+ usr.api_client = admin_api_client
+ usr.hard_delete_on_api_removal = true
+ end
+ end
+
+ let(:api_client) { Runtime::API::Client.new(user: user) }
+
+ let(:sandbox) do
+ Resource::Sandbox.fabricate_via_api! do |group|
+ group.api_client = admin_api_client
+ end
+ end
+
+ let(:destination_group) do
+ Resource::Group.fabricate_via_api! do |group|
+ group.api_client = api_client
+ group.sandbox = sandbox
+ group.path = "destination-group-for-import-#{SecureRandom.hex(4)}"
+ end
+ end
+
+ let(:source_group) do
+ Resource::Group.fabricate_via_api! do |group|
+ group.api_client = api_client
+ group.sandbox = sandbox
+ group.path = "source-group-for-import-#{SecureRandom.hex(4)}"
+ group.avatar = File.new('qa/fixtures/designs/tanuki.jpg', 'r')
+ end
+ end
+
+ let(:imported_group) do
+ Resource::BulkImportGroup.fabricate_via_api! do |group|
+ group.api_client = api_client
+ group.sandbox = destination_group
+ group.source_group = source_group
+ end
+ end
+
+ let(:import_failures) do
+ imported_group.import_details.sum([]) { |details| details[:failures] }
+ end
+
+ before do
+ sandbox.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
+ end
+
+ 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?
+ user.remove_via_api!
+ end
+
+ context 'with subgroups and labels' do
+ let(:subgroup) do
+ Resource::Group.fabricate_via_api! do |group|
+ group.api_client = api_client
+ group.sandbox = source_group
+ group.path = "subgroup-for-import-#{SecureRandom.hex(4)}"
+ end
+ end
+
+ let(:imported_subgroup) do
+ Resource::Group.init do |group|
+ group.api_client = api_client
+ group.sandbox = imported_group
+ group.path = subgroup.path
+ end
+ end
+
+ before do
+ Resource::GroupLabel.fabricate_via_api! do |label|
+ label.api_client = api_client
+ label.group = source_group
+ label.title = "source-group-#{SecureRandom.hex(4)}"
+ end
+ Resource::GroupLabel.fabricate_via_api! do |label|
+ label.api_client = api_client
+ label.group = subgroup
+ label.title = "subgroup-#{SecureRandom.hex(4)}"
+ end
+
+ imported_group # trigger import
+ end
+
+ it(
+ 'successfully imports groups and labels',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347674'
+ ) do
+ expect { imported_group.import_status }.to eventually_eq('finished').within(import_wait_duration)
+
+ aggregate_failures do
+ expect(imported_group.reload!).to eq(source_group)
+ expect(imported_group.labels).to include(*source_group.labels)
+
+ expect(imported_subgroup.reload!).to eq(subgroup)
+ expect(imported_subgroup.labels).to include(*subgroup.labels)
+ end
+ end
+ end
+
+ context 'with milestones and badges' do
+ let(:source_milestone) do
+ Resource::GroupMilestone.fabricate_via_api! do |milestone|
+ milestone.api_client = api_client
+ milestone.group = source_group
+ end
+ end
+
+ before do
+ source_milestone
+
+ Resource::GroupBadge.fabricate_via_api! do |badge|
+ badge.api_client = api_client
+ badge.group = source_group
+ badge.link_url = "http://example.com/badge"
+ badge.image_url = "http://shields.io/badge"
+ end
+
+ imported_group # trigger import
+ end
+
+ it(
+ 'successfully imports group milestones and badges',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347628'
+ ) do
+ expect { imported_group.import_status }.to eventually_eq('finished').within(import_wait_duration)
+
+ imported_milestone = imported_group.reload!.milestones.find { |ml| ml.title == source_milestone.title }
+ aggregate_failures do
+ expect(imported_milestone).to eq(source_milestone)
+ expect(imported_milestone.iid).to eq(source_milestone.iid)
+ expect(imported_milestone.created_at).to eq(source_milestone.created_at)
+ expect(imported_milestone.updated_at).to eq(source_milestone.updated_at)
+
+ expect(imported_group.badges).to eq(source_group.badges)
+ 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_issue_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_issue_spec.rb
new file mode 100644
index 00000000000..8a2a382ac45
--- /dev/null
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_issue_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require_relative 'gitlab_project_migration_common'
+
+module QA
+ RSpec.describe 'Manage', :requires_admin do
+ describe 'Gitlab migration', quarantine: {
+ only: { job: 'praefect' },
+ type: :investigating,
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/348999'
+ } do
+ include_context 'with gitlab project migration'
+
+ context 'with project issues' do
+ let!(:source_issue) do
+ Resource::Issue.fabricate_via_api! do |issue|
+ issue.api_client = api_client
+ issue.project = source_project
+ issue.labels = %w[label_one label_two]
+ end
+ end
+
+ let!(:source_comment) { source_issue.add_comment(body: 'This is a test comment!') }
+
+ let(:imported_issues) { imported_projects.first.issues }
+
+ let(:imported_issue) do
+ issue = imported_issues.first
+ Resource::Issue.init do |resource|
+ resource.api_client = api_client
+ resource.project = imported_projects.first
+ resource.iid = issue[:iid]
+ end
+ end
+
+ let(:imported_comments) { imported_issue.comments }
+
+ it(
+ 'successfully imports issue',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347608'
+ ) do
+ expect_import_finished
+
+ aggregate_failures do
+ expect(imported_issues.count).to eq(1)
+ expect(imported_issue).to eq(source_issue.reload!)
+
+ expect(imported_comments.count).to eq(1)
+ expect(imported_comments.first[:body]).to include(source_comment[:body])
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb
new file mode 100644
index 00000000000..9dce9bff3c1
--- /dev/null
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+require_relative 'gitlab_project_migration_common'
+
+module QA
+ RSpec.describe 'Manage', :requires_admin do
+ describe 'Gitlab migration', quarantine: {
+ only: { job: 'praefect' },
+ type: :investigating,
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/348999'
+ } do
+ include_context 'with gitlab project migration'
+
+ context 'with merge request' do
+ let!(:source_project_with_readme) { true }
+
+ let!(:other_user) do
+ Resource::User
+ .fabricate_via_api! { |usr| usr.api_client = admin_api_client }
+ .tap do |usr|
+ usr.set_public_email
+ source_project.add_member(usr, Resource::Members::AccessLevel::MAINTAINER)
+ end
+ end
+
+ let!(:source_mr) do
+ Resource::MergeRequest.fabricate_via_api! do |mr|
+ mr.project = source_project
+ mr.api_client = Runtime::API::Client.new(user: other_user)
+ end
+ end
+
+ let!(:source_comment) { source_mr.add_comment('This is a test comment!') }
+
+ let(:imported_mrs) { imported_project.merge_requests }
+ let(:imported_mr_comments) { imported_mr.comments }
+
+ let(:imported_mr) do
+ Resource::MergeRequest.init do |mr|
+ mr.project = imported_project
+ mr.iid = imported_mrs.first[:iid]
+ mr.api_client = api_client
+ end
+ end
+
+ after do
+ other_user.remove_via_api!
+ end
+
+ it(
+ 'successfully imports merge request',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348478'
+ ) do
+ expect_import_finished
+
+ aggregate_failures do
+ expect(imported_mrs.count).to eq(1)
+ # TODO: remove custom comparison after member migration is implemented
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/341886
+ expect(imported_mr.comparable.except(:author)).to eq(source_mr.reload!.comparable.except(:author))
+
+ expect(imported_mr_comments.count).to eq(1)
+ expect(imported_mr_comments.first[:body]).to include(source_comment[:body])
+ # Comment will have mention of original user since members are not migrated yet
+ expect(imported_mr_comments.first[:body]).to include(other_user.name)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb
new file mode 100644
index 00000000000..a0c758c99e6
--- /dev/null
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+require_relative 'gitlab_project_migration_common'
+
+module QA
+ RSpec.describe 'Manage', :requires_admin do
+ describe 'Gitlab migration', quarantine: {
+ only: { job: 'praefect' },
+ type: :investigating,
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/348999'
+ } do
+ include_context 'with gitlab project migration'
+
+ context 'with uninitialized project' do
+ it(
+ 'successfully imports project',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347610'
+ ) do
+ expect_import_finished
+
+ expect(imported_projects.first).to eq(source_project)
+ end
+ end
+
+ context 'with repository' do
+ let(:source_project_with_readme) { true }
+ let(:source_commits) { source_project.commits.map { |c| c.except(:web_url) } }
+ let(:source_tags) do
+ source_project.repository_tags.tap do |tags|
+ tags.each { |t| t[:commit].delete(:web_url) }
+ end
+ end
+
+ let(:source_branches) do
+ source_project.repository_branches.tap do |branches|
+ branches.each do |b|
+ b.delete(:web_url)
+ b[:commit].delete(:web_url)
+ end
+ end
+ end
+
+ let(:imported_commits) { imported_project.commits.map { |c| c.except(:web_url) } }
+ let(:imported_tags) do
+ imported_project.repository_tags.tap do |tags|
+ tags.each { |t| t[:commit].delete(:web_url) }
+ end
+ end
+
+ let(:imported_branches) do
+ imported_project.repository_branches.tap do |branches|
+ branches.each do |b|
+ b.delete(:web_url)
+ b[:commit].delete(:web_url)
+ end
+ end
+ end
+
+ before do
+ source_project.create_repository_branch('test-branch')
+ source_project.create_repository_tag('v0.0.1')
+ end
+
+ it(
+ 'successfully imports repository',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347570'
+ ) do
+ expect_import_finished
+
+ aggregate_failures do
+ expect(imported_commits).to match_array(source_commits)
+ expect(imported_tags).to match_array(source_tags)
+ expect(imported_branches).to match_array(source_branches)
+ end
+ end
+ end
+
+ context 'with wiki' do
+ before do
+ source_project.create_wiki_page(title: 'Import test project wiki', content: 'Wiki content')
+ end
+
+ it(
+ 'successfully imports project wiki',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347567'
+ ) do
+ expect_import_finished
+
+ expect(imported_projects.first.wikis).to eq(source_project.wikis)
+ 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
new file mode 100644
index 00000000000..827ebc1f5e2
--- /dev/null
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.shared_context 'with gitlab project migration' 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 }
+ let(:user) do
+ Resource::User.fabricate_via_api! do |usr|
+ usr.api_client = admin_api_client
+ usr.hard_delete_on_api_removal = true
+ end
+ end
+
+ let(:api_client) { Runtime::API::Client.new(user: user) }
+
+ let(:sandbox) do
+ Resource::Sandbox.fabricate_via_api! do |group|
+ group.api_client = admin_api_client
+ end
+ end
+
+ let(:destination_group) do
+ Resource::Group.fabricate_via_api! do |group|
+ group.api_client = api_client
+ group.sandbox = sandbox
+ group.path = "destination-group-for-import-#{SecureRandom.hex(4)}"
+ end
+ end
+
+ let(:source_group) do
+ Resource::Group.fabricate_via_api! do |group|
+ group.api_client = api_client
+ group.path = "source-group-for-import-#{SecureRandom.hex(4)}"
+ end
+ end
+
+ let(:source_project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.api_client = api_client
+ project.group = source_group
+ project.initialize_with_readme = source_project_with_readme
+ end
+ end
+
+ let(:imported_group) do
+ Resource::BulkImportGroup.fabricate_via_api! do |group|
+ group.api_client = api_client
+ group.sandbox = destination_group
+ group.source_group = source_group
+ end
+ end
+
+ let(:imported_projects) { imported_group.reload!.projects }
+ let(:imported_project) { imported_projects.first }
+
+ let(:import_failures) do
+ imported_group.import_details.sum([]) { |details| details[:failures] }
+ end
+
+ def expect_import_finished
+ imported_group # trigger import
+
+ expect { imported_group.import_status }.to eventually_eq('finished').within(import_wait_duration)
+ expect(imported_projects.count).to eq(1), 'Expected to have 1 imported project'
+ end
+
+ before do
+ Runtime::Feature.enable(:bulk_import_projects)
+
+ sandbox.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
+ source_project # fabricate source group and project
+ 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
+ Runtime::Logger.warn("Import failures: #{import_failures}") if example.exception && !import_failures.empty?
+
+ user.remove_via_api!
+ ensure
+ Runtime::Feature.disable(:bulk_import_projects)
+ end
+ end
+end
diff --git a/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb b/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb
index e47e5d22e5e..6a31d173440 100644
--- a/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb
@@ -37,7 +37,7 @@ module QA
push.file_name = 'test.txt'
push.file_content = "# This is a test project named #{@project.name}"
push.commit_message = 'Add test.txt'
- push.branch_name = 'new_branch'
+ push.branch_name = "new_branch_#{SecureRandom.hex(8)}"
push.user = @user
end
end.to raise_error(QA::Support::Run::CommandError, /You are not allowed to push code to this project/)
@@ -48,7 +48,7 @@ module QA
Resource::File.fabricate_via_api! do |file|
file.api_client = @user_api_client
file.project = @project
- file.branch = 'new_branch'
+ file.branch = "new_branch_#{SecureRandom.hex(8)}"
file.commit_message = 'Add new file'
file.name = 'test.txt'
file.content = "New file"
@@ -61,7 +61,7 @@ module QA
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.api_client = @user_api_client
commit.project = @project
- commit.branch = 'new_branch'
+ commit.branch = "new_branch_#{SecureRandom.hex(8)}"
commit.start_branch = @project.default_branch
commit.commit_message = 'Add new file'
commit.add_files([
diff --git a/qa/qa/specs/features/api/3_create/gitaly/automatic_failover_and_recovery_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/automatic_failover_and_recovery_spec.rb
index 51927a30987..6a9be19efdd 100644
--- a/qa/qa/specs/features/api/3_create/gitaly/automatic_failover_and_recovery_spec.rb
+++ b/qa/qa/specs/features/api/3_create/gitaly/automatic_failover_and_recovery_spec.rb
@@ -49,7 +49,6 @@ module QA
# for Gitaly to be ready for writes again
praefect_manager.stop_primary_node
praefect_manager.wait_for_primary_node_health_check_failure
- praefect_manager.wait_for_gitaly_check
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
diff --git a/qa/qa/specs/features/api/3_create/gitaly/praefect_connectivity_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/praefect_connectivity_spec.rb
new file mode 100644
index 00000000000..28469b99d04
--- /dev/null
+++ b/qa/qa/specs/features/api/3_create/gitaly/praefect_connectivity_spec.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Create' do
+ context 'Praefect connectivity commands', :orchestrated, :gitaly_cluster do
+ praefect_manager = Service::PraefectManager.new
+
+ before do
+ praefect_manager.start_all_nodes
+ end
+
+ context 'in a healthy environment' do
+ it 'confirms healthy connection to database', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349937' do
+ expect(praefect_manager.praefect_sql_ping_healthy?).to be true
+ end
+
+ it 'confirms healthy connection to gitaly nodes', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349938' do
+ expect(praefect_manager.wait_for_dial_nodes_successful).to be true
+ end
+ end
+
+ context 'in an unhealthy environment' do
+ it 'diagnoses unhealthy connection to database', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349939' do
+ praefect_manager.stop_node(praefect_manager.postgres)
+ expect(praefect_manager.praefect_sql_ping_healthy?).to be false
+ end
+
+ it 'diagnoses connection issues to gitaly nodes', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349940' do
+ praefect_manager.stop_node(praefect_manager.primary_node)
+ praefect_manager.stop_node(praefect_manager.tertiary_node)
+ expect(praefect_manager.praefect_dial_nodes_status?(praefect_manager.primary_node, false)).to be true
+ expect(praefect_manager.praefect_dial_nodes_status?(praefect_manager.secondary_node)).to be true
+ expect(praefect_manager.praefect_dial_nodes_status?(praefect_manager.tertiary_node, false)).to be true
+
+ praefect_manager.stop_node(praefect_manager.secondary_node)
+ expect(praefect_manager.praefect_dial_nodes_status?(praefect_manager.secondary_node, false)).to be true
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/api/3_create/gitaly/praefect_repo_sync_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/praefect_repo_sync_spec.rb
index cc49e408954..e27f37abedf 100644
--- a/qa/qa/specs/features/api/3_create/gitaly/praefect_repo_sync_spec.rb
+++ b/qa/qa/specs/features/api/3_create/gitaly/praefect_repo_sync_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- context 'Praefect repository commands', :orchestrated, :gitaly_cluster, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/347415', type: :investigating } do
+ context 'Praefect repository commands', :orchestrated, :gitaly_cluster do
let(:praefect_manager) { Service::PraefectManager.new }
let(:repo1) { { "relative_path" => "@hashed/repo1.git", "storage" => "gitaly1", "virtual_storage" => "default" } }
@@ -59,6 +59,18 @@ module QA
untracked_repositories = praefect_manager.list_untracked_repositories
expect(untracked_repositories).not_to include(repo1)
end
+
+ it 'allows admin to control the number of replicas of data', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347566' do
+ praefect_manager.track_repository_in_praefect(repo1['relative_path'], repo1['storage'], repo1['virtual_storage'])
+
+ praefect_manager.set_replication_factor(repo1['relative_path'], repo1['virtual_storage'], 2)
+ replication_storages = praefect_manager.get_replication_storages(repo1['relative_path'], repo1['virtual_storage'])
+ expect(replication_storages).to have_attributes(size: 2)
+
+ praefect_manager.set_replication_factor(repo1['relative_path'], repo1['virtual_storage'], 3)
+ replication_storages = praefect_manager.get_replication_storages(repo1['relative_path'], repo1['virtual_storage'])
+ expect(replication_storages).to eq(%w(gitaly1 gitaly2 gitaly3))
+ end
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/bulk_import_group_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/bulk_import_group_spec.rb
deleted file mode 100644
index 74125b092b8..00000000000
--- a/qa/qa/specs/features/browser_ui/1_manage/group/bulk_import_group_spec.rb
+++ /dev/null
@@ -1,78 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Manage', :requires_admin do
- describe 'Bulk group import' do
- let!(:staging?) { Runtime::Scenario.gitlab_address.include?('staging.gitlab.com') }
- let!(:admin_api_client) { Runtime::API::Client.as_admin }
- let!(:user) do
- Resource::User.fabricate_via_api! do |usr|
- usr.api_client = admin_api_client
- usr.hard_delete_on_api_removal = true
- end
- end
-
- let!(:api_client) { Runtime::API::Client.new(user: user) }
- let!(:personal_access_token) { api_client.personal_access_token }
-
- let(:sandbox) do
- Resource::Sandbox.fabricate_via_api! do |group|
- group.api_client = admin_api_client
- end
- end
-
- let(:source_group) do
- Resource::Sandbox.fabricate! do |group|
- group.api_client = api_client
- group.path = "source-group-for-import-#{SecureRandom.hex(4)}"
- end
- end
-
- let(:imported_group) do
- Resource::BulkImportGroup.init do |group|
- group.api_client = api_client
- group.sandbox = sandbox
- group.source_group_path = source_group.path
- end
- end
-
- before do
- sandbox.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
-
- Flow::Login.sign_in(as: user)
-
- source_group
-
- Page::Main::Menu.perform(&:go_to_create_group)
- Page::Group::New.perform do |group|
- group.switch_to_import_tab
- group.connect_gitlab_instance(Runtime::Scenario.gitlab_address, personal_access_token)
- end
- end
-
- after do
- user.remove_via_api!
- end
-
- it(
- 'imports group from UI',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347862',
- issue_1: 'https://gitlab.com/gitlab-org/gitlab/-/issues/331252',
- issue_2: 'https://gitlab.com/gitlab-org/gitlab/-/issues/333678',
- issue_3: 'https://gitlab.com/gitlab-org/gitlab/-/issues/332351',
- except: { job: 'instance-image-slow-network' }
- ) do
- Page::Group::BulkImport.perform do |import_page|
- import_page.import_group(imported_group.path, imported_group.sandbox.path)
-
- expect(import_page).to have_imported_group(imported_group.path, wait: 300)
-
- imported_group.reload!.visit!
- Page::Group::Show.perform do |group|
- expect(group).to have_content(imported_group.path)
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/gitlab_migration_group_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/gitlab_migration_group_spec.rb
new file mode 100644
index 00000000000..a18e22f52f1
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/1_manage/group/gitlab_migration_group_spec.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+module QA
+ describe 'Manage', :requires_admin do
+ describe 'Gitlab migration' do
+ let!(:admin_api_client) { Runtime::API::Client.as_admin }
+ let!(:user) do
+ Resource::User.fabricate_via_api! do |usr|
+ usr.api_client = admin_api_client
+ usr.hard_delete_on_api_removal = true
+ end
+ end
+
+ let!(:api_client) { Runtime::API::Client.new(user: user) }
+ let!(:personal_access_token) { api_client.personal_access_token }
+
+ let(:sandbox) do
+ Resource::Sandbox.fabricate_via_api! do |group|
+ group.api_client = admin_api_client
+ end
+ end
+
+ let(:source_group) do
+ Resource::Sandbox.fabricate! do |group|
+ group.api_client = api_client
+ group.path = "source-group-for-import-#{SecureRandom.hex(4)}"
+ end
+ end
+
+ let(:imported_group) do
+ Resource::BulkImportGroup.init do |group|
+ group.api_client = api_client
+ group.sandbox = sandbox
+ group.source_group = source_group
+ end
+ end
+
+ before do
+ sandbox.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
+
+ Flow::Login.sign_in(as: user)
+
+ source_group
+
+ Page::Main::Menu.perform(&:go_to_create_group)
+ Page::Group::New.perform do |group|
+ group.switch_to_import_tab
+ group.connect_gitlab_instance(Runtime::Scenario.gitlab_address, personal_access_token)
+ end
+ end
+
+ after do
+ user.remove_via_api!
+ end
+
+ it(
+ 'imports group from UI',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347862',
+ issue_1: 'https://gitlab.com/gitlab-org/gitlab/-/issues/331252',
+ issue_2: 'https://gitlab.com/gitlab-org/gitlab/-/issues/333678',
+ issue_3: 'https://gitlab.com/gitlab-org/gitlab/-/issues/332351',
+ except: { job: 'instance-image-slow-network' }
+ ) do
+ Page::Group::BulkImport.perform do |import_page|
+ import_page.import_group(imported_group.path, imported_group.sandbox.path)
+
+ expect(import_page).to have_imported_group(imported_group.path, wait: 300)
+
+ imported_group.reload!.visit!
+ Page::Group::Show.perform do |group|
+ expect(group).to have_content(imported_group.path)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb
index 16f8df5a90d..098c0b3ba63 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb
@@ -64,6 +64,7 @@ module QA
Page::Profile::Accounts::Show.perform do |show|
show.delete_account(user.password)
end
+ Support::Waiter.wait_until { !user.exists? }
end
it 'allows recreating with same credentials', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347868' do
@@ -83,7 +84,7 @@ module QA
end
after do
- @recreated_user.remove_via_api!
+ @recreated_user&.remove_via_api!
end
def admin_api_client
@@ -117,11 +118,12 @@ module QA
Flow::Login.sign_in(as: @user, skip_page_validation: true)
- Page::Registration::Welcome.perform(&:click_get_started_button_if_available)
+ Flow::UserOnboarding.onboard_user
- Page::Main::Menu.perform do |menu|
- expect(menu).to have_personal_area
- end
+ # In development env and .com the user is asked to create a group and a project which can be skipped for
+ # the purpose of this test
+ Runtime::Browser.visit(:gitlab, Page::Dashboard::Welcome)
+ Page::Main::Menu.perform(&:has_personal_area?)
end
after do
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 6d09c8b1316..895027a588d 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,7 +1,11 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage', :requires_admin do
+ RSpec.describe 'Manage', :requires_admin, quarantine: {
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/350598',
+ type: :needs_update,
+ only: { subdomain: :staging }
+ } do
describe 'Add project member' do
before do
Runtime::Feature.enable(:invite_members_group_modal)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb
index 7f40818da03..0063ce2613a 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage', :smoke do
- describe 'Project', :requires_admin do
+ describe 'Project' do
shared_examples 'successful project creation' do
it 'creates a new project' do
Page::Project::Show.perform do |project_page|
@@ -17,7 +17,6 @@ module QA
end
before do
- Runtime::Feature.enable(:paginatable_namespace_drop_down_for_project_creation)
Flow::Login.sign_in
project
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
new file mode 100644
index 00000000000..6997447411a
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+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
+ 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
+ Page::Project::Menu.perform(&:click_members)
+ Page::Project::Members.perform do |project_members|
+ project_members.invite_group(group.path, 'Developer')
+
+ expect(project_members).to have_group(group.path)
+ end
+
+ Flow::Login.sign_in(as: @user)
+
+ Page::Dashboard::Projects.perform do |projects|
+ expect(projects).to have_project_with_access_role(project.name, 'Developer')
+ end
+
+ project.visit!
+
+ Page::Project::Show.perform do |project_page|
+ expect(project_page).to have_name(project.name)
+ end
+ end
+ 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
+
+ before do
+ Flow::Login.sign_in
+ group.add_member(@user, Resource::Members::AccessLevel::MAINTAINER)
+ project.visit!
+ end
+
+ context 'to personal namespace project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349223' do
+ let(:group) do
+ Resource::Group.fabricate_via_api! do |group|
+ group.path = "group-for-personal-project-#{SecureRandom.hex(8)}"
+ end
+ end
+
+ let(:project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = 'personal-namespace-project'
+ project.personal_namespace = Runtime::User.username
+ project.visibility = :private
+ project.description = 'test personal namespace project'
+ end
+ end
+
+ it_behaves_like 'invites group to project'
+ end
+
+ context 'to group project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349340' do
+ let(:group) do
+ Resource::Group.fabricate_via_api! do |group|
+ group.path = "group-for-group-project-#{SecureRandom.hex(8)}"
+ end
+ end
+
+ let(:project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = 'group-project'
+ project.visibility = :private
+ project.description = 'test group project'
+ end
+ end
+
+ it_behaves_like 'invites group to project'
+ end
+
+ after do
+ 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/project_access_token_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb
index be8567ee0b6..c2bd61155b1 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb
@@ -9,7 +9,7 @@ module QA
expect(project_access_token.token).not_to be_nil
project_access_token.revoke_via_ui!
- expect(page).to have_text("Revoked project access token #{project_access_token.name}!")
+ expect(page).to have_text("Revoked access token #{project_access_token.name}!")
end
after do
diff --git a/qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb
index 43100929acd..87b51edef08 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb
@@ -19,7 +19,7 @@ module QA
group = QA::Resource::Group.fabricate_via_api! do |group|
group.path = "group_for_follow_user_activity_#{SecureRandom.hex(8)}"
end
- group.add_member(user)
+ group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
group
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb
index d198d79c5fe..b0c6d01e8ca 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb
@@ -2,7 +2,11 @@
module QA
RSpec.describe 'Create' do
- describe 'Merge request creation from fork' do
+ describe 'Merge request creation from fork', quarantine: {
+ only: { subdomain: %i[canary production] },
+ issue: "https://gitlab.com/gitlab-org/gitlab/-/issues/343801",
+ type: :investigation
+ } do
let(:merge_request) do
Resource::MergeRequestFromFork.fabricate_via_browser_ui! do |merge_request|
merge_request.fork_branch = 'feature-branch'
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_merge_ref_diff_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_merge_ref_diff_spec.rb
deleted file mode 100644
index 0785b32b225..00000000000
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_merge_ref_diff_spec.rb
+++ /dev/null
@@ -1,90 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Create', :requires_admin, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/261793', type: :investigating } do
- describe 'View merge request merge-ref diff' do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'merge-ref-diff'
- end
- end
-
- let(:merge_request) do
- Resource::MergeRequest.fabricate_via_api! do |merge_request|
- merge_request.project = project
- merge_request.title = 'This is a merge request'
- merge_request.description = '... for viewing merge-ref and merge-base diffs'
- merge_request.file_content = 'This exists on the source branch only'
- end
- end
-
- let(:new_file_name) { "added_file-#{SecureRandom.hex(8)}.txt" }
-
- context 'when the feature flag default_merge_ref_for_diffs is enabled' do
- before do
- Runtime::Feature.enable('default_merge_ref_for_diffs', project: project)
-
- commit_to_branch(merge_request.target_branch, new_file_name)
- commit_to_branch(merge_request.source_branch, new_file_name)
-
- Flow::Login.sign_in
-
- merge_request.visit!
- end
-
- it 'views the merge-ref diff by default', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347651' do
- Page::MergeRequest::Show.perform do |mr_page|
- mr_page.click_diffs_tab
- mr_page.click_target_version_dropdown
-
- expect(mr_page.version_dropdown_content).to include("#{project.default_branch} (HEAD)")
- expect(mr_page.version_dropdown_content).not_to include("#{project.default_branch} (base)")
- expect(mr_page).to have_file(merge_request.file_name)
- expect(mr_page).not_to have_file(new_file_name)
- end
- end
- end
-
- context 'when the feature flag default_merge_ref_for_diffs is disabled' do
- before do
- Runtime::Feature.disable('default_merge_ref_for_diffs', project: project)
-
- commit_to_branch(merge_request.target_branch, new_file_name)
- commit_to_branch(merge_request.source_branch, new_file_name)
-
- Flow::Login.sign_in
-
- merge_request.visit!
- end
-
- it 'views the merge-base diff by default', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347650' do
- Page::MergeRequest::Show.perform do |mr_page|
- mr_page.click_diffs_tab
- mr_page.click_target_version_dropdown
-
- expect(mr_page.version_dropdown_content).to include("#{project.default_branch} (HEAD)")
- expect(mr_page.version_dropdown_content).to include("#{project.default_branch} (base)")
- expect(mr_page).to have_file(merge_request.file_name)
- expect(mr_page).to have_file(new_file_name)
- end
- end
- end
-
- def commit_to_branch(branch, file)
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = merge_request.project
- commit.branch = branch
- commit.commit_message = "Add new file on #{branch}"
- commit.add_files(
- [
- {
- file_path: file,
- content: "This exists on source and target branches"
- }
- ]
- )
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb
index a98925eab98..0bd470fcb77 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb
@@ -24,8 +24,6 @@ module QA
proj.initialize_with_readme = true
end
- Runtime::Feature.enable(:delete_branch_confirmation_modals, project: project)
-
master_branch = project.default_branch
Git::Repository.perform do |repository|
diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/content_editor_spec.rb b/qa/qa/specs/features/browser_ui/3_create/wiki/content_editor_spec.rb
index a063acbe146..67eee66b3d6 100644
--- a/qa/qa/specs/features/browser_ui/3_create/wiki/content_editor_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/wiki/content_editor_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create', :requires_admin do # remove :requires_admin once the ff is enabled by default in https://gitlab.com/gitlab-org/gitlab/-/issues/345398
+ RSpec.describe 'Create', :requires_admin, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/350220', type: :investigating } do # remove :requires_admin once the ff is enabled by default in https://gitlab.com/gitlab-org/gitlab/-/issues/345398
context 'Content Editor' do
let(:initial_wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
let(:page_title) { 'Content Editor Page' }
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
new file mode 100644
index 00000000000..8f3284662d7
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_lint_spec.rb
@@ -0,0 +1,95 @@
+# 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'
+ end
+ end
+
+ let!(:commit) 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
+ stages:
+ - stage1
+ - stage2
+
+ job1:
+ stage: stage1
+ script: echo 'Done.'
+
+ job2:
+ stage: stage2
+ script: echo 'Done.'
+ YAML
+ }
+ ]
+ )
+ 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
+
+ context 'when CI has valid syntax' do
+ it 'shows valid validations', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349128' do
+ Page::Project::PipelineEditor::Show.perform do |show|
+ aggregate_failures do
+ expect(show.ci_syntax_validate_message).to have_content('CI configuration is valid')
+
+ show.go_to_visualize_tab
+ { stage1: 'job1', stage2: 'job2' }.each_pair do |stage, job|
+ expect(show).to have_stage(stage), "Pipeline graph does not have stage #{stage}."
+ expect(show).to have_job(job), "Pipeline graph does not have job #{job}."
+ end
+
+ show.go_to_lint_tab
+ expect(show.tab_alert_message).to have_content('Syntax is correct')
+
+ show.go_to_view_merged_yaml_tab
+ expect(show).to have_source_editor
+ end
+ end
+ end
+ end
+
+ context 'when CI has invalid syntax' do
+ it 'shows invalid validations', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349129' do
+ invalid_msg = 'syntax is invalid'
+
+ Page::Project::PipelineEditor::Show.perform do |show|
+ show.write_to_editor(SecureRandom.hex(10))
+
+ aggregate_failures do
+ show.go_to_visualize_tab
+ expect(show.tab_alert_message).to have_content(invalid_msg)
+
+ show.go_to_lint_tab
+ expect(show.tab_alert_message).to have_content('Syntax is incorrect')
+
+ show.go_to_view_merged_yaml_tab
+ expect(show.tab_alert_message).to have_content(invalid_msg)
+
+ expect(show.ci_syntax_validate_message).to have_content('CI configuration is invalid')
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/update_ci_file_with_pipeline_editor_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/update_ci_file_with_pipeline_editor_spec.rb
new file mode 100644
index 00000000000..00c5d4c74d4
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/update_ci_file_with_pipeline_editor_spec.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Verify' do
+ describe 'Update CI file with pipeline editor' do
+ let(:random_test_string) { SecureRandom.hex(10) }
+
+ let(:project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = 'pipeline-editor-project'
+ end
+ end
+
+ let!(:runner) do
+ Resource::Runner.fabricate_via_api! do |runner|
+ runner.project = project
+ runner.name = random_test_string
+ runner.tags = [random_test_string]
+ end
+ end
+
+ let!(:commit) 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
+ test_job:
+ tags: ['#{random_test_string}']
+ script:
+ - echo "Simple test!"
+ YAML
+ }
+ ]
+ )
+ end
+ end
+
+ before do
+ Flow::Login.sign_in
+ project.visit!
+ Support::Waiter.wait_until { !project.pipelines.empty? && project.pipelines.first[:status] == 'success' }
+ Page::Project::Menu.perform(&:go_to_pipeline_editor)
+ end
+
+ after do
+ [runner, project].each(&:remove_via_api!)
+ end
+
+ it 'creates new pipeline and target branch', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349005' do
+ Page::Project::PipelineEditor::Show.perform do |show|
+ show.write_to_editor(random_test_string)
+ show.set_target_branch(random_test_string)
+ show.submit_changes
+
+ Support::Waiter.wait_until { project.pipelines.size > 1 }
+
+ aggregate_failures do
+ expect(show.target_branch_name).to eq(random_test_string)
+ expect(show.current_branch).to eq(random_test_string)
+ expect(show.editing_content).to have_content(random_test_string)
+ expect { show.pipeline_id }.to eventually_eq(project.pipelines.pluck(:id).max).within(max_duration: 60, sleep_interval: 3)
+ end
+ end
+
+ expect(project).to have_branch(random_test_string)
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/5_package/container_registry/online_garbage_collection_spec.rb b/qa/qa/specs/features/browser_ui/5_package/container_registry/online_garbage_collection_spec.rb
index e8d936e67b1..56e3ec82388 100644
--- a/qa/qa/specs/features/browser_ui/5_package/container_registry/online_garbage_collection_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/container_registry/online_garbage_collection_spec.rb
@@ -2,8 +2,7 @@
module QA
RSpec.describe 'Package' do
- # TODO: Remove :requires_admin when the `Runtime::Feature.enable` method call is removed
- describe 'Container Registry Online Garbage Collection', :registry_gc, :requires_admin, only: { subdomain: %i[pre] } do
+ describe 'Container Registry Online Garbage Collection', :registry_gc, only: { subdomain: %i[pre] } do
let(:group) { Resource::Group.fabricate_via_api! }
let(:imported_project) do
@@ -65,8 +64,6 @@ module QA
end
before do
- Runtime::Feature.enable(:paginatable_namespace_drop_down_for_project_creation)
-
Flow::Login.sign_in
imported_project
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb
index c58cdec622d..70b31c1beca 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package Registry', :orchestrated, :packages, :reliable, :object_storage do
+ RSpec.describe 'Package Registry', :orchestrated, :packages, :object_storage do
describe 'npm instance level endpoint' do
using RSpec::Parameterized::TableSyntax
include Runtime::Fixtures
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb
index cec902e073a..e25a742493b 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package Registry', :orchestrated, :packages, :reliable, :object_storage do
+ RSpec.describe 'Package Registry', :orchestrated, :packages, :object_storage do
describe 'npm project level endpoint' do
using RSpec::Parameterized::TableSyntax
include Runtime::Fixtures
diff --git a/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb b/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb
index 74a81ff429d..ef0c8d35c37 100644
--- a/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb
@@ -13,7 +13,7 @@ module QA
Resource::Runner.fabricate_via_api! do |runner|
runner.project = project
runner.name = project.name
- runner.tags = ["#{project.name}"]
+ runner.tags = [project.name]
end
end
diff --git a/qa/qa/specs/features/browser_ui/8_monitor/.gitkeep b/qa/qa/specs/features/browser_ui/8_monitor/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/8_monitor/.gitkeep
diff --git a/qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb b/qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb
deleted file mode 100644
index c13d2d2dddf..00000000000
--- a/qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb
+++ /dev/null
@@ -1,142 +0,0 @@
-# frozen_string_literal: true
-require_relative 'cluster_with_prometheus'
-
-module QA
- RSpec.describe 'Monitor', :orchestrated, :kubernetes, :requires_admin, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/241448', type: :investigating } do
- include_context "cluster with Prometheus installed"
-
- before do
- Flow::Login.sign_in_unless_signed_in
- @project.visit!
- end
-
- it 'configures custom metrics', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348082' do
- verify_add_custom_metric
- verify_edit_custom_metric
- verify_delete_custom_metric
- end
-
- it 'duplicates to create dashboard to custom', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348070' do
- Page::Project::Menu.perform(&:go_to_monitor_metrics)
-
- Page::Project::Monitor::Metrics::Show.perform do |on_dashboard|
- on_dashboard.duplicate_dashboard
-
- expect(on_dashboard).to have_metrics
- expect(on_dashboard).to have_edit_dashboard_enabled
- end
- end
-
- it 'verifies data on filtered deployed environment', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348071' do
- Page::Project::Menu.perform(&:go_to_monitor_metrics)
-
- Page::Project::Monitor::Metrics::Show.perform do |on_dashboard|
- on_dashboard.filter_environment
-
- expect(on_dashboard).to have_metrics
- end
- end
-
- it 'filters using the quick range', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348083' do
- Page::Project::Menu.perform(&:go_to_monitor_metrics)
-
- Page::Project::Monitor::Metrics::Show.perform do |on_dashboard|
- on_dashboard.show_last('30 minutes')
- expect(on_dashboard).to have_metrics
-
- on_dashboard.show_last('3 hours')
- expect(on_dashboard).to have_metrics
-
- on_dashboard.show_last('1 day')
- expect(on_dashboard).to have_metrics
- end
- end
-
- it 'observes cluster health graph', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348074' do
- Page::Project::Menu.perform(&:go_to_infrastructure_kubernetes)
-
- Page::Project::Infrastructure::Kubernetes::Index.perform do |cluster_list|
- cluster_list.click_on_cluster(@cluster)
- end
-
- Page::Project::Infrastructure::Kubernetes::Show.perform do |cluster_panel|
- cluster_panel.open_health
- cluster_panel.wait_for_cluster_health
- end
- end
-
- it 'uses templating variables for metrics dashboards', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347636' do
- templating_dashboard_yml = Pathname
- .new(__dir__)
- .join('../../../../fixtures/metrics_dashboards/templating.yml')
-
- Resource::Repository::ProjectPush.fabricate! do |push|
- push.project = @project
- push.file_name = '.gitlab/dashboards/templating.yml'
- push.file_content = File.read(templating_dashboard_yml)
- push.commit_message = 'Add templating in dashboard file'
- push.new_branch = false
- end
-
- Page::Project::Menu.perform(&:go_to_monitor_metrics)
-
- Page::Project::Monitor::Metrics::Show.perform do |dashboard|
- dashboard.select_dashboard('templating.yml')
-
- expect(dashboard).to have_template_metric('CPU usage GitLab Runner')
- expect(dashboard).to have_template_metric('Memory usage Postgresql')
- expect(dashboard).to have_templating_variable('GitLab Runner')
- expect(dashboard).to have_templating_variable('Postgresql')
- end
- end
-
- private
-
- def verify_add_custom_metric
- Page::Project::Menu.perform(&:go_to_integrations_settings)
- Page::Project::Settings::Integrations.perform(&:click_on_prometheus_integration)
-
- Page::Project::Settings::Services::Prometheus.perform do |metrics_panel|
- metrics_panel.click_on_new_metric
- metrics_panel.add_custom_metric
- end
-
- Page::Project::Menu.perform(&:go_to_monitor_metrics)
-
- Page::Project::Monitor::Metrics::Show.perform do |on_dashboard|
- expect(on_dashboard).to have_custom_metric('HTTP Requests Total')
- end
- end
-
- def verify_edit_custom_metric
- Page::Project::Menu.perform(&:go_to_integrations_settings)
- Page::Project::Settings::Integrations.perform(&:click_on_prometheus_integration)
- Page::Project::Settings::Services::Prometheus.perform do |metrics_panel|
- metrics_panel.click_on_custom_metric('Business / HTTP Requests Total (req/sec)')
- metrics_panel.edit_custom_metric
- end
-
- Page::Project::Menu.perform(&:go_to_monitor_metrics)
-
- Page::Project::Monitor::Metrics::Show.perform do |on_dashboard|
- expect(on_dashboard).to have_custom_metric('Throughput')
- end
- end
-
- def verify_delete_custom_metric
- Page::Project::Menu.perform(&:go_to_integrations_settings)
- Page::Project::Settings::Integrations.perform(&:click_on_prometheus_integration)
-
- Page::Project::Settings::Services::Prometheus.perform do |metrics_panel|
- metrics_panel.click_on_custom_metric('Business / Throughput (req/sec)')
- metrics_panel.delete_custom_metric
- end
-
- Page::Project::Menu.perform(&:go_to_monitor_metrics)
-
- Page::Project::Monitor::Metrics::Show.perform do |on_dashboard|
- expect(on_dashboard).not_to have_custom_metric('Throughput')
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/browser_ui/8_monitor/cluster_with_prometheus.rb b/qa/qa/specs/features/browser_ui/8_monitor/cluster_with_prometheus.rb
deleted file mode 100644
index 19e49400d5e..00000000000
--- a/qa/qa/specs/features/browser_ui/8_monitor/cluster_with_prometheus.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.shared_context "cluster with Prometheus installed" do
- before :all do
- @cluster = Service::KubernetesCluster.new(provider_class: Service::ClusterProvider::K3s).create!
- @project = Resource::Project.fabricate_via_api! do |project|
- project.name = 'monitoring-project'
- project.auto_devops_enabled = true
- project.template_name = 'express'
- end
-
- deploy_project_with_prometheus
- end
-
- def deploy_project_with_prometheus
- %w[
- CODE_QUALITY_DISABLED TEST_DISABLED LICENSE_MANAGEMENT_DISABLED
- SAST_DISABLED DAST_DISABLED DEPENDENCY_SCANNING_DISABLED
- CONTAINER_SCANNING_DISABLED BROWSER_PERFORMANCE_DISABLED SECRET_DETECTION_DISABLED
- ].each do |key|
- Resource::CiVariable.fabricate_via_api! do |resource|
- resource.project = @project
- resource.key = key
- resource.value = '1'
- resource.masked = false
- end
- end
-
- Flow::Login.sign_in
-
- Resource::KubernetesCluster::ProjectCluster.fabricate! do |cluster_settings|
- cluster_settings.project = @project
- cluster_settings.cluster = @cluster
- cluster_settings.install_runner = true
- cluster_settings.install_ingress = true
- cluster_settings.install_prometheus = true
- end
-
- Resource::Pipeline.fabricate_via_api! do |pipeline|
- pipeline.project = @project
- end.visit!
-
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('build')
- end
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 600)
-
- job.click_element(:pipeline_path)
- end
-
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('production')
- end
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 1200)
-
- job.click_element(:pipeline_path)
- end
- end
-
- after :all do
- @cluster&.remove!
- end
- end
-end
diff --git a/qa/qa/specs/helpers/quarantine.rb b/qa/qa/specs/helpers/quarantine.rb
index 49d91fc87cd..738c99efb28 100644
--- a/qa/qa/specs/helpers/quarantine.rb
+++ b/qa/qa/specs/helpers/quarantine.rb
@@ -11,9 +11,9 @@ module QA
extend self
# Skip tests in quarantine unless we explicitly focus on them.
- def skip_or_run_quarantined_tests_or_contexts(filters, example)
+ def skip_or_run_quarantined_tests_or_contexts(example)
if filters.key?(:quarantine)
- included_filters = filters_other_than_quarantine(filters)
+ included_filters = filters_other_than_quarantine
# If :quarantine is focused, skip the test/context unless its metadata
# includes quarantine and any other filters
@@ -29,18 +29,17 @@ module QA
elsif example.metadata.key?(:quarantine)
quarantine_tag = example.metadata[:quarantine]
- if quarantine_tag.is_a?(Hash) && quarantine_tag&.key?(:only) && !ContextSelector.context_matches?(quarantine_tag[:only])
- # If the :quarantine hash contains :only, we respect that.
- # For instance `quarantine: { only: { subdomain: :staging } }` will only quarantine the test when it runs against staging.
- return
- end
+ # If the :quarantine hash contains :only, we respect that.
+ # For instance `quarantine: { only: { subdomain: :staging } }`
+ # will only quarantine the test when it runs against staging.
+ return if quarantined_different_context?(quarantine_tag)
example.metadata[:skip] = quarantine_message(quarantine_tag)
end
end
- def filters_other_than_quarantine(filter)
- filter.reject { |key, _| key == :quarantine }
+ def filters_other_than_quarantine
+ filters.reject { |key, _| key == :quarantine }
end
def quarantine_message(quarantine_tag)
@@ -70,6 +69,14 @@ module QA
(metadata.keys & included_filters.keys).empty?
end
+
+ def quarantined_different_context?(quarantine)
+ quarantine.is_a?(Hash) && quarantine.key?(:only) && !ContextSelector.context_matches?(quarantine[:only])
+ end
+
+ def filters
+ @filters ||= ::RSpec.configuration.inclusion_filter.rules
+ end
end
end
end
diff --git a/qa/qa/specs/runner.rb b/qa/qa/specs/runner.rb
index d7d64834e7a..2c9e302fc56 100644
--- a/qa/qa/specs/runner.rb
+++ b/qa/qa/specs/runner.rb
@@ -9,6 +9,7 @@ module QA
attr_accessor :tty, :tags, :options
DEFAULT_TEST_PATH_ARGS = ['--', File.expand_path('./features', __dir__)].freeze
+ DEFAULT_STD_ARGS = [$stderr, $stdout].freeze
def initialize
@tty = false
@@ -19,13 +20,11 @@ module QA
def paths_from_knapsack
allocator = Knapsack::AllocatorBuilder.new(Knapsack::Adapters::RSpecAdapter).allocator
- QA::Runtime::Logger.info ''
+ QA::Runtime::Logger.info '==== Knapsack specs to execute ====='
QA::Runtime::Logger.info 'Report specs:'
QA::Runtime::Logger.info allocator.report_node_tests.join(', ')
- QA::Runtime::Logger.info ''
QA::Runtime::Logger.info 'Leftover specs:'
QA::Runtime::Logger.info allocator.leftover_node_tests.join(', ')
- QA::Runtime::Logger.info ''
['--', allocator.node_tests]
end
@@ -70,8 +69,15 @@ module QA
ParallelRunner.run(args.flatten)
elsif Runtime::Scenario.attributes[:loop]
LoopRunner.run(args.flatten)
+ elsif Runtime::Scenario.attributes[:count_examples_only]
+ args.unshift('--dry-run')
+ out = StringIO.new
+ RSpec::Core::Runner.run(args.flatten, $stderr, out).tap do |status|
+ abort if status.nonzero?
+ end
+ $stdout.puts out.string.match(/(\d+) examples,/)[1]
else
- RSpec::Core::Runner.run(args.flatten, $stderr, $stdout).tap do |status|
+ RSpec::Core::Runner.run(args.flatten, *DEFAULT_STD_ARGS).tap do |status|
abort if status.nonzero?
end
end
diff --git a/qa/qa/support/formatters/quarantine_formatter.rb b/qa/qa/support/formatters/quarantine_formatter.rb
index c5d16988dbd..4e4da99749c 100644
--- a/qa/qa/support/formatters/quarantine_formatter.rb
+++ b/qa/qa/support/formatters/quarantine_formatter.rb
@@ -18,7 +18,7 @@ module QA
def example_group_started(example_group_notification)
group = example_group_notification.group
- skip_or_run_quarantined_tests_or_contexts(filters, group)
+ skip_or_run_quarantined_tests_or_contexts(group)
end
# Starts example
@@ -28,13 +28,7 @@ module QA
example = example_notification.example
# if skip propagated from example_group, do not reset skip metadata
- skip_or_run_quarantined_tests_or_contexts(filters, example) unless example.metadata[:skip]
- end
-
- private
-
- def filters
- @filters ||= ::RSpec.configuration.inclusion_filter.rules
+ skip_or_run_quarantined_tests_or_contexts(example) unless example.metadata[:skip]
end
end
end
diff --git a/qa/qa/support/formatters/test_stats_formatter.rb b/qa/qa/support/formatters/test_stats_formatter.rb
index 6f6291b5856..7678cb8406c 100644
--- a/qa/qa/support/formatters/test_stats_formatter.rb
+++ b/qa/qa/support/formatters/test_stats_formatter.rb
@@ -84,7 +84,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'),
+ testcase: example.metadata[:testcase]
}
}
rescue StandardError => e
@@ -124,11 +125,11 @@ module QA
@merge_request ||= (!!env('CI_MERGE_REQUEST_IID') || !!env('TOP_UPSTREAM_MERGE_REQUEST_IID')).to_s
end
- # Test run type from staging, canary, preprod or production env
+ # Test run type from staging (`gstg`, `gstg-cny`, `gstg-ref`), canary, preprod or production env
#
# @return [String, nil]
def run_type
- return unless %w[staging canary preprod production].include?(project_name)
+ return unless %w[staging staging-canary staging-ref canary preprod production].include?(project_name)
@run_type ||= begin
test_subset = if env('NO_ADMIN') == 'true'
diff --git a/qa/qa/support/matchers/eventually_matcher.rb b/qa/qa/support/matchers/eventually_matcher.rb
index dedef8e6b98..2fb5249d9af 100644
--- a/qa/qa/support/matchers/eventually_matcher.rb
+++ b/qa/qa/support/matchers/eventually_matcher.rb
@@ -28,27 +28,21 @@ module QA
RSpec::Matchers.define(:"eventually_#{op}") do |*expected|
chain(:within) do |kwargs = {}|
@retry_args = kwargs
- @retry_args[:sleep_interval] = 0.5 unless @retry_args[:sleep_interval]
+ @retry_args[:sleep_interval] = 0.5 unless kwargs[:sleep_interval]
end
- def supports_block_expectations?
- true
- end
+ description { "eventually #{operator_msg}: #{expected_formatted}" }
match { |actual| wait_and_check(actual, :default_expectation) }
match_when_negated { |actual| wait_and_check(actual, :when_negated_expectation) }
- description do
- "eventually #{operator_msg} #{expected.inspect}"
- end
+ failure_message { fail_message }
- failure_message do
- "#{e}:\nexpected to #{description}, last attempt was #{@result.nil? ? 'nil' : @result}"
- end
+ failure_message_when_negated { fail_message(negate: true) }
- failure_message_when_negated do
- "#{e}:\nexpected not to #{description}, last attempt was #{@result.nil? ? 'nil' : @result}"
+ def supports_block_expectations?
+ true
end
# Execute rspec expectation within retrier
@@ -60,9 +54,9 @@ module QA
attempt = 0
QA::Runtime::Logger.debug(
- "Running eventually matcher with '#{operator_msg}' operator with: #{@retry_args}"
+ "Running eventually matcher with '#{operator_msg}' operator with: '#{retry_args}' arguments"
)
- QA::Support::Retrier.retry_until(**@retry_args, log: false) do
+ QA::Support::Retrier.retry_until(**retry_args, log: false) do
QA::Runtime::Logger.debug("evaluating expectation, attempt: #{attempt += 1}")
public_send(expectation_name, actual)
@@ -132,6 +126,44 @@ module QA
[operator, expected]
end
end
+
+ # Custom retry arguments
+ #
+ # @return [Hash]
+ def retry_args
+ @retry_args ||= { sleep_interval: 0.5 }
+ end
+
+ # Custom failure message
+ #
+ # @param [Boolean] negate
+ # @return [String]
+ def fail_message(negate: false)
+ "#{e}:\n\nexpected #{negate ? 'not ' : ''}to #{description}\n\n"\
+ "last attempt was: #{@result.nil? ? 'nil' : actual_formatted}\n\n"\
+ "Diff:#{diff}"
+ end
+
+ # Formatted expect
+ #
+ # @return [String]
+ def expected_formatted
+ RSpec::Support::ObjectFormatter.format(expected)
+ end
+
+ # Formatted actual result
+ #
+ # @return [String]
+ def actual_formatted
+ RSpec::Support::ObjectFormatter.format(@result)
+ end
+
+ # Object diff
+ #
+ # @return [String]
+ def diff
+ RSpec::Support::Differ.new(color: true).diff(@result, expected)
+ end
end
end
end
diff --git a/qa/qa/support/matchers/have_matcher.rb b/qa/qa/support/matchers/have_matcher.rb
index 47d2d246460..a90d2df96ae 100644
--- a/qa/qa/support/matchers/have_matcher.rb
+++ b/qa/qa/support/matchers/have_matcher.rb
@@ -5,6 +5,7 @@ module QA
module Matchers
module HaveMatcher
PREDICATE_TARGETS = %w[
+ auto_devops_container
element
file_content
assignee
@@ -17,6 +18,8 @@ module QA
package
pipeline
related_issue_item
+ sast_status
+ security_configuration_history_link
snippet_description
tag
label
diff --git a/qa/qa/support/page_error_checker.rb b/qa/qa/support/page_error_checker.rb
new file mode 100644
index 00000000000..5d16245b4cd
--- /dev/null
+++ b/qa/qa/support/page_error_checker.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+module QA
+ module Support
+ class PageErrorChecker
+ class << self
+ def report!(page, error_code)
+ 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}"
+ end
+
+ def return_chrome_errors(page, error_code)
+ severe_errors = logs(page).select { |log| log.level == 'SEVERE' }
+ if severe_errors.none?
+ status_code_report(error_code)
+ else
+ "There #{severe_errors.count == 1 ? 'was' : 'were'} #{severe_errors.count} "\
+ "SEVERE level error#{severe_errors.count == 1 ? '' : 's'}:\n\n#{error_report_for(severe_errors)}"
+ end
+ end
+
+ def status_code_report(error_code)
+ "Status code #{error_code} found"
+ end
+
+ def check_page_for_error_code(page)
+ error_code = 0
+ # Test for 404 img alt
+ error_code = 404 if Nokogiri::HTML.parse(page.html).xpath("//img").map { |t| t[:alt] }.first.eql?('404')
+
+ # 500 error page in header surrounded by newlines, try to match
+ five_hundred_test = Nokogiri::HTML.parse(page.html).xpath("//h1").map.first
+ unless five_hundred_test.nil?
+ error_code = 500 if five_hundred_test.text.include?('500')
+ end
+ # GDK shows backtrace rather than error page
+ error_code = 500 if Nokogiri::HTML.parse(page.html).xpath("//body//section").map { |t| t[:class] }.first.eql?('backtrace')
+
+ unless error_code == 0
+ report!(page, error_code)
+ end
+ end
+
+ def error_report_for(logs)
+ logs
+ .map(&:message)
+ .map { |message| message.gsub('\\n', "\n") }
+ end
+
+ def logs(page)
+ page.driver.browser.manage.logs.get(:browser)
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/support/wait_for_requests.rb b/qa/qa/support/wait_for_requests.rb
index 5109f51d4d7..16af4bae521 100644
--- a/qa/qa/support/wait_for_requests.rb
+++ b/qa/qa/support/wait_for_requests.rb
@@ -7,7 +7,12 @@ module QA
DEFAULT_MAX_WAIT_TIME = 60
- def wait_for_requests(skip_finished_loading_check: false)
+ def wait_for_requests(skip_finished_loading_check: false, skip_resp_code_check: false)
+ # We have tests that use 404 pages, allow them to skip this check
+ unless skip_resp_code_check
+ QA::Support::PageErrorChecker.check_page_for_error_code(Capybara.page)
+ end
+
Waiter.wait_until(log: false) do
finished_all_ajax_requests? && (!skip_finished_loading_check ? finished_loading?(wait: 1) : true)
end
diff --git a/qa/qa/tools/delete_projects.rb b/qa/qa/tools/delete_projects.rb
index 240901eea6f..1f550f035d1 100644
--- a/qa/qa/tools/delete_projects.rb
+++ b/qa/qa/tools/delete_projects.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require_relative '../../qa'
-
# This script deletes all projects directly under a group specified by ENV['TOP_LEVEL_GROUP_NAME']
# Required environment variables: GITLAB_QA_ACCESS_TOKEN and GITLAB_ADDRESS
# Optional environment variable: TOP_LEVEL_GROUP_NAME (defaults to 'gitlab-qa-sandbox-group')
diff --git a/qa/qa/tools/delete_subgroups.rb b/qa/qa/tools/delete_subgroups.rb
index bc905fdeadd..11b45365d4c 100644
--- a/qa/qa/tools/delete_subgroups.rb
+++ b/qa/qa/tools/delete_subgroups.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require_relative '../../qa'
-
# This script deletes all subgroups of a group specified by ENV['TOP_LEVEL_GROUP_NAME']
# Required environment variables: GITLAB_QA_ACCESS_TOKEN and GITLAB_ADDRESS
# Optional environment variable: TOP_LEVEL_GROUP_NAME (defaults to 'gitlab-qa-sandbox-group')
diff --git a/qa/qa/tools/delete_test_resources.rb b/qa/qa/tools/delete_test_resources.rb
new file mode 100644
index 00000000000..917cb2fa992
--- /dev/null
+++ b/qa/qa/tools/delete_test_resources.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+# This script reads from test_resources.txt file to collect data about resources to delete
+# Deletes all deletable resources that E2E tests created
+# Resource type: Sandbox, User, Fork and RSpec::Mocks::Double are not included
+#
+# 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
+
+ def initialize(file_pattern = nil)
+ 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
+ puts 'Deleting test created resources...'
+
+ if Runtime::Env.running_in_ci?
+ raise ArgumentError, 'Please provide QA_TEST_RESOURCES_FILE_PATTERN' unless ENV['QA_TEST_RESOURCES_FILE_PATTERN']
+
+ Dir.glob(@file_pattern).each do |file|
+ delete_resources(load_file(file))
+ end
+ else
+ file = Runtime::Env.test_resources_created_filepath
+ raise ArgumentError, "'#{file}' either does not exist or empty." if !File.exist?(file) || File.zero?(file)
+
+ delete_resources(load_file(file))
+ end
+
+ puts "\nDone"
+ end
+
+ private
+
+ def load_file(json)
+ JSON.parse(File.read(json))
+ end
+
+ def delete_resources(resources)
+ failures = []
+
+ resources.each_key do |type|
+ next if resources[type].empty?
+
+ resources[type].each do |resource|
+ next if resource_not_found?(resource['api_path'])
+
+ msg = resource['info'] ? "#{type} - #{resource['info']}" : "#{type} 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
+ print "\e[32m.\e[0m"
+ else
+ print "\e[31mF\e[0m"
+ failures << msg
+ end
+ end
+ end
+
+ unless failures.empty?
+ puts "\nFailed to delete #{failures.length} resources:\n"
+ puts failures
+ end
+ end
+
+ def resource_not_found?(api_path)
+ get_response = get Runtime::API::Request.new(@api_client, api_path).url
+
+ get_response.code.eql? 404
+ end
+ end
+ end
+end
diff --git a/qa/qa/tools/delete_test_ssh_keys.rb b/qa/qa/tools/delete_test_ssh_keys.rb
index 58ab4865336..9e5728a5509 100644
--- a/qa/qa/tools/delete_test_ssh_keys.rb
+++ b/qa/qa/tools/delete_test_ssh_keys.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require_relative '../../qa'
-
# This script deletes all selected test ssh keys for a specific user
# Keys can be selected by a string matching part of the key's title and by created date
# - Specify `title_portion` to delete only keys that include the string provided
diff --git a/qa/qa/tools/generate_perf_testdata.rb b/qa/qa/tools/generate_perf_testdata.rb
index 8e5da94e7e6..0f06fd2fbc4 100644
--- a/qa/qa/tools/generate_perf_testdata.rb
+++ b/qa/qa/tools/generate_perf_testdata.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'yaml'
-require_relative '../../qa'
+
# This script generates testdata for Performance Testing.
# Required environment variables: GITLAB_QA_ACCESS_TOKEN and GITLAB_ADDRESS
# This job creates a urls.txt which contains a hash of all the URLs needed for Performance Testing
diff --git a/qa/qa/tools/initialize_gitlab_auth.rb b/qa/qa/tools/initialize_gitlab_auth.rb
index 3ead8fc9bd4..86791f1f624 100644
--- a/qa/qa/tools/initialize_gitlab_auth.rb
+++ b/qa/qa/tools/initialize_gitlab_auth.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require_relative '../../qa'
-
module QA
module Tools
# Task to set default password from Runtime::Env.default_password if not set already
diff --git a/qa/qa/tools/knapsack_report.rb b/qa/qa/tools/knapsack_report.rb
index fb405e82e83..e50c4fe63d2 100644
--- a/qa/qa/tools/knapsack_report.rb
+++ b/qa/qa/tools/knapsack_report.rb
@@ -5,50 +5,86 @@ require "fog/google"
module QA
module Tools
class KnapsackReport
+ extend SingleForwardable
+
PROJECT = "gitlab-qa-resources"
BUCKET = "knapsack-reports"
+ FALLBACK_REPORT = "knapsack/master_report.json"
- class << self
- def download
- new.download_report
- end
+ def_delegators :new, :configure!, :move_regenerated_report, :download_report, :upload_report
- def upload(glob)
- new.upload_report(glob)
- end
- end
+ # Configure knapsack report
+ #
+ # * Setup variables
+ # * Fetch latest report
+ #
+ # @return [void]
+ def configure!
+ ENV["KNAPSACK_TEST_FILE_PATTERN"] ||= "qa/specs/features/**/*_spec.rb"
+ ENV["KNAPSACK_REPORT_PATH"] = report_path
- def initialize
- ENV["KNAPSACK_REPORT_PATH"] || raise("KNAPSACK_REPORT_PATH env var is required!")
- ENV["QA_KNAPSACK_REPORT_GCS_CREDENTIALS"] || raise("QA_KNAPSACK_REPORT_GCS_CREDENTIALS env var is required!")
+ Knapsack.logger = QA::Runtime::Logger.logger
+
+ download_report
end
# Download knapsack report from gcs bucket
#
# @return [void]
def download_report
- logger.info("Downloading latest knapsack report '#{report_file}'")
+ logger.debug("Downloading latest knapsack report for '#{report_name}' to '#{report_path}'")
file = client.get_object(BUCKET, report_file)
-
- logger.info("Saving latest knapsack report to '#{report_path}'")
File.write(report_path, file[:body])
+ rescue StandardError => e
+ ENV["KNAPSACK_REPORT_PATH"] = FALLBACK_REPORT
+ logger.warn("Failed to fetch latest knapsack report: #{e}")
+ logger.warn("Falling back to '#{FALLBACK_REPORT}'")
+ end
+
+ # Rename and move new regenerated report to a separate folder used to indicate report name
+ #
+ # @return [void]
+ def move_regenerated_report
+ return unless ENV["KNAPSACK_GENERATE_REPORT"] == "true"
+
+ tmp_path = "tmp/knapsack/#{report_name}"
+ FileUtils.mkdir_p(tmp_path)
+
+ # Use path from knapsack config in case of fallback to master_report.json
+ knapsack_report_path = Knapsack.report.report_path
+ logger.debug("Moving regenerated #{knapsack_report_path} to save as artifact")
+ FileUtils.cp(knapsack_report_path, "#{tmp_path}/#{ENV['CI_NODE_INDEX']}.json")
end
# Merge and upload knapsack report to gcs bucket
#
+ # Fetches all files defined in glob and uses parent folder as report name
+ #
# @param [String] glob
# @return [void]
def upload_report(glob)
- reports = Dir[glob]
- return logger.error("Pattern '#{glob}' did not match any files!") if reports.empty?
+ reports = Pathname.glob(glob).each_with_object(Hash.new { |hsh, key| hsh[key] = [] }) do |report, hash|
+ next unless report.extname == ".json"
+
+ hash[report.parent.basename.to_s].push(report)
+ end
+ return logger.error("Glob '#{glob}' did not contain any valid report files!") if reports.empty?
- report = reports
- .map { |path| JSON.parse(File.read(path)) }
- .reduce({}, :merge)
- return logger.error("Knapsack generated empty report, skipping upload!") if report.empty?
+ reports.each do |name, jsons|
+ file = "#{name}.json"
- logger.info("Uploading latest knapsack report '#{report_file}'")
- client.put_object(BUCKET, report_file, JSON.pretty_generate(report))
+ report = jsons
+ .map { |json| JSON.parse(File.read(json)) }
+ .reduce({}, :merge)
+ .sort_by { |k, v| v } # sort report by execution time
+ .to_h
+ next logger.warn("Knapsack generated empty report for '#{name}', skipping upload!") if report.empty?
+
+ logger.info("Uploading latest knapsack report '#{file}'")
+ client.put_object(BUCKET, file, JSON.pretty_generate(report))
+ rescue StandardError => e
+ logger.error("Failed to upload knapsack report for '#{name}'. Error: #{e}")
+ end
end
private
@@ -64,24 +100,50 @@ module QA
#
# @return [Fog::Storage::GoogleJSON]
def client
- @client ||= Fog::Storage::Google.new(
- google_project: PROJECT,
- google_json_key_location: ENV["QA_KNAPSACK_REPORT_GCS_CREDENTIALS"]
- )
+ @client ||= Fog::Storage::Google.new(google_project: PROJECT, **gcs_credentials)
+ end
+
+ # Base path of knapsack report
+ #
+ # @return [String]
+ def report_base_path
+ @report_base_path ||= "knapsack"
end
# Knapsack report path
#
# @return [String]
def report_path
- @report_path ||= ENV["KNAPSACK_REPORT_PATH"]
+ @report_path ||= "#{report_base_path}/#{report_file}"
end
# Knapsack report name
#
# @return [String]
def report_file
- @report_name ||= report_path.split("/").last
+ @report_file ||= "#{report_name}.json"
+ end
+
+ # Report name
+ #
+ # Infer report name from ci job name
+ # Remove characters incompatible with gcs bucket naming from job names like ee:instance-parallel
+ #
+ # @return [String]
+ def report_name
+ @report_name ||= ENV["CI_JOB_NAME"].split(" ").first.tr(":", "-")
+ end
+
+ # GCS credentials json
+ #
+ # @return [Hash]
+ def gcs_credentials
+ json_key = ENV["QA_KNAPSACK_REPORT_GCS_CREDENTIALS"] || raise(
+ "QA_KNAPSACK_REPORT_GCS_CREDENTIALS env variable is required!"
+ )
+ return { google_json_key_location: json_key } if File.exist?(json_key)
+
+ { google_json_key_string: json_key }
end
end
end
diff --git a/qa/qa/tools/long_running_spec_reporter.rb b/qa/qa/tools/long_running_spec_reporter.rb
new file mode 100644
index 00000000000..ce035248baa
--- /dev/null
+++ b/qa/qa/tools/long_running_spec_reporter.rb
@@ -0,0 +1,97 @@
+# frozen_string_literal: true
+
+require "fog/google"
+require "slack-notifier"
+
+module QA
+ module Tools
+ class LongRunningSpecReporter
+ extend SingleForwardable
+
+ SLACK_CHANNEL = "#quality-reports"
+ PROJECT = "gitlab-qa-resources"
+ BUCKET = "knapsack-reports"
+ REPORT_NAME = "ee-instance-parallel.json"
+ RUNTIME_THRESHOLD = 300
+
+ def_delegator :new, :execute
+
+ # Find and report specs exceeding runtime threshold
+ #
+ # @return [void]
+ def execute
+ return puts("No long running specs detected, all good!") if long_running_specs.empty?
+
+ specs = long_running_specs.map { |k, v| "#{k}: #{(v / 60).round(2)} minutes" }.join("\n")
+ average = mean_runtime < 60 ? "#{mean_runtime.round(0)} seconds" : "#{(mean_runtime / 60).round(2)} minutes"
+ msg = <<~MSG
+ Following spec files are exceeding #{RUNTIME_THRESHOLD / 60} minute runtime threshold!
+ Current average spec runtime: #{average}.
+ MSG
+
+ puts("#{msg}\n#{specs}")
+ notifier.post(icon_emoji: ":time-out:", text: "#{msg}\n```#{specs}```")
+ end
+
+ private
+
+ # Average runtime of spec files
+ #
+ # @return [Number]
+ def mean_runtime
+ @mean_runtime ||= latest_report.values
+ .select { |v| v < RUNTIME_THRESHOLD }
+ .yield_self { |runtimes| runtimes.sum(0.0) / runtimes.length }
+ end
+
+ # Spec files exceeding runtime threshold
+ #
+ # @return [Hash]
+ def long_running_specs
+ @long_running_specs ||= latest_report.select { |k, v| v > RUNTIME_THRESHOLD }
+ end
+
+ # Latest knapsack report
+ #
+ # @return [Hash]
+ def latest_report
+ @latest_report ||= JSON.parse(client.get_object(BUCKET, REPORT_NAME)[:body])
+ end
+
+ # Slack notifier
+ #
+ # @return [Slack::Notifier]
+ def notifier
+ @notifier ||= Slack::Notifier.new(
+ slack_webhook_url,
+ channel: SLACK_CHANNEL,
+ username: "Spec Runtime Report"
+ )
+ end
+
+ # GCS client
+ #
+ # @return [Fog::Storage::GoogleJSON]
+ def client
+ @client ||= Fog::Storage::Google.new(
+ google_project: PROJECT,
+ **(File.exist?(gcs_json) ? { google_json_key_location: gcs_json } : { google_json_key_string: gcs_json })
+ )
+ end
+
+ # Slack webhook url
+ #
+ # @return [String]
+ def slack_webhook_url
+ @slack_webhook_url ||= ENV["SLACK_WEBHOOK"] || raise("Missing SLACK_WEBHOOK env variable")
+ end
+
+ # GCS credentials json
+ #
+ # @return [Hash]
+ def gcs_json
+ ENV["QA_KNAPSACK_REPORT_GCS_CREDENTIALS"] || raise("Missing QA_KNAPSACK_REPORT_GCS_CREDENTIALS env variable!")
+ end
+ end
+ end
+end
diff --git a/qa/qa/tools/reliable_report.rb b/qa/qa/tools/reliable_report.rb
index 40a452be36e..b99b97c1ea6 100644
--- a/qa/qa/tools/reliable_report.rb
+++ b/qa/qa/tools/reliable_report.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require_relative "../../qa"
-
require "influxdb-client"
require "terminal-table"
require "slack-notifier"
@@ -16,7 +14,7 @@ module QA
PROJECT_ID = 278964
def initialize(range)
- @range = 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")
@@ -34,9 +32,8 @@ module QA
reporter.print_report
reporter.report_in_issue_and_slack if report_in_issue_and_slack == "true"
rescue StandardError => e
- puts "Report creation failed! Error: '#{e}'".colorize(:red)
- reporter.notify_failure(e)
- exit(1)
+ reporter&.notify_failure(e)
+ raise(e)
end
# Print top stable specs
@@ -58,7 +55,11 @@ module QA
puts "Creating report".colorize(:green)
response = post(
"#{gitlab_api_url}/projects/#{PROJECT_ID}/issues",
- { title: "Reliable spec report", description: report_issue_body, labels: "Quality,test" },
+ {
+ title: "Reliable e2e test report",
+ description: report_issue_body,
+ labels: "Quality,test,type::maintenance,reliable test report"
+ },
headers: { "PRIVATE-TOKEN" => gitlab_access_token }
)
web_url = parse_body(response)[:web_url]
@@ -96,68 +97,79 @@ module QA
#
# @return [String]
def report_issue_body
+ execution_interval = "(#{Date.today - range} - #{Date.today})"
+
issue = []
issue << "[[_TOC_]]"
- issue << "# Candidates for promotion to reliable\n\n```\n#{stable_summary_table}\n```"
- issue << results_markdown(stable_results_tables)
+ issue << "# Candidates for promotion to reliable #{execution_interval}"
+ issue << "Total amount: **#{stable_test_runs.sum { |_k, v| v.count }}**"
+ issue << stable_summary_table(markdown: true).to_s
+ issue << results_markdown(:stable)
return issue.join("\n\n") if unstable_reliable_test_runs.empty?
- issue << "# Reliable specs with failures\n\n```\n#{unstable_summary_table}\n```"
- issue << results_markdown(unstable_reliable_results_tables)
+ issue << "# Reliable specs with failures #{execution_interval}"
+ issue << "Total amount: **#{unstable_reliable_test_runs.sum { |_k, v| v.count }}**"
+ issue << unstable_summary_table(markdown: true).to_s
+ issue << results_markdown(:unstable)
issue.join("\n\n")
end
# Stable spec summary table
#
+ # @param [Boolean] markdown
# @return [Terminal::Table]
- def stable_summary_table
- @stable_summary_table ||= terminal_table(
+ def stable_summary_table(markdown: false)
+ terminal_table(
rows: stable_test_runs.map { |stage, specs| [stage, specs.length] },
title: "Stable spec summary for past #{range} days".ljust(50),
- headings: %w[STAGE COUNT]
+ headings: %w[STAGE COUNT],
+ markdown: markdown
)
end
# Unstable reliable summary table
#
+ # @param [Boolean] markdown
# @return [Terminal::Table]
- def unstable_summary_table
- @unstable_summary_table ||= terminal_table(
+ def unstable_summary_table(markdown: false)
+ terminal_table(
rows: unstable_reliable_test_runs.map { |stage, specs| [stage, specs.length] },
title: "Unstable spec summary for past #{range} days".ljust(50),
- headings: %w[STAGE COUNT]
+ headings: %w[STAGE COUNT],
+ markdown: markdown
)
end
# Result tables for stable specs
#
+ # @param [Boolean] markdown
# @return [Hash]
- def stable_results_tables
- @stable_results ||= results_tables(:stable)
+ def stable_results_tables(markdown: false)
+ results_tables(:stable, markdown: markdown)
end
# Result table for unstable specs
#
+ # @param [Boolean] markdown
# @return [Hash]
- def unstable_reliable_results_tables
- @unstable_results ||= results_tables(:unstable)
+ def unstable_reliable_results_tables(markdown: false)
+ results_tables(:unstable, markdown: markdown)
end
# Markdown formatted tables
#
- # @param [Hash] results
+ # @param [Symbol] type result type - :stable, :unstable
# @return [String]
- def results_markdown(results)
- results.map do |stage, table|
+ def results_markdown(type)
+ runs = type == :stable ? stable_test_runs : unstable_reliable_test_runs
+ results_tables(type, markdown: true).map do |stage, table|
<<~STAGE.strip
- ## #{stage}
+ ## #{stage} (#{runs[stage].count})
<details>
<summary>Executions table</summary>
- ```
#{table}
- ```
</details>
STAGE
@@ -167,15 +179,19 @@ module QA
# Results table
#
# @param [Symbol] type result type - :stable, :unstable
+ # @param [Boolean] markdown
# @return [Hash<Symbol, Terminal::Table>]
- def results_tables(type)
+ def results_tables(type, markdown: false)
(type == :stable ? stable_test_runs : unstable_reliable_test_runs).to_h do |stage, specs|
headings = ["name", "runs", "failures", "failure rate"]
[stage, terminal_table(
- rows: specs.map { |k, v| [name_column(k, v[:file]), *table_params(v.values)] },
title: "Top #{type} specs in '#{stage}' stage for past #{range} days",
- headings: headings.map(&:upcase)
+ headings: headings.map(&:upcase),
+ markdown: markdown,
+ rows: specs.map do |k, v|
+ [name_column(name: k, file: v[:file], markdown: markdown), *table_params(v.values)]
+ end
)]
end
end
@@ -214,13 +230,17 @@ module QA
# Terminal table for result formatting
#
+ # @param [Array] rows
+ # @param [Array] headings
+ # @param [String] title
+ # @param [Boolean] markdown
# @return [Terminal::Table]
- def terminal_table(rows:, headings:, title: nil)
+ def terminal_table(rows:, headings:, title:, markdown:)
Terminal::Table.new(
headings: headings,
- style: { all_separators: true },
- title: title,
- rows: rows
+ title: markdown ? nil : title,
+ rows: rows,
+ style: markdown ? { border: :markdown } : { all_separators: true }
)
end
@@ -232,17 +252,17 @@ module QA
[*parameters[1..2], "#{parameters.last}%"]
end
- # Name column value
+ # Name column content
#
# @param [String] name
# @param [String] file
+ # @param [Boolean] markdown
# @return [String]
- def name_column(name, file)
- spec_name = name.length > 150 ? "#{name} ".scan(/.{1,150} /).map(&:strip).join("\n") : name
- name_line = "name: '#{spec_name}'"
- file_line = "file: '#{file}'"
+ def name_column(name:, file:, markdown: false)
+ return "**name**: #{name}<br>**file**: #{file}" if markdown
- "#{name_line}\n#{file_line.ljust(160)}"
+ wrapped_name = name.length > 150 ? "#{name} ".scan(/.{1,150} /).map(&:strip).join("\n") : name
+ "name: '#{wrapped_name}'\nfile: #{file.ljust(160)}"
end
# Test executions grouped by name
@@ -254,10 +274,16 @@ module QA
all_runs = query_api.query(query: query(reliable)).values
all_runs.each_with_object(Hash.new { |hsh, key| hsh[key] = {} }) do |table, result|
- records = table.records
- name = records.last.values["name"]
- file = records.last.values["file_path"].split("/").last
- stage = records.last.values["stage"] || "unknown"
+ records = table.records.sort_by { |record| record.values["_time"] }
+ # skip specs that executed less time than defined by range or stopped executing before report date
+ # offset 1 day due to how schedulers are configured and first run can be 1 day later
+ next if (Date.today - Date.parse(records.first.values["_time"])).to_i < (range - 1)
+ next if (Date.today - Date.parse(records.last.values["_time"])).to_i > 1
+
+ last_record = records.last.values
+ name = last_record["name"]
+ file = last_record["file_path"].split("/").last
+ stage = last_record["stage"] || "unknown"
runs = records.count
failed = records.count { |r| r.values["status"] == "failed" }
diff --git a/qa/qa/tools/revoke_all_personal_access_tokens.rb b/qa/qa/tools/revoke_all_personal_access_tokens.rb
index c0a1697fa16..b4fa02a36d4 100644
--- a/qa/qa/tools/revoke_all_personal_access_tokens.rb
+++ b/qa/qa/tools/revoke_all_personal_access_tokens.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
-require_relative '../../qa'
require 'net/protocol'
+
# This script revokes all personal access tokens with the name of 'api-test-token' on the host specified by GITLAB_ADDRESS
# Required environment variables: GITLAB_USERNAME, GITLAB_PASSWORD and GITLAB_ADDRESS
# Run `rake revoke_personal_access_tokens`
diff --git a/qa/qa/tools/test_resource_data_processor.rb b/qa/qa/tools/test_resource_data_processor.rb
new file mode 100644
index 00000000000..78fb6ef6cd0
--- /dev/null
+++ b/qa/qa/tools/test_resource_data_processor.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+# This script collects all resources created during each test execution
+# Save the data and write it to a JSON file at the end of suite
+
+module QA
+ module Tools
+ class TestResourceDataProcessor
+ @resources ||= Hash.new { |hsh, key| hsh[key] = [] }
+
+ class << self
+ # Ignoring rspec-mocks, sandbox, user and fork resources
+ # TODO: Will need to figure out which user resources can be collected, ignore for now
+ #
+ # Collecting resources created in E2E tests
+ # Data is a Hash of resources with keys as resource type (group, project, issue, etc.)
+ # Each type contains an array of resource object (hash) of the same type
+ # E.g: { "QA::Resource::Project": [ { info: 'foo', api_path: '/foo'}, {...} ] }
+ def collect(resource, info)
+ return if resource.api_response.nil? ||
+ resource.is_a?(RSpec::Mocks::Double) ||
+ resource.is_a?(Resource::Sandbox) ||
+ resource.is_a?(Resource::User) ||
+ resource.is_a?(Resource::Fork)
+
+ api_path = if resource.respond_to?(:api_delete_path)
+ resource.api_delete_path.gsub('%2F', '/')
+ elsif resource.respond_to?(:api_get_path)
+ resource.api_get_path.gsub('%2F', '/')
+ else
+ 'Cannot find resource API path'
+ end
+
+ type = resource.class.name
+
+ @resources[type] << { info: info, api_path: api_path }
+ end
+
+ # If JSON file exists and not empty, read and load file content
+ # Merge what is saved in @resources into the content from file
+ # Overwrite file content with the new data hash
+ # Otherwise create file and write data hash to file for the first time
+ def write_to_file
+ return if @resources.empty?
+
+ file = Runtime::Env.test_resources_created_filepath
+ FileUtils.mkdir_p('tmp/')
+ FileUtils.touch(file)
+ data = nil
+
+ if File.zero?(file)
+ data = @resources
+ else
+ data = JSON.parse(File.read(file))
+
+ @resources.each_pair do |key, val|
+ data[key].nil? ? data[key] = val : val.each { |item| data[key] << item }
+ end
+ end
+
+ File.open(file, 'w') { |f| f.write(JSON.pretty_generate(data.each_value(&:uniq!))) }
+ end
+ end
+ end
+ end
+end
diff --git a/qa/spec/page/logging_spec.rb b/qa/spec/page/logging_spec.rb
index 7c521f60b84..98326ecd343 100644
--- a/qa/spec/page/logging_spec.rb
+++ b/qa/spec/page/logging_spec.rb
@@ -14,6 +14,7 @@ RSpec.describe QA::Support::Page::Logging do
allow(page).to receive(:find).and_return(page)
allow(page).to receive(:current_url).and_return('http://current-url')
allow(page).to receive(:has_css?).with(any_args).and_return(true)
+ allow(QA::Support::PageErrorChecker).to receive(:check_page_for_error_code).and_return(0)
end
subject do
diff --git a/qa/spec/resource/base_spec.rb b/qa/spec/resource/base_spec.rb
index 2a26a479436..2dd25f983bf 100644
--- a/qa/spec/resource/base_spec.rb
+++ b/qa/spec/resource/base_spec.rb
@@ -277,17 +277,30 @@ RSpec.describe QA::Resource::Base do
describe '#visit!' do
include_context 'with simple resource'
+ let(:wait_for_requests_class) { QA::Support::WaitForRequests }
+
before do
allow(resource).to receive(:visit)
end
it 'calls #visit with the underlying #web_url' do
allow(resource).to receive(:current_url).and_return(subject.current_url)
+ expect(wait_for_requests_class).to receive(:wait_for_requests).with({ skip_resp_code_check: false }).twice
resource.web_url = subject.current_url
resource.visit!
expect(resource).to have_received(:visit).with(subject.current_url)
end
+
+ it 'calls #visit with the underlying #web_url with skip_resp_code_check specified as true' do
+ allow(resource).to receive(:current_url).and_return(subject.current_url)
+ expect(wait_for_requests_class).to receive(:wait_for_requests).with({ skip_resp_code_check: true }).twice
+
+ resource.web_url = subject.current_url
+ resource.visit!(skip_resp_code_check: true)
+
+ expect(resource).to have_received(:visit).with(subject.current_url)
+ end
end
end
diff --git a/qa/spec/runtime/env_spec.rb b/qa/spec/runtime/env_spec.rb
index 80d8a9a1892..0f752ad96b7 100644
--- a/qa/spec/runtime/env_spec.rb
+++ b/qa/spec/runtime/env_spec.rb
@@ -83,6 +83,46 @@ RSpec.describe QA::Runtime::Env do
end
end
+ describe '.running_on_dot_com?' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:url, :result) do
+ 'https://www.gitlab.com' | true
+ 'https://staging.gitlab.com' | true
+ 'http://www.gitlab.com' | true
+ 'http://localhost:3000' | false
+ 'http://localhost' | false
+ 'http://gdk.test:3000' | false
+ end
+
+ with_them do
+ before do
+ QA::Runtime::Scenario.define(:gitlab_address, url)
+ end
+
+ it { expect(described_class.running_on_dot_com?).to eq result }
+ end
+ end
+
+ describe '.running_on_dev?' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:url, :result) do
+ 'https://www.gitlab.com' | false
+ 'http://localhost:3000' | true
+ 'http://localhost' | false
+ 'http://gdk.test:3000' | true
+ end
+
+ with_them do
+ before do
+ QA::Runtime::Scenario.define(:gitlab_address, url)
+ end
+
+ it { expect(described_class.running_on_dev?).to eq result }
+ end
+ end
+
describe '.personal_access_token' do
around do |example|
described_class.instance_variable_set(:@personal_access_token, nil)
@@ -173,31 +213,23 @@ RSpec.describe QA::Runtime::Env do
stub_env('CI_NODE_TOTAL', '2')
end
- it 'returns true if KNAPSACK_GENERATE_REPORT is defined' do
- stub_env('KNAPSACK_GENERATE_REPORT', 'true')
-
+ it 'returns true if running in parallel CI run' do
expect(described_class.knapsack?).to be_truthy
end
- it 'returns true if KNAPSACK_REPORT_PATH is defined' do
- stub_env('KNAPSACK_REPORT_PATH', '/a/path')
-
- expect(described_class.knapsack?).to be_truthy
+ it 'returns false if knapsack disabled' do
+ stub_env('NO_KNAPSACK', 'true')
+ expect(described_class.knapsack?).to be_falsey
end
- it 'returns true if KNAPSACK_TEST_FILE_PATTERN is defined' do
- stub_env('KNAPSACK_TEST_FILE_PATTERN', '/a/**/pattern')
-
- expect(described_class.knapsack?).to be_truthy
- end
+ it 'returns false if not running in a parallel job' do
+ stub_env('CI_NODE_TOTAL', '1')
- it 'returns false if neither KNAPSACK_GENERATE_REPORT nor KNAPSACK_REPORT_PATH nor KNAPSACK_TEST_FILE_PATTERN are defined' do
expect(described_class.knapsack?).to be_falsey
end
- it 'returns false if not running in parallel job' do
- stub_env('CI_NODE_TOTAL', '1')
- stub_env('KNAPSACK_GENERATE_REPORT', 'true')
+ it 'returns false if not running in ci' do
+ stub_env('CI_NODE_TOTAL', nil)
expect(described_class.knapsack?).to be_falsey
end
@@ -328,4 +360,36 @@ 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/scenario/test/integration/github_spec.rb b/qa/spec/scenario/test/integration/github_spec.rb
index b68b06a7b9f..4ad42b4f5cc 100644
--- a/qa/spec/scenario/test/integration/github_spec.rb
+++ b/qa/spec/scenario/test/integration/github_spec.rb
@@ -2,7 +2,7 @@
RSpec.describe QA::Scenario::Test::Integration::Github do
describe '#perform' do
- let(:env) { spy('Runtime::Env') }
+ let(:env) { spy('Runtime::Env', knapsack?: false, dry_run: false) }
before do
stub_const('QA::Runtime::Env', env)
diff --git a/qa/spec/spec_helper.rb b/qa/spec/spec_helper.rb
index 4372d9d2728..47791f76970 100644
--- a/qa/spec/spec_helper.rb
+++ b/qa/spec/spec_helper.rb
@@ -10,9 +10,9 @@ require 'active_support/core_ext/object/blank'
require_relative 'qa_deprecation_toolkit_env'
QaDeprecationToolkitEnv.configure!
-Knapsack::Adapters::RSpecAdapter.bind if ENV['CI'] && QA::Runtime::Env.knapsack? && !ENV['NO_KNAPSACK']
+Knapsack::Adapters::RSpecAdapter.bind if QA::Runtime::Env.knapsack?
-QA::Runtime::Browser.configure!
+QA::Runtime::Browser.configure! unless QA::Runtime::Env.dry_run
QA::Runtime::AllureReport.configure!
QA::Runtime::Scenario.from_env(QA::Runtime::Env.runtime_scenario_attributes)
@@ -66,9 +66,14 @@ RSpec.configure do |config|
config.after(:suite) do |suite|
# If any tests failed, leave the resources behind to help troubleshoot
- next if suite.reporter.failed_examples.present?
+ QA::Resource::ReusableProject.remove_all_via_api! unless suite.reporter.failed_examples.present?
- QA::Resource::ReusableProject.remove_all_via_api!
+ # Write all test created resources to JSON file
+ QA::Tools::TestResourceDataProcessor.write_to_file
+ end
+
+ config.append_after(:suite) do
+ QA::Tools::KnapsackReport.move_regenerated_report if QA::Runtime::Env.knapsack?
end
config.expect_with :rspec do |expectations|
@@ -95,8 +100,14 @@ RSpec.configure do |config|
if ENV['CI'] && !QA::Runtime::Env.disable_rspec_retry?
non_quarantine_retries = QA::Runtime::Env.ci_project_name =~ /staging|canary|production/ ? 3 : 2
config.around do |example|
- retry_times = example.metadata.key?(:quarantine) ? 1 : non_quarantine_retries
- example.run_with_retry retry: retry_times
+ quarantine = example.metadata[:quarantine]
+ different_quarantine_context = QA::Specs::Helpers::Quarantine.quarantined_different_context?(quarantine)
+ focused_quarantine = QA::Specs::Helpers::Quarantine.filters.key?(:quarantine)
+
+ # Do not disable retry when spec is quarantined but on different environment
+ next example.run_with_retry(retry: non_quarantine_retries) if different_quarantine_context && !focused_quarantine
+
+ example.run_with_retry(retry: quarantine ? 1 : non_quarantine_retries)
end
end
end
diff --git a/qa/spec/specs/runner_spec.rb b/qa/spec/specs/runner_spec.rb
index 021ce9091e0..5cc9ff403cd 100644
--- a/qa/spec/specs/runner_spec.rb
+++ b/qa/spec/specs/runner_spec.rb
@@ -28,6 +28,26 @@ RSpec.describe QA::Specs::Runner do
end
end
+ context 'when count_examples_only is set as an option' do
+ let(:out) { StringIO.new }
+
+ before do
+ QA::Runtime::Scenario.define(:count_examples_only, true)
+ out.string = '22 examples,'
+ allow(StringIO).to receive(:new).and_return(out)
+ end
+
+ it 'sets the `--dry-run` flag' do
+ expect_rspec_runner_arguments(['--dry-run', '--tag', '~orchestrated', '--tag', '~transient', '--tag', '~geo', *described_class::DEFAULT_TEST_PATH_ARGS], [$stderr, anything])
+
+ subject.perform
+ end
+
+ after do
+ QA::Runtime::Scenario.attributes.delete(:count_examples_only)
+ end
+ end
+
context 'when tags are set' do
subject { described_class.new.tap { |runner| runner.tags = %i[orchestrated github] } }
@@ -158,10 +178,10 @@ RSpec.describe QA::Specs::Runner do
end
end
- def expect_rspec_runner_arguments(arguments)
+ def expect_rspec_runner_arguments(arguments, std_arguments = described_class::DEFAULT_STD_ARGS)
expect(RSpec::Core::Runner).to receive(:run)
- .with(arguments, $stderr, $stdout)
- .and_return(0)
+ .with(arguments, *std_arguments)
+ .and_return(0)
end
end
end
diff --git a/qa/spec/support/formatters/test_stats_formatter_spec.rb b/qa/spec/support/formatters/test_stats_formatter_spec.rb
index 71ab9c1d541..2bfd7863653 100644
--- a/qa/spec/support/formatters/test_stats_formatter_spec.rb
+++ b/qa/spec/support/formatters/test_stats_formatter_spec.rb
@@ -56,13 +56,14 @@ 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,
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/1234'
}
}
end
def run_spec(&spec)
- spec ||= -> { it('spec') {} }
+ spec ||= -> { it('spec', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/1234') {} }
describe_successfully('stats export', &spec).tap do |example_group|
example_group.examples.each { |ex| ex.metadata[:file_path] = file_path }
@@ -131,7 +132,7 @@ describe QA::Support::Formatters::TestStatsFormatter do
it 'exports data to influxdb with correct reliable tag' do
run_spec do
- it('spec', :reliable) {}
+ it('spec', :reliable, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/1234') {}
end
expect(influx_write_api).to have_received(:write).with(data: [data])
@@ -143,7 +144,7 @@ describe QA::Support::Formatters::TestStatsFormatter do
it 'exports data to influxdb with correct quarantine tag' do
run_spec do
- it('spec', :quarantine) {}
+ it('spec', :quarantine, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/1234') {}
end
expect(influx_write_api).to have_received(:write).with(data: [data])
diff --git a/qa/spec/support/page_error_checker_spec.rb b/qa/spec/support/page_error_checker_spec.rb
new file mode 100644
index 00000000000..764b6110e08
--- /dev/null
+++ b/qa/spec/support/page_error_checker_spec.rb
@@ -0,0 +1,217 @@
+# frozen_string_literal: true
+
+RSpec.describe QA::Support::PageErrorChecker do
+ let(:test_path) { '/test/path' }
+
+ let(:page) { double(Capybara.page) }
+
+ describe '.report!' do
+ context 'reports errors' do
+ let(:expected_chrome_error) do
+ "chrome errors\n\n"\
+ "Path: #{test_path}"
+ end
+
+ let(:expected_basic_error) do
+ "foo status\n\n"\
+ "Path: #{test_path}"
+ end
+
+ it 'reports error message on chrome browser' do
+ 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)
+
+ expect { QA::Support::PageErrorChecker.report!(page, 500) }.to raise_error(RuntimeError, expected_chrome_error)
+ end
+
+ it 'reports basic message on non-chrome browser' do
+ 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
+ end
+ end
+
+ describe '.return_chrome_errors' do
+ context 'returns error message' do
+ before do
+ single_log = Class.new do
+ def level
+ 'SEVERE'
+ end
+ end
+ stub_const('SingleLog', single_log)
+ one_error_mocked_logs = Class.new do
+ def self.select
+ [SingleLog]
+ end
+ end
+ stub_const('OneErrorMockedLogs', one_error_mocked_logs)
+ three_errors_mocked_logs = Class.new do
+ def self.select
+ [SingleLog, SingleLog, SingleLog]
+ end
+ end
+ stub_const('ThreeErrorsMockedLogs', three_errors_mocked_logs)
+ no_error_mocked_logs = Class.new do
+ def self.select
+ []
+ end
+ end
+ stub_const('NoErrorMockedLogs', no_error_mocked_logs)
+ end
+
+ let(:expected_single_error) do
+ "There was 1 SEVERE level error:\n\n"\
+ "bar foo"
+ end
+
+ let(:expected_multiple_error) do
+ "There were 3 SEVERE level errors:\n\n"\
+ "bar foo\n"\
+ "foo\n"\
+ "bar"
+ end
+
+ it 'returns status code report on no severe errors found' do
+ allow(QA::Support::PageErrorChecker).to receive(:logs).with(page).and_return(NoErrorMockedLogs)
+ allow(QA::Support::PageErrorChecker).to receive(:status_code_report).with('123').and_return('Test Status Code return 123')
+
+ expect(QA::Support::PageErrorChecker.return_chrome_errors(page, '123')).to eq('Test Status Code return 123')
+ end
+
+ it 'returns report on 1 severe error found' do
+ allow(QA::Support::PageErrorChecker).to receive(:error_report_for).with([SingleLog]).and_return('bar foo')
+ allow(QA::Support::PageErrorChecker).to receive(:logs).with(page).and_return(OneErrorMockedLogs)
+ allow(page).to receive(:current_path).and_return(test_path)
+
+ expect(QA::Support::PageErrorChecker.return_chrome_errors(page, '123')).to eq(expected_single_error)
+ end
+
+ it 'returns report on multiple severe errors found' do
+ allow(QA::Support::PageErrorChecker).to receive(:error_report_for)
+ .with([SingleLog, SingleLog, SingleLog]).and_return("bar foo\nfoo\nbar")
+ allow(QA::Support::PageErrorChecker).to receive(:logs).with(page).and_return(ThreeErrorsMockedLogs)
+ allow(page).to receive(:current_path).and_return(test_path)
+
+ expect(QA::Support::PageErrorChecker.return_chrome_errors(page, '123')).to eq(expected_multiple_error)
+ end
+ end
+ end
+
+ describe '.check_page_for_error_code' 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_404_str) do
+ "<div class=\"error\">"\
+ "<img src=\"404.png\" alt=\"404\" />"\
+ "</div>"
+ end
+
+ let(:error_500_str) { "<h1> 500 </h1>"}
+ let(:backtrace_str) {"<body><section class=\"backtrace\">foo</section></body>"}
+ let(:no_error_str) {"<body>no 404 or 500 or backtrace</body>"}
+
+ it 'calls report with 404 if 404 found' do
+ allow(page).to receive(:html).and_return(error_404_str)
+ allow(Nokogiri::HTML).to receive(:parse).with(error_404_str).and_return(NokogiriParse.parse(error_404_str))
+
+ expect(QA::Support::PageErrorChecker).to receive(:report!).with(page, 404)
+ QA::Support::PageErrorChecker.check_page_for_error_code(page)
+ end
+ it 'calls report with 500 if 500 found' 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).to receive(:report!).with(page, 500)
+ QA::Support::PageErrorChecker.check_page_for_error_code(page)
+ end
+ it 'calls report with 500 if GDK backtrace found' do
+ allow(page).to receive(:html).and_return(backtrace_str)
+ allow(Nokogiri::HTML).to receive(:parse).with(backtrace_str).and_return(NokogiriParse.parse(backtrace_str))
+
+ expect(QA::Support::PageErrorChecker).to receive(:report!).with(page, 500)
+ QA::Support::PageErrorChecker.check_page_for_error_code(page)
+ end
+ it 'does not call report if no 404, 500 or backtrace found' do
+ allow(page).to receive(:html).and_return(no_error_str)
+ allow(Nokogiri::HTML).to receive(:parse).with(no_error_str).and_return(NokogiriParse.parse(no_error_str))
+
+ expect(QA::Support::PageErrorChecker).not_to receive(:report!)
+ QA::Support::PageErrorChecker.check_page_for_error_code(page)
+ end
+ end
+
+ describe '.error_report_for' do
+ before do
+ logs_class_one = Class.new do
+ def self.message
+ 'foo\\n'
+ end
+ end
+ stub_const('LogOne', logs_class_one)
+ logs_class_two = Class.new do
+ def self.message
+ 'bar'
+ end
+ end
+ stub_const('LogTwo', logs_class_two)
+ end
+
+ it 'returns error report array of log messages' do
+ expect(QA::Support::PageErrorChecker.error_report_for([LogOne, LogTwo]))
+ .to eq(%W(foo\n bar))
+ end
+ end
+
+ describe '.logs' do
+ before do
+ logs_class = Class.new do
+ def self.get(level)
+ "logs at #{level} level"
+ end
+ end
+ stub_const('Logs', logs_class)
+ manage_class = Class.new do
+ def self.logs
+ Logs
+ end
+ end
+ stub_const('Manage', manage_class)
+ browser_class = Class.new do
+ def self.manage
+ Manage
+ end
+ end
+ stub_const('Browser', browser_class)
+ driver_class = Class.new do
+ def self.browser
+ Browser
+ end
+ end
+ stub_const('Driver', driver_class)
+ end
+
+ it 'gets driver browser logs' do
+ allow(page).to receive(:driver).and_return(Driver)
+
+ expect(QA::Support::PageErrorChecker.logs(page)).to eq('logs at browser level')
+ end
+ end
+
+ describe '.status_code_report' do
+ it 'returns a string message containing the status code' do
+ expect(QA::Support::PageErrorChecker.status_code_report(1234)).to eq('Status code 1234 found')
+ end
+ end
+end
diff --git a/qa/spec/support/wait_for_requests_spec.rb b/qa/spec/support/wait_for_requests_spec.rb
index 47c35addd9f..2492820b67f 100644
--- a/qa/spec/support/wait_for_requests_spec.rb
+++ b/qa/spec/support/wait_for_requests_spec.rb
@@ -22,5 +22,21 @@ RSpec.describe QA::Support::WaitForRequests do
subject.wait_for_requests(skip_finished_loading_check: true)
end
end
+
+ context 'when skip_resp_code_check is defaulted to false' do
+ it 'call report' do
+ allow(QA::Support::PageErrorChecker).to receive(:check_page_for_error_code).with(Capybara.page)
+
+ subject.wait_for_requests
+ end
+ end
+
+ context 'when skip_resp_code_check is true' do
+ it 'does not parse for an error code' do
+ expect(QA::Support::PageErrorChecker).not_to receive(:check_page_for_error_code)
+
+ subject.wait_for_requests(skip_resp_code_check: true)
+ end
+ end
end
end
diff --git a/qa/spec/tools/long_running_spec_reporter_spec.rb b/qa/spec/tools/long_running_spec_reporter_spec.rb
new file mode 100644
index 00000000000..1bf520c53af
--- /dev/null
+++ b/qa/spec/tools/long_running_spec_reporter_spec.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+RSpec.describe QA::Tools::LongRunningSpecReporter do
+ include QA::Support::Helpers::StubEnv
+
+ subject(:reporter) { described_class.execute }
+
+ let(:gcs_client) { double("Fog::Storage::GoogleJSON", get_object: report) }
+ let(:slack_notifier) { double("Slack::Notifier", post: nil) }
+
+ before do
+ stub_env("SLACK_WEBHOOK", "slack_url")
+ stub_env("QA_KNAPSACK_REPORT_GCS_CREDENTIALS", "gcs_json")
+
+ allow(Fog::Storage::Google).to receive(:new)
+ .with(google_project: "gitlab-qa-resources", google_json_key_string: "gcs_json")
+ .and_return(gcs_client)
+ allow(Slack::Notifier).to receive(:new)
+ .with("slack_url", channel: "#quality-reports", username: "Spec Runtime Report")
+ .and_return(slack_notifier)
+ end
+
+ context "without specs exceeding runtime" do
+ let(:report) do
+ {
+ body: <<~JSON
+ {
+ "spec.rb": 5,
+ "spec_2.rb": 10
+ }
+ JSON
+ }
+ end
+
+ it "returns all good message" do
+ expect { reporter }.to output("No long running specs detected, all good!\n").to_stdout
+ end
+ end
+
+ context "with specs exceeding runtime" do
+ let(:report) do
+ {
+ body: <<~JSON
+ {
+ "spec.rb": 5.0,
+ "spec_2.rb": 320.0
+ }
+ JSON
+ }
+ end
+
+ let(:spec) { "spec_2.rb: 5.33 minutes" }
+
+ let(:message) do
+ <<~MSG
+ Following spec files are exceeding 5 minute runtime threshold!
+ Current average spec runtime: 5 seconds.
+ MSG
+ end
+
+ it "notifies on long running specs" do
+ expect { reporter }.to output("#{message}\n#{spec}\n").to_stdout
+ expect(slack_notifier).to have_received(:post).with(
+ icon_emoji: ":time-out:",
+ text: "#{message}\n```#{spec}```"
+ )
+ end
+ end
+end
diff --git a/qa/spec/tools/reliable_report_spec.rb b/qa/spec/tools/reliable_report_spec.rb
index a048aa2e6ea..1ff62df34e0 100644
--- a/qa/spec/tools/reliable_report_spec.rb
+++ b/qa/spec/tools/reliable_report_spec.rb
@@ -13,30 +13,43 @@ describe QA::Tools::ReliableReport do
let(:slack_channel) { "#quality-reports" }
let(:range) { 14 }
let(:issue_url) { "https://gitlab.com/issue/1" }
+ let(:time) { "2021-12-07T04:05:25.000000000+00:00" }
let(:runs) do
- values = { "name" => "stable spec", "status" => "passed", "file_path" => "some/spec.rb", "stage" => "manage" }
+ values = {
+ "name" => "stable spec",
+ "status" => "passed",
+ "file_path" => "some/spec.rb",
+ "stage" => "manage",
+ "_time" => time
+ }
{
0 => instance_double(
"InfluxDB2::FluxTable",
records: [
instance_double("InfluxDB2::FluxRecord", values: values),
instance_double("InfluxDB2::FluxRecord", values: values),
- instance_double("InfluxDB2::FluxRecord", values: values)
+ instance_double("InfluxDB2::FluxRecord", values: values.merge({ "_time" => Time.now.to_s }))
]
)
}
end
let(:reliable_runs) do
- values = { "name" => "unstable spec", "status" => "failed", "file_path" => "some/spec.rb", "stage" => "create" }
+ values = {
+ "name" => "unstable spec",
+ "status" => "failed",
+ "file_path" => "some/spec.rb",
+ "stage" => "create",
+ "_time" => time
+ }
{
0 => instance_double(
"InfluxDB2::FluxTable",
records: [
instance_double("InfluxDB2::FluxRecord", values: { **values, "status" => "passed" }),
instance_double("InfluxDB2::FluxRecord", values: values),
- instance_double("InfluxDB2::FluxRecord", values: values)
+ instance_double("InfluxDB2::FluxRecord", values: values.merge({ "_time" => Time.now.to_s }))
]
)
}
@@ -67,41 +80,34 @@ describe QA::Tools::ReliableReport do
def markdown_section(summary, result, stage, type)
<<~SECTION.strip
- ```
- #{summary_table(summary, type)}
- ```
+ #{summary_table(summary, type, true)}
- ## #{stage}
+ ## #{stage} (1)
<details>
<summary>Executions table</summary>
- ```
- #{table(result, ['NAME', 'RUNS', 'FAILURES', 'FAILURE RATE'], "Top #{type} specs in '#{stage}' stage for past #{range} days")}
- ```
+ #{table(result, ['NAME', 'RUNS', 'FAILURES', 'FAILURE RATE'], "Top #{type} specs in '#{stage}' stage for past #{range} days", true)}
</details>
SECTION
end
- def summary_table(summary, type)
- table(summary, %w[STAGE COUNT], "#{type.capitalize} spec summary for past #{range} days".ljust(50))
+ def summary_table(summary, type, markdown = false)
+ table(summary, %w[STAGE COUNT], "#{type.capitalize} spec summary for past #{range} days".ljust(50), markdown)
end
- def table(rows, headings, title)
+ def table(rows, headings, title, markdown = false)
Terminal::Table.new(
headings: headings,
- style: { all_separators: true },
- title: title,
- rows: rows
+ title: markdown ? nil : title,
+ rows: rows,
+ style: markdown ? { border: :markdown } : { all_separators: true }
)
end
def name_column(spec_name)
- name = "name: '#{spec_name}'"
- file = "file: 'spec.rb'".ljust(160)
-
- "#{name}\n#{file}"
+ "**name**: #{spec_name}<br>**file**: spec.rb"
end
before do
@@ -136,11 +142,15 @@ describe QA::Tools::ReliableReport do
<<~TXT.strip
[[_TOC_]]
- # Candidates for promotion to reliable
+ # Candidates for promotion to reliable (#{Date.today - range} - #{Date.today})
+
+ Total amount: **1**
#{markdown_section([['manage', 1]], [[name_column('stable spec'), 3, 0, '0%']], 'manage', 'stable')}
- # Reliable specs with failures
+ # Reliable specs with failures (#{Date.today - range} - #{Date.today})
+
+ Total amount: **1**
#{markdown_section([['create', 1]], [[name_column('unstable spec'), 3, 2, '66.67%']], 'create', 'unstable')}
TXT
@@ -155,9 +165,9 @@ describe QA::Tools::ReliableReport do
verify_ssl: false,
headers: { "PRIVATE-TOKEN" => "gitlab_token" },
payload: {
- title: "Reliable spec report",
+ title: "Reliable e2e test report",
description: issue_body,
- labels: "Quality,test"
+ labels: "Quality,test,type::maintenance,reliable test report"
}
)
expect(slack_notifier).to have_received(:post).with(
@@ -180,7 +190,7 @@ describe QA::Tools::ReliableReport do
end
it "notifies failure", :aggregate_failures do
- expect { expect { run }.to raise_error(SystemExit) }.to output.to_stdout
+ expect { expect { run }.to raise_error("Connection error!") }.to output.to_stdout
expect(slack_notifier).to have_received(:post).with(
icon_emoji: ":sadpanda:",
diff --git a/qa/spec/tools/test_resources_data_processor_spec.rb b/qa/spec/tools/test_resources_data_processor_spec.rb
new file mode 100644
index 00000000000..6a8c0fd06a4
--- /dev/null
+++ b/qa/spec/tools/test_resources_data_processor_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+RSpec.describe QA::Tools::TestResourceDataProcessor do
+ let(:info) { 'information' }
+ let(:api_path) { '/foo' }
+ let(:result) { [{ info: info, api_path: api_path }] }
+
+ describe '.collect' do
+ context 'when resource is not restricted' do
+ let(:resource) { instance_double(QA::Resource::Project, api_delete_path: '/foo', api_response: 'foo') }
+
+ it 'collects resource' do
+ expect(described_class.collect(resource, info)).to eq(result)
+ end
+ end
+
+ context 'when resource api response is nil' do
+ let(:resource) { double(QA::Resource::Project, api_delete_path: '/foo', api_response: nil) }
+
+ it 'does not collect resource' do
+ expect(described_class.collect(resource, info)).to eq(nil)
+ end
+ end
+
+ context 'when resource is restricted' do
+ let(:resource) { double(QA::Resource::Sandbox, api_delete_path: '/foo', api_response: 'foo') }
+
+ it 'does not collect resource' do
+ expect(described_class.collect(resource, info)).to eq(nil)
+ end
+ end
+ end
+end
diff --git a/qa/tasks/knapsack.rake b/qa/tasks/knapsack.rake
index ea15793a457..ce4a1679bd1 100644
--- a/qa/tasks/knapsack.rake
+++ b/qa/tasks/knapsack.rake
@@ -1,8 +1,6 @@
# frozen_string_literal: true
# rubocop:disable Rails/RakeEnvironment
-require_relative "../qa/tools/knapsack_report"
-
namespace :knapsack do
desc "Download latest knapsack report"
task :download do
@@ -10,8 +8,13 @@ namespace :knapsack do
end
desc "Merge and upload knapsack report"
- task :upload, [:glob_pattern] do |_task, args|
- QA::Tools::KnapsackReport.upload(args[:glob_pattern])
+ task :upload, [:glob] do |_task, args|
+ QA::Tools::KnapsackReport.upload_report(args[:glob])
+ end
+
+ desc "Report long running spec files"
+ task :notify_long_running_specs do
+ QA::Tools::LongRunningSpecReporter.execute
end
end
# rubocop:enable Rails/RakeEnvironment
diff --git a/qa/tasks/reliable_report.rake b/qa/tasks/reliable_report.rake
index 4ec86779704..b4dcc2ebc01 100644
--- a/qa/tasks/reliable_report.rake
+++ b/qa/tasks/reliable_report.rake
@@ -1,8 +1,6 @@
# frozen_string_literal: true
# rubocop:disable Rails/RakeEnvironment
-require_relative "../qa/tools/reliable_report"
-
desc "Fetch reliable and unreliable spec data and create report"
task :reliable_spec_report, [:range, :report_in_issue_and_slack] do |_task, args|
QA::Tools::ReliableReport.run(**args)
diff --git a/rubocop/code_reuse_helpers.rb b/rubocop/code_reuse_helpers.rb
index 6ea12999cae..45cfa7ba78d 100644
--- a/rubocop/code_reuse_helpers.rb
+++ b/rubocop/code_reuse_helpers.rb
@@ -1,7 +1,15 @@
# frozen_string_literal: true
+require 'forwardable'
+
+require_relative '../lib/gitlab_edition'
+
module RuboCop
module CodeReuseHelpers
+ extend Forwardable
+
+ def_delegators :GitlabEdition, :ee?, :jh?
+
# Returns true for a `(send const ...)` node.
def send_to_constant?(node)
node.type == :send && node.children&.first&.type == :const
@@ -180,13 +188,5 @@ module RuboCop
def rails_root
File.expand_path('..', __dir__)
end
-
- def ee?
- File.exist?(File.expand_path('../ee/app/models/license.rb', __dir__)) && !%w[true 1].include?(ENV['FOSS_ONLY'].to_s)
- end
-
- def jh?
- ee? && Dir.exist?(File.expand_path('../jh', __dir__)) && !%w[true 1].include?(ENV['EE_ONLY'].to_s)
- end
end
end
diff --git a/rubocop/cop/database/establish_connection.rb b/rubocop/cop/database/establish_connection.rb
new file mode 100644
index 00000000000..20454887ce2
--- /dev/null
+++ b/rubocop/cop/database/establish_connection.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module RuboCop
+ module Cop
+ module Database
+ class EstablishConnection < RuboCop::Cop::Cop
+ MSG = "Don't establish new database connections, as this slows down " \
+ 'tests and may result in new connections using an incorrect configuration'
+
+ def_node_matcher :establish_connection?, <<~PATTERN
+ (send (const ...) :establish_connection ...)
+ PATTERN
+
+ def on_send(node)
+ add_offense(node, location: :expression) if establish_connection?(node)
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction.rb b/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction.rb
new file mode 100644
index 00000000000..f5343f973e1
--- /dev/null
+++ b/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+require_relative '../../migration_helpers'
+
+module RuboCop
+ module Cop
+ module Migration
+ # Cop that prevents usage of `enable_lock_retries!` within the `disable_ddl_transaction!` method.
+ class PreventGlobalEnableLockRetriesWithDisableDdlTransaction < RuboCop::Cop::Cop
+ include MigrationHelpers
+
+ MSG = '`enable_lock_retries!` cannot be used with `disable_ddl_transaction!`. Use the `with_lock_retries` helper method to define retriable code blocks.'
+
+ def_node_matcher :enable_lock_retries?, <<~PATTERN
+ (send _ :enable_lock_retries! ...)
+ PATTERN
+
+ def_node_matcher :disable_ddl_transaction?, <<~PATTERN
+ (send _ :disable_ddl_transaction! ...)
+ PATTERN
+
+ def on_begin(node)
+ return unless in_migration?(node)
+
+ has_enable_lock_retries = false
+ has_disable_ddl_transaction = false
+
+ node.each_descendant(:send) do |send_node|
+ has_enable_lock_retries = true if enable_lock_retries?(send_node)
+ has_disable_ddl_transaction = true if disable_ddl_transaction?(send_node)
+
+ if has_enable_lock_retries && has_disable_ddl_transaction
+ add_offense(send_node, message: MSG)
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/migration/schedule_async.rb b/rubocop/cop/migration/schedule_async.rb
index 74bd2baffa9..f31bfa46aa7 100644
--- a/rubocop/cop/migration/schedule_async.rb
+++ b/rubocop/cop/migration/schedule_async.rb
@@ -11,9 +11,8 @@ module RuboCop
ENFORCED_SINCE = 2020_02_12_00_00_00
MSG = <<~MSG
- Don't call the background migration worker directly, use the `#migrate_async`,
- `#migrate_in`, `#bulk_migrate_async` or `#bulk_migrate_in` migration helpers
- instead.
+ Don't call the background migration worker directly, use the `#migrate_in` or
+ `#queue_background_migration_jobs_by_range_at_intervals` migration helpers instead.
MSG
def_node_matcher :calls_background_migration_worker?, <<~PATTERN
@@ -26,28 +25,6 @@ module RuboCop
add_offense(node, location: :expression) if calls_background_migration_worker?(node)
end
-
- def autocorrect(node)
- # This gets rid of the receiver `BackgroundMigrationWorker` and
- # replaces `perform` with `schedule`
- schedule_method = method_name(node).to_s.sub('perform', 'migrate')
- arguments = arguments(node).map(&:source).join(', ')
-
- replacement = "#{schedule_method}(#{arguments})"
- lambda do |corrector|
- corrector.replace(node.source_range, replacement)
- end
- end
-
- private
-
- def method_name(node)
- node.children.second
- end
-
- def arguments(node)
- node.children[2..]
- end
end
end
end
diff --git a/scripts/gitaly-test-build b/scripts/gitaly-test-build
index e6afadccc7e..adc9b56ca4f 100755
--- a/scripts/gitaly-test-build
+++ b/scripts/gitaly-test-build
@@ -13,8 +13,6 @@ class GitalyTestBuild
include GitalySetup
def run
- set_bundler_config
-
# If we have the binaries from the cache, we can skip building them again
if File.exist?(tmp_tests_gitaly_bin_dir)
GitalySetup::LOGGER.debug "Gitaly binary already built. Skip building...\n"
diff --git a/scripts/gitaly-test-spawn b/scripts/gitaly-test-spawn
index e7e25a217b2..eed79f75224 100755
--- a/scripts/gitaly-test-spawn
+++ b/scripts/gitaly-test-spawn
@@ -9,17 +9,11 @@ class GitalyTestSpawn
include GitalySetup
def run
- set_bundler_config
- install_gitaly_gems if ENV['CI']
- check_gitaly_config!
+ install_gitaly_gems
- # # Uncomment line below to see all gitaly logs merged into CI trace
- # spawn('sleep 1; tail -f log/gitaly-test.log')
-
- # In local development this pid file is used by rspec.
- IO.write(File.expand_path('../tmp/tests/gitaly.pid', __dir__), start_gitaly)
- IO.write(File.expand_path('../tmp/tests/gitaly2.pid', __dir__), start_gitaly2)
- IO.write(File.expand_path('../tmp/tests/praefect.pid', __dir__), start_praefect)
+ # Optionally specify the path to the gitaly config toml as first argument.
+ # Used by workhorse in test.
+ spawn_gitaly(ARGV[0])
end
end
diff --git a/scripts/insert-rspec-profiling-data b/scripts/insert-rspec-profiling-data
index b2011858558..be25972644c 100755
--- a/scripts/insert-rspec-profiling-data
+++ b/scripts/insert-rspec-profiling-data
@@ -12,7 +12,7 @@ module RspecProfiling
# This disables the automatic creation of the database and
# table. In the future, we may want a way to specify the host of
# the database to connect so that we can call #install.
- Result.establish_connection(results_url)
+ Result.establish_connection(results_url) # rubocop: disable Database/EstablishConnection
end
def results_url
diff --git a/scripts/lint-doc.sh b/scripts/lint-doc.sh
index 1698d724fd2..a036b3f7342 100755
--- a/scripts/lint-doc.sh
+++ b/scripts/lint-doc.sh
@@ -128,7 +128,7 @@ function run_locally_or_in_docker() {
$cmd $args
elif hash docker 2>/dev/null
then
- docker run -t -v ${PWD}:/gitlab -w /gitlab --rm registry.gitlab.com/gitlab-org/gitlab-docs/lint-markdown:alpine-3.14-vale-2.12.0-markdownlint-0.29.0 ${cmd} ${args}
+ docker run -t -v ${PWD}:/gitlab -w /gitlab --rm registry.gitlab.com/gitlab-org/gitlab-docs/lint-markdown:alpine-3.15-vale-2.14.0-markdownlint-0.30.0 ${cmd} ${args}
else
echo
echo " ✖ ERROR: '${cmd}' not found. Install '${cmd}' or Docker to proceed." >&2
diff --git a/scripts/setup/find-jh-branch.rb b/scripts/setup/find-jh-branch.rb
new file mode 100755
index 00000000000..812e1c210f4
--- /dev/null
+++ b/scripts/setup/find-jh-branch.rb
@@ -0,0 +1,102 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+# In spec/scripts/setup/find_jh_branch_spec.rb we completely stub it
+require 'gitlab' unless Object.const_defined?(:Gitlab)
+
+require_relative '../api/default_options'
+
+class FindJhBranch
+ JH_DEFAULT_BRANCH = 'main-jh'
+ JH_PROJECT_PATH = 'gitlab-jh/gitlab'
+ BranchNotFound = Class.new(RuntimeError)
+
+ def run
+ return JH_DEFAULT_BRANCH unless merge_request?
+
+ jh_merge_request_ref_name ||
+ default_branch_merge_request_ref_name ||
+ stable_branch_merge_request_ref_name ||
+ default_branch_for_non_stable
+ end
+
+ private
+
+ def merge_request?
+ !!merge_request_id
+ end
+
+ def jh_merge_request_ref_name
+ branch_exist?(JH_PROJECT_PATH, jh_ref_name) && jh_ref_name
+ end
+
+ def default_branch_merge_request_ref_name
+ target_default_branch? && JH_DEFAULT_BRANCH
+ end
+
+ def stable_branch_merge_request_ref_name
+ target_stable_branch? && begin
+ jh_stable_branch_name = merge_request.target_branch.sub(/\-ee\z/, '-jh')
+
+ branch_exist?(JH_PROJECT_PATH, jh_stable_branch_name) &&
+ jh_stable_branch_name
+ end
+ end
+
+ def default_branch_for_non_stable
+ if target_stable_branch?
+ raise(BranchNotFound, "Cannot find a suitable JH branch")
+ else
+ JH_DEFAULT_BRANCH
+ end
+ end
+
+ def branch_exist?(project_path, branch_name)
+ !!gitlab.branch(project_path, branch_name)
+ rescue Gitlab::Error::NotFound
+ false
+ end
+
+ def target_default_branch?
+ merge_request.target_branch == default_branch
+ end
+
+ def target_stable_branch?
+ merge_request.target_branch.match?(/\A(?:\d+\-)+\d+\-stable\-ee\z/)
+ end
+
+ def ref_name
+ ENV['CI_COMMIT_REF_NAME']
+ end
+
+ def default_branch
+ ENV['CI_DEFAULT_BRANCH']
+ end
+
+ def merge_request_project_id
+ ENV['CI_MERGE_REQUEST_PROJECT_ID']
+ end
+
+ def merge_request_id
+ ENV['CI_MERGE_REQUEST_IID']
+ end
+
+ def jh_ref_name
+ "#{ref_name}-jh"
+ end
+
+ def merge_request
+ @merge_request ||= gitlab.merge_request(merge_request_project_id, merge_request_id)
+ end
+
+ def gitlab
+ @gitlab ||= Gitlab.client(
+ endpoint: API::DEFAULT_OPTIONS[:endpoint],
+ private_token: API::DEFAULT_OPTIONS[:api_token] || ''
+ )
+ end
+end
+
+if $0 == __FILE__
+ puts FindJhBranch.new.run
+end
diff --git a/scripts/undercoverage b/scripts/undercoverage
index cc7415d67ac..d6e6197911e 100755
--- a/scripts/undercoverage
+++ b/scripts/undercoverage
@@ -1,3 +1,3 @@
#!/usr/bin/env bash
-bundle exec undercover -c "${CI_MERGE_REQUEST_DIFF_BASE_SHA:-$(git merge-base origin/master HEAD)}"
+bundle exec undercover -c "${1:-$(git merge-base origin/master HEAD)}"
diff --git a/scripts/used-feature-flags b/scripts/used-feature-flags
index 552adbfbd9f..89ea99c6984 100755
--- a/scripts/used-feature-flags
+++ b/scripts/used-feature-flags
@@ -3,7 +3,7 @@
require 'set'
require 'fileutils'
-require_relative 'lib/gitlab'
+require_relative '../lib/gitlab_edition'
class String
def red
@@ -28,7 +28,7 @@ flags_paths = [
]
# For EE additionally process `ee/` feature flags
-if Gitlab.ee?
+if GitlabEdition.ee?
flags_paths << 'ee/config/feature_flags/**/*.yml'
# Geo feature flags are constructed dynamically and there's no explicit checks in the codebase so we mark all
@@ -43,7 +43,7 @@ if Gitlab.ee?
end
# For JH additionally process `jh/` feature flags
-if Gitlab.jh?
+if GitlabEdition.jh?
flags_paths << 'jh/config/feature_flags/**/*.yml'
Dir.glob('jh/app/replicators/geo/*_replicator.rb').each_with_object(Set.new) do |path, memo|
diff --git a/scripts/utils.sh b/scripts/utils.sh
index ed27edcadb2..15047d35fc3 100644
--- a/scripts/utils.sh
+++ b/scripts/utils.sh
@@ -39,7 +39,7 @@ function bundle_install_script() {
bundle --version
bundle config set path "$(pwd)/vendor"
bundle config set clean 'true'
- test -d jh && bundle config set gemfile 'jh/Gemfile'
+ test -d jh && bundle config set --local gemfile 'jh/Gemfile'
echo "${BUNDLE_WITHOUT}"
bundle config
diff --git a/shared/packages/.gitkeep b/shared/packages/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/shared/packages/.gitkeep
diff --git a/shared/terraform_state/.gitkeep b/shared/terraform_state/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/shared/terraform_state/.gitkeep
diff --git a/sidekiq_cluster/cli.rb b/sidekiq_cluster/cli.rb
index 57649ec74c8..bbe95788a35 100644
--- a/sidekiq_cluster/cli.rb
+++ b/sidekiq_cluster/cli.rb
@@ -200,9 +200,7 @@ module Gitlab
end
def sidekiq_exporter_enabled?
- ::Settings.monitoring.sidekiq_exporter.enabled
- rescue Settingslogic::MissingSetting
- nil
+ ::Settings.dig('monitoring', 'sidekiq_exporter', 'enabled')
end
def exporter_has_a_unique_port?
@@ -216,15 +214,11 @@ module Gitlab
end
def sidekiq_exporter_port
- ::Settings.monitoring.sidekiq_exporter.port
- rescue Settingslogic::MissingSetting
- nil
+ ::Settings.dig('monitoring', 'sidekiq_exporter', 'port')
end
def sidekiq_health_check_port
- ::Settings.monitoring.sidekiq_health_checks.port
- rescue Settingslogic::MissingSetting
- nil
+ ::Settings.dig('monitoring', 'sidekiq_health_checks', 'port')
end
def metrics_server_enabled?
diff --git a/spec/commands/metrics_server/metrics_server_spec.rb b/spec/commands/metrics_server/metrics_server_spec.rb
index f3936e6b346..b755801bb65 100644
--- a/spec/commands/metrics_server/metrics_server_spec.rb
+++ b/spec/commands/metrics_server/metrics_server_spec.rb
@@ -23,6 +23,8 @@ RSpec.describe 'bin/metrics-server', :aggregate_failures do
end
context 'with a running server' do
+ let(:metrics_dir) { Dir.mktmpdir }
+
before do
# We need to send a request to localhost
WebMock.allow_net_connect!
@@ -33,7 +35,8 @@ RSpec.describe 'bin/metrics-server', :aggregate_failures do
env = {
'GITLAB_CONFIG' => config_file.path,
'METRICS_SERVER_TARGET' => 'sidekiq',
- 'WIPE_METRICS_DIR' => '1'
+ 'WIPE_METRICS_DIR' => '1',
+ 'prometheus_multiproc_dir' => metrics_dir
}
@pid = Process.spawn(env, 'bin/metrics-server', pgroup: true)
end
@@ -55,6 +58,7 @@ RSpec.describe 'bin/metrics-server', :aggregate_failures do
# 'No such process' means the process died before
ensure
config_file.unlink
+ FileUtils.rm_rf(metrics_dir, secure: true)
end
it 'serves /metrics endpoint' do
diff --git a/spec/commands/sidekiq_cluster/cli_spec.rb b/spec/commands/sidekiq_cluster/cli_spec.rb
index 148b8720740..d7488e8d965 100644
--- a/spec/commands/sidekiq_cluster/cli_spec.rb
+++ b/spec/commands/sidekiq_cluster/cli_spec.rb
@@ -5,7 +5,7 @@ require 'rspec-parameterized'
require_relative '../../../sidekiq_cluster/cli'
-RSpec.describe Gitlab::SidekiqCluster::CLI do # rubocop:disable RSpec/FilePath
+RSpec.describe Gitlab::SidekiqCluster::CLI, stubbing_settings_source: true do # rubocop:disable RSpec/FilePath
let(:cli) { described_class.new('/dev/null') }
let(:timeout) { Gitlab::SidekiqCluster::DEFAULT_SOFT_TIMEOUT_SECONDS }
let(:default_options) do
@@ -16,19 +16,39 @@ RSpec.describe Gitlab::SidekiqCluster::CLI do # rubocop:disable RSpec/FilePath
let(:sidekiq_exporter_port) { '3807' }
let(:sidekiq_health_checks_port) { '3807' }
- before do
- stub_env('RAILS_ENV', 'test')
- stub_config(
- monitoring: {
- sidekiq_exporter: {
- enabled: sidekiq_exporter_enabled,
- port: sidekiq_exporter_port
- },
- sidekiq_health_checks: {
- port: sidekiq_health_checks_port
+ let(:config_file) { Tempfile.new('gitlab.yml') }
+ let(:config) do
+ {
+ 'test' => {
+ 'monitoring' => {
+ 'sidekiq_exporter' => {
+ 'address' => 'localhost',
+ 'enabled' => sidekiq_exporter_enabled,
+ 'port' => sidekiq_exporter_port
+ },
+ 'sidekiq_health_checks' => {
+ 'address' => 'localhost',
+ 'enabled' => sidekiq_exporter_enabled,
+ 'port' => sidekiq_health_checks_port
+ }
}
}
- )
+ }
+ end
+
+ before do
+ stub_env('RAILS_ENV', 'test')
+
+ config_file.write(YAML.dump(config))
+ config_file.close
+
+ allow(::Settings).to receive(:source).and_return(config_file.path)
+
+ ::Settings.reload!
+ end
+
+ after do
+ config_file.unlink
end
describe '#run' do
@@ -272,16 +292,9 @@ RSpec.describe Gitlab::SidekiqCluster::CLI do # rubocop:disable RSpec/FilePath
context 'starting the server' do
context 'without --dryrun' do
context 'when there are no sidekiq_health_checks settings set' do
- before do
- stub_config(
- monitoring: {
- sidekiq_exporter: {
- enabled: true,
- port: sidekiq_exporter_port
- }
- }
- )
+ 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)
@@ -293,25 +306,42 @@ RSpec.describe Gitlab::SidekiqCluster::CLI do # rubocop:disable RSpec/FilePath
cli.run(%w(foo))
end
-
- it 'rescues Settingslogic::MissingSetting' do
- expect { cli.run(%w(foo)) }.not_to raise_error(Settingslogic::MissingSetting)
- end
end
context 'when the sidekiq_exporter.port setting is not set' do
+ let(:sidekiq_exporter_enabled) { true }
+
before do
- stub_config(
- monitoring: {
- sidekiq_exporter: {
- enabled: true
- },
- sidekiq_health_checks: {
- port: sidekiq_health_checks_port
+ 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(:spawn)
+
+ cli.run(%w(foo))
+ end
+ end
+
+ context 'when sidekiq_exporter.enabled setting is not set' do
+ let(:config) do
+ {
+ 'test' => {
+ 'monitoring' => {
+ 'sidekiq_exporter' => {},
+ 'sidekiq_health_checks' => {
+ 'address' => 'localhost',
+ 'enabled' => sidekiq_exporter_enabled,
+ 'port' => sidekiq_health_checks_port
+ }
}
}
- )
+ }
+ end
+ before do
allow(Gitlab::SidekiqCluster).to receive(:start)
allow(cli).to receive(:write_pid)
allow(cli).to receive(:trap_signals)
@@ -323,23 +353,21 @@ RSpec.describe Gitlab::SidekiqCluster::CLI do # rubocop:disable RSpec/FilePath
cli.run(%w(foo))
end
-
- it 'rescues Settingslogic::MissingSetting' do
- expect { cli.run(%w(foo)) }.not_to raise_error(Settingslogic::MissingSetting)
- end
end
- context 'when sidekiq_exporter.enabled setting is not set' do
- before do
- stub_config(
- monitoring: {
- sidekiq_exporter: {},
- sidekiq_health_checks: {
- port: sidekiq_health_checks_port
+ context 'with a blank sidekiq_exporter setting' do
+ let(:config) do
+ {
+ 'test' => {
+ 'monitoring' => {
+ 'sidekiq_exporter' => nil,
+ 'sidekiq_health_checks' => nil
}
}
- )
+ }
+ end
+ before do
allow(Gitlab::SidekiqCluster).to receive(:start)
allow(cli).to receive(:write_pid)
allow(cli).to receive(:trap_signals)
@@ -351,6 +379,10 @@ RSpec.describe Gitlab::SidekiqCluster::CLI do # rubocop:disable RSpec/FilePath
cli.run(%w(foo))
end
+
+ it 'does not throw an error' do
+ expect { cli.run(%w(foo)) }.not_to raise_error
+ end
end
context 'with valid settings' do
diff --git a/spec/config/inject_enterprise_edition_module_spec.rb b/spec/config/inject_enterprise_edition_module_spec.rb
index 61b40e46001..6ef74a2b616 100644
--- a/spec/config/inject_enterprise_edition_module_spec.rb
+++ b/spec/config/inject_enterprise_edition_module_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe InjectEnterpriseEditionModule do
before do
# Make sure we're not relying on which mode we're running under
- allow(Gitlab).to receive(:extensions).and_return([extension_name.downcase])
+ allow(GitlabEdition).to receive(:extensions).and_return([extension_name.downcase])
# Test on an imagined extension and imagined class
stub_const(fish_name, fish_class) # Fish
diff --git a/spec/config/mail_room_spec.rb b/spec/config/mail_room_spec.rb
index 55f8fdd78ba..ec306837361 100644
--- a/spec/config/mail_room_spec.rb
+++ b/spec/config/mail_room_spec.rb
@@ -18,8 +18,9 @@ RSpec.describe 'mail_room.yml' do
result = Gitlab::Popen.popen_with_detail(%W(ruby -rerb -e #{cmd}), absolute_path('config'), vars)
output = result.stdout
+ errors = result.stderr
status = result.status
- raise "Error interpreting #{mailroom_config_path}: #{output}" unless status == 0
+ raise "Error interpreting #{mailroom_config_path}: #{output}\n#{errors}" unless status == 0
YAML.safe_load(output, permitted_classes: [Symbol])
end
diff --git a/spec/controllers/admin/application_settings_controller_spec.rb b/spec/controllers/admin/application_settings_controller_spec.rb
index 478bd1b7f0a..fb4c0970653 100644
--- a/spec/controllers/admin/application_settings_controller_spec.rb
+++ b/spec/controllers/admin/application_settings_controller_spec.rb
@@ -62,6 +62,7 @@ RSpec.describe Admin::ApplicationSettingsController, :do_not_mock_admin_mode_set
describe 'GET #usage_data' do
before do
stub_usage_data_connections
+ stub_database_flavor_check
sign_in(admin)
end
diff --git a/spec/controllers/admin/instance_review_controller_spec.rb b/spec/controllers/admin/instance_review_controller_spec.rb
index 898cd30cdca..2169be4e70c 100644
--- a/spec/controllers/admin/instance_review_controller_spec.rb
+++ b/spec/controllers/admin/instance_review_controller_spec.rb
@@ -22,6 +22,7 @@ RSpec.describe Admin::InstanceReviewController do
before do
stub_application_setting(usage_ping_enabled: true)
stub_usage_data_connections
+ stub_database_flavor_check
::Gitlab::UsageData.data(force_refresh: true)
subject
end
diff --git a/spec/controllers/admin/runner_projects_controller_spec.rb b/spec/controllers/admin/runner_projects_controller_spec.rb
new file mode 100644
index 00000000000..e5f63025cf7
--- /dev/null
+++ b/spec/controllers/admin/runner_projects_controller_spec.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Admin::RunnerProjectsController do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, group: group) }
+
+ before do
+ sign_in(create(:admin))
+ end
+
+ describe '#create' do
+ let(:project_id) { project.path }
+
+ subject do
+ post :create, params: {
+ namespace_id: group.path,
+ project_id: project_id,
+ runner_project: { runner_id: project_runner.id }
+ }
+ end
+
+ context 'assigning runner to same project' do
+ let(:project_runner) { create(:ci_runner, :project, projects: [project]) }
+
+ it 'redirects to the admin runner edit page' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:redirect)
+ expect(response).to redirect_to edit_admin_runner_url(project_runner)
+ end
+ end
+
+ context 'assigning runner to another project' do
+ let(:project_runner) { create(:ci_runner, :project, projects: [source_project]) }
+ let(:source_project) { create(:project) }
+
+ it 'redirects to the admin runner edit page' do
+ subject
+
+ 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' do
+ let_it_be(:project_runner) { create(:ci_runner, :project, projects: [project]) }
+
+ let(:project_id) { 0 }
+
+ it 'shows 404 for unknown project' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+end
diff --git a/spec/controllers/admin/runners_controller_spec.rb b/spec/controllers/admin/runners_controller_spec.rb
index b9a59e9ae5f..08fb12c375e 100644
--- a/spec/controllers/admin/runners_controller_spec.rb
+++ b/spec/controllers/admin/runners_controller_spec.rb
@@ -26,6 +26,32 @@ RSpec.describe Admin::RunnersController do
render_views
let_it_be(:project) { create(:project) }
+
+ before_all do
+ create(:ci_build, runner: runner, project: project)
+ end
+
+ it 'shows a runner show page' do
+ get :show, params: { id: runner.id }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to render_template(:show)
+ end
+
+ it 'when runner_read_only_admin_view is off, redirects to the runner edit page' do
+ stub_feature_flags(runner_read_only_admin_view: false)
+
+ get :show, params: { id: runner.id }
+
+ expect(response).to have_gitlab_http_status(:redirect)
+ expect(response).to redirect_to edit_admin_runner_path(runner)
+ end
+ end
+
+ describe '#edit' do
+ render_views
+
+ let_it_be(:project) { create(:project) }
let_it_be(:project_two) { create(:project) }
before_all do
@@ -33,29 +59,29 @@ RSpec.describe Admin::RunnersController do
create(:ci_build, runner: runner, project: project_two)
end
- it 'shows a particular runner' do
- get :show, params: { id: runner.id }
+ it 'shows a runner edit page' do
+ get :edit, params: { id: runner.id }
expect(response).to have_gitlab_http_status(:ok)
end
it 'shows 404 for unknown runner' do
- get :show, params: { id: 0 }
+ get :edit, params: { id: 0 }
expect(response).to have_gitlab_http_status(:not_found)
end
it 'avoids N+1 queries', :request_store do
- get :show, params: { id: runner.id }
+ get :edit, params: { id: runner.id }
- control_count = ActiveRecord::QueryRecorder.new { get :show, params: { id: runner.id } }.count
+ control_count = ActiveRecord::QueryRecorder.new { get :edit, params: { id: runner.id } }.count
new_project = create(:project)
create(:ci_build, runner: runner, project: new_project)
# There is one additional query looking up subject.group in ProjectPolicy for the
# needs_new_sso_session permission
- expect { get :show, params: { id: runner.id } }.not_to exceed_query_limit(control_count + 1)
+ expect { get :edit, params: { id: runner.id } }.not_to exceed_query_limit(control_count + 1)
expect(response).to have_gitlab_http_status(:ok)
end
diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb
index 3a2b5dcb99d..c52223d4758 100644
--- a/spec/controllers/admin/users_controller_spec.rb
+++ b/spec/controllers/admin/users_controller_spec.rb
@@ -421,16 +421,37 @@ RSpec.describe Admin::UsersController do
end
describe 'PUT confirm/:id' do
- let(:user) { create(:user, confirmed_at: nil) }
+ shared_examples_for 'confirms the user' do
+ it 'confirms the user' do
+ put :confirm, params: { id: user.username }
+ user.reload
+ expect(user.confirmed?).to be_truthy
+ end
+ end
+
+ let(:expired_confirmation_sent_at) { Date.today - User.confirm_within - 7.days }
+ let(:extant_confirmation_sent_at) { Date.today }
+
+ let(:user) do
+ create(:user, :unconfirmed).tap do |user|
+ user.update!(confirmation_sent_at: confirmation_sent_at)
+ end
+ end
before do
request.env["HTTP_REFERER"] = "/"
end
- it 'confirms user' do
- put :confirm, params: { id: user.username }
- user.reload
- expect(user.confirmed?).to be_truthy
+ context 'when the confirmation period has expired' do
+ let(:confirmation_sent_at) { expired_confirmation_sent_at }
+
+ it_behaves_like 'confirms the user'
+ end
+
+ context 'when the confirmation period has not expired' do
+ let(:confirmation_sent_at) { extant_confirmation_sent_at }
+
+ it_behaves_like 'confirms the user'
end
end
@@ -591,8 +612,8 @@ RSpec.describe Admin::UsersController do
end
context 'when the new password does not match the password confirmation' do
- let(:password) { 'some_password' }
- let(:password_confirmation) { 'not_same_as_password' }
+ let(:password) { Gitlab::Password.test_default }
+ let(:password_confirmation) { "not" + Gitlab::Password.test_default }
it 'shows the edit page again' do
update_password(user, password, password_confirmation)
diff --git a/spec/controllers/autocomplete_controller_spec.rb b/spec/controllers/autocomplete_controller_spec.rb
index c2eb9d54303..6ccba866ebb 100644
--- a/spec/controllers/autocomplete_controller_spec.rb
+++ b/spec/controllers/autocomplete_controller_spec.rb
@@ -234,6 +234,18 @@ RSpec.describe AutocompleteController do
expect(json_response.first).to have_key('can_merge')
end
end
+
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :user_email_lookup do
+ let(:current_user) { user }
+
+ def request
+ get(:users, params: { search: 'foo@bar.com' })
+ end
+
+ before do
+ sign_in(current_user)
+ end
+ end
end
context 'GET projects' do
diff --git a/spec/controllers/concerns/check_rate_limit_spec.rb b/spec/controllers/concerns/check_rate_limit_spec.rb
new file mode 100644
index 00000000000..34ececfe639
--- /dev/null
+++ b/spec/controllers/concerns/check_rate_limit_spec.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe CheckRateLimit do
+ let(:key) { :some_key }
+ let(:scope) { [:some, :scope] }
+ let(:request) { instance_double('Rack::Request') }
+ let(:user) { build_stubbed(:user) }
+
+ let(:controller_class) do
+ Class.new do
+ include CheckRateLimit
+
+ attr_reader :request, :current_user
+
+ def initialize(request, current_user)
+ @request = request
+ @current_user = current_user
+ end
+
+ def redirect_back_or_default(**args)
+ end
+
+ def render(**args)
+ end
+ end
+ end
+
+ subject { controller_class.new(request, user) }
+
+ before do
+ allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?)
+ allow(::Gitlab::ApplicationRateLimiter).to receive(:log_request)
+ end
+
+ describe '#check_rate_limit!' do
+ it 'calls ApplicationRateLimiter#throttled? with the right arguments' do
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).with(key, scope: scope).and_return(false)
+ expect(subject).not_to receive(:render)
+
+ subject.check_rate_limit!(key, scope: scope)
+ end
+
+ it 'renders error and logs request if throttled' do
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).with(key, scope: scope).and_return(true)
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:log_request).with(request, "#{key}_request_limit".to_sym, user)
+ expect(subject).to receive(:render).with({ plain: _('This endpoint has been requested too many times. Try again later.'), status: :too_many_requests })
+
+ subject.check_rate_limit!(key, scope: scope)
+ end
+
+ it 'redirects back if throttled and redirect_back option is set to true' do
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).with(key, scope: scope).and_return(true)
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:log_request).with(request, "#{key}_request_limit".to_sym, user)
+ expect(subject).not_to receive(:render)
+ expect(subject).to receive(:redirect_back_or_default).with(options: { alert: _('This endpoint has been requested too many times. Try again later.') })
+
+ subject.check_rate_limit!(key, scope: scope, redirect_back: true)
+ end
+
+ context 'when the bypass header is set' do
+ before do
+ allow(Gitlab::Throttle).to receive(:bypass_header).and_return('SOME_HEADER')
+ end
+
+ it 'skips rate limit if set to "1"' do
+ allow(request).to receive(:get_header).with(Gitlab::Throttle.bypass_header).and_return('1')
+
+ expect(::Gitlab::ApplicationRateLimiter).not_to receive(:throttled?)
+ expect(subject).not_to receive(:render)
+
+ subject.check_rate_limit!(key, scope: scope)
+ end
+
+ it 'does not skip rate limit if set to something else than "1"' do
+ allow(request).to receive(:get_header).with(Gitlab::Throttle.bypass_header).and_return('0')
+
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:throttled?)
+
+ subject.check_rate_limit!(key, scope: scope)
+ end
+ end
+ end
+end
diff --git a/spec/controllers/groups/boards_controller_spec.rb b/spec/controllers/groups/boards_controller_spec.rb
index ca4931bdc90..6201cddecb0 100644
--- a/spec/controllers/groups/boards_controller_spec.rb
+++ b/spec/controllers/groups/boards_controller_spec.rb
@@ -16,15 +16,6 @@ RSpec.describe Groups::BoardsController do
expect { list_boards }.to change(group.boards, :count).by(1)
end
- it 'pushes swimlanes_buffered_rendering feature flag' do
- allow(controller).to receive(:push_frontend_feature_flag).and_call_original
-
- expect(controller).to receive(:push_frontend_feature_flag)
- .with(:swimlanes_buffered_rendering, group, default_enabled: :yaml)
-
- list_boards
- end
-
context 'when format is HTML' do
it 'renders template' do
list_boards
@@ -107,15 +98,6 @@ RSpec.describe Groups::BoardsController do
describe 'GET show' do
let!(:board) { create(:board, group: group) }
- it 'pushes swimlanes_buffered_rendering feature flag' do
- allow(controller).to receive(:push_frontend_feature_flag).and_call_original
-
- expect(controller).to receive(:push_frontend_feature_flag)
- .with(:swimlanes_buffered_rendering, group, default_enabled: :yaml)
-
- read_board board: board
- end
-
context 'when format is HTML' do
it 'renders template' do
expect { read_board board: board }.to change(BoardGroupRecentVisit, :count).by(1)
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 0f262d93d4c..f438be534fa 100644
--- a/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb
+++ b/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb
@@ -178,10 +178,6 @@ RSpec.describe Groups::DependencyProxyForContainersController do
subject { get_manifest(tag) }
context 'feature enabled' do
- before do
- enable_dependency_proxy
- end
-
it_behaves_like 'without a token'
it_behaves_like 'without permission'
it_behaves_like 'feature flag disabled with private group'
@@ -270,7 +266,6 @@ RSpec.describe Groups::DependencyProxyForContainersController do
let_it_be_with_reload(:group) { create(:group, parent: parent_group) }
before do
- parent_group.create_dependency_proxy_setting!(enabled: true)
group_deploy_token.update_column(:group_id, parent_group.id)
end
@@ -294,10 +289,6 @@ RSpec.describe Groups::DependencyProxyForContainersController do
subject { get_blob }
context 'feature enabled' do
- before do
- enable_dependency_proxy
- end
-
it_behaves_like 'without a token'
it_behaves_like 'without permission'
it_behaves_like 'feature flag disabled with private group'
@@ -341,81 +332,12 @@ RSpec.describe Groups::DependencyProxyForContainersController do
let_it_be_with_reload(:group) { create(:group, parent: parent_group) }
before do
- parent_group.create_dependency_proxy_setting!(enabled: true)
group_deploy_token.update_column(:group_id, parent_group.id)
end
it_behaves_like 'a successful blob pull'
end
end
-
- context 'when dependency_proxy_workhorse disabled' do
- let(:blob_response) { { status: :success, blob: blob, from_cache: false } }
-
- before do
- stub_feature_flags(dependency_proxy_workhorse: false)
-
- allow_next_instance_of(DependencyProxy::FindOrCreateBlobService) do |instance|
- allow(instance).to receive(:execute).and_return(blob_response)
- end
- end
-
- context 'remote blob request fails' do
- let(:blob_response) do
- {
- status: :error,
- http_status: 400,
- message: ''
- }
- end
-
- before do
- group.add_guest(user)
- end
-
- it 'proxies status from the remote blob request', :aggregate_failures do
- subject
-
- expect(response).to have_gitlab_http_status(:bad_request)
- expect(response.body).to be_empty
- end
- end
-
- context 'a valid user' do
- before do
- group.add_guest(user)
- end
-
- it_behaves_like 'a successful blob pull'
- it_behaves_like 'a package tracking event', described_class.name, 'pull_blob'
-
- context 'with a cache entry' do
- let(:blob_response) { { status: :success, blob: blob, from_cache: true } }
-
- it_behaves_like 'returning response status', :success
- it_behaves_like 'a package tracking event', described_class.name, 'pull_blob_from_cache'
- end
- end
-
- context 'a valid deploy token' do
- let_it_be(:user) { create(:deploy_token, :group, :dependency_proxy_scopes) }
- let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: user, group: group) }
-
- it_behaves_like 'a successful blob pull'
-
- context 'pulling from a subgroup' do
- let_it_be_with_reload(:parent_group) { create(:group) }
- let_it_be_with_reload(:group) { create(:group, parent: parent_group) }
-
- before do
- parent_group.create_dependency_proxy_setting!(enabled: true)
- group_deploy_token.update_column(:group_id, parent_group.id)
- end
-
- it_behaves_like 'a successful blob pull'
- end
- end
- end
end
it_behaves_like 'not found when disabled'
@@ -542,10 +464,6 @@ RSpec.describe Groups::DependencyProxyForContainersController do
end
end
- def enable_dependency_proxy
- group.create_dependency_proxy_setting!(enabled: true)
- end
-
def disable_dependency_proxy
group.create_dependency_proxy_setting!(enabled: false)
end
diff --git a/spec/controllers/groups/packages_controller_spec.rb b/spec/controllers/groups/packages_controller_spec.rb
new file mode 100644
index 00000000000..fc9b79da47c
--- /dev/null
+++ b/spec/controllers/groups/packages_controller_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Groups::PackagesController do
+ let_it_be(:group) { create(:group) }
+
+ let(:page) { :index }
+ let(:additional_parameters) { {} }
+
+ subject do
+ get page, params: additional_parameters.merge({
+ group_id: group
+ })
+ end
+
+ context 'GET #index' do
+ it_behaves_like 'returning response status', :ok
+ end
+
+ context 'GET #show' do
+ let(:page) { :show }
+ let(:additional_parameters) { { id: 1 } }
+
+ it_behaves_like 'returning response status', :ok
+ end
+end
diff --git a/spec/controllers/import/gitlab_controller_spec.rb b/spec/controllers/import/gitlab_controller_spec.rb
index 826625ba9c3..117c934ad5d 100644
--- a/spec/controllers/import/gitlab_controller_spec.rb
+++ b/spec/controllers/import/gitlab_controller_spec.rb
@@ -30,18 +30,27 @@ RSpec.describe Import::GitlabController do
expect(session[:gitlab_access_token]).to eq(token)
expect(controller).to redirect_to(status_import_gitlab_url)
end
+
+ it "importable_repos should return an array" do
+ allow_next_instance_of(Gitlab::GitlabImport::Client) do |instance|
+ allow(instance).to receive(:projects).and_return([{ "id": 1 }].to_enum)
+ end
+
+ expect(controller.send(:importable_repos)).to be_an_instance_of(Array)
+ end
end
describe "GET status" do
+ let(:repo_fake) { Struct.new(:id, :path, :path_with_namespace, :web_url, keyword_init: true) }
+ let(:repo) { repo_fake.new(id: 1, path: 'vim', path_with_namespace: 'asd/vim', web_url: 'https://gitlab.com/asd/vim') }
+
before do
- @repo = OpenStruct.new(id: 1, path: 'vim', path_with_namespace: 'asd/vim', web_url: 'https://gitlab.com/asd/vim')
assign_session_token
end
it_behaves_like 'import controller status' do
- let(:repo) { @repo }
- let(:repo_id) { @repo.id }
- let(:import_source) { @repo.path_with_namespace }
+ let(:repo_id) { repo.id }
+ let(:import_source) { repo.path_with_namespace }
let(:provider_name) { 'gitlab' }
let(:client_repos_field) { :projects }
end
diff --git a/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb b/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb
index ecff173b8ac..29678706bba 100644
--- a/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb
+++ b/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb
@@ -58,7 +58,7 @@ RSpec.describe Ldap::OmniauthCallbacksController do
end
context 'sign up' do
- let(:user) { double(email: +'new@example.com') }
+ let(:user) { create(:user) }
before do
stub_omniauth_setting(block_auto_created_users: false)
diff --git a/spec/controllers/oauth/token_info_controller_spec.rb b/spec/controllers/oauth/token_info_controller_spec.rb
index 6d01a534673..b66fff4d4e9 100644
--- a/spec/controllers/oauth/token_info_controller_spec.rb
+++ b/spec/controllers/oauth/token_info_controller_spec.rb
@@ -5,11 +5,11 @@ require 'spec_helper'
RSpec.describe Oauth::TokenInfoController do
describe '#show' do
context 'when the user is not authenticated' do
- it 'responds with a 400' do
+ it 'responds with a 401' do
get :show
- expect(response).to have_gitlab_http_status(:bad_request)
- expect(Gitlab::Json.parse(response.body)).to include('error' => 'invalid_request')
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ expect(Gitlab::Json.parse(response.body)).to include('error' => 'invalid_token')
end
end
@@ -36,11 +36,11 @@ RSpec.describe Oauth::TokenInfoController do
end
context 'when the doorkeeper_token is not recognised' do
- it 'responds with a 400' do
+ it 'responds with a 401' do
get :show, params: { access_token: 'unknown_token' }
- expect(response).to have_gitlab_http_status(:bad_request)
- expect(Gitlab::Json.parse(response.body)).to include('error' => 'invalid_request')
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ expect(Gitlab::Json.parse(response.body)).to include('error' => 'invalid_token')
end
end
@@ -49,22 +49,22 @@ RSpec.describe Oauth::TokenInfoController do
create(:oauth_access_token, created_at: 2.days.ago, expires_in: 10.minutes)
end
- it 'responds with a 400' do
+ it 'responds with a 401' do
get :show, params: { access_token: access_token.token }
- expect(response).to have_gitlab_http_status(:bad_request)
- expect(Gitlab::Json.parse(response.body)).to include('error' => 'invalid_request')
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ expect(Gitlab::Json.parse(response.body)).to include('error' => 'invalid_token')
end
end
context 'when the token is revoked' do
let(:access_token) { create(:oauth_access_token, revoked_at: 2.days.ago) }
- it 'responds with a 400' do
+ it 'responds with a 401' do
get :show, params: { access_token: access_token.token }
- expect(response).to have_gitlab_http_status(:bad_request)
- expect(Gitlab::Json.parse(response.body)).to include('error' => 'invalid_request')
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ expect(Gitlab::Json.parse(response.body)).to include('error' => 'invalid_token')
end
end
end
diff --git a/spec/controllers/profiles/emails_controller_spec.rb b/spec/controllers/profiles/emails_controller_spec.rb
index 214a893f0fa..e41ae406d13 100644
--- a/spec/controllers/profiles/emails_controller_spec.rb
+++ b/spec/controllers/profiles/emails_controller_spec.rb
@@ -49,7 +49,7 @@ RSpec.describe Profiles::EmailsController do
end
context 'when email address is invalid' do
- let(:email) { 'invalid.@example.com' }
+ let(:email) { 'invalid@@example.com' }
it 'does not send an email confirmation' do
expect { subject }.not_to change { ActionMailer::Base.deliveries.size }
diff --git a/spec/controllers/profiles_controller_spec.rb b/spec/controllers/profiles_controller_spec.rb
index 9a1f8a8442d..6e7cc058fbc 100644
--- a/spec/controllers/profiles_controller_spec.rb
+++ b/spec/controllers/profiles_controller_spec.rb
@@ -153,9 +153,12 @@ RSpec.describe ProfilesController, :request_store do
let(:gitlab_shell) { Gitlab::Shell.new }
let(:new_username) { generate(:username) }
- it 'allows username change' do
+ before do
sign_in(user)
+ allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(false)
+ end
+ it 'allows username change' do
put :update_username,
params: { user: { username: new_username } }
@@ -166,8 +169,6 @@ RSpec.describe ProfilesController, :request_store do
end
it 'updates a username using JSON request' do
- sign_in(user)
-
put :update_username,
params: {
user: { username: new_username }
@@ -179,8 +180,6 @@ RSpec.describe ProfilesController, :request_store do
end
it 'renders an error message when the username was not updated' do
- sign_in(user)
-
put :update_username,
params: {
user: { username: 'invalid username.git' }
@@ -192,8 +191,6 @@ RSpec.describe ProfilesController, :request_store do
end
it 'raises a correct error when the username is missing' do
- sign_in(user)
-
expect { put :update_username, params: { user: { gandalf: 'you shall not pass' } } }
.to raise_error(ActionController::ParameterMissing)
end
@@ -202,8 +199,6 @@ RSpec.describe ProfilesController, :request_store do
it 'moves dependent projects to new namespace' do
project = create(:project_empty_repo, :legacy_storage, namespace: namespace)
- sign_in(user)
-
put :update_username,
params: { user: { username: new_username } }
@@ -220,8 +215,6 @@ RSpec.describe ProfilesController, :request_store do
before_disk_path = project.disk_path
- sign_in(user)
-
put :update_username,
params: { user: { username: new_username } }
@@ -232,5 +225,18 @@ RSpec.describe ProfilesController, :request_store do
expect(before_disk_path).to eq(project.disk_path)
end
end
+
+ context 'when the rate limit is reached' do
+ it 'does not update the username and returns status 429 Too Many Requests' do
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).with(:profile_update_username, scope: user).and_return(true)
+
+ expect do
+ put :update_username,
+ params: { user: { username: new_username } }
+ end.not_to change { user.reload.username }
+
+ expect(response).to have_gitlab_http_status(:too_many_requests)
+ end
+ end
end
end
diff --git a/spec/controllers/projects/boards_controller_spec.rb b/spec/controllers/projects/boards_controller_spec.rb
index 48a12a27911..cde3a8d4761 100644
--- a/spec/controllers/projects/boards_controller_spec.rb
+++ b/spec/controllers/projects/boards_controller_spec.rb
@@ -22,15 +22,6 @@ RSpec.describe Projects::BoardsController do
expect(assigns(:boards_endpoint)).to eq project_boards_path(project)
end
- it 'pushes swimlanes_buffered_rendering feature flag' do
- allow(controller).to receive(:push_frontend_feature_flag).and_call_original
-
- expect(controller).to receive(:push_frontend_feature_flag)
- .with(:swimlanes_buffered_rendering, project, default_enabled: :yaml)
-
- list_boards
- end
-
context 'when format is HTML' do
it 'renders template' do
list_boards
@@ -125,15 +116,6 @@ RSpec.describe Projects::BoardsController do
describe 'GET show' do
let!(:board) { create(:board, project: project) }
- it 'pushes swimlanes_buffered_rendering feature flag' do
- allow(controller).to receive(:push_frontend_feature_flag).and_call_original
-
- expect(controller).to receive(:push_frontend_feature_flag)
- .with(:swimlanes_buffered_rendering, project, default_enabled: :yaml)
-
- read_board board: board
- end
-
it 'sets boards_endpoint instance variable to a boards path' do
read_board board: board
diff --git a/spec/controllers/projects/mattermosts_controller_spec.rb b/spec/controllers/projects/mattermosts_controller_spec.rb
index edec8c3e9c6..596cd5c1a20 100644
--- a/spec/controllers/projects/mattermosts_controller_spec.rb
+++ b/spec/controllers/projects/mattermosts_controller_spec.rb
@@ -60,9 +60,9 @@ RSpec.describe Projects::MattermostsController do
it 'redirects to the new page' do
subject
- service = project.integrations.last
+ integration = project.integrations.last
- expect(subject).to redirect_to(edit_project_service_url(project, service))
+ expect(subject).to redirect_to(edit_project_integration_path(project, integration))
end
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 f7370a1a1ac..a5c59b7e22d 100644
--- a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
@@ -205,7 +205,6 @@ RSpec.describe Projects::MergeRequests::DiffsController do
let(:collection) { Gitlab::Diff::FileCollection::MergeRequestDiff }
let(:expected_options) do
{
- environment: nil,
merge_request: merge_request,
merge_request_diff: merge_request.merge_request_diff,
merge_request_diffs: merge_request.merge_request_diffs,
@@ -280,7 +279,6 @@ RSpec.describe Projects::MergeRequests::DiffsController do
let(:collection) { Gitlab::Diff::FileCollection::MergeRequestDiff }
let(:expected_options) do
{
- environment: nil,
merge_request: merge_request,
merge_request_diff: merge_request.merge_request_diff,
merge_request_diffs: merge_request.merge_request_diffs,
@@ -303,7 +301,6 @@ RSpec.describe Projects::MergeRequests::DiffsController do
let(:collection) { Gitlab::Diff::FileCollection::Commit }
let(:expected_options) do
{
- environment: nil,
merge_request: merge_request,
merge_request_diff: nil,
merge_request_diffs: merge_request.merge_request_diffs,
@@ -330,7 +327,6 @@ RSpec.describe Projects::MergeRequests::DiffsController do
let(:collection) { Gitlab::Diff::FileCollection::MergeRequestDiff }
let(:expected_options) do
{
- environment: nil,
merge_request: merge_request,
merge_request_diff: merge_request.merge_request_diff,
merge_request_diffs: merge_request.merge_request_diffs,
@@ -494,7 +490,6 @@ RSpec.describe Projects::MergeRequests::DiffsController do
def collection_arguments(pagination_data = {})
{
- environment: nil,
merge_request: merge_request,
commit: nil,
diff_view: :inline,
diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb
index 66af546b113..2df31904380 100644
--- a/spec/controllers/projects/notes_controller_spec.rb
+++ b/spec/controllers/projects/notes_controller_spec.rb
@@ -762,9 +762,12 @@ RSpec.describe Projects::NotesController do
end
end
- it_behaves_like 'request exceeding rate limit', :clean_gitlab_redis_cache do
- let(:params) { request_params.except(:format) }
- let(:request_full_path) { project_notes_path(project) }
+ it_behaves_like 'create notes request exceeding rate limit', :clean_gitlab_redis_cache do
+ let(:current_user) { user }
+
+ def request
+ post :create, params: request_params.except(:format)
+ end
end
end
diff --git a/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb b/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb
index fc741d0f3f6..707edeaeee3 100644
--- a/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb
+++ b/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb
@@ -41,5 +41,29 @@ RSpec.describe Projects::Packages::InfrastructureRegistryController do
it_behaves_like 'returning response status', :not_found
end
+
+ context 'with package file pending destruction' do
+ let_it_be(:package_file_pending_destruction) { create(:package_file, :pending_destruction, package: terraform_module) }
+
+ let(:terraform_module_package_file) { terraform_module.package_files.first }
+
+ it 'does not return them' do
+ subject
+
+ expect(assigns(:package_files)).to contain_exactly(terraform_module_package_file)
+ end
+
+ context 'with packages_installable_package_files disabled' do
+ before do
+ stub_feature_flags(packages_installable_package_files: false)
+ end
+
+ it 'returns them' do
+ subject
+
+ expect(assigns(:package_files)).to contain_exactly(package_file_pending_destruction, terraform_module_package_file)
+ end
+ end
+ end
end
end
diff --git a/spec/controllers/projects/packages/packages_controller_spec.rb b/spec/controllers/projects/packages/packages_controller_spec.rb
new file mode 100644
index 00000000000..da9cae47c62
--- /dev/null
+++ b/spec/controllers/projects/packages/packages_controller_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::Packages::PackagesController do
+ let_it_be(:project) { create(:project, :public) }
+
+ let(:page) { :index }
+ let(:additional_parameters) { {} }
+
+ subject do
+ get page, params: additional_parameters.merge({
+ project_id: project,
+ namespace_id: project.namespace
+ })
+ end
+
+ context 'GET #index' do
+ it_behaves_like 'returning response status', :ok
+ end
+
+ context 'GET #show' do
+ let(:page) { :show }
+ let(:additional_parameters) { { id: 1 } }
+
+ it_behaves_like 'returning response status', :ok
+ end
+end
diff --git a/spec/controllers/projects/prometheus/metrics_controller_spec.rb b/spec/controllers/projects/prometheus/metrics_controller_spec.rb
index 5338b77bd08..7dfa283195e 100644
--- a/spec/controllers/projects/prometheus/metrics_controller_spec.rb
+++ b/spec/controllers/projects/prometheus/metrics_controller_spec.rb
@@ -141,7 +141,7 @@ RSpec.describe Projects::Prometheus::MetricsController do
expect(flash[:notice]).to include('Metric was successfully added.')
- expect(response).to redirect_to(edit_project_service_path(project, ::Integrations::Prometheus))
+ expect(response).to redirect_to(edit_project_integration_path(project, ::Integrations::Prometheus))
end
end
@@ -157,6 +157,22 @@ RSpec.describe Projects::Prometheus::MetricsController do
end
end
+ describe 'PUT #update' do
+ context 'metric is updated' do
+ let_it_be(:metric) { create(:prometheus_metric, project: project) }
+
+ let(:metric_params) { { prometheus_metric: { title: 'new_title' }, id: metric.id } }
+
+ it 'shows a success flash message' do
+ put :update, params: project_params(metric_params)
+
+ expect(metric.reload.title).to eq('new_title')
+ expect(flash[:notice]).to include('Metric was successfully updated.')
+ expect(response).to redirect_to(edit_project_integration_path(project, ::Integrations::Prometheus))
+ end
+ end
+ end
+
describe 'DELETE #destroy' do
context 'format html' do
let!(:metric) { create(:prometheus_metric, project: project) }
@@ -164,7 +180,7 @@ RSpec.describe Projects::Prometheus::MetricsController do
it 'destroys the metric' do
delete :destroy, params: project_params(id: metric.id)
- expect(response).to redirect_to(edit_project_service_path(project, ::Integrations::Prometheus))
+ expect(response).to redirect_to(edit_project_integration_path(project, ::Integrations::Prometheus))
expect(PrometheusMetric.find_by(id: metric.id)).to be_nil
end
end
diff --git a/spec/controllers/projects/raw_controller_spec.rb b/spec/controllers/projects/raw_controller_spec.rb
index 4d99afb6b1f..e0d88fa799f 100644
--- a/spec/controllers/projects/raw_controller_spec.rb
+++ b/spec/controllers/projects/raw_controller_spec.rb
@@ -8,6 +8,7 @@ RSpec.describe Projects::RawController do
let_it_be(:project) { create(:project, :public, :repository) }
let(:inline) { nil }
+ let(:params) { {} }
describe 'GET #show' do
def get_show
@@ -15,9 +16,9 @@ RSpec.describe Projects::RawController do
params: {
namespace_id: project.namespace,
project_id: project,
- id: filepath,
+ id: file_path,
inline: inline
- })
+ }.merge(params))
end
subject { get_show }
@@ -33,7 +34,7 @@ RSpec.describe Projects::RawController do
end
context 'regular filename' do
- let(:filepath) { 'master/CONTRIBUTING.md' }
+ let(:file_path) { 'master/CONTRIBUTING.md' }
it 'delivers ASCII file' do
allow(Gitlab::Workhorse).to receive(:send_git_blob).and_call_original
@@ -60,7 +61,7 @@ RSpec.describe Projects::RawController do
end
context 'image header' do
- let(:filepath) { 'master/files/images/6049019_460s.jpg' }
+ let(:file_path) { 'master/files/images/6049019_460s.jpg' }
it 'leaves image content disposition' do
subject
@@ -77,44 +78,30 @@ RSpec.describe Projects::RawController do
context 'with LFS files' do
let(:filename) { 'lfs_object.iso' }
- let(:filepath) { "be93687/files/lfs/#{filename}" }
+ let(:file_path) { "be93687/files/lfs/#{filename}" }
it_behaves_like 'a controller that can serve LFS files'
it_behaves_like 'project cache control headers'
include_examples 'single Gitaly request'
end
- context 'when the endpoint receives requests above the limit', :clean_gitlab_redis_rate_limiting do
+ context 'when the endpoint receives requests above the limit' do
let(:file_path) { 'master/README.md' }
+ let(:path_without_ref) { 'README.md' }
before do
- stub_application_setting(raw_blob_request_limit: 5)
+ allow(::Gitlab::ApplicationRateLimiter).to(
+ receive(:throttled?).with(:raw_blob, scope: [project, path_without_ref]).and_return(true)
+ )
end
- it 'prevents from accessing the raw file', :request_store do
- execute_raw_requests(requests: 5, project: project, file_path: file_path)
-
- expect { execute_raw_requests(requests: 1, project: project, file_path: file_path) }
- .to change { Gitlab::GitalyClient.get_request_count }.by(0)
+ it 'prevents from accessing the raw file' do
+ expect { get_show }.not_to change { Gitlab::GitalyClient.get_request_count }
expect(response.body).to eq(_('You cannot access the raw file. Please wait a minute.'))
expect(response).to have_gitlab_http_status(:too_many_requests)
end
- it 'logs the event on auth.log', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/345889' do
- attributes = {
- message: 'Application_Rate_Limiter_Request',
- env: :raw_blob_request_limit,
- remote_ip: '0.0.0.0',
- request_method: 'GET',
- path: "/#{project.full_path}/-/raw/#{file_path}"
- }
-
- expect(Gitlab::AuthLogger).to receive(:error).with(attributes).once
-
- execute_raw_requests(requests: 6, project: project, file_path: file_path)
- end
-
context 'when receiving an external storage request' do
let(:token) { 'letmein' }
@@ -126,62 +113,10 @@ RSpec.describe Projects::RawController do
end
it 'does not prevent from accessing the raw file' do
- request.headers['X-Gitlab-External-Storage-Token'] = token
- execute_raw_requests(requests: 6, project: project, file_path: file_path)
-
- expect(response).to have_gitlab_http_status(:ok)
- end
- end
-
- context 'when the request uses a different version of a commit' do
- it 'prevents from accessing the raw file' do
- # 3 times with the normal sha
- commit_sha = project.repository.commit.sha
- file_path = "#{commit_sha}/README.md"
-
- execute_raw_requests(requests: 3, project: project, file_path: file_path)
-
- # 3 times with the modified version
- modified_sha = commit_sha.gsub(commit_sha[0..5], commit_sha[0..5].upcase)
- modified_path = "#{modified_sha}/README.md"
-
- execute_raw_requests(requests: 3, project: project, file_path: modified_path)
-
- expect(response.body).to eq(_('You cannot access the raw file. Please wait a minute.'))
- expect(response).to have_gitlab_http_status(:too_many_requests)
- end
- end
-
- context 'when the throttling has been disabled' do
- before do
- stub_application_setting(raw_blob_request_limit: 0)
- end
-
- it 'does not prevent from accessing the raw file' do
- execute_raw_requests(requests: 10, project: project, file_path: file_path)
-
- expect(response).to have_gitlab_http_status(:ok)
- end
- end
-
- context 'with case-sensitive files' do
- it 'prevents from accessing the specific file' do
- create_file_in_repo(project, 'master', 'master', 'readme.md', 'Add readme.md')
- create_file_in_repo(project, 'master', 'master', 'README.md', 'Add README.md')
-
- commit_sha = project.repository.commit.sha
- file_path = "#{commit_sha}/readme.md"
-
- # Accessing downcase version of readme
- execute_raw_requests(requests: 6, project: project, file_path: file_path)
-
- expect(response.body).to eq(_('You cannot access the raw file. Please wait a minute.'))
- expect(response).to have_gitlab_http_status(:too_many_requests)
+ expect(::Gitlab::ApplicationRateLimiter).not_to receive(:throttled?)
- # Accessing upcase version of readme
- file_path = "#{commit_sha}/README.md"
-
- execute_raw_requests(requests: 1, project: project, file_path: file_path)
+ request.headers['X-Gitlab-External-Storage-Token'] = token
+ get_show
expect(response).to have_gitlab_http_status(:ok)
end
@@ -201,7 +136,7 @@ RSpec.describe Projects::RawController do
context 'when no token is provided' do
it 'redirects to sign in page' do
- execute_raw_requests(requests: 1, project: project, file_path: file_path)
+ get_show
expect(response).to have_gitlab_http_status(:found)
expect(response.location).to end_with('/users/sign_in')
@@ -209,13 +144,11 @@ RSpec.describe Projects::RawController do
end
context 'when a token param is present' do
- subject(:execute_raw_request_with_token_in_params) do
- execute_raw_requests(requests: 1, project: project, file_path: file_path, token: token)
- end
-
context 'when token is correct' do
+ let(:params) { { token: token } }
+
it 'calls the action normally' do
- execute_raw_request_with_token_in_params
+ get_show
expect(response).to have_gitlab_http_status(:ok)
end
@@ -224,7 +157,7 @@ RSpec.describe Projects::RawController do
let_it_be(:user) { create(:user, password_expires_at: 2.minutes.ago) }
it 'redirects to sign in page' do
- execute_raw_request_with_token_in_params
+ get_show
expect(response).to have_gitlab_http_status(:found)
expect(response.location).to end_with('/users/sign_in')
@@ -236,7 +169,7 @@ RSpec.describe Projects::RawController do
let_it_be(:user) { create(:omniauth_user, provider: 'ldap', password_expires_at: 2.minutes.ago) }
it 'calls the action normally' do
- execute_raw_request_with_token_in_params
+ get_show
expect(response).to have_gitlab_http_status(:ok)
end
@@ -245,10 +178,10 @@ RSpec.describe Projects::RawController do
end
context 'when token is incorrect' do
- let(:token) { 'foobar' }
+ let(:params) { { token: 'foobar' } }
it 'redirects to sign in page' do
- execute_raw_request_with_token_in_params
+ get_show
expect(response).to have_gitlab_http_status(:found)
expect(response.location).to end_with('/users/sign_in')
@@ -257,14 +190,13 @@ RSpec.describe Projects::RawController do
end
context 'when a token header is present' do
- subject(:execute_raw_request_with_token_in_headers) do
+ before do
request.headers['X-Gitlab-Static-Object-Token'] = token
- execute_raw_requests(requests: 1, project: project, file_path: file_path)
end
context 'when token is correct' do
it 'calls the action normally' do
- execute_raw_request_with_token_in_headers
+ get_show
expect(response).to have_gitlab_http_status(:ok)
end
@@ -273,7 +205,7 @@ RSpec.describe Projects::RawController do
let_it_be(:user) { create(:user, password_expires_at: 2.minutes.ago) }
it 'redirects to sign in page' do
- execute_raw_request_with_token_in_headers
+ get_show
expect(response).to have_gitlab_http_status(:found)
expect(response.location).to end_with('/users/sign_in')
@@ -285,7 +217,7 @@ RSpec.describe Projects::RawController do
let_it_be(:user) { create(:omniauth_user, provider: 'ldap', password_expires_at: 2.minutes.ago) }
it 'calls the action normally' do
- execute_raw_request_with_token_in_headers
+ get_show
expect(response).to have_gitlab_http_status(:ok)
end
@@ -297,7 +229,7 @@ RSpec.describe Projects::RawController do
let(:token) { 'foobar' }
it 'redirects to sign in page' do
- execute_raw_request_with_token_in_headers
+ get_show
expect(response).to have_gitlab_http_status(:found)
expect(response.location).to end_with('/users/sign_in')
@@ -344,14 +276,4 @@ RSpec.describe Projects::RawController do
end
end
end
-
- def execute_raw_requests(requests:, project:, file_path:, **params)
- requests.times do
- get :show, params: {
- namespace_id: project.namespace,
- project_id: project,
- id: file_path
- }.merge(params)
- end
- end
end
diff --git a/spec/controllers/projects/repositories_controller_spec.rb b/spec/controllers/projects/repositories_controller_spec.rb
index f7cf55d8a95..1370ec9cc0b 100644
--- a/spec/controllers/projects/repositories_controller_spec.rb
+++ b/spec/controllers/projects/repositories_controller_spec.rb
@@ -210,6 +210,25 @@ RSpec.describe Projects::RepositoriesController do
expect(response).to have_gitlab_http_status(:found)
end
end
+
+ context 'when token is migrated' do
+ let(:user) { create(:user, static_object_token: '') }
+ let(:token) { 'Test' }
+
+ it 'calls the action normally' do
+ user.update_column(:static_object_token, token)
+
+ get :archive, params: { namespace_id: project.namespace, project_id: project, id: 'master', token: token }, format: 'zip'
+ expect(user.static_object_token).to eq(token)
+ expect(response).to have_gitlab_http_status(:ok)
+
+ user.update_column(:static_object_token_encrypted, Gitlab::CryptoHelper.aes256_gcm_encrypt(token))
+
+ get :archive, params: { namespace_id: project.namespace, project_id: project, id: 'master', token: token }, format: 'zip'
+ expect(user.static_object_token).to eq(token)
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
end
context 'when a token header is present' do
diff --git a/spec/controllers/projects/security/configuration_controller_spec.rb b/spec/controllers/projects/security/configuration_controller_spec.rb
index 848db16fb02..1ce0fcd85db 100644
--- a/spec/controllers/projects/security/configuration_controller_spec.rb
+++ b/spec/controllers/projects/security/configuration_controller_spec.rb
@@ -36,6 +36,31 @@ RSpec.describe Projects::Security::ConfigurationController do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:show)
end
+
+ it 'responds with configuration data json' do
+ get :show, params: { namespace_id: project.namespace, project_id: project, format: :json }
+
+ features = json_response['features']
+ sast_feature = features.find { |feature| feature['type'] == 'sast' }
+ dast_feature = features.find { |feature| feature['type'] == 'dast' }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(sast_feature['available']).to be_truthy
+ expect(dast_feature['available']).to be_falsey
+ end
+
+ context 'with feature flag unify_security_configuration turned off' do
+ before do
+ stub_feature_flags(unify_security_configuration: false)
+ end
+
+ it 'responds with empty configuration data json' do
+ get :show, params: { namespace_id: project.namespace, project_id: project, format: :json }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to be_empty
+ end
+ end
end
end
end
diff --git a/spec/controllers/projects/service_hook_logs_controller_spec.rb b/spec/controllers/projects/service_hook_logs_controller_spec.rb
index 9caa4a06b44..be78668aa88 100644
--- a/spec/controllers/projects/service_hook_logs_controller_spec.rb
+++ b/spec/controllers/projects/service_hook_logs_controller_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe Projects::ServiceHookLogsController do
{
namespace_id: project.namespace,
project_id: project,
- service_id: integration.to_param,
+ integration_id: integration.to_param,
id: log.id
}
end
@@ -44,7 +44,7 @@ RSpec.describe Projects::ServiceHookLogsController do
it 'executes the hook and redirects to the service form' do
expect_any_instance_of(ServiceHook).to receive(:execute)
expect_any_instance_of(described_class).to receive(:set_hook_execution_notice)
- expect(subject).to redirect_to(edit_project_service_path(project, integration))
+ expect(subject).to redirect_to(edit_project_integration_path(project, integration))
end
it 'renders a 404 if the hook does not exist' do
diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb
index 29988da6e60..f3c7b501faa 100644
--- a/spec/controllers/projects/services_controller_spec.rb
+++ b/spec/controllers/projects/services_controller_spec.rb
@@ -183,7 +183,7 @@ RSpec.describe Projects::ServicesController do
let(:params) { project_params(service: integration_params) }
let(:message) { 'Jira settings saved and active.' }
- let(:redirect_url) { edit_project_service_path(project, integration) }
+ let(:redirect_url) { edit_project_integration_path(project, integration) }
before do
stub_jira_integration_test
@@ -341,7 +341,7 @@ RSpec.describe Projects::ServicesController do
it 'redirects user back to edit page with alert' do
put :update, params: project_params.merge(service: integration_params)
- expect(response).to redirect_to(edit_project_service_path(project, integration))
+ expect(response).to redirect_to(edit_project_integration_path(project, integration))
expected_alert = [
"You can now manage your Prometheus settings on the",
%(<a href="#{project_settings_operations_path(project)}">Operations</a> page.),
diff --git a/spec/controllers/projects/settings/access_tokens_controller_spec.rb b/spec/controllers/projects/settings/access_tokens_controller_spec.rb
deleted file mode 100644
index 834a9e276f9..00000000000
--- a/spec/controllers/projects/settings/access_tokens_controller_spec.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-# frozen_string_literal: true
-
-require('spec_helper')
-
-RSpec.describe Projects::Settings::AccessTokensController do
- let_it_be(:user) { create(:user) }
- let_it_be(:group) { create(:group) }
- let_it_be(:project) { create(:project, group: group) }
- let_it_be(:bot_user) { create(:user, :project_bot) }
-
- before_all do
- project.add_maintainer(user)
- project.add_maintainer(bot_user)
- end
-
- before do
- sign_in(user)
- end
-
- shared_examples 'feature unavailable' do
- context 'user is not a maintainer' do
- before do
- project.add_developer(user)
- end
-
- it { is_expected.to have_gitlab_http_status(:not_found) }
- end
- end
-
- describe '#index' do
- subject { get :index, params: { namespace_id: project.namespace, project_id: project } }
-
- it_behaves_like 'feature unavailable'
- it_behaves_like 'project access tokens available #index'
- end
-
- describe '#create' do
- let(:access_token_params) { { name: 'Nerd bot', scopes: ["api"], expires_at: Date.today + 1.month } }
-
- subject { post :create, params: { namespace_id: project.namespace, project_id: project }.merge(project_access_token: access_token_params) }
-
- it_behaves_like 'feature unavailable'
- it_behaves_like 'project access tokens available #create'
-
- context 'when project access token creation is disabled' do
- before do
- group.namespace_settings.update_column(:resource_access_token_creation_allowed, false)
- end
-
- it { is_expected.to have_gitlab_http_status(:not_found) }
-
- it 'does not create the token' do
- expect { subject }.not_to change { PersonalAccessToken.count }
- end
-
- it 'does not add the project bot as a member' do
- expect { subject }.not_to change { Member.count }
- end
-
- it 'does not create the project bot user' do
- expect { subject }.not_to change { User.count }
- end
- end
-
- context 'with custom access level' do
- let(:access_token_params) { { name: 'Nerd bot', scopes: ["api"], expires_at: Date.today + 1.month, access_level: 20 } }
-
- subject { post :create, params: { namespace_id: project.namespace, project_id: project }.merge(project_access_token: access_token_params) }
-
- it_behaves_like 'project access tokens available #create'
- end
- end
-
- describe '#revoke', :sidekiq_inline do
- let(:project_access_token) { create(:personal_access_token, user: bot_user) }
-
- subject { put :revoke, params: { namespace_id: project.namespace, project_id: project, id: project_access_token } }
-
- it_behaves_like 'feature unavailable'
- it_behaves_like 'project access tokens available #revoke'
- end
-end
diff --git a/spec/controllers/projects/settings/ci_cd_controller_spec.rb b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
index d50f1aa1dd8..7e96e99640a 100644
--- a/spec/controllers/projects/settings/ci_cd_controller_spec.rb
+++ b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
@@ -25,6 +25,19 @@ RSpec.describe Projects::Settings::CiCdController do
expect(response).to render_template(:show)
end
+ context 'when the FF ci_owned_runners_cross_joins_fix is disabled' do
+ before do
+ stub_feature_flags(ci_owned_runners_cross_joins_fix: false)
+ end
+
+ it 'renders show with 200 status code' do
+ get :show, params: { namespace_id: project.namespace, project_id: project }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to render_template(:show)
+ end
+ end
+
context 'with CI/CD disabled' do
before do
project.project_feature.update_attribute(:builds_access_level, ProjectFeature::DISABLED)
diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb
index 3f7941b3456..d5fe32ac094 100644
--- a/spec/controllers/registrations_controller_spec.rb
+++ b/spec/controllers/registrations_controller_spec.rb
@@ -20,6 +20,10 @@ RSpec.describe RegistrationsController do
end
describe '#create' do
+ before do
+ allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(false)
+ end
+
let_it_be(:base_user_params) do
{ first_name: 'first', last_name: 'last', username: 'new_username', email: 'new@user.com', password: 'Any_password' }
end
@@ -410,6 +414,18 @@ RSpec.describe RegistrationsController do
end
end
+ context 'when the rate limit has been reached' do
+ it 'returns status 429 Too Many Requests', :aggregate_failures do
+ ip = '1.2.3.4'
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).with(:user_sign_up, scope: ip).and_return(true)
+
+ controller.request.env['REMOTE_ADDR'] = ip
+ post(:create, params: user_params, session: session_params)
+
+ expect(response).to have_gitlab_http_status(:too_many_requests)
+ end
+ end
+
it "logs a 'User Created' message" do
expect(Gitlab::AppLogger).to receive(:info).with(/\AUser Created: username=new_username email=new@user.com.+\z/).and_call_original
@@ -483,7 +499,7 @@ RSpec.describe RegistrationsController do
end
it 'succeeds if password is confirmed' do
- post :destroy, params: { password: '12345678' }
+ post :destroy, params: { password: Gitlab::Password.test_default }
expect_success
end
@@ -524,7 +540,7 @@ RSpec.describe RegistrationsController do
end
it 'fails' do
- delete :destroy, params: { password: '12345678' }
+ delete :destroy, params: { password: Gitlab::Password.test_default }
expect_failure(s_('Profiles|You must transfer ownership or delete groups you are an owner of before you can delete your account'))
end
diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb
index a54f16ec237..58d34a5e5c1 100644
--- a/spec/controllers/search_controller_spec.rb
+++ b/spec/controllers/search_controller_spec.rb
@@ -290,6 +290,14 @@ RSpec.describe SearchController do
expect(assigns[:search_objects].count).to eq(0)
end
end
+
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :user_email_lookup do
+ let(:current_user) { user }
+
+ def request
+ get(:show, params: { search: 'foo@bar.com', scope: 'users' })
+ end
+ end
end
describe 'GET #count', :aggregate_failures do
@@ -346,6 +354,14 @@ RSpec.describe SearchController do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to eq({ 'count' => '0' })
end
+
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :user_email_lookup do
+ let(:current_user) { user }
+
+ def request
+ get(:count, params: { search: 'foo@bar.com', scope: 'users' })
+ end
+ end
end
describe 'GET #autocomplete' do
@@ -358,6 +374,14 @@ RSpec.describe SearchController do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to match_array([])
end
+
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :user_email_lookup do
+ let(:current_user) { user }
+
+ def request
+ get(:autocomplete, params: { term: 'foo@bar.com', scope: 'users' })
+ end
+ end
end
describe '#append_info_to_payload' do
@@ -372,9 +396,10 @@ RSpec.describe SearchController do
expect(payload[:metadata]['meta.search.force_search_results']).to eq('true')
expect(payload[:metadata]['meta.search.filters.confidential']).to eq('true')
expect(payload[:metadata]['meta.search.filters.state']).to eq('true')
+ expect(payload[:metadata]['meta.search.project_ids']).to eq(%w(456 789))
end
- get :show, params: { scope: 'issues', search: 'hello world', group_id: '123', project_id: '456', confidential: true, state: true, force_search_results: true }
+ get :show, params: { scope: 'issues', search: 'hello world', group_id: '123', project_id: '456', project_ids: %w(456 789), confidential: true, state: true, force_search_results: true }
end
it 'appends the default scope in meta.search.scope' do
diff --git a/spec/controllers/snippets/notes_controller_spec.rb b/spec/controllers/snippets/notes_controller_spec.rb
index 558e68fbb8f..8e85e283b31 100644
--- a/spec/controllers/snippets/notes_controller_spec.rb
+++ b/spec/controllers/snippets/notes_controller_spec.rb
@@ -142,9 +142,12 @@ RSpec.describe Snippets::NotesController do
expect { post :create, params: request_params }.to change { Note.count }.by(1)
end
- it_behaves_like 'request exceeding rate limit', :clean_gitlab_redis_cache do
- let(:params) { request_params }
- let(:request_full_path) { snippet_notes_path(public_snippet) }
+ it_behaves_like 'create notes request exceeding rate limit', :clean_gitlab_redis_cache do
+ let(:current_user) { user }
+
+ def request
+ post :create, params: request_params
+ end
end
end
@@ -170,9 +173,12 @@ RSpec.describe Snippets::NotesController do
expect { post :create, params: request_params }.to change { Note.count }.by(1)
end
- it_behaves_like 'request exceeding rate limit', :clean_gitlab_redis_cache do
- let(:params) { request_params }
- let(:request_full_path) { snippet_notes_path(internal_snippet) }
+ it_behaves_like 'create notes request exceeding rate limit', :clean_gitlab_redis_cache do
+ let(:current_user) { user }
+
+ def request
+ post :create, params: request_params
+ end
end
end
@@ -239,10 +245,12 @@ RSpec.describe Snippets::NotesController do
expect { post :create, params: request_params }.to change { Note.count }.by(1)
end
- it_behaves_like 'request exceeding rate limit', :clean_gitlab_redis_cache do
- let(:params) { request_params }
- let(:request_full_path) { snippet_notes_path(private_snippet) }
- let(:user) { private_snippet.author }
+ it_behaves_like 'create notes request exceeding rate limit', :clean_gitlab_redis_cache do
+ let(:current_user) { private_snippet.author }
+
+ def request
+ post :create, params: request_params
+ end
end
end
end
diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb
index edb412cbb9c..9bd6691bdb2 100644
--- a/spec/db/schema_spec.rb
+++ b/spec/db/schema_spec.rb
@@ -88,7 +88,8 @@ RSpec.describe 'Database schema' do
users_star_projects: %w[user_id],
vulnerability_identifiers: %w[external_id],
vulnerability_scanners: %w[external_id],
- security_scans: %w[pipeline_id] # foreign key is not added as ci_pipeline table will be moved into different db soon
+ security_scans: %w[pipeline_id], # foreign key is not added as ci_pipeline table will be moved into different db soon
+ vulnerability_reads: %w[cluster_agent_id]
}.with_indifferent_access.freeze
context 'for table' do
diff --git a/spec/experiments/change_continuous_onboarding_link_urls_experiment_spec.rb b/spec/experiments/change_continuous_onboarding_link_urls_experiment_spec.rb
deleted file mode 100644
index 815aaf7c397..00000000000
--- a/spec/experiments/change_continuous_onboarding_link_urls_experiment_spec.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe ChangeContinuousOnboardingLinkUrlsExperiment, :snowplow do
- before do
- stub_experiments(change_continuous_onboarding_link_urls: 'control')
- end
-
- describe '#track' do
- context 'when no namespace has been set' do
- it 'tracks the action as normal' do
- subject.track(:some_action)
-
- expect_snowplow_event(
- category: subject.name,
- action: 'some_action',
- namespace: nil,
- context: [
- {
- schema: 'iglu:com.gitlab/gitlab_experiment/jsonschema/1-0-0',
- data: an_instance_of(Hash)
- }
- ]
- )
- end
- end
-
- context 'when a namespace has been set' do
- let_it_be(:namespace) { create(:namespace) }
-
- before do
- subject.namespace = namespace
- end
-
- it 'tracks the action and merges the namespace into the event args' do
- subject.track(:some_action)
-
- expect_snowplow_event(
- category: subject.name,
- action: 'some_action',
- namespace: namespace,
- context: [
- {
- schema: 'iglu:com.gitlab/gitlab_experiment/jsonschema/1-0-0',
- data: an_instance_of(Hash)
- }
- ]
- )
- end
- end
- end
-end
diff --git a/spec/experiments/new_project_sast_enabled_experiment_spec.rb b/spec/experiments/new_project_sast_enabled_experiment_spec.rb
index 38f58c01973..041e5dfa469 100644
--- a/spec/experiments/new_project_sast_enabled_experiment_spec.rb
+++ b/spec/experiments/new_project_sast_enabled_experiment_spec.rb
@@ -4,7 +4,12 @@ require 'spec_helper'
RSpec.describe NewProjectSastEnabledExperiment do
it "defines the expected behaviors and variants" do
- expect(subject.behaviors.keys).to match_array(%w[control candidate free_indicator unchecked_candidate])
+ expect(subject.variant_names).to match_array([
+ :candidate,
+ :free_indicator,
+ :unchecked_candidate,
+ :unchecked_free_indicator
+ ])
end
it "publishes to the database" do
diff --git a/spec/experiments/require_verification_for_namespace_creation_experiment_spec.rb b/spec/experiments/require_verification_for_namespace_creation_experiment_spec.rb
new file mode 100644
index 00000000000..87417fe1637
--- /dev/null
+++ b/spec/experiments/require_verification_for_namespace_creation_experiment_spec.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe RequireVerificationForNamespaceCreationExperiment, :experiment do
+ subject(:experiment) { described_class.new(user: user) }
+
+ let_it_be(:user) { create(:user) }
+
+ describe '#candidate?' do
+ context 'when experiment subject is candidate' do
+ before do
+ stub_experiments(require_verification_for_namespace_creation: :candidate)
+ end
+
+ it 'returns true' do
+ expect(experiment.candidate?).to eq(true)
+ end
+ end
+
+ context 'when experiment subject is control' do
+ before do
+ stub_experiments(require_verification_for_namespace_creation: :control)
+ end
+
+ it 'returns false' do
+ expect(experiment.candidate?).to eq(false)
+ end
+ end
+ end
+
+ describe '#record_conversion' do
+ let_it_be(:namespace) { create(:namespace) }
+
+ context 'when should_track? is false' do
+ before do
+ allow(experiment).to receive(:should_track?).and_return(false)
+ end
+
+ it 'does not record a conversion event' do
+ expect(experiment.publish_to_database).to be_nil
+ expect(experiment.record_conversion(namespace)).to be_nil
+ end
+ end
+
+ context 'when should_track? is true' do
+ before do
+ allow(experiment).to receive(:should_track?).and_return(true)
+ end
+
+ it 'records a conversion event' do
+ experiment_subject = experiment.publish_to_database
+
+ expect { experiment.record_conversion(namespace) }.to change { experiment_subject.reload.converted_at }.from(nil)
+ .and change { experiment_subject.context }.to include('namespace_id' => namespace.id)
+ end
+ end
+ end
+end
diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb
index e6eaebc9b6b..011021f6320 100644
--- a/spec/factories/ci/builds.rb
+++ b/spec/factories/ci/builds.rb
@@ -338,6 +338,10 @@ FactoryBot.define do
running
runner factory: :ci_runner
+
+ after(:create) do |build|
+ build.create_runtime_metadata!
+ end
end
trait :artifacts do
@@ -596,6 +600,11 @@ FactoryBot.define do
failure_reason { 13 }
end
+ trait :deployment_rejected do
+ failed
+ failure_reason { 22 }
+ end
+
trait :with_runner_session do
after(:build) do |build|
build.build_runner_session(url: 'https://localhost')
diff --git a/spec/factories/ci/job_artifacts.rb b/spec/factories/ci/job_artifacts.rb
index 223de873a04..e6eec280ed0 100644
--- a/spec/factories/ci/job_artifacts.rb
+++ b/spec/factories/ci/job_artifacts.rb
@@ -10,6 +10,10 @@ FactoryBot.define do
expire_at { Date.yesterday }
end
+ trait :locked do
+ locked { Ci::JobArtifact.lockeds[:artifacts_locked] }
+ end
+
trait :remote_store do
file_store { JobArtifactUploader::Store::REMOTE}
end
diff --git a/spec/factories/ci/pipeline_message.rb b/spec/factories/ci/pipeline_message.rb
new file mode 100644
index 00000000000..71fac24922d
--- /dev/null
+++ b/spec/factories/ci/pipeline_message.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :ci_pipeline_message, class: 'Ci::PipelineMessage' do
+ pipeline factory: :ci_pipeline
+ content { 'warning' }
+ severity { 1 }
+ end
+end
diff --git a/spec/factories/ci/pipelines.rb b/spec/factories/ci/pipelines.rb
index b2c1eff6fbd..122af139985 100644
--- a/spec/factories/ci/pipelines.rb
+++ b/spec/factories/ci/pipelines.rb
@@ -87,6 +87,10 @@ FactoryBot.define do
locked { Ci::Pipeline.lockeds[:unlocked] }
end
+ trait :artifacts_locked do
+ locked { Ci::Pipeline.lockeds[:artifacts_locked] }
+ end
+
trait :protected do
add_attribute(:protected) { true }
end
diff --git a/spec/factories/ci/secure_files.rb b/spec/factories/ci/secure_files.rb
new file mode 100644
index 00000000000..9198ea61d14
--- /dev/null
+++ b/spec/factories/ci/secure_files.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :ci_secure_file, class: 'Ci::SecureFile' do
+ name { 'filename' }
+ file { fixture_file_upload('spec/fixtures/ci_secure_files/upload-keystore.jks', 'application/octet-stream') }
+ checksum { 'foo1234' }
+ project
+ end
+end
diff --git a/spec/factories/clusters/agent_tokens.rb b/spec/factories/clusters/agent_tokens.rb
index c49d197c3cd..03f765123db 100644
--- a/spec/factories/clusters/agent_tokens.rb
+++ b/spec/factories/clusters/agent_tokens.rb
@@ -7,5 +7,9 @@ FactoryBot.define do
token_encrypted { Gitlab::CryptoHelper.aes256_gcm_encrypt(SecureRandom.hex(50)) }
sequence(:name) { |n| "agent-token-#{n}" }
+
+ trait :revoked do
+ status { :revoked }
+ end
end
end
diff --git a/spec/factories/clusters/applications/helm.rb b/spec/factories/clusters/applications/helm.rb
index 29197768ec0..10fa739acc1 100644
--- a/spec/factories/clusters/applications/helm.rb
+++ b/spec/factories/clusters/applications/helm.rb
@@ -118,7 +118,6 @@ FactoryBot.define do
end
factory :clusters_applications_runner, class: 'Clusters::Applications::Runner' do
- runner factory: %i(ci_runner)
cluster factory: %i(cluster with_installed_helm provided_by_gcp)
end
diff --git a/spec/factories/dependency_proxy.rb b/spec/factories/dependency_proxy.rb
index 836ee87e4d7..afa6c61116a 100644
--- a/spec/factories/dependency_proxy.rb
+++ b/spec/factories/dependency_proxy.rb
@@ -8,8 +8,8 @@ FactoryBot.define do
file_name { 'a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4.gz' }
status { :default }
- trait :expired do
- status { :expired }
+ trait :pending_destruction do
+ status { :pending_destruction }
end
end
@@ -22,8 +22,8 @@ FactoryBot.define do
content_type { 'application/vnd.docker.distribution.manifest.v2+json' }
status { :default }
- trait :expired do
- status { :expired }
+ trait :pending_destruction do
+ status { :pending_destruction }
end
end
end
diff --git a/spec/factories/group/crm_settings.rb b/spec/factories/group/crm_settings.rb
new file mode 100644
index 00000000000..06a31fd69c0
--- /dev/null
+++ b/spec/factories/group/crm_settings.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :crm_settings, class: 'Group::CrmSettings' do
+ group
+ end
+end
diff --git a/spec/factories/groups.rb b/spec/factories/groups.rb
index 859f381e4c1..152ae061605 100644
--- a/spec/factories/groups.rb
+++ b/spec/factories/groups.rb
@@ -112,5 +112,11 @@ FactoryBot.define do
)
end
end
+
+ trait :crm_enabled do
+ after(:create) do |group|
+ create(:crm_settings, group: group, enabled: true)
+ end
+ end
end
end
diff --git a/spec/factories/incident_management/issuable_escalation_statuses.rb b/spec/factories/incident_management/issuable_escalation_statuses.rb
index 54d0887f386..0486e0481bf 100644
--- a/spec/factories/incident_management/issuable_escalation_statuses.rb
+++ b/spec/factories/incident_management/issuable_escalation_statuses.rb
@@ -2,7 +2,7 @@
FactoryBot.define do
factory :incident_management_issuable_escalation_status, class: 'IncidentManagement::IssuableEscalationStatus' do
- issue
+ association :issue, factory: :incident
triggered
trait :triggered do
diff --git a/spec/factories/integrations.rb b/spec/factories/integrations.rb
index 76415f82ed0..f3a00ac083a 100644
--- a/spec/factories/integrations.rb
+++ b/spec/factories/integrations.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
FactoryBot.define do
- factory :integration, aliases: [:service] do
+ factory :integration do
project
type { 'Integration' }
end
diff --git a/spec/factories/labels.rb b/spec/factories/labels.rb
index a9a9416c48b..f0cef41db69 100644
--- a/spec/factories/labels.rb
+++ b/spec/factories/labels.rb
@@ -42,4 +42,6 @@ FactoryBot.define do
factory :group_label, traits: [:base_label] do
group
end
+
+ factory :admin_label, traits: [:base_label], class: 'Label'
end
diff --git a/spec/factories/namespaces.rb b/spec/factories/namespaces.rb
index 2b3dabc07d8..e88bb634898 100644
--- a/spec/factories/namespaces.rb
+++ b/spec/factories/namespaces.rb
@@ -11,6 +11,14 @@ FactoryBot.define do
owner { association(:user, strategy: :build, namespace: instance, username: path) }
+ after(:create) do |namespace, evaluator|
+ # simulating ::Namespaces::ProcessSyncEventsWorker because most tests don't run Sidekiq inline
+ # Note: we need to get refreshed `traversal_ids` it is updated via SQL query
+ # in `Namespaces::Traversal::Linear#sync_traversal_ids` (see the NOTE in that method).
+ # We cannot use `.reload` because it cleans other on-the-fly attributes.
+ namespace.create_ci_namespace_mirror!(traversal_ids: Namespace.find(namespace.id).traversal_ids) unless namespace.ci_namespace_mirror
+ end
+
trait :with_aggregation_schedule do
after(:create) do |namespace|
create(:namespace_aggregation_schedules, namespace: namespace)
diff --git a/spec/factories/packages/package_files.rb b/spec/factories/packages/package_files.rb
index 845fd882beb..5eac0036b91 100644
--- a/spec/factories/packages/package_files.rb
+++ b/spec/factories/packages/package_files.rb
@@ -6,6 +6,8 @@ FactoryBot.define do
file_name { 'somefile.txt' }
+ status { :default }
+
transient do
file_fixture { 'spec/fixtures/packages/conan/recipe_files/conanfile.py' }
end
@@ -14,6 +16,10 @@ FactoryBot.define do
package_file.file = fixture_file_upload(evaluator.file_fixture)
end
+ trait :pending_destruction do
+ status { :pending_destruction }
+ end
+
factory :conan_package_file do
package { association(:conan_package, without_package_files: true) }
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb
index 981f10e8260..c345fa0c8b4 100644
--- a/spec/factories/projects.rb
+++ b/spec/factories/projects.rb
@@ -49,6 +49,8 @@ FactoryBot.define do
forward_deployment_enabled { nil }
restrict_user_defined_variables { nil }
ci_job_token_scope_enabled { nil }
+ runner_token_expiration_interval { nil }
+ runner_token_expiration_interval_human_readable { nil }
end
after(:build) do |project, evaluator|
@@ -92,6 +94,8 @@ FactoryBot.define do
project.keep_latest_artifact = evaluator.keep_latest_artifact unless evaluator.keep_latest_artifact.nil?
project.restrict_user_defined_variables = evaluator.restrict_user_defined_variables unless evaluator.restrict_user_defined_variables.nil?
project.ci_job_token_scope_enabled = evaluator.ci_job_token_scope_enabled unless evaluator.ci_job_token_scope_enabled.nil?
+ project.runner_token_expiration_interval = evaluator.runner_token_expiration_interval unless evaluator.runner_token_expiration_interval.nil?
+ project.runner_token_expiration_interval_human_readable = evaluator.runner_token_expiration_interval_human_readable unless evaluator.runner_token_expiration_interval_human_readable.nil?
if evaluator.import_status
import_state = project.import_state || project.build_import_state
@@ -101,6 +105,9 @@ FactoryBot.define do
import_state.last_error = evaluator.import_last_error
import_state.save!
end
+
+ # simulating ::Projects::ProcessSyncEventsWorker because most tests don't run Sidekiq inline
+ project.create_ci_project_mirror!(namespace_id: project.namespace_id) unless project.ci_project_mirror
end
trait :public do
diff --git a/spec/factories/usage_data.rb b/spec/factories/usage_data.rb
index fc1f5d71f39..f00d1f8b808 100644
--- a/spec/factories/usage_data.rb
+++ b/spec/factories/usage_data.rb
@@ -19,16 +19,16 @@ 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(:service, project: projects[1], type: 'JenkinsService', active: true)
- create(:service, project: projects[0], type: 'SlackSlashCommandsService', active: true)
- create(:service, project: projects[1], type: 'SlackService', active: true)
- create(:service, project: projects[2], type: 'SlackService', active: true)
- create(:service, project: projects[2], type: 'MattermostService', active: false)
- create(:service, group: group, project: nil, type: 'MattermostService', active: true)
- mattermost_instance = create(:service, :instance, type: 'MattermostService', active: true)
- create(:service, project: projects[1], type: 'MattermostService', active: true, inherit_from_id: mattermost_instance.id)
- create(:service, group: group, project: nil, type: 'SlackService', active: true, inherit_from_id: mattermost_instance.id)
- create(:service, project: projects[2], type: 'CustomIssueTrackerService', active: true)
+ 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(: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 8aa9654956e..5f325717ec5 100644
--- a/spec/factories/users.rb
+++ b/spec/factories/users.rb
@@ -5,7 +5,7 @@ FactoryBot.define do
email { generate(:email) }
name { generate(:name) }
username { generate(:username) }
- password { "12345678" }
+ password { Gitlab::Password.test_default }
role { 'software_developer' }
confirmed_at { Time.now }
confirmation_token { nil }
diff --git a/spec/factories/wikis.rb b/spec/factories/wikis.rb
index 05f6fb0de58..a357f4b448d 100644
--- a/spec/factories/wikis.rb
+++ b/spec/factories/wikis.rb
@@ -4,7 +4,7 @@ FactoryBot.define do
factory :wiki do
transient do
container { association(:project) }
- user { container.default_owner || association(:user) }
+ user { container.first_owner || association(:user) }
end
initialize_with { Wiki.for_container(container, user) }
diff --git a/spec/factories/work_item/work_item_types.rb b/spec/factories/work_item/work_item_types.rb
deleted file mode 100644
index 1c586aab59b..00000000000
--- a/spec/factories/work_item/work_item_types.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-# frozen_string_literal: true
-
-FactoryBot.define do
- factory :work_item_type, class: 'WorkItem::Type' do
- namespace
-
- name { generate(:work_item_type_name) }
- base_type { WorkItem::Type.base_types[:issue] }
- icon_name { 'issue-type-issue' }
-
- initialize_with do
- type_base_attributes = attributes.with_indifferent_access.slice(:base_type, :namespace, :namespace_id)
-
- # Expect base_types to exist on the DB
- if type_base_attributes.slice(:namespace, :namespace_id).compact.empty?
- WorkItem::Type.find_or_initialize_by(type_base_attributes).tap { |type| type.assign_attributes(attributes) }
- else
- WorkItem::Type.new(attributes)
- end
- end
-
- trait :default do
- namespace { nil }
- end
-
- trait :incident do
- base_type { WorkItem::Type.base_types[:incident] }
- icon_name { 'issue-type-incident' }
- end
-
- trait :test_case do
- base_type { WorkItem::Type.base_types[:test_case] }
- icon_name { 'issue-type-test-case' }
- end
-
- trait :requirement do
- base_type { WorkItem::Type.base_types[:requirement] }
- icon_name { 'issue-type-requirements' }
- end
- end
-end
diff --git a/spec/factories/work_items/work_item_types.rb b/spec/factories/work_items/work_item_types.rb
new file mode 100644
index 00000000000..0920b36bcbd
--- /dev/null
+++ b/spec/factories/work_items/work_item_types.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :work_item_type, class: 'WorkItems::Type' do
+ namespace
+
+ name { generate(:work_item_type_name) }
+ base_type { WorkItems::Type.base_types[:issue] }
+ icon_name { 'issue-type-issue' }
+
+ initialize_with do
+ type_base_attributes = attributes.with_indifferent_access.slice(:base_type, :namespace, :namespace_id)
+
+ # Expect base_types to exist on the DB
+ if type_base_attributes.slice(:namespace, :namespace_id).compact.empty?
+ WorkItems::Type.find_or_initialize_by(type_base_attributes).tap { |type| type.assign_attributes(attributes) }
+ else
+ WorkItems::Type.new(attributes)
+ end
+ end
+
+ trait :default do
+ namespace { nil }
+ end
+
+ trait :incident do
+ base_type { WorkItems::Type.base_types[:incident] }
+ icon_name { 'issue-type-incident' }
+ end
+
+ trait :test_case do
+ base_type { WorkItems::Type.base_types[:test_case] }
+ icon_name { 'issue-type-test-case' }
+ end
+
+ trait :requirement do
+ base_type { WorkItems::Type.base_types[:requirement] }
+ icon_name { 'issue-type-requirements' }
+ end
+ end
+end
diff --git a/spec/features/admin/admin_deploy_keys_spec.rb b/spec/features/admin/admin_deploy_keys_spec.rb
index 9b74aa2ac5a..88b8fcd8d5e 100644
--- a/spec/features/admin/admin_deploy_keys_spec.rb
+++ b/spec/features/admin/admin_deploy_keys_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'admin deploy keys' do
+RSpec.describe 'admin deploy keys', :js do
include Spec::Support::Helpers::ModalHelpers
let_it_be(:admin) { create(:admin) }
@@ -15,112 +15,81 @@ RSpec.describe 'admin deploy keys' do
gitlab_enable_admin_mode_sign_in(admin)
end
- shared_examples 'renders deploy keys correctly' do
- it 'show all public deploy keys' do
- visit admin_deploy_keys_path
+ it 'show all public deploy keys' do
+ visit admin_deploy_keys_path
- page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do
- expect(page).to have_content(deploy_key.title)
- expect(page).to have_content(another_deploy_key.title)
- end
+ page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do
+ expect(page).to have_content(deploy_key.title)
+ expect(page).to have_content(another_deploy_key.title)
end
+ end
- it 'shows all the projects the deploy key has write access' do
- write_key = create(:deploy_keys_project, :write_access, deploy_key: deploy_key)
+ it 'shows all the projects the deploy key has write access' do
+ write_key = create(:deploy_keys_project, :write_access, deploy_key: deploy_key)
- visit admin_deploy_keys_path
+ visit admin_deploy_keys_path
- page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do
- expect(page).to have_content(write_key.project.full_name)
- end
+ page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do
+ expect(page).to have_content(write_key.project.full_name)
end
+ end
- describe 'create a new deploy key' do
- let(:new_ssh_key) { attributes_for(:key)[:key] }
-
- before do
- visit admin_deploy_keys_path
- click_link 'New deploy key'
- end
-
- it 'creates a new deploy key' do
- fill_in 'deploy_key_title', with: 'laptop'
- fill_in 'deploy_key_key', with: new_ssh_key
- click_button 'Create'
-
- expect(current_path).to eq admin_deploy_keys_path
+ describe 'create a new deploy key' do
+ let(:new_ssh_key) { attributes_for(:key)[:key] }
- page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do
- expect(page).to have_content('laptop')
- end
- end
+ before do
+ visit admin_deploy_keys_path
+ click_link 'New deploy key'
end
- describe 'update an existing deploy key' do
- before do
- visit admin_deploy_keys_path
- page.within('tr', text: deploy_key.title) do
- click_link(_('Edit deploy key'))
- end
- end
+ it 'creates a new deploy key' do
+ fill_in 'deploy_key_title', with: 'laptop'
+ fill_in 'deploy_key_key', with: new_ssh_key
+ click_button 'Create'
- it 'updates an existing deploy key' do
- fill_in 'deploy_key_title', with: 'new-title'
- click_button 'Save changes'
+ expect(current_path).to eq admin_deploy_keys_path
- expect(current_path).to eq admin_deploy_keys_path
-
- page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do
- expect(page).to have_content('new-title')
- end
+ page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do
+ expect(page).to have_content('laptop')
end
end
end
- context 'when `admin_deploy_keys_vue` feature flag is enabled', :js do
- it_behaves_like 'renders deploy keys correctly'
-
- describe 'remove an existing deploy key' do
- before do
- visit admin_deploy_keys_path
+ describe 'update an existing deploy key' do
+ before do
+ visit admin_deploy_keys_path
+ page.within('tr', text: deploy_key.title) do
+ click_link(_('Edit deploy key'))
end
+ end
- it 'removes an existing deploy key' do
- accept_gl_confirm('Are you sure you want to delete this deploy key?', button_text: 'Delete') do
- page.within('tr', text: deploy_key.title) do
- click_button _('Delete deploy key')
- end
- end
+ it 'updates an existing deploy key' do
+ fill_in 'deploy_key_title', with: 'new-title'
+ click_button 'Save changes'
- expect(current_path).to eq admin_deploy_keys_path
- page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do
- expect(page).not_to have_content(deploy_key.title)
- end
+ expect(current_path).to eq admin_deploy_keys_path
+
+ page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do
+ expect(page).to have_content('new-title')
end
end
end
- context 'when `admin_deploy_keys_vue` feature flag is disabled' do
+ describe 'remove an existing deploy key' do
before do
- stub_feature_flags(admin_deploy_keys_vue: false)
+ visit admin_deploy_keys_path
end
- it_behaves_like 'renders deploy keys correctly'
-
- describe 'remove an existing deploy key' do
- before do
- visit admin_deploy_keys_path
- end
-
- it 'removes an existing deploy key' do
+ it 'removes an existing deploy key' do
+ accept_gl_confirm('Are you sure you want to delete this deploy key?', button_text: 'Delete') do
page.within('tr', text: deploy_key.title) do
- click_link _('Remove deploy key')
+ click_button _('Delete deploy key')
end
+ end
- expect(current_path).to eq admin_deploy_keys_path
- page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do
- expect(page).not_to have_content(deploy_key.title)
- end
+ expect(current_path).to eq admin_deploy_keys_path
+ page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do
+ expect(page).not_to have_content(deploy_key.title)
end
end
end
diff --git a/spec/features/admin/admin_labels_spec.rb b/spec/features/admin/admin_labels_spec.rb
index 86d60b5d483..ba0870a53ae 100644
--- a/spec/features/admin/admin_labels_spec.rb
+++ b/spec/features/admin/admin_labels_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'admin issues labels' do
+ include Spec::Support::Helpers::ModalHelpers
+
let!(:bug_label) { Label.create!(title: 'bug', template: true) }
let!(:feature_label) { Label.create!(title: 'feature', template: true) }
@@ -59,7 +61,7 @@ RSpec.describe 'admin issues labels' do
it 'creates new label' do
fill_in 'Title', with: 'support'
fill_in 'Background color', with: '#F95610'
- click_button 'Save'
+ click_button 'Create label'
page.within '.manage-labels-list' do
expect(page).to have_content('support')
@@ -69,7 +71,7 @@ RSpec.describe 'admin issues labels' do
it 'does not creates label with invalid color' do
fill_in 'Title', with: 'support'
fill_in 'Background color', with: '#12'
- click_button 'Save'
+ click_button 'Create label'
page.within '.label-form' do
expect(page).to have_content('Color must be a valid color code')
@@ -79,7 +81,7 @@ RSpec.describe 'admin issues labels' do
it 'does not creates label if label already exists' do
fill_in 'Title', with: 'bug'
fill_in 'Background color', with: '#F95610'
- click_button 'Save'
+ click_button 'Create label'
page.within '.label-form' do
expect(page).to have_content 'Title has already been taken'
@@ -93,11 +95,25 @@ RSpec.describe 'admin issues labels' do
fill_in 'Title', with: 'fix'
fill_in 'Background color', with: '#F15610'
- click_button 'Save'
+ click_button 'Save changes'
page.within '.manage-labels-list' do
expect(page).to have_content('fix')
end
end
+
+ it 'allows user to delete label', :js do
+ visit edit_admin_label_path(bug_label)
+
+ click_button 'Delete'
+
+ within_modal do
+ expect(page).to have_content("#{bug_label.title} will be permanently deleted. This cannot be undone.")
+
+ click_link 'Delete label'
+ end
+
+ expect(page).to have_content('Label was removed')
+ end
end
end
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index cc2d36221dc..ceb91b86876 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -21,12 +21,16 @@ RSpec.describe "Admin Runners" do
context "when there are runners" do
it 'has all necessary texts' do
- create(:ci_runner, :instance, contacted_at: Time.now)
+ create(:ci_runner, :instance, created_at: 1.year.ago, contacted_at: Time.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)
visit admin_runners_path
expect(page).to have_text "Register an instance runner"
- expect(page).to have_text "Online Runners 1"
+ expect(page).to have_text "Online runners 1"
+ expect(page).to have_text "Offline runners 2"
+ expect(page).to have_text "Stale runners 1"
end
it 'with an instance runner shows an instance badge' do
@@ -131,6 +135,9 @@ RSpec.describe "Admin Runners" do
it 'shows correct runner when description matches' do
input_filtered_search_keys('runner-foo')
+ expect(page).to have_link('All 1')
+ expect(page).to have_link('Instance 1')
+
expect(page).to have_content("runner-foo")
expect(page).not_to have_content("runner-bar")
end
@@ -138,71 +145,78 @@ RSpec.describe "Admin Runners" do
it 'shows no runner when description does not match' do
input_filtered_search_keys('runner-baz')
+ expect(page).to have_link('All 0')
+ expect(page).to have_link('Instance 0')
+
expect(page).to have_text 'No runners found'
end
end
describe 'filter by status' do
- it 'shows correct runner when status matches' do
- create(:ci_runner, :instance, description: 'runner-active', active: true)
- create(:ci_runner, :instance, description: 'runner-paused', active: false)
+ 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)
visit admin_runners_path
+ end
- expect(page).to have_content 'runner-active'
+ it 'shows all runners' do
+ expect(page).to have_content 'runner-1'
+ expect(page).to have_content 'runner-2'
expect(page).to have_content 'runner-paused'
+ expect(page).to have_content 'runner-never-contacted'
+ expect(page).to have_link('All 4')
+ end
+
+ it 'shows correct runner when status matches' do
input_filtered_search_filter_is_only('Status', 'Active')
- expect(page).to have_content 'runner-active'
+ expect(page).to have_link('All 3')
+
+ expect(page).to have_content 'runner-1'
+ expect(page).to have_content 'runner-2'
+ expect(page).to have_content 'runner-never-contacted'
expect(page).not_to have_content 'runner-paused'
end
it 'shows no runner when status does not match' do
- create(:ci_runner, :instance, description: 'runner-active', active: true)
- create(:ci_runner, :instance, description: 'runner-paused', active: false)
+ input_filtered_search_filter_is_only('Status', 'Stale')
- visit admin_runners_path
-
- input_filtered_search_filter_is_only('Status', 'Online')
-
- expect(page).not_to have_content 'runner-active'
- expect(page).not_to have_content 'runner-paused'
+ expect(page).to have_link('All 0')
expect(page).to have_text 'No runners found'
end
it 'shows correct runner when status is selected and search term is entered' do
- create(:ci_runner, :instance, description: 'runner-a-1', active: true)
- create(:ci_runner, :instance, description: 'runner-a-2', active: false)
- create(:ci_runner, :instance, description: 'runner-b-1', active: true)
-
- visit admin_runners_path
-
input_filtered_search_filter_is_only('Status', 'Active')
+ input_filtered_search_keys('runner-1')
- expect(page).to have_content 'runner-a-1'
- expect(page).to have_content 'runner-b-1'
- expect(page).not_to have_content 'runner-a-2'
-
- input_filtered_search_keys('runner-a')
+ expect(page).to have_link('All 1')
- expect(page).to have_content 'runner-a-1'
- expect(page).not_to have_content 'runner-b-1'
- expect(page).not_to have_content 'runner-a-2'
+ expect(page).to have_content 'runner-1'
+ expect(page).not_to have_content 'runner-2'
+ expect(page).not_to have_content 'runner-never-contacted'
+ expect(page).not_to have_content 'runner-paused'
end
- it 'shows correct runner when type is selected and search term is entered' do
- create(:ci_runner, :instance, description: 'runner-connected', contacted_at: Time.now)
- create(:ci_runner, :instance, description: 'runner-not-connected', contacted_at: nil)
+ it 'shows correct runner when status filter is entered' do
+ # use the string "Never" to avoid using space and trigger an early selection
+ input_filtered_search_filter_is_only('Status', 'Never')
- visit admin_runners_path
+ expect(page).to have_link('All 1')
- # use the string "Not" to avoid using space and trigger an early selection
- input_filtered_search_filter_is_only('Status', 'Not')
+ expect(page).not_to have_content 'runner-1'
+ expect(page).not_to have_content 'runner-2'
+ expect(page).not_to have_content 'runner-paused'
+ expect(page).to have_content 'runner-never-contacted'
- expect(page).not_to have_content 'runner-connected'
- expect(page).to have_content 'runner-not-connected'
+ within "[data-testid='runner-row-#{never_contacted.id}']" do
+ expect(page).to have_selector '.badge', text: 'never contacted'
+ end
end
end
@@ -215,6 +229,10 @@ RSpec.describe "Admin Runners" do
it '"All" tab is selected by default' do
visit admin_runners_path
+ expect(page).to have_link('All 2')
+ expect(page).to have_link('Group 1')
+ expect(page).to have_link('Project 1')
+
page.within('[data-testid="runner-type-tabs"]') do
expect(page).to have_link('All', class: 'active')
end
@@ -373,9 +391,28 @@ RSpec.describe "Admin Runners" do
it 'has all necessary texts including no runner message' do
expect(page).to have_text "Register an instance runner"
- expect(page).to have_text "Online Runners 0"
+
+ expect(page).to have_text "Online runners 0"
+ expect(page).to have_text "Offline runners 0"
+ expect(page).to have_text "Stale runners 0"
+
expect(page).to have_text 'No runners found'
end
+
+ it 'shows tabs with total counts equal to 0' do
+ expect(page).to have_link('All 0')
+ expect(page).to have_link('Instance 0')
+ expect(page).to have_link('Group 0')
+ expect(page).to have_link('Project 0')
+ end
+ end
+
+ context "when visiting outdated URLs" do
+ it 'updates NOT_CONNECTED runner status to NEVER_CONNECTED' do
+ visit admin_runners_path('status[]': 'NOT_CONNECTED')
+
+ expect(page).to have_current_path(admin_runners_path('status[]': 'NEVER_CONTACTED') )
+ end
end
describe 'runners registration' do
@@ -422,7 +459,9 @@ RSpec.describe "Admin Runners" do
before do
click_on 'Reset registration token'
- page.accept_alert
+ within_modal do
+ click_button('OK', match: :first)
+ end
wait_for_requests
end
@@ -437,26 +476,29 @@ RSpec.describe "Admin Runners" do
end
end
- describe "Runner show page" do
+ describe "Runner edit page" do
let(:runner) { create(:ci_runner) }
before do
@project1 = create(:project)
@project2 = create(:project)
- visit admin_runner_path(runner)
+ visit edit_admin_runner_path(runner)
+
+ wait_for_requests
end
describe 'runner page breadcrumbs' do
- it 'contains the current runner token' do
+ it 'contains the current runner id and token' do
page.within '[data-testid="breadcrumb-links"]' do
- expect(page.find('h2')).to have_content(runner.short_sha)
+ expect(page).to have_link("##{runner.id} (#{runner.short_sha})")
+ expect(page.find('h2')).to have_content("Edit")
end
end
end
- describe 'runner page title', :js do
- it 'contains the runner id' do
- expect(find('.page-title')).to have_content("Runner ##{runner.id}")
+ describe 'runner header', :js do
+ it 'contains the runner status, type and id' do
+ expect(page).to have_content("never contacted shared Runner ##{runner.id} created")
end
end
@@ -498,7 +540,7 @@ RSpec.describe "Admin Runners" do
let(:runner) { create(:ci_runner, :project, projects: [@project1]) }
before do
- visit admin_runner_path(runner)
+ visit edit_admin_runner_path(runner)
end
it_behaves_like 'assignable runner'
@@ -508,7 +550,7 @@ RSpec.describe "Admin Runners" do
let(:runner) { create(:ci_runner, :project, projects: [@project1], locked: true) }
before do
- visit admin_runner_path(runner)
+ visit edit_admin_runner_path(runner)
end
it_behaves_like 'assignable runner'
@@ -519,7 +561,7 @@ RSpec.describe "Admin Runners" do
before do
@project1.destroy!
- visit admin_runner_path(runner)
+ visit edit_admin_runner_path(runner)
end
it_behaves_like 'assignable runner'
@@ -530,7 +572,7 @@ RSpec.describe "Admin Runners" do
let(:runner) { create(:ci_runner, :project, projects: [@project1]) }
before do
- visit admin_runner_path(runner)
+ visit edit_admin_runner_path(runner)
end
it 'removed specific runner from project' do
@@ -567,6 +609,8 @@ RSpec.describe "Admin Runners" do
page.find('input').send_keys(search_term)
click_on 'Search'
end
+
+ wait_for_requests
end
def input_filtered_search_filter_is_only(filter, value)
@@ -583,5 +627,7 @@ RSpec.describe "Admin Runners" do
click_on 'Search'
end
+
+ wait_for_requests
end
end
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 29323c604ef..e136ab41966 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -275,7 +275,7 @@ RSpec.describe 'Admin updates settings' do
it 'enable hiding third party offers' do
page.within('.as-third-party-offers') do
- check 'Do not display offers from third parties'
+ check 'Do not display content for customer experience improvement and offers from third parties'
click_button 'Save changes'
end
@@ -530,6 +530,7 @@ RSpec.describe 'Admin updates settings' do
it 'loads usage ping payload on click', :js do
stub_usage_data_connections
+ stub_database_flavor_check
page.within('#js-usage-settings') do
expected_payload_content = /(?=.*"uuid")(?=.*"hostname")/m
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index 2b627707ff2..95e3f5c70e5 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -57,4 +57,33 @@ RSpec.describe "Admin::Users" do
expect(page).to have_content("#{Time.now.strftime('%b %Y')} 3 0")
end
end
+
+ describe 'prompt user about registration features' do
+ let(:message) { s_("RegistrationFeatures|Want to %{feature_title} for free?") % { feature_title: s_('RegistrationFeatures|send emails to users') } }
+
+ it 'does not render registration features CTA when service ping is enabled' do
+ stub_application_setting(usage_ping_enabled: true)
+
+ visit admin_users_path
+
+ expect(page).not_to have_content(message)
+ end
+
+ context 'with no license and service ping disabled' do
+ before do
+ stub_application_setting(usage_ping_enabled: false)
+
+ if Gitlab.ee?
+ allow(License).to receive(:current).and_return(nil)
+ end
+ end
+
+ it 'renders registration features CTA' do
+ visit admin_users_path
+
+ expect(page).to have_content(message)
+ expect(page).to have_link(s_('RegistrationFeatures|Registration Features Program'))
+ end
+ end
+ end
end
diff --git a/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb b/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb
index 22a27b33671..793a5bced00 100644
--- a/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb
+++ b/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb
@@ -19,4 +19,19 @@ RSpec.describe 'User activates the instance-level Mattermost Slash Command integ
expect(page).to have_link('Settings', href: edit_path)
expect(page).to have_link('Projects using custom settings', href: overrides_path)
end
+
+ it 'does not render integration form element' do
+ expect(page).not_to have_selector('[data-testid="integration-form"]')
+ end
+
+ context 'when `vue_integration_form` feature flag is disabled' do
+ before do
+ stub_feature_flags(vue_integration_form: false)
+ visit_instance_integration('Mattermost slash commands')
+ end
+
+ it 'renders integration form element' do
+ expect(page).to have_selector('[data-testid="integration-form"]')
+ end
+ end
end
diff --git a/spec/features/admin/users/user_spec.rb b/spec/features/admin/users/user_spec.rb
index ae940fecabe..0d053329627 100644
--- a/spec/features/admin/users/user_spec.rb
+++ b/spec/features/admin/users/user_spec.rb
@@ -125,6 +125,26 @@ RSpec.describe 'Admin::Users::User' do
end
end
+ context 'when a user is locked', time_travel_to: '2020-02-02 10:30:45 -0700' do
+ let_it_be(:locked_user) { create(:user, locked_at: DateTime.parse('2020-02-02 10:30:00 -0700')) }
+
+ before do
+ visit admin_user_path(locked_user)
+ end
+
+ it "displays `(Locked)` next to user's name" do
+ expect(page).to have_content("#{locked_user.name} (Locked)")
+ end
+
+ it 'allows a user to be unlocked from the `User administration dropdown', :js do
+ accept_gl_confirm("Unlock user #{locked_user.name}?", button_text: 'Unlock') do
+ click_action_in_user_dropdown(locked_user.id, 'Unlock')
+ end
+
+ expect(page).not_to have_content("#{locked_user.name} (Locked)")
+ end
+ end
+
describe 'Impersonation' do
let_it_be(:another_user) { create(:user) }
diff --git a/spec/features/admin/users/users_spec.rb b/spec/features/admin/users/users_spec.rb
index fa943245fcb..473f51370b3 100644
--- a/spec/features/admin/users/users_spec.rb
+++ b/spec/features/admin/users/users_spec.rb
@@ -462,9 +462,9 @@ RSpec.describe 'Admin::Users' do
visit projects_admin_user_path(user)
end
- it 'lists group projects' do
+ it 'lists groups' do
within(:css, '.gl-mb-3 + .card') do
- expect(page).to have_content 'Group projects'
+ expect(page).to have_content 'Groups'
expect(page).to have_link group.name, href: admin_group_path(group)
end
end
diff --git a/spec/features/boards/board_filters_spec.rb b/spec/features/boards/board_filters_spec.rb
index 25e474bb676..49375e4b37b 100644
--- a/spec/features/boards/board_filters_spec.rb
+++ b/spec/features/boards/board_filters_spec.rb
@@ -34,7 +34,9 @@ RSpec.describe 'Issue board filters', :js do
it 'and submit one as filter', :aggregate_failures do
expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 2)
- expect_filtered_search_dropdown_results(filter_dropdown, 3)
+ wait_for_requests
+
+ expect_filtered_search_dropdown_results(filter_dropdown, 4)
click_on user.username
filter_submit.click
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index 2f21961d1fc..d25cddea902 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -528,7 +528,7 @@ RSpec.describe 'Project issue boards', :js do
end
it 'does not allow dragging' do
- expect(page).not_to have_selector('.user-can-drag')
+ expect(page).not_to have_selector('.gl-cursor-grab')
end
end
diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb
index 0bb8e0bcdc0..0e914ae19d1 100644
--- a/spec/features/boards/sidebar_spec.rb
+++ b/spec/features/boards/sidebar_spec.rb
@@ -6,9 +6,11 @@ RSpec.describe 'Project issue boards sidebar', :js do
include BoardHelpers
let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project, :public) }
+ let_it_be(:group) { create(:group, :public) }
+ let_it_be(:project) { create(:project, :public, namespace: group) }
let_it_be(:board) { create(:board, project: project) }
- let_it_be(:list) { create(:list, board: board, position: 0) }
+ let_it_be(:label) { create(:label, project: project, name: 'Label') }
+ let_it_be(:list) { create(:list, board: board, label: label, position: 0) }
let_it_be(:issue, reload: true) { create(:issue, project: project, relative_position: 1) }
diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb
index 4378e88f7c1..e600a99e3b6 100644
--- a/spec/features/commits_spec.rb
+++ b/spec/features/commits_spec.rb
@@ -30,10 +30,10 @@ RSpec.describe 'Commits' do
project.add_reporter(user)
end
- describe 'Commit builds with jobs_tab_feature flag off' do
+ describe 'Commit builds with jobs_tab_vue feature flag off' do
before do
stub_feature_flags(jobs_tab_vue: false)
- visit pipeline_path(pipeline)
+ visit builds_project_pipeline_path(project, pipeline)
end
it { expect(page).to have_content pipeline.sha[0..7] }
@@ -45,6 +45,23 @@ RSpec.describe 'Commits' do
end
end
end
+
+ describe 'Commit builds with jobs_tab_vue feature flag on', :js do
+ before do
+ visit builds_project_pipeline_path(project, pipeline)
+
+ wait_for_requests
+ end
+
+ it { expect(page).to have_content pipeline.sha[0..7] }
+
+ it 'contains generic commit status build' do
+ page.within('[data-testid="jobs-tab-table"]') do
+ expect(page).to have_content "##{status.id}" # build id
+ expect(page).to have_content 'generic' # build name
+ end
+ end
+ end
end
context 'commit status is Ci Build' do
@@ -103,6 +120,18 @@ RSpec.describe 'Commits' do
end
end
+ context 'Download artifacts with jobs_tab_vue feature flag on', :js do
+ before do
+ create(:ci_job_artifact, :archive, file: artifacts_file, job: build)
+ end
+
+ it do
+ visit builds_project_pipeline_path(project, pipeline)
+ wait_for_requests
+ expect(page).to have_link('Download artifacts', href: download_project_job_artifacts_path(project, build, file_type: :archive))
+ end
+ end
+
describe 'Cancel all builds' do
it 'cancels commit', :js, :sidekiq_might_not_need_inline do
visit pipeline_path(pipeline)
@@ -141,6 +170,27 @@ RSpec.describe 'Commits' do
end
end
+ context "when logged as reporter and with jobs_tab_vue feature flag on", :js do
+ before do
+ project.add_reporter(user)
+ create(:ci_job_artifact, :archive, file: artifacts_file, job: build)
+ visit builds_project_pipeline_path(project, pipeline)
+ wait_for_requests
+ end
+
+ it 'renders header' 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 accessing internal project with disallowed access', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/299575' do
before do
project.update!(
diff --git a/spec/features/dashboard/issues_spec.rb b/spec/features/dashboard/issues_spec.rb
index a9fb6a2ae7e..64181041be5 100644
--- a/spec/features/dashboard/issues_spec.rb
+++ b/spec/features/dashboard/issues_spec.rb
@@ -71,7 +71,7 @@ RSpec.describe 'Dashboard Issues' do
find('#select2-drop-mask', visible: false)
execute_script("$('#select2-drop-mask').remove();")
- find('.new-project-item-link').click
+ find('.js-new-project-item-link').click
expect(page).to have_current_path("#{project_path}/-/issues/new")
diff --git a/spec/features/dashboard/milestones_spec.rb b/spec/features/dashboard/milestones_spec.rb
index 1ba16bf879a..9758454ab61 100644
--- a/spec/features/dashboard/milestones_spec.rb
+++ b/spec/features/dashboard/milestones_spec.rb
@@ -41,7 +41,7 @@ RSpec.describe 'Dashboard > Milestones' do
first('.select2-result-label').click
end
- find('.new-project-item-link').click
+ find('.js-new-project-item-link').click
expect(current_path).to eq(new_group_milestone_path(group))
end
diff --git a/spec/features/dashboard/todos/todos_spec.rb b/spec/features/dashboard/todos/todos_spec.rb
index 7345bfa19e2..b00bdeac3b9 100644
--- a/spec/features/dashboard/todos/todos_spec.rb
+++ b/spec/features/dashboard/todos/todos_spec.rb
@@ -5,10 +5,11 @@ require 'spec_helper'
RSpec.describe 'Dashboard Todos' do
include DesignManagementTestHelpers
- let_it_be(:user) { create(:user, username: 'john') }
- let_it_be(:author) { create(:user) }
+ let_it_be(:user) { create(:user, username: 'john') }
+ let_it_be(:user2) { create(:user, username: 'diane') }
+ let_it_be(:author) { create(:user) }
let_it_be(:project) { create(:project, :public) }
- let_it_be(:issue) { create(:issue, project: project, due_date: Date.today, title: "Fix bug") }
+ let_it_be(:issue) { create(:issue, project: project, due_date: Date.today, title: "Fix bug") }
before_all do
project.add_developer(user)
@@ -23,6 +24,19 @@ RSpec.describe 'Dashboard Todos' do
it 'shows "All done" message' do
expect(page).to have_content 'Your To-Do List shows what to work on next'
end
+
+ context 'when user was assigned to an issue and marked it as done' do
+ before do
+ sign_in(user)
+ end
+
+ it 'shows "Are you looking for things to do?" message' do
+ create(:todo, :assigned, :done, user: user, project: project, target: issue, author: user2)
+ visit dashboard_todos_path
+
+ expect(page).to have_content 'Are you looking for things to do? Take a look at open issues, contribute to a merge request, or mention someone in a comment to automatically assign them a new to-do item.'
+ end
+ end
end
context 'when the todo references a merge request' do
diff --git a/spec/features/dashboard/user_filters_projects_spec.rb b/spec/features/dashboard/user_filters_projects_spec.rb
index 9fa77d5917d..f6821ae66e8 100644
--- a/spec/features/dashboard/user_filters_projects_spec.rb
+++ b/spec/features/dashboard/user_filters_projects_spec.rb
@@ -168,7 +168,7 @@ RSpec.describe 'Dashboard > User filters projects' do
sorting_dropdown.click
- ['Last updated', 'Created date', 'Name', 'Stars'].each do |label|
+ ['Updated date', 'Created date', 'Name', 'Stars'].each do |label|
expect(sorting_dropdown).to have_content(label)
end
end
@@ -192,9 +192,9 @@ RSpec.describe 'Dashboard > User filters projects' do
end
end
- context 'Sorting by Last updated' do
+ context 'Sorting by Updated date' do
it 'sorts the project list' do
- select_dropdown_option '#filtered-search-sorting-dropdown', 'Last updated'
+ select_dropdown_option '#filtered-search-sorting-dropdown', 'Updated date'
expect_to_see_projects(desc_sorted_project_names)
diff --git a/spec/features/graphiql_spec.rb b/spec/features/graphiql_spec.rb
index 91f53b4bb7c..7729cdaa362 100644
--- a/spec/features/graphiql_spec.rb
+++ b/spec/features/graphiql_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe 'GraphiQL' do
end
it 'has the correct graphQLEndpoint' do
- expect(page.body).to include('var graphQLEndpoint = "/api/graphql";')
+ expect(page.body).to include('<div id="graphiql-container" data-graphql-endpoint-path="/api/graphql"')
end
end
@@ -26,7 +26,7 @@ RSpec.describe 'GraphiQL' do
end
it 'has the correct graphQLEndpoint' do
- expect(page.body).to include('var graphQLEndpoint = "/gitlab/root/api/graphql";')
+ expect(page.body).to include('<div id="graphiql-container" data-graphql-endpoint-path="/gitlab/root/api/graphql"')
end
end
end
diff --git a/spec/features/groups/dependency_proxy_for_containers_spec.rb b/spec/features/groups/dependency_proxy_for_containers_spec.rb
index a4cd6d0f503..ae721e7b91f 100644
--- a/spec/features/groups/dependency_proxy_for_containers_spec.rb
+++ b/spec/features/groups/dependency_proxy_for_containers_spec.rb
@@ -81,28 +81,11 @@ RSpec.describe 'Group Dependency Proxy for containers', :js do
let!(:dependency_proxy_blob) { create(:dependency_proxy_blob, group: group) }
it_behaves_like 'responds with the file'
-
- context 'dependency_proxy_workhorse feature flag disabled' do
- before do
- stub_feature_flags({ dependency_proxy_workhorse: false })
- end
-
- it_behaves_like 'responds with the file'
- end
end
end
context 'when the blob must be downloaded' do
it_behaves_like 'responds with the file'
it_behaves_like 'caches the file'
-
- context 'dependency_proxy_workhorse feature flag disabled' do
- before do
- stub_feature_flags({ dependency_proxy_workhorse: false })
- end
-
- it_behaves_like 'responds with the file'
- it_behaves_like 'caches the file'
- end
end
end
diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb
index 1bac1bcdf5a..3fc1484826c 100644
--- a/spec/features/groups/issues_spec.rb
+++ b/spec/features/groups/issues_spec.rb
@@ -156,10 +156,10 @@ RSpec.describe 'Group issues page' do
expect(page).to have_selector('.manual-ordering')
end
- it 'each issue item has a user-can-drag css applied' do
+ it 'each issue item has a gl-cursor-grab css applied' do
visit issues_group_path(group, sort: 'relative_position')
- expect(page).to have_selector('.issue.user-can-drag', count: 3)
+ expect(page).to have_selector('.issue.gl-cursor-grab', count: 3)
end
it 'issues should be draggable and persist order' do
diff --git a/spec/features/groups/labels/edit_spec.rb b/spec/features/groups/labels/edit_spec.rb
index 2be7f61eeb9..8e6560af352 100644
--- a/spec/features/groups/labels/edit_spec.rb
+++ b/spec/features/groups/labels/edit_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Edit group label' do
+ include Spec::Support::Helpers::ModalHelpers
+
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:label) { create(:group_label, group: group) }
@@ -20,4 +22,16 @@ RSpec.describe 'Edit group label' do
expect(current_path).to eq(root_path)
expect(label.reload.title).to eq('new label name')
end
+
+ it 'allows user to delete label', :js do
+ click_button 'Delete'
+
+ within_modal do
+ expect(page).to have_content("#{label.title} will be permanently deleted from #{group.name}. This cannot be undone.")
+
+ click_link 'Delete label'
+ end
+
+ expect(page).to have_content("#{label.title} deleted permanently")
+ end
end
diff --git a/spec/features/groups/labels/sort_labels_spec.rb b/spec/features/groups/labels/sort_labels_spec.rb
index b5657db23cb..df75ff7c3cb 100644
--- a/spec/features/groups/labels/sort_labels_spec.rb
+++ b/spec/features/groups/labels/sort_labels_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe 'Sort labels', :js do
expect(sort_options[1]).to eq('Name, descending')
expect(sort_options[2]).to eq('Last created')
expect(sort_options[3]).to eq('Oldest created')
- expect(sort_options[4]).to eq('Last updated')
+ expect(sort_options[4]).to eq('Updated date')
expect(sort_options[5]).to eq('Oldest updated')
click_link 'Name, descending'
diff --git a/spec/features/groups/merge_requests_spec.rb b/spec/features/groups/merge_requests_spec.rb
index 077f680629f..7541e54f014 100644
--- a/spec/features/groups/merge_requests_spec.rb
+++ b/spec/features/groups/merge_requests_spec.rb
@@ -67,7 +67,7 @@ RSpec.describe 'Group merge requests page' do
end
it 'shows projects only with merge requests feature enabled', :js do
- find('.new-project-item-link').click
+ find('.js-new-project-item-link').click
page.within('.select2-results') do
expect(page).to have_content(project.name_with_namespace)
diff --git a/spec/features/groups/navbar_spec.rb b/spec/features/groups/navbar_spec.rb
index da8032dc4dd..c5d2f5e6733 100644
--- a/spec/features/groups/navbar_spec.rb
+++ b/spec/features/groups/navbar_spec.rb
@@ -9,7 +9,8 @@ RSpec.describe 'Group navbar' do
include_context 'group navbar structure'
let_it_be(:user) { create(:user) }
- let_it_be(:group) { create(:group) }
+
+ let(:group) { create(:group) }
before do
insert_package_nav(_('Kubernetes'))
@@ -40,7 +41,9 @@ RSpec.describe 'Group navbar' do
it_behaves_like 'verified navigation bar'
end
- context 'when customer_relations feature flag is enabled' do
+ context 'when customer_relations feature and flag is enabled' do
+ let(:group) { create(:group, :crm_enabled) }
+
before do
stub_feature_flags(customer_relations: true)
diff --git a/spec/features/groups/packages_spec.rb b/spec/features/groups/packages_spec.rb
index 3c2ade6b274..26338b03349 100644
--- a/spec/features/groups/packages_spec.rb
+++ b/spec/features/groups/packages_spec.rb
@@ -42,6 +42,9 @@ RSpec.describe 'Group Packages' do
let_it_be(:maven_package) { create(:maven_package, project: second_project, name: 'aaa', created_at: 2.days.ago, version: '2.0.0') }
let_it_be(:packages) { [npm_package, maven_package] }
+ let(:package) { packages.first }
+ let(:package_details_path) { group_package_path(group, package) }
+
it_behaves_like 'packages list', check_project_name: true
it_behaves_like 'package details link'
diff --git a/spec/features/groups/settings/access_tokens_spec.rb b/spec/features/groups/settings/access_tokens_spec.rb
new file mode 100644
index 00000000000..20787c4c2f5
--- /dev/null
+++ b/spec/features/groups/settings/access_tokens_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Group > Settings > Access Tokens', :js do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:bot_user) { create(:user, :project_bot) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:resource_settings_access_tokens_path) { group_settings_access_tokens_path(group) }
+
+ before_all do
+ group.add_owner(user)
+ end
+
+ before do
+ stub_feature_flags(bootstrap_confirmation_modals: false)
+ sign_in(user)
+ end
+
+ def create_resource_access_token
+ group.add_maintainer(bot_user)
+
+ create(:personal_access_token, user: bot_user)
+ end
+
+ context 'when user is not a group owner' do
+ before do
+ group.add_maintainer(user)
+ end
+
+ it_behaves_like 'resource access tokens missing access rights'
+ end
+
+ describe 'token creation' do
+ it_behaves_like 'resource access tokens creation', 'group'
+
+ context 'when token creation is not allowed' do
+ it_behaves_like 'resource access tokens creation disallowed', 'Group access token creation is disabled in this group. You can still use and manage existing tokens.'
+ end
+ end
+
+ describe 'active tokens' do
+ let!(:resource_access_token) { create_resource_access_token }
+
+ it_behaves_like 'active resource access tokens'
+ end
+
+ describe 'inactive tokens' do
+ let!(:resource_access_token) { create_resource_access_token }
+
+ it_behaves_like 'inactive resource access tokens', 'This group has no active access tokens.'
+ end
+end
diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb
index 9c11b84fa8f..19f60ce55d3 100644
--- a/spec/features/groups_spec.rb
+++ b/spec/features/groups_spec.rb
@@ -171,6 +171,28 @@ RSpec.describe 'Group' do
expect(page).not_to have_css('.recaptcha')
end
end
+
+ describe 'showing personalization questions on group creation when it is enabled' do
+ before do
+ stub_application_setting(hide_third_party_offers: false)
+ visit new_group_path(anchor: 'create-group-pane')
+ end
+
+ it 'renders personalization questions' do
+ expect(page).to have_content('Now, personalize your GitLab experience')
+ end
+ end
+
+ describe 'not showing personalization questions on group creation when it is enabled' do
+ before do
+ stub_application_setting(hide_third_party_offers: true)
+ visit new_group_path(anchor: 'create-group-pane')
+ end
+
+ it 'does not render personalization questions' do
+ expect(page).not_to have_content('Now, personalize your GitLab experience')
+ end
+ end
end
describe 'create a nested group', :js do
diff --git a/spec/features/help_dropdown_spec.rb b/spec/features/help_dropdown_spec.rb
new file mode 100644
index 00000000000..db98f58240d
--- /dev/null
+++ b/spec/features/help_dropdown_spec.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe "Help Dropdown", :js do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:admin) { create(:admin) }
+
+ before do
+ stub_application_setting(version_check_enabled: true)
+ end
+
+ context 'when logged in as non-admin' do
+ before do
+ sign_in(user)
+ visit root_path
+ end
+
+ it 'does not render version data' do
+ page.within '.header-help' do
+ find('.header-help-dropdown-toggle').click
+
+ expect(page).not_to have_text('Your GitLab Version')
+ expect(page).not_to have_text("#{Gitlab.version_info.major}.#{Gitlab.version_info.minor}")
+ expect(page).not_to have_selector('.version-check-badge')
+ expect(page).not_to have_text('Up to date')
+ end
+ end
+ end
+
+ context 'when logged in as admin' do
+ before do
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
+ end
+
+ describe 'does render version data' do
+ where(:response, :ui_text) do
+ [
+ [{ "severity" => "success" }, 'Up to date'],
+ [{ "severity" => "warning" }, 'Update available'],
+ [{ "severity" => "danger" }, 'Update ASAP']
+ ]
+ end
+
+ with_them do
+ before do
+ allow_next_instance_of(VersionCheck) do |instance|
+ allow(instance).to receive(:response).and_return(response)
+ end
+ visit root_path
+ end
+
+ it 'renders correct version badge variant' do
+ page.within '.header-help' do
+ find('.header-help-dropdown-toggle').click
+
+ expect(page).to have_text('Your GitLab Version')
+ expect(page).to have_text("#{Gitlab.version_info.major}.#{Gitlab.version_info.minor}")
+ expect(page).to have_selector('.version-check-badge')
+ expect(page).to have_text(ui_text)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/features/help_pages_spec.rb b/spec/features/help_pages_spec.rb
index a1e2990202c..546257b9f10 100644
--- a/spec/features/help_pages_spec.rb
+++ b/spec/features/help_pages_spec.rb
@@ -28,21 +28,20 @@ RSpec.describe 'Help Pages' do
end
end
- context 'in a production environment with version check enabled' do
+ describe 'with version check enabled' do
+ let_it_be(:user) { create(:user) }
+
before do
stub_application_setting(version_check_enabled: true)
+ allow(User).to receive(:single_user).and_return(double(user, requires_usage_stats_consent?: false))
+ allow(user).to receive(:can_read_all_resources?).and_return(true)
- stub_rails_env('production')
- allow(VersionCheck).to receive(:image_url).and_return('/version-check-url')
-
- sign_in(create(:user))
+ sign_in(user)
visit help_path
end
- it 'has a version check image' do
- # Check `data-src` due to lazy image loading
- expect(find('.js-version-status-badge', visible: false)['data-src'])
- .to end_with('/version-check-url')
+ it 'renders the version check badge' do
+ expect(page).to have_selector('.js-gitlab-version-check')
end
end
diff --git a/spec/features/issuables/sorting_list_spec.rb b/spec/features/issuables/sorting_list_spec.rb
index f646cdbd71b..bc40fb713ac 100644
--- a/spec/features/issuables/sorting_list_spec.rb
+++ b/spec/features/issuables/sorting_list_spec.rb
@@ -54,10 +54,10 @@ RSpec.describe 'Sort Issuable List' do
context 'in the "merge requests / merged" tab', :js do
let(:issuable_type) { :merged_merge_request }
- it 'is "last updated"' do
+ it 'is "updated date"' do
visit_merge_requests_with_state(project, 'merged')
- expect(page).to have_button 'Last updated'
+ expect(page).to have_button 'Updated date'
expect(first_merge_request).to include(last_updated_issuable.title)
expect(last_merge_request).to include(first_updated_issuable.title)
end
@@ -66,10 +66,10 @@ RSpec.describe 'Sort Issuable List' do
context 'in the "merge requests / closed" tab', :js do
let(:issuable_type) { :closed_merge_request }
- it 'is "last updated"' do
+ it 'is "updated date"' do
visit_merge_requests_with_state(project, 'closed')
- expect(page).to have_button 'Last updated'
+ expect(page).to have_button 'Updated date'
expect(first_merge_request).to include(last_updated_issuable.title)
expect(last_merge_request).to include(first_updated_issuable.title)
end
@@ -95,7 +95,7 @@ RSpec.describe 'Sort Issuable List' do
visit_merge_requests_with_state(project, 'open')
click_button('Created date')
- click_link('Last updated')
+ click_link('Updated date')
expect(first_merge_request).to include(last_updated_issuable.title)
expect(last_merge_request).to include(first_updated_issuable.title)
@@ -152,10 +152,10 @@ RSpec.describe 'Sort Issuable List' do
context 'in the "issues / closed" tab', :js do
let(:issuable_type) { :closed_issue }
- it 'is "last updated"' do
+ it 'is "updated date"' do
visit_issues_with_state(project, 'closed')
- expect(page).to have_button 'Last updated'
+ expect(page).to have_button 'Updated date'
expect(first_issue).to include(last_updated_issuable.title)
expect(last_issue).to include(first_updated_issuable.title)
end
@@ -195,7 +195,7 @@ RSpec.describe 'Sort Issuable List' do
visit_issues_with_state(project, 'opened')
click_button('Created date')
- click_on('Last updated')
+ click_on('Updated date')
expect(page).to have_css('.issue:first-child', text: last_updated_issuable.title)
expect(page).to have_css('.issue:last-child', text: first_updated_issuable.title)
diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb
index 9da6694c681..868946814c3 100644
--- a/spec/features/issues/issue_sidebar_spec.rb
+++ b/spec/features/issues/issue_sidebar_spec.rb
@@ -8,10 +8,9 @@ RSpec.describe 'Issue Sidebar' do
let_it_be(:group) { create(:group, :nested) }
let_it_be(:project) { create(:project, :public, namespace: group) }
let_it_be(:user) { create(:user) }
- let_it_be(:label) { create(:label, project: project, title: 'bug') }
- let_it_be(:issue) { create(:labeled_issue, project: project, labels: [label]) }
+ let_it_be(:issue) { create(:issue, project: project) }
+ let_it_be(:label) { create(:label, project: project, name: 'Label') }
let_it_be(:mock_date) { Date.today.at_beginning_of_month + 2.days }
- let_it_be(:xss_label) { create(:label, project: project, title: '&lt;script&gt;alert("xss");&lt;&#x2F;script&gt;') }
before do
stub_incoming_email_setting(enabled: true, address: "p+%{key}@gl.ab")
@@ -223,14 +222,6 @@ RSpec.describe 'Issue Sidebar' do
restore_window_size
open_issue_sidebar
end
-
- it 'escapes XSS when viewing issue labels' do
- page.within('.block.labels') do
- click_on 'Edit'
-
- expect(page).to have_content '<script>alert("xss");</script>'
- end
- end
end
context 'editing issue milestone', :js do
@@ -242,62 +233,7 @@ RSpec.describe 'Issue Sidebar' do
end
context 'editing issue labels', :js do
- before do
- issue.update!(labels: [label])
- page.within('.block.labels') do
- click_on 'Edit'
- end
- end
-
- it 'shows the current set of labels' do
- page.within('.issuable-show-labels') do
- expect(page).to have_content label.title
- end
- end
-
- it 'shows option to create a project label' do
- page.within('.block.labels') do
- expect(page).to have_content 'Create project'
- end
- end
-
- context 'creating a project label', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/27992' do
- before do
- page.within('.block.labels') do
- click_link 'Create project'
- end
- end
-
- it 'shows dropdown switches to "create label" section' do
- page.within('.block.labels') do
- expect(page).to have_content 'Create project label'
- end
- end
-
- it 'adds new label' do
- page.within('.block.labels') do
- fill_in 'new_label_name', with: 'wontfix'
- page.find('.suggest-colors a', match: :first).click
- page.find('button', text: 'Create').click
-
- page.within('.dropdown-page-one') do
- expect(page).to have_content 'wontfix'
- end
- end
- end
-
- it 'shows error message if label title is taken' do
- page.within('.block.labels') do
- fill_in 'new_label_name', with: label.title
- page.find('.suggest-colors a', match: :first).click
- page.find('button', text: 'Create').click
-
- page.within('.dropdown-page-two') do
- expect(page).to have_content 'Title has already been taken'
- end
- end
- end
- end
+ it_behaves_like 'labels sidebar widget'
end
context 'interacting with collapsed sidebar', :js do
diff --git a/spec/features/issues/service_desk_spec.rb b/spec/features/issues/service_desk_spec.rb
index 0a879fdd4d4..cc0d35afd60 100644
--- a/spec/features/issues/service_desk_spec.rb
+++ b/spec/features/issues/service_desk_spec.rb
@@ -9,8 +9,6 @@ RSpec.describe 'Service Desk Issue Tracker', :js do
let_it_be(:support_bot) { User.support_bot }
before do
- stub_feature_flags(vue_issuables_list: true)
-
# The following two conditions equate to Gitlab::ServiceDesk.supported == true
allow(Gitlab::IncomingEmail).to receive(:enabled?).and_return(true)
allow(Gitlab::IncomingEmail).to receive(:supports_wildcard?).and_return(true)
diff --git a/spec/features/issues/user_bulk_edits_issues_spec.rb b/spec/features/issues/user_bulk_edits_issues_spec.rb
index 44c23813e3c..625303f89e4 100644
--- a/spec/features/issues/user_bulk_edits_issues_spec.rb
+++ b/spec/features/issues/user_bulk_edits_issues_spec.rb
@@ -104,6 +104,26 @@ RSpec.describe 'Multiple issue updating from issues#index', :js do
end
end
+ describe 'select all issues' do
+ let!(:issue_2) { create(:issue, project: project) }
+
+ before do
+ stub_feature_flags(vue_issues_list: true)
+ end
+
+ it 'after selecting all issues, unchecking one issue only unselects that one issue' do
+ visit project_issues_path(project)
+
+ click_button 'Edit issues'
+ check 'Select all'
+ uncheck issue.title
+
+ expect(page).to have_unchecked_field 'Select all'
+ expect(page).to have_unchecked_field issue.title
+ expect(page).to have_checked_field issue_2.title
+ end
+ end
+
def create_closed
create(:issue, project: project, state: :closed)
end
diff --git a/spec/features/issues/user_comments_on_issue_spec.rb b/spec/features/issues/user_comments_on_issue_spec.rb
index 09d3ad15641..5d03aa1fc2b 100644
--- a/spec/features/issues/user_comments_on_issue_spec.rb
+++ b/spec/features/issues/user_comments_on_issue_spec.rb
@@ -11,6 +11,7 @@ RSpec.describe "User comments on issue", :js do
before do
stub_feature_flags(tribute_autocomplete: false)
+ stub_feature_flags(sandboxed_mermaid: false)
project.add_guest(user)
sign_in(user)
@@ -49,7 +50,7 @@ RSpec.describe "User comments on issue", :js do
add_note(comment)
- expect(page.find('svg.mermaid')).to have_content html_content
+ expect(page.find('svg.mermaid')).not_to have_content 'javascript'
within('svg.mermaid') { expect(page).not_to have_selector('img') }
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 6e8b3e4fb7c..875b0a60634 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
@@ -217,7 +217,7 @@ RSpec.describe 'User creates branch and merge request on issue page', :js do
# Javascript debounces AJAX calls.
# So we have to wait until AJAX requests are started.
- # Details are in app/assets/javascripts/create_merge_request_dropdown.js
+ # Details are in app/assets/javascripts/issues/create_merge_request_dropdown.js
# this.refDebounce = _.debounce(...)
sleep 0.5
diff --git a/spec/features/issues/user_scrolls_to_deeplinked_note_spec.rb b/spec/features/issues/user_scrolls_to_deeplinked_note_spec.rb
new file mode 100644
index 00000000000..1fa8f533869
--- /dev/null
+++ b/spec/features/issues/user_scrolls_to_deeplinked_note_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'User scrolls to deep-linked note' do
+ let_it_be(:project) { create(:project, :public, :repository) }
+ let_it_be(:issue) { create(:issue, project: project) }
+ let_it_be(:comment_1) { create(:note_on_issue, noteable: issue, project: project, note: 'written first') }
+ let_it_be(:comments) { create_list(:note_on_issue, 20, noteable: issue, project: project, note: 'spacer note') }
+
+ context 'on issue page', :js do
+ it 'on comment' do
+ visit project_issue_path(project, issue, anchor: "note_#{comment_1.id}")
+
+ wait_for_requests
+
+ expect(first_comment).to have_content(comment_1.note)
+
+ bottom_of_title = find('.issue-sticky-header.gl-fixed').evaluate_script("this.getBoundingClientRect().bottom;")
+ top = first_comment.evaluate_script("this.getBoundingClientRect().top;")
+
+ expect(top).to be_within(1).of(bottom_of_title)
+ end
+ end
+
+ def all_comments
+ all('.timeline > .note.timeline-entry')
+ end
+
+ def first_comment
+ all_comments.first
+ end
+end
diff --git a/spec/features/issues/user_sees_breadcrumb_links_spec.rb b/spec/features/issues/user_sees_breadcrumb_links_spec.rb
index 9f8cd2a769d..669c7c45411 100644
--- a/spec/features/issues/user_sees_breadcrumb_links_spec.rb
+++ b/spec/features/issues/user_sees_breadcrumb_links_spec.rb
@@ -8,8 +8,6 @@ RSpec.describe 'New issue breadcrumb' do
let(:user) { project.creator }
before do
- stub_feature_flags(vue_issuables_list: false)
-
sign_in(user)
visit(new_project_issue_path(project))
end
diff --git a/spec/features/markdown/copy_as_gfm_spec.rb b/spec/features/markdown/copy_as_gfm_spec.rb
index d3aaf339421..0e5a20fe24a 100644
--- a/spec/features/markdown/copy_as_gfm_spec.rb
+++ b/spec/features/markdown/copy_as_gfm_spec.rb
@@ -7,6 +7,10 @@ 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
diff --git a/spec/features/markdown/mermaid_spec.rb b/spec/features/markdown/mermaid_spec.rb
index e080c7ffb3f..6a91d4e03c1 100644
--- a/spec/features/markdown/mermaid_spec.rb
+++ b/spec/features/markdown/mermaid_spec.rb
@@ -5,6 +5,10 @@ require 'spec_helper'
RSpec.describe 'Mermaid rendering', :js do
let_it_be(:project) { create(:project, :public) }
+ before do
+ stub_feature_flags(sandboxed_mermaid: false)
+ end
+
it 'renders Mermaid diagrams correctly' do
description = <<~MERMAID
```mermaid
diff --git a/spec/features/markdown/sandboxed_mermaid_spec.rb b/spec/features/markdown/sandboxed_mermaid_spec.rb
new file mode 100644
index 00000000000..f118fb3db66
--- /dev/null
+++ b/spec/features/markdown/sandboxed_mermaid_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Sandboxed Mermaid rendering', :js do
+ let_it_be(:project) { create(:project, :public) }
+
+ before do
+ stub_feature_flags(sandboxed_mermaid: true)
+ end
+
+ it 'includes mermaid frame correctly' do
+ description = <<~MERMAID
+ ```mermaid
+ graph TD;
+ A-->B;
+ A-->C;
+ B-->D;
+ C-->D;
+ ```
+ MERMAID
+
+ issue = create(:issue, project: project, description: description)
+
+ visit project_issue_path(project, issue)
+
+ wait_for_requests
+
+ expected = %(<iframe src="/-/sandbox/mermaid" sandbox="allow-scripts" frameborder="0" scrolling="no")
+ expect(page.html).to include(expected)
+ 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 0117cf01e53..8761ee89463 100644
--- a/spec/features/merge_request/user_sees_merge_widget_spec.rb
+++ b/spec/features/merge_request/user_sees_merge_widget_spec.rb
@@ -96,7 +96,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
context 'view merge request with external CI service' do
before do
- create(:service, project: project,
+ create(:integration, project: project,
active: true,
type: 'DroneCiService',
category: 'ci')
diff --git a/spec/features/password_reset_spec.rb b/spec/features/password_reset_spec.rb
index 31b2b2d15aa..322ccc6a0c0 100644
--- a/spec/features/password_reset_spec.rb
+++ b/spec/features/password_reset_spec.rb
@@ -44,8 +44,8 @@ RSpec.describe 'Password reset' do
visit(edit_user_password_path(reset_password_token: token))
- fill_in 'New password', with: 'hello1234'
- fill_in 'Confirm new password', with: 'hello1234'
+ fill_in 'New password', with: "new" + Gitlab::Password.test_default
+ fill_in 'Confirm new password', with: "new" + Gitlab::Password.test_default
click_button 'Change your password'
diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb
index 24ba55994ae..34eb07d78f1 100644
--- a/spec/features/profile_spec.rb
+++ b/spec/features/profile_spec.rb
@@ -29,7 +29,7 @@ RSpec.describe 'Profile account page', :js do
it 'deletes user', :js, :sidekiq_might_not_need_inline do
click_button 'Delete account'
- fill_in 'password', with: '12345678'
+ fill_in 'password', with: Gitlab::Password.test_default
page.within '.modal' do
click_button 'Delete account'
@@ -62,66 +62,33 @@ RSpec.describe 'Profile account page', :js do
end
end
- describe 'when I reset feed token' do
- it 'resets feed token with `hide_access_tokens` feature flag enabled' do
- visit profile_personal_access_tokens_path
+ it 'allows resetting of feed token' do
+ visit profile_personal_access_tokens_path
- within('[data-testid="feed-token-container"]') do
- previous_token = find_field('Feed token').value
+ within('[data-testid="feed-token-container"]') do
+ previous_token = find_field('Feed token').value
- accept_confirm { click_link('reset this token') }
+ accept_confirm { click_link('reset this token') }
- click_button('Click to reveal')
+ click_button('Click to reveal')
- expect(find_field('Feed token').value).not_to eq(previous_token)
- end
- end
-
- it 'resets feed token with `hide_access_tokens` feature flag disabled' do
- stub_feature_flags(hide_access_tokens: false)
- visit profile_personal_access_tokens_path
-
- within('.feed-token-reset') do
- previous_token = find("#feed_token").value
-
- accept_confirm { find('[data-testid="reset_feed_token_link"]').click }
-
- expect(find('#feed_token').value).not_to eq(previous_token)
- end
+ expect(find_field('Feed token').value).not_to eq(previous_token)
end
end
- describe 'when I reset incoming email token' do
- before do
- allow(Gitlab.config.incoming_email).to receive(:enabled).and_return(true)
- stub_feature_flags(bootstrap_confirmation_modals: false)
- end
-
- it 'resets incoming email token with `hide_access_tokens` feature flag enabled' do
- visit profile_personal_access_tokens_path
-
- within('[data-testid="incoming-email-token-container"]') do
- previous_token = find_field('Incoming email token').value
-
- accept_confirm { click_link('reset this token') }
+ it 'allows resetting of incoming email token' do
+ allow(Gitlab.config.incoming_email).to receive(:enabled).and_return(true)
- click_button('Click to reveal')
+ visit profile_personal_access_tokens_path
- expect(find_field('Incoming email token').value).not_to eq(previous_token)
- end
- end
+ within('[data-testid="incoming-email-token-container"]') do
+ previous_token = find_field('Incoming email token').value
- it 'resets incoming email token with `hide_access_tokens` feature flag disabled' do
- stub_feature_flags(hide_access_tokens: false)
- visit profile_personal_access_tokens_path
+ accept_confirm { click_link('reset this token') }
- within('.incoming-email-token-reset') do
- previous_token = find('#incoming_email_token').value
+ click_button('Click to reveal')
- accept_confirm { find('[data-testid="reset_email_token_link"]').click }
-
- expect(find('#incoming_email_token').value).not_to eq(previous_token)
- end
+ expect(find_field('Incoming email token').value).not_to eq(previous_token)
end
end
diff --git a/spec/features/profiles/chat_names_spec.rb b/spec/features/profiles/chat_names_spec.rb
index 6270fa7347d..b392d8dfa8e 100644
--- a/spec/features/profiles/chat_names_spec.rb
+++ b/spec/features/profiles/chat_names_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe 'Profile > Chat' do
let(:user) { create(:user) }
- let(:integration) { create(:service) }
+ let(:integration) { create(:integration) }
before do
sign_in(user)
diff --git a/spec/features/profiles/emails_spec.rb b/spec/features/profiles/emails_spec.rb
index 8f05de60be9..24917412826 100644
--- a/spec/features/profiles/emails_spec.rb
+++ b/spec/features/profiles/emails_spec.rb
@@ -44,7 +44,7 @@ RSpec.describe 'Profile > Emails' do
end
it 'does not add an invalid email' do
- fill_in('Email', with: 'test.@example.com')
+ fill_in('Email', with: 'test@@example.com')
click_button('Add email address')
email = user.emails.find_by(email: email)
diff --git a/spec/features/profiles/keys_spec.rb b/spec/features/profiles/keys_spec.rb
index c1e2d19ad9a..b9e59a0239b 100644
--- a/spec/features/profiles/keys_spec.rb
+++ b/spec/features/profiles/keys_spec.rb
@@ -32,10 +32,10 @@ RSpec.describe 'Profile > SSH Keys' do
expect(find('.breadcrumbs-sub-title')).to have_link(attrs[:title])
end
- it 'shows a confirmable warning if the key does not start with ssh-' do
+ it 'shows a confirmable warning if the key begins with an algorithm name that is unsupported' do
attrs = attributes_for(:key)
- fill_in('Key', with: 'invalid-key')
+ fill_in('Key', with: 'unsupported-ssh-rsa key')
fill_in('Title', with: attrs[:title])
click_button('Add key')
diff --git a/spec/features/profiles/password_spec.rb b/spec/features/profiles/password_spec.rb
index 7059697354d..25fe43617fd 100644
--- a/spec/features/profiles/password_spec.rb
+++ b/spec/features/profiles/password_spec.rb
@@ -39,7 +39,7 @@ RSpec.describe 'Profile > Password' do
describe 'User puts the same passwords in the field and in the confirmation' do
it 'shows a success message' do
- fill_passwords('mypassword', 'mypassword')
+ fill_passwords(Gitlab::Password.test_default, Gitlab::Password.test_default)
page.within('.flash-notice') do
expect(page).to have_content('Password was successfully updated. Please sign in again.')
@@ -79,7 +79,7 @@ RSpec.describe 'Profile > Password' do
end
context 'Change password' do
- let(:new_password) { '22233344' }
+ let(:new_password) { "new" + Gitlab::Password.test_default }
before do
sign_in(user)
@@ -170,8 +170,8 @@ RSpec.describe 'Profile > Password' do
expect(current_path).to eq new_profile_password_path
fill_in :user_password, with: user.password
- fill_in :user_new_password, with: '12345678'
- fill_in :user_password_confirmation, with: '12345678'
+ 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
diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb
index 135a940807e..f1e5658cd7b 100644
--- a/spec/features/profiles/personal_access_tokens_spec.rb
+++ b/spec/features/profiles/personal_access_tokens_spec.rb
@@ -132,7 +132,7 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
describe "feed token" do
context "when enabled" do
- it "displays feed token with `hide_access_tokens` feature flag enabled" do
+ it "displays feed token" do
allow(Gitlab::CurrentSettings).to receive(:disable_feed_token).and_return(false)
visit profile_personal_access_tokens_path
@@ -143,15 +143,6 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
expect(page).to have_content(feed_token_description)
end
end
-
- it "displays feed token with `hide_access_tokens` feature flag disabled" do
- stub_feature_flags(hide_access_tokens: false)
- allow(Gitlab::CurrentSettings).to receive(:disable_feed_token).and_return(false)
- visit profile_personal_access_tokens_path
-
- expect(page).to have_field('Feed token', with: user.feed_token)
- expect(page).to have_content(feed_token_description)
- end
end
context "when disabled" do
diff --git a/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb b/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb
index 1a368676a5e..11e2d24c36a 100644
--- a/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb
+++ b/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb
@@ -34,26 +34,23 @@ RSpec.describe 'Blob button line permalinks (BlobLinePermalinkUpdater)', :js do
end
it 'changes fragment hash if line number clicked' do
- ending_fragment = "L5"
-
visit_blob
find('#L3').click
- find("##{ending_fragment}").click
+ find("#L5").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)))
+ expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(project_blob_path(project, tree_join(sha, path), anchor: "LC5")))
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
+ find("#L5").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)))
+ expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(project_blob_path(project, tree_join(sha, path), anchor: "LC5")))
end
end
@@ -73,26 +70,23 @@ RSpec.describe 'Blob button line permalinks (BlobLinePermalinkUpdater)', :js do
end
it 'changes fragment hash if line number clicked' do
- ending_fragment = "L5"
-
visit_blob
find('#L3').click
- find("##{ending_fragment}").click
+ find("#L5").click
- expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path), anchor: ending_fragment)))
+ expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path), anchor: "LC5")))
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
+ find("#L5").click
- expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path), anchor: ending_fragment)))
+ expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path), anchor: "LC5")))
end
end
end
diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb
index 9d05c985af1..62994d19fc0 100644
--- a/spec/features/projects/blobs/blob_show_spec.rb
+++ b/spec/features/projects/blobs/blob_show_spec.rb
@@ -29,6 +29,10 @@ RSpec.describe 'File blob', :js do
).execute
end
+ before do
+ stub_feature_flags(refactor_blob_viewer: false) # This stub will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/350455
+ end
+
context 'Ruby file' do
before do
visit_blob('files/ruby/popen.rb')
diff --git a/spec/features/projects/branches/user_deletes_branch_spec.rb b/spec/features/projects/branches/user_deletes_branch_spec.rb
index 8fc5c3d2e1b..0d08e7ea10d 100644
--- a/spec/features/projects/branches/user_deletes_branch_spec.rb
+++ b/spec/features/projects/branches/user_deletes_branch_spec.rb
@@ -32,28 +32,4 @@ RSpec.describe "User deletes branch", :js do
expect(page).to have_content('Branch was deleted')
end
-
- context 'when the feature flag :delete_branch_confirmation_modals is disabled' do
- before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
- stub_feature_flags(delete_branch_confirmation_modals: false)
- end
-
- it "deletes branch" do
- visit(project_branches_path(project))
-
- branch_search = find('input[data-testid="branch-search"]')
-
- branch_search.set('improve/awesome')
- branch_search.native.send_keys(:enter)
-
- page.within(".js-branch-improve\\/awesome") do
- accept_alert { click_link(title: 'Delete branch') }
- end
-
- wait_for_requests
-
- expect(page).to have_css(".js-branch-improve\\/awesome", visible: :hidden)
- end
- end
end
diff --git a/spec/features/projects/branches_spec.rb b/spec/features/projects/branches_spec.rb
index 2725c6a91be..363d08da024 100644
--- a/spec/features/projects/branches_spec.rb
+++ b/spec/features/projects/branches_spec.rb
@@ -117,7 +117,7 @@ RSpec.describe 'Branches' do
it 'sorts the branches by name', :js do
visit project_branches_filtered_path(project, state: 'all')
- click_button "Last updated" # Open sorting dropdown
+ click_button "Updated date" # Open sorting dropdown
within '[data-testid="branches-dropdown"]' do
find('p', text: 'Name').click
end
@@ -128,7 +128,7 @@ RSpec.describe 'Branches' do
it 'sorts the branches by oldest updated', :js do
visit project_branches_filtered_path(project, state: 'all')
- click_button "Last updated" # Open sorting dropdown
+ click_button "Updated date" # Open sorting dropdown
within '[data-testid="branches-dropdown"]' do
find('p', text: 'Oldest updated').click
end
@@ -175,26 +175,6 @@ RSpec.describe 'Branches' do
expect(page).not_to have_content('fix')
expect(all('.all-branches').last).to have_selector('li', count: 0)
end
-
- context 'when the delete_branch_confirmation_modals feature flag is disabled' do
- it 'removes branch after confirmation', :js do
- stub_feature_flags(delete_branch_confirmation_modals: false)
- stub_feature_flags(bootstrap_confirmation_modals: false)
-
- visit project_branches_filtered_path(project, state: 'all')
-
- search_for_branch('fix')
-
- expect(page).to have_content('fix')
- expect(find('.all-branches')).to have_selector('li', count: 1)
- accept_confirm do
- within('.js-branch-item', match: :first) { click_link(title: 'Delete branch') }
- end
-
- expect(page).not_to have_content('fix')
- expect(find('.all-branches')).to have_selector('li', count: 0)
- end
- end
end
context 'on project with 0 branch' do
diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb
index 6e88cbf52b5..0c9db24f1d8 100644
--- a/spec/features/projects/clusters/gcp_spec.rb
+++ b/spec/features/projects/clusters/gcp_spec.rb
@@ -219,7 +219,7 @@ RSpec.describe 'Gcp Cluster', :js do
it 'user does not see the offer' do
page.within('.as-third-party-offers') do
click_button 'Expand'
- check 'Do not display offers from third parties'
+ check 'Do not display content for customer experience improvement and offers from third parties'
click_button 'Save changes'
end
diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb
index bcbf2f46f79..d88ff5c1aa5 100644
--- a/spec/features/projects/environments/environment_spec.rb
+++ b/spec/features/projects/environments/environment_spec.rb
@@ -342,24 +342,6 @@ RSpec.describe 'Environment' do
expect(page).not_to have_button('Stop')
end
- context 'when the feature flag :delete_branch_confirmation_modals is disabled' do
- before do
- stub_feature_flags(delete_branch_confirmation_modals: false)
- end
-
- it 'user deletes the branch with running environment' do
- visit project_branches_filtered_path(project, state: 'all', search: 'feature')
-
- remove_branch_with_hooks(project, user, 'feature') do
- within('.js-branch-feature') { click_link(title: 'Delete branch') }
- end
-
- visit_environment(environment)
-
- expect(page).not_to have_button('Stop')
- end
- end
-
##
# This is a workaround for problem described in #24543
#
diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb
index a7e773dda2d..23fcc1fe444 100644
--- a/spec/features/projects/features_visibility_spec.rb
+++ b/spec/features/projects/features_visibility_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe 'Edit Project Settings' do
# disable by clicking toggle
toggle_feature_off("project[project_feature_attributes][#{tool_name}_access_level]")
page.within('.sharing-permissions') do
- find('input[value="Save changes"]').click
+ find('[data-testid="project-features-save-button"]').click
end
wait_for_requests
expect(page).not_to have_selector(".shortcuts-#{shortcut_name}")
@@ -32,7 +32,7 @@ RSpec.describe 'Edit Project Settings' do
# re-enable by clicking toggle again
toggle_feature_on("project[project_feature_attributes][#{tool_name}_access_level]")
page.within('.sharing-permissions') do
- find('input[value="Save changes"]').click
+ find('[data-testid="project-features-save-button"]').click
end
wait_for_requests
expect(page).to have_selector(".shortcuts-#{shortcut_name}")
diff --git a/spec/features/projects/files/user_browses_files_spec.rb b/spec/features/projects/files/user_browses_files_spec.rb
index 4e9e129042c..508dec70db6 100644
--- a/spec/features/projects/files/user_browses_files_spec.rb
+++ b/spec/features/projects/files/user_browses_files_spec.rb
@@ -340,6 +340,7 @@ RSpec.describe "User browses files" do
let(:newrev) { project.repository.commit('master').sha }
before do
+ stub_feature_flags(refactor_blob_viewer: false) # This stub will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/350456
create_file_in_repo(project, 'master', 'master', filename, 'Test file')
path = File.join('master', filename)
@@ -355,6 +356,7 @@ RSpec.describe "User browses files" do
context "when browsing a raw file" do
before do
+ stub_feature_flags(refactor_blob_viewer: false) # This stub will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/350456
path = File.join(RepoHelpers.sample_commit.id, RepoHelpers.sample_blob.path)
visit(project_blob_path(project, path))
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 3be5ab64834..17699847704 100644
--- a/spec/features/projects/files/user_browses_lfs_files_spec.rb
+++ b/spec/features/projects/files/user_browses_lfs_files_spec.rb
@@ -35,7 +35,7 @@ RSpec.describe 'Projects > Files > User browses LFS files' do
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)'
+ expect(page).not_to have_content 'Download (1.50 MiB)'
end
end
@@ -56,7 +56,7 @@ RSpec.describe 'Projects > Files > User browses LFS files' do
click_link('lfs')
click_link('lfs_object.iso')
- expect(page).to have_content('Download (1.5 MB)')
+ expect(page).to have_content('Download (1.50 MiB)')
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')
@@ -88,7 +88,7 @@ RSpec.describe 'Projects > Files > User browses LFS files' do
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_selector(:link_or_button, 'Edit')
+ expect(page).not_to have_css('button[data-testid="edit"')
end
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 b6e300e9e59..c508b2ddba9 100644
--- a/spec/features/projects/files/user_deletes_files_spec.rb
+++ b/spec/features/projects/files/user_deletes_files_spec.rb
@@ -15,6 +15,7 @@ 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
diff --git a/spec/features/projects/files/user_edits_files_spec.rb b/spec/features/projects/files/user_edits_files_spec.rb
index 453cc14c267..2b4ac3dc1d8 100644
--- a/spec/features/projects/files/user_edits_files_spec.rb
+++ b/spec/features/projects/files/user_edits_files_spec.rb
@@ -150,7 +150,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do
expect_fork_prompt
- click_link_or_button('Fork project')
+ click_link_or_button('Fork')
expect_fork_status
@@ -169,7 +169,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do
expect_fork_prompt
- click_link_or_button('Fork project')
+ click_link_or_button('Fork')
expect_fork_status
@@ -183,7 +183,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do
click_link_or_button('Edit')
expect_fork_prompt
- click_link_or_button('Fork project')
+ click_link_or_button('Fork')
find('.file-editor', match: :first)
@@ -214,7 +214,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do
click_link('.gitignore')
click_link_or_button('Edit')
- expect(page).not_to have_link('Fork project')
+ expect(page).not_to have_link('Fork')
find('#editor')
set_editor_value('*.rbca')
diff --git a/spec/features/projects/files/user_replaces_files_spec.rb b/spec/features/projects/files/user_replaces_files_spec.rb
index c9b472260bd..fe9520fffc8 100644
--- a/spec/features/projects/files/user_replaces_files_spec.rb
+++ b/spec/features/projects/files/user_replaces_files_spec.rb
@@ -17,6 +17,7 @@ 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
diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb
index 3afd1937652..2fbec4e22f4 100644
--- a/spec/features/projects/import_export/import_file_spec.rb
+++ b/spec/features/projects/import_export/import_file_spec.rb
@@ -10,12 +10,11 @@ RSpec.describe 'Import/Export - project import integration test', :js do
let(:export_path) { "#{Dir.tmpdir}/import_file_spec" }
before do
- stub_feature_flags(paginatable_namespace_drop_down_for_project_creation: false)
stub_uploads_object_storage(FileUploader)
allow_next_instance_of(Gitlab::ImportExport) do |instance|
allow(instance).to receive(:storage_path).and_return(export_path)
end
- gitlab_sign_in(user)
+ sign_in(user)
end
after do
diff --git a/spec/features/projects/integrations/user_activates_jira_spec.rb b/spec/features/projects/integrations/user_activates_jira_spec.rb
index 7a035248440..50010950f0e 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 service' do
expect(page).to have_content('Jira settings saved and active.')
- expect(current_path).to eq(edit_project_service_path(project, :jira))
+ expect(current_path).to eq(edit_project_integration_path(project, :jira))
end
unless Gitlab.ee?
@@ -41,7 +41,7 @@ RSpec.describe 'User activates Jira', :js do
fill_in 'service_password', with: 'password'
click_test_integration
- page.within('.service-settings') do
+ page.within('[data-testid="integration-settings-form"]') do
expect(page).to have_content('This field is required.')
end
end
@@ -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_service_path(project, :jira))
+ expect(current_path).to eq(edit_project_integration_path(project, :jira))
end
end
end
@@ -72,7 +72,7 @@ RSpec.describe 'User activates Jira', :js do
it 'saves but does not activate the Jira service' do
expect(page).to have_content('Jira settings saved, but not active.')
- expect(current_path).to eq(edit_project_service_path(project, :jira))
+ expect(current_path).to eq(edit_project_integration_path(project, :jira))
end
it 'does not show the Jira link in the menu' do
diff --git a/spec/features/projects/labels/sort_labels_spec.rb b/spec/features/projects/labels/sort_labels_spec.rb
index 83559b816d2..26b3d08253c 100644
--- a/spec/features/projects/labels/sort_labels_spec.rb
+++ b/spec/features/projects/labels/sort_labels_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe 'Sort labels', :js do
expect(sort_options[1]).to eq('Name, descending')
expect(sort_options[2]).to eq('Last created')
expect(sort_options[3]).to eq('Oldest created')
- expect(sort_options[4]).to eq('Last updated')
+ expect(sort_options[4]).to eq('Updated date')
expect(sort_options[5]).to eq('Oldest updated')
click_link 'Name, descending'
diff --git a/spec/features/projects/labels/user_edits_labels_spec.rb b/spec/features/projects/labels/user_edits_labels_spec.rb
index 8300a1a8542..999c238c7b3 100644
--- a/spec/features/projects/labels/user_edits_labels_spec.rb
+++ b/spec/features/projects/labels/user_edits_labels_spec.rb
@@ -3,6 +3,8 @@
require "spec_helper"
RSpec.describe "User edits labels" do
+ include Spec::Support::Helpers::ModalHelpers
+
let_it_be(:project) { create(:project_empty_repo, :public) }
let_it_be(:label) { create(:label, project: project) }
let_it_be(:user) { create(:user) }
@@ -24,4 +26,16 @@ RSpec.describe "User edits labels" do
expect(page).to have_content(new_title).and have_no_content(label.title)
end
end
+
+ it 'allows user to delete label', :js do
+ click_button 'Delete'
+
+ within_modal do
+ expect(page).to have_content("#{label.title} will be permanently deleted from #{project.name}. This cannot be undone.")
+
+ click_link 'Delete label'
+ end
+
+ expect(page).to have_content('Label was removed')
+ end
end
diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb
index 4dedd5689de..f1786c1be40 100644
--- a/spec/features/projects/new_project_spec.rb
+++ b/spec/features/projects/new_project_spec.rb
@@ -6,10 +6,6 @@ RSpec.describe 'New project', :js do
include Select2Helper
include Spec::Support::Helpers::Features::TopNavSpecHelpers
- before do
- stub_feature_flags(paginatable_namespace_drop_down_for_project_creation: false)
- end
-
context 'as a user' do
let(:user) { create(:user) }
@@ -179,7 +175,7 @@ RSpec.describe 'New project', :js do
it 'does not show the initialize with Readme checkbox on "Import project" tab' do
visit new_project_path
click_link 'Import project'
- first('.js-import-git-toggle-button').click
+ click_button 'Repo by URL'
page.within '#import-project-pane' do
expect(page).not_to have_css('input#project_initialize_with_readme')
@@ -196,9 +192,7 @@ RSpec.describe 'New project', :js do
end
it 'selects the user namespace' do
- page.within('#blank-project-pane') do
- expect(page).to have_select('project[namespace_id]', visible: false, selected: user.username)
- end
+ expect(page).to have_button user.username
end
end
@@ -212,9 +206,7 @@ RSpec.describe 'New project', :js do
end
it 'selects the group namespace' do
- page.within('#blank-project-pane') do
- expect(page).to have_select('project[namespace_id]', visible: false, selected: group.name)
- end
+ expect(page).to have_button group.name
end
end
@@ -229,9 +221,7 @@ RSpec.describe 'New project', :js do
end
it 'selects the group namespace' do
- page.within('#blank-project-pane') do
- expect(page).to have_select('project[namespace_id]', visible: false, selected: subgroup.full_path)
- end
+ expect(page).to have_button subgroup.full_path
end
end
@@ -249,22 +239,30 @@ RSpec.describe 'New project', :js do
end
it 'enables the correct visibility options' do
- select2(user.namespace_id, from: '#project_namespace_id')
+ click_button public_group.full_path
+ click_button user.username
+
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).not_to be_disabled
- select2(public_group.id, from: '#project_namespace_id')
+ click_button user.username
+ click_button public_group.full_path
+
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).not_to be_disabled
- select2(internal_group.id, from: '#project_namespace_id')
+ click_button public_group.full_path
+ click_button internal_group.full_path
+
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).to be_disabled
- select2(private_group.id, from: '#project_namespace_id')
+ click_button internal_group.full_path
+ click_button private_group.full_path
+
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).to be_disabled
@@ -355,9 +353,7 @@ RSpec.describe 'New project', :js do
end
it 'selects the group namespace' do
- page.within('#blank-project-pane') do
- expect(page).to have_select('project[namespace_id]', visible: false, selected: group.full_path)
- end
+ expect(page).to have_button group.full_path
end
end
end
diff --git a/spec/features/projects/packages_spec.rb b/spec/features/projects/packages_spec.rb
index 7fcc8200b1c..8180f6b9aff 100644
--- a/spec/features/projects/packages_spec.rb
+++ b/spec/features/projects/packages_spec.rb
@@ -35,6 +35,9 @@ RSpec.describe 'Packages' do
let_it_be(:maven_package) { create(:maven_package, project: project, name: 'aaa', created_at: 2.days.ago, version: '2.0.0') }
let_it_be(:packages) { [npm_package, maven_package] }
+ let(:package) { packages.first }
+ let(:package_details_path) { project_package_path(project, package) }
+
it_behaves_like 'packages list'
it_behaves_like 'package details link'
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index 6ddc8e43762..5176a7ec5a1 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -1020,6 +1020,103 @@ RSpec.describe 'Pipeline', :js do
end
end
+ describe 'GET /:project/-/pipelines/:id/builds with jobs_tab_vue feature flag turned on' 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
+ 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_button('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="retry"]', match: :first).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 '[data-testid="jobs-tab-table"]' do
+ click_button('Play')
+
+ wait_for_requests
+ end
+ end
+
+ it { expect(build_manual.reload).to be_pending }
+ end
+
+ context 'when user unschedules a delayed job' do
+ before do
+ within '[data-testid="jobs-tab-table"]' do
+ click_button('Unschedule')
+ end
+ end
+
+ it 'unschedules the delayed job and shows play button as a manual job' do
+ expect(page).to have_button('Play')
+ expect(page).not_to have_button('Unschedule')
+ end
+ end
+ end
+
describe 'GET /:project/-/pipelines/:id/failures' do
let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: '1234') }
let(:pipeline_failures_page) { failures_project_pipeline_path(project, pipeline) }
diff --git a/spec/features/projects/services/user_activates_issue_tracker_spec.rb b/spec/features/projects/services/user_activates_issue_tracker_spec.rb
index 019d50a497b..27c23e7beb5 100644
--- a/spec/features/projects/services/user_activates_issue_tracker_spec.rb
+++ b/spec/features/projects/services/user_activates_issue_tracker_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe 'User activates issue tracker', :js do
it 'activates the service' do
expect(page).to have_content("#{tracker} settings saved and active.")
- expect(current_path).to eq(edit_project_service_path(project, tracker.parameterize(separator: '_')))
+ expect(current_path).to eq(edit_project_integration_path(project, tracker.parameterize(separator: '_')))
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_service_path(project, tracker.parameterize(separator: '_')))
+ expect(current_path).to eq(edit_project_integration_path(project, tracker.parameterize(separator: '_')))
end
end
end
@@ -73,7 +73,7 @@ RSpec.describe 'User activates issue tracker', :js do
it 'saves but does not activate the service' do
expect(page).to have_content("#{tracker} settings saved, but not active.")
- expect(current_path).to eq(edit_project_service_path(project, tracker.parameterize(separator: '_')))
+ expect(current_path).to eq(edit_project_integration_path(project, tracker.parameterize(separator: '_')))
end
it 'does not show the external tracker link in the menu' do
diff --git a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb
index b2ca0424b6d..74919a99f04 100644
--- a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb
+++ b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe 'Set up Mattermost slash commands', :js do
let(:mattermost_enabled) { true }
describe 'activation' do
- let(:edit_path) { edit_project_service_path(project, :mattermost_slash_commands) }
+ let(:edit_path) { edit_project_integration_path(project, :mattermost_slash_commands) }
include_examples 'user activates the Mattermost Slash Command integration'
end
diff --git a/spec/features/projects/services/user_activates_slack_notifications_spec.rb b/spec/features/projects/services/user_activates_slack_notifications_spec.rb
index d5fe8b083ba..38b6ad84c77 100644
--- a/spec/features/projects/services/user_activates_slack_notifications_spec.rb
+++ b/spec/features/projects/services/user_activates_slack_notifications_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe 'User activates Slack notifications', :js do
pipeline_channel: 6,
wiki_page_channel: 7)
- visit(edit_project_service_path(project, integration))
+ visit(edit_project_integration_path(project, integration))
end
it 'filters events by channel' do
diff --git a/spec/features/projects/services/user_activates_slack_slash_command_spec.rb b/spec/features/projects/services/user_activates_slack_slash_command_spec.rb
index bc84ccaa432..d46d1f739b7 100644
--- a/spec/features/projects/services/user_activates_slack_slash_command_spec.rb
+++ b/spec/features/projects/services/user_activates_slack_slash_command_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe 'Slack slash commands', :js do
click_active_checkbox
click_on 'Save'
- expect(current_path).to eq(edit_project_service_path(project, :slack_slash_commands))
+ expect(current_path).to eq(edit_project_integration_path(project, :slack_slash_commands))
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_service_path(project, :slack_slash_commands))
+ expect(current_path).to eq(edit_project_integration_path(project, :slack_slash_commands))
expect(page).to have_content('Slack slash commands settings saved and active.')
end
diff --git a/spec/features/projects/settings/access_tokens_spec.rb b/spec/features/projects/settings/access_tokens_spec.rb
index d8de9e0449e..122bf267021 100644
--- a/spec/features/projects/settings/access_tokens_spec.rb
+++ b/spec/features/projects/settings/access_tokens_spec.rb
@@ -7,6 +7,7 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do
let_it_be(:bot_user) { create(:user, :project_bot) }
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, group: group) }
+ let_it_be(:resource_settings_access_tokens_path) { project_settings_access_tokens_path(project) }
before_all do
project.add_maintainer(user)
@@ -17,78 +18,25 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do
sign_in(user)
end
- def create_project_access_token
+ def create_resource_access_token
project.add_maintainer(bot_user)
create(:personal_access_token, user: bot_user)
end
- def active_project_access_tokens
- find('.table.active-tokens')
- end
-
- def no_project_access_tokens_message
- find('.settings-message')
- end
-
- def created_project_access_token
- find('#created-personal-access-token').value
- end
-
context 'when user is not a project maintainer' do
before do
project.add_developer(user)
end
- it 'does not show project access token page' do
- visit project_settings_access_tokens_path(project)
-
- expect(page).to have_content("Page Not Found")
- end
+ it_behaves_like 'resource access tokens missing access rights'
end
describe 'token creation' do
- it 'allows creation of a project access token' do
- name = 'My project access token'
-
- visit project_settings_access_tokens_path(project)
- fill_in 'Token name', with: name
-
- # Set date to 1st of next month
- find_field('Expiration date').click
- find('.pika-next').click
- click_on '1'
-
- # Scopes
- check 'api'
- check 'read_api'
-
- click_on 'Create project access token'
-
- expect(active_project_access_tokens).to have_text(name)
- expect(active_project_access_tokens).to have_text('in')
- expect(active_project_access_tokens).to have_text('api')
- expect(active_project_access_tokens).to have_text('read_api')
- expect(active_project_access_tokens).to have_text('Maintainer')
- expect(created_project_access_token).not_to be_empty
- end
+ it_behaves_like 'resource access tokens creation', 'project'
context 'when token creation is not allowed' do
- before do
- group.namespace_settings.update_column(:resource_access_token_creation_allowed, false)
- end
-
- it 'does not show project access token creation form' do
- visit project_settings_access_tokens_path(project)
-
- expect(page).not_to have_selector('#new_project_access_token')
- end
-
- it 'shows project access token creation disabled text' do
- visit project_settings_access_tokens_path(project)
-
- expect(page).to have_text('Project access token creation is disabled in this group. You can still use and manage existing tokens.')
- end
+ it_behaves_like 'resource access tokens creation disallowed', 'Project access token creation is disabled in this group. You can still use and manage existing tokens.'
context 'with a project in a personal namespace' do
let(:personal_project) { create(:project) }
@@ -97,113 +45,25 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do
personal_project.add_maintainer(user)
end
- it 'shows project access token creation form and text' do
+ it 'shows access token creation form and text' do
visit project_settings_access_tokens_path(personal_project)
- expect(page).to have_selector('#new_project_access_token')
+ expect(page).to have_selector('#new_resource_access_token')
expect(page).to have_text('Generate project access tokens scoped to this project for your applications that need access to the GitLab API.')
end
end
-
- context 'group settings link' do
- context 'when user is not a group owner' do
- before do
- group.add_developer(user)
- end
-
- it 'does not show group settings link' do
- visit project_settings_access_tokens_path(project)
-
- expect(page).not_to have_link('group settings', href: edit_group_path(group))
- end
- end
-
- context 'with nested groups' do
- let(:subgroup) { create(:group, parent: group) }
-
- context 'when user is not a top level group owner' do
- before do
- subgroup.add_owner(user)
- end
-
- it 'does not show group settings link' do
- visit project_settings_access_tokens_path(project)
-
- expect(page).not_to have_link('group settings', href: edit_group_path(group))
- end
- end
- end
-
- context 'when user is a group owner' do
- before do
- group.add_owner(user)
- end
-
- it 'shows group settings link' do
- visit project_settings_access_tokens_path(project)
-
- expect(page).to have_link('group settings', href: edit_group_path(group))
- end
- end
- end
end
end
describe 'active tokens' do
- let!(:project_access_token) { create_project_access_token }
+ let!(:resource_access_token) { create_resource_access_token }
- it 'shows active project access tokens' do
- visit project_settings_access_tokens_path(project)
-
- expect(active_project_access_tokens).to have_text(project_access_token.name)
- end
-
- context 'when User#time_display_relative is false' do
- before do
- user.update!(time_display_relative: false)
- end
-
- it 'shows absolute times for expires_at' do
- visit project_settings_access_tokens_path(project)
-
- expect(active_project_access_tokens).to have_text(PersonalAccessToken.last.expires_at.strftime('%b %-d'))
- end
- end
+ it_behaves_like 'active resource access tokens'
end
describe 'inactive tokens' do
- let!(:project_access_token) { create_project_access_token }
-
- no_active_tokens_text = 'This project has no active access tokens.'
+ let!(:resource_access_token) { create_resource_access_token }
- it 'allows revocation of an active token' do
- visit project_settings_access_tokens_path(project)
- accept_confirm { click_on 'Revoke' }
-
- expect(page).to have_selector('.settings-message')
- expect(no_project_access_tokens_message).to have_text(no_active_tokens_text)
- end
-
- it 'removes expired tokens from active section' do
- project_access_token.update!(expires_at: 5.days.ago)
- visit project_settings_access_tokens_path(project)
-
- expect(page).to have_selector('.settings-message')
- expect(no_project_access_tokens_message).to have_text(no_active_tokens_text)
- end
-
- context 'when resource access token creation is not allowed' do
- before do
- group.namespace_settings.update_column(:resource_access_token_creation_allowed, false)
- end
-
- it 'allows revocation of an active token' do
- visit project_settings_access_tokens_path(project)
- accept_confirm { click_on 'Revoke' }
-
- expect(page).to have_selector('.settings-message')
- expect(no_project_access_tokens_message).to have_text(no_active_tokens_text)
- end
- end
+ it_behaves_like 'inactive resource access tokens', 'This project has no active access tokens.'
end
end
diff --git a/spec/features/projects/settings/project_settings_spec.rb b/spec/features/projects/settings/project_settings_spec.rb
index 71b319d192c..b67caa5a5f9 100644
--- a/spec/features/projects/settings/project_settings_spec.rb
+++ b/spec/features/projects/settings/project_settings_spec.rb
@@ -47,7 +47,7 @@ RSpec.describe 'Projects settings' do
# disable by clicking toggle
forking_enabled_button.click
page.within('.sharing-permissions') do
- find('input[value="Save changes"]').click
+ find('[data-testid="project-features-save-button"]').click
end
wait_for_requests
@@ -77,7 +77,7 @@ RSpec.describe 'Projects settings' do
expect(default_award_emojis_input.value).to eq('false')
page.within('.sharing-permissions') do
- find('input[value="Save changes"]').click
+ find('[data-testid="project-features-save-button"]').click
end
wait_for_requests
diff --git a/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb
index 862bae45fc6..77be351f3d8 100644
--- a/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb
+++ b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb
@@ -54,7 +54,7 @@ RSpec.describe 'Projects > Settings > User manages merge request settings' do
within('.sharing-permissions-form') do
find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .gl-toggle').click
- find('input[value="Save changes"]').send_keys(:return)
+ find('[data-testid="project-features-save-button"]').send_keys(:return)
end
expect(page).not_to have_content 'Pipelines must succeed'
@@ -74,7 +74,7 @@ RSpec.describe 'Projects > Settings > User manages merge request settings' do
within('.sharing-permissions-form') do
find('.project-feature-controls[data-for="project[project_feature_attributes][builds_access_level]"] .gl-toggle').click
- find('input[value="Save changes"]').send_keys(:return)
+ find('[data-testid="project-features-save-button"]').send_keys(:return)
end
expect(page).to have_content 'Pipelines must succeed'
@@ -95,7 +95,7 @@ RSpec.describe 'Projects > Settings > User manages merge request settings' do
within('.sharing-permissions-form') do
find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .gl-toggle').click
- find('input[value="Save changes"]').send_keys(:return)
+ find('[data-testid="project-features-save-button"]').send_keys(:return)
end
expect(page).to have_content 'Pipelines must succeed'
diff --git a/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb b/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb
index dc551158895..89f6b4237a4 100644
--- a/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb
+++ b/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb
@@ -316,7 +316,7 @@ RSpec.describe 'Projects > Show > User sees setup shortcut buttons' do
visit project_path(project)
page.within('.project-buttons') do
- expect(page).to have_link('Add Kubernetes cluster', href: new_project_cluster_path(project))
+ expect(page).to have_link('Add Kubernetes cluster', href: project_clusters_path(project))
end
end
diff --git a/spec/features/projects/user_changes_project_visibility_spec.rb b/spec/features/projects/user_changes_project_visibility_spec.rb
index 345d16982fd..68fed9b8a74 100644
--- a/spec/features/projects/user_changes_project_visibility_spec.rb
+++ b/spec/features/projects/user_changes_project_visibility_spec.rb
@@ -5,14 +5,6 @@ require 'spec_helper'
RSpec.describe 'User changes public project visibility', :js do
include ProjectForksHelper
- before do
- fork_project(project, project.owner)
-
- sign_in(project.owner)
-
- visit edit_project_path(project)
- end
-
shared_examples 'changing visibility to private' do
it 'requires confirmation' do
visibility_select = first('.project-feature-controls .select-control')
@@ -22,7 +14,7 @@ RSpec.describe 'User changes public project visibility', :js do
click_button 'Save changes'
end
- find('.js-legacy-confirm-danger-input').send_keys(project.path_with_namespace)
+ fill_in 'confirm_name_input', with: project.path_with_namespace
page.within '.modal' do
click_button 'Reduce project visibility'
@@ -34,15 +26,85 @@ RSpec.describe 'User changes public project visibility', :js do
end
end
- context 'when a project is public' do
+ shared_examples 'does not require confirmation' do
+ it 'saves without confirmation' do
+ visibility_select = first('.project-feature-controls .select-control')
+ visibility_select.select('Private')
+
+ page.within('#js-shared-permissions') do
+ click_button 'Save changes'
+ end
+
+ wait_for_requests
+
+ expect(project.reload).to be_private
+ end
+ end
+
+ context 'when the project has forks' do
+ before do
+ fork_project(project, project.owner)
+
+ sign_in(project.owner)
+
+ visit edit_project_path(project)
+ end
+
+ context 'when a project is public' do
+ let(:project) { create(:project, :empty_repo, :public) }
+
+ it_behaves_like 'changing visibility to private'
+ end
+
+ context 'when the project is internal' do
+ let(:project) { create(:project, :empty_repo, :internal) }
+
+ it_behaves_like 'changing visibility to private'
+ end
+
+ context 'when the visibility level is untouched' do
+ let(:project) { create(:project, :empty_repo, :public) }
+
+ it 'saves without confirmation' do
+ expect(page).to have_selector('.js-emails-disabled', visible: true)
+ find('.js-emails-disabled input[type="checkbox"]').click
+
+ page.within('#js-shared-permissions') do
+ click_button 'Save changes'
+ end
+
+ wait_for_requests
+
+ expect(project.reload).to be_public
+ end
+ end
+ end
+
+ context 'when the project is not forked' do
let(:project) { create(:project, :empty_repo, :public) }
- it_behaves_like 'changing visibility to private'
+ before do
+ sign_in(project.owner)
+
+ visit edit_project_path(project)
+ end
+
+ it_behaves_like 'does not require confirmation'
end
- context 'when the project is internal' do
- let(:project) { create(:project, :empty_repo, :internal) }
+ context 'with unlink_fork_network_upon_visibility_decrease = false' do
+ let(:project) { create(:project, :empty_repo, :public) }
+
+ before do
+ stub_feature_flags(unlink_fork_network_upon_visibility_decrease: false)
+
+ fork_project(project, project.owner)
+
+ sign_in(project.owner)
+
+ visit edit_project_path(project)
+ end
- it_behaves_like 'changing visibility to private'
+ it_behaves_like 'does not require confirmation'
end
end
diff --git a/spec/features/projects/user_creates_project_spec.rb b/spec/features/projects/user_creates_project_spec.rb
index 17c65e645f4..c4e2e3353a4 100644
--- a/spec/features/projects/user_creates_project_spec.rb
+++ b/spec/features/projects/user_creates_project_spec.rb
@@ -6,7 +6,6 @@ RSpec.describe 'User creates a project', :js do
let(:user) { create(:user) }
before do
- stub_feature_flags(paginatable_namespace_drop_down_for_project_creation: false)
sign_in(user)
create(:personal_key, user: user)
end
@@ -44,9 +43,7 @@ RSpec.describe 'User creates a project', :js do
expect(page).to have_checked_field 'Initialize repository with a README'
expect(page).to have_checked_field 'Enable Static Application Security Testing (SAST)'
- page.within('#content-body') do
- click_button('Create project')
- end
+ click_button('Create project')
project = Project.last
@@ -96,12 +93,10 @@ RSpec.describe 'User creates a project', :js do
fill_in :project_name, with: 'A Subgroup Project'
fill_in :project_path, with: 'a-subgroup-project'
- page.find('.js-select-namespace').click
- page.find("div[role='option']", text: subgroup.full_path).click
+ click_button user.username
+ click_button subgroup.full_path
- page.within('#content-body') do
- click_button('Create project')
- end
+ click_button('Create project')
expect(page).to have_content("Project 'A Subgroup Project' was successfully created")
@@ -125,8 +120,8 @@ RSpec.describe 'User creates a project', :js do
fill_in :project_name, with: 'a-new-project'
fill_in :project_path, with: 'a-new-project'
- page.find('.js-select-namespace').click
- page.find("div[role='option']", text: group.full_path).click
+ click_button user.username
+ click_button group.full_path
page.within('#content-body') do
click_button('Create project')
diff --git a/spec/features/projects/user_sorts_projects_spec.rb b/spec/features/projects/user_sorts_projects_spec.rb
index 6a5ed49f1a6..71e43467a39 100644
--- a/spec/features/projects/user_sorts_projects_spec.rb
+++ b/spec/features/projects/user_sorts_projects_spec.rb
@@ -41,10 +41,10 @@ RSpec.describe 'User sorts projects and order persists' do
sign_in(user)
visit(explore_projects_path)
find('#sort-projects-dropdown').click
- first(:link, 'Last updated').click
+ first(:link, 'Updated date').click
end
- it_behaves_like "sort order persists across all views", "Last updated", "Last updated"
+ it_behaves_like "sort order persists across all views", 'Updated date', 'Updated date'
end
context 'from dashboard projects' do
diff --git a/spec/features/projects/view_on_env_spec.rb b/spec/features/projects/view_on_env_spec.rb
index d220db01c24..94085b075aa 100644
--- a/spec/features/projects/view_on_env_spec.rb
+++ b/spec/features/projects/view_on_env_spec.rb
@@ -9,6 +9,7 @@ RSpec.describe 'View on environment', :js do
let(:user) { project.creator }
before do
+ stub_feature_flags(refactor_blob_viewer: false) # This stub will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/350457
project.add_maintainer(user)
end
@@ -48,26 +49,6 @@ RSpec.describe 'View on environment', :js do
let(:environment) { create(:environment, project: project, name: 'review/feature', external_url: 'http://feature.review.example.com') }
let!(:deployment) { create(:deployment, :success, environment: environment, ref: branch_name, sha: sha) }
- context 'when visiting the diff of a merge request for the branch' do
- let(:merge_request) { create(:merge_request, :simple, source_project: project, source_branch: branch_name) }
-
- before do
- sign_in(user)
-
- visit diffs_project_merge_request_path(project, merge_request)
-
- wait_for_requests
- end
-
- it 'has a "View on env" button' do
- within '.diffs' do
- text = 'View on feature.review.example.com'
- url = 'http://feature.review.example.com/ruby/feature'
- expect(page).to have_selector("a[title='#{text}'][href='#{url}']")
- end
- end
- end
-
context 'when visiting a comparison for the branch' do
before do
sign_in(user)
diff --git a/spec/features/protected_branches_spec.rb b/spec/features/protected_branches_spec.rb
index 15ec11c256f..4278efc5a8f 100644
--- a/spec/features/protected_branches_spec.rb
+++ b/spec/features/protected_branches_spec.rb
@@ -29,21 +29,6 @@ RSpec.describe 'Protected Branches', :js do
expect(page).to have_button('Only a project maintainer or owner can delete a protected branch', disabled: true)
end
-
- context 'when feature flag :delete_branch_confirmation_modals is disabled' do
- before do
- stub_feature_flags(delete_branch_confirmation_modals: false)
- end
-
- it 'does not allow developer to remove protected branch' do
- visit project_branches_path(project)
-
- find('input[data-testid="branch-search"]').set('fix')
- find('input[data-testid="branch-search"]').native.send_keys(:enter)
-
- expect(page).to have_selector('button[data-testid="remove-protected-branch"][disabled]')
- end
- end
end
end
@@ -79,32 +64,6 @@ RSpec.describe 'Protected Branches', :js do
expect(page).to have_content('No branches to show')
end
-
- context 'when the feature flag :delete_branch_confirmation_modals is disabled' do
- before do
- stub_feature_flags(delete_branch_confirmation_modals: false)
- end
-
- it 'removes branch after modal confirmation' do
- visit project_branches_path(project)
-
- find('input[data-testid="branch-search"]').set('fix')
- find('input[data-testid="branch-search"]').native.send_keys(:enter)
-
- expect(page).to have_content('fix')
- expect(find('.all-branches')).to have_selector('li', count: 1)
- page.find('[data-target="#modal-delete-branch"]').click
-
- expect(page).to have_css('.js-delete-branch[disabled]')
- fill_in 'delete_branch_input', with: 'fix'
- click_link 'Delete protected branch'
-
- find('input[data-testid="branch-search"]').set('fix')
- find('input[data-testid="branch-search"]').native.send_keys(:enter)
-
- expect(page).to have_content('No branches to show')
- end
- end
end
end
diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb
index 22de77f7cd0..49c468976b9 100644
--- a/spec/features/runners_spec.rb
+++ b/spec/features/runners_spec.rb
@@ -268,10 +268,27 @@ RSpec.describe 'Runners' do
it 'group runners are not available' do
visit project_runners_path(project)
+ expect(page).not_to have_content 'Group owners can register group runners in the group\'s CI/CD settings.'
+ expect(page).to have_content 'Ask your group owner to set up a group runner'
+ end
+ end
+ end
+
+ context 'as project maintainer and group owner' do
+ before do
+ group.add_owner(user)
+ end
+
+ context 'project with a group but no group runner' do
+ let(:project) { create :project, group: group }
+
+ it 'group runners are available' do
+ visit project_runners_path(project)
+
expect(page).to have_content 'This group does not have any group runners yet.'
- expect(page).to have_content 'Group maintainers can register group runners in the group\'s CI/CD settings.'
- expect(page).not_to have_content 'Ask your group maintainer to set up a group runner'
+ expect(page).to have_content 'Group owners can register group runners in the group\'s CI/CD settings.'
+ expect(page).not_to have_content 'Ask your group owner to set up a group runner'
end
end
end
@@ -296,8 +313,8 @@ RSpec.describe 'Runners' do
expect(page).to have_content 'This group does not have any group runners yet.'
- expect(page).not_to have_content 'Group maintainers can register group runners in the group\'s CI/CD settings.'
- expect(page).to have_content 'Ask your group maintainer to set up a group runner.'
+ expect(page).not_to have_content 'Group owners can register group runners in the group\'s CI/CD settings.'
+ expect(page).to have_content 'Ask your group owner to set up a group runner.'
end
end
diff --git a/spec/features/user_sees_marketing_header_spec.rb b/spec/features/user_sees_marketing_header_spec.rb
new file mode 100644
index 00000000000..31f088ce010
--- /dev/null
+++ b/spec/features/user_sees_marketing_header_spec.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe 'User sees experimental lmarketing header' do
+ let_it_be(:project) { create(:project, :public) }
+
+ context 'when not logged in' do
+ context 'when experiment candidate' do
+ it 'shows marketing header links', :aggregate_failures do
+ stub_experiments(logged_out_marketing_header: :candidate)
+
+ visit project_path(project)
+
+ expect(page).to have_text "About GitLab"
+ expect(page).to have_text "Pricing"
+ expect(page).to have_text "Talk to an expert"
+ expect(page).to have_text "Sign up now"
+ expect(page).to have_text "Login"
+ end
+ end
+
+ context 'when experiment candidate (trial focused variant)' do
+ it 'shows marketing header links', :aggregate_failures do
+ stub_experiments(logged_out_marketing_header: :trial_focused)
+
+ visit project_path(project)
+
+ expect(page).to have_text "About GitLab"
+ expect(page).to have_text "Pricing"
+ expect(page).to have_text "Talk to an expert"
+ expect(page).to have_text "Get a free trial"
+ expect(page).to have_text "Sign up"
+ expect(page).to have_text "Login"
+ end
+ end
+
+ context 'when experiment control' do
+ it 'does not show marketing header links', :aggregate_failures do
+ stub_experiments(logged_out_marketing_header: :control)
+
+ visit project_path(project)
+
+ expect(page).not_to have_text "About GitLab"
+ expect(page).not_to have_text "Pricing"
+ expect(page).not_to have_text "Talk to an expert"
+ expect(page).not_to have_text "Sign up now"
+ expect(page).not_to have_text "Login"
+ expect(page).not_to have_text "Get a free trial"
+ expect(page).not_to have_text "Sign up"
+ expect(page).to have_text "Sign in / Register"
+ end
+ end
+ end
+
+ context 'when logged in' do
+ it 'does not show marketing header links', :aggregate_failures do
+ sign_in(create(:user))
+
+ stub_experiments(logged_out_marketing_header: :candidate)
+
+ visit project_path(project)
+
+ expect(page).not_to have_text "About GitLab"
+ expect(page).not_to have_text "Pricing"
+ expect(page).not_to have_text "Talk to an expert"
+ end
+ end
+end
diff --git a/spec/features/user_sorts_things_spec.rb b/spec/features/user_sorts_things_spec.rb
index 6eaa620b538..8e6f6a96bd2 100644
--- a/spec/features/user_sorts_things_spec.rb
+++ b/spec/features/user_sorts_things_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe "User sorts things" do
end
it "issues -> project home page -> issues" do
- sort_option = "Last updated"
+ sort_option = 'Updated date'
visit(project_issues_path(project))
@@ -34,7 +34,7 @@ RSpec.describe "User sorts things" do
end
it "issues -> merge requests" do
- sort_option = "Last updated"
+ sort_option = 'Updated date'
visit(project_issues_path(project))
@@ -46,7 +46,7 @@ RSpec.describe "User sorts things" do
end
it "merge requests -> dashboard merge requests" do
- sort_option = "Last updated"
+ sort_option = 'Updated date'
visit(project_merge_requests_path(project))
diff --git a/spec/features/users/anonymous_sessions_spec.rb b/spec/features/users/anonymous_sessions_spec.rb
index 6b21412ae3d..f9b23626397 100644
--- a/spec/features/users/anonymous_sessions_spec.rb
+++ b/spec/features/users/anonymous_sessions_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe 'Session TTLs', :clean_gitlab_redis_shared_state do
visit new_user_session_path
# The session key only gets created after a post
fill_in 'user_login', with: 'non-existant@gitlab.org'
- fill_in 'user_password', with: '12345678'
+ fill_in 'user_password', with: Gitlab::Password.test_default
click_button 'Sign in'
expect(page).to have_content('Invalid login or password')
diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb
index 7ef11194ff9..2780549eea1 100644
--- a/spec/features/users/login_spec.rb
+++ b/spec/features/users/login_spec.rb
@@ -49,15 +49,15 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
expect(current_path).to eq edit_user_password_path
expect(page).to have_content('Please create a password for your new account.')
- fill_in 'user_password', with: 'password'
- fill_in 'user_password_confirmation', with: 'password'
+ 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_content(I18n.t('devise.passwords.updated_not_active'))
fill_in 'user_login', with: user.username
- fill_in 'user_password', with: 'password'
+ fill_in 'user_password', with: Gitlab::Password.test_default
click_button 'Sign in'
expect_single_session_with_authenticated_ttl
@@ -210,7 +210,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
end
it 'does not allow sign-in if the user password is updated before entering a one-time code' do
- user.update!(password: 'new_password')
+ user.update!(password: "new" + Gitlab::Password.test_default)
enter_code(user.current_otp)
@@ -447,7 +447,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
visit new_user_session_path
fill_in 'user_login', with: user.email
- fill_in 'user_password', with: '12345678'
+ fill_in 'user_password', with: Gitlab::Password.test_default
click_button 'Sign in'
expect(current_path).to eq(new_profile_password_path)
@@ -456,7 +456,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
end
context 'with invalid username and password' do
- let(:user) { create(:user, password: 'not-the-default') }
+ let(:user) { create(:user, password: "not" + Gitlab::Password.test_default) }
it 'blocks invalid login' do
expect(authentication_metrics)
@@ -767,7 +767,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
visit new_user_session_path
fill_in 'user_login', with: user.email
- fill_in 'user_password', with: '12345678'
+ fill_in 'user_password', with: Gitlab::Password.test_default
click_button 'Sign in'
@@ -788,7 +788,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
visit new_user_session_path
fill_in 'user_login', with: user.email
- fill_in 'user_password', with: '12345678'
+ fill_in 'user_password', with: Gitlab::Password.test_default
click_button 'Sign in'
@@ -809,7 +809,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
visit new_user_session_path
fill_in 'user_login', with: user.email
- fill_in 'user_password', with: '12345678'
+ fill_in 'user_password', with: Gitlab::Password.test_default
click_button 'Sign in'
@@ -844,7 +844,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
visit new_user_session_path
fill_in 'user_login', with: user.email
- fill_in 'user_password', with: '12345678'
+ fill_in 'user_password', with: Gitlab::Password.test_default
click_button 'Sign in'
fill_in 'user_otp_attempt', with: user.reload.current_otp
@@ -870,7 +870,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
visit new_user_session_path
fill_in 'user_login', with: user.email
- fill_in 'user_password', with: '12345678'
+ fill_in 'user_password', with: Gitlab::Password.test_default
click_button 'Sign in'
expect_to_be_on_terms_page
@@ -878,7 +878,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
expect(current_path).to eq(new_profile_password_path)
- fill_in 'user_password', with: '12345678'
+ fill_in 'user_password', with: Gitlab::Password.test_default
fill_in 'user_new_password', with: 'new password'
fill_in 'user_password_confirmation', with: 'new password'
click_button 'Set new password'
diff --git a/spec/finders/ci/runners_finder_spec.rb b/spec/finders/ci/runners_finder_spec.rb
index 7e3c1abd6d1..dac244e4300 100644
--- a/spec/finders/ci/runners_finder_spec.rb
+++ b/spec/finders/ci/runners_finder_spec.rb
@@ -206,7 +206,7 @@ RSpec.describe Ci::RunnersFinder do
sub_group_4.runners << runner_sub_group_4
end
- describe '#execute' do
+ shared_examples '#execute' do
subject { described_class.new(current_user: user, params: params).execute }
shared_examples 'membership equal to :descendants' do
@@ -349,6 +349,16 @@ RSpec.describe Ci::RunnersFinder do
end
end
+ it_behaves_like '#execute'
+
+ context 'when the FF ci_find_runners_by_ci_mirrors is disabled' do
+ before do
+ stub_feature_flags(ci_find_runners_by_ci_mirrors: false)
+ end
+
+ it_behaves_like '#execute'
+ end
+
describe '#sort_key' do
subject { described_class.new(current_user: user, params: params.merge(group: group)).sort_key }
diff --git a/spec/finders/environments/environments_by_deployments_finder_spec.rb b/spec/finders/environments/environments_by_deployments_finder_spec.rb
index 1b86aced67d..8349092c79e 100644
--- a/spec/finders/environments/environments_by_deployments_finder_spec.rb
+++ b/spec/finders/environments/environments_by_deployments_finder_spec.rb
@@ -22,16 +22,6 @@ RSpec.describe Environments::EnvironmentsByDeploymentsFinder do
create(:deployment, :success, environment: environment_two, ref: 'v1.1.0', tag: true, sha: project.commit('HEAD~1').id)
end
- it 'returns environment when with_tags is set' do
- expect(described_class.new(project, user, ref: 'master', commit: commit, with_tags: true).execute)
- .to contain_exactly(environment, environment_two)
- end
-
- it 'does not return environment when no with_tags is set' do
- expect(described_class.new(project, user, ref: 'master', commit: commit).execute)
- .to be_empty
- end
-
it 'does not return environment when commit is not part of deployment' do
expect(described_class.new(project, user, ref: 'master', commit: project.commit('feature')).execute)
.to be_empty
@@ -41,7 +31,7 @@ RSpec.describe Environments::EnvironmentsByDeploymentsFinder do
# This tests to ensure we don't call one CommitIsAncestor per environment
it 'only calls Gitaly twice when multiple environments are present', :request_store do
expect do
- result = described_class.new(project, user, ref: 'master', commit: commit, with_tags: true, find_latest: true).execute
+ result = described_class.new(project, user, ref: 'v1.1.0', commit: commit, find_latest: true).execute
expect(result).to contain_exactly(environment_two)
end.to change { Gitlab::GitalyClient.get_request_count }.by(2)
diff --git a/spec/finders/fork_targets_finder_spec.rb b/spec/finders/fork_targets_finder_spec.rb
index 12f01227af8..fe5b50ef030 100644
--- a/spec/finders/fork_targets_finder_spec.rb
+++ b/spec/finders/fork_targets_finder_spec.rb
@@ -16,7 +16,9 @@ RSpec.describe ForkTargetsFinder do
end
let!(:developer_group) do
- create(:group).tap { |g| g.add_developer(user) }
+ create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS).tap do |g|
+ g.add_developer(user)
+ end
end
let!(:reporter_group) do
@@ -33,11 +35,11 @@ RSpec.describe ForkTargetsFinder do
describe '#execute' do
it 'returns all user manageable namespaces' do
- expect(finder.execute).to match_array([user.namespace, maintained_group, owned_group, project.namespace])
+ expect(finder.execute).to match_array([user.namespace, maintained_group, owned_group, project.namespace, developer_group])
end
it 'returns only groups when only_groups option is passed' do
- expect(finder.execute(only_groups: true)).to match_array([maintained_group, owned_group, project.namespace])
+ expect(finder.execute(only_groups: true)).to match_array([maintained_group, owned_group, project.namespace, developer_group])
end
it 'returns groups relation when only_groups option is passed' do
diff --git a/spec/finders/group_descendants_finder_spec.rb b/spec/finders/group_descendants_finder_spec.rb
index f6b87f7eeab..59eeb078e9e 100644
--- a/spec/finders/group_descendants_finder_spec.rb
+++ b/spec/finders/group_descendants_finder_spec.rb
@@ -17,262 +17,250 @@ RSpec.describe GroupDescendantsFinder do
described_class.new(current_user: user, parent_group: group, params: params)
end
- shared_examples 'group descentants finder examples' do
- describe '#has_children?' do
+ describe '#has_children?' do
+ it 'is true when there are projects' do
+ create(:project, namespace: group)
+
+ expect(finder.has_children?).to be_truthy
+ end
+
+ context 'when there are subgroups' do
it 'is true when there are projects' do
- create(:project, namespace: group)
+ create(:group, parent: group)
expect(finder.has_children?).to be_truthy
end
+ end
+ end
- context 'when there are subgroups' do
- it 'is true when there are projects' do
- create(:group, parent: group)
+ describe '#execute' do
+ it 'includes projects' do
+ project = create(:project, namespace: group)
- expect(finder.has_children?).to be_truthy
- end
- end
+ expect(finder.execute).to contain_exactly(project)
end
- describe '#execute' do
- it 'includes projects' do
+ context 'when archived is `true`' do
+ let(:params) { { archived: 'true' } }
+
+ it 'includes archived projects' do
+ archived_project = create(:project, namespace: group, archived: true)
project = create(:project, namespace: group)
- expect(finder.execute).to contain_exactly(project)
+ expect(finder.execute).to contain_exactly(archived_project, project)
end
+ end
- context 'when archived is `true`' do
- let(:params) { { archived: 'true' } }
+ context 'when archived is `only`' do
+ let(:params) { { archived: 'only' } }
- it 'includes archived projects' do
- archived_project = create(:project, namespace: group, archived: true)
- project = create(:project, namespace: group)
+ it 'includes only archived projects' do
+ archived_project = create(:project, namespace: group, archived: true)
+ _project = create(:project, namespace: group)
- expect(finder.execute).to contain_exactly(archived_project, project)
- end
+ expect(finder.execute).to contain_exactly(archived_project)
end
+ end
- context 'when archived is `only`' do
- let(:params) { { archived: 'only' } }
+ it 'does not include archived projects' do
+ _archived_project = create(:project, :archived, namespace: group)
- it 'includes only archived projects' do
- archived_project = create(:project, namespace: group, archived: true)
- _project = create(:project, namespace: group)
+ expect(finder.execute).to be_empty
+ end
- expect(finder.execute).to contain_exactly(archived_project)
- end
- end
+ context 'with a filter' do
+ let(:params) { { filter: 'test' } }
- it 'does not include archived projects' do
- _archived_project = create(:project, :archived, namespace: group)
+ it 'includes only projects matching the filter' do
+ _other_project = create(:project, namespace: group)
+ matching_project = create(:project, namespace: group, name: 'testproject')
- expect(finder.execute).to be_empty
+ expect(finder.execute).to contain_exactly(matching_project)
end
+ end
- context 'with a filter' do
- let(:params) { { filter: 'test' } }
+ it 'sorts elements by name as default' do
+ project1 = create(:project, namespace: group, name: 'z')
+ project2 = create(:project, namespace: group, name: 'a')
- it 'includes only projects matching the filter' do
- _other_project = create(:project, namespace: group)
- matching_project = create(:project, namespace: group, name: 'testproject')
+ expect(subject.execute).to match_array([project2, project1])
+ end
- expect(finder.execute).to contain_exactly(matching_project)
- end
+ context 'sorting by name' do
+ let!(:project1) { create(:project, namespace: group, name: 'a', path: 'project-a') }
+ let!(:project2) { create(:project, namespace: group, name: 'z', path: 'project-z') }
+ let(:params) do
+ {
+ sort: 'name_asc'
+ }
end
- it 'sorts elements by name as default' do
- project1 = create(:project, namespace: group, name: 'z')
- project2 = create(:project, namespace: group, name: 'a')
-
- expect(subject.execute).to match_array([project2, project1])
+ it 'sorts elements by name' do
+ expect(subject.execute).to eq(
+ [
+ project1,
+ project2
+ ]
+ )
end
- context 'sorting by name' do
- let!(:project1) { create(:project, namespace: group, name: 'a', path: 'project-a') }
- let!(:project2) { create(:project, namespace: group, name: 'z', path: 'project-z') }
- let(:params) do
- {
- sort: 'name_asc'
- }
- end
+ context 'with nested groups' do
+ let!(:subgroup1) { create(:group, parent: group, name: 'a', path: 'sub-a') }
+ let!(:subgroup2) { create(:group, parent: group, name: 'z', path: 'sub-z') }
it 'sorts elements by name' do
expect(subject.execute).to eq(
[
+ subgroup1,
+ subgroup2,
project1,
project2
]
)
end
-
- context 'with nested groups' do
- let!(:subgroup1) { create(:group, parent: group, name: 'a', path: 'sub-a') }
- let!(:subgroup2) { create(:group, parent: group, name: 'z', path: 'sub-z') }
-
- it 'sorts elements by name' do
- expect(subject.execute).to eq(
- [
- subgroup1,
- subgroup2,
- project1,
- project2
- ]
- )
- end
- end
end
+ end
- it 'does not include projects shared with the group' do
- project = create(:project, namespace: group)
- other_project = create(:project)
- other_project.project_group_links.create!(group: group,
- group_access: Gitlab::Access::MAINTAINER)
+ it 'does not include projects shared with the group' do
+ project = create(:project, namespace: group)
+ other_project = create(:project)
+ other_project.project_group_links.create!(group: group,
+ group_access: Gitlab::Access::MAINTAINER)
- expect(finder.execute).to contain_exactly(project)
- end
+ expect(finder.execute).to contain_exactly(project)
end
+ end
- context 'with shared groups' do
- let_it_be(:other_group) { create(:group) }
- let_it_be(:shared_group_link) do
- create(:group_group_link,
- shared_group: group,
- shared_with_group: other_group)
- end
+ context 'with shared groups' do
+ let_it_be(:other_group) { create(:group) }
+ let_it_be(:shared_group_link) do
+ create(:group_group_link,
+ shared_group: group,
+ shared_with_group: other_group)
+ end
- context 'without common ancestor' do
+ context 'without common ancestor' do
+ it { expect(finder.execute).to be_empty }
+ end
+
+ context 'with common ancestor' do
+ let_it_be(:common_ancestor) { create(:group) }
+ let_it_be(:other_group) { create(:group, parent: common_ancestor) }
+ let_it_be(:group) { create(:group, parent: common_ancestor) }
+
+ context 'querying under the common ancestor' do
it { expect(finder.execute).to be_empty }
end
- context 'with common ancestor' do
- let_it_be(:common_ancestor) { create(:group) }
- let_it_be(:other_group) { create(:group, parent: common_ancestor) }
- let_it_be(:group) { create(:group, parent: common_ancestor) }
-
- context 'querying under the common ancestor' do
- it { expect(finder.execute).to be_empty }
+ context 'querying the common ancestor' do
+ subject(:finder) do
+ described_class.new(current_user: user, parent_group: common_ancestor, params: params)
end
- context 'querying the common ancestor' do
- subject(:finder) do
- described_class.new(current_user: user, parent_group: common_ancestor, params: params)
- end
-
- it 'contains shared subgroups' do
- expect(finder.execute).to contain_exactly(group, other_group)
- end
+ it 'contains shared subgroups' do
+ expect(finder.execute).to contain_exactly(group, other_group)
end
end
end
+ end
- context 'with nested groups' do
- let!(:project) { create(:project, namespace: group) }
- let!(:subgroup) { create(:group, :private, parent: group) }
+ context 'with nested groups' do
+ let!(:project) { create(:project, namespace: group) }
+ let!(:subgroup) { create(:group, :private, parent: group) }
- describe '#execute' do
- it 'contains projects and subgroups' do
- expect(finder.execute).to contain_exactly(subgroup, project)
- end
+ describe '#execute' do
+ it 'contains projects and subgroups' do
+ expect(finder.execute).to contain_exactly(subgroup, project)
+ end
- it 'does not include subgroups the user does not have access to' do
- subgroup.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
+ it 'does not include subgroups the user does not have access to' do
+ subgroup.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
- public_subgroup = create(:group, :public, parent: group, path: 'public-group')
- other_subgroup = create(:group, :private, parent: group, path: 'visible-private-group')
- other_user = create(:user)
- other_subgroup.add_developer(other_user)
+ public_subgroup = create(:group, :public, parent: group, path: 'public-group')
+ other_subgroup = create(:group, :private, parent: group, path: 'visible-private-group')
+ other_user = create(:user)
+ other_subgroup.add_developer(other_user)
- finder = described_class.new(current_user: other_user, parent_group: group)
+ finder = described_class.new(current_user: other_user, parent_group: group)
- expect(finder.execute).to contain_exactly(public_subgroup, other_subgroup)
- end
+ expect(finder.execute).to contain_exactly(public_subgroup, other_subgroup)
+ end
- it 'only includes public groups when no user is given' do
- public_subgroup = create(:group, :public, parent: group)
- _private_subgroup = create(:group, :private, parent: group)
+ it 'only includes public groups when no user is given' do
+ public_subgroup = create(:group, :public, parent: group)
+ _private_subgroup = create(:group, :private, parent: group)
- finder = described_class.new(current_user: nil, parent_group: group)
+ finder = described_class.new(current_user: nil, parent_group: group)
- expect(finder.execute).to contain_exactly(public_subgroup)
- end
+ expect(finder.execute).to contain_exactly(public_subgroup)
+ end
- context 'when archived is `true`' do
- let(:params) { { archived: 'true' } }
+ context 'when archived is `true`' do
+ let(:params) { { archived: 'true' } }
- it 'includes archived projects in the count of subgroups' do
- create(:project, namespace: subgroup, archived: true)
+ it 'includes archived projects in the count of subgroups' do
+ create(:project, namespace: subgroup, archived: true)
- expect(finder.execute.first.preloaded_project_count).to eq(1)
- end
+ expect(finder.execute.first.preloaded_project_count).to eq(1)
end
+ end
- context 'with a filter' do
- let(:params) { { filter: 'test' } }
+ context 'with a filter' do
+ let(:params) { { filter: 'test' } }
- it 'contains only matching projects and subgroups' do
- matching_project = create(:project, namespace: group, name: 'Testproject')
- matching_subgroup = create(:group, name: 'testgroup', parent: group)
+ it 'contains only matching projects and subgroups' do
+ matching_project = create(:project, namespace: group, name: 'Testproject')
+ matching_subgroup = create(:group, name: 'testgroup', parent: group)
- expect(finder.execute).to contain_exactly(matching_subgroup, matching_project)
- end
+ expect(finder.execute).to contain_exactly(matching_subgroup, matching_project)
+ end
- it 'does not include subgroups the user does not have access to' do
- _invisible_subgroup = create(:group, :private, parent: group, name: 'test1')
- other_subgroup = create(:group, :private, parent: group, name: 'test2')
- public_subgroup = create(:group, :public, parent: group, name: 'test3')
- other_subsubgroup = create(:group, :private, parent: other_subgroup, name: 'test4')
- other_user = create(:user)
- other_subgroup.add_developer(other_user)
+ it 'does not include subgroups the user does not have access to' do
+ _invisible_subgroup = create(:group, :private, parent: group, name: 'test1')
+ other_subgroup = create(:group, :private, parent: group, name: 'test2')
+ public_subgroup = create(:group, :public, parent: group, name: 'test3')
+ other_subsubgroup = create(:group, :private, parent: other_subgroup, name: 'test4')
+ other_user = create(:user)
+ other_subgroup.add_developer(other_user)
- finder = described_class.new(current_user: other_user,
- parent_group: group,
- params: params)
+ finder = described_class.new(current_user: other_user,
+ parent_group: group,
+ params: params)
- expect(finder.execute).to contain_exactly(other_subgroup, public_subgroup, other_subsubgroup)
- end
+ expect(finder.execute).to contain_exactly(other_subgroup, public_subgroup, other_subsubgroup)
+ end
- context 'with matching children' do
- it 'includes a group that has a subgroup matching the query and its parent' do
- matching_subgroup = create(:group, :private, name: 'testgroup', parent: subgroup)
+ context 'with matching children' do
+ it 'includes a group that has a subgroup matching the query and its parent' do
+ matching_subgroup = create(:group, :private, name: 'testgroup', parent: subgroup)
- expect(finder.execute).to contain_exactly(subgroup, matching_subgroup)
- end
+ expect(finder.execute).to contain_exactly(subgroup, matching_subgroup)
+ end
- it 'includes the parent of a matching project' do
- matching_project = create(:project, namespace: subgroup, name: 'Testproject')
+ it 'includes the parent of a matching project' do
+ matching_project = create(:project, namespace: subgroup, name: 'Testproject')
- expect(finder.execute).to contain_exactly(subgroup, matching_project)
- end
+ expect(finder.execute).to contain_exactly(subgroup, matching_project)
+ end
- context 'with a small page size' do
- let(:params) { { filter: 'test', per_page: 1 } }
+ context 'with a small page size' do
+ let(:params) { { filter: 'test', per_page: 1 } }
- it 'contains all the ancestors of a matching subgroup regardless the page size' do
- subgroup = create(:group, :private, parent: group)
- matching = create(:group, :private, name: 'testgroup', parent: subgroup)
+ it 'contains all the ancestors of a matching subgroup regardless the page size' do
+ subgroup = create(:group, :private, parent: group)
+ matching = create(:group, :private, name: 'testgroup', parent: subgroup)
- expect(finder.execute).to contain_exactly(subgroup, matching)
- end
+ expect(finder.execute).to contain_exactly(subgroup, matching)
end
+ end
- it 'does not include the parent itself' do
- group.update!(name: 'test')
+ it 'does not include the parent itself' do
+ group.update!(name: 'test')
- expect(finder.execute).not_to include(group)
- end
+ expect(finder.execute).not_to include(group)
end
end
end
end
end
-
- it_behaves_like 'group descentants finder examples'
-
- context 'when feature flag :linear_group_descendants_finder is disabled' do
- before do
- stub_feature_flags(linear_group_descendants_finder: false)
- end
-
- it_behaves_like 'group descentants finder examples'
- end
end
diff --git a/spec/finders/group_members_finder_spec.rb b/spec/finders/group_members_finder_spec.rb
index 0d797b7923c..a9a8e9d19b8 100644
--- a/spec/finders/group_members_finder_spec.rb
+++ b/spec/finders/group_members_finder_spec.rb
@@ -3,83 +3,93 @@
require 'spec_helper'
RSpec.describe GroupMembersFinder, '#execute' do
- let(:group) { create(:group) }
- let(:sub_group) { create(:group, parent: group) }
- let(:sub_sub_group) { create(:group, parent: sub_group) }
- let(:user1) { create(:user) }
- let(:user2) { create(:user) }
- let(:user3) { create(:user) }
- let(:user4) { create(:user) }
- let(:user5) { create(:user, :two_factor_via_otp) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:sub_group) { create(:group, parent: group) }
+ let_it_be(:sub_sub_group) { create(:group, parent: sub_group) }
+ let_it_be(:public_shared_group) { create(:group, :public) }
+ let_it_be(:private_shared_group) { create(:group, :private) }
+ let_it_be(:user1) { create(:user) }
+ let_it_be(:user2) { create(:user) }
+ let_it_be(:user3) { create(:user) }
+ let_it_be(:user4) { create(:user) }
+ let_it_be(:user5) { create(:user, :two_factor_via_otp) }
+
+ let!(:link) do
+ create(:group_group_link, shared_group: group, shared_with_group: public_shared_group)
+ create(:group_group_link, shared_group: sub_group, shared_with_group: private_shared_group)
+ end
let(:groups) do
{
- group: group,
- sub_group: sub_group,
- sub_sub_group: sub_sub_group
+ group: group,
+ sub_group: sub_group,
+ sub_sub_group: sub_sub_group,
+ public_shared_group: public_shared_group,
+ private_shared_group: private_shared_group
}
end
context 'relations' do
let!(:members) do
{
- user1_sub_sub_group: create(:group_member, :maintainer, group: sub_sub_group, user: user1),
- user1_sub_group: create(:group_member, :developer, group: sub_group, user: user1),
- user1_group: create(:group_member, :reporter, group: group, user: user1),
- user2_sub_sub_group: create(:group_member, :reporter, group: sub_sub_group, user: user2),
- user2_sub_group: create(:group_member, :developer, group: sub_group, user: user2),
- user2_group: create(:group_member, :maintainer, group: group, user: user2),
- user3_sub_sub_group: create(:group_member, :developer, group: sub_sub_group, user: user3, expires_at: 1.day.from_now),
- user3_sub_group: create(:group_member, :developer, group: sub_group, user: user3, expires_at: 2.days.from_now),
- user3_group: create(:group_member, :reporter, group: group, user: user3),
- user4_sub_sub_group: create(:group_member, :reporter, group: sub_sub_group, user: user4),
- user4_sub_group: create(:group_member, :developer, group: sub_group, user: user4, expires_at: 1.day.from_now),
- user4_group: create(:group_member, :developer, group: group, user: user4, expires_at: 2.days.from_now)
+ user1_sub_sub_group: create(:group_member, :maintainer, group: sub_sub_group, user: user1),
+ user1_sub_group: create(:group_member, :developer, group: sub_group, user: user1),
+ user1_group: create(:group_member, :reporter, group: group, user: user1),
+ user1_public_shared_group: create(:group_member, :maintainer, group: public_shared_group, user: user1),
+ user1_private_shared_group: create(:group_member, :maintainer, group: private_shared_group, user: user1),
+ user2_sub_sub_group: create(:group_member, :reporter, group: sub_sub_group, user: user2),
+ user2_sub_group: create(:group_member, :developer, group: sub_group, user: user2),
+ user2_group: create(:group_member, :maintainer, group: group, user: user2),
+ user2_public_shared_group: create(:group_member, :developer, group: public_shared_group, user: user2),
+ user2_private_shared_group: create(:group_member, :developer, group: private_shared_group, user: user2),
+ user3_sub_sub_group: create(:group_member, :developer, group: sub_sub_group, user: user3, expires_at: 1.day.from_now),
+ user3_sub_group: create(:group_member, :developer, group: sub_group, user: user3, expires_at: 2.days.from_now),
+ user3_group: create(:group_member, :reporter, group: group, user: user3),
+ user3_public_shared_group: create(:group_member, :reporter, group: public_shared_group, user: user3),
+ user3_private_shared_group: create(:group_member, :reporter, group: private_shared_group, user: user3),
+ user4_sub_sub_group: create(:group_member, :reporter, group: sub_sub_group, user: user4),
+ user4_sub_group: create(:group_member, :developer, group: sub_group, user: user4, expires_at: 1.day.from_now),
+ user4_group: create(:group_member, :developer, group: group, user: user4, expires_at: 2.days.from_now),
+ user4_public_shared_group: create(:group_member, :developer, group: public_shared_group, user: user4),
+ user4_private_shared_group: create(:group_member, :developer, group: private_shared_group, user: user4)
}
end
it 'raises an error if a non-supported relation type is used' do
expect do
described_class.new(group).execute(include_relations: [:direct, :invalid_relation_type])
- end.to raise_error(ArgumentError, "invalid_relation_type is not a valid relation type. Valid relation types are direct, inherited, descendants.")
+ end.to raise_error(ArgumentError, "invalid_relation_type is not a valid relation type. Valid relation types are direct, inherited, descendants, shared_from_groups.")
end
using RSpec::Parameterized::TableSyntax
where(:subject_relations, :subject_group, :expected_members) do
- nil | :group | [:user1_group, :user2_group, :user3_group, :user4_group]
- [:direct] | :group | [:user1_group, :user2_group, :user3_group, :user4_group]
- [:inherited] | :group | []
- [:descendants] | :group | [:user1_sub_sub_group, :user2_sub_group, :user3_sub_group, :user4_sub_group]
- [:direct, :inherited] | :group | [:user1_group, :user2_group, :user3_group, :user4_group]
- [:direct, :descendants] | :group | [:user1_sub_sub_group, :user2_group, :user3_sub_group, :user4_group]
- [:descendants, :inherited] | :group | [:user1_sub_sub_group, :user2_sub_group, :user3_sub_group, :user4_sub_group]
- [:direct, :descendants, :inherited] | :group | [:user1_sub_sub_group, :user2_group, :user3_sub_group, :user4_group]
- nil | :sub_group | [:user1_sub_group, :user2_group, :user3_sub_group, :user4_group]
- [:direct] | :sub_group | [:user1_sub_group, :user2_sub_group, :user3_sub_group, :user4_sub_group]
- [:inherited] | :sub_group | [:user1_group, :user2_group, :user3_group, :user4_group]
- [:descendants] | :sub_group | [:user1_sub_sub_group, :user2_sub_sub_group, :user3_sub_sub_group, :user4_sub_sub_group]
- [:direct, :inherited] | :sub_group | [:user1_sub_group, :user2_group, :user3_sub_group, :user4_group]
- [:direct, :descendants] | :sub_group | [:user1_sub_sub_group, :user2_sub_group, :user3_sub_group, :user4_sub_group]
- [:descendants, :inherited] | :sub_group | [:user1_sub_sub_group, :user2_group, :user3_sub_sub_group, :user4_group]
- [:direct, :descendants, :inherited] | :sub_group | [:user1_sub_sub_group, :user2_group, :user3_sub_group, :user4_group]
- nil | :sub_sub_group | [:user1_sub_sub_group, :user2_group, :user3_sub_group, :user4_group]
- [:direct] | :sub_sub_group | [:user1_sub_sub_group, :user2_sub_sub_group, :user3_sub_sub_group, :user4_sub_sub_group]
- [:inherited] | :sub_sub_group | [:user1_sub_group, :user2_group, :user3_sub_group, :user4_group]
- [:descendants] | :sub_sub_group | []
- [:direct, :inherited] | :sub_sub_group | [:user1_sub_sub_group, :user2_group, :user3_sub_group, :user4_group]
- [:direct, :descendants] | :sub_sub_group | [:user1_sub_sub_group, :user2_sub_sub_group, :user3_sub_sub_group, :user4_sub_sub_group]
- [:descendants, :inherited] | :sub_sub_group | [:user1_sub_group, :user2_group, :user3_sub_group, :user4_group]
- [:direct, :descendants, :inherited] | :sub_sub_group | [:user1_sub_sub_group, :user2_group, :user3_sub_group, :user4_group]
+ [] | :group | []
+ GroupMembersFinder::DEFAULT_RELATIONS | :group | [:user1_group, :user2_group, :user3_group, :user4_group]
+ [:direct] | :group | [:user1_group, :user2_group, :user3_group, :user4_group]
+ [:inherited] | :group | []
+ [:descendants] | :group | [:user1_sub_sub_group, :user2_sub_group, :user3_sub_group, :user4_sub_group]
+ [:shared_from_groups] | :group | [:user1_public_shared_group, :user2_public_shared_group, :user3_public_shared_group, :user4_public_shared_group]
+ [:direct, :inherited, :descendants, :shared_from_groups] | :group | [:user1_sub_sub_group, :user2_group, :user3_sub_group, :user4_public_shared_group]
+ [] | :sub_group | []
+ GroupMembersFinder::DEFAULT_RELATIONS | :sub_group | [:user1_sub_group, :user2_group, :user3_sub_group, :user4_group]
+ [:direct] | :sub_group | [:user1_sub_group, :user2_sub_group, :user3_sub_group, :user4_sub_group]
+ [:inherited] | :sub_group | [:user1_group, :user2_group, :user3_group, :user4_group]
+ [:descendants] | :sub_group | [:user1_sub_sub_group, :user2_sub_sub_group, :user3_sub_sub_group, :user4_sub_sub_group]
+ [:shared_from_groups] | :sub_group | []
+ [:direct, :inherited, :descendants, :shared_from_groups] | :sub_group | [:user1_sub_sub_group, :user2_group, :user3_sub_group, :user4_group]
+ [] | :sub_sub_group | []
+ GroupMembersFinder::DEFAULT_RELATIONS | :sub_sub_group | [:user1_sub_sub_group, :user2_group, :user3_sub_group, :user4_group]
+ [:direct] | :sub_sub_group | [:user1_sub_sub_group, :user2_sub_sub_group, :user3_sub_sub_group, :user4_sub_sub_group]
+ [:inherited] | :sub_sub_group | [:user1_sub_group, :user2_group, :user3_sub_group, :user4_group]
+ [:descendants] | :sub_sub_group | []
+ [:shared_from_groups] | :sub_sub_group | []
+ [:direct, :inherited, :descendants, :shared_from_groups] | :sub_sub_group | [:user1_sub_sub_group, :user2_group, :user3_sub_group, :user4_group]
end
with_them do
it 'returns correct members' do
- result = if subject_relations
- described_class.new(groups[subject_group]).execute(include_relations: subject_relations)
- else
- described_class.new(groups[subject_group]).execute
- end
+ result = described_class.new(groups[subject_group]).execute(include_relations: subject_relations)
expect(result.to_a).to match_array(expected_members.map { |name| members[name] })
end
diff --git a/spec/finders/groups/user_groups_finder_spec.rb b/spec/finders/groups/user_groups_finder_spec.rb
index 4cce3ab72eb..a4a9b8d16d0 100644
--- a/spec/finders/groups/user_groups_finder_spec.rb
+++ b/spec/finders/groups/user_groups_finder_spec.rb
@@ -59,23 +59,6 @@ RSpec.describe Groups::UserGroupsFinder do
)
end
- context 'when paginatable_namespace_drop_down_for_project_creation feature flag is disabled' do
- before do
- stub_feature_flags(paginatable_namespace_drop_down_for_project_creation: false)
- end
-
- it 'ignores project creation scope and returns all groups where the user is a direct member' do
- is_expected.to match(
- [
- public_maintainer_group,
- private_maintainer_group,
- public_developer_group,
- guest_group
- ]
- )
- end
- end
-
context 'when search is provided' do
let(:arguments) { { permission_scope: :create_projects, search: 'maintainer' } }
diff --git a/spec/finders/merge_requests_finder_spec.rb b/spec/finders/merge_requests_finder_spec.rb
index 03639bc0b98..0b6c438fd02 100644
--- a/spec/finders/merge_requests_finder_spec.rb
+++ b/spec/finders/merge_requests_finder_spec.rb
@@ -278,33 +278,38 @@ RSpec.describe MergeRequestsFinder do
end
describe 'draft state' do
- let!(:wip_merge_request1) { create(:merge_request, :simple, author: user, source_project: project5, target_project: project5, title: 'WIP: thing') }
- let!(:wip_merge_request2) { create(:merge_request, :simple, author: user, source_project: project6, target_project: project6, title: 'wip thing') }
- let!(:wip_merge_request3) { create(:merge_request, :simple, author: user, source_project: project1, target_project: project1, title: '[wip] thing') }
- let!(:wip_merge_request4) { create(:merge_request, :simple, author: user, source_project: project1, target_project: project2, title: 'wip: thing') }
- let!(:draft_merge_request1) { create(:merge_request, :simple, author: user, source_branch: 'draft1', source_project: project5, target_project: project5, title: 'Draft: thing') }
- let!(:draft_merge_request2) { create(:merge_request, :simple, author: user, source_branch: 'draft2', source_project: project6, target_project: project6, title: '[draft] thing') }
- let!(:draft_merge_request3) { create(:merge_request, :simple, author: user, source_branch: 'draft3', source_project: project1, target_project: project1, title: '(draft) thing') }
- let!(:draft_merge_request4) { create(:merge_request, :simple, author: user, source_branch: 'draft4', source_project: project1, target_project: project2, title: 'Draft - thing') }
-
- [:wip, :draft].each do |draft_param_key|
- it "filters by #{draft_param_key}" do
- params = { draft_param_key => 'yes' }
+ shared_examples 'draft MRs filtering' do |draft_param_key, draft_param_value, title_prefix, draft_only|
+ it "filters by #{draft_param_key} => #{draft_param_value}" do
+ merge_request1.reload.update!(title: "#{title_prefix} #{merge_request1.title}")
+
+ params = { draft_param_key => draft_param_value }
merge_requests = described_class.new(user, params).execute
- expect(merge_requests).to contain_exactly(
- merge_request4, merge_request5, wip_merge_request1, wip_merge_request2, wip_merge_request3, wip_merge_request4,
- draft_merge_request1, draft_merge_request2, draft_merge_request3, draft_merge_request4
- )
+ if draft_only
+ expect(merge_requests).to contain_exactly(merge_request1, merge_request4, merge_request5)
+ else
+ expect(merge_requests).to contain_exactly(merge_request2, merge_request3)
+ end
end
+ end
- it "filters by not #{draft_param_key}" do
- params = { draft_param_key => 'no' }
-
- merge_requests = described_class.new(user, params).execute
+ {
+ wip: ["WIP:", "wip", "[wip]"],
+ draft: ["Draft:", "Draft -", "[Draft]", "(Draft)"]
+ }.each do |draft_param_key, title_prefixes|
+ title_prefixes.each do |title_prefix|
+ it_behaves_like 'draft MRs filtering', draft_param_key, 1, title_prefix, true
+ it_behaves_like 'draft MRs filtering', draft_param_key, '1', title_prefix, true
+ it_behaves_like 'draft MRs filtering', draft_param_key, true, title_prefix, true
+ it_behaves_like 'draft MRs filtering', draft_param_key, 'true', title_prefix, true
+ it_behaves_like 'draft MRs filtering', draft_param_key, 'yes', title_prefix, true
- expect(merge_requests).to contain_exactly(merge_request1, merge_request2, merge_request3)
+ it_behaves_like 'draft MRs filtering', draft_param_key, 0, title_prefix, false
+ it_behaves_like 'draft MRs filtering', draft_param_key, '0', title_prefix, false
+ it_behaves_like 'draft MRs filtering', draft_param_key, false, title_prefix, false
+ it_behaves_like 'draft MRs filtering', draft_param_key, 'false', title_prefix, false
+ it_behaves_like 'draft MRs filtering', draft_param_key, 'no', title_prefix, false
end
it "returns all items if no valid #{draft_param_key} param exists" do
@@ -313,43 +318,41 @@ RSpec.describe MergeRequestsFinder do
merge_requests = described_class.new(user, params).execute
expect(merge_requests).to contain_exactly(
- merge_request1, merge_request2, merge_request3, merge_request4,
- merge_request5, wip_merge_request1, wip_merge_request2, wip_merge_request3, wip_merge_request4,
- draft_merge_request1, draft_merge_request2, draft_merge_request3, draft_merge_request4
+ merge_request1, merge_request2, merge_request3, merge_request4, merge_request5
)
end
end
+ end
- context 'filter by deployment' do
- let_it_be(:project_with_repo) { create(:project, :repository) }
+ context 'filter by deployment' do
+ let_it_be(:project_with_repo) { create(:project, :repository) }
- it 'returns the relevant merge requests' do
- deployment1 = create(
- :deployment,
- project: project_with_repo,
- sha: project_with_repo.commit.id
- )
- deployment2 = create(
- :deployment,
- project: project_with_repo,
- sha: project_with_repo.commit.id
- )
- deployment1.link_merge_requests(MergeRequest.where(id: [merge_request1.id, merge_request2.id]))
- deployment2.link_merge_requests(MergeRequest.where(id: merge_request3.id))
+ it 'returns the relevant merge requests' do
+ deployment1 = create(
+ :deployment,
+ project: project_with_repo,
+ sha: project_with_repo.commit.id
+ )
+ deployment2 = create(
+ :deployment,
+ project: project_with_repo,
+ sha: project_with_repo.commit.id
+ )
+ deployment1.link_merge_requests(MergeRequest.where(id: [merge_request1.id, merge_request2.id]))
+ deployment2.link_merge_requests(MergeRequest.where(id: merge_request3.id))
- params = { deployment_id: deployment1.id }
- merge_requests = described_class.new(user, params).execute
+ params = { deployment_id: deployment1.id }
+ merge_requests = described_class.new(user, params).execute
- expect(merge_requests).to contain_exactly(merge_request1, merge_request2)
- end
+ expect(merge_requests).to contain_exactly(merge_request1, merge_request2)
+ end
- context 'when a deployment does not contain any merge requests' do
- it 'returns an empty result' do
- params = { deployment_id: create(:deployment, project: project_with_repo, sha: project_with_repo.commit.sha).id }
- merge_requests = described_class.new(user, params).execute
+ context 'when a deployment does not contain any merge requests' do
+ it 'returns an empty result' do
+ params = { deployment_id: create(:deployment, project: project_with_repo, sha: project_with_repo.commit.sha).id }
+ merge_requests = described_class.new(user, params).execute
- expect(merge_requests).to be_empty
- end
+ expect(merge_requests).to be_empty
end
end
end
diff --git a/spec/finders/packages/conan/package_file_finder_spec.rb b/spec/finders/packages/conan/package_file_finder_spec.rb
index c2f445c58f7..3da7da456c2 100644
--- a/spec/finders/packages/conan/package_file_finder_spec.rb
+++ b/spec/finders/packages/conan/package_file_finder_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe ::Packages::Conan::PackageFileFinder do
let(:package_file_name) { package_file.file_name }
let(:params) { {} }
- RSpec.shared_examples 'package file finder examples' do
+ shared_examples 'package file finder examples' do
it { is_expected.to eq(package_file) }
context 'with conan_file_type' do
@@ -39,11 +39,37 @@ RSpec.describe ::Packages::Conan::PackageFileFinder do
end
end
+ shared_examples 'not returning pending_destruction package files' do
+ let_it_be(:recent_package_file_pending_destruction) do
+ create(:package_file, :pending_destruction, package: package, file_name: package_file.file_name)
+ end
+
+ it 'returns the correct package file' do
+ expect(package.package_files.last).to eq(recent_package_file_pending_destruction)
+
+ expect(subject).to eq(package_file)
+ end
+
+ context 'with packages_installable_package_files disabled' do
+ before do
+ stub_feature_flags(packages_installable_package_files: false)
+ end
+
+ it 'returns the correct package file' do
+ expect(package.package_files.last).to eq(recent_package_file_pending_destruction)
+
+ expect(subject).to eq(recent_package_file_pending_destruction)
+ end
+ end
+ end
+
describe '#execute' do
subject { described_class.new(package, package_file_name, params).execute }
it_behaves_like 'package file finder examples'
+ it_behaves_like 'not returning pending_destruction package files'
+
context 'with unknown file_name' do
let(:package_file_name) { 'unknown.jpg' }
@@ -56,6 +82,8 @@ RSpec.describe ::Packages::Conan::PackageFileFinder do
it_behaves_like 'package file finder examples'
+ it_behaves_like 'not returning pending_destruction package files'
+
context 'with unknown file_name' do
let(:package_file_name) { 'unknown.jpg' }
diff --git a/spec/finders/packages/go/package_finder_spec.rb b/spec/finders/packages/go/package_finder_spec.rb
index dbcb8255d47..b928336f958 100644
--- a/spec/finders/packages/go/package_finder_spec.rb
+++ b/spec/finders/packages/go/package_finder_spec.rb
@@ -59,7 +59,7 @@ RSpec.describe Packages::Go::PackageFinder do
let(:version_name) { version.name }
before do
- package.update_column(:status, 1)
+ package.update_column(:status, :error)
end
it { is_expected.to eq(nil) }
diff --git a/spec/finders/packages/maven/package_finder_spec.rb b/spec/finders/packages/maven/package_finder_spec.rb
index 38fc3b7cce4..8b45dbdad51 100644
--- a/spec/finders/packages/maven/package_finder_spec.rb
+++ b/spec/finders/packages/maven/package_finder_spec.rb
@@ -39,7 +39,7 @@ RSpec.describe ::Packages::Maven::PackageFinder do
let(:param_path) { package.maven_metadatum.path }
before do
- package.update_column(:status, 1)
+ package.update_column(:status, :error)
end
it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
diff --git a/spec/finders/packages/npm/package_finder_spec.rb b/spec/finders/packages/npm/package_finder_spec.rb
index 230d267e508..7fabb3eed86 100644
--- a/spec/finders/packages/npm/package_finder_spec.rb
+++ b/spec/finders/packages/npm/package_finder_spec.rb
@@ -52,7 +52,7 @@ RSpec.describe ::Packages::Npm::PackageFinder do
context 'with an uninstallable package' do
before do
- package.update_column(:status, 1)
+ package.update_column(:status, :error)
end
it { is_expected.to be_empty }
diff --git a/spec/finders/packages/nuget/package_finder_spec.rb b/spec/finders/packages/nuget/package_finder_spec.rb
index 045dba295ac..415bf796a72 100644
--- a/spec/finders/packages/nuget/package_finder_spec.rb
+++ b/spec/finders/packages/nuget/package_finder_spec.rb
@@ -36,7 +36,7 @@ RSpec.describe Packages::Nuget::PackageFinder do
context 'with an uninstallable package' do
before do
- package1.update_column(:status, 1)
+ package1.update_column(:status, :error)
end
it { is_expected.to contain_exactly(package2) }
diff --git a/spec/finders/packages/package_file_finder_spec.rb b/spec/finders/packages/package_file_finder_spec.rb
index 8014f04d917..8b21c9cd3ec 100644
--- a/spec/finders/packages/package_file_finder_spec.rb
+++ b/spec/finders/packages/package_file_finder_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe Packages::PackageFileFinder do
let(:package_file_name) { package_file.file_name }
let(:params) { {} }
- RSpec.shared_examples 'package file finder examples' do
+ shared_examples 'package file finder examples' do
it { is_expected.to eq(package_file) }
context 'with file_name_like' do
@@ -19,11 +19,35 @@ RSpec.describe Packages::PackageFileFinder do
end
end
+ shared_examples 'not returning pending_destruction package files' do
+ let_it_be(:recent_package_file_pending_destruction) do
+ create(:package_file, :pending_destruction, package: package, file_name: package_file.file_name)
+ end
+
+ it 'returns the correct package file' do
+ expect(package.package_files.last).to eq(recent_package_file_pending_destruction)
+
+ expect(subject).to eq(package_file)
+ end
+
+ context 'with packages_installable_package_files disabled' do
+ before do
+ stub_feature_flags(packages_installable_package_files: false)
+ end
+
+ it 'returns them' do
+ expect(subject).to eq(recent_package_file_pending_destruction)
+ end
+ end
+ end
+
describe '#execute' do
subject { described_class.new(package, package_file_name, params).execute }
it_behaves_like 'package file finder examples'
+ it_behaves_like 'not returning pending_destruction package files'
+
context 'with unknown file_name' do
let(:package_file_name) { 'unknown.jpg' }
@@ -36,6 +60,8 @@ RSpec.describe Packages::PackageFileFinder do
it_behaves_like 'package file finder examples'
+ it_behaves_like 'not returning pending_destruction package files'
+
context 'with unknown file_name' do
let(:package_file_name) { 'unknown.jpg' }
diff --git a/spec/finders/user_group_notification_settings_finder_spec.rb b/spec/finders/user_group_notification_settings_finder_spec.rb
index ea44688bc8d..ac59a42d813 100644
--- a/spec/finders/user_group_notification_settings_finder_spec.rb
+++ b/spec/finders/user_group_notification_settings_finder_spec.rb
@@ -11,167 +11,155 @@ RSpec.describe UserGroupNotificationSettingsFinder do
subject.map(&proc).uniq
end
- shared_examples 'user group notifications settings tests' do
- context 'when the groups have no existing notification settings' do
- context 'when the groups have no ancestors' do
- let_it_be(:groups) { create_list(:group, 3) }
-
- it 'will be a default Global notification setting', :aggregate_failures do
- expect(subject.count).to eq(3)
- expect(attributes(&:notification_email)).to match_array([nil])
- expect(attributes(&:level)).to match_array(['global'])
- end
+ context 'when the groups have no existing notification settings' do
+ context 'when the groups have no ancestors' do
+ let_it_be(:groups) { create_list(:group, 3) }
+
+ it 'will be a default Global notification setting', :aggregate_failures do
+ expect(subject.count).to eq(3)
+ expect(attributes(&:notification_email)).to match_array([nil])
+ expect(attributes(&:level)).to match_array(['global'])
end
+ end
- context 'when the groups have ancestors' do
- context 'when an ancestor has a level other than Global' do
- let_it_be(:ancestor_a) { create(:group) }
- let_it_be(:group_a) { create(:group, parent: ancestor_a) }
- let_it_be(:ancestor_b) { create(:group) }
- let_it_be(:group_b) { create(:group, parent: ancestor_b) }
- let_it_be(:email) { create(:email, :confirmed, email: 'ancestor@example.com', user: user) }
-
- let_it_be(:groups) { [group_a, group_b] }
+ context 'when the groups have ancestors' do
+ context 'when an ancestor has a level other than Global' do
+ let_it_be(:ancestor_a) { create(:group) }
+ let_it_be(:group_a) { create(:group, parent: ancestor_a) }
+ let_it_be(:ancestor_b) { create(:group) }
+ let_it_be(:group_b) { create(:group, parent: ancestor_b) }
+ let_it_be(:email) { create(:email, :confirmed, email: 'ancestor@example.com', user: user) }
- before do
- create(:notification_setting, user: user, source: ancestor_a, level: 'participating', notification_email: email.email)
- create(:notification_setting, user: user, source: ancestor_b, level: 'participating', notification_email: email.email)
- end
+ let_it_be(:groups) { [group_a, group_b] }
- it 'has the same level set' do
- expect(attributes(&:level)).to match_array(['participating'])
- end
+ before do
+ create(:notification_setting, user: user, source: ancestor_a, level: 'participating', notification_email: email.email)
+ create(:notification_setting, user: user, source: ancestor_b, level: 'participating', notification_email: email.email)
+ end
- it 'has the same email set' do
- expect(attributes(&:notification_email)).to match_array(['ancestor@example.com'])
- end
+ it 'has the same level set' do
+ expect(attributes(&:level)).to match_array(['participating'])
+ end
- it 'only returns the two queried groups' do
- expect(subject.count).to eq(2)
- end
+ it 'has the same email set' do
+ expect(attributes(&:notification_email)).to match_array(['ancestor@example.com'])
end
- context 'when an ancestor has a Global level but has an email set' do
- let_it_be(:grand_ancestor) { create(:group) }
- let_it_be(:ancestor) { create(:group, parent: grand_ancestor) }
- let_it_be(:group) { create(:group, parent: ancestor) }
- let_it_be(:ancestor_email) { create(:email, :confirmed, email: 'ancestor@example.com', user: user) }
- let_it_be(:grand_email) { create(:email, :confirmed, email: 'grand@example.com', user: user) }
-
- let_it_be(:groups) { [group] }
-
- before do
- create(:notification_setting, user: user, source: grand_ancestor, level: 'participating', notification_email: grand_email.email)
- create(:notification_setting, user: user, source: ancestor, level: 'global', notification_email: ancestor_email.email)
- end
-
- it 'has the same email and level set', :aggregate_failures do
- expect(subject.count).to eq(1)
- expect(attributes(&:level)).to match_array(['global'])
- expect(attributes(&:notification_email)).to match_array(['ancestor@example.com'])
- end
+ it 'only returns the two queried groups' do
+ expect(subject.count).to eq(2)
end
+ end
- context 'when the group has parent_id set but that does not belong to any group' do
- let_it_be(:group) { create(:group) }
- let_it_be(:groups) { [group] }
+ context 'when an ancestor has a Global level but has an email set' do
+ let_it_be(:grand_ancestor) { create(:group) }
+ let_it_be(:ancestor) { create(:group, parent: grand_ancestor) }
+ let_it_be(:group) { create(:group, parent: ancestor) }
+ let_it_be(:ancestor_email) { create(:email, :confirmed, email: 'ancestor@example.com', user: user) }
+ let_it_be(:grand_email) { create(:email, :confirmed, email: 'grand@example.com', user: user) }
- before do
- # Let's set a parent_id for a group that definitely doesn't exist
- group.update_columns(parent_id: 19283746)
- end
+ let_it_be(:groups) { [group] }
- it 'returns a default Global notification setting' do
- expect(subject.count).to eq(1)
- expect(attributes(&:level)).to match_array(['global'])
- expect(attributes(&:notification_email)).to match_array([nil])
- end
+ before do
+ create(:notification_setting, user: user, source: grand_ancestor, level: 'participating', notification_email: grand_email.email)
+ create(:notification_setting, user: user, source: ancestor, level: 'global', notification_email: ancestor_email.email)
end
- context 'when the group has a private parent' do
- let_it_be(:ancestor) { create(:group, :private) }
- let_it_be(:group) { create(:group, :private, parent: ancestor) }
- let_it_be(:ancestor_email) { create(:email, :confirmed, email: 'ancestor@example.com', user: user) }
- let_it_be(:groups) { [group] }
-
- before do
- group.add_reporter(user)
- # Adding the user creates a NotificationSetting, so we remove it here
- user.notification_settings.where(source: group).delete_all
-
- create(:notification_setting, user: user, source: ancestor, level: 'participating', notification_email: ancestor_email.email)
- end
-
- it 'still inherits the notification settings' do
- expect(subject.count).to eq(1)
- expect(attributes(&:level)).to match_array(['participating'])
- expect(attributes(&:notification_email)).to match_array([ancestor_email.email])
- end
+ it 'has the same email and level set', :aggregate_failures do
+ expect(subject.count).to eq(1)
+ expect(attributes(&:level)).to match_array(['global'])
+ expect(attributes(&:notification_email)).to match_array(['ancestor@example.com'])
end
+ end
- it 'does not cause an N+1', :aggregate_failures do
- parent = create(:group)
- child = create(:group, parent: parent)
-
- control = ActiveRecord::QueryRecorder.new do
- described_class.new(user, Group.where(id: child.id)).execute
- end
-
- other_parent = create(:group)
- other_children = create_list(:group, 2, parent: other_parent)
-
- result = nil
+ context 'when the group has parent_id set but that does not belong to any group' do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:groups) { [group] }
- expect do
- result = described_class.new(user, Group.where(id: other_children.append(child).map(&:id))).execute
- end.not_to exceed_query_limit(control)
+ before do
+ # Let's set a parent_id for a group that definitely doesn't exist
+ group.update_columns(parent_id: 19283746)
+ end
- expect(result.count).to eq(3)
+ it 'returns a default Global notification setting' do
+ expect(subject.count).to eq(1)
+ expect(attributes(&:level)).to match_array(['global'])
+ expect(attributes(&:notification_email)).to match_array([nil])
end
end
- end
- context 'preloading `emails_disabled`' do
- let_it_be(:root_group) { create(:group) }
- let_it_be(:sub_group) { create(:group, parent: root_group) }
- let_it_be(:sub_sub_group) { create(:group, parent: sub_group) }
+ context 'when the group has a private parent' do
+ let_it_be(:ancestor) { create(:group, :private) }
+ let_it_be(:group) { create(:group, :private, parent: ancestor) }
+ let_it_be(:ancestor_email) { create(:email, :confirmed, email: 'ancestor@example.com', user: user) }
+ let_it_be(:groups) { [group] }
- let_it_be(:another_root_group) { create(:group) }
- let_it_be(:sub_group_with_emails_disabled) { create(:group, emails_disabled: true, parent: another_root_group) }
- let_it_be(:another_sub_sub_group) { create(:group, parent: sub_group_with_emails_disabled) }
+ before do
+ group.add_reporter(user)
+ # Adding the user creates a NotificationSetting, so we remove it here
+ user.notification_settings.where(source: group).delete_all
- let_it_be(:root_group_with_emails_disabled) { create(:group, emails_disabled: true) }
- let_it_be(:group) { create(:group, parent: root_group_with_emails_disabled) }
-
- let(:groups) { Group.where(id: [sub_sub_group, another_sub_sub_group, group]) }
+ create(:notification_setting, user: user, source: ancestor, level: 'participating', notification_email: ancestor_email.email)
+ end
- before do
- described_class.new(user, groups).execute
+ it 'still inherits the notification settings' do
+ expect(subject.count).to eq(1)
+ expect(attributes(&:level)).to match_array(['participating'])
+ expect(attributes(&:notification_email)).to match_array([ancestor_email.email])
+ end
end
- it 'preloads the `group.emails_disabled` method' do
- recorder = ActiveRecord::QueryRecorder.new do
- groups.each(&:emails_disabled?)
+ it 'does not cause an N+1', :aggregate_failures do
+ parent = create(:group)
+ child = create(:group, parent: parent)
+
+ control = ActiveRecord::QueryRecorder.new do
+ described_class.new(user, Group.where(id: child.id)).execute
end
- expect(recorder.count).to eq(0)
- end
+ other_parent = create(:group)
+ other_children = create_list(:group, 2, parent: other_parent)
- it 'preloads the `group.emails_disabled` method correctly' do
- groups.each do |group|
- expect(group.emails_disabled?).to eq(Group.find(group.id).emails_disabled?) # compare the memoized and the freshly loaded value
- end
+ result = nil
+
+ expect do
+ result = described_class.new(user, Group.where(id: other_children.append(child).map(&:id))).execute
+ end.not_to exceed_query_limit(control)
+
+ expect(result.count).to eq(3)
end
end
end
- it_behaves_like 'user group notifications settings tests'
+ context 'preloading `emails_disabled`' do
+ let_it_be(:root_group) { create(:group) }
+ let_it_be(:sub_group) { create(:group, parent: root_group) }
+ let_it_be(:sub_sub_group) { create(:group, parent: sub_group) }
+
+ let_it_be(:another_root_group) { create(:group) }
+ let_it_be(:sub_group_with_emails_disabled) { create(:group, emails_disabled: true, parent: another_root_group) }
+ let_it_be(:another_sub_sub_group) { create(:group, parent: sub_group_with_emails_disabled) }
+
+ let_it_be(:root_group_with_emails_disabled) { create(:group, emails_disabled: true) }
+ let_it_be(:group) { create(:group, parent: root_group_with_emails_disabled) }
+
+ let(:groups) { Group.where(id: [sub_sub_group, another_sub_sub_group, group]) }
- context 'when feature flag :linear_user_group_notification_settings_finder_ancestors_scopes is disabled' do
before do
- stub_feature_flags(linear_user_group_notification_settings_finder_ancestors_scopes: false)
+ described_class.new(user, groups).execute
+ end
+
+ it 'preloads the `group.emails_disabled` method' do
+ recorder = ActiveRecord::QueryRecorder.new do
+ groups.each(&:emails_disabled?)
+ end
+
+ expect(recorder.count).to eq(0)
end
- it_behaves_like 'user group notifications settings tests'
+ it 'preloads the `group.emails_disabled` method correctly' do
+ groups.each do |group|
+ expect(group.emails_disabled?).to eq(Group.find(group.id).emails_disabled?) # compare the memoized and the freshly loaded value
+ end
+ end
end
end
diff --git a/spec/finders/user_recent_events_finder_spec.rb b/spec/finders/user_recent_events_finder_spec.rb
index 74c563b9bf6..6019d22059d 100644
--- a/spec/finders/user_recent_events_finder_spec.rb
+++ b/spec/finders/user_recent_events_finder_spec.rb
@@ -59,14 +59,46 @@ RSpec.describe UserRecentEventsFinder do
expect(events.size).to eq(6)
end
+ context 'selected events' do
+ let!(:push_event) { create(:push_event, project: public_project, author: project_owner) }
+ let!(:push_event_second_user) { create(:push_event, project: public_project_second_user, author: second_user) }
+
+ it 'only includes selected events (PUSH) from all users', :aggregate_failures do
+ event_filter = EventFilter.new(EventFilter::PUSH)
+ events = described_class.new(current_user, [project_owner, second_user], event_filter, params).execute
+
+ expect(events).to contain_exactly(push_event, push_event_second_user)
+ end
+ end
+
it 'does not include events from users with private profile', :aggregate_failures do
allow(Ability).to receive(:allowed?).and_call_original
allow(Ability).to receive(:allowed?).with(current_user, :read_user_profile, second_user).and_return(false)
events = described_class.new(current_user, [project_owner, second_user], nil, params).execute
- expect(events).to include(private_event, internal_event, public_event)
- expect(events.size).to eq(3)
+ expect(events).to contain_exactly(private_event, internal_event, public_event)
+ end
+
+ context 'with pagination params' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:limit, :offset, :ordered_expected_events) do
+ nil | nil | lazy { [public_event_second_user, internal_event_second_user, private_event_second_user, public_event, internal_event, private_event] }
+ 2 | nil | lazy { [public_event_second_user, internal_event_second_user] }
+ nil | 4 | lazy { [internal_event, private_event] }
+ 2 | 2 | lazy { [private_event_second_user, public_event] }
+ end
+
+ with_them do
+ let(:params) { { limit: limit, offset: offset }.compact }
+
+ it 'returns paginated events sorted by id (DESC)' do
+ events = described_class.new(current_user, [project_owner, second_user], nil, params).execute
+
+ expect(events).to eq(ordered_expected_events)
+ end
+ end
end
end
diff --git a/spec/fixtures/api/schemas/graphql/packages/package_details.json b/spec/fixtures/api/schemas/graphql/packages/package_details.json
index 9ef7f6c9271..50e52a7bb87 100644
--- a/spec/fixtures/api/schemas/graphql/packages/package_details.json
+++ b/spec/fixtures/api/schemas/graphql/packages/package_details.json
@@ -149,6 +149,30 @@
}
}
}
+ },
+ "npmUrl": {
+ "type": "string"
+ },
+ "mavenUrl": {
+ "type": "string"
+ },
+ "conanUrl": {
+ "type": "string"
+ },
+ "nugetUrl": {
+ "type": "string"
+ },
+ "pypiUrl": {
+ "type": "string"
+ },
+ "pypiSetupUrl": {
+ "type": "string"
+ },
+ "composerUrl": {
+ "type": "string"
+ },
+ "composerConfigRepositoryUrl": {
+ "type": "string"
}
}
}
diff --git a/spec/fixtures/api/schemas/public_api/v4/merge_request.json b/spec/fixtures/api/schemas/public_api/v4/merge_request.json
index c31e91cfef8..a55c4b8974b 100644
--- a/spec/fixtures/api/schemas/public_api/v4/merge_request.json
+++ b/spec/fixtures/api/schemas/public_api/v4/merge_request.json
@@ -20,6 +20,18 @@
},
"additionalProperties": false
},
+ "merge_user": {
+ "type": ["object", "null"],
+ "properties": {
+ "name": { "type": "string" },
+ "username": { "type": "string" },
+ "id": { "type": "integer" },
+ "state": { "type": "string" },
+ "avatar_url": { "type": "uri" },
+ "web_url": { "type": "uri" }
+ },
+ "additionalProperties": false
+ },
"merged_at": { "type": ["string", "null"] },
"closed_by": {
"type": ["object", "null"],
diff --git a/spec/fixtures/ci_secure_files/upload-keystore.jks b/spec/fixtures/ci_secure_files/upload-keystore.jks
new file mode 100644
index 00000000000..715adad4a89
--- /dev/null
+++ b/spec/fixtures/ci_secure_files/upload-keystore.jks
Binary files differ
diff --git a/spec/fixtures/error_tracking/go_two_exception_event.json b/spec/fixtures/error_tracking/go_two_exception_event.json
new file mode 100644
index 00000000000..97ed8372a27
--- /dev/null
+++ b/spec/fixtures/error_tracking/go_two_exception_event.json
@@ -0,0 +1 @@
+{"contexts":{"device":{"arch":"amd64","num_cpu":16},"os":{"name":"darwin"},"runtime":{"go_maxprocs":16,"go_numcgocalls":1,"go_numroutines":2,"name":"go","version":"go1.16.10"}},"event_id":"f92492349cda4ceaba1aab9dac55a412","level":"error","platform":"go","release":"v0.12.0-1-g6b72962","sdk":{"name":"sentry.go","version":"0.12.0","integrations":["ContextifyFrames","Environment","IgnoreErrors","Modules"],"packages":[{"name":"sentry-go","version":"0.12.0"}]},"server_name":"jet.fios-router.home","user":{},"modules":{"github.com/getsentry/sentry-go":"(devel)","golang.org/x/sys":"v0.0.0-20211007075335-d3039528d8ac"},"exception":[{"type":"*errors.errorString","value":"unsupported protocol scheme \"\""},{"type":"*url.Error","value":"Get \"foobar\": unsupported protocol scheme \"\"","stacktrace":{"frames":[{"function":"main","module":"main","abs_path":"/Users/stanhu/github/sentry-go/example/basic/main.go","lineno":54,"pre_context":["\t// Set the timeout to the maximum duration the program can afford to wait.","\tdefer sentry.Flush(2 * time.Second)","","\tresp, err := http.Get(os.Args[1])","\tif err != nil {"],"context_line":"\t\tsentry.CaptureException(err)","post_context":["\t\tlog.Printf(\"reported to Sentry: %s\", err)","\t\treturn","\t}","\tdefer resp.Body.Close()",""],"in_app":true}]}}],"timestamp":"2021-12-25T22:32:06.191665-08:00"}
diff --git a/spec/fixtures/security_reports/master/gl-sast-report.json b/spec/fixtures/security_reports/master/gl-sast-report.json
index 3323c1fffe3..63504e6fccc 100644
--- a/spec/fixtures/security_reports/master/gl-sast-report.json
+++ b/spec/fixtures/security_reports/master/gl-sast-report.json
@@ -26,6 +26,16 @@
"value": "PREDICTABLE_RANDOM",
"url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM"
}
+ ],
+ "links": [
+ {
+ "name": "Link1",
+ "url": "https://www.url1.com"
+ },
+ {
+ "name": "Link2",
+ "url": "https://www.url2.com"
+ }
]
},
{
diff --git a/spec/frontend/__helpers__/matchers.js b/spec/frontend/__helpers__/matchers.js
deleted file mode 100644
index 945abdafe9a..00000000000
--- a/spec/frontend/__helpers__/matchers.js
+++ /dev/null
@@ -1,68 +0,0 @@
-export default {
- toHaveSpriteIcon: (element, iconName) => {
- if (!iconName) {
- throw new Error('toHaveSpriteIcon is missing iconName argument!');
- }
-
- if (!(element instanceof HTMLElement)) {
- throw new Error(`${element} is not a DOM element!`);
- }
-
- const iconReferences = [].slice.apply(element.querySelectorAll('svg use'));
- const matchingIcon = iconReferences.find(
- (reference) => reference.parentNode.getAttribute('data-testid') === `${iconName}-icon`,
- );
-
- const pass = Boolean(matchingIcon);
-
- let message;
- if (pass) {
- message = `${element.outerHTML} contains the sprite icon "${iconName}"!`;
- } else {
- message = `${element.outerHTML} does not contain the sprite icon "${iconName}"!`;
-
- const existingIcons = iconReferences.map((reference) => {
- const iconUrl = reference.getAttribute('href');
- return `"${iconUrl.replace(/^.+#/, '')}"`;
- });
- if (existingIcons.length > 0) {
- message += ` (only found ${existingIcons.join(',')})`;
- }
- }
-
- return {
- pass,
- message: () => message,
- };
- },
- toMatchInterpolatedText(received, match) {
- let clearReceived;
- let clearMatch;
-
- try {
- clearReceived = received.replace(/\s\s+/gm, ' ').replace(/\s\./gm, '.').trim();
- } catch (e) {
- return { actual: received, message: 'The received value is not a string', pass: false };
- }
- try {
- clearMatch = match.replace(/%{\w+}/gm, '').trim();
- } catch (e) {
- return { message: 'The comparator value is not a string', pass: false };
- }
- const pass = clearReceived === clearMatch;
- const message = pass
- ? () => `
- \n\n
- Expected: ${this.utils.printExpected(clearReceived)}
- To not equal: ${this.utils.printReceived(clearMatch)}
- `
- : () =>
- `
- \n\n
- Expected: ${this.utils.printExpected(clearReceived)}
- To equal: ${this.utils.printReceived(clearMatch)}
- `;
-
- return { actual: received, message, pass };
- },
-};
diff --git a/spec/frontend/__helpers__/matchers/index.js b/spec/frontend/__helpers__/matchers/index.js
new file mode 100644
index 00000000000..76571bafb06
--- /dev/null
+++ b/spec/frontend/__helpers__/matchers/index.js
@@ -0,0 +1,3 @@
+export * from './to_have_sprite_icon';
+export * from './to_have_tracking_attributes';
+export * from './to_match_interpolated_text';
diff --git a/spec/frontend/__helpers__/matchers/to_have_sprite_icon.js b/spec/frontend/__helpers__/matchers/to_have_sprite_icon.js
new file mode 100644
index 00000000000..bce9d93bea8
--- /dev/null
+++ b/spec/frontend/__helpers__/matchers/to_have_sprite_icon.js
@@ -0,0 +1,36 @@
+export const toHaveSpriteIcon = (element, iconName) => {
+ if (!iconName) {
+ throw new Error('toHaveSpriteIcon is missing iconName argument!');
+ }
+
+ if (!(element instanceof HTMLElement)) {
+ throw new Error(`${element} is not a DOM element!`);
+ }
+
+ const iconReferences = [].slice.apply(element.querySelectorAll('svg use'));
+ const matchingIcon = iconReferences.find(
+ (reference) => reference.parentNode.getAttribute('data-testid') === `${iconName}-icon`,
+ );
+
+ const pass = Boolean(matchingIcon);
+
+ let message;
+ if (pass) {
+ message = `${element.outerHTML} contains the sprite icon "${iconName}"!`;
+ } else {
+ message = `${element.outerHTML} does not contain the sprite icon "${iconName}"!`;
+
+ const existingIcons = iconReferences.map((reference) => {
+ const iconUrl = reference.getAttribute('href');
+ return `"${iconUrl.replace(/^.+#/, '')}"`;
+ });
+ if (existingIcons.length > 0) {
+ message += ` (only found ${existingIcons.join(',')})`;
+ }
+ }
+
+ return {
+ pass,
+ message: () => message,
+ };
+};
diff --git a/spec/frontend/__helpers__/matchers/to_have_tracking_attributes.js b/spec/frontend/__helpers__/matchers/to_have_tracking_attributes.js
new file mode 100644
index 00000000000..fd3f3aa042f
--- /dev/null
+++ b/spec/frontend/__helpers__/matchers/to_have_tracking_attributes.js
@@ -0,0 +1,35 @@
+import { diff } from 'jest-diff';
+import { isObject, mapValues, isEqual } from 'lodash';
+
+export const toHaveTrackingAttributes = (actual, obj) => {
+ if (!(actual instanceof Element)) {
+ return { actual, message: () => 'The received value must be an Element.', pass: false };
+ }
+
+ if (!isObject(obj)) {
+ return {
+ message: () => `The matching object must be an object. Found ${obj}.`,
+ pass: false,
+ };
+ }
+
+ const actualAttributes = mapValues(obj, (val, key) => actual.getAttribute(`data-track-${key}`));
+
+ const matcherPass = isEqual(actualAttributes, obj);
+
+ const failMessage = () => {
+ // We can match, but still fail because we're in a `expect...not.` context
+ if (matcherPass) {
+ return `Expected the element's tracking attributes not to match. Found that they matched ${JSON.stringify(
+ obj,
+ )}.`;
+ }
+
+ const objDiff = diff(actualAttributes, obj);
+ return `Expected the element's tracking attributes to match the given object. Diff:
+${objDiff}
+`;
+ };
+
+ return { actual, message: failMessage, pass: matcherPass };
+};
diff --git a/spec/frontend/__helpers__/matchers/to_have_tracking_attributes_spec.js b/spec/frontend/__helpers__/matchers/to_have_tracking_attributes_spec.js
new file mode 100644
index 00000000000..74073ed4063
--- /dev/null
+++ b/spec/frontend/__helpers__/matchers/to_have_tracking_attributes_spec.js
@@ -0,0 +1,65 @@
+import { diff } from 'jest-diff';
+
+describe('custom matcher toHaveTrackingAttributes', () => {
+ const createElementWithAttrs = (attributes) => {
+ const el = document.createElement('div');
+
+ Object.entries(attributes).forEach(([key, value]) => {
+ el.setAttribute(key, value);
+ });
+
+ return el;
+ };
+
+ it('blows up if actual is not an element', () => {
+ expect(() => {
+ expect({}).toHaveTrackingAttributes({});
+ }).toThrow('The received value must be an Element.');
+ });
+
+ it('blows up if expected is not an object', () => {
+ expect(() => {
+ expect(createElementWithAttrs({})).toHaveTrackingAttributes('foo');
+ }).toThrow('The matching object must be an object.');
+ });
+
+ it('prints diff when fails', () => {
+ const expectedDiff = diff({ label: 'foo' }, { label: 'a' });
+ expect(() => {
+ expect(createElementWithAttrs({ 'data-track-label': 'foo' })).toHaveTrackingAttributes({
+ label: 'a',
+ });
+ }).toThrow(
+ `Expected the element's tracking attributes to match the given object. Diff:\n${expectedDiff}\n`,
+ );
+ });
+
+ describe('positive assertions', () => {
+ it.each`
+ attrs | expected
+ ${{ 'data-track-label': 'foo' }} | ${{ label: 'foo' }}
+ ${{ 'data-track-label': 'foo' }} | ${{}}
+ ${{ 'data-track-label': 'foo', label: 'bar' }} | ${{ label: 'foo' }}
+ ${{ 'data-track-label': 'foo', 'data-track-extra': '123' }} | ${{ label: 'foo', extra: '123' }}
+ ${{ 'data-track-label': 'foo', 'data-track-extra': '123' }} | ${{ extra: '123' }}
+ ${{ label: 'foo', extra: '123', id: '7' }} | ${{}}
+ `('$expected matches element with attrs $attrs', ({ attrs, expected }) => {
+ expect(createElementWithAttrs(attrs)).toHaveTrackingAttributes(expected);
+ });
+ });
+
+ describe('negative assertions', () => {
+ it.each`
+ attrs | expected
+ ${{}} | ${{ label: 'foo' }}
+ ${{ label: 'foo' }} | ${{ label: 'foo' }}
+ ${{ 'data-track-label': 'bar', label: 'foo' }} | ${{ label: 'foo' }}
+ ${{ 'data-track-label': 'foo' }} | ${{ extra: '123' }}
+ ${{ 'data-track-label': 'foo', 'data-track-extra': '123' }} | ${{ label: 'foo', extra: '456' }}
+ ${{ 'data-track-label': 'foo', 'data-track-extra': '123' }} | ${{ label: 'foo', extra: '123', action: 'click' }}
+ ${{ label: 'foo', extra: '123', id: '7' }} | ${{ id: '7' }}
+ `('$expected does not match element with attrs $attrs', ({ attrs, expected }) => {
+ expect(createElementWithAttrs(attrs)).not.toHaveTrackingAttributes(expected);
+ });
+ });
+});
diff --git a/spec/frontend/__helpers__/matchers/to_match_interpolated_text.js b/spec/frontend/__helpers__/matchers/to_match_interpolated_text.js
new file mode 100644
index 00000000000..4ce814a01b4
--- /dev/null
+++ b/spec/frontend/__helpers__/matchers/to_match_interpolated_text.js
@@ -0,0 +1,30 @@
+export const toMatchInterpolatedText = (received, match) => {
+ let clearReceived;
+ let clearMatch;
+
+ try {
+ clearReceived = received.replace(/\s\s+/gm, ' ').replace(/\s\./gm, '.').trim();
+ } catch (e) {
+ return { actual: received, message: 'The received value is not a string', pass: false };
+ }
+ try {
+ clearMatch = match.replace(/%{\w+}/gm, '').trim();
+ } catch (e) {
+ return { message: 'The comparator value is not a string', pass: false };
+ }
+ const pass = clearReceived === clearMatch;
+ const message = pass
+ ? () => `
+ \n\n
+ Expected: ${this.utils.printExpected(clearReceived)}
+ To not equal: ${this.utils.printReceived(clearMatch)}
+ `
+ : () =>
+ `
+ \n\n
+ Expected: ${this.utils.printExpected(clearReceived)}
+ To equal: ${this.utils.printReceived(clearMatch)}
+ `;
+
+ return { actual: received, message, pass };
+};
diff --git a/spec/frontend/__helpers__/matchers/to_match_interpolated_text_spec.js b/spec/frontend/__helpers__/matchers/to_match_interpolated_text_spec.js
new file mode 100644
index 00000000000..f6fd00011fe
--- /dev/null
+++ b/spec/frontend/__helpers__/matchers/to_match_interpolated_text_spec.js
@@ -0,0 +1,46 @@
+describe('custom matcher toMatchInterpolatedText', () => {
+ describe('malformed input', () => {
+ it.each([null, 1, Symbol, Array, Object])(
+ 'fails graciously if the expected value is %s',
+ (expected) => {
+ expect(expected).not.toMatchInterpolatedText('null');
+ },
+ );
+ });
+ describe('malformed matcher', () => {
+ it.each([null, 1, Symbol, Array, Object])(
+ 'fails graciously if the matcher is %s',
+ (matcher) => {
+ expect('null').not.toMatchInterpolatedText(matcher);
+ },
+ );
+ });
+
+ describe('positive assertion', () => {
+ it.each`
+ htmlString | templateString
+ ${'foo'} | ${'foo'}
+ ${'foo'} | ${'foo%{foo}'}
+ ${'foo '} | ${'foo'}
+ ${'foo '} | ${'foo%{foo}'}
+ ${'foo . '} | ${'foo%{foo}.'}
+ ${'foo bar . '} | ${'foo%{foo} bar.'}
+ ${'foo\n\nbar . '} | ${'foo%{foo} bar.'}
+ ${'foo bar . .'} | ${'foo%{fooStart} bar.%{fooEnd}.'}
+ `('$htmlString equals $templateString', ({ htmlString, templateString }) => {
+ expect(htmlString).toMatchInterpolatedText(templateString);
+ });
+ });
+
+ describe('negative assertion', () => {
+ it.each`
+ htmlString | templateString
+ ${'foo'} | ${'bar'}
+ ${'foo'} | ${'bar%{foo}'}
+ ${'foo'} | ${'@{lol}foo%{foo}'}
+ ${' fo o '} | ${'foo'}
+ `('$htmlString does not equal $templateString', ({ htmlString, templateString }) => {
+ expect(htmlString).not.toMatchInterpolatedText(templateString);
+ });
+ });
+});
diff --git a/spec/frontend/__helpers__/matchers_spec.js b/spec/frontend/__helpers__/matchers_spec.js
deleted file mode 100644
index dfd6f754c72..00000000000
--- a/spec/frontend/__helpers__/matchers_spec.js
+++ /dev/null
@@ -1,48 +0,0 @@
-describe('Custom jest matchers', () => {
- describe('toMatchInterpolatedText', () => {
- describe('malformed input', () => {
- it.each([null, 1, Symbol, Array, Object])(
- 'fails graciously if the expected value is %s',
- (expected) => {
- expect(expected).not.toMatchInterpolatedText('null');
- },
- );
- });
- describe('malformed matcher', () => {
- it.each([null, 1, Symbol, Array, Object])(
- 'fails graciously if the matcher is %s',
- (matcher) => {
- expect('null').not.toMatchInterpolatedText(matcher);
- },
- );
- });
-
- describe('positive assertion', () => {
- it.each`
- htmlString | templateString
- ${'foo'} | ${'foo'}
- ${'foo'} | ${'foo%{foo}'}
- ${'foo '} | ${'foo'}
- ${'foo '} | ${'foo%{foo}'}
- ${'foo . '} | ${'foo%{foo}.'}
- ${'foo bar . '} | ${'foo%{foo} bar.'}
- ${'foo\n\nbar . '} | ${'foo%{foo} bar.'}
- ${'foo bar . .'} | ${'foo%{fooStart} bar.%{fooEnd}.'}
- `('$htmlString equals $templateString', ({ htmlString, templateString }) => {
- expect(htmlString).toMatchInterpolatedText(templateString);
- });
- });
-
- describe('negative assertion', () => {
- it.each`
- htmlString | templateString
- ${'foo'} | ${'bar'}
- ${'foo'} | ${'bar%{foo}'}
- ${'foo'} | ${'@{lol}foo%{foo}'}
- ${' fo o '} | ${'foo'}
- `('$htmlString does not equal $templateString', ({ htmlString, templateString }) => {
- expect(htmlString).not.toMatchInterpolatedText(templateString);
- });
- });
- });
-});
diff --git a/spec/frontend/__helpers__/shared_test_setup.js b/spec/frontend/__helpers__/shared_test_setup.js
index 03389e16b65..7b5df18ee0f 100644
--- a/spec/frontend/__helpers__/shared_test_setup.js
+++ b/spec/frontend/__helpers__/shared_test_setup.js
@@ -8,7 +8,7 @@ import setWindowLocation from './set_window_location_helper';
import { setGlobalDateToFakeDate } from './fake_date';
import { loadHTMLFixture, setHTMLFixture } from './fixtures';
import { TEST_HOST } from './test_constants';
-import customMatchers from './matchers';
+import * as customMatchers from './matchers';
import './dom_shims';
import './jquery';
diff --git a/spec/frontend/__helpers__/wait_using_real_timer.js b/spec/frontend/__helpers__/wait_using_real_timer.js
deleted file mode 100644
index 110d5f46c08..00000000000
--- a/spec/frontend/__helpers__/wait_using_real_timer.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/* useful for timing promises when jest fakeTimers are not reliable enough */
-export default (timeout) =>
- new Promise((resolve) => {
- jest.useRealTimers();
- setTimeout(resolve, timeout);
- jest.useFakeTimers();
- });
diff --git a/spec/frontend/alerts_settings/components/alerts_settings_form_spec.js b/spec/frontend/alerts_settings/components/alerts_settings_form_spec.js
index bdc1dde7d48..018303fcae7 100644
--- a/spec/frontend/alerts_settings/components/alerts_settings_form_spec.js
+++ b/spec/frontend/alerts_settings/components/alerts_settings_form_spec.js
@@ -319,6 +319,8 @@ describe('AlertsSettingsForm', () => {
const validPayloadMsg = payload === emptySamplePayload ? 'not valid' : 'valid';
it(`textarea should be ${enabledState} when payload reset ${payloadResetMsg} and payload is ${validPayloadMsg}`, async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
currentIntegration: { payloadExample: payload },
resetPayloadAndMappingConfirmed,
@@ -345,6 +347,8 @@ describe('AlertsSettingsForm', () => {
: 'was not confirmed';
it(`shows ${caption} button when sample payload ${samplePayloadMsg} and payload reset ${payloadResetMsg}`, async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
currentIntegration: {
payloadExample,
@@ -359,6 +363,8 @@ describe('AlertsSettingsForm', () => {
describe('Parsing payload', () => {
beforeEach(() => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
resetPayloadAndMappingConfirmed: true,
});
@@ -456,6 +462,8 @@ describe('AlertsSettingsForm', () => {
});
it('should be able to submit when form is dirty', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
currentIntegration: { type: typeSet.http, name: 'Existing integration' },
});
@@ -466,6 +474,8 @@ describe('AlertsSettingsForm', () => {
});
it('should not be able to submit when form is pristine', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
currentIntegration: { type: typeSet.http, name: 'Existing integration' },
});
diff --git a/spec/frontend/analytics/shared/components/projects_dropdown_filter_spec.js b/spec/frontend/analytics/shared/components/projects_dropdown_filter_spec.js
index 5d681c7da4f..28d7ebe28df 100644
--- a/spec/frontend/analytics/shared/components/projects_dropdown_filter_spec.js
+++ b/spec/frontend/analytics/shared/components/projects_dropdown_filter_spec.js
@@ -126,6 +126,8 @@ describe('ProjectsDropdownFilter component', () => {
});
it('applies the correct queryParams when making an api call', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ searchTerm: 'gitlab' });
expect(spyQuery).toHaveBeenCalledTimes(1);
@@ -204,6 +206,8 @@ describe('ProjectsDropdownFilter component', () => {
await createWithMockDropdown({ multiSelect: true });
selectDropdownItemAtIndex(0);
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ searchTerm: 'this is a very long search string' });
});
diff --git a/spec/frontend/api/packages_api_spec.js b/spec/frontend/api/packages_api_spec.js
index 3286dccb1b2..d55d2036dcf 100644
--- a/spec/frontend/api/packages_api_spec.js
+++ b/spec/frontend/api/packages_api_spec.js
@@ -38,12 +38,17 @@ describe('Api', () => {
mock.onPut(expectedUrl).replyOnce(httpStatus.OK, apiResponse);
return publishPackage(
- { projectPath, name, version: 0, fileName: name, files: [{}] },
+ {
+ projectPath,
+ name,
+ version: 0,
+ fileName: name,
+ files: [new File(['zip contents'], 'bar.zip')],
+ },
{ status: 'hidden', select: 'package_file' },
).then(({ data }) => {
expect(data).toEqual(apiResponse);
- expect(axios.put).toHaveBeenCalledWith(expectedUrl, expect.any(FormData), {
- headers: { 'Content-Type': 'multipart/form-data' },
+ expect(axios.put).toHaveBeenCalledWith(expectedUrl, expect.any(File), {
params: { select: 'package_file', status: 'hidden' },
});
});
diff --git a/spec/frontend/behaviors/copy_to_clipboard_spec.js b/spec/frontend/behaviors/copy_to_clipboard_spec.js
new file mode 100644
index 00000000000..c5beaa0ba5d
--- /dev/null
+++ b/spec/frontend/behaviors/copy_to_clipboard_spec.js
@@ -0,0 +1,187 @@
+import initCopyToClipboard, {
+ CLIPBOARD_SUCCESS_EVENT,
+ CLIPBOARD_ERROR_EVENT,
+ I18N_ERROR_MESSAGE,
+} from '~/behaviors/copy_to_clipboard';
+import { show, hide, fixTitle, once } from '~/tooltips';
+
+let onceCallback = () => {};
+jest.mock('~/tooltips', () => ({
+ show: jest.fn(),
+ hide: jest.fn(),
+ fixTitle: jest.fn(),
+ once: jest.fn((event, callback) => {
+ onceCallback = callback;
+ }),
+}));
+
+describe('initCopyToClipboard', () => {
+ let clearSelection;
+ let focusSpy;
+ let dispatchEventSpy;
+ let button;
+ let clipboardInstance;
+
+ afterEach(() => {
+ document.body.innerHTML = '';
+ clipboardInstance = null;
+ });
+
+ const title = 'Copy this value';
+ const defaultButtonAttributes = {
+ 'data-clipboard-text': 'foo bar',
+ title,
+ 'data-title': title,
+ };
+ const createButton = (attributes = {}) => {
+ const combinedAttributes = { ...defaultButtonAttributes, ...attributes };
+ button = document.createElement('button');
+ Object.keys(combinedAttributes).forEach((attributeName) => {
+ button.setAttribute(attributeName, combinedAttributes[attributeName]);
+ });
+ document.body.appendChild(button);
+ };
+
+ const init = () => {
+ clipboardInstance = initCopyToClipboard();
+ };
+
+ const setupSpies = () => {
+ clearSelection = jest.fn();
+ focusSpy = jest.spyOn(button, 'focus');
+ dispatchEventSpy = jest.spyOn(button, 'dispatchEvent');
+ };
+
+ const emitSuccessEvent = () => {
+ clipboardInstance.emit('success', {
+ action: 'copy',
+ text: 'foo bar',
+ trigger: button,
+ clearSelection,
+ });
+ };
+
+ const emitErrorEvent = () => {
+ clipboardInstance.emit('error', {
+ action: 'copy',
+ text: 'foo bar',
+ trigger: button,
+ clearSelection,
+ });
+ };
+
+ const itHandlesTooltip = (expectedTooltip) => {
+ it('handles tooltip', () => {
+ expect(button.getAttribute('title')).toBe(expectedTooltip);
+ expect(button.getAttribute('aria-label')).toBe(expectedTooltip);
+ expect(fixTitle).toHaveBeenCalledWith(button);
+ expect(show).toHaveBeenCalledWith(button);
+ expect(once).toHaveBeenCalledWith('hidden', expect.any(Function));
+
+ expect(hide).not.toHaveBeenCalled();
+ jest.runAllTimers();
+ expect(hide).toHaveBeenCalled();
+
+ onceCallback({ target: button });
+ expect(button.getAttribute('title')).toBe(title);
+ expect(button.getAttribute('aria-label')).toBe(title);
+ expect(fixTitle).toHaveBeenCalledWith(button);
+ });
+ };
+
+ describe('when value is successfully copied', () => {
+ it(`calls clearSelection, focuses the button, and dispatches ${CLIPBOARD_SUCCESS_EVENT} event`, () => {
+ createButton();
+ init();
+ setupSpies();
+ emitSuccessEvent();
+
+ expect(clearSelection).toHaveBeenCalled();
+ expect(focusSpy).toHaveBeenCalled();
+ expect(dispatchEventSpy).toHaveBeenCalledWith(new Event(CLIPBOARD_SUCCESS_EVENT));
+ });
+
+ describe('when `data-clipboard-handle-tooltip` is set to `false`', () => {
+ beforeEach(() => {
+ createButton({
+ 'data-clipboard-handle-tooltip': 'false',
+ });
+ init();
+ emitSuccessEvent();
+ });
+
+ it('does not handle success tooltip', () => {
+ expect(show).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('when `data-clipboard-handle-tooltip` is set to `true`', () => {
+ beforeEach(() => {
+ createButton({
+ 'data-clipboard-handle-tooltip': 'true',
+ });
+ init();
+ emitSuccessEvent();
+ });
+
+ itHandlesTooltip('Copied');
+ });
+
+ describe('when `data-clipboard-handle-tooltip` is not set', () => {
+ beforeEach(() => {
+ createButton();
+ init();
+ emitSuccessEvent();
+ });
+
+ itHandlesTooltip('Copied');
+ });
+ });
+
+ describe('when there is an error copying the value', () => {
+ it(`dispatches ${CLIPBOARD_ERROR_EVENT} event`, () => {
+ createButton();
+ init();
+ setupSpies();
+ emitErrorEvent();
+
+ expect(dispatchEventSpy).toHaveBeenCalledWith(new Event(CLIPBOARD_ERROR_EVENT));
+ });
+
+ describe('when `data-clipboard-handle-tooltip` is set to `false`', () => {
+ beforeEach(() => {
+ createButton({
+ 'data-clipboard-handle-tooltip': 'false',
+ });
+ init();
+ emitErrorEvent();
+ });
+
+ it('does not handle error tooltip', () => {
+ expect(show).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('when `data-clipboard-handle-tooltip` is set to `true`', () => {
+ beforeEach(() => {
+ createButton({
+ 'data-clipboard-handle-tooltip': 'true',
+ });
+ init();
+ emitErrorEvent();
+ });
+
+ itHandlesTooltip(I18N_ERROR_MESSAGE);
+ });
+
+ describe('when `data-clipboard-handle-tooltip` is not set', () => {
+ beforeEach(() => {
+ createButton();
+ init();
+ emitErrorEvent();
+ });
+
+ itHandlesTooltip(I18N_ERROR_MESSAGE);
+ });
+ });
+});
diff --git a/spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap b/spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap
index 46a5631b028..d698ee72ea4 100644
--- a/spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap
+++ b/spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap
@@ -20,12 +20,6 @@ exports[`Blob Header Filepath rendering matches the snapshot 1`] = `
foo/bar/dummy.md
</strong>
- <small
- class="mr-2"
- >
- a lot
- </small>
-
<clipboard-button-stub
category="tertiary"
cssclass="btn-clipboard btn-transparent lh-100 position-static"
@@ -36,5 +30,13 @@ exports[`Blob Header Filepath rendering matches the snapshot 1`] = `
tooltipplacement="top"
variant="default"
/>
+
+ <small
+ class="mr-2"
+ >
+ a lot
+ </small>
+
+ <!---->
</div>
`;
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 db9684239a1..22bec77276b 100644
--- a/spec/frontend/blob/components/__snapshots__/blob_header_spec.js.snap
+++ b/spec/frontend/blob/components/__snapshots__/blob_header_spec.js.snap
@@ -17,7 +17,7 @@ exports[`Blob Header Default Actions rendering matches the snapshot 1`] = `
</div>
<div
- class="gl-display-none gl-sm-display-flex"
+ class="gl-sm-display-flex file-actions"
>
<viewer-switcher-stub
value="simple"
diff --git a/spec/frontend/blob/components/blob_edit_header_spec.js b/spec/frontend/blob/components/blob_edit_header_spec.js
index ac3080c65a5..910fc5c946d 100644
--- a/spec/frontend/blob/components/blob_edit_header_spec.js
+++ b/spec/frontend/blob/components/blob_edit_header_spec.js
@@ -44,6 +44,8 @@ describe('Blob Header Editing', () => {
const inputComponent = wrapper.find(GlFormInput);
const newValue = 'bar.txt';
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
name: newValue,
});
diff --git a/spec/frontend/blob/components/blob_header_filepath_spec.js b/spec/frontend/blob/components/blob_header_filepath_spec.js
index d935f73c0d1..8220b598ff6 100644
--- a/spec/frontend/blob/components/blob_header_filepath_spec.js
+++ b/spec/frontend/blob/components/blob_header_filepath_spec.js
@@ -1,3 +1,4 @@
+import { GlBadge } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import BlobHeaderFilepath from '~/blob/components/blob_header_filepath.vue';
import { numberToHumanSize } from '~/lib/utils/number_utils';
@@ -24,6 +25,8 @@ describe('Blob Header Filepath', () => {
wrapper.destroy();
});
+ const findBadge = () => wrapper.find(GlBadge);
+
describe('rendering', () => {
it('matches the snapshot', () => {
createComponent();
@@ -54,6 +57,11 @@ describe('Blob Header Filepath', () => {
expect(wrapper.vm.blobSize).toBe('a lot');
});
+ it('renders LFS badge if LFS if enabled', () => {
+ createComponent({ storedExternally: true, externalStorage: 'lfs' });
+ expect(findBadge().text()).toBe('LFS');
+ });
+
it('renders a slot and prepends its contents to the existing one', () => {
const slotContent = 'Foo Bar';
createComponent(
diff --git a/spec/frontend/blob/line_highlighter_spec.js b/spec/frontend/blob/line_highlighter_spec.js
new file mode 100644
index 00000000000..330f1f3137e
--- /dev/null
+++ b/spec/frontend/blob/line_highlighter_spec.js
@@ -0,0 +1,275 @@
+/* eslint-disable no-return-assign, no-new, no-underscore-dangle */
+
+import $ from 'jquery';
+import LineHighlighter from '~/blob/line_highlighter';
+import * as utils from '~/lib/utils/common_utils';
+
+describe('LineHighlighter', () => {
+ const testContext = {};
+
+ const clickLine = (number, eventData = {}) => {
+ if ($.isEmptyObject(eventData)) {
+ return $(`#L${number}`).click();
+ }
+ const e = $.Event('click', eventData);
+ return $(`#L${number}`).trigger(e);
+ };
+ beforeEach(() => {
+ loadFixtures('static/line_highlighter.html');
+ testContext.class = new LineHighlighter();
+ testContext.css = testContext.class.highlightLineClass;
+ return (testContext.spies = {
+ __setLocationHash__: jest
+ .spyOn(testContext.class, '__setLocationHash__')
+ .mockImplementation(() => {}),
+ });
+ });
+
+ describe('behavior', () => {
+ it('highlights one line given in the URL hash', () => {
+ new LineHighlighter({ hash: '#L13' });
+
+ expect($('#LC13')).toHaveClass(testContext.css);
+ });
+
+ it('highlights one line given in the URL hash with given CSS class name', () => {
+ const hiliter = new LineHighlighter({ hash: '#L13', highlightLineClass: 'hilite' });
+
+ expect(hiliter.highlightLineClass).toBe('hilite');
+ expect($('#LC13')).toHaveClass('hilite');
+ expect($('#LC13')).not.toHaveClass('hll');
+ });
+
+ it('highlights a range of lines given in the URL hash', () => {
+ new LineHighlighter({ hash: '#L5-25' });
+
+ expect($(`.${testContext.css}`).length).toBe(21);
+ for (let line = 5; line <= 25; line += 1) {
+ expect($(`#LC${line}`)).toHaveClass(testContext.css);
+ }
+ });
+
+ it('highlights a range of lines given in the URL hash using GitHub format', () => {
+ new LineHighlighter({ hash: '#L5-L25' });
+
+ expect($(`.${testContext.css}`).length).toBe(21);
+ for (let line = 5; line <= 25; line += 1) {
+ expect($(`#LC${line}`)).toHaveClass(testContext.css);
+ }
+ });
+
+ it('scrolls to the first highlighted line on initial load', () => {
+ jest.spyOn(utils, 'scrollToElement');
+ new LineHighlighter({ hash: '#L5-25' });
+
+ expect(utils.scrollToElement).toHaveBeenCalledWith('#L5', expect.anything());
+ });
+
+ it('discards click events', () => {
+ const clickSpy = jest.fn();
+
+ $('a[data-line-number]').click(clickSpy);
+
+ clickLine(13);
+
+ expect(clickSpy.mock.calls[0][0].isDefaultPrevented()).toEqual(true);
+ });
+
+ it('handles garbage input from the hash', () => {
+ const func = () => {
+ return new LineHighlighter({ fileHolderSelector: '#blob-content-holder' });
+ };
+
+ expect(func).not.toThrow();
+ });
+
+ it('handles hashchange event', () => {
+ const highlighter = new LineHighlighter();
+
+ jest.spyOn(highlighter, 'highlightHash').mockImplementation(() => {});
+
+ window.dispatchEvent(new Event('hashchange'), 'L15');
+
+ expect(highlighter.highlightHash).toHaveBeenCalled();
+ });
+ });
+
+ describe('clickHandler', () => {
+ it('handles clicking on a child icon element', () => {
+ const spy = jest.spyOn(testContext.class, 'setHash');
+ $('#L13 [data-testid="link-icon"]').mousedown().click();
+
+ expect(spy).toHaveBeenCalledWith(13);
+ expect($('#LC13')).toHaveClass(testContext.css);
+ });
+
+ describe('without shiftKey', () => {
+ it('highlights one line when clicked', () => {
+ clickLine(13);
+
+ expect($('#LC13')).toHaveClass(testContext.css);
+ });
+
+ it('unhighlights previously highlighted lines', () => {
+ clickLine(13);
+ clickLine(20);
+
+ expect($('#LC13')).not.toHaveClass(testContext.css);
+ expect($('#LC20')).toHaveClass(testContext.css);
+ });
+
+ it('sets the hash', () => {
+ const spy = jest.spyOn(testContext.class, 'setHash');
+ clickLine(13);
+
+ expect(spy).toHaveBeenCalledWith(13);
+ });
+ });
+
+ describe('with shiftKey', () => {
+ it('sets the hash', () => {
+ const spy = jest.spyOn(testContext.class, 'setHash');
+ clickLine(13);
+ clickLine(20, {
+ shiftKey: true,
+ });
+
+ expect(spy).toHaveBeenCalledWith(13);
+ expect(spy).toHaveBeenCalledWith(13, 20);
+ });
+
+ describe('without existing highlight', () => {
+ it('highlights the clicked line', () => {
+ clickLine(13, {
+ shiftKey: true,
+ });
+
+ expect($('#LC13')).toHaveClass(testContext.css);
+ expect($(`.${testContext.css}`).length).toBe(1);
+ });
+
+ it('sets the hash', () => {
+ const spy = jest.spyOn(testContext.class, 'setHash');
+ clickLine(13, {
+ shiftKey: true,
+ });
+
+ expect(spy).toHaveBeenCalledWith(13);
+ });
+ });
+
+ describe('with existing single-line highlight', () => {
+ it('uses existing line as last line when target is lesser', () => {
+ clickLine(20);
+ clickLine(15, {
+ shiftKey: true,
+ });
+
+ expect($(`.${testContext.css}`).length).toBe(6);
+ for (let line = 15; line <= 20; line += 1) {
+ expect($(`#LC${line}`)).toHaveClass(testContext.css);
+ }
+ });
+
+ it('uses existing line as first line when target is greater', () => {
+ clickLine(5);
+ clickLine(10, {
+ shiftKey: true,
+ });
+
+ expect($(`.${testContext.css}`).length).toBe(6);
+ for (let line = 5; line <= 10; line += 1) {
+ expect($(`#LC${line}`)).toHaveClass(testContext.css);
+ }
+ });
+ });
+
+ describe('with existing multi-line highlight', () => {
+ beforeEach(() => {
+ clickLine(10, {
+ shiftKey: true,
+ });
+ clickLine(13, {
+ shiftKey: true,
+ });
+ });
+
+ it('uses target as first line when it is less than existing first line', () => {
+ clickLine(5, {
+ shiftKey: true,
+ });
+
+ expect($(`.${testContext.css}`).length).toBe(6);
+ for (let line = 5; line <= 10; line += 1) {
+ expect($(`#LC${line}`)).toHaveClass(testContext.css);
+ }
+ });
+
+ it('uses target as last line when it is greater than existing first line', () => {
+ clickLine(15, {
+ shiftKey: true,
+ });
+
+ expect($(`.${testContext.css}`).length).toBe(6);
+ for (let line = 10; line <= 15; line += 1) {
+ expect($(`#LC${line}`)).toHaveClass(testContext.css);
+ }
+ });
+ });
+ });
+ });
+
+ describe('hashToRange', () => {
+ beforeEach(() => {
+ testContext.subject = testContext.class.hashToRange;
+ });
+
+ it('extracts a single line number from the hash', () => {
+ expect(testContext.subject('#L5')).toEqual([5, null]);
+ });
+
+ it('extracts a range of line numbers from the hash', () => {
+ expect(testContext.subject('#L5-15')).toEqual([5, 15]);
+ });
+
+ it('returns [null, null] when the hash is not a line number', () => {
+ expect(testContext.subject('#foo')).toEqual([null, null]);
+ });
+ });
+
+ describe('highlightLine', () => {
+ beforeEach(() => {
+ testContext.subject = testContext.class.highlightLine;
+ });
+
+ it('highlights the specified line', () => {
+ testContext.subject(13);
+
+ expect($('#LC13')).toHaveClass(testContext.css);
+ });
+
+ it('accepts a String-based number', () => {
+ testContext.subject('13');
+
+ expect($('#LC13')).toHaveClass(testContext.css);
+ });
+ });
+
+ describe('setHash', () => {
+ beforeEach(() => {
+ testContext.subject = testContext.class.setHash;
+ });
+
+ it('sets the location hash for a single line', () => {
+ testContext.subject(5);
+
+ expect(testContext.spies.__setLocationHash__).toHaveBeenCalledWith('#L5');
+ });
+
+ it('sets the location hash for a range', () => {
+ testContext.subject(5, 15);
+
+ expect(testContext.spies.__setLocationHash__).toHaveBeenCalledWith('#L5-15');
+ });
+ });
+});
diff --git a/spec/frontend/blob/viewer/index_spec.js b/spec/frontend/blob/viewer/index_spec.js
index 061ac7ad167..9e9f866d40c 100644
--- a/spec/frontend/blob/viewer/index_spec.js
+++ b/spec/frontend/blob/viewer/index_spec.js
@@ -21,6 +21,7 @@ describe('Blob viewer', () => {
setTestTimeout(2000);
beforeEach(() => {
+ window.gon.features = { refactorBlobViewer: false }; // This file is based on the old (non-refactored) blob viewer
jest.spyOn(window, 'requestIdleCallback').mockImplementation(execImmediately);
$.fn.extend(jQueryMock);
mock = new MockAdapter(axios);
diff --git a/spec/frontend/boards/components/board_card_spec.js b/spec/frontend/boards/components/board_card_spec.js
index 5742dfdc5d2..3af173aa18c 100644
--- a/spec/frontend/boards/components/board_card_spec.js
+++ b/spec/frontend/boards/components/board_card_spec.js
@@ -167,7 +167,7 @@ describe('Board card', () => {
mountComponent({ item: { ...mockIssue, isLoading: true } });
expect(wrapper.classes()).toContain('is-disabled');
- expect(wrapper.classes()).not.toContain('user-can-drag');
+ expect(wrapper.classes()).not.toContain('gl-cursor-grab');
});
});
@@ -177,7 +177,7 @@ describe('Board card', () => {
mountComponent();
expect(wrapper.classes()).not.toContain('is-disabled');
- expect(wrapper.classes()).toContain('user-can-drag');
+ expect(wrapper.classes()).toContain('gl-cursor-grab');
});
});
});
diff --git a/spec/frontend/boards/components/board_content_sidebar_spec.js b/spec/frontend/boards/components/board_content_sidebar_spec.js
index 7b176cea2a3..368c7d561f8 100644
--- a/spec/frontend/boards/components/board_content_sidebar_spec.js
+++ b/spec/frontend/boards/components/board_content_sidebar_spec.js
@@ -9,6 +9,7 @@ import BoardContentSidebar from '~/boards/components/board_content_sidebar.vue';
import BoardSidebarTitle from '~/boards/components/sidebar/board_sidebar_title.vue';
import { ISSUABLE } from '~/boards/constants';
import SidebarDateWidget from '~/sidebar/components/date/sidebar_date_widget.vue';
+import SidebarSeverity from '~/sidebar/components/severity/sidebar_severity.vue';
import SidebarSubscriptionsWidget from '~/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue';
import SidebarTodoWidget from '~/sidebar/components/todo_toggle/sidebar_todo_widget.vue';
import SidebarLabelsWidget from '~/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue';
@@ -96,7 +97,7 @@ describe('BoardContentSidebar', () => {
});
it('confirms we render MountingPortal', () => {
- expect(wrapper.find(MountingPortal).props()).toMatchObject({
+ expect(wrapper.findComponent(MountingPortal).props()).toMatchObject({
mountTo: '#js-right-sidebar-portal',
append: true,
name: 'board-content-sidebar',
@@ -141,6 +142,10 @@ describe('BoardContentSidebar', () => {
);
});
+ it('does not render SidebarSeverity', () => {
+ expect(wrapper.findComponent(SidebarSeverity).exists()).toBe(false);
+ });
+
describe('when we emit close', () => {
let toggleBoardItem;
@@ -160,4 +165,17 @@ describe('BoardContentSidebar', () => {
});
});
});
+
+ describe('incident sidebar', () => {
+ beforeEach(() => {
+ createStore({
+ mockGetters: { activeBoardItem: () => ({ ...mockIssue, epic: null, type: 'INCIDENT' }) },
+ });
+ createComponent();
+ });
+
+ it('renders SidebarSeverity', () => {
+ expect(wrapper.findComponent(SidebarSeverity).exists()).toBe(true);
+ });
+ });
});
diff --git a/spec/frontend/boards/components/board_filtered_search_spec.js b/spec/frontend/boards/components/board_filtered_search_spec.js
index ea551e94f2f..a8398a138ba 100644
--- a/spec/frontend/boards/components/board_filtered_search_spec.js
+++ b/spec/frontend/boards/components/board_filtered_search_spec.js
@@ -118,6 +118,7 @@ describe('BoardFilteredSearch', () => {
it('sets the url params to the correct results', async () => {
const mockFilters = [
{ type: 'author', value: { data: 'root', operator: '=' } },
+ { type: 'assignee', value: { data: 'root', operator: '=' } },
{ type: 'label', value: { data: 'label', operator: '=' } },
{ type: 'label', value: { data: 'label2', operator: '=' } },
{ type: 'milestone', value: { data: 'New Milestone', operator: '=' } },
@@ -133,7 +134,26 @@ describe('BoardFilteredSearch', () => {
title: '',
replace: true,
url:
- 'http://test.host/?author_username=root&label_name[]=label&label_name[]=label2&milestone_title=New+Milestone&iteration_id=3341&types=INCIDENT&weight=2&release_tag=v1.0.0',
+ 'http://test.host/?author_username=root&label_name[]=label&label_name[]=label2&assignee_username=root&milestone_title=New+Milestone&iteration_id=3341&types=INCIDENT&weight=2&release_tag=v1.0.0',
+ });
+ });
+
+ describe('when assignee is passed a wildcard value', () => {
+ const url = (arg) => `http://test.host/?assignee_id=${arg}`;
+
+ it.each([
+ ['None', url('None')],
+ ['Any', url('Any')],
+ ])('sets the url param %s', (assigneeParam, expected) => {
+ const mockFilters = [{ type: 'assignee', value: { data: assigneeParam, operator: '=' } }];
+ jest.spyOn(urlUtility, 'updateHistory');
+ findFilteredSearch().vm.$emit('onFilter', mockFilters);
+
+ expect(urlUtility.updateHistory).toHaveBeenCalledWith({
+ title: '',
+ replace: true,
+ url: expected,
+ });
});
});
});
diff --git a/spec/frontend/boards/components/board_list_header_spec.js b/spec/frontend/boards/components/board_list_header_spec.js
index 148d0c5684d..8cc0ad5f30c 100644
--- a/spec/frontend/boards/components/board_list_header_spec.js
+++ b/spec/frontend/boards/components/board_list_header_spec.js
@@ -180,18 +180,18 @@ describe('Board List Header Component', () => {
const canDragList = [ListType.label, ListType.milestone, ListType.iteration, ListType.assignee];
it.each(cannotDragList)(
- 'does not have user-can-drag-class so user cannot drag list',
+ 'does not have gl-cursor-grab class so user cannot drag list',
(listType) => {
createComponent({ listType });
- expect(findTitle().classes()).not.toContain('user-can-drag');
+ expect(findTitle().classes()).not.toContain('gl-cursor-grab');
},
);
- it.each(canDragList)('has user-can-drag-class so user can drag list', (listType) => {
+ it.each(canDragList)('has gl-cursor-grab class so user can drag list', (listType) => {
createComponent({ listType });
- expect(findTitle().classes()).toContain('user-can-drag');
+ expect(findTitle().classes()).toContain('gl-cursor-grab');
});
});
});
diff --git a/spec/frontend/boards/components/boards_selector_spec.js b/spec/frontend/boards/components/boards_selector_spec.js
index c841c17a029..9cf7c5774bf 100644
--- a/spec/frontend/boards/components/boards_selector_spec.js
+++ b/spec/frontend/boards/components/boards_selector_spec.js
@@ -96,6 +96,8 @@ describe('BoardsSelector', () => {
});
wrapper.vm.$apollo.addSmartQuery = jest.fn((_, options) => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
[options.loadingKey]: true,
});
@@ -161,6 +163,8 @@ describe('BoardsSelector', () => {
// Emits gl-dropdown show event to simulate the dropdown is opened at initialization time
findDropdown().vm.$emit('show');
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
await wrapper.setData({
loadingBoards: false,
loadingRecentBoards: false,
@@ -176,6 +180,8 @@ describe('BoardsSelector', () => {
describe('filtering', () => {
beforeEach(async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
boards,
});
@@ -208,6 +214,8 @@ describe('BoardsSelector', () => {
describe('recent boards section', () => {
it('shows only when boards are greater than 10', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
boards,
});
@@ -217,6 +225,8 @@ describe('BoardsSelector', () => {
});
it('does not show when boards are less than 10', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
boards: boards.slice(0, 5),
});
@@ -226,6 +236,8 @@ describe('BoardsSelector', () => {
});
it('does not show when recentBoards api returns empty array', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
recentBoards: [],
});
diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js
index 51340a3ea4f..7c842d71688 100644
--- a/spec/frontend/boards/stores/actions_spec.js
+++ b/spec/frontend/boards/stores/actions_spec.js
@@ -29,6 +29,8 @@ import * as types from '~/boards/stores/mutation_types';
import mutations from '~/boards/stores/mutations';
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 {
mockLists,
mockListsById,
@@ -308,6 +310,36 @@ describe('fetchMilestones', () => {
expect(() => actions.fetchMilestones(store)).toThrow(new Error('Unknown board type'));
});
+ it.each([
+ [
+ 'project',
+ {
+ query: projectBoardMilestones,
+ variables: { fullPath: 'gitlab-org/gitlab', state: 'active' },
+ },
+ ],
+ [
+ 'group',
+ {
+ query: groupBoardMilestones,
+ variables: { fullPath: 'gitlab-org/gitlab', state: 'active' },
+ },
+ ],
+ ])(
+ 'when boardType is %s it calls fetchMilestones with the correct query and variables',
+ (boardType, variables) => {
+ jest.spyOn(gqlClient, 'query').mockResolvedValue(queryResponse);
+
+ const store = createStore();
+
+ store.state.boardType = boardType;
+
+ actions.fetchMilestones(store);
+
+ expect(gqlClient.query).toHaveBeenCalledWith(variables);
+ },
+ );
+
it('sets milestonesLoading to true', async () => {
jest.spyOn(gqlClient, 'query').mockResolvedValue(queryResponse);
diff --git a/spec/frontend/branches/branches_delete_modal_spec.js b/spec/frontend/branches/branches_delete_modal_spec.js
deleted file mode 100644
index 8b10cca7a11..00000000000
--- a/spec/frontend/branches/branches_delete_modal_spec.js
+++ /dev/null
@@ -1,40 +0,0 @@
-import $ from 'jquery';
-import DeleteModal from '~/branches/branches_delete_modal';
-
-describe('branches delete modal', () => {
- describe('setDisableDeleteButton', () => {
- let submitSpy;
- let $deleteButton;
-
- beforeEach(() => {
- setFixtures(`
- <div id="modal-delete-branch">
- <form>
- <button type="submit" class="js-delete-branch">Delete</button>
- </form>
- </div>
- `);
- $deleteButton = $('.js-delete-branch');
- submitSpy = jest.fn((event) => event.preventDefault());
- $('#modal-delete-branch form').on('submit', submitSpy);
- // eslint-disable-next-line no-new
- new DeleteModal();
- });
-
- it('does not submit if button is disabled', () => {
- $deleteButton.attr('disabled', true);
-
- $deleteButton.click();
-
- expect(submitSpy).not.toHaveBeenCalled();
- });
-
- it('submits if button is not disabled', () => {
- $deleteButton.attr('disabled', false);
-
- $deleteButton.click();
-
- expect(submitSpy).toHaveBeenCalled();
- });
- });
-});
diff --git a/spec/frontend/ci_lint/components/ci_lint_spec.js b/spec/frontend/ci_lint/components/ci_lint_spec.js
index 70d116c12d3..c4b2927764e 100644
--- a/spec/frontend/ci_lint/components/ci_lint_spec.js
+++ b/spec/frontend/ci_lint/components/ci_lint_spec.js
@@ -66,6 +66,8 @@ describe('CI Lint', () => {
it('validate action calls mutation with dry run', async () => {
const dryRunEnabled = true;
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
await wrapper.setData({ dryRun: dryRunEnabled });
findValidateBtn().vm.$emit('click');
diff --git a/spec/frontend/clusters/agents/components/show_spec.js b/spec/frontend/clusters/agents/components/show_spec.js
index d5a8117f48c..2a3c11f4b47 100644
--- a/spec/frontend/clusters/agents/components/show_spec.js
+++ b/spec/frontend/clusters/agents/components/show_spec.js
@@ -19,7 +19,7 @@ describe('ClusterAgentShow', () => {
let wrapper;
useFakeDate([2021, 2, 15]);
- const propsData = {
+ const provide = {
agentName: 'cluster-agent',
projectPath: 'path/to/project',
};
@@ -49,7 +49,7 @@ describe('ClusterAgentShow', () => {
shallowMount(ClusterAgentShow, {
localVue,
apolloProvider,
- propsData,
+ provide,
stubs: { GlSprintf, TimeAgoTooltip, GlTab },
}),
);
@@ -60,7 +60,7 @@ describe('ClusterAgentShow', () => {
wrapper = extendedWrapper(
shallowMount(ClusterAgentShow, {
- propsData,
+ provide,
mocks: { $apollo, clusterAgent },
slots,
stubs: { GlTab },
@@ -85,7 +85,7 @@ describe('ClusterAgentShow', () => {
});
it('displays the agent name', () => {
- expect(wrapper.text()).toContain(propsData.agentName);
+ expect(wrapper.text()).toContain(provide.agentName);
});
it('displays agent create information', () => {
diff --git a/spec/frontend/clusters/forms/components/integration_form_spec.js b/spec/frontend/clusters/forms/components/integration_form_spec.js
index b129baa2d83..d041cd1e164 100644
--- a/spec/frontend/clusters/forms/components/integration_form_spec.js
+++ b/spec/frontend/clusters/forms/components/integration_form_spec.js
@@ -82,6 +82,8 @@ describe('ClusterIntegrationForm', () => {
.then(() => {
// setData is a bad approach because it changes the internal implementation which we should not touch
// but our GlFormInput lacks the ability to set a new value.
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ toggleEnabled: !defaultStoreValues.enabled });
})
.then(() => {
@@ -93,6 +95,8 @@ describe('ClusterIntegrationForm', () => {
return wrapper.vm
.$nextTick()
.then(() => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ envScope: `${defaultStoreValues.environmentScope}1` });
})
.then(() => {
diff --git a/spec/frontend/clusters_list/components/agent_options_spec.js b/spec/frontend/clusters_list/components/agent_options_spec.js
new file mode 100644
index 00000000000..05bab247816
--- /dev/null
+++ b/spec/frontend/clusters_list/components/agent_options_spec.js
@@ -0,0 +1,211 @@
+import { GlDropdown, GlDropdownItem, GlModal, GlFormInput } from '@gitlab/ui';
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { ENTER_KEY } from '~/lib/utils/keys';
+import getAgentsQuery from '~/clusters_list/graphql/queries/get_agents.query.graphql';
+import deleteAgentMutation from '~/clusters_list/graphql/mutations/delete_agent.mutation.graphql';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import AgentOptions from '~/clusters_list/components/agent_options.vue';
+import { MAX_LIST_COUNT } from '~/clusters_list/constants';
+import { getAgentResponse, mockDeleteResponse, mockErrorDeleteResponse } from '../mocks/apollo';
+
+Vue.use(VueApollo);
+
+const projectPath = 'path/to/project';
+const defaultBranchName = 'default';
+const maxAgents = MAX_LIST_COUNT;
+const agent = {
+ id: 'agent-id',
+ name: 'agent-name',
+ webPath: 'agent-webPath',
+};
+
+describe('AgentOptions', () => {
+ let wrapper;
+ let toast;
+ let apolloProvider;
+ let deleteResponse;
+
+ const findModal = () => wrapper.findComponent(GlModal);
+ const findDropdown = () => wrapper.findComponent(GlDropdown);
+ const findDeleteBtn = () => wrapper.findComponent(GlDropdownItem);
+ const findInput = () => wrapper.findComponent(GlFormInput);
+ const findPrimaryAction = () => findModal().props('actionPrimary');
+ const findPrimaryActionAttributes = (attr) => findPrimaryAction().attributes[0][attr];
+
+ const createMockApolloProvider = ({ mutationResponse }) => {
+ deleteResponse = jest.fn().mockResolvedValue(mutationResponse);
+
+ return createMockApollo([[deleteAgentMutation, deleteResponse]]);
+ };
+
+ const writeQuery = () => {
+ apolloProvider.clients.defaultClient.cache.writeQuery({
+ query: getAgentsQuery,
+ variables: {
+ projectPath,
+ defaultBranchName,
+ first: maxAgents,
+ last: null,
+ },
+ data: getAgentResponse.data,
+ });
+ };
+
+ const createWrapper = ({ mutationResponse = mockDeleteResponse } = {}) => {
+ apolloProvider = createMockApolloProvider({ mutationResponse });
+ const provide = {
+ projectPath,
+ };
+ const propsData = {
+ defaultBranchName,
+ maxAgents,
+ agent,
+ };
+
+ toast = jest.fn();
+
+ wrapper = shallowMountExtended(AgentOptions, {
+ apolloProvider,
+ provide,
+ propsData,
+ mocks: { $toast: { show: toast } },
+ stubs: { GlModal },
+ });
+ wrapper.vm.$refs.modal.hide = jest.fn();
+
+ writeQuery();
+ return wrapper.vm.$nextTick();
+ };
+
+ const submitAgentToDelete = async () => {
+ findDeleteBtn().vm.$emit('click');
+ findInput().vm.$emit('input', agent.name);
+ await findModal().vm.$emit('primary');
+ };
+
+ beforeEach(() => {
+ return createWrapper({});
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ apolloProvider = null;
+ deleteResponse = null;
+ toast = null;
+ });
+
+ describe('delete agent action', () => {
+ it('displays a delete button', () => {
+ expect(findDeleteBtn().text()).toBe('Delete agent');
+ });
+
+ describe('when clicking the delete button', () => {
+ beforeEach(() => {
+ findDeleteBtn().vm.$emit('click');
+ });
+
+ it('displays a delete confirmation modal', () => {
+ expect(findModal().isVisible()).toBe(true);
+ });
+ });
+
+ describe.each`
+ condition | agentName | isDisabled | mutationCalled
+ ${'the input with agent name is missing'} | ${''} | ${true} | ${false}
+ ${'the input with agent name is incorrect'} | ${'wrong-name'} | ${true} | ${false}
+ ${'the input with agent name is correct'} | ${agent.name} | ${false} | ${true}
+ `('when $condition', ({ agentName, isDisabled, mutationCalled }) => {
+ beforeEach(() => {
+ findDeleteBtn().vm.$emit('click');
+ findInput().vm.$emit('input', agentName);
+ });
+
+ it(`${isDisabled ? 'disables' : 'enables'} the modal primary button`, () => {
+ expect(findPrimaryActionAttributes('disabled')).toBe(isDisabled);
+ });
+
+ describe('when user clicks the modal primary button', () => {
+ beforeEach(async () => {
+ await findModal().vm.$emit('primary');
+ });
+
+ if (mutationCalled) {
+ it('calls the delete mutation', () => {
+ expect(deleteResponse).toHaveBeenCalledWith({ input: { id: agent.id } });
+ });
+ } else {
+ it("doesn't call the delete mutation", () => {
+ expect(deleteResponse).not.toHaveBeenCalled();
+ });
+ }
+ });
+
+ describe('when user presses the enter button', () => {
+ beforeEach(async () => {
+ await findInput().vm.$emit('keydown', new KeyboardEvent({ key: ENTER_KEY }));
+ });
+
+ if (mutationCalled) {
+ it('calls the delete mutation', () => {
+ expect(deleteResponse).toHaveBeenCalledWith({ input: { id: agent.id } });
+ });
+ } else {
+ it("doesn't call the delete mutation", () => {
+ expect(deleteResponse).not.toHaveBeenCalled();
+ });
+ }
+ });
+ });
+
+ describe('when agent was deleted successfully', () => {
+ beforeEach(async () => {
+ await submitAgentToDelete();
+ });
+
+ it('calls the toast action', () => {
+ expect(toast).toHaveBeenCalledWith(`${agent.name} successfully deleted`);
+ });
+ });
+ });
+
+ describe('when getting an error deleting agent', () => {
+ beforeEach(async () => {
+ await createWrapper({ mutationResponse: mockErrorDeleteResponse });
+
+ submitAgentToDelete();
+ });
+
+ it('displays the error message', () => {
+ expect(toast).toHaveBeenCalledWith('could not delete agent');
+ });
+ });
+
+ describe('when the delete modal was closed', () => {
+ beforeEach(async () => {
+ const loadingResponse = new Promise(() => {});
+ await createWrapper({ mutationResponse: loadingResponse });
+
+ submitAgentToDelete();
+ });
+
+ it('reenables the options dropdown', async () => {
+ expect(findPrimaryActionAttributes('loading')).toBe(true);
+ expect(findDropdown().attributes('disabled')).toBe('true');
+
+ await findModal().vm.$emit('hide');
+
+ expect(findPrimaryActionAttributes('loading')).toBe(false);
+ expect(findDropdown().attributes('disabled')).toBeUndefined();
+ });
+
+ it('clears the agent name input', async () => {
+ expect(findInput().attributes('value')).toBe(agent.name);
+
+ await findModal().vm.$emit('hide');
+
+ expect(findInput().attributes('value')).toBeUndefined();
+ });
+ });
+});
diff --git a/spec/frontend/clusters_list/components/agent_table_spec.js b/spec/frontend/clusters_list/components/agent_table_spec.js
index a6d76b069cf..887c17bb4ad 100644
--- a/spec/frontend/clusters_list/components/agent_table_spec.js
+++ b/spec/frontend/clusters_list/components/agent_table_spec.js
@@ -1,16 +1,22 @@
import { GlLink, GlIcon } from '@gitlab/ui';
import AgentTable from '~/clusters_list/components/agent_table.vue';
+import AgentOptions from '~/clusters_list/components/agent_options.vue';
import { ACTIVE_CONNECTION_TIME } from '~/clusters_list/constants';
import { mountExtended } from 'helpers/vue_test_utils_helper';
+import { stubComponent } from 'helpers/stub_component';
import timeagoMixin from '~/vue_shared/mixins/timeago';
const connectedTimeNow = new Date();
const connectedTimeInactive = new Date(connectedTimeNow.getTime() - ACTIVE_CONNECTION_TIME);
+const provideData = {
+ projectPath: 'path/to/project',
+};
const propsData = {
agents: [
{
name: 'agent-1',
+ id: 'agent-1-id',
configFolder: {
webPath: '/agent/full/path',
},
@@ -21,6 +27,7 @@ const propsData = {
},
{
name: 'agent-2',
+ id: 'agent-2-id',
webPath: '/agent-2',
status: 'active',
lastContact: connectedTimeNow.getTime(),
@@ -34,6 +41,7 @@ const propsData = {
},
{
name: 'agent-3',
+ id: 'agent-3-id',
webPath: '/agent-3',
status: 'inactive',
lastContact: connectedTimeInactive.getTime(),
@@ -48,6 +56,10 @@ const propsData = {
],
};
+const AgentOptionsStub = stubComponent(AgentOptions, {
+ template: `<div></div>`,
+});
+
describe('AgentTable', () => {
let wrapper;
@@ -57,15 +69,21 @@ describe('AgentTable', () => {
const findLastContactText = (at) => wrapper.findAllByTestId('cluster-agent-last-contact').at(at);
const findConfiguration = (at) =>
wrapper.findAllByTestId('cluster-agent-configuration-link').at(at);
+ const findAgentOptions = () => wrapper.findAllComponents(AgentOptions);
beforeEach(() => {
- wrapper = mountExtended(AgentTable, { propsData });
+ wrapper = mountExtended(AgentTable, {
+ propsData,
+ provide: provideData,
+ stubs: {
+ AgentOptions: AgentOptionsStub,
+ },
+ });
});
afterEach(() => {
if (wrapper) {
wrapper.destroy();
- wrapper = null;
}
});
@@ -108,5 +126,9 @@ describe('AgentTable', () => {
expect(findLink.exists()).toBe(hasLink);
expect(findConfiguration(lineNumber).text()).toBe(agentPath);
});
+
+ it('displays actions menu for each agent', () => {
+ expect(findAgentOptions()).toHaveLength(3);
+ });
});
});
diff --git a/spec/frontend/clusters_list/components/clusters_spec.js b/spec/frontend/clusters_list/components/clusters_spec.js
index a34202c789d..9af25a534d8 100644
--- a/spec/frontend/clusters_list/components/clusters_spec.js
+++ b/spec/frontend/clusters_list/components/clusters_spec.js
@@ -272,6 +272,8 @@ describe('Clusters', () => {
describe('when updating currentPage', () => {
beforeEach(() => {
mockPollingApi(200, apiData, paginationHeader(totalSecondPage, perPage, 2));
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ currentPage: 2 });
return axios.waitForAll();
});
diff --git a/spec/frontend/clusters_list/mocks/apollo.js b/spec/frontend/clusters_list/mocks/apollo.js
index 804f9834506..c4a31ed4394 100644
--- a/spec/frontend/clusters_list/mocks/apollo.js
+++ b/spec/frontend/clusters_list/mocks/apollo.js
@@ -75,3 +75,15 @@ export const getAgentResponse = {
},
},
};
+
+export const mockDeleteResponse = {
+ data: { clusterAgentDelete: { errors: [] } },
+};
+
+export const mockErrorDeleteResponse = {
+ data: {
+ clusterAgentDelete: {
+ errors: ['could not delete agent'],
+ },
+ },
+};
diff --git a/spec/frontend/commit/pipelines/pipelines_table_spec.js b/spec/frontend/commit/pipelines/pipelines_table_spec.js
index c376b58cc72..e209f628aa2 100644
--- a/spec/frontend/commit/pipelines/pipelines_table_spec.js
+++ b/spec/frontend/commit/pipelines/pipelines_table_spec.js
@@ -92,6 +92,8 @@ describe('Pipelines table in Commits and Merge requests', () => {
it('should make an API request when using pagination', async () => {
jest.spyOn(wrapper.vm, 'updateContent').mockImplementation(() => {});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
await wrapper.setData({
store: {
state: {
diff --git a/spec/frontend/content_editor/components/wrappers/frontmatter_spec.js b/spec/frontend/content_editor/components/wrappers/frontmatter_spec.js
index de8f8efd260..415f1314a36 100644
--- a/spec/frontend/content_editor/components/wrappers/frontmatter_spec.js
+++ b/spec/frontend/content_editor/components/wrappers/frontmatter_spec.js
@@ -26,6 +26,11 @@ describe('content/components/wrappers/frontmatter', () => {
expect(wrapper.findComponent(NodeViewWrapper).classes()).toContain('gl-relative');
});
+ it('adds content-editor-code-block class to the pre element', () => {
+ createWrapper();
+ expect(wrapper.findComponent(NodeViewWrapper).classes()).toContain('content-editor-code-block');
+ });
+
it('renders a node-view-content as a code element', () => {
createWrapper();
diff --git a/spec/frontend/content_editor/extensions/code_block_highlight_spec.js b/spec/frontend/content_editor/extensions/code_block_highlight_spec.js
index 6a0a0c76825..05fa0f79ef0 100644
--- a/spec/frontend/content_editor/extensions/code_block_highlight_spec.js
+++ b/spec/frontend/content_editor/extensions/code_block_highlight_spec.js
@@ -36,4 +36,10 @@ describe('content_editor/extensions/code_block_highlight', () => {
expect(editorHtmlOutput.classList.toString()).toContain('code highlight js-syntax-highlight');
});
+
+ it('adds content-editor-code-block class to the pre element', () => {
+ const editorHtmlOutput = parseHTML(tiptapEditor.getHTML()).querySelector('pre');
+
+ expect(editorHtmlOutput.classList.toString()).toContain('content-editor-code-block');
+ });
});
diff --git a/spec/frontend/content_editor/extensions/code_spec.js b/spec/frontend/content_editor/extensions/code_spec.js
new file mode 100644
index 00000000000..0a54ac6a96b
--- /dev/null
+++ b/spec/frontend/content_editor/extensions/code_spec.js
@@ -0,0 +1,8 @@
+import Code from '~/content_editor/extensions/code';
+import { EXTENSION_PRIORITY_LOWER } from '~/content_editor/constants';
+
+describe('content_editor/extensions/code', () => {
+ it('has a lower loading priority', () => {
+ expect(Code.config.priority).toBe(EXTENSION_PRIORITY_LOWER);
+ });
+});
diff --git a/spec/frontend/content_editor/extensions/frontmatter_spec.js b/spec/frontend/content_editor/extensions/frontmatter_spec.js
index 517f6947b9a..a8cbad6ef81 100644
--- a/spec/frontend/content_editor/extensions/frontmatter_spec.js
+++ b/spec/frontend/content_editor/extensions/frontmatter_spec.js
@@ -1,30 +1,47 @@
import Frontmatter from '~/content_editor/extensions/frontmatter';
+import CodeBlockHighlight from '~/content_editor/extensions/code_block_highlight';
import { createTestEditor, createDocBuilder, triggerNodeInputRule } from '../test_utils';
describe('content_editor/extensions/frontmatter', () => {
let tiptapEditor;
let doc;
- let p;
+ let frontmatter;
+ let codeBlock;
beforeEach(() => {
- tiptapEditor = createTestEditor({ extensions: [Frontmatter] });
+ tiptapEditor = createTestEditor({ extensions: [Frontmatter, CodeBlockHighlight] });
({
- builders: { doc, p },
+ builders: { doc, codeBlock, frontmatter },
} = createDocBuilder({
tiptapEditor,
names: {
frontmatter: { nodeType: Frontmatter.name },
+ codeBlock: { nodeType: CodeBlockHighlight.name },
},
}));
});
it('does not insert a frontmatter block when executing code block input rule', () => {
- const expectedDoc = doc(p(''));
+ const expectedDoc = doc(codeBlock(''));
const inputRuleText = '``` ';
triggerNodeInputRule({ tiptapEditor, inputRuleText });
expect(tiptapEditor.getJSON()).toEqual(expectedDoc.toJSON());
});
+
+ it.each`
+ command | result | resultDesc
+ ${'toggleCodeBlock'} | ${() => doc(codeBlock(''))} | ${'code block element'}
+ ${'setCodeBlock'} | ${() => doc(codeBlock(''))} | ${'code block element'}
+ ${'setFrontmatter'} | ${() => doc(frontmatter(''))} | ${'frontmatter element'}
+ ${'toggleFrontmatter'} | ${() => doc(frontmatter(''))} | ${'frontmatter element'}
+ `('executing $command should generate a document with a $resultDesc', ({ command, result }) => {
+ const expectedDoc = result();
+
+ tiptapEditor.commands[command]();
+
+ expect(tiptapEditor.getJSON()).toEqual(expectedDoc.toJSON());
+ });
});
diff --git a/spec/frontend/content_editor/extensions/image_spec.js b/spec/frontend/content_editor/extensions/image_spec.js
new file mode 100644
index 00000000000..256f7bad309
--- /dev/null
+++ b/spec/frontend/content_editor/extensions/image_spec.js
@@ -0,0 +1,41 @@
+import Image from '~/content_editor/extensions/image';
+import { createTestEditor, createDocBuilder } from '../test_utils';
+
+describe('content_editor/extensions/image', () => {
+ let tiptapEditor;
+ let doc;
+ let p;
+ let image;
+
+ beforeEach(() => {
+ tiptapEditor = createTestEditor({ extensions: [Image] });
+
+ ({
+ builders: { doc, p, image },
+ } = createDocBuilder({
+ tiptapEditor,
+ names: {
+ image: { nodeType: Image.name },
+ },
+ }));
+ });
+
+ it('adds data-canonical-src attribute when rendering to HTML', () => {
+ const initialDoc = doc(
+ p(
+ image({
+ canonicalSrc: 'uploads/image.jpg',
+ src: '/-/wikis/uploads/image.jpg',
+ alt: 'image',
+ title: 'this is an image',
+ }),
+ ),
+ );
+
+ tiptapEditor.commands.setContent(initialDoc.toJSON());
+
+ expect(tiptapEditor.getHTML()).toEqual(
+ '<p><img src="/-/wikis/uploads/image.jpg" alt="image" title="this is an image" data-canonical-src="uploads/image.jpg"></p>',
+ );
+ });
+});
diff --git a/spec/frontend/content_editor/extensions/link_spec.js b/spec/frontend/content_editor/extensions/link_spec.js
index ead898554d1..bb841357d37 100644
--- a/spec/frontend/content_editor/extensions/link_spec.js
+++ b/spec/frontend/content_editor/extensions/link_spec.js
@@ -33,7 +33,7 @@ describe('content_editor/extensions/link', () => {
${'documentation](readme.md'} | ${() => p('documentation](readme.md')}
${'http://example.com '} | ${() => p(link({ href: 'http://example.com' }, 'http://example.com'))}
${'https://example.com '} | ${() => p(link({ href: 'https://example.com' }, 'https://example.com'))}
- ${'www.example.com '} | ${() => p(link({ href: 'www.example.com' }, 'www.example.com'))}
+ ${'www.example.com '} | ${() => p(link({ href: 'http://www.example.com' }, 'www.example.com'))}
${'example.com/ab.html '} | ${() => p('example.com/ab.html')}
${'https://www.google.com '} | ${() => p(link({ href: 'https://www.google.com' }, 'https://www.google.com'))}
`('with input=$input, then should insert a $insertedNode', ({ input, insertedNode }) => {
diff --git a/spec/frontend/content_editor/services/markdown_serializer_spec.js b/spec/frontend/content_editor/services/markdown_serializer_spec.js
index 97f6d8f6334..01d4c994e88 100644
--- a/spec/frontend/content_editor/services/markdown_serializer_spec.js
+++ b/spec/frontend/content_editor/services/markdown_serializer_spec.js
@@ -164,6 +164,17 @@ describe('markdownSerializer', () => {
expect(serialize(paragraph(italic('italics')))).toBe('_italics_');
});
+ it('correctly serializes code blocks wrapped by italics and bold marks', () => {
+ const text = 'code block';
+
+ expect(serialize(paragraph(italic(code(text))))).toBe(`_\`${text}\`_`);
+ expect(serialize(paragraph(code(italic(text))))).toBe(`_\`${text}\`_`);
+ expect(serialize(paragraph(bold(code(text))))).toBe(`**\`${text}\`**`);
+ expect(serialize(paragraph(code(bold(text))))).toBe(`**\`${text}\`**`);
+ expect(serialize(paragraph(strike(code(text))))).toBe(`~~\`${text}\`~~`);
+ expect(serialize(paragraph(code(strike(text))))).toBe(`~~\`${text}\`~~`);
+ });
+
it('correctly serializes inline diff', () => {
expect(
serialize(
@@ -341,6 +352,10 @@ this is not really json but just trying out whether this case works or not
);
});
+ it('does not serialize an image when src and canonicalSrc are empty', () => {
+ expect(serialize(paragraph(image({})))).toBe('');
+ });
+
it('correctly serializes an image with a title', () => {
expect(serialize(paragraph(image({ src: 'img.jpg', title: 'baz', alt: 'foo bar' })))).toBe(
'![foo bar](img.jpg "baz")',
diff --git a/spec/frontend/create_cluster/components/cluster_form_dropdown_spec.js b/spec/frontend/create_cluster/components/cluster_form_dropdown_spec.js
index 0c6095e601f..4e92fa1df16 100644
--- a/spec/frontend/create_cluster/components/cluster_form_dropdown_spec.js
+++ b/spec/frontend/create_cluster/components/cluster_form_dropdown_spec.js
@@ -206,6 +206,8 @@ describe('ClusterFormDropdown', () => {
const searchQuery = secondItem.name;
wrapper.setProps({ items });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ searchQuery });
return wrapper.vm.$nextTick().then(() => {
diff --git a/spec/frontend/create_cluster/eks_cluster/components/service_credentials_form_spec.js b/spec/frontend/create_cluster/eks_cluster/components/service_credentials_form_spec.js
index d866ffd4efb..a0510d46794 100644
--- a/spec/frontend/create_cluster/eks_cluster/components/service_credentials_form_spec.js
+++ b/spec/frontend/create_cluster/eks_cluster/components/service_credentials_form_spec.js
@@ -67,6 +67,8 @@ describe('ServiceCredentialsForm', () => {
});
it('enables submit button when role ARN is not provided', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
vm.setData({ roleArn: '123' });
return vm.vm.$nextTick().then(() => {
@@ -75,6 +77,8 @@ describe('ServiceCredentialsForm', () => {
});
it('dispatches createRole action when submit button is clicked', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
vm.setData({ roleArn: '123' }); // set role ARN to enable button
findSubmitButton().vm.$emit('click', new Event('click'));
@@ -84,6 +88,8 @@ describe('ServiceCredentialsForm', () => {
describe('when is creating role', () => {
beforeEach(() => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
vm.setData({ roleArn: '123' }); // set role ARN to enable button
state.isCreatingRole = true;
diff --git a/spec/frontend/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js b/spec/frontend/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js
index 8f4903dd91b..2b6f2134553 100644
--- a/spec/frontend/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js
+++ b/spec/frontend/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js
@@ -79,6 +79,8 @@ describe('GkeMachineTypeDropdown', () => {
store = createStore();
wrapper = createComponent(store);
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ isLoading: true });
return wrapper.vm.$nextTick().then(() => {
diff --git a/spec/frontend/create_cluster/gke_cluster/components/gke_project_id_dropdown_spec.js b/spec/frontend/create_cluster/gke_cluster/components/gke_project_id_dropdown_spec.js
index b191b107609..2b0acc8cf5d 100644
--- a/spec/frontend/create_cluster/gke_cluster/components/gke_project_id_dropdown_spec.js
+++ b/spec/frontend/create_cluster/gke_cluster/components/gke_project_id_dropdown_spec.js
@@ -83,6 +83,8 @@ describe('GkeProjectIdDropdown', () => {
it('returns default toggle text', () => {
bootstrap();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ isLoading: false });
return wrapper.vm.$nextTick().then(() => {
@@ -99,6 +101,8 @@ describe('GkeProjectIdDropdown', () => {
hasProject: () => true,
},
);
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ isLoading: false });
return wrapper.vm.$nextTick().then(() => {
@@ -110,6 +114,8 @@ describe('GkeProjectIdDropdown', () => {
bootstrap({
projects: null,
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ isLoading: false });
return wrapper.vm.$nextTick().then(() => {
diff --git a/spec/frontend/create_cluster/gke_cluster/components/gke_zone_dropdown_spec.js b/spec/frontend/create_cluster/gke_cluster/components/gke_zone_dropdown_spec.js
index 4054b768e34..22fc681f863 100644
--- a/spec/frontend/create_cluster/gke_cluster/components/gke_zone_dropdown_spec.js
+++ b/spec/frontend/create_cluster/gke_cluster/components/gke_zone_dropdown_spec.js
@@ -47,6 +47,8 @@ describe('GkeZoneDropdown', () => {
describe('isLoading', () => {
beforeEach(() => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ isLoading: true });
return wrapper.vm.$nextTick();
});
diff --git a/spec/frontend/create_merge_request_dropdown_spec.js b/spec/frontend/create_merge_request_dropdown_spec.js
deleted file mode 100644
index 9f07eea433a..00000000000
--- a/spec/frontend/create_merge_request_dropdown_spec.js
+++ /dev/null
@@ -1,122 +0,0 @@
-import MockAdapter from 'axios-mock-adapter';
-import { TEST_HOST } from 'helpers/test_constants';
-import confidentialState from '~/confidential_merge_request/state';
-import CreateMergeRequestDropdown from '~/create_merge_request_dropdown';
-import axios from '~/lib/utils/axios_utils';
-
-describe('CreateMergeRequestDropdown', () => {
- let axiosMock;
- let dropdown;
-
- beforeEach(() => {
- axiosMock = new MockAdapter(axios);
-
- document.body.innerHTML = `
- <div id="dummy-wrapper-element">
- <div class="available"></div>
- <div class="unavailable">
- <div class="gl-spinner"></div>
- <div class="text"></div>
- </div>
- <div class="js-ref"></div>
- <div class="js-create-mr"></div>
- <div class="js-create-merge-request">
- <span class="js-spinner"></span>
- </div>
- <div class="js-create-target"></div>
- <div class="js-dropdown-toggle"></div>
- </div>
- `;
-
- const dummyElement = document.getElementById('dummy-wrapper-element');
- dropdown = new CreateMergeRequestDropdown(dummyElement);
- dropdown.refsPath = `${TEST_HOST}/dummy/refs?search=`;
- });
-
- afterEach(() => {
- axiosMock.restore();
- });
-
- describe('getRef', () => {
- it('escapes branch names correctly', (done) => {
- const endpoint = `${dropdown.refsPath}contains%23hash`;
- jest.spyOn(axios, 'get');
- axiosMock.onGet(endpoint).replyOnce({});
-
- dropdown
- .getRef('contains#hash')
- .then(() => {
- expect(axios.get).toHaveBeenCalledWith(
- endpoint,
- expect.objectContaining({ cancelToken: expect.anything() }),
- );
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('updateCreatePaths', () => {
- it('escapes branch names correctly', () => {
- dropdown.createBranchPath = `${TEST_HOST}/branches?branch_name=some-branch&issue=42`;
- dropdown.createMrPath = `${TEST_HOST}/create_merge_request?branch_name=some-branch&ref=main`;
-
- dropdown.updateCreatePaths('branch', 'contains#hash');
-
- expect(dropdown.createBranchPath).toBe(
- `${TEST_HOST}/branches?branch_name=contains%23hash&issue=42`,
- );
-
- expect(dropdown.createMrPath).toBe(
- `${TEST_HOST}/create_merge_request?branch_name=contains%23hash&ref=main`,
- );
- });
- });
-
- describe('enable', () => {
- beforeEach(() => {
- dropdown.createMergeRequestButton.classList.add('disabled');
- });
-
- afterEach(() => {
- confidentialState.selectedProject = {};
- });
-
- it('enables button when not confidential issue', () => {
- dropdown.enable();
-
- expect(dropdown.createMergeRequestButton.classList).not.toContain('disabled');
- });
-
- it('enables when can create confidential issue', () => {
- document.querySelector('.js-create-mr').setAttribute('data-is-confidential', 'true');
- confidentialState.selectedProject = { name: 'test' };
-
- dropdown.enable();
-
- expect(dropdown.createMergeRequestButton.classList).not.toContain('disabled');
- });
-
- it('does not enable when can not create confidential issue', () => {
- document.querySelector('.js-create-mr').setAttribute('data-is-confidential', 'true');
-
- dropdown.enable();
-
- expect(dropdown.createMergeRequestButton.classList).toContain('disabled');
- });
- });
-
- describe('setLoading', () => {
- it.each`
- loading | hasClass
- ${true} | ${false}
- ${false} | ${true}
- `('it toggle loading spinner when loading is $loading', ({ loading, hasClass }) => {
- dropdown.setLoading(loading);
-
- expect(document.querySelector('.js-spinner').classList.contains('gl-display-none')).toEqual(
- hasClass,
- );
- });
- });
-});
diff --git a/spec/frontend/crm/contact_form_spec.js b/spec/frontend/crm/contact_form_spec.js
index b2753ad8cf5..0edab4f5ec5 100644
--- a/spec/frontend/crm/contact_form_spec.js
+++ b/spec/frontend/crm/contact_form_spec.js
@@ -112,7 +112,7 @@ describe('Customer relations contact form component', () => {
await waitForPromises();
expect(findError().exists()).toBe(true);
- expect(findError().text()).toBe('Phone is invalid.');
+ expect(findError().text()).toBe('create contact is invalid.');
});
});
@@ -151,7 +151,7 @@ describe('Customer relations contact form component', () => {
await waitForPromises();
expect(findError().exists()).toBe(true);
- expect(findError().text()).toBe('Email is invalid.');
+ expect(findError().text()).toBe('update contact is invalid.');
});
});
});
diff --git a/spec/frontend/crm/form_spec.js b/spec/frontend/crm/form_spec.js
new file mode 100644
index 00000000000..0e3abc05c37
--- /dev/null
+++ b/spec/frontend/crm/form_spec.js
@@ -0,0 +1,278 @@
+import { GlAlert } from '@gitlab/ui';
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import VueRouter from 'vue-router';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import Form from '~/crm/components/form.vue';
+import routes from '~/crm/routes';
+import createContactMutation from '~/crm/components/queries/create_contact.mutation.graphql';
+import updateContactMutation from '~/crm/components/queries/update_contact.mutation.graphql';
+import getGroupContactsQuery from '~/crm/components/queries/get_group_contacts.query.graphql';
+import createOrganizationMutation from '~/crm/components/queries/create_organization.mutation.graphql';
+import getGroupOrganizationsQuery from '~/crm/components/queries/get_group_organizations.query.graphql';
+import {
+ createContactMutationErrorResponse,
+ createContactMutationResponse,
+ getGroupContactsQueryResponse,
+ updateContactMutationErrorResponse,
+ updateContactMutationResponse,
+ createOrganizationMutationErrorResponse,
+ createOrganizationMutationResponse,
+ getGroupOrganizationsQueryResponse,
+} from './mock_data';
+
+const FORM_CREATE_CONTACT = 'create contact';
+const FORM_UPDATE_CONTACT = 'update contact';
+const FORM_CREATE_ORG = 'create organization';
+
+describe('Reusable form component', () => {
+ Vue.use(VueApollo);
+ Vue.use(VueRouter);
+
+ const DEFAULT_RESPONSES = {
+ createContact: Promise.resolve(createContactMutationResponse),
+ updateContact: Promise.resolve(updateContactMutationResponse),
+ createOrg: Promise.resolve(createOrganizationMutationResponse),
+ };
+
+ let wrapper;
+ let handler;
+ let fakeApollo;
+ let router;
+
+ beforeEach(() => {
+ router = new VueRouter({
+ base: '',
+ mode: 'history',
+ routes,
+ });
+ router.push('/test');
+
+ handler = jest.fn().mockImplementation((key) => DEFAULT_RESPONSES[key]);
+
+ const hanlderWithKey = (key) => (...args) => handler(key, ...args);
+
+ fakeApollo = createMockApollo([
+ [createContactMutation, hanlderWithKey('createContact')],
+ [updateContactMutation, hanlderWithKey('updateContact')],
+ [createOrganizationMutation, hanlderWithKey('createOrg')],
+ ]);
+
+ fakeApollo.clients.defaultClient.cache.writeQuery({
+ query: getGroupContactsQuery,
+ variables: { groupFullPath: 'flightjs' },
+ data: getGroupContactsQueryResponse.data,
+ });
+
+ fakeApollo.clients.defaultClient.cache.writeQuery({
+ query: getGroupOrganizationsQuery,
+ variables: { groupFullPath: 'flightjs' },
+ data: getGroupOrganizationsQueryResponse.data,
+ });
+ });
+
+ const mockToastShow = jest.fn();
+
+ const findSaveButton = () => wrapper.findByTestId('save-button');
+ const findForm = () => wrapper.find('form');
+ const findError = () => wrapper.findComponent(GlAlert);
+
+ const mountComponent = (propsData) => {
+ wrapper = shallowMountExtended(Form, {
+ router,
+ apolloProvider: fakeApollo,
+ propsData: { drawerOpen: true, ...propsData },
+ mocks: {
+ $toast: {
+ show: mockToastShow,
+ },
+ },
+ });
+ };
+
+ const mountContact = ({ propsData } = {}) => {
+ mountComponent({
+ fields: [
+ { name: 'firstName', label: 'First name', required: true },
+ { name: 'lastName', label: 'Last name', required: true },
+ { name: 'email', label: 'Email', required: true },
+ { name: 'phone', label: 'Phone' },
+ { name: 'description', label: 'Description' },
+ ],
+ ...propsData,
+ });
+ };
+
+ const mountContactCreate = () => {
+ const propsData = {
+ title: 'New contact',
+ successMessage: 'Contact has been added',
+ buttonLabel: 'Create contact',
+ getQuery: {
+ query: getGroupContactsQuery,
+ variables: { groupFullPath: 'flightjs' },
+ },
+ getQueryNodePath: 'group.contacts',
+ mutation: createContactMutation,
+ additionalCreateParams: { groupId: 'gid://gitlab/Group/26' },
+ };
+ mountContact({ propsData });
+ };
+
+ const mountContactUpdate = () => {
+ const propsData = {
+ title: 'Edit contact',
+ successMessage: 'Contact has been updated',
+ mutation: updateContactMutation,
+ existingModel: {
+ id: 'gid://gitlab/CustomerRelations::Contact/12',
+ firstName: 'First',
+ lastName: 'Last',
+ email: 'email@example.com',
+ },
+ };
+ mountContact({ propsData });
+ };
+
+ const mountOrganization = ({ propsData } = {}) => {
+ mountComponent({
+ fields: [
+ { name: 'name', label: 'Name', required: true },
+ { name: 'defaultRate', label: 'Default rate', input: { type: 'number', step: '0.01' } },
+ { name: 'description', label: 'Description' },
+ ],
+ ...propsData,
+ });
+ };
+
+ const mountOrganizationCreate = () => {
+ const propsData = {
+ title: 'New organization',
+ successMessage: 'Organization has been added',
+ buttonLabel: 'Create organization',
+ getQuery: {
+ query: getGroupOrganizationsQuery,
+ variables: { groupFullPath: 'flightjs' },
+ },
+ getQueryNodePath: 'group.organizations',
+ mutation: createOrganizationMutation,
+ additionalCreateParams: { groupId: 'gid://gitlab/Group/26' },
+ };
+ mountOrganization({ propsData });
+ };
+
+ const forms = {
+ [FORM_CREATE_CONTACT]: {
+ mountFunction: mountContactCreate,
+ mutationErrorResponse: createContactMutationErrorResponse,
+ toastMessage: 'Contact has been added',
+ },
+ [FORM_UPDATE_CONTACT]: {
+ mountFunction: mountContactUpdate,
+ mutationErrorResponse: updateContactMutationErrorResponse,
+ toastMessage: 'Contact has been updated',
+ },
+ [FORM_CREATE_ORG]: {
+ mountFunction: mountOrganizationCreate,
+ mutationErrorResponse: createOrganizationMutationErrorResponse,
+ toastMessage: 'Organization has been added',
+ },
+ };
+ const asTestParams = (...keys) => keys.map((name) => [name, forms[name]]);
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe.each(asTestParams(FORM_CREATE_CONTACT, FORM_UPDATE_CONTACT))(
+ '%s form save button',
+ (name, { mountFunction }) => {
+ beforeEach(() => {
+ mountFunction();
+ });
+
+ it('should be disabled when required fields are empty', async () => {
+ wrapper.find('#firstName').vm.$emit('input', '');
+ await waitForPromises();
+
+ expect(findSaveButton().props('disabled')).toBe(true);
+ });
+
+ it('should not be disabled when required fields have values', async () => {
+ wrapper.find('#firstName').vm.$emit('input', 'A');
+ wrapper.find('#lastName').vm.$emit('input', 'B');
+ wrapper.find('#email').vm.$emit('input', 'C');
+ await waitForPromises();
+
+ expect(findSaveButton().props('disabled')).toBe(false);
+ });
+ },
+ );
+
+ describe.each(asTestParams(FORM_CREATE_ORG))('%s form save button', (name, { mountFunction }) => {
+ beforeEach(() => {
+ mountFunction();
+ });
+
+ it('should be disabled when required field is empty', async () => {
+ wrapper.find('#name').vm.$emit('input', '');
+ await waitForPromises();
+
+ expect(findSaveButton().props('disabled')).toBe(true);
+ });
+
+ it('should not be disabled when required field has a value', async () => {
+ wrapper.find('#name').vm.$emit('input', 'A');
+ await waitForPromises();
+
+ expect(findSaveButton().props('disabled')).toBe(false);
+ });
+ });
+
+ describe.each(asTestParams(FORM_CREATE_CONTACT, FORM_UPDATE_CONTACT, FORM_CREATE_ORG))(
+ 'when %s mutation is successful',
+ (name, { mountFunction, toastMessage }) => {
+ it('form should display correct toast message', async () => {
+ mountFunction();
+
+ findForm().trigger('submit');
+ await waitForPromises();
+
+ expect(mockToastShow).toHaveBeenCalledWith(toastMessage);
+ });
+ },
+ );
+
+ describe.each(asTestParams(FORM_CREATE_CONTACT, FORM_UPDATE_CONTACT, FORM_CREATE_ORG))(
+ 'when %s mutation fails',
+ (formName, { mutationErrorResponse, mountFunction }) => {
+ beforeEach(() => {
+ jest.spyOn(console, 'error').mockImplementation();
+ });
+
+ it('should show error on reject', async () => {
+ handler.mockRejectedValue('ERROR');
+
+ mountFunction();
+
+ findForm().trigger('submit');
+ await waitForPromises();
+
+ expect(findError().text()).toBe('Something went wrong. Please try again.');
+ });
+
+ it('should show error on error response', async () => {
+ handler.mockResolvedValue(mutationErrorResponse);
+
+ mountFunction();
+
+ findForm().trigger('submit');
+ await waitForPromises();
+
+ expect(findError().text()).toBe(`${formName} is invalid.`);
+ });
+ },
+ );
+});
diff --git a/spec/frontend/crm/mock_data.js b/spec/frontend/crm/mock_data.js
index f7af2ccdb72..e351e101b29 100644
--- a/spec/frontend/crm/mock_data.js
+++ b/spec/frontend/crm/mock_data.js
@@ -82,7 +82,6 @@ export const getGroupOrganizationsQueryResponse = {
export const createContactMutationResponse = {
data: {
customerRelationsContactCreate: {
- __typeName: 'CustomerRelationsContactCreatePayload',
contact: {
__typename: 'CustomerRelationsContact',
id: 'gid://gitlab/CustomerRelations::Contact/1',
@@ -102,7 +101,7 @@ export const createContactMutationErrorResponse = {
data: {
customerRelationsContactCreate: {
contact: null,
- errors: ['Phone is invalid.'],
+ errors: ['create contact is invalid.'],
},
},
};
@@ -130,7 +129,7 @@ export const updateContactMutationErrorResponse = {
data: {
customerRelationsContactUpdate: {
contact: null,
- errors: ['Email is invalid.'],
+ errors: ['update contact is invalid.'],
},
},
};
@@ -138,7 +137,6 @@ export const updateContactMutationErrorResponse = {
export const createOrganizationMutationResponse = {
data: {
customerRelationsOrganizationCreate: {
- __typeName: 'CustomerRelationsOrganizationCreatePayload',
organization: {
__typename: 'CustomerRelationsOrganization',
id: 'gid://gitlab/CustomerRelations::Organization/2',
@@ -155,7 +153,7 @@ export const createOrganizationMutationErrorResponse = {
data: {
customerRelationsOrganizationCreate: {
organization: null,
- errors: ['Name cannot be blank.'],
+ errors: ['create organization is invalid.'],
},
},
};
diff --git a/spec/frontend/crm/new_organization_form_spec.js b/spec/frontend/crm/new_organization_form_spec.js
index 976b626f35f..0a7909774c9 100644
--- a/spec/frontend/crm/new_organization_form_spec.js
+++ b/spec/frontend/crm/new_organization_form_spec.js
@@ -103,7 +103,7 @@ describe('Customer relations organizations root app', () => {
await waitForPromises();
expect(findError().exists()).toBe(true);
- expect(findError().text()).toBe('Name cannot be blank.');
+ expect(findError().text()).toBe('create organization is invalid.');
});
});
});
diff --git a/spec/frontend/cycle_analytics/stage_table_spec.js b/spec/frontend/cycle_analytics/stage_table_spec.js
index 3158446c37d..9605dce2668 100644
--- a/spec/frontend/cycle_analytics/stage_table_spec.js
+++ b/spec/frontend/cycle_analytics/stage_table_spec.js
@@ -24,6 +24,7 @@ const findTable = () => wrapper.findComponent(GlTable);
const findTableHead = () => wrapper.find('thead');
const findTableHeadColumns = () => findTableHead().findAll('th');
const findStageEventTitle = (ev) => extendedWrapper(ev).findByTestId('vsa-stage-event-title');
+const findStageEventLink = (ev) => extendedWrapper(ev).findByTestId('vsa-stage-event-link');
const findStageTime = () => wrapper.findByTestId('vsa-stage-event-time');
const findIcon = (name) => wrapper.findByTestId(`${name}-icon`);
@@ -86,6 +87,15 @@ describe('StageTable', () => {
expect(titles[index]).toBe(ev.title);
});
});
+
+ it('will not display the project name in the record link', () => {
+ const evs = findStageEvents();
+
+ const links = evs.wrappers.map((ev) => findStageEventLink(ev).text());
+ issueEventItems.forEach((ev, index) => {
+ expect(links[index]).toBe(`#${ev.iid}`);
+ });
+ });
});
describe('default event', () => {
@@ -187,6 +197,53 @@ describe('StageTable', () => {
});
});
+ describe('includeProjectName set', () => {
+ const fakenamespace = 'some/fake/path';
+ beforeEach(() => {
+ wrapper = createComponent({ includeProjectName: true });
+ });
+
+ it('will display the project name in the record link', () => {
+ const evs = findStageEvents();
+
+ const links = evs.wrappers.map((ev) => findStageEventLink(ev).text());
+ issueEventItems.forEach((ev, index) => {
+ expect(links[index]).toBe(`${ev.projectPath}#${ev.iid}`);
+ });
+ });
+
+ describe.each`
+ namespaceFullPath | hasFullPath
+ ${'fake'} | ${false}
+ ${fakenamespace} | ${true}
+ `('with a namespace', ({ namespaceFullPath, hasFullPath }) => {
+ let evs = null;
+ let links = null;
+
+ beforeEach(() => {
+ wrapper = createComponent({
+ includeProjectName: true,
+ stageEvents: issueEventItems.map((ie) => ({ ...ie, namespaceFullPath })),
+ });
+
+ evs = findStageEvents();
+ links = evs.wrappers.map((ev) => findStageEventLink(ev).text());
+ });
+
+ it(`with namespaceFullPath='${namespaceFullPath}' ${
+ hasFullPath ? 'will' : 'does not'
+ } include the namespace`, () => {
+ issueEventItems.forEach((ev, index) => {
+ if (hasFullPath) {
+ expect(links[index]).toBe(`${namespaceFullPath}/${ev.projectPath}#${ev.iid}`);
+ } else {
+ expect(links[index]).toBe(`${ev.projectPath}#${ev.iid}`);
+ }
+ });
+ });
+ });
+ });
+
describe('Pagination', () => {
beforeEach(() => {
wrapper = createComponent();
diff --git a/spec/frontend/cycle_analytics/value_stream_metrics_spec.js b/spec/frontend/cycle_analytics/value_stream_metrics_spec.js
index c97e4845bc2..082db2cc312 100644
--- a/spec/frontend/cycle_analytics/value_stream_metrics_spec.js
+++ b/spec/frontend/cycle_analytics/value_stream_metrics_spec.js
@@ -63,6 +63,8 @@ describe('ValueStreamMetrics', () => {
it('renders hidden GlSingleStat components for each metric', async () => {
await waitForPromises();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ isLoading: true });
await wrapper.vm.$nextTick();
diff --git a/spec/frontend/deploy_freeze/components/timezone_dropdown_spec.js b/spec/frontend/deploy_freeze/components/timezone_dropdown_spec.js
index 4dd5c29a917..5f4d4071f29 100644
--- a/spec/frontend/deploy_freeze/components/timezone_dropdown_spec.js
+++ b/spec/frontend/deploy_freeze/components/timezone_dropdown_spec.js
@@ -26,6 +26,8 @@ describe('Deploy freeze timezone dropdown', () => {
},
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ searchTerm });
};
diff --git a/spec/frontend/design_management/components/design_notes/__snapshots__/design_note_signed_out_spec.js.snap b/spec/frontend/design_management/components/design_notes/__snapshots__/design_note_signed_out_spec.js.snap
new file mode 100644
index 00000000000..ab37cb90bd3
--- /dev/null
+++ b/spec/frontend/design_management/components/design_notes/__snapshots__/design_note_signed_out_spec.js.snap
@@ -0,0 +1,41 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`DesignNoteSignedOut renders message containing register and sign-in links while user wants to reply to a discussion 1`] = `
+<div
+ class="disabled-comment text-center"
+>
+ Please
+ <gl-link-stub
+ href="/users/sign_up?redirect_to_referer=yes"
+ >
+ register
+ </gl-link-stub>
+ or
+ <gl-link-stub
+ href="/users/sign_in?redirect_to_referer=yes"
+ >
+ sign in
+ </gl-link-stub>
+ to reply.
+</div>
+`;
+
+exports[`DesignNoteSignedOut renders message containing register and sign-in links while user wants to start a new discussion 1`] = `
+<div
+ class="disabled-comment text-center"
+>
+ Please
+ <gl-link-stub
+ href="/users/sign_up?redirect_to_referer=yes"
+ >
+ register
+ </gl-link-stub>
+ or
+ <gl-link-stub
+ href="/users/sign_in?redirect_to_referer=yes"
+ >
+ sign in
+ </gl-link-stub>
+ to start a new discussion.
+</div>
+`;
diff --git a/spec/frontend/design_management/components/design_notes/design_discussion_spec.js b/spec/frontend/design_management/components/design_notes/design_discussion_spec.js
index 9335d800a16..e816a05ba53 100644
--- a/spec/frontend/design_management/components/design_notes/design_discussion_spec.js
+++ b/spec/frontend/design_management/components/design_notes/design_discussion_spec.js
@@ -1,7 +1,9 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import { ApolloMutation } from 'vue-apollo';
import DesignDiscussion from '~/design_management/components/design_notes/design_discussion.vue';
import DesignNote from '~/design_management/components/design_notes/design_note.vue';
+import DesignNoteSignedOut from '~/design_management/components/design_notes/design_note_signed_out.vue';
import DesignReplyForm from '~/design_management/components/design_notes/design_reply_form.vue';
import ToggleRepliesWidget from '~/design_management/components/design_notes/toggle_replies_widget.vue';
import createNoteMutation from '~/design_management/graphql/mutations/create_note.mutation.graphql';
@@ -20,6 +22,7 @@ const defaultMockDiscussion = {
const DEFAULT_TODO_COUNT = 2;
describe('Design discussions component', () => {
+ const originalGon = window.gon;
let wrapper;
const findDesignNotes = () => wrapper.findAll(DesignNote);
@@ -31,6 +34,7 @@ describe('Design discussions component', () => {
const findResolvedMessage = () => wrapper.find('[data-testid="resolved-message"]');
const findResolveLoadingIcon = () => wrapper.find(GlLoadingIcon);
const findResolveCheckbox = () => wrapper.find('[data-testid="resolve-checkbox"]');
+ const findApolloMutation = () => wrapper.findComponent(ApolloMutation);
const mutationVariables = {
mutation: createNoteMutation,
@@ -42,6 +46,8 @@ describe('Design discussions component', () => {
},
},
};
+ const registerPath = '/users/sign_up?redirect_to_referer=yes';
+ const signInPath = '/users/sign_in?redirect_to_referer=yes';
const mutate = jest.fn().mockResolvedValue({ data: { createNote: { errors: [] } } });
const readQuery = jest.fn().mockReturnValue({
project: {
@@ -62,6 +68,8 @@ describe('Design discussions component', () => {
designId: 'design-id',
discussionIndex: 1,
discussionWithOpenForm: '',
+ registerPath,
+ signInPath,
...props,
},
data() {
@@ -88,8 +96,13 @@ describe('Design discussions component', () => {
});
}
+ beforeEach(() => {
+ window.gon = { current_user_id: 1 };
+ });
+
afterEach(() => {
wrapper.destroy();
+ window.gon = originalGon;
});
describe('when discussion is not resolvable', () => {
@@ -349,4 +362,41 @@ describe('Design discussions component', () => {
expect(wrapper.emitted('open-form')).toBeTruthy();
});
+
+ describe('when user is not logged in', () => {
+ const findDesignNoteSignedOut = () => wrapper.findComponent(DesignNoteSignedOut);
+
+ beforeEach(() => {
+ window.gon = { current_user_id: null };
+ createComponent(
+ {
+ discussion: {
+ ...defaultMockDiscussion,
+ },
+ discussionWithOpenForm: defaultMockDiscussion.id,
+ },
+ { discussionComment: 'test', isFormRendered: true },
+ );
+ });
+
+ it('does not render resolve discussion button', () => {
+ expect(findResolveButton().exists()).toBe(false);
+ });
+
+ it('does not render replace-placeholder component', () => {
+ expect(findReplyPlaceholder().exists()).toBe(false);
+ });
+
+ it('does not render apollo-mutation component', () => {
+ expect(findApolloMutation().exists()).toBe(false);
+ });
+
+ it('renders design-note-signed-out component', () => {
+ expect(findDesignNoteSignedOut().exists()).toBe(true);
+ expect(findDesignNoteSignedOut().props()).toMatchObject({
+ registerPath,
+ signInPath,
+ });
+ });
+ });
});
diff --git a/spec/frontend/design_management/components/design_notes/design_note_signed_out_spec.js b/spec/frontend/design_management/components/design_notes/design_note_signed_out_spec.js
new file mode 100644
index 00000000000..e71bb5ab520
--- /dev/null
+++ b/spec/frontend/design_management/components/design_notes/design_note_signed_out_spec.js
@@ -0,0 +1,36 @@
+import { GlSprintf } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import DesignNoteSignedOut from '~/design_management/components/design_notes/design_note_signed_out.vue';
+
+function createComponent(isAddDiscussion = false) {
+ return shallowMount(DesignNoteSignedOut, {
+ propsData: {
+ registerPath: '/users/sign_up?redirect_to_referer=yes',
+ signInPath: '/users/sign_in?redirect_to_referer=yes',
+ isAddDiscussion,
+ },
+ stubs: {
+ GlSprintf,
+ },
+ });
+}
+
+describe('DesignNoteSignedOut', () => {
+ let wrapper;
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders message containing register and sign-in links while user wants to reply to a discussion', () => {
+ wrapper = createComponent();
+
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ it('renders message containing register and sign-in links while user wants to start a new discussion', () => {
+ wrapper = createComponent(true);
+
+ expect(wrapper.element).toMatchSnapshot();
+ });
+});
diff --git a/spec/frontend/design_management/components/design_overlay_spec.js b/spec/frontend/design_management/components/design_overlay_spec.js
index d3119be7159..4bda5054090 100644
--- a/spec/frontend/design_management/components/design_overlay_spec.js
+++ b/spec/frontend/design_management/components/design_overlay_spec.js
@@ -117,6 +117,8 @@ describe('Design overlay component', () => {
it.each([notes[0].discussion.notes.nodes[1], notes[0].discussion.notes.nodes[0]])(
'should not apply inactive class to the pin for the active discussion',
(note) => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
activeDiscussion: {
id: note.id,
@@ -131,6 +133,8 @@ describe('Design overlay component', () => {
);
it('should apply inactive class to all pins besides the active one', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
activeDiscussion: {
id: notes[0].id,
@@ -212,6 +216,8 @@ describe('Design overlay component', () => {
const { position } = note;
const newCoordinates = { x: 20, y: 20 };
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
movingNoteNewPosition: {
...position,
@@ -345,6 +351,8 @@ describe('Design overlay component', () => {
});
const newCoordinates = { x: 20, y: 20 };
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
movingNoteStartPosition: {
...notes[0].position,
@@ -368,6 +376,8 @@ describe('Design overlay component', () => {
it('should calculate delta correctly from state', () => {
createComponent();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
movingNoteStartPosition: {
clientX: 10,
diff --git a/spec/frontend/design_management/components/design_presentation_spec.js b/spec/frontend/design_management/components/design_presentation_spec.js
index edf8b965153..adec9ef469d 100644
--- a/spec/frontend/design_management/components/design_presentation_spec.js
+++ b/spec/frontend/design_management/components/design_presentation_spec.js
@@ -15,6 +15,7 @@ const mockOverlayData = {
};
describe('Design management design presentation component', () => {
+ const originalGon = window.gon;
let wrapper;
function createComponent(
@@ -39,6 +40,8 @@ describe('Design management design presentation component', () => {
stubs,
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData(data);
wrapper.element.scrollTo = jest.fn();
}
@@ -113,8 +116,13 @@ describe('Design management design presentation component', () => {
});
}
+ beforeEach(() => {
+ window.gon = { current_user_id: 1 };
+ });
+
afterEach(() => {
wrapper.destroy();
+ window.gon = originalGon;
});
it('renders image and overlay when image provided', () => {
@@ -550,4 +558,23 @@ describe('Design management design presentation component', () => {
});
});
});
+
+ describe('when user is not logged in', () => {
+ beforeEach(() => {
+ window.gon = { current_user_id: null };
+ createComponent(
+ {
+ image: 'test.jpg',
+ imageName: 'test',
+ },
+ mockOverlayData,
+ );
+ });
+
+ it('disables commenting from design overlay', () => {
+ expect(wrapper.findComponent(DesignOverlay).props()).toMatchObject({
+ disableCommenting: true,
+ });
+ });
+ });
});
diff --git a/spec/frontend/design_management/components/design_sidebar_spec.js b/spec/frontend/design_management/components/design_sidebar_spec.js
index 8eb993ec7b5..4cd71bdb7f3 100644
--- a/spec/frontend/design_management/components/design_sidebar_spec.js
+++ b/spec/frontend/design_management/components/design_sidebar_spec.js
@@ -2,6 +2,7 @@ import { GlCollapse, GlPopover } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Cookies from 'js-cookie';
import DesignDiscussion from '~/design_management/components/design_notes/design_discussion.vue';
+import DesignNoteSignedOut from '~/design_management/components/design_notes/design_note_signed_out.vue';
import DesignSidebar from '~/design_management/components/design_sidebar.vue';
import DesignTodoButton from '~/design_management/components/design_todo_button.vue';
import updateActiveDiscussionMutation from '~/design_management/graphql/mutations/update_active_discussion.mutation.graphql';
@@ -30,6 +31,7 @@ const cookieKey = 'hide_design_resolved_comments_popover';
const mutate = jest.fn().mockResolvedValue();
describe('Design management design sidebar component', () => {
+ const originalGon = window.gon;
let wrapper;
const findDiscussions = () => wrapper.findAll(DesignDiscussion);
@@ -58,11 +60,20 @@ describe('Design management design sidebar component', () => {
},
},
stubs: { GlPopover },
+ provide: {
+ registerPath: '/users/sign_up?redirect_to_referer=yes',
+ signInPath: '/users/sign_in?redirect_to_referer=yes',
+ },
});
}
+ beforeEach(() => {
+ window.gon = { current_user_id: 1 };
+ });
+
afterEach(() => {
wrapper.destroy();
+ window.gon = originalGon;
});
it('renders participants', () => {
@@ -248,4 +259,44 @@ describe('Design management design sidebar component', () => {
expect(Cookies.set).toHaveBeenCalledWith(cookieKey, 'true', { expires: 365 * 10 });
});
});
+
+ describe('when user is not logged in', () => {
+ const findDesignNoteSignedOut = () => wrapper.findComponent(DesignNoteSignedOut);
+
+ beforeEach(() => {
+ window.gon = { current_user_id: null };
+ });
+
+ describe('design has no discussions', () => {
+ beforeEach(() => {
+ createComponent({
+ design: {
+ ...design,
+ discussions: {
+ nodes: [],
+ },
+ },
+ });
+ });
+
+ it('does not render a message about possibility to create a new discussion', () => {
+ expect(findNewDiscussionDisclaimer().exists()).toBe(false);
+ });
+
+ it('renders design-note-signed-out component', () => {
+ expect(findDesignNoteSignedOut().exists()).toBe(true);
+ });
+ });
+
+ describe('design has discussions', () => {
+ beforeEach(() => {
+ Cookies.set(cookieKey, true);
+ createComponent();
+ });
+
+ it('renders design-note-signed-out component', () => {
+ expect(findDesignNoteSignedOut().exists()).toBe(true);
+ });
+ });
+ });
});
diff --git a/spec/frontend/design_management/components/image_spec.js b/spec/frontend/design_management/components/image_spec.js
index 765d902f9a6..ac3afc73c86 100644
--- a/spec/frontend/design_management/components/image_spec.js
+++ b/spec/frontend/design_management/components/image_spec.js
@@ -9,6 +9,8 @@ describe('Design management large image component', () => {
wrapper = shallowMount(DesignImage, {
propsData,
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData(data);
}
diff --git a/spec/frontend/design_management/components/toolbar/design_navigation_spec.js b/spec/frontend/design_management/components/toolbar/design_navigation_spec.js
index 1d9b9c002f9..6e0592984a2 100644
--- a/spec/frontend/design_management/components/toolbar/design_navigation_spec.js
+++ b/spec/frontend/design_management/components/toolbar/design_navigation_spec.js
@@ -42,6 +42,8 @@ describe('Design management pagination component', () => {
});
it('renders navigation buttons', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
designCollection: { designs: [{ id: '1' }, { id: '2' }] },
});
@@ -53,6 +55,8 @@ describe('Design management pagination component', () => {
describe('keyboard buttons navigation', () => {
beforeEach(() => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
designCollection: { designs: [{ filename: '1' }, { filename: '2' }, { filename: '3' }] },
});
diff --git a/spec/frontend/design_management/components/toolbar/index_spec.js b/spec/frontend/design_management/components/toolbar/index_spec.js
index 009ffe57744..cf872046f53 100644
--- a/spec/frontend/design_management/components/toolbar/index_spec.js
+++ b/spec/frontend/design_management/components/toolbar/index_spec.js
@@ -48,6 +48,8 @@ describe('Design management toolbar component', () => {
},
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
permissions: {
createDesign,
diff --git a/spec/frontend/design_management/components/upload/design_version_dropdown_spec.js b/spec/frontend/design_management/components/upload/design_version_dropdown_spec.js
index ebfe27eaa71..a4fb671ae13 100644
--- a/spec/frontend/design_management/components/upload/design_version_dropdown_spec.js
+++ b/spec/frontend/design_management/components/upload/design_version_dropdown_spec.js
@@ -34,6 +34,8 @@ describe('Design management design version dropdown component', () => {
stubs: { GlSprintf },
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
allVersions: maxVersions > -1 ? mockAllVersions.slice(0, maxVersions) : mockAllVersions,
});
diff --git a/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap b/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap
index 3d04840b1f8..31b3117cb6c 100644
--- a/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap
+++ b/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap
@@ -70,6 +70,13 @@ exports[`Design management design index page renders design index 1`] = `
<!---->
+ <design-note-signed-out-stub
+ class="gl-mb-4"
+ isadddiscussion="true"
+ registerpath=""
+ signinpath=""
+ />
+
<design-discussion-stub
data-testid="unresolved-discussion"
designid="gid::/gitlab/Design/1"
@@ -77,6 +84,8 @@ exports[`Design management design index page renders design index 1`] = `
discussionwithopenform=""
markdownpreviewpath="/project-path/preview_markdown?target_type=Issue"
noteableid="gid::/gitlab/Design/1"
+ registerpath=""
+ signinpath=""
/>
<gl-button-stub
@@ -126,6 +135,8 @@ exports[`Design management design index page renders design index 1`] = `
discussionwithopenform=""
markdownpreviewpath="/project-path/preview_markdown?target_type=Issue"
noteableid="gid::/gitlab/Design/1"
+ registerpath=""
+ signinpath=""
/>
</gl-collapse-stub>
@@ -231,14 +242,14 @@ exports[`Design management design index page with error GlAlert is rendered in c
participants="[object Object]"
/>
- <h2
- class="new-discussion-disclaimer gl-font-base gl-m-0 gl-mb-4"
- data-testid="new-discussion-disclaimer"
- >
-
- Click the image where you'd like to start a new discussion
-
- </h2>
+ <!---->
+
+ <design-note-signed-out-stub
+ class="gl-mb-4"
+ isadddiscussion="true"
+ registerpath=""
+ signinpath=""
+ />
<!---->
diff --git a/spec/frontend/design_management/pages/design/index_spec.js b/spec/frontend/design_management/pages/design/index_spec.js
index 6ce384b4869..98e2313e9f2 100644
--- a/spec/frontend/design_management/pages/design/index_spec.js
+++ b/spec/frontend/design_management/pages/design/index_spec.js
@@ -317,6 +317,8 @@ describe('Design management design index page', () => {
describe('when no design exists for given version', () => {
it('redirects to /designs', () => {
createComponent({ loading: true });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
allVersions: mockAllVersions,
});
diff --git a/spec/frontend/design_management/pages/index_spec.js b/spec/frontend/design_management/pages/index_spec.js
index 427161a391b..dd0f7972553 100644
--- a/spec/frontend/design_management/pages/index_spec.js
+++ b/spec/frontend/design_management/pages/index_spec.js
@@ -91,6 +91,8 @@ const designToMove = {
};
describe('Design management index page', () => {
+ const registerPath = '/users/sign_up?redirect_to_referer=yes';
+ const signInPath = '/users/sign_in?redirect_to_referer=yes';
let mutate;
let wrapper;
let fakeApollo;
@@ -164,6 +166,8 @@ describe('Design management index page', () => {
provide: {
projectPath: 'project-path',
issueIid: '1',
+ registerPath,
+ signInPath,
},
});
}
@@ -186,6 +190,10 @@ describe('Design management index page', () => {
apolloProvider: fakeApollo,
router,
stubs: { VueDraggable },
+ provide: {
+ registerPath,
+ signInPath,
+ },
});
}
@@ -204,6 +212,8 @@ describe('Design management index page', () => {
it('renders error', async () => {
createComponent();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ error: true });
await nextTick();
@@ -381,6 +391,8 @@ describe('Design management index page', () => {
it('updates state appropriately after upload complete', async () => {
createComponent({ stubs: { GlEmptyState } });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ filesToBeSaved: [{ name: 'test' }] });
wrapper.vm.onUploadDesignDone(designUploadMutationCreatedResponse);
@@ -393,6 +405,8 @@ describe('Design management index page', () => {
it('updates state appropriately after upload error', async () => {
createComponent({ stubs: { GlEmptyState } });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ filesToBeSaved: [{ name: 'test' }] });
wrapper.vm.onUploadDesignError();
diff --git a/spec/frontend/diffs/components/image_diff_overlay_spec.js b/spec/frontend/diffs/components/image_diff_overlay_spec.js
index 47b144b2387..8c1a8041f6c 100644
--- a/spec/frontend/diffs/components/image_diff_overlay_spec.js
+++ b/spec/frontend/diffs/components/image_diff_overlay_spec.js
@@ -6,8 +6,8 @@ import { imageDiffDiscussions } from '../mock_data/diff_discussions';
describe('Diffs image diff overlay component', () => {
const dimensions = {
- width: 100,
- height: 200,
+ width: 99.9,
+ height: 199.5,
};
let wrapper;
let dispatch;
@@ -38,7 +38,6 @@ describe('Diffs image diff overlay component', () => {
afterEach(() => {
wrapper.destroy();
- wrapper = null;
});
it('renders comment badges', () => {
@@ -81,17 +80,21 @@ describe('Diffs image diff overlay component', () => {
it('dispatches openDiffFileCommentForm when clicking overlay', () => {
createComponent({ canComment: true });
- wrapper.find('.js-add-image-diff-note-button').trigger('click', { offsetX: 0, offsetY: 0 });
+ wrapper.find('.js-add-image-diff-note-button').trigger('click', { offsetX: 1.2, offsetY: 3.8 });
expect(dispatch).toHaveBeenCalledWith('diffs/openDiffFileCommentForm', {
fileHash: 'ABC',
- x: 0,
- y: 0,
+ x: 1,
+ y: 4,
width: 100,
height: 200,
- xPercent: 0,
- yPercent: 0,
+ xPercent: expect.any(Number),
+ yPercent: expect.any(Number),
});
+
+ const { xPercent, yPercent } = dispatch.mock.calls[0][1];
+ expect(xPercent).toBeCloseTo(0.6);
+ expect(yPercent).toBeCloseTo(1.9);
});
describe('toggle discussion', () => {
diff --git a/spec/frontend/editor/source_editor_spec.js b/spec/frontend/editor/source_editor_spec.js
index bc53202c919..049cab3a83b 100644
--- a/spec/frontend/editor/source_editor_spec.js
+++ b/spec/frontend/editor/source_editor_spec.js
@@ -342,27 +342,30 @@ describe('Base editor', () => {
describe('implementation', () => {
let instance;
- beforeEach(() => {
- instance = editor.createInstance({ el: editorEl, blobPath, blobContent });
- });
it('correctly proxies value from the model', () => {
+ instance = editor.createInstance({ el: editorEl, blobPath, blobContent });
expect(instance.getValue()).toBe(blobContent);
});
- it('emits the EDITOR_READY_EVENT event after setting up the instance', () => {
+ it('emits the EDITOR_READY_EVENT event passing the instance after setting it up', () => {
jest.spyOn(monacoEditor, 'create').mockImplementation(() => {
return {
setModel: jest.fn(),
onDidDispose: jest.fn(),
layout: jest.fn(),
+ dispose: jest.fn(),
};
});
- const eventSpy = jest.fn();
+ let passedInstance;
+ const eventSpy = jest.fn().mockImplementation((ev) => {
+ passedInstance = ev.detail.instance;
+ });
editorEl.addEventListener(EDITOR_READY_EVENT, eventSpy);
expect(eventSpy).not.toHaveBeenCalled();
- editor.createInstance({ el: editorEl });
+ instance = editor.createInstance({ el: editorEl });
expect(eventSpy).toHaveBeenCalled();
+ expect(passedInstance).toBe(instance);
});
});
diff --git a/spec/frontend/emoji/components/category_spec.js b/spec/frontend/emoji/components/category_spec.js
index afd36a1eb88..82dc0cdc250 100644
--- a/spec/frontend/emoji/components/category_spec.js
+++ b/spec/frontend/emoji/components/category_spec.js
@@ -26,6 +26,8 @@ describe('Emoji category component', () => {
});
it('renders group', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
await wrapper.setData({ renderGroup: true });
expect(wrapper.find(EmojiGroup).attributes('rendergroup')).toBe('true');
diff --git a/spec/frontend/emoji/components/emoji_list_spec.js b/spec/frontend/emoji/components/emoji_list_spec.js
index 9dc73ef191e..a72ba614d9f 100644
--- a/spec/frontend/emoji/components/emoji_list_spec.js
+++ b/spec/frontend/emoji/components/emoji_list_spec.js
@@ -28,6 +28,8 @@ async function factory(render, propsData = { searchValue: '' }) {
await nextTick();
if (render) {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ render: true });
// Wait for component to render
diff --git a/spec/frontend/environments/confirm_rollback_modal_spec.js b/spec/frontend/environments/confirm_rollback_modal_spec.js
index b699f953945..b8dcb7c0d08 100644
--- a/spec/frontend/environments/confirm_rollback_modal_spec.js
+++ b/spec/frontend/environments/confirm_rollback_modal_spec.js
@@ -26,7 +26,7 @@ describe('Confirm Rollback Modal Component', () => {
commit: {
shortId: 'abc0123',
},
- 'last?': true,
+ isLast: true,
},
modalId: 'test',
};
@@ -145,7 +145,7 @@ describe('Confirm Rollback Modal Component', () => {
...environment,
lastDeployment: {
...environment.lastDeployment,
- 'last?': false,
+ isLast: false,
},
},
hasMultipleCommits,
@@ -167,7 +167,7 @@ describe('Confirm Rollback Modal Component', () => {
...environment,
lastDeployment: {
...environment.lastDeployment,
- 'last?': false,
+ isLast: false,
},
},
hasMultipleCommits,
@@ -191,7 +191,7 @@ describe('Confirm Rollback Modal Component', () => {
...environment,
lastDeployment: {
...environment.lastDeployment,
- 'last?': true,
+ isLast: true,
},
},
hasMultipleCommits,
diff --git a/spec/frontend/environments/deployment_spec.js b/spec/frontend/environments/deployment_spec.js
new file mode 100644
index 00000000000..37209bdc86c
--- /dev/null
+++ b/spec/frontend/environments/deployment_spec.js
@@ -0,0 +1,29 @@
+import { mountExtended } from 'helpers/vue_test_utils_helper';
+import Deployment from '~/environments/components/deployment.vue';
+import DeploymentStatusBadge from '~/environments/components/deployment_status_badge.vue';
+import { resolvedEnvironment } from './graphql/mock_data';
+
+describe('~/environments/components/deployment.vue', () => {
+ let wrapper;
+
+ const createWrapper = ({ propsData = {} } = {}) =>
+ mountExtended(Deployment, {
+ propsData: {
+ deployment: resolvedEnvironment.lastDeployment,
+ ...propsData,
+ },
+ });
+
+ afterEach(() => {
+ wrapper?.destroy();
+ });
+
+ describe('status', () => {
+ it('should pass the deployable status to the badge', () => {
+ wrapper = createWrapper();
+ expect(wrapper.findComponent(DeploymentStatusBadge).props('status')).toBe(
+ resolvedEnvironment.lastDeployment.status,
+ );
+ });
+ });
+});
diff --git a/spec/frontend/environments/deployment_status_badge_spec.js b/spec/frontend/environments/deployment_status_badge_spec.js
new file mode 100644
index 00000000000..02aae57396a
--- /dev/null
+++ b/spec/frontend/environments/deployment_status_badge_spec.js
@@ -0,0 +1,42 @@
+import { GlBadge } from '@gitlab/ui';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
+import { s__ } from '~/locale';
+import DeploymentStatusBadge from '~/environments/components/deployment_status_badge.vue';
+
+describe('~/environments/components/deployment_status_badge.vue', () => {
+ let wrapper;
+
+ const createWrapper = ({ propsData = {} } = {}) =>
+ mountExtended(DeploymentStatusBadge, {
+ propsData,
+ });
+
+ describe.each`
+ status | text | variant | icon
+ ${'created'} | ${s__('Deployment|Created')} | ${'neutral'} | ${'status_created'}
+ ${'running'} | ${s__('Deployment|Running')} | ${'info'} | ${'status_running'}
+ ${'success'} | ${s__('Deployment|Success')} | ${'success'} | ${'status_success'}
+ ${'failed'} | ${s__('Deployment|Failed')} | ${'danger'} | ${'status_failed'}
+ ${'canceled'} | ${s__('Deployment|Cancelled')} | ${'neutral'} | ${'status_canceled'}
+ ${'skipped'} | ${s__('Deployment|Skipped')} | ${'neutral'} | ${'status_skipped'}
+ ${'blocked'} | ${s__('Deployment|Waiting')} | ${'neutral'} | ${'status_manual'}
+ `('$status', ({ status, text, variant, icon }) => {
+ let badge;
+
+ beforeEach(() => {
+ wrapper = createWrapper({ propsData: { status } });
+ badge = wrapper.findComponent(GlBadge);
+ });
+
+ it(`sets the text to ${text}`, () => {
+ expect(wrapper.text()).toBe(text);
+ });
+
+ it(`sets the variant to ${variant}`, () => {
+ expect(badge.props('variant')).toBe(variant);
+ });
+ it(`sets the icon to ${icon}`, () => {
+ expect(badge.props('icon')).toBe(icon);
+ });
+ });
+});
diff --git a/spec/frontend/environments/environment_actions_spec.js b/spec/frontend/environments/environment_actions_spec.js
index db78a6b0cdd..1b68a692db8 100644
--- a/spec/frontend/environments/environment_actions_spec.js
+++ b/spec/frontend/environments/environment_actions_spec.js
@@ -1,9 +1,13 @@
import { GlDropdown, GlDropdownItem, GlLoadingIcon, GlIcon } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
import { TEST_HOST } from 'helpers/test_constants';
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 createMockApollo from 'helpers/mock_apollo_helper';
const scheduledJobAction = {
name: 'scheduled action',
@@ -25,12 +29,13 @@ describe('EnvironmentActions Component', () => {
const findEnvironmentActionsButton = () =>
wrapper.find('[data-testid="environment-actions-button"]');
- function createComponent(props, { mountFn = shallowMount } = {}) {
+ function createComponent(props, { mountFn = shallowMount, options = {} } = {}) {
wrapper = mountFn(EnvironmentActions, {
propsData: { actions: [], ...props },
directives: {
GlTooltip: createMockDirective(),
},
+ ...options,
});
}
@@ -150,4 +155,32 @@ describe('EnvironmentActions Component', () => {
expect(findDropdownItem(expiredJobAction).text()).toContain('00:00:00');
});
});
+
+ describe('graphql', () => {
+ Vue.use(VueApollo);
+
+ const action = {
+ name: 'bar',
+ play_path: 'https://gitlab.com/play',
+ };
+
+ let mockApollo;
+
+ beforeEach(() => {
+ mockApollo = createMockApollo();
+ createComponent(
+ { actions: [action], graphql: true },
+ { options: { apolloProvider: mockApollo } },
+ );
+ });
+
+ it('should trigger a graphql mutation on click', () => {
+ jest.spyOn(mockApollo.defaultClient, 'mutate');
+ findDropdownItem(action).vm.$emit('click');
+ expect(mockApollo.defaultClient.mutate).toHaveBeenCalledWith({
+ mutation: actionMutation,
+ variables: { action },
+ });
+ });
+ });
});
diff --git a/spec/frontend/environments/environment_stop_spec.js b/spec/frontend/environments/environment_stop_spec.js
index dff444b79f3..358abca2f77 100644
--- a/spec/frontend/environments/environment_stop_spec.js
+++ b/spec/frontend/environments/environment_stop_spec.js
@@ -1,38 +1,80 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import $ from 'jquery';
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import setEnvironmentToStopMutation from '~/environments/graphql/mutations/set_environment_to_stop.mutation.graphql';
+import isEnvironmentStoppingQuery from '~/environments/graphql/queries/is_environment_stopping.query.graphql';
import StopComponent from '~/environments/components/environment_stop.vue';
import eventHub from '~/environments/event_hub';
-
-$.fn.tooltip = () => {};
+import createMockApollo from 'helpers/mock_apollo_helper';
+import { resolvedEnvironment } from './graphql/mock_data';
describe('Stop Component', () => {
let wrapper;
- const createWrapper = () => {
+ const createWrapper = (props = {}, options = {}) => {
wrapper = shallowMount(StopComponent, {
propsData: {
environment: {},
+ ...props,
},
+ ...options,
});
};
const findButton = () => wrapper.find(GlButton);
- beforeEach(() => {
- jest.spyOn(window, 'confirm');
+ describe('eventHub', () => {
+ beforeEach(() => {
+ createWrapper();
+ });
- createWrapper();
- });
+ it('should render a button to stop the environment', () => {
+ expect(findButton().exists()).toBe(true);
+ expect(wrapper.attributes('title')).toEqual('Stop environment');
+ });
- it('should render a button to stop the environment', () => {
- expect(findButton().exists()).toBe(true);
- expect(wrapper.attributes('title')).toEqual('Stop environment');
+ it('emits requestStopEnvironment in the event hub when button is clicked', () => {
+ jest.spyOn(eventHub, '$emit');
+ findButton().vm.$emit('click');
+ expect(eventHub.$emit).toHaveBeenCalledWith('requestStopEnvironment', wrapper.vm.environment);
+ });
});
- it('emits requestStopEnvironment in the event hub when button is clicked', () => {
- jest.spyOn(eventHub, '$emit');
- findButton().vm.$emit('click');
- expect(eventHub.$emit).toHaveBeenCalledWith('requestStopEnvironment', wrapper.vm.environment);
+ describe('graphql', () => {
+ Vue.use(VueApollo);
+ let mockApollo;
+
+ beforeEach(() => {
+ mockApollo = createMockApollo();
+ mockApollo.clients.defaultClient.writeQuery({
+ query: isEnvironmentStoppingQuery,
+ variables: { environment: resolvedEnvironment },
+ data: { isEnvironmentStopping: true },
+ });
+
+ createWrapper(
+ { graphql: true, environment: resolvedEnvironment },
+ { apolloProvider: mockApollo },
+ );
+ });
+
+ it('should render a button to stop the environment', () => {
+ expect(findButton().exists()).toBe(true);
+ expect(wrapper.attributes('title')).toEqual('Stop environment');
+ });
+
+ it('sets the environment to stop on click', () => {
+ jest.spyOn(mockApollo.defaultClient, 'mutate');
+ findButton().vm.$emit('click');
+ expect(mockApollo.defaultClient.mutate).toHaveBeenCalledWith({
+ mutation: setEnvironmentToStopMutation,
+ variables: { environment: resolvedEnvironment },
+ });
+ });
+
+ it('should show a loading icon if the environment is currently stopping', async () => {
+ expect(findButton().props('loading')).toBe(true);
+ });
});
});
diff --git a/spec/frontend/environments/graphql/mock_data.js b/spec/frontend/environments/graphql/mock_data.js
index e75d3ac0321..fce30973547 100644
--- a/spec/frontend/environments/graphql/mock_data.js
+++ b/spec/frontend/environments/graphql/mock_data.js
@@ -477,7 +477,141 @@ export const resolvedEnvironment = {
externalUrl: 'https://example.org',
environmentType: 'review',
nameWithoutType: 'hello',
- lastDeployment: null,
+ lastDeployment: {
+ id: 78,
+ iid: 24,
+ sha: 'f3ba6dd84f8f891373e9b869135622b954852db1',
+ ref: { name: 'main', refPath: '/h5bp/html5-boilerplate/-/tree/main' },
+ status: 'success',
+ createdAt: '2022-01-07T15:47:27.415Z',
+ deployedAt: '2022-01-07T15:47:32.450Z',
+ tag: false,
+ isLast: true,
+ user: {
+ id: 1,
+ username: 'root',
+ name: 'Administrator',
+ state: 'active',
+ avatarUrl:
+ 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ webUrl: 'http://gck.test:3000/root',
+ showStatus: false,
+ path: '/root',
+ },
+ deployable: {
+ id: 1014,
+ name: 'deploy-prod',
+ started: '2022-01-07T15:47:31.037Z',
+ complete: true,
+ archived: false,
+ buildPath: '/h5bp/html5-boilerplate/-/jobs/1014',
+ retryPath: '/h5bp/html5-boilerplate/-/jobs/1014/retry',
+ playable: false,
+ scheduled: false,
+ createdAt: '2022-01-07T15:47:27.404Z',
+ updatedAt: '2022-01-07T15:47:32.341Z',
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ hasDetails: true,
+ detailsPath: '/h5bp/html5-boilerplate/-/jobs/1014',
+ illustration: {
+ image:
+ '/assets/illustrations/skipped-job_empty-29a8a37d8a61d1b6f68cf3484f9024e53cd6eb95e28eae3554f8011a1146bf27.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/h5bp/html5-boilerplate/-/jobs/1014/retry',
+ method: 'post',
+ buttonTitle: 'Retry this job',
+ },
+ },
+ },
+ commit: {
+ id: 'f3ba6dd84f8f891373e9b869135622b954852db1',
+ shortId: 'f3ba6dd8',
+ createdAt: '2022-01-07T15:47:26.000+00:00',
+ parentIds: ['3213b6ac17afab99be37d5d38f38c6c8407387cc'],
+ title: 'Update .gitlab-ci.yml file',
+ message: 'Update .gitlab-ci.yml file',
+ authorName: 'Administrator',
+ authorEmail: 'admin@example.com',
+ authoredDate: '2022-01-07T15:47:26.000+00:00',
+ committerName: 'Administrator',
+ committerEmail: 'admin@example.com',
+ committedDate: '2022-01-07T15:47:26.000+00:00',
+ trailers: {},
+ webUrl:
+ 'http://gck.test:3000/h5bp/html5-boilerplate/-/commit/f3ba6dd84f8f891373e9b869135622b954852db1',
+ author: {
+ id: 1,
+ username: 'root',
+ name: 'Administrator',
+ state: 'active',
+ avatarUrl:
+ 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ webUrl: 'http://gck.test:3000/root',
+ showStatus: false,
+ path: '/root',
+ },
+ authorGravatarUrl:
+ 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ commitUrl:
+ 'http://gck.test:3000/h5bp/html5-boilerplate/-/commit/f3ba6dd84f8f891373e9b869135622b954852db1',
+ commitPath: '/h5bp/html5-boilerplate/-/commit/f3ba6dd84f8f891373e9b869135622b954852db1',
+ },
+ manualActions: [
+ {
+ id: 1015,
+ name: 'deploy-staging',
+ started: null,
+ complete: false,
+ archived: false,
+ buildPath: '/h5bp/html5-boilerplate/-/jobs/1015',
+ playPath: '/h5bp/html5-boilerplate/-/jobs/1015/play',
+ playable: true,
+ scheduled: false,
+ createdAt: '2022-01-07T15:47:27.422Z',
+ updatedAt: '2022-01-07T15:47:28.557Z',
+ status: {
+ icon: 'status_manual',
+ text: 'manual',
+ label: 'manual play action',
+ group: 'manual',
+ tooltip: 'manual action',
+ hasDetails: true,
+ detailsPath: '/h5bp/html5-boilerplate/-/jobs/1015',
+ illustration: {
+ image:
+ '/assets/illustrations/manual_action-c55aee2c5f9ebe9f72751480af8bb307be1a6f35552f344cc6d1bf979d3422f6.svg',
+ size: 'svg-394',
+ title: 'This job requires a manual action',
+ content:
+ 'This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
+ action: {
+ icon: 'play',
+ title: 'Play',
+ path: '/h5bp/html5-boilerplate/-/jobs/1015/play',
+ method: 'post',
+ buttonTitle: 'Trigger this manual action',
+ },
+ },
+ },
+ ],
+ scheduledActions: [],
+ cluster: null,
+ },
hasStopAction: false,
rolloutStatus: null,
environmentPath: '/h5bp/html5-boilerplate/-/environments/41',
diff --git a/spec/frontend/environments/graphql/resolvers_spec.js b/spec/frontend/environments/graphql/resolvers_spec.js
index d8d26b74504..6b53dc24f0f 100644
--- a/spec/frontend/environments/graphql/resolvers_spec.js
+++ b/spec/frontend/environments/graphql/resolvers_spec.js
@@ -1,8 +1,10 @@
import MockAdapter from 'axios-mock-adapter';
+import { s__ } from '~/locale';
import axios from '~/lib/utils/axios_utils';
import { resolvers } from '~/environments/graphql/resolvers';
import environmentToRollback from '~/environments/graphql/queries/environment_to_rollback.query.graphql';
import environmentToDelete from '~/environments/graphql/queries/environment_to_delete.query.graphql';
+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 pageInfoQuery from '~/environments/graphql/queries/page_info.query.graphql';
@@ -210,4 +212,36 @@ describe('~/frontend/environments/graphql/resolvers', () => {
});
});
});
+ describe('setEnvironmentToStop', () => {
+ it('should write the given environment to the cache', () => {
+ localState.client.writeQuery = jest.fn();
+ mockResolvers.Mutation.setEnvironmentToStop(
+ null,
+ { environment: resolvedEnvironment },
+ localState,
+ );
+
+ expect(localState.client.writeQuery).toHaveBeenCalledWith({
+ query: environmentToStopQuery,
+ data: { environmentToStop: resolvedEnvironment },
+ });
+ });
+ });
+ describe('action', () => {
+ it('should POST to the given path', async () => {
+ mock.onPost(ENDPOINT).reply(200);
+ const errors = await mockResolvers.Mutation.action(null, { action: { playPath: ENDPOINT } });
+
+ expect(errors).toEqual({ __typename: 'LocalEnvironmentErrors', errors: [] });
+ });
+ it('should return a nice error message on fail', async () => {
+ mock.onPost(ENDPOINT).reply(500);
+ const errors = await mockResolvers.Mutation.action(null, { action: { playPath: ENDPOINT } });
+
+ expect(errors).toEqual({
+ __typename: 'LocalEnvironmentErrors',
+ errors: [s__('Environments|An error occurred while making the request.')],
+ });
+ });
+ });
});
diff --git a/spec/frontend/environments/new_environment_folder_spec.js b/spec/frontend/environments/new_environment_folder_spec.js
index 27d27d5869a..6823c88a5a1 100644
--- a/spec/frontend/environments/new_environment_folder_spec.js
+++ b/spec/frontend/environments/new_environment_folder_spec.js
@@ -1,10 +1,13 @@
import VueApollo from 'vue-apollo';
-import Vue from 'vue';
+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);
@@ -25,13 +28,20 @@ describe('~/environments/components/new_environments_folder.vue', () => {
};
const createWrapper = (propsData, apolloProvider) =>
- mountExtended(EnvironmentsFolder, { apolloProvider, propsData });
+ mountExtended(EnvironmentsFolder, {
+ apolloProvider,
+ propsData,
+ stubs: { transition: stubTransition() },
+ });
- beforeEach(() => {
+ 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') });
});
@@ -57,7 +67,8 @@ describe('~/environments/components/new_environments_folder.vue', () => {
const link = findLink();
expect(collapse.attributes('visible')).toBeUndefined();
- expect(icons.wrappers.map((i) => i.props('name'))).toEqual(['angle-right', 'folder-o']);
+ 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);
});
@@ -68,10 +79,21 @@ describe('~/environments/components/new_environments_folder.vue', () => {
const link = findLink();
expect(button.attributes('aria-label')).toBe(__('Collapse'));
- expect(collapse.attributes('visible')).toBe('true');
- expect(icons.wrappers.map((i) => i.props('name'))).toEqual(['angle-down', 'folder-open']);
+ 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
new file mode 100644
index 00000000000..244aef5c43b
--- /dev/null
+++ b/spec/frontend/environments/new_environment_item_spec.js
@@ -0,0 +1,341 @@
+import VueApollo from 'vue-apollo';
+import Vue from 'vue';
+import { GlCollapse, GlIcon } from '@gitlab/ui';
+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 EnvironmentItem from '~/environments/components/new_environment_item.vue';
+import Deployment from '~/environments/components/deployment.vue';
+import { resolvedEnvironment } from './graphql/mock_data';
+
+Vue.use(VueApollo);
+
+describe('~/environments/components/new_environment_item.vue', () => {
+ let wrapper;
+
+ const createApolloProvider = () => {
+ return createMockApollo();
+ };
+
+ const createWrapper = ({ propsData = {}, apolloProvider } = {}) =>
+ mountExtended(EnvironmentItem, {
+ apolloProvider,
+ propsData: { environment: resolvedEnvironment, ...propsData },
+ stubs: { transition: stubTransition() },
+ });
+
+ const findDeployment = () => wrapper.findComponent(Deployment);
+
+ afterEach(() => {
+ wrapper?.destroy();
+ });
+
+ it('displays the name when not in a folder', () => {
+ wrapper = createWrapper({ apolloProvider: createApolloProvider() });
+
+ const name = wrapper.findByRole('link', { name: resolvedEnvironment.name });
+ expect(name.exists()).toBe(true);
+ });
+
+ it('displays the name minus the folder prefix when in a folder', () => {
+ wrapper = createWrapper({
+ propsData: { inFolder: true },
+ apolloProvider: createApolloProvider(),
+ });
+
+ const name = wrapper.findByRole('link', { name: resolvedEnvironment.nameWithoutType });
+ expect(name.exists()).toBe(true);
+ });
+
+ it('truncates the name if it is very long', () => {
+ const environment = {
+ ...resolvedEnvironment,
+ name:
+ 'this is a really long name that should be truncated because otherwise it would look strange in the UI',
+ };
+ wrapper = createWrapper({ propsData: { environment }, apolloProvider: createApolloProvider() });
+
+ const name = wrapper.findByRole('link', {
+ name: (text) => environment.name.startsWith(text.slice(0, -1)),
+ });
+ expect(name.exists()).toBe(true);
+ expect(name.text()).toHaveLength(80);
+ });
+
+ describe('url', () => {
+ it('shows a link for the url if one is present', () => {
+ wrapper = createWrapper({ apolloProvider: createApolloProvider() });
+
+ const url = wrapper.findByRole('link', { name: s__('Environments|Open live environment') });
+
+ expect(url.attributes('href')).toEqual(resolvedEnvironment.externalUrl);
+ });
+
+ it('does not show a link for the url if one is missing', () => {
+ wrapper = createWrapper({
+ propsData: { environment: { ...resolvedEnvironment, externalUrl: '' } },
+ apolloProvider: createApolloProvider(),
+ });
+
+ const url = wrapper.findByRole('link', { name: s__('Environments|Open live environment') });
+
+ expect(url.exists()).toBe(false);
+ });
+ });
+
+ describe('actions', () => {
+ it('shows a dropdown if there are actions to perform', () => {
+ wrapper = createWrapper({ apolloProvider: createApolloProvider() });
+
+ const actions = wrapper.findByRole('button', { name: __('Deploy to...') });
+
+ expect(actions.exists()).toBe(true);
+ });
+
+ it('does not show a dropdown if there are no actions to perform', () => {
+ wrapper = createWrapper({
+ propsData: {
+ environment: {
+ ...resolvedEnvironment,
+ lastDeployment: null,
+ },
+ apolloProvider: createApolloProvider(),
+ },
+ });
+
+ const actions = wrapper.findByRole('button', { name: __('Deploy to...') });
+
+ expect(actions.exists()).toBe(false);
+ });
+
+ it('passes all the actions down to the action component', () => {
+ wrapper = createWrapper({ apolloProvider: createApolloProvider() });
+
+ const action = wrapper.findByRole('menuitem', { name: 'deploy-staging' });
+
+ expect(action.exists()).toBe(true);
+ });
+ });
+
+ describe('stop', () => {
+ it('shows a buton to stop the environment if the environment is available', () => {
+ wrapper = createWrapper({ apolloProvider: createApolloProvider() });
+
+ const stop = wrapper.findByRole('button', { name: s__('Environments|Stop environment') });
+
+ expect(stop.exists()).toBe(true);
+ });
+
+ it('does not show a buton to stop the environment if the environment is stopped', () => {
+ wrapper = createWrapper({
+ propsData: { environment: { ...resolvedEnvironment, canStop: false } },
+ apolloProvider: createApolloProvider(),
+ });
+
+ const stop = wrapper.findByRole('button', { name: s__('Environments|Stop environment') });
+
+ expect(stop.exists()).toBe(false);
+ });
+ });
+
+ describe('rollback', () => {
+ it('shows the option to rollback/re-deploy if available', () => {
+ wrapper = createWrapper({ apolloProvider: createApolloProvider() });
+
+ const rollback = wrapper.findByRole('menuitem', {
+ name: s__('Environments|Re-deploy to environment'),
+ });
+
+ expect(rollback.exists()).toBe(true);
+ });
+
+ it('does not show the option to rollback/re-deploy if not available', () => {
+ wrapper = createWrapper({
+ propsData: { environment: { ...resolvedEnvironment, lastDeployment: null } },
+ apolloProvider: createApolloProvider(),
+ });
+
+ const rollback = wrapper.findByRole('menuitem', {
+ name: s__('Environments|Re-deploy to environment'),
+ });
+
+ expect(rollback.exists()).toBe(false);
+ });
+ });
+
+ describe('pin', () => {
+ it('shows the option to pin the environment if there is an autostop date', () => {
+ wrapper = createWrapper({
+ propsData: {
+ environment: { ...resolvedEnvironment, autoStopAt: new Date(Date.now() + 100000) },
+ },
+ apolloProvider: createApolloProvider(),
+ });
+
+ const rollback = wrapper.findByRole('menuitem', { name: __('Prevent auto-stopping') });
+
+ expect(rollback.exists()).toBe(true);
+ });
+
+ it('does not show the option to pin the environment if there is no autostop date', () => {
+ wrapper = createWrapper({ apolloProvider: createApolloProvider() });
+
+ const rollback = wrapper.findByRole('menuitem', { name: __('Prevent auto-stopping') });
+
+ expect(rollback.exists()).toBe(false);
+ });
+ });
+
+ describe('monitoring', () => {
+ it('shows the link to monitoring if metrics are set up', () => {
+ wrapper = createWrapper({
+ propsData: { environment: { ...resolvedEnvironment, metricsPath: '/metrics' } },
+ apolloProvider: createApolloProvider(),
+ });
+
+ const rollback = wrapper.findByRole('menuitem', { name: __('Monitoring') });
+
+ expect(rollback.exists()).toBe(true);
+ });
+
+ it('does not show the link to monitoring if metrics are not set up', () => {
+ wrapper = createWrapper({ apolloProvider: createApolloProvider() });
+
+ const rollback = wrapper.findByRole('menuitem', { name: __('Monitoring') });
+
+ expect(rollback.exists()).toBe(false);
+ });
+ });
+ describe('terminal', () => {
+ it('shows the link to the terminal if set up', () => {
+ wrapper = createWrapper({
+ propsData: { environment: { ...resolvedEnvironment, terminalPath: '/terminal' } },
+ apolloProvider: createApolloProvider(),
+ });
+
+ const rollback = wrapper.findByRole('menuitem', { name: __('Terminal') });
+
+ expect(rollback.exists()).toBe(true);
+ });
+
+ it('does not show the link to the terminal if not set up', () => {
+ wrapper = createWrapper({ apolloProvider: createApolloProvider() });
+
+ const rollback = wrapper.findByRole('menuitem', { name: __('Terminal') });
+
+ expect(rollback.exists()).toBe(false);
+ });
+ });
+
+ describe('delete', () => {
+ it('shows the button to delete the environment if possible', () => {
+ wrapper = createWrapper({
+ propsData: {
+ environment: { ...resolvedEnvironment, canDelete: true, deletePath: '/terminal' },
+ },
+ apolloProvider: createApolloProvider(),
+ });
+
+ const rollback = wrapper.findByRole('menuitem', {
+ name: s__('Environments|Delete environment'),
+ });
+
+ expect(rollback.exists()).toBe(true);
+ });
+
+ it('does not show the button to delete the environment if not possible', () => {
+ wrapper = createWrapper({ apolloProvider: createApolloProvider() });
+
+ const rollback = wrapper.findByRole('menuitem', {
+ name: s__('Environments|Delete environment'),
+ });
+
+ expect(rollback.exists()).toBe(false);
+ });
+ });
+
+ describe('collapse', () => {
+ let icon;
+ let collapse;
+ let button;
+ let environmentName;
+
+ beforeEach(() => {
+ wrapper = createWrapper({ apolloProvider: createApolloProvider() });
+ collapse = wrapper.findComponent(GlCollapse);
+ icon = wrapper.findComponent(GlIcon);
+ button = wrapper.findByRole('button', { name: __('Expand') });
+ environmentName = wrapper.findByText(resolvedEnvironment.name);
+ });
+
+ it('is collapsed by default', () => {
+ expect(collapse.attributes('visible')).toBeUndefined();
+ expect(icon.props('name')).toEqual('angle-right');
+ expect(environmentName.classes('gl-font-weight-bold')).toBe(false);
+ });
+
+ it('opens on click', async () => {
+ expect(findDeployment().isVisible()).toBe(false);
+
+ await button.trigger('click');
+
+ expect(button.attributes('aria-label')).toBe(__('Collapse'));
+ expect(collapse.attributes('visible')).toBe('visible');
+ expect(icon.props('name')).toEqual('angle-down');
+ expect(environmentName.classes('gl-font-weight-bold')).toBe(true);
+ expect(findDeployment().isVisible()).toBe(true);
+ });
+ });
+ describe('last deployment', () => {
+ it('should pass the last deployment to the deployment component when it exists', () => {
+ wrapper = createWrapper({ apolloProvider: createApolloProvider() });
+
+ const deployment = findDeployment();
+ expect(deployment.props('deployment')).toEqual(resolvedEnvironment.lastDeployment);
+ });
+ it('should not show the last deployment when it is missing', () => {
+ const environment = {
+ ...resolvedEnvironment,
+ lastDeployment: null,
+ };
+
+ wrapper = createWrapper({
+ propsData: { environment },
+ apolloProvider: createApolloProvider(),
+ });
+
+ const deployment = findDeployment();
+ expect(deployment.exists()).toBe(false);
+ });
+ });
+
+ describe('upcoming deployment', () => {
+ it('should pass the upcoming deployment to the deployment component when it exists', () => {
+ const upcomingDeployment = resolvedEnvironment.lastDeployment;
+ const environment = { ...resolvedEnvironment, lastDeployment: null, upcomingDeployment };
+ wrapper = createWrapper({
+ propsData: { environment },
+ apolloProvider: createApolloProvider(),
+ });
+
+ const deployment = findDeployment();
+ expect(deployment.props('deployment')).toEqual(upcomingDeployment);
+ });
+ it('should not show the upcoming deployment when it is missing', () => {
+ const environment = {
+ ...resolvedEnvironment,
+ lastDeployment: null,
+ upcomingDeployment: null,
+ };
+
+ wrapper = createWrapper({
+ propsData: { environment },
+ apolloProvider: createApolloProvider(),
+ });
+
+ const deployment = findDeployment();
+ expect(deployment.exists()).toBe(false);
+ });
+ });
+});
diff --git a/spec/frontend/environments/new_environments_app_spec.js b/spec/frontend/environments/new_environments_app_spec.js
index 1e9bd4d64c9..c9eccc26694 100644
--- a/spec/frontend/environments/new_environments_app_spec.js
+++ b/spec/frontend/environments/new_environments_app_spec.js
@@ -8,7 +8,9 @@ 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 { resolvedEnvironmentsApp, resolvedFolder } from './graphql/mock_data';
+import EnvironmentsItem from '~/environments/components/new_environment_item.vue';
+import StopEnvironmentModal from '~/environments/components/stop_environment_modal.vue';
+import { resolvedEnvironmentsApp, resolvedFolder, resolvedEnvironment } from './graphql/mock_data';
Vue.use(VueApollo);
@@ -17,6 +19,7 @@ describe('~/environments/components/new_environments_app.vue', () => {
let environmentAppMock;
let environmentFolderMock;
let paginationMock;
+ let environmentToStopMock;
const createApolloProvider = () => {
const mockResolvers = {
@@ -24,6 +27,7 @@ describe('~/environments/components/new_environments_app.vue', () => {
environmentApp: environmentAppMock,
folder: environmentFolderMock,
pageInfo: paginationMock,
+ environmentToStop: environmentToStopMock,
},
};
@@ -45,6 +49,7 @@ describe('~/environments/components/new_environments_app.vue', () => {
provide = {},
environmentsApp,
folder,
+ environmentToStop = {},
pageInfo = {
total: 20,
perPage: 5,
@@ -58,6 +63,7 @@ describe('~/environments/components/new_environments_app.vue', () => {
environmentAppMock.mockReturnValue(environmentsApp);
environmentFolderMock.mockReturnValue(folder);
paginationMock.mockReturnValue(pageInfo);
+ environmentToStopMock.mockReturnValue(environmentToStop);
const apolloProvider = createApolloProvider();
wrapper = createWrapper({ apolloProvider, provide });
@@ -68,6 +74,7 @@ describe('~/environments/components/new_environments_app.vue', () => {
beforeEach(() => {
environmentAppMock = jest.fn();
environmentFolderMock = jest.fn();
+ environmentToStopMock = jest.fn();
paginationMock = jest.fn();
});
@@ -87,6 +94,18 @@ describe('~/environments/components/new_environments_app.vue', () => {
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,
@@ -168,13 +187,27 @@ describe('~/environments/components/new_environments_app.vue', () => {
expect(environmentAppMock).toHaveBeenCalledWith(
expect.anything(),
- expect.objectContaining({ scope: 'stopped' }),
+ 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);
+ });
+ });
+
describe('pagination', () => {
it('should sync page from query params on load', async () => {
await createWrapperWithMocked({
diff --git a/spec/frontend/error_tracking/components/error_details_spec.js b/spec/frontend/error_tracking/components/error_details_spec.js
index 4e459d800e8..77f51193258 100644
--- a/spec/frontend/error_tracking/components/error_details_spec.js
+++ b/spec/frontend/error_tracking/components/error_details_spec.js
@@ -173,6 +173,8 @@ describe('ErrorDetails', () => {
beforeEach(() => {
mocks.$apollo.queries.error.loading = false;
mountComponent();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
error: {
id: 'gid://gitlab/Gitlab::ErrorTracking::DetailedError/129381',
@@ -203,6 +205,8 @@ describe('ErrorDetails', () => {
const culprit = '<script>console.log("surprise!")</script>';
beforeEach(() => {
store.state.details.loadingStacktrace = false;
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
error: {
culprit,
@@ -222,6 +226,8 @@ describe('ErrorDetails', () => {
describe('Badges', () => {
it('should show language and error level badges', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
error: {
tags: { level: 'error', logger: 'ruby' },
@@ -233,6 +239,8 @@ describe('ErrorDetails', () => {
});
it('should NOT show the badge if the tag is not present', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
error: {
tags: { level: 'error' },
@@ -246,6 +254,8 @@ describe('ErrorDetails', () => {
it.each(Object.keys(severityLevel))(
'should set correct severity level variant for %s badge',
(level) => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
error: {
tags: { level: severityLevel[level] },
@@ -260,6 +270,8 @@ describe('ErrorDetails', () => {
);
it('should fallback for ERROR severityLevelVariant when severityLevel is unknown', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
error: {
tags: { level: 'someNewErrorLevel' },
@@ -408,6 +420,8 @@ describe('ErrorDetails', () => {
it('should show alert with closed issueId', () => {
const closedIssueId = 123;
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
isAlertVisible: true,
closedIssueId,
@@ -429,6 +443,8 @@ describe('ErrorDetails', () => {
describe('is present', () => {
beforeEach(() => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
error: {
gitlabIssuePath,
@@ -451,6 +467,8 @@ describe('ErrorDetails', () => {
describe('is not present', () => {
beforeEach(() => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
error: {
gitlabIssuePath: null,
@@ -480,6 +498,8 @@ describe('ErrorDetails', () => {
it('should display a link', () => {
mocks.$apollo.queries.error.loading = false;
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
error: {
gitlabCommit,
@@ -493,6 +513,8 @@ describe('ErrorDetails', () => {
it('should not display a link', () => {
mocks.$apollo.queries.error.loading = false;
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
error: {
gitlabCommit: null,
@@ -519,6 +541,8 @@ describe('ErrorDetails', () => {
it('should display links to Sentry', async () => {
mocks.$apollo.queries.error.loading = false;
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
await wrapper.setData({
error: {
firstReleaseVersion,
@@ -535,6 +559,8 @@ describe('ErrorDetails', () => {
it('should display links to GitLab when integrated', async () => {
mocks.$apollo.queries.error.loading = false;
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
await wrapper.setData({
error: {
firstReleaseVersion,
@@ -557,6 +583,8 @@ describe('ErrorDetails', () => {
jest.spyOn(Tracking, 'event');
mocks.$apollo.queries.error.loading = false;
mountComponent();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
error: { externalUrl },
});
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 c0c542ae587..74d5731bbea 100644
--- a/spec/frontend/error_tracking/components/error_tracking_list_spec.js
+++ b/spec/frontend/error_tracking/components/error_tracking_list_spec.js
@@ -396,6 +396,8 @@ describe('ErrorTrackingList', () => {
GlPagination: false,
},
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ pageValue: 2 });
return wrapper.vm.$nextTick();
});
diff --git a/spec/frontend/fixtures/blob.rb b/spec/frontend/fixtures/blob.rb
index bfdeee0881b..35a7ff4eb07 100644
--- a/spec/frontend/fixtures/blob.rb
+++ b/spec/frontend/fixtures/blob.rb
@@ -12,6 +12,7 @@ RSpec.describe Projects::BlobController, '(JavaScript fixtures)', type: :control
render_views
before do
+ stub_feature_flags(refactor_blob_viewer: false) # This fixture is only used by the legacy (non-refactored) blob viewer
sign_in(user)
allow(SecureRandom).to receive(:hex).and_return('securerandomhex:thereisnospoon')
end
diff --git a/spec/frontend/fixtures/runner.rb b/spec/frontend/fixtures/runner.rb
index fa150fbf57c..36e6cf72750 100644
--- a/spec/frontend/fixtures/runner.rb
+++ b/spec/frontend/fixtures/runner.rb
@@ -24,80 +24,109 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
remove_repository(project)
end
- describe GraphQL::Query, type: :request do
- get_runners_query_name = 'get_runners.query.graphql'
-
+ describe do
before do
sign_in(admin)
enable_admin_mode!(admin)
end
- let_it_be(:query) do
- get_graphql_query_as_string("#{query_path}#{get_runners_query_name}")
- end
+ describe GraphQL::Query, type: :request do
+ get_runners_query_name = 'get_runners.query.graphql'
- it "#{fixtures_path}#{get_runners_query_name}.json" do
- post_graphql(query, current_user: admin, variables: {})
+ let_it_be(:query) do
+ get_graphql_query_as_string("#{query_path}#{get_runners_query_name}")
+ end
- expect_graphql_errors_to_be_empty
- end
+ it "#{fixtures_path}#{get_runners_query_name}.json" do
+ post_graphql(query, current_user: admin, variables: {})
- it "#{fixtures_path}#{get_runners_query_name}.paginated.json" do
- post_graphql(query, current_user: admin, variables: { first: 2 })
+ expect_graphql_errors_to_be_empty
+ end
- expect_graphql_errors_to_be_empty
+ it "#{fixtures_path}#{get_runners_query_name}.paginated.json" do
+ post_graphql(query, current_user: admin, variables: { first: 2 })
+
+ expect_graphql_errors_to_be_empty
+ end
end
- end
- describe GraphQL::Query, type: :request do
- get_runner_query_name = 'get_runner.query.graphql'
+ describe GraphQL::Query, type: :request do
+ get_runners_count_query_name = 'get_runners_count.query.graphql'
- before do
- sign_in(admin)
- enable_admin_mode!(admin)
- end
+ let_it_be(:query) do
+ get_graphql_query_as_string("#{query_path}#{get_runners_count_query_name}")
+ end
+
+ it "#{fixtures_path}#{get_runners_count_query_name}.json" do
+ post_graphql(query, current_user: admin, variables: {})
- let_it_be(:query) do
- get_graphql_query_as_string("#{query_path}#{get_runner_query_name}")
+ expect_graphql_errors_to_be_empty
+ end
end
- it "#{fixtures_path}#{get_runner_query_name}.json" do
- post_graphql(query, current_user: admin, variables: {
- id: instance_runner.to_global_id.to_s
- })
+ describe GraphQL::Query, type: :request do
+ get_runner_query_name = 'get_runner.query.graphql'
- expect_graphql_errors_to_be_empty
+ let_it_be(:query) do
+ get_graphql_query_as_string("#{query_path}#{get_runner_query_name}")
+ end
+
+ it "#{fixtures_path}#{get_runner_query_name}.json" do
+ post_graphql(query, current_user: admin, variables: {
+ id: instance_runner.to_global_id.to_s
+ })
+
+ expect_graphql_errors_to_be_empty
+ end
end
end
- describe GraphQL::Query, type: :request do
- get_group_runners_query_name = 'get_group_runners.query.graphql'
-
+ describe do
let_it_be(:group_owner) { create(:user) }
before do
group.add_owner(group_owner)
end
- let_it_be(:query) do
- get_graphql_query_as_string("#{query_path}#{get_group_runners_query_name}")
- end
+ describe GraphQL::Query, type: :request do
+ get_group_runners_query_name = 'get_group_runners.query.graphql'
+
+ let_it_be(:query) do
+ get_graphql_query_as_string("#{query_path}#{get_group_runners_query_name}")
+ end
- it "#{fixtures_path}#{get_group_runners_query_name}.json" do
- post_graphql(query, current_user: group_owner, variables: {
- groupFullPath: group.full_path
- })
+ it "#{fixtures_path}#{get_group_runners_query_name}.json" do
+ post_graphql(query, current_user: group_owner, variables: {
+ groupFullPath: group.full_path
+ })
- expect_graphql_errors_to_be_empty
+ expect_graphql_errors_to_be_empty
+ end
+
+ it "#{fixtures_path}#{get_group_runners_query_name}.paginated.json" do
+ post_graphql(query, current_user: group_owner, variables: {
+ groupFullPath: group.full_path,
+ first: 1
+ })
+
+ expect_graphql_errors_to_be_empty
+ end
end
- it "#{fixtures_path}#{get_group_runners_query_name}.paginated.json" do
- post_graphql(query, current_user: group_owner, variables: {
- groupFullPath: group.full_path,
- first: 1
- })
+ describe GraphQL::Query, type: :request do
+ get_group_runners_count_query_name = 'get_group_runners_count.query.graphql'
+
+ let_it_be(:query) do
+ get_graphql_query_as_string("#{query_path}#{get_group_runners_count_query_name}")
+ end
+
+ it "#{fixtures_path}#{get_group_runners_count_query_name}.json" do
+ post_graphql(query, current_user: group_owner, variables: {
+ groupFullPath: group.full_path
+ })
- expect_graphql_errors_to_be_empty
+ expect_graphql_errors_to_be_empty
+ end
end
end
end
diff --git a/spec/frontend/fixtures/static/project_select_combo_button.html b/spec/frontend/fixtures/static/project_select_combo_button.html
index 444e0bc84a2..3776610ed4c 100644
--- a/spec/frontend/fixtures/static/project_select_combo_button.html
+++ b/spec/frontend/fixtures/static/project_select_combo_button.html
@@ -1,6 +1,6 @@
<div class="project-item-select-holder">
<input class="project-item-select" data-group-id="12345" data-relative-path="issues/new" />
- <a class="new-project-item-link" data-label="New issue" data-type="issues" href="">
+ <a class="js-new-project-item-link" data-label="issue" data-type="issues" href="">
<span class="gl-spinner"></span>
</a>
<a class="new-project-item-select-button">
diff --git a/spec/frontend/flash_spec.js b/spec/frontend/flash_spec.js
index fc736f2d155..d5451ec2064 100644
--- a/spec/frontend/flash_spec.js
+++ b/spec/frontend/flash_spec.js
@@ -1,9 +1,12 @@
import * as Sentry from '@sentry/browser';
+import { setHTMLFixture } from 'helpers/fixtures';
import createFlash, {
hideFlash,
addDismissFlashClickListener,
FLASH_TYPES,
FLASH_CLOSED_EVENT,
+ createAlert,
+ VARIANT_WARNING,
} from '~/flash';
jest.mock('@sentry/browser');
@@ -68,6 +71,236 @@ describe('Flash', () => {
});
});
+ describe('createAlert', () => {
+ const mockMessage = 'a message';
+ let alert;
+
+ describe('no flash-container', () => {
+ it('does not add to the DOM', () => {
+ alert = createAlert({ message: mockMessage });
+
+ expect(alert).toBeNull();
+ expect(document.querySelector('.gl-alert')).toBeNull();
+ });
+ });
+
+ describe('with flash-container', () => {
+ beforeEach(() => {
+ setHTMLFixture('<div class="flash-container"></div>');
+ });
+
+ afterEach(() => {
+ if (alert) {
+ alert.$destroy();
+ }
+ document.querySelector('.flash-container')?.remove();
+ });
+
+ it('adds alert element into the document by default', () => {
+ alert = createAlert({ message: mockMessage });
+
+ expect(document.querySelector('.flash-container').textContent.trim()).toBe(mockMessage);
+ expect(document.querySelector('.flash-container .gl-alert')).not.toBeNull();
+ });
+
+ it('adds flash of a warning type', () => {
+ alert = createAlert({ message: mockMessage, variant: VARIANT_WARNING });
+
+ expect(
+ document.querySelector('.flash-container .gl-alert.gl-alert-warning'),
+ ).not.toBeNull();
+ });
+
+ it('escapes text', () => {
+ alert = createAlert({ message: '<script>alert("a");</script>' });
+
+ const html = document.querySelector('.flash-container').innerHTML;
+
+ expect(html).toContain('&lt;script&gt;alert("a");&lt;/script&gt;');
+ expect(html).not.toContain('<script>alert("a");</script>');
+ });
+
+ it('adds alert into specified container', () => {
+ setHTMLFixture(`
+ <div class="my-alert-container"></div>
+ <div class="my-other-container"></div>
+ `);
+
+ alert = createAlert({ message: mockMessage, containerSelector: '.my-alert-container' });
+
+ expect(document.querySelector('.my-alert-container .gl-alert')).not.toBeNull();
+ expect(document.querySelector('.my-alert-container').innerText.trim()).toBe(mockMessage);
+
+ expect(document.querySelector('.my-other-container .gl-alert')).toBeNull();
+ expect(document.querySelector('.my-other-container').innerText.trim()).toBe('');
+ });
+
+ it('adds alert into specified parent', () => {
+ setHTMLFixture(`
+ <div id="my-parent">
+ <div class="flash-container"></div>
+ </div>
+ <div id="my-other-parent">
+ <div class="flash-container"></div>
+ </div>
+ `);
+
+ alert = createAlert({ message: mockMessage, parent: document.getElementById('my-parent') });
+
+ expect(document.querySelector('#my-parent .flash-container .gl-alert')).not.toBeNull();
+ expect(document.querySelector('#my-parent .flash-container').innerText.trim()).toBe(
+ mockMessage,
+ );
+
+ expect(document.querySelector('#my-other-parent .flash-container .gl-alert')).toBeNull();
+ expect(document.querySelector('#my-other-parent .flash-container').innerText.trim()).toBe(
+ '',
+ );
+ });
+
+ it('removes element after clicking', () => {
+ alert = createAlert({ message: mockMessage });
+
+ expect(document.querySelector('.flash-container .gl-alert')).not.toBeNull();
+
+ document.querySelector('.gl-dismiss-btn').click();
+
+ expect(document.querySelector('.flash-container .gl-alert')).toBeNull();
+ });
+
+ it('does not capture error using Sentry', () => {
+ alert = createAlert({
+ message: mockMessage,
+ captureError: false,
+ error: new Error('Error!'),
+ });
+
+ expect(Sentry.captureException).not.toHaveBeenCalled();
+ });
+
+ it('captures error using Sentry', () => {
+ alert = createAlert({
+ message: mockMessage,
+ captureError: true,
+ error: new Error('Error!'),
+ });
+
+ expect(Sentry.captureException).toHaveBeenCalledWith(expect.any(Error));
+ expect(Sentry.captureException).toHaveBeenCalledWith(
+ expect.objectContaining({
+ message: 'Error!',
+ }),
+ );
+ });
+
+ describe('with buttons', () => {
+ const findAlertAction = () => document.querySelector('.flash-container .gl-alert-action');
+
+ it('adds primary button', () => {
+ alert = createAlert({
+ message: mockMessage,
+ primaryButton: {
+ text: 'Ok',
+ },
+ });
+
+ expect(findAlertAction().textContent.trim()).toBe('Ok');
+ });
+
+ it('creates link with href', () => {
+ alert = createAlert({
+ message: mockMessage,
+ primaryButton: {
+ link: '/url',
+ text: 'Ok',
+ },
+ });
+
+ const action = findAlertAction();
+
+ expect(action.textContent.trim()).toBe('Ok');
+ expect(action.nodeName).toBe('A');
+ expect(action.getAttribute('href')).toBe('/url');
+ });
+
+ it('create button as href when no href is present', () => {
+ alert = createAlert({
+ message: mockMessage,
+ primaryButton: {
+ text: 'Ok',
+ },
+ });
+
+ const action = findAlertAction();
+
+ expect(action.nodeName).toBe('BUTTON');
+ expect(action.getAttribute('href')).toBe(null);
+ });
+
+ it('escapes the title text', () => {
+ alert = createAlert({
+ message: mockMessage,
+ primaryButton: {
+ text: '<script>alert("a")</script>',
+ },
+ });
+
+ const html = findAlertAction().innerHTML;
+
+ expect(html).toContain('&lt;script&gt;alert("a")&lt;/script&gt;');
+ expect(html).not.toContain('<script>alert("a")</script>');
+ });
+
+ it('calls actionConfig clickHandler on click', () => {
+ const clickHandler = jest.fn();
+
+ alert = createAlert({
+ message: mockMessage,
+ primaryButton: {
+ text: 'Ok',
+ clickHandler,
+ },
+ });
+
+ expect(clickHandler).toHaveBeenCalledTimes(0);
+
+ findAlertAction().click();
+
+ expect(clickHandler).toHaveBeenCalledTimes(1);
+ expect(clickHandler).toHaveBeenCalledWith(expect.any(MouseEvent));
+ });
+ });
+
+ describe('Alert API', () => {
+ describe('dismiss', () => {
+ it('dismiss programmatically with .dismiss()', () => {
+ expect(document.querySelector('.gl-alert')).toBeNull();
+
+ alert = createAlert({ message: mockMessage });
+
+ expect(document.querySelector('.gl-alert')).not.toBeNull();
+
+ alert.dismiss();
+
+ expect(document.querySelector('.gl-alert')).toBeNull();
+ });
+
+ it('calls onDismiss when dismissed', () => {
+ const dismissHandler = jest.fn();
+
+ alert = createAlert({ message: mockMessage, onDismiss: dismissHandler });
+
+ expect(dismissHandler).toHaveBeenCalledTimes(0);
+
+ alert.dismiss();
+
+ expect(dismissHandler).toHaveBeenCalledTimes(1);
+ });
+ });
+ });
+ });
+ });
+
describe('createFlash', () => {
const message = 'test';
const fadeTransition = false;
@@ -91,7 +324,7 @@ describe('Flash', () => {
describe('with flash-container', () => {
beforeEach(() => {
- setFixtures(
+ setHTMLFixture(
'<div class="content-wrapper js-content-wrapper"><div class="flash-container"></div></div>',
);
});
@@ -115,11 +348,12 @@ describe('Flash', () => {
});
it('escapes text', () => {
- createFlash({ ...defaultParams, message: '<script>alert("a");</script>' });
+ createFlash({ ...defaultParams, message: '<script>alert("a")</script>' });
- expect(document.querySelector('.flash-text').textContent.trim()).toBe(
- '<script>alert("a");</script>',
- );
+ const html = document.querySelector('.flash-text').innerHTML;
+
+ expect(html).toContain('&lt;script&gt;alert("a")&lt;/script&gt;');
+ expect(html).not.toContain('<script>alert("a")</script>');
});
it('adds flash into specified parent', () => {
@@ -193,8 +427,10 @@ describe('Flash', () => {
},
});
- expect(findFlashAction().href).toBe(`${window.location}testing`);
- expect(findFlashAction().textContent.trim()).toBe('test');
+ const action = findFlashAction();
+
+ expect(action.href).toBe(`${window.location}testing`);
+ expect(action.textContent.trim()).toBe('test');
});
it('uses hash as href when no href is present', () => {
@@ -227,7 +463,10 @@ describe('Flash', () => {
},
});
- expect(findFlashAction().textContent.trim()).toBe('<script>alert("a")</script>');
+ const html = findFlashAction().innerHTML;
+
+ expect(html).toContain('&lt;script&gt;alert("a")&lt;/script&gt;');
+ expect(html).not.toContain('<script>alert("a")</script>');
});
it('calls actionConfig clickHandler on click', () => {
diff --git a/spec/frontend/google_cloud/components/app_spec.js b/spec/frontend/google_cloud/components/app_spec.js
index 570ac1e6ed1..92bc7596f7d 100644
--- a/spec/frontend/google_cloud/components/app_spec.js
+++ b/spec/frontend/google_cloud/components/app_spec.js
@@ -24,6 +24,8 @@ const HOME_PROPS = {
serviceAccounts: [{}, {}],
createServiceAccountUrl: '#url-create-service-account',
emptyIllustrationUrl: '#url-empty-illustration',
+ deploymentsCloudRunUrl: '#url-deployments-cloud-run',
+ deploymentsCloudStorageUrl: '#deploymentsCloudStorageUrl',
};
describe('google_cloud App component', () => {
diff --git a/spec/frontend/google_cloud/components/deployments_service_table_spec.js b/spec/frontend/google_cloud/components/deployments_service_table_spec.js
new file mode 100644
index 00000000000..76c3bfd00a8
--- /dev/null
+++ b/spec/frontend/google_cloud/components/deployments_service_table_spec.js
@@ -0,0 +1,40 @@
+import { mount } from '@vue/test-utils';
+import { GlButton, GlTable } from '@gitlab/ui';
+import DeploymentsServiceTable from '~/google_cloud/components/deployments_service_table.vue';
+
+describe('google_cloud DeploymentsServiceTable component', () => {
+ let wrapper;
+
+ const findTable = () => wrapper.findComponent(GlTable);
+ const findButtons = () => findTable().findAllComponents(GlButton);
+ const findCloudRunButton = () => findButtons().at(0);
+ const findCloudStorageButton = () => findButtons().at(1);
+
+ beforeEach(() => {
+ const propsData = {
+ cloudRunUrl: '#url-deployments-cloud-run',
+ cloudStorageUrl: '#url-deployments-cloud-storage',
+ };
+ wrapper = mount(DeploymentsServiceTable, { propsData });
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('should contain a table', () => {
+ expect(findTable().exists()).toBe(true);
+ });
+
+ it('should contain configure cloud run button', () => {
+ const cloudRunButton = findCloudRunButton();
+ expect(cloudRunButton.exists()).toBe(true);
+ expect(cloudRunButton.props().disabled).toBe(true);
+ });
+
+ it('should contain configure cloud storage button', () => {
+ const cloudStorageButton = findCloudStorageButton();
+ expect(cloudStorageButton.exists()).toBe(true);
+ expect(cloudStorageButton.props().disabled).toBe(true);
+ });
+});
diff --git a/spec/frontend/google_cloud/components/home_spec.js b/spec/frontend/google_cloud/components/home_spec.js
index 9b4c3a79f11..3a009fc88ce 100644
--- a/spec/frontend/google_cloud/components/home_spec.js
+++ b/spec/frontend/google_cloud/components/home_spec.js
@@ -20,6 +20,8 @@ describe('google_cloud Home component', () => {
serviceAccounts: [{}, {}],
createServiceAccountUrl: '#url-create-service-account',
emptyIllustrationUrl: '#url-empty-illustration',
+ deploymentsCloudRunUrl: '#url-deployments-cloud-run',
+ deploymentsCloudStorageUrl: '#deploymentsCloudStorageUrl',
};
beforeEach(() => {
@@ -42,7 +44,7 @@ describe('google_cloud Home component', () => {
it('should contain three tab items', () => {
expect(findTabItemsModel()).toEqual([
{ title: 'Configuration', disabled: undefined },
- { title: 'Deployments', disabled: '' },
+ { title: 'Deployments', disabled: undefined },
{ title: 'Services', disabled: '' },
]);
});
diff --git a/spec/frontend/google_tag_manager/index_spec.js b/spec/frontend/google_tag_manager/index_spec.js
new file mode 100644
index 00000000000..ff38de28da6
--- /dev/null
+++ b/spec/frontend/google_tag_manager/index_spec.js
@@ -0,0 +1,259 @@
+import { merge } from 'lodash';
+import {
+ trackFreeTrialAccountSubmissions,
+ trackNewRegistrations,
+ trackSaasTrialSubmit,
+ trackSaasTrialSkip,
+ trackSaasTrialGroup,
+ trackSaasTrialProject,
+ trackSaasTrialProjectImport,
+ trackSaasTrialGetStarted,
+} from '~/google_tag_manager';
+import { setHTMLFixture } from 'helpers/fixtures';
+import { logError } from '~/lib/logger';
+
+jest.mock('~/lib/logger');
+
+describe('~/google_tag_manager/index', () => {
+ let spy;
+
+ beforeEach(() => {
+ spy = jest.fn();
+
+ window.dataLayer = {
+ push: spy,
+ };
+ window.gon.features = {
+ gitlabGtmDatalayer: true,
+ };
+ });
+
+ const createHTML = ({ links = [], forms = [] } = {}) => {
+ // .foo elements are used to test elements which shouldn't do anything
+ const allLinks = links.concat({ cls: 'foo' });
+ const allForms = forms.concat({ cls: 'foo' });
+
+ const el = document.createElement('div');
+
+ allLinks.forEach(({ cls = '', id = '', href = '#', text = 'Hello', attributes = {} }) => {
+ const a = document.createElement('a');
+ a.id = id;
+ a.href = href || '#';
+ a.className = cls;
+ a.textContent = text;
+
+ Object.entries(attributes).forEach(([key, value]) => {
+ a.setAttribute(key, value);
+ });
+
+ el.append(a);
+ });
+
+ allForms.forEach(({ cls = '', id = '' }) => {
+ const form = document.createElement('form');
+ form.id = id;
+ form.className = cls;
+
+ el.append(form);
+ });
+
+ return el.innerHTML;
+ };
+
+ const triggerEvent = (selector, eventType) => {
+ const el = document.querySelector(selector);
+
+ el.dispatchEvent(new Event(eventType));
+ };
+
+ const getSelector = ({ id, cls }) => (id ? `#${id}` : `.${cls}`);
+
+ const createTestCase = (subject, { forms = [], links = [] }) => {
+ const expectedFormEvents = forms.map(({ expectation, ...form }) => ({
+ selector: getSelector(form),
+ trigger: 'submit',
+ expectation,
+ }));
+
+ const expectedLinkEvents = links.map(({ expectation, ...link }) => ({
+ selector: getSelector(link),
+ trigger: 'click',
+ expectation,
+ }));
+
+ return [
+ subject,
+ {
+ forms,
+ links,
+ expectedEvents: [...expectedFormEvents, ...expectedLinkEvents],
+ },
+ ];
+ };
+
+ const createOmniAuthTestCase = (subject, accountType) =>
+ createTestCase(subject, {
+ forms: [
+ {
+ id: 'new_new_user',
+ expectation: {
+ event: 'accountSubmit',
+ accountMethod: 'form',
+ accountType,
+ },
+ },
+ ],
+ links: [
+ {
+ // id is needed so that the test selects the right element to trigger
+ id: 'test-0',
+ cls: 'js-oauth-login',
+ attributes: {
+ 'data-provider': 'myspace',
+ },
+ expectation: {
+ event: 'accountSubmit',
+ accountMethod: 'myspace',
+ accountType,
+ },
+ },
+ {
+ id: 'test-1',
+ cls: 'js-oauth-login',
+ attributes: {
+ 'data-provider': 'gitlab',
+ },
+ expectation: {
+ event: 'accountSubmit',
+ accountMethod: 'gitlab',
+ accountType,
+ },
+ },
+ ],
+ });
+
+ describe.each([
+ createOmniAuthTestCase(trackFreeTrialAccountSubmissions, 'freeThirtyDayTrial'),
+ createOmniAuthTestCase(trackNewRegistrations, 'standardSignUp'),
+ createTestCase(trackSaasTrialSkip, {
+ links: [{ cls: 'js-skip-trial', expectation: { event: 'saasTrialSkip' } }],
+ }),
+ createTestCase(trackSaasTrialGroup, {
+ forms: [{ cls: 'js-saas-trial-group', expectation: { event: 'saasTrialGroup' } }],
+ }),
+ createTestCase(trackSaasTrialProject, {
+ forms: [{ id: 'new_project', expectation: { event: 'saasTrialProject' } }],
+ }),
+ createTestCase(trackSaasTrialProjectImport, {
+ links: [
+ {
+ id: 'js-test-btn-0',
+ cls: 'js-import-project-btn',
+ attributes: { 'data-platform': 'bitbucket' },
+ expectation: { event: 'saasTrialProjectImport', saasProjectImport: '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' },
+ },
+ ],
+ }),
+ createTestCase(trackSaasTrialGetStarted, {
+ links: [
+ {
+ cls: 'js-get-started-btn',
+ expectation: { event: 'saasTrialGetStarted' },
+ },
+ ],
+ }),
+ ])('%p', (subject, { links = [], forms = [], expectedEvents }) => {
+ beforeEach(() => {
+ setHTMLFixture(createHTML({ links, forms }));
+
+ subject();
+ });
+
+ it.each(expectedEvents)('when %p', ({ selector, trigger, expectation }) => {
+ expect(spy).not.toHaveBeenCalled();
+
+ triggerEvent(selector, trigger);
+
+ expect(spy).toHaveBeenCalledTimes(1);
+ expect(spy).toHaveBeenCalledWith(expectation);
+ expect(logError).not.toHaveBeenCalled();
+ });
+
+ it('when random link is clicked, does nothing', () => {
+ triggerEvent('a.foo', 'click');
+
+ expect(spy).not.toHaveBeenCalled();
+ });
+
+ it('when random form is submitted, does nothing', () => {
+ triggerEvent('form.foo', 'submit');
+
+ expect(spy).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('No listener events', () => {
+ it('when trackSaasTrialSubmit is invoked', () => {
+ expect(spy).not.toHaveBeenCalled();
+
+ trackSaasTrialSubmit();
+
+ expect(spy).toHaveBeenCalledTimes(1);
+ expect(spy).toHaveBeenCalledWith({ event: 'saasTrialSubmit' });
+ expect(logError).not.toHaveBeenCalled();
+ });
+ });
+
+ describe.each([
+ { dataLayer: null },
+ { gon: { features: null } },
+ { gon: { features: { gitlabGtmDatalayer: false } } },
+ ])('when window %o', (windowAttrs) => {
+ beforeEach(() => {
+ merge(window, windowAttrs);
+ });
+
+ it('no ops', () => {
+ setHTMLFixture(createHTML({ forms: [{ id: 'new_project' }] }));
+
+ trackSaasTrialProject();
+
+ triggerEvent('#new_project', 'submit');
+
+ expect(spy).not.toHaveBeenCalled();
+ expect(logError).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('when window.dataLayer throws error', () => {
+ const pushError = new Error('test');
+
+ beforeEach(() => {
+ window.dataLayer = {
+ push() {
+ throw pushError;
+ },
+ };
+ });
+
+ it('logs error', () => {
+ setHTMLFixture(createHTML({ forms: [{ id: 'new_project' }] }));
+
+ trackSaasTrialProject();
+
+ triggerEvent('#new_project', 'submit');
+
+ expect(logError).toHaveBeenCalledWith(
+ 'Unexpected error while pushing to dataLayer',
+ pushError,
+ );
+ });
+ });
+});
diff --git a/spec/frontend/groups/components/group_item_spec.js b/spec/frontend/groups/components/group_item_spec.js
index 60d47895a95..8ea7e54aef4 100644
--- a/spec/frontend/groups/components/group_item_spec.js
+++ b/spec/frontend/groups/components/group_item_spec.js
@@ -100,6 +100,7 @@ describe('GroupItemComponent', () => {
wrapper.destroy();
group.type = 'project';
+ group.lastActivityAt = '2017-04-09T18:40:39.101Z';
wrapper = createComponent({ group });
expect(wrapper.vm.isGroup).toBe(false);
diff --git a/spec/frontend/groups/components/item_stats_spec.js b/spec/frontend/groups/components/item_stats_spec.js
index 49f3f5da43c..fdc267bc14a 100644
--- a/spec/frontend/groups/components/item_stats_spec.js
+++ b/spec/frontend/groups/components/item_stats_spec.js
@@ -38,6 +38,7 @@ describe('ItemStats', () => {
...mockParentGroupItem,
type: ITEM_TYPE.PROJECT,
starCount: 4,
+ lastActivityAt: '2017-04-09T18:40:39.101Z',
};
createComponent({ item });
diff --git a/spec/frontend/groups/landing_spec.js b/spec/frontend/groups/landing_spec.js
new file mode 100644
index 00000000000..f90f541eb96
--- /dev/null
+++ b/spec/frontend/groups/landing_spec.js
@@ -0,0 +1,184 @@
+import Cookies from 'js-cookie';
+import Landing from '~/groups/landing';
+
+describe('Landing', () => {
+ const test = {};
+
+ describe('class constructor', () => {
+ beforeEach(() => {
+ test.landingElement = {};
+ test.dismissButton = {};
+ test.cookieName = 'cookie_name';
+
+ test.landing = new Landing(test.landingElement, test.dismissButton, test.cookieName);
+ });
+
+ it('should set .landing', () => {
+ expect(test.landing.landingElement).toBe(test.landingElement);
+ });
+
+ it('should set .cookieName', () => {
+ expect(test.landing.cookieName).toBe(test.cookieName);
+ });
+
+ it('should set .dismissButton', () => {
+ expect(test.landing.dismissButton).toBe(test.dismissButton);
+ });
+
+ it('should set .eventWrapper', () => {
+ expect(test.landing.eventWrapper).toEqual({});
+ });
+ });
+
+ describe('toggle', () => {
+ beforeEach(() => {
+ test.isDismissed = false;
+ test.landingElement = {
+ classList: {
+ toggle: jest.fn(),
+ },
+ };
+ test.landing = {
+ isDismissed: () => {},
+ addEvents: () => {},
+ landingElement: test.landingElement,
+ };
+
+ jest.spyOn(test.landing, 'isDismissed').mockReturnValue(test.isDismissed);
+ jest.spyOn(test.landing, 'addEvents').mockImplementation(() => {});
+
+ Landing.prototype.toggle.call(test.landing);
+ });
+
+ it('should call .isDismissed', () => {
+ expect(test.landing.isDismissed).toHaveBeenCalled();
+ });
+
+ it('should call .classList.toggle', () => {
+ expect(test.landingElement.classList.toggle).toHaveBeenCalledWith('hidden', test.isDismissed);
+ });
+
+ it('should call .addEvents', () => {
+ expect(test.landing.addEvents).toHaveBeenCalled();
+ });
+
+ describe('if isDismissed is true', () => {
+ beforeEach(() => {
+ test.isDismissed = true;
+ test.landingElement = {
+ classList: {
+ toggle: jest.fn(),
+ },
+ };
+ test.landing = {
+ isDismissed: () => {},
+ addEvents: () => {},
+ landingElement: test.landingElement,
+ };
+
+ jest.spyOn(test.landing, 'isDismissed').mockReturnValue(test.isDismissed);
+ jest.spyOn(test.landing, 'addEvents').mockImplementation(() => {});
+
+ test.landing.isDismissed.mockClear();
+
+ Landing.prototype.toggle.call(test.landing);
+ });
+
+ it('should not call .addEvents', () => {
+ expect(test.landing.addEvents).not.toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('addEvents', () => {
+ beforeEach(() => {
+ test.dismissButton = {
+ addEventListener: jest.fn(),
+ };
+ test.eventWrapper = {};
+ test.landing = {
+ eventWrapper: test.eventWrapper,
+ dismissButton: test.dismissButton,
+ dismissLanding: () => {},
+ };
+
+ Landing.prototype.addEvents.call(test.landing);
+ });
+
+ it('should set .eventWrapper.dismissLanding', () => {
+ expect(test.eventWrapper.dismissLanding).toEqual(expect.any(Function));
+ });
+
+ it('should call .addEventListener', () => {
+ expect(test.dismissButton.addEventListener).toHaveBeenCalledWith(
+ 'click',
+ test.eventWrapper.dismissLanding,
+ );
+ });
+ });
+
+ describe('removeEvents', () => {
+ beforeEach(() => {
+ test.dismissButton = {
+ removeEventListener: jest.fn(),
+ };
+ test.eventWrapper = { dismissLanding: () => {} };
+ test.landing = {
+ eventWrapper: test.eventWrapper,
+ dismissButton: test.dismissButton,
+ };
+
+ Landing.prototype.removeEvents.call(test.landing);
+ });
+
+ it('should call .removeEventListener', () => {
+ expect(test.dismissButton.removeEventListener).toHaveBeenCalledWith(
+ 'click',
+ test.eventWrapper.dismissLanding,
+ );
+ });
+ });
+
+ describe('dismissLanding', () => {
+ beforeEach(() => {
+ test.landingElement = {
+ classList: {
+ add: jest.fn(),
+ },
+ };
+ test.cookieName = 'cookie_name';
+ test.landing = { landingElement: test.landingElement, cookieName: test.cookieName };
+
+ jest.spyOn(Cookies, 'set').mockImplementation(() => {});
+
+ Landing.prototype.dismissLanding.call(test.landing);
+ });
+
+ it('should call .classList.add', () => {
+ expect(test.landingElement.classList.add).toHaveBeenCalledWith('hidden');
+ });
+
+ it('should call Cookies.set', () => {
+ expect(Cookies.set).toHaveBeenCalledWith(test.cookieName, 'true', { expires: 365 });
+ });
+ });
+
+ describe('isDismissed', () => {
+ beforeEach(() => {
+ test.cookieName = 'cookie_name';
+ test.landing = { cookieName: test.cookieName };
+
+ jest.spyOn(Cookies, 'get').mockReturnValue('true');
+
+ test.isDismissed = Landing.prototype.isDismissed.call(test.landing);
+ });
+
+ it('should call Cookies.get', () => {
+ expect(Cookies.get).toHaveBeenCalledWith(test.cookieName);
+ });
+
+ it('should return a boolean', () => {
+ expect(typeof test.isDismissed).toEqual('boolean');
+ });
+ });
+});
diff --git a/spec/frontend/groups/transfer_edit_spec.js b/spec/frontend/groups/transfer_edit_spec.js
new file mode 100644
index 00000000000..bc070920d02
--- /dev/null
+++ b/spec/frontend/groups/transfer_edit_spec.js
@@ -0,0 +1,31 @@
+import $ from 'jquery';
+
+import { loadHTMLFixture } from 'helpers/fixtures';
+import setupTransferEdit from '~/groups/transfer_edit';
+
+describe('setupTransferEdit', () => {
+ const formSelector = '.js-group-transfer-form';
+ const targetSelector = '#new_parent_group_id';
+
+ beforeEach(() => {
+ loadHTMLFixture('groups/edit.html');
+ setupTransferEdit(formSelector, targetSelector);
+ });
+
+ it('disables submit button on load', () => {
+ expect($(formSelector).find(':submit').prop('disabled')).toBe(true);
+ });
+
+ it('enables submit button when selection changes to non-empty value', () => {
+ const lastValue = $(formSelector).find(targetSelector).find('.dropdown-content li').last();
+ $(formSelector).find(targetSelector).val(lastValue).trigger('change');
+
+ expect($(formSelector).find(':submit').prop('disabled')).toBeFalsy();
+ });
+
+ it('disables submit button when selection changes to empty value', () => {
+ $(formSelector).find(targetSelector).val('').trigger('change');
+
+ expect($(formSelector).find(':submit').prop('disabled')).toBe(true);
+ });
+});
diff --git a/spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap b/spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap
index faa70982fac..d1cf9f2e248 100644
--- a/spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap
+++ b/spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap
@@ -25,11 +25,12 @@ exports[`IDE pipeline stage renders stage details & icon 1`] = `
<div
class="gl-mr-3 gl-ml-2"
>
- <span
- class="badge badge-pill"
+ <gl-badge-stub
+ size="md"
+ variant="muted"
>
- 4
- </span>
+ 4
+ </gl-badge-stub>
</div>
<gl-icon-stub
diff --git a/spec/frontend/ide/components/preview/clientside_spec.js b/spec/frontend/ide/components/preview/clientside_spec.js
index 1768f01f3b8..b168eec0f16 100644
--- a/spec/frontend/ide/components/preview/clientside_spec.js
+++ b/spec/frontend/ide/components/preview/clientside_spec.js
@@ -73,6 +73,8 @@ describe('IDE clientside preview', () => {
const createInitializedComponent = () => {
createComponent();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
sandpackReady: true,
manager: {
@@ -202,6 +204,8 @@ describe('IDE clientside preview', () => {
it('returns false if loading and mainEntry exists', () => {
createComponent({ getters: { packageJson: dummyPackageJson } });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ loading: true });
expect(wrapper.vm.showPreview).toBe(false);
@@ -209,6 +213,8 @@ describe('IDE clientside preview', () => {
it('returns true if not loading and mainEntry exists', () => {
createComponent({ getters: { packageJson: dummyPackageJson } });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ loading: false });
expect(wrapper.vm.showPreview).toBe(true);
@@ -218,12 +224,16 @@ describe('IDE clientside preview', () => {
describe('showEmptyState', () => {
it('returns true if no mainEntry exists', () => {
createComponent();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ loading: false });
expect(wrapper.vm.showEmptyState).toBe(true);
});
it('returns false if loading', () => {
createComponent();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ loading: true });
expect(wrapper.vm.showEmptyState).toBe(false);
@@ -231,6 +241,8 @@ describe('IDE clientside preview', () => {
it('returns false if not loading and mainEntry exists', () => {
createComponent({ getters: { packageJson: dummyPackageJson } });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ loading: false });
expect(wrapper.vm.showEmptyState).toBe(false);
@@ -307,6 +319,8 @@ describe('IDE clientside preview', () => {
describe('update', () => {
it('initializes manager if manager is empty', () => {
createComponent({ getters: { packageJson: dummyPackageJson } });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ sandpackReady: true });
wrapper.vm.update();
@@ -340,6 +354,8 @@ describe('IDE clientside preview', () => {
describe('template', () => {
it('renders ide-preview element when showPreview is true', () => {
createComponent({ getters: { packageJson: dummyPackageJson } });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ loading: false });
return wrapper.vm.$nextTick(() => {
@@ -349,6 +365,8 @@ describe('IDE clientside preview', () => {
it('renders empty state', () => {
createComponent();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ loading: false });
return wrapper.vm.$nextTick(() => {
@@ -360,6 +378,8 @@ describe('IDE clientside preview', () => {
it('renders loading icon', () => {
createComponent();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ loading: true });
return wrapper.vm.$nextTick(() => {
diff --git a/spec/frontend/ide/components/repo_editor_spec.js b/spec/frontend/ide/components/repo_editor_spec.js
index c957c64aa10..15af2d03704 100644
--- a/spec/frontend/ide/components/repo_editor_spec.js
+++ b/spec/frontend/ide/components/repo_editor_spec.js
@@ -5,7 +5,6 @@ import Vue from 'vue';
import Vuex from 'vuex';
import '~/behaviors/markdown/render_gfm';
import waitForPromises from 'helpers/wait_for_promises';
-import waitUsingRealTimer from 'helpers/wait_using_real_timer';
import { exampleConfigs, exampleFiles } from 'jest/ide/lib/editorconfig/mock_data';
import { EDITOR_CODE_INSTANCE_FN, EDITOR_DIFF_INSTANCE_FN } from '~/editor/constants';
import { EditorMarkdownExtension } from '~/editor/extensions/source_editor_markdown_ext';
@@ -540,7 +539,6 @@ describe('RepoEditor', () => {
},
});
await vm.$nextTick();
- await vm.$nextTick();
expect(vm.initEditor).toHaveBeenCalled();
});
@@ -567,8 +565,8 @@ describe('RepoEditor', () => {
// switching from edit to diff mode usually triggers editor initialization
vm.$store.state.viewer = viewerTypes.diff;
- // we delay returning the file to make sure editor doesn't initialize before we fetch file content
- await waitUsingRealTimer(30);
+ jest.runOnlyPendingTimers();
+
return 'rawFileData123\n';
});
@@ -598,8 +596,9 @@ describe('RepoEditor', () => {
return aContent;
})
.mockImplementationOnce(async () => {
- // we delay returning fileB content to make sure the editor doesn't initialize prematurely
- await waitUsingRealTimer(30);
+ // we delay returning fileB content
+ // to make sure the editor doesn't initialize prematurely
+ jest.advanceTimersByTime(30);
return bContent;
});
diff --git a/spec/frontend/ide/components/terminal/terminal_spec.js b/spec/frontend/ide/components/terminal/terminal_spec.js
index c4b186c004a..afc49e22c83 100644
--- a/spec/frontend/ide/components/terminal/terminal_spec.js
+++ b/spec/frontend/ide/components/terminal/terminal_spec.js
@@ -128,6 +128,8 @@ describe('IDE Terminal', () => {
canScrollDown: false,
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ canScrollUp: true, canScrollDown: true });
return nextTick().then(() => {
diff --git a/spec/frontend/ide/stores/modules/pipelines/actions_spec.js b/spec/frontend/ide/stores/modules/pipelines/actions_spec.js
index 9aa31136c89..3ede37e2eed 100644
--- a/spec/frontend/ide/stores/modules/pipelines/actions_spec.js
+++ b/spec/frontend/ide/stores/modules/pipelines/actions_spec.js
@@ -188,6 +188,24 @@ describe('IDE pipelines actions', () => {
.catch(done.fail);
});
});
+
+ it('sets latest pipeline to `null` and stops polling on empty project', (done) => {
+ mockedState = {
+ ...mockedState,
+ rootGetters: {
+ lastCommit: null,
+ },
+ };
+
+ testAction(
+ fetchLatestPipeline,
+ {},
+ mockedState,
+ [{ type: types.RECEIVE_LASTEST_PIPELINE_SUCCESS, payload: null }],
+ [{ type: 'stopPipelinePolling' }],
+ done,
+ );
+ });
});
describe('requestJobs', () => {
diff --git a/spec/frontend/integrations/edit/components/dynamic_field_spec.js b/spec/frontend/integrations/edit/components/dynamic_field_spec.js
index bf044e388ea..b0fb94d2b29 100644
--- a/spec/frontend/integrations/edit/components/dynamic_field_spec.js
+++ b/spec/frontend/integrations/edit/components/dynamic_field_spec.js
@@ -61,7 +61,7 @@ describe('DynamicField', () => {
});
it(`renders GlFormCheckbox with correct text content when checkboxLabel is ${checkboxLabel}`, () => {
- expect(findGlFormCheckbox().text()).toBe(checkboxLabel ?? defaultProps.title);
+ expect(findGlFormCheckbox().text()).toContain(checkboxLabel ?? defaultProps.title);
});
it('does not render other types of input', () => {
@@ -182,6 +182,17 @@ describe('DynamicField', () => {
expect(findGlFormGroup().find('small').text()).toBe(defaultProps.help);
});
+ describe('when type is checkbox', () => {
+ it('renders description with help text', () => {
+ createComponent({
+ type: 'checkbox',
+ });
+
+ expect(findGlFormGroup().find('small').exists()).toBe(false);
+ expect(findGlFormCheckbox().text()).toContain(defaultProps.help);
+ });
+ });
+
it('renders description with help text as HTML', () => {
const helpHTML = 'The <strong>URL</strong> of the project';
diff --git a/spec/frontend/integrations/edit/components/integration_form_spec.js b/spec/frontend/integrations/edit/components/integration_form_spec.js
index 4c1394f3a87..8cf8a403e5d 100644
--- a/spec/frontend/integrations/edit/components/integration_form_spec.js
+++ b/spec/frontend/integrations/edit/components/integration_form_spec.js
@@ -1,9 +1,10 @@
+import { GlForm } from '@gitlab/ui';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import * as Sentry from '@sentry/browser';
import { setHTMLFixture } from 'helpers/fixtures';
-import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import { mockIntegrationProps } from 'jest/integrations/edit/mock_data';
+import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import waitForPromises from 'helpers/wait_for_promises';
import ActiveCheckbox from '~/integrations/edit/components/active_checkbox.vue';
import ConfirmationModal from '~/integrations/edit/components/confirmation_modal.vue';
import DynamicField from '~/integrations/edit/components/dynamic_field.vue';
@@ -13,7 +14,6 @@ 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 waitForPromises from 'helpers/wait_for_promises';
import {
integrationLevels,
I18N_SUCCESSFUL_CONNECTION_MESSAGE,
@@ -23,9 +23,12 @@ import {
import { createStore } from '~/integrations/edit/store';
import eventHub from '~/integrations/edit/event_hub';
import httpStatus from '~/lib/utils/http_status';
+import { refreshCurrentPage } from '~/lib/utils/url_utility';
+import { mockIntegrationProps } from '../mock_data';
jest.mock('~/integrations/edit/event_hub');
jest.mock('@sentry/browser');
+jest.mock('~/lib/utils/url_utility');
describe('IntegrationForm', () => {
const mockToastShow = jest.fn();
@@ -34,12 +37,18 @@ describe('IntegrationForm', () => {
let dispatch;
let mockAxios;
let mockForm;
+ let vueIntegrationFormFeatureFlag;
+
+ const createForm = () => {
+ mockForm = document.createElement('form');
+ jest.spyOn(document, 'querySelector').mockReturnValue(mockForm);
+ };
const createComponent = ({
customStateProps = {},
- featureFlags = {},
initialState = {},
props = {},
+ mountFn = shallowMountExtended,
} = {}) => {
const store = createStore({
customState: { ...mockIntegrationProps, ...customStateProps },
@@ -47,11 +56,12 @@ describe('IntegrationForm', () => {
});
dispatch = jest.spyOn(store, 'dispatch').mockImplementation();
- wrapper = shallowMountExtended(IntegrationForm, {
- propsData: { ...props, formSelector: '.test' },
- provide: {
- glFeatures: featureFlags,
- },
+ if (!vueIntegrationFormFeatureFlag) {
+ createForm();
+ }
+
+ wrapper = mountFn(IntegrationForm, {
+ propsData: { ...props },
store,
stubs: {
OverrideDropdown,
@@ -65,26 +75,33 @@ describe('IntegrationForm', () => {
show: mockToastShow,
},
},
+ provide: {
+ glFeatures: {
+ vueIntegrationForm: vueIntegrationFormFeatureFlag,
+ },
+ },
});
};
- const createForm = ({ isValid = true } = {}) => {
- mockForm = document.createElement('form');
- jest.spyOn(document, 'querySelector').mockReturnValue(mockForm);
- jest.spyOn(mockForm, 'checkValidity').mockReturnValue(isValid);
- jest.spyOn(mockForm, 'submit');
- };
-
const findOverrideDropdown = () => wrapper.findComponent(OverrideDropdown);
const findActiveCheckbox = () => wrapper.findComponent(ActiveCheckbox);
const findConfirmationModal = () => wrapper.findComponent(ConfirmationModal);
const findResetConfirmationModal = () => wrapper.findComponent(ResetConfirmationModal);
const findResetButton = () => wrapper.findByTestId('reset-button');
- const findSaveButton = () => wrapper.findByTestId('save-button');
+ const findProjectSaveButton = () => wrapper.findByTestId('save-button');
+ const findInstanceOrGroupSaveButton = () => wrapper.findByTestId('save-button-instance-group');
const findTestButton = () => wrapper.findByTestId('test-button');
const findJiraTriggerFields = () => wrapper.findComponent(JiraTriggerFields);
const findJiraIssuesFields = () => wrapper.findComponent(JiraIssuesFields);
const findTriggerFields = () => wrapper.findComponent(TriggerFields);
+ const findGlForm = () => wrapper.findComponent(GlForm);
+ const findRedirectToField = () => wrapper.findByTestId('redirect-to-field');
+ const findFormElement = () => (vueIntegrationFormFeatureFlag ? findGlForm().element : mockForm);
+
+ const mockFormFunctions = ({ checkValidityReturn }) => {
+ jest.spyOn(findFormElement(), 'checkValidity').mockReturnValue(checkValidityReturn);
+ jest.spyOn(findFormElement(), 'submit');
+ };
beforeEach(() => {
mockAxios = new MockAdapter(axios);
@@ -220,6 +237,7 @@ describe('IntegrationForm', () => {
createComponent({
customStateProps: { type: 'jira', testPath: '/test' },
+ mountFn: mountExtended,
});
});
@@ -338,6 +356,19 @@ describe('IntegrationForm', () => {
});
});
});
+
+ describe('when `vueIntegrationForm` feature flag is $vueIntegrationFormEnabled', () => {
+ it('renders hidden fields', () => {
+ vueIntegrationFormFeatureFlag = true;
+ createComponent({
+ customStateProps: {
+ redirectTo: '/services',
+ },
+ });
+
+ expect(findRedirectToField().attributes('value')).toBe('/services');
+ });
+ });
});
describe('ActiveCheckbox', () => {
@@ -358,190 +389,292 @@ describe('IntegrationForm', () => {
});
describe.each`
- formActive | novalidate
- ${true} | ${null}
- ${false} | ${'true'}
+ formActive | vueIntegrationFormEnabled | novalidate
+ ${true} | ${true} | ${null}
+ ${false} | ${true} | ${'novalidate'}
+ ${true} | ${false} | ${null}
+ ${false} | ${false} | ${'true'}
`(
- 'when `toggle-integration-active` is emitted with $formActive',
- ({ formActive, novalidate }) => {
+ 'when `vueIntegrationForm` feature flag is $vueIntegrationFormEnabled and `toggle-integration-active` is emitted with $formActive',
+ ({ formActive, vueIntegrationFormEnabled, novalidate }) => {
beforeEach(async () => {
- createForm();
+ vueIntegrationFormFeatureFlag = vueIntegrationFormEnabled;
+
createComponent({
customStateProps: {
showActive: true,
initialActivated: false,
},
+ mountFn: mountExtended,
});
+ mockFormFunctions({ checkValidityReturn: false });
await findActiveCheckbox().vm.$emit('toggle-integration-active', formActive);
});
it(`sets noValidate to ${novalidate}`, () => {
- expect(mockForm.getAttribute('novalidate')).toBe(novalidate);
+ expect(findFormElement().getAttribute('novalidate')).toBe(novalidate);
});
},
);
});
- describe('when `save` button is clicked', () => {
- describe('buttons', () => {
- beforeEach(async () => {
- createForm();
- createComponent({
- customStateProps: {
- showActive: true,
- canTest: true,
- initialActivated: true,
- },
+ describe.each`
+ vueIntegrationFormEnabled
+ ${true}
+ ${false}
+ `(
+ 'when `vueIntegrationForm` feature flag is $vueIntegrationFormEnabled',
+ ({ vueIntegrationFormEnabled }) => {
+ beforeEach(() => {
+ vueIntegrationFormFeatureFlag = vueIntegrationFormEnabled;
+ });
+
+ describe('when `save` button is clicked', () => {
+ describe('buttons', () => {
+ beforeEach(async () => {
+ createComponent({
+ customStateProps: {
+ showActive: true,
+ canTest: true,
+ initialActivated: true,
+ },
+ mountFn: mountExtended,
+ });
+
+ await findProjectSaveButton().vm.$emit('click', new Event('click'));
+ });
+
+ it('sets save button `loading` prop to `true`', () => {
+ expect(findProjectSaveButton().props('loading')).toBe(true);
+ });
+
+ it('sets test button `disabled` prop to `true`', () => {
+ expect(findTestButton().props('disabled')).toBe(true);
+ });
});
- await findSaveButton().vm.$emit('click', new Event('click'));
- });
+ describe.each`
+ checkValidityReturn | integrationActive
+ ${true} | ${false}
+ ${true} | ${true}
+ ${false} | ${false}
+ `(
+ 'when form is valid (checkValidity returns $checkValidityReturn and integrationActive is $integrationActive)',
+ ({ integrationActive, checkValidityReturn }) => {
+ beforeEach(async () => {
+ createComponent({
+ customStateProps: {
+ showActive: true,
+ canTest: true,
+ initialActivated: integrationActive,
+ },
+ mountFn: mountExtended,
+ });
+
+ mockFormFunctions({ checkValidityReturn });
+
+ await findProjectSaveButton().vm.$emit('click', new Event('click'));
+ });
+
+ it('submits form', () => {
+ expect(findFormElement().submit).toHaveBeenCalledTimes(1);
+ });
+ },
+ );
+
+ describe('when form is invalid (checkValidity returns false and integrationActive is true)', () => {
+ beforeEach(async () => {
+ createComponent({
+ customStateProps: {
+ showActive: true,
+ canTest: true,
+ initialActivated: true,
+ },
+ mountFn: mountExtended,
+ });
+ mockFormFunctions({ checkValidityReturn: false });
+
+ await findProjectSaveButton().vm.$emit('click', new Event('click'));
+ });
- it('sets save button `loading` prop to `true`', () => {
- expect(findSaveButton().props('loading')).toBe(true);
- });
+ it('does not submit form', () => {
+ expect(findFormElement().submit).not.toHaveBeenCalled();
+ });
- it('sets test button `disabled` prop to `true`', () => {
- expect(findTestButton().props('disabled')).toBe(true);
- });
- });
+ it('sets save button `loading` prop to `false`', () => {
+ expect(findProjectSaveButton().props('loading')).toBe(false);
+ });
- describe.each`
- checkValidityReturn | integrationActive
- ${true} | ${false}
- ${true} | ${true}
- ${false} | ${false}
- `(
- 'when form is valid (checkValidity returns $checkValidityReturn and integrationActive is $integrationActive)',
- ({ integrationActive, checkValidityReturn }) => {
- beforeEach(async () => {
- createForm({ isValid: checkValidityReturn });
- createComponent({
- customStateProps: {
- showActive: true,
- canTest: true,
- initialActivated: integrationActive,
- },
+ it('sets test button `disabled` prop to `false`', () => {
+ expect(findTestButton().props('disabled')).toBe(false);
});
- await findSaveButton().vm.$emit('click', new Event('click'));
+ it('emits `VALIDATE_INTEGRATION_FORM_EVENT`', () => {
+ expect(eventHub.$emit).toHaveBeenCalledWith(VALIDATE_INTEGRATION_FORM_EVENT);
+ });
});
+ });
- it('submit form', () => {
- expect(mockForm.submit).toHaveBeenCalledTimes(1);
- });
- },
- );
+ describe('when `test` button is clicked', () => {
+ describe('when form is invalid', () => {
+ it('emits `VALIDATE_INTEGRATION_FORM_EVENT` event to the event hub', () => {
+ createComponent({
+ customStateProps: {
+ showActive: true,
+ canTest: true,
+ },
+ mountFn: mountExtended,
+ });
+ mockFormFunctions({ checkValidityReturn: false });
- describe('when form is invalid (checkValidity returns false and integrationActive is true)', () => {
- beforeEach(async () => {
- createForm({ isValid: false });
- createComponent({
- customStateProps: {
- showActive: true,
- canTest: true,
- initialActivated: true,
- },
+ findTestButton().vm.$emit('click', new Event('click'));
+
+ expect(eventHub.$emit).toHaveBeenCalledWith(VALIDATE_INTEGRATION_FORM_EVENT);
+ });
});
- await findSaveButton().vm.$emit('click', new Event('click'));
- });
+ describe('when form is valid', () => {
+ const mockTestPath = '/test';
- it('does not submit form', () => {
- expect(mockForm.submit).not.toHaveBeenCalled();
- });
+ beforeEach(() => {
+ createComponent({
+ customStateProps: {
+ showActive: true,
+ canTest: true,
+ testPath: mockTestPath,
+ },
+ mountFn: mountExtended,
+ });
+ mockFormFunctions({ checkValidityReturn: true });
+ });
- it('sets save button `loading` prop to `false`', () => {
- expect(findSaveButton().props('loading')).toBe(false);
- });
+ describe('buttons', () => {
+ beforeEach(async () => {
+ await findTestButton().vm.$emit('click', new Event('click'));
+ });
- it('sets test button `disabled` prop to `false`', () => {
- expect(findTestButton().props('disabled')).toBe(false);
- });
+ it('sets test button `loading` prop to `true`', () => {
+ expect(findTestButton().props('loading')).toBe(true);
+ });
- it('emits `VALIDATE_INTEGRATION_FORM_EVENT`', () => {
- expect(eventHub.$emit).toHaveBeenCalledWith(VALIDATE_INTEGRATION_FORM_EVENT);
+ it('sets save button `disabled` prop to `true`', () => {
+ expect(findProjectSaveButton().props('disabled')).toBe(true);
+ });
+ });
+
+ describe.each`
+ scenario | replyStatus | errorMessage | expectToast | expectSentry
+ ${'when "test settings" request fails'} | ${httpStatus.INTERNAL_SERVER_ERROR} | ${undefined} | ${I18N_DEFAULT_ERROR_MESSAGE} | ${true}
+ ${'when "test settings" returns an error'} | ${httpStatus.OK} | ${'an error'} | ${'an error'} | ${false}
+ ${'when "test settings" succeeds'} | ${httpStatus.OK} | ${undefined} | ${I18N_SUCCESSFUL_CONNECTION_MESSAGE} | ${false}
+ `('$scenario', ({ replyStatus, errorMessage, expectToast, expectSentry }) => {
+ beforeEach(async () => {
+ mockAxios.onPut(mockTestPath).replyOnce(replyStatus, {
+ error: Boolean(errorMessage),
+ message: errorMessage,
+ });
+
+ await findTestButton().vm.$emit('click', new Event('click'));
+ await waitForPromises();
+ });
+
+ it(`calls toast with '${expectToast}'`, () => {
+ expect(mockToastShow).toHaveBeenCalledWith(expectToast);
+ });
+
+ it('sets `loading` prop of test button to `false`', () => {
+ expect(findTestButton().props('loading')).toBe(false);
+ });
+
+ it('sets save button `disabled` prop to `false`', () => {
+ expect(findProjectSaveButton().props('disabled')).toBe(false);
+ });
+
+ it(`${expectSentry ? 'does' : 'does not'} capture exception in Sentry`, () => {
+ expect(Sentry.captureException).toHaveBeenCalledTimes(expectSentry ? 1 : 0);
+ });
+ });
+ });
});
- });
- });
+ },
+ );
+
+ describe('when `reset-confirmation-modal` emits `reset` event', () => {
+ const mockResetPath = '/reset';
- describe('when `test` button is clicked', () => {
- describe('when form is invalid', () => {
- it('emits `VALIDATE_INTEGRATION_FORM_EVENT` event to the event hub', () => {
- createForm({ isValid: false });
+ describe('buttons', () => {
+ beforeEach(async () => {
createComponent({
customStateProps: {
- showActive: true,
+ integrationLevel: integrationLevels.GROUP,
canTest: true,
+ resetPath: mockResetPath,
},
});
- findTestButton().vm.$emit('click', new Event('click'));
+ await findResetConfirmationModal().vm.$emit('reset');
+ });
- expect(eventHub.$emit).toHaveBeenCalledWith(VALIDATE_INTEGRATION_FORM_EVENT);
+ it('sets reset button `loading` prop to `true`', () => {
+ expect(findResetButton().props('loading')).toBe(true);
});
- });
- describe('when form is valid', () => {
- const mockTestPath = '/test';
+ it('sets other button `disabled` props to `true`', () => {
+ expect(findInstanceOrGroupSaveButton().props('disabled')).toBe(true);
+ expect(findTestButton().props('disabled')).toBe(true);
+ });
+ });
- beforeEach(() => {
- createForm({ isValid: true });
+ describe('when "reset settings" request fails', () => {
+ beforeEach(async () => {
+ mockAxios.onPost(mockResetPath).replyOnce(httpStatus.INTERNAL_SERVER_ERROR);
createComponent({
customStateProps: {
- showActive: true,
+ integrationLevel: integrationLevels.GROUP,
canTest: true,
- testPath: mockTestPath,
+ resetPath: mockResetPath,
},
});
- });
-
- describe('buttons', () => {
- beforeEach(async () => {
- await findTestButton().vm.$emit('click', new Event('click'));
- });
- it('sets test button `loading` prop to `true`', () => {
- expect(findTestButton().props('loading')).toBe(true);
- });
+ await findResetConfirmationModal().vm.$emit('reset');
+ await waitForPromises();
+ });
- it('sets save button `disabled` prop to `true`', () => {
- expect(findSaveButton().props('disabled')).toBe(true);
- });
+ it('displays a toast', () => {
+ expect(mockToastShow).toHaveBeenCalledWith(I18N_DEFAULT_ERROR_MESSAGE);
});
- describe.each`
- scenario | replyStatus | errorMessage | expectToast | expectSentry
- ${'when "test settings" request fails'} | ${httpStatus.INTERNAL_SERVER_ERROR} | ${undefined} | ${I18N_DEFAULT_ERROR_MESSAGE} | ${true}
- ${'when "test settings" returns an error'} | ${httpStatus.OK} | ${'an error'} | ${'an error'} | ${false}
- ${'when "test settings" succeeds'} | ${httpStatus.OK} | ${undefined} | ${I18N_SUCCESSFUL_CONNECTION_MESSAGE} | ${false}
- `('$scenario', ({ replyStatus, errorMessage, expectToast, expectSentry }) => {
- beforeEach(async () => {
- mockAxios.onPut(mockTestPath).replyOnce(replyStatus, {
- error: Boolean(errorMessage),
- message: errorMessage,
- });
+ it('captures exception in Sentry', () => {
+ expect(Sentry.captureException).toHaveBeenCalledTimes(1);
+ });
- await findTestButton().vm.$emit('click', new Event('click'));
- await waitForPromises();
- });
+ it('sets reset button `loading` prop to `false`', () => {
+ expect(findResetButton().props('loading')).toBe(false);
+ });
- it(`calls toast with '${expectToast}'`, () => {
- expect(mockToastShow).toHaveBeenCalledWith(expectToast);
- });
+ it('sets button `disabled` props to `false`', () => {
+ expect(findInstanceOrGroupSaveButton().props('disabled')).toBe(false);
+ expect(findTestButton().props('disabled')).toBe(false);
+ });
+ });
- it('sets `loading` prop of test button to `false`', () => {
- expect(findTestButton().props('loading')).toBe(false);
+ describe('when "reset settings" succeeds', () => {
+ beforeEach(async () => {
+ mockAxios.onPost(mockResetPath).replyOnce(httpStatus.OK);
+ createComponent({
+ customStateProps: {
+ integrationLevel: integrationLevels.GROUP,
+ resetPath: mockResetPath,
+ },
});
- it('sets save button `disabled` prop to `false`', () => {
- expect(findSaveButton().props('disabled')).toBe(false);
- });
+ await findResetConfirmationModal().vm.$emit('reset');
+ await waitForPromises();
+ });
- it(`${expectSentry ? 'does' : 'does not'} capture exception in Sentry`, () => {
- expect(Sentry.captureException).toHaveBeenCalledTimes(expectSentry ? 1 : 0);
- });
+ it('calls `refreshCurrentPage`', () => {
+ expect(refreshCurrentPage).toHaveBeenCalledTimes(1);
});
});
});
diff --git a/spec/frontend/integrations/edit/store/actions_spec.js b/spec/frontend/integrations/edit/store/actions_spec.js
index b413de2b286..a5627d8b669 100644
--- a/spec/frontend/integrations/edit/store/actions_spec.js
+++ b/spec/frontend/integrations/edit/store/actions_spec.js
@@ -4,17 +4,12 @@ import testAction from 'helpers/vuex_action_helper';
import { I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE } from '~/integrations/constants';
import {
setOverride,
- setIsResetting,
- requestResetIntegration,
- receiveResetIntegrationSuccess,
- receiveResetIntegrationError,
requestJiraIssueTypes,
receiveJiraIssueTypesSuccess,
receiveJiraIssueTypesError,
} from '~/integrations/edit/store/actions';
import * as types from '~/integrations/edit/store/mutation_types';
import createState from '~/integrations/edit/store/state';
-import { refreshCurrentPage } from '~/lib/utils/url_utility';
import { mockJiraIssueTypes } from '../mock_data';
jest.mock('~/lib/utils/url_utility');
@@ -38,38 +33,6 @@ describe('Integration form store actions', () => {
});
});
- describe('setIsResetting', () => {
- it('should commit isResetting mutation', () => {
- return testAction(setIsResetting, true, state, [
- { type: types.SET_IS_RESETTING, payload: true },
- ]);
- });
- });
-
- describe('requestResetIntegration', () => {
- it('should commit REQUEST_RESET_INTEGRATION mutation', () => {
- return testAction(requestResetIntegration, null, state, [
- { type: types.REQUEST_RESET_INTEGRATION },
- ]);
- });
- });
-
- describe('receiveResetIntegrationSuccess', () => {
- it('should call refreshCurrentPage()', () => {
- return testAction(receiveResetIntegrationSuccess, null, state, [], [], () => {
- expect(refreshCurrentPage).toHaveBeenCalled();
- });
- });
- });
-
- describe('receiveResetIntegrationError', () => {
- it('should commit RECEIVE_RESET_INTEGRATION_ERROR mutation', () => {
- return testAction(receiveResetIntegrationError, null, state, [
- { type: types.RECEIVE_RESET_INTEGRATION_ERROR },
- ]);
- });
- });
-
describe('requestJiraIssueTypes', () => {
describe.each`
scenario | responseCode | response | action
diff --git a/spec/frontend/integrations/edit/store/mutations_spec.js b/spec/frontend/integrations/edit/store/mutations_spec.js
index 641547550d1..ecac9d88982 100644
--- a/spec/frontend/integrations/edit/store/mutations_spec.js
+++ b/spec/frontend/integrations/edit/store/mutations_spec.js
@@ -17,30 +17,6 @@ describe('Integration form store mutations', () => {
});
});
- describe(`${types.SET_IS_RESETTING}`, () => {
- it('sets isResetting', () => {
- mutations[types.SET_IS_RESETTING](state, true);
-
- expect(state.isResetting).toBe(true);
- });
- });
-
- describe(`${types.REQUEST_RESET_INTEGRATION}`, () => {
- it('sets isResetting', () => {
- mutations[types.REQUEST_RESET_INTEGRATION](state);
-
- expect(state.isResetting).toBe(true);
- });
- });
-
- describe(`${types.RECEIVE_RESET_INTEGRATION_ERROR}`, () => {
- it('sets isResetting', () => {
- mutations[types.RECEIVE_RESET_INTEGRATION_ERROR](state);
-
- expect(state.isResetting).toBe(false);
- });
- });
-
describe(`${types.SET_JIRA_ISSUE_TYPES}`, () => {
it('sets jiraIssueTypes', () => {
const jiraIssueTypes = ['issue', 'epic'];
diff --git a/spec/frontend/integrations/edit/store/state_spec.js b/spec/frontend/integrations/edit/store/state_spec.js
index 5582be7fd3c..0b4ca8fb65c 100644
--- a/spec/frontend/integrations/edit/store/state_spec.js
+++ b/spec/frontend/integrations/edit/store/state_spec.js
@@ -5,8 +5,6 @@ describe('Integration form state factory', () => {
expect(createState()).toEqual({
defaultState: null,
customState: {},
- isSaving: false,
- isResetting: false,
override: false,
isLoadingJiraIssueTypes: false,
jiraIssueTypes: [],
diff --git a/spec/frontend/integrations/overrides/components/integration_overrides_spec.js b/spec/frontend/integrations/overrides/components/integration_overrides_spec.js
index 8abd83887f7..6aa3e661677 100644
--- a/spec/frontend/integrations/overrides/components/integration_overrides_spec.js
+++ b/spec/frontend/integrations/overrides/components/integration_overrides_spec.js
@@ -5,6 +5,8 @@ import MockAdapter from 'axios-mock-adapter';
import waitForPromises from 'helpers/wait_for_promises';
import { DEFAULT_PER_PAGE } from '~/api';
import IntegrationOverrides from '~/integrations/overrides/components/integration_overrides.vue';
+import IntegrationTabs from '~/integrations/overrides/components/integration_tabs.vue';
+
import axios from '~/lib/utils/axios_utils';
import httpStatus from '~/lib/utils/http_status';
import ProjectAvatar from '~/vue_shared/components/project_avatar.vue';
@@ -49,6 +51,7 @@ describe('IntegrationOverrides', () => {
const findGlTable = () => wrapper.findComponent(GlTable);
const findPagination = () => wrapper.findComponent(GlPagination);
+ const findIntegrationTabs = () => wrapper.findComponent(IntegrationTabs);
const findRowsAsModel = () =>
findGlTable()
.findAllComponents(GlLink)
@@ -72,6 +75,12 @@ describe('IntegrationOverrides', () => {
expect(table.exists()).toBe(true);
expect(table.attributes('busy')).toBe('true');
});
+
+ it('renders IntegrationTabs with count as `null`', () => {
+ createComponent();
+
+ expect(findIntegrationTabs().props('projectOverridesCount')).toBe(null);
+ });
});
describe('when initial request is successful', () => {
@@ -84,6 +93,13 @@ describe('IntegrationOverrides', () => {
expect(table.attributes('busy')).toBeFalsy();
});
+ it('renders IntegrationTabs with count', async () => {
+ createComponent();
+ await waitForPromises();
+
+ expect(findIntegrationTabs().props('projectOverridesCount')).toBe(mockOverrides.length);
+ });
+
describe('table template', () => {
beforeEach(async () => {
createComponent({ mountFn: mount });
diff --git a/spec/frontend/integrations/overrides/components/integration_tabs_spec.js b/spec/frontend/integrations/overrides/components/integration_tabs_spec.js
new file mode 100644
index 00000000000..a728b4d391f
--- /dev/null
+++ b/spec/frontend/integrations/overrides/components/integration_tabs_spec.js
@@ -0,0 +1,64 @@
+import { mount, shallowMount } from '@vue/test-utils';
+import { GlBadge, GlTab } from '@gitlab/ui';
+
+import IntegrationTabs from '~/integrations/overrides/components/integration_tabs.vue';
+import { settingsTabTitle, overridesTabTitle } from '~/integrations/constants';
+
+describe('IntegrationTabs', () => {
+ let wrapper;
+
+ const editPath = 'mock/edit';
+
+ const createComponent = ({ mountFn = shallowMount, props = {} } = {}) => {
+ wrapper = mountFn(IntegrationTabs, {
+ propsData: props,
+ provide: {
+ editPath,
+ },
+ stubs: {
+ GlTab,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const findGlBadge = () => wrapper.findComponent(GlBadge);
+ const findGlTab = () => wrapper.findComponent(GlTab);
+ const findSettingsLink = () => wrapper.find('a');
+
+ describe('template', () => {
+ it('renders "Settings" tab as a link', () => {
+ createComponent({ mountFn: mount });
+
+ expect(findSettingsLink().text()).toMatchInterpolatedText(settingsTabTitle);
+ expect(findSettingsLink().attributes('href')).toBe(editPath);
+ });
+
+ it('renders "Projects using custom settings" tab as active', () => {
+ const projectOverridesCount = '1';
+
+ createComponent({
+ props: { projectOverridesCount },
+ });
+
+ expect(findGlTab().exists()).toBe(true);
+ expect(findGlTab().text()).toMatchInterpolatedText(
+ `${overridesTabTitle} ${projectOverridesCount}`,
+ );
+ expect(findGlBadge().text()).toBe(projectOverridesCount);
+ });
+
+ describe('when count is `null', () => {
+ it('renders "Projects using custom settings" tab without count', () => {
+ createComponent();
+
+ expect(findGlTab().exists()).toBe(true);
+ expect(findGlTab().text()).toMatchInterpolatedText(overridesTabTitle);
+ expect(findGlBadge().exists()).toBe(false);
+ });
+ });
+ });
+});
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 e190ddf243e..3ab89b3dff2 100644
--- a/spec/frontend/invite_members/components/invite_members_modal_spec.js
+++ b/spec/frontend/invite_members/components/invite_members_modal_spec.js
@@ -474,6 +474,8 @@ describe('InviteMembersModal', () => {
beforeEach(() => {
createInviteMembersToGroupWrapper();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ newUsersToInvite: [user1] });
});
@@ -644,6 +646,8 @@ describe('InviteMembersModal', () => {
beforeEach(() => {
createInviteMembersToGroupWrapper();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ newUsersToInvite: [user3] });
});
@@ -712,6 +716,8 @@ describe('InviteMembersModal', () => {
it('displays the invalid syntax error if one of the emails is invalid', async () => {
createInviteMembersToGroupWrapper();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ newUsersToInvite: [user3, user4] });
mockInvitationsApi(httpStatus.CREATED, invitationsApiResponse.ERROR_EMAIL_INVALID);
@@ -787,6 +793,8 @@ describe('InviteMembersModal', () => {
beforeEach(() => {
createInviteMembersToGroupWrapper();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ newUsersToInvite: [user1, user3] });
mockInvitationsApi(httpStatus.BAD_REQUEST, invitationsApiResponse.EMAIL_INVALID);
@@ -815,6 +823,8 @@ describe('InviteMembersModal', () => {
beforeEach(() => {
createComponent({ groupToBeSharedWith: sharedGroup });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ inviteeType: 'group' });
wrapper.vm.$toast = { show: jest.fn() };
jest.spyOn(Api, 'groupShareWithGroup').mockResolvedValue({ data: groupPostData });
@@ -837,6 +847,8 @@ describe('InviteMembersModal', () => {
beforeEach(() => {
createInviteGroupToGroupWrapper();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ groupToBeSharedWith: sharedGroup });
wrapper.vm.$toast = { show: jest.fn() };
diff --git a/spec/frontend/invite_members/mock_data/api_responses.js b/spec/frontend/invite_members/mock_data/api_responses.js
index dd84b4fd78f..a3e426376d8 100644
--- a/spec/frontend/invite_members/mock_data/api_responses.js
+++ b/spec/frontend/invite_members/mock_data/api_responses.js
@@ -26,7 +26,7 @@ const INVITATIONS_API_MULTIPLE_EMAIL_RESTRICTED = {
const INVITATIONS_API_EMAIL_TAKEN = {
message: {
- 'email@example2.com': 'Invite email has already been taken',
+ 'email@example.org': 'Invite email has already been taken',
},
status: 'error',
};
diff --git a/spec/frontend/issuable/components/related_issuable_item_spec.js b/spec/frontend/issuable/components/related_issuable_item_spec.js
index 6ac4c9e8546..6a896ccd21a 100644
--- a/spec/frontend/issuable/components/related_issuable_item_spec.js
+++ b/spec/frontend/issuable/components/related_issuable_item_spec.js
@@ -169,6 +169,8 @@ describe('RelatedIssuableItem', () => {
});
it('renders disabled button when removeDisabled', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ removeDisabled: true });
await wrapper.vm.$nextTick();
diff --git a/spec/frontend/issues/create_merge_request_dropdown_spec.js b/spec/frontend/issues/create_merge_request_dropdown_spec.js
new file mode 100644
index 00000000000..fdc0bd7d72e
--- /dev/null
+++ b/spec/frontend/issues/create_merge_request_dropdown_spec.js
@@ -0,0 +1,122 @@
+import MockAdapter from 'axios-mock-adapter';
+import { TEST_HOST } from 'helpers/test_constants';
+import confidentialState from '~/confidential_merge_request/state';
+import CreateMergeRequestDropdown from '~/issues/create_merge_request_dropdown';
+import axios from '~/lib/utils/axios_utils';
+
+describe('CreateMergeRequestDropdown', () => {
+ let axiosMock;
+ let dropdown;
+
+ beforeEach(() => {
+ axiosMock = new MockAdapter(axios);
+
+ document.body.innerHTML = `
+ <div id="dummy-wrapper-element">
+ <div class="available"></div>
+ <div class="unavailable">
+ <div class="gl-spinner"></div>
+ <div class="text"></div>
+ </div>
+ <div class="js-ref"></div>
+ <div class="js-create-mr"></div>
+ <div class="js-create-merge-request">
+ <span class="js-spinner"></span>
+ </div>
+ <div class="js-create-target"></div>
+ <div class="js-dropdown-toggle"></div>
+ </div>
+ `;
+
+ const dummyElement = document.getElementById('dummy-wrapper-element');
+ dropdown = new CreateMergeRequestDropdown(dummyElement);
+ dropdown.refsPath = `${TEST_HOST}/dummy/refs?search=`;
+ });
+
+ afterEach(() => {
+ axiosMock.restore();
+ });
+
+ describe('getRef', () => {
+ it('escapes branch names correctly', (done) => {
+ const endpoint = `${dropdown.refsPath}contains%23hash`;
+ jest.spyOn(axios, 'get');
+ axiosMock.onGet(endpoint).replyOnce({});
+
+ dropdown
+ .getRef('contains#hash')
+ .then(() => {
+ expect(axios.get).toHaveBeenCalledWith(
+ endpoint,
+ expect.objectContaining({ cancelToken: expect.anything() }),
+ );
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('updateCreatePaths', () => {
+ it('escapes branch names correctly', () => {
+ dropdown.createBranchPath = `${TEST_HOST}/branches?branch_name=some-branch&issue=42`;
+ dropdown.createMrPath = `${TEST_HOST}/create_merge_request?branch_name=some-branch&ref=main`;
+
+ dropdown.updateCreatePaths('branch', 'contains#hash');
+
+ expect(dropdown.createBranchPath).toBe(
+ `${TEST_HOST}/branches?branch_name=contains%23hash&issue=42`,
+ );
+
+ expect(dropdown.createMrPath).toBe(
+ `${TEST_HOST}/create_merge_request?branch_name=contains%23hash&ref=main`,
+ );
+ });
+ });
+
+ describe('enable', () => {
+ beforeEach(() => {
+ dropdown.createMergeRequestButton.classList.add('disabled');
+ });
+
+ afterEach(() => {
+ confidentialState.selectedProject = {};
+ });
+
+ it('enables button when not confidential issue', () => {
+ dropdown.enable();
+
+ expect(dropdown.createMergeRequestButton.classList).not.toContain('disabled');
+ });
+
+ it('enables when can create confidential issue', () => {
+ document.querySelector('.js-create-mr').setAttribute('data-is-confidential', 'true');
+ confidentialState.selectedProject = { name: 'test' };
+
+ dropdown.enable();
+
+ expect(dropdown.createMergeRequestButton.classList).not.toContain('disabled');
+ });
+
+ it('does not enable when can not create confidential issue', () => {
+ document.querySelector('.js-create-mr').setAttribute('data-is-confidential', 'true');
+
+ dropdown.enable();
+
+ expect(dropdown.createMergeRequestButton.classList).toContain('disabled');
+ });
+ });
+
+ describe('setLoading', () => {
+ it.each`
+ loading | hasClass
+ ${true} | ${false}
+ ${false} | ${true}
+ `('it toggle loading spinner when loading is $loading', ({ loading, hasClass }) => {
+ dropdown.setLoading(loading);
+
+ expect(document.querySelector('.js-spinner').classList.contains('gl-display-none')).toEqual(
+ hasClass,
+ );
+ });
+ });
+});
diff --git a/spec/frontend/issues/list/components/issue_card_time_info_spec.js b/spec/frontend/issues/list/components/issue_card_time_info_spec.js
new file mode 100644
index 00000000000..e9c48b60da4
--- /dev/null
+++ b/spec/frontend/issues/list/components/issue_card_time_info_spec.js
@@ -0,0 +1,122 @@
+import { GlIcon, GlLink } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import { useFakeDate } from 'helpers/fake_date';
+import IssueCardTimeInfo from '~/issues/list/components/issue_card_time_info.vue';
+
+describe('CE IssueCardTimeInfo component', () => {
+ useFakeDate(2020, 11, 11);
+
+ let wrapper;
+
+ const issue = {
+ milestone: {
+ dueDate: '2020-12-17',
+ startDate: '2020-12-10',
+ title: 'My milestone',
+ webPath: '/milestone/webPath',
+ },
+ dueDate: '2020-12-12',
+ humanTimeEstimate: '1w',
+ };
+
+ const findMilestone = () => wrapper.find('[data-testid="issuable-milestone"]');
+ const findMilestoneTitle = () => findMilestone().find(GlLink).attributes('title');
+ const findDueDate = () => wrapper.find('[data-testid="issuable-due-date"]');
+
+ const mountComponent = ({
+ closedAt = null,
+ dueDate = issue.dueDate,
+ milestoneDueDate = issue.milestone.dueDate,
+ milestoneStartDate = issue.milestone.startDate,
+ } = {}) =>
+ shallowMount(IssueCardTimeInfo, {
+ propsData: {
+ issue: {
+ ...issue,
+ milestone: {
+ ...issue.milestone,
+ dueDate: milestoneDueDate,
+ startDate: milestoneStartDate,
+ },
+ closedAt,
+ dueDate,
+ },
+ },
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('milestone', () => {
+ it('renders', () => {
+ wrapper = mountComponent();
+
+ const milestone = findMilestone();
+
+ expect(milestone.text()).toBe(issue.milestone.title);
+ expect(milestone.find(GlIcon).props('name')).toBe('clock');
+ expect(milestone.find(GlLink).attributes('href')).toBe(issue.milestone.webPath);
+ });
+
+ describe.each`
+ time | text | milestoneDueDate | milestoneStartDate | expected
+ ${'due date is in past'} | ${'Past due'} | ${'2020-09-09'} | ${null} | ${'Sep 9, 2020 (Past due)'}
+ ${'due date is today'} | ${'Today'} | ${'2020-12-11'} | ${null} | ${'Dec 11, 2020 (Today)'}
+ ${'start date is in future'} | ${'Upcoming'} | ${'2021-03-01'} | ${'2021-02-01'} | ${'Mar 1, 2021 (Upcoming)'}
+ ${'due date is in future'} | ${'2 weeks remaining'} | ${'2020-12-25'} | ${null} | ${'Dec 25, 2020 (2 weeks remaining)'}
+ `('when $description', ({ text, milestoneDueDate, milestoneStartDate, expected }) => {
+ it(`renders with "${text}"`, () => {
+ wrapper = mountComponent({ milestoneDueDate, milestoneStartDate });
+
+ expect(findMilestoneTitle()).toBe(expected);
+ });
+ });
+ });
+
+ describe('due date', () => {
+ describe('when upcoming', () => {
+ it('renders', () => {
+ wrapper = mountComponent();
+
+ const dueDate = findDueDate();
+
+ expect(dueDate.text()).toBe('Dec 12, 2020');
+ expect(dueDate.attributes('title')).toBe('Due date');
+ expect(dueDate.find(GlIcon).props('name')).toBe('calendar');
+ expect(dueDate.classes()).not.toContain('gl-text-red-500');
+ });
+ });
+
+ describe('when in the past', () => {
+ describe('when issue is open', () => {
+ it('renders in red', () => {
+ wrapper = mountComponent({ dueDate: new Date('2020-10-10') });
+
+ expect(findDueDate().classes()).toContain('gl-text-red-500');
+ });
+ });
+
+ describe('when issue is closed', () => {
+ it('does not render in red', () => {
+ wrapper = mountComponent({
+ dueDate: new Date('2020-10-10'),
+ closedAt: '2020-09-05T13:06:25Z',
+ });
+
+ expect(findDueDate().classes()).not.toContain('gl-text-red-500');
+ });
+ });
+ });
+ });
+
+ it('renders time estimate', () => {
+ wrapper = mountComponent();
+
+ const timeEstimate = wrapper.find('[data-testid="time-estimate"]');
+
+ expect(timeEstimate.text()).toBe(issue.humanTimeEstimate);
+ expect(timeEstimate.attributes('title')).toBe('Estimate');
+ expect(timeEstimate.find(GlIcon).props('name')).toBe('timer');
+ });
+});
diff --git a/spec/frontend/issues/list/components/issues_list_app_spec.js b/spec/frontend/issues/list/components/issues_list_app_spec.js
new file mode 100644
index 00000000000..66428ee0492
--- /dev/null
+++ b/spec/frontend/issues/list/components/issues_list_app_spec.js
@@ -0,0 +1,829 @@
+import { GlButton, GlEmptyState, GlLink } from '@gitlab/ui';
+import * as Sentry from '@sentry/browser';
+import { mount, shallowMount } from '@vue/test-utils';
+import AxiosMockAdapter from 'axios-mock-adapter';
+import { cloneDeep } from 'lodash';
+import Vue, { nextTick } from 'vue';
+import VueApollo from 'vue-apollo';
+import getIssuesQuery from 'ee_else_ce/issues/list/queries/get_issues.query.graphql';
+import getIssuesCountsQuery from 'ee_else_ce/issues/list/queries/get_issues_counts.query.graphql';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import setWindowLocation from 'helpers/set_window_location_helper';
+import { TEST_HOST } from 'helpers/test_constants';
+import waitForPromises from 'helpers/wait_for_promises';
+import {
+ getIssuesCountsQueryResponse,
+ getIssuesQueryResponse,
+ filteredTokens,
+ locationSearch,
+ urlParams,
+} from 'jest/issues/list/mock_data';
+import createFlash, { FLASH_TYPES } from '~/flash';
+import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
+import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue';
+import IssuableByEmail from '~/issuable/components/issuable_by_email.vue';
+import IssuableList from '~/vue_shared/issuable/list/components/issuable_list_root.vue';
+import { IssuableListTabs, IssuableStates } from '~/vue_shared/issuable/list/constants';
+import IssuesListApp from '~/issues/list/components/issues_list_app.vue';
+import NewIssueDropdown from '~/issues/list/components/new_issue_dropdown.vue';
+import {
+ CREATED_DESC,
+ DUE_DATE_OVERDUE,
+ PARAM_DUE_DATE,
+ RELATIVE_POSITION,
+ RELATIVE_POSITION_ASC,
+ TOKEN_TYPE_ASSIGNEE,
+ TOKEN_TYPE_AUTHOR,
+ TOKEN_TYPE_CONFIDENTIAL,
+ TOKEN_TYPE_LABEL,
+ TOKEN_TYPE_MILESTONE,
+ TOKEN_TYPE_MY_REACTION,
+ TOKEN_TYPE_RELEASE,
+ TOKEN_TYPE_TYPE,
+ urlSortParams,
+} from '~/issues/list/constants';
+import eventHub from '~/issues/list/eventhub';
+import { getSortOptions } from '~/issues/list/utils';
+import axios from '~/lib/utils/axios_utils';
+import { scrollUp } from '~/lib/utils/scroll_utils';
+import { joinPaths } from '~/lib/utils/url_utility';
+
+jest.mock('@sentry/browser');
+jest.mock('~/flash');
+jest.mock('~/lib/utils/scroll_utils', () => ({
+ scrollUp: jest.fn().mockName('scrollUpMock'),
+}));
+
+describe('CE IssuesListApp component', () => {
+ let axiosMock;
+ let wrapper;
+
+ Vue.use(VueApollo);
+
+ const defaultProvide = {
+ calendarPath: 'calendar/path',
+ canBulkUpdate: false,
+ emptyStateSvgPath: 'empty-state.svg',
+ exportCsvPath: 'export/csv/path',
+ fullPath: 'path/to/project',
+ hasAnyIssues: true,
+ hasAnyProjects: true,
+ hasBlockedIssuesFeature: true,
+ hasIssuableHealthStatusFeature: true,
+ hasIssueWeightsFeature: true,
+ hasIterationsFeature: true,
+ isProject: true,
+ isSignedIn: true,
+ jiraIntegrationPath: 'jira/integration/path',
+ newIssuePath: 'new/issue/path',
+ rssPath: 'rss/path',
+ showNewIssueLink: true,
+ signInPath: 'sign/in/path',
+ };
+
+ let defaultQueryResponse = getIssuesQueryResponse;
+ if (IS_EE) {
+ defaultQueryResponse = cloneDeep(getIssuesQueryResponse);
+ defaultQueryResponse.data.project.issues.nodes[0].blockingCount = 1;
+ defaultQueryResponse.data.project.issues.nodes[0].healthStatus = null;
+ defaultQueryResponse.data.project.issues.nodes[0].weight = 5;
+ }
+
+ const findCsvImportExportButtons = () => wrapper.findComponent(CsvImportExportButtons);
+ const findIssuableByEmail = () => wrapper.findComponent(IssuableByEmail);
+ const findGlButton = () => wrapper.findComponent(GlButton);
+ const findGlButtons = () => wrapper.findAllComponents(GlButton);
+ const findGlButtonAt = (index) => findGlButtons().at(index);
+ const findGlEmptyState = () => wrapper.findComponent(GlEmptyState);
+ const findGlLink = () => wrapper.findComponent(GlLink);
+ const findIssuableList = () => wrapper.findComponent(IssuableList);
+ const findNewIssueDropdown = () => wrapper.findComponent(NewIssueDropdown);
+
+ const mountComponent = ({
+ provide = {},
+ issuesQueryResponse = jest.fn().mockResolvedValue(defaultQueryResponse),
+ issuesCountsQueryResponse = jest.fn().mockResolvedValue(getIssuesCountsQueryResponse),
+ mountFn = shallowMount,
+ } = {}) => {
+ const requestHandlers = [
+ [getIssuesQuery, issuesQueryResponse],
+ [getIssuesCountsQuery, issuesCountsQueryResponse],
+ ];
+ const apolloProvider = createMockApollo(requestHandlers);
+
+ return mountFn(IssuesListApp, {
+ apolloProvider,
+ provide: {
+ ...defaultProvide,
+ ...provide,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ setWindowLocation(TEST_HOST);
+ axiosMock = new AxiosMockAdapter(axios);
+ });
+
+ afterEach(() => {
+ axiosMock.reset();
+ wrapper.destroy();
+ });
+
+ describe('IssuableList', () => {
+ beforeEach(() => {
+ wrapper = mountComponent();
+ jest.runOnlyPendingTimers();
+ });
+
+ it('renders', () => {
+ expect(findIssuableList().props()).toMatchObject({
+ namespace: defaultProvide.fullPath,
+ recentSearchesStorageKey: 'issues',
+ searchInputPlaceholder: IssuesListApp.i18n.searchPlaceholder,
+ sortOptions: getSortOptions(true, true),
+ initialSortBy: CREATED_DESC,
+ issuables: getIssuesQueryResponse.data.project.issues.nodes,
+ tabs: IssuableListTabs,
+ currentTab: IssuableStates.Opened,
+ tabCounts: {
+ opened: 1,
+ closed: 1,
+ all: 1,
+ },
+ issuablesLoading: false,
+ isManualOrdering: false,
+ showBulkEditSidebar: false,
+ showPaginationControls: true,
+ useKeysetPagination: true,
+ hasPreviousPage: getIssuesQueryResponse.data.project.issues.pageInfo.hasPreviousPage,
+ hasNextPage: getIssuesQueryResponse.data.project.issues.pageInfo.hasNextPage,
+ urlParams: {
+ sort: urlSortParams[CREATED_DESC],
+ state: IssuableStates.Opened,
+ },
+ });
+ });
+ });
+
+ describe('header action buttons', () => {
+ it('renders rss button', () => {
+ wrapper = mountComponent({ mountFn: mount });
+
+ expect(findGlButtonAt(0).props('icon')).toBe('rss');
+ expect(findGlButtonAt(0).attributes()).toMatchObject({
+ href: defaultProvide.rssPath,
+ 'aria-label': IssuesListApp.i18n.rssLabel,
+ });
+ });
+
+ it('renders calendar button', () => {
+ wrapper = mountComponent({ mountFn: mount });
+
+ expect(findGlButtonAt(1).props('icon')).toBe('calendar');
+ expect(findGlButtonAt(1).attributes()).toMatchObject({
+ href: defaultProvide.calendarPath,
+ 'aria-label': IssuesListApp.i18n.calendarLabel,
+ });
+ });
+
+ describe('csv import/export component', () => {
+ describe('when user is signed in', () => {
+ const search = '?search=refactor&sort=created_date&state=opened';
+
+ beforeEach(() => {
+ setWindowLocation(search);
+
+ wrapper = mountComponent({ provide: { isSignedIn: true }, mountFn: mount });
+
+ jest.runOnlyPendingTimers();
+ });
+
+ it('renders', () => {
+ expect(findCsvImportExportButtons().props()).toMatchObject({
+ exportCsvPath: `${defaultProvide.exportCsvPath}${search}`,
+ issuableCount: 1,
+ });
+ });
+ });
+
+ describe('when user is not signed in', () => {
+ it('does not render', () => {
+ wrapper = mountComponent({ provide: { isSignedIn: false }, mountFn: mount });
+
+ expect(findCsvImportExportButtons().exists()).toBe(false);
+ });
+ });
+
+ describe('when in a group context', () => {
+ it('does not render', () => {
+ wrapper = mountComponent({ provide: { isProject: false }, mountFn: mount });
+
+ expect(findCsvImportExportButtons().exists()).toBe(false);
+ });
+ });
+ });
+
+ describe('bulk edit button', () => {
+ it('renders when user has permissions', () => {
+ wrapper = mountComponent({ provide: { canBulkUpdate: true }, mountFn: mount });
+
+ expect(findGlButtonAt(2).text()).toBe('Edit issues');
+ });
+
+ it('does not render when user does not have permissions', () => {
+ wrapper = mountComponent({ provide: { canBulkUpdate: false }, mountFn: mount });
+
+ expect(findGlButtons().filter((button) => button.text() === 'Edit issues')).toHaveLength(0);
+ });
+
+ it('emits "issuables:enableBulkEdit" event to legacy bulk edit class', async () => {
+ wrapper = mountComponent({ provide: { canBulkUpdate: true }, mountFn: mount });
+
+ jest.spyOn(eventHub, '$emit');
+
+ findGlButtonAt(2).vm.$emit('click');
+
+ await waitForPromises();
+
+ expect(eventHub.$emit).toHaveBeenCalledWith('issuables:enableBulkEdit');
+ });
+ });
+
+ describe('new issue button', () => {
+ it('renders when user has permissions', () => {
+ wrapper = mountComponent({ provide: { showNewIssueLink: true }, mountFn: mount });
+
+ expect(findGlButtonAt(2).text()).toBe('New issue');
+ expect(findGlButtonAt(2).attributes('href')).toBe(defaultProvide.newIssuePath);
+ });
+
+ it('does not render when user does not have permissions', () => {
+ wrapper = mountComponent({ provide: { showNewIssueLink: false }, mountFn: mount });
+
+ expect(findGlButtons().filter((button) => button.text() === 'New issue')).toHaveLength(0);
+ });
+ });
+
+ describe('new issue split dropdown', () => {
+ it('does not render in a project context', () => {
+ wrapper = mountComponent({ provide: { isProject: true }, mountFn: mount });
+
+ expect(findNewIssueDropdown().exists()).toBe(false);
+ });
+
+ it('renders in a group context', () => {
+ wrapper = mountComponent({ provide: { isProject: false }, mountFn: mount });
+
+ expect(findNewIssueDropdown().exists()).toBe(true);
+ });
+ });
+ });
+
+ describe('initial url params', () => {
+ describe('due_date', () => {
+ it('is set from the url params', () => {
+ setWindowLocation(`?${PARAM_DUE_DATE}=${DUE_DATE_OVERDUE}`);
+
+ wrapper = mountComponent();
+
+ expect(findIssuableList().props('urlParams')).toMatchObject({ due_date: DUE_DATE_OVERDUE });
+ });
+ });
+
+ describe('search', () => {
+ it('is set from the url params', () => {
+ setWindowLocation(locationSearch);
+
+ wrapper = mountComponent();
+
+ expect(findIssuableList().props('urlParams')).toMatchObject({ search: 'find issues' });
+ });
+ });
+
+ describe('sort', () => {
+ it.each(Object.keys(urlSortParams))('is set as %s from the url params', (sortKey) => {
+ setWindowLocation(`?sort=${urlSortParams[sortKey]}`);
+
+ wrapper = mountComponent();
+
+ expect(findIssuableList().props()).toMatchObject({
+ initialSortBy: sortKey,
+ urlParams: {
+ sort: urlSortParams[sortKey],
+ },
+ });
+ });
+
+ describe('when issue repositioning is disabled and the sort is manual', () => {
+ beforeEach(() => {
+ setWindowLocation(`?sort=${RELATIVE_POSITION}`);
+ wrapper = mountComponent({ provide: { isIssueRepositioningDisabled: true } });
+ });
+
+ it('changes the sort to the default of created descending', () => {
+ expect(findIssuableList().props()).toMatchObject({
+ initialSortBy: CREATED_DESC,
+ urlParams: {
+ sort: urlSortParams[CREATED_DESC],
+ },
+ });
+ });
+
+ it('shows an alert to tell the user that manual reordering is disabled', () => {
+ expect(createFlash).toHaveBeenCalledWith({
+ message: IssuesListApp.i18n.issueRepositioningMessage,
+ type: FLASH_TYPES.NOTICE,
+ });
+ });
+ });
+ });
+
+ describe('state', () => {
+ it('is set from the url params', () => {
+ const initialState = IssuableStates.All;
+
+ setWindowLocation(`?state=${initialState}`);
+
+ wrapper = mountComponent();
+
+ expect(findIssuableList().props('currentTab')).toBe(initialState);
+ });
+ });
+
+ describe('filter tokens', () => {
+ it('is set from the url params', () => {
+ setWindowLocation(locationSearch);
+
+ wrapper = mountComponent();
+
+ expect(findIssuableList().props('initialFilterValue')).toEqual(filteredTokens);
+ });
+
+ describe('when anonymous searching is performed', () => {
+ beforeEach(() => {
+ setWindowLocation(locationSearch);
+
+ wrapper = mountComponent({
+ provide: { isAnonymousSearchDisabled: true, isSignedIn: false },
+ });
+ });
+
+ it('is not set from url params', () => {
+ expect(findIssuableList().props('initialFilterValue')).toEqual([]);
+ });
+
+ it('shows an alert to tell the user they must be signed in to search', () => {
+ expect(createFlash).toHaveBeenCalledWith({
+ message: IssuesListApp.i18n.anonymousSearchingMessage,
+ type: FLASH_TYPES.NOTICE,
+ });
+ });
+ });
+ });
+ });
+
+ describe('bulk edit', () => {
+ describe.each([true, false])(
+ 'when "issuables:toggleBulkEdit" event is received with payload `%s`',
+ (isBulkEdit) => {
+ beforeEach(() => {
+ wrapper = mountComponent();
+
+ eventHub.$emit('issuables:toggleBulkEdit', isBulkEdit);
+ });
+
+ it(`${isBulkEdit ? 'enables' : 'disables'} bulk edit`, () => {
+ expect(findIssuableList().props('showBulkEditSidebar')).toBe(isBulkEdit);
+ });
+ },
+ );
+ });
+
+ describe('IssuableByEmail component', () => {
+ describe.each([true, false])(`when issue creation by email is enabled=%s`, (enabled) => {
+ it(`${enabled ? 'renders' : 'does not render'}`, () => {
+ wrapper = mountComponent({ provide: { initialEmail: enabled } });
+
+ expect(findIssuableByEmail().exists()).toBe(enabled);
+ });
+ });
+ });
+
+ describe('empty states', () => {
+ describe('when there are issues', () => {
+ describe('when search returns no results', () => {
+ beforeEach(() => {
+ setWindowLocation(`?search=no+results`);
+
+ wrapper = mountComponent({ provide: { hasAnyIssues: true }, mountFn: mount });
+ });
+
+ it('shows empty state', () => {
+ expect(findGlEmptyState().props()).toMatchObject({
+ description: IssuesListApp.i18n.noSearchResultsDescription,
+ title: IssuesListApp.i18n.noSearchResultsTitle,
+ svgPath: defaultProvide.emptyStateSvgPath,
+ });
+ });
+ });
+
+ describe('when "Open" tab has no issues', () => {
+ beforeEach(() => {
+ wrapper = mountComponent({ provide: { hasAnyIssues: true }, mountFn: mount });
+ });
+
+ it('shows empty state', () => {
+ expect(findGlEmptyState().props()).toMatchObject({
+ description: IssuesListApp.i18n.noOpenIssuesDescription,
+ title: IssuesListApp.i18n.noOpenIssuesTitle,
+ svgPath: defaultProvide.emptyStateSvgPath,
+ });
+ });
+ });
+
+ describe('when "Closed" tab has no issues', () => {
+ beforeEach(() => {
+ setWindowLocation(`?state=${IssuableStates.Closed}`);
+
+ wrapper = mountComponent({ provide: { hasAnyIssues: true }, mountFn: mount });
+ });
+
+ it('shows empty state', () => {
+ expect(findGlEmptyState().props()).toMatchObject({
+ title: IssuesListApp.i18n.noClosedIssuesTitle,
+ svgPath: defaultProvide.emptyStateSvgPath,
+ });
+ });
+ });
+ });
+
+ describe('when there are no issues', () => {
+ describe('when user is logged in', () => {
+ beforeEach(() => {
+ wrapper = mountComponent({
+ provide: { hasAnyIssues: false, isSignedIn: true },
+ mountFn: mount,
+ });
+ });
+
+ it('shows empty state', () => {
+ expect(findGlEmptyState().props()).toMatchObject({
+ description: IssuesListApp.i18n.noIssuesSignedInDescription,
+ title: IssuesListApp.i18n.noIssuesSignedInTitle,
+ svgPath: defaultProvide.emptyStateSvgPath,
+ });
+ });
+
+ it('shows "New issue" and import/export buttons', () => {
+ expect(findGlButton().text()).toBe(IssuesListApp.i18n.newIssueLabel);
+ expect(findGlButton().attributes('href')).toBe(defaultProvide.newIssuePath);
+ expect(findCsvImportExportButtons().props()).toMatchObject({
+ exportCsvPath: defaultProvide.exportCsvPath,
+ issuableCount: 0,
+ });
+ });
+
+ it('shows Jira integration information', () => {
+ const paragraphs = wrapper.findAll('p');
+ expect(paragraphs.at(1).text()).toContain(IssuesListApp.i18n.jiraIntegrationTitle);
+ expect(paragraphs.at(2).text()).toContain(
+ 'Enable the Jira integration to view your Jira issues in GitLab.',
+ );
+ expect(paragraphs.at(3).text()).toContain(
+ IssuesListApp.i18n.jiraIntegrationSecondaryMessage,
+ );
+ expect(findGlLink().text()).toBe('Enable the Jira integration');
+ expect(findGlLink().attributes('href')).toBe(defaultProvide.jiraIntegrationPath);
+ });
+ });
+
+ describe('when user is logged out', () => {
+ beforeEach(() => {
+ wrapper = mountComponent({
+ provide: { hasAnyIssues: false, isSignedIn: false },
+ });
+ });
+
+ it('shows empty state', () => {
+ expect(findGlEmptyState().props()).toMatchObject({
+ description: IssuesListApp.i18n.noIssuesSignedOutDescription,
+ title: IssuesListApp.i18n.noIssuesSignedOutTitle,
+ svgPath: defaultProvide.emptyStateSvgPath,
+ primaryButtonText: IssuesListApp.i18n.noIssuesSignedOutButtonText,
+ primaryButtonLink: defaultProvide.signInPath,
+ });
+ });
+ });
+ });
+ });
+
+ describe('tokens', () => {
+ const mockCurrentUser = {
+ id: 1,
+ name: 'Administrator',
+ username: 'root',
+ avatar_url: 'avatar/url',
+ };
+
+ describe('when user is signed out', () => {
+ beforeEach(() => {
+ wrapper = mountComponent({ provide: { isSignedIn: false } });
+ });
+
+ it('does not render My-Reaction or Confidential tokens', () => {
+ expect(findIssuableList().props('searchTokens')).not.toMatchObject([
+ { type: TOKEN_TYPE_AUTHOR, preloadedAuthors: [mockCurrentUser] },
+ { type: TOKEN_TYPE_ASSIGNEE, preloadedAuthors: [mockCurrentUser] },
+ { type: TOKEN_TYPE_MY_REACTION },
+ { type: TOKEN_TYPE_CONFIDENTIAL },
+ ]);
+ });
+ });
+
+ describe('when all tokens are available', () => {
+ const originalGon = window.gon;
+
+ beforeEach(() => {
+ window.gon = {
+ ...originalGon,
+ current_user_id: mockCurrentUser.id,
+ current_user_fullname: mockCurrentUser.name,
+ current_username: mockCurrentUser.username,
+ current_user_avatar_url: mockCurrentUser.avatar_url,
+ };
+
+ wrapper = mountComponent({ provide: { isSignedIn: true } });
+ });
+
+ afterEach(() => {
+ window.gon = originalGon;
+ });
+
+ it('renders all tokens alphabetically', () => {
+ const preloadedAuthors = [
+ { ...mockCurrentUser, id: convertToGraphQLId('User', mockCurrentUser.id) },
+ ];
+
+ expect(findIssuableList().props('searchTokens')).toMatchObject([
+ { type: TOKEN_TYPE_ASSIGNEE, preloadedAuthors },
+ { type: TOKEN_TYPE_AUTHOR, preloadedAuthors },
+ { type: TOKEN_TYPE_CONFIDENTIAL },
+ { type: TOKEN_TYPE_LABEL },
+ { type: TOKEN_TYPE_MILESTONE },
+ { type: TOKEN_TYPE_MY_REACTION },
+ { type: TOKEN_TYPE_RELEASE },
+ { type: TOKEN_TYPE_TYPE },
+ ]);
+ });
+ });
+ });
+
+ describe('errors', () => {
+ describe.each`
+ error | mountOption | message
+ ${'fetching issues'} | ${'issuesQueryResponse'} | ${IssuesListApp.i18n.errorFetchingIssues}
+ ${'fetching issue counts'} | ${'issuesCountsQueryResponse'} | ${IssuesListApp.i18n.errorFetchingCounts}
+ `('when there is an error $error', ({ mountOption, message }) => {
+ beforeEach(() => {
+ wrapper = mountComponent({
+ [mountOption]: jest.fn().mockRejectedValue(new Error('ERROR')),
+ });
+ jest.runOnlyPendingTimers();
+ });
+
+ it('shows an error message', () => {
+ expect(findIssuableList().props('error')).toBe(message);
+ expect(Sentry.captureException).toHaveBeenCalledWith(new Error('Network error: ERROR'));
+ });
+ });
+
+ it('clears error message when "dismiss-alert" event is emitted from IssuableList', () => {
+ wrapper = mountComponent({ issuesQueryResponse: jest.fn().mockRejectedValue(new Error()) });
+
+ findIssuableList().vm.$emit('dismiss-alert');
+
+ expect(findIssuableList().props('error')).toBeNull();
+ });
+ });
+
+ describe('events', () => {
+ describe('when "click-tab" event is emitted by IssuableList', () => {
+ beforeEach(() => {
+ wrapper = mountComponent();
+
+ findIssuableList().vm.$emit('click-tab', IssuableStates.Closed);
+ });
+
+ it('updates to the new tab', () => {
+ expect(findIssuableList().props('currentTab')).toBe(IssuableStates.Closed);
+ });
+ });
+
+ describe.each(['next-page', 'previous-page'])(
+ 'when "%s" event is emitted by IssuableList',
+ (event) => {
+ beforeEach(() => {
+ wrapper = mountComponent();
+
+ findIssuableList().vm.$emit(event);
+ });
+
+ it('scrolls to the top', () => {
+ expect(scrollUp).toHaveBeenCalled();
+ });
+ },
+ );
+
+ describe('when "reorder" event is emitted by IssuableList', () => {
+ const issueOne = {
+ ...defaultQueryResponse.data.project.issues.nodes[0],
+ id: 'gid://gitlab/Issue/1',
+ iid: '101',
+ reference: 'group/project#1',
+ webPath: '/group/project/-/issues/1',
+ };
+ const issueTwo = {
+ ...defaultQueryResponse.data.project.issues.nodes[0],
+ id: 'gid://gitlab/Issue/2',
+ iid: '102',
+ reference: 'group/project#2',
+ webPath: '/group/project/-/issues/2',
+ };
+ const issueThree = {
+ ...defaultQueryResponse.data.project.issues.nodes[0],
+ id: 'gid://gitlab/Issue/3',
+ iid: '103',
+ reference: 'group/project#3',
+ webPath: '/group/project/-/issues/3',
+ };
+ const issueFour = {
+ ...defaultQueryResponse.data.project.issues.nodes[0],
+ id: 'gid://gitlab/Issue/4',
+ iid: '104',
+ reference: 'group/project#4',
+ webPath: '/group/project/-/issues/4',
+ };
+ const response = (isProject = true) => ({
+ data: {
+ [isProject ? 'project' : 'group']: {
+ id: '1',
+ issues: {
+ ...defaultQueryResponse.data.project.issues,
+ nodes: [issueOne, issueTwo, issueThree, issueFour],
+ },
+ },
+ },
+ });
+
+ describe('when successful', () => {
+ describe.each([true, false])('when isProject=%s', (isProject) => {
+ describe.each`
+ description | issueToMove | oldIndex | newIndex | moveBeforeId | moveAfterId
+ ${'to the beginning of the list'} | ${issueThree} | ${2} | ${0} | ${null} | ${issueOne.id}
+ ${'down the list'} | ${issueOne} | ${0} | ${1} | ${issueTwo.id} | ${issueThree.id}
+ ${'up the list'} | ${issueThree} | ${2} | ${1} | ${issueOne.id} | ${issueTwo.id}
+ ${'to the end of the list'} | ${issueTwo} | ${1} | ${3} | ${issueFour.id} | ${null}
+ `(
+ 'when moving issue $description',
+ ({ issueToMove, oldIndex, newIndex, moveBeforeId, moveAfterId }) => {
+ beforeEach(() => {
+ wrapper = mountComponent({
+ provide: { isProject },
+ issuesQueryResponse: jest.fn().mockResolvedValue(response(isProject)),
+ });
+ jest.runOnlyPendingTimers();
+ });
+
+ it('makes API call to reorder the issue', async () => {
+ findIssuableList().vm.$emit('reorder', { oldIndex, newIndex });
+
+ await waitForPromises();
+
+ expect(axiosMock.history.put[0]).toMatchObject({
+ url: joinPaths(issueToMove.webPath, 'reorder'),
+ data: JSON.stringify({
+ move_before_id: getIdFromGraphQLId(moveBeforeId),
+ move_after_id: getIdFromGraphQLId(moveAfterId),
+ group_full_path: isProject ? undefined : defaultProvide.fullPath,
+ }),
+ });
+ });
+ },
+ );
+ });
+ });
+
+ describe('when unsuccessful', () => {
+ beforeEach(() => {
+ wrapper = mountComponent({
+ issuesQueryResponse: jest.fn().mockResolvedValue(response()),
+ });
+ jest.runOnlyPendingTimers();
+ });
+
+ it('displays an error message', async () => {
+ axiosMock.onPut(joinPaths(issueOne.webPath, 'reorder')).reply(500);
+
+ findIssuableList().vm.$emit('reorder', { oldIndex: 0, newIndex: 1 });
+
+ await waitForPromises();
+
+ expect(findIssuableList().props('error')).toBe(IssuesListApp.i18n.reorderError);
+ expect(Sentry.captureException).toHaveBeenCalledWith(
+ new Error('Request failed with status code 500'),
+ );
+ });
+ });
+ });
+
+ describe('when "sort" event is emitted by IssuableList', () => {
+ it.each(Object.keys(urlSortParams))(
+ 'updates to the new sort when payload is `%s`',
+ async (sortKey) => {
+ wrapper = mountComponent();
+
+ findIssuableList().vm.$emit('sort', sortKey);
+
+ jest.runOnlyPendingTimers();
+ await nextTick();
+
+ expect(findIssuableList().props('urlParams')).toMatchObject({
+ sort: urlSortParams[sortKey],
+ });
+ },
+ );
+
+ describe('when issue repositioning is disabled', () => {
+ const initialSort = CREATED_DESC;
+
+ beforeEach(() => {
+ setWindowLocation(`?sort=${initialSort}`);
+ wrapper = mountComponent({ provide: { isIssueRepositioningDisabled: true } });
+
+ findIssuableList().vm.$emit('sort', RELATIVE_POSITION_ASC);
+ });
+
+ it('does not update the sort to manual', () => {
+ expect(findIssuableList().props('urlParams')).toMatchObject({
+ sort: urlSortParams[initialSort],
+ });
+ });
+
+ it('shows an alert to tell the user that manual reordering is disabled', () => {
+ expect(createFlash).toHaveBeenCalledWith({
+ message: IssuesListApp.i18n.issueRepositioningMessage,
+ type: FLASH_TYPES.NOTICE,
+ });
+ });
+ });
+ });
+
+ describe('when "update-legacy-bulk-edit" event is emitted by IssuableList', () => {
+ beforeEach(() => {
+ wrapper = mountComponent();
+ jest.spyOn(eventHub, '$emit');
+
+ findIssuableList().vm.$emit('update-legacy-bulk-edit');
+ });
+
+ it('emits an "issuables:updateBulkEdit" event to the legacy bulk edit class', () => {
+ expect(eventHub.$emit).toHaveBeenCalledWith('issuables:updateBulkEdit');
+ });
+ });
+
+ describe('when "filter" event is emitted by IssuableList', () => {
+ it('updates IssuableList with url params', async () => {
+ wrapper = mountComponent();
+
+ findIssuableList().vm.$emit('filter', filteredTokens);
+ await nextTick();
+
+ expect(findIssuableList().props('urlParams')).toMatchObject(urlParams);
+ });
+
+ describe('when anonymous searching is performed', () => {
+ beforeEach(() => {
+ wrapper = mountComponent({
+ provide: { isAnonymousSearchDisabled: true, isSignedIn: false },
+ });
+
+ findIssuableList().vm.$emit('filter', filteredTokens);
+ });
+
+ it('does not update IssuableList with url params ', async () => {
+ const defaultParams = { sort: 'created_date', state: 'opened' };
+
+ expect(findIssuableList().props('urlParams')).toEqual(defaultParams);
+ });
+
+ it('shows an alert to tell the user they must be signed in to search', () => {
+ expect(createFlash).toHaveBeenCalledWith({
+ message: IssuesListApp.i18n.anonymousSearchingMessage,
+ type: FLASH_TYPES.NOTICE,
+ });
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/issues/list/components/jira_issues_import_status_app_spec.js b/spec/frontend/issues/list/components/jira_issues_import_status_app_spec.js
new file mode 100644
index 00000000000..d6d6bb14e9d
--- /dev/null
+++ b/spec/frontend/issues/list/components/jira_issues_import_status_app_spec.js
@@ -0,0 +1,117 @@
+import { GlAlert, GlLabel } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
+import JiraIssuesImportStatus from '~/issues/list/components/jira_issues_import_status_app.vue';
+
+describe('JiraIssuesImportStatus', () => {
+ const issuesPath = 'gitlab-org/gitlab-test/-/issues';
+ const label = {
+ color: '#333',
+ title: 'jira-import::MTG-3',
+ };
+ let wrapper;
+
+ const findAlert = () => wrapper.find(GlAlert);
+
+ const findAlertLabel = () => wrapper.find(GlAlert).find(GlLabel);
+
+ const mountComponent = ({
+ shouldShowFinishedAlert = false,
+ shouldShowInProgressAlert = false,
+ } = {}) =>
+ shallowMount(JiraIssuesImportStatus, {
+ propsData: {
+ canEdit: true,
+ isJiraConfigured: true,
+ issuesPath,
+ projectPath: 'gitlab-org/gitlab-test',
+ },
+ data() {
+ return {
+ jiraImport: {
+ importedIssuesCount: 1,
+ label,
+ shouldShowFinishedAlert,
+ shouldShowInProgressAlert,
+ },
+ };
+ },
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('when Jira import is neither in progress nor finished', () => {
+ beforeEach(() => {
+ wrapper = mountComponent();
+ });
+
+ it('does not show an alert', () => {
+ expect(wrapper.find(GlAlert).exists()).toBe(false);
+ });
+ });
+
+ describe('when Jira import is in progress', () => {
+ it('shows an alert that tells the user a Jira import is in progress', () => {
+ wrapper = mountComponent({
+ shouldShowInProgressAlert: true,
+ });
+
+ expect(findAlert().text()).toBe(
+ 'Import in progress. Refresh page to see newly added issues.',
+ );
+ });
+ });
+
+ describe('when Jira import has finished', () => {
+ beforeEach(() => {
+ wrapper = mountComponent({
+ shouldShowFinishedAlert: true,
+ });
+ });
+
+ describe('shows an alert', () => {
+ it('tells the user the Jira import has finished', () => {
+ expect(findAlert().text()).toBe('1 issue successfully imported with the label');
+ });
+
+ it('contains the label title associated with the Jira import', () => {
+ const alertLabelTitle = findAlertLabel().props('title');
+
+ expect(alertLabelTitle).toBe(label.title);
+ });
+
+ it('contains the correct label color', () => {
+ const alertLabelTitle = findAlertLabel().props('backgroundColor');
+
+ expect(alertLabelTitle).toBe(label.color);
+ });
+
+ it('contains a link within the label', () => {
+ const alertLabelTarget = findAlertLabel().props('target');
+
+ expect(alertLabelTarget).toBe(
+ `${issuesPath}?label_name[]=${encodeURIComponent(label.title)}`,
+ );
+ });
+ });
+ });
+
+ describe('alert message', () => {
+ it('is hidden when dismissed', () => {
+ wrapper = mountComponent({
+ shouldShowInProgressAlert: true,
+ });
+
+ expect(wrapper.find(GlAlert).exists()).toBe(true);
+
+ findAlert().vm.$emit('dismiss');
+
+ return Vue.nextTick(() => {
+ expect(wrapper.find(GlAlert).exists()).toBe(false);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/issues/list/components/new_issue_dropdown_spec.js b/spec/frontend/issues/list/components/new_issue_dropdown_spec.js
new file mode 100644
index 00000000000..0c52e66ff14
--- /dev/null
+++ b/spec/frontend/issues/list/components/new_issue_dropdown_spec.js
@@ -0,0 +1,131 @@
+import { GlDropdown, GlDropdownItem, GlSearchBoxByType } from '@gitlab/ui';
+import { createLocalVue, mount, shallowMount } from '@vue/test-utils';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import NewIssueDropdown from '~/issues/list/components/new_issue_dropdown.vue';
+import searchProjectsQuery from '~/issues/list/queries/search_projects.query.graphql';
+import { DASH_SCOPE, joinPaths } from '~/lib/utils/url_utility';
+import {
+ emptySearchProjectsQueryResponse,
+ project1,
+ project3,
+ searchProjectsQueryResponse,
+} from '../mock_data';
+
+describe('NewIssueDropdown component', () => {
+ let wrapper;
+
+ const localVue = createLocalVue();
+ localVue.use(VueApollo);
+
+ const mountComponent = ({
+ search = '',
+ queryResponse = searchProjectsQueryResponse,
+ mountFn = shallowMount,
+ } = {}) => {
+ const requestHandlers = [[searchProjectsQuery, jest.fn().mockResolvedValue(queryResponse)]];
+ const apolloProvider = createMockApollo(requestHandlers);
+
+ return mountFn(NewIssueDropdown, {
+ localVue,
+ apolloProvider,
+ provide: {
+ fullPath: 'mushroom-kingdom',
+ },
+ data() {
+ return { search };
+ },
+ });
+ };
+
+ const findDropdown = () => wrapper.findComponent(GlDropdown);
+ const findInput = () => wrapper.findComponent(GlSearchBoxByType);
+ const showDropdown = async () => {
+ findDropdown().vm.$emit('shown');
+ await wrapper.vm.$apollo.queries.projects.refetch();
+ jest.runOnlyPendingTimers();
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders a split dropdown', () => {
+ wrapper = mountComponent();
+
+ expect(findDropdown().props('split')).toBe(true);
+ });
+
+ it('renders a label for the dropdown toggle button', () => {
+ wrapper = mountComponent();
+
+ expect(findDropdown().attributes('toggle-text')).toBe(NewIssueDropdown.i18n.toggleButtonLabel);
+ });
+
+ it('focuses on input when dropdown is shown', async () => {
+ wrapper = mountComponent({ mountFn: mount });
+
+ const inputSpy = jest.spyOn(findInput().vm, 'focusInput');
+
+ await showDropdown();
+
+ expect(inputSpy).toHaveBeenCalledTimes(1);
+ });
+
+ it('renders projects with issues enabled', async () => {
+ wrapper = mountComponent({ mountFn: mount });
+
+ await showDropdown();
+
+ const listItems = wrapper.findAll('li');
+
+ expect(listItems.at(0).text()).toBe(project1.nameWithNamespace);
+ expect(listItems.at(1).text()).toBe(project3.nameWithNamespace);
+ });
+
+ it('renders `No matches found` when there are no matches', async () => {
+ wrapper = mountComponent({
+ search: 'no matches',
+ queryResponse: emptySearchProjectsQueryResponse,
+ mountFn: mount,
+ });
+
+ await showDropdown();
+
+ expect(wrapper.find('li').text()).toBe(NewIssueDropdown.i18n.noMatchesFound);
+ });
+
+ describe('when no project is selected', () => {
+ beforeEach(() => {
+ wrapper = mountComponent();
+ });
+
+ it('dropdown button is not a link', () => {
+ expect(findDropdown().attributes('split-href')).toBeUndefined();
+ });
+
+ it('displays default text on the dropdown button', () => {
+ expect(findDropdown().props('text')).toBe(NewIssueDropdown.i18n.defaultDropdownText);
+ });
+ });
+
+ describe('when a project is selected', () => {
+ beforeEach(async () => {
+ wrapper = mountComponent({ mountFn: mount });
+
+ await showDropdown();
+
+ wrapper.findComponent(GlDropdownItem).vm.$emit('click', project1);
+ });
+
+ it('dropdown button is a link', () => {
+ const href = joinPaths(project1.webUrl, DASH_SCOPE, 'issues/new');
+
+ expect(findDropdown().attributes('split-href')).toBe(href);
+ });
+
+ it('displays project name on the dropdown button', () => {
+ expect(findDropdown().props('text')).toBe(`New issue in ${project1.name}`);
+ });
+ });
+});
diff --git a/spec/frontend/issues_list/mock_data.js b/spec/frontend/issues/list/mock_data.js
index 948699876ce..948699876ce 100644
--- a/spec/frontend/issues_list/mock_data.js
+++ b/spec/frontend/issues/list/mock_data.js
diff --git a/spec/frontend/issues/list/utils_spec.js b/spec/frontend/issues/list/utils_spec.js
new file mode 100644
index 00000000000..0e4979fd7b4
--- /dev/null
+++ b/spec/frontend/issues/list/utils_spec.js
@@ -0,0 +1,127 @@
+import {
+ apiParams,
+ apiParamsWithSpecialValues,
+ filteredTokens,
+ filteredTokensWithSpecialValues,
+ locationSearch,
+ locationSearchWithSpecialValues,
+ urlParams,
+ urlParamsWithSpecialValues,
+} from 'jest/issues/list/mock_data';
+import {
+ defaultPageSizeParams,
+ DUE_DATE_VALUES,
+ largePageSizeParams,
+ RELATIVE_POSITION_ASC,
+ urlSortParams,
+} from '~/issues/list/constants';
+import {
+ convertToApiParams,
+ convertToSearchQuery,
+ convertToUrlParams,
+ getDueDateValue,
+ getFilterTokens,
+ getInitialPageParams,
+ getSortKey,
+ getSortOptions,
+} from '~/issues/list/utils';
+
+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;
+
+ expect(getInitialPageParams(sortKey)).toBe(expectedPageParams);
+ },
+ );
+});
+
+describe('getSortKey', () => {
+ it.each(Object.keys(urlSortParams))('returns %s given the correct inputs', (sortKey) => {
+ const sort = urlSortParams[sortKey];
+ expect(getSortKey(sort)).toBe(sortKey);
+ });
+});
+
+describe('getDueDateValue', () => {
+ it.each(DUE_DATE_VALUES)('returns the argument when it is `%s`', (value) => {
+ expect(getDueDateValue(value)).toBe(value);
+ });
+
+ it('returns undefined when the argument is invalid', () => {
+ expect(getDueDateValue('invalid value')).toBeUndefined();
+ });
+});
+
+describe('getSortOptions', () => {
+ describe.each`
+ hasIssueWeightsFeature | hasBlockedIssuesFeature | length | containsWeight | containsBlocking
+ ${false} | ${false} | ${9} | ${false} | ${false}
+ ${true} | ${false} | ${10} | ${true} | ${false}
+ ${false} | ${true} | ${10} | ${false} | ${true}
+ ${true} | ${true} | ${11} | ${true} | ${true}
+ `(
+ 'when hasIssueWeightsFeature=$hasIssueWeightsFeature and hasBlockedIssuesFeature=$hasBlockedIssuesFeature',
+ ({
+ hasIssueWeightsFeature,
+ hasBlockedIssuesFeature,
+ length,
+ containsWeight,
+ containsBlocking,
+ }) => {
+ const sortOptions = getSortOptions(hasIssueWeightsFeature, hasBlockedIssuesFeature);
+
+ it('returns the correct length of sort options', () => {
+ expect(sortOptions).toHaveLength(length);
+ });
+
+ it(`${containsWeight ? 'contains' : 'does not contain'} weight option`, () => {
+ expect(sortOptions.some((option) => option.title === 'Weight')).toBe(containsWeight);
+ });
+
+ it(`${containsBlocking ? 'contains' : 'does not contain'} blocking option`, () => {
+ expect(sortOptions.some((option) => option.title === 'Blocking')).toBe(containsBlocking);
+ });
+ },
+ );
+});
+
+describe('getFilterTokens', () => {
+ it('returns filtered tokens given "window.location.search"', () => {
+ expect(getFilterTokens(locationSearch)).toEqual(filteredTokens);
+ });
+
+ it('returns filtered tokens given "window.location.search" with special values', () => {
+ expect(getFilterTokens(locationSearchWithSpecialValues)).toEqual(
+ filteredTokensWithSpecialValues,
+ );
+ });
+});
+
+describe('convertToApiParams', () => {
+ it('returns api params given filtered tokens', () => {
+ expect(convertToApiParams(filteredTokens)).toEqual(apiParams);
+ });
+
+ it('returns api params given filtered tokens with special values', () => {
+ expect(convertToApiParams(filteredTokensWithSpecialValues)).toEqual(apiParamsWithSpecialValues);
+ });
+});
+
+describe('convertToUrlParams', () => {
+ it('returns url params given filtered tokens', () => {
+ expect(convertToUrlParams(filteredTokens)).toEqual(urlParams);
+ });
+
+ it('returns url params given filtered tokens with special values', () => {
+ expect(convertToUrlParams(filteredTokensWithSpecialValues)).toEqual(urlParamsWithSpecialValues);
+ });
+});
+
+describe('convertToSearchQuery', () => {
+ it('returns search string given filtered tokens', () => {
+ expect(convertToSearchQuery(filteredTokens)).toBe('find issues');
+ });
+});
diff --git a/spec/frontend/issues/new/components/title_suggestions_spec.js b/spec/frontend/issues/new/components/title_suggestions_spec.js
index 984d0c9d25b..f6b93cc5a62 100644
--- a/spec/frontend/issues/new/components/title_suggestions_spec.js
+++ b/spec/frontend/issues/new/components/title_suggestions_spec.js
@@ -38,6 +38,8 @@ describe('Issue title suggestions component', () => {
});
it('renders component', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData(data);
return wrapper.vm.$nextTick(() => {
@@ -47,6 +49,8 @@ describe('Issue title suggestions component', () => {
it('does not render with empty search', () => {
wrapper.setProps({ search: '' });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData(data);
return wrapper.vm.$nextTick(() => {
@@ -55,6 +59,8 @@ describe('Issue title suggestions component', () => {
});
it('does not render when loading', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
...data,
loading: 1,
@@ -66,6 +72,8 @@ describe('Issue title suggestions component', () => {
});
it('does not render with empty issues data', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ issues: [] });
return wrapper.vm.$nextTick(() => {
@@ -74,6 +82,8 @@ describe('Issue title suggestions component', () => {
});
it('renders list of issues', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData(data);
return wrapper.vm.$nextTick(() => {
@@ -82,6 +92,8 @@ describe('Issue title suggestions component', () => {
});
it('adds margin class to first item', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData(data);
return wrapper.vm.$nextTick(() => {
@@ -90,6 +102,8 @@ describe('Issue title suggestions component', () => {
});
it('does not add margin class to last item', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData(data);
return wrapper.vm.$nextTick(() => {
diff --git a/spec/frontend/issues/sentry_error_stack_trace/components/sentry_error_stack_trace_spec.js b/spec/frontend/issues/sentry_error_stack_trace/components/sentry_error_stack_trace_spec.js
deleted file mode 100644
index 5a51ae3cfe0..00000000000
--- a/spec/frontend/issues/sentry_error_stack_trace/components/sentry_error_stack_trace_spec.js
+++ /dev/null
@@ -1,82 +0,0 @@
-import { GlLoadingIcon } from '@gitlab/ui';
-import { createLocalVue, shallowMount } from '@vue/test-utils';
-import Vuex from 'vuex';
-import Stacktrace from '~/error_tracking/components/stacktrace.vue';
-import SentryErrorStackTrace from '~/issues/sentry_error_stack_trace/components/sentry_error_stack_trace.vue';
-
-const localVue = createLocalVue();
-localVue.use(Vuex);
-
-describe('Sentry Error Stack Trace', () => {
- let actions;
- let getters;
- let store;
- let wrapper;
-
- function mountComponent({
- stubs = {
- stacktrace: Stacktrace,
- },
- } = {}) {
- wrapper = shallowMount(SentryErrorStackTrace, {
- localVue,
- stubs,
- store,
- propsData: {
- issueStackTracePath: '/stacktrace',
- },
- });
- }
-
- beforeEach(() => {
- actions = {
- startPollingStacktrace: () => {},
- };
-
- getters = {
- stacktrace: () => [{ context: [1, 2], lineNo: 53, filename: 'index.js' }],
- };
-
- const state = {
- stacktraceData: {},
- loadingStacktrace: true,
- };
-
- store = new Vuex.Store({
- modules: {
- details: {
- namespaced: true,
- actions,
- getters,
- state,
- },
- },
- });
- });
-
- afterEach(() => {
- if (wrapper) {
- wrapper.destroy();
- }
- });
-
- describe('loading', () => {
- it('should show spinner while loading', () => {
- mountComponent();
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
- expect(wrapper.find(Stacktrace).exists()).toBe(false);
- });
- });
-
- describe('Stack trace', () => {
- beforeEach(() => {
- store.state.details.loadingStacktrace = false;
- });
-
- it('should show stacktrace', () => {
- mountComponent({ stubs: {} });
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
- expect(wrapper.find(Stacktrace).exists()).toBe(true);
- });
- });
-});
diff --git a/spec/frontend/issues/show/components/fields/type_spec.js b/spec/frontend/issues/show/components/fields/type_spec.js
index 3ece10e70db..7f7b16583e6 100644
--- a/spec/frontend/issues/show/components/fields/type_spec.js
+++ b/spec/frontend/issues/show/components/fields/type_spec.js
@@ -4,7 +4,7 @@ import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import IssueTypeField, { i18n } from '~/issues/show/components/fields/type.vue';
-import { IssuableTypes } from '~/issues/show/constants';
+import { issuableTypes } from '~/issues/show/constants';
import {
getIssueStateQueryResponse,
updateIssueStateQueryResponse,
@@ -69,8 +69,8 @@ describe('Issue type field component', () => {
it.each`
at | text | icon
- ${0} | ${IssuableTypes[0].text} | ${IssuableTypes[0].icon}
- ${1} | ${IssuableTypes[1].text} | ${IssuableTypes[1].icon}
+ ${0} | ${issuableTypes[0].text} | ${issuableTypes[0].icon}
+ ${1} | ${issuableTypes[1].text} | ${issuableTypes[1].icon}
`(`renders the issue type $text with an icon in the dropdown`, ({ at, text, icon }) => {
expect(findTypeFromDropDownItemIconAt(at).attributes('name')).toBe(icon);
expect(findTypeFromDropDownItemAt(at).text()).toBe(text);
@@ -81,20 +81,20 @@ describe('Issue type field component', () => {
});
it('renders a form select with the `issue_type` value', () => {
- expect(findTypeFromDropDown().attributes('value')).toBe(IssuableTypes.issue);
+ expect(findTypeFromDropDown().attributes('value')).toBe(issuableTypes.issue);
});
describe('with Apollo cache mock', () => {
it('renders the selected issueType', async () => {
mockIssueStateData.mockResolvedValue(getIssueStateQueryResponse);
await waitForPromises();
- expect(findTypeFromDropDown().attributes('value')).toBe(IssuableTypes.issue);
+ expect(findTypeFromDropDown().attributes('value')).toBe(issuableTypes.issue);
});
it('updates the `issue_type` in the apollo cache when the value is changed', async () => {
- findTypeFromDropDownItems().at(1).vm.$emit('click', IssuableTypes.incident);
+ findTypeFromDropDownItems().at(1).vm.$emit('click', issuableTypes.incident);
await wrapper.vm.$nextTick();
- expect(findTypeFromDropDown().attributes('value')).toBe(IssuableTypes.incident);
+ expect(findTypeFromDropDown().attributes('value')).toBe(issuableTypes.incident);
});
describe('when user is a guest', () => {
@@ -104,7 +104,7 @@ describe('Issue type field component', () => {
expect(findTypeFromDropDownItemAt(0).isVisible()).toBe(true);
expect(findTypeFromDropDownItemAt(1).isVisible()).toBe(false);
- expect(findTypeFromDropDown().attributes('value')).toBe(IssuableTypes.issue);
+ expect(findTypeFromDropDown().attributes('value')).toBe(issuableTypes.issue);
});
it('and incident is selected, includes incident in the dropdown', async () => {
@@ -113,7 +113,7 @@ describe('Issue type field component', () => {
expect(findTypeFromDropDownItemAt(0).isVisible()).toBe(true);
expect(findTypeFromDropDownItemAt(1).isVisible()).toBe(true);
- expect(findTypeFromDropDown().attributes('value')).toBe(IssuableTypes.incident);
+ expect(findTypeFromDropDown().attributes('value')).toBe(issuableTypes.incident);
});
});
});
diff --git a/spec/frontend/issues/show/components/header_actions_spec.js b/spec/frontend/issues/show/components/header_actions_spec.js
index 2a16c699c4d..d09bf6faa13 100644
--- a/spec/frontend/issues/show/components/header_actions_spec.js
+++ b/spec/frontend/issues/show/components/header_actions_spec.js
@@ -4,11 +4,10 @@ import { shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import { mockTracking } from 'helpers/tracking_helper';
import createFlash, { FLASH_TYPES } from '~/flash';
-import { IssuableType } from '~/vue_shared/issuable/show/constants';
+import { IssuableStatus, IssueType } from '~/issues/constants';
import DeleteIssueModal from '~/issues/show/components/delete_issue_modal.vue';
import HeaderActions from '~/issues/show/components/header_actions.vue';
-import { IssuableStatus } from '~/issues/constants';
-import { IssueStateEvent } from '~/issues/show/constants';
+import { ISSUE_STATE_EVENT_CLOSE, ISSUE_STATE_EVENT_REOPEN } from '~/issues/show/constants';
import promoteToEpicMutation from '~/issues/show/queries/promote_to_epic.mutation.graphql';
import * as urlUtility from '~/lib/utils/url_utility';
import eventHub from '~/notes/event_hub';
@@ -36,7 +35,7 @@ describe('HeaderActions component', () => {
iid: '32',
isIssueAuthor: true,
issuePath: 'gitlab-org/gitlab-test/-/issues/1',
- issueType: IssuableType.Issue,
+ issueType: IssueType.Issue,
newIssuePath: 'gitlab-org/gitlab-test/-/issues/new',
projectPath: 'gitlab-org/gitlab-test',
reportAbusePath:
@@ -112,14 +111,14 @@ describe('HeaderActions component', () => {
describe.each`
issueType
- ${IssuableType.Issue}
- ${IssuableType.Incident}
+ ${IssueType.Issue}
+ ${IssueType.Incident}
`('when issue type is $issueType', ({ issueType }) => {
describe('close/reopen button', () => {
describe.each`
description | issueState | buttonText | newIssueState
- ${`when the ${issueType} is open`} | ${IssuableStatus.Open} | ${`Close ${issueType}`} | ${IssueStateEvent.Close}
- ${`when the ${issueType} is closed`} | ${IssuableStatus.Closed} | ${`Reopen ${issueType}`} | ${IssueStateEvent.Reopen}
+ ${`when the ${issueType} is open`} | ${IssuableStatus.Open} | ${`Close ${issueType}`} | ${ISSUE_STATE_EVENT_CLOSE}
+ ${`when the ${issueType} is closed`} | ${IssuableStatus.Closed} | ${`Reopen ${issueType}`} | ${ISSUE_STATE_EVENT_REOPEN}
`('$description', ({ issueState, buttonText, newIssueState }) => {
beforeEach(() => {
dispatchEventSpy = jest.spyOn(document, 'dispatchEvent');
@@ -306,7 +305,7 @@ describe('HeaderActions component', () => {
input: {
iid: defaultProps.iid,
projectPath: defaultProps.projectPath,
- stateEvent: IssueStateEvent.Close,
+ stateEvent: ISSUE_STATE_EVENT_CLOSE,
},
},
}),
@@ -345,7 +344,7 @@ describe('HeaderActions component', () => {
input: {
iid: defaultProps.iid.toString(),
projectPath: defaultProps.projectPath,
- stateEvent: IssueStateEvent.Close,
+ stateEvent: ISSUE_STATE_EVENT_CLOSE,
},
},
}),
diff --git a/spec/frontend/issues/show/components/sentry_error_stack_trace_spec.js b/spec/frontend/issues/show/components/sentry_error_stack_trace_spec.js
new file mode 100644
index 00000000000..b38d2b60057
--- /dev/null
+++ b/spec/frontend/issues/show/components/sentry_error_stack_trace_spec.js
@@ -0,0 +1,81 @@
+import Vue from 'vue';
+import { GlLoadingIcon } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import Vuex from 'vuex';
+import Stacktrace from '~/error_tracking/components/stacktrace.vue';
+import SentryErrorStackTrace from '~/issues/show/components/sentry_error_stack_trace.vue';
+
+describe('Sentry Error Stack Trace', () => {
+ let actions;
+ let getters;
+ let store;
+ let wrapper;
+
+ Vue.use(Vuex);
+
+ function mountComponent({
+ stubs = {
+ stacktrace: Stacktrace,
+ },
+ } = {}) {
+ wrapper = shallowMount(SentryErrorStackTrace, {
+ stubs,
+ store,
+ propsData: {
+ issueStackTracePath: '/stacktrace',
+ },
+ });
+ }
+
+ beforeEach(() => {
+ actions = {
+ startPollingStacktrace: () => {},
+ };
+
+ getters = {
+ stacktrace: () => [{ context: [1, 2], lineNo: 53, filename: 'index.js' }],
+ };
+
+ const state = {
+ stacktraceData: {},
+ loadingStacktrace: true,
+ };
+
+ store = new Vuex.Store({
+ modules: {
+ details: {
+ namespaced: true,
+ actions,
+ getters,
+ state,
+ },
+ },
+ });
+ });
+
+ afterEach(() => {
+ if (wrapper) {
+ wrapper.destroy();
+ }
+ });
+
+ describe('loading', () => {
+ it('should show spinner while loading', () => {
+ mountComponent();
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
+ expect(wrapper.find(Stacktrace).exists()).toBe(false);
+ });
+ });
+
+ describe('Stack trace', () => {
+ beforeEach(() => {
+ store.state.details.loadingStacktrace = false;
+ });
+
+ it('should show stacktrace', () => {
+ mountComponent({ stubs: {} });
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
+ expect(wrapper.find(Stacktrace).exists()).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/issues/show/issue_spec.js b/spec/frontend/issues/show/issue_spec.js
index 6d7a31a6c8c..68c2e3768c7 100644
--- a/spec/frontend/issues/show/issue_spec.js
+++ b/spec/frontend/issues/show/issue_spec.js
@@ -1,6 +1,6 @@
import MockAdapter from 'axios-mock-adapter';
import waitForPromises from 'helpers/wait_for_promises';
-import { initIssuableApp } from '~/issues/show/issue';
+import { initIssueApp } from '~/issues/show';
import * as parseData from '~/issues/show/utils/parse_data';
import axios from '~/lib/utils/axios_utils';
import createStore from '~/notes/stores';
@@ -17,7 +17,7 @@ const setupHTML = (initialData) => {
};
describe('Issue show index', () => {
- describe('initIssuableApp', () => {
+ describe('initIssueApp', () => {
it('should initialize app with no potential XSS attack', async () => {
const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => {});
const parseDataSpy = jest.spyOn(parseData, 'parseIssuableData');
@@ -29,7 +29,7 @@ describe('Issue show index', () => {
const initialDataEl = document.getElementById('js-issuable-app');
const issuableData = parseData.parseIssuableData(initialDataEl);
- initIssuableApp(issuableData, createStore());
+ initIssueApp(issuableData, createStore());
await waitForPromises();
diff --git a/spec/frontend/issues_list/components/__snapshots__/issuables_list_app_spec.js.snap b/spec/frontend/issues_list/components/__snapshots__/issuables_list_app_spec.js.snap
deleted file mode 100644
index c327b7de827..00000000000
--- a/spec/frontend/issues_list/components/__snapshots__/issuables_list_app_spec.js.snap
+++ /dev/null
@@ -1,14 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Issuables list component with empty issues response with all state should display a catch-all if there are no issues to show 1`] = `
-<gl-empty-state-stub
- svgpath="/emptySvg"
- title="There are no issues to show"
-/>
-`;
-
-exports[`Issuables list component with empty issues response with closed state should display a message "There are no closed issues" if there are no closed issues 1`] = `"There are no closed issues"`;
-
-exports[`Issuables list component with empty issues response with empty query should display the message "There are no open issues" 1`] = `"There are no open issues"`;
-
-exports[`Issuables list component with empty issues response with query in window location should display "Sorry, your filter produced no results" if filters are too specific 1`] = `"Sorry, your filter produced no results"`;
diff --git a/spec/frontend/issues_list/components/issuable_spec.js b/spec/frontend/issues_list/components/issuable_spec.js
deleted file mode 100644
index f3c2ae1f9dc..00000000000
--- a/spec/frontend/issues_list/components/issuable_spec.js
+++ /dev/null
@@ -1,508 +0,0 @@
-import { GlSprintf, GlLabel, GlIcon, GlLink } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import { TEST_HOST } from 'helpers/test_constants';
-import { trimText } from 'helpers/text_helper';
-import Issuable from '~/issues_list/components/issuable.vue';
-import { isScopedLabel } from '~/lib/utils/common_utils';
-import { formatDate } from '~/lib/utils/datetime_utility';
-import { mergeUrlParams } from '~/lib/utils/url_utility';
-import initUserPopovers from '~/user_popovers';
-import IssueAssignees from '~/issuable/components/issue_assignees.vue';
-import { simpleIssue, testAssignees, testLabels } from '../issuable_list_test_data';
-
-jest.mock('~/user_popovers');
-
-const TODAY = new Date();
-
-const createTestDateFromDelta = (timeDelta) =>
- formatDate(new Date(TODAY.getTime() + timeDelta), 'yyyy-mm-dd');
-
-// TODO: Encapsulate date helpers https://gitlab.com/gitlab-org/gitlab/-/issues/320883
-const MONTHS_IN_MS = 1000 * 60 * 60 * 24 * 31;
-const TEST_MONTH_AGO = createTestDateFromDelta(-MONTHS_IN_MS);
-const TEST_MONTH_LATER = createTestDateFromDelta(MONTHS_IN_MS);
-const DATE_FORMAT = 'mmm d, yyyy';
-const TEST_USER_NAME = 'Tyler Durden';
-const TEST_BASE_URL = `${TEST_HOST}/issues`;
-const TEST_TASK_STATUS = '50 of 100 tasks completed';
-const TEST_MILESTONE = {
- title: 'Milestone title',
- web_url: `${TEST_HOST}/milestone/1`,
-};
-const TEXT_CLOSED = 'CLOSED';
-const TEST_META_COUNT = 100;
-const MOCK_GITLAB_URL = 'http://0.0.0.0:3000';
-
-describe('Issuable component', () => {
- let issuable;
- let wrapper;
-
- const factory = (props = {}, scopedLabelsAvailable = false) => {
- wrapper = shallowMount(Issuable, {
- propsData: {
- issuable: simpleIssue,
- baseUrl: TEST_BASE_URL,
- ...props,
- },
- provide: {
- scopedLabelsAvailable,
- },
- stubs: {
- 'gl-sprintf': GlSprintf,
- },
- });
- };
-
- beforeEach(() => {
- issuable = { ...simpleIssue };
- gon.gitlab_url = MOCK_GITLAB_URL;
- });
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- const checkExists = (findFn) => () => findFn().exists();
- const hasIcon = (iconName, iconWrapper = wrapper) =>
- iconWrapper.findAll(GlIcon).wrappers.some((icon) => icon.props('name') === iconName);
- const hasConfidentialIcon = () => hasIcon('eye-slash');
- const findTaskStatus = () => wrapper.find('.task-status');
- const findOpenedAgoContainer = () => wrapper.find('[data-testid="openedByMessage"]');
- const findAuthor = () => wrapper.find({ ref: 'openedAgoByContainer' });
- const findMilestone = () => wrapper.find('.js-milestone');
- const findMilestoneTooltip = () => findMilestone().attributes('title');
- const findDueDate = () => wrapper.find('.js-due-date');
- const findLabels = () => wrapper.findAll(GlLabel);
- const findWeight = () => wrapper.find('[data-testid="weight"]');
- const findAssignees = () => wrapper.find(IssueAssignees);
- const findBlockingIssuesCount = () => wrapper.find('[data-testid="blocking-issues"]');
- const findMergeRequestsCount = () => wrapper.find('[data-testid="merge-requests"]');
- const findUpvotes = () => wrapper.find('[data-testid="upvotes"]');
- const findDownvotes = () => wrapper.find('[data-testid="downvotes"]');
- const findNotes = () => wrapper.find('[data-testid="notes-count"]');
- const findBulkCheckbox = () => wrapper.find('input.selected-issuable');
- const findScopedLabels = () => findLabels().filter((w) => isScopedLabel({ title: w.text() }));
- const findUnscopedLabels = () => findLabels().filter((w) => !isScopedLabel({ title: w.text() }));
- const findIssuableTitle = () => wrapper.find('[data-testid="issuable-title"]');
- const findIssuableStatus = () => wrapper.find('[data-testid="issuable-status"]');
- const containsJiraLogo = () => wrapper.find('[data-testid="jira-logo"]').exists();
- const findHealthStatus = () => wrapper.find('.health-status');
-
- describe('when mounted', () => {
- it('initializes user popovers', () => {
- expect(initUserPopovers).not.toHaveBeenCalled();
-
- factory();
-
- expect(initUserPopovers).toHaveBeenCalledWith([wrapper.vm.$refs.openedAgoByContainer.$el]);
- });
- });
-
- describe('when scopedLabels feature is available', () => {
- beforeEach(() => {
- issuable.labels = [...testLabels];
-
- factory({ issuable }, true);
- });
-
- describe('when label is scoped', () => {
- it('returns label with correct props', () => {
- const scopedLabel = findScopedLabels().at(0);
-
- expect(scopedLabel.props('scoped')).toBe(true);
- });
- });
-
- describe('when label is not scoped', () => {
- it('returns label with correct props', () => {
- const notScopedLabel = findUnscopedLabels().at(0);
-
- expect(notScopedLabel.props('scoped')).toBe(false);
- });
- });
- });
-
- describe('when scopedLabels feature is not available', () => {
- beforeEach(() => {
- issuable.labels = [...testLabels];
-
- factory({ issuable });
- });
-
- describe('when label is scoped', () => {
- it('label scoped props is false', () => {
- const scopedLabel = findScopedLabels().at(0);
-
- expect(scopedLabel.props('scoped')).toBe(false);
- });
- });
-
- describe('when label is not scoped', () => {
- it('label scoped props is false', () => {
- const notScopedLabel = findUnscopedLabels().at(0);
-
- expect(notScopedLabel.props('scoped')).toBe(false);
- });
- });
- });
-
- describe('with simple issuable', () => {
- beforeEach(() => {
- Object.assign(issuable, {
- has_tasks: false,
- task_status: TEST_TASK_STATUS,
- created_at: TEST_MONTH_AGO,
- author: {
- ...issuable.author,
- name: TEST_USER_NAME,
- },
- labels: [],
- });
-
- factory({ issuable });
- });
-
- it.each`
- desc | check
- ${'bulk editing checkbox'} | ${checkExists(findBulkCheckbox)}
- ${'confidential icon'} | ${hasConfidentialIcon}
- ${'task status'} | ${checkExists(findTaskStatus)}
- ${'milestone'} | ${checkExists(findMilestone)}
- ${'due date'} | ${checkExists(findDueDate)}
- ${'labels'} | ${checkExists(findLabels)}
- ${'weight'} | ${checkExists(findWeight)}
- ${'blocking issues count'} | ${checkExists(findBlockingIssuesCount)}
- ${'merge request count'} | ${checkExists(findMergeRequestsCount)}
- ${'upvotes'} | ${checkExists(findUpvotes)}
- ${'downvotes'} | ${checkExists(findDownvotes)}
- `('does not render $desc', ({ check }) => {
- expect(check()).toBe(false);
- });
-
- it('show relative reference path', () => {
- expect(wrapper.find('.js-ref-path').text()).toBe(issuable.references.relative);
- });
-
- it('does not have closed text', () => {
- expect(wrapper.text()).not.toContain(TEXT_CLOSED);
- });
-
- it('does not have closed class', () => {
- expect(wrapper.classes('closed')).toBe(false);
- });
-
- it('renders fuzzy created date and author', () => {
- expect(trimText(findOpenedAgoContainer().text())).toContain(
- `created 1 month ago by ${TEST_USER_NAME}`,
- );
- });
-
- it('renders no comments', () => {
- expect(findNotes().classes('no-comments')).toBe(true);
- });
-
- it.each`
- gitlabWebUrl | webUrl | expectedHref | expectedTarget | isExternal
- ${undefined} | ${`${MOCK_GITLAB_URL}/issue`} | ${`${MOCK_GITLAB_URL}/issue`} | ${undefined} | ${false}
- ${undefined} | ${'https://jira.com/issue'} | ${'https://jira.com/issue'} | ${'_blank'} | ${true}
- ${'/gitlab-org/issue'} | ${'https://jira.com/issue'} | ${'/gitlab-org/issue'} | ${undefined} | ${false}
- `(
- 'renders issuable title correctly when `gitlabWebUrl` is `$gitlabWebUrl` and webUrl is `$webUrl`',
- async ({ webUrl, gitlabWebUrl, expectedHref, expectedTarget, isExternal }) => {
- factory({
- issuable: {
- ...issuable,
- web_url: webUrl,
- gitlab_web_url: gitlabWebUrl,
- },
- });
-
- const titleEl = findIssuableTitle();
-
- expect(titleEl.exists()).toBe(true);
- expect(titleEl.find(GlLink).attributes('href')).toBe(expectedHref);
- expect(titleEl.find(GlLink).attributes('target')).toBe(expectedTarget);
- expect(titleEl.find(GlLink).text()).toBe(issuable.title);
-
- expect(titleEl.find(GlIcon).exists()).toBe(isExternal);
- },
- );
- });
-
- describe('with confidential issuable', () => {
- beforeEach(() => {
- issuable.confidential = true;
-
- factory({ issuable });
- });
-
- it('renders the confidential icon', () => {
- expect(hasConfidentialIcon()).toBe(true);
- });
- });
-
- describe('with Jira issuable', () => {
- beforeEach(() => {
- issuable.external_tracker = 'jira';
-
- factory({ issuable });
- });
-
- it('renders the Jira icon', () => {
- expect(containsJiraLogo()).toBe(true);
- });
-
- it('opens issuable in a new tab', () => {
- expect(findIssuableTitle().props('target')).toBe('_blank');
- });
-
- it('opens author in a new tab', () => {
- expect(findAuthor().props('target')).toBe('_blank');
- });
-
- describe('with Jira status', () => {
- const expectedStatus = 'In Progress';
-
- beforeEach(() => {
- issuable.status = expectedStatus;
-
- factory({ issuable });
- });
-
- it('renders the Jira status', () => {
- expect(findIssuableStatus().text()).toBe(expectedStatus);
- });
- });
- });
-
- describe('with task status', () => {
- beforeEach(() => {
- Object.assign(issuable, {
- has_tasks: true,
- task_status: TEST_TASK_STATUS,
- });
-
- factory({ issuable });
- });
-
- it('renders task status', () => {
- expect(findTaskStatus().exists()).toBe(true);
- expect(findTaskStatus().text()).toBe(TEST_TASK_STATUS);
- });
- });
-
- describe.each`
- desc | dueDate | expectedTooltipPart
- ${'past due'} | ${TEST_MONTH_AGO} | ${'Past due'}
- ${'future due'} | ${TEST_MONTH_LATER} | ${'1 month remaining'}
- `('with milestone with $desc', ({ dueDate, expectedTooltipPart }) => {
- beforeEach(() => {
- issuable.milestone = { ...TEST_MILESTONE, due_date: dueDate };
-
- factory({ issuable });
- });
-
- it('renders milestone', () => {
- expect(findMilestone().exists()).toBe(true);
- expect(hasIcon('clock', findMilestone())).toBe(true);
- expect(findMilestone().text()).toEqual(TEST_MILESTONE.title);
- });
-
- it('renders tooltip', () => {
- expect(findMilestoneTooltip()).toBe(
- `${formatDate(dueDate, DATE_FORMAT)} (${expectedTooltipPart})`,
- );
- });
-
- it('renders milestone with the correct href', () => {
- const { title } = issuable.milestone;
- const expected = mergeUrlParams({ milestone_title: title }, TEST_BASE_URL);
-
- expect(findMilestone().attributes('href')).toBe(expected);
- });
- });
-
- describe.each`
- dueDate | hasClass | desc
- ${TEST_MONTH_LATER} | ${false} | ${'with future due date'}
- ${TEST_MONTH_AGO} | ${true} | ${'with past due date'}
- `('$desc', ({ dueDate, hasClass }) => {
- beforeEach(() => {
- issuable.due_date = dueDate;
-
- factory({ issuable });
- });
-
- it('renders due date', () => {
- expect(findDueDate().exists()).toBe(true);
- expect(findDueDate().text()).toBe(formatDate(dueDate, DATE_FORMAT));
- });
-
- it(hasClass ? 'has cred class' : 'does not have cred class', () => {
- expect(findDueDate().classes('cred')).toEqual(hasClass);
- });
- });
-
- describe('with labels', () => {
- beforeEach(() => {
- issuable.labels = [...testLabels];
-
- factory({ issuable });
- });
-
- it('renders labels', () => {
- factory({ issuable });
-
- const labels = findLabels().wrappers.map((label) => ({
- href: label.props('target'),
- text: label.text(),
- tooltip: label.attributes('description'),
- }));
-
- const expected = testLabels.map((label) => ({
- href: mergeUrlParams({ 'label_name[]': label.name }, TEST_BASE_URL),
- text: label.name,
- tooltip: label.description,
- }));
-
- expect(labels).toEqual(expected);
- });
- });
-
- describe('with labels for Jira issuable', () => {
- beforeEach(() => {
- issuable.labels = [...testLabels];
- issuable.external_tracker = 'jira';
-
- factory({ issuable });
- });
-
- it('renders labels', () => {
- factory({ issuable });
-
- const labels = findLabels().wrappers.map((label) => ({
- href: label.props('target'),
- text: label.text(),
- tooltip: label.attributes('description'),
- }));
-
- const expected = testLabels.map((label) => ({
- href: mergeUrlParams({ 'labels[]': label.name }, TEST_BASE_URL),
- text: label.name,
- tooltip: label.description,
- }));
-
- expect(labels).toEqual(expected);
- });
- });
-
- describe.each`
- weight
- ${0}
- ${10}
- ${12345}
- `('with weight $weight', ({ weight }) => {
- beforeEach(() => {
- issuable.weight = weight;
-
- factory({ issuable });
- });
-
- it('renders weight', () => {
- expect(findWeight().exists()).toBe(true);
- expect(findWeight().text()).toEqual(weight.toString());
- });
- });
-
- describe('with closed state', () => {
- beforeEach(() => {
- issuable.state = 'closed';
-
- factory({ issuable });
- });
-
- it('renders closed text', () => {
- expect(wrapper.text()).toContain(TEXT_CLOSED);
- });
-
- it('has closed class', () => {
- expect(wrapper.classes('closed')).toBe(true);
- });
- });
-
- describe('with assignees', () => {
- beforeEach(() => {
- issuable.assignees = testAssignees;
-
- factory({ issuable });
- });
-
- it('renders assignees', () => {
- expect(findAssignees().exists()).toBe(true);
- expect(findAssignees().props('assignees')).toEqual(testAssignees);
- });
- });
-
- describe.each`
- desc | key | finder
- ${'with blocking issues count'} | ${'blocking_issues_count'} | ${findBlockingIssuesCount}
- ${'with merge requests count'} | ${'merge_requests_count'} | ${findMergeRequestsCount}
- ${'with upvote count'} | ${'upvotes'} | ${findUpvotes}
- ${'with downvote count'} | ${'downvotes'} | ${findDownvotes}
- ${'with notes count'} | ${'user_notes_count'} | ${findNotes}
- `('$desc', ({ key, finder }) => {
- beforeEach(() => {
- issuable[key] = TEST_META_COUNT;
-
- factory({ issuable });
- });
-
- it('renders correct count', () => {
- expect(finder().exists()).toBe(true);
- expect(finder().text()).toBe(TEST_META_COUNT.toString());
- expect(finder().classes('no-comments')).toBe(false);
- });
- });
-
- describe('with bulk editing', () => {
- describe.each`
- selected | desc
- ${true} | ${'when selected'}
- ${false} | ${'when unselected'}
- `('$desc', ({ selected }) => {
- beforeEach(() => {
- factory({ isBulkEditing: true, selected });
- });
-
- it(`renders checked is ${selected}`, () => {
- expect(findBulkCheckbox().element.checked).toBe(selected);
- });
-
- it('emits select when clicked', () => {
- expect(wrapper.emitted().select).toBeUndefined();
-
- findBulkCheckbox().trigger('click');
-
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted().select).toEqual([[{ issuable, selected: !selected }]]);
- });
- });
- });
- });
-
- if (IS_EE) {
- describe('with health status', () => {
- it('renders health status tag', () => {
- factory({ issuable });
- expect(findHealthStatus().exists()).toBe(true);
- });
-
- it('does not render when health status is absent', () => {
- issuable.health_status = null;
- factory({ issuable });
- expect(findHealthStatus().exists()).toBe(false);
- });
- });
- }
-});
diff --git a/spec/frontend/issues_list/components/issuables_list_app_spec.js b/spec/frontend/issues_list/components/issuables_list_app_spec.js
deleted file mode 100644
index 11854db534e..00000000000
--- a/spec/frontend/issues_list/components/issuables_list_app_spec.js
+++ /dev/null
@@ -1,653 +0,0 @@
-import {
- GlEmptyState,
- GlPagination,
- GlDeprecatedSkeletonLoading as GlSkeletonLoading,
-} from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import axios from 'axios';
-import MockAdapter from 'axios-mock-adapter';
-import setWindowLocation from 'helpers/set_window_location_helper';
-import { TEST_HOST } from 'helpers/test_constants';
-import waitForPromises from 'helpers/wait_for_promises';
-import createFlash from '~/flash';
-import Issuable from '~/issues_list/components/issuable.vue';
-import IssuablesListApp from '~/issues_list/components/issuables_list_app.vue';
-import { PAGE_SIZE, PAGE_SIZE_MANUAL, RELATIVE_POSITION } from '~/issues_list/constants';
-import issuablesEventBus from '~/issues_list/eventhub';
-import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
-
-jest.mock('~/flash');
-jest.mock('~/issues_list/eventhub');
-jest.mock('~/lib/utils/common_utils', () => ({
- ...jest.requireActual('~/lib/utils/common_utils'),
- scrollToElement: () => {},
-}));
-
-const TEST_LOCATION = `${TEST_HOST}/issues`;
-const TEST_ENDPOINT = '/issues';
-const TEST_CREATE_ISSUES_PATH = '/createIssue';
-const TEST_SVG_PATH = '/emptySvg';
-
-const MOCK_ISSUES = Array(PAGE_SIZE_MANUAL)
- .fill(0)
- .map((_, i) => ({
- id: i,
- web_url: `url${i}`,
- }));
-
-describe('Issuables list component', () => {
- let mockAxios;
- let wrapper;
- let apiSpy;
-
- const setupApiMock = (cb) => {
- apiSpy = jest.fn(cb);
-
- mockAxios.onGet(TEST_ENDPOINT).reply((cfg) => apiSpy(cfg));
- };
-
- const factory = (props = { sortKey: 'priority' }) => {
- const emptyStateMeta = {
- createIssuePath: TEST_CREATE_ISSUES_PATH,
- svgPath: TEST_SVG_PATH,
- };
-
- wrapper = shallowMount(IssuablesListApp, {
- propsData: {
- endpoint: TEST_ENDPOINT,
- emptyStateMeta,
- ...props,
- },
- });
- };
-
- const findLoading = () => wrapper.find(GlSkeletonLoading);
- const findIssuables = () => wrapper.findAll(Issuable);
- const findFilteredSearchBar = () => wrapper.find(FilteredSearchBar);
- const findFirstIssuable = () => findIssuables().wrappers[0];
- const findEmptyState = () => wrapper.find(GlEmptyState);
-
- beforeEach(() => {
- mockAxios = new MockAdapter(axios);
-
- setWindowLocation(TEST_LOCATION);
- });
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- mockAxios.restore();
- });
-
- describe('with failed issues response', () => {
- beforeEach(() => {
- setupApiMock(() => [500]);
-
- factory();
-
- return waitForPromises();
- });
-
- it('does not show loading', () => {
- expect(wrapper.vm.loading).toBe(false);
- });
-
- it('flashes an error', () => {
- expect(createFlash).toHaveBeenCalledTimes(1);
- });
- });
-
- describe('with successful issues response', () => {
- beforeEach(() => {
- setupApiMock(() => [
- 200,
- MOCK_ISSUES.slice(0, PAGE_SIZE),
- {
- 'x-total': 100,
- 'x-page': 2,
- },
- ]);
- });
-
- it('has default props and data', () => {
- factory();
- expect(wrapper.vm).toMatchObject({
- // Props
- canBulkEdit: false,
- emptyStateMeta: {
- createIssuePath: TEST_CREATE_ISSUES_PATH,
- svgPath: TEST_SVG_PATH,
- },
- // Data
- filters: {
- state: 'opened',
- },
- isBulkEditing: false,
- issuables: [],
- loading: true,
- page: 1,
- selection: {},
- totalItems: 0,
- });
- });
-
- it('does not call API until mounted', () => {
- factory();
- expect(apiSpy).not.toHaveBeenCalled();
- });
-
- describe('when mounted', () => {
- beforeEach(() => {
- factory();
- });
-
- it('calls API', () => {
- expect(apiSpy).toHaveBeenCalled();
- });
-
- it('shows loading', () => {
- expect(findLoading().exists()).toBe(true);
- expect(findIssuables().length).toBe(0);
- expect(findEmptyState().exists()).toBe(false);
- });
- });
-
- describe('when finished loading', () => {
- beforeEach(() => {
- factory();
-
- return waitForPromises();
- });
-
- it('does not display empty state', () => {
- expect(wrapper.vm.issuables.length).toBeGreaterThan(0);
- expect(wrapper.vm.emptyState).toEqual({});
- expect(wrapper.find(GlEmptyState).exists()).toBe(false);
- });
-
- it('sets the proper page and total items', () => {
- expect(wrapper.vm.totalItems).toBe(100);
- expect(wrapper.vm.page).toBe(2);
- });
-
- it('renders one page of issuables and pagination', () => {
- expect(findIssuables().length).toBe(PAGE_SIZE);
- expect(wrapper.find(GlPagination).exists()).toBe(true);
- });
- });
-
- it('does not render FilteredSearchBar', () => {
- factory();
-
- expect(findFilteredSearchBar().exists()).toBe(false);
- });
- });
-
- describe('with bulk editing enabled', () => {
- beforeEach(() => {
- issuablesEventBus.$on.mockReset();
- issuablesEventBus.$emit.mockReset();
-
- setupApiMock(() => [200, MOCK_ISSUES.slice(0)]);
- factory({ canBulkEdit: true });
-
- return waitForPromises();
- });
-
- it('is not enabled by default', () => {
- expect(wrapper.vm.isBulkEditing).toBe(false);
- });
-
- it('does not select issues by default', () => {
- expect(wrapper.vm.selection).toEqual({});
- });
-
- it('"Select All" checkbox toggles all visible issuables"', () => {
- wrapper.vm.onSelectAll();
- expect(wrapper.vm.selection).toEqual(
- wrapper.vm.issuables.reduce((acc, i) => ({ ...acc, [i.id]: true }), {}),
- );
-
- wrapper.vm.onSelectAll();
- expect(wrapper.vm.selection).toEqual({});
- });
-
- it('"Select All checkbox" selects all issuables if only some are selected"', () => {
- wrapper.vm.selection = { [wrapper.vm.issuables[0].id]: true };
- wrapper.vm.onSelectAll();
- expect(wrapper.vm.selection).toEqual(
- wrapper.vm.issuables.reduce((acc, i) => ({ ...acc, [i.id]: true }), {}),
- );
- });
-
- it('selects and deselects issuables', () => {
- const [i0, i1, i2] = wrapper.vm.issuables;
-
- expect(wrapper.vm.selection).toEqual({});
- wrapper.vm.onSelectIssuable({ issuable: i0, selected: false });
- expect(wrapper.vm.selection).toEqual({});
- wrapper.vm.onSelectIssuable({ issuable: i1, selected: true });
- expect(wrapper.vm.selection).toEqual({ 1: true });
- wrapper.vm.onSelectIssuable({ issuable: i0, selected: true });
- expect(wrapper.vm.selection).toEqual({ 1: true, 0: true });
- wrapper.vm.onSelectIssuable({ issuable: i2, selected: true });
- expect(wrapper.vm.selection).toEqual({ 1: true, 0: true, 2: true });
- wrapper.vm.onSelectIssuable({ issuable: i2, selected: true });
- expect(wrapper.vm.selection).toEqual({ 1: true, 0: true, 2: true });
- wrapper.vm.onSelectIssuable({ issuable: i0, selected: false });
- expect(wrapper.vm.selection).toEqual({ 1: true, 2: true });
- });
-
- it('broadcasts a message to the bulk edit sidebar when a value is added to selection', () => {
- issuablesEventBus.$emit.mockReset();
- const i1 = wrapper.vm.issuables[1];
-
- wrapper.vm.onSelectIssuable({ issuable: i1, selected: true });
-
- return wrapper.vm.$nextTick().then(() => {
- expect(issuablesEventBus.$emit).toHaveBeenCalledTimes(1);
- expect(issuablesEventBus.$emit).toHaveBeenCalledWith('issuables:updateBulkEdit');
- });
- });
-
- it('does not broadcast a message to the bulk edit sidebar when a value is not added to selection', () => {
- issuablesEventBus.$emit.mockReset();
-
- return wrapper.vm
- .$nextTick()
- .then(waitForPromises)
- .then(() => {
- const i1 = wrapper.vm.issuables[1];
-
- wrapper.vm.onSelectIssuable({ issuable: i1, selected: false });
- })
- .then(wrapper.vm.$nextTick)
- .then(() => {
- expect(issuablesEventBus.$emit).toHaveBeenCalledTimes(0);
- });
- });
-
- it('listens to a message to toggle bulk editing', () => {
- expect(wrapper.vm.isBulkEditing).toBe(false);
- expect(issuablesEventBus.$on.mock.calls[0][0]).toBe('issuables:toggleBulkEdit');
- issuablesEventBus.$on.mock.calls[0][1](true); // Call the message handler
-
- return waitForPromises()
- .then(() => {
- expect(wrapper.vm.isBulkEditing).toBe(true);
- issuablesEventBus.$on.mock.calls[0][1](false);
- })
- .then(() => {
- expect(wrapper.vm.isBulkEditing).toBe(false);
- });
- });
- });
-
- describe('with query params in window.location', () => {
- const expectedFilters = {
- assignee_username: 'root',
- author_username: 'root',
- confidential: 'yes',
- my_reaction_emoji: 'airplane',
- scope: 'all',
- state: 'opened',
- weight: '0',
- milestone: 'v3.0',
- labels: 'Aquapod,Astro',
- order_by: 'milestone_due',
- sort: 'desc',
- };
-
- describe('when page is not present in params', () => {
- const query =
- '?assignee_username=root&author_username=root&confidential=yes&label_name%5B%5D=Aquapod&label_name%5B%5D=Astro&milestone_title=v3.0&my_reaction_emoji=airplane&scope=all&sort=priority&state=opened&weight=0&not[label_name][]=Afterpod&not[milestone_title][]=13';
-
- beforeEach(() => {
- setWindowLocation(query);
-
- setupApiMock(() => [200, MOCK_ISSUES.slice(0)]);
- factory({ sortKey: 'milestone_due_desc' });
-
- return waitForPromises();
- });
-
- afterEach(() => {
- apiSpy.mockClear();
- });
-
- it('applies filters and sorts', () => {
- expect(wrapper.vm.hasFilters).toBe(true);
- expect(wrapper.vm.filters).toEqual({
- ...expectedFilters,
- 'not[milestone]': ['13'],
- 'not[labels]': ['Afterpod'],
- });
-
- expect(apiSpy).toHaveBeenCalledWith(
- expect.objectContaining({
- params: {
- ...expectedFilters,
- with_labels_details: true,
- page: 1,
- per_page: PAGE_SIZE,
- 'not[milestone]': ['13'],
- 'not[labels]': ['Afterpod'],
- },
- }),
- );
- });
-
- it('passes the base url to issuable', () => {
- expect(findFirstIssuable().props('baseUrl')).toBe(TEST_LOCATION);
- });
- });
-
- describe('when page is present in the param', () => {
- const query =
- '?assignee_username=root&author_username=root&confidential=yes&label_name%5B%5D=Aquapod&label_name%5B%5D=Astro&milestone_title=v3.0&my_reaction_emoji=airplane&scope=all&sort=priority&state=opened&weight=0&page=3';
-
- beforeEach(() => {
- setWindowLocation(query);
-
- setupApiMock(() => [200, MOCK_ISSUES.slice(0)]);
- factory({ sortKey: 'milestone_due_desc' });
-
- return waitForPromises();
- });
-
- afterEach(() => {
- apiSpy.mockClear();
- });
-
- it('applies filters and sorts', () => {
- expect(apiSpy).toHaveBeenCalledWith(
- expect.objectContaining({
- params: {
- ...expectedFilters,
- with_labels_details: true,
- page: 3,
- per_page: PAGE_SIZE,
- },
- }),
- );
- });
- });
- });
-
- describe('with hash in window.location', () => {
- beforeEach(() => {
- setWindowLocation(`${TEST_LOCATION}#stuff`);
- setupApiMock(() => [200, MOCK_ISSUES.slice(0)]);
- factory();
- return waitForPromises();
- });
-
- it('passes the base url to issuable', () => {
- expect(findFirstIssuable().props('baseUrl')).toBe(TEST_LOCATION);
- });
- });
-
- describe('with manual sort', () => {
- beforeEach(() => {
- setupApiMock(() => [200, MOCK_ISSUES.slice(0)]);
- factory({ sortKey: RELATIVE_POSITION });
- });
-
- it('uses manual page size', () => {
- expect(apiSpy).toHaveBeenCalledWith(
- expect.objectContaining({
- params: expect.objectContaining({
- per_page: PAGE_SIZE_MANUAL,
- }),
- }),
- );
- });
- });
-
- describe('with empty issues response', () => {
- beforeEach(() => {
- setupApiMock(() => [200, []]);
- });
-
- describe('with query in window location', () => {
- beforeEach(() => {
- setWindowLocation('?weight=Any');
-
- factory();
-
- return waitForPromises().then(() => wrapper.vm.$nextTick());
- });
-
- it('should display "Sorry, your filter produced no results" if filters are too specific', () => {
- expect(findEmptyState().props('title')).toMatchSnapshot();
- });
- });
-
- describe('with closed state', () => {
- beforeEach(() => {
- setWindowLocation('?state=closed');
-
- factory();
-
- return waitForPromises().then(() => wrapper.vm.$nextTick());
- });
-
- it('should display a message "There are no closed issues" if there are no closed issues', () => {
- expect(findEmptyState().props('title')).toMatchSnapshot();
- });
- });
-
- describe('with all state', () => {
- beforeEach(() => {
- setWindowLocation('?state=all');
-
- factory();
-
- return waitForPromises().then(() => wrapper.vm.$nextTick());
- });
-
- it('should display a catch-all if there are no issues to show', () => {
- expect(findEmptyState().element).toMatchSnapshot();
- });
- });
-
- describe('with empty query', () => {
- beforeEach(() => {
- factory();
-
- return wrapper.vm.$nextTick().then(waitForPromises);
- });
-
- it('should display the message "There are no open issues"', () => {
- expect(findEmptyState().props('title')).toMatchSnapshot();
- });
- });
- });
-
- describe('when paginates', () => {
- const newPage = 3;
-
- describe('when total-items is defined in response headers', () => {
- beforeEach(() => {
- window.history.pushState = jest.fn();
- setupApiMock(() => [
- 200,
- MOCK_ISSUES.slice(0, PAGE_SIZE),
- {
- 'x-total': 100,
- 'x-page': 2,
- },
- ]);
-
- factory();
-
- return waitForPromises();
- });
-
- afterEach(() => {
- // reset to original value
- window.history.pushState.mockRestore();
- });
-
- it('calls window.history.pushState one time', () => {
- // Trigger pagination
- wrapper.find(GlPagination).vm.$emit('input', newPage);
-
- expect(window.history.pushState).toHaveBeenCalledTimes(1);
- });
-
- it('sets params in the url', () => {
- // Trigger pagination
- wrapper.find(GlPagination).vm.$emit('input', newPage);
-
- expect(window.history.pushState).toHaveBeenCalledWith(
- {},
- '',
- `${TEST_LOCATION}?state=opened&order_by=priority&sort=asc&page=${newPage}`,
- );
- });
- });
-
- describe('when total-items is not defined in the headers', () => {
- const page = 2;
- const prevPage = page - 1;
- const nextPage = page + 1;
-
- beforeEach(() => {
- setupApiMock(() => [
- 200,
- MOCK_ISSUES.slice(0, PAGE_SIZE),
- {
- 'x-page': page,
- },
- ]);
-
- factory();
-
- return waitForPromises();
- });
-
- it('finds the correct props applied to GlPagination', () => {
- expect(wrapper.find(GlPagination).props()).toMatchObject({
- nextPage,
- prevPage,
- value: page,
- });
- });
- });
- });
-
- describe('when type is "jira"', () => {
- it('renders FilteredSearchBar', () => {
- factory({ type: 'jira' });
-
- expect(findFilteredSearchBar().exists()).toBe(true);
- });
-
- describe('initialSortBy', () => {
- const query = '?sort=updated_asc';
-
- it('sets default value', () => {
- factory({ type: 'jira' });
-
- expect(findFilteredSearchBar().props('initialSortBy')).toBe('created_desc');
- });
-
- it('sets value according to query', () => {
- setWindowLocation(query);
-
- factory({ type: 'jira' });
-
- expect(findFilteredSearchBar().props('initialSortBy')).toBe('updated_asc');
- });
- });
-
- describe('initialFilterValue', () => {
- it('does not set value when no query', () => {
- factory({ type: 'jira' });
-
- expect(findFilteredSearchBar().props('initialFilterValue')).toEqual([]);
- });
-
- it('sets value according to query', () => {
- const query = '?search=free+text';
-
- setWindowLocation(query);
-
- factory({ type: 'jira' });
-
- expect(findFilteredSearchBar().props('initialFilterValue')).toEqual(['free text']);
- });
- });
-
- describe('on filter search', () => {
- beforeEach(() => {
- factory({ type: 'jira' });
-
- window.history.pushState = jest.fn();
- });
-
- afterEach(() => {
- window.history.pushState.mockRestore();
- });
-
- const emitOnFilter = (filter) => findFilteredSearchBar().vm.$emit('onFilter', filter);
-
- describe('empty filter', () => {
- const mockFilter = [];
-
- it('updates URL with correct params', () => {
- emitOnFilter(mockFilter);
-
- expect(window.history.pushState).toHaveBeenCalledWith(
- {},
- '',
- `${TEST_LOCATION}?state=opened`,
- );
- });
- });
-
- describe('filter with search term', () => {
- const mockFilter = [
- {
- type: 'filtered-search-term',
- value: { data: 'free' },
- },
- ];
-
- it('updates URL with correct params', () => {
- emitOnFilter(mockFilter);
-
- expect(window.history.pushState).toHaveBeenCalledWith(
- {},
- '',
- `${TEST_LOCATION}?state=opened&search=free`,
- );
- });
- });
-
- describe('filter with multiple search terms', () => {
- const mockFilter = [
- {
- type: 'filtered-search-term',
- value: { data: 'free' },
- },
- {
- type: 'filtered-search-term',
- value: { data: 'text' },
- },
- ];
-
- it('updates URL with correct params', () => {
- emitOnFilter(mockFilter);
-
- expect(window.history.pushState).toHaveBeenCalledWith(
- {},
- '',
- `${TEST_LOCATION}?state=opened&search=free+text`,
- );
- });
- });
- });
- });
-});
diff --git a/spec/frontend/issues_list/components/issue_card_time_info_spec.js b/spec/frontend/issues_list/components/issue_card_time_info_spec.js
deleted file mode 100644
index 7c5faeb8dc1..00000000000
--- a/spec/frontend/issues_list/components/issue_card_time_info_spec.js
+++ /dev/null
@@ -1,122 +0,0 @@
-import { GlIcon, GlLink } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import { useFakeDate } from 'helpers/fake_date';
-import IssueCardTimeInfo from '~/issues_list/components/issue_card_time_info.vue';
-
-describe('CE IssueCardTimeInfo component', () => {
- useFakeDate(2020, 11, 11);
-
- let wrapper;
-
- const issue = {
- milestone: {
- dueDate: '2020-12-17',
- startDate: '2020-12-10',
- title: 'My milestone',
- webPath: '/milestone/webPath',
- },
- dueDate: '2020-12-12',
- humanTimeEstimate: '1w',
- };
-
- const findMilestone = () => wrapper.find('[data-testid="issuable-milestone"]');
- const findMilestoneTitle = () => findMilestone().find(GlLink).attributes('title');
- const findDueDate = () => wrapper.find('[data-testid="issuable-due-date"]');
-
- const mountComponent = ({
- closedAt = null,
- dueDate = issue.dueDate,
- milestoneDueDate = issue.milestone.dueDate,
- milestoneStartDate = issue.milestone.startDate,
- } = {}) =>
- shallowMount(IssueCardTimeInfo, {
- propsData: {
- issue: {
- ...issue,
- milestone: {
- ...issue.milestone,
- dueDate: milestoneDueDate,
- startDate: milestoneStartDate,
- },
- closedAt,
- dueDate,
- },
- },
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('milestone', () => {
- it('renders', () => {
- wrapper = mountComponent();
-
- const milestone = findMilestone();
-
- expect(milestone.text()).toBe(issue.milestone.title);
- expect(milestone.find(GlIcon).props('name')).toBe('clock');
- expect(milestone.find(GlLink).attributes('href')).toBe(issue.milestone.webPath);
- });
-
- describe.each`
- time | text | milestoneDueDate | milestoneStartDate | expected
- ${'due date is in past'} | ${'Past due'} | ${'2020-09-09'} | ${null} | ${'Sep 9, 2020 (Past due)'}
- ${'due date is today'} | ${'Today'} | ${'2020-12-11'} | ${null} | ${'Dec 11, 2020 (Today)'}
- ${'start date is in future'} | ${'Upcoming'} | ${'2021-03-01'} | ${'2021-02-01'} | ${'Mar 1, 2021 (Upcoming)'}
- ${'due date is in future'} | ${'2 weeks remaining'} | ${'2020-12-25'} | ${null} | ${'Dec 25, 2020 (2 weeks remaining)'}
- `('when $description', ({ text, milestoneDueDate, milestoneStartDate, expected }) => {
- it(`renders with "${text}"`, () => {
- wrapper = mountComponent({ milestoneDueDate, milestoneStartDate });
-
- expect(findMilestoneTitle()).toBe(expected);
- });
- });
- });
-
- describe('due date', () => {
- describe('when upcoming', () => {
- it('renders', () => {
- wrapper = mountComponent();
-
- const dueDate = findDueDate();
-
- expect(dueDate.text()).toBe('Dec 12, 2020');
- expect(dueDate.attributes('title')).toBe('Due date');
- expect(dueDate.find(GlIcon).props('name')).toBe('calendar');
- expect(dueDate.classes()).not.toContain('gl-text-red-500');
- });
- });
-
- describe('when in the past', () => {
- describe('when issue is open', () => {
- it('renders in red', () => {
- wrapper = mountComponent({ dueDate: new Date('2020-10-10') });
-
- expect(findDueDate().classes()).toContain('gl-text-red-500');
- });
- });
-
- describe('when issue is closed', () => {
- it('does not render in red', () => {
- wrapper = mountComponent({
- dueDate: new Date('2020-10-10'),
- closedAt: '2020-09-05T13:06:25Z',
- });
-
- expect(findDueDate().classes()).not.toContain('gl-text-red-500');
- });
- });
- });
- });
-
- it('renders time estimate', () => {
- wrapper = mountComponent();
-
- const timeEstimate = wrapper.find('[data-testid="time-estimate"]');
-
- expect(timeEstimate.text()).toBe(issue.humanTimeEstimate);
- expect(timeEstimate.attributes('title')).toBe('Estimate');
- expect(timeEstimate.find(GlIcon).props('name')).toBe('timer');
- });
-});
diff --git a/spec/frontend/issues_list/components/issues_list_app_spec.js b/spec/frontend/issues_list/components/issues_list_app_spec.js
deleted file mode 100644
index f24c090fa92..00000000000
--- a/spec/frontend/issues_list/components/issues_list_app_spec.js
+++ /dev/null
@@ -1,829 +0,0 @@
-import { GlButton, GlEmptyState, GlLink } from '@gitlab/ui';
-import * as Sentry from '@sentry/browser';
-import { mount, shallowMount } from '@vue/test-utils';
-import AxiosMockAdapter from 'axios-mock-adapter';
-import { cloneDeep } from 'lodash';
-import Vue, { nextTick } from 'vue';
-import VueApollo from 'vue-apollo';
-import getIssuesQuery from 'ee_else_ce/issues_list/queries/get_issues.query.graphql';
-import getIssuesCountsQuery from 'ee_else_ce/issues_list/queries/get_issues_counts.query.graphql';
-import createMockApollo from 'helpers/mock_apollo_helper';
-import setWindowLocation from 'helpers/set_window_location_helper';
-import { TEST_HOST } from 'helpers/test_constants';
-import waitForPromises from 'helpers/wait_for_promises';
-import {
- getIssuesCountsQueryResponse,
- getIssuesQueryResponse,
- filteredTokens,
- locationSearch,
- urlParams,
-} from 'jest/issues_list/mock_data';
-import createFlash, { FLASH_TYPES } from '~/flash';
-import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
-import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue';
-import IssuableByEmail from '~/issuable/components/issuable_by_email.vue';
-import IssuableList from '~/vue_shared/issuable/list/components/issuable_list_root.vue';
-import { IssuableListTabs, IssuableStates } from '~/vue_shared/issuable/list/constants';
-import IssuesListApp from '~/issues_list/components/issues_list_app.vue';
-import NewIssueDropdown from '~/issues_list/components/new_issue_dropdown.vue';
-import {
- CREATED_DESC,
- DUE_DATE_OVERDUE,
- PARAM_DUE_DATE,
- RELATIVE_POSITION,
- RELATIVE_POSITION_ASC,
- TOKEN_TYPE_ASSIGNEE,
- TOKEN_TYPE_AUTHOR,
- TOKEN_TYPE_CONFIDENTIAL,
- TOKEN_TYPE_LABEL,
- TOKEN_TYPE_MILESTONE,
- TOKEN_TYPE_MY_REACTION,
- TOKEN_TYPE_RELEASE,
- TOKEN_TYPE_TYPE,
- urlSortParams,
-} from '~/issues_list/constants';
-import eventHub from '~/issues_list/eventhub';
-import { getSortOptions } from '~/issues_list/utils';
-import axios from '~/lib/utils/axios_utils';
-import { scrollUp } from '~/lib/utils/scroll_utils';
-import { joinPaths } from '~/lib/utils/url_utility';
-
-jest.mock('@sentry/browser');
-jest.mock('~/flash');
-jest.mock('~/lib/utils/scroll_utils', () => ({
- scrollUp: jest.fn().mockName('scrollUpMock'),
-}));
-
-describe('CE IssuesListApp component', () => {
- let axiosMock;
- let wrapper;
-
- Vue.use(VueApollo);
-
- const defaultProvide = {
- calendarPath: 'calendar/path',
- canBulkUpdate: false,
- emptyStateSvgPath: 'empty-state.svg',
- exportCsvPath: 'export/csv/path',
- fullPath: 'path/to/project',
- hasAnyIssues: true,
- hasAnyProjects: true,
- hasBlockedIssuesFeature: true,
- hasIssuableHealthStatusFeature: true,
- hasIssueWeightsFeature: true,
- hasIterationsFeature: true,
- isProject: true,
- isSignedIn: true,
- jiraIntegrationPath: 'jira/integration/path',
- newIssuePath: 'new/issue/path',
- rssPath: 'rss/path',
- showNewIssueLink: true,
- signInPath: 'sign/in/path',
- };
-
- let defaultQueryResponse = getIssuesQueryResponse;
- if (IS_EE) {
- defaultQueryResponse = cloneDeep(getIssuesQueryResponse);
- defaultQueryResponse.data.project.issues.nodes[0].blockingCount = 1;
- defaultQueryResponse.data.project.issues.nodes[0].healthStatus = null;
- defaultQueryResponse.data.project.issues.nodes[0].weight = 5;
- }
-
- const findCsvImportExportButtons = () => wrapper.findComponent(CsvImportExportButtons);
- const findIssuableByEmail = () => wrapper.findComponent(IssuableByEmail);
- const findGlButton = () => wrapper.findComponent(GlButton);
- const findGlButtons = () => wrapper.findAllComponents(GlButton);
- const findGlButtonAt = (index) => findGlButtons().at(index);
- const findGlEmptyState = () => wrapper.findComponent(GlEmptyState);
- const findGlLink = () => wrapper.findComponent(GlLink);
- const findIssuableList = () => wrapper.findComponent(IssuableList);
- const findNewIssueDropdown = () => wrapper.findComponent(NewIssueDropdown);
-
- const mountComponent = ({
- provide = {},
- issuesQueryResponse = jest.fn().mockResolvedValue(defaultQueryResponse),
- issuesCountsQueryResponse = jest.fn().mockResolvedValue(getIssuesCountsQueryResponse),
- mountFn = shallowMount,
- } = {}) => {
- const requestHandlers = [
- [getIssuesQuery, issuesQueryResponse],
- [getIssuesCountsQuery, issuesCountsQueryResponse],
- ];
- const apolloProvider = createMockApollo(requestHandlers);
-
- return mountFn(IssuesListApp, {
- apolloProvider,
- provide: {
- ...defaultProvide,
- ...provide,
- },
- });
- };
-
- beforeEach(() => {
- setWindowLocation(TEST_HOST);
- axiosMock = new AxiosMockAdapter(axios);
- });
-
- afterEach(() => {
- axiosMock.reset();
- wrapper.destroy();
- });
-
- describe('IssuableList', () => {
- beforeEach(() => {
- wrapper = mountComponent();
- jest.runOnlyPendingTimers();
- });
-
- it('renders', () => {
- expect(findIssuableList().props()).toMatchObject({
- namespace: defaultProvide.fullPath,
- recentSearchesStorageKey: 'issues',
- searchInputPlaceholder: IssuesListApp.i18n.searchPlaceholder,
- sortOptions: getSortOptions(true, true),
- initialSortBy: CREATED_DESC,
- issuables: getIssuesQueryResponse.data.project.issues.nodes,
- tabs: IssuableListTabs,
- currentTab: IssuableStates.Opened,
- tabCounts: {
- opened: 1,
- closed: 1,
- all: 1,
- },
- issuablesLoading: false,
- isManualOrdering: false,
- showBulkEditSidebar: false,
- showPaginationControls: true,
- useKeysetPagination: true,
- hasPreviousPage: getIssuesQueryResponse.data.project.issues.pageInfo.hasPreviousPage,
- hasNextPage: getIssuesQueryResponse.data.project.issues.pageInfo.hasNextPage,
- urlParams: {
- sort: urlSortParams[CREATED_DESC],
- state: IssuableStates.Opened,
- },
- });
- });
- });
-
- describe('header action buttons', () => {
- it('renders rss button', () => {
- wrapper = mountComponent({ mountFn: mount });
-
- expect(findGlButtonAt(0).props('icon')).toBe('rss');
- expect(findGlButtonAt(0).attributes()).toMatchObject({
- href: defaultProvide.rssPath,
- 'aria-label': IssuesListApp.i18n.rssLabel,
- });
- });
-
- it('renders calendar button', () => {
- wrapper = mountComponent({ mountFn: mount });
-
- expect(findGlButtonAt(1).props('icon')).toBe('calendar');
- expect(findGlButtonAt(1).attributes()).toMatchObject({
- href: defaultProvide.calendarPath,
- 'aria-label': IssuesListApp.i18n.calendarLabel,
- });
- });
-
- describe('csv import/export component', () => {
- describe('when user is signed in', () => {
- const search = '?search=refactor&sort=created_date&state=opened';
-
- beforeEach(() => {
- setWindowLocation(search);
-
- wrapper = mountComponent({ provide: { isSignedIn: true }, mountFn: mount });
-
- jest.runOnlyPendingTimers();
- });
-
- it('renders', () => {
- expect(findCsvImportExportButtons().props()).toMatchObject({
- exportCsvPath: `${defaultProvide.exportCsvPath}${search}`,
- issuableCount: 1,
- });
- });
- });
-
- describe('when user is not signed in', () => {
- it('does not render', () => {
- wrapper = mountComponent({ provide: { isSignedIn: false }, mountFn: mount });
-
- expect(findCsvImportExportButtons().exists()).toBe(false);
- });
- });
-
- describe('when in a group context', () => {
- it('does not render', () => {
- wrapper = mountComponent({ provide: { isProject: false }, mountFn: mount });
-
- expect(findCsvImportExportButtons().exists()).toBe(false);
- });
- });
- });
-
- describe('bulk edit button', () => {
- it('renders when user has permissions', () => {
- wrapper = mountComponent({ provide: { canBulkUpdate: true }, mountFn: mount });
-
- expect(findGlButtonAt(2).text()).toBe('Edit issues');
- });
-
- it('does not render when user does not have permissions', () => {
- wrapper = mountComponent({ provide: { canBulkUpdate: false }, mountFn: mount });
-
- expect(findGlButtons().filter((button) => button.text() === 'Edit issues')).toHaveLength(0);
- });
-
- it('emits "issuables:enableBulkEdit" event to legacy bulk edit class', async () => {
- wrapper = mountComponent({ provide: { canBulkUpdate: true }, mountFn: mount });
-
- jest.spyOn(eventHub, '$emit');
-
- findGlButtonAt(2).vm.$emit('click');
-
- await waitForPromises();
-
- expect(eventHub.$emit).toHaveBeenCalledWith('issuables:enableBulkEdit');
- });
- });
-
- describe('new issue button', () => {
- it('renders when user has permissions', () => {
- wrapper = mountComponent({ provide: { showNewIssueLink: true }, mountFn: mount });
-
- expect(findGlButtonAt(2).text()).toBe('New issue');
- expect(findGlButtonAt(2).attributes('href')).toBe(defaultProvide.newIssuePath);
- });
-
- it('does not render when user does not have permissions', () => {
- wrapper = mountComponent({ provide: { showNewIssueLink: false }, mountFn: mount });
-
- expect(findGlButtons().filter((button) => button.text() === 'New issue')).toHaveLength(0);
- });
- });
-
- describe('new issue split dropdown', () => {
- it('does not render in a project context', () => {
- wrapper = mountComponent({ provide: { isProject: true }, mountFn: mount });
-
- expect(findNewIssueDropdown().exists()).toBe(false);
- });
-
- it('renders in a group context', () => {
- wrapper = mountComponent({ provide: { isProject: false }, mountFn: mount });
-
- expect(findNewIssueDropdown().exists()).toBe(true);
- });
- });
- });
-
- describe('initial url params', () => {
- describe('due_date', () => {
- it('is set from the url params', () => {
- setWindowLocation(`?${PARAM_DUE_DATE}=${DUE_DATE_OVERDUE}`);
-
- wrapper = mountComponent();
-
- expect(findIssuableList().props('urlParams')).toMatchObject({ due_date: DUE_DATE_OVERDUE });
- });
- });
-
- describe('search', () => {
- it('is set from the url params', () => {
- setWindowLocation(locationSearch);
-
- wrapper = mountComponent();
-
- expect(findIssuableList().props('urlParams')).toMatchObject({ search: 'find issues' });
- });
- });
-
- describe('sort', () => {
- it.each(Object.keys(urlSortParams))('is set as %s from the url params', (sortKey) => {
- setWindowLocation(`?sort=${urlSortParams[sortKey]}`);
-
- wrapper = mountComponent();
-
- expect(findIssuableList().props()).toMatchObject({
- initialSortBy: sortKey,
- urlParams: {
- sort: urlSortParams[sortKey],
- },
- });
- });
-
- describe('when issue repositioning is disabled and the sort is manual', () => {
- beforeEach(() => {
- setWindowLocation(`?sort=${RELATIVE_POSITION}`);
- wrapper = mountComponent({ provide: { isIssueRepositioningDisabled: true } });
- });
-
- it('changes the sort to the default of created descending', () => {
- expect(findIssuableList().props()).toMatchObject({
- initialSortBy: CREATED_DESC,
- urlParams: {
- sort: urlSortParams[CREATED_DESC],
- },
- });
- });
-
- it('shows an alert to tell the user that manual reordering is disabled', () => {
- expect(createFlash).toHaveBeenCalledWith({
- message: IssuesListApp.i18n.issueRepositioningMessage,
- type: FLASH_TYPES.NOTICE,
- });
- });
- });
- });
-
- describe('state', () => {
- it('is set from the url params', () => {
- const initialState = IssuableStates.All;
-
- setWindowLocation(`?state=${initialState}`);
-
- wrapper = mountComponent();
-
- expect(findIssuableList().props('currentTab')).toBe(initialState);
- });
- });
-
- describe('filter tokens', () => {
- it('is set from the url params', () => {
- setWindowLocation(locationSearch);
-
- wrapper = mountComponent();
-
- expect(findIssuableList().props('initialFilterValue')).toEqual(filteredTokens);
- });
-
- describe('when anonymous searching is performed', () => {
- beforeEach(() => {
- setWindowLocation(locationSearch);
-
- wrapper = mountComponent({
- provide: { isAnonymousSearchDisabled: true, isSignedIn: false },
- });
- });
-
- it('is not set from url params', () => {
- expect(findIssuableList().props('initialFilterValue')).toEqual([]);
- });
-
- it('shows an alert to tell the user they must be signed in to search', () => {
- expect(createFlash).toHaveBeenCalledWith({
- message: IssuesListApp.i18n.anonymousSearchingMessage,
- type: FLASH_TYPES.NOTICE,
- });
- });
- });
- });
- });
-
- describe('bulk edit', () => {
- describe.each([true, false])(
- 'when "issuables:toggleBulkEdit" event is received with payload `%s`',
- (isBulkEdit) => {
- beforeEach(() => {
- wrapper = mountComponent();
-
- eventHub.$emit('issuables:toggleBulkEdit', isBulkEdit);
- });
-
- it(`${isBulkEdit ? 'enables' : 'disables'} bulk edit`, () => {
- expect(findIssuableList().props('showBulkEditSidebar')).toBe(isBulkEdit);
- });
- },
- );
- });
-
- describe('IssuableByEmail component', () => {
- describe.each([true, false])(`when issue creation by email is enabled=%s`, (enabled) => {
- it(`${enabled ? 'renders' : 'does not render'}`, () => {
- wrapper = mountComponent({ provide: { initialEmail: enabled } });
-
- expect(findIssuableByEmail().exists()).toBe(enabled);
- });
- });
- });
-
- describe('empty states', () => {
- describe('when there are issues', () => {
- describe('when search returns no results', () => {
- beforeEach(() => {
- setWindowLocation(`?search=no+results`);
-
- wrapper = mountComponent({ provide: { hasAnyIssues: true }, mountFn: mount });
- });
-
- it('shows empty state', () => {
- expect(findGlEmptyState().props()).toMatchObject({
- description: IssuesListApp.i18n.noSearchResultsDescription,
- title: IssuesListApp.i18n.noSearchResultsTitle,
- svgPath: defaultProvide.emptyStateSvgPath,
- });
- });
- });
-
- describe('when "Open" tab has no issues', () => {
- beforeEach(() => {
- wrapper = mountComponent({ provide: { hasAnyIssues: true }, mountFn: mount });
- });
-
- it('shows empty state', () => {
- expect(findGlEmptyState().props()).toMatchObject({
- description: IssuesListApp.i18n.noOpenIssuesDescription,
- title: IssuesListApp.i18n.noOpenIssuesTitle,
- svgPath: defaultProvide.emptyStateSvgPath,
- });
- });
- });
-
- describe('when "Closed" tab has no issues', () => {
- beforeEach(() => {
- setWindowLocation(`?state=${IssuableStates.Closed}`);
-
- wrapper = mountComponent({ provide: { hasAnyIssues: true }, mountFn: mount });
- });
-
- it('shows empty state', () => {
- expect(findGlEmptyState().props()).toMatchObject({
- title: IssuesListApp.i18n.noClosedIssuesTitle,
- svgPath: defaultProvide.emptyStateSvgPath,
- });
- });
- });
- });
-
- describe('when there are no issues', () => {
- describe('when user is logged in', () => {
- beforeEach(() => {
- wrapper = mountComponent({
- provide: { hasAnyIssues: false, isSignedIn: true },
- mountFn: mount,
- });
- });
-
- it('shows empty state', () => {
- expect(findGlEmptyState().props()).toMatchObject({
- description: IssuesListApp.i18n.noIssuesSignedInDescription,
- title: IssuesListApp.i18n.noIssuesSignedInTitle,
- svgPath: defaultProvide.emptyStateSvgPath,
- });
- });
-
- it('shows "New issue" and import/export buttons', () => {
- expect(findGlButton().text()).toBe(IssuesListApp.i18n.newIssueLabel);
- expect(findGlButton().attributes('href')).toBe(defaultProvide.newIssuePath);
- expect(findCsvImportExportButtons().props()).toMatchObject({
- exportCsvPath: defaultProvide.exportCsvPath,
- issuableCount: 0,
- });
- });
-
- it('shows Jira integration information', () => {
- const paragraphs = wrapper.findAll('p');
- expect(paragraphs.at(1).text()).toContain(IssuesListApp.i18n.jiraIntegrationTitle);
- expect(paragraphs.at(2).text()).toContain(
- 'Enable the Jira integration to view your Jira issues in GitLab.',
- );
- expect(paragraphs.at(3).text()).toContain(
- IssuesListApp.i18n.jiraIntegrationSecondaryMessage,
- );
- expect(findGlLink().text()).toBe('Enable the Jira integration');
- expect(findGlLink().attributes('href')).toBe(defaultProvide.jiraIntegrationPath);
- });
- });
-
- describe('when user is logged out', () => {
- beforeEach(() => {
- wrapper = mountComponent({
- provide: { hasAnyIssues: false, isSignedIn: false },
- });
- });
-
- it('shows empty state', () => {
- expect(findGlEmptyState().props()).toMatchObject({
- description: IssuesListApp.i18n.noIssuesSignedOutDescription,
- title: IssuesListApp.i18n.noIssuesSignedOutTitle,
- svgPath: defaultProvide.emptyStateSvgPath,
- primaryButtonText: IssuesListApp.i18n.noIssuesSignedOutButtonText,
- primaryButtonLink: defaultProvide.signInPath,
- });
- });
- });
- });
- });
-
- describe('tokens', () => {
- const mockCurrentUser = {
- id: 1,
- name: 'Administrator',
- username: 'root',
- avatar_url: 'avatar/url',
- };
-
- describe('when user is signed out', () => {
- beforeEach(() => {
- wrapper = mountComponent({ provide: { isSignedIn: false } });
- });
-
- it('does not render My-Reaction or Confidential tokens', () => {
- expect(findIssuableList().props('searchTokens')).not.toMatchObject([
- { type: TOKEN_TYPE_AUTHOR, preloadedAuthors: [mockCurrentUser] },
- { type: TOKEN_TYPE_ASSIGNEE, preloadedAuthors: [mockCurrentUser] },
- { type: TOKEN_TYPE_MY_REACTION },
- { type: TOKEN_TYPE_CONFIDENTIAL },
- ]);
- });
- });
-
- describe('when all tokens are available', () => {
- const originalGon = window.gon;
-
- beforeEach(() => {
- window.gon = {
- ...originalGon,
- current_user_id: mockCurrentUser.id,
- current_user_fullname: mockCurrentUser.name,
- current_username: mockCurrentUser.username,
- current_user_avatar_url: mockCurrentUser.avatar_url,
- };
-
- wrapper = mountComponent({ provide: { isSignedIn: true } });
- });
-
- afterEach(() => {
- window.gon = originalGon;
- });
-
- it('renders all tokens alphabetically', () => {
- const preloadedAuthors = [
- { ...mockCurrentUser, id: convertToGraphQLId('User', mockCurrentUser.id) },
- ];
-
- expect(findIssuableList().props('searchTokens')).toMatchObject([
- { type: TOKEN_TYPE_ASSIGNEE, preloadedAuthors },
- { type: TOKEN_TYPE_AUTHOR, preloadedAuthors },
- { type: TOKEN_TYPE_CONFIDENTIAL },
- { type: TOKEN_TYPE_LABEL },
- { type: TOKEN_TYPE_MILESTONE },
- { type: TOKEN_TYPE_MY_REACTION },
- { type: TOKEN_TYPE_RELEASE },
- { type: TOKEN_TYPE_TYPE },
- ]);
- });
- });
- });
-
- describe('errors', () => {
- describe.each`
- error | mountOption | message
- ${'fetching issues'} | ${'issuesQueryResponse'} | ${IssuesListApp.i18n.errorFetchingIssues}
- ${'fetching issue counts'} | ${'issuesCountsQueryResponse'} | ${IssuesListApp.i18n.errorFetchingCounts}
- `('when there is an error $error', ({ mountOption, message }) => {
- beforeEach(() => {
- wrapper = mountComponent({
- [mountOption]: jest.fn().mockRejectedValue(new Error('ERROR')),
- });
- jest.runOnlyPendingTimers();
- });
-
- it('shows an error message', () => {
- expect(findIssuableList().props('error')).toBe(message);
- expect(Sentry.captureException).toHaveBeenCalledWith(new Error('Network error: ERROR'));
- });
- });
-
- it('clears error message when "dismiss-alert" event is emitted from IssuableList', () => {
- wrapper = mountComponent({ issuesQueryResponse: jest.fn().mockRejectedValue(new Error()) });
-
- findIssuableList().vm.$emit('dismiss-alert');
-
- expect(findIssuableList().props('error')).toBeNull();
- });
- });
-
- describe('events', () => {
- describe('when "click-tab" event is emitted by IssuableList', () => {
- beforeEach(() => {
- wrapper = mountComponent();
-
- findIssuableList().vm.$emit('click-tab', IssuableStates.Closed);
- });
-
- it('updates to the new tab', () => {
- expect(findIssuableList().props('currentTab')).toBe(IssuableStates.Closed);
- });
- });
-
- describe.each(['next-page', 'previous-page'])(
- 'when "%s" event is emitted by IssuableList',
- (event) => {
- beforeEach(() => {
- wrapper = mountComponent();
-
- findIssuableList().vm.$emit(event);
- });
-
- it('scrolls to the top', () => {
- expect(scrollUp).toHaveBeenCalled();
- });
- },
- );
-
- describe('when "reorder" event is emitted by IssuableList', () => {
- const issueOne = {
- ...defaultQueryResponse.data.project.issues.nodes[0],
- id: 'gid://gitlab/Issue/1',
- iid: '101',
- reference: 'group/project#1',
- webPath: '/group/project/-/issues/1',
- };
- const issueTwo = {
- ...defaultQueryResponse.data.project.issues.nodes[0],
- id: 'gid://gitlab/Issue/2',
- iid: '102',
- reference: 'group/project#2',
- webPath: '/group/project/-/issues/2',
- };
- const issueThree = {
- ...defaultQueryResponse.data.project.issues.nodes[0],
- id: 'gid://gitlab/Issue/3',
- iid: '103',
- reference: 'group/project#3',
- webPath: '/group/project/-/issues/3',
- };
- const issueFour = {
- ...defaultQueryResponse.data.project.issues.nodes[0],
- id: 'gid://gitlab/Issue/4',
- iid: '104',
- reference: 'group/project#4',
- webPath: '/group/project/-/issues/4',
- };
- const response = (isProject = true) => ({
- data: {
- [isProject ? 'project' : 'group']: {
- id: '1',
- issues: {
- ...defaultQueryResponse.data.project.issues,
- nodes: [issueOne, issueTwo, issueThree, issueFour],
- },
- },
- },
- });
-
- describe('when successful', () => {
- describe.each([true, false])('when isProject=%s', (isProject) => {
- describe.each`
- description | issueToMove | oldIndex | newIndex | moveBeforeId | moveAfterId
- ${'to the beginning of the list'} | ${issueThree} | ${2} | ${0} | ${null} | ${issueOne.id}
- ${'down the list'} | ${issueOne} | ${0} | ${1} | ${issueTwo.id} | ${issueThree.id}
- ${'up the list'} | ${issueThree} | ${2} | ${1} | ${issueOne.id} | ${issueTwo.id}
- ${'to the end of the list'} | ${issueTwo} | ${1} | ${3} | ${issueFour.id} | ${null}
- `(
- 'when moving issue $description',
- ({ issueToMove, oldIndex, newIndex, moveBeforeId, moveAfterId }) => {
- beforeEach(() => {
- wrapper = mountComponent({
- provide: { isProject },
- issuesQueryResponse: jest.fn().mockResolvedValue(response(isProject)),
- });
- jest.runOnlyPendingTimers();
- });
-
- it('makes API call to reorder the issue', async () => {
- findIssuableList().vm.$emit('reorder', { oldIndex, newIndex });
-
- await waitForPromises();
-
- expect(axiosMock.history.put[0]).toMatchObject({
- url: joinPaths(issueToMove.webPath, 'reorder'),
- data: JSON.stringify({
- move_before_id: getIdFromGraphQLId(moveBeforeId),
- move_after_id: getIdFromGraphQLId(moveAfterId),
- group_full_path: isProject ? undefined : defaultProvide.fullPath,
- }),
- });
- });
- },
- );
- });
- });
-
- describe('when unsuccessful', () => {
- beforeEach(() => {
- wrapper = mountComponent({
- issuesQueryResponse: jest.fn().mockResolvedValue(response()),
- });
- jest.runOnlyPendingTimers();
- });
-
- it('displays an error message', async () => {
- axiosMock.onPut(joinPaths(issueOne.webPath, 'reorder')).reply(500);
-
- findIssuableList().vm.$emit('reorder', { oldIndex: 0, newIndex: 1 });
-
- await waitForPromises();
-
- expect(findIssuableList().props('error')).toBe(IssuesListApp.i18n.reorderError);
- expect(Sentry.captureException).toHaveBeenCalledWith(
- new Error('Request failed with status code 500'),
- );
- });
- });
- });
-
- describe('when "sort" event is emitted by IssuableList', () => {
- it.each(Object.keys(urlSortParams))(
- 'updates to the new sort when payload is `%s`',
- async (sortKey) => {
- wrapper = mountComponent();
-
- findIssuableList().vm.$emit('sort', sortKey);
-
- jest.runOnlyPendingTimers();
- await nextTick();
-
- expect(findIssuableList().props('urlParams')).toMatchObject({
- sort: urlSortParams[sortKey],
- });
- },
- );
-
- describe('when issue repositioning is disabled', () => {
- const initialSort = CREATED_DESC;
-
- beforeEach(() => {
- setWindowLocation(`?sort=${initialSort}`);
- wrapper = mountComponent({ provide: { isIssueRepositioningDisabled: true } });
-
- findIssuableList().vm.$emit('sort', RELATIVE_POSITION_ASC);
- });
-
- it('does not update the sort to manual', () => {
- expect(findIssuableList().props('urlParams')).toMatchObject({
- sort: urlSortParams[initialSort],
- });
- });
-
- it('shows an alert to tell the user that manual reordering is disabled', () => {
- expect(createFlash).toHaveBeenCalledWith({
- message: IssuesListApp.i18n.issueRepositioningMessage,
- type: FLASH_TYPES.NOTICE,
- });
- });
- });
- });
-
- describe('when "update-legacy-bulk-edit" event is emitted by IssuableList', () => {
- beforeEach(() => {
- wrapper = mountComponent();
- jest.spyOn(eventHub, '$emit');
-
- findIssuableList().vm.$emit('update-legacy-bulk-edit');
- });
-
- it('emits an "issuables:updateBulkEdit" event to the legacy bulk edit class', () => {
- expect(eventHub.$emit).toHaveBeenCalledWith('issuables:updateBulkEdit');
- });
- });
-
- describe('when "filter" event is emitted by IssuableList', () => {
- it('updates IssuableList with url params', async () => {
- wrapper = mountComponent();
-
- findIssuableList().vm.$emit('filter', filteredTokens);
- await nextTick();
-
- expect(findIssuableList().props('urlParams')).toMatchObject(urlParams);
- });
-
- describe('when anonymous searching is performed', () => {
- beforeEach(() => {
- wrapper = mountComponent({
- provide: { isAnonymousSearchDisabled: true, isSignedIn: false },
- });
-
- findIssuableList().vm.$emit('filter', filteredTokens);
- });
-
- it('does not update IssuableList with url params ', async () => {
- const defaultParams = { sort: 'created_date', state: 'opened' };
-
- expect(findIssuableList().props('urlParams')).toEqual(defaultParams);
- });
-
- it('shows an alert to tell the user they must be signed in to search', () => {
- expect(createFlash).toHaveBeenCalledWith({
- message: IssuesListApp.i18n.anonymousSearchingMessage,
- type: FLASH_TYPES.NOTICE,
- });
- });
- });
- });
- });
-});
diff --git a/spec/frontend/issues_list/components/jira_issues_import_status_app_spec.js b/spec/frontend/issues_list/components/jira_issues_import_status_app_spec.js
deleted file mode 100644
index 633799816d8..00000000000
--- a/spec/frontend/issues_list/components/jira_issues_import_status_app_spec.js
+++ /dev/null
@@ -1,117 +0,0 @@
-import { GlAlert, GlLabel } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
-import JiraIssuesImportStatus from '~/issues_list/components/jira_issues_import_status_app.vue';
-
-describe('JiraIssuesImportStatus', () => {
- const issuesPath = 'gitlab-org/gitlab-test/-/issues';
- const label = {
- color: '#333',
- title: 'jira-import::MTG-3',
- };
- let wrapper;
-
- const findAlert = () => wrapper.find(GlAlert);
-
- const findAlertLabel = () => wrapper.find(GlAlert).find(GlLabel);
-
- const mountComponent = ({
- shouldShowFinishedAlert = false,
- shouldShowInProgressAlert = false,
- } = {}) =>
- shallowMount(JiraIssuesImportStatus, {
- propsData: {
- canEdit: true,
- isJiraConfigured: true,
- issuesPath,
- projectPath: 'gitlab-org/gitlab-test',
- },
- data() {
- return {
- jiraImport: {
- importedIssuesCount: 1,
- label,
- shouldShowFinishedAlert,
- shouldShowInProgressAlert,
- },
- };
- },
- });
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- describe('when Jira import is neither in progress nor finished', () => {
- beforeEach(() => {
- wrapper = mountComponent();
- });
-
- it('does not show an alert', () => {
- expect(wrapper.find(GlAlert).exists()).toBe(false);
- });
- });
-
- describe('when Jira import is in progress', () => {
- it('shows an alert that tells the user a Jira import is in progress', () => {
- wrapper = mountComponent({
- shouldShowInProgressAlert: true,
- });
-
- expect(findAlert().text()).toBe(
- 'Import in progress. Refresh page to see newly added issues.',
- );
- });
- });
-
- describe('when Jira import has finished', () => {
- beforeEach(() => {
- wrapper = mountComponent({
- shouldShowFinishedAlert: true,
- });
- });
-
- describe('shows an alert', () => {
- it('tells the user the Jira import has finished', () => {
- expect(findAlert().text()).toBe('1 issue successfully imported with the label');
- });
-
- it('contains the label title associated with the Jira import', () => {
- const alertLabelTitle = findAlertLabel().props('title');
-
- expect(alertLabelTitle).toBe(label.title);
- });
-
- it('contains the correct label color', () => {
- const alertLabelTitle = findAlertLabel().props('backgroundColor');
-
- expect(alertLabelTitle).toBe(label.color);
- });
-
- it('contains a link within the label', () => {
- const alertLabelTarget = findAlertLabel().props('target');
-
- expect(alertLabelTarget).toBe(
- `${issuesPath}?label_name[]=${encodeURIComponent(label.title)}`,
- );
- });
- });
- });
-
- describe('alert message', () => {
- it('is hidden when dismissed', () => {
- wrapper = mountComponent({
- shouldShowInProgressAlert: true,
- });
-
- expect(wrapper.find(GlAlert).exists()).toBe(true);
-
- findAlert().vm.$emit('dismiss');
-
- return Vue.nextTick(() => {
- expect(wrapper.find(GlAlert).exists()).toBe(false);
- });
- });
- });
-});
diff --git a/spec/frontend/issues_list/components/new_issue_dropdown_spec.js b/spec/frontend/issues_list/components/new_issue_dropdown_spec.js
deleted file mode 100644
index 1c9a87e8af2..00000000000
--- a/spec/frontend/issues_list/components/new_issue_dropdown_spec.js
+++ /dev/null
@@ -1,131 +0,0 @@
-import { GlDropdown, GlDropdownItem, GlSearchBoxByType } from '@gitlab/ui';
-import { createLocalVue, mount, shallowMount } from '@vue/test-utils';
-import VueApollo from 'vue-apollo';
-import createMockApollo from 'helpers/mock_apollo_helper';
-import NewIssueDropdown from '~/issues_list/components/new_issue_dropdown.vue';
-import searchProjectsQuery from '~/issues_list/queries/search_projects.query.graphql';
-import { DASH_SCOPE, joinPaths } from '~/lib/utils/url_utility';
-import {
- emptySearchProjectsQueryResponse,
- project1,
- project3,
- searchProjectsQueryResponse,
-} from '../mock_data';
-
-describe('NewIssueDropdown component', () => {
- let wrapper;
-
- const localVue = createLocalVue();
- localVue.use(VueApollo);
-
- const mountComponent = ({
- search = '',
- queryResponse = searchProjectsQueryResponse,
- mountFn = shallowMount,
- } = {}) => {
- const requestHandlers = [[searchProjectsQuery, jest.fn().mockResolvedValue(queryResponse)]];
- const apolloProvider = createMockApollo(requestHandlers);
-
- return mountFn(NewIssueDropdown, {
- localVue,
- apolloProvider,
- provide: {
- fullPath: 'mushroom-kingdom',
- },
- data() {
- return { search };
- },
- });
- };
-
- const findDropdown = () => wrapper.findComponent(GlDropdown);
- const findInput = () => wrapper.findComponent(GlSearchBoxByType);
- const showDropdown = async () => {
- findDropdown().vm.$emit('shown');
- await wrapper.vm.$apollo.queries.projects.refetch();
- jest.runOnlyPendingTimers();
- };
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('renders a split dropdown', () => {
- wrapper = mountComponent();
-
- expect(findDropdown().props('split')).toBe(true);
- });
-
- it('renders a label for the dropdown toggle button', () => {
- wrapper = mountComponent();
-
- expect(findDropdown().attributes('toggle-text')).toBe(NewIssueDropdown.i18n.toggleButtonLabel);
- });
-
- it('focuses on input when dropdown is shown', async () => {
- wrapper = mountComponent({ mountFn: mount });
-
- const inputSpy = jest.spyOn(findInput().vm, 'focusInput');
-
- await showDropdown();
-
- expect(inputSpy).toHaveBeenCalledTimes(1);
- });
-
- it('renders projects with issues enabled', async () => {
- wrapper = mountComponent({ mountFn: mount });
-
- await showDropdown();
-
- const listItems = wrapper.findAll('li');
-
- expect(listItems.at(0).text()).toBe(project1.nameWithNamespace);
- expect(listItems.at(1).text()).toBe(project3.nameWithNamespace);
- });
-
- it('renders `No matches found` when there are no matches', async () => {
- wrapper = mountComponent({
- search: 'no matches',
- queryResponse: emptySearchProjectsQueryResponse,
- mountFn: mount,
- });
-
- await showDropdown();
-
- expect(wrapper.find('li').text()).toBe(NewIssueDropdown.i18n.noMatchesFound);
- });
-
- describe('when no project is selected', () => {
- beforeEach(() => {
- wrapper = mountComponent();
- });
-
- it('dropdown button is not a link', () => {
- expect(findDropdown().attributes('split-href')).toBeUndefined();
- });
-
- it('displays default text on the dropdown button', () => {
- expect(findDropdown().props('text')).toBe(NewIssueDropdown.i18n.defaultDropdownText);
- });
- });
-
- describe('when a project is selected', () => {
- beforeEach(async () => {
- wrapper = mountComponent({ mountFn: mount });
-
- await showDropdown();
-
- wrapper.findComponent(GlDropdownItem).vm.$emit('click', project1);
- });
-
- it('dropdown button is a link', () => {
- const href = joinPaths(project1.webUrl, DASH_SCOPE, 'issues/new');
-
- expect(findDropdown().attributes('split-href')).toBe(href);
- });
-
- it('displays project name on the dropdown button', () => {
- expect(findDropdown().props('text')).toBe(`New issue in ${project1.name}`);
- });
- });
-});
diff --git a/spec/frontend/issues_list/issuable_list_test_data.js b/spec/frontend/issues_list/issuable_list_test_data.js
deleted file mode 100644
index 313aa15bd31..00000000000
--- a/spec/frontend/issues_list/issuable_list_test_data.js
+++ /dev/null
@@ -1,77 +0,0 @@
-export const simpleIssue = {
- id: 442,
- iid: 31,
- title: 'Dismiss Cipher with no integrity',
- state: 'opened',
- created_at: '2019-08-26T19:06:32.667Z',
- updated_at: '2019-08-28T19:53:58.314Z',
- labels: [],
- milestone: null,
- assignees: [],
- author: {
- id: 3,
- name: 'Elnora Bernhard',
- username: 'treva.lesch',
- state: 'active',
- avatar_url: 'https://www.gravatar.com/avatar/a8c0d9c2882406cf2a9b71494625a796?s=80&d=identicon',
- web_url: 'http://localhost:3001/treva.lesch',
- },
- assignee: null,
- user_notes_count: 0,
- blocking_issues_count: 0,
- merge_requests_count: 0,
- upvotes: 0,
- downvotes: 0,
- due_date: null,
- confidential: false,
- web_url: 'http://localhost:3001/h5bp/html5-boilerplate/issues/31',
- has_tasks: false,
- weight: null,
- references: {
- relative: 'html-boilerplate#45',
- },
- health_status: 'on_track',
-};
-
-export const testLabels = [
- {
- id: 1,
- name: 'Tanuki',
- description: 'A cute animal',
- color: '#ff0000',
- text_color: '#ffffff',
- },
- {
- id: 2,
- name: 'Octocat',
- description: 'A grotesque mish-mash of whiskers and tentacles',
- color: '#333333',
- text_color: '#000000',
- },
- {
- id: 3,
- name: 'scoped::label',
- description: 'A scoped label',
- color: '#00ff00',
- text_color: '#ffffff',
- },
-];
-
-export const testAssignees = [
- {
- id: 1,
- name: 'Administrator',
- username: 'root',
- state: 'active',
- avatar_url: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- web_url: 'http://localhost:3001/root',
- },
- {
- id: 22,
- name: 'User 0',
- username: 'user0',
- state: 'active',
- avatar_url: 'https://www.gravatar.com/avatar/52e4ce24a915fb7e51e1ad3b57f4b00a?s=80&d=identicon',
- web_url: 'http://localhost:3001/user0',
- },
-];
diff --git a/spec/frontend/issues_list/service_desk_helper_spec.js b/spec/frontend/issues_list/service_desk_helper_spec.js
deleted file mode 100644
index 16aee853341..00000000000
--- a/spec/frontend/issues_list/service_desk_helper_spec.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import { emptyStateHelper, generateMessages } from '~/issues_list/service_desk_helper';
-
-describe('service desk helper', () => {
- const emptyStateMessages = generateMessages({});
-
- // Note: isServiceDeskEnabled must not be true when isServiceDeskSupported is false (it's an invalid case).
- describe.each`
- isServiceDeskSupported | isServiceDeskEnabled | canEditProjectSettings | expectedMessage
- ${true} | ${true} | ${true} | ${'serviceDeskEnabledAndCanEditProjectSettings'}
- ${true} | ${true} | ${false} | ${'serviceDeskEnabledAndCannotEditProjectSettings'}
- ${true} | ${false} | ${true} | ${'serviceDeskDisabledAndCanEditProjectSettings'}
- ${true} | ${false} | ${false} | ${'serviceDeskDisabledAndCannotEditProjectSettings'}
- ${false} | ${false} | ${true} | ${'serviceDeskIsNotSupported'}
- ${false} | ${false} | ${false} | ${'serviceDeskIsNotEnabled'}
- `(
- 'isServiceDeskSupported = $isServiceDeskSupported, isServiceDeskEnabled = $isServiceDeskEnabled, canEditProjectSettings = $canEditProjectSettings',
- ({ isServiceDeskSupported, isServiceDeskEnabled, canEditProjectSettings, expectedMessage }) => {
- it(`displays ${expectedMessage} message`, () => {
- const emptyStateMeta = {
- isServiceDeskEnabled,
- isServiceDeskSupported,
- canEditProjectSettings,
- };
- expect(emptyStateHelper(emptyStateMeta)).toEqual(emptyStateMessages[expectedMessage]);
- });
- },
- );
-});
diff --git a/spec/frontend/issues_list/utils_spec.js b/spec/frontend/issues_list/utils_spec.js
deleted file mode 100644
index 8e1d70db92d..00000000000
--- a/spec/frontend/issues_list/utils_spec.js
+++ /dev/null
@@ -1,127 +0,0 @@
-import {
- apiParams,
- apiParamsWithSpecialValues,
- filteredTokens,
- filteredTokensWithSpecialValues,
- locationSearch,
- locationSearchWithSpecialValues,
- urlParams,
- urlParamsWithSpecialValues,
-} from 'jest/issues_list/mock_data';
-import {
- defaultPageSizeParams,
- DUE_DATE_VALUES,
- largePageSizeParams,
- RELATIVE_POSITION_ASC,
- urlSortParams,
-} from '~/issues_list/constants';
-import {
- convertToApiParams,
- convertToSearchQuery,
- convertToUrlParams,
- getDueDateValue,
- getFilterTokens,
- getInitialPageParams,
- getSortKey,
- getSortOptions,
-} from '~/issues_list/utils';
-
-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;
-
- expect(getInitialPageParams(sortKey)).toBe(expectedPageParams);
- },
- );
-});
-
-describe('getSortKey', () => {
- it.each(Object.keys(urlSortParams))('returns %s given the correct inputs', (sortKey) => {
- const sort = urlSortParams[sortKey];
- expect(getSortKey(sort)).toBe(sortKey);
- });
-});
-
-describe('getDueDateValue', () => {
- it.each(DUE_DATE_VALUES)('returns the argument when it is `%s`', (value) => {
- expect(getDueDateValue(value)).toBe(value);
- });
-
- it('returns undefined when the argument is invalid', () => {
- expect(getDueDateValue('invalid value')).toBeUndefined();
- });
-});
-
-describe('getSortOptions', () => {
- describe.each`
- hasIssueWeightsFeature | hasBlockedIssuesFeature | length | containsWeight | containsBlocking
- ${false} | ${false} | ${9} | ${false} | ${false}
- ${true} | ${false} | ${10} | ${true} | ${false}
- ${false} | ${true} | ${10} | ${false} | ${true}
- ${true} | ${true} | ${11} | ${true} | ${true}
- `(
- 'when hasIssueWeightsFeature=$hasIssueWeightsFeature and hasBlockedIssuesFeature=$hasBlockedIssuesFeature',
- ({
- hasIssueWeightsFeature,
- hasBlockedIssuesFeature,
- length,
- containsWeight,
- containsBlocking,
- }) => {
- const sortOptions = getSortOptions(hasIssueWeightsFeature, hasBlockedIssuesFeature);
-
- it('returns the correct length of sort options', () => {
- expect(sortOptions).toHaveLength(length);
- });
-
- it(`${containsWeight ? 'contains' : 'does not contain'} weight option`, () => {
- expect(sortOptions.some((option) => option.title === 'Weight')).toBe(containsWeight);
- });
-
- it(`${containsBlocking ? 'contains' : 'does not contain'} blocking option`, () => {
- expect(sortOptions.some((option) => option.title === 'Blocking')).toBe(containsBlocking);
- });
- },
- );
-});
-
-describe('getFilterTokens', () => {
- it('returns filtered tokens given "window.location.search"', () => {
- expect(getFilterTokens(locationSearch)).toEqual(filteredTokens);
- });
-
- it('returns filtered tokens given "window.location.search" with special values', () => {
- expect(getFilterTokens(locationSearchWithSpecialValues)).toEqual(
- filteredTokensWithSpecialValues,
- );
- });
-});
-
-describe('convertToApiParams', () => {
- it('returns api params given filtered tokens', () => {
- expect(convertToApiParams(filteredTokens)).toEqual(apiParams);
- });
-
- it('returns api params given filtered tokens with special values', () => {
- expect(convertToApiParams(filteredTokensWithSpecialValues)).toEqual(apiParamsWithSpecialValues);
- });
-});
-
-describe('convertToUrlParams', () => {
- it('returns url params given filtered tokens', () => {
- expect(convertToUrlParams(filteredTokens)).toEqual(urlParams);
- });
-
- it('returns url params given filtered tokens with special values', () => {
- expect(convertToUrlParams(filteredTokensWithSpecialValues)).toEqual(urlParamsWithSpecialValues);
- });
-});
-
-describe('convertToSearchQuery', () => {
- it('returns search string given filtered tokens', () => {
- expect(convertToSearchQuery(filteredTokens)).toBe('find issues');
- });
-});
diff --git a/spec/frontend/jira_import/utils/jira_import_utils_spec.js b/spec/frontend/jira_import/utils/jira_import_utils_spec.js
index 9696d95f8c4..4207038f50c 100644
--- a/spec/frontend/jira_import/utils/jira_import_utils_spec.js
+++ b/spec/frontend/jira_import/utils/jira_import_utils_spec.js
@@ -1,5 +1,5 @@
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
-import { JIRA_IMPORT_SUCCESS_ALERT_HIDE_MAP_KEY } from '~/issues_list/constants';
+import { JIRA_IMPORT_SUCCESS_ALERT_HIDE_MAP_KEY } from '~/jira_import/utils/constants';
import {
calculateJiraImportLabel,
extractJiraProjectsOptions,
diff --git a/spec/frontend/jobs/bridge/app_spec.js b/spec/frontend/jobs/bridge/app_spec.js
index 0e232ab240d..c0faab90552 100644
--- a/spec/frontend/jobs/bridge/app_spec.js
+++ b/spec/frontend/jobs/bridge/app_spec.js
@@ -1,27 +1,104 @@
-import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
+import { GlLoadingIcon } from '@gitlab/ui';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import getPipelineQuery from '~/jobs/bridge/graphql/queries/pipeline.query.graphql';
+import waitForPromises from 'helpers/wait_for_promises';
import BridgeApp from '~/jobs/bridge/app.vue';
import BridgeEmptyState from '~/jobs/bridge/components/empty_state.vue';
import BridgeSidebar from '~/jobs/bridge/components/sidebar.vue';
+import CiHeader from '~/vue_shared/components/header_ci_component.vue';
+import {
+ MOCK_BUILD_ID,
+ MOCK_PIPELINE_IID,
+ MOCK_PROJECT_FULL_PATH,
+ mockPipelineQueryResponse,
+} from './mock_data';
+
+const localVue = createLocalVue();
+localVue.use(VueApollo);
describe('Bridge Show Page', () => {
let wrapper;
+ let mockApollo;
+ let mockPipelineQuery;
+
+ const createComponent = (options) => {
+ wrapper = shallowMount(BridgeApp, {
+ provide: {
+ buildId: MOCK_BUILD_ID,
+ projectFullPath: MOCK_PROJECT_FULL_PATH,
+ pipelineIid: MOCK_PIPELINE_IID,
+ },
+ mocks: {
+ $apollo: {
+ queries: {
+ pipeline: {
+ loading: true,
+ },
+ },
+ },
+ },
+ ...options,
+ });
+ };
- const createComponent = () => {
- wrapper = shallowMount(BridgeApp, {});
+ const createComponentWithApollo = () => {
+ const handlers = [[getPipelineQuery, mockPipelineQuery]];
+ mockApollo = createMockApollo(handlers);
+
+ createComponent({
+ localVue,
+ apolloProvider: mockApollo,
+ mocks: {},
+ });
};
+ const findCiHeader = () => wrapper.findComponent(CiHeader);
const findEmptyState = () => wrapper.findComponent(BridgeEmptyState);
+ const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findSidebar = () => wrapper.findComponent(BridgeSidebar);
+ beforeEach(() => {
+ mockPipelineQuery = jest.fn();
+ });
+
afterEach(() => {
+ mockPipelineQuery.mockReset();
wrapper.destroy();
});
- describe('template', () => {
+ describe('while pipeline query is loading', () => {
beforeEach(() => {
createComponent();
});
+ it('renders loading icon', () => {
+ expect(findLoadingIcon().exists()).toBe(true);
+ });
+ });
+
+ describe('after pipeline query is loaded', () => {
+ beforeEach(() => {
+ mockPipelineQuery.mockResolvedValue(mockPipelineQueryResponse);
+ createComponentWithApollo();
+ waitForPromises();
+ });
+
+ it('query is called with correct variables', async () => {
+ expect(mockPipelineQuery).toHaveBeenCalledTimes(1);
+ expect(mockPipelineQuery).toHaveBeenCalledWith({
+ fullPath: MOCK_PROJECT_FULL_PATH,
+ iid: MOCK_PIPELINE_IID,
+ });
+ });
+
+ it('renders CI header state', () => {
+ expect(findCiHeader().exists()).toBe(true);
+ });
+
it('renders empty state', () => {
expect(findEmptyState().exists()).toBe(true);
});
@@ -30,4 +107,42 @@ describe('Bridge Show Page', () => {
expect(findSidebar().exists()).toBe(true);
});
});
+
+ describe('sidebar expansion', () => {
+ beforeEach(() => {
+ mockPipelineQuery.mockResolvedValue(mockPipelineQueryResponse);
+ createComponentWithApollo();
+ waitForPromises();
+ });
+
+ describe('on resize', () => {
+ it.each`
+ breakpoint | isSidebarExpanded
+ ${'xs'} | ${false}
+ ${'sm'} | ${false}
+ ${'md'} | ${true}
+ ${'lg'} | ${true}
+ ${'xl'} | ${true}
+ `(
+ 'sets isSidebarExpanded to `$isSidebarExpanded` when the breakpoint is "$breakpoint"',
+ async ({ breakpoint, isSidebarExpanded }) => {
+ jest.spyOn(GlBreakpointInstance, 'getBreakpointSize').mockReturnValue(breakpoint);
+
+ window.dispatchEvent(new Event('resize'));
+ await nextTick();
+
+ expect(findSidebar().exists()).toBe(isSidebarExpanded);
+ },
+ );
+ });
+
+ it('toggles expansion on button click', async () => {
+ expect(findSidebar().exists()).toBe(true);
+
+ wrapper.vm.toggleSidebar();
+ await nextTick();
+
+ expect(findSidebar().exists()).toBe(false);
+ });
+ });
});
diff --git a/spec/frontend/jobs/bridge/components/empty_state_spec.js b/spec/frontend/jobs/bridge/components/empty_state_spec.js
index 83642450118..38c55b296f0 100644
--- a/spec/frontend/jobs/bridge/components/empty_state_spec.js
+++ b/spec/frontend/jobs/bridge/components/empty_state_spec.js
@@ -6,14 +6,13 @@ import { MOCK_EMPTY_ILLUSTRATION_PATH, MOCK_PATH_TO_DOWNSTREAM } from '../mock_d
describe('Bridge Empty State', () => {
let wrapper;
- const createComponent = (props) => {
+ const createComponent = ({ downstreamPipelinePath }) => {
wrapper = shallowMount(BridgeEmptyState, {
provide: {
emptyStateIllustrationPath: MOCK_EMPTY_ILLUSTRATION_PATH,
},
propsData: {
- downstreamPipelinePath: MOCK_PATH_TO_DOWNSTREAM,
- ...props,
+ downstreamPipelinePath,
},
});
};
@@ -28,7 +27,7 @@ describe('Bridge Empty State', () => {
describe('template', () => {
beforeEach(() => {
- createComponent();
+ createComponent({ downstreamPipelinePath: MOCK_PATH_TO_DOWNSTREAM });
});
it('renders illustration', () => {
diff --git a/spec/frontend/jobs/bridge/components/sidebar_spec.js b/spec/frontend/jobs/bridge/components/sidebar_spec.js
index ba4018753af..5006d4f08a6 100644
--- a/spec/frontend/jobs/bridge/components/sidebar_spec.js
+++ b/spec/frontend/jobs/bridge/components/sidebar_spec.js
@@ -1,24 +1,38 @@
import { GlButton, GlDropdown } from '@gitlab/ui';
-import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
-import { nextTick } from 'vue';
import { shallowMount } from '@vue/test-utils';
import BridgeSidebar from '~/jobs/bridge/components/sidebar.vue';
-import { BUILD_NAME } from '../mock_data';
+import CommitBlock from '~/jobs/components/commit_block.vue';
+import { mockCommit, mockJob } from '../mock_data';
describe('Bridge Sidebar', () => {
let wrapper;
- const createComponent = () => {
+ const MockHeaderEl = {
+ getBoundingClientRect() {
+ return {
+ bottom: '40',
+ };
+ },
+ };
+
+ const createComponent = ({ featureFlag } = {}) => {
wrapper = shallowMount(BridgeSidebar, {
provide: {
- buildName: BUILD_NAME,
+ glFeatures: {
+ triggerJobRetryAction: featureFlag,
+ },
+ },
+ propsData: {
+ bridgeJob: mockJob,
+ commit: mockCommit,
},
});
};
- const findSidebar = () => wrapper.find('aside');
+ const findJobTitle = () => wrapper.find('h4');
+ const findCommitBlock = () => wrapper.findComponent(CommitBlock);
const findRetryDropdown = () => wrapper.find(GlDropdown);
- const findToggle = () => wrapper.find(GlButton);
+ const findToggleBtn = () => wrapper.findComponent(GlButton);
afterEach(() => {
wrapper.destroy();
@@ -29,8 +43,23 @@ describe('Bridge Sidebar', () => {
createComponent();
});
- it('renders retry dropdown', () => {
- expect(findRetryDropdown().exists()).toBe(true);
+ it('renders job name', () => {
+ expect(findJobTitle().text()).toBe(mockJob.name);
+ });
+
+ it('renders commit information', () => {
+ expect(findCommitBlock().exists()).toBe(true);
+ });
+ });
+
+ describe('styles', () => {
+ beforeEach(async () => {
+ jest.spyOn(document, 'querySelector').mockReturnValue(MockHeaderEl);
+ createComponent();
+ });
+
+ it('calculates root styles correctly', () => {
+ expect(wrapper.attributes('style')).toBe('width: 290px; top: 40px;');
});
});
@@ -39,38 +68,32 @@ describe('Bridge Sidebar', () => {
createComponent();
});
- it('toggles expansion on button click', async () => {
- expect(findSidebar().classes()).not.toContain('gl-display-none');
+ it('emits toggle sidebar event on button click', async () => {
+ expect(wrapper.emitted('toggleSidebar')).toBe(undefined);
- findToggle().vm.$emit('click');
- await nextTick();
+ findToggleBtn().vm.$emit('click');
- expect(findSidebar().classes()).toContain('gl-display-none');
+ expect(wrapper.emitted('toggleSidebar')).toHaveLength(1);
});
+ });
- describe('on resize', () => {
- it.each`
- breakpoint | isSidebarExpanded
- ${'xs'} | ${false}
- ${'sm'} | ${false}
- ${'md'} | ${true}
- ${'lg'} | ${true}
- ${'xl'} | ${true}
- `(
- 'sets isSidebarExpanded to `$isSidebarExpanded` when the breakpoint is "$breakpoint"',
- async ({ breakpoint, isSidebarExpanded }) => {
- jest.spyOn(GlBreakpointInstance, 'getBreakpointSize').mockReturnValue(breakpoint);
-
- window.dispatchEvent(new Event('resize'));
- await nextTick();
-
- if (isSidebarExpanded) {
- expect(findSidebar().classes()).not.toContain('gl-display-none');
- } else {
- expect(findSidebar().classes()).toContain('gl-display-none');
- }
- },
- );
+ describe('retry action', () => {
+ describe('when feature flag is ON', () => {
+ beforeEach(() => {
+ createComponent({ featureFlag: true });
+ });
+
+ it('renders retry dropdown', () => {
+ expect(findRetryDropdown().exists()).toBe(true);
+ });
+ });
+
+ describe('when feature flag is OFF', () => {
+ it('does not render retry dropdown', () => {
+ createComponent({ featureFlag: false });
+
+ expect(findRetryDropdown().exists()).toBe(false);
+ });
});
});
});
diff --git a/spec/frontend/jobs/bridge/mock_data.js b/spec/frontend/jobs/bridge/mock_data.js
index 146d1a062ac..4084bb54163 100644
--- a/spec/frontend/jobs/bridge/mock_data.js
+++ b/spec/frontend/jobs/bridge/mock_data.js
@@ -1,3 +1,102 @@
export const MOCK_EMPTY_ILLUSTRATION_PATH = '/path/to/svg';
export const MOCK_PATH_TO_DOWNSTREAM = '/path/to/downstream/pipeline';
-export const BUILD_NAME = 'Child Pipeline Trigger';
+export const MOCK_BUILD_ID = '1331';
+export const MOCK_PIPELINE_IID = '174';
+export const MOCK_PROJECT_FULL_PATH = '/root/project/';
+export const MOCK_SHA = '38f3d89147765427a7ce58be28cd76d14efa682a';
+
+export const mockCommit = {
+ id: `gid://gitlab/CommitPresenter/${MOCK_SHA}`,
+ shortId: '38f3d891',
+ title: 'Update .gitlab-ci.yml file',
+ webPath: `/root/project/-/commit/${MOCK_SHA}`,
+ __typename: 'Commit',
+};
+
+export const mockJob = {
+ createdAt: '2021-12-10T09:05:45Z',
+ id: 'gid://gitlab/Ci::Build/1331',
+ name: 'triggerJobName',
+ scheduledAt: null,
+ startedAt: '2021-12-10T09:13:43Z',
+ status: 'SUCCESS',
+ triggered: null,
+ detailedStatus: {
+ id: '1',
+ detailsPath: '/root/project/-/jobs/1331',
+ icon: 'status_success',
+ group: 'success',
+ text: 'passed',
+ tooltip: 'passed',
+ __typename: 'DetailedStatus',
+ },
+ downstreamPipeline: {
+ id: '1',
+ path: '/root/project/-/pipelines/175',
+ },
+ stage: {
+ id: '1',
+ name: 'build',
+ __typename: 'CiStage',
+ },
+ __typename: 'CiJob',
+};
+
+export const mockUser = {
+ id: 'gid://gitlab/User/1',
+ avatarUrl: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ name: 'Administrator',
+ username: 'root',
+ webPath: '/root',
+ webUrl: 'http://gdk.test:3000/root',
+ status: {
+ message: 'making great things',
+ __typename: 'UserStatus',
+ },
+ __typename: 'UserCore',
+};
+
+export const mockStage = {
+ id: '1',
+ name: 'build',
+ jobs: {
+ nodes: [mockJob],
+ __typename: 'CiJobConnection',
+ },
+ __typename: 'CiStage',
+};
+
+export const mockPipelineQueryResponse = {
+ data: {
+ project: {
+ id: '1',
+ pipeline: {
+ commit: mockCommit,
+ id: 'gid://gitlab/Ci::Pipeline/174',
+ iid: '88',
+ path: '/root/project/-/pipelines/174',
+ sha: MOCK_SHA,
+ ref: 'main',
+ refPath: 'path/to/ref',
+ user: mockUser,
+ detailedStatus: {
+ id: '1',
+ icon: 'status_failed',
+ group: 'failed',
+ __typename: 'DetailedStatus',
+ },
+ stages: {
+ edges: [
+ {
+ node: mockStage,
+ __typename: 'CiStageEdge',
+ },
+ ],
+ __typename: 'CiStageConnection',
+ },
+ __typename: 'Pipeline',
+ },
+ __typename: 'Project',
+ },
+ },
+};
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 482d0df4e9a..05988eecb10 100644
--- a/spec/frontend/jobs/components/table/job_table_app_spec.js
+++ b/spec/frontend/jobs/components/table/job_table_app_spec.js
@@ -114,6 +114,8 @@ describe('Job table app', () => {
await wrapper.vm.$nextTick();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
jobs: {
pageInfo: {
diff --git a/spec/frontend/labels/delete_label_modal_spec.js b/spec/frontend/labels/delete_label_modal_spec.js
index c1e6ce87990..98049538948 100644
--- a/spec/frontend/labels/delete_label_modal_spec.js
+++ b/spec/frontend/labels/delete_label_modal_spec.js
@@ -13,6 +13,10 @@ describe('DeleteLabelModal', () => {
subjectName: 'GitLab Org',
destroyPath: `${TEST_HOST}/2`,
},
+ {
+ labelName: 'admin label',
+ destroyPath: `${TEST_HOST}/3`,
+ },
];
beforeEach(() => {
@@ -22,8 +26,12 @@ describe('DeleteLabelModal', () => {
const button = document.createElement('button');
button.setAttribute('class', 'js-delete-label-modal-button');
button.setAttribute('data-label-name', x.labelName);
- button.setAttribute('data-subject-name', x.subjectName);
button.setAttribute('data-destroy-path', x.destroyPath);
+
+ if (x.subjectName) {
+ button.setAttribute('data-subject-name', x.subjectName);
+ }
+
button.innerHTML = 'Action';
buttonContainer.appendChild(button);
});
@@ -62,6 +70,7 @@ describe('DeleteLabelModal', () => {
index
${0}
${1}
+ ${2}
`(`when multiple buttons exist`, ({ index }) => {
beforeEach(() => {
initDeleteLabelModal();
@@ -69,14 +78,22 @@ describe('DeleteLabelModal', () => {
});
it('correct props are passed to gl-modal', () => {
- expect(findModal().querySelector('.modal-title').innerHTML).toContain(
- buttons[index].labelName,
- );
- expect(findModal().querySelector('.modal-body').innerHTML).toContain(
- buttons[index].subjectName,
- );
+ const button = buttons[index];
+
+ expect(findModal().querySelector('.modal-title').innerHTML).toContain(button.labelName);
+
+ if (button.subjectName) {
+ expect(findModal().querySelector('.modal-body').textContent).toContain(
+ `${button.labelName} will be permanently deleted from ${button.subjectName}. This cannot be undone.`,
+ );
+ } else {
+ expect(findModal().querySelector('.modal-body').textContent).toContain(
+ `${button.labelName} will be permanently deleted. This cannot be undone.`,
+ );
+ }
+
expect(findModal().querySelector('.modal-footer .btn-danger').href).toContain(
- buttons[index].destroyPath,
+ button.destroyPath,
);
});
});
diff --git a/spec/frontend/landing_spec.js b/spec/frontend/landing_spec.js
deleted file mode 100644
index 448d8ee2e81..00000000000
--- a/spec/frontend/landing_spec.js
+++ /dev/null
@@ -1,184 +0,0 @@
-import Cookies from 'js-cookie';
-import Landing from '~/landing';
-
-describe('Landing', () => {
- const test = {};
-
- describe('class constructor', () => {
- beforeEach(() => {
- test.landingElement = {};
- test.dismissButton = {};
- test.cookieName = 'cookie_name';
-
- test.landing = new Landing(test.landingElement, test.dismissButton, test.cookieName);
- });
-
- it('should set .landing', () => {
- expect(test.landing.landingElement).toBe(test.landingElement);
- });
-
- it('should set .cookieName', () => {
- expect(test.landing.cookieName).toBe(test.cookieName);
- });
-
- it('should set .dismissButton', () => {
- expect(test.landing.dismissButton).toBe(test.dismissButton);
- });
-
- it('should set .eventWrapper', () => {
- expect(test.landing.eventWrapper).toEqual({});
- });
- });
-
- describe('toggle', () => {
- beforeEach(() => {
- test.isDismissed = false;
- test.landingElement = {
- classList: {
- toggle: jest.fn(),
- },
- };
- test.landing = {
- isDismissed: () => {},
- addEvents: () => {},
- landingElement: test.landingElement,
- };
-
- jest.spyOn(test.landing, 'isDismissed').mockReturnValue(test.isDismissed);
- jest.spyOn(test.landing, 'addEvents').mockImplementation(() => {});
-
- Landing.prototype.toggle.call(test.landing);
- });
-
- it('should call .isDismissed', () => {
- expect(test.landing.isDismissed).toHaveBeenCalled();
- });
-
- it('should call .classList.toggle', () => {
- expect(test.landingElement.classList.toggle).toHaveBeenCalledWith('hidden', test.isDismissed);
- });
-
- it('should call .addEvents', () => {
- expect(test.landing.addEvents).toHaveBeenCalled();
- });
-
- describe('if isDismissed is true', () => {
- beforeEach(() => {
- test.isDismissed = true;
- test.landingElement = {
- classList: {
- toggle: jest.fn(),
- },
- };
- test.landing = {
- isDismissed: () => {},
- addEvents: () => {},
- landingElement: test.landingElement,
- };
-
- jest.spyOn(test.landing, 'isDismissed').mockReturnValue(test.isDismissed);
- jest.spyOn(test.landing, 'addEvents').mockImplementation(() => {});
-
- test.landing.isDismissed.mockClear();
-
- Landing.prototype.toggle.call(test.landing);
- });
-
- it('should not call .addEvents', () => {
- expect(test.landing.addEvents).not.toHaveBeenCalled();
- });
- });
- });
-
- describe('addEvents', () => {
- beforeEach(() => {
- test.dismissButton = {
- addEventListener: jest.fn(),
- };
- test.eventWrapper = {};
- test.landing = {
- eventWrapper: test.eventWrapper,
- dismissButton: test.dismissButton,
- dismissLanding: () => {},
- };
-
- Landing.prototype.addEvents.call(test.landing);
- });
-
- it('should set .eventWrapper.dismissLanding', () => {
- expect(test.eventWrapper.dismissLanding).toEqual(expect.any(Function));
- });
-
- it('should call .addEventListener', () => {
- expect(test.dismissButton.addEventListener).toHaveBeenCalledWith(
- 'click',
- test.eventWrapper.dismissLanding,
- );
- });
- });
-
- describe('removeEvents', () => {
- beforeEach(() => {
- test.dismissButton = {
- removeEventListener: jest.fn(),
- };
- test.eventWrapper = { dismissLanding: () => {} };
- test.landing = {
- eventWrapper: test.eventWrapper,
- dismissButton: test.dismissButton,
- };
-
- Landing.prototype.removeEvents.call(test.landing);
- });
-
- it('should call .removeEventListener', () => {
- expect(test.dismissButton.removeEventListener).toHaveBeenCalledWith(
- 'click',
- test.eventWrapper.dismissLanding,
- );
- });
- });
-
- describe('dismissLanding', () => {
- beforeEach(() => {
- test.landingElement = {
- classList: {
- add: jest.fn(),
- },
- };
- test.cookieName = 'cookie_name';
- test.landing = { landingElement: test.landingElement, cookieName: test.cookieName };
-
- jest.spyOn(Cookies, 'set').mockImplementation(() => {});
-
- Landing.prototype.dismissLanding.call(test.landing);
- });
-
- it('should call .classList.add', () => {
- expect(test.landingElement.classList.add).toHaveBeenCalledWith('hidden');
- });
-
- it('should call Cookies.set', () => {
- expect(Cookies.set).toHaveBeenCalledWith(test.cookieName, 'true', { expires: 365 });
- });
- });
-
- describe('isDismissed', () => {
- beforeEach(() => {
- test.cookieName = 'cookie_name';
- test.landing = { cookieName: test.cookieName };
-
- jest.spyOn(Cookies, 'get').mockReturnValue('true');
-
- test.isDismissed = Landing.prototype.isDismissed.call(test.landing);
- });
-
- it('should call Cookies.get', () => {
- expect(Cookies.get).toHaveBeenCalledWith(test.cookieName);
- });
-
- it('should return a boolean', () => {
- expect(typeof test.isDismissed).toEqual('boolean');
- });
- });
-});
diff --git a/spec/frontend/lib/utils/resize_observer_spec.js b/spec/frontend/lib/utils/resize_observer_spec.js
new file mode 100644
index 00000000000..419aff28935
--- /dev/null
+++ b/spec/frontend/lib/utils/resize_observer_spec.js
@@ -0,0 +1,68 @@
+import { contentTop } from '~/lib/utils/common_utils';
+import { scrollToTargetOnResize } from '~/lib/utils/resize_observer';
+
+jest.mock('~/lib/utils/common_utils');
+
+function mockStickyHeaderSize(val) {
+ contentTop.mockReturnValue(val);
+}
+
+describe('ResizeObserver Utility', () => {
+ let observer;
+ const triggerResize = () => {
+ const entry = document.querySelector('#content-body');
+ entry.dispatchEvent(new CustomEvent(`ResizeUpdate`, { detail: { entry } }));
+ };
+
+ beforeEach(() => {
+ mockStickyHeaderSize(90);
+
+ jest.spyOn(document.documentElement, 'scrollTo');
+
+ setFixtures(`<div id="content-body"><div class="target">element to scroll to</div></div>`);
+
+ const target = document.querySelector('.target');
+
+ jest.spyOn(target, 'getBoundingClientRect').mockReturnValue({ top: 200 });
+
+ observer = scrollToTargetOnResize({
+ target: '.target',
+ container: '#content-body',
+ });
+ });
+
+ afterEach(() => {
+ contentTop.mockReset();
+ });
+
+ describe('Observer behavior', () => {
+ it('returns null for empty target', () => {
+ observer = scrollToTargetOnResize({
+ target: '',
+ container: '#content-body',
+ });
+
+ expect(observer).toBe(null);
+ });
+
+ 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 });
+ });
+
+ const interactionEvents = ['mousedown', 'touchstart', 'keydown', 'wheel'];
+ it.each(interactionEvents)('does not hijack scroll after user input from %s', (eventType) => {
+ const event = new Event(eventType);
+ document.dispatchEvent(event);
+
+ triggerResize();
+
+ expect(document.documentElement.scrollTo).not.toHaveBeenCalledWith();
+ });
+ });
+});
diff --git a/spec/frontend/line_highlighter_spec.js b/spec/frontend/line_highlighter_spec.js
deleted file mode 100644
index 97ae6c0e3b7..00000000000
--- a/spec/frontend/line_highlighter_spec.js
+++ /dev/null
@@ -1,275 +0,0 @@
-/* eslint-disable no-return-assign, no-new, no-underscore-dangle */
-
-import $ from 'jquery';
-import * as utils from '~/lib/utils/common_utils';
-import LineHighlighter from '~/line_highlighter';
-
-describe('LineHighlighter', () => {
- const testContext = {};
-
- const clickLine = (number, eventData = {}) => {
- if ($.isEmptyObject(eventData)) {
- return $(`#L${number}`).click();
- }
- const e = $.Event('click', eventData);
- return $(`#L${number}`).trigger(e);
- };
- beforeEach(() => {
- loadFixtures('static/line_highlighter.html');
- testContext.class = new LineHighlighter();
- testContext.css = testContext.class.highlightLineClass;
- return (testContext.spies = {
- __setLocationHash__: jest
- .spyOn(testContext.class, '__setLocationHash__')
- .mockImplementation(() => {}),
- });
- });
-
- describe('behavior', () => {
- it('highlights one line given in the URL hash', () => {
- new LineHighlighter({ hash: '#L13' });
-
- expect($('#LC13')).toHaveClass(testContext.css);
- });
-
- it('highlights one line given in the URL hash with given CSS class name', () => {
- const hiliter = new LineHighlighter({ hash: '#L13', highlightLineClass: 'hilite' });
-
- expect(hiliter.highlightLineClass).toBe('hilite');
- expect($('#LC13')).toHaveClass('hilite');
- expect($('#LC13')).not.toHaveClass('hll');
- });
-
- it('highlights a range of lines given in the URL hash', () => {
- new LineHighlighter({ hash: '#L5-25' });
-
- expect($(`.${testContext.css}`).length).toBe(21);
- for (let line = 5; line <= 25; line += 1) {
- expect($(`#LC${line}`)).toHaveClass(testContext.css);
- }
- });
-
- it('highlights a range of lines given in the URL hash using GitHub format', () => {
- new LineHighlighter({ hash: '#L5-L25' });
-
- expect($(`.${testContext.css}`).length).toBe(21);
- for (let line = 5; line <= 25; line += 1) {
- expect($(`#LC${line}`)).toHaveClass(testContext.css);
- }
- });
-
- it('scrolls to the first highlighted line on initial load', () => {
- jest.spyOn(utils, 'scrollToElement');
- new LineHighlighter({ hash: '#L5-25' });
-
- expect(utils.scrollToElement).toHaveBeenCalledWith('#L5', expect.anything());
- });
-
- it('discards click events', () => {
- const clickSpy = jest.fn();
-
- $('a[data-line-number]').click(clickSpy);
-
- clickLine(13);
-
- expect(clickSpy.mock.calls[0][0].isDefaultPrevented()).toEqual(true);
- });
-
- it('handles garbage input from the hash', () => {
- const func = () => {
- return new LineHighlighter({ fileHolderSelector: '#blob-content-holder' });
- };
-
- expect(func).not.toThrow();
- });
-
- it('handles hashchange event', () => {
- const highlighter = new LineHighlighter();
-
- jest.spyOn(highlighter, 'highlightHash').mockImplementation(() => {});
-
- window.dispatchEvent(new Event('hashchange'), 'L15');
-
- expect(highlighter.highlightHash).toHaveBeenCalled();
- });
- });
-
- describe('clickHandler', () => {
- it('handles clicking on a child icon element', () => {
- const spy = jest.spyOn(testContext.class, 'setHash');
- $('#L13 [data-testid="link-icon"]').mousedown().click();
-
- expect(spy).toHaveBeenCalledWith(13);
- expect($('#LC13')).toHaveClass(testContext.css);
- });
-
- describe('without shiftKey', () => {
- it('highlights one line when clicked', () => {
- clickLine(13);
-
- expect($('#LC13')).toHaveClass(testContext.css);
- });
-
- it('unhighlights previously highlighted lines', () => {
- clickLine(13);
- clickLine(20);
-
- expect($('#LC13')).not.toHaveClass(testContext.css);
- expect($('#LC20')).toHaveClass(testContext.css);
- });
-
- it('sets the hash', () => {
- const spy = jest.spyOn(testContext.class, 'setHash');
- clickLine(13);
-
- expect(spy).toHaveBeenCalledWith(13);
- });
- });
-
- describe('with shiftKey', () => {
- it('sets the hash', () => {
- const spy = jest.spyOn(testContext.class, 'setHash');
- clickLine(13);
- clickLine(20, {
- shiftKey: true,
- });
-
- expect(spy).toHaveBeenCalledWith(13);
- expect(spy).toHaveBeenCalledWith(13, 20);
- });
-
- describe('without existing highlight', () => {
- it('highlights the clicked line', () => {
- clickLine(13, {
- shiftKey: true,
- });
-
- expect($('#LC13')).toHaveClass(testContext.css);
- expect($(`.${testContext.css}`).length).toBe(1);
- });
-
- it('sets the hash', () => {
- const spy = jest.spyOn(testContext.class, 'setHash');
- clickLine(13, {
- shiftKey: true,
- });
-
- expect(spy).toHaveBeenCalledWith(13);
- });
- });
-
- describe('with existing single-line highlight', () => {
- it('uses existing line as last line when target is lesser', () => {
- clickLine(20);
- clickLine(15, {
- shiftKey: true,
- });
-
- expect($(`.${testContext.css}`).length).toBe(6);
- for (let line = 15; line <= 20; line += 1) {
- expect($(`#LC${line}`)).toHaveClass(testContext.css);
- }
- });
-
- it('uses existing line as first line when target is greater', () => {
- clickLine(5);
- clickLine(10, {
- shiftKey: true,
- });
-
- expect($(`.${testContext.css}`).length).toBe(6);
- for (let line = 5; line <= 10; line += 1) {
- expect($(`#LC${line}`)).toHaveClass(testContext.css);
- }
- });
- });
-
- describe('with existing multi-line highlight', () => {
- beforeEach(() => {
- clickLine(10, {
- shiftKey: true,
- });
- clickLine(13, {
- shiftKey: true,
- });
- });
-
- it('uses target as first line when it is less than existing first line', () => {
- clickLine(5, {
- shiftKey: true,
- });
-
- expect($(`.${testContext.css}`).length).toBe(6);
- for (let line = 5; line <= 10; line += 1) {
- expect($(`#LC${line}`)).toHaveClass(testContext.css);
- }
- });
-
- it('uses target as last line when it is greater than existing first line', () => {
- clickLine(15, {
- shiftKey: true,
- });
-
- expect($(`.${testContext.css}`).length).toBe(6);
- for (let line = 10; line <= 15; line += 1) {
- expect($(`#LC${line}`)).toHaveClass(testContext.css);
- }
- });
- });
- });
- });
-
- describe('hashToRange', () => {
- beforeEach(() => {
- testContext.subject = testContext.class.hashToRange;
- });
-
- it('extracts a single line number from the hash', () => {
- expect(testContext.subject('#L5')).toEqual([5, null]);
- });
-
- it('extracts a range of line numbers from the hash', () => {
- expect(testContext.subject('#L5-15')).toEqual([5, 15]);
- });
-
- it('returns [null, null] when the hash is not a line number', () => {
- expect(testContext.subject('#foo')).toEqual([null, null]);
- });
- });
-
- describe('highlightLine', () => {
- beforeEach(() => {
- testContext.subject = testContext.class.highlightLine;
- });
-
- it('highlights the specified line', () => {
- testContext.subject(13);
-
- expect($('#LC13')).toHaveClass(testContext.css);
- });
-
- it('accepts a String-based number', () => {
- testContext.subject('13');
-
- expect($('#LC13')).toHaveClass(testContext.css);
- });
- });
-
- describe('setHash', () => {
- beforeEach(() => {
- testContext.subject = testContext.class.setHash;
- });
-
- it('sets the location hash for a single line', () => {
- testContext.subject(5);
-
- expect(testContext.spies.__setLocationHash__).toHaveBeenCalledWith('#L5');
- });
-
- it('sets the location hash for a range', () => {
- testContext.subject(5, 15);
-
- expect(testContext.spies.__setLocationHash__).toHaveBeenCalledWith('#L5-15');
- });
- });
-});
diff --git a/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap b/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap
index aaa0a91ffe0..681fb05a6c4 100644
--- a/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap
+++ b/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap
@@ -128,7 +128,7 @@ exports[`Dashboard template matches the default snapshot 1`] = `
emptynodatasvgpath="/images/illustrations/monitoring/no_data.svg"
emptyunabletoconnectsvgpath="/images/illustrations/monitoring/unable_to_connect.svg"
selectedstate="gettingStarted"
- settingspath="/monitoring/monitor-project/-/services/prometheus/edit"
+ settingspath="/monitoring/monitor-project/-/integrations/prometheus/edit"
/>
</div>
`;
diff --git a/spec/frontend/monitoring/components/charts/time_series_spec.js b/spec/frontend/monitoring/components/charts/time_series_spec.js
index 27f7489aa49..ff6f0b9b0c7 100644
--- a/spec/frontend/monitoring/components/charts/time_series_spec.js
+++ b/spec/frontend/monitoring/components/charts/time_series_spec.js
@@ -661,6 +661,8 @@ describe('Time series component', () => {
const commitUrl = `${mockProjectDir}/-/commit/${mockSha}`;
beforeEach(() => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
tooltip: {
type: 'deployments',
diff --git a/spec/frontend/monitoring/components/dashboard_spec.js b/spec/frontend/monitoring/components/dashboard_spec.js
index 9331048bce3..7730e7f347f 100644
--- a/spec/frontend/monitoring/components/dashboard_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_spec.js
@@ -792,6 +792,8 @@ describe('Dashboard', () => {
});
createShallowWrapper({ hasMetrics: true });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ hoveredPanel: panelRef });
return wrapper.vm.$nextTick();
diff --git a/spec/frontend/monitoring/components/dashboards_dropdown_spec.js b/spec/frontend/monitoring/components/dashboards_dropdown_spec.js
index 589354e7849..f6d30384847 100644
--- a/spec/frontend/monitoring/components/dashboards_dropdown_spec.js
+++ b/spec/frontend/monitoring/components/dashboards_dropdown_spec.js
@@ -38,6 +38,8 @@ describe('DashboardsDropdown', () => {
const findSearchInput = () => wrapper.find({ ref: 'monitorDashboardsDropdownSearch' });
const findNoItemsMsg = () => wrapper.find({ ref: 'monitorDashboardsDropdownMsg' });
const findStarredListDivider = () => wrapper.find({ ref: 'starredListDivider' });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
const setSearchTerm = (searchTerm) => wrapper.setData({ searchTerm });
beforeEach(() => {
diff --git a/spec/frontend/mr_popover/mr_popover_spec.js b/spec/frontend/mr_popover/mr_popover_spec.js
index 0c6e4211b10..36ad82e93a5 100644
--- a/spec/frontend/mr_popover/mr_popover_spec.js
+++ b/spec/frontend/mr_popover/mr_popover_spec.js
@@ -35,6 +35,8 @@ describe('MR Popover', () => {
describe('loaded state', () => {
it('matches the snapshot', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
mergeRequest: {
title: 'Updated Title',
@@ -55,6 +57,8 @@ describe('MR Popover', () => {
});
it('does not show CI Icon if there is no pipeline data', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
mergeRequest: {
state: 'opened',
diff --git a/spec/frontend/notes/components/comment_form_spec.js b/spec/frontend/notes/components/comment_form_spec.js
index c3a51c51de0..16dbf60cef4 100644
--- a/spec/frontend/notes/components/comment_form_spec.js
+++ b/spec/frontend/notes/components/comment_form_spec.js
@@ -263,6 +263,8 @@ describe('issue_comment_form component', () => {
jest.spyOn(wrapper.vm, 'stopPolling');
jest.spyOn(wrapper.vm, 'saveNote').mockResolvedValue();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
await wrapper.setData({ note: 'hello world' });
await findCommentButton().trigger('click');
@@ -388,6 +390,8 @@ describe('issue_comment_form component', () => {
it('should enable comment button if it has note', async () => {
mountComponent();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
await wrapper.setData({ note: 'Foo' });
expect(findCommentTypeDropdown().props('disabled')).toBe(false);
diff --git a/spec/frontend/notes/components/note_form_spec.js b/spec/frontend/notes/components/note_form_spec.js
index 48bfd6eac5a..d3b5ab02f24 100644
--- a/spec/frontend/notes/components/note_form_spec.js
+++ b/spec/frontend/notes/components/note_form_spec.js
@@ -257,6 +257,8 @@ describe('issue_note_form component', () => {
props = { ...props, ...options };
wrapper = createComponentWrapper();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ isSubmittingWithKeydown: true });
const textarea = wrapper.find('textarea');
diff --git a/spec/frontend/notifications/components/custom_notifications_modal_spec.js b/spec/frontend/notifications/components/custom_notifications_modal_spec.js
index 0782ec7cdd5..7a036d25559 100644
--- a/spec/frontend/notifications/components/custom_notifications_modal_spec.js
+++ b/spec/frontend/notifications/components/custom_notifications_modal_spec.js
@@ -88,6 +88,8 @@ describe('CustomNotificationsModal', () => {
beforeEach(async () => {
wrapper = createComponent();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
events: [
{ id: 'new_release', enabled: true, name: 'New release', loading: false },
@@ -211,6 +213,8 @@ describe('CustomNotificationsModal', () => {
wrapper = createComponent({ injectedProperties });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
events: [
{ id: 'new_release', enabled: true, name: 'New release', loading: false },
@@ -239,6 +243,8 @@ describe('CustomNotificationsModal', () => {
mockAxios.onPut('/api/v4/notification_settings').reply(httpStatus.NOT_FOUND, {});
wrapper = createComponent();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
events: [
{ id: 'new_release', enabled: true, name: 'New release', loading: false },
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/__snapshots__/registry_breadcrumb_spec.js.snap b/spec/frontend/packages_and_registries/container_registry/explorer/components/__snapshots__/registry_breadcrumb_spec.js.snap
deleted file mode 100644
index 7044c1285d8..00000000000
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/__snapshots__/registry_breadcrumb_spec.js.snap
+++ /dev/null
@@ -1,84 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Registry Breadcrumb when is not rootRoute renders 1`] = `
-<div
- class="gl-breadcrumbs"
->
-
- <ol
- class="breadcrumb gl-breadcrumb-list"
- >
- <li
- class="breadcrumb-item gl-breadcrumb-item"
- >
- <a
- class=""
- href="/"
- target="_self"
- >
- <span>
-
- </span>
-
- <span
- class="gl-breadcrumb-separator"
- data-testid="separator"
- >
- <svg
- aria-hidden="true"
- class="gl-icon s8"
- data-testid="angle-right-icon"
- role="img"
- >
- <use
- href="#angle-right"
- />
- </svg>
- </span>
- </a>
- </li>
- <li
- class="breadcrumb-item gl-breadcrumb-item"
- >
- <a
- class=""
- href="#"
- target="_self"
- >
- <span>
-
- </span>
-
- <!---->
- </a>
- </li>
- </ol>
-</div>
-`;
-
-exports[`Registry Breadcrumb when is rootRoute renders 1`] = `
-<div
- class="gl-breadcrumbs"
->
-
- <ol
- class="breadcrumb gl-breadcrumb-list"
- >
- <li
- class="breadcrumb-item gl-breadcrumb-item"
- >
- <a
- class=""
- href="/"
- target="_self"
- >
- <span>
-
- </span>
-
- <!---->
- </a>
- </li>
- </ol>
-</div>
-`;
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 f06300efa29..5278e730ec9 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
@@ -1,7 +1,6 @@
-import { GlDropdownItem, GlIcon } from '@gitlab/ui';
+import { GlDropdownItem, GlIcon, GlDropdown } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
-import { GlDropdown } from 'jest/packages_and_registries/container_registry/explorer/stubs';
import { useFakeDate } from 'helpers/fake_date';
import createMockApollo from 'helpers/mock_apollo_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
@@ -51,6 +50,7 @@ describe('Details Header', () => {
const findCleanup = () => findByTestId('cleanup');
const findDeleteButton = () => wrapper.findComponent(GlDropdownItem);
const findInfoIcon = () => wrapper.findComponent(GlIcon);
+ const findMenu = () => wrapper.findComponent(GlDropdown);
const waitForMetadataItems = async () => {
// Metadata items are printed by a loop in the title-area and it takes two ticks for them to be available
@@ -139,51 +139,53 @@ describe('Details Header', () => {
});
});
- describe('delete button', () => {
- it('exists', () => {
- mountComponent();
+ describe('menu', () => {
+ it.each`
+ canDelete | disabled | isVisible
+ ${true} | ${false} | ${true}
+ ${true} | ${true} | ${false}
+ ${false} | ${false} | ${false}
+ ${false} | ${true} | ${false}
+ `(
+ 'when canDelete is $canDelete and disabled is $disabled is $isVisible that the menu is visible',
+ ({ canDelete, disabled, isVisible }) => {
+ mountComponent({ propsData: { image: { ...defaultImage, canDelete }, disabled } });
- expect(findDeleteButton().exists()).toBe(true);
- });
+ expect(findMenu().exists()).toBe(isVisible);
+ },
+ );
- it('has the correct text', () => {
- mountComponent();
+ describe('delete button', () => {
+ it('exists', () => {
+ mountComponent();
- expect(findDeleteButton().text()).toBe('Delete image repository');
- });
+ expect(findDeleteButton().exists()).toBe(true);
+ });
- it('has the correct props', () => {
- mountComponent();
+ it('has the correct text', () => {
+ mountComponent();
- expect(findDeleteButton().attributes()).toMatchObject(
- expect.objectContaining({
- variant: 'danger',
- }),
- );
- });
+ expect(findDeleteButton().text()).toBe('Delete image repository');
+ });
- it('emits the correct event', () => {
- mountComponent();
+ it('has the correct props', () => {
+ mountComponent();
- findDeleteButton().vm.$emit('click');
+ expect(findDeleteButton().attributes()).toMatchObject(
+ expect.objectContaining({
+ variant: 'danger',
+ }),
+ );
+ });
- expect(wrapper.emitted('delete')).toEqual([[]]);
- });
+ it('emits the correct event', () => {
+ mountComponent();
- it.each`
- canDelete | disabled | isDisabled
- ${true} | ${false} | ${undefined}
- ${true} | ${true} | ${'true'}
- ${false} | ${false} | ${'true'}
- ${false} | ${true} | ${'true'}
- `(
- 'when canDelete is $canDelete and disabled is $disabled is $isDisabled that the button is disabled',
- ({ canDelete, disabled, isDisabled }) => {
- mountComponent({ propsData: { image: { ...defaultImage, canDelete }, disabled } });
+ findDeleteButton().vm.$emit('click');
- expect(findDeleteButton().attributes('disabled')).toBe(isDisabled);
- },
- );
+ expect(wrapper.emitted('delete')).toEqual([[]]);
+ });
+ });
});
describe('metadata items', () => {
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/empty_state_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/empty_state_spec.js
deleted file mode 100644
index f14284e9efe..00000000000
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/empty_state_spec.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import { GlEmptyState } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import component from '~/packages_and_registries/container_registry/explorer/components/details_page/empty_state.vue';
-import {
- NO_TAGS_TITLE,
- NO_TAGS_MESSAGE,
- MISSING_OR_DELETED_IMAGE_TITLE,
- MISSING_OR_DELETED_IMAGE_MESSAGE,
-} from '~/packages_and_registries/container_registry/explorer/constants';
-
-describe('EmptyTagsState component', () => {
- let wrapper;
-
- const findEmptyState = () => wrapper.find(GlEmptyState);
-
- const mountComponent = (propsData) => {
- wrapper = shallowMount(component, {
- stubs: {
- GlEmptyState,
- },
- propsData,
- });
- };
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- it('contains gl-empty-state', () => {
- mountComponent();
- expect(findEmptyState().exists()).toBe(true);
- });
-
- it.each`
- isEmptyImage | title | description
- ${false} | ${NO_TAGS_TITLE} | ${NO_TAGS_MESSAGE}
- ${true} | ${MISSING_OR_DELETED_IMAGE_TITLE} | ${MISSING_OR_DELETED_IMAGE_MESSAGE}
- `(
- 'when isEmptyImage is $isEmptyImage has the correct props',
- ({ isEmptyImage, title, description }) => {
- mountComponent({
- noContainersImage: 'foo',
- isEmptyImage,
- });
-
- expect(findEmptyState().props()).toMatchObject({
- title,
- description,
- svgPath: 'foo',
- });
- },
- );
-});
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js
index 00b1d03b7c2..057312828ff 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js
@@ -75,16 +75,19 @@ describe('tags list row', () => {
});
it.each`
- digest | disabled
- ${'foo'} | ${true}
- ${null} | ${false}
- ${null} | ${true}
- ${'foo'} | ${true}
- `('is disabled when the digest $digest and disabled is $disabled', ({ digest, disabled }) => {
- mountComponent({ tag: { ...tag, digest }, disabled });
+ digest | disabled | isDisabled
+ ${'foo'} | ${true} | ${'true'}
+ ${null} | ${true} | ${'true'}
+ ${null} | ${false} | ${undefined}
+ ${'foo'} | ${false} | ${undefined}
+ `(
+ 'disabled attribute is set to $isDisabled when the digest $digest and disabled is $disabled',
+ ({ digest, disabled, isDisabled }) => {
+ mountComponent({ tag: { ...tag, digest }, disabled });
- expect(findCheckbox().attributes('disabled')).toBe('true');
- });
+ expect(findCheckbox().attributes('disabled')).toBe(isDisabled);
+ },
+ );
it('is wired to the selected prop', () => {
mountComponent({ ...defaultProps, selected: true });
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js
index 56f12e2f0bb..0dcf988c814 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js
@@ -1,16 +1,25 @@
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { nextTick } from 'vue';
+import { GlEmptyState } from '@gitlab/ui';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { stripTypenames } from 'helpers/graphql_helpers';
-import EmptyTagsState from '~/packages_and_registries/container_registry/explorer/components/details_page/empty_state.vue';
+
import component from '~/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue';
import TagsListRow from '~/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row.vue';
import TagsLoader from '~/packages_and_registries/container_registry/explorer/components/details_page/tags_loader.vue';
import RegistryList from '~/packages_and_registries/shared/components/registry_list.vue';
+import PersistedSearch from '~/packages_and_registries/shared/components/persisted_search.vue';
import getContainerRepositoryTagsQuery from '~/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags.query.graphql';
-import { GRAPHQL_PAGE_SIZE } from '~/packages_and_registries/container_registry/explorer/constants/index';
+import {
+ GRAPHQL_PAGE_SIZE,
+ NO_TAGS_TITLE,
+ NO_TAGS_MESSAGE,
+ NO_TAGS_MATCHING_FILTERS_TITLE,
+ NO_TAGS_MATCHING_FILTERS_DESCRIPTION,
+} from '~/packages_and_registries/container_registry/explorer/constants/index';
+import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants';
import { tagsMock, imageTagsMock, tagsPageInfo } from '../../mock_data';
const localVue = createLocalVue();
@@ -21,11 +30,20 @@ describe('Tags List', () => {
let resolver;
const tags = [...tagsMock];
+ const defaultConfig = {
+ noContainersImage: 'noContainersImage',
+ };
+
+ const findPersistedSearch = () => wrapper.findComponent(PersistedSearch);
const findTagsListRow = () => wrapper.findAllComponents(TagsListRow);
const findRegistryList = () => wrapper.findComponent(RegistryList);
- const findEmptyState = () => wrapper.findComponent(EmptyTagsState);
+ const findEmptyState = () => wrapper.findComponent(GlEmptyState);
const findTagsLoader = () => wrapper.findComponent(TagsLoader);
+ const fireFirstSortUpdate = () => {
+ findPersistedSearch().vm.$emit('update', { sort: 'NAME_ASC', filters: [] });
+ };
+
const waitForApolloRequestRender = async () => {
await waitForPromises();
await nextTick();
@@ -44,7 +62,7 @@ describe('Tags List', () => {
stubs: { RegistryList },
provide() {
return {
- config: {},
+ config: defaultConfig,
};
},
});
@@ -61,10 +79,23 @@ describe('Tags List', () => {
describe('registry list', () => {
beforeEach(() => {
mountComponent();
-
+ fireFirstSortUpdate();
return waitForApolloRequestRender();
});
+ it('has a persisted search', () => {
+ expect(findPersistedSearch().props()).toMatchObject({
+ defaultOrder: 'NAME',
+ defaultSort: 'asc',
+ sortableFields: [
+ {
+ label: 'Name',
+ orderBy: 'NAME',
+ },
+ ],
+ });
+ });
+
it('binds the correct props', () => {
expect(findRegistryList().props()).toMatchObject({
title: '2 tags',
@@ -75,11 +106,13 @@ describe('Tags List', () => {
});
describe('events', () => {
- it('prev-page fetch the previous page', () => {
+ it('prev-page fetch the previous page', async () => {
findRegistryList().vm.$emit('prev-page');
expect(resolver).toHaveBeenCalledWith({
first: null,
+ name: '',
+ sort: 'NAME_ASC',
before: tagsPageInfo.startCursor,
last: GRAPHQL_PAGE_SIZE,
id: '1',
@@ -92,6 +125,8 @@ describe('Tags List', () => {
expect(resolver).toHaveBeenCalledWith({
after: tagsPageInfo.endCursor,
first: GRAPHQL_PAGE_SIZE,
+ name: '',
+ sort: 'NAME_ASC',
id: '1',
});
});
@@ -108,6 +143,7 @@ describe('Tags List', () => {
describe('list rows', () => {
it('one row exist for each tag', async () => {
mountComponent();
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
@@ -116,6 +152,7 @@ describe('Tags List', () => {
it('the correct props are bound to it', async () => {
mountComponent({ propsData: { disabled: true, id: 1 } });
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
@@ -130,7 +167,7 @@ describe('Tags List', () => {
describe('events', () => {
it('select event update the selected items', async () => {
mountComponent();
-
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
findTagsListRow().at(0).vm.$emit('select');
@@ -142,7 +179,7 @@ describe('Tags List', () => {
it('delete event emit a delete event', async () => {
mountComponent();
-
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
findTagsListRow().at(0).vm.$emit('delete');
@@ -154,32 +191,45 @@ describe('Tags List', () => {
describe('when the list of tags is empty', () => {
beforeEach(() => {
resolver = jest.fn().mockResolvedValue(imageTagsMock([]));
- });
-
- it('has the empty state', async () => {
mountComponent();
-
- await waitForApolloRequestRender();
-
- expect(findEmptyState().exists()).toBe(true);
+ fireFirstSortUpdate();
+ return waitForApolloRequestRender();
});
- it('does not show the loader', async () => {
- mountComponent();
-
- await waitForApolloRequestRender();
-
+ it('does not show the loader', () => {
expect(findTagsLoader().exists()).toBe(false);
});
- it('does not show the list', async () => {
- mountComponent();
+ it('does not show the list', () => {
+ expect(findRegistryList().exists()).toBe(false);
+ });
- await waitForApolloRequestRender();
+ describe('empty state', () => {
+ it('default empty state', () => {
+ expect(findEmptyState().props()).toMatchObject({
+ svgPath: defaultConfig.noContainersImage,
+ title: NO_TAGS_TITLE,
+ description: NO_TAGS_MESSAGE,
+ });
+ });
- expect(findRegistryList().exists()).toBe(false);
+ it('when filtered shows a filtered message', async () => {
+ findPersistedSearch().vm.$emit('update', {
+ sort: 'NAME_ASC',
+ filters: [{ type: FILTERED_SEARCH_TERM, value: { data: 'foo' } }],
+ });
+
+ await waitForApolloRequestRender();
+
+ expect(findEmptyState().props()).toMatchObject({
+ svgPath: defaultConfig.noContainersImage,
+ title: NO_TAGS_MATCHING_FILTERS_TITLE,
+ description: NO_TAGS_MATCHING_FILTERS_DESCRIPTION,
+ });
+ });
});
});
+
describe('loading state', () => {
it.each`
isImageLoading | queryExecuting | loadingVisible
@@ -191,7 +241,7 @@ describe('Tags List', () => {
'when the isImageLoading is $isImageLoading, and is $queryExecuting that the query is still executing is $loadingVisible that the loader is shown',
async ({ isImageLoading, queryExecuting, loadingVisible }) => {
mountComponent({ propsData: { isImageLoading, isMobile: false, id: 1 } });
-
+ fireFirstSortUpdate();
if (!queryExecuting) {
await waitForApolloRequestRender();
}
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/registry_breadcrumb_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/registry_breadcrumb_spec.js
deleted file mode 100644
index e5a8438f23f..00000000000
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/registry_breadcrumb_spec.js
+++ /dev/null
@@ -1,78 +0,0 @@
-import { mount } from '@vue/test-utils';
-
-import component from '~/packages_and_registries/container_registry/explorer/components/registry_breadcrumb.vue';
-
-describe('Registry Breadcrumb', () => {
- let wrapper;
- const nameGenerator = jest.fn();
-
- const routes = [
- { name: 'list', path: '/', meta: { nameGenerator, root: true } },
- { name: 'details', path: '/:id', meta: { nameGenerator } },
- ];
-
- const mountComponent = ($route) => {
- wrapper = mount(component, {
- mocks: {
- $route,
- $router: {
- options: {
- routes,
- },
- },
- },
- });
- };
-
- beforeEach(() => {
- nameGenerator.mockClear();
- });
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- describe('when is rootRoute', () => {
- beforeEach(() => {
- mountComponent(routes[0]);
- });
-
- it('renders', () => {
- expect(wrapper.element).toMatchSnapshot();
- });
-
- it('contains only a single router-link to list', () => {
- const links = wrapper.findAll('a');
-
- expect(links).toHaveLength(1);
- expect(links.at(0).attributes('href')).toBe('/');
- });
-
- it('the link text is calculated by nameGenerator', () => {
- expect(nameGenerator).toHaveBeenCalledTimes(1);
- });
- });
-
- describe('when is not rootRoute', () => {
- beforeEach(() => {
- mountComponent(routes[1]);
- });
-
- it('renders', () => {
- expect(wrapper.element).toMatchSnapshot();
- });
-
- it('contains two router-links to list and details', () => {
- const links = wrapper.findAll('a');
-
- expect(links).toHaveLength(2);
- expect(links.at(0).attributes('href')).toBe('/');
- expect(links.at(1).attributes('href')).toBe('#');
- });
-
- it('the link text is calculated by nameGenerator', () => {
- expect(nameGenerator).toHaveBeenCalledTimes(2);
- });
- });
-});
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 9b821ba8ef3..7992bead60a 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
@@ -1,4 +1,4 @@
-import { GlKeysetPagination } from '@gitlab/ui';
+import { GlKeysetPagination, GlEmptyState } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import { nextTick } from 'vue';
@@ -8,7 +8,6 @@ import axios from '~/lib/utils/axios_utils';
import DeleteImage from '~/packages_and_registries/container_registry/explorer/components/delete_image.vue';
import DeleteAlert from '~/packages_and_registries/container_registry/explorer/components/details_page/delete_alert.vue';
import DetailsHeader from '~/packages_and_registries/container_registry/explorer/components/details_page/details_header.vue';
-import EmptyTagsState from '~/packages_and_registries/container_registry/explorer/components/details_page/empty_state.vue';
import PartialCleanupAlert from '~/packages_and_registries/container_registry/explorer/components/details_page/partial_cleanup_alert.vue';
import StatusAlert from '~/packages_and_registries/container_registry/explorer/components/details_page/status_alert.vue';
import TagsList from '~/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue';
@@ -20,6 +19,8 @@ import {
ALERT_DANGER_IMAGE,
MISSING_OR_DELETED_IMAGE_BREADCRUMB,
ROOT_IMAGE_TEXT,
+ MISSING_OR_DELETED_IMAGE_TITLE,
+ MISSING_OR_DELETED_IMAGE_MESSAGE,
} from '~/packages_and_registries/container_registry/explorer/constants';
import deleteContainerRepositoryTagsMutation from '~/packages_and_registries/container_registry/explorer/graphql/mutations/delete_container_repository_tags.mutation.graphql';
import getContainerRepositoryDetailsQuery from '~/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_details.query.graphql';
@@ -50,7 +51,7 @@ describe('Details Page', () => {
const findTagsList = () => wrapper.find(TagsList);
const findDeleteAlert = () => wrapper.find(DeleteAlert);
const findDetailsHeader = () => wrapper.find(DetailsHeader);
- const findEmptyState = () => wrapper.find(EmptyTagsState);
+ const findEmptyState = () => wrapper.find(GlEmptyState);
const findPartialCleanupAlert = () => wrapper.find(PartialCleanupAlert);
const findStatusAlert = () => wrapper.find(StatusAlert);
const findDeleteImage = () => wrapper.find(DeleteImage);
@@ -61,6 +62,10 @@ describe('Details Page', () => {
updateName: jest.fn(),
};
+ const defaultConfig = {
+ noContainersImage: 'noContainersImage',
+ };
+
const cleanTags = tagsMock.map((t) => {
const result = { ...t };
// eslint-disable-next-line no-underscore-dangle
@@ -78,7 +83,7 @@ describe('Details Page', () => {
mutationResolver = jest.fn().mockResolvedValue(graphQLDeleteImageRepositoryTagsMock),
tagsResolver = jest.fn().mockResolvedValue(graphQLImageDetailsMock(imageTagsMock)),
options,
- config = {},
+ config = defaultConfig,
} = {}) => {
localVue.use(VueApollo);
@@ -154,7 +159,11 @@ describe('Details Page', () => {
await waitForApolloRequestRender();
- expect(findEmptyState().exists()).toBe(true);
+ expect(findEmptyState().props()).toMatchObject({
+ description: MISSING_OR_DELETED_IMAGE_MESSAGE,
+ svgPath: defaultConfig.noContainersImage,
+ title: MISSING_OR_DELETED_IMAGE_TITLE,
+ });
});
});
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/__snapshots__/file_sha_spec.js.snap b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/__snapshots__/file_sha_spec.js.snap
index 881d441e116..f95564e3fad 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/__snapshots__/file_sha_spec.js.snap
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/__snapshots__/file_sha_spec.js.snap
@@ -15,11 +15,14 @@ exports[`FileSha renders 1`] = `
foo
<gl-button-stub
- aria-label="Copy this value"
+ aria-label="Copy SHA"
+ aria-live="polite"
buttontextclasses=""
category="tertiary"
+ data-clipboard-handle-tooltip="false"
data-clipboard-text="foo"
icon="copy-to-clipboard"
+ id="clipboard-button-1"
size="small"
title="Copy SHA"
variant="default"
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/file_sha_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/file_sha_spec.js
index 9ce590bfb51..d7caa8ca2d8 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/file_sha_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/file_sha_spec.js
@@ -4,6 +4,8 @@ import FileSha from '~/packages_and_registries/infrastructure_registry/details/c
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
+jest.mock('lodash/uniqueId', () => (prefix) => (prefix ? `${prefix}1` : 1));
+
describe('FileSha', () => {
let wrapper;
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/__snapshots__/packages_list_app_spec.js.snap b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/__snapshots__/packages_list_app_spec.js.snap
index 99a7b8e427a..7cdf21dde46 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/__snapshots__/packages_list_app_spec.js.snap
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/__snapshots__/packages_list_app_spec.js.snap
@@ -10,10 +10,10 @@ exports[`packages_list_app renders 1`] = `
<div>
<section
- class="row empty-state text-center"
+ class="gl-display-flex empty-state gl-text-center gl-flex-direction-column"
>
<div
- class="col-12"
+ class="gl-max-w-full"
>
<div
class="svg-250 svg-content"
@@ -28,10 +28,10 @@ exports[`packages_list_app renders 1`] = `
</div>
<div
- class="col-12"
+ class="gl-max-w-full gl-m-auto"
>
<div
- class="text-content gl-mx-auto gl-my-0 gl-p-5"
+ class="gl-mx-auto gl-my-0 gl-p-5"
>
<h1
class="gl-font-size-h-display gl-line-height-36 h4"
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js
index 2fb76b98925..26569f20e94 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js
@@ -134,6 +134,8 @@ describe('packages_list', () => {
});
it('deleteItemConfirmation resets itemToBeDeleted', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ itemToBeDeleted: 1 });
wrapper.vm.deleteItemConfirmation();
expect(wrapper.vm.itemToBeDeleted).toEqual(null);
@@ -141,6 +143,8 @@ describe('packages_list', () => {
it('deleteItemConfirmation emit package:delete', () => {
const itemToBeDeleted = { id: 2 };
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ itemToBeDeleted });
wrapper.vm.deleteItemConfirmation();
return wrapper.vm.$nextTick(() => {
@@ -149,6 +153,8 @@ describe('packages_list', () => {
});
it('deleteItemCanceled resets itemToBeDeleted', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ itemToBeDeleted: 1 });
wrapper.vm.deleteItemCanceled();
expect(wrapper.vm.itemToBeDeleted).toEqual(null);
@@ -194,6 +200,8 @@ describe('packages_list', () => {
beforeEach(() => {
mountComponent();
eventSpy = jest.spyOn(Tracking, 'event');
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ itemToBeDeleted: { package_type: 'conan' } });
});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/conan_installation_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/conan_installation_spec.js.snap
index e9f80d5f512..b3d0d88be4d 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/conan_installation_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/conan_installation_spec.js.snap
@@ -23,14 +23,18 @@ exports[`ConanInstallation renders all the messages 1`] = `
<code-instruction-stub
copytext="Copy Conan Setup Command"
- instruction="conan remote add gitlab conanPath"
+ instruction="conan remote add gitlab http://gdk.test:3000/api/v4/projects/1/packages/conan"
label="Add Conan Remote"
trackingaction="copy_conan_setup_command"
trackinglabel="code_instruction"
/>
-
- <gl-sprintf-stub
- message="For more information on the Conan registry, %{linkStart}see the documentation%{linkEnd}."
- />
+ For more information on the Conan registry,
+ <gl-link-stub
+ href="/help/user/packages/conan_repository/index"
+ target="_blank"
+ >
+ see the documentation
+ </gl-link-stub>
+ .
</div>
`;
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/file_sha_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/file_sha_spec.js.snap
index 881d441e116..f95564e3fad 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/file_sha_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/file_sha_spec.js.snap
@@ -15,11 +15,14 @@ exports[`FileSha renders 1`] = `
foo
<gl-button-stub
- aria-label="Copy this value"
+ aria-label="Copy SHA"
+ aria-live="polite"
buttontextclasses=""
category="tertiary"
+ data-clipboard-handle-tooltip="false"
data-clipboard-text="foo"
icon="copy-to-clipboard"
+ id="clipboard-button-1"
size="small"
title="Copy SHA"
variant="default"
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/maven_installation_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/maven_installation_spec.js.snap
index 4865b8205ab..67f1906f6fd 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/maven_installation_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/maven_installation_spec.js.snap
@@ -19,7 +19,7 @@ exports[`MavenInstallation groovy renders all the messages 1`] = `
<code-instruction-stub
copytext="Copy add Gradle Groovy DSL repository command"
instruction="maven {
- url 'mavenPath'
+ url 'http://gdk.test:3000/api/v4/projects/1/packages/maven'
}"
label="Add Gradle Groovy DSL repository command"
multiline="true"
@@ -47,7 +47,7 @@ exports[`MavenInstallation kotlin renders all the messages 1`] = `
<code-instruction-stub
copytext="Copy add Gradle Kotlin DSL repository command"
- instruction="maven(\\"mavenPath\\")"
+ instruction="maven(\\"http://gdk.test:3000/api/v4/projects/1/packages/maven\\")"
label="Add Gradle Kotlin DSL repository command"
multiline="true"
trackingaction="copy_kotlin_add_to_source_command"
@@ -64,9 +64,15 @@ exports[`MavenInstallation maven renders all the messages 1`] = `
/>
<p>
- <gl-sprintf-stub
- message="Copy and paste this inside your %{codeStart}pom.xml%{codeEnd} %{codeStart}dependencies%{codeEnd} block."
- />
+ Copy and paste this inside your
+ <code>
+ pom.xml
+ </code>
+
+ <code>
+ dependencies
+ </code>
+ block.
</p>
<code-instruction-stub
@@ -97,9 +103,11 @@ exports[`MavenInstallation maven renders all the messages 1`] = `
</h3>
<p>
- <gl-sprintf-stub
- message="If you haven't already done so, you will need to add the below to your %{codeStart}pom.xml%{codeEnd} file."
- />
+ If you haven't already done so, you will need to add the below to your
+ <code>
+ pom.xml
+ </code>
+ file.
</p>
<code-instruction-stub
@@ -107,19 +115,19 @@ exports[`MavenInstallation maven renders all the messages 1`] = `
instruction="<repositories>
<repository>
<id>gitlab-maven</id>
- <url>mavenPath</url>
+ <url>http://gdk.test:3000/api/v4/projects/1/packages/maven</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>gitlab-maven</id>
- <url>mavenPath</url>
+ <url>http://gdk.test:3000/api/v4/projects/1/packages/maven</url>
</repository>
<snapshotRepository>
<id>gitlab-maven</id>
- <url>mavenPath</url>
+ <url>http://gdk.test:3000/api/v4/projects/1/packages/maven</url>
</snapshotRepository>
</distributionManagement>"
label=""
@@ -127,9 +135,13 @@ exports[`MavenInstallation maven renders all the messages 1`] = `
trackingaction="copy_maven_setup_xml"
trackinglabel="code_instruction"
/>
-
- <gl-sprintf-stub
- message="For more information on the Maven registry, %{linkStart}see the documentation%{linkEnd}."
- />
+ For more information on the Maven registry,
+ <gl-link-stub
+ href="/help/user/packages/maven_repository/index"
+ target="_blank"
+ >
+ see the documentation
+ </gl-link-stub>
+ .
</div>
`;
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/npm_installation_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/npm_installation_spec.js.snap
index d5649e39561..4520ae9c328 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/npm_installation_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/npm_installation_spec.js.snap
@@ -32,14 +32,18 @@ exports[`NpmInstallation renders all the messages 1`] = `
<code-instruction-stub
copytext="Copy npm setup command"
- instruction="echo @gitlab-org:registry=npmPath/ >> .npmrc"
+ instruction="echo @gitlab-org:registry=npmInstanceUrl/ >> .npmrc"
label=""
trackingaction="copy_npm_setup_command"
trackinglabel="code_instruction"
/>
-
- <gl-sprintf-stub
- message="You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
- />
+ You may also need to setup authentication using an auth token.
+ <gl-link-stub
+ href="/help/user/packages/npm_registry/index"
+ target="_blank"
+ >
+ See the documentation
+ </gl-link-stub>
+ to find out more.
</div>
`;
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/nuget_installation_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/nuget_installation_spec.js.snap
index 29ddd7b77ed..92930a6309a 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/nuget_installation_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/nuget_installation_spec.js.snap
@@ -23,14 +23,18 @@ exports[`NugetInstallation renders all the messages 1`] = `
<code-instruction-stub
copytext="Copy NuGet Setup Command"
- instruction="nuget source Add -Name \\"GitLab\\" -Source \\"nugetPath\\" -UserName <your_username> -Password <your_token>"
+ instruction="nuget source Add -Name \\"GitLab\\" -Source \\"http://gdk.test:3000/api/v4/projects/1/packages/nuget/index.json\\" -UserName <your_username> -Password <your_token>"
label="Add NuGet Source"
trackingaction="copy_nuget_setup_command"
trackinglabel="code_instruction"
/>
-
- <gl-sprintf-stub
- message="For more information on the NuGet registry, %{linkStart}see the documentation%{linkEnd}."
- />
+ For more information on the NuGet registry,
+ <gl-link-stub
+ href="/help/user/packages/nuget_repository/index"
+ target="_blank"
+ >
+ see the documentation
+ </gl-link-stub>
+ .
</div>
`;
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap
index 158bbbc3463..06ae8645101 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap
@@ -10,7 +10,7 @@ exports[`PypiInstallation renders all the messages 1`] = `
<code-instruction-stub
copytext="Copy Pip command"
data-testid="pip-command"
- instruction="pip install @gitlab-org/package-15 --extra-index-url pypiPath"
+ instruction="pip install @gitlab-org/package-15 --extra-index-url http://__token__:<your_personal_token>@gdk.test:3000/api/v4/projects/1/packages/pypi/simple"
label="Pip Command"
trackingaction="copy_pip_install_command"
trackinglabel="code_instruction"
@@ -23,16 +23,18 @@ exports[`PypiInstallation renders all the messages 1`] = `
</h3>
<p>
- <gl-sprintf-stub
- message="If you haven't already done so, you will need to add the below to your %{codeStart}.pypirc%{codeEnd} file."
- />
+ If you haven't already done so, you will need to add the below to your
+ <code>
+ .pypirc
+ </code>
+ file.
</p>
<code-instruction-stub
copytext="Copy .pypirc content"
data-testid="pypi-setup-content"
instruction="[gitlab]
-repository = pypiSetupPath
+repository = http://gdk.test:3000/api/v4/projects/1/packages/pypi
username = __token__
password = <your personal access token>"
label=""
@@ -40,9 +42,13 @@ password = <your personal access token>"
trackingaction="copy_pypi_setup_command"
trackinglabel="code_instruction"
/>
-
- <gl-sprintf-stub
- message="For more information on the PyPi registry, %{linkStart}see the documentation%{linkEnd}."
- />
+ For more information on the PyPi registry,
+ <gl-link-stub
+ href="/help/user/packages/pypi_repository/index"
+ target="_blank"
+ >
+ see the documentation
+ </gl-link-stub>
+ .
</div>
`;
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/app_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/app_spec.js
deleted file mode 100644
index 0bea84693f6..00000000000
--- a/spec/frontend/packages_and_registries/package_registry/components/details/app_spec.js
+++ /dev/null
@@ -1,408 +0,0 @@
-import { GlEmptyState, GlBadge, GlTabs, GlTab } from '@gitlab/ui';
-import { createLocalVue } from '@vue/test-utils';
-import { nextTick } from 'vue';
-import VueApollo from 'vue-apollo';
-import createMockApollo from 'helpers/mock_apollo_helper';
-import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
-import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import waitForPromises from 'helpers/wait_for_promises';
-import createFlash from '~/flash';
-
-import AdditionalMetadata from '~/packages_and_registries/package_registry/components/details/additional_metadata.vue';
-import PackagesApp from '~/packages_and_registries/package_registry/components/details/app.vue';
-import DependencyRow from '~/packages_and_registries/package_registry/components/details/dependency_row.vue';
-import InstallationCommands from '~/packages_and_registries/package_registry/components/details/installation_commands.vue';
-import PackageFiles from '~/packages_and_registries/package_registry/components/details/package_files.vue';
-import PackageHistory from '~/packages_and_registries/package_registry/components/details/package_history.vue';
-import PackageTitle from '~/packages_and_registries/package_registry/components/details/package_title.vue';
-import VersionRow from '~/packages_and_registries/package_registry/components/details/version_row.vue';
-import DeletePackage from '~/packages_and_registries/package_registry/components/functional/delete_package.vue';
-import {
- FETCH_PACKAGE_DETAILS_ERROR_MESSAGE,
- PACKAGE_TYPE_COMPOSER,
- DELETE_PACKAGE_FILE_SUCCESS_MESSAGE,
- DELETE_PACKAGE_FILE_ERROR_MESSAGE,
- PACKAGE_TYPE_NUGET,
-} from '~/packages_and_registries/package_registry/constants';
-
-import destroyPackageFileMutation from '~/packages_and_registries/package_registry/graphql/mutations/destroy_package_file.mutation.graphql';
-import getPackageDetails from '~/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql';
-import {
- packageDetailsQuery,
- packageData,
- packageVersions,
- dependencyLinks,
- emptyPackageDetailsQuery,
- packageFiles,
- packageDestroyFileMutation,
- packageDestroyFileMutationError,
-} from '../../mock_data';
-
-jest.mock('~/flash');
-useMockLocationHelper();
-
-const localVue = createLocalVue();
-
-describe('PackagesApp', () => {
- let wrapper;
- let apolloProvider;
-
- const provide = {
- packageId: '111',
- titleComponent: 'PackageTitle',
- projectName: 'projectName',
- canDelete: 'canDelete',
- svgPath: 'svgPath',
- npmPath: 'npmPath',
- npmHelpPath: 'npmHelpPath',
- projectListUrl: 'projectListUrl',
- groupListUrl: 'groupListUrl',
- };
-
- function createComponent({
- resolver = jest.fn().mockResolvedValue(packageDetailsQuery()),
- fileDeleteMutationResolver = jest.fn().mockResolvedValue(packageDestroyFileMutation()),
- } = {}) {
- localVue.use(VueApollo);
-
- const requestHandlers = [
- [getPackageDetails, resolver],
- [destroyPackageFileMutation, fileDeleteMutationResolver],
- ];
- apolloProvider = createMockApollo(requestHandlers);
-
- wrapper = shallowMountExtended(PackagesApp, {
- localVue,
- apolloProvider,
- provide,
- stubs: {
- PackageTitle,
- DeletePackage,
- GlModal: {
- template: '<div></div>',
- methods: {
- show: jest.fn(),
- },
- },
- GlTabs,
- GlTab,
- },
- });
- }
-
- const findEmptyState = () => wrapper.findComponent(GlEmptyState);
- const findPackageTitle = () => wrapper.findComponent(PackageTitle);
- const findPackageHistory = () => wrapper.findComponent(PackageHistory);
- const findAdditionalMetadata = () => wrapper.findComponent(AdditionalMetadata);
- const findInstallationCommands = () => wrapper.findComponent(InstallationCommands);
- const findDeleteModal = () => wrapper.findByTestId('delete-modal');
- const findDeleteButton = () => wrapper.findByTestId('delete-package');
- const findPackageFiles = () => wrapper.findComponent(PackageFiles);
- const findDeleteFileModal = () => wrapper.findByTestId('delete-file-modal');
- const findVersionRows = () => wrapper.findAllComponents(VersionRow);
- const noVersionsMessage = () => wrapper.findByTestId('no-versions-message');
- const findDependenciesCountBadge = () => wrapper.findComponent(GlBadge);
- const findNoDependenciesMessage = () => wrapper.findByTestId('no-dependencies-message');
- const findDependencyRows = () => wrapper.findAllComponents(DependencyRow);
- const findDeletePackage = () => wrapper.findComponent(DeletePackage);
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('renders an empty state component', async () => {
- createComponent({ resolver: jest.fn().mockResolvedValue(emptyPackageDetailsQuery) });
-
- await waitForPromises();
-
- expect(findEmptyState().exists()).toBe(true);
- });
-
- it('renders the app and displays the package title', async () => {
- createComponent();
-
- await waitForPromises();
-
- expect(findPackageTitle().exists()).toBe(true);
- expect(findPackageTitle().props()).toMatchObject({
- packageEntity: expect.objectContaining(packageData()),
- });
- });
-
- it('emits an error message if the load fails', async () => {
- createComponent({ resolver: jest.fn().mockRejectedValue() });
-
- await waitForPromises();
-
- expect(createFlash).toHaveBeenCalledWith(
- expect.objectContaining({
- message: FETCH_PACKAGE_DETAILS_ERROR_MESSAGE,
- }),
- );
- });
-
- it('renders history and has the right props', async () => {
- createComponent();
-
- await waitForPromises();
-
- expect(findPackageHistory().exists()).toBe(true);
- expect(findPackageHistory().props()).toMatchObject({
- packageEntity: expect.objectContaining(packageData()),
- projectName: provide.projectName,
- });
- });
-
- it('renders additional metadata and has the right props', async () => {
- createComponent();
-
- await waitForPromises();
-
- expect(findAdditionalMetadata().exists()).toBe(true);
- expect(findAdditionalMetadata().props()).toMatchObject({
- packageEntity: expect.objectContaining(packageData()),
- });
- });
-
- it('renders installation commands and has the right props', async () => {
- createComponent();
-
- await waitForPromises();
-
- expect(findInstallationCommands().exists()).toBe(true);
- expect(findInstallationCommands().props()).toMatchObject({
- packageEntity: expect.objectContaining(packageData()),
- });
- });
-
- describe('delete package', () => {
- const originalReferrer = document.referrer;
- const setReferrer = (value = provide.projectName) => {
- Object.defineProperty(document, 'referrer', {
- value,
- configurable: true,
- });
- };
-
- afterEach(() => {
- Object.defineProperty(document, 'referrer', {
- value: originalReferrer,
- configurable: true,
- });
- });
-
- it('shows the delete confirmation modal when delete is clicked', async () => {
- createComponent();
-
- await waitForPromises();
-
- await findDeleteButton().trigger('click');
-
- expect(findDeleteModal().exists()).toBe(true);
- });
-
- describe('successful request', () => {
- it('when referrer contains project name calls window.replace with project url', async () => {
- setReferrer();
-
- createComponent();
-
- await waitForPromises();
-
- findDeletePackage().vm.$emit('end');
-
- expect(window.location.replace).toHaveBeenCalledWith(
- 'projectListUrl?showSuccessDeleteAlert=true',
- );
- });
-
- it('when referrer does not contain project name calls window.replace with group url', async () => {
- setReferrer('baz');
-
- createComponent();
-
- await waitForPromises();
-
- findDeletePackage().vm.$emit('end');
-
- expect(window.location.replace).toHaveBeenCalledWith(
- 'groupListUrl?showSuccessDeleteAlert=true',
- );
- });
- });
- });
-
- describe('package files', () => {
- it('renders the package files component and has the right props', async () => {
- const expectedFile = { ...packageFiles()[0] };
- // eslint-disable-next-line no-underscore-dangle
- delete expectedFile.__typename;
- createComponent();
-
- await waitForPromises();
-
- expect(findPackageFiles().exists()).toBe(true);
-
- expect(findPackageFiles().props('packageFiles')[0]).toMatchObject(expectedFile);
- });
-
- it('does not render the package files table when the package is composer', async () => {
- createComponent({
- resolver: jest
- .fn()
- .mockResolvedValue(packageDetailsQuery({ packageType: PACKAGE_TYPE_COMPOSER })),
- });
-
- await waitForPromises();
-
- expect(findPackageFiles().exists()).toBe(false);
- });
-
- describe('deleting a file', () => {
- const [fileToDelete] = packageFiles();
-
- const doDeleteFile = () => {
- findPackageFiles().vm.$emit('delete-file', fileToDelete);
-
- findDeleteFileModal().vm.$emit('primary');
-
- return waitForPromises();
- };
-
- it('opens a confirmation modal', async () => {
- createComponent();
-
- await waitForPromises();
-
- findPackageFiles().vm.$emit('delete-file', fileToDelete);
-
- await nextTick();
-
- expect(findDeleteFileModal().exists()).toBe(true);
- });
-
- it('confirming on the modal deletes the file and shows a success message', async () => {
- const resolver = jest.fn().mockResolvedValue(packageDetailsQuery());
- createComponent({ resolver });
-
- await waitForPromises();
-
- await doDeleteFile();
-
- expect(createFlash).toHaveBeenCalledWith(
- expect.objectContaining({
- message: DELETE_PACKAGE_FILE_SUCCESS_MESSAGE,
- }),
- );
- // we are re-fetching the package details, so we expect the resolver to have been called twice
- expect(resolver).toHaveBeenCalledTimes(2);
- });
-
- describe('errors', () => {
- it('shows an error when the mutation request fails', async () => {
- createComponent({ fileDeleteMutationResolver: jest.fn().mockRejectedValue() });
- await waitForPromises();
-
- await doDeleteFile();
-
- expect(createFlash).toHaveBeenCalledWith(
- expect.objectContaining({
- message: DELETE_PACKAGE_FILE_ERROR_MESSAGE,
- }),
- );
- });
-
- it('shows an error when the mutation request returns an error payload', async () => {
- createComponent({
- fileDeleteMutationResolver: jest
- .fn()
- .mockResolvedValue(packageDestroyFileMutationError()),
- });
- await waitForPromises();
-
- await doDeleteFile();
-
- expect(createFlash).toHaveBeenCalledWith(
- expect.objectContaining({
- message: DELETE_PACKAGE_FILE_ERROR_MESSAGE,
- }),
- );
- });
- });
- });
- });
-
- describe('versions', () => {
- it('displays the correct version count when the package has versions', async () => {
- createComponent();
-
- await waitForPromises();
-
- expect(findVersionRows()).toHaveLength(packageVersions().length);
- });
-
- it('binds the correct props', async () => {
- const [versionPackage] = packageVersions();
- // eslint-disable-next-line no-underscore-dangle
- delete versionPackage.__typename;
- delete versionPackage.tags;
-
- createComponent();
-
- await waitForPromises();
-
- expect(findVersionRows().at(0).props()).toMatchObject({
- packageEntity: expect.objectContaining(versionPackage),
- });
- });
-
- it('displays the no versions message when there are none', async () => {
- createComponent({
- resolver: jest.fn().mockResolvedValue(packageDetailsQuery({ versions: { nodes: [] } })),
- });
-
- await waitForPromises();
-
- expect(noVersionsMessage().exists()).toBe(true);
- });
- });
- describe('dependency links', () => {
- it('does not show the dependency links for a non nuget package', async () => {
- createComponent();
-
- expect(findDependenciesCountBadge().exists()).toBe(false);
- });
-
- it('shows the dependencies tab with 0 count when a nuget package with no dependencies', async () => {
- createComponent({
- resolver: jest.fn().mockResolvedValue(
- packageDetailsQuery({
- packageType: PACKAGE_TYPE_NUGET,
- dependencyLinks: { nodes: [] },
- }),
- ),
- });
-
- await waitForPromises();
-
- expect(findDependenciesCountBadge().exists()).toBe(true);
- expect(findDependenciesCountBadge().text()).toBe('0');
- expect(findNoDependenciesMessage().exists()).toBe(true);
- });
-
- it('renders the correct number of dependency rows for a nuget package', async () => {
- createComponent({
- resolver: jest.fn().mockResolvedValue(
- packageDetailsQuery({
- packageType: PACKAGE_TYPE_NUGET,
- }),
- ),
- });
- await waitForPromises();
-
- expect(findDependenciesCountBadge().exists()).toBe(true);
- expect(findDependenciesCountBadge().text()).toBe(dependencyLinks().length.toString());
- expect(findDependencyRows()).toHaveLength(dependencyLinks().length);
- });
- });
-});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/composer_installation_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/composer_installation_spec.js
index aedf20e873a..0aba8f7efc7 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/composer_installation_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/composer_installation_spec.js
@@ -7,6 +7,7 @@ import {
TRACKING_ACTION_COPY_COMPOSER_REGISTRY_INCLUDE_COMMAND,
TRACKING_ACTION_COPY_COMPOSER_PACKAGE_INCLUDE_COMMAND,
PACKAGE_TYPE_COMPOSER,
+ COMPOSER_HELP_PATH,
} from '~/packages_and_registries/package_registry/constants';
const packageEntity = { ...packageData(), packageType: PACKAGE_TYPE_COMPOSER };
@@ -24,9 +25,6 @@ describe('ComposerInstallation', () => {
function createComponent(groupListUrl = 'groupListUrl') {
wrapper = shallowMountExtended(ComposerInstallation, {
provide: {
- composerHelpPath: 'composerHelpPath',
- composerConfigRepositoryName: 'composerConfigRepositoryName',
- composerPath: 'composerPath',
groupListUrl,
},
propsData: { packageEntity },
@@ -61,7 +59,7 @@ describe('ComposerInstallation', () => {
const registryIncludeCommand = findRegistryInclude();
expect(registryIncludeCommand.exists()).toBe(true);
expect(registryIncludeCommand.props()).toMatchObject({
- instruction: `composer config repositories.composerConfigRepositoryName '{"type": "composer", "url": "composerPath"}'`,
+ instruction: `composer config repositories.${packageEntity.composerConfigRepositoryUrl} '{"type": "composer", "url": "${packageEntity.composerUrl}"}'`,
copyText: 'Copy registry include',
trackingAction: TRACKING_ACTION_COPY_COMPOSER_REGISTRY_INCLUDE_COMMAND,
});
@@ -96,7 +94,7 @@ describe('ComposerInstallation', () => {
'For more information on Composer packages in GitLab, see the documentation.',
);
expect(findHelpLink().attributes()).toMatchObject({
- href: 'composerHelpPath',
+ href: COMPOSER_HELP_PATH,
target: '_blank',
});
});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/conan_installation_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/conan_installation_spec.js
index 6b642cc21b7..bf9425def9a 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/conan_installation_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/conan_installation_spec.js
@@ -1,8 +1,12 @@
+import { GlLink, GlSprintf } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { packageData } from 'jest/packages_and_registries/package_registry/mock_data';
import ConanInstallation from '~/packages_and_registries/package_registry/components/details/conan_installation.vue';
import InstallationTitle from '~/packages_and_registries/package_registry/components/details/installation_title.vue';
-import { PACKAGE_TYPE_CONAN } from '~/packages_and_registries/package_registry/constants';
+import {
+ PACKAGE_TYPE_CONAN,
+ CONAN_HELP_PATH,
+} from '~/packages_and_registries/package_registry/constants';
import CodeInstructions from '~/vue_shared/components/registry/code_instruction.vue';
const packageEntity = { ...packageData(), packageType: PACKAGE_TYPE_CONAN };
@@ -12,16 +16,16 @@ describe('ConanInstallation', () => {
const findCodeInstructions = () => wrapper.findAllComponents(CodeInstructions);
const findInstallationTitle = () => wrapper.findComponent(InstallationTitle);
+ const findSetupDocsLink = () => wrapper.findComponent(GlLink);
function createComponent() {
wrapper = shallowMountExtended(ConanInstallation, {
- provide: {
- conanHelpPath: 'conanHelpPath',
- conanPath: 'conanPath',
- },
propsData: {
packageEntity,
},
+ stubs: {
+ GlSprintf,
+ },
});
}
@@ -58,8 +62,15 @@ describe('ConanInstallation', () => {
describe('setup commands', () => {
it('renders the correct command', () => {
expect(findCodeInstructions().at(1).props('instruction')).toBe(
- 'conan remote add gitlab conanPath',
+ `conan remote add gitlab ${packageEntity.conanUrl}`,
);
});
+
+ it('has a link to the docs', () => {
+ expect(findSetupDocsLink().attributes()).toMatchObject({
+ href: CONAN_HELP_PATH,
+ target: '_blank',
+ });
+ });
});
});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/file_sha_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/file_sha_spec.js
index ebfbbe5b864..feed7a7c46c 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/file_sha_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/file_sha_spec.js
@@ -4,6 +4,8 @@ import FileSha from '~/packages_and_registries/package_registry/components/detai
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
+jest.mock('lodash/uniqueId', () => (prefix) => (prefix ? `${prefix}1` : 1));
+
describe('FileSha', () => {
let wrapper;
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/maven_installation_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/maven_installation_spec.js
index eed7e903833..fc60039db30 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/maven_installation_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/maven_installation_spec.js
@@ -1,3 +1,4 @@
+import { GlLink, GlSprintf } from '@gitlab/ui';
import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
@@ -16,6 +17,7 @@ import {
TRACKING_ACTION_COPY_KOTLIN_INSTALL_COMMAND,
TRACKING_ACTION_COPY_KOTLIN_ADD_TO_SOURCE_COMMAND,
PACKAGE_TYPE_MAVEN,
+ MAVEN_HELP_PATH,
} from '~/packages_and_registries/package_registry/constants';
import CodeInstructions from '~/vue_shared/components/registry/code_instruction.vue';
@@ -28,9 +30,6 @@ describe('MavenInstallation', () => {
metadata: mavenMetadata(),
};
- const mavenHelpPath = 'mavenHelpPath';
- const mavenPath = 'mavenPath';
-
const xmlCodeBlock = `<dependency>
<groupId>appGroup</groupId>
<artifactId>appName</artifactId>
@@ -40,43 +39,43 @@ describe('MavenInstallation', () => {
const mavenSetupXml = `<repositories>
<repository>
<id>gitlab-maven</id>
- <url>${mavenPath}</url>
+ <url>${packageEntity.mavenUrl}</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>gitlab-maven</id>
- <url>${mavenPath}</url>
+ <url>${packageEntity.mavenUrl}</url>
</repository>
<snapshotRepository>
<id>gitlab-maven</id>
- <url>${mavenPath}</url>
+ <url>${packageEntity.mavenUrl}</url>
</snapshotRepository>
</distributionManagement>`;
const gradleGroovyInstallCommandText = `implementation 'appGroup:appName:appVersion'`;
const gradleGroovyAddSourceCommandText = `maven {
- url '${mavenPath}'
+ url '${packageEntity.mavenUrl}'
}`;
const gradleKotlinInstallCommandText = `implementation("appGroup:appName:appVersion")`;
- const gradleKotlinAddSourceCommandText = `maven("${mavenPath}")`;
+ const gradleKotlinAddSourceCommandText = `maven("${packageEntity.mavenUrl}")`;
const findCodeInstructions = () => wrapper.findAllComponents(CodeInstructions);
const findInstallationTitle = () => wrapper.findComponent(InstallationTitle);
+ const findSetupDocsLink = () => wrapper.findComponent(GlLink);
function createComponent({ data = {} } = {}) {
wrapper = shallowMountExtended(MavenInstallation, {
- provide: {
- mavenHelpPath,
- mavenPath,
- },
propsData: {
packageEntity,
},
data() {
return data;
},
+ stubs: {
+ GlSprintf,
+ },
});
}
@@ -148,6 +147,13 @@ describe('MavenInstallation', () => {
trackingAction: TRACKING_ACTION_COPY_MAVEN_SETUP,
});
});
+
+ it('has a setup link', () => {
+ expect(findSetupDocsLink().attributes()).toMatchObject({
+ href: MAVEN_HELP_PATH,
+ target: '_blank',
+ });
+ });
});
});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/npm_installation_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/npm_installation_spec.js
index b89410ede13..8c0e2d948ca 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/npm_installation_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/npm_installation_spec.js
@@ -1,4 +1,4 @@
-import { GlFormRadioGroup } from '@gitlab/ui';
+import { GlLink, GlSprintf, GlFormRadioGroup } from '@gitlab/ui';
import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
@@ -15,6 +15,7 @@ import {
YARN_PACKAGE_MANAGER,
PROJECT_PACKAGE_ENDPOINT_TYPE,
INSTANCE_PACKAGE_ENDPOINT_TYPE,
+ NPM_HELP_PATH,
} from '~/packages_and_registries/package_registry/constants';
import CodeInstructions from '~/vue_shared/components/registry/code_instruction.vue';
@@ -29,13 +30,12 @@ describe('NpmInstallation', () => {
const findCodeInstructions = () => wrapper.findAllComponents(CodeInstructions);
const findInstallationTitle = () => wrapper.findComponent(InstallationTitle);
const findEndPointTypeSector = () => wrapper.findComponent(GlFormRadioGroup);
+ const findSetupDocsLink = () => wrapper.findComponent(GlLink);
function createComponent({ data = {} } = {}) {
wrapper = shallowMountExtended(NpmInstallation, {
provide: {
- npmHelpPath: 'npmHelpPath',
- npmPath: 'npmPath',
- npmProjectPath: 'npmProjectPath',
+ npmInstanceUrl: 'npmInstanceUrl',
},
propsData: {
packageEntity,
@@ -43,6 +43,7 @@ describe('NpmInstallation', () => {
data() {
return data;
},
+ stubs: { GlSprintf },
});
}
@@ -58,6 +59,13 @@ describe('NpmInstallation', () => {
expect(wrapper.element).toMatchSnapshot();
});
+ it('has a setup link', () => {
+ expect(findSetupDocsLink().attributes()).toMatchObject({
+ href: NPM_HELP_PATH,
+ target: '_blank',
+ });
+ });
+
describe('endpoint type selector', () => {
it('has the endpoint type selector', () => {
expect(findEndPointTypeSector().exists()).toBe(true);
@@ -109,7 +117,7 @@ describe('NpmInstallation', () => {
it('renders the correct setup command', () => {
expect(findCodeInstructions().at(1).props()).toMatchObject({
- instruction: 'echo @gitlab-org:registry=npmPath/ >> .npmrc',
+ instruction: 'echo @gitlab-org:registry=npmInstanceUrl/ >> .npmrc',
multiline: false,
trackingAction: TRACKING_ACTION_COPY_NPM_SETUP_COMMAND,
});
@@ -121,7 +129,7 @@ describe('NpmInstallation', () => {
await nextTick();
expect(findCodeInstructions().at(1).props()).toMatchObject({
- instruction: `echo @gitlab-org:registry=npmProjectPath/ >> .npmrc`,
+ instruction: `echo @gitlab-org:registry=${packageEntity.npmUrl}/ >> .npmrc`,
multiline: false,
trackingAction: TRACKING_ACTION_COPY_NPM_SETUP_COMMAND,
});
@@ -131,7 +139,7 @@ describe('NpmInstallation', () => {
await nextTick();
expect(findCodeInstructions().at(1).props()).toMatchObject({
- instruction: `echo @gitlab-org:registry=npmPath/ >> .npmrc`,
+ instruction: `echo @gitlab-org:registry=npmInstanceUrl/ >> .npmrc`,
multiline: false,
trackingAction: TRACKING_ACTION_COPY_NPM_SETUP_COMMAND,
});
@@ -153,7 +161,7 @@ describe('NpmInstallation', () => {
it('renders the correct registry command', () => {
expect(findCodeInstructions().at(1).props()).toMatchObject({
- instruction: 'echo \\"@gitlab-org:registry\\" \\"npmPath/\\" >> .yarnrc',
+ instruction: 'echo \\"@gitlab-org:registry\\" \\"npmInstanceUrl/\\" >> .yarnrc',
multiline: false,
trackingAction: TRACKING_ACTION_COPY_YARN_SETUP_COMMAND,
});
@@ -165,7 +173,7 @@ describe('NpmInstallation', () => {
await nextTick();
expect(findCodeInstructions().at(1).props()).toMatchObject({
- instruction: `echo \\"@gitlab-org:registry\\" \\"npmProjectPath/\\" >> .yarnrc`,
+ instruction: `echo \\"@gitlab-org:registry\\" \\"${packageEntity.npmUrl}/\\" >> .yarnrc`,
multiline: false,
trackingAction: TRACKING_ACTION_COPY_YARN_SETUP_COMMAND,
});
@@ -175,7 +183,7 @@ describe('NpmInstallation', () => {
await nextTick();
expect(findCodeInstructions().at(1).props()).toMatchObject({
- instruction: 'echo \\"@gitlab-org:registry\\" \\"npmPath/\\" >> .yarnrc',
+ instruction: 'echo \\"@gitlab-org:registry\\" \\"npmInstanceUrl/\\" >> .yarnrc',
multiline: false,
trackingAction: TRACKING_ACTION_COPY_YARN_SETUP_COMMAND,
});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/nuget_installation_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/nuget_installation_spec.js
index c48a3f07299..d324d43258c 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/nuget_installation_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/nuget_installation_spec.js
@@ -1,3 +1,4 @@
+import { GlLink, GlSprintf } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { packageData } from 'jest/packages_and_registries/package_registry/mock_data';
import InstallationTitle from '~/packages_and_registries/package_registry/components/details/installation_title.vue';
@@ -6,6 +7,7 @@ import {
TRACKING_ACTION_COPY_NUGET_INSTALL_COMMAND,
TRACKING_ACTION_COPY_NUGET_SETUP_COMMAND,
PACKAGE_TYPE_NUGET,
+ NUGET_HELP_PATH,
} from '~/packages_and_registries/package_registry/constants';
import CodeInstructions from '~/vue_shared/components/registry/code_instruction.vue';
@@ -15,21 +17,18 @@ describe('NugetInstallation', () => {
let wrapper;
const nugetInstallationCommandStr = 'nuget install @gitlab-org/package-15 -Source "GitLab"';
- const nugetSetupCommandStr =
- 'nuget source Add -Name "GitLab" -Source "nugetPath" -UserName <your_username> -Password <your_token>';
+ const nugetSetupCommandStr = `nuget source Add -Name "GitLab" -Source "${packageEntity.nugetUrl}" -UserName <your_username> -Password <your_token>`;
const findCodeInstructions = () => wrapper.findAllComponents(CodeInstructions);
const findInstallationTitle = () => wrapper.findComponent(InstallationTitle);
+ const findSetupDocsLink = () => wrapper.findComponent(GlLink);
function createComponent() {
wrapper = shallowMountExtended(NugetInstallation, {
- provide: {
- nugetHelpPath: 'nugetHelpPath',
- nugetPath: 'nugetPath',
- },
propsData: {
packageEntity,
},
+ stubs: { GlSprintf },
});
}
@@ -71,5 +70,12 @@ describe('NugetInstallation', () => {
trackingAction: TRACKING_ACTION_COPY_NUGET_SETUP_COMMAND,
});
});
+
+ it('it has docs link', () => {
+ expect(findSetupDocsLink().attributes()).toMatchObject({
+ href: NUGET_HELP_PATH,
+ target: '_blank',
+ });
+ });
});
});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/package_files_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/package_files_spec.js
index 042b2026199..f8a4ba8f3bc 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/package_files_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/package_files_spec.js
@@ -28,8 +28,8 @@ describe('Package Files', () => {
const createComponent = ({ packageFiles = [file], canDelete = true } = {}) => {
wrapper = mountExtended(PackageFiles, {
- provide: { canDelete },
propsData: {
+ canDelete,
packageFiles,
},
stubs: {
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/pypi_installation_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/pypi_installation_spec.js
index 410c1b65348..f2fef6436a6 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/pypi_installation_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/pypi_installation_spec.js
@@ -1,3 +1,4 @@
+import { GlLink, GlSprintf } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { packageData } from 'jest/packages_and_registries/package_registry/mock_data';
import InstallationTitle from '~/packages_and_registries/package_registry/components/details/installation_title.vue';
@@ -6,6 +7,7 @@ import {
PACKAGE_TYPE_PYPI,
TRACKING_ACTION_COPY_PIP_INSTALL_COMMAND,
TRACKING_ACTION_COPY_PYPI_SETUP_COMMAND,
+ PYPI_HELP_PATH,
} from '~/packages_and_registries/package_registry/constants';
const packageEntity = { ...packageData(), packageType: PACKAGE_TYPE_PYPI };
@@ -13,9 +15,9 @@ const packageEntity = { ...packageData(), packageType: PACKAGE_TYPE_PYPI };
describe('PypiInstallation', () => {
let wrapper;
- const pipCommandStr = 'pip install @gitlab-org/package-15 --extra-index-url pypiPath';
+ const pipCommandStr = `pip install @gitlab-org/package-15 --extra-index-url ${packageEntity.pypiUrl}`;
const pypiSetupStr = `[gitlab]
-repository = pypiSetupPath
+repository = ${packageEntity.pypiSetupUrl}
username = __token__
password = <your personal access token>`;
@@ -23,17 +25,16 @@ password = <your personal access token>`;
const setupInstruction = () => wrapper.findByTestId('pypi-setup-content');
const findInstallationTitle = () => wrapper.findComponent(InstallationTitle);
+ const findSetupDocsLink = () => wrapper.findComponent(GlLink);
function createComponent() {
wrapper = shallowMountExtended(PypiInstallation, {
- provide: {
- pypiHelpPath: 'pypiHelpPath',
- pypiPath: 'pypiPath',
- pypiSetupPath: 'pypiSetupPath',
- },
propsData: {
packageEntity,
},
+ stubs: {
+ GlSprintf,
+ },
});
}
@@ -76,5 +77,12 @@ password = <your personal access token>`;
trackingAction: TRACKING_ACTION_COPY_PYPI_SETUP_COMMAND,
});
});
+
+ it('has a link to the docs', () => {
+ expect(findSetupDocsLink().attributes()).toMatchObject({
+ href: PYPI_HELP_PATH,
+ target: '_blank',
+ });
+ });
});
});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/list/__snapshots__/package_list_row_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/list/__snapshots__/package_list_row_spec.js.snap
index 165ee962417..18a99f70756 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/list/__snapshots__/package_list_row_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/components/list/__snapshots__/package_list_row_spec.js.snap
@@ -22,16 +22,20 @@ exports[`packages_list_row renders 1`] = `
<div
class="gl-display-flex gl-align-items-center gl-mr-3 gl-min-w-0"
>
- <gl-link-stub
+ <router-link-stub
+ ariacurrentvalue="page"
class="gl-text-body gl-min-w-0"
data-qa-selector="package_link"
- href="http://gdk.test:3000/gitlab-org/gitlab-test/-/packages/111"
+ data-testid="details-link"
+ event="click"
+ tag="a"
+ to="[object Object]"
>
<gl-truncate-stub
position="end"
text="@gitlab-org/package-15"
/>
- </gl-link-stub>
+ </router-link-stub>
<!---->
diff --git a/spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js b/spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js
index 292667ec47c..9467a613b2a 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js
@@ -1,7 +1,11 @@
-import { GlLink, GlSprintf } from '@gitlab/ui';
+import { GlSprintf } from '@gitlab/ui';
+import { createLocalVue } from '@vue/test-utils';
+import VueRouter from 'vue-router';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+
import PackagesListRow from '~/packages_and_registries/package_registry/components/list/package_list_row.vue';
import PackagePath from '~/packages_and_registries/shared/components/package_path.vue';
import PackageTags from '~/packages_and_registries/shared/components/package_tags.vue';
@@ -13,6 +17,9 @@ import { PACKAGE_ERROR_STATUS } from '~/packages_and_registries/package_registry
import ListItem from '~/vue_shared/components/registry/list_item.vue';
import { packageData, packagePipelines, packageProject, packageTags } from '../../mock_data';
+const localVue = createLocalVue();
+localVue.use(VueRouter);
+
describe('packages_list_row', () => {
let wrapper;
@@ -28,7 +35,7 @@ describe('packages_list_row', () => {
const findDeleteButton = () => wrapper.findByTestId('action-delete');
const findPackageIconAndName = () => wrapper.find(PackageIconAndName);
const findListItem = () => wrapper.findComponent(ListItem);
- const findPackageLink = () => wrapper.findComponent(GlLink);
+ const findPackageLink = () => wrapper.findByTestId('details-link');
const findWarningIcon = () => wrapper.findByTestId('warning-icon');
const findLeftSecondaryInfos = () => wrapper.findByTestId('left-secondary-infos');
const findPublishMethod = () => wrapper.findComponent(PublishMethod);
@@ -40,6 +47,7 @@ describe('packages_list_row', () => {
provide = defaultProvide,
} = {}) => {
wrapper = shallowMountExtended(PackagesListRow, {
+ localVue,
provide,
stubs: {
ListItem,
@@ -63,6 +71,15 @@ describe('packages_list_row', () => {
expect(wrapper.element).toMatchSnapshot();
});
+ it('has a link to navigate to the details page', () => {
+ mountComponent();
+
+ expect(findPackageLink().props()).toMatchObject({
+ event: 'click',
+ to: { name: 'details', params: { id: getIdFromGraphQLId(packageWithoutTags.id) } },
+ });
+ });
+
describe('tags', () => {
it('renders package tags when a package has tags', () => {
mountComponent({ packageEntity: packageWithTags });
@@ -120,7 +137,7 @@ describe('packages_list_row', () => {
});
it('details link is disabled', () => {
- expect(findPackageLink().attributes('disabled')).toBe('true');
+ expect(findPackageLink().props('event')).toBe('');
});
it('has a warning icon', () => {
diff --git a/spec/frontend/packages_and_registries/package_registry/mock_data.js b/spec/frontend/packages_and_registries/package_registry/mock_data.js
index 4c23b52b8a2..c6a59f20998 100644
--- a/spec/frontend/packages_and_registries/package_registry/mock_data.js
+++ b/spec/frontend/packages_and_registries/package_registry/mock_data.js
@@ -120,12 +120,22 @@ export const packageVersions = () => [
export const packageData = (extend) => ({
id: 'gid://gitlab/Packages::Package/111',
+ canDestroy: true,
name: '@gitlab-org/package-15',
packageType: 'NPM',
version: '1.0.0',
createdAt: '2020-08-17T14:23:32Z',
updatedAt: '2020-08-17T14:23:32Z',
status: 'DEFAULT',
+ mavenUrl: 'http://gdk.test:3000/api/v4/projects/1/packages/maven',
+ npmUrl: 'http://gdk.test:3000/api/v4/projects/1/packages/npm',
+ nugetUrl: 'http://gdk.test:3000/api/v4/projects/1/packages/nuget/index.json',
+ composerConfigRepositoryUrl: 'gdk.test/22',
+ composerUrl: 'http://gdk.test:3000/api/v4/group/22/-/packages/composer/packages.json',
+ conanUrl: 'http://gdk.test:3000/api/v4/projects/1/packages/conan',
+ pypiUrl:
+ 'http://__token__:<your_personal_token>@gdk.test:3000/api/v4/projects/1/packages/pypi/simple',
+ pypiSetupUrl: 'http://gdk.test:3000/api/v4/projects/1/packages/pypi',
...extend,
});
@@ -185,6 +195,7 @@ export const packageDetailsQuery = (extendPackage) => ({
project: {
id: '1',
path: 'projectPath',
+ name: 'gitlab-test',
},
tags: {
nodes: packageTags(),
diff --git a/spec/frontend/packages_and_registries/package_registry/pages/__snapshots__/list_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/pages/__snapshots__/list_spec.js.snap
index dbe3c70c3cb..ed96abe24b1 100644
--- a/spec/frontend/packages_and_registries/package_registry/pages/__snapshots__/list_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/pages/__snapshots__/list_spec.js.snap
@@ -11,10 +11,10 @@ exports[`PackagesListApp renders 1`] = `
<div>
<section
- class="row empty-state text-center"
+ class="gl-display-flex empty-state gl-text-center gl-flex-direction-column"
>
<div
- class="col-12"
+ class="gl-max-w-full"
>
<div
class="svg-250 svg-content"
@@ -29,10 +29,10 @@ exports[`PackagesListApp renders 1`] = `
</div>
<div
- class="col-12"
+ class="gl-max-w-full gl-m-auto"
>
<div
- class="text-content gl-mx-auto gl-my-0 gl-p-5"
+ class="gl-mx-auto gl-my-0 gl-p-5"
>
<h1
class="gl-font-size-h-display gl-line-height-36 h4"
diff --git a/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js b/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js
new file mode 100644
index 00000000000..637e2edf3be
--- /dev/null
+++ b/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js
@@ -0,0 +1,426 @@
+import { GlEmptyState, GlBadge, GlTabs, GlTab } from '@gitlab/ui';
+import { createLocalVue } from '@vue/test-utils';
+import { nextTick } from 'vue';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import createFlash from '~/flash';
+
+import AdditionalMetadata from '~/packages_and_registries/package_registry/components/details/additional_metadata.vue';
+import PackagesApp from '~/packages_and_registries/package_registry/pages/details.vue';
+import DependencyRow from '~/packages_and_registries/package_registry/components/details/dependency_row.vue';
+import InstallationCommands from '~/packages_and_registries/package_registry/components/details/installation_commands.vue';
+import PackageFiles from '~/packages_and_registries/package_registry/components/details/package_files.vue';
+import PackageHistory from '~/packages_and_registries/package_registry/components/details/package_history.vue';
+import PackageTitle from '~/packages_and_registries/package_registry/components/details/package_title.vue';
+import VersionRow from '~/packages_and_registries/package_registry/components/details/version_row.vue';
+import DeletePackage from '~/packages_and_registries/package_registry/components/functional/delete_package.vue';
+import {
+ FETCH_PACKAGE_DETAILS_ERROR_MESSAGE,
+ PACKAGE_TYPE_COMPOSER,
+ DELETE_PACKAGE_FILE_SUCCESS_MESSAGE,
+ DELETE_PACKAGE_FILE_ERROR_MESSAGE,
+ PACKAGE_TYPE_NUGET,
+} from '~/packages_and_registries/package_registry/constants';
+
+import destroyPackageFileMutation from '~/packages_and_registries/package_registry/graphql/mutations/destroy_package_file.mutation.graphql';
+import getPackageDetails from '~/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql';
+import {
+ packageDetailsQuery,
+ packageData,
+ packageVersions,
+ dependencyLinks,
+ emptyPackageDetailsQuery,
+ packageFiles,
+ packageDestroyFileMutation,
+ packageDestroyFileMutationError,
+} from '../mock_data';
+
+jest.mock('~/flash');
+useMockLocationHelper();
+
+const localVue = createLocalVue();
+
+describe('PackagesApp', () => {
+ let wrapper;
+ let apolloProvider;
+
+ const breadCrumbState = {
+ updateName: jest.fn(),
+ };
+
+ const provide = {
+ packageId: '111',
+ emptyListIllustration: 'svgPath',
+ projectListUrl: 'projectListUrl',
+ groupListUrl: 'groupListUrl',
+ breadCrumbState,
+ };
+
+ function createComponent({
+ resolver = jest.fn().mockResolvedValue(packageDetailsQuery()),
+ fileDeleteMutationResolver = jest.fn().mockResolvedValue(packageDestroyFileMutation()),
+ routeId = '1',
+ } = {}) {
+ localVue.use(VueApollo);
+
+ const requestHandlers = [
+ [getPackageDetails, resolver],
+ [destroyPackageFileMutation, fileDeleteMutationResolver],
+ ];
+ apolloProvider = createMockApollo(requestHandlers);
+
+ wrapper = shallowMountExtended(PackagesApp, {
+ localVue,
+ apolloProvider,
+ provide,
+ stubs: {
+ PackageTitle,
+ DeletePackage,
+ GlModal: {
+ template: '<div></div>',
+ methods: {
+ show: jest.fn(),
+ },
+ },
+ GlTabs,
+ GlTab,
+ },
+ mocks: {
+ $route: {
+ params: {
+ id: routeId,
+ },
+ },
+ },
+ });
+ }
+
+ const findEmptyState = () => wrapper.findComponent(GlEmptyState);
+ const findPackageTitle = () => wrapper.findComponent(PackageTitle);
+ const findPackageHistory = () => wrapper.findComponent(PackageHistory);
+ const findAdditionalMetadata = () => wrapper.findComponent(AdditionalMetadata);
+ const findInstallationCommands = () => wrapper.findComponent(InstallationCommands);
+ const findDeleteModal = () => wrapper.findByTestId('delete-modal');
+ const findDeleteButton = () => wrapper.findByTestId('delete-package');
+ const findPackageFiles = () => wrapper.findComponent(PackageFiles);
+ const findDeleteFileModal = () => wrapper.findByTestId('delete-file-modal');
+ const findVersionRows = () => wrapper.findAllComponents(VersionRow);
+ const noVersionsMessage = () => wrapper.findByTestId('no-versions-message');
+ const findDependenciesCountBadge = () => wrapper.findComponent(GlBadge);
+ const findNoDependenciesMessage = () => wrapper.findByTestId('no-dependencies-message');
+ const findDependencyRows = () => wrapper.findAllComponents(DependencyRow);
+ const findDeletePackage = () => wrapper.findComponent(DeletePackage);
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders an empty state component', async () => {
+ createComponent({ resolver: jest.fn().mockResolvedValue(emptyPackageDetailsQuery) });
+
+ await waitForPromises();
+
+ expect(findEmptyState().exists()).toBe(true);
+ });
+
+ it('renders the app and displays the package title', async () => {
+ createComponent();
+
+ await waitForPromises();
+
+ expect(findPackageTitle().exists()).toBe(true);
+ expect(findPackageTitle().props()).toMatchObject({
+ packageEntity: expect.objectContaining(packageData()),
+ });
+ });
+
+ it('emits an error message if the load fails', async () => {
+ createComponent({ resolver: jest.fn().mockRejectedValue() });
+
+ await waitForPromises();
+
+ expect(createFlash).toHaveBeenCalledWith(
+ expect.objectContaining({
+ message: FETCH_PACKAGE_DETAILS_ERROR_MESSAGE,
+ }),
+ );
+ });
+
+ it('renders history and has the right props', async () => {
+ createComponent();
+
+ await waitForPromises();
+
+ expect(findPackageHistory().exists()).toBe(true);
+ expect(findPackageHistory().props()).toMatchObject({
+ packageEntity: expect.objectContaining(packageData()),
+ projectName: packageDetailsQuery().data.package.project.name,
+ });
+ });
+
+ it('renders additional metadata and has the right props', async () => {
+ createComponent();
+
+ await waitForPromises();
+
+ expect(findAdditionalMetadata().exists()).toBe(true);
+ expect(findAdditionalMetadata().props()).toMatchObject({
+ packageEntity: expect.objectContaining(packageData()),
+ });
+ });
+
+ it('renders installation commands and has the right props', async () => {
+ createComponent();
+
+ await waitForPromises();
+
+ expect(findInstallationCommands().exists()).toBe(true);
+ expect(findInstallationCommands().props()).toMatchObject({
+ packageEntity: expect.objectContaining(packageData()),
+ });
+ });
+
+ it('calls the appropriate function to set the breadcrumbState', async () => {
+ const { name, version } = packageData();
+ createComponent();
+
+ await waitForPromises();
+
+ expect(breadCrumbState.updateName).toHaveBeenCalledWith(`${name} v ${version}`);
+ });
+
+ describe('delete package', () => {
+ const originalReferrer = document.referrer;
+ const setReferrer = (value = packageDetailsQuery().data.package.project.name) => {
+ Object.defineProperty(document, 'referrer', {
+ value,
+ configurable: true,
+ });
+ };
+
+ afterEach(() => {
+ Object.defineProperty(document, 'referrer', {
+ value: originalReferrer,
+ configurable: true,
+ });
+ });
+
+ it('shows the delete confirmation modal when delete is clicked', async () => {
+ createComponent();
+
+ await waitForPromises();
+
+ await findDeleteButton().trigger('click');
+
+ expect(findDeleteModal().exists()).toBe(true);
+ });
+
+ describe('successful request', () => {
+ it('when referrer contains project name calls window.replace with project url', async () => {
+ setReferrer();
+
+ createComponent();
+
+ await waitForPromises();
+
+ findDeletePackage().vm.$emit('end');
+
+ expect(window.location.replace).toHaveBeenCalledWith(
+ 'projectListUrl?showSuccessDeleteAlert=true',
+ );
+ });
+
+ it('when referrer does not contain project name calls window.replace with group url', async () => {
+ setReferrer('baz');
+
+ createComponent();
+
+ await waitForPromises();
+
+ findDeletePackage().vm.$emit('end');
+
+ expect(window.location.replace).toHaveBeenCalledWith(
+ 'groupListUrl?showSuccessDeleteAlert=true',
+ );
+ });
+ });
+ });
+
+ describe('package files', () => {
+ it('renders the package files component and has the right props', async () => {
+ const expectedFile = { ...packageFiles()[0] };
+ // eslint-disable-next-line no-underscore-dangle
+ delete expectedFile.__typename;
+ createComponent();
+
+ await waitForPromises();
+
+ expect(findPackageFiles().exists()).toBe(true);
+
+ expect(findPackageFiles().props('packageFiles')[0]).toMatchObject(expectedFile);
+ expect(findPackageFiles().props('canDelete')).toBe(packageData().canDestroy);
+ });
+
+ it('does not render the package files table when the package is composer', async () => {
+ createComponent({
+ resolver: jest
+ .fn()
+ .mockResolvedValue(packageDetailsQuery({ packageType: PACKAGE_TYPE_COMPOSER })),
+ });
+
+ await waitForPromises();
+
+ expect(findPackageFiles().exists()).toBe(false);
+ });
+
+ describe('deleting a file', () => {
+ const [fileToDelete] = packageFiles();
+
+ const doDeleteFile = () => {
+ findPackageFiles().vm.$emit('delete-file', fileToDelete);
+
+ findDeleteFileModal().vm.$emit('primary');
+
+ return waitForPromises();
+ };
+
+ it('opens a confirmation modal', async () => {
+ createComponent();
+
+ await waitForPromises();
+
+ findPackageFiles().vm.$emit('delete-file', fileToDelete);
+
+ await nextTick();
+
+ expect(findDeleteFileModal().exists()).toBe(true);
+ });
+
+ it('confirming on the modal deletes the file and shows a success message', async () => {
+ const resolver = jest.fn().mockResolvedValue(packageDetailsQuery());
+ createComponent({ resolver });
+
+ await waitForPromises();
+
+ await doDeleteFile();
+
+ expect(createFlash).toHaveBeenCalledWith(
+ expect.objectContaining({
+ message: DELETE_PACKAGE_FILE_SUCCESS_MESSAGE,
+ }),
+ );
+ // we are re-fetching the package details, so we expect the resolver to have been called twice
+ expect(resolver).toHaveBeenCalledTimes(2);
+ });
+
+ describe('errors', () => {
+ it('shows an error when the mutation request fails', async () => {
+ createComponent({ fileDeleteMutationResolver: jest.fn().mockRejectedValue() });
+ await waitForPromises();
+
+ await doDeleteFile();
+
+ expect(createFlash).toHaveBeenCalledWith(
+ expect.objectContaining({
+ message: DELETE_PACKAGE_FILE_ERROR_MESSAGE,
+ }),
+ );
+ });
+
+ it('shows an error when the mutation request returns an error payload', async () => {
+ createComponent({
+ fileDeleteMutationResolver: jest
+ .fn()
+ .mockResolvedValue(packageDestroyFileMutationError()),
+ });
+ await waitForPromises();
+
+ await doDeleteFile();
+
+ expect(createFlash).toHaveBeenCalledWith(
+ expect.objectContaining({
+ message: DELETE_PACKAGE_FILE_ERROR_MESSAGE,
+ }),
+ );
+ });
+ });
+ });
+ });
+
+ describe('versions', () => {
+ it('displays the correct version count when the package has versions', async () => {
+ createComponent();
+
+ await waitForPromises();
+
+ expect(findVersionRows()).toHaveLength(packageVersions().length);
+ });
+
+ it('binds the correct props', async () => {
+ const [versionPackage] = packageVersions();
+ // eslint-disable-next-line no-underscore-dangle
+ delete versionPackage.__typename;
+ delete versionPackage.tags;
+
+ createComponent();
+
+ await waitForPromises();
+
+ expect(findVersionRows().at(0).props()).toMatchObject({
+ packageEntity: expect.objectContaining(versionPackage),
+ });
+ });
+
+ it('displays the no versions message when there are none', async () => {
+ createComponent({
+ resolver: jest.fn().mockResolvedValue(packageDetailsQuery({ versions: { nodes: [] } })),
+ });
+
+ await waitForPromises();
+
+ expect(noVersionsMessage().exists()).toBe(true);
+ });
+ });
+ describe('dependency links', () => {
+ it('does not show the dependency links for a non nuget package', async () => {
+ createComponent();
+
+ expect(findDependenciesCountBadge().exists()).toBe(false);
+ });
+
+ it('shows the dependencies tab with 0 count when a nuget package with no dependencies', async () => {
+ createComponent({
+ resolver: jest.fn().mockResolvedValue(
+ packageDetailsQuery({
+ packageType: PACKAGE_TYPE_NUGET,
+ dependencyLinks: { nodes: [] },
+ }),
+ ),
+ });
+
+ await waitForPromises();
+
+ expect(findDependenciesCountBadge().exists()).toBe(true);
+ expect(findDependenciesCountBadge().text()).toBe('0');
+ expect(findNoDependenciesMessage().exists()).toBe(true);
+ });
+
+ it('renders the correct number of dependency rows for a nuget package', async () => {
+ createComponent({
+ resolver: jest.fn().mockResolvedValue(
+ packageDetailsQuery({
+ packageType: PACKAGE_TYPE_NUGET,
+ }),
+ ),
+ });
+ await waitForPromises();
+
+ expect(findDependenciesCountBadge().exists()).toBe(true);
+ expect(findDependenciesCountBadge().text()).toBe(dependencyLinks().length.toString());
+ expect(findDependencyRows()).toHaveLength(dependencyLinks().length);
+ });
+ });
+});
diff --git a/spec/frontend/packages_and_registries/shared/__snapshots__/publish_method_spec.js.snap b/spec/frontend/packages_and_registries/shared/components/__snapshots__/publish_method_spec.js.snap
index 5f243799bae..5f243799bae 100644
--- a/spec/frontend/packages_and_registries/shared/__snapshots__/publish_method_spec.js.snap
+++ b/spec/frontend/packages_and_registries/shared/components/__snapshots__/publish_method_spec.js.snap
diff --git a/spec/frontend/packages_and_registries/shared/components/__snapshots__/registry_breadcrumb_spec.js.snap b/spec/frontend/packages_and_registries/shared/components/__snapshots__/registry_breadcrumb_spec.js.snap
new file mode 100644
index 00000000000..ceae8eebaef
--- /dev/null
+++ b/spec/frontend/packages_and_registries/shared/components/__snapshots__/registry_breadcrumb_spec.js.snap
@@ -0,0 +1,96 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Registry Breadcrumb when is not rootRoute renders 1`] = `
+<nav
+ aria-label="Breadcrumb"
+ class="gl-breadcrumbs"
+>
+
+ <ol
+ class="breadcrumb gl-breadcrumb-list"
+ >
+ <li
+ class="breadcrumb-item gl-breadcrumb-item"
+ >
+ <a
+ class=""
+ href="/"
+ target="_self"
+ >
+ <span>
+
+ </span>
+
+ <span
+ class="gl-breadcrumb-separator"
+ data-testid="separator"
+ >
+ <span
+ class="gl-mx-n5"
+ >
+ <svg
+ aria-hidden="true"
+ class="gl-icon s8"
+ data-testid="angle-right-icon"
+ role="img"
+ >
+ <use
+ href="#angle-right"
+ />
+ </svg>
+ </span>
+ </span>
+ </a>
+ </li>
+
+ <!---->
+ <li
+ class="breadcrumb-item gl-breadcrumb-item"
+ >
+ <a
+ class=""
+ href="#"
+ target="_self"
+ >
+ <span>
+
+ </span>
+
+ <!---->
+ </a>
+ </li>
+
+ <!---->
+ </ol>
+</nav>
+`;
+
+exports[`Registry Breadcrumb when is rootRoute renders 1`] = `
+<nav
+ aria-label="Breadcrumb"
+ class="gl-breadcrumbs"
+>
+
+ <ol
+ class="breadcrumb gl-breadcrumb-list"
+ >
+ <li
+ class="breadcrumb-item gl-breadcrumb-item"
+ >
+ <a
+ class=""
+ href="/"
+ target="_self"
+ >
+ <span>
+
+ </span>
+
+ <!---->
+ </a>
+ </li>
+
+ <!---->
+ </ol>
+</nav>
+`;
diff --git a/spec/frontend/packages_and_registries/shared/package_icon_and_name_spec.js b/spec/frontend/packages_and_registries/shared/components/package_icon_and_name_spec.js
index d6d1970cb12..d6d1970cb12 100644
--- a/spec/frontend/packages_and_registries/shared/package_icon_and_name_spec.js
+++ b/spec/frontend/packages_and_registries/shared/components/package_icon_and_name_spec.js
diff --git a/spec/frontend/packages_and_registries/shared/package_path_spec.js b/spec/frontend/packages_and_registries/shared/components/package_path_spec.js
index 93425d4f399..93425d4f399 100644
--- a/spec/frontend/packages_and_registries/shared/package_path_spec.js
+++ b/spec/frontend/packages_and_registries/shared/components/package_path_spec.js
diff --git a/spec/frontend/packages_and_registries/shared/package_tags_spec.js b/spec/frontend/packages_and_registries/shared/components/package_tags_spec.js
index 33e96c0775e..33e96c0775e 100644
--- a/spec/frontend/packages_and_registries/shared/package_tags_spec.js
+++ b/spec/frontend/packages_and_registries/shared/components/package_tags_spec.js
diff --git a/spec/frontend/packages_and_registries/shared/packages_list_loader_spec.js b/spec/frontend/packages_and_registries/shared/components/packages_list_loader_spec.js
index 0005162e0bb..0005162e0bb 100644
--- a/spec/frontend/packages_and_registries/shared/packages_list_loader_spec.js
+++ b/spec/frontend/packages_and_registries/shared/components/packages_list_loader_spec.js
diff --git a/spec/frontend/packages_and_registries/shared/components/persisted_search_spec.js b/spec/frontend/packages_and_registries/shared/components/persisted_search_spec.js
new file mode 100644
index 00000000000..bd492a5ae8f
--- /dev/null
+++ b/spec/frontend/packages_and_registries/shared/components/persisted_search_spec.js
@@ -0,0 +1,145 @@
+import { nextTick } from 'vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue';
+import component from '~/packages_and_registries/shared/components/persisted_search.vue';
+import UrlSync from '~/vue_shared/components/url_sync.vue';
+import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
+import { getQueryParams, extractFilterAndSorting } from '~/packages_and_registries/shared/utils';
+
+jest.mock('~/packages_and_registries/shared/utils');
+
+useMockLocationHelper();
+
+describe('Persisted Search', () => {
+ let wrapper;
+
+ const defaultQueryParamsMock = {
+ filters: ['foo'],
+ sorting: { sort: 'desc', orderBy: 'test' },
+ };
+
+ const defaultProps = {
+ sortableFields: [
+ { orderBy: 'test', label: 'test' },
+ { orderBy: 'foo', label: 'foo' },
+ ],
+ defaultOrder: 'test',
+ defaultSort: 'asc',
+ };
+
+ const findRegistrySearch = () => wrapper.findComponent(RegistrySearch);
+ const findUrlSync = () => wrapper.findComponent(UrlSync);
+
+ const mountComponent = (propsData = defaultProps) => {
+ wrapper = shallowMountExtended(component, {
+ propsData,
+ stubs: {
+ UrlSync,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ extractFilterAndSorting.mockReturnValue(defaultQueryParamsMock);
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('has a registry search component', async () => {
+ mountComponent();
+
+ await nextTick();
+
+ expect(findRegistrySearch().exists()).toBe(true);
+ });
+
+ it('registry search is mounted after mount', async () => {
+ mountComponent();
+
+ expect(findRegistrySearch().exists()).toBe(false);
+ });
+
+ it('has a UrlSync component', () => {
+ mountComponent();
+
+ expect(findUrlSync().exists()).toBe(true);
+ });
+
+ it('on sorting:changed emits update event and update internal sort', async () => {
+ const payload = { sort: 'desc', orderBy: 'test' };
+
+ mountComponent();
+
+ await nextTick();
+
+ findRegistrySearch().vm.$emit('sorting:changed', payload);
+
+ await nextTick();
+
+ expect(findRegistrySearch().props('sorting')).toMatchObject(payload);
+
+ // there is always a first call on mounted that emits up default values
+ expect(wrapper.emitted('update')[1]).toEqual([
+ {
+ filters: ['foo'],
+ sort: 'TEST_DESC',
+ },
+ ]);
+ });
+
+ it('on filter:changed updates the filters', async () => {
+ const payload = ['foo'];
+
+ mountComponent();
+
+ await nextTick();
+
+ findRegistrySearch().vm.$emit('filter:changed', payload);
+
+ await nextTick();
+
+ expect(findRegistrySearch().props('filter')).toEqual(['foo']);
+ });
+
+ it('on filter:submit emits update event', async () => {
+ mountComponent();
+
+ await nextTick();
+
+ findRegistrySearch().vm.$emit('filter:submit');
+
+ expect(wrapper.emitted('update')[1]).toEqual([
+ {
+ filters: ['foo'],
+ sort: 'TEST_DESC',
+ },
+ ]);
+ });
+
+ it('on query:changed calls updateQuery from UrlSync', async () => {
+ jest.spyOn(UrlSync.methods, 'updateQuery').mockImplementation(() => {});
+
+ mountComponent();
+
+ await nextTick();
+
+ findRegistrySearch().vm.$emit('query:changed');
+
+ expect(UrlSync.methods.updateQuery).toHaveBeenCalled();
+ });
+
+ it('sets the component sorting and filtering based on the querystring', async () => {
+ mountComponent();
+
+ await nextTick();
+
+ expect(getQueryParams).toHaveBeenCalled();
+
+ expect(findRegistrySearch().props()).toMatchObject({
+ filter: defaultQueryParamsMock.filters,
+ sorting: defaultQueryParamsMock.sorting,
+ });
+ });
+});
diff --git a/spec/frontend/packages_and_registries/shared/publish_method_spec.js b/spec/frontend/packages_and_registries/shared/components/publish_method_spec.js
index fa8f8f7641a..fa8f8f7641a 100644
--- a/spec/frontend/packages_and_registries/shared/publish_method_spec.js
+++ b/spec/frontend/packages_and_registries/shared/components/publish_method_spec.js
diff --git a/spec/frontend/packages_and_registries/shared/components/registry_breadcrumb_spec.js b/spec/frontend/packages_and_registries/shared/components/registry_breadcrumb_spec.js
new file mode 100644
index 00000000000..6dfe116c285
--- /dev/null
+++ b/spec/frontend/packages_and_registries/shared/components/registry_breadcrumb_spec.js
@@ -0,0 +1,78 @@
+import { mount } from '@vue/test-utils';
+
+import component from '~/packages_and_registries/shared/components/registry_breadcrumb.vue';
+
+describe('Registry Breadcrumb', () => {
+ let wrapper;
+ const nameGenerator = jest.fn();
+
+ const routes = [
+ { name: 'list', path: '/', meta: { nameGenerator, root: true } },
+ { name: 'details', path: '/:id', meta: { nameGenerator } },
+ ];
+
+ const mountComponent = ($route) => {
+ wrapper = mount(component, {
+ mocks: {
+ $route,
+ $router: {
+ options: {
+ routes,
+ },
+ },
+ },
+ });
+ };
+
+ beforeEach(() => {
+ nameGenerator.mockClear();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('when is rootRoute', () => {
+ beforeEach(() => {
+ mountComponent(routes[0]);
+ });
+
+ it('renders', () => {
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ it('contains only a single router-link to list', () => {
+ const links = wrapper.findAll('a');
+
+ expect(links).toHaveLength(1);
+ expect(links.at(0).attributes('href')).toBe('/');
+ });
+
+ it('the link text is calculated by nameGenerator', () => {
+ expect(nameGenerator).toHaveBeenCalledTimes(1);
+ });
+ });
+
+ describe('when is not rootRoute', () => {
+ beforeEach(() => {
+ mountComponent(routes[1]);
+ });
+
+ it('renders', () => {
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ it('contains two router-links to list and details', () => {
+ const links = wrapper.findAll('a');
+
+ expect(links).toHaveLength(2);
+ expect(links.at(0).attributes('href')).toBe('/');
+ expect(links.at(1).attributes('href')).toBe('#');
+ });
+
+ it('the link text is calculated by nameGenerator', () => {
+ expect(nameGenerator).toHaveBeenCalledTimes(2);
+ });
+ });
+});
diff --git a/spec/frontend/pages/dashboard/todos/index/todos_spec.js b/spec/frontend/pages/dashboard/todos/index/todos_spec.js
index 5bba98bdf96..6a7ce80ec5a 100644
--- a/spec/frontend/pages/dashboard/todos/index/todos_spec.js
+++ b/spec/frontend/pages/dashboard/todos/index/todos_spec.js
@@ -94,13 +94,13 @@ describe('Todos', () => {
});
it('updates pending text', () => {
- expect(document.querySelector('.js-todos-pending .badge').innerHTML).toEqual(
+ expect(document.querySelector('.js-todos-pending .js-todos-badge').innerHTML).toEqual(
addDelimiter(TEST_COUNT_BIG),
);
});
it('updates done text', () => {
- expect(document.querySelector('.js-todos-done .badge').innerHTML).toEqual(
+ expect(document.querySelector('.js-todos-done .js-todos-badge').innerHTML).toEqual(
addDelimiter(TEST_DONE_COUNT_BIG),
);
});
diff --git a/spec/frontend/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js b/spec/frontend/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js
index 53c1733eab9..b700c255e8c 100644
--- a/spec/frontend/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js
+++ b/spec/frontend/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js
@@ -38,14 +38,14 @@ describe('Timezone Dropdown', () => {
const tzStr = '[UTC + 5.5] Sri Jayawardenepura';
const tzValue = 'Asia/Colombo';
- expect($inputEl.val()).toBe('UTC');
+ expect($inputEl.val()).toBe('Etc/UTC');
$(`${tzListSel}:contains('${tzStr}')`, $wrapper).trigger('click');
const val = $inputEl.val();
expect(val).toBe(tzValue);
- expect(val).not.toBe('UTC');
+ expect(val).not.toBe('Etc/UTC');
});
it('will format data array of timezones into a list of offsets', () => {
@@ -67,7 +67,7 @@ describe('Timezone Dropdown', () => {
it('will default the timezone to UTC', () => {
const tz = $inputEl.val();
- expect(tz).toBe('UTC');
+ expect(tz).toBe('Etc/UTC');
});
});
diff --git a/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js b/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js
index 0020269e4e7..8a9bb025d55 100644
--- a/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js
+++ b/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js
@@ -7,6 +7,7 @@ import {
visibilityLevelDescriptions,
visibilityOptions,
} from '~/pages/projects/shared/permissions/constants';
+import ConfirmDanger from '~/vue_shared/components/confirm_danger/confirm_danger.vue';
const defaultProps = {
currentSettings: {
@@ -47,6 +48,8 @@ const defaultProps = {
packagesAvailable: false,
packagesHelpPath: '/help/user/packages/index',
requestCveAvailable: true,
+ confirmationPhrase: 'my-fake-project',
+ showVisibilityConfirmModal: false,
};
describe('Settings Panel', () => {
@@ -104,6 +107,7 @@ describe('Settings Panel', () => {
);
const findMetricsVisibilitySettings = () => wrapper.find({ ref: 'metrics-visibility-settings' });
const findOperationsSettings = () => wrapper.find({ ref: 'operations-settings' });
+ const findConfirmDangerButton = () => wrapper.findComponent(ConfirmDanger);
afterEach(() => {
wrapper.destroy();
@@ -177,6 +181,44 @@ describe('Settings Panel', () => {
expect(findRequestAccessEnabledInput().exists()).toBe(false);
});
+
+ it('does not require confirmation if the visibility is reduced', async () => {
+ wrapper = mountComponent({
+ currentSettings: { visibilityLevel: visibilityOptions.INTERNAL },
+ });
+
+ expect(findConfirmDangerButton().exists()).toBe(false);
+
+ await findProjectVisibilityLevelInput().setValue(visibilityOptions.PRIVATE);
+
+ expect(findConfirmDangerButton().exists()).toBe(false);
+ });
+
+ describe('showVisibilityConfirmModal=true', () => {
+ beforeEach(() => {
+ wrapper = mountComponent({
+ currentSettings: { visibilityLevel: visibilityOptions.INTERNAL },
+ showVisibilityConfirmModal: true,
+ });
+ });
+
+ it('will render the confirmation dialog if the visibility is reduced', async () => {
+ expect(findConfirmDangerButton().exists()).toBe(false);
+
+ await findProjectVisibilityLevelInput().setValue(visibilityOptions.PRIVATE);
+
+ expect(findConfirmDangerButton().exists()).toBe(true);
+ });
+
+ it('emits the `confirm` event when the reduce visibility warning is confirmed', async () => {
+ expect(wrapper.emitted('confirm')).toBeUndefined();
+
+ await findProjectVisibilityLevelInput().setValue(visibilityOptions.PRIVATE);
+ await findConfirmDangerButton().vm.$emit('confirm');
+
+ expect(wrapper.emitted('confirm')).toHaveLength(1);
+ });
+ });
});
describe('Issues settings', () => {
diff --git a/spec/frontend/pages/shared/nav/sidebar_tracking_spec.js b/spec/frontend/pages/shared/nav/sidebar_tracking_spec.js
index 2c8eb8e459f..04f53e048ed 100644
--- a/spec/frontend/pages/shared/nav/sidebar_tracking_spec.js
+++ b/spec/frontend/pages/shared/nav/sidebar_tracking_spec.js
@@ -57,9 +57,9 @@ describe('~/pages/shared/nav/sidebar_tracking.js', () => {
menu.classList.add('is-over', 'is-showing-fly-out');
menuLink.click();
- expect(menu.dataset).toMatchObject({
- trackAction: 'click_menu',
- trackExtra: JSON.stringify({
+ expect(menu).toHaveTrackingAttributes({
+ action: 'click_menu',
+ extra: JSON.stringify({
sidebar_display: 'Expanded',
menu_display: 'Fly out',
}),
@@ -74,9 +74,9 @@ describe('~/pages/shared/nav/sidebar_tracking.js', () => {
submenuList.classList.add('fly-out-list');
menuLink.click();
- expect(menu.dataset).toMatchObject({
- trackAction: 'click_menu_item',
- trackExtra: JSON.stringify({
+ expect(menu).toHaveTrackingAttributes({
+ action: 'click_menu_item',
+ extra: JSON.stringify({
sidebar_display: 'Expanded',
menu_display: 'Fly out',
}),
@@ -92,9 +92,9 @@ describe('~/pages/shared/nav/sidebar_tracking.js', () => {
menu.classList.add('active');
menuLink.click();
- expect(menu.dataset).toMatchObject({
- trackAction: 'click_menu',
- trackExtra: JSON.stringify({
+ expect(menu).toHaveTrackingAttributes({
+ action: 'click_menu',
+ extra: JSON.stringify({
sidebar_display: 'Expanded',
menu_display: 'Expanded',
}),
@@ -108,9 +108,9 @@ describe('~/pages/shared/nav/sidebar_tracking.js', () => {
menu.classList.add('active');
menuLink.click();
- expect(menu.dataset).toMatchObject({
- trackAction: 'click_menu_item',
- trackExtra: JSON.stringify({
+ expect(menu).toHaveTrackingAttributes({
+ action: 'click_menu_item',
+ extra: JSON.stringify({
sidebar_display: 'Expanded',
menu_display: 'Expanded',
}),
@@ -131,9 +131,9 @@ describe('~/pages/shared/nav/sidebar_tracking.js', () => {
menu.classList.add('is-over', 'is-showing-fly-out');
menuLink.click();
- expect(menu.dataset).toMatchObject({
- trackAction: 'click_menu',
- trackExtra: JSON.stringify({
+ expect(menu).toHaveTrackingAttributes({
+ action: 'click_menu',
+ extra: JSON.stringify({
sidebar_display: 'Collapsed',
menu_display: 'Fly out',
}),
@@ -148,9 +148,9 @@ describe('~/pages/shared/nav/sidebar_tracking.js', () => {
submenuList.classList.add('fly-out-list');
menuLink.click();
- expect(menu.dataset).toMatchObject({
- trackAction: 'click_menu_item',
- trackExtra: JSON.stringify({
+ expect(menu).toHaveTrackingAttributes({
+ action: 'click_menu_item',
+ extra: JSON.stringify({
sidebar_display: 'Collapsed',
menu_display: 'Fly out',
}),
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 f4236146d33..fd581eebd1e 100644
--- a/spec/frontend/pages/shared/wikis/components/wiki_form_spec.js
+++ b/spec/frontend/pages/shared/wikis/components/wiki_form_spec.js
@@ -1,5 +1,5 @@
import { nextTick } from 'vue';
-import { GlLoadingIcon, GlModal } from '@gitlab/ui';
+import { GlLoadingIcon, GlModal, GlAlert, GlButton } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
@@ -31,25 +31,28 @@ describe('WikiForm', () => {
const findContent = () => wrapper.find('#wiki_content');
const findMessage = () => wrapper.find('#wiki_message');
const findSubmitButton = () => wrapper.findByTestId('wiki-submit-button');
- const findCancelButton = () => wrapper.findByRole('link', { name: 'Cancel' });
- const findUseNewEditorButton = () => wrapper.findByRole('button', { name: 'Use the new editor' });
+ const findCancelButton = () => wrapper.findByTestId('wiki-cancel-button');
+ const findUseNewEditorButton = () => wrapper.findByText('Use the new editor');
const findToggleEditingModeButton = () => wrapper.findByTestId('toggle-editing-mode-button');
- const findDismissContentEditorAlertButton = () =>
- wrapper.findByRole('button', { name: 'Try this later' });
+ const findDismissContentEditorAlertButton = () => wrapper.findByText('Try this later');
const findSwitchToOldEditorButton = () =>
wrapper.findByRole('button', { name: 'Switch me back to the classic editor.' });
- const findTitleHelpLink = () => wrapper.findByRole('link', { name: 'Learn more.' });
+ const findTitleHelpLink = () => wrapper.findByText('Learn more.');
const findMarkdownHelpLink = () => wrapper.findByTestId('wiki-markdown-help-link');
const findContentEditor = () => wrapper.findComponent(ContentEditor);
const findClassicEditor = () => wrapper.findComponent(MarkdownField);
const setFormat = (value) => {
const format = findFormat();
- format.find(`option[value=${value}]`).setSelected();
- format.element.dispatchEvent(new Event('change'));
+
+ return format.find(`option[value=${value}]`).setSelected();
};
- const triggerFormSubmit = () => findForm().element.dispatchEvent(new Event('submit'));
+ const triggerFormSubmit = () => {
+ findForm().element.dispatchEvent(new Event('submit'));
+
+ return nextTick();
+ };
const dispatchBeforeUnload = () => {
const e = new Event('beforeunload');
@@ -84,34 +87,14 @@ describe('WikiForm', () => {
Org: 'org',
};
- function createWrapper(
- persisted = false,
- { pageInfo, glFeatures = { wikiSwitchBetweenContentEditorRawMarkdown: false } } = {},
- ) {
- wrapper = extendedWrapper(
- mount(
- WikiForm,
- {
- provide: {
- formatOptions,
- glFeatures,
- pageInfo: {
- ...(persisted ? pageInfoPersisted : pageInfoNew),
- ...pageInfo,
- },
- },
- },
- { attachToDocument: true },
- ),
- );
- }
-
- const createShallowWrapper = (
+ function createWrapper({
+ mountFn = shallowMount,
persisted = false,
- { pageInfo, glFeatures = { wikiSwitchBetweenContentEditorRawMarkdown: false } } = {},
- ) => {
+ pageInfo,
+ glFeatures = { wikiSwitchBetweenContentEditorRawMarkdown: false },
+ } = {}) {
wrapper = extendedWrapper(
- shallowMount(WikiForm, {
+ mountFn(WikiForm, {
provide: {
formatOptions,
glFeatures,
@@ -122,10 +105,12 @@ describe('WikiForm', () => {
},
stubs: {
MarkdownField,
+ GlAlert,
+ GlButton,
},
}),
);
- };
+ }
beforeEach(() => {
trackingSpy = mockTracking(undefined, null, jest.spyOn);
@@ -147,26 +132,24 @@ describe('WikiForm', () => {
`(
'updates the commit message to $message when title is $title and persisted=$persisted',
async ({ title, message, persisted }) => {
- createWrapper(persisted);
-
- findTitle().setValue(title);
+ createWrapper({ persisted });
- await wrapper.vm.$nextTick();
+ await findTitle().setValue(title);
expect(findMessage().element.value).toBe(message);
},
);
it('sets the commit message to "Update My page" when the page first loads when persisted', async () => {
- createWrapper(true);
+ createWrapper({ persisted: true });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findMessage().element.value).toBe('Update My page');
});
it('does not trim page content by default', () => {
- createWrapper(true);
+ createWrapper({ persisted: true });
expect(findContent().element.value).toBe(' My page content ');
});
@@ -178,20 +161,16 @@ describe('WikiForm', () => {
${'asciidoc'} | ${'link:page-slug[Link title]'}
${'org'} | ${'[[page-slug]]'}
`('updates the link help message when format=$value is selected', async ({ value, text }) => {
- createWrapper();
+ createWrapper({ mountFn: mount });
- setFormat(value);
-
- await wrapper.vm.$nextTick();
+ await setFormat(value);
expect(wrapper.text()).toContain(text);
});
- it('starts with no unload warning', async () => {
+ it('starts with no unload warning', () => {
createWrapper();
- await wrapper.vm.$nextTick();
-
const e = dispatchBeforeUnload();
expect(typeof e.returnValue).not.toBe('string');
expect(e.preventDefault).not.toHaveBeenCalled();
@@ -203,20 +182,16 @@ describe('WikiForm', () => {
${false} | ${'You can specify the full path for the new file. We will automatically create any missing directories.'} | ${'/help/user/project/wiki/index#create-a-new-wiki-page'}
`(
'shows appropriate title help text and help link for when persisted=$persisted',
- async ({ persisted, titleHelpLink, titleHelpText }) => {
- createWrapper(persisted);
-
- await wrapper.vm.$nextTick();
+ ({ persisted, titleHelpLink, titleHelpText }) => {
+ createWrapper({ persisted });
expect(wrapper.text()).toContain(titleHelpText);
expect(findTitleHelpLink().attributes().href).toBe(titleHelpLink);
},
);
- it('shows correct link for wiki specific markdown docs', async () => {
- createWrapper();
-
- await wrapper.vm.$nextTick();
+ it('shows correct link for wiki specific markdown docs', () => {
+ createWrapper({ mountFn: mount });
expect(findMarkdownHelpLink().attributes().href).toBe(
'/help/user/markdown#wiki-specific-markdown',
@@ -225,12 +200,11 @@ describe('WikiForm', () => {
describe('when wiki content is updated', () => {
beforeEach(async () => {
- createWrapper(true);
+ createWrapper({ mountFn: mount, persisted: true });
const input = findContent();
- input.setValue(' Lorem ipsum dolar sit! ');
- await input.trigger('input');
+ await input.setValue(' Lorem ipsum dolar sit! ');
});
it('sets before unload warning', () => {
@@ -241,17 +215,15 @@ describe('WikiForm', () => {
describe('form submit', () => {
beforeEach(async () => {
- triggerFormSubmit();
-
- await wrapper.vm.$nextTick();
+ await triggerFormSubmit();
});
- it('when form submitted, unsets before unload warning', async () => {
+ it('when form submitted, unsets before unload warning', () => {
const e = dispatchBeforeUnload();
expect(e.preventDefault).not.toHaveBeenCalled();
});
- it('triggers wiki format tracking event', async () => {
+ it('triggers wiki format tracking event', () => {
expect(trackingSpy).toHaveBeenCalledTimes(1);
});
@@ -264,22 +236,20 @@ describe('WikiForm', () => {
describe('submit button state', () => {
it.each`
title | content | buttonState | disabledAttr
- ${'something'} | ${'something'} | ${'enabled'} | ${undefined}
- ${''} | ${'something'} | ${'disabled'} | ${'disabled'}
- ${'something'} | ${''} | ${'disabled'} | ${'disabled'}
- ${''} | ${''} | ${'disabled'} | ${'disabled'}
- ${' '} | ${' '} | ${'disabled'} | ${'disabled'}
+ ${'something'} | ${'something'} | ${'enabled'} | ${false}
+ ${''} | ${'something'} | ${'disabled'} | ${true}
+ ${'something'} | ${''} | ${'disabled'} | ${true}
+ ${''} | ${''} | ${'disabled'} | ${true}
+ ${' '} | ${' '} | ${'disabled'} | ${true}
`(
"when title='$title', content='$content', then the button is $buttonState'",
async ({ title, content, disabledAttr }) => {
createWrapper();
- findTitle().setValue(title);
- findContent().setValue(content);
+ await findTitle().setValue(title);
+ await findContent().setValue(content);
- await wrapper.vm.$nextTick();
-
- expect(findSubmitButton().attributes().disabled).toBe(disabledAttr);
+ expect(findSubmitButton().props().disabled).toBe(disabledAttr);
},
);
@@ -288,7 +258,7 @@ describe('WikiForm', () => {
${true} | ${'Save changes'}
${false} | ${'Create page'}
`('when persisted=$persisted, label is set to $buttonLabel', ({ persisted, buttonLabel }) => {
- createWrapper(persisted);
+ createWrapper({ persisted });
expect(findSubmitButton().text()).toBe(buttonLabel);
});
@@ -302,7 +272,7 @@ describe('WikiForm', () => {
`(
'when persisted=$persisted, redirects the user to appropriate path',
({ persisted, redirectLink }) => {
- createWrapper(persisted);
+ createWrapper({ persisted });
expect(findCancelButton().attributes().href).toBe(redirectLink);
},
@@ -311,7 +281,7 @@ describe('WikiForm', () => {
describe('when wikiSwitchBetweenContentEditorRawMarkdown feature flag is not enabled', () => {
beforeEach(() => {
- createShallowWrapper(true, {
+ createWrapper({
glFeatures: { wikiSwitchBetweenContentEditorRawMarkdown: false },
});
});
@@ -323,7 +293,7 @@ describe('WikiForm', () => {
describe('when wikiSwitchBetweenContentEditorRawMarkdown feature flag is enabled', () => {
beforeEach(() => {
- createShallowWrapper(true, {
+ createWrapper({
glFeatures: { wikiSwitchBetweenContentEditorRawMarkdown: true },
});
});
@@ -404,10 +374,6 @@ describe('WikiForm', () => {
});
describe('wiki content editor', () => {
- beforeEach(() => {
- createWrapper(true);
- });
-
it.each`
format | buttonExists
${'markdown'} | ${true}
@@ -415,15 +381,17 @@ describe('WikiForm', () => {
`(
'gl-alert containing "use new editor" button exists: $buttonExists if format is $format',
async ({ format, buttonExists }) => {
- setFormat(format);
+ createWrapper();
- await wrapper.vm.$nextTick();
+ await setFormat(format);
expect(findUseNewEditorButton().exists()).toBe(buttonExists);
},
);
it('gl-alert containing "use new editor" button is dismissed on clicking dismiss button', async () => {
+ createWrapper();
+
await findDismissContentEditorAlertButton().trigger('click');
expect(findUseNewEditorButton().exists()).toBe(false);
@@ -442,22 +410,24 @@ describe('WikiForm', () => {
);
};
- it('shows classic editor by default', assertOldEditorIsVisible);
+ it('shows classic editor by default', () => {
+ createWrapper({ persisted: true });
+
+ assertOldEditorIsVisible();
+ });
describe('switch format to rdoc', () => {
beforeEach(async () => {
- setFormat('rdoc');
+ createWrapper({ persisted: true });
- await wrapper.vm.$nextTick();
+ await setFormat('rdoc');
});
it('continues to show the classic editor', assertOldEditorIsVisible);
describe('switch format back to markdown', () => {
beforeEach(async () => {
- setFormat('rdoc');
-
- await wrapper.vm.$nextTick();
+ await setFormat('markdown');
});
it(
@@ -469,6 +439,7 @@ describe('WikiForm', () => {
describe('clicking "use new editor": editor fails to load', () => {
beforeEach(async () => {
+ createWrapper({ mountFn: mount });
mock.onPost(/preview-markdown/).reply(400);
await findUseNewEditorButton().trigger('click');
@@ -494,10 +465,12 @@ describe('WikiForm', () => {
});
describe('clicking "use new editor": editor loads successfully', () => {
- beforeEach(() => {
+ beforeEach(async () => {
+ createWrapper({ persisted: true, mountFn: mount });
+
mock.onPost(/preview-markdown/).reply(200, { body: '<p>hello <strong>world</strong></p>' });
- findUseNewEditorButton().trigger('click');
+ await findUseNewEditorButton().trigger('click');
});
it('shows a tip to send feedback', () => {
@@ -542,46 +515,40 @@ describe('WikiForm', () => {
});
it('unsets before unload warning on form submit', async () => {
- triggerFormSubmit();
-
- await nextTick();
+ await triggerFormSubmit();
const e = dispatchBeforeUnload();
expect(e.preventDefault).not.toHaveBeenCalled();
});
- });
- it('triggers tracking events on form submit', async () => {
- triggerFormSubmit();
+ it('triggers tracking events on form submit', async () => {
+ await triggerFormSubmit();
- await wrapper.vm.$nextTick();
-
- expect(trackingSpy).toHaveBeenCalledWith(undefined, SAVED_USING_CONTENT_EDITOR_ACTION, {
- label: WIKI_CONTENT_EDITOR_TRACKING_LABEL,
- });
+ expect(trackingSpy).toHaveBeenCalledWith(undefined, SAVED_USING_CONTENT_EDITOR_ACTION, {
+ label: WIKI_CONTENT_EDITOR_TRACKING_LABEL,
+ });
- expect(trackingSpy).toHaveBeenCalledWith(undefined, WIKI_FORMAT_UPDATED_ACTION, {
- label: WIKI_FORMAT_LABEL,
- extra: {
- value: findFormat().element.value,
- old_format: pageInfoPersisted.format,
- project_path: pageInfoPersisted.path,
- },
+ expect(trackingSpy).toHaveBeenCalledWith(undefined, WIKI_FORMAT_UPDATED_ACTION, {
+ label: WIKI_FORMAT_LABEL,
+ extra: {
+ value: findFormat().element.value,
+ old_format: pageInfoPersisted.format,
+ project_path: pageInfoPersisted.path,
+ },
+ });
});
- });
-
- it('updates content from content editor on form submit', async () => {
- // old value
- expect(findContent().element.value).toBe(' My page content ');
- // wait for content editor to load
- await waitForPromises();
+ it('updates content from content editor on form submit', async () => {
+ // old value
+ expect(findContent().element.value).toBe(' My page content ');
- triggerFormSubmit();
+ // wait for content editor to load
+ await waitForPromises();
- await wrapper.vm.$nextTick();
+ await triggerFormSubmit();
- expect(findContent().element.value).toBe('hello **world**');
+ expect(findContent().element.value).toBe('hello **world**');
+ });
});
describe('clicking "switch to classic editor"', () => {
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 cab4810cbf1..f15d5f334d6 100644
--- a/spec/frontend/pipeline_editor/components/editor/text_editor_spec.js
+++ b/spec/frontend/pipeline_editor/components/editor/text_editor_spec.js
@@ -17,19 +17,12 @@ describe('Pipeline Editor | Text editor component', () => {
let editorReadyListener;
let mockUse;
let mockRegisterCiSchema;
+ let mockEditorInstance;
+ let editorInstanceDetail;
const MockSourceEditor = {
template: '<div/>',
props: ['value', 'fileName'],
- mounted() {
- this.$emit(EDITOR_READY_EVENT);
- },
- methods: {
- getEditor: () => ({
- use: mockUse,
- registerCiSchema: mockRegisterCiSchema,
- }),
- },
};
const createComponent = (glFeatures = {}, mountFn = shallowMount) => {
@@ -58,6 +51,21 @@ describe('Pipeline Editor | Text editor component', () => {
const findEditor = () => wrapper.findComponent(MockSourceEditor);
+ beforeEach(() => {
+ editorReadyListener = jest.fn();
+ mockUse = jest.fn();
+ mockRegisterCiSchema = jest.fn();
+ mockEditorInstance = {
+ use: mockUse,
+ registerCiSchema: mockRegisterCiSchema,
+ };
+ editorInstanceDetail = {
+ detail: {
+ instance: mockEditorInstance,
+ },
+ };
+ });
+
afterEach(() => {
wrapper.destroy();
@@ -67,10 +75,6 @@ describe('Pipeline Editor | Text editor component', () => {
describe('template', () => {
beforeEach(() => {
- editorReadyListener = jest.fn();
- mockUse = jest.fn();
- mockRegisterCiSchema = jest.fn();
-
createComponent();
});
@@ -87,7 +91,7 @@ describe('Pipeline Editor | Text editor component', () => {
});
it('bubbles up events', () => {
- findEditor().vm.$emit(EDITOR_READY_EVENT);
+ findEditor().vm.$emit(EDITOR_READY_EVENT, editorInstanceDetail);
expect(editorReadyListener).toHaveBeenCalled();
});
@@ -97,11 +101,7 @@ describe('Pipeline Editor | Text editor component', () => {
describe('when `schema_linting` feature flag is on', () => {
beforeEach(() => {
createComponent({ schemaLinting: true });
- // Since the editor will have already mounted, the event will have fired.
- // To ensure we properly test this, we clear the mock and re-remit the event.
- mockRegisterCiSchema.mockClear();
- mockUse.mockClear();
- findEditor().vm.$emit(EDITOR_READY_EVENT);
+ findEditor().vm.$emit(EDITOR_READY_EVENT, editorInstanceDetail);
});
it('configures editor with syntax highlight', () => {
@@ -113,7 +113,7 @@ describe('Pipeline Editor | Text editor component', () => {
describe('when `schema_linting` feature flag is off', () => {
beforeEach(() => {
createComponent();
- findEditor().vm.$emit(EDITOR_READY_EVENT);
+ findEditor().vm.$emit(EDITOR_READY_EVENT, editorInstanceDetail);
});
it('does not call the register CI schema function', () => {
diff --git a/spec/frontend/pipeline_editor/components/header/validation_segment_spec.js b/spec/frontend/pipeline_editor/components/header/validation_segment_spec.js
index fd8a100bb2c..570323826d1 100644
--- a/spec/frontend/pipeline_editor/components/header/validation_segment_spec.js
+++ b/spec/frontend/pipeline_editor/components/header/validation_segment_spec.js
@@ -1,40 +1,61 @@
+import VueApollo from 'vue-apollo';
import { GlIcon } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
+import { shallowMount, createLocalVue } from '@vue/test-utils';
import { escape } from 'lodash';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
+import createMockApollo from 'helpers/mock_apollo_helper';
import { sprintf } from '~/locale';
import ValidationSegment, {
i18n,
} from '~/pipeline_editor/components/header/validation_segment.vue';
+import getAppStatus from '~/pipeline_editor/graphql/queries/client/app_status.query.graphql';
import {
CI_CONFIG_STATUS_INVALID,
EDITOR_APP_STATUS_EMPTY,
EDITOR_APP_STATUS_INVALID,
EDITOR_APP_STATUS_LOADING,
+ EDITOR_APP_STATUS_LINT_UNAVAILABLE,
EDITOR_APP_STATUS_VALID,
} from '~/pipeline_editor/constants';
-import { mockYmlHelpPagePath, mergeUnwrappedCiConfig, mockCiYml } from '../../mock_data';
+import {
+ mergeUnwrappedCiConfig,
+ mockCiYml,
+ mockLintUnavailableHelpPagePath,
+ mockYmlHelpPagePath,
+} from '../../mock_data';
+
+const localVue = createLocalVue();
+localVue.use(VueApollo);
describe('Validation segment component', () => {
let wrapper;
- const createComponent = ({ props = {}, appStatus }) => {
+ const mockApollo = createMockApollo();
+
+ const createComponent = ({ props = {}, appStatus = EDITOR_APP_STATUS_INVALID }) => {
+ mockApollo.clients.defaultClient.cache.writeQuery({
+ query: getAppStatus,
+ data: {
+ app: {
+ __typename: 'PipelineEditorApp',
+ status: appStatus,
+ },
+ },
+ });
+
wrapper = extendedWrapper(
shallowMount(ValidationSegment, {
+ localVue,
+ apolloProvider: mockApollo,
provide: {
ymlHelpPagePath: mockYmlHelpPagePath,
+ lintUnavailableHelpPagePath: mockLintUnavailableHelpPagePath,
},
propsData: {
ciConfig: mergeUnwrappedCiConfig(),
ciFileContent: mockCiYml,
...props,
},
- // Simulate graphQL client query result
- data() {
- return {
- appStatus,
- };
- },
}),
);
};
@@ -92,6 +113,7 @@ describe('Validation segment component', () => {
appStatus: EDITOR_APP_STATUS_INVALID,
});
});
+
it('has warning icon', () => {
expect(findIcon().props('name')).toBe('warning-solid');
});
@@ -149,4 +171,28 @@ describe('Validation segment component', () => {
});
});
});
+
+ describe('when the lint service is unavailable', () => {
+ beforeEach(() => {
+ createComponent({
+ appStatus: EDITOR_APP_STATUS_LINT_UNAVAILABLE,
+ props: {
+ ciConfig: {},
+ },
+ });
+ });
+
+ it('show a message that the service is unavailable', () => {
+ expect(findValidationMsg().text()).toBe(i18n.unavailableValidation);
+ });
+
+ it('shows the time-out icon', () => {
+ expect(findIcon().props('name')).toBe('time-out');
+ });
+
+ it('shows the learn more link', () => {
+ expect(findLearnMoreLink().attributes('href')).toBe(mockLintUnavailableHelpPagePath);
+ expect(findLearnMoreLink().text()).toBe(i18n.learnMore);
+ });
+ });
});
diff --git a/spec/frontend/pipeline_editor/components/ui/editor_tab_spec.js b/spec/frontend/pipeline_editor/components/ui/editor_tab_spec.js
index 3becf82ed6e..6206a0f6aed 100644
--- a/spec/frontend/pipeline_editor/components/ui/editor_tab_spec.js
+++ b/spec/frontend/pipeline_editor/components/ui/editor_tab_spec.js
@@ -75,34 +75,83 @@ describe('~/pipeline_editor/components/ui/editor_tab.vue', () => {
expect(mockChildMounted).toHaveBeenCalledWith(mockContent1);
});
- describe('showing the tab content depending on `isEmpty` and `isInvalid`', () => {
+ describe('alerts', () => {
+ describe('unavailable state', () => {
+ beforeEach(() => {
+ createWrapper({ props: { isUnavailable: true } });
+ });
+
+ it('shows the invalid alert when the status is invalid', () => {
+ const alert = findAlert();
+
+ expect(alert.exists()).toBe(true);
+ expect(alert.text()).toContain(wrapper.vm.$options.i18n.unavailable);
+ });
+ });
+
+ describe('invalid state', () => {
+ beforeEach(() => {
+ createWrapper({ props: { isInvalid: true } });
+ });
+
+ it('shows the invalid alert when the status is invalid', () => {
+ const alert = findAlert();
+
+ expect(alert.exists()).toBe(true);
+ expect(alert.text()).toBe(wrapper.vm.$options.i18n.invalid);
+ });
+ });
+
+ describe('empty state', () => {
+ const text = 'my custom alert message';
+
+ beforeEach(() => {
+ createWrapper({
+ props: { isEmpty: true, emptyMessage: text },
+ });
+ });
+
+ it('displays an empty message', () => {
+ createWrapper({
+ props: { isEmpty: true },
+ });
+
+ const alert = findAlert();
+
+ expect(alert.exists()).toBe(true);
+ expect(alert.text()).toBe(
+ 'This tab will be usable when the CI/CD configuration file is populated with valid syntax.',
+ );
+ });
+
+ it('can have a custom empty message', () => {
+ const alert = findAlert();
+
+ expect(alert.exists()).toBe(true);
+ expect(alert.text()).toBe(text);
+ });
+ });
+ });
+
+ describe('showing the tab content depending on `isEmpty`, `isUnavailable` and `isInvalid`', () => {
it.each`
- isEmpty | isInvalid | showSlotComponent | text
- ${undefined} | ${undefined} | ${true} | ${'renders'}
- ${false} | ${false} | ${true} | ${'renders'}
- ${undefined} | ${true} | ${false} | ${'hides'}
- ${true} | ${false} | ${false} | ${'hides'}
- ${false} | ${true} | ${false} | ${'hides'}
+ isEmpty | isUnavailable | isInvalid | showSlotComponent | text
+ ${undefined} | ${undefined} | ${undefined} | ${true} | ${'renders'}
+ ${false} | ${false} | ${false} | ${true} | ${'renders'}
+ ${undefined} | ${true} | ${true} | ${false} | ${'hides'}
+ ${true} | ${false} | ${false} | ${false} | ${'hides'}
+ ${false} | ${true} | ${false} | ${false} | ${'hides'}
+ ${false} | ${false} | ${true} | ${false} | ${'hides'}
`(
- '$text the slot component when isEmpty:$isEmpty and isInvalid:$isInvalid',
- ({ isEmpty, isInvalid, showSlotComponent }) => {
+ '$text the slot component when isEmpty:$isEmpty, isUnavailable:$isUnavailable and isInvalid:$isInvalid',
+ ({ isEmpty, isUnavailable, isInvalid, showSlotComponent }) => {
createWrapper({
- props: { isEmpty, isInvalid },
+ props: { isEmpty, isUnavailable, isInvalid },
});
expect(findSlotComponent().exists()).toBe(showSlotComponent);
expect(findAlert().exists()).toBe(!showSlotComponent);
},
);
-
- it('can have a custom empty message', () => {
- const text = 'my custom alert message';
- createWrapper({ props: { isEmpty: true, emptyMessage: text } });
-
- const alert = findAlert();
-
- expect(alert.exists()).toBe(true);
- expect(alert.text()).toBe(text);
- });
});
describe('user interaction', () => {
diff --git a/spec/frontend/pipeline_editor/mock_data.js b/spec/frontend/pipeline_editor/mock_data.js
index fc2cbdeda0a..f02f6870653 100644
--- a/spec/frontend/pipeline_editor/mock_data.js
+++ b/spec/frontend/pipeline_editor/mock_data.js
@@ -10,6 +10,7 @@ export const mockNewMergeRequestPath = '/-/merge_requests/new';
export const mockCommitSha = 'aabbccdd';
export const mockCommitNextSha = 'eeffgghh';
export const mockLintHelpPagePath = '/-/lint-help';
+export const mockLintUnavailableHelpPagePath = '/-/pipeline-editor/troubleshoot';
export const mockYmlHelpPagePath = '/-/yml-help';
export const mockCommitMessage = 'My commit message';
diff --git a/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js b/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js
index 09d7d4f7ca6..63eca253c48 100644
--- a/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js
+++ b/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js
@@ -5,10 +5,15 @@ import createMockApollo from 'helpers/mock_apollo_helper';
import setWindowLocation from 'helpers/set_window_location_helper';
import waitForPromises from 'helpers/wait_for_promises';
+import { resolvers } from '~/pipeline_editor/graphql/resolvers';
import PipelineEditorTabs from '~/pipeline_editor/components/pipeline_editor_tabs.vue';
import PipelineEditorEmptyState from '~/pipeline_editor/components/ui/pipeline_editor_empty_state.vue';
import PipelineEditorMessages from '~/pipeline_editor/components/ui/pipeline_editor_messages.vue';
-import { COMMIT_SUCCESS, COMMIT_FAILURE, LOAD_FAILURE_UNKNOWN } from '~/pipeline_editor/constants';
+import PipelineEditorHeader from '~/pipeline_editor/components/header/pipeline_editor_header.vue';
+import ValidationSegment, {
+ i18n as validationSegmenti18n,
+} from '~/pipeline_editor/components/header/validation_segment.vue';
+import { COMMIT_SUCCESS, COMMIT_FAILURE } 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';
@@ -61,11 +66,6 @@ describe('Pipeline editor app component', () => {
wrapper = shallowMount(PipelineEditorApp, {
provide: { ...mockProvide, ...provide },
stubs,
- data() {
- return {
- commitSha: '',
- };
- },
mocks: {
$apollo: {
queries: {
@@ -90,17 +90,11 @@ describe('Pipeline editor app component', () => {
[getLatestCommitShaQuery, mockLatestCommitShaQuery],
[getPipelineQuery, mockPipelineQuery],
];
- mockApollo = createMockApollo(handlers);
+
+ mockApollo = createMockApollo(handlers, resolvers);
const options = {
localVue,
- data() {
- return {
- currentBranch: mockDefaultBranch,
- lastCommitBranch: '',
- appStatus: '',
- };
- },
mocks: {},
apolloProvider: mockApollo,
};
@@ -116,6 +110,7 @@ describe('Pipeline editor app component', () => {
const findEmptyState = () => wrapper.findComponent(PipelineEditorEmptyState);
const findEmptyStateButton = () =>
wrapper.findComponent(PipelineEditorEmptyState).findComponent(GlButton);
+ const findValidationSegment = () => wrapper.findComponent(ValidationSegment);
beforeEach(() => {
mockBlobContentData = jest.fn();
@@ -240,6 +235,26 @@ describe('Pipeline editor app component', () => {
});
});
+ describe('when the lint query returns a 500 error', () => {
+ beforeEach(async () => {
+ mockCiConfigData.mockRejectedValueOnce(new Error(500));
+ await createComponentWithApollo({
+ stubs: { PipelineEditorHome, PipelineEditorHeader, ValidationSegment },
+ });
+ });
+
+ it('shows that the lint service is down', () => {
+ expect(findValidationSegment().text()).toContain(
+ validationSegmenti18n.unavailableValidation,
+ );
+ });
+
+ it('does not report an error or scroll to the top', () => {
+ expect(findAlert().exists()).toBe(false);
+ expect(window.scrollTo).not.toHaveBeenCalled();
+ });
+ });
+
describe('when the user commits', () => {
const updateFailureMessage = 'The GitLab CI configuration could not be updated.';
const updateSuccessMessage = 'Your changes have been successfully committed.';
@@ -411,94 +426,6 @@ describe('Pipeline editor app component', () => {
});
});
- describe('when multiple errors occurs in a row', () => {
- const updateFailureMessage = 'The GitLab CI configuration could not be updated.';
- const unknownFailureMessage = 'The CI configuration was not loaded, please try again.';
- const unknownReasons = ['Commit failed'];
- const alertErrorMessage = `${updateFailureMessage} ${unknownReasons[0]}`;
-
- const emitError = (type = COMMIT_FAILURE, reasons = unknownReasons) =>
- findEditorHome().vm.$emit('showError', {
- type,
- reasons,
- });
-
- beforeEach(async () => {
- mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponse);
- mockCiConfigData.mockResolvedValue(mockCiConfigQueryResponse);
- mockLatestCommitShaQuery.mockResolvedValue(mockCommitShaResults);
-
- window.scrollTo = jest.fn();
-
- await createComponentWithApollo({ stubs: { PipelineEditorMessages } });
- await emitError();
- });
-
- it('shows an error message for the first error', () => {
- expect(findAlert().text()).toMatchInterpolatedText(alertErrorMessage);
- });
-
- it('scrolls to the top of the page to bring attention to the error message', () => {
- expect(window.scrollTo).toHaveBeenCalledWith({ top: 0, behavior: 'smooth' });
- expect(window.scrollTo).toHaveBeenCalledTimes(1);
- });
-
- it('does not scroll to the top of the page if the same error occur multiple times in a row', async () => {
- await emitError();
-
- expect(window.scrollTo).toHaveBeenCalledTimes(1);
- expect(findAlert().text()).toMatchInterpolatedText(alertErrorMessage);
- });
-
- it('scrolls to the top if the error is different', async () => {
- await emitError(LOAD_FAILURE_UNKNOWN, []);
-
- expect(findAlert().text()).toMatchInterpolatedText(unknownFailureMessage);
- expect(window.scrollTo).toHaveBeenCalledTimes(2);
- });
-
- describe('when a user dismiss the alert', () => {
- beforeEach(async () => {
- await findAlert().vm.$emit('dismiss');
- });
-
- it('shows an error if the type is the same, but the reason is different', async () => {
- const newReason = 'Something broke';
-
- await emitError(COMMIT_FAILURE, [newReason]);
-
- expect(window.scrollTo).toHaveBeenCalledTimes(2);
- expect(findAlert().text()).toMatchInterpolatedText(`${updateFailureMessage} ${newReason}`);
- });
-
- it('does not show an error or scroll if a new error with the same type occurs', async () => {
- await emitError();
-
- expect(window.scrollTo).toHaveBeenCalledTimes(1);
- expect(findAlert().exists()).toBe(false);
- });
-
- it('it shows an error and scroll when a new type is emitted', async () => {
- await emitError(LOAD_FAILURE_UNKNOWN, []);
-
- expect(window.scrollTo).toHaveBeenCalledTimes(2);
- expect(findAlert().text()).toMatchInterpolatedText(unknownFailureMessage);
- });
-
- it('it shows an error and scroll if a previously shown type happen again', async () => {
- await emitError(LOAD_FAILURE_UNKNOWN, []);
-
- expect(window.scrollTo).toHaveBeenCalledTimes(2);
- expect(findAlert().text()).toMatchInterpolatedText(unknownFailureMessage);
-
- await emitError();
-
- expect(window.scrollTo).toHaveBeenCalledTimes(3);
- expect(findAlert().text()).toMatchInterpolatedText(alertErrorMessage);
- });
- });
- });
-
describe('when add_new_config_file query param is present', () => {
const originalLocation = window.location.href;
diff --git a/spec/frontend/pipelines/__snapshots__/utils_spec.js.snap b/spec/frontend/pipelines/__snapshots__/utils_spec.js.snap
index 99de0d2a3ef..52461885342 100644
--- a/spec/frontend/pipelines/__snapshots__/utils_spec.js.snap
+++ b/spec/frontend/pipelines/__snapshots__/utils_spec.js.snap
@@ -13,6 +13,7 @@ Array [
"id": "6",
"name": "build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl",
"needs": Array [],
+ "previousStageJobsOrNeeds": Array [],
"scheduledAt": null,
"status": Object {
"__typename": "DetailedStatus",
@@ -53,6 +54,7 @@ Array [
"id": "11",
"name": "build_b",
"needs": Array [],
+ "previousStageJobsOrNeeds": Array [],
"scheduledAt": null,
"status": Object {
"__typename": "DetailedStatus",
@@ -93,6 +95,7 @@ Array [
"id": "16",
"name": "build_c",
"needs": Array [],
+ "previousStageJobsOrNeeds": Array [],
"scheduledAt": null,
"status": Object {
"__typename": "DetailedStatus",
@@ -133,6 +136,7 @@ Array [
"id": "21",
"name": "build_d 1/3",
"needs": Array [],
+ "previousStageJobsOrNeeds": Array [],
"scheduledAt": null,
"status": Object {
"__typename": "DetailedStatus",
@@ -157,6 +161,7 @@ Array [
"id": "24",
"name": "build_d 2/3",
"needs": Array [],
+ "previousStageJobsOrNeeds": Array [],
"scheduledAt": null,
"status": Object {
"__typename": "DetailedStatus",
@@ -181,6 +186,7 @@ Array [
"id": "27",
"name": "build_d 3/3",
"needs": Array [],
+ "previousStageJobsOrNeeds": Array [],
"scheduledAt": null,
"status": Object {
"__typename": "DetailedStatus",
@@ -221,6 +227,7 @@ Array [
"id": "59",
"name": "test_c",
"needs": Array [],
+ "previousStageJobsOrNeeds": Array [],
"scheduledAt": null,
"status": Object {
"__typename": "DetailedStatus",
@@ -267,6 +274,11 @@ Array [
"build_b",
"build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl",
],
+ "previousStageJobsOrNeeds": Array [
+ "build_c",
+ "build_b",
+ "build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl",
+ ],
"scheduledAt": null,
"status": Object {
"__typename": "DetailedStatus",
@@ -313,6 +325,13 @@ Array [
"build_b",
"build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl",
],
+ "previousStageJobsOrNeeds": Array [
+ "build_d 3/3",
+ "build_d 2/3",
+ "build_d 1/3",
+ "build_b",
+ "build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl",
+ ],
"scheduledAt": null,
"status": Object {
"__typename": "DetailedStatus",
@@ -343,6 +362,13 @@ Array [
"build_b",
"build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl",
],
+ "previousStageJobsOrNeeds": Array [
+ "build_d 3/3",
+ "build_d 2/3",
+ "build_d 1/3",
+ "build_b",
+ "build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl",
+ ],
"scheduledAt": null,
"status": Object {
"__typename": "DetailedStatus",
@@ -385,6 +411,9 @@ Array [
"needs": Array [
"build_b",
],
+ "previousStageJobsOrNeeds": Array [
+ "build_b",
+ ],
"scheduledAt": null,
"status": Object {
"__typename": "DetailedStatus",
diff --git a/spec/frontend/pipelines/graph/mock_data.js b/spec/frontend/pipelines/graph/mock_data.js
index dcbbde7bf36..41823bfdb9f 100644
--- a/spec/frontend/pipelines/graph/mock_data.js
+++ b/spec/frontend/pipelines/graph/mock_data.js
@@ -73,6 +73,10 @@ export const mockPipelineResponse = {
__typename: 'CiBuildNeedConnection',
nodes: [],
},
+ previousStageJobsOrNeeds: {
+ __typename: 'CiJobConnection',
+ nodes: [],
+ },
},
],
},
@@ -118,6 +122,10 @@ export const mockPipelineResponse = {
__typename: 'CiBuildNeedConnection',
nodes: [],
},
+ previousStageJobsOrNeeds: {
+ __typename: 'CiJobConnection',
+ nodes: [],
+ },
},
],
},
@@ -163,6 +171,10 @@ export const mockPipelineResponse = {
__typename: 'CiBuildNeedConnection',
nodes: [],
},
+ previousStageJobsOrNeeds: {
+ __typename: 'CiJobConnection',
+ nodes: [],
+ },
},
],
},
@@ -208,6 +220,10 @@ export const mockPipelineResponse = {
__typename: 'CiBuildNeedConnection',
nodes: [],
},
+ previousStageJobsOrNeeds: {
+ __typename: 'CiJobConnection',
+ nodes: [],
+ },
},
{
__typename: 'CiJob',
@@ -235,6 +251,10 @@ export const mockPipelineResponse = {
__typename: 'CiBuildNeedConnection',
nodes: [],
},
+ previousStageJobsOrNeeds: {
+ __typename: 'CiJobConnection',
+ nodes: [],
+ },
},
{
__typename: 'CiJob',
@@ -262,6 +282,10 @@ export const mockPipelineResponse = {
__typename: 'CiBuildNeedConnection',
nodes: [],
},
+ previousStageJobsOrNeeds: {
+ __typename: 'CiJobConnection',
+ nodes: [],
+ },
},
],
},
@@ -339,6 +363,27 @@ export const mockPipelineResponse = {
},
],
},
+ previousStageJobsOrNeeds: {
+ __typename: 'CiJobConnection',
+ nodes: [
+ {
+ __typename: 'CiBuildNeed',
+ id: '37',
+ name: 'build_c',
+ },
+ {
+ __typename: 'CiBuildNeed',
+ id: '38',
+ name: 'build_b',
+ },
+ {
+ __typename: 'CiBuildNeed',
+ id: '39',
+ name:
+ 'build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl',
+ },
+ ],
+ },
},
],
},
@@ -411,6 +456,37 @@ export const mockPipelineResponse = {
},
],
},
+ previousStageJobsOrNeeds: {
+ __typename: 'CiJobConnection',
+ nodes: [
+ {
+ __typename: 'CiBuildNeed',
+ id: '45',
+ name: 'build_d 3/3',
+ },
+ {
+ __typename: 'CiBuildNeed',
+ id: '46',
+ name: 'build_d 2/3',
+ },
+ {
+ __typename: 'CiBuildNeed',
+ id: '47',
+ name: 'build_d 1/3',
+ },
+ {
+ __typename: 'CiBuildNeed',
+ id: '48',
+ name: 'build_b',
+ },
+ {
+ __typename: 'CiBuildNeed',
+ id: '49',
+ name:
+ 'build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl',
+ },
+ ],
+ },
},
{
__typename: 'CiJob',
@@ -465,6 +541,37 @@ export const mockPipelineResponse = {
},
],
},
+ previousStageJobsOrNeeds: {
+ __typename: 'CiJobConnection',
+ nodes: [
+ {
+ __typename: 'CiBuildNeed',
+ id: '52',
+ name: 'build_d 3/3',
+ },
+ {
+ __typename: 'CiBuildNeed',
+ id: '53',
+ name: 'build_d 2/3',
+ },
+ {
+ __typename: 'CiBuildNeed',
+ id: '54',
+ name: 'build_d 1/3',
+ },
+ {
+ __typename: 'CiBuildNeed',
+ id: '55',
+ name: 'build_b',
+ },
+ {
+ __typename: 'CiBuildNeed',
+ id: '56',
+ name:
+ 'build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl',
+ },
+ ],
+ },
},
],
},
@@ -503,6 +610,10 @@ export const mockPipelineResponse = {
__typename: 'CiBuildNeedConnection',
nodes: [],
},
+ previousStageJobsOrNeeds: {
+ __typename: 'CiJobConnection',
+ nodes: [],
+ },
},
],
},
@@ -547,6 +658,16 @@ export const mockPipelineResponse = {
},
],
},
+ previousStageJobsOrNeeds: {
+ __typename: 'CiJobConnection',
+ nodes: [
+ {
+ __typename: 'CiBuildNeed',
+ id: '65',
+ name: 'build_b',
+ },
+ ],
+ },
},
],
},
@@ -720,6 +841,10 @@ export const wrappedPipelineReturn = {
__typename: 'CiBuildNeedConnection',
nodes: [],
},
+ previousStageJobsOrNeeds: {
+ __typename: 'CiJobConnection',
+ nodes: [],
+ },
status: {
__typename: 'DetailedStatus',
id: '84',
diff --git a/spec/frontend/profile/account/components/update_username_spec.js b/spec/frontend/profile/account/components/update_username_spec.js
index 42adefcd0bb..bda07af4feb 100644
--- a/spec/frontend/profile/account/components/update_username_spec.js
+++ b/spec/frontend/profile/account/components/update_username_spec.js
@@ -79,6 +79,8 @@ describe('UpdateUsername component', () => {
beforeEach(async () => {
createComponent();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ newUsername });
await wrapper.vm.$nextTick();
diff --git a/spec/frontend/profile/add_ssh_key_validation_spec.js b/spec/frontend/profile/add_ssh_key_validation_spec.js
index 1fec864599c..a6bcca0ccb3 100644
--- a/spec/frontend/profile/add_ssh_key_validation_spec.js
+++ b/spec/frontend/profile/add_ssh_key_validation_spec.js
@@ -3,18 +3,18 @@ import AddSshKeyValidation from '../../../app/assets/javascripts/profile/add_ssh
describe('AddSshKeyValidation', () => {
describe('submit', () => {
it('returns true if isValid is true', () => {
- const addSshKeyValidation = new AddSshKeyValidation({});
- jest.spyOn(AddSshKeyValidation, 'isPublicKey').mockReturnValue(true);
+ const addSshKeyValidation = new AddSshKeyValidation([], {});
+ jest.spyOn(addSshKeyValidation, 'isPublicKey').mockReturnValue(true);
- expect(addSshKeyValidation.submit()).toBeTruthy();
+ expect(addSshKeyValidation.submit()).toBe(true);
});
it('calls preventDefault and toggleWarning if isValid is false', () => {
- const addSshKeyValidation = new AddSshKeyValidation({});
+ const addSshKeyValidation = new AddSshKeyValidation([], {});
const event = {
preventDefault: jest.fn(),
};
- jest.spyOn(AddSshKeyValidation, 'isPublicKey').mockReturnValue(false);
+ jest.spyOn(addSshKeyValidation, 'isPublicKey').mockReturnValue(false);
jest.spyOn(addSshKeyValidation, 'toggleWarning').mockImplementation(() => {});
addSshKeyValidation.submit(event);
@@ -31,14 +31,15 @@ describe('AddSshKeyValidation', () => {
warningElement.classList.add('hide');
const addSshKeyValidation = new AddSshKeyValidation(
+ [],
{},
warningElement,
originalSubmitElement,
);
addSshKeyValidation.toggleWarning(true);
- expect(warningElement.classList.contains('hide')).toBeFalsy();
- expect(originalSubmitElement.classList.contains('hide')).toBeTruthy();
+ expect(warningElement.classList.contains('hide')).toBe(false);
+ expect(originalSubmitElement.classList.contains('hide')).toBe(true);
});
it('hides warningElement and shows originalSubmitElement if isVisible is false', () => {
@@ -47,25 +48,32 @@ describe('AddSshKeyValidation', () => {
originalSubmitElement.classList.add('hide');
const addSshKeyValidation = new AddSshKeyValidation(
+ [],
{},
warningElement,
originalSubmitElement,
);
addSshKeyValidation.toggleWarning(false);
- expect(warningElement.classList.contains('hide')).toBeTruthy();
- expect(originalSubmitElement.classList.contains('hide')).toBeFalsy();
+ expect(warningElement.classList.contains('hide')).toBe(true);
+ expect(originalSubmitElement.classList.contains('hide')).toBe(false);
});
});
describe('isPublicKey', () => {
- it('returns false if probably invalid public ssh key', () => {
- expect(AddSshKeyValidation.isPublicKey('nope')).toBeFalsy();
+ it('returns false if value begins with an algorithm name that is unsupported', () => {
+ const addSshKeyValidation = new AddSshKeyValidation(['ssh-rsa', 'ssh-algorithm'], {});
+
+ expect(addSshKeyValidation.isPublicKey('nope key')).toBe(false);
+ expect(addSshKeyValidation.isPublicKey('ssh- key')).toBe(false);
+ expect(addSshKeyValidation.isPublicKey('unsupported-ssh-rsa key')).toBe(false);
});
- it('returns true if probably valid public ssh key', () => {
- expect(AddSshKeyValidation.isPublicKey('ssh-')).toBeTruthy();
- expect(AddSshKeyValidation.isPublicKey('ecdsa-sha2-')).toBeTruthy();
+ it('returns true if value begins with an algorithm name that is supported', () => {
+ const addSshKeyValidation = new AddSshKeyValidation(['ssh-rsa', 'ssh-algorithm'], {});
+
+ expect(addSshKeyValidation.isPublicKey('ssh-rsa key')).toBe(true);
+ expect(addSshKeyValidation.isPublicKey('ssh-algorithm key')).toBe(true);
});
});
});
diff --git a/spec/frontend/project_find_file_spec.js b/spec/frontend/project_find_file_spec.js
deleted file mode 100644
index 106b41bcc02..00000000000
--- a/spec/frontend/project_find_file_spec.js
+++ /dev/null
@@ -1,91 +0,0 @@
-import MockAdapter from 'axios-mock-adapter';
-import $ from 'jquery';
-import { TEST_HOST } from 'helpers/test_constants';
-import { sanitize } from '~/lib/dompurify';
-import axios from '~/lib/utils/axios_utils';
-import ProjectFindFile from '~/project_find_file';
-
-jest.mock('~/lib/dompurify', () => ({
- addHook: jest.fn(),
- sanitize: jest.fn((val) => val),
-}));
-
-const BLOB_URL_TEMPLATE = `${TEST_HOST}/namespace/project/blob/main`;
-const FILE_FIND_URL = `${TEST_HOST}/namespace/project/files/main?format=json`;
-const FIND_TREE_URL = `${TEST_HOST}/namespace/project/tree/main`;
-const TEMPLATE = `<div class="file-finder-holder tree-holder js-file-finder" data-blob-url-template="${BLOB_URL_TEMPLATE}" data-file-find-url="${FILE_FIND_URL}" data-find-tree-url="${FIND_TREE_URL}">
- <input class="file-finder-input" id="file_find" />
- <div class="tree-content-holder">
- <div class="table-holder">
- <table class="files-slider tree-table">
- <tbody />
- </table>
- </div>
- </div>
-</div>`;
-
-describe('ProjectFindFile', () => {
- let element;
- let mock;
-
- const getProjectFindFileInstance = () =>
- new ProjectFindFile(element, {
- url: FILE_FIND_URL,
- treeUrl: FIND_TREE_URL,
- blobUrlTemplate: BLOB_URL_TEMPLATE,
- });
-
- const findFiles = () =>
- element
- .find('.tree-table tr')
- .toArray()
- .map((el) => ({
- text: el.textContent,
- href: el.querySelector('a').href,
- }));
-
- const files = [
- { path: 'fileA.txt', escaped: 'fileA.txt' },
- { path: 'fileB.txt', escaped: 'fileB.txt' },
- { path: 'fi#leC.txt', escaped: 'fi%23leC.txt' },
- { path: 'folderA/fileD.txt', escaped: 'folderA/fileD.txt' },
- { path: 'folder#B/fileE.txt', escaped: 'folder%23B/fileE.txt' },
- { path: 'folde?rC/fil#F.txt', escaped: 'folde%3FrC/fil%23F.txt' },
- ];
-
- beforeEach((done) => {
- // Create a mock adapter for stubbing axios API requests
- mock = new MockAdapter(axios);
-
- element = $(TEMPLATE);
- mock.onGet(FILE_FIND_URL).replyOnce(
- 200,
- files.map((x) => x.path),
- );
- getProjectFindFileInstance(); // This triggers a load / axios call + subsequent render in the constructor
-
- setImmediate(done);
- });
-
- afterEach(() => {
- // Reset the mock adapter
- mock.restore();
- sanitize.mockClear();
- });
-
- it('loads and renders elements from remote server', () => {
- expect(findFiles()).toEqual(
- files.map(({ path, escaped }) => ({
- text: path,
- href: `${BLOB_URL_TEMPLATE}/${escaped}`,
- })),
- );
- });
-
- it('sanitizes search text', () => {
- const searchText = element.find('.file-finder-input').val();
-
- expect(sanitize).toHaveBeenCalledTimes(1);
- expect(sanitize).toHaveBeenCalledWith(searchText);
- });
-});
diff --git a/spec/frontend/project_select_combo_button_spec.js b/spec/frontend/project_select_combo_button_spec.js
index 5cdc3d174a1..40e7d27edc8 100644
--- a/spec/frontend/project_select_combo_button_spec.js
+++ b/spec/frontend/project_select_combo_button_spec.js
@@ -28,7 +28,7 @@ describe('Project Select Combo Button', () => {
loadFixtures(fixturePath);
- testContext.newItemBtn = document.querySelector('.new-project-item-link');
+ testContext.newItemBtn = document.querySelector('.js-new-project-item-link');
testContext.projectSelectInput = document.querySelector('.project-item-select');
});
@@ -120,7 +120,6 @@ describe('Project Select Combo Button', () => {
const returnedVariants = testContext.method();
expect(returnedVariants.localStorageItemType).toBe('new-merge-request');
- expect(returnedVariants.defaultTextPrefix).toBe('New merge request');
expect(returnedVariants.presetTextSuffix).toBe('merge request');
});
@@ -131,7 +130,6 @@ describe('Project Select Combo Button', () => {
const returnedVariants = testContext.method();
expect(returnedVariants.localStorageItemType).toBe('new-issue');
- expect(returnedVariants.defaultTextPrefix).toBe('New issue');
expect(returnedVariants.presetTextSuffix).toBe('issue');
});
});
diff --git a/spec/frontend/projects/commits/components/author_select_spec.js b/spec/frontend/projects/commits/components/author_select_spec.js
index 60d36597fda..23b4cccd92c 100644
--- a/spec/frontend/projects/commits/components/author_select_spec.js
+++ b/spec/frontend/projects/commits/components/author_select_spec.js
@@ -65,6 +65,8 @@ describe('Author Select', () => {
describe('user is searching via "filter by commit message"', () => {
it('disables dropdown container', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ hasSearchParam: true });
return wrapper.vm.$nextTick().then(() => {
@@ -73,6 +75,8 @@ describe('Author Select', () => {
});
it('has correct tooltip message', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ hasSearchParam: true });
return wrapper.vm.$nextTick().then(() => {
@@ -83,6 +87,8 @@ describe('Author Select', () => {
});
it('disables dropdown', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ hasSearchParam: false });
return wrapper.vm.$nextTick().then(() => {
@@ -103,6 +109,8 @@ describe('Author Select', () => {
});
it('displays the current selected author', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ currentAuthor });
return wrapper.vm.$nextTick().then(() => {
@@ -156,6 +164,8 @@ describe('Author Select', () => {
isChecked: true,
};
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ currentAuthor });
return wrapper.vm.$nextTick().then(() => {
diff --git a/spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js b/spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js
index 38e13dc5462..eb80d57fb3c 100644
--- a/spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js
+++ b/spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js
@@ -101,6 +101,8 @@ describe('RevisionDropdown component', () => {
const findGlDropdownItems = () => wrapper.findAll(GlDropdownItem);
const findFirstGlDropdownItem = () => findGlDropdownItems().at(0);
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ branches: ['some-branch'] });
await wrapper.vm.$nextTick();
diff --git a/spec/frontend/projects/project_find_file_spec.js b/spec/frontend/projects/project_find_file_spec.js
new file mode 100644
index 00000000000..9c1000039b1
--- /dev/null
+++ b/spec/frontend/projects/project_find_file_spec.js
@@ -0,0 +1,91 @@
+import MockAdapter from 'axios-mock-adapter';
+import $ from 'jquery';
+import { TEST_HOST } from 'helpers/test_constants';
+import { sanitize } from '~/lib/dompurify';
+import axios from '~/lib/utils/axios_utils';
+import ProjectFindFile from '~/projects/project_find_file';
+
+jest.mock('~/lib/dompurify', () => ({
+ addHook: jest.fn(),
+ sanitize: jest.fn((val) => val),
+}));
+
+const BLOB_URL_TEMPLATE = `${TEST_HOST}/namespace/project/blob/main`;
+const FILE_FIND_URL = `${TEST_HOST}/namespace/project/files/main?format=json`;
+const FIND_TREE_URL = `${TEST_HOST}/namespace/project/tree/main`;
+const TEMPLATE = `<div class="file-finder-holder tree-holder js-file-finder" data-blob-url-template="${BLOB_URL_TEMPLATE}" data-file-find-url="${FILE_FIND_URL}" data-find-tree-url="${FIND_TREE_URL}">
+ <input class="file-finder-input" id="file_find" />
+ <div class="tree-content-holder">
+ <div class="table-holder">
+ <table class="files-slider tree-table">
+ <tbody />
+ </table>
+ </div>
+ </div>
+</div>`;
+
+describe('ProjectFindFile', () => {
+ let element;
+ let mock;
+
+ const getProjectFindFileInstance = () =>
+ new ProjectFindFile(element, {
+ url: FILE_FIND_URL,
+ treeUrl: FIND_TREE_URL,
+ blobUrlTemplate: BLOB_URL_TEMPLATE,
+ });
+
+ const findFiles = () =>
+ element
+ .find('.tree-table tr')
+ .toArray()
+ .map((el) => ({
+ text: el.textContent,
+ href: el.querySelector('a').href,
+ }));
+
+ const files = [
+ { path: 'fileA.txt', escaped: 'fileA.txt' },
+ { path: 'fileB.txt', escaped: 'fileB.txt' },
+ { path: 'fi#leC.txt', escaped: 'fi%23leC.txt' },
+ { path: 'folderA/fileD.txt', escaped: 'folderA/fileD.txt' },
+ { path: 'folder#B/fileE.txt', escaped: 'folder%23B/fileE.txt' },
+ { path: 'folde?rC/fil#F.txt', escaped: 'folde%3FrC/fil%23F.txt' },
+ ];
+
+ beforeEach((done) => {
+ // Create a mock adapter for stubbing axios API requests
+ mock = new MockAdapter(axios);
+
+ element = $(TEMPLATE);
+ mock.onGet(FILE_FIND_URL).replyOnce(
+ 200,
+ files.map((x) => x.path),
+ );
+ getProjectFindFileInstance(); // This triggers a load / axios call + subsequent render in the constructor
+
+ setImmediate(done);
+ });
+
+ afterEach(() => {
+ // Reset the mock adapter
+ mock.restore();
+ sanitize.mockClear();
+ });
+
+ it('loads and renders elements from remote server', () => {
+ expect(findFiles()).toEqual(
+ files.map(({ path, escaped }) => ({
+ text: path,
+ href: `${BLOB_URL_TEMPLATE}/${escaped}`,
+ })),
+ );
+ });
+
+ it('sanitizes search text', () => {
+ const searchText = element.find('.file-finder-input').val();
+
+ expect(sanitize).toHaveBeenCalledTimes(1);
+ expect(sanitize).toHaveBeenCalledWith(searchText);
+ });
+});
diff --git a/spec/frontend/repository/components/blob_button_group_spec.js b/spec/frontend/repository/components/blob_button_group_spec.js
index 9f9d574a8ed..d5b882bd715 100644
--- a/spec/frontend/repository/components/blob_button_group_spec.js
+++ b/spec/frontend/repository/components/blob_button_group_spec.js
@@ -1,6 +1,5 @@
import { GlButton } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
import BlobButtonGroup from '~/repository/components/blob_button_group.vue';
import DeleteBlobModal from '~/repository/components/delete_blob_modal.vue';
import UploadBlobModal from '~/repository/components/upload_blob_modal.vue';
@@ -16,6 +15,7 @@ const DEFAULT_PROPS = {
projectPath: 'some/project/path',
isLocked: false,
canLock: true,
+ showForkSuggestion: false,
};
const DEFAULT_INJECT = {
@@ -27,7 +27,7 @@ describe('BlobButtonGroup component', () => {
let wrapper;
const createComponent = (props = {}) => {
- wrapper = shallowMount(BlobButtonGroup, {
+ wrapper = mountExtended(BlobButtonGroup, {
propsData: {
...DEFAULT_PROPS,
...props,
@@ -35,9 +35,6 @@ describe('BlobButtonGroup component', () => {
provide: {
...DEFAULT_INJECT,
},
- directives: {
- GlModal: createMockDirective(),
- },
});
};
@@ -47,7 +44,8 @@ describe('BlobButtonGroup component', () => {
const findDeleteBlobModal = () => wrapper.findComponent(DeleteBlobModal);
const findUploadBlobModal = () => wrapper.findComponent(UploadBlobModal);
- const findReplaceButton = () => wrapper.find('[data-testid="replace"]');
+ const findDeleteButton = () => wrapper.findByTestId('delete');
+ const findReplaceButton = () => wrapper.findByTestId('replace');
it('renders component', () => {
createComponent();
@@ -63,6 +61,8 @@ describe('BlobButtonGroup component', () => {
describe('buttons', () => {
beforeEach(() => {
createComponent();
+ jest.spyOn(findUploadBlobModal().vm, 'show');
+ jest.spyOn(findDeleteBlobModal().vm, 'show');
});
it('renders both the replace and delete button', () => {
@@ -75,10 +75,37 @@ describe('BlobButtonGroup component', () => {
});
it('triggers the UploadBlobModal from the replace button', () => {
- const { value } = getBinding(findReplaceButton().element, 'gl-modal');
- const modalId = findUploadBlobModal().props('modalId');
+ findReplaceButton().trigger('click');
+
+ expect(findUploadBlobModal().vm.show).toHaveBeenCalled();
+ });
+
+ it('triggers the DeleteBlobModal from the delete button', () => {
+ findDeleteButton().trigger('click');
+
+ expect(findDeleteBlobModal().vm.show).toHaveBeenCalled();
+ });
+
+ describe('showForkSuggestion set to true', () => {
+ beforeEach(() => {
+ createComponent({ showForkSuggestion: true });
+ jest.spyOn(findUploadBlobModal().vm, 'show');
+ jest.spyOn(findDeleteBlobModal().vm, 'show');
+ });
+
+ it('does not trigger the UploadBlobModal from the replace button', () => {
+ findReplaceButton().trigger('click');
+
+ expect(findUploadBlobModal().vm.show).not.toHaveBeenCalled();
+ expect(wrapper.emitted().fork).toBeTruthy();
+ });
+
+ it('does not trigger the DeleteBlobModal from the delete button', () => {
+ findDeleteButton().trigger('click');
- expect(modalId).toEqual(value);
+ expect(findDeleteBlobModal().vm.show).not.toHaveBeenCalled();
+ expect(wrapper.emitted().fork).toBeTruthy();
+ });
});
});
diff --git a/spec/frontend/repository/components/blob_content_viewer_spec.js b/spec/frontend/repository/components/blob_content_viewer_spec.js
index 9e00a2d0408..d3b60ec3768 100644
--- a/spec/frontend/repository/components/blob_content_viewer_spec.js
+++ b/spec/frontend/repository/components/blob_content_viewer_spec.js
@@ -83,6 +83,8 @@ const createComponent = async (mockData = {}, mountFn = shallowMount) => {
}),
);
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ project, isBinary });
await waitForPromises();
@@ -336,35 +338,11 @@ describe('Blob content viewer component', () => {
deletePath: webPath,
canPushCode: pushCode,
canLock: true,
- isLocked: true,
+ isLocked: false,
emptyRepo: empty,
});
});
- it.each`
- canPushCode | canDownloadCode | username | canLock
- ${true} | ${true} | ${'root'} | ${true}
- ${false} | ${true} | ${'root'} | ${false}
- ${true} | ${false} | ${'root'} | ${false}
- ${true} | ${true} | ${'peter'} | ${false}
- `(
- 'passes the correct lock states',
- async ({ canPushCode, canDownloadCode, username, canLock }) => {
- gon.current_username = username;
-
- await createComponent(
- {
- pushCode: canPushCode,
- downloadCode: canDownloadCode,
- empty,
- },
- mount,
- );
-
- expect(findBlobButtonGroup().props('canLock')).toBe(canLock);
- },
- );
-
it('does not render if not logged in', async () => {
isLoggedIn.mockReturnValueOnce(false);
diff --git a/spec/frontend/repository/components/blob_controls_spec.js b/spec/frontend/repository/components/blob_controls_spec.js
new file mode 100644
index 00000000000..03e389ea5cb
--- /dev/null
+++ b/spec/frontend/repository/components/blob_controls_spec.js
@@ -0,0 +1,88 @@
+import { createLocalVue } from '@vue/test-utils';
+import VueApollo from 'vue-apollo';
+import { nextTick } from 'vue';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import BlobControls from '~/repository/components/blob_controls.vue';
+import blobControlsQuery from '~/repository/queries/blob_controls.query.graphql';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import createRouter from '~/repository/router';
+import { updateElementsVisibility } from '~/repository/utils/dom';
+import { blobControlsDataMock, refMock } from '../mock_data';
+
+jest.mock('~/repository/utils/dom');
+
+let router;
+let wrapper;
+let mockResolver;
+
+const localVue = createLocalVue();
+
+const createComponent = async () => {
+ localVue.use(VueApollo);
+
+ const project = { ...blobControlsDataMock };
+ const projectPath = 'some/project';
+
+ router = createRouter(projectPath, refMock);
+
+ router.replace({ name: 'blobPath', params: { path: '/some/file.js' } });
+
+ mockResolver = jest.fn().mockResolvedValue({ data: { project } });
+
+ wrapper = shallowMountExtended(BlobControls, {
+ localVue,
+ router,
+ apolloProvider: createMockApollo([[blobControlsQuery, mockResolver]]),
+ propsData: { projectPath },
+ mixins: [{ data: () => ({ ref: refMock }) }],
+ });
+
+ await waitForPromises();
+};
+
+describe('Blob controls component', () => {
+ const findFindButton = () => wrapper.findByTestId('find');
+ const findBlameButton = () => wrapper.findByTestId('blame');
+ const findHistoryButton = () => wrapper.findByTestId('history');
+ const findPermalinkButton = () => wrapper.findByTestId('permalink');
+
+ beforeEach(() => createComponent());
+
+ afterEach(() => wrapper.destroy());
+
+ it('renders a find button with the correct href', () => {
+ expect(findFindButton().attributes('href')).toBe('find/file.js');
+ });
+
+ it('renders a blame button with the correct href', () => {
+ expect(findBlameButton().attributes('href')).toBe('blame/file.js');
+ });
+
+ it('renders a history button with the correct href', () => {
+ expect(findHistoryButton().attributes('href')).toBe('history/file.js');
+ });
+
+ it('renders a permalink button with the correct href', () => {
+ expect(findPermalinkButton().attributes('href')).toBe('permalink/file.js');
+ });
+
+ it.each`
+ name | path
+ ${'blobPathDecoded'} | ${null}
+ ${'treePathDecoded'} | ${'myFile.js'}
+ `(
+ 'does not render any buttons if router name is $name and router path is $path',
+ async ({ name, path }) => {
+ router.replace({ name, params: { path } });
+
+ await nextTick();
+
+ expect(findFindButton().exists()).toBe(false);
+ expect(findBlameButton().exists()).toBe(false);
+ expect(findHistoryButton().exists()).toBe(false);
+ expect(findPermalinkButton().exists()).toBe(false);
+ expect(updateElementsVisibility).toHaveBeenCalledWith('.tree-controls', true);
+ },
+ );
+});
diff --git a/spec/frontend/repository/components/breadcrumbs_spec.js b/spec/frontend/repository/components/breadcrumbs_spec.js
index eb957c635ac..ad2cbd70187 100644
--- a/spec/frontend/repository/components/breadcrumbs_spec.js
+++ b/spec/frontend/repository/components/breadcrumbs_spec.js
@@ -75,6 +75,8 @@ describe('Repository breadcrumbs component', () => {
it('does not render add to tree dropdown when permissions are false', async () => {
factory('/', { canCollaborate: false });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ userPermissions: { forkProject: false, createMergeRequestIn: false } });
await wrapper.vm.$nextTick();
@@ -100,6 +102,8 @@ describe('Repository breadcrumbs component', () => {
it('renders add to tree dropdown when permissions are true', async () => {
factory('/', { canCollaborate: true });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ userPermissions: { forkProject: true, createMergeRequestIn: true } });
await wrapper.vm.$nextTick();
@@ -117,6 +121,8 @@ describe('Repository breadcrumbs component', () => {
});
it('renders the modal once loaded', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ $apollo: { queries: { userPermissions: { loading: false } } } });
await wrapper.vm.$nextTick();
@@ -139,6 +145,8 @@ describe('Repository breadcrumbs component', () => {
});
it('renders the modal once loaded', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ $apollo: { queries: { userPermissions: { loading: false } } } });
await wrapper.vm.$nextTick();
diff --git a/spec/frontend/repository/components/last_commit_spec.js b/spec/frontend/repository/components/last_commit_spec.js
index ebea7dde34a..fe05a981845 100644
--- a/spec/frontend/repository/components/last_commit_spec.js
+++ b/spec/frontend/repository/components/last_commit_spec.js
@@ -43,6 +43,8 @@ function factory(commit = createCommitData(), loading = false) {
},
},
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
vm.setData({ commit });
vm.vm.$apollo.queries.commit.loading = loading;
}
diff --git a/spec/frontend/repository/components/preview/index_spec.js b/spec/frontend/repository/components/preview/index_spec.js
index 466eed52739..2490258a048 100644
--- a/spec/frontend/repository/components/preview/index_spec.js
+++ b/spec/frontend/repository/components/preview/index_spec.js
@@ -34,6 +34,8 @@ describe('Repository file preview component', () => {
name: 'README.md',
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
vm.setData({ readme: { html: '<div class="blob">test</div>' } });
return vm.vm.$nextTick(() => {
@@ -47,6 +49,8 @@ describe('Repository file preview component', () => {
name: 'README.md',
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
vm.setData({ readme: { html: '<div class="blob">test</div>' } });
return vm.vm
@@ -63,6 +67,8 @@ describe('Repository file preview component', () => {
name: 'README.md',
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
vm.setData({ loading: 1 });
return vm.vm.$nextTick(() => {
diff --git a/spec/frontend/repository/components/table/index_spec.js b/spec/frontend/repository/components/table/index_spec.js
index c8dddefc4f2..2cd88944f81 100644
--- a/spec/frontend/repository/components/table/index_spec.js
+++ b/spec/frontend/repository/components/table/index_spec.js
@@ -89,6 +89,8 @@ describe('Repository table component', () => {
`('renders table caption for $ref in $path', ({ path, ref }) => {
factory({ path });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
vm.setData({ ref });
return vm.vm.$nextTick(() => {
diff --git a/spec/frontend/repository/components/table/row_spec.js b/spec/frontend/repository/components/table/row_spec.js
index 7f59dbfe0d1..440baa72a3c 100644
--- a/spec/frontend/repository/components/table/row_spec.js
+++ b/spec/frontend/repository/components/table/row_spec.js
@@ -40,6 +40,8 @@ function factory(propsData = {}) {
},
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
vm.setData({ escapedRef: 'main' });
}
diff --git a/spec/frontend/repository/components/tree_content_spec.js b/spec/frontend/repository/components/tree_content_spec.js
index 9c5d07eede3..00ad1fc05f6 100644
--- a/spec/frontend/repository/components/tree_content_spec.js
+++ b/spec/frontend/repository/components/tree_content_spec.js
@@ -46,6 +46,8 @@ describe('Repository table component', () => {
it('renders file preview', async () => {
factory('/');
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
vm.setData({ entries: { blobs: [{ name: 'README.md' }] } });
await vm.vm.$nextTick();
@@ -134,6 +136,8 @@ describe('Repository table component', () => {
it('is not rendered if less than 1000 files', async () => {
factory('/');
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
vm.setData({ fetchCounter: 5, clickedShowMore: false });
await vm.vm.$nextTick();
@@ -153,6 +157,8 @@ describe('Repository table component', () => {
factory('/');
const blobs = new Array(totalBlobs).fill('fakeBlob');
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
vm.setData({ entries: { blobs }, pagesLoaded });
await vm.vm.$nextTick();
@@ -173,6 +179,8 @@ describe('Repository table component', () => {
${200} | ${100}
`('exponentially increases page size, to a maximum of 100', ({ fetchCounter, pageSize }) => {
factory('/');
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
vm.setData({ fetchCounter });
vm.vm.fetchFiles();
diff --git a/spec/frontend/repository/components/upload_blob_modal_spec.js b/spec/frontend/repository/components/upload_blob_modal_spec.js
index e9dfa3cd495..6b8b0752485 100644
--- a/spec/frontend/repository/components/upload_blob_modal_spec.js
+++ b/spec/frontend/repository/components/upload_blob_modal_spec.js
@@ -109,6 +109,8 @@ describe('UploadBlobModal', () => {
if (canPushCode) {
describe('when changing the branch name', () => {
it('displays the MR toggle', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ target: 'Not main' });
await wrapper.vm.$nextTick();
@@ -120,6 +122,8 @@ describe('UploadBlobModal', () => {
describe('completed form', () => {
beforeEach(() => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
file: { type: 'jpg' },
filePreviewURL: 'http://file.com?format=jpg',
diff --git a/spec/frontend/repository/mock_data.js b/spec/frontend/repository/mock_data.js
index 74d35daf578..a5ee17ba672 100644
--- a/spec/frontend/repository/mock_data.js
+++ b/spec/frontend/repository/mock_data.js
@@ -13,7 +13,9 @@ export const simpleViewerMock = {
ideForkAndEditPath: 'some_file.js/fork/ide',
canModifyBlob: true,
canCurrentUserPushToBranch: true,
+ archived: false,
storedExternally: false,
+ externalStorage: 'lfs',
rawPath: 'some_file.js',
replacePath: 'some_file.js/replace',
pipelineEditorPath: '',
@@ -50,7 +52,7 @@ export const projectMock = {
nodes: [
{
id: 'test',
- path: simpleViewerMock.path,
+ path: 'locked_file.js',
user: { id: '123', username: 'root' },
},
],
@@ -63,3 +65,22 @@ export const projectMock = {
export const propsMock = { path: 'some_file.js', projectPath: 'some/path' };
export const refMock = 'default-ref';
+
+export const blobControlsDataMock = {
+ id: '1234',
+ repository: {
+ blobs: {
+ nodes: [
+ {
+ id: '5678',
+ findFilePath: 'find/file.js',
+ blamePath: 'blame/file.js',
+ historyPath: 'history/file.js',
+ permalinkPath: 'permalink/file.js',
+ storedExternally: false,
+ externalStorage: '',
+ },
+ ],
+ },
+ },
+};
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
new file mode 100644
index 00000000000..ad0bce5c9af
--- /dev/null
+++ b/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js
@@ -0,0 +1,88 @@
+import { createLocalVue, mount, shallowMount } from '@vue/test-utils';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+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 AdminRunnerEditApp from '~//runner/admin_runner_edit/admin_runner_edit_app.vue';
+import { captureException } from '~/runner/sentry_utils';
+
+import { runnerData } from '../mock_data';
+
+jest.mock('~/flash');
+jest.mock('~/runner/sentry_utils');
+
+const mockRunnerGraphqlId = runnerData.data.runner.id;
+const mockRunnerId = `${getIdFromGraphQLId(mockRunnerGraphqlId)}`;
+
+const localVue = createLocalVue();
+localVue.use(VueApollo);
+
+describe('AdminRunnerEditApp', () => {
+ let wrapper;
+ let mockRunnerQuery;
+
+ const findRunnerHeader = () => wrapper.findComponent(RunnerHeader);
+
+ const createComponentWithApollo = ({ props = {}, mountFn = shallowMount } = {}) => {
+ wrapper = mountFn(AdminRunnerEditApp, {
+ localVue,
+ apolloProvider: createMockApollo([[getRunnerQuery, mockRunnerQuery]]),
+ propsData: {
+ runnerId: mockRunnerId,
+ ...props,
+ },
+ });
+
+ return waitForPromises();
+ };
+
+ beforeEach(() => {
+ mockRunnerQuery = jest.fn().mockResolvedValue(runnerData);
+ });
+
+ afterEach(() => {
+ mockRunnerQuery.mockReset();
+ wrapper.destroy();
+ });
+
+ it('expect GraphQL ID to be requested', async () => {
+ await createComponentWithApollo();
+
+ expect(mockRunnerQuery).toHaveBeenCalledWith({ id: mockRunnerGraphqlId });
+ });
+
+ it('displays the runner id', async () => {
+ await createComponentWithApollo({ mountFn: mount });
+
+ expect(findRunnerHeader().text()).toContain(`Runner #${mockRunnerId} created`);
+ });
+
+ it('displays the runner type and status', async () => {
+ await createComponentWithApollo({ mountFn: mount });
+
+ expect(findRunnerHeader().text()).toContain(`never contacted`);
+ expect(findRunnerHeader().text()).toContain(`shared`);
+ });
+
+ describe('When there is an error', () => {
+ beforeEach(async () => {
+ mockRunnerQuery = jest.fn().mockRejectedValueOnce(new Error('Error!'));
+ await createComponentWithApollo();
+ });
+
+ it('error is reported to sentry', () => {
+ expect(captureException).toHaveBeenCalledWith({
+ error: new Error('Network error: Error!'),
+ component: 'AdminRunnerEditApp',
+ });
+ });
+
+ it('error is shown to the user', () => {
+ expect(createAlert).toHaveBeenCalled();
+ });
+ });
+});
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 7015fe809b0..42be691ba4c 100644
--- a/spec/frontend/runner/admin_runners/admin_runners_app_spec.js
+++ b/spec/frontend/runner/admin_runners/admin_runners_app_spec.js
@@ -5,7 +5,7 @@ import createMockApollo from 'helpers/mock_apollo_helper';
import setWindowLocation from 'helpers/set_window_location_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
-import createFlash from '~/flash';
+import { createAlert } from '~/flash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { updateHistory } from '~/lib/utils/url_utility';
@@ -13,6 +13,7 @@ import AdminRunnersApp from '~/runner/admin_runners/admin_runners_app.vue';
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 RegistrationDropdown from '~/runner/components/registration/registration_dropdown.vue';
import RunnerPagination from '~/runner/components/runner_pagination.vue';
@@ -22,23 +23,21 @@ import {
CREATED_DESC,
DEFAULT_SORT,
INSTANCE_TYPE,
+ GROUP_TYPE,
+ PROJECT_TYPE,
PARAM_KEY_STATUS,
PARAM_KEY_TAG,
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 { captureException } from '~/runner/sentry_utils';
import FilteredSearch from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
-import { runnersData, runnersDataPaginated } from '../mock_data';
+import { runnersData, runnersCountData, runnersDataPaginated } from '../mock_data';
const mockRegistrationToken = 'MOCK_REGISTRATION_TOKEN';
-const mockActiveRunnersCount = '2';
-const mockAllRunnersCount = '6';
-const mockInstanceRunnersCount = '3';
-const mockGroupRunnersCount = '2';
-const mockProjectRunnersCount = '1';
jest.mock('~/flash');
jest.mock('~/runner/sentry_utils');
@@ -53,7 +52,9 @@ localVue.use(VueApollo);
describe('AdminRunnersApp', () => {
let wrapper;
let mockRunnersQuery;
+ let mockRunnersCountQuery;
+ const findRunnerStats = () => wrapper.findComponent(RunnerStats);
const findRegistrationDropdown = () => wrapper.findComponent(RegistrationDropdown);
const findRunnerTypeTabs = () => wrapper.findComponent(RunnerTypeTabs);
const findRunnerList = () => wrapper.findComponent(RunnerList);
@@ -65,27 +66,28 @@ describe('AdminRunnersApp', () => {
const findFilteredSearch = () => wrapper.findComponent(FilteredSearch);
const createComponent = ({ props = {}, mountFn = shallowMount } = {}) => {
- const handlers = [[getRunnersQuery, mockRunnersQuery]];
-
- wrapper = mountFn(AdminRunnersApp, {
- localVue,
- apolloProvider: createMockApollo(handlers),
- propsData: {
- registrationToken: mockRegistrationToken,
- activeRunnersCount: mockActiveRunnersCount,
- allRunnersCount: mockAllRunnersCount,
- instanceRunnersCount: mockInstanceRunnersCount,
- groupRunnersCount: mockGroupRunnersCount,
- projectRunnersCount: mockProjectRunnersCount,
- ...props,
- },
- });
+ const handlers = [
+ [getRunnersQuery, mockRunnersQuery],
+ [getRunnersCountQuery, mockRunnersCountQuery],
+ ];
+
+ wrapper = extendedWrapper(
+ mountFn(AdminRunnersApp, {
+ localVue,
+ apolloProvider: createMockApollo(handlers),
+ propsData: {
+ registrationToken: mockRegistrationToken,
+ ...props,
+ },
+ }),
+ );
};
beforeEach(async () => {
setWindowLocation('/admin/runners');
mockRunnersQuery = jest.fn().mockResolvedValue(runnersData);
+ mockRunnersCountQuery = jest.fn().mockResolvedValue(runnersCountData);
createComponent();
await waitForPromises();
});
@@ -95,13 +97,71 @@ describe('AdminRunnersApp', () => {
wrapper.destroy();
});
- it('shows the runner tabs with a runner count', async () => {
+ it('shows total runner counts', async () => {
createComponent({ mountFn: mount });
await waitForPromises();
+ const stats = findRunnerStats().text();
+
+ expect(stats).toMatch('Online runners 4');
+ expect(stats).toMatch('Offline runners 4');
+ expect(stats).toMatch('Stale runners 4');
+ });
+
+ it('shows the runner tabs with a runner count for each type', async () => {
+ mockRunnersCountQuery.mockImplementation(({ type }) => {
+ let count;
+ switch (type) {
+ case INSTANCE_TYPE:
+ count = 3;
+ break;
+ case GROUP_TYPE:
+ count = 2;
+ break;
+ case PROJECT_TYPE:
+ count = 1;
+ break;
+ default:
+ count = 6;
+ break;
+ }
+ return Promise.resolve({ data: { runners: { count } } });
+ });
+
+ createComponent({ mountFn: mount });
+ await waitForPromises();
+
expect(findRunnerTypeTabs().text()).toMatchInterpolatedText(
- `All ${mockAllRunnersCount} Instance ${mockInstanceRunnersCount} Group ${mockGroupRunnersCount} Project ${mockProjectRunnersCount}`,
+ `All 6 Instance 3 Group 2 Project 1`,
+ );
+ });
+
+ it('shows the runner tabs with a formatted runner count', async () => {
+ mockRunnersCountQuery.mockImplementation(({ type }) => {
+ let count;
+ switch (type) {
+ case INSTANCE_TYPE:
+ count = 3000;
+ break;
+ case GROUP_TYPE:
+ count = 2000;
+ break;
+ case PROJECT_TYPE:
+ count = 1000;
+ break;
+ default:
+ count = 6000;
+ break;
+ }
+ return Promise.resolve({ data: { runners: { count } } });
+ });
+
+ createComponent({ mountFn: mount });
+ await waitForPromises();
+
+ expect(findRunnerTypeTabs().text()).toMatchInterpolatedText(
+ `All 6,000 Instance 3,000 Group 2,000 Project 1,000`,
);
});
@@ -152,12 +212,6 @@ describe('AdminRunnersApp', () => {
]);
});
- it('shows the active runner count', () => {
- createComponent({ mountFn: mount });
-
- expect(wrapper.text()).toMatch(new RegExp(`Online Runners ${mockActiveRunnersCount}`));
- });
-
describe('when a filter is preselected', () => {
beforeEach(async () => {
setWindowLocation(`?status[]=${STATUS_ACTIVE}&runner_type[]=${INSTANCE_TYPE}&tag[]=tag1`);
@@ -241,7 +295,7 @@ describe('AdminRunnersApp', () => {
});
it('error is shown to the user', async () => {
- expect(createFlash).toHaveBeenCalledTimes(1);
+ expect(createAlert).toHaveBeenCalledTimes(1);
});
it('error is reported to sentry', async () => {
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 95c212cb0a9..4233d86c24c 100644
--- a/spec/frontend/runner/components/cells/runner_actions_cell_spec.js
+++ b/spec/frontend/runner/components/cells/runner_actions_cell_spec.js
@@ -4,7 +4,7 @@ import createMockApollo from 'helpers/mock_apollo_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
-import createFlash from '~/flash';
+import { createAlert } from '~/flash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { captureException } from '~/runner/sentry_utils';
@@ -40,15 +40,17 @@ describe('RunnerTypeCell', () => {
const findDeleteBtn = () => wrapper.findByTestId('delete-runner');
const getTooltip = (w) => getBinding(w.element, 'gl-tooltip')?.value;
- const createComponent = ({ active = true } = {}, options) => {
+ const createComponent = (runner = {}, options) => {
wrapper = extendedWrapper(
shallowMount(RunnerActionCell, {
propsData: {
runner: {
id: mockRunner.id,
shortSha: mockRunner.shortSha,
- adminUrl: mockRunner.adminUrl,
- active,
+ editAdminUrl: mockRunner.editAdminUrl,
+ userPermissions: mockRunner.userPermissions,
+ active: mockRunner.active,
+ ...runner,
},
},
localVue,
@@ -101,7 +103,26 @@ describe('RunnerTypeCell', () => {
it('Displays the runner edit link with the correct href', () => {
createComponent();
- expect(findEditBtn().attributes('href')).toBe(mockRunner.adminUrl);
+ expect(findEditBtn().attributes('href')).toBe(mockRunner.editAdminUrl);
+ });
+
+ it('Does not render the runner edit link when user cannot update', () => {
+ createComponent({
+ userPermissions: {
+ ...mockRunner.userPermissions,
+ updateRunner: false,
+ },
+ });
+
+ expect(findEditBtn().exists()).toBe(false);
+ });
+
+ it('Does not render the runner edit link when editAdminUrl is not provided', () => {
+ createComponent({
+ editAdminUrl: null,
+ });
+
+ expect(findEditBtn().exists()).toBe(false);
});
});
@@ -179,7 +200,7 @@ describe('RunnerTypeCell', () => {
});
it('error is shown to the user', () => {
- expect(createFlash).toHaveBeenCalledTimes(1);
+ expect(createAlert).toHaveBeenCalledTimes(1);
});
});
@@ -208,11 +229,22 @@ describe('RunnerTypeCell', () => {
});
it('error is shown to the user', () => {
- expect(createFlash).toHaveBeenCalledTimes(1);
+ expect(createAlert).toHaveBeenCalledTimes(1);
});
});
});
});
+
+ it('Does not render the runner toggle active button when user cannot update', () => {
+ createComponent({
+ userPermissions: {
+ ...mockRunner.userPermissions,
+ updateRunner: false,
+ },
+ });
+
+ expect(findToggleActiveBtn().exists()).toBe(false);
+ });
});
describe('Delete action', () => {
@@ -225,6 +257,10 @@ describe('RunnerTypeCell', () => {
);
});
+ it('Renders delete button', () => {
+ expect(findDeleteBtn().exists()).toBe(true);
+ });
+
it('Delete button opens delete modal', () => {
const modalId = getBinding(findDeleteBtn().element, 'gl-modal').value;
@@ -259,6 +295,18 @@ describe('RunnerTypeCell', () => {
});
});
+ it('Does not render the runner delete button when user cannot delete', () => {
+ createComponent({
+ userPermissions: {
+ ...mockRunner.userPermissions,
+ deleteRunner: false,
+ },
+ });
+
+ expect(findDeleteBtn().exists()).toBe(false);
+ expect(findRunnerDeleteModal().exists()).toBe(false);
+ });
+
describe('When delete is clicked', () => {
beforeEach(() => {
findRunnerDeleteModal().vm.$emit('primary');
@@ -302,7 +350,7 @@ describe('RunnerTypeCell', () => {
});
it('error is shown to the user', () => {
- expect(createFlash).toHaveBeenCalledTimes(1);
+ expect(createAlert).toHaveBeenCalledTimes(1);
});
it('toast notification is not shown', () => {
@@ -334,7 +382,7 @@ describe('RunnerTypeCell', () => {
});
it('error is shown to the user', () => {
- expect(createFlash).toHaveBeenCalledTimes(1);
+ 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 0d002c272b4..e75decddf70 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
@@ -1,14 +1,15 @@
-import { GlDropdownItem, GlLoadingIcon, GlToast } from '@gitlab/ui';
+import { GlDropdownItem, GlLoadingIcon, GlToast, GlModal } from '@gitlab/ui';
import { createLocalVue, shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
-import createFlash from '~/flash';
+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 { captureException } from '~/runner/sentry_utils';
+import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
jest.mock('~/flash');
jest.mock('~/runner/sentry_utils');
@@ -18,14 +19,18 @@ localVue.use(VueApollo);
localVue.use(GlToast);
const mockNewToken = 'NEW_TOKEN';
+const modalID = 'token-reset-modal';
describe('RegistrationTokenResetDropdownItem', () => {
let wrapper;
let runnersRegistrationTokenResetMutationHandler;
let showToast;
+ const mockEvent = { preventDefault: jest.fn() };
const findDropdownItem = () => wrapper.findComponent(GlDropdownItem);
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
+ const findModal = () => wrapper.findComponent(GlModal);
+ const clickSubmit = () => findModal().vm.$emit('primary', mockEvent);
const createComponent = ({ props, provide = {} } = {}) => {
wrapper = shallowMount(RegistrationTokenResetDropdownItem, {
@@ -38,6 +43,9 @@ describe('RegistrationTokenResetDropdownItem', () => {
apolloProvider: createMockApollo([
[runnersRegistrationTokenResetMutation, runnersRegistrationTokenResetMutationHandler],
]),
+ directives: {
+ GlModal: createMockDirective(),
+ },
});
showToast = wrapper.vm.$toast ? jest.spyOn(wrapper.vm.$toast, 'show') : null;
@@ -54,8 +62,6 @@ describe('RegistrationTokenResetDropdownItem', () => {
});
createComponent();
-
- jest.spyOn(window, 'confirm');
});
afterEach(() => {
@@ -66,6 +72,18 @@ describe('RegistrationTokenResetDropdownItem', () => {
expect(findDropdownItem().exists()).toBe(true);
});
+ describe('modal directive integration', () => {
+ it('has the correct ID on the dropdown', () => {
+ const binding = getBinding(findDropdownItem().element, 'gl-modal');
+
+ expect(binding.value).toBe(modalID);
+ });
+
+ it('has the correct ID on the modal', () => {
+ expect(findModal().props('modalId')).toBe(modalID);
+ });
+ });
+
describe('On click and confirmation', () => {
const mockGroupId = '11';
const mockProjectId = '22';
@@ -82,9 +100,8 @@ describe('RegistrationTokenResetDropdownItem', () => {
props: { type },
});
- window.confirm.mockReturnValueOnce(true);
-
findDropdownItem().trigger('click');
+ clickSubmit();
await waitForPromises();
});
@@ -114,7 +131,6 @@ describe('RegistrationTokenResetDropdownItem', () => {
describe('On click without confirmation', () => {
beforeEach(async () => {
- window.confirm.mockReturnValueOnce(false);
findDropdownItem().vm.$emit('click');
await waitForPromises();
});
@@ -142,11 +158,11 @@ describe('RegistrationTokenResetDropdownItem', () => {
runnersRegistrationTokenResetMutationHandler.mockRejectedValueOnce(new Error(mockErrorMsg));
- window.confirm.mockReturnValueOnce(true);
findDropdownItem().trigger('click');
+ clickSubmit();
await waitForPromises();
- expect(createFlash).toHaveBeenLastCalledWith({
+ expect(createAlert).toHaveBeenLastCalledWith({
message: `Network error: ${mockErrorMsg}`,
});
expect(captureException).toHaveBeenCalledWith({
@@ -168,11 +184,11 @@ describe('RegistrationTokenResetDropdownItem', () => {
},
});
- window.confirm.mockReturnValueOnce(true);
findDropdownItem().trigger('click');
+ clickSubmit();
await waitForPromises();
- expect(createFlash).toHaveBeenLastCalledWith({
+ expect(createAlert).toHaveBeenLastCalledWith({
message: `${mockErrorMsg} ${mockErrorMsg2}`,
});
expect(captureException).toHaveBeenCalledWith({
@@ -184,8 +200,8 @@ describe('RegistrationTokenResetDropdownItem', () => {
describe('Immediately after click', () => {
it('shows loading state', async () => {
- window.confirm.mockReturnValue(true);
findDropdownItem().trigger('click');
+ clickSubmit();
await nextTick();
expect(findLoadingIcon().exists()).toBe(true);
diff --git a/spec/frontend/runner/components/runner_header_spec.js b/spec/frontend/runner/components/runner_header_spec.js
new file mode 100644
index 00000000000..50699df3a44
--- /dev/null
+++ b/spec/frontend/runner/components/runner_header_spec.js
@@ -0,0 +1,93 @@
+import { GlSprintf } from '@gitlab/ui';
+import { mount, shallowMount } from '@vue/test-utils';
+import { GROUP_TYPE, STATUS_ONLINE } from '~/runner/constants';
+import { TYPE_CI_RUNNER } from '~/graphql_shared/constants';
+import { convertToGraphQLId } from '~/graphql_shared/utils';
+import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
+
+import RunnerHeader from '~/runner/components/runner_header.vue';
+import RunnerTypeBadge from '~/runner/components/runner_type_badge.vue';
+import RunnerStatusBadge from '~/runner/components/runner_status_badge.vue';
+
+import { runnerData } from '../mock_data';
+
+const mockRunner = runnerData.data.runner;
+
+describe('RunnerHeader', () => {
+ let wrapper;
+
+ const findRunnerTypeBadge = () => wrapper.findComponent(RunnerTypeBadge);
+ const findRunnerStatusBadge = () => wrapper.findComponent(RunnerStatusBadge);
+ const findTimeAgo = () => wrapper.findComponent(TimeAgo);
+
+ const createComponent = ({ runner = {}, mountFn = shallowMount } = {}) => {
+ wrapper = mountFn(RunnerHeader, {
+ propsData: {
+ runner: {
+ ...mockRunner,
+ ...runner,
+ },
+ },
+ stubs: {
+ GlSprintf,
+ TimeAgo,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('displays the runner status', () => {
+ createComponent({
+ mountFn: mount,
+ runner: {
+ status: STATUS_ONLINE,
+ },
+ });
+
+ expect(findRunnerStatusBadge().text()).toContain(`online`);
+ });
+
+ it('displays the runner type', () => {
+ createComponent({
+ mountFn: mount,
+ runner: {
+ runnerType: GROUP_TYPE,
+ },
+ });
+
+ expect(findRunnerTypeBadge().text()).toContain(`group`);
+ });
+
+ it('displays the runner id', () => {
+ createComponent({
+ runner: {
+ id: convertToGraphQLId(TYPE_CI_RUNNER, 99),
+ },
+ });
+
+ expect(wrapper.text()).toContain(`Runner #99`);
+ });
+
+ it('displays the runner creation time', () => {
+ createComponent();
+
+ expect(wrapper.text()).toMatch(/created .+/);
+ expect(findTimeAgo().props('time')).toBe(mockRunner.createdAt);
+ });
+
+ it('does not display runner creation time if createdAt missing', () => {
+ createComponent({
+ runner: {
+ id: convertToGraphQLId(TYPE_CI_RUNNER, 99),
+ createdAt: null,
+ },
+ });
+
+ expect(wrapper.text()).toContain(`Runner #99`);
+ expect(wrapper.text()).not.toMatch(/created .+/);
+ expect(findTimeAgo().exists()).toBe(false);
+ });
+});
diff --git a/spec/frontend/runner/components/runner_list_spec.js b/spec/frontend/runner/components/runner_list_spec.js
index 5a14fa5a2d5..452430b7237 100644
--- a/spec/frontend/runner/components/runner_list_spec.js
+++ b/spec/frontend/runner/components/runner_list_spec.js
@@ -69,7 +69,9 @@ describe('RunnerList', () => {
const { id, description, version, ipAddress, shortSha } = mockRunners[0];
// Badges
- expect(findCell({ fieldKey: 'status' }).text()).toMatchInterpolatedText('not connected paused');
+ expect(findCell({ fieldKey: 'status' }).text()).toMatchInterpolatedText(
+ 'never contacted paused',
+ );
// Runner summary
expect(findCell({ fieldKey: 'summary' }).text()).toContain(
diff --git a/spec/frontend/runner/components/runner_status_badge_spec.js b/spec/frontend/runner/components/runner_status_badge_spec.js
index a19515d6ed2..c470c6bb989 100644
--- a/spec/frontend/runner/components/runner_status_badge_spec.js
+++ b/spec/frontend/runner/components/runner_status_badge_spec.js
@@ -6,7 +6,6 @@ import {
STATUS_ONLINE,
STATUS_OFFLINE,
STATUS_STALE,
- STATUS_NOT_CONNECTED,
STATUS_NEVER_CONTACTED,
} from '~/runner/constants';
@@ -50,20 +49,7 @@ describe('RunnerTypeBadge', () => {
expect(getTooltip().value).toBe('Runner is online; last contact was 1 minute ago');
});
- it('renders not connected state', () => {
- createComponent({
- runner: {
- contactedAt: null,
- status: STATUS_NOT_CONNECTED,
- },
- });
-
- expect(wrapper.text()).toBe('not connected');
- expect(findBadge().props('variant')).toBe('muted');
- expect(getTooltip().value).toMatch('This runner has never connected');
- });
-
- it('renders never contacted state as not connected, for backwards compatibility', () => {
+ it('renders never contacted state', () => {
createComponent({
runner: {
contactedAt: null,
@@ -71,9 +57,9 @@ describe('RunnerTypeBadge', () => {
},
});
- expect(wrapper.text()).toBe('not connected');
+ expect(wrapper.text()).toBe('never contacted');
expect(findBadge().props('variant')).toBe('muted');
- expect(getTooltip().value).toMatch('This runner has never connected');
+ expect(getTooltip().value).toMatch('This runner has never contacted');
});
it('renders offline state', () => {
diff --git a/spec/frontend/runner/components/runner_type_alert_spec.js b/spec/frontend/runner/components/runner_type_alert_spec.js
deleted file mode 100644
index 4023c75c9a8..00000000000
--- a/spec/frontend/runner/components/runner_type_alert_spec.js
+++ /dev/null
@@ -1,61 +0,0 @@
-import { GlAlert, GlLink } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import RunnerTypeAlert from '~/runner/components/runner_type_alert.vue';
-import { INSTANCE_TYPE, GROUP_TYPE, PROJECT_TYPE } from '~/runner/constants';
-
-describe('RunnerTypeAlert', () => {
- let wrapper;
-
- const findAlert = () => wrapper.findComponent(GlAlert);
- const findLink = () => wrapper.findComponent(GlLink);
-
- const createComponent = ({ props = {} } = {}) => {
- wrapper = shallowMount(RunnerTypeAlert, {
- propsData: {
- type: INSTANCE_TYPE,
- ...props,
- },
- });
- };
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe.each`
- type | exampleText | anchor
- ${INSTANCE_TYPE} | ${'This runner is available to all groups and projects'} | ${'#shared-runners'}
- ${GROUP_TYPE} | ${'This runner is available to all projects and subgroups in a group'} | ${'#group-runners'}
- ${PROJECT_TYPE} | ${'This runner is associated with one or more projects'} | ${'#specific-runners'}
- `('When it is an $type level runner', ({ type, exampleText, anchor }) => {
- beforeEach(() => {
- createComponent({ props: { type } });
- });
-
- it('Describes runner type', () => {
- expect(wrapper.text()).toMatch(exampleText);
- });
-
- it(`Shows an "info" variant`, () => {
- expect(findAlert().props('variant')).toBe('info');
- });
-
- it(`Links to anchor "${anchor}"`, () => {
- expect(findLink().attributes('href')).toBe(`/help/ci/runners/runners_scope${anchor}`);
- });
- });
-
- describe('When runner type is not correct', () => {
- it('Does not render content when type is missing', () => {
- createComponent({ props: { type: undefined } });
-
- expect(wrapper.html()).toBe('');
- });
-
- it('Validation fails for an incorrect type', () => {
- expect(() => {
- createComponent({ props: { type: 'NOT_A_TYPE' } });
- }).toThrow();
- });
- });
-});
diff --git a/spec/frontend/runner/components/runner_update_form_spec.js b/spec/frontend/runner/components/runner_update_form_spec.js
index 0e0844a785b..ebb2e67d1e2 100644
--- a/spec/frontend/runner/components/runner_update_form_spec.js
+++ b/spec/frontend/runner/components/runner_update_form_spec.js
@@ -5,7 +5,7 @@ import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
-import createFlash, { FLASH_TYPES } from '~/flash';
+import { createAlert, VARIANT_SUCCESS } from '~/flash';
import RunnerUpdateForm from '~/runner/components/runner_update_form.vue';
import {
INSTANCE_TYPE,
@@ -79,9 +79,9 @@ describe('RunnerUpdateForm', () => {
input: expect.objectContaining(submittedRunner),
});
- expect(createFlash).toHaveBeenLastCalledWith({
+ expect(createAlert).toHaveBeenLastCalledWith({
message: expect.stringContaining('saved'),
- type: FLASH_TYPES.SUCCESS,
+ variant: VARIANT_SUCCESS,
});
expect(findSubmitDisabledAttr()).toBeUndefined();
@@ -127,7 +127,7 @@ describe('RunnerUpdateForm', () => {
await submitFormAndWait();
// Some fields are not submitted
- const { ipAddress, runnerType, ...submitted } = mockRunner;
+ const { ipAddress, runnerType, createdAt, status, ...submitted } = mockRunner;
expectToHaveSubmittedRunnerContaining(submitted);
});
@@ -238,7 +238,7 @@ describe('RunnerUpdateForm', () => {
await submitFormAndWait();
- expect(createFlash).toHaveBeenLastCalledWith({
+ expect(createAlert).toHaveBeenLastCalledWith({
message: `Network error: ${mockErrorMsg}`,
});
expect(captureException).toHaveBeenCalledWith({
@@ -262,7 +262,7 @@ describe('RunnerUpdateForm', () => {
await submitFormAndWait();
- expect(createFlash).toHaveBeenLastCalledWith({
+ expect(createAlert).toHaveBeenLastCalledWith({
message: mockErrorMsg,
});
expect(captureException).not.toHaveBeenCalled();
diff --git a/spec/frontend/runner/components/search_tokens/tag_token_spec.js b/spec/frontend/runner/components/search_tokens/tag_token_spec.js
index 89c06ba2df4..52557ff716d 100644
--- a/spec/frontend/runner/components/search_tokens/tag_token_spec.js
+++ b/spec/frontend/runner/components/search_tokens/tag_token_spec.js
@@ -3,7 +3,7 @@ import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises';
-import createFlash from '~/flash';
+import { createAlert } from '~/flash';
import axios from '~/lib/utils/axios_utils';
import TagToken, { TAG_SUGGESTIONS_PATH } from '~/runner/components/search_tokens/tag_token.vue';
@@ -168,8 +168,8 @@ describe('TagToken', () => {
});
it('error is shown', async () => {
- expect(createFlash).toHaveBeenCalledTimes(1);
- expect(createFlash).toHaveBeenCalledWith({ message: expect.any(String) });
+ expect(createAlert).toHaveBeenCalledTimes(1);
+ expect(createAlert).toHaveBeenCalledWith({ message: expect.any(String) });
});
});
diff --git a/spec/frontend/runner/components/stat/runner_online_stat_spec.js b/spec/frontend/runner/components/stat/runner_online_stat_spec.js
deleted file mode 100644
index 18f865aa22c..00000000000
--- a/spec/frontend/runner/components/stat/runner_online_stat_spec.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import { GlSingleStat } from '@gitlab/ui/dist/charts';
-import { shallowMount, mount } from '@vue/test-utils';
-import RunnerOnlineBadge from '~/runner/components/stat/runner_online_stat.vue';
-
-describe('RunnerOnlineBadge', () => {
- let wrapper;
-
- const findSingleStat = () => wrapper.findComponent(GlSingleStat);
-
- const createComponent = ({ props = {} } = {}, mountFn = shallowMount) => {
- wrapper = mountFn(RunnerOnlineBadge, {
- propsData: {
- value: '99',
- ...props,
- },
- });
- };
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('Uses a success appearance', () => {
- createComponent({}, shallowMount);
-
- expect(findSingleStat().props('variant')).toBe('success');
- });
-
- it('Renders a value', () => {
- createComponent({}, mount);
-
- expect(wrapper.text()).toMatch(new RegExp(`Online Runners 99\\s+online`));
- });
-});
diff --git a/spec/frontend/runner/components/stat/runner_stats_spec.js b/spec/frontend/runner/components/stat/runner_stats_spec.js
new file mode 100644
index 00000000000..68db8621ef0
--- /dev/null
+++ b/spec/frontend/runner/components/stat/runner_stats_spec.js
@@ -0,0 +1,46 @@
+import { shallowMount, mount } from '@vue/test-utils';
+import RunnerStats from '~/runner/components/stat/runner_stats.vue';
+import RunnerStatusStat from '~/runner/components/stat/runner_status_stat.vue';
+import { STATUS_ONLINE, STATUS_OFFLINE, STATUS_STALE } from '~/runner/constants';
+
+describe('RunnerStats', () => {
+ let wrapper;
+
+ const findRunnerStatusStatAt = (i) => wrapper.findAllComponents(RunnerStatusStat).at(i);
+
+ const createComponent = ({ props = {}, mountFn = shallowMount } = {}) => {
+ wrapper = mountFn(RunnerStats, {
+ propsData: {
+ onlineRunnersCount: 3,
+ offlineRunnersCount: 2,
+ staleRunnersCount: 1,
+ ...props,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('Displays all the stats', () => {
+ createComponent({ mountFn: mount });
+
+ const stats = wrapper.text();
+
+ expect(stats).toMatch('Online runners 3');
+ expect(stats).toMatch('Offline runners 2');
+ expect(stats).toMatch('Stale runners 1');
+ });
+
+ it.each`
+ i | status
+ ${0} | ${STATUS_ONLINE}
+ ${1} | ${STATUS_OFFLINE}
+ ${2} | ${STATUS_STALE}
+ `('Displays status types at index $i', ({ i, status }) => {
+ createComponent();
+
+ expect(findRunnerStatusStatAt(i).props('status')).toBe(status);
+ });
+});
diff --git a/spec/frontend/runner/components/stat/runner_status_stat_spec.js b/spec/frontend/runner/components/stat/runner_status_stat_spec.js
new file mode 100644
index 00000000000..3218272eac7
--- /dev/null
+++ b/spec/frontend/runner/components/stat/runner_status_stat_spec.js
@@ -0,0 +1,67 @@
+import { GlSingleStat } from '@gitlab/ui/dist/charts';
+import { shallowMount, mount } from '@vue/test-utils';
+import RunnerStatusStat from '~/runner/components/stat/runner_status_stat.vue';
+import { STATUS_ONLINE, STATUS_OFFLINE, STATUS_STALE } from '~/runner/constants';
+
+describe('RunnerStatusStat', () => {
+ let wrapper;
+
+ const findSingleStat = () => wrapper.findComponent(GlSingleStat);
+
+ const createComponent = ({ props = {} } = {}, mountFn = shallowMount) => {
+ wrapper = mountFn(RunnerStatusStat, {
+ propsData: {
+ status: STATUS_ONLINE,
+ value: 99,
+ ...props,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe.each`
+ status | variant | title | badge
+ ${STATUS_ONLINE} | ${'success'} | ${'Online runners'} | ${'online'}
+ ${STATUS_OFFLINE} | ${'muted'} | ${'Offline runners'} | ${'offline'}
+ ${STATUS_STALE} | ${'warning'} | ${'Stale runners'} | ${'stale'}
+ `('Renders a stat for status "$status"', ({ status, variant, title, badge }) => {
+ beforeEach(() => {
+ createComponent({ props: { status } }, mount);
+ });
+
+ it('Renders text', () => {
+ expect(wrapper.text()).toMatch(new RegExp(`${title} 99\\s+${badge}`));
+ });
+
+ it(`Uses variant ${variant}`, () => {
+ expect(findSingleStat().props('variant')).toBe(variant);
+ });
+ });
+
+ it('Formats stat number', () => {
+ createComponent({ props: { value: 1000 } }, mount);
+
+ expect(wrapper.text()).toMatch('Online runners 1,000');
+ });
+
+ it('Shows a null result', () => {
+ createComponent({ props: { value: null } }, mount);
+
+ expect(wrapper.text()).toMatch('Online runners -');
+ });
+
+ it('Shows an undefined result', () => {
+ createComponent({ props: { value: undefined } }, mount);
+
+ expect(wrapper.text()).toMatch('Online runners -');
+ });
+
+ it('Shows result for an unknown status', () => {
+ createComponent({ props: { status: 'UNKNOWN' } }, mount);
+
+ expect(wrapper.text()).toMatch('Runners 99');
+ });
+});
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 4451100de19..034b7848f35 100644
--- a/spec/frontend/runner/group_runners/group_runners_app_spec.js
+++ b/spec/frontend/runner/group_runners/group_runners_app_spec.js
@@ -6,12 +6,13 @@ import createMockApollo from 'helpers/mock_apollo_helper';
import setWindowLocation from 'helpers/set_window_location_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
-import createFlash from '~/flash';
+import { createAlert } from '~/flash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { updateHistory } from '~/lib/utils/url_utility';
import RunnerFilteredSearchBar from '~/runner/components/runner_filtered_search_bar.vue';
import RunnerList from '~/runner/components/runner_list.vue';
+import RunnerStats from '~/runner/components/stat/runner_stats.vue';
import RegistrationDropdown from '~/runner/components/registration/registration_dropdown.vue';
import RunnerPagination from '~/runner/components/runner_pagination.vue';
@@ -26,10 +27,11 @@ import {
RUNNER_PAGE_SIZE,
} 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 GroupRunnersApp from '~/runner/group_runners/group_runners_app.vue';
import { captureException } from '~/runner/sentry_utils';
import FilteredSearch from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
-import { groupRunnersData, groupRunnersDataPaginated } from '../mock_data';
+import { groupRunnersData, groupRunnersDataPaginated, groupRunnersCountData } from '../mock_data';
const localVue = createLocalVue();
localVue.use(VueApollo);
@@ -48,7 +50,9 @@ jest.mock('~/lib/utils/url_utility', () => ({
describe('GroupRunnersApp', () => {
let wrapper;
let mockGroupRunnersQuery;
+ let mockGroupRunnersCountQuery;
+ const findRunnerStats = () => wrapper.findComponent(RunnerStats);
const findRegistrationDropdown = () => wrapper.findComponent(RegistrationDropdown);
const findRunnerList = () => wrapper.findComponent(RunnerList);
const findRunnerPagination = () => extendedWrapper(wrapper.findComponent(RunnerPagination));
@@ -59,7 +63,10 @@ describe('GroupRunnersApp', () => {
const findFilteredSearch = () => wrapper.findComponent(FilteredSearch);
const createComponent = ({ props = {}, mountFn = shallowMount } = {}) => {
- const handlers = [[getGroupRunnersQuery, mockGroupRunnersQuery]];
+ const handlers = [
+ [getGroupRunnersQuery, mockGroupRunnersQuery],
+ [getGroupRunnersCountQuery, mockGroupRunnersCountQuery],
+ ];
wrapper = mountFn(GroupRunnersApp, {
localVue,
@@ -77,11 +84,24 @@ describe('GroupRunnersApp', () => {
setWindowLocation(`/groups/${mockGroupFullPath}/-/runners`);
mockGroupRunnersQuery = jest.fn().mockResolvedValue(groupRunnersData);
+ mockGroupRunnersCountQuery = jest.fn().mockResolvedValue(groupRunnersCountData);
createComponent();
await waitForPromises();
});
+ it('shows total runner counts', async () => {
+ createComponent({ mountFn: mount });
+
+ await waitForPromises();
+
+ const stats = findRunnerStats().text();
+
+ expect(stats).toMatch('Online runners 2');
+ expect(stats).toMatch('Offline runners 2');
+ expect(stats).toMatch('Stale runners 2');
+ });
+
it('shows the runner setup instructions', () => {
expect(findRegistrationDropdown().props('registrationToken')).toBe(mockRegistrationToken);
expect(findRegistrationDropdown().props('type')).toBe(GROUP_TYPE);
@@ -129,28 +149,6 @@ describe('GroupRunnersApp', () => {
);
});
- describe('shows the active runner count', () => {
- const expectedOnlineCount = (count) => new RegExp(`Online Runners ${count}`);
-
- it('with a regular value', () => {
- createComponent({ mountFn: mount });
-
- expect(wrapper.text()).toMatch(expectedOnlineCount(mockGroupRunnersLimitedCount));
- });
-
- it('at the limit', () => {
- createComponent({ props: { groupRunnersLimitedCount: 1000 }, mountFn: mount });
-
- expect(wrapper.text()).toMatch(expectedOnlineCount('1,000'));
- });
-
- it('over the limit', () => {
- createComponent({ props: { groupRunnersLimitedCount: 1001 }, mountFn: mount });
-
- expect(wrapper.text()).toMatch(expectedOnlineCount('1,000\\+'));
- });
- });
-
describe('when a filter is preselected', () => {
beforeEach(async () => {
setWindowLocation(`?status[]=${STATUS_ACTIVE}&runner_type[]=${INSTANCE_TYPE}`);
@@ -236,7 +234,7 @@ describe('GroupRunnersApp', () => {
});
it('error is shown to the user', async () => {
- expect(createFlash).toHaveBeenCalledTimes(1);
+ expect(createAlert).toHaveBeenCalledTimes(1);
});
it('error is reported to sentry', async () => {
diff --git a/spec/frontend/runner/mock_data.js b/spec/frontend/runner/mock_data.js
index b8d0f1273c7..9c430e205ea 100644
--- a/spec/frontend/runner/mock_data.js
+++ b/spec/frontend/runner/mock_data.js
@@ -2,17 +2,21 @@
// 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';
// 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';
export {
runnerData,
+ runnersCountData,
runnersDataPaginated,
runnersData,
groupRunnersData,
+ groupRunnersCountData,
groupRunnersDataPaginated,
};
diff --git a/spec/frontend/runner/runner_detail/runner_details_app_spec.js b/spec/frontend/runner/runner_detail/runner_details_app_spec.js
deleted file mode 100644
index 1a1428e8cb1..00000000000
--- a/spec/frontend/runner/runner_detail/runner_details_app_spec.js
+++ /dev/null
@@ -1,87 +0,0 @@
-import { createLocalVue, mount, shallowMount } from '@vue/test-utils';
-import VueApollo from 'vue-apollo';
-import createMockApollo from 'helpers/mock_apollo_helper';
-import waitForPromises from 'helpers/wait_for_promises';
-import createFlash from '~/flash';
-
-import { getIdFromGraphQLId } from '~/graphql_shared/utils';
-import RunnerTypeBadge from '~/runner/components/runner_type_badge.vue';
-import getRunnerQuery from '~/runner/graphql/get_runner.query.graphql';
-import RunnerDetailsApp from '~/runner/runner_details/runner_details_app.vue';
-import { captureException } from '~/runner/sentry_utils';
-
-import { runnerData } from '../mock_data';
-
-jest.mock('~/flash');
-jest.mock('~/runner/sentry_utils');
-
-const mockRunnerGraphqlId = runnerData.data.runner.id;
-const mockRunnerId = `${getIdFromGraphQLId(mockRunnerGraphqlId)}`;
-
-const localVue = createLocalVue();
-localVue.use(VueApollo);
-
-describe('RunnerDetailsApp', () => {
- let wrapper;
- let mockRunnerQuery;
-
- const findRunnerTypeBadge = () => wrapper.findComponent(RunnerTypeBadge);
-
- const createComponentWithApollo = ({ props = {}, mountFn = shallowMount } = {}) => {
- wrapper = mountFn(RunnerDetailsApp, {
- localVue,
- apolloProvider: createMockApollo([[getRunnerQuery, mockRunnerQuery]]),
- propsData: {
- runnerId: mockRunnerId,
- ...props,
- },
- });
-
- return waitForPromises();
- };
-
- beforeEach(async () => {
- mockRunnerQuery = jest.fn().mockResolvedValue(runnerData);
- });
-
- afterEach(() => {
- mockRunnerQuery.mockReset();
- wrapper.destroy();
- });
-
- it('expect GraphQL ID to be requested', async () => {
- await createComponentWithApollo();
-
- expect(mockRunnerQuery).toHaveBeenCalledWith({ id: mockRunnerGraphqlId });
- });
-
- it('displays the runner id', async () => {
- await createComponentWithApollo();
-
- expect(wrapper.text()).toContain(`Runner #${mockRunnerId}`);
- });
-
- it('displays the runner type', async () => {
- await createComponentWithApollo({ mountFn: mount });
-
- expect(findRunnerTypeBadge().text()).toBe('shared');
- });
-
- describe('When there is an error', () => {
- beforeEach(async () => {
- mockRunnerQuery = jest.fn().mockRejectedValueOnce(new Error('Error!'));
- await createComponentWithApollo();
- });
-
- it('error is reported to sentry', async () => {
- expect(captureException).toHaveBeenCalledWith({
- error: new Error('Network error: Error!'),
- component: 'RunnerDetailsApp',
- });
- });
-
- it('error is shown to the user', async () => {
- expect(createFlash).toHaveBeenCalled();
- });
- });
-});
diff --git a/spec/frontend/runner/runner_detail/runner_update_form_utils_spec.js b/spec/frontend/runner/runner_detail/runner_update_form_utils_spec.js
deleted file mode 100644
index 510b4e604ac..00000000000
--- a/spec/frontend/runner/runner_detail/runner_update_form_utils_spec.js
+++ /dev/null
@@ -1,96 +0,0 @@
-import { ACCESS_LEVEL_NOT_PROTECTED } from '~/runner/constants';
-import {
- modelToUpdateMutationVariables,
- runnerToModel,
-} from '~/runner/runner_details/runner_update_form_utils';
-
-const mockId = 'gid://gitlab/Ci::Runner/1';
-const mockDescription = 'Runner Desc.';
-
-const mockRunner = {
- id: mockId,
- description: mockDescription,
- maximumTimeout: 100,
- accessLevel: ACCESS_LEVEL_NOT_PROTECTED,
- active: true,
- locked: true,
- runUntagged: true,
- tagList: ['tag-1', 'tag-2'],
-};
-
-const mockModel = {
- ...mockRunner,
- tagList: 'tag-1, tag-2',
-};
-
-describe('~/runner/runner_details/runner_update_form_utils', () => {
- describe('runnerToModel', () => {
- it('collects all model data', () => {
- expect(runnerToModel(mockRunner)).toEqual(mockModel);
- });
-
- it('does not collect other data', () => {
- const model = runnerToModel({
- ...mockRunner,
- unrelated: 'unrelatedValue',
- });
-
- expect(model.unrelated).toEqual(undefined);
- });
-
- it('tag list defaults to an empty string', () => {
- const model = runnerToModel({
- ...mockRunner,
- tagList: undefined,
- });
-
- expect(model.tagList).toEqual('');
- });
- });
-
- describe('modelToUpdateMutationVariables', () => {
- it('collects all model data', () => {
- expect(modelToUpdateMutationVariables(mockModel)).toEqual({
- input: {
- ...mockRunner,
- },
- });
- });
-
- it('collects a nullable timeout from the model', () => {
- const variables = modelToUpdateMutationVariables({
- ...mockModel,
- maximumTimeout: '',
- });
-
- expect(variables).toEqual({
- input: {
- ...mockRunner,
- maximumTimeout: null,
- },
- });
- });
-
- it.each`
- tagList | tagListInput
- ${''} | ${[]}
- ${'tag1, tag2'} | ${['tag1', 'tag2']}
- ${'with spaces'} | ${['with spaces']}
- ${',,,,, commas'} | ${['commas']}
- ${'more ,,,,, commas'} | ${['more', 'commas']}
- ${' trimmed , trimmed2 '} | ${['trimmed', 'trimmed2']}
- `('collect tags separated by commas for "$value"', ({ tagList, tagListInput }) => {
- const variables = modelToUpdateMutationVariables({
- ...mockModel,
- tagList,
- });
-
- expect(variables).toEqual({
- input: {
- ...mockRunner,
- tagList: tagListInput,
- },
- });
- });
- });
-});
diff --git a/spec/frontend/runner/runner_search_utils_spec.js b/spec/frontend/runner/runner_search_utils_spec.js
index 0fc7917663e..aff1ec882bb 100644
--- a/spec/frontend/runner/runner_search_utils_spec.js
+++ b/spec/frontend/runner/runner_search_utils_spec.js
@@ -1,6 +1,7 @@
import { RUNNER_PAGE_SIZE } from '~/runner/constants';
import {
searchValidator,
+ updateOutdatedUrl,
fromUrlQueryToSearch,
fromSearchToUrl,
fromSearchToVariables,
@@ -190,6 +191,23 @@ describe('search_params.js', () => {
});
});
+ describe('updateOutdatedUrl', () => {
+ it('returns null for urls that do not need updating', () => {
+ expect(updateOutdatedUrl('http://test.host/')).toBe(null);
+ expect(updateOutdatedUrl('http://test.host/?a=b')).toBe(null);
+ });
+
+ it('returns updated url for updating NOT_CONNECTED to NEVER_CONTACTED', () => {
+ expect(updateOutdatedUrl('http://test.host/admin/runners?status[]=NOT_CONNECTED')).toBe(
+ 'http://test.host/admin/runners?status[]=NEVER_CONTACTED',
+ );
+
+ expect(updateOutdatedUrl('http://test.host/admin/runners?status[]=NOT_CONNECTED&a=b')).toBe(
+ 'http://test.host/admin/runners?status[]=NEVER_CONTACTED&a=b',
+ );
+ });
+ });
+
describe('fromUrlQueryToSearch', () => {
examples.forEach(({ name, urlQuery, search }) => {
it(`Converts ${name} to a search object`, () => {
diff --git a/spec/frontend/runner/runner_update_form_utils_spec.js b/spec/frontend/runner/runner_update_form_utils_spec.js
new file mode 100644
index 00000000000..a633aee92f7
--- /dev/null
+++ b/spec/frontend/runner/runner_update_form_utils_spec.js
@@ -0,0 +1,93 @@
+import { ACCESS_LEVEL_NOT_PROTECTED } from '~/runner/constants';
+import { modelToUpdateMutationVariables, runnerToModel } from '~/runner/runner_update_form_utils';
+
+const mockId = 'gid://gitlab/Ci::Runner/1';
+const mockDescription = 'Runner Desc.';
+
+const mockRunner = {
+ id: mockId,
+ description: mockDescription,
+ maximumTimeout: 100,
+ accessLevel: ACCESS_LEVEL_NOT_PROTECTED,
+ active: true,
+ locked: true,
+ runUntagged: true,
+ tagList: ['tag-1', 'tag-2'],
+};
+
+const mockModel = {
+ ...mockRunner,
+ tagList: 'tag-1, tag-2',
+};
+
+describe('~/runner/runner_update_form_utils', () => {
+ describe('runnerToModel', () => {
+ it('collects all model data', () => {
+ expect(runnerToModel(mockRunner)).toEqual(mockModel);
+ });
+
+ it('does not collect other data', () => {
+ const model = runnerToModel({
+ ...mockRunner,
+ unrelated: 'unrelatedValue',
+ });
+
+ expect(model.unrelated).toEqual(undefined);
+ });
+
+ it('tag list defaults to an empty string', () => {
+ const model = runnerToModel({
+ ...mockRunner,
+ tagList: undefined,
+ });
+
+ expect(model.tagList).toEqual('');
+ });
+ });
+
+ describe('modelToUpdateMutationVariables', () => {
+ it('collects all model data', () => {
+ expect(modelToUpdateMutationVariables(mockModel)).toEqual({
+ input: {
+ ...mockRunner,
+ },
+ });
+ });
+
+ it('collects a nullable timeout from the model', () => {
+ const variables = modelToUpdateMutationVariables({
+ ...mockModel,
+ maximumTimeout: '',
+ });
+
+ expect(variables).toEqual({
+ input: {
+ ...mockRunner,
+ maximumTimeout: null,
+ },
+ });
+ });
+
+ it.each`
+ tagList | tagListInput
+ ${''} | ${[]}
+ ${'tag1, tag2'} | ${['tag1', 'tag2']}
+ ${'with spaces'} | ${['with spaces']}
+ ${',,,,, commas'} | ${['commas']}
+ ${'more ,,,,, commas'} | ${['more', 'commas']}
+ ${' trimmed , trimmed2 '} | ${['trimmed', 'trimmed2']}
+ `('collect tags separated by commas for "$value"', ({ tagList, tagListInput }) => {
+ const variables = modelToUpdateMutationVariables({
+ ...mockModel,
+ tagList,
+ });
+
+ expect(variables).toEqual({
+ input: {
+ ...mockRunner,
+ tagList: tagListInput,
+ },
+ });
+ });
+ });
+});
diff --git a/spec/frontend/search/topbar/components/searchable_dropdown_spec.js b/spec/frontend/search/topbar/components/searchable_dropdown_spec.js
index b21cf5c6b79..de1cefa9e9d 100644
--- a/spec/frontend/search/topbar/components/searchable_dropdown_spec.js
+++ b/spec/frontend/search/topbar/components/searchable_dropdown_spec.js
@@ -133,6 +133,8 @@ describe('Global Search Searchable Dropdown', () => {
describe(`when search is ${searchText} and frequentItems length is ${frequentItems.length}`, () => {
beforeEach(() => {
createComponent({}, { frequentItems });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ searchText });
});
@@ -202,6 +204,8 @@ describe('Global Search Searchable Dropdown', () => {
describe('not for the first time', () => {
beforeEach(() => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ hasBeenOpened: true });
findGlDropdown().vm.$emit('show');
});
diff --git a/spec/frontend/security_configuration/components/app_spec.js b/spec/frontend/security_configuration/components/app_spec.js
index 0a2b18caf25..cbdf7f53913 100644
--- a/spec/frontend/security_configuration/components/app_spec.js
+++ b/spec/frontend/security_configuration/components/app_spec.js
@@ -1,4 +1,4 @@
-import { GlTab } from '@gitlab/ui';
+import { GlTab, GlTabs } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
@@ -77,6 +77,7 @@ describe('App component', () => {
const findMainHeading = () => wrapper.find('h1');
const findTab = () => wrapper.findComponent(GlTab);
const findTabs = () => wrapper.findAllComponents(GlTab);
+ const findGlTabs = () => wrapper.findComponent(GlTabs);
const findByTestId = (id) => wrapper.findByTestId(id);
const findFeatureCards = () => wrapper.findAllComponents(FeatureCard);
const findTrainingProviderList = () => wrapper.findComponent(TrainingProviderList);
@@ -154,6 +155,14 @@ describe('App component', () => {
expect(findTab().exists()).toBe(true);
});
+ it('passes the `sync-active-tab-with-query-params` prop', () => {
+ expect(findGlTabs().props('syncActiveTabWithQueryParams')).toBe(true);
+ });
+
+ it('lazy loads each tab', () => {
+ expect(findGlTabs().attributes('lazy')).not.toBe(undefined);
+ });
+
it('renders correct amount of tabs', () => {
expect(findTabs()).toHaveLength(expectedTabs.length);
});
@@ -161,6 +170,10 @@ describe('App component', () => {
it.each(expectedTabs)('renders the %s tab', (tabName) => {
expect(findByTestId(`${tabName}-tab`).exists()).toBe(true);
});
+
+ it.each(expectedTabs)('has the %s query-param-value', (tabName) => {
+ expect(findByTestId(`${tabName}-tab`).props('queryParamValue')).toBe(tabName);
+ });
});
it('renders right amount of feature cards for given props with correct props', () => {
@@ -182,10 +195,6 @@ describe('App component', () => {
expect(findComplianceViewHistoryLink().exists()).toBe(false);
expect(findSecurityViewHistoryLink().exists()).toBe(false);
});
-
- it('renders TrainingProviderList component', () => {
- expect(findTrainingProviderList().exists()).toBe(true);
- });
});
describe('Manage via MR Error Alert', () => {
@@ -432,6 +441,25 @@ describe('App component', () => {
});
});
+ describe('Vulnerability management', () => {
+ beforeEach(() => {
+ createComponent({
+ augmentedSecurityFeatures: securityFeaturesMock,
+ augmentedComplianceFeatures: complianceFeaturesMock,
+ });
+ });
+
+ it('renders TrainingProviderList component', () => {
+ expect(findTrainingProviderList().exists()).toBe(true);
+ });
+
+ it('renders security training description', () => {
+ const vulnerabilityManagementTab = wrapper.findByTestId('vulnerability-management-tab');
+
+ expect(vulnerabilityManagementTab.text()).toContain(i18n.securityTrainingDescription);
+ });
+ });
+
describe('when secureVulnerabilityTraining feature flag is disabled', () => {
beforeEach(() => {
createComponent({
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 60cc36a634c..578248e696f 100644
--- a/spec/frontend/security_configuration/components/training_provider_list_spec.js
+++ b/spec/frontend/security_configuration/components/training_provider_list_spec.js
@@ -1,87 +1,192 @@
-import { GlLink, GlToggle, GlCard, GlSkeletonLoader } from '@gitlab/ui';
+import { GlAlert, GlLink, GlToggle, GlCard, GlSkeletonLoader } 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 TrainingProviderList from '~/security_configuration/components/training_provider_list.vue';
+import configureSecurityTrainingProvidersMutation from '~/security_configuration/graphql/configure_security_training_providers.mutation.graphql';
import waitForPromises from 'helpers/wait_for_promises';
-import { securityTrainingProviders, mockResolvers } from '../mock_data';
+import {
+ securityTrainingProviders,
+ createMockResolvers,
+ testProjectPath,
+ textProviderIds,
+} from '../mock_data';
Vue.use(VueApollo);
describe('TrainingProviderList component', () => {
let wrapper;
- let mockApollo;
- let mockSecurityTrainingProvidersData;
+ let apolloProvider;
- const createComponent = () => {
- mockApollo = createMockApollo([], mockResolvers);
+ const createApolloProvider = ({ resolvers } = {}) => {
+ apolloProvider = createMockApollo([], createMockResolvers({ resolvers }));
+ };
+ const createComponent = () => {
wrapper = shallowMount(TrainingProviderList, {
- apolloProvider: mockApollo,
+ provide: {
+ projectPath: testProjectPath,
+ },
+ apolloProvider,
});
};
const waitForQueryToBeLoaded = () => waitForPromises();
+ const waitForMutationToBeLoaded = waitForQueryToBeLoaded;
const findCards = () => wrapper.findAllComponents(GlCard);
const findLinks = () => wrapper.findAllComponents(GlLink);
const findToggles = () => wrapper.findAllComponents(GlToggle);
+ const findFirstToggle = () => findToggles().at(0);
const findLoader = () => wrapper.findComponent(GlSkeletonLoader);
+ const findErrorAlert = () => wrapper.findComponent(GlAlert);
- beforeEach(() => {
- mockSecurityTrainingProvidersData = jest.fn();
- mockSecurityTrainingProvidersData.mockResolvedValue(securityTrainingProviders);
-
- createComponent();
- });
+ const toggleFirstProvider = () => findFirstToggle().vm.$emit('change');
afterEach(() => {
wrapper.destroy();
- mockApollo = null;
+ apolloProvider = null;
});
- describe('when loading', () => {
- it('shows the loader', () => {
- expect(findLoader().exists()).toBe(true);
+ describe('with a successful response', () => {
+ beforeEach(() => {
+ createApolloProvider();
+ createComponent();
});
- it('does not show the cards', () => {
- expect(findCards().exists()).toBe(false);
+ describe('when loading', () => {
+ it('shows the loader', () => {
+ expect(findLoader().exists()).toBe(true);
+ });
+
+ it('does not show the cards', () => {
+ expect(findCards().exists()).toBe(false);
+ });
});
- });
- describe('basic structure', () => {
- beforeEach(async () => {
- await waitForQueryToBeLoaded();
+ describe('basic structure', () => {
+ beforeEach(async () => {
+ await waitForQueryToBeLoaded();
+ });
+
+ it('renders correct amount of cards', () => {
+ expect(findCards()).toHaveLength(securityTrainingProviders.length);
+ });
+
+ securityTrainingProviders.forEach(({ name, description, url, isEnabled }, index) => {
+ it(`shows the name for card ${index}`, () => {
+ expect(findCards().at(index).text()).toContain(name);
+ });
+
+ it(`shows the description for card ${index}`, () => {
+ 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 toggle with the correct value for card ${index}`, () => {
+ expect(findToggles().at(index).props('value')).toEqual(isEnabled);
+ });
+
+ it('does not show loader when query is populated', () => {
+ expect(findLoader().exists()).toBe(false);
+ });
+ });
});
- it('renders correct amount of cards', () => {
- expect(findCards()).toHaveLength(securityTrainingProviders.length);
+ describe('storing training provider settings', () => {
+ beforeEach(async () => {
+ jest.spyOn(apolloProvider.defaultClient, 'mutate');
+
+ await waitForMutationToBeLoaded();
+
+ 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: { enabledProviders: textProviderIds, fullPath: testProjectPath } },
+ }),
+ );
+ });
});
+ });
+
+ describe('with errors', () => {
+ const expectErrorAlertToExist = () => {
+ expect(findErrorAlert().props()).toMatchObject({
+ dismissible: false,
+ variant: 'danger',
+ });
+ };
+
+ describe('when fetching training providers', () => {
+ beforeEach(async () => {
+ createApolloProvider({
+ resolvers: {
+ Query: {
+ securityTrainingProviders: jest.fn().mockReturnValue(new Error()),
+ },
+ },
+ });
+ createComponent();
- securityTrainingProviders.forEach(({ name, description, url, isEnabled }, index) => {
- it(`shows the name for card ${index}`, () => {
- expect(findCards().at(index).text()).toContain(name);
+ await waitForQueryToBeLoaded();
});
- it(`shows the description for card ${index}`, () => {
- expect(findCards().at(index).text()).toContain(description);
+ it('shows an non-dismissible error alert', () => {
+ expectErrorAlertToExist();
});
- it(`shows the learn more link for card ${index}`, () => {
- expect(findLinks().at(index).attributes()).toEqual({
- target: '_blank',
- href: url,
+ it('shows an error description', () => {
+ expect(findErrorAlert().text()).toBe(TrainingProviderList.i18n.providerQueryErrorMessage);
+ });
+ });
+
+ describe('when storing training provider configurations', () => {
+ beforeEach(async () => {
+ createApolloProvider({
+ resolvers: {
+ Mutation: {
+ configureSecurityTrainingProviders: () => ({
+ errors: ['something went wrong!'],
+ securityTrainingProviders: [],
+ }),
+ },
+ },
});
+ createComponent();
+
+ await waitForQueryToBeLoaded();
+ toggleFirstProvider();
+ await waitForMutationToBeLoaded();
});
- it(`shows the toggle with the correct value for card ${index}`, () => {
- expect(findToggles().at(index).props('value')).toEqual(isEnabled);
+ it('shows an non-dismissible error alert', () => {
+ expectErrorAlertToExist();
});
- it('does not show loader when query is populated', () => {
- expect(findLoader().exists()).toBe(false);
+ it('shows an error description', () => {
+ expect(findErrorAlert().text()).toBe(TrainingProviderList.i18n.configMutationErrorMessage);
});
});
});
diff --git a/spec/frontend/security_configuration/mock_data.js b/spec/frontend/security_configuration/mock_data.js
index cdb859c3800..37ecce3886d 100644
--- a/spec/frontend/security_configuration/mock_data.js
+++ b/spec/frontend/security_configuration/mock_data.js
@@ -1,16 +1,20 @@
+export const testProjectPath = 'foo/bar';
+
+export const textProviderIds = [101, 102];
+
export const securityTrainingProviders = [
{
- id: 101,
- name: 'Kontra',
- description: 'Interactive developer security education.',
- url: 'https://application.security/',
+ id: textProviderIds[0],
+ name: 'Vendor Name 1',
+ description: 'Interactive developer security education',
+ url: 'https://www.example.org/security/training',
isEnabled: false,
},
{
- id: 102,
- name: 'SecureCodeWarrior',
+ id: textProviderIds[1],
+ name: 'Vendor Name 2',
description: 'Security training with guide and learning pathways.',
- url: 'https://www.securecodewarrior.com/',
+ url: 'https://www.vendornametwo.com/',
isEnabled: true,
},
];
@@ -21,10 +25,15 @@ export const securityTrainingProvidersResponse = {
},
};
-export const mockResolvers = {
+const defaultMockResolvers = {
Query: {
securityTrainingProviders() {
return securityTrainingProviders;
},
},
};
+
+export const createMockResolvers = ({ resolvers: customMockResolvers = {} } = {}) => ({
+ ...defaultMockResolvers,
+ ...customMockResolvers,
+});
diff --git a/spec/frontend/serverless/components/__snapshots__/empty_state_spec.js.snap b/spec/frontend/serverless/components/__snapshots__/empty_state_spec.js.snap
index c25a8d4bb92..350055cb935 100644
--- a/spec/frontend/serverless/components/__snapshots__/empty_state_spec.js.snap
+++ b/spec/frontend/serverless/components/__snapshots__/empty_state_spec.js.snap
@@ -1,12 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`EmptyStateComponent should render content 1`] = `
-"<section class=\\"row empty-state text-center\\">
- <div class=\\"col-12\\">
+"<section class=\\"gl-display-flex empty-state gl-text-center gl-flex-direction-column\\">
+ <div class=\\"gl-max-w-full\\">
<div class=\\"svg-250 svg-content\\"><img src=\\"/image.svg\\" alt=\\"\\" role=\\"img\\" class=\\"gl-max-w-full\\"></div>
</div>
- <div class=\\"col-12\\">
- <div class=\\"text-content gl-mx-auto gl-my-0 gl-p-5\\">
+ <div class=\\"gl-max-w-full gl-m-auto\\">
+ <div class=\\"gl-mx-auto gl-my-0 gl-p-5\\">
<h1 class=\\"gl-font-size-h-display gl-line-height-36 h4\\">
Getting started with serverless
</h1>
diff --git a/spec/frontend/set_status_modal/set_status_modal_wrapper_spec.js b/spec/frontend/set_status_modal/set_status_modal_wrapper_spec.js
index d7261784edc..0c6ed998747 100644
--- a/spec/frontend/set_status_modal/set_status_modal_wrapper_spec.js
+++ b/spec/frontend/set_status_modal/set_status_modal_wrapper_spec.js
@@ -110,14 +110,23 @@ describe('SetStatusModalWrapper', () => {
});
describe('improvedEmojiPicker is true', () => {
+ const getEmojiPicker = () => wrapper.findComponent(EmojiPicker);
+
beforeEach(async () => {
await initEmojiMock();
wrapper = createComponent({}, true);
return initModal();
});
+ it('renders emoji picker dropdown with custom positioning', () => {
+ expect(getEmojiPicker().props()).toMatchObject({
+ right: false,
+ boundary: 'viewport',
+ });
+ });
+
it('sets emojiTag when clicking in emoji picker', async () => {
- await wrapper.findComponent(EmojiPicker).vm.$emit('click', 'thumbsup');
+ await getEmojiPicker().vm.$emit('click', 'thumbsup');
expect(wrapper.vm.emojiTag).toContain('data-name="thumbsup"');
});
diff --git a/spec/frontend/sidebar/components/reviewers/uncollapsed_reviewer_list_spec.js b/spec/frontend/sidebar/components/reviewers/uncollapsed_reviewer_list_spec.js
index 13887f28d22..d0792fa7b73 100644
--- a/spec/frontend/sidebar/components/reviewers/uncollapsed_reviewer_list_spec.js
+++ b/spec/frontend/sidebar/components/reviewers/uncollapsed_reviewer_list_spec.js
@@ -48,12 +48,16 @@ describe('UncollapsedReviewerList component', () => {
});
it('renders re-request loading icon', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
await wrapper.setData({ loadingStates: { 1: 'loading' } });
expect(wrapper.find('[data-testid="re-request-button"]').props('loading')).toBe(true);
});
it('renders re-request success icon', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
await wrapper.setData({ loadingStates: { 1: 'success' } });
expect(wrapper.find('[data-testid="re-request-success"]').exists()).toBe(true);
@@ -98,6 +102,8 @@ describe('UncollapsedReviewerList component', () => {
});
it('renders re-request loading icon', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
await wrapper.setData({ loadingStates: { 2: 'loading' } });
expect(wrapper.findAll('[data-testid="re-request-button"]').length).toBe(2);
@@ -107,6 +113,8 @@ describe('UncollapsedReviewerList component', () => {
});
it('renders re-request success icon', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
await wrapper.setData({ loadingStates: { 2: 'success' } });
expect(wrapper.findAll('[data-testid="re-request-button"]').length).toBe(1);
diff --git a/spec/frontend/sidebar/participants_spec.js b/spec/frontend/sidebar/participants_spec.js
index 1210f7c9531..94cdbe7f2ef 100644
--- a/spec/frontend/sidebar/participants_spec.js
+++ b/spec/frontend/sidebar/participants_spec.js
@@ -85,6 +85,8 @@ describe('Participants', () => {
numberOfLessParticipants,
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
isShowingMoreParticipants: false,
});
@@ -101,6 +103,8 @@ describe('Participants', () => {
numberOfLessParticipants: 2,
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
isShowingMoreParticipants: true,
});
@@ -129,6 +133,8 @@ describe('Participants', () => {
numberOfLessParticipants: 2,
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
isShowingMoreParticipants: false,
});
@@ -145,6 +151,8 @@ describe('Participants', () => {
numberOfLessParticipants: 2,
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
isShowingMoreParticipants: true,
});
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 40bc6fe6aa5..c193bb08543 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
@@ -90,6 +90,8 @@ exports[`Snippet Description Edit component rendering matches the snapshot 1`] =
/>
<!---->
+
+ <!---->
</div>
</div>
</div>
diff --git a/spec/frontend/snippets/components/snippet_blob_view_spec.js b/spec/frontend/snippets/components/snippet_blob_view_spec.js
index b92c1907980..172089f9ee6 100644
--- a/spec/frontend/snippets/components/snippet_blob_view_spec.js
+++ b/spec/frontend/snippets/components/snippet_blob_view_spec.js
@@ -157,6 +157,8 @@ describe('Blob Embeddable', () => {
});
// mimic apollo's update
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
blobContent: wrapper.vm.onContentUpdate(apolloData),
});
diff --git a/spec/frontend/snippets/components/snippet_header_spec.js b/spec/frontend/snippets/components/snippet_header_spec.js
index 2d5e0cfd615..daa9d6345b0 100644
--- a/spec/frontend/snippets/components/snippet_header_spec.js
+++ b/spec/frontend/snippets/components/snippet_header_spec.js
@@ -242,6 +242,8 @@ describe('Snippet header component', () => {
// TODO: we should avoid `wrapper.setData` since they
// are component internals. Let's use the apollo mock helpers
// in a follow-up.
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ canCreateSnippet: true });
await wrapper.vm.$nextTick();
diff --git a/spec/frontend/static_site_editor/components/edit_area_spec.js b/spec/frontend/static_site_editor/components/edit_area_spec.js
index 1d6245e9dbb..a833fd9ff9e 100644
--- a/spec/frontend/static_site_editor/components/edit_area_spec.js
+++ b/spec/frontend/static_site_editor/components/edit_area_spec.js
@@ -132,6 +132,8 @@ describe('~/static_site_editor/components/edit_area.vue', () => {
describe('when the mode changes', () => {
const setInitialMode = (mode) => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ editorMode: mode });
};
@@ -207,6 +209,8 @@ describe('~/static_site_editor/components/edit_area.vue', () => {
});
it('syncs matter changes to content in markdown mode', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ editorMode: EDITOR_TYPES.markdown });
const newSettings = { title: 'test' };
diff --git a/spec/frontend/static_site_editor/rich_content_editor/modals/add_image/add_image_modal_spec.js b/spec/frontend/static_site_editor/rich_content_editor/modals/add_image/add_image_modal_spec.js
index 86ae016987d..c8c9f45618d 100644
--- a/spec/frontend/static_site_editor/rich_content_editor/modals/add_image/add_image_modal_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/modals/add_image/add_image_modal_spec.js
@@ -48,6 +48,8 @@ describe('Add Image Modal', () => {
const file = { name: 'some_file.png' };
wrapper.vm.$refs.uploadImageTab = { validateFile: jest.fn() };
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ file, description, tabIndex: IMAGE_TABS.UPLOAD_TAB });
findModal().vm.$emit('ok', { preventDefault });
@@ -60,6 +62,8 @@ describe('Add Image Modal', () => {
it('emits an addImage event when a valid URL is specified', () => {
const preventDefault = jest.fn();
const mockImage = { imageUrl: '/some/valid/url.png', description: 'some description' };
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ ...mockImage, tabIndex: IMAGE_TABS.URL_TAB });
findModal().vm.$emit('ok', { preventDefault });
diff --git a/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_identifier_paragraph_spec.js b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_identifier_paragraph_spec.js
index 6a2b89a8dcf..ddc96ed6832 100644
--- a/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_identifier_paragraph_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_identifier_paragraph_spec.js
@@ -13,7 +13,7 @@ const normalParagraphNode = buildMockParagraphNode(
'This is just normal paragraph. It has multiple sentences.',
);
const identifierParagraphNode = buildMockParagraphNode(
- `[another-identifier]: https://example.com "This example has a title" [identifier]: http://example1.com [this link]: http://example2.com`,
+ `[another-identifier]: https://example.com "This example has a title" [identifier]: http://example1.com [this link]: http://example.org`,
);
describe('rich_content_editor/renderers_render_identifier_paragraph', () => {
diff --git a/spec/frontend/terraform/components/states_table_actions_spec.js b/spec/frontend/terraform/components/states_table_actions_spec.js
index 9d28e8ce294..fbe55306f37 100644
--- a/spec/frontend/terraform/components/states_table_actions_spec.js
+++ b/spec/frontend/terraform/components/states_table_actions_spec.js
@@ -293,6 +293,8 @@ describe('StatesTableActions', () => {
describe('when state name is present', () => {
beforeEach(async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
await wrapper.setData({ removeConfirmText: defaultProps.state.name });
findRemoveModal().vm.$emit('ok');
diff --git a/spec/frontend/tracking/tracking_initialization_spec.js b/spec/frontend/tracking/tracking_initialization_spec.js
index 2b70aacc4cb..f1628ad9793 100644
--- a/spec/frontend/tracking/tracking_initialization_spec.js
+++ b/spec/frontend/tracking/tracking_initialization_spec.js
@@ -81,7 +81,8 @@ describe('Tracking', () => {
it('should activate features based on what has been enabled', () => {
initDefaultTrackers();
expect(snowplowSpy).toHaveBeenCalledWith('enableActivityTracking', 30, 30);
- expect(snowplowSpy).toHaveBeenCalledWith('trackPageView', null, [standardContext]);
+ expect(snowplowSpy).toHaveBeenCalledWith('trackPageView', 'GitLab', [standardContext]);
+ expect(snowplowSpy).toHaveBeenCalledWith('setDocumentTitle', 'GitLab');
expect(snowplowSpy).not.toHaveBeenCalledWith('enableFormTracking');
expect(snowplowSpy).not.toHaveBeenCalledWith('enableLinkClickTracking');
@@ -130,7 +131,7 @@ describe('Tracking', () => {
it('includes those contexts alongside the standard context', () => {
initDefaultTrackers();
- expect(snowplowSpy).toHaveBeenCalledWith('trackPageView', null, [
+ expect(snowplowSpy).toHaveBeenCalledWith('trackPageView', 'GitLab', [
standardContext,
...experimentContexts,
]);
diff --git a/spec/frontend/transfer_edit_spec.js b/spec/frontend/transfer_edit_spec.js
deleted file mode 100644
index 4091d753fe5..00000000000
--- a/spec/frontend/transfer_edit_spec.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import $ from 'jquery';
-
-import { loadHTMLFixture } from 'helpers/fixtures';
-import setupTransferEdit from '~/transfer_edit';
-
-describe('setupTransferEdit', () => {
- const formSelector = '.js-group-transfer-form';
- const targetSelector = '#new_parent_group_id';
-
- beforeEach(() => {
- loadHTMLFixture('groups/edit.html');
- setupTransferEdit(formSelector, targetSelector);
- });
-
- it('disables submit button on load', () => {
- expect($(formSelector).find(':submit').prop('disabled')).toBe(true);
- });
-
- it('enables submit button when selection changes to non-empty value', () => {
- const lastValue = $(formSelector).find(targetSelector).find('.dropdown-content li').last();
- $(formSelector).find(targetSelector).val(lastValue).trigger('change');
-
- expect($(formSelector).find(':submit').prop('disabled')).toBeFalsy();
- });
-
- it('disables submit button when selection changes to empty value', () => {
- $(formSelector).find(targetSelector).val('').trigger('change');
-
- expect($(formSelector).find(':submit').prop('disabled')).toBe(true);
- });
-});
diff --git a/spec/frontend/version_check_image_spec.js b/spec/frontend/version_check_image_spec.js
deleted file mode 100644
index 13bd104a91c..00000000000
--- a/spec/frontend/version_check_image_spec.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import $ from 'jquery';
-import ClassSpecHelper from 'helpers/class_spec_helper';
-import VersionCheckImage from '~/version_check_image';
-
-describe('VersionCheckImage', () => {
- let testContext;
-
- beforeEach(() => {
- testContext = {};
- });
-
- describe('bindErrorEvent', () => {
- ClassSpecHelper.itShouldBeAStaticMethod(VersionCheckImage, 'bindErrorEvent');
-
- beforeEach(() => {
- testContext.imageElement = $('<div></div>');
- });
-
- it('registers an error event', () => {
- jest.spyOn($.prototype, 'on').mockImplementation(() => {});
- // eslint-disable-next-line func-names
- jest.spyOn($.prototype, 'off').mockImplementation(function () {
- return this;
- });
-
- VersionCheckImage.bindErrorEvent(testContext.imageElement);
-
- expect($.prototype.off).toHaveBeenCalledWith('error');
- expect($.prototype.on).toHaveBeenCalledWith('error', expect.any(Function));
- });
-
- it('hides the imageElement on error', () => {
- jest.spyOn($.prototype, 'hide').mockImplementation(() => {});
-
- VersionCheckImage.bindErrorEvent(testContext.imageElement);
-
- testContext.imageElement.trigger('error');
-
- expect($.prototype.hide).toHaveBeenCalled();
- });
- });
-});
diff --git a/spec/frontend/vue_mr_widget/components/approvals/approvals_spec.js b/spec/frontend/vue_mr_widget/components/approvals/approvals_spec.js
index af6624a6c43..36850e623c7 100644
--- a/spec/frontend/vue_mr_widget/components/approvals/approvals_spec.js
+++ b/spec/frontend/vue_mr_widget/components/approvals/approvals_spec.js
@@ -101,6 +101,8 @@ describe('MRWidget approvals', () => {
});
it('shows loading message', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ fetchingApprovals: true });
return tick().then(() => {
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_header_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_header_spec.js
index a09269e869c..5a1f17573d4 100644
--- a/spec/frontend/vue_mr_widget/components/mr_widget_header_spec.js
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_header_spec.js
@@ -153,6 +153,8 @@ describe('MRWidgetHeader', () => {
gitpodEnabled: true,
showGitpodButton: true,
gitpodUrl: 'http://gitpod.localhost',
+ userPreferencesGitpodPath: '/-/profile/preferences#user_gitpod_enabled',
+ userProfileEnableGitpodPath: '/-/profile?user%5Bgitpod_enabled%5D=true',
};
it('renders checkout branch button with modal trigger', () => {
@@ -208,6 +210,8 @@ describe('MRWidgetHeader', () => {
gitpodEnabled: true,
showGitpodButton: true,
gitpodUrl: 'http://gitpod.localhost',
+ userPreferencesGitpodPath: mrDefaultOptions.userPreferencesGitpodPath,
+ userProfileEnableGitpodPath: mrDefaultOptions.userProfileEnableGitpodPath,
webIdeUrl,
});
});
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 d3221cc2fc7..27604868b3e 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,10 +2,15 @@ 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;
-function factory(propsData, mergeRequestWidgetGraphql) {
+function createWrapper(propsData, mergeRequestWidgetGraphql, rebaseWithoutCiUi) {
wrapper = shallowMount(WidgetRebase, {
propsData,
data() {
@@ -19,7 +24,7 @@ function factory(propsData, mergeRequestWidgetGraphql) {
},
};
},
- provide: { glFeatures: { mergeRequestWidgetGraphql } },
+ provide: { glFeatures: { mergeRequestWidgetGraphql, rebaseWithoutCiUi } },
mocks: {
$apollo: {
queries: {
@@ -31,8 +36,10 @@ function factory(propsData, mergeRequestWidgetGraphql) {
}
describe('Merge request widget rebase component', () => {
- const findRebaseMessageEl = () => wrapper.find('[data-testid="rebase-message"]');
- const findRebaseMessageElText = () => findRebaseMessageEl().text();
+ 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"]');
afterEach(() => {
wrapper.destroy();
@@ -40,10 +47,10 @@ describe('Merge request widget rebase component', () => {
});
[true, false].forEach((mergeRequestWidgetGraphql) => {
- describe(`widget graphql is ${mergeRequestWidgetGraphql ? 'enabled' : 'dislabed'}`, () => {
- describe('While rebasing', () => {
+ describe(`widget graphql is ${mergeRequestWidgetGraphql ? 'enabled' : 'disabled'}`, () => {
+ describe('while rebasing', () => {
it('should show progress message', () => {
- factory(
+ createWrapper(
{
mr: { rebaseInProgress: true },
service: {},
@@ -51,24 +58,30 @@ describe('Merge request widget rebase component', () => {
mergeRequestWidgetGraphql,
);
- expect(findRebaseMessageElText()).toContain('Rebase in progress');
+ expect(findRebaseMessageText()).toContain('Rebase in progress');
});
});
- describe('With permissions', () => {
- it('it should render rebase button and warning message', () => {
- factory(
+ describe('with permissions', () => {
+ const rebaseMock = jest.fn().mockResolvedValue();
+ const pollMock = jest.fn().mockResolvedValue({});
+
+ it('renders the warning message', () => {
+ createWrapper(
{
mr: {
rebaseInProgress: false,
canPushToSourceBranch: true,
},
- service: {},
+ service: {
+ rebase: rebaseMock,
+ poll: pollMock,
+ },
},
mergeRequestWidgetGraphql,
);
- const text = findRebaseMessageElText();
+ const text = findRebaseMessageText();
expect(text).toContain('Merge blocked');
expect(text.replace(/\s\s+/g, ' ')).toContain(
@@ -76,73 +89,195 @@ describe('Merge request widget rebase component', () => {
);
});
- it('it should render error message when it fails', async () => {
- factory(
+ it('renders an error message when rebasing has failed', async () => {
+ createWrapper(
{
mr: {
rebaseInProgress: false,
canPushToSourceBranch: true,
},
- service: {},
+ service: {
+ rebase: rebaseMock,
+ poll: pollMock,
+ },
},
mergeRequestWidgetGraphql,
);
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ rebasingError: 'Something went wrong!' });
await nextTick();
- expect(findRebaseMessageElText()).toContain('Something went wrong!');
+ expect(findRebaseMessageText()).toContain('Something went wrong!');
+ });
+
+ describe('Rebase button with flag rebaseWithoutCiUi', () => {
+ beforeEach(() => {
+ createWrapper(
+ {
+ mr: {
+ rebaseInProgress: false,
+ canPushToSourceBranch: true,
+ },
+ service: {
+ rebase: rebaseMock,
+ poll: pollMock,
+ },
+ },
+ mergeRequestWidgetGraphql,
+ { rebaseWithoutCiUi: true },
+ );
+ });
+
+ 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('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();
+
+ await nextTick();
+
+ expect(rebaseMock).toHaveBeenCalledWith({ skipCi: false });
+ });
+
+ 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();
+
+ await nextTick();
+
+ expect(rebaseMock).toHaveBeenCalledWith({ skipCi: true });
+ });
+ });
+
+ describe('Rebase button with rebaseWithoutCiUI flag disabled', () => {
+ beforeEach(() => {
+ createWrapper(
+ {
+ mr: {
+ rebaseInProgress: false,
+ canPushToSourceBranch: true,
+ },
+ service: {
+ rebase: rebaseMock,
+ poll: pollMock,
+ },
+ },
+ mergeRequestWidgetGraphql,
+ );
+ });
+
+ it('standard rebase button is rendered', () => {
+ expect(findStandardRebaseButton().exists()).toBe(true);
+ expect(findRebaseButtonActions().exists()).toBe(false);
+ });
+
+ it('calls rebase method with skip_ci false', () => {
+ findStandardRebaseButton().vm.$emit('click');
+
+ expect(rebaseMock).toHaveBeenCalledWith({ skipCi: false });
+ });
});
});
- describe('Without permissions', () => {
- it('should render a message explaining user does not have permissions', () => {
- factory(
+ describe('without permissions', () => {
+ const exampleTargetBranch = 'fake-branch-to-test-with';
+
+ describe('UI text', () => {
+ beforeEach(() => {
+ createWrapper(
+ {
+ mr: {
+ rebaseInProgress: false,
+ canPushToSourceBranch: false,
+ targetBranch: exampleTargetBranch,
+ },
+ service: {},
+ },
+ mergeRequestWidgetGraphql,
+ );
+ });
+
+ it('renders a message explaining user does not have permissions', () => {
+ const text = findRebaseMessageText();
+
+ expect(text).toContain(
+ 'Merge blocked: the source branch must be rebased onto the target branch.',
+ );
+ expect(text).toContain('the source branch must be rebased');
+ });
+
+ it('renders the correct target branch name', () => {
+ const elem = findRebaseMessage();
+
+ expect(elem.text()).toContain(
+ 'Merge blocked: the source branch must be rebased onto the target branch.',
+ );
+ });
+ });
+
+ it('does not render the rebase actions button with rebaseWithoutCiUI flag enabled', () => {
+ createWrapper(
{
mr: {
rebaseInProgress: false,
canPushToSourceBranch: false,
- targetBranch: 'foo',
+ targetBranch: exampleTargetBranch,
},
service: {},
},
mergeRequestWidgetGraphql,
+ { rebaseWithoutCiUi: true },
);
- const text = findRebaseMessageElText();
-
- expect(text).toContain(
- 'Merge blocked: the source branch must be rebased onto the target branch.',
- );
- expect(text).toContain('the source branch must be rebased');
+ expect(findRebaseButtonActions().exists()).toBe(false);
});
- it('should render the correct target branch name', () => {
- const targetBranch = 'fake-branch-to-test-with';
- factory(
+ it('does not render the standard rebase button with rebaseWithoutCiUI flag disabled', () => {
+ createWrapper(
{
mr: {
rebaseInProgress: false,
canPushToSourceBranch: false,
- targetBranch,
+ targetBranch: exampleTargetBranch,
},
service: {},
},
mergeRequestWidgetGraphql,
);
- const elem = findRebaseMessageEl();
-
- expect(elem.text()).toContain(
- `Merge blocked: the source branch must be rebased onto the target branch.`,
- );
+ expect(findStandardRebaseButton().exists()).toBe(false);
});
});
describe('methods', () => {
it('checkRebaseStatus', async () => {
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
- factory(
+ createWrapper(
{
mr: {},
service: {
diff --git a/spec/frontend/vue_mr_widget/components/states/merge_checks_failed_spec.js b/spec/frontend/vue_mr_widget/components/states/merge_checks_failed_spec.js
index bdad0bada5f..1900b53ac11 100644
--- a/spec/frontend/vue_mr_widget/components/states/merge_checks_failed_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/merge_checks_failed_spec.js
@@ -15,35 +15,12 @@ describe('Merge request widget merge checks failed state component', () => {
});
it.each`
- mrState | displayText
- ${{ isPipelineFailed: true }} | ${'pipelineFailed'}
- ${{ approvals: true, isApproved: false }} | ${'approvalNeeded'}
- ${{ hasMergeableDiscussionsState: true }} | ${'unresolvedDiscussions'}
+ mrState | displayText
+ ${{ approvals: true, isApproved: false }} | ${'approvalNeeded'}
+ ${{ blockingMergeRequests: { total_count: 1 } }} | ${'blockingMergeRequests'}
`('display $displayText text for $mrState', ({ mrState, displayText }) => {
factory({ mr: mrState });
expect(wrapper.text()).toContain(MergeChecksFailed.i18n[displayText]);
});
-
- describe('unresolved discussions', () => {
- it('renders jump to button', () => {
- factory({ mr: { hasMergeableDiscussionsState: true } });
-
- expect(wrapper.find('[data-testid="jumpToUnresolved"]').exists()).toBe(true);
- });
-
- it('renders resolve thread button', () => {
- factory({
- mr: {
- hasMergeableDiscussionsState: true,
- createIssueToResolveDiscussionsPath: 'https://gitlab.com',
- },
- });
-
- expect(wrapper.find('[data-testid="resolveIssue"]').exists()).toBe(true);
- expect(wrapper.find('[data-testid="resolveIssue"]').attributes('href')).toBe(
- 'https://gitlab.com',
- );
- });
- });
});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js
index d0a6af9970e..52a56af454f 100644
--- a/spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js
@@ -253,6 +253,8 @@ describe('MRWidgetAutoMergeEnabled', () => {
factory({
...defaultMrProps(),
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
isCancellingAutoMerge: true,
});
@@ -287,6 +289,8 @@ describe('MRWidgetAutoMergeEnabled', () => {
factory({
...defaultMrProps(),
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
isRemovingSourceBranch: true,
});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_commits_header_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_commits_header_spec.js
index 5858654e518..4d05e732f48 100644
--- a/spec/frontend/vue_mr_widget/components/states/mr_widget_commits_header_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_commits_header_spec.js
@@ -60,6 +60,8 @@ describe('Commits header component', () => {
it('has a chevron-right icon', () => {
createComponent();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ expanded: false });
return wrapper.vm.$nextTick().then(() => {
@@ -111,6 +113,8 @@ describe('Commits header component', () => {
describe('when expanded', () => {
beforeEach(() => {
createComponent();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ expanded: true });
});
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 89de160b02f..ec222e66a97 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
@@ -41,6 +41,8 @@ describe('MRWidgetConflicts', () => {
);
if (mergeRequestWidgetGraphql) {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
userPermissions: {
canMerge: propsData.mr.canMerge,
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js
index 848677bf4d2..936d673768c 100644
--- a/spec/frontend/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js
@@ -14,6 +14,8 @@ function factory(sourceBranchRemoved, mergeRequestWidgetGraphql) {
});
if (mergeRequestWidgetGraphql) {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ state: { sourceBranchExists: !sourceBranchRemoved } });
}
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 7082a19a8e7..f4ecebbb40c 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
@@ -192,6 +192,8 @@ describe('ReadyToMerge', () => {
it('should return "Merge in progress"', async () => {
createComponent();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ isMergingImmediately: true });
await Vue.nextTick();
@@ -260,6 +262,8 @@ describe('ReadyToMerge', () => {
it('should return true when the vm instance is making request', async () => {
createComponent({ mr: { isMergeAllowed: true } });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ isMakingRequest: true });
await Vue.nextTick();
@@ -287,6 +291,8 @@ describe('ReadyToMerge', () => {
jest
.spyOn(wrapper.vm.service, 'merge')
.mockReturnValue(returnPromise('merge_when_pipeline_succeeds'));
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ removeSourceBranch: false });
wrapper.vm.handleMergeButtonClick(true);
@@ -691,6 +697,8 @@ describe('ReadyToMerge', () => {
true,
);
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
loading: false,
state: {
diff --git a/spec/frontend/vue_mr_widget/components/terraform/mock_data.js b/spec/frontend/vue_mr_widget/components/terraform/mock_data.js
index ae280146c22..8e46af5dfd6 100644
--- a/spec/frontend/vue_mr_widget/components/terraform/mock_data.js
+++ b/spec/frontend/vue_mr_widget/components/terraform/mock_data.js
@@ -1,6 +1,6 @@
export const invalidPlanWithName = {
job_name: 'Invalid Plan',
- job_path: '/path/to/ci/logs/1',
+ job_path: '/path/to/ci/logs/3',
tf_report_error: 'api_error',
};
@@ -20,12 +20,12 @@ export const validPlanWithoutName = {
create: 10,
update: 20,
delete: 30,
- job_path: '/path/to/ci/logs/1',
+ job_path: '/path/to/ci/logs/2',
};
export const plans = {
invalid_plan_one: invalidPlanWithName,
- invalid_plan_two: invalidPlanWithName,
+ invalid_plan_two: invalidPlanWithoutName,
valid_plan_one: validPlanWithName,
valid_plan_two: validPlanWithoutName,
};
diff --git a/spec/frontend/vue_mr_widget/components/terraform/mr_widget_terraform_container_spec.js b/spec/frontend/vue_mr_widget/components/terraform/mr_widget_terraform_container_spec.js
index 364f849eb4f..9048975875a 100644
--- a/spec/frontend/vue_mr_widget/components/terraform/mr_widget_terraform_container_spec.js
+++ b/spec/frontend/vue_mr_widget/components/terraform/mr_widget_terraform_container_spec.js
@@ -43,6 +43,8 @@ describe('MrWidgetTerraformConainer', () => {
mockPollingApi(200, plans, {});
return mountWrapper().then(() => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ loading: true });
return wrapper.vm.$nextTick();
});
diff --git a/spec/frontend/vue_mr_widget/extentions/terraform/index_spec.js b/spec/frontend/vue_mr_widget/extentions/terraform/index_spec.js
new file mode 100644
index 00000000000..f8ea6fc23a2
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/extentions/terraform/index_spec.js
@@ -0,0 +1,178 @@
+import MockAdapter from 'axios-mock-adapter';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import axios from '~/lib/utils/axios_utils';
+import Poll from '~/lib/utils/poll';
+import extensionsContainer from '~/vue_merge_request_widget/components/extensions/container';
+import { registerExtension } from '~/vue_merge_request_widget/components/extensions';
+import terraformExtension from '~/vue_merge_request_widget/extensions/terraform';
+import {
+ plans,
+ validPlanWithName,
+ validPlanWithoutName,
+ invalidPlanWithName,
+ invalidPlanWithoutName,
+} from '../../components/terraform/mock_data';
+
+describe('Terraform extension', () => {
+ let wrapper;
+ let mock;
+
+ const endpoint = '/path/to/terraform/report.json';
+ const successStatusCode = 200;
+ const errorStatusCode = 500;
+
+ const findListItem = (at) => wrapper.findAllByTestId('extension-list-item').at(at);
+
+ registerExtension(terraformExtension);
+
+ const mockPollingApi = (response, body, header) => {
+ mock.onGet(endpoint).reply(response, body, header);
+ };
+
+ const createComponent = () => {
+ wrapper = mountExtended(extensionsContainer, {
+ propsData: {
+ mr: {
+ terraformReportsPath: endpoint,
+ },
+ },
+ });
+ return axios.waitForAll();
+ };
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ mock.restore();
+ });
+
+ describe('summary', () => {
+ describe('while loading', () => {
+ const loadingText = 'Loading Terraform reports...';
+ it('should render loading text', async () => {
+ mockPollingApi(successStatusCode, plans, {});
+ createComponent();
+
+ expect(wrapper.text()).toContain(loadingText);
+ await waitForPromises();
+ expect(wrapper.text()).not.toContain(loadingText);
+ });
+ });
+
+ describe('when the fetching fails', () => {
+ beforeEach(() => {
+ mockPollingApi(errorStatusCode, null, {});
+ return createComponent();
+ });
+
+ it('should generate one invalid plan and render correct summary text', () => {
+ expect(wrapper.text()).toContain('1 Terraform report failed to generate');
+ });
+ });
+
+ describe('when the fetching succeeds', () => {
+ describe.each`
+ responseType | response | summaryTitle | summarySubtitle
+ ${'1 invalid report'} | ${{ 0: invalidPlanWithName }} | ${'1 Terraform report failed to generate'} | ${''}
+ ${'2 valid reports'} | ${{ 0: validPlanWithName, 1: validPlanWithName }} | ${'2 Terraform reports were generated in your pipelines'} | ${''}
+ ${'1 valid and 2 invalid reports'} | ${{ 0: validPlanWithName, 1: invalidPlanWithName, 2: invalidPlanWithName }} | ${'Terraform report was generated in your pipelines'} | ${'2 Terraform reports failed to generate'}
+ `('and received $responseType', ({ response, summaryTitle, summarySubtitle }) => {
+ beforeEach(async () => {
+ mockPollingApi(successStatusCode, response, {});
+ return createComponent();
+ });
+
+ it(`should render correct summary text`, () => {
+ expect(wrapper.text()).toContain(summaryTitle);
+
+ if (summarySubtitle) {
+ expect(wrapper.text()).toContain(summarySubtitle);
+ }
+ });
+ });
+ });
+ });
+
+ describe('expanded data', () => {
+ beforeEach(async () => {
+ mockPollingApi(successStatusCode, plans, {});
+ await createComponent();
+
+ wrapper.findByTestId('toggle-button').trigger('click');
+ });
+
+ describe.each`
+ reportType | title | subtitle | logLink | lineNumber
+ ${'a valid report with name'} | ${`The job ${validPlanWithName.job_name} generated a report.`} | ${`Reported Resource Changes: ${validPlanWithName.create} to add, ${validPlanWithName.update} to change, ${validPlanWithName.delete} to delete`} | ${validPlanWithName.job_path} | ${0}
+ ${'a valid report without name'} | ${'A Terraform report was generated in your pipelines.'} | ${`Reported Resource Changes: ${validPlanWithoutName.create} to add, ${validPlanWithoutName.update} to change, ${validPlanWithoutName.delete} to delete`} | ${validPlanWithoutName.job_path} | ${1}
+ ${'an invalid report with name'} | ${`The job ${invalidPlanWithName.job_name} failed to generate a report.`} | ${'Generating the report caused an error.'} | ${invalidPlanWithName.job_path} | ${2}
+ ${'an invalid report without name'} | ${'A Terraform report failed to generate.'} | ${'Generating the report caused an error.'} | ${invalidPlanWithoutName.job_path} | ${3}
+ `('renders correct text for $reportType', ({ title, subtitle, logLink, lineNumber }) => {
+ it('renders correct text', () => {
+ expect(findListItem(lineNumber).text()).toContain(title);
+ expect(findListItem(lineNumber).text()).toContain(subtitle);
+ });
+
+ it(`${logLink ? 'renders' : "doesn't render"} the log link`, () => {
+ const logText = 'Full log';
+ if (logLink) {
+ expect(
+ findListItem(lineNumber)
+ .find('[data-testid="extension-actions-button"]')
+ .attributes('href'),
+ ).toBe(logLink);
+ } else {
+ expect(findListItem(lineNumber).text()).not.toContain(logText);
+ }
+ });
+ });
+ });
+
+ describe('polling', () => {
+ let pollRequest;
+ let pollStop;
+
+ beforeEach(() => {
+ pollRequest = jest.spyOn(Poll.prototype, 'makeRequest');
+ pollStop = jest.spyOn(Poll.prototype, 'stop');
+ });
+
+ afterEach(() => {
+ pollRequest.mockRestore();
+ pollStop.mockRestore();
+ });
+
+ describe('successful poll', () => {
+ beforeEach(() => {
+ mockPollingApi(successStatusCode, plans, {});
+
+ return createComponent();
+ });
+
+ it('does not make additional requests after poll is successful', () => {
+ expect(pollRequest).toHaveBeenCalledTimes(1);
+ expect(pollStop).toHaveBeenCalledTimes(1);
+ });
+ });
+
+ describe('polling fails', () => {
+ beforeEach(() => {
+ mockPollingApi(errorStatusCode, null, {});
+ return createComponent();
+ });
+
+ it('generates one broken plan', () => {
+ expect(wrapper.text()).toContain('1 Terraform report failed to generate');
+ });
+
+ it('does not make additional requests after poll is unsuccessful', () => {
+ expect(pollRequest).toHaveBeenCalledTimes(1);
+ expect(pollStop).toHaveBeenCalledTimes(1);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/mock_data.js b/spec/frontend/vue_mr_widget/mock_data.js
index 4538c1320d0..20d00a116bb 100644
--- a/spec/frontend/vue_mr_widget/mock_data.js
+++ b/spec/frontend/vue_mr_widget/mock_data.js
@@ -282,6 +282,8 @@ export default {
gitpod_enabled: true,
show_gitpod_button: true,
gitpod_url: 'http://gitpod.localhost',
+ user_preferences_gitpod_path: '/-/profile/preferences#user_gitpod_enabled',
+ user_profile_enable_gitpod_path: '/-/profile?user%5Bgitpod_enabled%5D=true',
};
export const mockStore = {
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 8d41f6620ff..56c9bae0b76 100644
--- a/spec/frontend/vue_mr_widget/mr_widget_options_spec.js
+++ b/spec/frontend/vue_mr_widget/mr_widget_options_spec.js
@@ -9,6 +9,7 @@ import waitForPromises from 'helpers/wait_for_promises';
import { securityReportMergeRequestDownloadPathsQueryResponse } from 'jest/vue_shared/security_reports/mock_data';
import api from '~/api';
import axios from '~/lib/utils/axios_utils';
+import Poll from '~/lib/utils/poll';
import { setFaviconOverlay } from '~/lib/utils/favicon';
import notify from '~/lib/utils/notify';
import SmartInterval from '~/smart_interval';
@@ -28,6 +29,8 @@ import {
workingExtension,
collapsedDataErrorExtension,
fullDataErrorExtension,
+ pollingExtension,
+ pollingErrorExtension,
} from './test_extensions';
jest.mock('~/api.js');
@@ -897,13 +900,19 @@ describe('MrWidgetOptions', () => {
});
describe('mock extension', () => {
+ let pollRequest;
+
beforeEach(() => {
+ pollRequest = jest.spyOn(Poll.prototype, 'makeRequest');
+
registerExtension(workingExtension);
createComponent();
});
afterEach(() => {
+ pollRequest.mockRestore();
+
registeredExtensions.extensions = [];
});
@@ -957,6 +966,66 @@ describe('MrWidgetOptions', () => {
expect(collapsedSection.find(GlButton).exists()).toBe(true);
expect(collapsedSection.find(GlButton).text()).toBe('Full report');
});
+
+ it('extension polling is not called if enablePolling flag is not passed', () => {
+ // called one time due to parent component polling (mount)
+ expect(pollRequest).toHaveBeenCalledTimes(1);
+ });
+ });
+
+ describe('mock polling extension', () => {
+ let pollRequest;
+ let pollStop;
+
+ beforeEach(() => {
+ pollRequest = jest.spyOn(Poll.prototype, 'makeRequest');
+ pollStop = jest.spyOn(Poll.prototype, 'stop');
+ });
+
+ afterEach(() => {
+ pollRequest.mockRestore();
+ pollStop.mockRestore();
+
+ registeredExtensions.extensions = [];
+ });
+
+ describe('success', () => {
+ beforeEach(() => {
+ registerExtension(pollingExtension);
+
+ createComponent();
+ });
+
+ it('does not make additional requests after poll is successful', () => {
+ // called two times due to parent component polling (mount) and extension polling
+ expect(pollRequest).toHaveBeenCalledTimes(2);
+ expect(pollStop).toHaveBeenCalledTimes(1);
+ });
+ });
+
+ describe('error', () => {
+ let captureException;
+
+ beforeEach(() => {
+ captureException = jest.spyOn(Sentry, 'captureException');
+
+ registerExtension(pollingErrorExtension);
+
+ createComponent();
+ });
+
+ it('does not make additional requests after poll has failed', () => {
+ // called two times due to parent component polling (mount) and extension polling
+ expect(pollRequest).toHaveBeenCalledTimes(2);
+ expect(pollStop).toHaveBeenCalledTimes(1);
+ });
+
+ it('captures sentry error and displays error when poll has failed', () => {
+ expect(captureException).toHaveBeenCalledTimes(1);
+ expect(captureException).toHaveBeenCalledWith(new Error('Fetch error'));
+ expect(wrapper.findComponent(StatusIcon).props('iconName')).toBe('error');
+ });
+ });
});
describe('mock extension errors', () => {
diff --git a/spec/frontend/vue_mr_widget/stores/mr_widget_store_spec.js b/spec/frontend/vue_mr_widget/stores/mr_widget_store_spec.js
index 6eb68a1b00d..3cdb4265ef0 100644
--- a/spec/frontend/vue_mr_widget/stores/mr_widget_store_spec.js
+++ b/spec/frontend/vue_mr_widget/stores/mr_widget_store_spec.js
@@ -15,6 +15,8 @@ describe('MergeRequestStore', () => {
gitpodEnabled: mockData.gitpod_enabled,
showGitpodButton: mockData.show_gitpod_button,
gitpodUrl: mockData.gitpod_url,
+ userPreferencesGitpodPath: mockData.user_preferences_gitpod_path,
+ userProfileEnableGitpodPath: mockData.user_profile_enable_gitpod_path,
});
});
diff --git a/spec/frontend/vue_mr_widget/test_extensions.js b/spec/frontend/vue_mr_widget/test_extensions.js
index c7ff02ab726..986c1d6545a 100644
--- a/spec/frontend/vue_mr_widget/test_extensions.js
+++ b/spec/frontend/vue_mr_widget/test_extensions.js
@@ -97,3 +97,13 @@ export const fullDataErrorExtension = {
},
},
};
+
+export const pollingExtension = {
+ ...workingExtension,
+ enablePolling: true,
+};
+
+export const pollingErrorExtension = {
+ ...collapsedDataErrorExtension,
+ enablePolling: true,
+};
diff --git a/spec/frontend/vue_shared/alert_details/alert_details_spec.js b/spec/frontend/vue_shared/alert_details/alert_details_spec.js
index 1fc655f1ebc..221beed744b 100644
--- a/spec/frontend/vue_shared/alert_details/alert_details_spec.js
+++ b/spec/frontend/vue_shared/alert_details/alert_details_spec.js
@@ -349,6 +349,8 @@ describe('AlertDetails', () => {
${1} | ${'metrics'}
${2} | ${'activity'}
`('will navigate to the correct tab via $tabId', ({ index, tabId }) => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ currentTabIndex: index });
expect($router.replace).toHaveBeenCalledWith({ name: 'tab', params: { tabId } });
});
diff --git a/spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_assignees_spec.js b/spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_assignees_spec.js
index 9ae45071f45..29e0eee2c9a 100644
--- a/spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_assignees_spec.js
+++ b/spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_assignees_spec.js
@@ -109,6 +109,8 @@ describe('Alert Details Sidebar Assignees', () => {
});
it('renders a unassigned option', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ isDropdownSearching: false });
await wrapper.vm.$nextTick();
expect(findDropdown().text()).toBe('Unassigned');
@@ -120,6 +122,8 @@ describe('Alert Details Sidebar Assignees', () => {
it('calls `$apollo.mutate` with `AlertSetAssignees` mutation and variables containing `iid`, `assigneeUsernames`, & `projectPath`', async () => {
jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(mockUpdatedMutationResult);
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ isDropdownSearching: false });
await wrapper.vm.$nextTick();
@@ -136,6 +140,8 @@ describe('Alert Details Sidebar Assignees', () => {
});
it('emits an error when request contains error messages', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ isDropdownSearching: false });
const errorMutationResult = {
data: {
diff --git a/spec/frontend/vue_shared/components/chronic_duration_input_spec.js b/spec/frontend/vue_shared/components/chronic_duration_input_spec.js
index 530d01402c6..083a5f60d1d 100644
--- a/spec/frontend/vue_shared/components/chronic_duration_input_spec.js
+++ b/spec/frontend/vue_shared/components/chronic_duration_input_spec.js
@@ -315,6 +315,8 @@ describe('vue_shared/components/chronic_duration_input', () => {
});
it('passes updated prop via v-model', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ value: MOCK_VALUE });
await wrapper.vm.$nextTick();
diff --git a/spec/frontend/vue_shared/components/clipboard_button_spec.js b/spec/frontend/vue_shared/components/clipboard_button_spec.js
index 33445923a49..fca5e664a96 100644
--- a/spec/frontend/vue_shared/components/clipboard_button_spec.js
+++ b/spec/frontend/vue_shared/components/clipboard_button_spec.js
@@ -1,8 +1,16 @@
import { GlButton } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
-import initCopyToClipboard from '~/behaviors/copy_to_clipboard';
+import { nextTick } from 'vue';
+
+import initCopyToClipboard, {
+ CLIPBOARD_SUCCESS_EVENT,
+ CLIPBOARD_ERROR_EVENT,
+ I18N_ERROR_MESSAGE,
+} from '~/behaviors/copy_to_clipboard';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
+jest.mock('lodash/uniqueId', () => (prefix) => (prefix ? `${prefix}1` : 1));
+
describe('clipboard button', () => {
let wrapper;
@@ -15,6 +23,42 @@ describe('clipboard button', () => {
const findButton = () => wrapper.find(GlButton);
+ const expectConfirmationTooltip = async ({ event, message }) => {
+ const title = 'Copy this value';
+
+ createWrapper({
+ text: 'copy me',
+ title,
+ });
+
+ wrapper.vm.$root.$emit = jest.fn();
+
+ const button = findButton();
+
+ expect(button.attributes()).toMatchObject({
+ title,
+ 'aria-label': title,
+ });
+
+ await button.trigger(event);
+
+ expect(wrapper.vm.$root.$emit).toHaveBeenCalledWith('bv::show::tooltip', 'clipboard-button-1');
+
+ expect(button.attributes()).toMatchObject({
+ title: message,
+ 'aria-label': message,
+ });
+
+ jest.runAllTimers();
+ await nextTick();
+
+ expect(button.attributes()).toMatchObject({
+ title,
+ 'aria-label': title,
+ });
+ expect(wrapper.vm.$root.$emit).toHaveBeenCalledWith('bv::hide::tooltip', 'clipboard-button-1');
+ };
+
afterEach(() => {
wrapper.destroy();
wrapper = null;
@@ -99,6 +143,32 @@ describe('clipboard button', () => {
expect(findButton().props('variant')).toBe(variant);
});
+ describe('confirmation tooltip', () => {
+ it('adds `id` and `data-clipboard-handle-tooltip` attributes to button', () => {
+ createWrapper({
+ text: 'copy me',
+ title: 'Copy this value',
+ });
+
+ expect(findButton().attributes()).toMatchObject({
+ id: 'clipboard-button-1',
+ 'data-clipboard-handle-tooltip': 'false',
+ 'aria-live': 'polite',
+ });
+ });
+
+ it('shows success tooltip after successful copy', () => {
+ expectConfirmationTooltip({
+ event: CLIPBOARD_SUCCESS_EVENT,
+ message: ClipboardButton.i18n.copied,
+ });
+ });
+
+ it('shows error tooltip after failed copy', () => {
+ expectConfirmationTooltip({ event: CLIPBOARD_ERROR_EVENT, message: I18N_ERROR_MESSAGE });
+ });
+ });
+
describe('integration', () => {
it('actually copies to clipboard', () => {
initCopyToClipboard();
diff --git a/spec/frontend/vue_shared/components/confirm_danger/confirm_danger_spec.js b/spec/frontend/vue_shared/components/confirm_danger/confirm_danger_spec.js
index af7f85769aa..a179afccae0 100644
--- a/spec/frontend/vue_shared/components/confirm_danger/confirm_danger_spec.js
+++ b/spec/frontend/vue_shared/components/confirm_danger/confirm_danger_spec.js
@@ -10,6 +10,7 @@ describe('Confirm Danger Modal', () => {
const phrase = 'En Taro Adun';
const buttonText = 'Click me!';
const buttonClass = 'gl-w-full';
+ const buttonVariant = 'info';
const modalId = CONFIRM_DANGER_MODAL_ID;
const findBtn = () => wrapper.findComponent(GlButton);
@@ -21,6 +22,7 @@ describe('Confirm Danger Modal', () => {
propsData: {
buttonText,
buttonClass,
+ buttonVariant,
phrase,
...props,
},
@@ -57,6 +59,10 @@ describe('Confirm Danger Modal', () => {
expect(findBtn().classes()).toContain(buttonClass);
});
+ it('passes `buttonVariant` prop to button', () => {
+ expect(findBtn().attributes('variant')).toBe(buttonVariant);
+ });
+
it('will emit `confirm` when the modal confirms', () => {
expect(wrapper.emitted('confirm')).toBeUndefined();
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js
index 64d15884333..4e9eac2dde2 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js
@@ -122,6 +122,8 @@ describe('FilteredSearchBarRoot', () => {
describe('sortDirectionIcon', () => {
it('returns string "sort-lowest" when `selectedSortDirection` is "ascending"', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
selectedSortDirection: SortDirection.ascending,
});
@@ -130,6 +132,8 @@ describe('FilteredSearchBarRoot', () => {
});
it('returns string "sort-highest" when `selectedSortDirection` is "descending"', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
selectedSortDirection: SortDirection.descending,
});
@@ -140,6 +144,8 @@ describe('FilteredSearchBarRoot', () => {
describe('sortDirectionTooltip', () => {
it('returns string "Sort direction: Ascending" when `selectedSortDirection` is "ascending"', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
selectedSortDirection: SortDirection.ascending,
});
@@ -148,6 +154,8 @@ describe('FilteredSearchBarRoot', () => {
});
it('returns string "Sort direction: Descending" when `selectedSortDirection` is "descending"', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
selectedSortDirection: SortDirection.descending,
});
@@ -158,6 +166,8 @@ describe('FilteredSearchBarRoot', () => {
describe('filteredRecentSearches', () => {
it('returns array of recent searches filtering out any string type (unsupported) items', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
recentSearches: [{ foo: 'bar' }, 'foo'],
});
@@ -169,6 +179,8 @@ describe('FilteredSearchBarRoot', () => {
});
it('returns array of recent searches sanitizing any duplicate token values', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
recentSearches: [
[tokenValueAuthor, tokenValueLabel, tokenValueMilestone, tokenValueLabel],
@@ -198,6 +210,8 @@ describe('FilteredSearchBarRoot', () => {
describe('filterValue', () => {
it('emits component event `onFilter` with empty array and false when filter was never selected', () => {
wrapper = createComponent({ initialFilterValue: [tokenValueEmpty] });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
initialRender: false,
filterValue: [tokenValueEmpty],
@@ -210,6 +224,8 @@ describe('FilteredSearchBarRoot', () => {
it('emits component event `onFilter` with empty array and true when initially selected filter value was cleared', () => {
wrapper = createComponent({ initialFilterValue: [tokenValueLabel] });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
initialRender: false,
filterValue: [tokenValueEmpty],
@@ -264,6 +280,8 @@ describe('FilteredSearchBarRoot', () => {
describe('handleSortDirectionClick', () => {
beforeEach(() => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
selectedSortOption: mockSortOptions[0],
});
@@ -312,6 +330,8 @@ describe('FilteredSearchBarRoot', () => {
const mockFilters = [tokenValueAuthor, 'foo'];
beforeEach(async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
filterValue: mockFilters,
});
@@ -376,6 +396,8 @@ describe('FilteredSearchBarRoot', () => {
describe('template', () => {
beforeEach(() => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
selectedSortOption: mockSortOptions[0],
selectedSortDirection: SortDirection.descending,
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js
index b29c394e7ae..5865c6a41b8 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js
@@ -10,10 +10,7 @@ import waitForPromises from 'helpers/wait_for_promises';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
-import {
- DEFAULT_LABEL_ANY,
- DEFAULT_NONE_ANY,
-} from '~/vue_shared/components/filtered_search_bar/constants';
+import { DEFAULT_NONE_ANY } from '~/vue_shared/components/filtered_search_bar/constants';
import AuthorToken from '~/vue_shared/components/filtered_search_bar/tokens/author_token.vue';
import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
@@ -227,6 +224,8 @@ describe('AuthorToken', () => {
expect(getAvatarEl().props('src')).toBe(mockAuthors[0].avatar_url);
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
authors: [
{
@@ -274,7 +273,7 @@ describe('AuthorToken', () => {
expect(wrapper.find(GlDropdownDivider).exists()).toBe(false);
});
- it('renders `DEFAULT_LABEL_ANY` as default suggestions', async () => {
+ it('renders `DEFAULT_NONE_ANY` as default suggestions', async () => {
wrapper = createComponent({
active: true,
config: { ...mockAuthorToken, preloadedAuthors: mockPreloadedAuthors },
@@ -285,8 +284,9 @@ describe('AuthorToken', () => {
const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
- expect(suggestions).toHaveLength(1 + currentUserLength);
- expect(suggestions.at(0).text()).toBe(DEFAULT_LABEL_ANY.text);
+ expect(suggestions).toHaveLength(2 + currentUserLength);
+ expect(suggestions.at(0).text()).toBe(DEFAULT_NONE_ANY[0].text);
+ expect(suggestions.at(1).text()).toBe(DEFAULT_NONE_ANY[1].text);
});
it('emits listeners in the base-token', () => {
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/branch_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/branch_token_spec.js
index f3e8b2d0c1b..cd8be765fb5 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/branch_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/branch_token_spec.js
@@ -121,6 +121,8 @@ describe('BranchToken', () => {
beforeEach(async () => {
wrapper = createComponent({ value: { data: mockBranches[0].name } });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
branches: mockBranches,
});
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js
index 36071c900df..ed9ac7c271e 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js
@@ -123,6 +123,8 @@ describe('EmojiToken', () => {
value: { data: `"${mockEmojis[0].name}"` },
});
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
emojis: mockEmojis,
});
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js
index f55fb2836e3..b9af71ad8a7 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js
@@ -144,6 +144,8 @@ describe('LabelToken', () => {
beforeEach(async () => {
wrapper = createComponent({ value: { data: `"${mockRegularLabel.title}"` } });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
labels: mockLabels,
});
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js
index 4a098db33c5..c0d8b5fd139 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js
@@ -121,6 +121,8 @@ describe('MilestoneToken', () => {
beforeEach(async () => {
wrapper = createComponent({ value: { data: `"${mockRegularMilestone.title}"` } });
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
milestones: mockMilestones,
});
diff --git a/spec/frontend/vue_shared/components/gitlab_version_check_spec.js b/spec/frontend/vue_shared/components/gitlab_version_check_spec.js
new file mode 100644
index 00000000000..b673e5407d4
--- /dev/null
+++ b/spec/frontend/vue_shared/components/gitlab_version_check_spec.js
@@ -0,0 +1,77 @@
+import { GlBadge } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import MockAdapter from 'axios-mock-adapter';
+import flushPromises from 'helpers/flush_promises';
+import axios from '~/lib/utils/axios_utils';
+import GitlabVersionCheck from '~/vue_shared/components/gitlab_version_check.vue';
+
+describe('GitlabVersionCheck', () => {
+ let wrapper;
+ let mock;
+
+ const defaultResponse = {
+ code: 200,
+ res: { severity: 'success' },
+ };
+
+ const createComponent = (mockResponse) => {
+ const response = {
+ ...defaultResponse,
+ ...mockResponse,
+ };
+
+ mock = new MockAdapter(axios);
+ mock.onGet().replyOnce(response.code, response.res);
+
+ wrapper = shallowMount(GitlabVersionCheck);
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ mock.restore();
+ });
+
+ const findGlBadge = () => wrapper.findComponent(GlBadge);
+
+ describe('template', () => {
+ describe.each`
+ description | mockResponse | renders
+ ${'successful but null'} | ${{ code: 200, res: null }} | ${false}
+ ${'successful and valid'} | ${{ code: 200, res: { severity: 'success' } }} | ${true}
+ ${'an error'} | ${{ code: 500, res: null }} | ${false}
+ `('version_check.json response', ({ description, mockResponse, renders }) => {
+ describe(`is ${description}`, () => {
+ beforeEach(async () => {
+ createComponent(mockResponse);
+ await flushPromises(); // Ensure we wrap up the axios call
+ });
+
+ it(`does${renders ? '' : ' not'} render GlBadge`, () => {
+ expect(findGlBadge().exists()).toBe(renders);
+ });
+ });
+ });
+
+ describe.each`
+ mockResponse | expectedUI
+ ${{ code: 200, res: { severity: 'success' } }} | ${{ title: 'Up to date', variant: 'success' }}
+ ${{ code: 200, res: { severity: 'warning' } }} | ${{ title: 'Update available', variant: 'warning' }}
+ ${{ code: 200, res: { severity: 'danger' } }} | ${{ title: 'Update ASAP', variant: 'danger' }}
+ `('badge ui', ({ mockResponse, expectedUI }) => {
+ describe(`when response is ${mockResponse.res.severity}`, () => {
+ beforeEach(async () => {
+ createComponent(mockResponse);
+ await flushPromises(); // Ensure we wrap up the axios call
+ });
+
+ it(`title is ${expectedUI.title}`, () => {
+ expect(findGlBadge().text()).toBe(expectedUI.title);
+ });
+
+ it(`variant is ${expectedUI.variant}`, () => {
+ expect(findGlBadge().attributes('variant')).toBe(expectedUI.variant);
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/line_numbers_spec.js b/spec/frontend/vue_shared/components/line_numbers_spec.js
index 5bedd0ccd02..38c26226863 100644
--- a/spec/frontend/vue_shared/components/line_numbers_spec.js
+++ b/spec/frontend/vue_shared/components/line_numbers_spec.js
@@ -13,7 +13,6 @@ describe('Line Numbers component', () => {
const findGlIcon = () => wrapper.findComponent(GlIcon);
const findLineNumbers = () => wrapper.findAllComponents(GlLink);
const findFirstLineNumber = () => findLineNumbers().at(0);
- const findSecondLineNumber = () => findLineNumbers().at(1);
beforeEach(() => createComponent());
@@ -24,7 +23,7 @@ describe('Line Numbers component', () => {
expect(findLineNumbers().length).toBe(lines);
expect(findFirstLineNumber().attributes()).toMatchObject({
id: 'L1',
- href: '#L1',
+ to: '#LC1',
});
});
@@ -35,37 +34,4 @@ describe('Line Numbers component', () => {
});
});
});
-
- describe('clicking a line number', () => {
- let firstLineNumber;
- let firstLineNumberElement;
-
- beforeEach(() => {
- firstLineNumber = findFirstLineNumber();
- firstLineNumberElement = firstLineNumber.element;
-
- jest.spyOn(firstLineNumberElement, 'scrollIntoView');
- jest.spyOn(firstLineNumberElement.classList, 'add');
- jest.spyOn(firstLineNumberElement.classList, 'remove');
-
- firstLineNumber.vm.$emit('click');
- });
-
- it('adds the highlight (hll) class', () => {
- expect(firstLineNumberElement.classList.add).toHaveBeenCalledWith('hll');
- });
-
- it('removes the highlight (hll) class from a previously highlighted line', () => {
- findSecondLineNumber().vm.$emit('click');
-
- expect(firstLineNumberElement.classList.remove).toHaveBeenCalledWith('hll');
- });
-
- it('scrolls the line into view', () => {
- expect(firstLineNumberElement.scrollIntoView).toHaveBeenCalledWith({
- behavior: 'smooth',
- block: 'center',
- });
- });
- });
});
diff --git a/spec/frontend/vue_shared/components/markdown/field_spec.js b/spec/frontend/vue_shared/components/markdown/field_spec.js
index 76e1a1162ad..0d90ca7f1f6 100644
--- a/spec/frontend/vue_shared/components/markdown/field_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/field_spec.js
@@ -1,4 +1,5 @@
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import AxiosMockAdapter from 'axios-mock-adapter';
import $ from 'jquery';
import { TEST_HOST, FIXTURES_PATH } from 'spec/test_constants';
@@ -242,6 +243,41 @@ describe('Markdown field component', () => {
expect(dropzoneSpy).toHaveBeenCalled();
});
+
+ describe('mentioning all users', () => {
+ const users = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].map((i) => `user_${i}`);
+
+ it('shows warning on mention of all users', async () => {
+ axiosMock.onPost(markdownPreviewPath).reply(200, { references: { users } });
+
+ subject.setProps({ textareaValue: 'hello @all' });
+
+ await axios.waitFor(markdownPreviewPath).then(() => {
+ expect(subject.text()).toContain(
+ 'You are about to add 11 people to the discussion. They will all receive a notification.',
+ );
+ });
+ });
+
+ it('removes warning when all mention is removed', async () => {
+ axiosMock.onPost(markdownPreviewPath).reply(200, { references: { users } });
+
+ subject.setProps({ textareaValue: 'hello @all' });
+
+ await axios.waitFor(markdownPreviewPath);
+
+ jest.spyOn(axios, 'post');
+
+ subject.setProps({ textareaValue: 'hello @allan' });
+
+ await nextTick();
+
+ expect(axios.post).not.toHaveBeenCalled();
+ expect(subject.text()).not.toContain(
+ 'You are about to add 11 people to the discussion. They will all receive a notification.',
+ );
+ });
+ });
});
});
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 acf97713885..b330b4f5657 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
@@ -313,6 +313,8 @@ describe('AlertManagementEmptyState', () => {
it('returns correctly applied filter search values', async () => {
const searchTerm = 'foo';
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
searchTerm,
});
@@ -330,6 +332,8 @@ describe('AlertManagementEmptyState', () => {
});
it('updates props `searchTerm` and `authorUsername` with empty values when passed filters param is empty', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
authorUsername: 'foo',
searchTerm: 'bar',
diff --git a/spec/frontend/vue_shared/components/registry/__snapshots__/code_instruction_spec.js.snap b/spec/frontend/vue_shared/components/registry/__snapshots__/code_instruction_spec.js.snap
index 23cf6ef9785..e8d76991b90 100644
--- a/spec/frontend/vue_shared/components/registry/__snapshots__/code_instruction_spec.js.snap
+++ b/spec/frontend/vue_shared/components/registry/__snapshots__/code_instruction_spec.js.snap
@@ -3,7 +3,7 @@
exports[`Package code instruction multiline to match the snapshot 1`] = `
<div>
<label
- for="instruction-input_3"
+ for="instruction-input_1"
>
foo_label
</label>
@@ -23,7 +23,7 @@ multiline text
exports[`Package code instruction single line to match the default snapshot 1`] = `
<div>
<label
- for="instruction-input_2"
+ for="instruction-input_1"
>
foo_label
</label>
@@ -37,7 +37,7 @@ exports[`Package code instruction single line to match the default snapshot 1`]
<input
class="form-control gl-font-monospace"
data-testid="instruction-input"
- id="instruction-input_2"
+ id="instruction-input_1"
readonly="readonly"
type="text"
/>
@@ -47,9 +47,12 @@ exports[`Package code instruction single line to match the default snapshot 1`]
data-testid="instruction-button"
>
<button
- aria-label="Copy this value"
+ aria-label="Copy npm install command"
+ aria-live="polite"
class="btn input-group-text btn-default btn-md gl-button btn-default-secondary btn-icon"
+ data-clipboard-handle-tooltip="false"
data-clipboard-text="npm i @my-package"
+ id="clipboard-button-1"
title="Copy npm install command"
type="button"
>
diff --git a/spec/frontend/vue_shared/components/registry/code_instruction_spec.js b/spec/frontend/vue_shared/components/registry/code_instruction_spec.js
index 4ec608aaf07..3a2ea263a05 100644
--- a/spec/frontend/vue_shared/components/registry/code_instruction_spec.js
+++ b/spec/frontend/vue_shared/components/registry/code_instruction_spec.js
@@ -3,6 +3,8 @@ import Tracking from '~/tracking';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import CodeInstruction from '~/vue_shared/components/registry/code_instruction.vue';
+jest.mock('lodash/uniqueId', () => (prefix) => (prefix ? `${prefix}1` : 1));
+
describe('Package code instruction', () => {
let wrapper;
diff --git a/spec/frontend/vue_shared/components/sidebar/issuable_move_dropdown_spec.js b/spec/frontend/vue_shared/components/sidebar/issuable_move_dropdown_spec.js
index a5a099d803a..5336ecc614c 100644
--- a/spec/frontend/vue_shared/components/sidebar/issuable_move_dropdown_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/issuable_move_dropdown_spec.js
@@ -68,6 +68,8 @@ describe('IssuableMoveDropdown', () => {
describe('searchKey', () => {
it('calls `fetchProjects` with value of the prop', async () => {
jest.spyOn(wrapper.vm, 'fetchProjects');
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
searchKey: 'foo',
});
@@ -143,6 +145,8 @@ describe('IssuableMoveDropdown', () => {
`(
'returns $returnValue when selectedProject and provided project param $title',
async ({ project, selectedProject, returnValue }) => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
selectedProject,
});
@@ -154,6 +158,8 @@ describe('IssuableMoveDropdown', () => {
);
it('returns false when selectedProject is null', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
selectedProject: null,
});
@@ -206,6 +212,8 @@ describe('IssuableMoveDropdown', () => {
});
it('renders gl-loading-icon component when projectsListLoading prop is true', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
projectsListLoading: true,
});
@@ -216,6 +224,8 @@ describe('IssuableMoveDropdown', () => {
});
it('renders gl-dropdown-item components for available projects', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
projects: mockProjects,
selectedProject: mockProjects[0],
@@ -234,6 +244,8 @@ describe('IssuableMoveDropdown', () => {
});
it('renders string "No matching results" when search does not yield any matches', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
searchKey: 'foo',
});
@@ -241,6 +253,8 @@ describe('IssuableMoveDropdown', () => {
// Wait for `searchKey` watcher to run.
await wrapper.vm.$nextTick();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
projects: [],
projectsListLoading: false,
@@ -254,6 +268,8 @@ describe('IssuableMoveDropdown', () => {
});
it('renders string "Failed to load projects" when loading projects list fails', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
projects: [],
projectsListLoading: false,
@@ -273,6 +289,8 @@ describe('IssuableMoveDropdown', () => {
expect(moveButtonEl.text()).toBe('Move');
expect(moveButtonEl.attributes('disabled')).toBe('true');
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
selectedProject: mockProjects[0],
});
@@ -303,6 +321,8 @@ describe('IssuableMoveDropdown', () => {
});
it('gl-dropdown component prevents dropdown body from closing on `hide` event when `projectItemClick` prop is true', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
projectItemClick: true,
});
@@ -326,6 +346,8 @@ describe('IssuableMoveDropdown', () => {
});
it('sets project for clicked gl-dropdown-item to selectedProject', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
projects: mockProjects,
});
@@ -338,6 +360,8 @@ describe('IssuableMoveDropdown', () => {
});
it('hides dropdown and emits `move-issuable` event when move button is clicked', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
selectedProject: mockProjects[0],
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js
index 1fe85637a62..0eff6a1dace 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js
@@ -43,6 +43,8 @@ describe('DropdownContentsCreateView', () => {
});
it('returns `true` when `labelCreateInProgress` is true', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
labelTitle: 'Foo',
selectedColor: '#ff0000',
@@ -55,6 +57,8 @@ describe('DropdownContentsCreateView', () => {
});
it('returns `false` when label title and color is defined and create request is not already in progress', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
labelTitle: 'Foo',
selectedColor: '#ff0000',
@@ -99,6 +103,8 @@ describe('DropdownContentsCreateView', () => {
describe('handleCreateClick', () => {
it('calls action `createLabel` with object containing `labelTitle` & `selectedColor`', () => {
jest.spyOn(wrapper.vm, 'createLabel').mockImplementation();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
labelTitle: 'Foo',
selectedColor: '#ff0000',
@@ -164,6 +170,8 @@ describe('DropdownContentsCreateView', () => {
});
it('renders color input element', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
selectedColor: '#ff0000',
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js
index 80b8edd28ba..93a0e2f75bb 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js
@@ -63,6 +63,8 @@ describe('DropdownContentsLabelsView', () => {
describe('computed', () => {
describe('visibleLabels', () => {
it('returns matching labels filtered with `searchKey`', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
searchKey: 'bug',
});
@@ -72,6 +74,8 @@ describe('DropdownContentsLabelsView', () => {
});
it('returns matching labels with fuzzy filtering', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
searchKey: 'bg',
});
@@ -82,6 +86,8 @@ describe('DropdownContentsLabelsView', () => {
});
it('returns all labels when `searchKey` is empty', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
searchKey: '',
});
@@ -100,6 +106,8 @@ describe('DropdownContentsLabelsView', () => {
`(
'returns $returnValue when searchKey is "$searchKey" and visibleLabels is $labelsDescription',
async ({ searchKey, labels, returnValue }) => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
searchKey,
});
@@ -161,6 +169,8 @@ describe('DropdownContentsLabelsView', () => {
describe('handleKeyDown', () => {
it('decreases `currentHighlightItem` value by 1 when Up arrow key is pressed', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
currentHighlightItem: 1,
});
@@ -173,6 +183,8 @@ describe('DropdownContentsLabelsView', () => {
});
it('increases `currentHighlightItem` value by 1 when Down arrow key is pressed', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
currentHighlightItem: 1,
});
@@ -185,6 +197,8 @@ describe('DropdownContentsLabelsView', () => {
});
it('resets the search text when the Enter key is pressed', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
currentHighlightItem: 1,
searchKey: 'bug',
@@ -201,6 +215,8 @@ describe('DropdownContentsLabelsView', () => {
it('calls action `updateSelectedLabels` with currently highlighted label when Enter key is pressed', () => {
jest.spyOn(wrapper.vm, 'updateSelectedLabels').mockImplementation();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
currentHighlightItem: 2,
});
@@ -220,6 +236,8 @@ describe('DropdownContentsLabelsView', () => {
it('calls action `toggleDropdownContents` when Esc key is pressed', () => {
jest.spyOn(wrapper.vm, 'toggleDropdownContents').mockImplementation();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
currentHighlightItem: 1,
});
@@ -233,6 +251,8 @@ describe('DropdownContentsLabelsView', () => {
it('calls action `scrollIntoViewIfNeeded` in next tick when any key is pressed', () => {
jest.spyOn(wrapper.vm, 'scrollIntoViewIfNeeded').mockImplementation();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
currentHighlightItem: 1,
});
@@ -320,6 +340,8 @@ describe('DropdownContentsLabelsView', () => {
});
it('renders label element with `highlight` set to true when value of `currentHighlightItem` is more than -1', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
currentHighlightItem: 0,
});
@@ -332,6 +354,8 @@ describe('DropdownContentsLabelsView', () => {
});
it('renders element containing "No matching results" when `searchKey` does not match with any label', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
searchKey: 'abc',
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js
index d8491334b5d..3ceed670d77 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js
@@ -1,4 +1,4 @@
-import { GlLoadingIcon, GlLink } from '@gitlab/ui';
+import { GlAlert, GlLoadingIcon, GlLink } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
@@ -9,6 +9,7 @@ import { workspaceLabelsQueries } from '~/sidebar/constants';
import DropdownContentsCreateView from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue';
import createLabelMutation from '~/vue_shared/components/sidebar/labels_select_widget/graphql/create_label.mutation.graphql';
import {
+ mockRegularLabel,
mockSuggestedColors,
createLabelSuccessfulResponse,
workspaceLabelsQueryResponse,
@@ -25,8 +26,18 @@ const userRecoverableError = {
errors: ['Houston, we have a problem'],
};
+const titleTakenError = {
+ data: {
+ labelCreate: {
+ label: mockRegularLabel,
+ errors: ['Title has already been taken'],
+ },
+ },
+};
+
const createLabelSuccessHandler = jest.fn().mockResolvedValue(createLabelSuccessfulResponse);
const createLabelUserRecoverableErrorHandler = jest.fn().mockResolvedValue(userRecoverableError);
+const createLabelDuplicateErrorHandler = jest.fn().mockResolvedValue(titleTakenError);
const createLabelErrorHandler = jest.fn().mockRejectedValue('Houston, we have a problem');
describe('DropdownContentsCreateView', () => {
@@ -208,4 +219,17 @@ describe('DropdownContentsCreateView', () => {
expect(createFlash).toHaveBeenCalled();
});
+
+ it('displays error in alert if label title is already taken', async () => {
+ createComponent({ mutationHandler: createLabelDuplicateErrorHandler });
+ fillLabelAttributes();
+ await nextTick();
+
+ findCreateButton().vm.$emit('click');
+ await waitForPromises();
+
+ expect(wrapper.findComponent(GlAlert).text()).toEqual(
+ titleTakenError.data.labelCreate.errors[0],
+ );
+ });
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js
index 6f5a4b7e613..7f6770e0bea 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js
@@ -110,6 +110,19 @@ describe('DropdownContentsLabelsView', () => {
});
});
+ it('first item is highlighted when search is not empty', async () => {
+ createComponent({
+ queryHandler: jest.fn().mockResolvedValue(workspaceLabelsQueryResponse),
+ searchKey: 'Label',
+ });
+ await makeObserverAppear();
+ await waitForPromises();
+ await nextTick();
+
+ expect(findLabelsList().exists()).toBe(true);
+ expect(findFirstLabel().attributes('active')).toBe('true');
+ });
+
it('when search returns 0 results', async () => {
createComponent({
queryHandler: jest.fn().mockResolvedValue({
diff --git a/spec/frontend/vue_shared/components/source_viewer_spec.js b/spec/frontend/vue_shared/components/source_viewer_spec.js
index 758068379de..094d8d42a47 100644
--- a/spec/frontend/vue_shared/components/source_viewer_spec.js
+++ b/spec/frontend/vue_shared/components/source_viewer_spec.js
@@ -1,27 +1,35 @@
import hljs from 'highlight.js/lib/core';
+import Vue, { nextTick } from 'vue';
+import VueRouter from 'vue-router';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import SourceViewer from '~/vue_shared/components/source_viewer.vue';
import LineNumbers from '~/vue_shared/components/line_numbers.vue';
import waitForPromises from 'helpers/wait_for_promises';
jest.mock('highlight.js/lib/core');
+Vue.use(VueRouter);
+const router = new VueRouter();
describe('Source Viewer component', () => {
let wrapper;
const content = `// Some source code`;
- const highlightedContent = `<span data-testid='test-highlighted'>${content}</span>`;
+ const highlightedContent = `<span data-testid='test-highlighted' id='LC1'>${content}</span><span id='LC2'></span>`;
const language = 'javascript';
hljs.highlight.mockImplementation(() => ({ value: highlightedContent }));
hljs.highlightAuto.mockImplementation(() => ({ value: highlightedContent }));
const createComponent = async (props = {}) => {
- wrapper = shallowMountExtended(SourceViewer, { propsData: { content, language, ...props } });
+ wrapper = shallowMountExtended(SourceViewer, {
+ router,
+ propsData: { content, language, ...props },
+ });
await waitForPromises();
};
const findLineNumbers = () => wrapper.findComponent(LineNumbers);
const findHighlightedContent = () => wrapper.findByTestId('test-highlighted');
+ const findFirstLine = () => wrapper.find('#LC1');
beforeEach(() => createComponent());
@@ -56,4 +64,39 @@ describe('Source Viewer component', () => {
expect(findHighlightedContent().exists()).toBe(true);
});
});
+
+ describe('selecting a line', () => {
+ let firstLine;
+ let firstLineElement;
+
+ beforeEach(() => {
+ firstLine = findFirstLine();
+ firstLineElement = firstLine.element;
+
+ jest.spyOn(firstLineElement, 'scrollIntoView');
+ jest.spyOn(firstLineElement.classList, 'add');
+ jest.spyOn(firstLineElement.classList, 'remove');
+ });
+
+ it('adds the highlight (hll) class', async () => {
+ wrapper.vm.$router.push('#LC1');
+ await nextTick();
+
+ expect(firstLineElement.classList.add).toHaveBeenCalledWith('hll');
+ });
+
+ it('removes the highlight (hll) class from a previously highlighted line', async () => {
+ wrapper.vm.$router.push('#LC2');
+ await nextTick();
+
+ expect(firstLineElement.classList.remove).toHaveBeenCalledWith('hll');
+ });
+
+ it('scrolls the line into view', () => {
+ expect(firstLineElement.scrollIntoView).toHaveBeenCalledWith({
+ behavior: 'smooth',
+ block: 'center',
+ });
+ });
+ });
});
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 92938b2717f..659d93d6597 100644
--- a/spec/frontend/vue_shared/components/web_ide_link_spec.js
+++ b/spec/frontend/vue_shared/components/web_ide_link_spec.js
@@ -1,11 +1,18 @@
-import { shallowMount } from '@vue/test-utils';
+import { GlModal } from '@gitlab/ui';
+import { nextTick } from 'vue';
+
import ActionsButton from '~/vue_shared/components/actions_button.vue';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
import WebIdeLink from '~/vue_shared/components/web_ide_link.vue';
+import { stubComponent } from 'helpers/stub_component';
+import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper';
+
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_USER_PREFERENCES_GITPOD_PATH = '/-/profile/preferences#user_gitpod_enabled';
+const TEST_USER_PROFILE_ENABLE_GITPOD_PATH = '/-/profile?user%5Bgitpod_enabled%5D=true';
const ACTION_EDIT = {
href: TEST_EDIT_URL,
@@ -54,21 +61,31 @@ const ACTION_GITPOD = {
};
const ACTION_GITPOD_ENABLE = {
...ACTION_GITPOD,
- href: '#modal-enable-gitpod',
+ href: undefined,
handle: expect.any(Function),
};
describe('Web IDE link component', () => {
let wrapper;
- function createComponent(props) {
- wrapper = shallowMount(WebIdeLink, {
+ function createComponent(props, mountFn = shallowMountExtended) {
+ wrapper = mountFn(WebIdeLink, {
propsData: {
editUrl: TEST_EDIT_URL,
webIdeUrl: TEST_WEB_IDE_URL,
gitpodUrl: TEST_GITPOD_URL,
...props,
},
+ stubs: {
+ GlModal: stubComponent(GlModal, {
+ template: `
+ <div>
+ <slot name="modal-title"></slot>
+ <slot></slot>
+ <slot name="modal-footer"></slot>
+ </div>`,
+ }),
+ },
});
}
@@ -78,6 +95,7 @@ describe('Web IDE link component', () => {
const findActionsButton = () => wrapper.find(ActionsButton);
const findLocalStorageSync = () => wrapper.find(LocalStorageSync);
+ const findModal = () => wrapper.findComponent(GlModal);
it.each([
{
@@ -97,19 +115,68 @@ describe('Web IDE link component', () => {
expectedActions: [ACTION_WEB_IDE_CONFIRM_FORK, ACTION_EDIT_CONFIRM_FORK],
},
{
- props: { showWebIdeButton: false, showGitpodButton: true, gitpodEnabled: true },
+ props: {
+ showWebIdeButton: false,
+ showGitpodButton: true,
+ userPreferencesGitpodPath: TEST_USER_PREFERENCES_GITPOD_PATH,
+ userProfileEnableGitpodPath: TEST_USER_PROFILE_ENABLE_GITPOD_PATH,
+ gitpodEnabled: true,
+ },
expectedActions: [ACTION_EDIT, ACTION_GITPOD],
},
{
- props: { showWebIdeButton: false, showGitpodButton: true, gitpodEnabled: false },
+ props: {
+ showWebIdeButton: false,
+ showGitpodButton: true,
+ userPreferencesGitpodPath: TEST_USER_PREFERENCES_GITPOD_PATH,
+ gitpodEnabled: true,
+ },
+ expectedActions: [ACTION_EDIT],
+ },
+ {
+ props: {
+ showWebIdeButton: false,
+ showGitpodButton: true,
+ userProfileEnableGitpodPath: TEST_USER_PROFILE_ENABLE_GITPOD_PATH,
+ gitpodEnabled: true,
+ },
+ expectedActions: [ACTION_EDIT],
+ },
+ {
+ props: {
+ showWebIdeButton: false,
+ showGitpodButton: true,
+ gitpodEnabled: true,
+ },
+ expectedActions: [ACTION_EDIT],
+ },
+ {
+ props: {
+ showWebIdeButton: false,
+ showGitpodButton: true,
+ userPreferencesGitpodPath: TEST_USER_PREFERENCES_GITPOD_PATH,
+ userProfileEnableGitpodPath: TEST_USER_PROFILE_ENABLE_GITPOD_PATH,
+ gitpodEnabled: false,
+ },
expectedActions: [ACTION_EDIT, ACTION_GITPOD_ENABLE],
},
{
- props: { showGitpodButton: true, gitpodEnabled: false },
+ props: {
+ showGitpodButton: true,
+ userPreferencesGitpodPath: TEST_USER_PREFERENCES_GITPOD_PATH,
+ userProfileEnableGitpodPath: TEST_USER_PROFILE_ENABLE_GITPOD_PATH,
+ gitpodEnabled: false,
+ },
expectedActions: [ACTION_WEB_IDE, ACTION_EDIT, ACTION_GITPOD_ENABLE],
},
{
- props: { showEditButton: false, showGitpodButton: true, gitpodText: 'Test Gitpod' },
+ props: {
+ showEditButton: false,
+ showGitpodButton: true,
+ userPreferencesGitpodPath: TEST_USER_PREFERENCES_GITPOD_PATH,
+ userProfileEnableGitpodPath: TEST_USER_PROFILE_ENABLE_GITPOD_PATH,
+ gitpodText: 'Test Gitpod',
+ },
expectedActions: [ACTION_WEB_IDE, { ...ACTION_GITPOD_ENABLE, text: 'Test Gitpod' }],
},
{
@@ -128,6 +195,8 @@ describe('Web IDE link component', () => {
showEditButton: false,
showWebIdeButton: true,
showGitpodButton: true,
+ userPreferencesGitpodPath: TEST_USER_PREFERENCES_GITPOD_PATH,
+ userProfileEnableGitpodPath: TEST_USER_PROFILE_ENABLE_GITPOD_PATH,
gitpodEnabled: true,
});
});
@@ -174,7 +243,7 @@ describe('Web IDE link component', () => {
])(
'emits the correct event when an action handler is called',
async ({ props, expectedEventPayload }) => {
- createComponent({ ...props, needsToFork: true });
+ createComponent({ ...props, needsToFork: true, disableForkModal: true });
findActionsButton().props('actions')[0].handle();
@@ -182,4 +251,72 @@ describe('Web IDE link component', () => {
},
);
});
+
+ describe('when Gitpod is not enabled', () => {
+ it('renders closed modal to enable Gitpod', () => {
+ createComponent({
+ showGitpodButton: true,
+ userPreferencesGitpodPath: TEST_USER_PREFERENCES_GITPOD_PATH,
+ userProfileEnableGitpodPath: TEST_USER_PROFILE_ENABLE_GITPOD_PATH,
+ gitpodEnabled: false,
+ });
+
+ const modal = findModal();
+
+ expect(modal.exists()).toBe(true);
+ expect(modal.props()).toMatchObject({
+ visible: false,
+ modalId: 'enable-gitpod-modal',
+ size: 'sm',
+ title: WebIdeLink.i18n.modal.title,
+ actionCancel: {
+ text: WebIdeLink.i18n.modal.actionCancelText,
+ },
+ actionPrimary: {
+ text: WebIdeLink.i18n.modal.actionPrimaryText,
+ attributes: {
+ variant: 'confirm',
+ category: 'primary',
+ href: TEST_USER_PROFILE_ENABLE_GITPOD_PATH,
+ 'data-method': 'put',
+ },
+ },
+ });
+ });
+
+ it('opens modal when `Gitpod` action is clicked', async () => {
+ const gitpodText = 'Open in Gitpod';
+
+ createComponent(
+ {
+ showGitpodButton: true,
+ userPreferencesGitpodPath: TEST_USER_PREFERENCES_GITPOD_PATH,
+ userProfileEnableGitpodPath: TEST_USER_PROFILE_ENABLE_GITPOD_PATH,
+ gitpodEnabled: false,
+ gitpodText,
+ },
+ mountExtended,
+ );
+
+ findLocalStorageSync().vm.$emit('input', ACTION_GITPOD.key);
+
+ await nextTick();
+ await wrapper.findByRole('button', { name: gitpodText }).trigger('click');
+
+ expect(findModal().props('visible')).toBe(true);
+ });
+ });
+
+ describe('when Gitpod is enabled', () => {
+ it('does not render modal', () => {
+ createComponent({
+ showGitpodButton: true,
+ userPreferencesGitpodPath: TEST_USER_PREFERENCES_GITPOD_PATH,
+ userProfileEnableGitpodPath: TEST_USER_PROFILE_ENABLE_GITPOD_PATH,
+ gitpodEnabled: true,
+ });
+
+ expect(findModal().exists()).toBe(false);
+ });
+ });
});
diff --git a/spec/frontend/vue_shared/directives/track_event_spec.js b/spec/frontend/vue_shared/directives/track_event_spec.js
index d7d7f4edc3f..b3f94d0242a 100644
--- a/spec/frontend/vue_shared/directives/track_event_spec.js
+++ b/spec/frontend/vue_shared/directives/track_event_spec.js
@@ -38,6 +38,8 @@ describe('Error Tracking directive', () => {
label: 'Trackable Info',
};
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ trackingOptions });
const { category, action, label, property, value } = trackingOptions;
diff --git a/spec/frontend/vue_shared/issuable/list/components/issuable_list_root_spec.js b/spec/frontend/vue_shared/issuable/list/components/issuable_list_root_spec.js
index 5979a65e3cd..14e93108447 100644
--- a/spec/frontend/vue_shared/issuable/list/components/issuable_list_root_spec.js
+++ b/spec/frontend/vue_shared/issuable/list/components/issuable_list_root_spec.js
@@ -98,6 +98,8 @@ describe('IssuableListRoot', () => {
await wrapper.vm.$nextTick();
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
checkedIssuables,
});
@@ -111,6 +113,8 @@ describe('IssuableListRoot', () => {
describe('bulkEditIssuables', () => {
it('returns array of issuables which have `checked` set to true within checkedIssuables map', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
checkedIssuables: mockCheckedIssuables,
});
@@ -180,6 +184,8 @@ describe('IssuableListRoot', () => {
describe('issuableChecked', () => {
it('returns boolean value representing checked status of issuable item', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
checkedIssuables: {
[mockIssuables[0].iid]: { checked: true, issuable: mockIssuables[0] },
diff --git a/spec/frontend/vue_shared/issuable/list/components/issuable_tabs_spec.js b/spec/frontend/vue_shared/issuable/list/components/issuable_tabs_spec.js
index 8c22b67bdbe..5723e2da586 100644
--- a/spec/frontend/vue_shared/issuable/list/components/issuable_tabs_spec.js
+++ b/spec/frontend/vue_shared/issuable/list/components/issuable_tabs_spec.js
@@ -1,5 +1,6 @@
import { GlTab, GlBadge } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import { setLanguage } from 'helpers/locale_helper';
import IssuableTabs from '~/vue_shared/issuable/list/components/issuable_tabs.vue';
@@ -27,10 +28,12 @@ describe('IssuableTabs', () => {
let wrapper;
beforeEach(() => {
+ setLanguage('en');
wrapper = createComponent();
});
afterEach(() => {
+ setLanguage(null);
wrapper.destroy();
});
@@ -71,7 +74,7 @@ describe('IssuableTabs', () => {
// Does not render `All` badge since it has an undefined count
expect(badges).toHaveLength(2);
- expect(badges.at(0).text()).toBe(`${mockIssuableListProps.tabCounts.opened}`);
+ expect(badges.at(0).text()).toBe('5,000');
expect(badges.at(1).text()).toBe(`${mockIssuableListProps.tabCounts.closed}`);
});
diff --git a/spec/frontend/vue_shared/issuable/list/mock_data.js b/spec/frontend/vue_shared/issuable/list/mock_data.js
index e2fa99f7cc9..cfc7937b412 100644
--- a/spec/frontend/vue_shared/issuable/list/mock_data.js
+++ b/spec/frontend/vue_shared/issuable/list/mock_data.js
@@ -133,7 +133,7 @@ export const mockTabs = [
];
export const mockTabCounts = {
- opened: 5,
+ opened: 5000,
closed: 0,
all: undefined,
};
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 1fcf37a0477..cb418371760 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
@@ -84,6 +84,8 @@ describe('IssuableTitle', () => {
});
it('renders sticky header when `stickyTitleVisible` prop is true', async () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
stickyTitleVisible: true,
});
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 02795751f33..ea26b2b4fb3 100644
--- a/spec/frontend/work_items/pages/work_item_root_spec.js
+++ b/spec/frontend/work_items/pages/work_item_root_spec.js
@@ -3,6 +3,7 @@ import { shallowMount } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
+import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import workItemQuery from '~/work_items/graphql/work_item.query.graphql';
import updateWorkItemMutation from '~/work_items/graphql/update_work_item.mutation.graphql';
import WorkItemsRoot from '~/work_items/pages/work_item_root.vue';
@@ -15,6 +16,7 @@ Vue.use(VueApollo);
const WORK_ITEM_ID = '1';
describe('Work items root component', () => {
+ const mockUpdatedTitle = 'Updated title';
let wrapper;
let fakeApollo;
@@ -53,7 +55,6 @@ describe('Work items root component', () => {
it('updates the title when it is edited', async () => {
createComponent();
jest.spyOn(wrapper.vm.$apollo, 'mutate');
- const mockUpdatedTitle = 'Updated title';
await findTitle().vm.$emit('title-changed', mockUpdatedTitle);
@@ -91,4 +92,32 @@ describe('Work items root component', () => {
expect(findTitle().exists()).toBe(false);
});
+
+ describe('tracking', () => {
+ let trackingSpy;
+
+ beforeEach(() => {
+ trackingSpy = mockTracking('_category_', undefined, jest.spyOn);
+
+ createComponent();
+ });
+
+ afterEach(() => {
+ unmockTracking();
+ });
+
+ it('tracks item title updates', async () => {
+ await findTitle().vm.$emit('title-changed', mockUpdatedTitle);
+
+ await waitForPromises();
+
+ expect(trackingSpy).toHaveBeenCalledTimes(1);
+ expect(trackingSpy).toHaveBeenCalledWith('workItems:show', undefined, {
+ action: 'updated_title',
+ category: 'workItems:show',
+ label: 'item_title',
+ property: '[type_work_item]',
+ });
+ });
+ });
});
diff --git a/spec/graphql/mutations/ci/runner/delete_spec.rb b/spec/graphql/mutations/ci/runner/delete_spec.rb
index 27e8236d593..9f30c95edd5 100644
--- a/spec/graphql/mutations/ci/runner/delete_spec.rb
+++ b/spec/graphql/mutations/ci/runner/delete_spec.rb
@@ -5,9 +5,9 @@ require 'spec_helper'
RSpec.describe Mutations::Ci::Runner::Delete do
include GraphqlHelpers
- let_it_be(:user) { create(:user) }
let_it_be(:runner) { create(:ci_runner) }
+ let(:user) { create(:user) }
let(:current_ctx) { { current_user: user } }
let(:mutation_params) do
@@ -46,10 +46,10 @@ RSpec.describe Mutations::Ci::Runner::Delete do
end
context 'when user can delete owned runner' do
- let_it_be(:project) { create(:project, creator_id: user.id) }
- let_it_be(:project_runner, reload: true) { create(:ci_runner, :project, description: 'Project runner', projects: [project]) }
+ let!(:project) { create(:project, creator_id: user.id) }
+ let!(:project_runner) { create(:ci_runner, :project, description: 'Project runner', projects: [project]) }
- before_all do
+ before do
project.add_maintainer(user)
end
@@ -63,10 +63,10 @@ RSpec.describe Mutations::Ci::Runner::Delete do
end
context 'with more than one associated project' do
- let_it_be(:project2) { create(:project, creator_id: user.id) }
- let_it_be(:two_projects_runner) { create(:ci_runner, :project, description: 'Two projects runner', projects: [project, project2]) }
+ let!(:project2) { create(:project, creator_id: user.id) }
+ let!(:two_projects_runner) { create(:ci_runner, :project, description: 'Two projects runner', projects: [project, project2]) }
- before_all do
+ before do
project2.add_maintainer(user)
end
diff --git a/spec/graphql/mutations/clusters/agent_tokens/revoke_spec.rb b/spec/graphql/mutations/clusters/agent_tokens/revoke_spec.rb
new file mode 100644
index 00000000000..f5f4c0cefad
--- /dev/null
+++ b/spec/graphql/mutations/clusters/agent_tokens/revoke_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::Clusters::AgentTokens::Revoke do
+ let_it_be(:token) { create(:cluster_agent_token) }
+ let_it_be(:user) { create(:user) }
+
+ let(:mutation) do
+ described_class.new(
+ object: double,
+ context: { current_user: user },
+ field: double
+ )
+ end
+
+ it { expect(described_class.graphql_name).to eq('ClusterAgentTokenRevoke') }
+ it { expect(described_class).to require_graphql_authorizations(:admin_cluster) }
+
+ describe '#resolve' do
+ let(:global_id) { token.to_global_id }
+
+ subject { mutation.resolve(id: global_id) }
+
+ context 'user does not have permission' do
+ it 'does not revoke the token' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+
+ expect(token.reload).not_to be_revoked
+ end
+ end
+
+ context 'user has permission' do
+ before do
+ token.agent.project.add_maintainer(user)
+ end
+
+ it 'revokes the token' do
+ subject
+
+ expect(token.reload).to be_revoked
+ end
+
+ context 'supplied ID is invalid' do
+ let(:global_id) { token.id }
+
+ it 'raises a coercion error' do
+ expect { subject }.to raise_error(::GraphQL::CoercionError)
+
+ expect(token.reload).not_to be_revoked
+ end
+ end
+ end
+ end
+end
diff --git a/spec/graphql/mutations/customer_relations/contacts/create_spec.rb b/spec/graphql/mutations/customer_relations/contacts/create_spec.rb
index 0f05504d4f2..d17d11305b1 100644
--- a/spec/graphql/mutations/customer_relations/contacts/create_spec.rb
+++ b/spec/graphql/mutations/customer_relations/contacts/create_spec.rb
@@ -4,8 +4,8 @@ require 'spec_helper'
RSpec.describe Mutations::CustomerRelations::Contacts::Create do
let_it_be(:user) { create(:user) }
- let_it_be(:group) { create(:group) }
+ let(:group) { create(:group, :crm_enabled) }
let(:not_found_or_does_not_belong) { 'The specified organization was not found or does not belong to this group' }
let(:valid_params) do
attributes_for(:contact,
@@ -34,11 +34,11 @@ RSpec.describe Mutations::CustomerRelations::Contacts::Create do
end
context 'when the user has permission' do
- before_all do
+ before do
group.add_developer(user)
end
- context 'when the feature is disabled' do
+ context 'when the feature flag is disabled' do
before do
stub_feature_flags(customer_relations: false)
end
@@ -49,6 +49,15 @@ RSpec.describe Mutations::CustomerRelations::Contacts::Create do
end
end
+ context 'when crm_enabled is false' do
+ let(:group) { create(:group) }
+
+ it 'raises an error' do
+ expect { resolve_mutation }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ .with_message("The resource that you are attempting to access does not exist or you don't have permission to perform this action")
+ end
+ end
+
context 'when the params are invalid' do
it 'returns the validation error' do
valid_params[:first_name] = nil
diff --git a/spec/graphql/mutations/customer_relations/contacts/update_spec.rb b/spec/graphql/mutations/customer_relations/contacts/update_spec.rb
index 4f59de194fd..c8206eca442 100644
--- a/spec/graphql/mutations/customer_relations/contacts/update_spec.rb
+++ b/spec/graphql/mutations/customer_relations/contacts/update_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Mutations::CustomerRelations::Contacts::Update do
let_it_be(:user) { create(:user) }
- let_it_be(:group) { create(:group) }
+ let_it_be(:group) { create(:group, :crm_enabled) }
let(:first_name) { 'Lionel' }
let(:last_name) { 'Smith' }
diff --git a/spec/graphql/mutations/customer_relations/organizations/create_spec.rb b/spec/graphql/mutations/customer_relations/organizations/create_spec.rb
index 9be0f5d4289..ee78d2b16f6 100644
--- a/spec/graphql/mutations/customer_relations/organizations/create_spec.rb
+++ b/spec/graphql/mutations/customer_relations/organizations/create_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Mutations::CustomerRelations::Organizations::Create do
let_it_be(:user) { create(:user) }
- let_it_be(:group) { create(:group) }
+ let_it_be(:group) { create(:group, :crm_enabled) }
let(:valid_params) do
attributes_for(:organization,
diff --git a/spec/graphql/mutations/customer_relations/organizations/update_spec.rb b/spec/graphql/mutations/customer_relations/organizations/update_spec.rb
index e3aa8eafe0c..90fd7a0a9f1 100644
--- a/spec/graphql/mutations/customer_relations/organizations/update_spec.rb
+++ b/spec/graphql/mutations/customer_relations/organizations/update_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Mutations::CustomerRelations::Organizations::Update do
let_it_be(:user) { create(:user) }
- let_it_be(:group) { create(:group) }
+ let_it_be(:group) { create(:group, :crm_enabled) }
let(:name) { 'GitLab' }
let(:default_rate) { 1000.to_f }
@@ -56,7 +56,7 @@ RSpec.describe Mutations::CustomerRelations::Organizations::Update do
expect(resolve_mutation[:organization]).to have_attributes(attributes)
end
- context 'when the feature is disabled' do
+ context 'when the feature flag is disabled' do
before do
stub_feature_flags(customer_relations: false)
end
@@ -66,6 +66,15 @@ RSpec.describe Mutations::CustomerRelations::Organizations::Update do
.with_message("The resource that you are attempting to access does not exist or you don't have permission to perform this action")
end
end
+
+ context 'when the feature is disabled' do
+ let_it_be(:group) { create(:group) }
+
+ it 'raises an error' do
+ expect { resolve_mutation }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ .with_message("The resource that you are attempting to access does not exist or you don't have permission to perform this action")
+ end
+ end
end
end
diff --git a/spec/graphql/mutations/issues/set_escalation_status_spec.rb b/spec/graphql/mutations/issues/set_escalation_status_spec.rb
new file mode 100644
index 00000000000..d41118b1812
--- /dev/null
+++ b/spec/graphql/mutations/issues/set_escalation_status_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::Issues::SetEscalationStatus do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:issue, reload: true) { create(:incident, project: project) }
+ let_it_be(:escalation_status, reload: true) { create(:incident_management_issuable_escalation_status, issue: issue) }
+
+ let(:status) { :acknowledged }
+ let(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
+
+ describe '#resolve' do
+ let(:args) { { status: status } }
+ let(:mutated_issue) { result[:issue] }
+
+ subject(:result) { mutation.resolve(project_path: issue.project.full_path, iid: issue.iid, **args) }
+
+ it_behaves_like 'permission level for issue mutation is correctly verified', true
+
+ context 'when the user can update the issue' do
+ before_all do
+ project.add_reporter(user)
+ end
+
+ it_behaves_like 'permission level for issue mutation is correctly verified', true
+
+ context 'when the user can update the escalation status' do
+ before_all do
+ project.add_developer(user)
+ end
+
+ it 'returns the issue with the escalation policy' do
+ expect(mutated_issue).to eq(issue)
+ expect(mutated_issue.escalation_status.status_name).to eq(status)
+ expect(result[:errors]).to be_empty
+ end
+
+ it 'returns errors when issue update fails' do
+ issue.update_column(:author_id, nil)
+
+ expect(result[:errors]).not_to be_empty
+ end
+
+ context 'with non-incident issue is provided' do
+ let_it_be(:issue) { create(:issue, project: project) }
+
+ it 'raises an error' do
+ expect { result }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature unavailable for provided issue')
+ end
+ end
+
+ context 'with feature disabled' do
+ before do
+ stub_feature_flags(incident_escalations: false)
+ end
+
+ it 'raises an error' do
+ expect { result }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature unavailable for provided issue')
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/graphql/resolvers/clusters/agent_tokens_resolver_spec.rb b/spec/graphql/resolvers/clusters/agent_tokens_resolver_spec.rb
index 6b8b88928d8..9b54d466681 100644
--- a/spec/graphql/resolvers/clusters/agent_tokens_resolver_spec.rb
+++ b/spec/graphql/resolvers/clusters/agent_tokens_resolver_spec.rb
@@ -7,6 +7,7 @@ RSpec.describe Resolvers::Clusters::AgentTokensResolver do
it { expect(described_class.type).to eq(Types::Clusters::AgentTokenType) }
it { expect(described_class.null).to be_truthy }
+ it { expect(described_class.arguments.keys).to contain_exactly('status') }
describe '#resolve' do
let(:agent) { create(:cluster_agent) }
@@ -23,6 +24,14 @@ RSpec.describe Resolvers::Clusters::AgentTokensResolver do
expect(subject).to eq([matching_token2, matching_token1])
end
+ context 'token status is specified' do
+ let!(:revoked_token) { create(:cluster_agent_token, :revoked, agent: agent) }
+
+ subject { resolve(described_class, obj: agent, ctx: ctx, args: { status: 'revoked' }) }
+
+ it { is_expected.to contain_exactly(revoked_token) }
+ end
+
context 'user does not have permission' do
let(:user) { create(:user, developer_projects: [agent.project]) }
diff --git a/spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb b/spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb
index 3fcfa967452..9fe4c78f551 100644
--- a/spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb
+++ b/spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb
@@ -62,24 +62,12 @@ RSpec.describe ResolvesPipelines do
context 'filtering by source' do
let_it_be(:source_pipeline) { create(:ci_pipeline, project: project, source: 'web') }
- context 'when `dast_view_scans` feature flag is disabled' do
- before do
- stub_feature_flags(dast_view_scans: false)
- end
-
- it 'does not filter by source' do
- expect(resolve_pipelines(source: 'web')).to contain_exactly(*all_pipelines, source_pipeline)
- end
+ it 'does filter by source' do
+ expect(resolve_pipelines(source: 'web')).to contain_exactly(source_pipeline)
end
- context 'when `dast_view_scans` feature flag is enabled' do
- it 'does filter by source' do
- expect(resolve_pipelines(source: 'web')).to contain_exactly(source_pipeline)
- end
-
- it 'returns all the pipelines' do
- expect(resolve_pipelines).to contain_exactly(*all_pipelines, source_pipeline)
- end
+ it 'returns all the pipelines' do
+ expect(resolve_pipelines).to contain_exactly(*all_pipelines, source_pipeline)
end
end
diff --git a/spec/graphql/resolvers/merge_requests_resolver_spec.rb b/spec/graphql/resolvers/merge_requests_resolver_spec.rb
index a931b0a3f77..1d0eac30a23 100644
--- a/spec/graphql/resolvers/merge_requests_resolver_spec.rb
+++ b/spec/graphql/resolvers/merge_requests_resolver_spec.rb
@@ -172,6 +172,28 @@ RSpec.describe Resolvers::MergeRequestsResolver do
end
end
+ context 'with draft argument' do
+ before do
+ merge_request_4.update!(title: MergeRequest.wip_title(merge_request_4.title))
+ end
+
+ context 'with draft: true argument' do
+ it 'takes one argument' do
+ result = resolve_mr(project, draft: true)
+
+ expect(result).to contain_exactly(merge_request_4)
+ end
+ end
+
+ context 'with draft: false argument' do
+ it 'takes one argument' do
+ result = resolve_mr(project, draft: false)
+
+ expect(result).not_to contain_exactly(merge_request_1, merge_request_2, merge_request_3, merge_request_5, merge_request_6)
+ end
+ end
+ end
+
context 'with label argument' do
let_it_be(:label) { merge_request_6.labels.first }
let_it_be(:with_label) { create(:labeled_merge_request, :closed, labels: [label], **common_attrs) }
diff --git a/spec/graphql/resolvers/users/groups_resolver_spec.rb b/spec/graphql/resolvers/users/groups_resolver_spec.rb
index 0fdb6da5ae9..5ac7aac4898 100644
--- a/spec/graphql/resolvers/users/groups_resolver_spec.rb
+++ b/spec/graphql/resolvers/users/groups_resolver_spec.rb
@@ -26,14 +26,6 @@ RSpec.describe Resolvers::Users::GroupsResolver do
public_maintainer_group.add_maintainer(user)
end
- context 'when paginatable_namespace_drop_down_for_project_creation feature flag is disabled' do
- before do
- stub_feature_flags(paginatable_namespace_drop_down_for_project_creation: false)
- end
-
- it { is_expected.to be_nil }
- end
-
context 'when resolver object is current user' do
context 'when permission is :create_projects' do
let(:group_arguments) { { permission_scope: :create_projects } }
diff --git a/spec/graphql/resolvers/work_items/types_resolver_spec.rb b/spec/graphql/resolvers/work_items/types_resolver_spec.rb
new file mode 100644
index 00000000000..b85989256b5
--- /dev/null
+++ b/spec/graphql/resolvers/work_items/types_resolver_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Resolvers::WorkItems::TypesResolver do
+ include GraphqlHelpers
+
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:group) { create(: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)
+
+ expect(result.to_a).to match(WorkItems::Type.default.order_by_name_asc)
+ end
+ end
+end
diff --git a/spec/graphql/types/ci/config/config_type_spec.rb b/spec/graphql/types/ci/config/config_type_spec.rb
index edd190a4365..0012ae9f51f 100644
--- a/spec/graphql/types/ci/config/config_type_spec.rb
+++ b/spec/graphql/types/ci/config/config_type_spec.rb
@@ -11,6 +11,7 @@ RSpec.describe Types::Ci::Config::ConfigType do
mergedYaml
stages
status
+ warnings
]
expect(described_class).to have_graphql_fields(*expected_fields)
diff --git a/spec/graphql/types/ci/job_type_spec.rb b/spec/graphql/types/ci/job_type_spec.rb
index e3cb56c2ad5..47d697ab8b8 100644
--- a/spec/graphql/types/ci/job_type_spec.rb
+++ b/spec/graphql/types/ci/job_type_spec.rb
@@ -18,6 +18,7 @@ RSpec.describe Types::Ci::JobType do
created_by_tag
detailedStatus
duration
+ downstreamPipeline
finished_at
id
manual_job
diff --git a/spec/graphql/types/ci/pipeline_message_type_spec.rb b/spec/graphql/types/ci/pipeline_message_type_spec.rb
new file mode 100644
index 00000000000..f5c20cd9bf6
--- /dev/null
+++ b/spec/graphql/types/ci/pipeline_message_type_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::Ci::PipelineMessageType do
+ specify { expect(described_class.graphql_name).to eq('PipelineMessage') }
+
+ it 'contains attributes related to a pipeline message' do
+ expected_fields = %w[
+ id content
+ ]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/ci/pipeline_type_spec.rb b/spec/graphql/types/ci/pipeline_type_spec.rb
index 58724524785..94d1b42da37 100644
--- a/spec/graphql/types/ci/pipeline_type_spec.rb
+++ b/spec/graphql/types/ci/pipeline_type_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe Types::Ci::PipelineType do
coverage created_at updated_at started_at finished_at committed_at
stages user retryable cancelable jobs source_job job job_artifacts downstream
upstream path project active user_permissions warnings commit commit_path uses_needs
- test_report_summary test_suite ref
+ test_report_summary test_suite ref ref_path warning_messages
]
if Gitlab.ee?
diff --git a/spec/graphql/types/ci/runner_type_spec.rb b/spec/graphql/types/ci/runner_type_spec.rb
index cf8650a4a03..43d8b585d6b 100644
--- a/spec/graphql/types/ci/runner_type_spec.rb
+++ b/spec/graphql/types/ci/runner_type_spec.rb
@@ -9,9 +9,9 @@ RSpec.describe GitlabSchema.types['CiRunner'] do
it 'contains attributes related to a runner' do
expected_fields = %w[
- id description contacted_at maximum_timeout access_level active status
+ id description created_at contacted_at maximum_timeout access_level active status
version short_sha revision locked run_untagged ip_address runner_type tag_list
- project_count job_count admin_url user_permissions
+ project_count job_count admin_url edit_admin_url user_permissions executor_name
]
expect(described_class).to include_graphql_fields(*expected_fields)
diff --git a/spec/graphql/types/clusters/agent_token_status_enum_spec.rb b/spec/graphql/types/clusters/agent_token_status_enum_spec.rb
new file mode 100644
index 00000000000..071e4050cfb
--- /dev/null
+++ b/spec/graphql/types/clusters/agent_token_status_enum_spec.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::Clusters::AgentTokenStatusEnum do
+ it { expect(described_class.graphql_name).to eq('AgentTokenStatus') }
+ it { expect(described_class.values.keys).to match_array(Clusters::AgentToken.statuses.keys.map(&:upcase)) }
+end
diff --git a/spec/graphql/types/clusters/agent_token_type_spec.rb b/spec/graphql/types/clusters/agent_token_type_spec.rb
index c872d201fd9..3f0720cb4b5 100644
--- a/spec/graphql/types/clusters/agent_token_type_spec.rb
+++ b/spec/graphql/types/clusters/agent_token_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe GitlabSchema.types['ClusterAgentToken'] do
- let(:fields) { %i[cluster_agent created_at created_by_user description id last_used_at name] }
+ let(:fields) { %i[cluster_agent created_at created_by_user description id last_used_at name status] }
it { expect(described_class.graphql_name).to eq('ClusterAgentToken') }
diff --git a/spec/graphql/types/commit_type_spec.rb b/spec/graphql/types/commit_type_spec.rb
index 2f74ce81761..c1d838c3117 100644
--- a/spec/graphql/types/commit_type_spec.rb
+++ b/spec/graphql/types/commit_type_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe GitlabSchema.types['Commit'] do
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,
- :author_name, :author_gravatar, :author, :web_url, :web_path,
+ :author_name, :author_email, :author_gravatar, :author, :web_url, :web_path,
:pipelines, :signature_html
)
end
diff --git a/spec/graphql/types/group_member_relation_enum_spec.rb b/spec/graphql/types/group_member_relation_enum_spec.rb
index 315809ef75e..89ee8c574c4 100644
--- a/spec/graphql/types/group_member_relation_enum_spec.rb
+++ b/spec/graphql/types/group_member_relation_enum_spec.rb
@@ -6,6 +6,6 @@ RSpec.describe Types::GroupMemberRelationEnum do
specify { expect(described_class.graphql_name).to eq('GroupMemberRelation') }
it 'exposes all the existing group member relation type values' do
- expect(described_class.values.keys).to contain_exactly('DIRECT', 'INHERITED', 'DESCENDANTS')
+ expect(described_class.values.keys).to contain_exactly('DIRECT', 'INHERITED', 'DESCENDANTS', 'SHARED_FROM_GROUPS')
end
end
diff --git a/spec/graphql/types/group_type_spec.rb b/spec/graphql/types/group_type_spec.rb
index dca2c930eea..0ba322a100a 100644
--- a/spec/graphql/types/group_type_spec.rb
+++ b/spec/graphql/types/group_type_spec.rb
@@ -22,7 +22,7 @@ RSpec.describe GitlabSchema.types['Group'] do
dependency_proxy_blobs dependency_proxy_image_count
dependency_proxy_blob_count dependency_proxy_total_size
dependency_proxy_image_prefix dependency_proxy_image_ttl_policy
- shared_runners_setting timelogs organizations contacts
+ shared_runners_setting timelogs organizations contacts work_item_types
]
expect(described_class).to include_graphql_fields(*expected_fields)
diff --git a/spec/graphql/types/incident_management/escalation_status_enum_spec.rb b/spec/graphql/types/incident_management/escalation_status_enum_spec.rb
new file mode 100644
index 00000000000..b39d4d9324e
--- /dev/null
+++ b/spec/graphql/types/incident_management/escalation_status_enum_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['IssueEscalationStatus'] do
+ specify { expect(described_class.graphql_name).to eq('IssueEscalationStatus') }
+
+ describe 'statuses' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:status_name, :status_value) do
+ 'TRIGGERED' | :triggered
+ 'ACKNOWLEDGED' | :acknowledged
+ 'RESOLVED' | :resolved
+ 'IGNORED' | :ignored
+ 'INVALID' | nil
+ end
+
+ with_them do
+ it 'exposes a status with the correct value' do
+ expect(described_class.values[status_name]&.value).to eq(status_value)
+ end
+ end
+ end
+end
diff --git a/spec/graphql/types/issue_type_spec.rb b/spec/graphql/types/issue_type_spec.rb
index 1b8bf007a73..1d4590cbb4e 100644
--- a/spec/graphql/types/issue_type_spec.rb
+++ b/spec/graphql/types/issue_type_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe GitlabSchema.types['Issue'] do
confidential hidden discussion_locked upvotes downvotes merge_requests_count user_notes_count user_discussions_count web_path web_url relative_position
emails_disabled subscribed time_estimate total_time_spent human_time_estimate human_total_time_spent closed_at created_at updated_at task_completion_status
design_collection alert_management_alert severity current_user_todos moved moved_to
- create_note_email timelogs project_id customer_relations_contacts]
+ create_note_email timelogs project_id customer_relations_contacts escalation_status]
fields.each do |field_name|
expect(described_class).to have_graphql_field(field_name)
@@ -257,4 +257,49 @@ RSpec.describe GitlabSchema.types['Issue'] do
end
end
end
+
+ describe 'escalation_status' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:issue, reload: true) { create(:issue, project: project) }
+
+ let(:execute) { GitlabSchema.execute(query, context: { current_user: user }).as_json }
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ issue(iid: "#{issue.iid}") {
+ escalationStatus
+ }
+ }
+ }
+ )
+ end
+
+ subject(:status) { execute.dig('data', 'project', 'issue', 'escalationStatus') }
+
+ it { is_expected.to be_nil }
+
+ context 'for an incident' do
+ before do
+ issue.update!(issue_type: Issue.issue_types[:incident])
+ end
+
+ it { is_expected.to be_nil }
+
+ context 'with an escalation status record' do
+ let!(:escalation_status) { create(:incident_management_issuable_escalation_status, issue: issue) }
+
+ it { is_expected.to eq(escalation_status.status_name.to_s.upcase) }
+
+ context 'with feature disabled' do
+ before do
+ stub_feature_flags(incident_escalations: false)
+ end
+
+ it { is_expected.to be_nil }
+ end
+ end
+ end
+ end
end
diff --git a/spec/graphql/types/merge_request_type_spec.rb b/spec/graphql/types/merge_request_type_spec.rb
index b17b7c32289..5ab8845246a 100644
--- a/spec/graphql/types/merge_request_type_spec.rb
+++ b/spec/graphql/types/merge_request_type_spec.rb
@@ -33,7 +33,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_without_merge_commits squash security_auto_fix default_squash_commit_message
+ has_ci mergeable commits commits_without_merge_commits squash security_auto_fix default_squash_commit_message
auto_merge_strategy merge_user
]
@@ -133,4 +133,28 @@ RSpec.describe GitlabSchema.types['MergeRequest'] do
end
end
end
+
+ describe '#merge_user' do
+ let_it_be(:project) { create(:project, :public) }
+
+ context 'when MR is merged' do
+ let(:merge_request) { create(:merge_request, :with_merged_metrics, target_project: project, source_project: project) }
+
+ it 'is not nil' do
+ value = resolve_field(:merge_user, merge_request)
+
+ expect(value).not_to be_nil
+ end
+ end
+
+ context 'when MR is set to merge when pipeline succeeds' do
+ let(:merge_request) { create(:merge_request, :merge_when_pipeline_succeeds, target_project: project, source_project: project) }
+
+ it 'is not nil' do
+ value = resolve_field(:merge_user, merge_request)
+
+ expect(value).not_to be_nil
+ end
+ end
+ end
end
diff --git a/spec/graphql/types/mutation_type_spec.rb b/spec/graphql/types/mutation_type_spec.rb
index 95d835c88cf..1fc46f2d511 100644
--- a/spec/graphql/types/mutation_type_spec.rb
+++ b/spec/graphql/types/mutation_type_spec.rb
@@ -7,6 +7,14 @@ RSpec.describe Types::MutationType do
expect(described_class).to have_graphql_mutation(Mutations::MergeRequests::SetDraft)
end
+ describe 'deprecated mutations' do
+ describe 'clusterAgentTokenDelete' do
+ let(:field) { get_field('clusterAgentTokenDelete') }
+
+ it { expect(field.deprecation_reason).to eq('Tokens must be revoked with ClusterAgentTokenRevoke. Deprecated in 14.7.') }
+ end
+ end
+
def get_field(name)
described_class.fields[GraphqlHelpers.fieldnamerize(name)]
end
diff --git a/spec/graphql/types/packages/package_details_type_spec.rb b/spec/graphql/types/packages/package_details_type_spec.rb
index f0b684d6b07..ceeb000ff85 100644
--- a/spec/graphql/types/packages/package_details_type_spec.rb
+++ b/spec/graphql/types/packages/package_details_type_spec.rb
@@ -5,7 +5,10 @@ require 'spec_helper'
RSpec.describe GitlabSchema.types['PackageDetailsType'] do
it 'includes all the package fields' do
expected_fields = %w[
- id name version created_at updated_at package_type tags project pipelines versions package_files dependency_links
+ id name version created_at updated_at package_type tags project
+ pipelines versions package_files dependency_links
+ npm_url maven_url conan_url nuget_url pypi_url pypi_setup_url
+ composer_url composer_config_repository_url
]
expect(described_class).to include_graphql_fields(*expected_fields)
diff --git a/spec/graphql/types/project_type_spec.rb b/spec/graphql/types/project_type_spec.rb
index adf5507571b..cd216232569 100644
--- a/spec/graphql/types/project_type_spec.rb
+++ b/spec/graphql/types/project_type_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe GitlabSchema.types['Project'] do
container_repositories container_repositories_count
pipeline_analytics squash_read_only sast_ci_configuration
cluster_agent cluster_agents agent_configurations
- ci_template timelogs merge_commit_template squash_commit_template
+ ci_template timelogs merge_commit_template squash_commit_template work_item_types
]
expect(described_class).to include_graphql_fields(*expected_fields)
@@ -289,6 +289,7 @@ RSpec.describe GitlabSchema.types['Project'] do
:source_branches,
:target_branches,
:state,
+ :draft,
:labels,
:before,
:after,
diff --git a/spec/graphql/types/projects/service_type_spec.rb b/spec/graphql/types/projects/service_type_spec.rb
index cb09f1ca6cc..0bffdfd629d 100644
--- a/spec/graphql/types/projects/service_type_spec.rb
+++ b/spec/graphql/types/projects/service_type_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe Types::Projects::ServiceType do
describe ".resolve_type" do
it 'resolves the corresponding type for objects' do
expect(described_class.resolve_type(build(:jira_integration), {})).to eq(Types::Projects::Services::JiraServiceType)
- expect(described_class.resolve_type(build(:service), {})).to eq(Types::Projects::Services::BaseServiceType)
+ expect(described_class.resolve_type(build(:integration), {})).to eq(Types::Projects::Services::BaseServiceType)
expect(described_class.resolve_type(build(:drone_ci_integration), {})).to eq(Types::Projects::Services::BaseServiceType)
expect(described_class.resolve_type(build(:custom_issue_tracker_integration), {})).to eq(Types::Projects::Services::BaseServiceType)
end
diff --git a/spec/graphql/types/repository/blob_type_spec.rb b/spec/graphql/types/repository/blob_type_spec.rb
index 21bc88e34c0..8d845e5d814 100644
--- a/spec/graphql/types/repository/blob_type_spec.rb
+++ b/spec/graphql/types/repository/blob_type_spec.rb
@@ -21,15 +21,21 @@ RSpec.describe Types::Repository::BlobType do
:file_type,
:edit_blob_path,
:stored_externally,
+ :external_storage,
:raw_path,
:replace_path,
:pipeline_editor_path,
+ :find_file_path,
+ :blame_path,
+ :history_path,
+ :permalink_path,
:code_owners,
:simple_viewer,
:rich_viewer,
:plain_data,
:can_modify_blob,
:can_current_user_push_to_branch,
+ :archived,
:ide_edit_path,
:external_storage_url,
:fork_and_edit_path,
diff --git a/spec/helpers/admin/background_migrations_helper_spec.rb b/spec/helpers/admin/background_migrations_helper_spec.rb
index 8880a00755b..9c1bb0b9c55 100644
--- a/spec/helpers/admin/background_migrations_helper_spec.rb
+++ b/spec/helpers/admin/background_migrations_helper_spec.rb
@@ -3,22 +3,22 @@
require "spec_helper"
RSpec.describe Admin::BackgroundMigrationsHelper do
- describe '#batched_migration_status_badge_class_name' do
+ describe '#batched_migration_status_badge_variant' do
using RSpec::Parameterized::TableSyntax
- where(:status, :class_name) do
- :active | 'badge-info'
- :paused | 'badge-warning'
- :failed | 'badge-danger'
- :finished | 'badge-success'
+ where(:status, :variant) do
+ :active | :info
+ :paused | :warning
+ :failed | :danger
+ :finished | :success
end
- subject { helper.batched_migration_status_badge_class_name(migration) }
+ subject { helper.batched_migration_status_badge_variant(migration) }
with_them do
let(:migration) { build(:batched_background_migration, status: status) }
- it { is_expected.to eq(class_name) }
+ it { is_expected.to eq(variant) }
end
end
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index 7390b9b3f58..8c2b4b16075 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -477,4 +477,44 @@ RSpec.describe ApplicationHelper do
expect(helper).to have_received(:form_for).with(user, expected_options)
end
end
+
+ describe '#page_class' do
+ context 'when logged_out_marketing_header experiment is enabled' do
+ let_it_be(:expected_class) { 'logged-out-marketing-header-candidate' }
+
+ let(:current_user) { nil }
+ let(:variant) { :candidate }
+
+ subject do
+ helper.page_class.flatten
+ end
+
+ before do
+ stub_experiments(logged_out_marketing_header: variant)
+ allow(helper).to receive(:current_user) { current_user }
+ end
+
+ context 'when candidate' do
+ it { is_expected.to include(expected_class) }
+ end
+
+ context 'when candidate (:trial_focused variant)' do
+ let(:variant) { :trial_focused }
+
+ it { is_expected.to include(expected_class) }
+ end
+
+ context 'when control' do
+ let(:variant) { :control }
+
+ it { is_expected.not_to include(expected_class) }
+ end
+
+ context 'when a user is logged in' do
+ let(:current_user) { create(:user) }
+
+ it { is_expected.not_to include(expected_class) }
+ end
+ end
+ end
end
diff --git a/spec/helpers/application_settings_helper_spec.rb b/spec/helpers/application_settings_helper_spec.rb
index 3c2ac954fe5..e722f301522 100644
--- a/spec/helpers/application_settings_helper_spec.rb
+++ b/spec/helpers/application_settings_helper_spec.rb
@@ -253,6 +253,32 @@ RSpec.describe ApplicationSettingsHelper do
end
end
+ describe '.registration_features_can_be_prompted?' do
+ subject { helper.registration_features_can_be_prompted? }
+
+ before do
+ if Gitlab.ee?
+ allow(License).to receive(:current).and_return(nil)
+ end
+ end
+
+ context 'when service ping is enabled' do
+ before do
+ stub_application_setting(usage_ping_enabled: true)
+ end
+
+ it { is_expected.to be_falsey }
+ end
+
+ context 'when service ping is disabled' do
+ before do
+ stub_application_setting(usage_ping_enabled: false)
+ end
+
+ it { is_expected.to be_truthy }
+ end
+ end
+
describe '#sidekiq_job_limiter_modes_for_select' do
subject { helper.sidekiq_job_limiter_modes_for_select }
diff --git a/spec/helpers/auth_helper_spec.rb b/spec/helpers/auth_helper_spec.rb
index b481c214ca1..4bb09699db4 100644
--- a/spec/helpers/auth_helper_spec.rb
+++ b/spec/helpers/auth_helper_spec.rb
@@ -312,12 +312,6 @@ RSpec.describe AuthHelper do
it { is_expected.to be_truthy }
end
- context 'when current user is set' do
- let(:user) { instance_double('User') }
-
- it { is_expected.to eq(false) }
- end
-
context 'when no key is set' do
before do
stub_config(extra: {})
diff --git a/spec/helpers/auto_devops_helper_spec.rb b/spec/helpers/auto_devops_helper_spec.rb
index 4f060a0ae3b..1083faa5e19 100644
--- a/spec/helpers/auto_devops_helper_spec.rb
+++ b/spec/helpers/auto_devops_helper_spec.rb
@@ -86,7 +86,7 @@ RSpec.describe AutoDevopsHelper do
context 'when another service is enabled' do
before do
- create(:service, project: project, category: :ci, active: true)
+ create(:integration, project: project, category: :ci, active: true)
end
it { is_expected.to eq(false) }
diff --git a/spec/helpers/button_helper_spec.rb b/spec/helpers/button_helper_spec.rb
index 5601ab2df2a..851e13d908f 100644
--- a/spec/helpers/button_helper_spec.rb
+++ b/spec/helpers/button_helper_spec.rb
@@ -167,6 +167,7 @@ RSpec.describe ButtonHelper do
expect(element.attr('class')).to eq('btn btn-clipboard btn-transparent')
expect(element.attr('type')).to eq('button')
expect(element.attr('aria-label')).to eq('Copy')
+ expect(element.attr('aria-live')).to eq('polite')
expect(element.attr('data-toggle')).to eq('tooltip')
expect(element.attr('data-placement')).to eq('bottom')
expect(element.attr('data-container')).to eq('body')
diff --git a/spec/helpers/ci/jobs_helper_spec.rb b/spec/helpers/ci/jobs_helper_spec.rb
index e5ef362e91b..489d9d3fcee 100644
--- a/spec/helpers/ci/jobs_helper_spec.rb
+++ b/spec/helpers/ci/jobs_helper_spec.rb
@@ -5,9 +5,9 @@ require 'spec_helper'
RSpec.describe Ci::JobsHelper do
describe 'jobs data' do
let(:project) { create(:project, :repository) }
- let(:bridge) { create(:ci_bridge, status: :pending) }
+ let(:bridge) { create(:ci_bridge) }
- subject(:bridge_data) { helper.bridge_data(bridge) }
+ subject(:bridge_data) { helper.bridge_data(bridge, project) }
before do
allow(helper)
@@ -17,8 +17,10 @@ RSpec.describe Ci::JobsHelper do
it 'returns bridge data' do
expect(bridge_data).to eq({
- "build_name" => bridge.name,
- "empty-state-illustration-path" => '/path/to/illustration'
+ "build_id" => bridge.id,
+ "empty-state-illustration-path" => '/path/to/illustration',
+ "pipeline_iid" => bridge.pipeline.iid,
+ "project_full_path" => project.full_path
})
end
end
diff --git a/spec/helpers/ci/pipeline_editor_helper_spec.rb b/spec/helpers/ci/pipeline_editor_helper_spec.rb
index 874937bc4ce..b15569f03c7 100644
--- a/spec/helpers/ci/pipeline_editor_helper_spec.rb
+++ b/spec/helpers/ci/pipeline_editor_helper_spec.rb
@@ -46,6 +46,7 @@ RSpec.describe Ci::PipelineEditorHelper do
"empty-state-illustration-path" => 'foo',
"initial-branch-name" => nil,
"lint-help-page-path" => help_page_path('ci/lint', anchor: 'validate-basic-logic-and-syntax'),
+ "lint-unavailable-help-page-path" => help_page_path('ci/pipeline_editor/index', anchor: 'configuration-validation-currently-not-available'),
"needs-help-page-path" => help_page_path('ci/yaml/index', anchor: 'needs'),
"new-merge-request-path" => '/mock/project/-/merge_requests/new',
"pipeline_etag" => graphql_etag_pipeline_sha_path(project.commit.sha),
@@ -72,6 +73,7 @@ RSpec.describe Ci::PipelineEditorHelper do
"empty-state-illustration-path" => 'foo',
"initial-branch-name" => nil,
"lint-help-page-path" => help_page_path('ci/lint', anchor: 'validate-basic-logic-and-syntax'),
+ "lint-unavailable-help-page-path" => help_page_path('ci/pipeline_editor/index', anchor: 'configuration-validation-currently-not-available'),
"needs-help-page-path" => help_page_path('ci/yaml/index', anchor: 'needs'),
"new-merge-request-path" => '/mock/project/-/merge_requests/new',
"pipeline_etag" => '',
diff --git a/spec/helpers/ci/runners_helper_spec.rb b/spec/helpers/ci/runners_helper_spec.rb
index 173a0d3ab3c..832b4da0e20 100644
--- a/spec/helpers/ci/runners_helper_spec.rb
+++ b/spec/helpers/ci/runners_helper_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe Ci::RunnersHelper do
describe '#runner_status_icon', :clean_gitlab_redis_cache do
it "returns - not contacted yet" do
runner = create(:ci_runner)
- expect(helper.runner_status_icon(runner)).to include("not connected yet")
+ expect(helper.runner_status_icon(runner)).to include("not contacted yet")
end
it "returns offline text" do
@@ -79,12 +79,7 @@ RSpec.describe Ci::RunnersHelper do
it 'returns the data in format' do
expect(helper.admin_runners_data_attributes).to eq({
runner_install_help_page: 'https://docs.gitlab.com/runner/install/',
- registration_token: Gitlab::CurrentSettings.runners_registration_token,
- active_runners_count: '0',
- all_runners_count: '2',
- instance_runners_count: '1',
- group_runners_count: '0',
- project_runners_count: '1'
+ registration_token: Gitlab::CurrentSettings.runners_registration_token
})
end
end
diff --git a/spec/helpers/environment_helper_spec.rb b/spec/helpers/environment_helper_spec.rb
index 49937a3b53a..8e5f38cd95a 100644
--- a/spec/helpers/environment_helper_spec.rb
+++ b/spec/helpers/environment_helper_spec.rb
@@ -21,6 +21,16 @@ RSpec.describe EnvironmentHelper do
expect(html).to have_css('a.ci-status.ci-success')
end
end
+
+ context 'for a blocked deployment' do
+ subject { helper.render_deployment_status(deployment) }
+
+ let(:deployment) { build(:deployment, :blocked) }
+
+ it 'indicates the status' do
+ expect(subject).to have_text('blocked')
+ end
+ end
end
describe '#environments_detail_data_json' do
diff --git a/spec/helpers/environments_helper_spec.rb b/spec/helpers/environments_helper_spec.rb
index aef240db5b8..38f06b19b94 100644
--- a/spec/helpers/environments_helper_spec.rb
+++ b/spec/helpers/environments_helper_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe EnvironmentsHelper do
it 'returns data' do
expect(metrics_data).to include(
- 'settings_path' => edit_project_service_path(project, 'prometheus'),
+ 'settings_path' => edit_project_integration_path(project, 'prometheus'),
'clusters_path' => project_clusters_path(project),
'metrics_dashboard_base_path' => environment_metrics_path(environment),
'current_environment_name' => environment.name,
diff --git a/spec/helpers/groups/crm_settings_helper_spec.rb b/spec/helpers/groups/crm_settings_helper_spec.rb
new file mode 100644
index 00000000000..6376cabda3a
--- /dev/null
+++ b/spec/helpers/groups/crm_settings_helper_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Groups::CrmSettingsHelper do
+ let_it_be(:group) { create(:group) }
+
+ describe '#crm_feature_flag_enabled?' do
+ subject do
+ helper.crm_feature_flag_enabled?(group)
+ end
+
+ 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
+end
diff --git a/spec/helpers/hooks_helper_spec.rb b/spec/helpers/hooks_helper_spec.rb
index 3b23d705790..bac73db5dd4 100644
--- a/spec/helpers/hooks_helper_spec.rb
+++ b/spec/helpers/hooks_helper_spec.rb
@@ -5,6 +5,7 @@ require 'spec_helper'
RSpec.describe HooksHelper do
let(:project) { create(:project) }
let(:project_hook) { create(:project_hook, project: project) }
+ let(:service_hook) { create(:service_hook, integration: create(:drone_ci_integration)) }
let(:system_hook) { create(:system_hook) }
describe '#link_to_test_hook' do
@@ -31,6 +32,15 @@ RSpec.describe HooksHelper do
end
end
+ context 'with a service hook' do
+ let(:web_hook_log) { create(:web_hook_log, web_hook: service_hook) }
+
+ it 'returns project-namespaced link' do
+ expect(helper.hook_log_path(project_hook, web_hook_log))
+ .to eq(web_hook_log.present.details_path)
+ end
+ end
+
context 'with a system hook' do
let(:web_hook_log) { create(:web_hook_log, web_hook: system_hook) }
diff --git a/spec/helpers/integrations_helper_spec.rb b/spec/helpers/integrations_helper_spec.rb
index 3a7d4d12513..38ce17e34ba 100644
--- a/spec/helpers/integrations_helper_spec.rb
+++ b/spec/helpers/integrations_helper_spec.rb
@@ -20,6 +20,12 @@ RSpec.describe IntegrationsHelper do
end
describe '#integration_form_data' do
+ before do
+ allow(helper).to receive_messages(
+ request: double(referer: '/services')
+ )
+ end
+
let(:fields) do
[
:id,
@@ -39,7 +45,9 @@ RSpec.describe IntegrationsHelper do
:cancel_path,
:can_test,
:test_path,
- :reset_path
+ :reset_path,
+ :form_path,
+ :redirect_to
]
end
@@ -61,6 +69,10 @@ RSpec.describe IntegrationsHelper do
specify do
expect(subject[:reset_path]).to eq(helper.scoped_reset_integration_path(integration))
end
+
+ specify do
+ expect(subject[:redirect_to]).to eq('/services')
+ end
end
context 'Jira service' do
@@ -70,6 +82,20 @@ RSpec.describe IntegrationsHelper do
end
end
+ describe '#integration_overrides_data' do
+ let(:integration) { build_stubbed(:jira_integration) }
+ let(:fields) do
+ [
+ edit_path: edit_admin_application_settings_integration_path(integration),
+ overrides_path: overrides_admin_application_settings_integration_path(integration, format: :json)
+ ]
+ end
+
+ subject { helper.integration_overrides_data(integration) }
+
+ it { is_expected.to include(*fields) }
+ end
+
describe '#scoped_reset_integration_path' do
let(:integration) { build_stubbed(:jira_integration) }
let(:group) { nil }
diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb
index ad0ea6911f1..065ac526ae4 100644
--- a/spec/helpers/issues_helper_spec.rb
+++ b/spec/helpers/issues_helper_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe IssuesHelper do
describe '#work_item_type_icon' do
it 'returns icon of all standard base types' do
- WorkItem::Type.base_types.each do |type|
+ WorkItems::Type.base_types.each do |type|
expect(work_item_type_icon(type[0])).to eq "issue-type-#{type[0].to_s.dasherize}"
end
end
@@ -246,27 +246,6 @@ RSpec.describe IssuesHelper do
end
end
- describe '#use_startup_call' do
- it 'returns false when a query param is present' do
- allow(controller.request).to receive(:query_parameters).and_return({ foo: 'bar' })
-
- expect(helper.use_startup_call?).to eq(false)
- end
-
- it 'returns false when user has stored sort preference' do
- controller.instance_variable_set(:@sort, 'updated_asc')
-
- expect(helper.use_startup_call?).to eq(false)
- end
-
- it 'returns true when request.query_parameters is empty with default sorting preference' do
- controller.instance_variable_set(:@sort, 'created_date')
- allow(controller.request).to receive(:query_parameters).and_return({})
-
- expect(helper.use_startup_call?).to eq(true)
- end
- end
-
describe '#issue_header_actions_data' do
let(:current_user) { create(:user) }
diff --git a/spec/helpers/learn_gitlab_helper_spec.rb b/spec/helpers/learn_gitlab_helper_spec.rb
index 9d13fc65de7..ffc2bb31b8f 100644
--- a/spec/helpers/learn_gitlab_helper_spec.rb
+++ b/spec/helpers/learn_gitlab_helper_spec.rb
@@ -176,6 +176,19 @@ RSpec.describe LearnGitlabHelper do
)
})
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/namespaces_helper_spec.rb b/spec/helpers/namespaces_helper_spec.rb
index 6eb560e3f5c..00aa0fd1cba 100644
--- a/spec/helpers/namespaces_helper_spec.rb
+++ b/spec/helpers/namespaces_helper_spec.rb
@@ -188,44 +188,6 @@ RSpec.describe NamespacesHelper do
helper.namespaces_options
end
end
-
- describe 'include_groups_with_developer_maintainer_access parameter' do
- context 'when DEVELOPER_MAINTAINER_PROJECT_ACCESS is set for a project' do
- let!(:admin_project_creation_level) { ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS }
-
- it 'returns groups where user is a developer' do
- allow(helper).to receive(:current_user).and_return(user)
- stub_application_setting(default_project_creation: ::Gitlab::Access::MAINTAINER_PROJECT_ACCESS)
- admin_group.add_user(user, GroupMember::DEVELOPER)
-
- options = helper.namespaces_options_with_developer_maintainer_access
-
- expect(options).to include(admin_group.name)
- expect(options).not_to include(subgroup1.name)
- expect(options).to include(subgroup2.name)
- expect(options).not_to include(subgroup3.name)
- expect(options).to include(user_group.name)
- expect(options).to include(user.name)
- end
- end
-
- context 'when DEVELOPER_MAINTAINER_PROJECT_ACCESS is set globally' do
- it 'return groups where default is not overridden' do
- allow(helper).to receive(:current_user).and_return(user)
- stub_application_setting(default_project_creation: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS)
- admin_group.add_user(user, GroupMember::DEVELOPER)
-
- options = helper.namespaces_options_with_developer_maintainer_access
-
- expect(options).to include(admin_group.name)
- expect(options).to include(subgroup1.name)
- expect(options).to include(subgroup2.name)
- expect(options).not_to include(subgroup3.name)
- expect(options).to include(user_group.name)
- expect(options).to include(user.name)
- end
- end
- end
end
describe '#cascading_namespace_settings_popover_data' do
diff --git a/spec/helpers/nav/top_nav_helper_spec.rb b/spec/helpers/nav/top_nav_helper_spec.rb
index 10bd45e3189..ef6a6827826 100644
--- a/spec/helpers/nav/top_nav_helper_spec.rb
+++ b/spec/helpers/nav/top_nav_helper_spec.rb
@@ -20,7 +20,6 @@ RSpec.describe Nav::TopNavHelper do
let(:current_group) { nil }
let(:with_current_settings_admin_mode) { false }
let(:with_header_link_admin_mode) { false }
- let(:with_sherlock_enabled) { false }
let(:with_projects) { false }
let(:with_groups) { false }
let(:with_milestones) { false }
@@ -34,7 +33,6 @@ RSpec.describe Nav::TopNavHelper do
before do
allow(Gitlab::CurrentSettings).to receive(:admin_mode) { with_current_settings_admin_mode }
allow(helper).to receive(:header_link?).with(:admin_mode) { with_header_link_admin_mode }
- allow(Gitlab::Sherlock).to receive(:enabled?) { with_sherlock_enabled }
# Defaulting all `dashboard_nav_link?` calls to false ensures the EE-specific behavior
# is not enabled in this CE spec
@@ -434,27 +432,6 @@ RSpec.describe Nav::TopNavHelper do
expect(subject[:shortcuts]).to eq([expected_shortcuts])
end
end
-
- context 'when sherlock is enabled' do
- let(:with_sherlock_enabled) { true }
-
- before do
- # Note: We have to mock the sherlock route because the route is conditional on
- # sherlock being enabled, but it parsed at Rails load time and can't be overridden
- # in a spec.
- allow(helper).to receive(:sherlock_transactions_path) { '/fake_sherlock_path' }
- end
-
- it 'has sherlock as last :secondary item' do
- expected_sherlock_item = ::Gitlab::Nav::TopNavMenuItem.build(
- id: 'sherlock',
- title: 'Sherlock Transactions',
- icon: 'admin',
- href: '/fake_sherlock_path'
- )
- expect(subject[:secondary].last).to eq(expected_sherlock_item)
- end
- end
end
context 'when current_user is admin' do
diff --git a/spec/helpers/operations_helper_spec.rb b/spec/helpers/operations_helper_spec.rb
index 1864f9fad15..857771ebba6 100644
--- a/spec/helpers/operations_helper_spec.rb
+++ b/spec/helpers/operations_helper_spec.rb
@@ -32,7 +32,7 @@ RSpec.describe OperationsHelper do
expect(subject).to eq(
'alerts_setup_url' => help_page_path('operations/incident_management/integrations.md', anchor: 'configuration'),
'alerts_usage_url' => project_alert_management_index_path(project),
- 'prometheus_form_path' => project_service_path(project, prometheus_integration),
+ 'prometheus_form_path' => project_integration_path(project, prometheus_integration),
'prometheus_reset_key_path' => reset_alerting_token_project_settings_operations_path(project),
'prometheus_authorization_key' => nil,
'prometheus_api_url' => nil,
diff --git a/spec/helpers/packages_helper_spec.rb b/spec/helpers/packages_helper_spec.rb
index 06c6cccd488..8b3c8411fbd 100644
--- a/spec/helpers/packages_helper_spec.rb
+++ b/spec/helpers/packages_helper_spec.rb
@@ -219,45 +219,4 @@ RSpec.describe PackagesHelper do
it { is_expected.to eq(expected_result) }
end
end
-
- describe '#package_details_data' do
- let_it_be(:package) { create(:package) }
-
- let(:expected_result) do
- {
- package_id: package.id,
- can_delete: 'true',
- project_name: project.name,
- group_list_url: ''
- }
- end
-
- before do
- allow(helper).to receive(:current_user) { project.owner }
- allow(helper).to receive(:can?) { true }
- end
-
- context 'in a project without a group' do
- it 'populates presenter data' do
- result = helper.package_details_data(project, package)
-
- expect(result).to match(hash_including(expected_result))
- end
- end
-
- context 'in a project with a group' do
- let_it_be(:group) { create(:group) }
- let_it_be(:project_with_group) { create(:project, group: group) }
-
- it 'populates presenter data' do
- result = helper.package_details_data(project_with_group, package)
- expected = expected_result.merge({
- group_list_url: group_packages_path(project_with_group.group),
- project_name: project_with_group.name
- })
-
- expect(result).to match(hash_including(expected))
- end
- end
- end
end
diff --git a/spec/helpers/projects/cluster_agents_helper_spec.rb b/spec/helpers/projects/cluster_agents_helper_spec.rb
index 2935a74586b..632544797ee 100644
--- a/spec/helpers/projects/cluster_agents_helper_spec.rb
+++ b/spec/helpers/projects/cluster_agents_helper_spec.rb
@@ -17,5 +17,10 @@ RSpec.describe Projects::ClusterAgentsHelper do
it 'returns project path' do
expect(subject[:project_path]).to eq(project.full_path)
end
+
+ it 'returns string contants' do
+ expect(subject[:activity_empty_state_image]).to be_kind_of(String)
+ expect(subject[:empty_state_svg_path]).to be_kind_of(String)
+ end
end
end
diff --git a/spec/helpers/projects/issues/service_desk_helper_spec.rb b/spec/helpers/projects/issues/service_desk_helper_spec.rb
deleted file mode 100644
index 05766ee13c6..00000000000
--- a/spec/helpers/projects/issues/service_desk_helper_spec.rb
+++ /dev/null
@@ -1,54 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Projects::Issues::ServiceDeskHelper do
- let_it_be(:project) { create(:project, :public, service_desk_enabled: true) }
-
- let(:user) { build_stubbed(:user) }
- let(:current_user) { user }
-
- describe '#service_desk_meta' do
- subject { helper.service_desk_meta(project) }
-
- context "when service desk is supported and user can edit project settings" do
- before do
- allow(Gitlab::IncomingEmail).to receive(:enabled?).and_return(true)
- allow(Gitlab::IncomingEmail).to receive(:supports_wildcard?).and_return(true)
- allow(helper).to receive(:current_user).and_return(user)
- allow(helper).to receive(:can?).with(current_user, :admin_project, project).and_return(true)
- end
-
- it {
- is_expected.to eq({
- is_service_desk_supported: true,
- is_service_desk_enabled: true,
- can_edit_project_settings: true,
- service_desk_address: project.service_desk_address,
- service_desk_help_page: help_page_path('user/project/service_desk'),
- edit_project_page: edit_project_path(project),
- svg_path: ActionController::Base.helpers.image_path('illustrations/service_desk_empty.svg')
- })
- }
- end
-
- context "when service desk is not supported and user cannot edit project settings" do
- before do
- allow(Gitlab::IncomingEmail).to receive(:enabled?).and_return(false)
- allow(Gitlab::IncomingEmail).to receive(:supports_wildcard?).and_return(false)
- allow(helper).to receive(:current_user).and_return(user)
- allow(helper).to receive(:can?).with(current_user, :admin_project, project).and_return(false)
- end
-
- it {
- is_expected.to eq({
- is_service_desk_supported: false,
- is_service_desk_enabled: false,
- can_edit_project_settings: false,
- incoming_email_help_page: help_page_path('administration/incoming_email', anchor: 'set-it-up'),
- svg_path: ActionController::Base.helpers.image_path('illustrations/service-desk-setup.svg')
- })
- }
- end
- end
-end
diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb
index 17dcbab09bb..40cfdafc9ac 100644
--- a/spec/helpers/search_helper_spec.rb
+++ b/spec/helpers/search_helper_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe SearchHelper do
include MarkupHelper
+ include BadgesHelper
# Override simple_sanitize for our testing purposes
def simple_sanitize(str)
@@ -640,7 +641,7 @@ RSpec.describe SearchHelper do
}
},
{
- title: _('Last updated'),
+ title: _('Updated date'),
sortable: true,
sortParam: {
asc: 'updated_asc',
diff --git a/spec/helpers/snippets_helper_spec.rb b/spec/helpers/snippets_helper_spec.rb
index 12d791d8710..913be164a00 100644
--- a/spec/helpers/snippets_helper_spec.rb
+++ b/spec/helpers/snippets_helper_spec.rb
@@ -5,6 +5,7 @@ require 'spec_helper'
RSpec.describe SnippetsHelper do
include Gitlab::Routing
include IconsHelper
+ include BadgesHelper
let_it_be(:public_personal_snippet) { create(:personal_snippet, :public, :repository) }
let_it_be(:public_project_snippet) { create(:project_snippet, :public, :repository) }
@@ -72,7 +73,7 @@ RSpec.describe SnippetsHelper do
let(:visibility) { :private }
it 'returns the snippet badge' do
- expect(subject).to eq "<span class=\"badge badge-gray\">#{sprite_icon('lock', size: 14, css_class: 'gl-vertical-align-middle')} private</span>"
+ expect(subject).to eq gl_badge_tag('private', icon: 'lock')
end
end
diff --git a/spec/helpers/ssh_keys_helper_spec.rb b/spec/helpers/ssh_keys_helper_spec.rb
new file mode 100644
index 00000000000..1aa604f19be
--- /dev/null
+++ b/spec/helpers/ssh_keys_helper_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe SshKeysHelper do
+ describe '#ssh_key_allowed_algorithms' do
+ it 'returns string with the names of allowed algorithms that are quoted and joined by commas' do
+ allowed_algorithms = Gitlab::CurrentSettings.allowed_key_types.flat_map do |ssh_key_type_name|
+ Gitlab::SSHPublicKey.supported_algorithms_for_name(ssh_key_type_name)
+ end
+
+ quoted_allowed_algorithms = allowed_algorithms.map { |name| "'#{name}'" }
+
+ expected_string = Gitlab::Utils.to_exclusive_sentence(quoted_allowed_algorithms)
+
+ expect(ssh_key_allowed_algorithms).to eq(expected_string)
+ end
+
+ it 'returns only allowed algorithms' do
+ expect(ssh_key_allowed_algorithms).to match('ed25519')
+ stub_application_setting(ed25519_key_restriction: ApplicationSetting::FORBIDDEN_KEY_VALUE)
+ expect(ssh_key_allowed_algorithms).not_to match('ed25519')
+ end
+ end
+end
diff --git a/spec/helpers/tree_helper_spec.rb b/spec/helpers/tree_helper_spec.rb
index bc25a2fcdfc..1a0ecd5d903 100644
--- a/spec/helpers/tree_helper_spec.rb
+++ b/spec/helpers/tree_helper_spec.rb
@@ -84,14 +84,21 @@ RSpec.describe TreeHelper do
describe '#web_ide_button_data' do
let(:blob) { project.repository.blob_at('refs/heads/master', @path) }
+ let_it_be(:user_preferences_gitpod_path) { '/-/profile/preferences#user_gitpod_enabled' }
+ let_it_be(:user_profile_enable_gitpod_path) { '/-/profile?user%5Bgitpod_enabled%5D=true' }
+
before do
@path = ''
@project = project
@ref = sha
- allow(helper).to receive(:current_user).and_return(nil)
- allow(helper).to receive(:can_collaborate_with_project?).and_return(true)
- allow(helper).to receive(:can?).and_return(true)
+ allow(helper).to receive_messages(
+ current_user: nil,
+ can_collaborate_with_project?: true,
+ can?: true,
+ user_preferences_gitpod_path: user_preferences_gitpod_path,
+ user_profile_enable_gitpod_path: user_profile_enable_gitpod_path
+ )
end
subject { helper.web_ide_button_data(blob: blob) }
@@ -112,7 +119,10 @@ RSpec.describe TreeHelper do
edit_url: '',
web_ide_url: "/-/ide/project/#{project.full_path}/edit/#{sha}",
- gitpod_url: ''
+
+ gitpod_url: '',
+ user_preferences_gitpod_path: user_preferences_gitpod_path,
+ user_profile_enable_gitpod_path: user_profile_enable_gitpod_path
)
end
diff --git a/spec/helpers/version_check_helper_spec.rb b/spec/helpers/version_check_helper_spec.rb
index bd52eda8a65..959c4a94a78 100644
--- a/spec/helpers/version_check_helper_spec.rb
+++ b/spec/helpers/version_check_helper_spec.rb
@@ -3,33 +3,34 @@
require 'spec_helper'
RSpec.describe VersionCheckHelper do
- describe '#version_status_badge' do
- it 'returns nil if not dev environment and not enabled' do
- stub_rails_env('development')
- allow(Gitlab::CurrentSettings.current_application_settings).to receive(:version_check_enabled) { false }
+ let_it_be(:user) { create(:user) }
- expect(helper.version_status_badge).to be(nil)
- end
-
- context 'when production and enabled' do
- before do
- stub_rails_env('production')
- allow(Gitlab::CurrentSettings.current_application_settings).to receive(:version_check_enabled) { true }
- allow(VersionCheck).to receive(:image_url) { 'https://version.host.com/check.svg?gitlab_info=xxx' }
+ describe '#show_version_check?' do
+ describe 'return conditions' do
+ where(:enabled, :consent, :is_admin, :result) do
+ [
+ [false, false, false, false],
+ [false, false, true, false],
+ [false, true, false, false],
+ [false, true, true, false],
+ [true, false, false, false],
+ [true, false, true, true],
+ [true, true, false, false],
+ [true, true, true, false]
+ ]
end
- it 'returns an image tag' do
- expect(helper.version_status_badge).to start_with('<img')
- end
-
- it 'has a js prefixed css class' do
- expect(helper.version_status_badge)
- .to match(/class="js-version-status-badge lazy"/)
- end
+ with_them do
+ before do
+ stub_application_setting(version_check_enabled: enabled)
+ allow(User).to receive(:single_user).and_return(double(user, requires_usage_stats_consent?: consent))
+ allow(helper).to receive(:current_user).and_return(user)
+ allow(user).to receive(:can_read_all_resources?).and_return(is_admin)
+ end
- it 'has a VersionCheck image_url as the src' do
- expect(helper.version_status_badge)
- .to include(%{src="https://version.host.com/check.svg?gitlab_info=xxx"})
+ it 'returns correct results' do
+ expect(helper.show_version_check?).to eq result
+ end
end
end
end
diff --git a/spec/initializers/doorkeeper_spec.rb b/spec/initializers/doorkeeper_spec.rb
index 164225a00b2..56e0a22d59f 100644
--- a/spec/initializers/doorkeeper_spec.rb
+++ b/spec/initializers/doorkeeper_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe Doorkeeper.configuration do
before do
allow(controller).to receive(:current_user).and_return(current_user)
allow(controller).to receive(:session).and_return({})
- allow(controller).to receive(:request).and_return(OpenStruct.new(fullpath: '/return-path'))
+ allow(controller).to receive(:request).and_return(double('request', fullpath: '/return-path'))
allow(controller).to receive(:redirect_to)
allow(controller).to receive(:new_user_session_url).and_return('/login')
end
diff --git a/spec/initializers/session_store_spec.rb b/spec/initializers/session_store_spec.rb
index db90b335dc9..a94ce327a92 100644
--- a/spec/initializers/session_store_spec.rb
+++ b/spec/initializers/session_store_spec.rb
@@ -10,40 +10,10 @@ RSpec.describe 'Session initializer for GitLab' do
end
describe 'config#session_store' do
- context 'when the GITLAB_USE_REDIS_SESSIONS_STORE env is not set' do
- before do
- stub_env('GITLAB_USE_REDIS_SESSIONS_STORE', nil)
- end
+ it 'initialized as a redis_store with a proper servers configuration' do
+ expect(subject).to receive(:session_store).with(:redis_store, a_hash_including(redis_store: kind_of(::Redis::Store)))
- it 'initialized with Multistore as ENV var defaults to true' do
- expect(subject).to receive(:session_store).with(:redis_store, a_hash_including(redis_store: kind_of(::Redis::Store)))
-
- load_session_store
- end
- end
-
- context 'when the GITLAB_USE_REDIS_SESSIONS_STORE env is disabled' do
- before do
- stub_env('GITLAB_USE_REDIS_SESSIONS_STORE', false)
- end
-
- it 'initialized as a redis_store with a proper servers configuration' do
- expect(subject).to receive(:session_store).with(:redis_store, a_hash_including(redis_store: kind_of(Redis::Store)))
-
- load_session_store
- end
- end
-
- context 'when the GITLAB_USE_REDIS_SESSIONS_STORE env is enabled' do
- before do
- stub_env('GITLAB_USE_REDIS_SESSIONS_STORE', true)
- end
-
- it 'initialized as a redis_store with a proper servers configuration' do
- expect(subject).to receive(:session_store).with(:redis_store, a_hash_including(redis_store: kind_of(::Redis::Store)))
-
- load_session_store
- end
+ load_session_store
end
end
end
diff --git a/spec/lib/api/entities/ci/pipeline_spec.rb b/spec/lib/api/entities/ci/pipeline_spec.rb
index 6a658cc3e18..2b8e59b68c6 100644
--- a/spec/lib/api/entities/ci/pipeline_spec.rb
+++ b/spec/lib/api/entities/ci/pipeline_spec.rb
@@ -3,14 +3,31 @@
require 'spec_helper'
RSpec.describe API::Entities::Ci::Pipeline do
- let_it_be(:pipeline) { create(:ci_empty_pipeline) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:pipeline) { create(:ci_empty_pipeline, user: user) }
let_it_be(:job) { create(:ci_build, name: "rspec", coverage: 30.212, pipeline: pipeline) }
let(:entity) { described_class.new(pipeline) }
subject { entity.as_json }
- it 'returns the coverage as a string' do
+ exposed_fields = %i[before_sha tag yaml_errors created_at updated_at started_at finished_at committed_at duration queued_duration]
+
+ exposed_fields.each do |field|
+ it "exposes pipeline #{field}" do
+ expect(subject[field]).to eq(pipeline.public_send(field))
+ end
+ end
+
+ it 'exposes pipeline user basic information' do
+ expect(subject[:user].keys).to include(:avatar_url, :web_url)
+ end
+
+ it 'exposes pipeline detailed status' do
+ expect(subject[:detailed_status].keys).to include(:icon, :favicon)
+ end
+
+ it 'exposes pipeline coverage as a string' do
expect(subject[:coverage]).to eq '30.21'
end
end
diff --git a/spec/lib/api/entities/merge_request_basic_spec.rb b/spec/lib/api/entities/merge_request_basic_spec.rb
index b9d6ab7a652..40f259b86e2 100644
--- a/spec/lib/api/entities/merge_request_basic_spec.rb
+++ b/spec/lib/api/entities/merge_request_basic_spec.rb
@@ -21,7 +21,8 @@ RSpec.describe ::API::Entities::MergeRequestBasic do
it 'includes basic fields' do
is_expected.to include(
draft: merge_request.draft?,
- work_in_progress: merge_request.draft?
+ work_in_progress: merge_request.draft?,
+ merge_user: nil
)
end
diff --git a/spec/lib/api/helpers/rate_limiter_spec.rb b/spec/lib/api/helpers/rate_limiter_spec.rb
new file mode 100644
index 00000000000..2fed1cf3604
--- /dev/null
+++ b/spec/lib/api/helpers/rate_limiter_spec.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Helpers::RateLimiter do
+ let(:key) { :some_key }
+ let(:scope) { [:some, :scope] }
+ let(:request) { instance_double('Rack::Request') }
+ let(:user) { build_stubbed(:user) }
+
+ let(:api_class) do
+ Class.new do
+ include API::Helpers::RateLimiter
+
+ attr_reader :request, :current_user
+
+ def initialize(request, current_user)
+ @request = request
+ @current_user = current_user
+ end
+
+ def render_api_error!(**args)
+ end
+ end
+ end
+
+ subject { api_class.new(request, user) }
+
+ before do
+ allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?)
+ allow(::Gitlab::ApplicationRateLimiter).to receive(:log_request)
+ end
+
+ describe '#check_rate_limit!' do
+ it 'calls ApplicationRateLimiter#throttled? with the right arguments' do
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).with(key, scope: scope).and_return(false)
+ expect(subject).not_to receive(:render_api_error!)
+
+ subject.check_rate_limit!(key, scope: scope)
+ end
+
+ it 'renders api error and logs request if throttled' do
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).with(key, scope: scope).and_return(true)
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:log_request).with(request, "#{key}_request_limit".to_sym, user)
+ expect(subject).to receive(:render_api_error!).with({ error: _('This endpoint has been requested too many times. Try again later.') }, 429)
+
+ subject.check_rate_limit!(key, scope: scope)
+ end
+
+ context 'when the bypass header is set' do
+ before do
+ allow(Gitlab::Throttle).to receive(:bypass_header).and_return('SOME_HEADER')
+ end
+
+ it 'skips rate limit if set to "1"' do
+ allow(request).to receive(:get_header).with(Gitlab::Throttle.bypass_header).and_return('1')
+
+ expect(::Gitlab::ApplicationRateLimiter).not_to receive(:throttled?)
+ expect(subject).not_to receive(:render_api_error!)
+
+ subject.check_rate_limit!(key, scope: scope)
+ end
+
+ it 'does not skip rate limit if set to something else than "1"' do
+ allow(request).to receive(:get_header).with(Gitlab::Throttle.bypass_header).and_return('0')
+
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:throttled?)
+
+ subject.check_rate_limit!(key, scope: scope)
+ end
+ end
+ end
+end
diff --git a/spec/lib/backup/artifacts_spec.rb b/spec/lib/backup/artifacts_spec.rb
index 5a965030b01..102d787a5e1 100644
--- a/spec/lib/backup/artifacts_spec.rb
+++ b/spec/lib/backup/artifacts_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe Backup::Artifacts do
Dir.mktmpdir do |tmpdir|
allow(JobArtifactUploader).to receive(:root) { "#{tmpdir}" }
- expect(backup.app_files_dir).to eq("#{tmpdir}")
+ expect(backup.app_files_dir).to eq("#{File.realpath(tmpdir)}")
end
end
end
diff --git a/spec/lib/backup/files_spec.rb b/spec/lib/backup/files_spec.rb
index 92de191da2d..6bff0919293 100644
--- a/spec/lib/backup/files_spec.rb
+++ b/spec/lib/backup/files_spec.rb
@@ -134,7 +134,7 @@ RSpec.describe Backup::Files do
expect do
subject.dump
- end.to raise_error(/Backup operation failed:/)
+ end.to raise_error(/Failed to create compressed file/)
end
describe 'with STRATEGY=copy' do
@@ -170,7 +170,7 @@ RSpec.describe Backup::Files do
expect do
subject.dump
end.to output(/rsync failed/).to_stdout
- .and raise_error(/Backup failed/)
+ .and raise_error(/Failed to create compressed file/)
end
end
end
diff --git a/spec/lib/backup/gitaly_backup_spec.rb b/spec/lib/backup/gitaly_backup_spec.rb
index 2ccde517533..cd0d984fbdb 100644
--- a/spec/lib/backup/gitaly_backup_spec.rb
+++ b/spec/lib/backup/gitaly_backup_spec.rb
@@ -3,8 +3,8 @@
require 'spec_helper'
RSpec.describe Backup::GitalyBackup do
- let(:parallel) { nil }
- let(:parallel_storage) { nil }
+ let(:max_parallelism) { nil }
+ let(:storage_parallelism) { nil }
let(:progress) do
Tempfile.new('progress').tap do |progress|
@@ -23,7 +23,7 @@ RSpec.describe Backup::GitalyBackup do
progress.close
end
- subject { described_class.new(progress, parallel: parallel, parallel_storage: parallel_storage) }
+ subject { described_class.new(progress, max_parallelism: max_parallelism, storage_parallelism: storage_parallelism) }
context 'unknown' do
it 'fails to start unknown' do
@@ -48,7 +48,7 @@ RSpec.describe Backup::GitalyBackup do
subject.enqueue(project, Gitlab::GlRepository::DESIGN)
subject.enqueue(personal_snippet, Gitlab::GlRepository::SNIPPET)
subject.enqueue(project_snippet, Gitlab::GlRepository::SNIPPET)
- subject.wait
+ 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'))
@@ -58,24 +58,24 @@ RSpec.describe Backup::GitalyBackup do
end
context 'parallel option set' do
- let(:parallel) { 3 }
+ 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
subject.start(:create)
- subject.wait
+ subject.finish!
end
end
context 'parallel_storage option set' do
- let(:parallel_storage) { 3 }
+ 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
subject.start(:create)
- subject.wait
+ subject.finish!
end
end
@@ -83,7 +83,7 @@ RSpec.describe Backup::GitalyBackup do
expect(subject).to receive(:bin_path).and_return(Gitlab::Utils.which('false'))
subject.start(:create)
- expect { subject.wait }.to raise_error(::Backup::Error, 'gitaly-backup exit status 1')
+ expect { subject.finish! }.to raise_error(::Backup::Error, 'gitaly-backup exit status 1')
end
end
@@ -115,7 +115,7 @@ RSpec.describe Backup::GitalyBackup do
expect(Open3).to receive(:popen2).with(ssl_env, anything, 'create', '-path', anything).and_call_original
subject.start(:create)
- subject.wait
+ subject.finish!
end
end
end
@@ -145,7 +145,7 @@ RSpec.describe Backup::GitalyBackup do
subject.enqueue(project, Gitlab::GlRepository::DESIGN)
subject.enqueue(personal_snippet, Gitlab::GlRepository::SNIPPET)
subject.enqueue(project_snippet, Gitlab::GlRepository::SNIPPET)
- subject.wait
+ subject.finish!
collect_commit_shas = -> (repo) { repo.commits('master', limit: 10).map(&:sha) }
@@ -157,24 +157,24 @@ RSpec.describe Backup::GitalyBackup do
end
context 'parallel option set' do
- let(:parallel) { 3 }
+ 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
subject.start(:restore)
- subject.wait
+ subject.finish!
end
end
context 'parallel_storage option set' do
- let(:parallel_storage) { 3 }
+ 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
subject.start(:restore)
- subject.wait
+ subject.finish!
end
end
@@ -182,7 +182,7 @@ RSpec.describe Backup::GitalyBackup do
expect(subject).to receive(:bin_path).and_return(Gitlab::Utils.which('false'))
subject.start(:restore)
- expect { subject.wait }.to raise_error(::Backup::Error, 'gitaly-backup exit status 1')
+ expect { subject.finish! }.to raise_error(::Backup::Error, 'gitaly-backup exit status 1')
end
end
end
diff --git a/spec/lib/backup/gitaly_rpc_backup_spec.rb b/spec/lib/backup/gitaly_rpc_backup_spec.rb
index fb442f4a86f..14f9d27ca6e 100644
--- a/spec/lib/backup/gitaly_rpc_backup_spec.rb
+++ b/spec/lib/backup/gitaly_rpc_backup_spec.rb
@@ -33,7 +33,7 @@ RSpec.describe Backup::GitalyRpcBackup do
subject.enqueue(project, Gitlab::GlRepository::DESIGN)
subject.enqueue(personal_snippet, Gitlab::GlRepository::SNIPPET)
subject.enqueue(project_snippet, Gitlab::GlRepository::SNIPPET)
- subject.wait
+ 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'))
@@ -52,7 +52,7 @@ RSpec.describe Backup::GitalyRpcBackup do
it 'logs an appropriate message', :aggregate_failures do
subject.start(:create)
subject.enqueue(project, Gitlab::GlRepository::PROJECT)
- subject.wait
+ subject.finish!
expect(progress).to have_received(:puts).with("[Failed] backing up #{project.full_path} (#{project.disk_path})")
expect(progress).to have_received(:puts).with("Error Fail in tests")
@@ -96,7 +96,7 @@ RSpec.describe Backup::GitalyRpcBackup do
subject.enqueue(project, Gitlab::GlRepository::DESIGN)
subject.enqueue(personal_snippet, Gitlab::GlRepository::SNIPPET)
subject.enqueue(project_snippet, Gitlab::GlRepository::SNIPPET)
- subject.wait
+ subject.finish!
collect_commit_shas = -> (repo) { repo.commits('master', limit: 10).map(&:sha) }
@@ -129,7 +129,7 @@ RSpec.describe Backup::GitalyRpcBackup do
subject.enqueue(project, Gitlab::GlRepository::DESIGN)
subject.enqueue(personal_snippet, Gitlab::GlRepository::SNIPPET)
subject.enqueue(project_snippet, Gitlab::GlRepository::SNIPPET)
- subject.wait
+ subject.finish!
end
context 'failure' do
@@ -143,7 +143,7 @@ RSpec.describe Backup::GitalyRpcBackup do
it 'logs an appropriate message', :aggregate_failures do
subject.start(:restore)
subject.enqueue(project, Gitlab::GlRepository::PROJECT)
- subject.wait
+ subject.finish!
expect(progress).to have_received(:puts).with("[Failed] restoring #{project.full_path} (#{project.disk_path})")
expect(progress).to have_received(:puts).with("Error Fail in tests")
diff --git a/spec/lib/backup/lfs_spec.rb b/spec/lib/backup/lfs_spec.rb
new file mode 100644
index 00000000000..fdc1c0c885d
--- /dev/null
+++ b/spec/lib/backup/lfs_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Backup::Lfs do
+ let(:progress) { StringIO.new }
+
+ subject(:backup) { described_class.new(progress) }
+
+ describe '#dump' do
+ before do
+ allow(File).to receive(:realpath).and_call_original
+ allow(File).to receive(:realpath).with('/var/lfs-objects').and_return('/var/lfs-objects')
+ allow(File).to receive(:realpath).with('/var/lfs-objects/..').and_return('/var')
+ allow(Settings.lfs).to receive(:storage_path).and_return('/var/lfs-objects')
+ end
+
+ it 'uses the correct lfs dir in tar command', :aggregate_failures do
+ expect(backup.app_files_dir).to eq('/var/lfs-objects')
+ expect(backup).to receive(:tar).and_return('blabla-tar')
+ 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
+ end
+ end
+end
diff --git a/spec/lib/backup/manager_spec.rb b/spec/lib/backup/manager_spec.rb
index 32eea82cfdf..31cc3012eb1 100644
--- a/spec/lib/backup/manager_spec.rb
+++ b/spec/lib/backup/manager_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe Backup::Manager do
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 backup_information.yml) }
+ 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) }
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] }
@@ -57,7 +57,7 @@ RSpec.describe Backup::Manager do
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 backup_information.yml} }
+ 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(:backup_information) do
{
backup_created_at: Time.zone.parse('2019-01-01'),
@@ -74,7 +74,7 @@ RSpec.describe Backup::Manager do
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 backup_information.yml} }
+ 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)
diff --git a/spec/lib/backup/object_backup_spec.rb b/spec/lib/backup/object_backup_spec.rb
new file mode 100644
index 00000000000..6192b5c3482
--- /dev/null
+++ b/spec/lib/backup/object_backup_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.shared_examples 'backup object' do |setting|
+ let(:progress) { StringIO.new }
+ let(:backup_path) { "/var/#{setting}" }
+
+ subject(:backup) { described_class.new(progress) }
+
+ describe '#dump' do
+ before do
+ allow(File).to receive(:realpath).and_call_original
+ allow(File).to receive(:realpath).with(backup_path).and_return(backup_path)
+ allow(File).to receive(:realpath).with("#{backup_path}/..").and_return('/var')
+ allow(Settings.send(setting)).to receive(:storage_path).and_return(backup_path)
+ end
+
+ it 'uses the correct storage dir in tar command and excludes tmp', :aggregate_failures do
+ expect(backup.app_files_dir).to eq(backup_path)
+ 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 #{backup_path} -cf - .), 'gzip -c -1'], any_args).and_return([[true, true], ''])
+ expect(backup).to receive(:pipeline_succeeded?).and_return(true)
+
+ backup.dump
+ end
+ end
+end
+
+RSpec.describe Backup::Packages do
+ it_behaves_like 'backup object', 'packages'
+end
+
+RSpec.describe Backup::TerraformState do
+ it_behaves_like 'backup object', 'terraform_state'
+end
diff --git a/spec/lib/backup/repositories_spec.rb b/spec/lib/backup/repositories_spec.rb
index 85818038c9d..f3830da344b 100644
--- a/spec/lib/backup/repositories_spec.rb
+++ b/spec/lib/backup/repositories_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe Backup::Repositories do
expect(strategy).to have_received(:enqueue).with(project, Gitlab::GlRepository::DESIGN)
expect(strategy).to have_received(:enqueue).with(project_snippet, Gitlab::GlRepository::SNIPPET)
expect(strategy).to have_received(:enqueue).with(personal_snippet, Gitlab::GlRepository::SNIPPET)
- expect(strategy).to have_received(:wait)
+ expect(strategy).to have_received(:finish!)
end
end
@@ -49,7 +49,7 @@ RSpec.describe Backup::Repositories do
projects.each do |project|
expect(strategy).to receive(:enqueue).with(project, Gitlab::GlRepository::PROJECT)
end
- expect(strategy).to receive(:wait)
+ expect(strategy).to receive(:finish!)
subject.dump(max_concurrency: 1, max_storage_concurrency: 1)
end
@@ -91,7 +91,7 @@ RSpec.describe Backup::Repositories do
projects.each do |project|
expect(strategy).to receive(:enqueue).with(project, Gitlab::GlRepository::PROJECT)
end
- expect(strategy).to receive(:wait)
+ expect(strategy).to receive(:finish!)
subject.dump(max_concurrency: 2, max_storage_concurrency: 2)
end
@@ -114,7 +114,7 @@ RSpec.describe Backup::Repositories do
projects.each do |project|
expect(strategy).to receive(:enqueue).with(project, Gitlab::GlRepository::PROJECT)
end
- expect(strategy).to receive(:wait)
+ expect(strategy).to receive(:finish!)
subject.dump(max_concurrency: 1, max_storage_concurrency: max_storage_concurrency)
end
@@ -128,7 +128,7 @@ RSpec.describe Backup::Repositories do
projects.each do |project|
expect(strategy).to receive(:enqueue).with(project, Gitlab::GlRepository::PROJECT)
end
- expect(strategy).to receive(:wait)
+ expect(strategy).to receive(:finish!)
subject.dump(max_concurrency: 3, max_storage_concurrency: max_storage_concurrency)
end
@@ -184,7 +184,7 @@ RSpec.describe Backup::Repositories do
expect(strategy).to have_received(:enqueue).with(project, Gitlab::GlRepository::DESIGN)
expect(strategy).to have_received(:enqueue).with(project_snippet, Gitlab::GlRepository::SNIPPET)
expect(strategy).to have_received(:enqueue).with(personal_snippet, Gitlab::GlRepository::SNIPPET)
- expect(strategy).to have_received(:wait)
+ expect(strategy).to have_received(:finish!)
end
context 'restoring object pools' do
diff --git a/spec/lib/backup/repository_backup_error_spec.rb b/spec/lib/backup/repository_backup_error_spec.rb
deleted file mode 100644
index 44c75c1cf77..00000000000
--- a/spec/lib/backup/repository_backup_error_spec.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Backup::RepositoryBackupError do
- let_it_be(:snippet) { create(:snippet, content: 'foo', file_name: 'foo') }
- let_it_be(:project) { create(:project, :repository) }
- let_it_be(:wiki) { ProjectWiki.new(project, nil ) }
-
- let(:backup_repos_path) { '/tmp/backup/repositories' }
-
- shared_examples 'includes backup path' do
- it { is_expected.to respond_to :container }
- it { is_expected.to respond_to :backup_repos_path }
-
- it 'expects exception message to include repo backup path location' do
- expect(subject.message).to include("#{subject.backup_repos_path}")
- end
-
- it 'expects exception message to include container being back-up' do
- expect(subject.message).to include("#{subject.container.disk_path}")
- end
- end
-
- context 'with snippet repository' do
- subject { described_class.new(snippet, backup_repos_path) }
-
- it_behaves_like 'includes backup path'
- end
-
- context 'with project repository' do
- subject { described_class.new(project, backup_repos_path) }
-
- it_behaves_like 'includes backup path'
- end
-
- context 'with wiki repository' do
- subject { described_class.new(wiki, backup_repos_path) }
-
- it_behaves_like 'includes backup path'
- end
-end
diff --git a/spec/lib/backup/uploads_spec.rb b/spec/lib/backup/uploads_spec.rb
index a82cb764f4d..c173916fe91 100644
--- a/spec/lib/backup/uploads_spec.rb
+++ b/spec/lib/backup/uploads_spec.rb
@@ -14,13 +14,14 @@ RSpec.describe Backup::Uploads do
allow(Gitlab.config.uploads).to receive(:storage_path) { tmpdir }
- expect(backup.app_files_dir).to eq("#{tmpdir}/uploads")
+ expect(backup.app_files_dir).to eq("#{File.realpath(tmpdir)}/uploads")
end
end
end
describe '#dump' do
before do
+ allow(File).to receive(:realpath).and_call_original
allow(File).to receive(:realpath).with('/var/uploads').and_return('/var/uploads')
allow(File).to receive(:realpath).with('/var/uploads/..').and_return('/var')
allow(Gitlab.config.uploads).to receive(:storage_path) { '/var' }
diff --git a/spec/lib/banzai/filter/footnote_filter_spec.rb b/spec/lib/banzai/filter/footnote_filter_spec.rb
index d41f5e8633d..5ac7d3af733 100644
--- a/spec/lib/banzai/filter/footnote_filter_spec.rb
+++ b/spec/lib/banzai/filter/footnote_filter_spec.rb
@@ -56,52 +56,6 @@ RSpec.describe Banzai::Filter::FootnoteFilter do
it 'properly adds the necessary ids and classes' do
expect(doc.to_html).to eq filtered_footnote.strip
end
-
- context 'using ruby-based HTML renderer' do
- # first[^1] and second[^second]
- # [^1]: one
- # [^second]: two
- let(:footnote) do
- <<~EOF
- <p>first<sup><a href="#fn1" id="fnref1">1</a></sup> and second<sup><a href="#fn2" id="fnref2">2</a></sup></p>
- <p>same reference<sup><a href="#fn1" id="fnref1">1</a></sup></p>
- <ol>
- <li id="fn1">
- <p>one <a href="#fnref1">↩</a></p>
- </li>
- <li id="fn2">
- <p>two <a href="#fnref2">↩</a></p>
- </li>
- </ol>
- EOF
- end
-
- let(:filtered_footnote) do
- <<~EOF
- <p>first<sup class="footnote-ref"><a href="#fn1-#{identifier}" id="fnref1-#{identifier}">1</a></sup> and second<sup class="footnote-ref"><a href="#fn2-#{identifier}" id="fnref2-#{identifier}">2</a></sup></p>
- <p>same reference<sup class="footnote-ref"><a href="#fn1-#{identifier}" id="fnref1-#{identifier}">1</a></sup></p>
- <section class="footnotes"><ol>
- <li id="fn1-#{identifier}">
- <p>one <a href="#fnref1-#{identifier}" class="footnote-backref">↩</a></p>
- </li>
- <li id="fn2-#{identifier}">
- <p>two <a href="#fnref2-#{identifier}" class="footnote-backref">↩</a></p>
- </li>
- </ol></section>
- EOF
- end
-
- let(:doc) { filter(footnote) }
- let(:identifier) { link_node[:id].delete_prefix('fnref1-') }
-
- before do
- stub_feature_flags(use_cmark_renderer: false)
- end
-
- it 'properly adds the necessary ids and classes' do
- expect(doc.to_html).to eq filtered_footnote
- end
- end
end
context 'when detecting footnotes' do
diff --git a/spec/lib/banzai/filter/markdown_filter_spec.rb b/spec/lib/banzai/filter/markdown_filter_spec.rb
index 1c9b894e885..e3c8d121587 100644
--- a/spec/lib/banzai/filter/markdown_filter_spec.rb
+++ b/spec/lib/banzai/filter/markdown_filter_spec.rb
@@ -5,125 +5,90 @@ require 'spec_helper'
RSpec.describe Banzai::Filter::MarkdownFilter do
include FilterSpecHelper
- shared_examples_for 'renders correct markdown' do
- describe 'markdown engine from context' do
- it 'defaults to CommonMark' do
- expect_next_instance_of(Banzai::Filter::MarkdownEngines::CommonMark) do |instance|
- expect(instance).to receive(:render).and_return('test')
- end
-
- filter('test')
+ describe 'markdown engine from context' do
+ it 'defaults to CommonMark' do
+ expect_next_instance_of(Banzai::Filter::MarkdownEngines::CommonMark) do |instance|
+ expect(instance).to receive(:render).and_return('test')
end
- it 'uses CommonMark' do
- expect_next_instance_of(Banzai::Filter::MarkdownEngines::CommonMark) do |instance|
- expect(instance).to receive(:render).and_return('test')
- end
+ filter('test')
+ end
- filter('test', { markdown_engine: :common_mark })
+ it 'uses CommonMark' do
+ expect_next_instance_of(Banzai::Filter::MarkdownEngines::CommonMark) do |instance|
+ expect(instance).to receive(:render).and_return('test')
end
+
+ filter('test', { markdown_engine: :common_mark })
end
+ end
- describe 'code block' do
- context 'using CommonMark' do
- before do
- stub_const('Banzai::Filter::MarkdownFilter::DEFAULT_ENGINE', :common_mark)
- end
-
- it 'adds language to lang attribute when specified' do
- result = filter("```html\nsome code\n```", no_sourcepos: true)
-
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- expect(result).to start_with('<pre lang="html"><code>')
- else
- expect(result).to start_with('<pre><code lang="html">')
- end
- end
-
- it 'does not add language to lang attribute when not specified' do
- result = filter("```\nsome code\n```", no_sourcepos: true)
-
- expect(result).to start_with('<pre><code>')
- end
-
- it 'works with utf8 chars in language' do
- result = filter("```æ—¥\nsome code\n```", no_sourcepos: true)
-
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- expect(result).to start_with('<pre lang="æ—¥"><code>')
- else
- expect(result).to start_with('<pre><code lang="æ—¥">')
- end
- end
-
- it 'works with additional language parameters' do
- result = filter("```ruby:red gem foo\nsome code\n```", no_sourcepos: true)
-
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- expect(result).to start_with('<pre lang="ruby:red" data-meta="gem foo"><code>')
- else
- expect(result).to start_with('<pre><code lang="ruby:red gem foo">')
- end
- end
+ describe 'code block' do
+ context 'using CommonMark' do
+ before do
+ stub_const('Banzai::Filter::MarkdownFilter::DEFAULT_ENGINE', :common_mark)
end
- end
- describe 'source line position' do
- context 'using CommonMark' do
- before do
- stub_const('Banzai::Filter::MarkdownFilter::DEFAULT_ENGINE', :common_mark)
- end
+ it 'adds language to lang attribute when specified' do
+ result = filter("```html\nsome code\n```", no_sourcepos: true)
- it 'defaults to add data-sourcepos' do
- result = filter('test')
+ expect(result).to start_with('<pre lang="html"><code>')
+ end
- expect(result).to eq '<p data-sourcepos="1:1-1:4">test</p>'
- end
+ it 'does not add language to lang attribute when not specified' do
+ result = filter("```\nsome code\n```", no_sourcepos: true)
- it 'disables data-sourcepos' do
- result = filter('test', no_sourcepos: true)
+ expect(result).to start_with('<pre><code>')
+ end
+
+ it 'works with utf8 chars in language' do
+ result = filter("```æ—¥\nsome code\n```", no_sourcepos: true)
- expect(result).to eq '<p>test</p>'
- end
+ expect(result).to start_with('<pre lang="æ—¥"><code>')
+ end
+
+ it 'works with additional language parameters' do
+ result = filter("```ruby:red gem foo\nsome code\n```", no_sourcepos: true)
+
+ expect(result).to start_with('<pre lang="ruby:red" data-meta="gem foo"><code>')
end
end
+ end
- describe 'footnotes in tables' do
- it 'processes footnotes in table cells' do
- text = <<-MD.strip_heredoc
- | Column1 |
- | --------- |
- | foot [^1] |
+ describe 'source line position' do
+ context 'using CommonMark' do
+ before do
+ stub_const('Banzai::Filter::MarkdownFilter::DEFAULT_ENGINE', :common_mark)
+ end
- [^1]: a footnote
- MD
+ it 'defaults to add data-sourcepos' do
+ result = filter('test')
- result = filter(text, no_sourcepos: true)
+ expect(result).to eq '<p data-sourcepos="1:1-1:4">test</p>'
+ end
- expect(result).to include('<td>foot <sup')
+ it 'disables data-sourcepos' do
+ result = filter('test', no_sourcepos: true)
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- expect(result).to include('<section class="footnotes" data-footnotes>')
- else
- expect(result).to include('<section class="footnotes">')
- end
+ expect(result).to eq '<p>test</p>'
end
end
end
- context 'using ruby-based HTML renderer' do
- before do
- stub_feature_flags(use_cmark_renderer: false)
- end
+ describe 'footnotes in tables' do
+ it 'processes footnotes in table cells' do
+ text = <<-MD.strip_heredoc
+ | Column1 |
+ | --------- |
+ | foot [^1] |
- it_behaves_like 'renders correct markdown'
- end
+ [^1]: a footnote
+ MD
- context 'using c-based HTML renderer' do
- before do
- stub_feature_flags(use_cmark_renderer: true)
- end
+ result = filter(text, no_sourcepos: true)
- it_behaves_like 'renders correct markdown'
+ expect(result).to include('<td>foot <sup')
+ expect(result).to include('<section class="footnotes" data-footnotes>')
+ end
end
end
diff --git a/spec/lib/banzai/filter/plantuml_filter_spec.rb b/spec/lib/banzai/filter/plantuml_filter_spec.rb
index e1e02c09fbe..2d1a01116e0 100644
--- a/spec/lib/banzai/filter/plantuml_filter_spec.rb
+++ b/spec/lib/banzai/filter/plantuml_filter_spec.rb
@@ -5,67 +5,33 @@ require 'spec_helper'
RSpec.describe Banzai::Filter::PlantumlFilter do
include FilterSpecHelper
- shared_examples_for 'renders correct markdown' do
- it 'replaces plantuml pre tag with img tag' do
- stub_application_setting(plantuml_enabled: true, plantuml_url: "http://localhost:8080")
+ it 'replaces plantuml pre tag with img tag' do
+ stub_application_setting(plantuml_enabled: true, plantuml_url: "http://localhost:8080")
- input = if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- '<pre lang="plantuml"><code>Bob -> Sara : Hello</code></pre>'
- else
- '<pre><code lang="plantuml">Bob -> Sara : Hello</code></pre>'
- end
+ input = '<pre lang="plantuml"><code>Bob -> Sara : Hello</code></pre>'
+ output = '<div class="imageblock"><div class="content"><img class="plantuml" src="http://localhost:8080/png/U9npoazIqBLJ24uiIbImKl18pSd91m0rkGMq"></div></div>'
+ doc = filter(input)
- output = '<div class="imageblock"><div class="content"><img class="plantuml" src="http://localhost:8080/png/U9npoazIqBLJ24uiIbImKl18pSd91m0rkGMq"></div></div>'
- doc = filter(input)
-
- expect(doc.to_s).to eq output
- end
-
- it 'does not replace plantuml pre tag with img tag if disabled' do
- stub_application_setting(plantuml_enabled: false)
-
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- input = '<pre lang="plantuml"><code>Bob -> Sara : Hello</code></pre>'
- output = '<pre lang="plantuml"><code>Bob -&gt; Sara : Hello</code></pre>'
- else
- input = '<pre><code lang="plantuml">Bob -> Sara : Hello</code></pre>'
- output = '<pre><code lang="plantuml">Bob -&gt; Sara : Hello</code></pre>'
- end
-
- doc = filter(input)
-
- expect(doc.to_s).to eq output
- end
-
- it 'does not replace plantuml pre tag with img tag if url is invalid' do
- stub_application_setting(plantuml_enabled: true, plantuml_url: "invalid")
+ expect(doc.to_s).to eq output
+ end
- input = if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- '<pre lang="plantuml"><code>Bob -> Sara : Hello</code></pre>'
- else
- '<pre><code lang="plantuml">Bob -> Sara : Hello</code></pre>'
- end
+ it 'does not replace plantuml pre tag with img tag if disabled' do
+ stub_application_setting(plantuml_enabled: false)
- output = '<div class="listingblock"><div class="content"><pre class="plantuml plantuml-error"> Error: cannot connect to PlantUML server at "invalid"</pre></div></div>'
- doc = filter(input)
+ input = '<pre lang="plantuml"><code>Bob -> Sara : Hello</code></pre>'
+ output = '<pre lang="plantuml"><code>Bob -&gt; Sara : Hello</code></pre>'
+ doc = filter(input)
- expect(doc.to_s).to eq output
- end
+ expect(doc.to_s).to eq output
end
- context 'using ruby-based HTML renderer' do
- before do
- stub_feature_flags(use_cmark_renderer: false)
- end
-
- it_behaves_like 'renders correct markdown'
- end
+ it 'does not replace plantuml pre tag with img tag if url is invalid' do
+ stub_application_setting(plantuml_enabled: true, plantuml_url: "invalid")
- context 'using c-based HTML renderer' do
- before do
- stub_feature_flags(use_cmark_renderer: true)
- end
+ input = '<pre lang="plantuml"><code>Bob -> Sara : Hello</code></pre>'
+ output = '<div class="listingblock"><div class="content"><pre class="plantuml plantuml-error"> Error: cannot connect to PlantUML server at "invalid"</pre></div></div>'
+ doc = filter(input)
- it_behaves_like 'renders correct markdown'
+ expect(doc.to_s).to eq output
end
end
diff --git a/spec/lib/banzai/filter/references/issue_reference_filter_spec.rb b/spec/lib/banzai/filter/references/issue_reference_filter_spec.rb
index 14c1542b724..b3523a25116 100644
--- a/spec/lib/banzai/filter/references/issue_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/references/issue_reference_filter_spec.rb
@@ -122,6 +122,7 @@ RSpec.describe Banzai::Filter::References::IssueReferenceFilter do
expect(link).to have_attribute('data-reference-format')
expect(link.attr('data-reference-format')).to eq('+')
+ expect(link.attr('href')).to eq(issue_url)
end
it 'includes a data-reference-format attribute for URL references' do
@@ -130,6 +131,7 @@ RSpec.describe Banzai::Filter::References::IssueReferenceFilter do
expect(link).to have_attribute('data-reference-format')
expect(link.attr('data-reference-format')).to eq('+')
+ expect(link.attr('href')).to eq(issue_url)
end
it 'supports an :only_path context' do
diff --git a/spec/lib/banzai/filter/references/merge_request_reference_filter_spec.rb b/spec/lib/banzai/filter/references/merge_request_reference_filter_spec.rb
index 3c488820853..e5809ac6949 100644
--- a/spec/lib/banzai/filter/references/merge_request_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/references/merge_request_reference_filter_spec.rb
@@ -51,6 +51,7 @@ RSpec.describe Banzai::Filter::References::MergeRequestReferenceFilter do
context 'internal reference' do
let(:reference) { merge.to_reference }
+ let(:merge_request_url) { urls.project_merge_request_url(project, merge) }
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
@@ -115,14 +116,16 @@ RSpec.describe Banzai::Filter::References::MergeRequestReferenceFilter do
expect(link).to have_attribute('data-reference-format')
expect(link.attr('data-reference-format')).to eq('+')
+ expect(link.attr('href')).to eq(merge_request_url)
end
it 'includes a data-reference-format attribute for URL references' do
- doc = reference_filter("Merge #{urls.project_merge_request_url(project, merge)}+")
+ doc = reference_filter("Merge #{merge_request_url}+")
link = doc.css('a').first
expect(link).to have_attribute('data-reference-format')
expect(link.attr('data-reference-format')).to eq('+')
+ expect(link.attr('href')).to eq(merge_request_url)
end
it 'supports an :only_path context' do
diff --git a/spec/lib/banzai/filter/sanitization_filter_spec.rb b/spec/lib/banzai/filter/sanitization_filter_spec.rb
index 24e787bddd5..039ca36af6e 100644
--- a/spec/lib/banzai/filter/sanitization_filter_spec.rb
+++ b/spec/lib/banzai/filter/sanitization_filter_spec.rb
@@ -177,53 +177,6 @@ RSpec.describe Banzai::Filter::SanitizationFilter do
expect(act.to_html).to eq exp
end
end
-
- context 'using ruby-based HTML renderer' do
- before do
- stub_feature_flags(use_cmark_renderer: false)
- end
-
- it 'allows correct footnote id property on links' do
- exp = %q(<a href="#fn1" id="fnref1">foo/bar.md</a>)
- act = filter(exp)
-
- expect(act.to_html).to eq exp
- end
-
- it 'allows correct footnote id property on li element' do
- exp = %q(<ol><li id="fn1">footnote</li></ol>)
- act = filter(exp)
-
- expect(act.to_html).to eq exp
- end
-
- it 'removes invalid id for footnote links' do
- exp = %q(<a href="#fn1">link</a>)
-
- %w[fnrefx test xfnref1].each do |id|
- act = filter(%(<a href="#fn1" id="#{id}">link</a>))
-
- expect(act.to_html).to eq exp
- end
- end
-
- it 'removes invalid id for footnote li' do
- exp = %q(<ol><li>footnote</li></ol>)
-
- %w[fnx test xfn1].each do |id|
- act = filter(%(<ol><li id="#{id}">footnote</li></ol>))
-
- expect(act.to_html).to eq exp
- end
- end
-
- it 'allows footnotes numbered higher than 9' do
- exp = %q(<a href="#fn15" id="fnref15">link</a><ol><li id="fn15">footnote</li></ol>)
- act = filter(exp)
-
- expect(act.to_html).to eq exp
- end
- end
end
end
end
diff --git a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
index ef46fd62486..aee4bd93207 100644
--- a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
+++ b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
@@ -19,202 +19,150 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
end
end
- shared_examples_for 'renders correct markdown' do
- context "when no language is specified" do
- it "highlights as plaintext" do
- result = filter('<pre><code>def fun end</code></pre>')
+ context "when no language is specified" do
+ it "highlights as plaintext" do
+ result = filter('<pre><code>def fun end</code></pre>')
- expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">def fun end</span></code></pre><copy-code></copy-code></div>')
- end
-
- include_examples "XSS prevention", ""
+ expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">def fun end</span></code></pre><copy-code></copy-code></div>')
end
- context "when contains mermaid diagrams" do
- it "ignores mermaid blocks" do
- result = filter('<pre data-mermaid-style="display"><code>mermaid code</code></pre>')
+ include_examples "XSS prevention", ""
+ end
- expect(result.to_html).to eq('<pre data-mermaid-style="display"><code>mermaid code</code></pre>')
- end
+ context "when contains mermaid diagrams" do
+ it "ignores mermaid blocks" do
+ result = filter('<pre data-mermaid-style="display"><code>mermaid code</code></pre>')
+
+ expect(result.to_html).to eq('<pre data-mermaid-style="display"><code>mermaid code</code></pre>')
end
+ end
- context "when a valid language is specified" do
- it "highlights as that language" do
- result = if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- filter('<pre lang="ruby"><code>def fun end</code></pre>')
- else
- filter('<pre><code lang="ruby">def fun end</code></pre>')
- end
+ context "when <pre> contains multiple <code> tags" do
+ it "ignores the block" do
+ result = filter('<pre><code>one</code> and <code>two</code></pre>')
- expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-ruby" lang="ruby" v-pre="true"><code><span id="LC1" class="line" lang="ruby"><span class="k">def</span> <span class="nf">fun</span> <span class="k">end</span></span></code></pre><copy-code></copy-code></div>')
- end
+ expect(result.to_html).to eq('<pre><code>one</code> and <code>two</code></pre>')
+ end
+ end
- include_examples "XSS prevention", "ruby"
+ context "when a valid language is specified" do
+ it "highlights as that language" do
+ result = filter('<pre lang="ruby"><code>def fun end</code></pre>')
+
+ expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-ruby" lang="ruby" v-pre="true"><code><span id="LC1" class="line" lang="ruby"><span class="k">def</span> <span class="nf">fun</span> <span class="k">end</span></span></code></pre><copy-code></copy-code></div>')
end
- context "when an invalid language is specified" do
- it "highlights as plaintext" do
- result = if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- filter('<pre lang="gnuplot"><code>This is a test</code></pre>')
- else
- filter('<pre><code lang="gnuplot">This is a test</code></pre>')
- end
+ include_examples "XSS prevention", "ruby"
+ end
- expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">This is a test</span></code></pre><copy-code></copy-code></div>')
- end
+ context "when an invalid language is specified" do
+ it "highlights as plaintext" do
+ result = filter('<pre lang="gnuplot"><code>This is a test</code></pre>')
- include_examples "XSS prevention", "gnuplot"
+ expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">This is a test</span></code></pre><copy-code></copy-code></div>')
end
- context "languages that should be passed through" do
- let(:delimiter) { described_class::LANG_PARAMS_DELIMITER }
- let(:data_attr) { described_class::LANG_PARAMS_ATTR }
+ include_examples "XSS prevention", "gnuplot"
+ end
- %w(math mermaid plantuml suggestion).each do |lang|
- context "when #{lang} is specified" do
- it "highlights as plaintext but with the correct language attribute and class" do
- result = if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- filter(%{<pre lang="#{lang}"><code>This is a test</code></pre>})
- else
- filter(%{<pre><code lang="#{lang}">This is a test</code></pre>})
- end
+ context "languages that should be passed through" do
+ let(:delimiter) { described_class::LANG_PARAMS_DELIMITER }
+ let(:data_attr) { described_class::LANG_PARAMS_ATTR }
- expect(result.to_html.delete("\n")).to eq(%{<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre><copy-code></copy-code></div>})
- end
+ %w(math mermaid plantuml suggestion).each do |lang|
+ context "when #{lang} is specified" do
+ it "highlights as plaintext but with the correct language attribute and class" do
+ result = filter(%{<pre lang="#{lang}"><code>This is a test</code></pre>})
- include_examples "XSS prevention", lang
+ expect(result.to_html.delete("\n")).to eq(%{<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre><copy-code></copy-code></div>})
end
- context "when #{lang} has extra params" do
- let(:lang_params) { 'foo-bar-kux' }
-
- let(:xss_lang) do
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- "#{lang} data-meta=\"foo-bar-kux\"&lt;script&gt;alert(1)&lt;/script&gt;"
- else
- "#{lang}#{described_class::LANG_PARAMS_DELIMITER}&lt;script&gt;alert(1)&lt;/script&gt;"
- end
- end
-
- it "includes data-lang-params tag with extra information" do
- result = if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- filter(%{<pre lang="#{lang}" data-meta="#{lang_params}"><code>This is a test</code></pre>})
- else
- filter(%{<pre><code lang="#{lang}#{delimiter}#{lang_params}">This is a test</code></pre>})
- end
-
- expect(result.to_html.delete("\n")).to eq(%{<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" #{data_attr}="#{lang_params}" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre><copy-code></copy-code></div>})
- end
-
- include_examples "XSS prevention", lang
-
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- include_examples "XSS prevention",
- "#{lang} data-meta=\"foo-bar-kux\"&lt;script&gt;alert(1)&lt;/script&gt;"
- else
- include_examples "XSS prevention",
- "#{lang}#{described_class::LANG_PARAMS_DELIMITER}&lt;script&gt;alert(1)&lt;/script&gt;"
- end
-
- include_examples "XSS prevention",
- "#{lang} data-meta=\"foo-bar-kux\"<script>alert(1)</script>"
- end
+ include_examples "XSS prevention", lang
end
- context 'when multiple param delimiters are used' do
- let(:lang) { 'suggestion' }
- let(:lang_params) { '-1+10' }
+ context "when #{lang} has extra params" do
+ let(:lang_params) { 'foo-bar-kux' }
+ let(:xss_lang) { "#{lang} data-meta=\"foo-bar-kux\"&lt;script&gt;alert(1)&lt;/script&gt;" }
- let(:expected_result) do
- %{<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" #{data_attr}="#{lang_params} more-things" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre><copy-code></copy-code></div>}
- end
-
- context 'when delimiter is space' do
- it 'delimits on the first appearance' do
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- result = filter(%{<pre lang="#{lang}" data-meta="#{lang_params} more-things"><code>This is a test</code></pre>})
+ it "includes data-lang-params tag with extra information" do
+ result = filter(%{<pre lang="#{lang}" data-meta="#{lang_params}"><code>This is a test</code></pre>})
- expect(result.to_html.delete("\n")).to eq(expected_result)
- else
- result = filter(%{<pre><code lang="#{lang}#{delimiter}#{lang_params}#{delimiter}more-things">This is a test</code></pre>})
-
- expect(result.to_html.delete("\n")).to eq(%{<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" #{data_attr}="#{lang_params}#{delimiter}more-things" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre><copy-code></copy-code></div>})
- end
- end
+ expect(result.to_html.delete("\n")).to eq(%{<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" #{data_attr}="#{lang_params}" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre><copy-code></copy-code></div>})
end
- context 'when delimiter is colon' do
- it 'delimits on the first appearance' do
- result = filter(%{<pre lang="#{lang}#{delimiter}#{lang_params} more-things"><code>This is a test</code></pre>})
+ include_examples "XSS prevention", lang
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- expect(result.to_html.delete("\n")).to eq(expected_result)
- else
- expect(result.to_html.delete("\n")).to eq(%{<div class="gl-relative markdown-code-block js-markdown-code"><pre class=\"code highlight js-syntax-highlight language-plaintext\" lang=\"plaintext\" v-pre=\"true\"><code><span id=\"LC1\" class=\"line\" lang=\"plaintext\">This is a test</span></code></pre><copy-code></copy-code></div>})
- end
- end
- end
+ include_examples "XSS prevention",
+ "#{lang} data-meta=\"foo-bar-kux\"&lt;script&gt;alert(1)&lt;/script&gt;"
+
+ include_examples "XSS prevention",
+ "#{lang} data-meta=\"foo-bar-kux\"<script>alert(1)</script>"
end
end
- context "when sourcepos metadata is available" do
- it "includes it in the highlighted code block" do
- result = filter('<pre data-sourcepos="1:1-3:3"><code lang="plaintext">This is a test</code></pre>')
+ context 'when multiple param delimiters are used' do
+ let(:lang) { 'suggestion' }
+ let(:lang_params) { '-1+10' }
- expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre data-sourcepos="1:1-3:3" class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">This is a test</span></code></pre><copy-code></copy-code></div>')
+ let(:expected_result) do
+ %{<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" #{data_attr}="#{lang_params} more-things" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre><copy-code></copy-code></div>}
end
- end
- context "when Rouge lexing fails" do
- before do
- allow_next_instance_of(Rouge::Lexers::Ruby) do |instance|
- allow(instance).to receive(:stream_tokens).and_raise(StandardError)
+ context 'when delimiter is space' do
+ it 'delimits on the first appearance' do
+ result = filter(%{<pre lang="#{lang}" data-meta="#{lang_params} more-things"><code>This is a test</code></pre>})
+
+ expect(result.to_html.delete("\n")).to eq(expected_result)
end
end
- it "highlights as plaintext" do
- result = if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- filter('<pre lang="ruby"><code>This is a test</code></pre>')
- else
- filter('<pre><code lang="ruby">This is a test</code></pre>')
- end
+ context 'when delimiter is colon' do
+ it 'delimits on the first appearance' do
+ result = filter(%{<pre lang="#{lang}#{delimiter}#{lang_params} more-things"><code>This is a test</code></pre>})
- expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight" lang="" v-pre="true"><code><span id="LC1" class="line" lang="">This is a test</span></code></pre><copy-code></copy-code></div>')
+ expect(result.to_html.delete("\n")).to eq(expected_result)
+ end
end
-
- include_examples "XSS prevention", "ruby"
end
+ end
- context "when Rouge lexing fails after a retry" do
- before do
- allow_next_instance_of(Rouge::Lexers::PlainText) do |instance|
- allow(instance).to receive(:stream_tokens).and_raise(StandardError)
- end
- end
+ context "when sourcepos metadata is available" do
+ it "includes it in the highlighted code block" do
+ result = filter('<pre data-sourcepos="1:1-3:3"><code lang="plaintext">This is a test</code></pre>')
- it "does not add highlighting classes" do
- result = filter('<pre><code>This is a test</code></pre>')
+ expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre data-sourcepos="1:1-3:3" class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">This is a test</span></code></pre><copy-code></copy-code></div>')
+ end
+ end
- expect(result.to_html).to eq('<pre><code>This is a test</code></pre>')
+ context "when Rouge lexing fails" do
+ before do
+ allow_next_instance_of(Rouge::Lexers::Ruby) do |instance|
+ allow(instance).to receive(:stream_tokens).and_raise(StandardError)
end
+ end
+
+ it "highlights as plaintext" do
+ result = filter('<pre lang="ruby"><code>This is a test</code></pre>')
- include_examples "XSS prevention", "ruby"
+ expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight" lang="" v-pre="true"><code><span id="LC1" class="line" lang="">This is a test</span></code></pre><copy-code></copy-code></div>')
end
+
+ include_examples "XSS prevention", "ruby"
end
- context 'using ruby-based HTML renderer' do
+ context "when Rouge lexing fails after a retry" do
before do
- stub_feature_flags(use_cmark_renderer: false)
+ allow_next_instance_of(Rouge::Lexers::PlainText) do |instance|
+ allow(instance).to receive(:stream_tokens).and_raise(StandardError)
+ end
end
- it_behaves_like 'renders correct markdown'
- end
+ it "does not add highlighting classes" do
+ result = filter('<pre><code>This is a test</code></pre>')
- context 'using c-based HTML renderer' do
- before do
- stub_feature_flags(use_cmark_renderer: true)
+ expect(result.to_html).to eq('<pre><code>This is a test</code></pre>')
end
- it_behaves_like 'renders correct markdown'
+ include_examples "XSS prevention", "ruby"
end
end
diff --git a/spec/lib/banzai/pipeline/full_pipeline_spec.rb b/spec/lib/banzai/pipeline/full_pipeline_spec.rb
index 620b7d97a5b..376edfb99fc 100644
--- a/spec/lib/banzai/pipeline/full_pipeline_spec.rb
+++ b/spec/lib/banzai/pipeline/full_pipeline_spec.rb
@@ -65,47 +65,6 @@ RSpec.describe Banzai::Pipeline::FullPipeline do
expect(html.lines.map(&:strip).join("\n")).to eq filtered_footnote.strip
end
-
- context 'using ruby-based HTML renderer' do
- let(:html) { described_class.to_html(footnote_markdown, project: project) }
- let(:identifier) { html[/.*fnref1-(\d+).*/, 1] }
- let(:footnote_markdown) do
- <<~EOF
- first[^1] and second[^second] and twenty[^twenty]
- [^1]: one
- [^second]: two
- [^twenty]: twenty
- EOF
- end
-
- let(:filtered_footnote) do
- <<~EOF
- <p dir="auto">first<sup class="footnote-ref"><a href="#fn1-#{identifier}" id="fnref1-#{identifier}">1</a></sup> and second<sup class="footnote-ref"><a href="#fn2-#{identifier}" id="fnref2-#{identifier}">2</a></sup> and twenty<sup class="footnote-ref"><a href="#fn3-#{identifier}" id="fnref3-#{identifier}">3</a></sup></p>
-
- <section class="footnotes"><ol>
- <li id="fn1-#{identifier}">
- <p>one <a href="#fnref1-#{identifier}" class="footnote-backref"><gl-emoji title="leftwards arrow with hook" data-name="leftwards_arrow_with_hook" data-unicode-version="1.1">↩</gl-emoji></a></p>
- </li>
- <li id="fn2-#{identifier}">
- <p>two <a href="#fnref2-#{identifier}" class="footnote-backref"><gl-emoji title="leftwards arrow with hook" data-name="leftwards_arrow_with_hook" data-unicode-version="1.1">↩</gl-emoji></a></p>
- </li>
- <li id="fn3-#{identifier}">
- <p>twenty <a href="#fnref3-#{identifier}" class="footnote-backref"><gl-emoji title="leftwards arrow with hook" data-name="leftwards_arrow_with_hook" data-unicode-version="1.1">↩</gl-emoji></a></p>
- </li>
- </ol></section>
- EOF
- end
-
- before do
- stub_feature_flags(use_cmark_renderer: false)
- end
-
- it 'properly adds the necessary ids and classes' do
- stub_commonmark_sourcepos_disabled
-
- expect(html.lines.map(&:strip).join("\n")).to eq filtered_footnote
- end
- end
end
describe 'links are detected as malicious' do
diff --git a/spec/lib/banzai/pipeline/plain_markdown_pipeline_spec.rb b/spec/lib/banzai/pipeline/plain_markdown_pipeline_spec.rb
index c8cd9d4fcac..80392fe264f 100644
--- a/spec/lib/banzai/pipeline/plain_markdown_pipeline_spec.rb
+++ b/spec/lib/banzai/pipeline/plain_markdown_pipeline_spec.rb
@@ -5,117 +5,93 @@ require 'spec_helper'
RSpec.describe Banzai::Pipeline::PlainMarkdownPipeline do
using RSpec::Parameterized::TableSyntax
- shared_examples_for 'renders correct markdown' do
- describe 'CommonMark tests', :aggregate_failures do
- it 'converts all reference punctuation to literals' do
- reference_chars = Banzai::Filter::MarkdownPreEscapeFilter::REFERENCE_CHARACTERS
- markdown = reference_chars.split('').map {|char| char.prepend("\\") }.join
- punctuation = Banzai::Filter::MarkdownPreEscapeFilter::REFERENCE_CHARACTERS.split('')
- punctuation = punctuation.delete_if {|char| char == '&' }
- punctuation << '&amp;'
-
- result = described_class.call(markdown, project: project)
- output = result[:output].to_html
-
- punctuation.each { |char| expect(output).to include("<span>#{char}</span>") }
- expect(result[:escaped_literals]).to be_truthy
- end
+ describe 'backslash escapes', :aggregate_failures do
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:issue) { create(:issue, project: project) }
- it 'ensure we handle all the GitLab reference characters', :eager_load do
- reference_chars = ObjectSpace.each_object(Class).map do |klass|
- next unless klass.included_modules.include?(Referable)
- next unless klass.respond_to?(:reference_prefix)
- next unless klass.reference_prefix.length == 1
+ it 'converts all reference punctuation to literals' do
+ reference_chars = Banzai::Filter::MarkdownPreEscapeFilter::REFERENCE_CHARACTERS
+ markdown = reference_chars.split('').map {|char| char.prepend("\\") }.join
+ punctuation = Banzai::Filter::MarkdownPreEscapeFilter::REFERENCE_CHARACTERS.split('')
+ punctuation = punctuation.delete_if {|char| char == '&' }
+ punctuation << '&amp;'
- klass.reference_prefix
- end.compact
+ result = described_class.call(markdown, project: project)
+ output = result[:output].to_html
- reference_chars.all? do |char|
- Banzai::Filter::MarkdownPreEscapeFilter::REFERENCE_CHARACTERS.include?(char)
- end
- end
+ punctuation.each { |char| expect(output).to include("<span>#{char}</span>") }
+ expect(result[:escaped_literals]).to be_truthy
+ end
- it 'does not convert non-reference punctuation to spans' do
- markdown = %q(\"\'\*\+\,\-\.\/\:\;\<\=\>\?\[\]\_\`\{\|\}) + %q[\(\)\\\\]
+ it 'ensure we handle all the GitLab reference characters', :eager_load do
+ reference_chars = ObjectSpace.each_object(Class).map do |klass|
+ next unless klass.included_modules.include?(Referable)
+ next unless klass.respond_to?(:reference_prefix)
+ next unless klass.reference_prefix.length == 1
- result = described_class.call(markdown, project: project)
- output = result[:output].to_html
+ klass.reference_prefix
+ end.compact
- expect(output).not_to include('<span>')
- expect(result[:escaped_literals]).to be_falsey
+ reference_chars.all? do |char|
+ Banzai::Filter::MarkdownPreEscapeFilter::REFERENCE_CHARACTERS.include?(char)
end
+ end
- it 'does not convert other characters to literals' do
- markdown = %q(\→\A\a\ \3\φ\«)
- expected = '\→\A\a\ \3\φ\«'
-
- result = correct_html_included(markdown, expected)
- expect(result[:escaped_literals]).to be_falsey
- end
+ it 'does not convert non-reference punctuation to spans' do
+ markdown = %q(\"\'\*\+\,\-\.\/\:\;\<\=\>\?\[\]\_\`\{\|\}) + %q[\(\)\\\\]
- describe 'backslash escapes do not work in code blocks, code spans, autolinks, or raw HTML' do
- where(:markdown, :expected) do
- %q(`` \@\! ``) | %q(<code>\@\!</code>)
- %q( \@\!) | %Q(<code>\\@\\!\n</code>)
- %Q(~~~\n\\@\\!\n~~~) | %Q(<code>\\@\\!\n</code>)
- %q(<http://example.com?find=\@>) | %q(<a href="http://example.com?find=%5C@">http://example.com?find=\@</a>)
- %q[<a href="/bar\@)">] | %q[<a href="/bar%5C@)">]
- end
-
- with_them do
- it { correct_html_included(markdown, expected) }
- end
- end
+ result = described_class.call(markdown, project: project)
+ output = result[:output].to_html
- describe 'work in all other contexts, including URLs and link titles, link references, and info strings in fenced code blocks' do
- let(:markdown) { %Q(``` foo\\@bar\nfoo\n```) }
-
- it 'renders correct html' do
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- correct_html_included(markdown, %Q(<pre data-sourcepos="1:1-3:3" lang="foo@bar"><code>foo\n</code></pre>))
- else
- correct_html_included(markdown, %Q(<code lang="foo@bar">foo\n</code>))
- end
- end
-
- where(:markdown, :expected) do
- %q![foo](/bar\@ "\@title")! | %q(<a href="/bar@" title="@title">foo</a>)
- %Q![foo]\n\n[foo]: /bar\\@ "\\@title"! | %q(<a href="/bar@" title="@title">foo</a>)
- end
-
- with_them do
- it { correct_html_included(markdown, expected) }
- end
- end
+ expect(output).not_to include('<span>')
+ expect(result[:escaped_literals]).to be_falsey
end
- end
-
- describe 'backslash escapes' do
- let_it_be(:project) { create(:project, :public) }
- let_it_be(:issue) { create(:issue, project: project) }
-
- def correct_html_included(markdown, expected)
- result = described_class.call(markdown, {})
- expect(result[:output].to_html).to include(expected)
+ it 'does not convert other characters to literals' do
+ markdown = %q(\→\A\a\ \3\φ\«)
+ expected = '\→\A\a\ \3\φ\«'
- result
+ result = correct_html_included(markdown, expected)
+ expect(result[:escaped_literals]).to be_falsey
end
- context 'using ruby-based HTML renderer' do
- before do
- stub_feature_flags(use_cmark_renderer: false)
+ describe 'backslash escapes do not work in code blocks, code spans, autolinks, or raw HTML' do
+ where(:markdown, :expected) do
+ %q(`` \@\! ``) | %q(<code>\@\!</code>)
+ %q( \@\!) | %Q(<code>\\@\\!\n</code>)
+ %Q(~~~\n\\@\\!\n~~~) | %Q(<code>\\@\\!\n</code>)
+ %q(<http://example.com?find=\@>) | %q(<a href="http://example.com?find=%5C@">http://example.com?find=\@</a>)
+ %q[<a href="/bar\@)">] | %q[<a href="/bar%5C@)">]
end
- it_behaves_like 'renders correct markdown'
+ with_them do
+ it { correct_html_included(markdown, expected) }
+ end
end
- context 'using c-based HTML renderer' do
- before do
- stub_feature_flags(use_cmark_renderer: true)
+ describe 'work in all other contexts, including URLs and link titles, link references, and info strings in fenced code blocks' do
+ let(:markdown) { %Q(``` foo\\@bar\nfoo\n```) }
+
+ it 'renders correct html' do
+ correct_html_included(markdown, %Q(<pre data-sourcepos="1:1-3:3" lang="foo@bar"><code>foo\n</code></pre>))
+ end
+
+ where(:markdown, :expected) do
+ %q![foo](/bar\@ "\@title")! | %q(<a href="/bar@" title="@title">foo</a>)
+ %Q![foo]\n\n[foo]: /bar\\@ "\\@title"! | %q(<a href="/bar@" title="@title">foo</a>)
end
- it_behaves_like 'renders correct markdown'
+ with_them do
+ it { correct_html_included(markdown, expected) }
+ end
end
end
+
+ def correct_html_included(markdown, expected)
+ result = described_class.call(markdown, {})
+
+ expect(result[:output].to_html).to include(expected)
+
+ result
+ end
end
diff --git a/spec/lib/banzai/reference_parser/merge_request_parser_spec.rb b/spec/lib/banzai/reference_parser/merge_request_parser_spec.rb
index 04c35c8b082..3fbda7f3239 100644
--- a/spec/lib/banzai/reference_parser/merge_request_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/merge_request_parser_spec.rb
@@ -23,14 +23,6 @@ RSpec.describe Banzai::ReferenceParser::MergeRequestParser do
end
it_behaves_like "referenced feature visibility", "merge_requests"
-
- context 'when optimize_merge_request_parser feature flag is off' do
- before do
- stub_feature_flags(optimize_merge_request_parser: false)
- end
-
- it_behaves_like "referenced feature visibility", "merge_requests"
- end
end
end
diff --git a/spec/lib/bulk_imports/common/extractors/ndjson_extractor_spec.rb b/spec/lib/bulk_imports/common/extractors/ndjson_extractor_spec.rb
index bd306233de8..d6e19a5fc85 100644
--- a/spec/lib/bulk_imports/common/extractors/ndjson_extractor_spec.rb
+++ b/spec/lib/bulk_imports/common/extractors/ndjson_extractor_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe BulkImports::Common::Extractors::NdjsonExtractor do
before do
allow(FileUtils).to receive(:remove_entry).with(any_args).and_call_original
- subject.instance_variable_set(:@tmp_dir, tmpdir)
+ subject.instance_variable_set(:@tmpdir, tmpdir)
end
after(:all) do
@@ -43,11 +43,11 @@ RSpec.describe BulkImports::Common::Extractors::NdjsonExtractor do
end
end
- describe '#remove_tmp_dir' do
+ describe '#remove_tmpdir' do
it 'removes tmp dir' do
expect(FileUtils).to receive(:remove_entry).with(tmpdir).once
- subject.remove_tmp_dir
+ subject.remove_tmpdir
end
end
end
diff --git a/spec/lib/bulk_imports/common/pipelines/uploads_pipeline_spec.rb b/spec/lib/bulk_imports/common/pipelines/uploads_pipeline_spec.rb
index 3b5ea131d0d..9d43bb3ebfb 100644
--- a/spec/lib/bulk_imports/common/pipelines/uploads_pipeline_spec.rb
+++ b/spec/lib/bulk_imports/common/pipelines/uploads_pipeline_spec.rb
@@ -3,10 +3,10 @@
require 'spec_helper'
RSpec.describe BulkImports::Common::Pipelines::UploadsPipeline do
- let_it_be(:tmpdir) { Dir.mktmpdir }
let_it_be(:project) { create(:project) }
let_it_be(:group) { create(:group) }
+ let(:tmpdir) { Dir.mktmpdir }
let(:uploads_dir_path) { File.join(tmpdir, '72a497a02fe3ee09edae2ed06d390038') }
let(:upload_file_path) { File.join(uploads_dir_path, 'upload.txt')}
let(:tracker) { create(:bulk_import_tracker, entity: entity) }
@@ -80,10 +80,10 @@ RSpec.describe BulkImports::Common::Pipelines::UploadsPipeline do
.with(
configuration: context.configuration,
relative_url: "/#{entity.pluralized_name}/test/export_relations/download?relation=uploads",
- dir: tmpdir,
+ tmpdir: tmpdir,
filename: 'uploads.tar.gz')
.and_return(download_service)
- expect(BulkImports::FileDecompressionService).to receive(:new).with(dir: tmpdir, filename: 'uploads.tar.gz').and_return(decompression_service)
+ expect(BulkImports::FileDecompressionService).to receive(:new).with(tmpdir: tmpdir, filename: 'uploads.tar.gz').and_return(decompression_service)
expect(BulkImports::ArchiveExtractionService).to receive(:new).with(tmpdir: tmpdir, filename: 'uploads.tar').and_return(extraction_service)
expect(download_service).to receive(:execute)
@@ -123,6 +123,31 @@ RSpec.describe BulkImports::Common::Pipelines::UploadsPipeline do
end
end
end
+
+ describe '#after_run' do
+ before do
+ allow(Dir).to receive(:mktmpdir).with('bulk_imports').and_return(tmpdir)
+ end
+
+ it 'removes tmp dir' do
+ allow(FileUtils).to receive(:remove_entry).and_call_original
+ expect(FileUtils).to receive(:remove_entry).with(tmpdir).and_call_original
+
+ pipeline.after_run(nil)
+
+ expect(Dir.exist?(tmpdir)).to eq(false)
+ end
+
+ context 'when dir does not exist' do
+ it 'does not attempt to remove tmpdir' do
+ FileUtils.remove_entry(tmpdir)
+
+ expect(FileUtils).not_to receive(:remove_entry).with(tmpdir)
+
+ pipeline.after_run(nil)
+ end
+ end
+ end
end
context 'when importing to group' do
diff --git a/spec/lib/bulk_imports/projects/pipelines/project_attributes_pipeline_spec.rb b/spec/lib/bulk_imports/projects/pipelines/project_attributes_pipeline_spec.rb
index 11c475318bb..df7ff5b8062 100644
--- a/spec/lib/bulk_imports/projects/pipelines/project_attributes_pipeline_spec.rb
+++ b/spec/lib/bulk_imports/projects/pipelines/project_attributes_pipeline_spec.rb
@@ -56,7 +56,7 @@ RSpec.describe BulkImports::Projects::Pipelines::ProjectAttributesPipeline do
subject(:pipeline) { described_class.new(context) }
before do
- allow(Dir).to receive(:mktmpdir).and_return(tmpdir)
+ allow(Dir).to receive(:mktmpdir).with('bulk_imports').and_return(tmpdir)
end
after do
@@ -95,13 +95,13 @@ RSpec.describe BulkImports::Projects::Pipelines::ProjectAttributesPipeline do
.with(
configuration: context.configuration,
relative_url: "/#{entity.pluralized_name}/#{entity.source_full_path}/export_relations/download?relation=self",
- dir: tmpdir,
+ tmpdir: tmpdir,
filename: 'self.json.gz')
.and_return(file_download_service)
expect(BulkImports::FileDecompressionService)
.to receive(:new)
- .with(dir: tmpdir, filename: 'self.json.gz')
+ .with(tmpdir: tmpdir, filename: 'self.json.gz')
.and_return(file_decompression_service)
expect(file_download_service).to receive(:execute)
@@ -156,4 +156,25 @@ RSpec.describe BulkImports::Projects::Pipelines::ProjectAttributesPipeline do
pipeline.json_attributes
end
end
+
+ describe '#after_run' do
+ it 'removes tmp dir' do
+ allow(FileUtils).to receive(:remove_entry).and_call_original
+ expect(FileUtils).to receive(:remove_entry).with(tmpdir).and_call_original
+
+ pipeline.after_run(nil)
+
+ expect(Dir.exist?(tmpdir)).to eq(false)
+ end
+
+ context 'when dir does not exist' do
+ it 'does not attempt to remove tmpdir' do
+ FileUtils.remove_entry(tmpdir)
+
+ expect(FileUtils).not_to receive(:remove_entry).with(tmpdir)
+
+ pipeline.after_run(nil)
+ end
+ end
+ end
end
diff --git a/spec/lib/error_tracking/collector/payload_validator_spec.rb b/spec/lib/error_tracking/collector/payload_validator_spec.rb
index ab5ec448dff..94708f63bf4 100644
--- a/spec/lib/error_tracking/collector/payload_validator_spec.rb
+++ b/spec/lib/error_tracking/collector/payload_validator_spec.rb
@@ -18,37 +18,25 @@ RSpec.describe ErrorTracking::Collector::PayloadValidator do
end
end
- context 'ruby payload' do
- let(:payload) { Gitlab::Json.parse(fixture_file('error_tracking/parsed_event.json')) }
-
- it_behaves_like 'valid payload'
- end
-
- context 'python payload' do
- let(:payload) { Gitlab::Json.parse(fixture_file('error_tracking/python_event.json')) }
-
- it_behaves_like 'valid payload'
- end
-
- context 'python payload in repl' do
- let(:payload) { Gitlab::Json.parse(fixture_file('error_tracking/python_event_repl.json')) }
-
- it_behaves_like 'valid payload'
- end
+ context 'with event fixtures' do
+ where(:event_fixture) do
+ Dir.glob(Rails.root.join('spec/fixtures/error_tracking/*event*.json'))
+ end
- context 'browser payload' do
- let(:payload) { Gitlab::Json.parse(fixture_file('error_tracking/browser_event.json')) }
+ with_them do
+ let(:payload) { Gitlab::Json.parse(fixture_file(event_fixture)) }
- it_behaves_like 'valid payload'
+ it_behaves_like 'valid payload'
+ end
end
- context 'empty payload' do
+ context 'when empty' do
let(:payload) { '' }
it_behaves_like 'invalid payload'
end
- context 'invalid payload' do
+ context 'when invalid' do
let(:payload) { { 'foo' => 'bar' } }
it_behaves_like 'invalid payload'
diff --git a/spec/lib/feature_spec.rb b/spec/lib/feature_spec.rb
index 82580d5d700..8c546390201 100644
--- a/spec/lib/feature_spec.rb
+++ b/spec/lib/feature_spec.rb
@@ -3,12 +3,40 @@
require 'spec_helper'
RSpec.describe Feature, stub_feature_flags: false do
+ include StubVersion
+
before do
# reset Flipper AR-engine
Feature.reset
skip_feature_flags_yaml_validation
end
+ describe '.feature_flags_available?' do
+ it 'returns false on connection error' do
+ expect(ActiveRecord::Base.connection).to receive(:active?).and_raise(PG::ConnectionBad) # rubocop:disable Database/MultipleDatabases
+
+ expect(described_class.feature_flags_available?).to eq(false)
+ end
+
+ it 'returns false when connection is not active' do
+ expect(ActiveRecord::Base.connection).to receive(:active?).and_return(false) # rubocop:disable Database/MultipleDatabases
+
+ expect(described_class.feature_flags_available?).to eq(false)
+ end
+
+ it 'returns false when the flipper table does not exist' do
+ expect(Feature::FlipperFeature).to receive(:table_exists?).and_return(false)
+
+ expect(described_class.feature_flags_available?).to eq(false)
+ end
+
+ it 'returns false on NoDatabaseError' do
+ expect(Feature::FlipperFeature).to receive(:table_exists?).and_raise(ActiveRecord::NoDatabaseError)
+
+ expect(described_class.feature_flags_available?).to eq(false)
+ end
+ end
+
describe '.get' do
let(:feature) { double(:feature) }
let(:key) { 'my_feature' }
@@ -585,6 +613,10 @@ RSpec.describe Feature, stub_feature_flags: false do
context 'when flag is new and not feature_flag_state_logs' do
let(:milestone) { "14.6" }
+ before do
+ stub_version('14.5.123', 'deadbeef')
+ end
+
it { is_expected.to be_truthy }
end
diff --git a/spec/lib/gitlab/asciidoc_spec.rb b/spec/lib/gitlab/asciidoc_spec.rb
index 7200ff3c4db..44bbbe49cd3 100644
--- a/spec/lib/gitlab/asciidoc_spec.rb
+++ b/spec/lib/gitlab/asciidoc_spec.rb
@@ -11,13 +11,27 @@ module Gitlab
allow_any_instance_of(ApplicationSetting).to receive(:current).and_return(::ApplicationSetting.create_from_defaults)
end
- shared_examples_for 'renders correct asciidoc' do
- context "without project" do
- let(:input) { '<b>ascii</b>' }
- let(:context) { {} }
- let(:html) { 'H<sub>2</sub>O' }
+ context "without project" do
+ let(:input) { '<b>ascii</b>' }
+ let(:context) { {} }
+ let(:html) { 'H<sub>2</sub>O' }
+
+ it "converts the input using Asciidoctor and default options" do
+ expected_asciidoc_opts = {
+ safe: :secure,
+ backend: :gitlab_html5,
+ attributes: described_class::DEFAULT_ADOC_ATTRS.merge({ "kroki-server-url" => nil }),
+ extensions: be_a(Proc)
+ }
+
+ expect(Asciidoctor).to receive(:convert)
+ .with(input, expected_asciidoc_opts).and_return(html)
+
+ expect(render(input, context)).to eq(html)
+ end
- it "converts the input using Asciidoctor and default options" do
+ context "with asciidoc_opts" do
+ it "merges the options with default ones" do
expected_asciidoc_opts = {
safe: :secure,
backend: :gitlab_html5,
@@ -28,845 +42,808 @@ module Gitlab
expect(Asciidoctor).to receive(:convert)
.with(input, expected_asciidoc_opts).and_return(html)
- expect(render(input, context)).to eq(html)
+ render(input, context)
end
+ end
- context "with asciidoc_opts" do
- it "merges the options with default ones" do
- expected_asciidoc_opts = {
- safe: :secure,
- backend: :gitlab_html5,
- attributes: described_class::DEFAULT_ADOC_ATTRS.merge({ "kroki-server-url" => nil }),
- extensions: be_a(Proc)
- }
+ context "with requested path" do
+ input = <<~ADOC
+ Document name: {docname}.
+ ADOC
+
+ it "ignores {docname} when not available" do
+ expect(render(input, {})).to include(input.strip)
+ end
+
+ [
+ ['/', '', 'root'],
+ ['README', 'README', 'just a filename'],
+ ['doc/api/', '', 'a directory'],
+ ['doc/api/README.adoc', 'README', 'a complete path']
+ ].each do |path, basename, desc|
+ it "sets {docname} for #{desc}" do
+ expect(render(input, { requested_path: path })).to include(": #{basename}.")
+ end
+ end
+ end
- expect(Asciidoctor).to receive(:convert)
- .with(input, expected_asciidoc_opts).and_return(html)
+ context "XSS" do
+ items = {
+ 'link with extra attribute' => {
+ input: 'link:mylink"onmouseover="alert(1)[Click Here]',
+ output: "<div>\n<p><a href=\"mylink\">Click Here</a></p>\n</div>"
+ },
+ 'link with unsafe scheme' => {
+ input: 'link:data://danger[Click Here]',
+ output: "<div>\n<p><a>Click Here</a></p>\n</div>"
+ },
+ 'image with onerror' => {
+ input: 'image:https://localhost.com/image.png[Alt text" onerror="alert(7)]',
+ output: "<div>\n<p><span><a class=\"no-attachment-icon\" href=\"https://localhost.com/image.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img src=\"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt='Alt text\" onerror=\"alert(7)' class=\"lazy\" data-src=\"https://localhost.com/image.png\"></a></span></p>\n</div>"
+ }
+ }
- render(input, context)
+ items.each do |name, data|
+ it "does not convert dangerous #{name} into HTML" do
+ expect(render(data[:input], context)).to include(data[:output])
end
end
- context "with requested path" do
+ # `stub_feature_flags method` runs AFTER declaration of `items` above.
+ # So the spec in its current implementation won't pass.
+ # Move this test back to the items hash when removing `use_cmark_renderer` feature flag.
+ it "does not convert dangerous fenced code with inline script into HTML" do
+ input = '```mypre"><script>alert(3)</script>'
+ output = "<div>\n<div>\n<div class=\"gl-relative markdown-code-block js-markdown-code\">\n<pre class=\"code highlight js-syntax-highlight language-plaintext\" lang=\"plaintext\" v-pre=\"true\"><code></code></pre>\n<copy-code></copy-code>\n</div>\n</div>\n</div>"
+
+ expect(render(input, context)).to include(output)
+ end
+
+ it 'does not allow locked attributes to be overridden' do
input = <<~ADOC
- Document name: {docname}.
+ {counter:max-include-depth:1234}
+ <|-- {max-include-depth}
ADOC
- it "ignores {docname} when not available" do
- expect(render(input, {})).to include(input.strip)
- end
+ expect(render(input, {})).not_to include('1234')
+ end
+ end
- [
- ['/', '', 'root'],
- ['README', 'README', 'just a filename'],
- ['doc/api/', '', 'a directory'],
- ['doc/api/README.adoc', 'README', 'a complete path']
- ].each do |path, basename, desc|
- it "sets {docname} for #{desc}" do
- expect(render(input, { requested_path: path })).to include(": #{basename}.")
- end
- end
+ context "images" do
+ it "does lazy load and link image" do
+ input = 'image:https://localhost.com/image.png[]'
+ output = "<div>\n<p><span><a class=\"no-attachment-icon\" href=\"https://localhost.com/image.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img src=\"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"image\" class=\"lazy\" data-src=\"https://localhost.com/image.png\"></a></span></p>\n</div>"
+ expect(render(input, context)).to include(output)
end
- context "XSS" do
- items = {
- 'link with extra attribute' => {
- input: 'link:mylink"onmouseover="alert(1)[Click Here]',
- output: "<div>\n<p><a href=\"mylink\">Click Here</a></p>\n</div>"
- },
- 'link with unsafe scheme' => {
- input: 'link:data://danger[Click Here]',
- output: "<div>\n<p><a>Click Here</a></p>\n</div>"
- },
- 'image with onerror' => {
- input: 'image:https://localhost.com/image.png[Alt text" onerror="alert(7)]',
- output: "<div>\n<p><span><a class=\"no-attachment-icon\" href=\"https://localhost.com/image.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img src=\"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt='Alt text\" onerror=\"alert(7)' class=\"lazy\" data-src=\"https://localhost.com/image.png\"></a></span></p>\n</div>"
- }
- }
+ it "does not automatically link image if link is explicitly defined" do
+ input = 'image:https://localhost.com/image.png[link=https://gitlab.com]'
+ output = "<div>\n<p><span><a href=\"https://gitlab.com\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"><img src=\"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"image\" class=\"lazy\" data-src=\"https://localhost.com/image.png\"></a></span></p>\n</div>"
+ expect(render(input, context)).to include(output)
+ end
+ end
- items.each do |name, data|
- it "does not convert dangerous #{name} into HTML" do
- expect(render(data[:input], context)).to include(data[:output])
- end
- end
+ context 'with admonition' do
+ it 'preserves classes' do
+ input = <<~ADOC
+ NOTE: An admonition paragraph, like this note, grabs the reader’s attention.
+ ADOC
- # `stub_feature_flags method` runs AFTER declaration of `items` above.
- # So the spec in its current implementation won't pass.
- # Move this test back to the items hash when removing `use_cmark_renderer` feature flag.
- it "does not convert dangerous fenced code with inline script into HTML" do
- input = '```mypre"><script>alert(3)</script>'
- output =
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- "<div>\n<div>\n<div class=\"gl-relative markdown-code-block js-markdown-code\">\n<pre class=\"code highlight js-syntax-highlight language-plaintext\" lang=\"plaintext\" v-pre=\"true\"><code></code></pre>\n<copy-code></copy-code>\n</div>\n</div>\n</div>"
- else
- "<div>\n<div>\n<div class=\"gl-relative markdown-code-block js-markdown-code\">\n<pre class=\"code highlight js-syntax-highlight language-plaintext\" lang=\"plaintext\" v-pre=\"true\"><code><span id=\"LC1\" class=\"line\" lang=\"plaintext\">\"&gt;</span></code></pre>\n<copy-code></copy-code>\n</div>\n</div>\n</div>"
- end
+ output = <<~HTML
+ <div class="admonitionblock">
+ <table>
+ <tr>
+ <td class="icon">
+ <i class="fa icon-note" title="Note"></i>
+ </td>
+ <td>
+ An admonition paragraph, like this note, grabs the reader’s attention.
+ </td>
+ </tr>
+ </table>
+ </div>
+ HTML
+
+ expect(render(input, context)).to include(output.strip)
+ end
+ end
- expect(render(input, context)).to include(output)
- end
+ context 'with passthrough' do
+ it 'removes non heading ids' do
+ input = <<~ADOC
+ ++++
+ <h2 id="foo">Title</h2>
+ ++++
+ ADOC
- it 'does not allow locked attributes to be overridden' do
- input = <<~ADOC
- {counter:max-include-depth:1234}
- <|-- {max-include-depth}
- ADOC
+ output = <<~HTML
+ <h2>Title</h2>
+ HTML
- expect(render(input, {})).not_to include('1234')
- end
+ expect(render(input, context)).to include(output.strip)
end
- context "images" do
- it "does lazy load and link image" do
- input = 'image:https://localhost.com/image.png[]'
- output = "<div>\n<p><span><a class=\"no-attachment-icon\" href=\"https://localhost.com/image.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img src=\"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"image\" class=\"lazy\" data-src=\"https://localhost.com/image.png\"></a></span></p>\n</div>"
- expect(render(input, context)).to include(output)
- end
+ it 'removes non footnote def ids' do
+ input = <<~ADOC
+ ++++
+ <div id="def">Footnote definition</div>
+ ++++
+ ADOC
- it "does not automatically link image if link is explicitly defined" do
- input = 'image:https://localhost.com/image.png[link=https://gitlab.com]'
- output = "<div>\n<p><span><a href=\"https://gitlab.com\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"><img src=\"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"image\" class=\"lazy\" data-src=\"https://localhost.com/image.png\"></a></span></p>\n</div>"
- expect(render(input, context)).to include(output)
- end
+ output = <<~HTML
+ <div>Footnote definition</div>
+ HTML
+
+ expect(render(input, context)).to include(output.strip)
end
- context 'with admonition' do
- it 'preserves classes' do
- input = <<~ADOC
- NOTE: An admonition paragraph, like this note, grabs the reader’s attention.
- ADOC
+ it 'removes non footnote ref ids' do
+ input = <<~ADOC
+ ++++
+ <a id="ref">Footnote reference</a>
+ ++++
+ ADOC
- output = <<~HTML
- <div class="admonitionblock">
- <table>
- <tr>
- <td class="icon">
- <i class="fa icon-note" title="Note"></i>
- </td>
- <td>
- An admonition paragraph, like this note, grabs the reader’s attention.
- </td>
- </tr>
- </table>
- </div>
- HTML
-
- expect(render(input, context)).to include(output.strip)
- end
+ output = <<~HTML
+ <a>Footnote reference</a>
+ HTML
+
+ expect(render(input, context)).to include(output.strip)
end
+ end
- context 'with passthrough' do
- it 'removes non heading ids' do
- input = <<~ADOC
- ++++
- <h2 id="foo">Title</h2>
- ++++
- ADOC
+ context 'with footnotes' do
+ it 'preserves ids and links' do
+ input = <<~ADOC
+ This paragraph has a footnote.footnote:[This is the text of the footnote.]
+ ADOC
- output = <<~HTML
- <h2>Title</h2>
- HTML
+ output = <<~HTML
+ <div>
+ <p>This paragraph has a footnote.<sup>[<a id="_footnoteref_1" href="#_footnotedef_1" title="View footnote.">1</a>]</sup></p>
+ </div>
+ <div>
+ <hr>
+ <div id="_footnotedef_1">
+ <a href="#_footnoteref_1">1</a>. This is the text of the footnote.
+ </div>
+ </div>
+ HTML
+
+ expect(render(input, context)).to include(output.strip)
+ end
+ end
- expect(render(input, context)).to include(output.strip)
- end
+ context 'with section anchors' do
+ it 'preserves ids and links' do
+ input = <<~ADOC
+ = Title
- it 'removes non footnote def ids' do
- input = <<~ADOC
- ++++
- <div id="def">Footnote definition</div>
- ++++
- ADOC
+ == First section
- output = <<~HTML
- <div>Footnote definition</div>
- HTML
+ This is the first section.
- expect(render(input, context)).to include(output.strip)
- end
+ == Second section
- it 'removes non footnote ref ids' do
- input = <<~ADOC
- ++++
- <a id="ref">Footnote reference</a>
- ++++
- ADOC
+ This is the second section.
- output = <<~HTML
- <a>Footnote reference</a>
- HTML
+ == Thunder âš¡ !
- expect(render(input, context)).to include(output.strip)
- end
+ This is the third section.
+ ADOC
+
+ output = <<~HTML
+ <h1>Title</h1>
+ <div>
+ <h2 id="user-content-first-section">
+ <a class="anchor" href="#user-content-first-section"></a>First section</h2>
+ <div>
+ <div>
+ <p>This is the first section.</p>
+ </div>
+ </div>
+ </div>
+ <div>
+ <h2 id="user-content-second-section">
+ <a class="anchor" href="#user-content-second-section"></a>Second section</h2>
+ <div>
+ <div>
+ <p>This is the second section.</p>
+ </div>
+ </div>
+ </div>
+ <div>
+ <h2 id="user-content-thunder">
+ <a class="anchor" href="#user-content-thunder"></a>Thunder âš¡ !</h2>
+ <div>
+ <div>
+ <p>This is the third section.</p>
+ </div>
+ </div>
+ </div>
+ HTML
+
+ expect(render(input, context)).to include(output.strip)
end
+ end
- context 'with footnotes' do
- it 'preserves ids and links' do
- input = <<~ADOC
- This paragraph has a footnote.footnote:[This is the text of the footnote.]
- ADOC
+ context 'with xrefs' do
+ it 'preserves ids' do
+ input = <<~ADOC
+ Learn how to xref:cross-references[use cross references].
- output = <<~HTML
- <div>
- <p>This paragraph has a footnote.<sup>[<a id="_footnoteref_1" href="#_footnotedef_1" title="View footnote.">1</a>]</sup></p>
- </div>
- <div>
- <hr>
- <div id="_footnotedef_1">
- <a href="#_footnoteref_1">1</a>. This is the text of the footnote.
- </div>
- </div>
- HTML
-
- expect(render(input, context)).to include(output.strip)
- end
+ [[cross-references]]A link to another location within an AsciiDoc document or between AsciiDoc documents is called a cross reference (also referred to as an xref).
+ ADOC
+
+ output = <<~HTML
+ <div>
+ <p>Learn how to <a href="#cross-references">use cross references</a>.</p>
+ </div>
+ <div>
+ <p><a id="user-content-cross-references"></a>A link to another location within an AsciiDoc document or between AsciiDoc documents is called a cross reference (also referred to as an xref).</p>
+ </div>
+ HTML
+
+ expect(render(input, context)).to include(output.strip)
end
+ end
- context 'with section anchors' do
- it 'preserves ids and links' do
- input = <<~ADOC
- = Title
-
- == First section
-
- This is the first section.
-
- == Second section
-
- This is the second section.
-
- == Thunder âš¡ !
-
- This is the third section.
- ADOC
+ context 'with checklist' do
+ it 'preserves classes' do
+ input = <<~ADOC
+ * [x] checked
+ * [ ] not checked
+ ADOC
- output = <<~HTML
- <h1>Title</h1>
- <div>
- <h2 id="user-content-first-section">
- <a class="anchor" href="#user-content-first-section"></a>First section</h2>
- <div>
- <div>
- <p>This is the first section.</p>
- </div>
- </div>
- </div>
- <div>
- <h2 id="user-content-second-section">
- <a class="anchor" href="#user-content-second-section"></a>Second section</h2>
- <div>
- <div>
- <p>This is the second section.</p>
- </div>
- </div>
- </div>
- <div>
- <h2 id="user-content-thunder">
- <a class="anchor" href="#user-content-thunder"></a>Thunder âš¡ !</h2>
- <div>
- <div>
- <p>This is the third section.</p>
- </div>
- </div>
- </div>
- HTML
-
- expect(render(input, context)).to include(output.strip)
- end
+ output = <<~HTML
+ <div>
+ <ul class="checklist">
+ <li>
+ <p><i class="fa fa-check-square-o"></i> checked</p>
+ </li>
+ <li>
+ <p><i class="fa fa-square-o"></i> not checked</p>
+ </li>
+ </ul>
+ </div>
+ HTML
+
+ expect(render(input, context)).to include(output.strip)
end
+ end
- context 'with xrefs' do
- it 'preserves ids' do
- input = <<~ADOC
- Learn how to xref:cross-references[use cross references].
-
- [[cross-references]]A link to another location within an AsciiDoc document or between AsciiDoc documents is called a cross reference (also referred to as an xref).
- ADOC
+ context 'with marks' do
+ it 'preserves classes' do
+ input = <<~ADOC
+ Werewolves are allergic to #cassia cinnamon#.
- output = <<~HTML
- <div>
- <p>Learn how to <a href="#cross-references">use cross references</a>.</p>
- </div>
- <div>
- <p><a id="user-content-cross-references"></a>A link to another location within an AsciiDoc document or between AsciiDoc documents is called a cross reference (also referred to as an xref).</p>
- </div>
- HTML
+ Did the werewolves read the [.small]#small print#?
- expect(render(input, context)).to include(output.strip)
- end
+ Where did all the [.underline.small]#cores# run off to?
+
+ We need [.line-through]#ten# make that twenty VMs.
+
+ [.big]##O##nce upon an infinite loop.
+ ADOC
+
+ output = <<~HTML
+ <div>
+ <p>Werewolves are allergic to <mark>cassia cinnamon</mark>.</p>
+ </div>
+ <div>
+ <p>Did the werewolves read the <span class="small">small print</span>?</p>
+ </div>
+ <div>
+ <p>Where did all the <span class="underline small">cores</span> run off to?</p>
+ </div>
+ <div>
+ <p>We need <span class="line-through">ten</span> make that twenty VMs.</p>
+ </div>
+ <div>
+ <p><span class="big">O</span>nce upon an infinite loop.</p>
+ </div>
+ HTML
+
+ expect(render(input, context)).to include(output.strip)
end
+ end
- context 'with checklist' do
- it 'preserves classes' do
- input = <<~ADOC
- * [x] checked
- * [ ] not checked
- ADOC
+ context 'with fenced block' do
+ it 'highlights syntax' do
+ input = <<~ADOC
+ ```js
+ console.log('hello world')
+ ```
+ ADOC
- output = <<~HTML
- <div>
- <ul class="checklist">
- <li>
- <p><i class="fa fa-check-square-o"></i> checked</p>
- </li>
- <li>
- <p><i class="fa fa-square-o"></i> not checked</p>
- </li>
- </ul>
- </div>
- HTML
-
- expect(render(input, context)).to include(output.strip)
- end
+ output = <<~HTML
+ <div>
+ <div>
+ <div class="gl-relative markdown-code-block js-markdown-code">
+ <pre class="code highlight js-syntax-highlight language-javascript" lang="javascript" v-pre="true"><code><span id="LC1" class="line" lang="javascript"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">hello world</span><span class="dl">'</span><span class="p">)</span></span></code></pre>
+ <copy-code></copy-code>
+ </div>
+ </div>
+ </div>
+ HTML
+
+ expect(render(input, context)).to include(output.strip)
end
+ end
- context 'with marks' do
- it 'preserves classes' do
- input = <<~ADOC
- Werewolves are allergic to #cassia cinnamon#.
-
- Did the werewolves read the [.small]#small print#?
-
- Where did all the [.underline.small]#cores# run off to?
-
- We need [.line-through]#ten# make that twenty VMs.
-
- [.big]##O##nce upon an infinite loop.
- ADOC
+ context 'with listing block' do
+ it 'highlights syntax' do
+ input = <<~ADOC
+ [source,c++]
+ .class.cpp
+ ----
+ #include <stdio.h>
- output = <<~HTML
- <div>
- <p>Werewolves are allergic to <mark>cassia cinnamon</mark>.</p>
- </div>
- <div>
- <p>Did the werewolves read the <span class="small">small print</span>?</p>
- </div>
- <div>
- <p>Where did all the <span class="underline small">cores</span> run off to?</p>
- </div>
- <div>
- <p>We need <span class="line-through">ten</span> make that twenty VMs.</p>
- </div>
- <div>
- <p><span class="big">O</span>nce upon an infinite loop.</p>
- </div>
- HTML
-
- expect(render(input, context)).to include(output.strip)
- end
+ for (int i = 0; i < 5; i++) {
+ std::cout<<"*"<<std::endl;
+ }
+ ----
+ ADOC
+
+ output = <<~HTML
+ <div>
+ <div>class.cpp</div>
+ <div>
+ <div class="gl-relative markdown-code-block js-markdown-code">
+ <pre class="code highlight js-syntax-highlight language-cpp" lang="cpp" v-pre="true"><code><span id="LC1" class="line" lang="cpp"><span class="cp">#include &lt;stdio.h&gt;</span></span>
+ <span id="LC2" class="line" lang="cpp"></span>
+ <span id="LC3" class="line" lang="cpp"><span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">5</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span></span>
+ <span id="LC4" class="line" lang="cpp"> <span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">"*"</span><span class="o">&lt;&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span></span>
+ <span id="LC5" class="line" lang="cpp"><span class="p">}</span></span></code></pre>
+ <copy-code></copy-code>
+ </div>
+ </div>
+ </div>
+ HTML
+
+ expect(render(input, context)).to include(output.strip)
end
+ end
- context 'with fenced block' do
- it 'highlights syntax' do
- input = <<~ADOC
- ```js
- console.log('hello world')
- ```
- ADOC
+ context 'with stem block' do
+ it 'does not apply syntax highlighting' do
+ input = <<~ADOC
+ [stem]
+ ++++
+ \sqrt{4} = 2
+ ++++
+ ADOC
- output = <<~HTML
- <div>
- <div>
- <div class="gl-relative markdown-code-block js-markdown-code">
- <pre class="code highlight js-syntax-highlight language-javascript" lang="javascript" v-pre="true"><code><span id="LC1" class="line" lang="javascript"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">hello world</span><span class="dl">'</span><span class="p">)</span></span></code></pre>
- <copy-code></copy-code>
- </div>
- </div>
- </div>
- HTML
-
- expect(render(input, context)).to include(output.strip)
- end
+ output = "<div>\n<div>\n\\$ qrt{4} = 2\\$\n</div>\n</div>"
+
+ expect(render(input, context)).to include(output)
end
+ end
- context 'with listing block' do
- it 'highlights syntax' do
- input = <<~ADOC
- [source,c++]
- .class.cpp
- ----
- #include <stdio.h>
-
- for (int i = 0; i < 5; i++) {
- std::cout<<"*"<<std::endl;
- }
- ----
- ADOC
+ context 'external links' do
+ it 'adds the `rel` attribute to the link' do
+ output = render('link:https://google.com[Google]', context)
- output = <<~HTML
- <div>
- <div>class.cpp</div>
- <div>
- <div class="gl-relative markdown-code-block js-markdown-code">
- <pre class="code highlight js-syntax-highlight language-cpp" lang="cpp" v-pre="true"><code><span id="LC1" class="line" lang="cpp"><span class="cp">#include &lt;stdio.h&gt;</span></span>
- <span id="LC2" class="line" lang="cpp"></span>
- <span id="LC3" class="line" lang="cpp"><span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">5</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span></span>
- <span id="LC4" class="line" lang="cpp"> <span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">"*"</span><span class="o">&lt;&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span></span>
- <span id="LC5" class="line" lang="cpp"><span class="p">}</span></span></code></pre>
- <copy-code></copy-code>
- </div>
- </div>
- </div>
- HTML
-
- expect(render(input, context)).to include(output.strip)
- end
+ expect(output).to include('rel="nofollow noreferrer noopener"')
end
+ end
- context 'with stem block' do
- it 'does not apply syntax highlighting' do
- input = <<~ADOC
- [stem]
- ++++
- \sqrt{4} = 2
- ++++
- ADOC
+ context 'LaTex code' do
+ it 'adds class js-render-math to the output' do
+ input = <<~MD
+ :stem: latexmath
- output = "<div>\n<div>\n\\$ qrt{4} = 2\\$\n</div>\n</div>"
+ [stem]
+ ++++
+ \sqrt{4} = 2
+ ++++
- expect(render(input, context)).to include(output)
- end
+ another part
+
+ [latexmath]
+ ++++
+ \beta_x \gamma
+ ++++
+
+ stem:[2+2] is 4
+ MD
+
+ expect(render(input, context)).to include('<pre data-math-style="display" class="code math js-render-math"><code>eta_x gamma</code></pre>')
+ expect(render(input, context)).to include('<p><code data-math-style="inline" class="code math js-render-math">2+2</code> is 4</p>')
end
+ end
- context 'external links' do
- it 'adds the `rel` attribute to the link' do
- output = render('link:https://google.com[Google]', context)
+ context 'outfilesuffix' do
+ it 'defaults to adoc' do
+ output = render("Inter-document reference <<README.adoc#>>", context)
- expect(output).to include('rel="nofollow noreferrer noopener"')
- end
+ expect(output).to include("a href=\"README.adoc\"")
end
+ end
- context 'LaTex code' do
- it 'adds class js-render-math to the output' do
- input = <<~MD
- :stem: latexmath
-
- [stem]
- ++++
- \sqrt{4} = 2
- ++++
-
- another part
-
- [latexmath]
- ++++
- \beta_x \gamma
- ++++
-
- stem:[2+2] is 4
- MD
-
- expect(render(input, context)).to include('<pre data-math-style="display" class="code math js-render-math"><code>eta_x gamma</code></pre>')
- expect(render(input, context)).to include('<p><code data-math-style="inline" class="code math js-render-math">2+2</code> is 4</p>')
- end
+ context 'with mermaid diagrams' do
+ it 'adds class js-render-mermaid to the output' do
+ input = <<~MD
+ [mermaid]
+ ....
+ graph LR
+ A[Square Rect] -- Link text --> B((Circle))
+ A --> C(Round Rect)
+ B --> D{Rhombus}
+ C --> D
+ ....
+ MD
+
+ output = <<~HTML
+ <pre data-mermaid-style="display" class="js-render-mermaid">graph LR
+ A[Square Rect] -- Link text --&gt; B((Circle))
+ A --&gt; C(Round Rect)
+ B --&gt; D{Rhombus}
+ C --&gt; D</pre>
+ HTML
+
+ expect(render(input, context)).to include(output.strip)
end
- context 'outfilesuffix' do
- it 'defaults to adoc' do
- output = render("Inter-document reference <<README.adoc#>>", context)
+ it 'applies subs in diagram block' do
+ input = <<~MD
+ :class-name: AveryLongClass
- expect(output).to include("a href=\"README.adoc\"")
- end
- end
+ [mermaid,subs=+attributes]
+ ....
+ classDiagram
+ Class01 <|-- {class-name} : Cool
+ ....
+ MD
- context 'with mermaid diagrams' do
- it 'adds class js-render-mermaid to the output' do
- input = <<~MD
- [mermaid]
- ....
- graph LR
- A[Square Rect] -- Link text --> B((Circle))
- A --> C(Round Rect)
- B --> D{Rhombus}
- C --> D
- ....
- MD
-
- output = <<~HTML
- <pre data-mermaid-style="display" class="js-render-mermaid">graph LR
- A[Square Rect] -- Link text --&gt; B((Circle))
- A --&gt; C(Round Rect)
- B --&gt; D{Rhombus}
- C --&gt; D</pre>
- HTML
-
- expect(render(input, context)).to include(output.strip)
- end
+ output = <<~HTML
+ <pre data-mermaid-style="display" class="js-render-mermaid">classDiagram
+ Class01 &lt;|-- AveryLongClass : Cool</pre>
+ HTML
- it 'applies subs in diagram block' do
- input = <<~MD
- :class-name: AveryLongClass
-
- [mermaid,subs=+attributes]
- ....
- classDiagram
- Class01 <|-- {class-name} : Cool
- ....
- MD
-
- output = <<~HTML
- <pre data-mermaid-style="display" class="js-render-mermaid">classDiagram
- Class01 &lt;|-- AveryLongClass : Cool</pre>
- HTML
-
- expect(render(input, context)).to include(output.strip)
- end
+ expect(render(input, context)).to include(output.strip)
end
+ end
- context 'with Kroki enabled' do
- before do
- allow_any_instance_of(ApplicationSetting).to receive(:kroki_enabled).and_return(true)
- allow_any_instance_of(ApplicationSetting).to receive(:kroki_url).and_return('https://kroki.io')
- end
-
- it 'converts a graphviz diagram to image' do
- input = <<~ADOC
- [graphviz]
- ....
- digraph G {
- Hello->World
- }
- ....
- ADOC
+ context 'with Kroki enabled' do
+ before do
+ allow_any_instance_of(ApplicationSetting).to receive(:kroki_enabled).and_return(true)
+ allow_any_instance_of(ApplicationSetting).to receive(:kroki_url).and_return('https://kroki.io')
+ end
- output = <<~HTML
- <div>
- <div>
- <a class="no-attachment-icon" href="https://kroki.io/graphviz/svg/eNpLyUwvSizIUHBXqOZSUPBIzcnJ17ULzy_KSeGqBQCEzQka" target="_blank" rel="noopener noreferrer"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="Diagram" class="lazy" data-src="https://kroki.io/graphviz/svg/eNpLyUwvSizIUHBXqOZSUPBIzcnJ17ULzy_KSeGqBQCEzQka"></a>
- </div>
- </div>
- HTML
+ it 'converts a graphviz diagram to image' do
+ input = <<~ADOC
+ [graphviz]
+ ....
+ digraph G {
+ Hello->World
+ }
+ ....
+ ADOC
- expect(render(input, context)).to include(output.strip)
- end
+ output = <<~HTML
+ <div>
+ <div>
+ <a class="no-attachment-icon" href="https://kroki.io/graphviz/svg/eNpLyUwvSizIUHBXqOZSUPBIzcnJ17ULzy_KSeGqBQCEzQka" target="_blank" rel="noopener noreferrer"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="Diagram" class="lazy" data-src="https://kroki.io/graphviz/svg/eNpLyUwvSizIUHBXqOZSUPBIzcnJ17ULzy_KSeGqBQCEzQka"></a>
+ </div>
+ </div>
+ HTML
- it 'does not convert a blockdiag diagram to image' do
- input = <<~ADOC
- [blockdiag]
- ....
- blockdiag {
- Kroki -> generates -> "Block diagrams";
- Kroki -> is -> "very easy!";
-
- Kroki [color = "greenyellow"];
- "Block diagrams" [color = "pink"];
- "very easy!" [color = "orange"];
- }
- ....
- ADOC
+ expect(render(input, context)).to include(output.strip)
+ end
- output = <<~HTML
- <div>
- <div>
- <pre>blockdiag {
- Kroki -&gt; generates -&gt; "Block diagrams";
- Kroki -&gt; is -&gt; "very easy!";
-
- Kroki [color = "greenyellow"];
- "Block diagrams" [color = "pink"];
- "very easy!" [color = "orange"];
- }</pre>
- </div>
- </div>
- HTML
-
- expect(render(input, context)).to include(output.strip)
- end
+ it 'does not convert a blockdiag diagram to image' do
+ input = <<~ADOC
+ [blockdiag]
+ ....
+ blockdiag {
+ Kroki -> generates -> "Block diagrams";
+ Kroki -> is -> "very easy!";
+
+ Kroki [color = "greenyellow"];
+ "Block diagrams" [color = "pink"];
+ "very easy!" [color = "orange"];
+ }
+ ....
+ ADOC
- it 'does not allow kroki-plantuml-include to be overridden' do
- input = <<~ADOC
- [plantuml, test="{counter:kroki-plantuml-include:/etc/passwd}", format="png"]
- ....
- class BlockProcessor
-
- BlockProcessor <|-- {counter:kroki-plantuml-include}
- ....
- ADOC
+ output = <<~HTML
+ <div>
+ <div>
+ <pre>blockdiag {
+ Kroki -&gt; generates -&gt; "Block diagrams";
+ Kroki -&gt; is -&gt; "very easy!";
+
+ Kroki [color = "greenyellow"];
+ "Block diagrams" [color = "pink"];
+ "very easy!" [color = "orange"];
+ }</pre>
+ </div>
+ </div>
+ HTML
+
+ expect(render(input, context)).to include(output.strip)
+ end
- output = <<~HTML
- <div>
- <div>
- <a class=\"no-attachment-icon\" href=\"https://kroki.io/plantuml/png/eNpLzkksLlZwyslPzg4oyk9OLS7OL-LiQuUr2NTo6ipUJ-eX5pWkFlllF-VnZ-oW5CTmlZTm5uhm5iXnlKak1gIABQEb8A==\" target=\"_blank\" rel=\"noopener noreferrer\"><img src=\"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"Diagram\" class=\"lazy\" data-src=\"https://kroki.io/plantuml/png/eNpLzkksLlZwyslPzg4oyk9OLS7OL-LiQuUr2NTo6ipUJ-eX5pWkFlllF-VnZ-oW5CTmlZTm5uhm5iXnlKak1gIABQEb8A==\"></a>
- </div>
- </div>
- HTML
+ it 'does not allow kroki-plantuml-include to be overridden' do
+ input = <<~ADOC
+ [plantuml, test="{counter:kroki-plantuml-include:/etc/passwd}", format="png"]
+ ....
+ class BlockProcessor
- expect(render(input, {})).to include(output.strip)
- end
+ BlockProcessor <|-- {counter:kroki-plantuml-include}
+ ....
+ ADOC
- it 'does not allow kroki-server-url to be overridden' do
- input = <<~ADOC
- [plantuml, test="{counter:kroki-server-url:evilsite}", format="png"]
- ....
- class BlockProcessor
-
- BlockProcessor
- ....
- ADOC
+ output = <<~HTML
+ <div>
+ <div>
+ <a class=\"no-attachment-icon\" href=\"https://kroki.io/plantuml/png/eNpLzkksLlZwyslPzg4oyk9OLS7OL-LiQuUr2NTo6ipUJ-eX5pWkFlllF-VnZ-oW5CTmlZTm5uhm5iXnlKak1gIABQEb8A==\" target=\"_blank\" rel=\"noopener noreferrer\"><img src=\"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"Diagram\" class=\"lazy\" data-src=\"https://kroki.io/plantuml/png/eNpLzkksLlZwyslPzg4oyk9OLS7OL-LiQuUr2NTo6ipUJ-eX5pWkFlllF-VnZ-oW5CTmlZTm5uhm5iXnlKak1gIABQEb8A==\"></a>
+ </div>
+ </div>
+ HTML
- expect(render(input, {})).not_to include('evilsite')
- end
+ expect(render(input, {})).to include(output.strip)
end
- context 'with Kroki and BlockDiag (additional format) enabled' do
- before do
- allow_any_instance_of(ApplicationSetting).to receive(:kroki_enabled).and_return(true)
- allow_any_instance_of(ApplicationSetting).to receive(:kroki_url).and_return('https://kroki.io')
- allow_any_instance_of(ApplicationSetting).to receive(:kroki_formats_blockdiag).and_return(true)
- end
-
- it 'converts a blockdiag diagram to image' do
- input = <<~ADOC
- [blockdiag]
- ....
- blockdiag {
- Kroki -> generates -> "Block diagrams";
- Kroki -> is -> "very easy!";
-
- Kroki [color = "greenyellow"];
- "Block diagrams" [color = "pink"];
- "very easy!" [color = "orange"];
- }
- ....
- ADOC
+ it 'does not allow kroki-server-url to be overridden' do
+ input = <<~ADOC
+ [plantuml, test="{counter:kroki-server-url:evilsite}", format="png"]
+ ....
+ class BlockProcessor
- output = <<~HTML
- <div>
- <div>
- <a class="no-attachment-icon" href="https://kroki.io/blockdiag/svg/eNpdzDEKQjEQhOHeU4zpPYFoYesRxGJ9bwghMSsbUYJ4d10UCZbDfPynolOek0Q8FsDeNCestoisNLmy-Qg7R3Blcm5hPcr0ITdaB6X15fv-_YdJixo2CNHI2lmK3sPRA__RwV5SzV80ZAegJjXSyfMFptc71w==" target="_blank" rel="noopener noreferrer"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="Diagram" class="lazy" data-src="https://kroki.io/blockdiag/svg/eNpdzDEKQjEQhOHeU4zpPYFoYesRxGJ9bwghMSsbUYJ4d10UCZbDfPynolOek0Q8FsDeNCestoisNLmy-Qg7R3Blcm5hPcr0ITdaB6X15fv-_YdJixo2CNHI2lmK3sPRA__RwV5SzV80ZAegJjXSyfMFptc71w=="></a>
- </div>
- </div>
- HTML
+ BlockProcessor
+ ....
+ ADOC
- expect(render(input, context)).to include(output.strip)
- end
+ expect(render(input, {})).not_to include('evilsite')
end
end
- context 'with project' do
- let(:context) do
- {
- commit: commit,
- project: project,
- ref: ref,
- requested_path: requested_path
- }
+ context 'with Kroki and BlockDiag (additional format) enabled' do
+ before do
+ allow_any_instance_of(ApplicationSetting).to receive(:kroki_enabled).and_return(true)
+ allow_any_instance_of(ApplicationSetting).to receive(:kroki_url).and_return('https://kroki.io')
+ allow_any_instance_of(ApplicationSetting).to receive(:kroki_formats_blockdiag).and_return(true)
end
- let(:commit) { project.commit(ref) }
- let(:project) { create(:project, :repository) }
- let(:ref) { 'asciidoc' }
- let(:requested_path) { '/' }
+ it 'converts a blockdiag diagram to image' do
+ input = <<~ADOC
+ [blockdiag]
+ ....
+ blockdiag {
+ Kroki -> generates -> "Block diagrams";
+ Kroki -> is -> "very easy!";
+
+ Kroki [color = "greenyellow"];
+ "Block diagrams" [color = "pink"];
+ "very easy!" [color = "orange"];
+ }
+ ....
+ ADOC
- context 'include directive' do
- subject(:output) { render(input, context) }
+ output = <<~HTML
+ <div>
+ <div>
+ <a class="no-attachment-icon" href="https://kroki.io/blockdiag/svg/eNpdzDEKQjEQhOHeU4zpPYFoYesRxGJ9bwghMSsbUYJ4d10UCZbDfPynolOek0Q8FsDeNCestoisNLmy-Qg7R3Blcm5hPcr0ITdaB6X15fv-_YdJixo2CNHI2lmK3sPRA__RwV5SzV80ZAegJjXSyfMFptc71w==" target="_blank" rel="noopener noreferrer"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="Diagram" class="lazy" data-src="https://kroki.io/blockdiag/svg/eNpdzDEKQjEQhOHeU4zpPYFoYesRxGJ9bwghMSsbUYJ4d10UCZbDfPynolOek0Q8FsDeNCestoisNLmy-Qg7R3Blcm5hPcr0ITdaB6X15fv-_YdJixo2CNHI2lmK3sPRA__RwV5SzV80ZAegJjXSyfMFptc71w=="></a>
+ </div>
+ </div>
+ HTML
- let(:input) { "Include this:\n\ninclude::#{include_path}[]" }
+ expect(render(input, context)).to include(output.strip)
+ end
+ end
+ end
- before do
- current_file = requested_path
- current_file += 'README.adoc' if requested_path.end_with? '/'
+ context 'with project' do
+ let(:context) do
+ {
+ commit: commit,
+ project: project,
+ ref: ref,
+ requested_path: requested_path
+ }
+ end
- create_file(current_file, "= AsciiDoc\n")
- end
+ let(:commit) { project.commit(ref) }
+ let(:project) { create(:project, :repository) }
+ let(:ref) { 'asciidoc' }
+ let(:requested_path) { '/' }
- def many_includes(target)
- Array.new(10, "include::#{target}[]").join("\n")
- end
+ context 'include directive' do
+ subject(:output) { render(input, context) }
- context 'cyclic imports' do
- before do
- create_file('doc/api/a.adoc', many_includes('b.adoc'))
- create_file('doc/api/b.adoc', many_includes('a.adoc'))
- end
+ let(:input) { "Include this:\n\ninclude::#{include_path}[]" }
- let(:include_path) { 'a.adoc' }
- let(:requested_path) { 'doc/api/README.md' }
+ before do
+ current_file = requested_path
+ current_file += 'README.adoc' if requested_path.end_with? '/'
- it 'completes successfully' do
- is_expected.to include('<p>Include this:</p>')
- end
+ create_file(current_file, "= AsciiDoc\n")
+ end
+
+ def many_includes(target)
+ Array.new(10, "include::#{target}[]").join("\n")
+ end
+
+ context 'cyclic imports' do
+ before do
+ create_file('doc/api/a.adoc', many_includes('b.adoc'))
+ create_file('doc/api/b.adoc', many_includes('a.adoc'))
end
- context 'with path to non-existing file' do
- let(:include_path) { 'not-exists.adoc' }
+ let(:include_path) { 'a.adoc' }
+ let(:requested_path) { 'doc/api/README.md' }
- it 'renders Unresolved directive placeholder' do
- is_expected.to include("<strong>[ERROR: include::#{include_path}[] - unresolved directive]</strong>")
- end
+ it 'completes successfully' do
+ is_expected.to include('<p>Include this:</p>')
end
+ end
- shared_examples :invalid_include do
- let(:include_path) { 'dk.png' }
+ context 'with path to non-existing file' do
+ let(:include_path) { 'not-exists.adoc' }
- before do
- allow(project.repository).to receive(:blob_at).and_return(blob)
- end
+ it 'renders Unresolved directive placeholder' do
+ is_expected.to include("<strong>[ERROR: include::#{include_path}[] - unresolved directive]</strong>")
+ end
+ end
- it 'does not read the blob' do
- expect(blob).not_to receive(:data)
- end
+ shared_examples :invalid_include do
+ let(:include_path) { 'dk.png' }
- it 'renders Unresolved directive placeholder' do
- is_expected.to include("<strong>[ERROR: include::#{include_path}[] - unresolved directive]</strong>")
- end
+ before do
+ allow(project.repository).to receive(:blob_at).and_return(blob)
end
- context 'with path to a binary file' do
- let(:blob) { fake_blob(path: 'dk.png', binary: true) }
+ it 'does not read the blob' do
+ expect(blob).not_to receive(:data)
+ end
- include_examples :invalid_include
+ it 'renders Unresolved directive placeholder' do
+ is_expected.to include("<strong>[ERROR: include::#{include_path}[] - unresolved directive]</strong>")
end
+ end
- context 'with path to file in external storage' do
- let(:blob) { fake_blob(path: 'dk.png', lfs: true) }
+ context 'with path to a binary file' do
+ let(:blob) { fake_blob(path: 'dk.png', binary: true) }
- before do
- allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
- project.update_attribute(:lfs_enabled, true)
- end
+ include_examples :invalid_include
+ end
- include_examples :invalid_include
+ context 'with path to file in external storage' do
+ let(:blob) { fake_blob(path: 'dk.png', lfs: true) }
+
+ before do
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
+ project.update_attribute(:lfs_enabled, true)
end
- context 'with path to a textual file' do
- let(:include_path) { 'sample.adoc' }
+ include_examples :invalid_include
+ end
- before do
- create_file(file_path, "Content from #{include_path}")
- end
+ context 'with path to a textual file' do
+ let(:include_path) { 'sample.adoc' }
- shared_examples :valid_include do
- [
- ['/doc/sample.adoc', 'doc/sample.adoc', 'absolute path'],
- ['sample.adoc', 'doc/api/sample.adoc', 'relative path'],
- ['./sample.adoc', 'doc/api/sample.adoc', 'relative path with leading ./'],
- ['../sample.adoc', 'doc/sample.adoc', 'relative path to a file up one directory'],
- ['../../sample.adoc', 'sample.adoc', 'relative path for a file up multiple directories']
- ].each do |include_path_, file_path_, desc|
- context "the file is specified by #{desc}" do
- let(:include_path) { include_path_ }
- let(:file_path) { file_path_ }
-
- it 'includes content of the file' do
- is_expected.to include('<p>Include this:</p>')
- is_expected.to include("<p>Content from #{include_path}</p>")
- end
+ before do
+ create_file(file_path, "Content from #{include_path}")
+ end
+
+ shared_examples :valid_include do
+ [
+ ['/doc/sample.adoc', 'doc/sample.adoc', 'absolute path'],
+ ['sample.adoc', 'doc/api/sample.adoc', 'relative path'],
+ ['./sample.adoc', 'doc/api/sample.adoc', 'relative path with leading ./'],
+ ['../sample.adoc', 'doc/sample.adoc', 'relative path to a file up one directory'],
+ ['../../sample.adoc', 'sample.adoc', 'relative path for a file up multiple directories']
+ ].each do |include_path_, file_path_, desc|
+ context "the file is specified by #{desc}" do
+ let(:include_path) { include_path_ }
+ let(:file_path) { file_path_ }
+
+ it 'includes content of the file' do
+ is_expected.to include('<p>Include this:</p>')
+ is_expected.to include("<p>Content from #{include_path}</p>")
end
end
end
+ end
- context 'when requested path is a file in the repo' do
- let(:requested_path) { 'doc/api/README.adoc' }
+ context 'when requested path is a file in the repo' do
+ let(:requested_path) { 'doc/api/README.adoc' }
- include_examples :valid_include
+ include_examples :valid_include
- context 'without a commit (only ref)' do
- let(:commit) { nil }
+ context 'without a commit (only ref)' do
+ let(:commit) { nil }
- include_examples :valid_include
- end
+ include_examples :valid_include
end
+ end
- context 'when requested path is a directory in the repo' do
- let(:requested_path) { 'doc/api/' }
+ context 'when requested path is a directory in the repo' do
+ let(:requested_path) { 'doc/api/' }
- include_examples :valid_include
+ include_examples :valid_include
- context 'without a commit (only ref)' do
- let(:commit) { nil }
+ context 'without a commit (only ref)' do
+ let(:commit) { nil }
- include_examples :valid_include
- end
+ include_examples :valid_include
end
end
+ end
- context 'when repository is passed into the context' do
- let(:wiki_repo) { project.wiki.repository }
- let(:include_path) { 'wiki_file.adoc' }
+ context 'when repository is passed into the context' do
+ let(:wiki_repo) { project.wiki.repository }
+ let(:include_path) { 'wiki_file.adoc' }
+ before do
+ project.create_wiki
+ context.merge!(repository: wiki_repo)
+ end
+
+ context 'when the file exists' do
before do
- project.create_wiki
- context.merge!(repository: wiki_repo)
+ create_file(include_path, 'Content from wiki', repository: wiki_repo)
end
- context 'when the file exists' do
- before do
- create_file(include_path, 'Content from wiki', repository: wiki_repo)
- end
+ it { is_expected.to include('<p>Content from wiki</p>') }
+ end
- it { is_expected.to include('<p>Content from wiki</p>') }
- end
+ context 'when the file does not exist' do
+ it { is_expected.to include("[ERROR: include::#{include_path}[] - unresolved directive]")}
+ end
+ end
- context 'when the file does not exist' do
- it { is_expected.to include("[ERROR: include::#{include_path}[] - unresolved directive]")}
- end
+ context 'recursive includes with relative paths' do
+ let(:input) do
+ <<~ADOC
+ Source: requested file
+
+ include::doc/README.adoc[]
+
+ include::license.adoc[]
+ ADOC
end
- context 'recursive includes with relative paths' do
- let(:input) do
- <<~ADOC
- Source: requested file
-
- include::doc/README.adoc[]
-
- include::license.adoc[]
- ADOC
- end
+ before do
+ create_file 'doc/README.adoc', <<~ADOC
+ Source: doc/README.adoc
- before do
- create_file 'doc/README.adoc', <<~ADOC
- Source: doc/README.adoc
-
- include::../license.adoc[]
-
- include::api/hello.adoc[]
- ADOC
- create_file 'license.adoc', <<~ADOC
- Source: license.adoc
- ADOC
- create_file 'doc/api/hello.adoc', <<~ADOC
- Source: doc/api/hello.adoc
-
- include::./common.adoc[]
- ADOC
- create_file 'doc/api/common.adoc', <<~ADOC
- Source: doc/api/common.adoc
- ADOC
- end
+ include::../license.adoc[]
- it 'includes content of the included files recursively' do
- expect(output.gsub(/<[^>]+>/, '').gsub(/\n\s*/, "\n").strip).to eq <<~ADOC.strip
- Source: requested file
- Source: doc/README.adoc
- Source: license.adoc
- Source: doc/api/hello.adoc
- Source: doc/api/common.adoc
- Source: license.adoc
- ADOC
- end
+ include::api/hello.adoc[]
+ ADOC
+ create_file 'license.adoc', <<~ADOC
+ Source: license.adoc
+ ADOC
+ create_file 'doc/api/hello.adoc', <<~ADOC
+ Source: doc/api/hello.adoc
+
+ include::./common.adoc[]
+ ADOC
+ create_file 'doc/api/common.adoc', <<~ADOC
+ Source: doc/api/common.adoc
+ ADOC
end
- def create_file(path, content, repository: project.repository)
- repository.create_file(project.creator, path, content,
- message: "Add #{path}", branch_name: 'asciidoc')
+ it 'includes content of the included files recursively' do
+ expect(output.gsub(/<[^>]+>/, '').gsub(/\n\s*/, "\n").strip).to eq <<~ADOC.strip
+ Source: requested file
+ Source: doc/README.adoc
+ Source: license.adoc
+ Source: doc/api/hello.adoc
+ Source: doc/api/common.adoc
+ Source: license.adoc
+ ADOC
end
end
- end
- end
- context 'using ruby-based HTML renderer' do
- before do
- stub_feature_flags(use_cmark_renderer: false)
- end
-
- it_behaves_like 'renders correct asciidoc'
- end
-
- context 'using c-based HTML renderer' do
- before do
- stub_feature_flags(use_cmark_renderer: true)
+ def create_file(path, content, repository: project.repository)
+ repository.create_file(project.creator, path, content,
+ message: "Add #{path}", branch_name: 'asciidoc')
+ end
end
-
- it_behaves_like 'renders correct asciidoc'
end
def render(*args)
diff --git a/spec/lib/gitlab/auth/auth_finders_spec.rb b/spec/lib/gitlab/auth/auth_finders_spec.rb
index f1c891b2adb..e985f66bfe9 100644
--- a/spec/lib/gitlab/auth/auth_finders_spec.rb
+++ b/spec/lib/gitlab/auth/auth_finders_spec.rb
@@ -939,21 +939,19 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
describe '#cluster_agent_token_from_authorization_token' do
- let_it_be(:agent_token, freeze: true) { create(:cluster_agent_token) }
+ let_it_be(:agent_token) { create(:cluster_agent_token) }
+
+ subject { cluster_agent_token_from_authorization_token }
context 'when route_setting is empty' do
- it 'returns nil' do
- expect(cluster_agent_token_from_authorization_token).to be_nil
- end
+ it { is_expected.to be_nil }
end
context 'when route_setting allows cluster agent token' do
let(:route_authentication_setting) { { cluster_agent_token_allowed: true } }
context 'Authorization header is empty' do
- it 'returns nil' do
- expect(cluster_agent_token_from_authorization_token).to be_nil
- end
+ it { is_expected.to be_nil }
end
context 'Authorization header is incorrect' do
@@ -961,9 +959,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
request.headers['Authorization'] = 'Bearer ABCD'
end
- it 'returns nil' do
- expect(cluster_agent_token_from_authorization_token).to be_nil
- end
+ it { is_expected.to be_nil }
end
context 'Authorization header is malformed' do
@@ -971,9 +967,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
request.headers['Authorization'] = 'Bearer'
end
- it 'returns nil' do
- expect(cluster_agent_token_from_authorization_token).to be_nil
- end
+ it { is_expected.to be_nil }
end
context 'Authorization header matches agent token' do
@@ -981,8 +975,14 @@ RSpec.describe Gitlab::Auth::AuthFinders do
request.headers['Authorization'] = "Bearer #{agent_token.token}"
end
- it 'returns the agent token' do
- expect(cluster_agent_token_from_authorization_token).to eq(agent_token)
+ it { is_expected.to eq(agent_token) }
+
+ context 'agent token has been revoked' do
+ before do
+ agent_token.revoked!
+ end
+
+ it { is_expected.to be_nil }
end
end
end
diff --git a/spec/lib/gitlab/auth/ldap/config_spec.rb b/spec/lib/gitlab/auth/ldap/config_spec.rb
index 7a657cce597..3039fce6141 100644
--- a/spec/lib/gitlab/auth/ldap/config_spec.rb
+++ b/spec/lib/gitlab/auth/ldap/config_spec.rb
@@ -121,10 +121,40 @@ AtlErSqafbECNDSwS5BX8yDpu5yRBJ4xegO/rNlmb8ICRYkuJapD1xXicFOsmfUK
expect(config.adapter_options).to eq(
host: 'ldap.example.com',
port: 386,
+ hosts: nil,
encryption: nil
)
end
+ it 'includes failover hosts when set' do
+ stub_ldap_config(
+ options: {
+ 'host' => 'ldap.example.com',
+ 'port' => 686,
+ 'hosts' => [
+ ['ldap1.example.com', 636],
+ ['ldap2.example.com', 636]
+ ],
+ 'encryption' => 'simple_tls',
+ 'verify_certificates' => true,
+ 'bind_dn' => 'uid=admin,dc=example,dc=com',
+ 'password' => 'super_secret'
+ }
+ )
+
+ expect(config.adapter_options).to include({
+ hosts: [
+ ['ldap1.example.com', 636],
+ ['ldap2.example.com', 636]
+ ],
+ auth: {
+ method: :simple,
+ username: 'uid=admin,dc=example,dc=com',
+ password: 'super_secret'
+ }
+ })
+ end
+
it 'includes authentication options when auth is configured' do
stub_ldap_config(
options: {
diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb
index 32e647688ff..611c70d73a1 100644
--- a/spec/lib/gitlab/auth_spec.rb
+++ b/spec/lib/gitlab/auth_spec.rb
@@ -87,7 +87,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
end
context 'when IP is already banned' do
- subject { gl_auth.find_for_git_client('username', 'password', project: nil, ip: 'ip') }
+ subject { gl_auth.find_for_git_client('username', Gitlab::Password.test_default, project: nil, ip: 'ip') }
before do
expect_next_instance_of(Gitlab::Auth::IpRateLimiter) do |rate_limiter|
@@ -204,16 +204,16 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
end
it 'recognizes master passwords' do
- user = create(:user, password: 'password')
+ user = create(:user, password: Gitlab::Password.test_default)
- expect(gl_auth.find_for_git_client(user.username, 'password', project: nil, ip: 'ip')).to have_attributes(actor: user, project: nil, type: :gitlab_or_ldap, authentication_abilities: described_class.full_authentication_abilities)
+ expect(gl_auth.find_for_git_client(user.username, Gitlab::Password.test_default, project: nil, ip: 'ip')).to have_attributes(actor: user, project: nil, type: :gitlab_or_ldap, authentication_abilities: described_class.full_authentication_abilities)
end
include_examples 'user login operation with unique ip limit' do
- let(:user) { create(:user, password: 'password') }
+ let(:user) { create(:user, password: Gitlab::Password.test_default) }
def operation
- expect(gl_auth.find_for_git_client(user.username, 'password', project: nil, ip: 'ip')).to have_attributes(actor: user, project: nil, type: :gitlab_or_ldap, authentication_abilities: described_class.full_authentication_abilities)
+ expect(gl_auth.find_for_git_client(user.username, Gitlab::Password.test_default, project: nil, ip: 'ip')).to have_attributes(actor: user, project: nil, type: :gitlab_or_ldap, authentication_abilities: described_class.full_authentication_abilities)
end
end
@@ -477,7 +477,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
:user,
:blocked,
username: 'normal_user',
- password: 'my-secret'
+ password: Gitlab::Password.test_default
)
expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip'))
@@ -486,7 +486,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
context 'when 2fa is enabled globally' do
let_it_be(:user) do
- create(:user, username: 'normal_user', password: 'my-secret', otp_grace_period_started_at: 1.day.ago)
+ create(:user, username: 'normal_user', password: Gitlab::Password.test_default, otp_grace_period_started_at: 1.day.ago)
end
before do
@@ -510,7 +510,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
context 'when 2fa is enabled personally' do
let(:user) do
- create(:user, :two_factor, username: 'normal_user', password: 'my-secret', otp_grace_period_started_at: 1.day.ago)
+ create(:user, :two_factor, username: 'normal_user', password: Gitlab::Password.test_default, otp_grace_period_started_at: 1.day.ago)
end
it 'fails' do
@@ -523,7 +523,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
user = create(
:user,
username: 'normal_user',
- password: 'my-secret'
+ password: Gitlab::Password.test_default
)
expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip'))
@@ -534,7 +534,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
user = create(
:user,
username: 'oauth2',
- password: 'my-secret'
+ password: Gitlab::Password.test_default
)
expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip'))
@@ -609,7 +609,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
context 'when deploy token and user have the same username' do
let(:username) { 'normal_user' }
- let(:user) { create(:user, username: username, password: 'my-secret') }
+ let(:user) { create(:user, username: username, password: Gitlab::Password.test_default) }
let(:deploy_token) { create(:deploy_token, username: username, read_registry: false, projects: [project]) }
it 'succeeds for the token' do
@@ -622,7 +622,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
it 'succeeds for the user' do
auth_success = { actor: user, project: nil, type: :gitlab_or_ldap, authentication_abilities: described_class.full_authentication_abilities }
- expect(gl_auth.find_for_git_client(username, 'my-secret', project: project, ip: 'ip'))
+ expect(gl_auth.find_for_git_client(username, Gitlab::Password.test_default, project: project, ip: 'ip'))
.to have_attributes(auth_success)
end
end
@@ -816,7 +816,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
end
let(:username) { 'John' } # username isn't lowercase, test this
- let(:password) { 'my-secret' }
+ let(:password) { Gitlab::Password.test_default }
it "finds user by valid login/password" do
expect(gl_auth.find_with_user_password(username, password)).to eql user
@@ -941,13 +941,13 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
it "does not find user by using ldap as fallback to for authentication" do
expect(Gitlab::Auth::Ldap::Authentication).to receive(:login).and_return(nil)
- expect(gl_auth.find_with_user_password('ldap_user', 'password')).to be_nil
+ expect(gl_auth.find_with_user_password('ldap_user', Gitlab::Password.test_default)).to be_nil
end
it "find new user by using ldap as fallback to for authentication" do
expect(Gitlab::Auth::Ldap::Authentication).to receive(:login).and_return(user)
- expect(gl_auth.find_with_user_password('ldap_user', 'password')).to eq(user)
+ expect(gl_auth.find_with_user_password('ldap_user', Gitlab::Password.test_default)).to eq(user)
end
end
diff --git a/spec/lib/gitlab/background_migration/backfill_artifact_expiry_date_spec.rb b/spec/lib/gitlab/background_migration/backfill_artifact_expiry_date_spec.rb
index 6ab1e3ecd70..f5d2224747a 100644
--- a/spec/lib/gitlab/background_migration/backfill_artifact_expiry_date_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_artifact_expiry_date_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::BackfillArtifactExpiryDate, :migration, schema: 20181228175414 do
+RSpec.describe Gitlab::BackgroundMigration::BackfillArtifactExpiryDate, :migration, schema: 20210301200959 do
subject(:perform) { migration.perform(1, 99) }
let(:migration) { described_class.new }
diff --git a/spec/lib/gitlab/background_migration/backfill_ci_namespace_mirrors_spec.rb b/spec/lib/gitlab/background_migration/backfill_ci_namespace_mirrors_spec.rb
new file mode 100644
index 00000000000..8980a26932b
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/backfill_ci_namespace_mirrors_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BackfillCiNamespaceMirrors, :migration, schema: 20211208122200 do
+ let(:namespaces) { table(:namespaces) }
+ let(:ci_namespace_mirrors) { table(:ci_namespace_mirrors) }
+
+ subject { described_class.new }
+
+ describe '#perform' do
+ it 'creates hierarchies for all namespaces in range' do
+ namespaces.create!(id: 5, name: 'test1', path: 'test1')
+ namespaces.create!(id: 7, name: 'test2', path: 'test2')
+ namespaces.create!(id: 8, name: 'test3', path: 'test3')
+
+ subject.perform(5, 7)
+
+ expect(ci_namespace_mirrors.all).to contain_exactly(
+ an_object_having_attributes(namespace_id: 5, traversal_ids: [5]),
+ an_object_having_attributes(namespace_id: 7, traversal_ids: [7])
+ )
+ end
+
+ it 'handles existing hierarchies gracefully' do
+ namespaces.create!(id: 5, name: 'test1', path: 'test1')
+ test2 = namespaces.create!(id: 7, name: 'test2', path: 'test2')
+ namespaces.create!(id: 8, name: 'test3', path: 'test3', parent_id: 7)
+ namespaces.create!(id: 9, name: 'test4', path: 'test4')
+
+ # Simulate a situation where a user has had a chance to move a group to another parent
+ # before the background migration has had a chance to run
+ test2.update!(parent_id: 5)
+ ci_namespace_mirrors.create!(namespace_id: test2.id, traversal_ids: [5, 7])
+
+ subject.perform(5, 8)
+
+ expect(ci_namespace_mirrors.all).to contain_exactly(
+ an_object_having_attributes(namespace_id: 5, traversal_ids: [5]),
+ an_object_having_attributes(namespace_id: 7, traversal_ids: [5, 7]),
+ an_object_having_attributes(namespace_id: 8, traversal_ids: [5, 7, 8])
+ )
+ end
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/backfill_ci_project_mirrors_spec.rb b/spec/lib/gitlab/background_migration/backfill_ci_project_mirrors_spec.rb
new file mode 100644
index 00000000000..4eec83879e3
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/backfill_ci_project_mirrors_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BackfillCiProjectMirrors, :migration, schema: 20211208122201 do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:ci_project_mirrors) { table(:ci_project_mirrors) }
+
+ subject { described_class.new }
+
+ describe '#perform' do
+ it 'creates ci_project_mirrors for all projects in range' do
+ namespaces.create!(id: 10, name: 'namespace1', path: 'namespace1')
+ projects.create!(id: 5, namespace_id: 10, name: 'test1', path: 'test1')
+ projects.create!(id: 7, namespace_id: 10, name: 'test2', path: 'test2')
+ projects.create!(id: 8, namespace_id: 10, name: 'test3', path: 'test3')
+
+ subject.perform(5, 7)
+
+ expect(ci_project_mirrors.all).to contain_exactly(
+ an_object_having_attributes(project_id: 5, namespace_id: 10),
+ an_object_having_attributes(project_id: 7, namespace_id: 10)
+ )
+ end
+
+ it 'handles existing ci_project_mirrors gracefully' do
+ namespaces.create!(id: 10, name: 'namespace1', path: 'namespace1')
+ namespaces.create!(id: 11, name: 'namespace2', path: 'namespace2', parent_id: 10)
+ projects.create!(id: 5, namespace_id: 10, name: 'test1', path: 'test1')
+ projects.create!(id: 7, namespace_id: 11, name: 'test2', path: 'test2')
+ projects.create!(id: 8, namespace_id: 11, name: 'test3', path: 'test3')
+
+ # Simulate a situation where a user has had a chance to move a project to another namespace
+ # before the background migration has had a chance to run
+ ci_project_mirrors.create!(project_id: 7, namespace_id: 10)
+
+ subject.perform(5, 7)
+
+ expect(ci_project_mirrors.all).to contain_exactly(
+ an_object_having_attributes(project_id: 5, namespace_id: 10),
+ an_object_having_attributes(project_id: 7, namespace_id: 10)
+ )
+ end
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/backfill_incident_issue_escalation_statuses_spec.rb b/spec/lib/gitlab/background_migration/backfill_incident_issue_escalation_statuses_spec.rb
new file mode 100644
index 00000000000..242da383453
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/backfill_incident_issue_escalation_statuses_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BackfillIncidentIssueEscalationStatuses, schema: 20211214012507 do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:issues) { table(:issues) }
+ let(:issuable_escalation_statuses) { table(:incident_management_issuable_escalation_statuses) }
+
+ subject(:migration) { described_class.new }
+
+ it 'correctly backfills issuable escalation status records' do
+ namespace = namespaces.create!(name: 'foo', path: 'foo')
+ project = projects.create!(namespace_id: namespace.id)
+
+ issues.create!(project_id: project.id, title: 'issue 1', issue_type: 0) # non-incident issue
+ issues.create!(project_id: project.id, title: 'incident 1', issue_type: 1)
+ issues.create!(project_id: project.id, title: 'incident 2', issue_type: 1)
+ incident_issue_existing_status = issues.create!(project_id: project.id, title: 'incident 3', issue_type: 1)
+ issuable_escalation_statuses.create!(issue_id: incident_issue_existing_status.id)
+
+ migration.perform(1, incident_issue_existing_status.id)
+
+ expect(issuable_escalation_statuses.count).to eq(3)
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2_spec.rb b/spec/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2_spec.rb
index 446d62bbd2a..65f5f8368df 100644
--- a/spec/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::BackfillJiraTrackerDeploymentType2, :migration, schema: 20181228175414 do
+RSpec.describe Gitlab::BackgroundMigration::BackfillJiraTrackerDeploymentType2, :migration, schema: 20210301200959 do
let_it_be(:jira_integration_temp) { described_class::JiraServiceTemp }
let_it_be(:jira_tracker_data_temp) { described_class::JiraTrackerDataTemp }
let_it_be(:atlassian_host) { 'https://api.atlassian.net' }
diff --git a/spec/lib/gitlab/background_migration/backfill_project_updated_at_after_repository_storage_move_spec.rb b/spec/lib/gitlab/background_migration/backfill_project_updated_at_after_repository_storage_move_spec.rb
index 708e5e21dbe..ed44b819a97 100644
--- a/spec/lib/gitlab/background_migration/backfill_project_updated_at_after_repository_storage_move_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_project_updated_at_after_repository_storage_move_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::BackfillProjectUpdatedAtAfterRepositoryStorageMove, :migration, schema: 20210210093901 do
+RSpec.describe Gitlab::BackgroundMigration::BackfillProjectUpdatedAtAfterRepositoryStorageMove, :migration, schema: 20210301200959 do
let(:projects) { table(:projects) }
let(:project_repository_storage_moves) { table(:project_repository_storage_moves) }
let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
diff --git a/spec/lib/gitlab/background_migration/base_job_spec.rb b/spec/lib/gitlab/background_migration/base_job_spec.rb
new file mode 100644
index 00000000000..86abe4257e4
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/base_job_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BaseJob, '#perform' do
+ let(:connection) { double(:connection) }
+
+ let(:test_job_class) { Class.new(described_class) }
+ let(:test_job) { test_job_class.new(connection: connection) }
+
+ describe '#perform' do
+ it 'raises an error if not overridden by a subclass' do
+ expect { test_job.perform }.to raise_error(NotImplementedError, /must implement perform/)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/cleanup_concurrent_schema_change_spec.rb b/spec/lib/gitlab/background_migration/cleanup_concurrent_schema_change_spec.rb
deleted file mode 100644
index 2931b5e6dd3..00000000000
--- a/spec/lib/gitlab/background_migration/cleanup_concurrent_schema_change_spec.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# frozen_string_literal: true
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::CleanupConcurrentSchemaChange do
- describe '#perform' do
- it 'new column does not exist' do
- expect(subject).to receive(:column_exists?).with(:issues, :closed_at_timestamp).and_return(false)
- expect(subject).not_to receive(:column_exists?).with(:issues, :closed_at)
- expect(subject).not_to receive(:define_model_for)
-
- expect(subject.perform(:issues, :closed_at, :closed_at_timestamp)).to be_nil
- end
-
- it 'old column does not exist' do
- expect(subject).to receive(:column_exists?).with(:issues, :closed_at_timestamp).and_return(true)
- expect(subject).to receive(:column_exists?).with(:issues, :closed_at).and_return(false)
- expect(subject).not_to receive(:define_model_for)
-
- expect(subject.perform(:issues, :closed_at, :closed_at_timestamp)).to be_nil
- end
-
- it 'has both old and new columns' do
- expect(subject).to receive(:column_exists?).twice.and_return(true)
-
- expect { subject.perform('issues', :closed_at, :created_at) }.to raise_error(NotImplementedError)
- end
- end
-end
diff --git a/spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_spec.rb b/spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_spec.rb
index b83dc6fff7a..5b6722a3384 100644
--- a/spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_spec.rb
+++ b/spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::DropInvalidVulnerabilities, schema: 20181228175414 do
+RSpec.describe Gitlab::BackgroundMigration::DropInvalidVulnerabilities, schema: 20210301200959 do
let_it_be(:background_migration_jobs) { table(:background_migration_jobs) }
let_it_be(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
let_it_be(:users) { table(:users) }
diff --git a/spec/lib/gitlab/background_migration/encrypt_static_object_token_spec.rb b/spec/lib/gitlab/background_migration/encrypt_static_object_token_spec.rb
new file mode 100644
index 00000000000..94d9f4509a7
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/encrypt_static_object_token_spec.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::EncryptStaticObjectToken do
+ let(:users) { table(:users) }
+ let!(:user_without_tokens) { create_user!(name: 'notoken') }
+ let!(:user_with_plaintext_token_1) { create_user!(name: 'plaintext_1', token: 'token') }
+ let!(:user_with_plaintext_token_2) { create_user!(name: 'plaintext_2', token: 'TOKEN') }
+ let!(:user_with_plaintext_empty_token) { create_user!(name: 'plaintext_3', token: '') }
+ let!(:user_with_encrypted_token) { create_user!(name: 'encrypted', encrypted_token: 'encrypted') }
+ let!(:user_with_both_tokens) { create_user!(name: 'both', token: 'token2', encrypted_token: 'encrypted2') }
+
+ before do
+ allow(Gitlab::CryptoHelper).to receive(:aes256_gcm_encrypt).and_call_original
+ allow(Gitlab::CryptoHelper).to receive(:aes256_gcm_encrypt).with('token') { 'secure_token' }
+ allow(Gitlab::CryptoHelper).to receive(:aes256_gcm_encrypt).with('TOKEN') { 'SECURE_TOKEN' }
+ end
+
+ subject { described_class.new.perform(start_id, end_id) }
+
+ let(:start_id) { users.minimum(:id) }
+ let(:end_id) { users.maximum(:id) }
+
+ it 'backfills encrypted tokens to users with plaintext token only', :aggregate_failures do
+ subject
+
+ new_state = users.pluck(:id, :static_object_token, :static_object_token_encrypted).to_h do |row|
+ [row[0], [row[1], row[2]]]
+ end
+
+ expect(new_state.count).to eq(6)
+
+ expect(new_state[user_with_plaintext_token_1.id]).to match_array(%w[token secure_token])
+ expect(new_state[user_with_plaintext_token_2.id]).to match_array(%w[TOKEN SECURE_TOKEN])
+
+ expect(new_state[user_with_plaintext_empty_token.id]).to match_array(['', nil])
+ expect(new_state[user_without_tokens.id]).to match_array([nil, nil])
+ expect(new_state[user_with_both_tokens.id]).to match_array(%w[token2 encrypted2])
+ expect(new_state[user_with_encrypted_token.id]).to match_array([nil, 'encrypted'])
+ end
+
+ private
+
+ def create_user!(name:, token: nil, encrypted_token: nil)
+ email = "#{name}@example.com"
+
+ table(:users).create!(
+ name: name,
+ email: email,
+ username: name,
+ projects_limit: 0,
+ static_object_token: token,
+ static_object_token_encrypted: encrypted_token
+ )
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/fix_vulnerability_occurrences_with_hashes_as_raw_metadata_spec.rb b/spec/lib/gitlab/background_migration/fix_vulnerability_occurrences_with_hashes_as_raw_metadata_spec.rb
new file mode 100644
index 00000000000..af551861d47
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/fix_vulnerability_occurrences_with_hashes_as_raw_metadata_spec.rb
@@ -0,0 +1,232 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::FixVulnerabilityOccurrencesWithHashesAsRawMetadata, schema: 20211209203821 do
+ let(:users) { table(:users) }
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:scanners) { table(:vulnerability_scanners) }
+ let(:identifiers) { table(:vulnerability_identifiers) }
+ let(:findings) { table(:vulnerability_occurrences) }
+
+ let(:user) { users.create!(name: 'Test User', projects_limit: 10, username: 'test-user', email: '1') }
+
+ let(:namespace) do
+ namespaces.create!(
+ owner_id: user.id,
+ name: user.name,
+ path: user.username
+ )
+ end
+
+ let(:project) do
+ projects.create!(namespace_id: namespace.id, name: 'Test Project')
+ end
+
+ let(:scanner) do
+ scanners.create!(
+ project_id: project.id,
+ external_id: 'test-scanner',
+ name: 'Test Scanner',
+ vendor: 'GitLab'
+ )
+ end
+
+ let(:primary_identifier) do
+ identifiers.create!(
+ project_id: project.id,
+ external_type: 'cve',
+ name: 'CVE-2021-1234',
+ external_id: 'CVE-2021-1234',
+ fingerprint: '4c0fe491999f94701ee437588554ef56322ae276'
+ )
+ end
+
+ let(:finding) do
+ findings.create!(
+ raw_metadata: raw_metadata,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ primary_identifier_id: primary_identifier.id,
+ uuid: '4deb090a-bedf-5ccc-aa9a-ac8055a1ea81',
+ project_fingerprint: '1caa750a6dad769a18ad6f40b413b3b6ab1c8d77',
+ location_fingerprint: '6d1f35f53b065238abfcadc01336ce65d112a2bd',
+ name: 'name',
+ report_type: 7,
+ severity: 0,
+ confidence: 0,
+ detection_method: 'gitlab_security_report',
+ metadata_version: 'cluster_image_scanning:1.0',
+ created_at: "2021-12-10 14:27:42 -0600",
+ updated_at: "2021-12-10 14:27:42 -0600"
+ )
+ end
+
+ subject(:perform) { described_class.new.perform(finding.id, finding.id) }
+
+ context 'with stringified hash as raw_metadata' do
+ let(:raw_metadata) do
+ '{:location=>{"image"=>"index.docker.io/library/nginx:latest", "kubernetes_resource"=>{"namespace"=>"production", "kind"=>"deployment", "name"=>"nginx", "container_name"=>"nginx", "agent_id"=>"2"}, "dependency"=>{"package"=>{"name"=>"libc"}, "version"=>"v1.2.3"}}}'
+ end
+
+ it 'converts stringified hash to JSON' do
+ expect { perform }.not_to raise_error
+
+ result = finding.reload.raw_metadata
+ metadata = Oj.load(result)
+ expect(metadata).to eq(
+ {
+ 'location' => {
+ 'image' => 'index.docker.io/library/nginx:latest',
+ 'kubernetes_resource' => {
+ 'namespace' => 'production',
+ 'kind' => 'deployment',
+ 'name' => 'nginx',
+ 'container_name' => 'nginx',
+ 'agent_id' => '2'
+ },
+ 'dependency' => {
+ 'package' => { 'name' => 'libc' },
+ 'version' => 'v1.2.3'
+ }
+ }
+ }
+ )
+ end
+ end
+
+ context 'with valid raw_metadata' do
+ where(:raw_metadata) do
+ [
+ '{}',
+ '{"location":null}',
+ '{"location":{"image":"index.docker.io/library/nginx:latest","kubernetes_resource":{"namespace":"production","kind":"deployment","name":"nginx","container_name":"nginx","agent_id":"2"},"dependency":{"package":{"name":"libc"},"version":"v1.2.3"}}}'
+ ]
+ end
+
+ with_them do
+ it 'does not change the raw_metadata' do
+ expect { perform }.not_to raise_error
+
+ result = finding.reload.raw_metadata
+ expect(result).to eq(raw_metadata)
+ end
+ end
+ end
+
+ context 'when raw_metadata contains forbidden types' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:raw_metadata, :type) do
+ 'def foo; "bar"; end' | :def
+ '`cat somefile`' | :xstr
+ 'exec("cat /etc/passwd")' | :send
+ end
+
+ with_them do
+ it 'does not change the raw_metadata' do
+ expect(Gitlab::AppLogger).to receive(:error).with(message: "expected raw_metadata to be a hash", type: type)
+
+ expect { perform }.not_to raise_error
+
+ result = finding.reload.raw_metadata
+ expect(result).to eq(raw_metadata)
+ end
+ end
+ end
+
+ context 'when forbidden types are nested inside a hash' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:raw_metadata, :type) do
+ '{:location=>Env.fetch("SOME_VAR")}' | :send
+ '{:location=>{:image=>Env.fetch("SOME_VAR")}}' | :send
+ # rubocop:disable Lint/InterpolationCheck
+ '{"key"=>"value: #{send}"}' | :dstr
+ # rubocop:enable Lint/InterpolationCheck
+ end
+
+ with_them do
+ it 'does not change the raw_metadata' do
+ expect(Gitlab::AppLogger).to receive(:error).with(
+ message: "error parsing raw_metadata",
+ error: "value of a pair was an unexpected type",
+ type: type
+ )
+
+ expect { perform }.not_to raise_error
+
+ result = finding.reload.raw_metadata
+ expect(result).to eq(raw_metadata)
+ end
+ end
+ end
+
+ context 'when key is an unexpected type' do
+ let(:raw_metadata) { "{nil=>nil}" }
+
+ it 'logs error' do
+ expect(Gitlab::AppLogger).to receive(:error).with(
+ message: "error parsing raw_metadata",
+ error: "expected key to be either symbol, string, or integer",
+ type: :nil
+ )
+
+ expect { perform }.not_to raise_error
+ end
+ end
+
+ context 'when raw_metadata cannot be parsed' do
+ let(:raw_metadata) { "{" }
+
+ it 'logs error' do
+ expect(Gitlab::AppLogger).to receive(:error).with(message: "error parsing raw_metadata", error: "unexpected token $end")
+
+ expect { perform }.not_to raise_error
+ end
+ end
+
+ describe '#hash_from_s' do
+ subject { described_class.new.hash_from_s(input) }
+
+ context 'with valid input' do
+ let(:input) { '{:location=>{"image"=>"index.docker.io/library/nginx:latest", "kubernetes_resource"=>{"namespace"=>"production", "kind"=>"deployment", "name"=>"nginx", "container_name"=>"nginx", "agent_id"=>2}, "dependency"=>{"package"=>{"name"=>"libc"}, "version"=>"v1.2.3"}}}' }
+
+ it 'converts string to a hash' do
+ expect(subject).to eq({
+ location: {
+ 'image' => 'index.docker.io/library/nginx:latest',
+ 'kubernetes_resource' => {
+ 'namespace' => 'production',
+ 'kind' => 'deployment',
+ 'name' => 'nginx',
+ 'container_name' => 'nginx',
+ 'agent_id' => 2
+ },
+ 'dependency' => {
+ 'package' => { 'name' => 'libc' },
+ 'version' => 'v1.2.3'
+ }
+ }
+ })
+ end
+ end
+
+ using RSpec::Parameterized::TableSyntax
+
+ where(:input, :expected) do
+ '{}' | {}
+ '{"bool"=>true}' | { 'bool' => true }
+ '{"bool"=>false}' | { 'bool' => false }
+ '{"nil"=>nil}' | { 'nil' => nil }
+ '{"array"=>[1, "foo", nil]}' | { 'array' => [1, "foo", nil] }
+ '{foo: :bar}' | { foo: :bar }
+ '{foo: {bar: "bin"}}' | { foo: { bar: "bin" } }
+ end
+
+ with_them do
+ specify { expect(subject).to eq(expected) }
+ end
+ 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 7a524d1489a..43d41408e66 100644
--- a/spec/lib/gitlab/background_migration/job_coordinator_spec.rb
+++ b/spec/lib/gitlab/background_migration/job_coordinator_spec.rb
@@ -202,23 +202,50 @@ RSpec.describe Gitlab::BackgroundMigration::JobCoordinator do
end
describe '#perform' do
- let(:migration) { spy(:migration) }
- let(:connection) { double('connection') }
+ let(:connection) { double(:connection) }
before do
- stub_const('Gitlab::BackgroundMigration::Foo', migration)
-
allow(coordinator).to receive(:connection).and_return(connection)
end
- it 'performs a background migration with the configured shared connection' do
- expect(coordinator).to receive(:with_shared_connection).and_call_original
+ context 'when the background migration does not inherit from BaseJob' do
+ let(:migration_class) { Class.new }
+
+ before do
+ stub_const('Gitlab::BackgroundMigration::Foo', migration_class)
+ end
+
+ it 'performs a background migration with the configured shared connection' do
+ expect(coordinator).to receive(:with_shared_connection).and_call_original
+
+ expect_next_instance_of(migration_class) do |migration|
+ expect(migration).to receive(:perform).with(10, 20).once do
+ expect(Gitlab::Database::SharedModel.connection).to be(connection)
+ end
+ end
+
+ coordinator.perform('Foo', [10, 20])
+ end
+ end
+
+ context 'when the background migration inherits from BaseJob' do
+ let(:migration_class) { Class.new(::Gitlab::BackgroundMigration::BaseJob) }
+ let(:migration) { double(:migration) }
- expect(migration).to receive(:perform).with(10, 20).once do
- expect(Gitlab::Database::SharedModel.connection).to be(connection)
+ before do
+ stub_const('Gitlab::BackgroundMigration::Foo', migration_class)
end
- coordinator.perform('Foo', [10, 20])
+ it 'passes the correct connection when constructing the migration' do
+ expect(coordinator).to receive(:with_shared_connection).and_call_original
+
+ expect(migration_class).to receive(:new).with(connection: connection).and_return(migration)
+ expect(migration).to receive(:perform).with(10, 20).once do
+ expect(Gitlab::Database::SharedModel.connection).to be(connection)
+ end
+
+ coordinator.perform('Foo', [10, 20])
+ end
end
end
diff --git a/spec/lib/gitlab/background_migration/migrate_legacy_artifacts_spec.rb b/spec/lib/gitlab/background_migration/migrate_legacy_artifacts_spec.rb
deleted file mode 100644
index 5c93e69b5e5..00000000000
--- a/spec/lib/gitlab/background_migration/migrate_legacy_artifacts_spec.rb
+++ /dev/null
@@ -1,158 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::MigrateLegacyArtifacts, schema: 20210210093901 do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:pipelines) { table(:ci_pipelines) }
- let(:jobs) { table(:ci_builds) }
- let(:job_artifacts) { table(:ci_job_artifacts) }
-
- subject { described_class.new.perform(*range) }
-
- context 'when a pipeline exists' do
- let!(:namespace) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') }
- let!(:project) { projects.create!(name: 'gitlab', path: 'gitlab-ce', namespace_id: namespace.id) }
- let!(:pipeline) { pipelines.create!(project_id: project.id, ref: 'master', sha: 'adf43c3a') }
-
- context 'when a legacy artifacts exists' do
- let(:artifacts_expire_at) { 1.day.since.to_s }
- let(:file_store) { ::ObjectStorage::Store::REMOTE }
-
- let!(:job) do
- jobs.create!(
- commit_id: pipeline.id,
- project_id: project.id,
- status: :success,
- **artifacts_archive_attributes,
- **artifacts_metadata_attributes)
- end
-
- let(:artifacts_archive_attributes) do
- {
- artifacts_file: 'archive.zip',
- artifacts_file_store: file_store,
- artifacts_size: 123,
- artifacts_expire_at: artifacts_expire_at
- }
- end
-
- let(:artifacts_metadata_attributes) do
- {
- artifacts_metadata: 'metadata.gz',
- artifacts_metadata_store: file_store
- }
- end
-
- it 'has legacy artifacts' do
- expect(jobs.pluck('artifacts_file, artifacts_file_store, artifacts_size, artifacts_expire_at')).to eq([artifacts_archive_attributes.values])
- expect(jobs.pluck('artifacts_metadata, artifacts_metadata_store')).to eq([artifacts_metadata_attributes.values])
- end
-
- it 'does not have new artifacts yet' do
- expect(job_artifacts.count).to be_zero
- end
-
- context 'when the record exists inside of the range of a background migration' do
- let(:range) { [job.id, job.id] }
-
- it 'migrates a legacy artifact to ci_job_artifacts table' do
- expect { subject }.to change { job_artifacts.count }.by(2)
-
- expect(job_artifacts.order(:id).pluck('project_id, job_id, file_type, file_store, size, expire_at, file, file_sha256, file_location'))
- .to eq([[project.id,
- job.id,
- described_class::ARCHIVE_FILE_TYPE,
- file_store,
- artifacts_archive_attributes[:artifacts_size],
- artifacts_expire_at,
- 'archive.zip',
- nil,
- described_class::LEGACY_PATH_FILE_LOCATION],
- [project.id,
- job.id,
- described_class::METADATA_FILE_TYPE,
- file_store,
- nil,
- artifacts_expire_at,
- 'metadata.gz',
- nil,
- described_class::LEGACY_PATH_FILE_LOCATION]])
-
- expect(jobs.pluck('artifacts_file, artifacts_file_store, artifacts_size, artifacts_expire_at')).to eq([[nil, nil, nil, artifacts_expire_at]])
- expect(jobs.pluck('artifacts_metadata, artifacts_metadata_store')).to eq([[nil, nil]])
- end
-
- context 'when file_store is nil' do
- let(:file_store) { nil }
-
- it 'has nullified file_store in all legacy artifacts' do
- expect(jobs.pluck('artifacts_file_store, artifacts_metadata_store')).to eq([[nil, nil]])
- end
-
- it 'fills file_store by the value of local file store' do
- subject
-
- expect(job_artifacts.pluck('file_store')).to all(eq(::ObjectStorage::Store::LOCAL))
- end
- end
-
- context 'when new artifacts has already existed' do
- context 'when only archive.zip existed' do
- before do
- job_artifacts.create!(project_id: project.id, job_id: job.id, file_type: described_class::ARCHIVE_FILE_TYPE, size: 999, file: 'archive.zip')
- end
-
- it 'had archive.zip already' do
- expect(job_artifacts.exists?(job_id: job.id, file_type: described_class::ARCHIVE_FILE_TYPE)).to be_truthy
- end
-
- it 'migrates metadata' do
- expect { subject }.to change { job_artifacts.count }.by(1)
-
- expect(job_artifacts.exists?(job_id: job.id, file_type: described_class::METADATA_FILE_TYPE)).to be_truthy
- end
- end
-
- context 'when both archive and metadata existed' do
- before do
- job_artifacts.create!(project_id: project.id, job_id: job.id, file_type: described_class::ARCHIVE_FILE_TYPE, size: 999, file: 'archive.zip')
- job_artifacts.create!(project_id: project.id, job_id: job.id, file_type: described_class::METADATA_FILE_TYPE, size: 999, file: 'metadata.zip')
- end
-
- it 'does not migrate' do
- expect { subject }.not_to change { job_artifacts.count }
- end
- end
- end
- end
-
- context 'when the record exists outside of the range of a background migration' do
- let(:range) { [job.id + 1, job.id + 1] }
-
- it 'does not migrate' do
- expect { subject }.not_to change { job_artifacts.count }
- end
- end
- end
-
- context 'when the job does not have legacy artifacts' do
- let!(:job) { jobs.create!(commit_id: pipeline.id, project_id: project.id, status: :success) }
-
- it 'does not have the legacy artifacts in database' do
- expect(jobs.count).to eq(1)
- expect(jobs.pluck('artifacts_file, artifacts_file_store, artifacts_size, artifacts_expire_at')).to eq([[nil, nil, nil, nil]])
- expect(jobs.pluck('artifacts_metadata, artifacts_metadata_store')).to eq([[nil, nil]])
- end
-
- context 'when the record exists inside of the range of a background migration' do
- let(:range) { [job.id, job.id] }
-
- it 'does not migrate' do
- expect { subject }.not_to change { job_artifacts.count }
- end
- end
- end
- end
-end
diff --git a/spec/lib/gitlab/background_migration/migrate_u2f_webauthn_spec.rb b/spec/lib/gitlab/background_migration/migrate_u2f_webauthn_spec.rb
index ab183d01357..fc957a7c425 100644
--- a/spec/lib/gitlab/background_migration/migrate_u2f_webauthn_spec.rb
+++ b/spec/lib/gitlab/background_migration/migrate_u2f_webauthn_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require 'webauthn/u2f_migrator'
-RSpec.describe Gitlab::BackgroundMigration::MigrateU2fWebauthn, :migration, schema: 20181228175414 do
+RSpec.describe Gitlab::BackgroundMigration::MigrateU2fWebauthn, :migration, schema: 20210301200959 do
let(:users) { table(:users) }
let(:user) { users.create!(email: 'email@email.com', name: 'foo', username: 'foo', projects_limit: 0) }
diff --git a/spec/lib/gitlab/background_migration/move_container_registry_enabled_to_project_feature_spec.rb b/spec/lib/gitlab/background_migration/move_container_registry_enabled_to_project_feature_spec.rb
index b34a57f51f1..79b5567f5b3 100644
--- a/spec/lib/gitlab/background_migration/move_container_registry_enabled_to_project_feature_spec.rb
+++ b/spec/lib/gitlab/background_migration/move_container_registry_enabled_to_project_feature_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::MoveContainerRegistryEnabledToProjectFeature, :migration, schema: 2021_02_26_120851 do
+RSpec.describe Gitlab::BackgroundMigration::MoveContainerRegistryEnabledToProjectFeature, :migration, schema: 20210301200959 do
let(:enabled) { 20 }
let(:disabled) { 0 }
diff --git a/spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb b/spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb
index 25006e663ab..68fe8f39f59 100644
--- a/spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb
+++ b/spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::PopulateFindingUuidForVulnerabilityFeedback, schema: 20181228175414 do
+RSpec.describe Gitlab::BackgroundMigration::PopulateFindingUuidForVulnerabilityFeedback, schema: 20210301200959 do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:users) { table(:users) }
diff --git a/spec/lib/gitlab/background_migration/populate_issue_email_participants_spec.rb b/spec/lib/gitlab/background_migration/populate_issue_email_participants_spec.rb
index a03a11489b5..b00eb185b34 100644
--- a/spec/lib/gitlab/background_migration/populate_issue_email_participants_spec.rb
+++ b/spec/lib/gitlab/background_migration/populate_issue_email_participants_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::PopulateIssueEmailParticipants, schema: 20181228175414 do
+RSpec.describe Gitlab::BackgroundMigration::PopulateIssueEmailParticipants, schema: 20210301200959 do
let!(:namespace) { table(:namespaces).create!(name: 'namespace', path: 'namespace') }
let!(:project) { table(:projects).create!(id: 1, namespace_id: namespace.id) }
let!(:issue1) { table(:issues).create!(id: 1, project_id: project.id, service_desk_reply_to: "a@gitlab.com") }
diff --git a/spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb b/spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb
index 4cdb56d3d3b..a54c840dd8e 100644
--- a/spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb
+++ b/spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb
@@ -2,82 +2,124 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrencesUuid, schema: 20181228175414 do
+def create_background_migration_job(ids, status)
+ proper_status = case status
+ when :pending
+ Gitlab::Database::BackgroundMigrationJob.statuses['pending']
+ when :succeeded
+ Gitlab::Database::BackgroundMigrationJob.statuses['succeeded']
+ else
+ raise ArgumentError
+ end
+
+ background_migration_jobs.create!(
+ class_name: 'RecalculateVulnerabilitiesOccurrencesUuid',
+ arguments: Array(ids),
+ status: proper_status,
+ created_at: Time.now.utc
+ )
+end
+
+RSpec.describe Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrencesUuid, schema: 20211124132705 do
+ let(:background_migration_jobs) { table(:background_migration_jobs) }
+ let(:pending_jobs) { background_migration_jobs.where(status: Gitlab::Database::BackgroundMigrationJob.statuses['pending']) }
+ let(:succeeded_jobs) { background_migration_jobs.where(status: Gitlab::Database::BackgroundMigrationJob.statuses['succeeded']) }
let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
let(:users) { table(:users) }
let(:user) { create_user! }
let(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) }
let(:scanners) { table(:vulnerability_scanners) }
let(:scanner) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
- let(:different_scanner) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') }
+ let(:scanner2) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') }
let(:vulnerabilities) { table(:vulnerabilities) }
- let(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
+ let(:vulnerability_findings) { table(:vulnerability_occurrences) }
+ let(:vulnerability_finding_pipelines) { table(:vulnerability_occurrence_pipelines) }
+ let(:vulnerability_finding_signatures) { table(:vulnerability_finding_signatures) }
let(:vulnerability_identifiers) { table(:vulnerability_identifiers) }
- let(:vulnerability_identifier) do
+ let(:identifier_1) { 'identifier-1' }
+ let!(:vulnerability_identifier) do
vulnerability_identifiers.create!(
project_id: project.id,
- external_type: 'uuid-v5',
- external_id: 'uuid-v5',
- fingerprint: Gitlab::Database::ShaAttribute.serialize('7e394d1b1eb461a7406d7b1e08f057a1cf11287a'),
- name: 'Identifier for UUIDv5')
+ external_type: identifier_1,
+ external_id: identifier_1,
+ fingerprint: Gitlab::Database::ShaAttribute.serialize('ff9ef548a6e30a0462795d916f3f00d1e2b082ca'),
+ name: 'Identifier 1')
end
- let(:different_vulnerability_identifier) do
+ let(:identifier_2) { 'identifier-2' }
+ let!(:vulnerability_identfier2) do
vulnerability_identifiers.create!(
project_id: project.id,
- external_type: 'uuid-v4',
- external_id: 'uuid-v4',
- fingerprint: Gitlab::Database::ShaAttribute.serialize('772da93d34a1ba010bcb5efa9fb6f8e01bafcc89'),
- name: 'Identifier for UUIDv4')
+ external_type: identifier_2,
+ external_id: identifier_2,
+ fingerprint: Gitlab::Database::ShaAttribute.serialize('4299e8ddd819f9bde9cfacf45716724c17b5ddf7'),
+ name: 'Identifier 2')
end
- let!(:vulnerability_for_uuidv4) do
- create_vulnerability!(
- project_id: project.id,
- author_id: user.id
- )
- end
-
- let!(:vulnerability_for_uuidv5) do
- create_vulnerability!(
+ let(:identifier_3) { 'identifier-3' }
+ let!(:vulnerability_identifier3) do
+ vulnerability_identifiers.create!(
project_id: project.id,
- author_id: user.id
- )
+ external_type: identifier_3,
+ external_id: identifier_3,
+ fingerprint: Gitlab::Database::ShaAttribute.serialize('8e91632f9c6671e951834a723ee221c44cc0d844'),
+ name: 'Identifier 3')
end
- let(:known_uuid_v5) { "77211ed6-7dff-5f6b-8c9a-da89ad0a9b60" }
let(:known_uuid_v4) { "b3cc2518-5446-4dea-871c-89d5e999c1ac" }
- let(:desired_uuid_v5) { "3ca8ad45-6344-508b-b5e3-306a3bd6c6ba" }
+ let(:known_uuid_v5) { "05377088-dc26-5161-920e-52a7159fdaa1" }
+ let(:desired_uuid_v5) { "f3e9a23f-9181-54bf-a5ab-c5bc7a9b881a" }
- subject { described_class.new.perform(finding.id, finding.id) }
+ subject { described_class.new.perform(start_id, end_id) }
+
+ context 'when the migration is disabled by the feature flag' do
+ let(:start_id) { 1 }
+ let(:end_id) { 1001 }
+
+ before do
+ stub_feature_flags(migrate_vulnerability_finding_uuids: false)
+ end
+
+ it 'logs the info message and does not run the migration' do
+ expect_next_instance_of(Gitlab::BackgroundMigration::Logger) do |instance|
+ expect(instance).to receive(:info).once.with(message: 'Migration is disabled by the feature flag',
+ migrator: 'RecalculateVulnerabilitiesOccurrencesUuid',
+ start_id: start_id,
+ end_id: end_id)
+ end
+
+ subject
+ end
+ end
context "when finding has a UUIDv4" do
before do
@uuid_v4 = create_finding!(
- vulnerability_id: vulnerability_for_uuidv4.id,
+ vulnerability_id: nil,
project_id: project.id,
- scanner_id: different_scanner.id,
- primary_identifier_id: different_vulnerability_identifier.id,
+ scanner_id: scanner2.id,
+ primary_identifier_id: vulnerability_identfier2.id,
report_type: 0, # "sast"
location_fingerprint: Gitlab::Database::ShaAttribute.serialize("fa18f432f1d56675f4098d318739c3cd5b14eb3e"),
uuid: known_uuid_v4
)
end
- let(:finding) { @uuid_v4 }
+ let(:start_id) { @uuid_v4.id }
+ let(:end_id) { @uuid_v4.id }
it "replaces it with UUIDv5" do
- expect(vulnerabilities_findings.pluck(:uuid)).to eq([known_uuid_v4])
+ expect(vulnerability_findings.pluck(:uuid)).to match_array([known_uuid_v4])
subject
- expect(vulnerabilities_findings.pluck(:uuid)).to eq([desired_uuid_v5])
+ expect(vulnerability_findings.pluck(:uuid)).to match_array([desired_uuid_v5])
end
it 'logs recalculation' do
expect_next_instance_of(Gitlab::BackgroundMigration::Logger) do |instance|
- expect(instance).to receive(:info).once
+ expect(instance).to receive(:info).twice
end
subject
@@ -87,7 +129,7 @@ RSpec.describe Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrence
context "when finding has a UUIDv5" do
before do
@uuid_v5 = create_finding!(
- vulnerability_id: vulnerability_for_uuidv5.id,
+ vulnerability_id: nil,
project_id: project.id,
scanner_id: scanner.id,
primary_identifier_id: vulnerability_identifier.id,
@@ -97,40 +139,340 @@ RSpec.describe Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrence
)
end
- let(:finding) { @uuid_v5 }
+ let(:start_id) { @uuid_v5.id }
+ let(:end_id) { @uuid_v5.id }
it "stays the same" do
- expect(vulnerabilities_findings.pluck(:uuid)).to eq([known_uuid_v5])
+ expect(vulnerability_findings.pluck(:uuid)).to match_array([known_uuid_v5])
subject
- expect(vulnerabilities_findings.pluck(:uuid)).to eq([known_uuid_v5])
+ expect(vulnerability_findings.pluck(:uuid)).to match_array([known_uuid_v5])
+ end
+ end
+
+ context 'if a duplicate UUID would be generated' do # rubocop: disable RSpec/MultipleMemoizedHelpers
+ let(:v1) do
+ create_vulnerability!(
+ project_id: project.id,
+ author_id: user.id
+ )
+ end
+
+ let!(:finding_with_incorrect_uuid) do
+ create_finding!(
+ vulnerability_id: v1.id,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ primary_identifier_id: vulnerability_identifier.id,
+ report_type: 0, # "sast"
+ location_fingerprint: Gitlab::Database::ShaAttribute.serialize('ca41a2544e941a007a73a666cb0592b255316ab8'), # sha1('youshouldntusethis')
+ uuid: 'bd95c085-71aa-51d7-9bb6-08ae669c262e'
+ )
+ end
+
+ let(:v2) do
+ create_vulnerability!(
+ project_id: project.id,
+ author_id: user.id
+ )
+ end
+
+ let!(:finding_with_correct_uuid) do
+ create_finding!(
+ vulnerability_id: v2.id,
+ project_id: project.id,
+ primary_identifier_id: vulnerability_identifier.id,
+ scanner_id: scanner2.id,
+ report_type: 0, # "sast"
+ location_fingerprint: Gitlab::Database::ShaAttribute.serialize('ca41a2544e941a007a73a666cb0592b255316ab8'), # sha1('youshouldntusethis')
+ uuid: '91984483-5efe-5215-b471-d524ac5792b1'
+ )
+ end
+
+ let(:v3) do
+ create_vulnerability!(
+ project_id: project.id,
+ author_id: user.id
+ )
+ end
+
+ let!(:finding_with_incorrect_uuid2) do
+ create_finding!(
+ vulnerability_id: v3.id,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ primary_identifier_id: vulnerability_identfier2.id,
+ report_type: 0, # "sast"
+ location_fingerprint: Gitlab::Database::ShaAttribute.serialize('ca41a2544e941a007a73a666cb0592b255316ab8'), # sha1('youshouldntusethis')
+ uuid: '00000000-1111-2222-3333-444444444444'
+ )
+ end
+
+ let(:v4) do
+ create_vulnerability!(
+ project_id: project.id,
+ author_id: user.id
+ )
+ end
+
+ let!(:finding_with_correct_uuid2) do
+ create_finding!(
+ vulnerability_id: v4.id,
+ project_id: project.id,
+ scanner_id: scanner2.id,
+ primary_identifier_id: vulnerability_identfier2.id,
+ report_type: 0, # "sast"
+ location_fingerprint: Gitlab::Database::ShaAttribute.serialize('ca41a2544e941a007a73a666cb0592b255316ab8'), # sha1('youshouldntusethis')
+ uuid: '1edd751e-ef9a-5391-94db-a832c8635bfc'
+ )
+ end
+
+ let!(:finding_with_incorrect_uuid3) do
+ create_finding!(
+ vulnerability_id: nil,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ primary_identifier_id: vulnerability_identifier3.id,
+ report_type: 0, # "sast"
+ location_fingerprint: Gitlab::Database::ShaAttribute.serialize('ca41a2544e941a007a73a666cb0592b255316ab8'), # sha1('youshouldntusethis')
+ uuid: '22222222-3333-4444-5555-666666666666'
+ )
+ end
+
+ let!(:duplicate_not_in_the_same_batch) do
+ create_finding!(
+ id: 99999,
+ vulnerability_id: nil,
+ project_id: project.id,
+ scanner_id: scanner2.id,
+ primary_identifier_id: vulnerability_identifier3.id,
+ report_type: 0, # "sast"
+ location_fingerprint: Gitlab::Database::ShaAttribute.serialize('ca41a2544e941a007a73a666cb0592b255316ab8'), # sha1('youshouldntusethis')
+ uuid: '4564f9d5-3c6b-5cc3-af8c-7c25285362a7'
+ )
+ end
+
+ let(:start_id) { finding_with_incorrect_uuid.id }
+ let(:end_id) { finding_with_incorrect_uuid3.id }
+
+ before do
+ 4.times do
+ create_finding_pipeline!(project_id: project.id, finding_id: finding_with_incorrect_uuid.id)
+ create_finding_pipeline!(project_id: project.id, finding_id: finding_with_correct_uuid.id)
+ create_finding_pipeline!(project_id: project.id, finding_id: finding_with_incorrect_uuid2.id)
+ create_finding_pipeline!(project_id: project.id, finding_id: finding_with_correct_uuid2.id)
+ end
+ end
+
+ it 'drops duplicates and related records', :aggregate_failures do
+ expect(vulnerability_findings.pluck(:id)).to match_array([
+ finding_with_correct_uuid.id, finding_with_incorrect_uuid.id, finding_with_correct_uuid2.id, finding_with_incorrect_uuid2.id, finding_with_incorrect_uuid3.id, duplicate_not_in_the_same_batch.id
+ ])
+
+ expect { subject }.to change(vulnerability_finding_pipelines, :count).from(16).to(8)
+ .and change(vulnerability_findings, :count).from(6).to(3)
+ .and change(vulnerabilities, :count).from(4).to(2)
+
+ expect(vulnerability_findings.pluck(:id)).to match_array([finding_with_incorrect_uuid.id, finding_with_incorrect_uuid2.id, finding_with_incorrect_uuid3.id])
+ end
+
+ context 'if there are conflicting UUID values within the batch' do # rubocop: disable RSpec/MultipleMemoizedHelpers
+ let(:end_id) { finding_with_broken_data_integrity.id }
+ let(:vulnerability_5) { create_vulnerability!(project_id: project.id, author_id: user.id) }
+ let(:different_project) { table(:projects).create!(namespace_id: namespace.id) }
+ let!(:identifier_with_broken_data_integrity) do
+ vulnerability_identifiers.create!(
+ project_id: different_project.id,
+ external_type: identifier_2,
+ external_id: identifier_2,
+ fingerprint: Gitlab::Database::ShaAttribute.serialize('4299e8ddd819f9bde9cfacf45716724c17b5ddf7'),
+ name: 'Identifier 2')
+ end
+
+ let(:finding_with_broken_data_integrity) do
+ create_finding!(
+ vulnerability_id: vulnerability_5,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ primary_identifier_id: identifier_with_broken_data_integrity.id,
+ report_type: 0, # "sast"
+ location_fingerprint: Gitlab::Database::ShaAttribute.serialize('ca41a2544e941a007a73a666cb0592b255316ab8'), # sha1('youshouldntusethis')
+ uuid: SecureRandom.uuid
+ )
+ end
+
+ it 'deletes the conflicting record' do
+ expect { subject }.to change { vulnerability_findings.find_by_id(finding_with_broken_data_integrity.id) }.to(nil)
+ end
+ end
+
+ context 'if a conflicting UUID is found during the migration' do # rubocop:disable RSpec/MultipleMemoizedHelpers
+ let(:finding_class) { Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrencesUuid::VulnerabilitiesFinding }
+ let(:uuid) { '4564f9d5-3c6b-5cc3-af8c-7c25285362a7' }
+
+ before do
+ exception = ActiveRecord::RecordNotUnique.new("(uuid)=(#{uuid})")
+
+ call_count = 0
+ allow(::Gitlab::Database::BulkUpdate).to receive(:execute) do
+ call_count += 1
+ call_count.eql?(1) ? raise(exception) : {}
+ end
+
+ allow(finding_class).to receive(:find_by).with(uuid: uuid).and_return(duplicate_not_in_the_same_batch)
+ end
+
+ it 'retries the recalculation' do
+ subject
+
+ expect(Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrencesUuid::VulnerabilitiesFinding).to have_received(:find_by).with(uuid: uuid).once
+ end
+
+ it 'logs the conflict' do
+ expect_next_instance_of(Gitlab::BackgroundMigration::Logger) do |instance|
+ expect(instance).to receive(:info).exactly(6).times
+ end
+
+ subject
+ end
+
+ it 'marks the job as done' do
+ create_background_migration_job([start_id, end_id], :pending)
+
+ subject
+
+ expect(pending_jobs.count).to eq(0)
+ expect(succeeded_jobs.count).to eq(1)
+ end
+ end
+
+ it 'logs an exception if a different uniquness problem was found' do
+ exception = ActiveRecord::RecordNotUnique.new("Totally not an UUID uniqueness problem")
+ allow(::Gitlab::Database::BulkUpdate).to receive(:execute).and_raise(exception)
+ allow(Gitlab::ErrorTracking).to receive(:track_and_raise_exception)
+
+ subject
+
+ expect(Gitlab::ErrorTracking).to have_received(:track_and_raise_exception).with(exception).once
+ end
+
+ it 'logs a duplicate found message' do
+ expect_next_instance_of(Gitlab::BackgroundMigration::Logger) do |instance|
+ expect(instance).to receive(:info).exactly(3).times
+ end
+
+ subject
+ end
+ end
+
+ context 'when finding has a signature' do
+ before do
+ @f1 = create_finding!(
+ vulnerability_id: nil,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ primary_identifier_id: vulnerability_identifier.id,
+ report_type: 0, # "sast"
+ location_fingerprint: Gitlab::Database::ShaAttribute.serialize('ca41a2544e941a007a73a666cb0592b255316ab8'), # sha1('youshouldntusethis')
+ uuid: 'd15d774d-e4b1-5a1b-929b-19f2a53e35ec'
+ )
+
+ vulnerability_finding_signatures.create!(
+ finding_id: @f1.id,
+ algorithm_type: 2, # location
+ signature_sha: Gitlab::Database::ShaAttribute.serialize('57d4e05205f6462a73f039a5b2751aa1ab344e6e') # sha1('youshouldusethis')
+ )
+
+ vulnerability_finding_signatures.create!(
+ finding_id: @f1.id,
+ algorithm_type: 1, # hash
+ signature_sha: Gitlab::Database::ShaAttribute.serialize('c554d8d8df1a7a14319eafdaae24af421bf5b587') # sha1('andnotthis')
+ )
+
+ @f2 = create_finding!(
+ vulnerability_id: nil,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ primary_identifier_id: vulnerability_identfier2.id,
+ report_type: 0, # "sast"
+ location_fingerprint: Gitlab::Database::ShaAttribute.serialize('ca41a2544e941a007a73a666cb0592b255316ab8'), # sha1('youshouldntusethis')
+ uuid: '4be029b5-75e5-5ac0-81a2-50ab41726135'
+ )
+
+ vulnerability_finding_signatures.create!(
+ finding_id: @f2.id,
+ algorithm_type: 2, # location
+ signature_sha: Gitlab::Database::ShaAttribute.serialize('57d4e05205f6462a73f039a5b2751aa1ab344e6e') # sha1('youshouldusethis')
+ )
+
+ vulnerability_finding_signatures.create!(
+ finding_id: @f2.id,
+ algorithm_type: 1, # hash
+ signature_sha: Gitlab::Database::ShaAttribute.serialize('c554d8d8df1a7a14319eafdaae24af421bf5b587') # sha1('andnotthis')
+ )
+ end
+
+ let(:start_id) { @f1.id }
+ let(:end_id) { @f2.id }
+
+ let(:uuids_before) { [@f1.uuid, @f2.uuid] }
+ let(:uuids_after) { %w[d3b60ddd-d312-5606-b4d3-ad058eebeacb 349d9bec-c677-5530-a8ac-5e58889c3b1a] }
+
+ it 'is recalculated using signature' do
+ expect(vulnerability_findings.pluck(:uuid)).to match_array(uuids_before)
+
+ subject
+
+ expect(vulnerability_findings.pluck(:uuid)).to match_array(uuids_after)
+ end
+ end
+
+ context 'if all records are removed before the job ran' do
+ let(:start_id) { 1 }
+ let(:end_id) { 9 }
+
+ before do
+ create_background_migration_job([start_id, end_id], :pending)
+ end
+
+ it 'does not error out' do
+ expect { subject }.not_to raise_error
+ end
+
+ it 'marks the job as done' do
+ subject
+
+ expect(pending_jobs.count).to eq(0)
+ expect(succeeded_jobs.count).to eq(1)
end
end
context 'when recalculation fails' do
before do
@uuid_v4 = create_finding!(
- vulnerability_id: vulnerability_for_uuidv4.id,
+ vulnerability_id: nil,
project_id: project.id,
- scanner_id: different_scanner.id,
- primary_identifier_id: different_vulnerability_identifier.id,
+ scanner_id: scanner2.id,
+ primary_identifier_id: vulnerability_identfier2.id,
report_type: 0, # "sast"
location_fingerprint: Gitlab::Database::ShaAttribute.serialize("fa18f432f1d56675f4098d318739c3cd5b14eb3e"),
uuid: known_uuid_v4
)
- allow(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception)
+ allow(Gitlab::ErrorTracking).to receive(:track_and_raise_exception)
allow(::Gitlab::Database::BulkUpdate).to receive(:execute).and_raise(expected_error)
end
- let(:finding) { @uuid_v4 }
+ let(:start_id) { @uuid_v4.id }
+ let(:end_id) { @uuid_v4.id }
let(:expected_error) { RuntimeError.new }
it 'captures the errors and does not crash entirely' do
expect { subject }.not_to raise_error
- expect(Gitlab::ErrorTracking).to have_received(:track_and_raise_for_dev_exception).with(expected_error).once
+ allow(Gitlab::ErrorTracking).to receive(:track_and_raise_exception)
+ expect(Gitlab::ErrorTracking).to have_received(:track_and_raise_exception).with(expected_error).once
end
end
@@ -149,25 +491,28 @@ RSpec.describe Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrence
# rubocop:disable Metrics/ParameterLists
def create_finding!(
+ id: nil,
vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:,
name: "test", severity: 7, confidence: 7, report_type: 0,
project_fingerprint: '123qweasdzxc', location_fingerprint: 'test',
metadata_version: 'test', raw_metadata: 'test', uuid: 'test')
- vulnerabilities_findings.create!(
- vulnerability_id: vulnerability_id,
- project_id: project_id,
- name: name,
- severity: severity,
- confidence: confidence,
- report_type: report_type,
- project_fingerprint: project_fingerprint,
- scanner_id: scanner.id,
- primary_identifier_id: vulnerability_identifier.id,
- location_fingerprint: location_fingerprint,
- metadata_version: metadata_version,
- raw_metadata: raw_metadata,
- uuid: uuid
- )
+ vulnerability_findings.create!({
+ id: id,
+ vulnerability_id: vulnerability_id,
+ project_id: project_id,
+ name: name,
+ severity: severity,
+ confidence: confidence,
+ report_type: report_type,
+ project_fingerprint: project_fingerprint,
+ scanner_id: scanner_id,
+ primary_identifier_id: primary_identifier_id,
+ location_fingerprint: location_fingerprint,
+ metadata_version: metadata_version,
+ raw_metadata: raw_metadata,
+ uuid: uuid
+ }.compact
+ )
end
# rubocop:enable Metrics/ParameterLists
@@ -181,4 +526,9 @@ RSpec.describe Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrence
confirmed_at: confirmed_at
)
end
+
+ def create_finding_pipeline!(project_id:, finding_id:)
+ pipeline = table(:ci_pipelines).create!(project_id: project_id)
+ vulnerability_finding_pipelines.create!(pipeline_id: pipeline.id, occurrence_id: finding_id)
+ end
end
diff --git a/spec/lib/gitlab/background_migration/remove_duplicate_services_spec.rb b/spec/lib/gitlab/background_migration/remove_duplicate_services_spec.rb
deleted file mode 100644
index afcdaaf1cb8..00000000000
--- a/spec/lib/gitlab/background_migration/remove_duplicate_services_spec.rb
+++ /dev/null
@@ -1,121 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::RemoveDuplicateServices, :migration, schema: 20181228175414 do
- let_it_be(:users) { table(:users) }
- let_it_be(:namespaces) { table(:namespaces) }
- let_it_be(:projects) { table(:projects) }
- let_it_be(:services) { table(:services) }
-
- let_it_be(:alerts_service_data) { table(:alerts_service_data) }
- let_it_be(:chat_names) { table(:chat_names) }
- let_it_be(:issue_tracker_data) { table(:issue_tracker_data) }
- let_it_be(:jira_tracker_data) { table(:jira_tracker_data) }
- let_it_be(:open_project_tracker_data) { table(:open_project_tracker_data) }
- let_it_be(:slack_integrations) { table(:slack_integrations) }
- let_it_be(:web_hooks) { table(:web_hooks) }
-
- let_it_be(:data_tables) do
- [alerts_service_data, chat_names, issue_tracker_data, jira_tracker_data, open_project_tracker_data, slack_integrations, web_hooks]
- end
-
- let!(:user) { users.create!(id: 1, projects_limit: 100) }
- let!(:namespace) { namespaces.create!(id: 1, name: 'group', path: 'group') }
-
- # project without duplicate services
- let!(:project1) { projects.create!(id: 1, namespace_id: namespace.id) }
- let!(:service1) { services.create!(id: 1, project_id: project1.id, type: 'AsanaService') }
- let!(:service2) { services.create!(id: 2, project_id: project1.id, type: 'JiraService') }
- let!(:service3) { services.create!(id: 3, project_id: project1.id, type: 'SlackService') }
-
- # project with duplicate services
- let!(:project2) { projects.create!(id: 2, namespace_id: namespace.id) }
- let!(:service4) { services.create!(id: 4, project_id: project2.id, type: 'AsanaService') }
- let!(:service5) { services.create!(id: 5, project_id: project2.id, type: 'JiraService') }
- let!(:service6) { services.create!(id: 6, project_id: project2.id, type: 'JiraService') }
- let!(:service7) { services.create!(id: 7, project_id: project2.id, type: 'SlackService') }
- let!(:service8) { services.create!(id: 8, project_id: project2.id, type: 'SlackService') }
- let!(:service9) { services.create!(id: 9, project_id: project2.id, type: 'SlackService') }
-
- # project with duplicate services and dependant records
- let!(:project3) { projects.create!(id: 3, namespace_id: namespace.id) }
- let!(:service10) { services.create!(id: 10, project_id: project3.id, type: 'AlertsService') }
- let!(:service11) { services.create!(id: 11, project_id: project3.id, type: 'AlertsService') }
- let!(:service12) { services.create!(id: 12, project_id: project3.id, type: 'SlashCommandsService') }
- let!(:service13) { services.create!(id: 13, project_id: project3.id, type: 'SlashCommandsService') }
- let!(:service14) { services.create!(id: 14, project_id: project3.id, type: 'IssueTrackerService') }
- let!(:service15) { services.create!(id: 15, project_id: project3.id, type: 'IssueTrackerService') }
- let!(:service16) { services.create!(id: 16, project_id: project3.id, type: 'JiraService') }
- let!(:service17) { services.create!(id: 17, project_id: project3.id, type: 'JiraService') }
- let!(:service18) { services.create!(id: 18, project_id: project3.id, type: 'OpenProjectService') }
- let!(:service19) { services.create!(id: 19, project_id: project3.id, type: 'OpenProjectService') }
- let!(:service20) { services.create!(id: 20, project_id: project3.id, type: 'SlackService') }
- let!(:service21) { services.create!(id: 21, project_id: project3.id, type: 'SlackService') }
- let!(:dependant_records) do
- alerts_service_data.create!(id: 1, service_id: service10.id)
- alerts_service_data.create!(id: 2, service_id: service11.id)
- chat_names.create!(id: 1, service_id: service12.id, user_id: user.id, team_id: 'team1', chat_id: 'chat1')
- chat_names.create!(id: 2, service_id: service13.id, user_id: user.id, team_id: 'team2', chat_id: 'chat2')
- issue_tracker_data.create!(id: 1, service_id: service14.id)
- issue_tracker_data.create!(id: 2, service_id: service15.id)
- jira_tracker_data.create!(id: 1, service_id: service16.id)
- jira_tracker_data.create!(id: 2, service_id: service17.id)
- open_project_tracker_data.create!(id: 1, service_id: service18.id)
- open_project_tracker_data.create!(id: 2, service_id: service19.id)
- slack_integrations.create!(id: 1, service_id: service20.id, user_id: user.id, team_id: 'team1', team_name: 'team1', alias: 'alias1')
- slack_integrations.create!(id: 2, service_id: service21.id, user_id: user.id, team_id: 'team2', team_name: 'team2', alias: 'alias2')
- web_hooks.create!(id: 1, service_id: service20.id)
- web_hooks.create!(id: 2, service_id: service21.id)
- end
-
- # project without services
- let!(:project4) { projects.create!(id: 4, namespace_id: namespace.id) }
-
- it 'removes duplicate services and dependant records' do
- # Determine which services we expect to keep
- expected_services = projects.pluck(:id).each_with_object({}) do |project_id, map|
- project_services = services.where(project_id: project_id)
- types = project_services.distinct.pluck(:type)
-
- map[project_id] = types.map { |type| project_services.where(type: type).take!.id }
- end
-
- expect do
- subject.perform(project2.id, project3.id)
- end.to change { services.count }.from(21).to(12)
-
- services1 = services.where(project_id: project1.id)
- expect(services1.count).to be(3)
- expect(services1.pluck(:type)).to contain_exactly('AsanaService', 'JiraService', 'SlackService')
- expect(services1.pluck(:id)).to contain_exactly(*expected_services[project1.id])
-
- services2 = services.where(project_id: project2.id)
- expect(services2.count).to be(3)
- expect(services2.pluck(:type)).to contain_exactly('AsanaService', 'JiraService', 'SlackService')
- expect(services2.pluck(:id)).to contain_exactly(*expected_services[project2.id])
-
- services3 = services.where(project_id: project3.id)
- expect(services3.count).to be(6)
- expect(services3.pluck(:type)).to contain_exactly('AlertsService', 'SlashCommandsService', 'IssueTrackerService', 'JiraService', 'OpenProjectService', 'SlackService')
- expect(services3.pluck(:id)).to contain_exactly(*expected_services[project3.id])
-
- kept_services = expected_services.values.flatten
- data_tables.each do |table|
- expect(table.count).to be(1)
- expect(kept_services).to include(table.pluck(:service_id).first)
- end
- end
-
- it 'does not delete services without duplicates' do
- expect do
- subject.perform(project1.id, project4.id)
- end.not_to change { services.count }
- end
-
- it 'only deletes duplicate services for the current batch' do
- expect do
- subject.perform(project2.id)
- end.to change { services.count }.by(-3)
- end
-end
diff --git a/spec/lib/gitlab/background_migration/remove_vulnerability_finding_links_spec.rb b/spec/lib/gitlab/background_migration/remove_vulnerability_finding_links_spec.rb
index fadee64886f..ccf96e036ae 100644
--- a/spec/lib/gitlab/background_migration/remove_vulnerability_finding_links_spec.rb
+++ b/spec/lib/gitlab/background_migration/remove_vulnerability_finding_links_spec.rb
@@ -41,8 +41,8 @@ RSpec.describe Gitlab::BackgroundMigration::RemoveVulnerabilityFindingLinks, :mi
# vulnerability finding links
let!(:links) do
{
- findings.first => Array.new(5) { |id| finding_links.create!(vulnerability_occurrence_id: findings.first.id, name: "Link Name 1", url: "link_url1.example") },
- findings.second => Array.new(5) { |id| finding_links.create!(vulnerability_occurrence_id: findings.second.id, name: "Link Name 2", url: "link_url2.example") }
+ findings.first => Array.new(5) { |id| finding_links.create!(vulnerability_occurrence_id: findings.first.id, name: "Link Name 1", url: "link_url1_#{id}.example") },
+ findings.second => Array.new(5) { |id| finding_links.create!(vulnerability_occurrence_id: findings.second.id, name: "Link Name 2", url: "link_url2_#{id}.example") }
}
end
diff --git a/spec/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer_spec.rb b/spec/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer_spec.rb
index 5c197526a55..17fe25c7f71 100644
--- a/spec/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer_spec.rb
+++ b/spec/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::WrongfullyConfirmedEmailUnconfirmer, schema: 20181228175414 do
+RSpec.describe Gitlab::BackgroundMigration::WrongfullyConfirmedEmailUnconfirmer, schema: 20210301200959 do
let(:users) { table(:users) }
let(:emails) { table(:emails) }
let(:user_synced_attributes_metadata) { table(:user_synced_attributes_metadata) }
diff --git a/spec/lib/gitlab/checks/changes_access_spec.rb b/spec/lib/gitlab/checks/changes_access_spec.rb
index 633c4baa931..1cb4edd7337 100644
--- a/spec/lib/gitlab/checks/changes_access_spec.rb
+++ b/spec/lib/gitlab/checks/changes_access_spec.rb
@@ -44,16 +44,30 @@ RSpec.describe Gitlab::Checks::ChangesAccess do
it 'calls #new_commits' do
expect(project.repository).to receive(:new_commits).and_call_original
- expect(subject.commits).to eq([])
+ expect(subject.commits).to match_array([])
end
context 'when changes contain empty revisions' do
- let(:changes) { [{ newrev: newrev }, { newrev: '' }, { newrev: Gitlab::Git::BLANK_SHA }] }
let(:expected_commit) { instance_double(Commit) }
- it 'returns only commits with non empty revisions' do
- expect(project.repository).to receive(:new_commits).with([newrev], { allow_quarantine: true }) { [expected_commit] }
- expect(subject.commits).to eq([expected_commit])
+ shared_examples 'returns only commits with non empty revisions' do
+ specify do
+ expect(project.repository).to receive(:new_commits).with([newrev], { allow_quarantine: allow_quarantine }) { [expected_commit] }
+ expect(subject.commits).to match_array([expected_commit])
+ end
+ end
+
+ it_behaves_like 'returns only commits with non empty revisions' do
+ let(:changes) { [{ oldrev: oldrev, newrev: newrev }, { newrev: '' }, { newrev: Gitlab::Git::BLANK_SHA }] }
+ let(:allow_quarantine) { true }
+ end
+
+ context 'without oldrev' do
+ it_behaves_like 'returns only commits with non empty revisions' do
+ let(:changes) { [{ newrev: newrev }, { newrev: '' }, { newrev: Gitlab::Git::BLANK_SHA }] }
+ # The quarantine directory should not be used because we're lacking oldrev.
+ let(:allow_quarantine) { false }
+ end
end
end
end
@@ -61,12 +75,13 @@ RSpec.describe Gitlab::Checks::ChangesAccess do
describe '#commits_for' do
let(:new_commits) { [] }
let(:expected_commits) { [] }
+ let(:oldrev) { Gitlab::Git::BLANK_SHA }
shared_examples 'a listing of new commits' do
it 'returns expected commits' do
expect(subject).to receive(:commits).and_return(new_commits)
- expect(subject.commits_for(newrev)).to eq(expected_commits)
+ expect(subject.commits_for(oldrev, newrev)).to eq(expected_commits)
end
end
@@ -172,6 +187,31 @@ RSpec.describe Gitlab::Checks::ChangesAccess do
it_behaves_like 'a listing of new commits'
end
+
+ context 'with over-push' do
+ let(:newrev) { '1' }
+ let(:oldrev) { '3' }
+
+ # `#new_commits` returns too many commits, where some commits are not
+ # part of the current change.
+ let(:new_commits) do
+ [
+ create_commit('1', %w[2]),
+ create_commit('2', %w[3]),
+ create_commit('3', %w[4]),
+ create_commit('4', %w[])
+ ]
+ end
+
+ let(:expected_commits) do
+ [
+ create_commit('1', %w[2]),
+ create_commit('2', %w[3])
+ ]
+ end
+
+ it_behaves_like 'a listing of new commits'
+ end
end
describe '#single_change_accesses' do
@@ -180,10 +220,10 @@ RSpec.describe Gitlab::Checks::ChangesAccess do
shared_examples '#single_change_access' do
before do
- commits_for.each do |id, commits|
+ commits_for.each do |oldrev, newrev, commits|
expect(subject)
.to receive(:commits_for)
- .with(id)
+ .with(oldrev, newrev)
.and_return(commits)
end
end
@@ -205,7 +245,12 @@ RSpec.describe Gitlab::Checks::ChangesAccess do
end
context 'with a single change and no new commits' do
- let(:commits_for) { { 'new' => [] } }
+ let(:commits_for) do
+ [
+ ['old', 'new', []]
+ ]
+ end
+
let(:changes) do
[
{ oldrev: 'old', newrev: 'new', ref: 'refs/heads/branch' }
@@ -222,7 +267,12 @@ RSpec.describe Gitlab::Checks::ChangesAccess do
end
context 'with a single change and new commits' do
- let(:commits_for) { { 'new' => [create_commit('new', [])] } }
+ let(:commits_for) do
+ [
+ ['old', 'new', [create_commit('new', [])]]
+ ]
+ end
+
let(:changes) do
[
{ oldrev: 'old', newrev: 'new', ref: 'refs/heads/branch' }
@@ -240,11 +290,11 @@ RSpec.describe Gitlab::Checks::ChangesAccess do
context 'with multiple changes' do
let(:commits_for) do
- {
- 'a' => [create_commit('a', [])],
- 'c' => [create_commit('c', [])],
- 'd' => []
- }
+ [
+ [nil, 'a', [create_commit('a', [])]],
+ ['a', 'c', [create_commit('c', [])]],
+ [nil, 'd', []]
+ ]
end
let(:changes) do
diff --git a/spec/lib/gitlab/ci/build/status/reason_spec.rb b/spec/lib/gitlab/ci/build/status/reason_spec.rb
new file mode 100644
index 00000000000..64f35c3f464
--- /dev/null
+++ b/spec/lib/gitlab/ci/build/status/reason_spec.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Ci::Build::Status::Reason do
+ let(:build) { double('build') }
+
+ describe '.fabricate' do
+ context 'when failure symbol reason is being passed' do
+ it 'correctly fabricates a status reason object' do
+ reason = described_class.fabricate(build, :script_failure)
+
+ expect(reason.failure_reason_enum).to eq 1
+ end
+ end
+
+ context 'when another status reason object is being passed' do
+ it 'correctly fabricates a status reason object' do
+ reason = described_class.fabricate(build, :script_failure)
+
+ new_reason = described_class.fabricate(build, reason)
+
+ expect(new_reason.failure_reason_enum).to eq 1
+ end
+ end
+ end
+
+ describe '#failure_reason_enum' do
+ it 'exposes a failure reason enum' do
+ reason = described_class.fabricate(build, :script_failure)
+
+ enum = ::CommitStatus.failure_reasons[:script_failure]
+
+ expect(reason.failure_reason_enum).to eq enum
+ end
+ end
+
+ describe '#force_allow_failure?' do
+ context 'when build is not allowed to fail' do
+ context 'when build is allowed to fail with a given exit code' do
+ it 'returns true' do
+ reason = described_class.new(build, :script_failure, 11)
+
+ allow(build).to receive(:allow_failure?).and_return(false)
+ allow(build).to receive(:allowed_to_fail_with_code?)
+ .with(11)
+ .and_return(true)
+
+ expect(reason.force_allow_failure?).to be true
+ end
+ end
+
+ context 'when build is not allowed to fail regardless of an exit code' do
+ it 'returns false' do
+ reason = described_class.new(build, :script_failure, 11)
+
+ allow(build).to receive(:allow_failure?).and_return(false)
+ allow(build).to receive(:allowed_to_fail_with_code?)
+ .with(11)
+ .and_return(false)
+
+ expect(reason.force_allow_failure?).to be false
+ end
+ end
+
+ context 'when an exit code is not specified' do
+ it 'returns false' do
+ reason = described_class.new(build, :script_failure)
+
+ expect(reason.force_allow_failure?).to be false
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/config/entry/root_spec.rb b/spec/lib/gitlab/ci/config/entry/root_spec.rb
index d862fbf5b78..749d1386ed9 100644
--- a/spec/lib/gitlab/ci/config/entry/root_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/root_spec.rb
@@ -3,7 +3,9 @@
require 'spec_helper'
RSpec.describe Gitlab::Ci::Config::Entry::Root do
- let(:root) { described_class.new(hash) }
+ let(:user) {}
+ let(:project) {}
+ let(:root) { described_class.new(hash, user: user, project: project) }
describe '.nodes' do
it 'returns a hash' do
@@ -53,6 +55,37 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do
}
end
+ context 'when deprecated types keyword is defined' do
+ let(:project) { create(:project, :repository) }
+ let(:user) { create(:user) }
+
+ let(:hash) do
+ { types: %w(test deploy),
+ rspec: { script: 'rspec' } }
+ end
+
+ before do
+ root.compose!
+ end
+
+ it 'returns array of types as stages with a warning' do
+ expect(root.stages_value).to eq %w[test deploy]
+ expect(root.warnings).to match_array(["root `types` is deprecated in 9.0 and will be removed in 15.0."])
+ end
+
+ it 'logs usage of types keyword' do
+ expect(Gitlab::AppJsonLogger).to(
+ receive(:info)
+ .with(event: 'ci_used_deprecated_keyword',
+ entry: root[:stages].key.to_s,
+ user_id: user.id,
+ project_id: project.id)
+ )
+
+ root.compose!
+ end
+ end
+
describe '#compose!' do
before do
root.compose!
@@ -108,17 +141,6 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do
expect(root.stages_value).to eq %w[build pages release]
end
end
-
- context 'when deprecated types key defined' do
- let(:hash) do
- { types: %w(test deploy),
- rspec: { script: 'rspec' } }
- end
-
- it 'returns array of types as stages' do
- expect(root.stages_value).to eq %w[test deploy]
- end
- end
end
describe '#jobs_value' do
diff --git a/spec/lib/gitlab/ci/jwt_v2_spec.rb b/spec/lib/gitlab/ci/jwt_v2_spec.rb
new file mode 100644
index 00000000000..33aaa145a39
--- /dev/null
+++ b/spec/lib/gitlab/ci/jwt_v2_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Ci::JwtV2 do
+ let(:namespace) { build_stubbed(:namespace) }
+ let(:project) { build_stubbed(:project, namespace: namespace) }
+ let(:user) { build_stubbed(:user) }
+ let(:pipeline) { build_stubbed(:ci_pipeline, ref: 'auto-deploy-2020-03-19') }
+ let(:build) do
+ build_stubbed(
+ :ci_build,
+ project: project,
+ user: user,
+ pipeline: pipeline
+ )
+ end
+
+ subject(:ci_job_jwt_v2) { described_class.new(build, ttl: 30) }
+
+ it { is_expected.to be_a Gitlab::Ci::Jwt }
+
+ describe '#payload' do
+ subject(:payload) { ci_job_jwt_v2.payload }
+
+ it 'has correct values for the standard JWT attributes' do
+ aggregate_failures do
+ expect(payload[:iss]).to eq(Settings.gitlab.base_url)
+ expect(payload[:aud]).to eq(Settings.gitlab.base_url)
+ expect(payload[:sub]).to eq("project_path:#{project.full_path}:ref_type:branch:ref:#{pipeline.source_ref}")
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/pipeline/chain/create_deployments_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/create_deployments_spec.rb
index 28bc685286f..0a592395c3a 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/create_deployments_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/create_deployments_spec.rb
@@ -38,20 +38,6 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::CreateDeployments do
expect(job.deployment.environment).to eq(job.persisted_environment)
end
- context 'when creation failure occures' do
- before do
- allow_next_instance_of(Deployment) do |deployment|
- allow(deployment).to receive(:save!) { raise ActiveRecord::RecordInvalid }
- end
- end
-
- it 'trackes the exception' do
- expect { subject }.to raise_error(described_class::DeploymentCreationError)
-
- expect(Deployment.count).to eq(0)
- end
- end
-
context 'when the corresponding environment does not exist' do
let!(:environment) { }
diff --git a/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb
index 4206483b228..1d020d3ea79 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Create do
let_it_be(:user) { create(:user) }
let(:pipeline) do
- build(:ci_empty_pipeline, project: project, ref: 'master')
+ build(:ci_empty_pipeline, project: project, ref: 'master', user: user)
end
let(:command) do
@@ -59,7 +59,7 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Create do
context 'tags persistence' do
let(:stage) do
- build(:ci_stage_entity, pipeline: pipeline)
+ build(:ci_stage_entity, pipeline: pipeline, project: project)
end
let(:job) do
@@ -79,12 +79,11 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Create do
it 'extracts an empty tag list' do
expect(CommitStatus)
.to receive(:bulk_insert_tags!)
- .with(stage.statuses, {})
+ .with([job])
.and_call_original
step.perform!
- expect(job.instance_variable_defined?(:@tag_list)).to be_falsey
expect(job).to be_persisted
expect(job.tag_list).to eq([])
end
@@ -98,14 +97,13 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Create do
it 'bulk inserts tags' do
expect(CommitStatus)
.to receive(:bulk_insert_tags!)
- .with(stage.statuses, { job.name => %w[tag1 tag2] })
+ .with([job])
.and_call_original
step.perform!
- expect(job.instance_variable_defined?(:@tag_list)).to be_falsey
expect(job).to be_persisted
- expect(job.tag_list).to match_array(%w[tag1 tag2])
+ expect(job.reload.tag_list).to match_array(%w[tag1 tag2])
end
end
@@ -120,7 +118,6 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Create do
step.perform!
- expect(job.instance_variable_defined?(:@tag_list)).to be_truthy
expect(job).to be_persisted
expect(job.reload.tag_list).to match_array(%w[tag1 tag2])
end
diff --git a/spec/lib/gitlab/ci/pipeline/logger_spec.rb b/spec/lib/gitlab/ci/pipeline/logger_spec.rb
index 0b44e35dec1..a488bc184f8 100644
--- a/spec/lib/gitlab/ci/pipeline/logger_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/logger_spec.rb
@@ -41,6 +41,90 @@ RSpec.describe ::Gitlab::Ci::Pipeline::Logger do
end
end
+ describe '#instrument_with_sql', :request_store do
+ subject(:instrument_with_sql) do
+ logger.instrument_with_sql(:expensive_operation, &operation)
+ end
+
+ def loggable_data(count:, db_count: nil)
+ keys = %w[
+ expensive_operation_duration_s
+ expensive_operation_db_count
+ expensive_operation_db_primary_count
+ expensive_operation_db_primary_duration_s
+ expensive_operation_db_main_count
+ expensive_operation_db_main_duration_s
+ ]
+
+ data = keys.each.with_object({}) do |key, accumulator|
+ accumulator[key] = {
+ 'count' => count,
+ 'avg' => a_kind_of(Numeric),
+ 'max' => a_kind_of(Numeric),
+ 'min' => a_kind_of(Numeric)
+ }
+ end
+
+ if db_count
+ data['expensive_operation_db_count']['max'] = db_count
+ data['expensive_operation_db_count']['min'] = db_count
+ data['expensive_operation_db_count']['avg'] = db_count
+ end
+
+ data
+ end
+
+ context 'with a single query' do
+ let(:operation) { -> { Project.count } }
+
+ it { is_expected.to eq(operation.call) }
+
+ it 'includes SQL metrics' do
+ instrument_with_sql
+
+ expect(logger.observations_hash)
+ .to match(a_hash_including(loggable_data(count: 1, db_count: 1)))
+ end
+ end
+
+ context 'with multiple queries' do
+ let(:operation) { -> { Ci::Build.count + Ci::Bridge.count } }
+
+ it { is_expected.to eq(operation.call) }
+
+ it 'includes SQL metrics' do
+ instrument_with_sql
+
+ expect(logger.observations_hash)
+ .to match(a_hash_including(loggable_data(count: 1, db_count: 2)))
+ end
+ end
+
+ context 'with multiple observations' do
+ let(:operation) { -> { Ci::Build.count + Ci::Bridge.count } }
+
+ it 'includes SQL metrics' do
+ 2.times { logger.instrument_with_sql(:expensive_operation, &operation) }
+
+ expect(logger.observations_hash)
+ .to match(a_hash_including(loggable_data(count: 2, db_count: 2)))
+ end
+ end
+
+ context 'when there are not SQL operations' do
+ let(:operation) { -> { 123 } }
+
+ it { is_expected.to eq(operation.call) }
+
+ it 'does not include SQL metrics' do
+ instrument_with_sql
+
+ expect(logger.observations_hash.keys)
+ .to match_array(['expensive_operation_duration_s'])
+ end
+ end
+ end
+
describe '#observe' do
it 'records durations of observed operations' do
loggable_data = {
diff --git a/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
index 68806fbf287..2f9fcd7caac 100644
--- a/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build do
let(:pipeline) { build(:ci_empty_pipeline, project: project, sha: head_sha) }
let(:root_variables) { [] }
- let(:seed_context) { double(pipeline: pipeline, root_variables: root_variables) }
+ let(:seed_context) { Gitlab::Ci::Pipeline::Seed::Context.new(pipeline, root_variables: root_variables) }
let(:attributes) { { name: 'rspec', ref: 'master', scheduling_type: :stage, when: 'on_success' } }
let(:previous_stages) { [] }
let(:current_stage) { double(seeds_names: [attributes[:name]]) }
diff --git a/spec/lib/gitlab/ci/pipeline/seed/pipeline_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/pipeline_spec.rb
index 5d8a9358e10..a76b4874eca 100644
--- a/spec/lib/gitlab/ci/pipeline/seed/pipeline_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/seed/pipeline_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Pipeline do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
- let(:seed_context) { double(pipeline: pipeline, root_variables: []) }
+ let(:seed_context) { Gitlab::Ci::Pipeline::Seed::Context.new(pipeline, root_variables: []) }
let(:stages_attributes) do
[
diff --git a/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb
index 5b04d2abd88..a632b5dedcf 100644
--- a/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Stage do
let(:project) { create(:project, :repository) }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:previous_stages) { [] }
- let(:seed_context) { double(pipeline: pipeline, root_variables: []) }
+ let(:seed_context) { Gitlab::Ci::Pipeline::Seed::Context.new(pipeline, root_variables: []) }
let(:attributes) do
{ name: 'test',
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
new file mode 100644
index 00000000000..b703a8a47ac
--- /dev/null
+++ b/spec/lib/gitlab/ci/status/build/waiting_for_approval_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Ci::Status::Build::WaitingForApproval do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:user) { create(:user) }
+
+ 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) }
+
+ let(:build) { create(:ci_build, :manual, environment: 'production', project: project) }
+
+ before do
+ create(:deployment, deployment_status, deployable: build, project: project)
+ end
+
+ context 'when build is waiting for approval' do
+ let(:deployment_status) { :blocked }
+
+ it 'is a correct match' do
+ expect(subject).to be_truthy
+ end
+ end
+
+ context 'when build is not waiting for approval' do
+ let(:deployment_status) { :created }
+
+ it 'does not match' do
+ expect(subject).to be_falsey
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/tags/bulk_insert_spec.rb b/spec/lib/gitlab/ci/tags/bulk_insert_spec.rb
index 6c1f56de840..6c4f69fb036 100644
--- a/spec/lib/gitlab/ci/tags/bulk_insert_spec.rb
+++ b/spec/lib/gitlab/ci/tags/bulk_insert_spec.rb
@@ -5,27 +5,37 @@ require 'spec_helper'
RSpec.describe Gitlab::Ci::Tags::BulkInsert do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
- let_it_be_with_refind(:job) { create(:ci_build, :unique_name, pipeline: pipeline, project: project) }
- let_it_be_with_refind(:other_job) { create(:ci_build, :unique_name, pipeline: pipeline, project: project) }
- let_it_be_with_refind(:bridge) { create(:ci_bridge, pipeline: pipeline, project: project) }
+ let_it_be_with_refind(:job) { create(:ci_build, :unique_name, pipeline: pipeline) }
+ let_it_be_with_refind(:other_job) { create(:ci_build, :unique_name, pipeline: pipeline) }
- let(:statuses) { [job, bridge, other_job] }
+ let(:statuses) { [job, other_job] }
- subject(:service) { described_class.new(statuses, tags_list) }
+ subject(:service) { described_class.new(statuses) }
+
+ describe 'gem version' do
+ let(:acceptable_version) { '9.0.0' }
+
+ let(:error_message) do
+ <<~MESSAGE
+ A mechanism depending on internals of 'act-as-taggable-on` has been designed
+ to bulk insert tags for Ci::Build records.
+ Please review the code carefully before updating the gem version
+ https://gitlab.com/gitlab-org/gitlab/-/issues/350053
+ MESSAGE
+ end
+
+ it { expect(ActsAsTaggableOn::VERSION).to eq(acceptable_version), error_message }
+ end
describe '#insert!' do
context 'without tags' do
- let(:tags_list) { {} }
-
it { expect(service.insert!).to be_falsey }
end
context 'with tags' do
- let(:tags_list) do
- {
- job.name => %w[tag1 tag2],
- other_job.name => %w[tag2 tag3 tag4]
- }
+ before do
+ job.tag_list = %w[tag1 tag2]
+ other_job.tag_list = %w[tag2 tag3 tag4]
end
it 'persists tags' do
@@ -35,5 +45,18 @@ RSpec.describe Gitlab::Ci::Tags::BulkInsert do
expect(other_job.reload.tag_list).to match_array(%w[tag2 tag3 tag4])
end
end
+
+ context 'with tags for only one job' do
+ before do
+ job.tag_list = %w[tag1 tag2]
+ end
+
+ it 'persists tags' do
+ expect(service.insert!).to be_truthy
+
+ expect(job.reload.tag_list).to match_array(%w[tag1 tag2])
+ expect(other_job.reload.tag_list).to be_empty
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/ci/trace/remote_checksum_spec.rb b/spec/lib/gitlab/ci/trace/remote_checksum_spec.rb
index 8837ebc3652..1cd88034166 100644
--- a/spec/lib/gitlab/ci/trace/remote_checksum_spec.rb
+++ b/spec/lib/gitlab/ci/trace/remote_checksum_spec.rb
@@ -30,14 +30,6 @@ RSpec.describe Gitlab::Ci::Trace::RemoteChecksum do
context 'with remote files' do
let(:file_store) { JobArtifactUploader::Store::REMOTE }
- context 'when the feature flag is disabled' do
- before do
- stub_feature_flags(ci_archived_build_trace_checksum: false)
- end
-
- it { is_expected.to be_nil }
- end
-
context 'with AWS as provider' do
it { is_expected.to eq(checksum) }
end
diff --git a/spec/lib/gitlab/ci/variables/builder_spec.rb b/spec/lib/gitlab/ci/variables/builder_spec.rb
index 5ff34592b2f..8a87cbe45c1 100644
--- a/spec/lib/gitlab/ci/variables/builder_spec.rb
+++ b/spec/lib/gitlab/ci/variables/builder_spec.rb
@@ -3,25 +3,201 @@
require 'spec_helper'
RSpec.describe Gitlab::Ci::Variables::Builder do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
+ let_it_be(:user) { project.owner }
+ let_it_be(:job) do
+ create(:ci_build,
+ pipeline: pipeline,
+ user: user,
+ yaml_variables: [{ key: 'YAML_VARIABLE', value: 'value' }]
+ )
+ end
+
let(:builder) { described_class.new(pipeline) }
- let(:pipeline) { create(:ci_pipeline) }
- let(:job) { create(:ci_build, pipeline: pipeline) }
describe '#scoped_variables' do
let(:environment) { job.expanded_environment_name }
let(:dependencies) { true }
+ let(:predefined_variables) do
+ [
+ { key: 'CI_JOB_NAME',
+ value: job.name },
+ { key: 'CI_JOB_STAGE',
+ value: job.stage },
+ { key: 'CI_NODE_TOTAL',
+ value: '1' },
+ { key: 'CI_BUILD_NAME',
+ value: job.name },
+ { key: 'CI_BUILD_STAGE',
+ value: job.stage },
+ { key: 'CI',
+ value: 'true' },
+ { key: 'GITLAB_CI',
+ value: 'true' },
+ { key: 'CI_SERVER_URL',
+ value: Gitlab.config.gitlab.url },
+ { key: 'CI_SERVER_HOST',
+ value: Gitlab.config.gitlab.host },
+ { key: 'CI_SERVER_PORT',
+ value: Gitlab.config.gitlab.port.to_s },
+ { key: 'CI_SERVER_PROTOCOL',
+ value: Gitlab.config.gitlab.protocol },
+ { key: 'CI_SERVER_NAME',
+ value: 'GitLab' },
+ { key: 'CI_SERVER_VERSION',
+ value: Gitlab::VERSION },
+ { key: 'CI_SERVER_VERSION_MAJOR',
+ value: Gitlab.version_info.major.to_s },
+ { key: 'CI_SERVER_VERSION_MINOR',
+ value: Gitlab.version_info.minor.to_s },
+ { key: 'CI_SERVER_VERSION_PATCH',
+ value: Gitlab.version_info.patch.to_s },
+ { key: 'CI_SERVER_REVISION',
+ value: Gitlab.revision },
+ { key: 'GITLAB_FEATURES',
+ value: project.licensed_features.join(',') },
+ { key: 'CI_PROJECT_ID',
+ value: project.id.to_s },
+ { key: 'CI_PROJECT_NAME',
+ value: project.path },
+ { key: 'CI_PROJECT_TITLE',
+ value: project.title },
+ { key: 'CI_PROJECT_PATH',
+ value: project.full_path },
+ { key: 'CI_PROJECT_PATH_SLUG',
+ value: project.full_path_slug },
+ { key: 'CI_PROJECT_NAMESPACE',
+ value: project.namespace.full_path },
+ { key: 'CI_PROJECT_ROOT_NAMESPACE',
+ value: project.namespace.root_ancestor.path },
+ { key: 'CI_PROJECT_URL',
+ value: project.web_url },
+ { key: 'CI_PROJECT_VISIBILITY',
+ value: "private" },
+ { key: 'CI_PROJECT_REPOSITORY_LANGUAGES',
+ value: project.repository_languages.map(&:name).join(',').downcase },
+ { key: 'CI_PROJECT_CLASSIFICATION_LABEL',
+ value: project.external_authorization_classification_label },
+ { key: 'CI_DEFAULT_BRANCH',
+ value: project.default_branch },
+ { key: 'CI_CONFIG_PATH',
+ value: project.ci_config_path_or_default },
+ { key: 'CI_PAGES_DOMAIN',
+ value: Gitlab.config.pages.host },
+ { key: 'CI_PAGES_URL',
+ value: project.pages_url },
+ { key: 'CI_API_V4_URL',
+ value: API::Helpers::Version.new('v4').root_url },
+ { key: 'CI_PIPELINE_IID',
+ value: pipeline.iid.to_s },
+ { key: 'CI_PIPELINE_SOURCE',
+ value: pipeline.source },
+ { key: 'CI_PIPELINE_CREATED_AT',
+ value: pipeline.created_at.iso8601 },
+ { key: 'CI_COMMIT_SHA',
+ value: job.sha },
+ { key: 'CI_COMMIT_SHORT_SHA',
+ value: job.short_sha },
+ { key: 'CI_COMMIT_BEFORE_SHA',
+ value: job.before_sha },
+ { key: 'CI_COMMIT_REF_NAME',
+ value: job.ref },
+ { key: 'CI_COMMIT_REF_SLUG',
+ value: job.ref_slug },
+ { key: 'CI_COMMIT_BRANCH',
+ value: job.ref },
+ { key: 'CI_COMMIT_MESSAGE',
+ value: pipeline.git_commit_message },
+ { key: 'CI_COMMIT_TITLE',
+ value: pipeline.git_commit_title },
+ { key: 'CI_COMMIT_DESCRIPTION',
+ value: pipeline.git_commit_description },
+ { key: 'CI_COMMIT_REF_PROTECTED',
+ value: (!!pipeline.protected_ref?).to_s },
+ { key: 'CI_COMMIT_TIMESTAMP',
+ value: pipeline.git_commit_timestamp },
+ { key: 'CI_COMMIT_AUTHOR',
+ value: pipeline.git_author_full_text },
+ { key: 'CI_BUILD_REF',
+ value: job.sha },
+ { key: 'CI_BUILD_BEFORE_SHA',
+ value: job.before_sha },
+ { key: 'CI_BUILD_REF_NAME',
+ value: job.ref },
+ { key: 'CI_BUILD_REF_SLUG',
+ value: job.ref_slug },
+ { key: 'YAML_VARIABLE',
+ value: 'value' },
+ { key: 'GITLAB_USER_ID',
+ value: user.id.to_s },
+ { key: 'GITLAB_USER_EMAIL',
+ value: user.email },
+ { key: 'GITLAB_USER_LOGIN',
+ value: user.username },
+ { key: 'GITLAB_USER_NAME',
+ value: user.name }
+ ].map { |var| var.merge(public: true, masked: false) }
+ end
subject { builder.scoped_variables(job, environment: environment, dependencies: dependencies) }
- it 'returns the expected variables' do
- keys = %w[CI_JOB_NAME
- CI_JOB_STAGE
- CI_NODE_TOTAL
- CI_BUILD_NAME
- CI_BUILD_STAGE]
+ it { is_expected.to be_instance_of(Gitlab::Ci::Variables::Collection) }
+
+ it { expect(subject.to_runner_variables).to eq(predefined_variables) }
+
+ context 'variables ordering' do
+ def var(name, value)
+ { key: name, value: value.to_s, public: true, masked: false }
+ end
+
+ before do
+ allow(builder).to receive(:predefined_variables) { [var('A', 1), var('B', 1)] }
+ allow(project).to receive(:predefined_variables) { [var('B', 2), var('C', 2)] }
+ 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)] }
+ allow(builder).to receive(:secret_instance_variables) { [var('J', 10), var('K', 10)] }
+ allow(builder).to receive(:secret_group_variables) { [var('K', 11), var('L', 11)] }
+ allow(builder).to receive(:secret_project_variables) { [var('L', 12), var('M', 12)] }
+ allow(job).to receive(:trigger_request) { double(user_variables: [var('M', 13), var('N', 13)]) }
+ allow(pipeline).to receive(:variables) { [var('N', 14), var('O', 14)] }
+ allow(pipeline).to receive(:pipeline_schedule) { double(job_variables: [var('O', 15), var('P', 15)]) }
+ end
+
+ it 'returns variables in order depending on resource hierarchy' do
+ expect(subject.to_runner_variables).to eq(
+ [var('A', 1), var('B', 1),
+ var('B', 2), var('C', 2),
+ 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),
+ var('J', 10), var('K', 10),
+ var('K', 11), var('L', 11),
+ var('L', 12), var('M', 12),
+ var('M', 13), var('N', 13),
+ var('N', 14), var('O', 14),
+ var('O', 15), var('P', 15)])
+ end
- subject.map { |env| env[:key] }.tap do |names|
- expect(names).to include(*keys)
+ it 'overrides duplicate keys depending on resource hierarchy' do
+ expect(subject.to_hash).to match(
+ 'A' => '1', 'B' => '2',
+ 'C' => '3', 'D' => '4',
+ 'E' => '5', 'F' => '6',
+ 'G' => '7', 'H' => '8',
+ 'I' => '9', 'J' => '10',
+ 'K' => '11', 'L' => '12',
+ 'M' => '13', 'N' => '14',
+ 'O' => '15', 'P' => '15')
end
end
end
diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb
index e8b38b21ef8..20af84ce648 100644
--- a/spec/lib/gitlab/ci/yaml_processor_spec.rb
+++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb
@@ -2097,6 +2097,12 @@ module Gitlab
it_behaves_like 'returns errors', 'test1 job: need deploy is not defined in current or prior stages'
end
+ context 'duplicate needs' do
+ let(:needs) { %w(build1 build1) }
+
+ it_behaves_like 'returns errors', 'test1 has duplicate entries in the needs section.'
+ end
+
context 'needs and dependencies that are mismatching' do
let(:needs) { %w(build1) }
let(:dependencies) { %w(build2) }
@@ -2602,7 +2608,7 @@ module Gitlab
end
context 'returns errors if job stage is not a defined stage' do
- let(:config) { YAML.dump({ types: %w(build test), rspec: { script: "test", type: "acceptance" } }) }
+ let(:config) { YAML.dump({ stages: %w(build test), rspec: { script: "test", type: "acceptance" } }) }
it_behaves_like 'returns errors', 'rspec job: chosen stage does not exist; available stages are .pre, build, test, .post'
end
@@ -2638,37 +2644,37 @@ module Gitlab
end
context 'returns errors if job artifacts:name is not an a string' do
- let(:config) { YAML.dump({ types: %w(build test), rspec: { script: "test", artifacts: { name: 1 } } }) }
+ let(:config) { YAML.dump({ stages: %w(build test), rspec: { script: "test", artifacts: { name: 1 } } }) }
it_behaves_like 'returns errors', 'jobs:rspec:artifacts name should be a string'
end
context 'returns errors if job artifacts:when is not an a predefined value' do
- let(:config) { YAML.dump({ types: %w(build test), rspec: { script: "test", artifacts: { when: 1 } } }) }
+ let(:config) { YAML.dump({ stages: %w(build test), rspec: { script: "test", artifacts: { when: 1 } } }) }
it_behaves_like 'returns errors', 'jobs:rspec:artifacts when should be on_success, on_failure or always'
end
context 'returns errors if job artifacts:expire_in is not an a string' do
- let(:config) { YAML.dump({ types: %w(build test), rspec: { script: "test", artifacts: { expire_in: 1 } } }) }
+ let(:config) { YAML.dump({ stages: %w(build test), rspec: { script: "test", artifacts: { expire_in: 1 } } }) }
it_behaves_like 'returns errors', 'jobs:rspec:artifacts expire in should be a duration'
end
context 'returns errors if job artifacts:expire_in is not an a valid duration' do
- let(:config) { YAML.dump({ types: %w(build test), rspec: { script: "test", artifacts: { expire_in: "7 elephants" } } }) }
+ let(:config) { YAML.dump({ stages: %w(build test), rspec: { script: "test", artifacts: { expire_in: "7 elephants" } } }) }
it_behaves_like 'returns errors', 'jobs:rspec:artifacts expire in should be a duration'
end
context 'returns errors if job artifacts:untracked is not an array of strings' do
- let(:config) { YAML.dump({ types: %w(build test), rspec: { script: "test", artifacts: { untracked: "string" } } }) }
+ let(:config) { YAML.dump({ stages: %w(build test), rspec: { script: "test", artifacts: { untracked: "string" } } }) }
it_behaves_like 'returns errors', 'jobs:rspec:artifacts untracked should be a boolean value'
end
context 'returns errors if job artifacts:paths is not an array of strings' do
- let(:config) { YAML.dump({ types: %w(build test), rspec: { script: "test", artifacts: { paths: "string" } } }) }
+ let(:config) { YAML.dump({ stages: %w(build test), rspec: { script: "test", artifacts: { paths: "string" } } }) }
it_behaves_like 'returns errors', 'jobs:rspec:artifacts paths should be an array of strings'
end
@@ -2692,49 +2698,49 @@ module Gitlab
end
context 'returns errors if job cache:key is not an a string' do
- let(:config) { YAML.dump({ types: %w(build test), rspec: { script: "test", cache: { key: 1 } } }) }
+ let(:config) { YAML.dump({ stages: %w(build test), rspec: { script: "test", cache: { key: 1 } } }) }
it_behaves_like 'returns errors', "jobs:rspec:cache:key should be a hash, a string or a symbol"
end
context 'returns errors if job cache:key:files is not an array of strings' do
- let(:config) { YAML.dump({ types: %w(build test), rspec: { script: "test", cache: { key: { files: [1] } } } }) }
+ let(:config) { YAML.dump({ stages: %w(build test), rspec: { script: "test", cache: { key: { files: [1] } } } }) }
it_behaves_like 'returns errors', 'jobs:rspec:cache:key:files config should be an array of strings'
end
context 'returns errors if job cache:key:files is an empty array' do
- let(:config) { YAML.dump({ types: %w(build test), rspec: { script: "test", cache: { key: { files: [] } } } }) }
+ let(:config) { YAML.dump({ stages: %w(build test), rspec: { script: "test", cache: { key: { files: [] } } } }) }
it_behaves_like 'returns errors', 'jobs:rspec:cache:key:files config requires at least 1 item'
end
context 'returns errors if job defines only cache:key:prefix' do
- let(:config) { YAML.dump({ types: %w(build test), rspec: { script: "test", cache: { key: { prefix: 'prefix-key' } } } }) }
+ let(:config) { YAML.dump({ stages: %w(build test), rspec: { script: "test", cache: { key: { prefix: 'prefix-key' } } } }) }
it_behaves_like 'returns errors', 'jobs:rspec:cache:key config missing required keys: files'
end
context 'returns errors if job cache:key:prefix is not an a string' do
- let(:config) { YAML.dump({ types: %w(build test), rspec: { script: "test", cache: { key: { prefix: 1, files: ['file'] } } } }) }
+ let(:config) { YAML.dump({ stages: %w(build test), rspec: { script: "test", cache: { key: { prefix: 1, files: ['file'] } } } }) }
it_behaves_like 'returns errors', 'jobs:rspec:cache:key:prefix config should be a string or symbol'
end
context "returns errors if job cache:untracked is not an array of strings" do
- let(:config) { YAML.dump({ types: %w(build test), rspec: { script: "test", cache: { untracked: "string" } } }) }
+ let(:config) { YAML.dump({ stages: %w(build test), rspec: { script: "test", cache: { untracked: "string" } } }) }
it_behaves_like 'returns errors', "jobs:rspec:cache:untracked config should be a boolean value"
end
context "returns errors if job cache:paths is not an array of strings" do
- let(:config) { YAML.dump({ types: %w(build test), rspec: { script: "test", cache: { paths: "string" } } }) }
+ let(:config) { YAML.dump({ stages: %w(build test), rspec: { script: "test", cache: { paths: "string" } } }) }
it_behaves_like 'returns errors', "jobs:rspec:cache:paths config should be an array of strings"
end
context "returns errors if job dependencies is not an array of strings" do
- let(:config) { YAML.dump({ types: %w(build test), rspec: { script: "test", dependencies: "string" } }) }
+ let(:config) { YAML.dump({ stages: %w(build test), rspec: { script: "test", dependencies: "string" } }) }
it_behaves_like 'returns errors', "jobs:rspec dependencies should be an array of strings"
end
diff --git a/spec/lib/gitlab/color_schemes_spec.rb b/spec/lib/gitlab/color_schemes_spec.rb
index fd9fccc2bf7..feb5648ff2d 100644
--- a/spec/lib/gitlab/color_schemes_spec.rb
+++ b/spec/lib/gitlab/color_schemes_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe Gitlab::ColorSchemes do
describe '.by_id' do
it 'returns a scheme by its ID' do
- expect(described_class.by_id(1).name).to eq 'White'
+ expect(described_class.by_id(1).name).to eq 'Light'
expect(described_class.by_id(4).name).to eq 'Solarized Dark'
end
end
diff --git a/spec/lib/gitlab/config/entry/configurable_spec.rb b/spec/lib/gitlab/config/entry/configurable_spec.rb
index 0153cfbf091..154038f51c7 100644
--- a/spec/lib/gitlab/config/entry/configurable_spec.rb
+++ b/spec/lib/gitlab/config/entry/configurable_spec.rb
@@ -39,7 +39,8 @@ RSpec.describe Gitlab::Config::Entry::Configurable do
entry :object, entry_class,
description: 'test object',
inherit: true,
- reserved: true
+ reserved: true,
+ deprecation: { deprecated: '10.0', warning: '10.1', removed: '11.0', documentation: 'docs.gitlab.com' }
end
end
@@ -52,6 +53,12 @@ RSpec.describe Gitlab::Config::Entry::Configurable do
factory = entry.nodes[:object]
expect(factory).to be_an_instance_of(Gitlab::Config::Entry::Factory)
+ expect(factory.deprecation).to eq(
+ deprecated: '10.0',
+ warning: '10.1',
+ removed: '11.0',
+ documentation: 'docs.gitlab.com'
+ )
expect(factory.description).to eq('test object')
expect(factory.inheritable?).to eq(true)
expect(factory.reserved?).to eq(true)
diff --git a/spec/lib/gitlab/config/entry/factory_spec.rb b/spec/lib/gitlab/config/entry/factory_spec.rb
index a00c45169ef..260b5cf0ade 100644
--- a/spec/lib/gitlab/config/entry/factory_spec.rb
+++ b/spec/lib/gitlab/config/entry/factory_spec.rb
@@ -115,5 +115,16 @@ RSpec.describe Gitlab::Config::Entry::Factory do
.with('some value', { some: 'hash' })
end
end
+
+ context 'when setting deprecation information' do
+ it 'passes deprecation as a parameter' do
+ entry = factory
+ .value('some value')
+ .with(deprecation: { deprecated: '10.0', warning: '10.1', removed: '11.0', documentation: 'docs' })
+ .create!
+
+ expect(entry.deprecation).to eq({ deprecated: '10.0', warning: '10.1', removed: '11.0', documentation: 'docs' })
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/content_security_policy/config_loader_spec.rb b/spec/lib/gitlab/content_security_policy/config_loader_spec.rb
index 56e3fc269e6..08d29f7842c 100644
--- a/spec/lib/gitlab/content_security_policy/config_loader_spec.rb
+++ b/spec/lib/gitlab/content_security_policy/config_loader_spec.rb
@@ -85,7 +85,7 @@ RSpec.describe Gitlab::ContentSecurityPolicy::ConfigLoader do
expect(directives['style_src']).to eq("'self' 'unsafe-inline' https://cdn.example.com")
expect(directives['font_src']).to eq("'self' https://cdn.example.com")
expect(directives['worker_src']).to eq('http://localhost/assets/ blob: data: https://cdn.example.com')
- expect(directives['frame_src']).to eq(::Gitlab::ContentSecurityPolicy::Directives.frame_src + " https://cdn.example.com http://localhost/admin/ http://localhost/assets/ http://localhost/-/speedscope/index.html")
+ expect(directives['frame_src']).to eq(::Gitlab::ContentSecurityPolicy::Directives.frame_src + " https://cdn.example.com http://localhost/admin/ http://localhost/assets/ http://localhost/-/speedscope/index.html http://localhost/-/sandbox/mermaid")
end
end
@@ -113,7 +113,7 @@ RSpec.describe Gitlab::ContentSecurityPolicy::ConfigLoader do
end
it 'does not add CUSTOMER_PORTAL_URL to CSP' do
- expect(directives['frame_src']).to eq(::Gitlab::ContentSecurityPolicy::Directives.frame_src + " http://localhost/admin/ http://localhost/assets/ http://localhost/-/speedscope/index.html")
+ expect(directives['frame_src']).to eq(::Gitlab::ContentSecurityPolicy::Directives.frame_src + " http://localhost/admin/ http://localhost/assets/ http://localhost/-/speedscope/index.html http://localhost/-/sandbox/mermaid")
end
end
@@ -123,7 +123,7 @@ RSpec.describe Gitlab::ContentSecurityPolicy::ConfigLoader do
end
it 'adds CUSTOMER_PORTAL_URL to CSP' do
- expect(directives['frame_src']).to eq(::Gitlab::ContentSecurityPolicy::Directives.frame_src + " http://localhost/rails/letter_opener/ https://customers.example.com http://localhost/admin/ http://localhost/assets/ http://localhost/-/speedscope/index.html")
+ expect(directives['frame_src']).to eq(::Gitlab::ContentSecurityPolicy::Directives.frame_src + " http://localhost/rails/letter_opener/ https://customers.example.com http://localhost/admin/ http://localhost/assets/ http://localhost/-/speedscope/index.html http://localhost/-/sandbox/mermaid")
end
end
end
diff --git a/spec/lib/gitlab/data_builder/archive_trace_spec.rb b/spec/lib/gitlab/data_builder/archive_trace_spec.rb
new file mode 100644
index 00000000000..a310b0f0a94
--- /dev/null
+++ b/spec/lib/gitlab/data_builder/archive_trace_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::DataBuilder::ArchiveTrace do
+ let_it_be(:build) { create(:ci_build, :trace_artifact) }
+
+ describe '.build' do
+ let(:data) { described_class.build(build) }
+
+ it 'has correct attributes', :aggregate_failures do
+ expect(data[:object_kind]).to eq 'archive_trace'
+ expect(data[:trace_url]).to eq build.job_artifacts_trace.file.url
+ expect(data[:build_id]).to eq build.id
+ expect(data[:pipeline_id]).to eq build.pipeline_id
+ expect(data[:project]).to eq build.project.hook_attrs
+ end
+ end
+end
diff --git a/spec/lib/gitlab/data_builder/deployment_spec.rb b/spec/lib/gitlab/data_builder/deployment_spec.rb
index 75741c52579..ab8c8a51694 100644
--- a/spec/lib/gitlab/data_builder/deployment_spec.rb
+++ b/spec/lib/gitlab/data_builder/deployment_spec.rb
@@ -37,6 +37,7 @@ RSpec.describe Gitlab::DataBuilder::Deployment do
expect(data[:user_url]).to eq(expected_user_url)
expect(data[:commit_url]).to eq(expected_commit_url)
expect(data[:commit_title]).to eq(commit.title)
+ expect(data[:ref]).to eq(deployment.ref)
end
it 'does not include the deployable URL when there is no deployable' do
diff --git a/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb b/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb
index 49714cfc4dd..01d61a525e6 100644
--- a/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb
+++ b/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb
@@ -336,8 +336,8 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigration, type: :m
end
describe '#smoothed_time_efficiency' do
- let(:migration) { create(:batched_background_migration, interval: 120.seconds) }
- let(:end_time) { Time.zone.now }
+ let_it_be(:migration) { create(:batched_background_migration, interval: 120.seconds) }
+ let_it_be(:end_time) { Time.zone.now }
around do |example|
freeze_time do
@@ -345,7 +345,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigration, type: :m
end
end
- let(:common_attrs) do
+ let_it_be(:common_attrs) do
{
status: :succeeded,
batched_migration: migration,
@@ -364,13 +364,14 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigration, type: :m
end
context 'when there are enough jobs' do
- subject { migration.smoothed_time_efficiency(number_of_jobs: number_of_jobs) }
+ let_it_be(:number_of_jobs) { 10 }
+ let_it_be(:jobs) { create_list(:batched_background_migration_job, number_of_jobs, **common_attrs.merge(batched_migration: migration)) }
- let!(:jobs) { create_list(:batched_background_migration_job, number_of_jobs, **common_attrs.merge(batched_migration: migration)) }
- let(:number_of_jobs) { 10 }
+ subject { migration.smoothed_time_efficiency(number_of_jobs: number_of_jobs) }
before do
- expect(migration).to receive_message_chain(:batched_jobs, :successful_in_execution_order, :reverse_order, :limit).with(no_args).with(no_args).with(number_of_jobs).and_return(jobs)
+ expect(migration).to receive_message_chain(:batched_jobs, :successful_in_execution_order, :reverse_order, :limit, :with_preloads)
+ .and_return(jobs)
end
def mock_efficiencies(*effs)
@@ -411,6 +412,18 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigration, type: :m
end
end
end
+
+ context 'with preloaded batched migration' do
+ it 'avoids N+1' do
+ create_list(:batched_background_migration_job, 11, **common_attrs.merge(started_at: end_time - 10.seconds))
+
+ control = ActiveRecord::QueryRecorder.new do
+ migration.smoothed_time_efficiency(number_of_jobs: 10)
+ end
+
+ expect { migration.smoothed_time_efficiency(number_of_jobs: 11) }.not_to exceed_query_limit(control)
+ end
+ end
end
describe '#optimize!' do
diff --git a/spec/lib/gitlab/database/background_migration_job_spec.rb b/spec/lib/gitlab/database/background_migration_job_spec.rb
index 42695925a1c..1117c17c84a 100644
--- a/spec/lib/gitlab/database/background_migration_job_spec.rb
+++ b/spec/lib/gitlab/database/background_migration_job_spec.rb
@@ -5,6 +5,8 @@ require 'spec_helper'
RSpec.describe Gitlab::Database::BackgroundMigrationJob do
it_behaves_like 'having unique enum values'
+ it { is_expected.to be_a Gitlab::Database::SharedModel }
+
describe '.for_migration_execution' do
let!(:job1) { create(:background_migration_job) }
let!(:job2) { create(:background_migration_job, arguments: ['hi', 2]) }
diff --git a/spec/lib/gitlab/database/batch_count_spec.rb b/spec/lib/gitlab/database/batch_count_spec.rb
index 9831510f014..028bdce852e 100644
--- a/spec/lib/gitlab/database/batch_count_spec.rb
+++ b/spec/lib/gitlab/database/batch_count_spec.rb
@@ -270,8 +270,6 @@ RSpec.describe Gitlab::Database::BatchCount do
end
it "defaults the batch size to #{Gitlab::Database::BatchCounter::DEFAULT_DISTINCT_BATCH_SIZE}" do
- stub_feature_flags(loose_index_scan_for_distinct_values: false)
-
min_id = model.minimum(:id)
relation = instance_double(ActiveRecord::Relation)
allow(model).to receive_message_chain(:select, public_send: relation)
@@ -317,85 +315,13 @@ RSpec.describe Gitlab::Database::BatchCount do
end
end
- context 'when the loose_index_scan_for_distinct_values feature flag is off' do
- it_behaves_like 'when batch fetch query is canceled' do
- let(:mode) { :distinct }
- let(:operation) { :count }
- let(:operation_args) { nil }
- let(:column) { nil }
-
- subject { described_class.method(:batch_distinct_count) }
-
- before do
- stub_feature_flags(loose_index_scan_for_distinct_values: false)
- end
- end
- end
-
- context 'when the loose_index_scan_for_distinct_values feature flag is on' do
+ it_behaves_like 'when batch fetch query is canceled' do
let(:mode) { :distinct }
let(:operation) { :count }
let(:operation_args) { nil }
let(:column) { nil }
- let(:batch_size) { 10_000 }
-
subject { described_class.method(:batch_distinct_count) }
-
- before do
- stub_feature_flags(loose_index_scan_for_distinct_values: true)
- end
-
- it 'reduces batch size by half and retry fetch' do
- too_big_batch_relation_mock = instance_double(ActiveRecord::Relation)
-
- count_method = double(send: 1)
-
- allow(too_big_batch_relation_mock).to receive(:send).and_raise(ActiveRecord::QueryCanceled)
- allow(Gitlab::Database::LooseIndexScanDistinctCount).to receive_message_chain(:new, :build_query).with(from: 0, to: batch_size).and_return(too_big_batch_relation_mock)
- allow(Gitlab::Database::LooseIndexScanDistinctCount).to receive_message_chain(:new, :build_query).with(from: 0, to: batch_size / 2).and_return(count_method)
- allow(Gitlab::Database::LooseIndexScanDistinctCount).to receive_message_chain(:new, :build_query).with(from: batch_size / 2, to: batch_size).and_return(count_method)
-
- subject.call(model, column, batch_size: batch_size, start: 0, finish: batch_size - 1)
- end
-
- context 'when all retries fail' do
- let(:batch_count_query) { 'SELECT COUNT(id) FROM relation WHERE id BETWEEN 0 and 1' }
-
- before do
- relation = instance_double(ActiveRecord::Relation)
- allow(Gitlab::Database::LooseIndexScanDistinctCount).to receive_message_chain(:new, :build_query).and_return(relation)
- allow(relation).to receive(:send).and_raise(ActiveRecord::QueryCanceled.new('query timed out'))
- allow(relation).to receive(:to_sql).and_return(batch_count_query)
- end
-
- it 'logs failing query' do
- expect(Gitlab::AppJsonLogger).to receive(:error).with(
- event: 'batch_count',
- relation: model.table_name,
- operation: operation,
- operation_args: operation_args,
- start: 0,
- mode: mode,
- query: batch_count_query,
- message: 'Query has been canceled with message: query timed out'
- )
- expect(subject.call(model, column, batch_size: batch_size, start: 0)).to eq(-1)
- end
- end
-
- context 'when LooseIndexScanDistinctCount raises error' do
- let(:column) { :creator_id }
- let(:error_class) { Gitlab::Database::LooseIndexScanDistinctCount::ColumnConfigurationError }
-
- it 'rescues ColumnConfigurationError' do
- allow(Gitlab::Database::LooseIndexScanDistinctCount).to receive(:new).and_raise(error_class.new('error message'))
-
- expect(Gitlab::AppJsonLogger).to receive(:error).with(a_hash_including(message: 'LooseIndexScanDistinctCount column error: error message'))
-
- expect(subject.call(Project, column, batch_size: 10_000, start: 0)).to eq(-1)
- end
- end
end
end
diff --git a/spec/lib/gitlab/database/bulk_update_spec.rb b/spec/lib/gitlab/database/bulk_update_spec.rb
index 9a6463c99fa..08b4d50f83b 100644
--- a/spec/lib/gitlab/database/bulk_update_spec.rb
+++ b/spec/lib/gitlab/database/bulk_update_spec.rb
@@ -101,7 +101,7 @@ RSpec.describe Gitlab::Database::BulkUpdate do
before do
configuration_hash = ActiveRecord::Base.connection_db_config.configuration_hash
- ActiveRecord::Base.establish_connection(
+ ActiveRecord::Base.establish_connection( # rubocop: disable Database/EstablishConnection
configuration_hash.merge(prepared_statements: prepared_statements)
)
end
diff --git a/spec/lib/gitlab/database/loose_index_scan_distinct_count_spec.rb b/spec/lib/gitlab/database/loose_index_scan_distinct_count_spec.rb
deleted file mode 100644
index e0eac26e4d9..00000000000
--- a/spec/lib/gitlab/database/loose_index_scan_distinct_count_spec.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::Database::LooseIndexScanDistinctCount do
- context 'counting distinct users' do
- let_it_be(:user) { create(:user) }
- let_it_be(:other_user) { create(:user) }
-
- let(:column) { :creator_id }
-
- before_all do
- create_list(:project, 3, creator: user)
- create_list(:project, 1, creator: other_user)
- end
-
- subject(:count) { described_class.new(Project, :creator_id).count(from: Project.minimum(:creator_id), to: Project.maximum(:creator_id) + 1) }
-
- it { is_expected.to eq(2) }
-
- context 'when STI model is queried' do
- it 'does not raise error' do
- expect { described_class.new(Group, :owner_id).count(from: 0, to: 1) }.not_to raise_error
- end
- end
-
- context 'when model with default_scope is queried' do
- it 'does not raise error' do
- expect { described_class.new(GroupMember, :id).count(from: 0, to: 1) }.not_to raise_error
- end
- end
-
- context 'when the fully qualified column is given' do
- let(:column) { 'projects.creator_id' }
-
- it { is_expected.to eq(2) }
- end
-
- context 'when AR attribute is given' do
- let(:column) { Project.arel_table[:creator_id] }
-
- it { is_expected.to eq(2) }
- end
-
- context 'when invalid value is given for the column' do
- let(:column) { Class.new }
-
- it { expect { described_class.new(Group, column) }.to raise_error(Gitlab::Database::LooseIndexScanDistinctCount::ColumnConfigurationError) }
- end
-
- context 'when null values are present' do
- before do
- create_list(:project, 2).each { |p| p.update_column(:creator_id, nil) }
- end
-
- it { is_expected.to eq(2) }
- end
- end
-
- context 'counting STI models' do
- let!(:groups) { create_list(:group, 3) }
- let!(:namespaces) { create_list(:namespace, 2) }
-
- let(:max_id) { Namespace.maximum(:id) + 1 }
-
- it 'counts groups' do
- count = described_class.new(Group, :id).count(from: 0, to: max_id)
- expect(count).to eq(3)
- end
- end
-end
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index 7f80bed04a4..7e3de32b965 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -1752,116 +1752,6 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
end
end
- describe '#change_column_type_using_background_migration' do
- let!(:issue) { create(:issue, :closed, closed_at: Time.zone.now) }
-
- let(:issue_model) do
- Class.new(ActiveRecord::Base) do
- self.table_name = 'issues'
- include EachBatch
- end
- end
-
- it 'changes the type of a column using a background migration' do
- expect(model)
- .to receive(:add_column)
- .with('issues', 'closed_at_for_type_change', :datetime_with_timezone)
-
- expect(model)
- .to receive(:install_rename_triggers)
- .with('issues', :closed_at, 'closed_at_for_type_change')
-
- expect(BackgroundMigrationWorker)
- .to receive(:perform_in)
- .ordered
- .with(
- 10.minutes,
- 'CopyColumn',
- ['issues', :closed_at, 'closed_at_for_type_change', issue.id, issue.id]
- )
-
- expect(BackgroundMigrationWorker)
- .to receive(:perform_in)
- .ordered
- .with(
- 1.hour + 10.minutes,
- 'CleanupConcurrentTypeChange',
- ['issues', :closed_at, 'closed_at_for_type_change']
- )
-
- expect(Gitlab::BackgroundMigration)
- .to receive(:steal)
- .ordered
- .with('CopyColumn')
-
- expect(Gitlab::BackgroundMigration)
- .to receive(:steal)
- .ordered
- .with('CleanupConcurrentTypeChange')
-
- model.change_column_type_using_background_migration(
- issue_model.all,
- :closed_at,
- :datetime_with_timezone
- )
- end
- end
-
- describe '#rename_column_using_background_migration' do
- let!(:issue) { create(:issue, :closed, closed_at: Time.zone.now) }
-
- it 'renames a column using a background migration' do
- expect(model)
- .to receive(:add_column)
- .with(
- 'issues',
- :closed_at_timestamp,
- :datetime_with_timezone,
- limit: anything,
- precision: anything,
- scale: anything
- )
-
- expect(model)
- .to receive(:install_rename_triggers)
- .with('issues', :closed_at, :closed_at_timestamp)
-
- expect(BackgroundMigrationWorker)
- .to receive(:perform_in)
- .ordered
- .with(
- 10.minutes,
- 'CopyColumn',
- ['issues', :closed_at, :closed_at_timestamp, issue.id, issue.id]
- )
-
- expect(BackgroundMigrationWorker)
- .to receive(:perform_in)
- .ordered
- .with(
- 1.hour + 10.minutes,
- 'CleanupConcurrentRename',
- ['issues', :closed_at, :closed_at_timestamp]
- )
-
- expect(Gitlab::BackgroundMigration)
- .to receive(:steal)
- .ordered
- .with('CopyColumn')
-
- expect(Gitlab::BackgroundMigration)
- .to receive(:steal)
- .ordered
- .with('CleanupConcurrentRename')
-
- model.rename_column_using_background_migration(
- 'issues',
- :closed_at,
- :closed_at_timestamp
- )
- end
- end
-
describe '#convert_to_bigint_column' do
it 'returns the name of the temporary column used to convert to bigint' do
expect(model.convert_to_bigint_column(:id)).to eq('id_convert_to_bigint')
@@ -2065,8 +1955,6 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
t.integer :other_id
t.timestamps
end
-
- allow(model).to receive(:perform_background_migration_inline?).and_return(false)
end
context 'when the target table does not exist' do
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 99c7d70724c..0abb76b9f8a 100644
--- a/spec/lib/gitlab/database/migrations/background_migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migrations/background_migration_helpers_spec.rb
@@ -7,249 +7,208 @@ RSpec.describe Gitlab::Database::Migrations::BackgroundMigrationHelpers do
ActiveRecord::Migration.new.extend(described_class)
end
- describe '#queue_background_migration_jobs_by_range_at_intervals' do
- context 'when the model has an ID column' do
- let!(:id1) { create(:user).id }
- let!(:id2) { create(:user).id }
- let!(:id3) { create(:user).id }
-
- around do |example|
- freeze_time { example.run }
- end
-
- before do
- User.class_eval do
- include EachBatch
- end
- end
+ shared_examples_for 'helpers that enqueue background migrations' do |worker_class, tracking_database|
+ before do
+ allow(model).to receive(:tracking_database).and_return(tracking_database)
+ end
- it 'returns the final expected delay' do
- Sidekiq::Testing.fake! do
- final_delay = model.queue_background_migration_jobs_by_range_at_intervals(User, 'FooJob', 10.minutes, batch_size: 2)
+ describe '#queue_background_migration_jobs_by_range_at_intervals' do
+ context 'when the model has an ID column' do
+ let!(:id1) { create(:user).id }
+ let!(:id2) { create(:user).id }
+ let!(:id3) { create(:user).id }
- expect(final_delay.to_f).to eq(20.minutes.to_f)
+ around do |example|
+ freeze_time { example.run }
end
- end
-
- it 'returns zero when nothing gets queued' do
- Sidekiq::Testing.fake! do
- final_delay = model.queue_background_migration_jobs_by_range_at_intervals(User.none, 'FooJob', 10.minutes)
- expect(final_delay).to eq(0)
+ before do
+ User.class_eval do
+ include EachBatch
+ end
end
- end
- context 'with batch_size option' do
- it 'queues jobs correctly' do
+ it 'returns the final expected delay' do
Sidekiq::Testing.fake! do
- model.queue_background_migration_jobs_by_range_at_intervals(User, 'FooJob', 10.minutes, batch_size: 2)
+ final_delay = model.queue_background_migration_jobs_by_range_at_intervals(User, 'FooJob', 10.minutes, batch_size: 2)
- expect(BackgroundMigrationWorker.jobs[0]['args']).to eq(['FooJob', [id1, id2]])
- expect(BackgroundMigrationWorker.jobs[0]['at']).to eq(10.minutes.from_now.to_f)
- expect(BackgroundMigrationWorker.jobs[1]['args']).to eq(['FooJob', [id3, id3]])
- expect(BackgroundMigrationWorker.jobs[1]['at']).to eq(20.minutes.from_now.to_f)
+ expect(final_delay.to_f).to eq(20.minutes.to_f)
end
end
- end
- context 'without batch_size option' do
- it 'queues jobs correctly' do
+ it 'returns zero when nothing gets queued' do
Sidekiq::Testing.fake! do
- model.queue_background_migration_jobs_by_range_at_intervals(User, 'FooJob', 10.minutes)
+ final_delay = model.queue_background_migration_jobs_by_range_at_intervals(User.none, 'FooJob', 10.minutes)
- expect(BackgroundMigrationWorker.jobs[0]['args']).to eq(['FooJob', [id1, id3]])
- expect(BackgroundMigrationWorker.jobs[0]['at']).to eq(10.minutes.from_now.to_f)
+ expect(final_delay).to eq(0)
end
end
- end
- context 'with other_job_arguments option' do
- it 'queues jobs correctly' do
- Sidekiq::Testing.fake! do
- model.queue_background_migration_jobs_by_range_at_intervals(User, 'FooJob', 10.minutes, other_job_arguments: [1, 2])
+ context 'when the delay_interval is smaller than the minimum' do
+ it 'sets the delay_interval to the minimum value' do
+ Sidekiq::Testing.fake! do
+ final_delay = model.queue_background_migration_jobs_by_range_at_intervals(User, 'FooJob', 1.minute, batch_size: 2)
- expect(BackgroundMigrationWorker.jobs[0]['args']).to eq(['FooJob', [id1, id3, 1, 2]])
- expect(BackgroundMigrationWorker.jobs[0]['at']).to eq(10.minutes.from_now.to_f)
+ expect(worker_class.jobs[0]['args']).to eq(['FooJob', [id1, id2]])
+ expect(worker_class.jobs[0]['at']).to eq(2.minutes.from_now.to_f)
+ expect(worker_class.jobs[1]['args']).to eq(['FooJob', [id3, id3]])
+ expect(worker_class.jobs[1]['at']).to eq(4.minutes.from_now.to_f)
+
+ expect(final_delay.to_f).to eq(4.minutes.to_f)
+ end
end
end
- end
- context 'with initial_delay option' do
- it 'queues jobs correctly' do
- Sidekiq::Testing.fake! do
- model.queue_background_migration_jobs_by_range_at_intervals(User, 'FooJob', 10.minutes, other_job_arguments: [1, 2], initial_delay: 10.minutes)
+ context 'with batch_size option' do
+ it 'queues jobs correctly' do
+ Sidekiq::Testing.fake! do
+ model.queue_background_migration_jobs_by_range_at_intervals(User, 'FooJob', 10.minutes, batch_size: 2)
- expect(BackgroundMigrationWorker.jobs[0]['args']).to eq(['FooJob', [id1, id3, 1, 2]])
- expect(BackgroundMigrationWorker.jobs[0]['at']).to eq(20.minutes.from_now.to_f)
+ expect(worker_class.jobs[0]['args']).to eq(['FooJob', [id1, id2]])
+ expect(worker_class.jobs[0]['at']).to eq(10.minutes.from_now.to_f)
+ expect(worker_class.jobs[1]['args']).to eq(['FooJob', [id3, id3]])
+ expect(worker_class.jobs[1]['at']).to eq(20.minutes.from_now.to_f)
+ end
end
end
- end
-
- context 'with track_jobs option' do
- it 'creates a record for each job in the database' do
- Sidekiq::Testing.fake! do
- expect do
- model.queue_background_migration_jobs_by_range_at_intervals(User, '::FooJob', 10.minutes,
- other_job_arguments: [1, 2], track_jobs: true)
- end.to change { Gitlab::Database::BackgroundMigrationJob.count }.from(0).to(1)
-
- expect(BackgroundMigrationWorker.jobs.size).to eq(1)
- tracked_job = Gitlab::Database::BackgroundMigrationJob.first
+ context 'without batch_size option' do
+ it 'queues jobs correctly' do
+ Sidekiq::Testing.fake! do
+ model.queue_background_migration_jobs_by_range_at_intervals(User, 'FooJob', 10.minutes)
- expect(tracked_job.class_name).to eq('FooJob')
- expect(tracked_job.arguments).to eq([id1, id3, 1, 2])
- expect(tracked_job).to be_pending
+ expect(worker_class.jobs[0]['args']).to eq(['FooJob', [id1, id3]])
+ expect(worker_class.jobs[0]['at']).to eq(10.minutes.from_now.to_f)
+ end
end
end
- end
- context 'without track_jobs option' do
- it 'does not create records in the database' do
- Sidekiq::Testing.fake! do
- expect do
+ context 'with other_job_arguments option' do
+ it 'queues jobs correctly' do
+ Sidekiq::Testing.fake! do
model.queue_background_migration_jobs_by_range_at_intervals(User, 'FooJob', 10.minutes, other_job_arguments: [1, 2])
- end.not_to change { Gitlab::Database::BackgroundMigrationJob.count }
- expect(BackgroundMigrationWorker.jobs.size).to eq(1)
+ expect(worker_class.jobs[0]['args']).to eq(['FooJob', [id1, id3, 1, 2]])
+ expect(worker_class.jobs[0]['at']).to eq(10.minutes.from_now.to_f)
+ end
end
end
- end
- end
-
- context 'when the model specifies a primary_column_name' do
- let!(:id1) { create(:container_expiration_policy).id }
- let!(:id2) { create(:container_expiration_policy).id }
- let!(:id3) { create(:container_expiration_policy).id }
- around do |example|
- freeze_time { example.run }
- end
+ context 'with initial_delay option' do
+ it 'queues jobs correctly' do
+ Sidekiq::Testing.fake! do
+ model.queue_background_migration_jobs_by_range_at_intervals(User, 'FooJob', 10.minutes, other_job_arguments: [1, 2], initial_delay: 10.minutes)
- before do
- ContainerExpirationPolicy.class_eval do
- include EachBatch
+ expect(worker_class.jobs[0]['args']).to eq(['FooJob', [id1, id3, 1, 2]])
+ expect(worker_class.jobs[0]['at']).to eq(20.minutes.from_now.to_f)
+ end
+ end
end
- end
- it 'returns the final expected delay', :aggregate_failures do
- Sidekiq::Testing.fake! do
- final_delay = model.queue_background_migration_jobs_by_range_at_intervals(ContainerExpirationPolicy, 'FooJob', 10.minutes, batch_size: 2, primary_column_name: :project_id)
+ context 'with track_jobs option' do
+ it 'creates a record for each job in the database' do
+ Sidekiq::Testing.fake! do
+ expect do
+ model.queue_background_migration_jobs_by_range_at_intervals(User, '::FooJob', 10.minutes,
+ other_job_arguments: [1, 2], track_jobs: true)
+ end.to change { Gitlab::Database::BackgroundMigrationJob.count }.from(0).to(1)
- expect(final_delay.to_f).to eq(20.minutes.to_f)
- expect(BackgroundMigrationWorker.jobs[0]['args']).to eq(['FooJob', [id1, id2]])
- expect(BackgroundMigrationWorker.jobs[0]['at']).to eq(10.minutes.from_now.to_f)
- expect(BackgroundMigrationWorker.jobs[1]['args']).to eq(['FooJob', [id3, id3]])
- expect(BackgroundMigrationWorker.jobs[1]['at']).to eq(20.minutes.from_now.to_f)
- end
- end
+ expect(worker_class.jobs.size).to eq(1)
- context "when the primary_column_name is not an integer" 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
- end
+ tracked_job = Gitlab::Database::BackgroundMigrationJob.first
- context "when the primary_column_name does not exist" do
- it 'raises error' do
- expect do
- model.queue_background_migration_jobs_by_range_at_intervals(ContainerExpirationPolicy, 'FooJob', 10.minutes, primary_column_name: :foo)
- end.to raise_error(StandardError, /does not have an ID column of foo/)
+ expect(tracked_job.class_name).to eq('FooJob')
+ expect(tracked_job.arguments).to eq([id1, id3, 1, 2])
+ expect(tracked_job).to be_pending
+ end
+ end
end
- end
- end
-
- context "when the model doesn't have an ID or primary_column_name column" do
- it 'raises error (for now)' do
- expect do
- model.queue_background_migration_jobs_by_range_at_intervals(ProjectAuthorization, 'FooJob', 10.seconds)
- end.to raise_error(StandardError, /does not have an ID/)
- end
- end
- end
- describe '#requeue_background_migration_jobs_by_range_at_intervals' do
- let!(:job_class_name) { 'TestJob' }
- let!(:pending_job_1) { create(:background_migration_job, class_name: job_class_name, status: :pending, arguments: [1, 2]) }
- let!(:pending_job_2) { create(:background_migration_job, class_name: job_class_name, status: :pending, arguments: [3, 4]) }
- let!(:successful_job_1) { create(:background_migration_job, class_name: job_class_name, status: :succeeded, arguments: [5, 6]) }
- let!(:successful_job_2) { create(:background_migration_job, class_name: job_class_name, status: :succeeded, arguments: [7, 8]) }
+ context 'without track_jobs option' do
+ it 'does not create records in the database' do
+ Sidekiq::Testing.fake! do
+ expect do
+ model.queue_background_migration_jobs_by_range_at_intervals(User, 'FooJob', 10.minutes, other_job_arguments: [1, 2])
+ end.not_to change { Gitlab::Database::BackgroundMigrationJob.count }
- around do |example|
- freeze_time do
- Sidekiq::Testing.fake! do
- example.run
+ expect(worker_class.jobs.size).to eq(1)
+ end
+ end
end
end
- end
-
- subject { model.requeue_background_migration_jobs_by_range_at_intervals(job_class_name, 10.minutes) }
-
- it 'returns the expected duration' do
- expect(subject).to eq(20.minutes)
- end
- context 'when nothing is queued' do
- subject { model.requeue_background_migration_jobs_by_range_at_intervals('FakeJob', 10.minutes) }
+ context 'when the model specifies a primary_column_name' do
+ let!(:id1) { create(:container_expiration_policy).id }
+ let!(:id2) { create(:container_expiration_policy).id }
+ let!(:id3) { create(:container_expiration_policy).id }
- it 'returns expected duration of zero when nothing gets queued' do
- expect(subject).to eq(0)
- end
- end
-
- it 'queues pending jobs' do
- subject
+ around do |example|
+ freeze_time { example.run }
+ end
- expect(BackgroundMigrationWorker.jobs[0]['args']).to eq([job_class_name, [1, 2]])
- expect(BackgroundMigrationWorker.jobs[0]['at']).to be_nil
- expect(BackgroundMigrationWorker.jobs[1]['args']).to eq([job_class_name, [3, 4]])
- expect(BackgroundMigrationWorker.jobs[1]['at']).to eq(10.minutes.from_now.to_f)
- end
+ before do
+ ContainerExpirationPolicy.class_eval do
+ include EachBatch
+ end
+ end
- context 'with batch_size option' do
- subject { model.requeue_background_migration_jobs_by_range_at_intervals(job_class_name, 10.minutes, batch_size: 1) }
+ it 'returns the final expected delay', :aggregate_failures do
+ Sidekiq::Testing.fake! do
+ final_delay = model.queue_background_migration_jobs_by_range_at_intervals(ContainerExpirationPolicy, 'FooJob', 10.minutes, batch_size: 2, primary_column_name: :project_id)
- it 'returns the expected duration' do
- expect(subject).to eq(20.minutes)
- end
+ expect(final_delay.to_f).to eq(20.minutes.to_f)
+ expect(worker_class.jobs[0]['args']).to eq(['FooJob', [id1, id2]])
+ expect(worker_class.jobs[0]['at']).to eq(10.minutes.from_now.to_f)
+ expect(worker_class.jobs[1]['args']).to eq(['FooJob', [id3, id3]])
+ expect(worker_class.jobs[1]['at']).to eq(20.minutes.from_now.to_f)
+ end
+ end
- it 'queues pending jobs' do
- subject
+ context "when the primary_column_name is not an integer" 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
+ end
- expect(BackgroundMigrationWorker.jobs[0]['args']).to eq([job_class_name, [1, 2]])
- expect(BackgroundMigrationWorker.jobs[0]['at']).to be_nil
- expect(BackgroundMigrationWorker.jobs[1]['args']).to eq([job_class_name, [3, 4]])
- expect(BackgroundMigrationWorker.jobs[1]['at']).to eq(10.minutes.from_now.to_f)
+ context "when the primary_column_name does not exist" do
+ it 'raises error' do
+ expect do
+ model.queue_background_migration_jobs_by_range_at_intervals(ContainerExpirationPolicy, 'FooJob', 10.minutes, primary_column_name: :foo)
+ end.to raise_error(StandardError, /does not have an ID column of foo/)
+ end
+ end
end
- it 'retrieve jobs in batches' do
- jobs = double('jobs')
- expect(Gitlab::Database::BackgroundMigrationJob).to receive(:pending) { jobs }
- allow(jobs).to receive(:where).with(class_name: job_class_name) { jobs }
- expect(jobs).to receive(:each_batch).with(of: 1)
-
- subject
+ context "when the model doesn't have an ID or primary_column_name column" do
+ it 'raises error (for now)' do
+ expect do
+ model.queue_background_migration_jobs_by_range_at_intervals(ProjectAuthorization, 'FooJob', 10.seconds)
+ end.to raise_error(StandardError, /does not have an ID/)
+ end
end
end
- context 'with initial_delay option' do
- let_it_be(:initial_delay) { 3.minutes }
+ describe '#requeue_background_migration_jobs_by_range_at_intervals' do
+ let!(:job_class_name) { 'TestJob' }
+ let!(:pending_job_1) { create(:background_migration_job, class_name: job_class_name, status: :pending, arguments: [1, 2]) }
+ let!(:pending_job_2) { create(:background_migration_job, class_name: job_class_name, status: :pending, arguments: [3, 4]) }
+ let!(:successful_job_1) { create(:background_migration_job, class_name: job_class_name, status: :succeeded, arguments: [5, 6]) }
+ let!(:successful_job_2) { create(:background_migration_job, class_name: job_class_name, status: :succeeded, arguments: [7, 8]) }
- subject { model.requeue_background_migration_jobs_by_range_at_intervals(job_class_name, 10.minutes, initial_delay: initial_delay) }
-
- it 'returns the expected duration' do
- expect(subject).to eq(23.minutes)
+ around do |example|
+ freeze_time do
+ Sidekiq::Testing.fake! do
+ example.run
+ end
+ end
end
- it 'queues pending jobs' do
- subject
+ subject { model.requeue_background_migration_jobs_by_range_at_intervals(job_class_name, 10.minutes) }
- expect(BackgroundMigrationWorker.jobs[0]['args']).to eq([job_class_name, [1, 2]])
- expect(BackgroundMigrationWorker.jobs[0]['at']).to eq(3.minutes.from_now.to_f)
- expect(BackgroundMigrationWorker.jobs[1]['args']).to eq([job_class_name, [3, 4]])
- expect(BackgroundMigrationWorker.jobs[1]['at']).to eq(13.minutes.from_now.to_f)
+ it 'returns the expected duration' do
+ expect(subject).to eq(20.minutes)
end
context 'when nothing is queued' do
@@ -259,195 +218,226 @@ RSpec.describe Gitlab::Database::Migrations::BackgroundMigrationHelpers do
expect(subject).to eq(0)
end
end
- end
- end
- describe '#perform_background_migration_inline?' do
- it 'returns true in a test environment' do
- stub_rails_env('test')
+ it 'queues pending jobs' do
+ subject
- expect(model.perform_background_migration_inline?).to eq(true)
- end
+ expect(worker_class.jobs[0]['args']).to eq([job_class_name, [1, 2]])
+ expect(worker_class.jobs[0]['at']).to be_nil
+ expect(worker_class.jobs[1]['args']).to eq([job_class_name, [3, 4]])
+ expect(worker_class.jobs[1]['at']).to eq(10.minutes.from_now.to_f)
+ end
- it 'returns true in a development environment' do
- stub_rails_env('development')
+ context 'with batch_size option' do
+ subject { model.requeue_background_migration_jobs_by_range_at_intervals(job_class_name, 10.minutes, batch_size: 1) }
- expect(model.perform_background_migration_inline?).to eq(true)
- end
+ it 'returns the expected duration' do
+ expect(subject).to eq(20.minutes)
+ end
- it 'returns false in a production environment' do
- stub_rails_env('production')
+ it 'queues pending jobs' do
+ subject
- expect(model.perform_background_migration_inline?).to eq(false)
- end
- end
+ expect(worker_class.jobs[0]['args']).to eq([job_class_name, [1, 2]])
+ expect(worker_class.jobs[0]['at']).to be_nil
+ expect(worker_class.jobs[1]['args']).to eq([job_class_name, [3, 4]])
+ expect(worker_class.jobs[1]['at']).to eq(10.minutes.from_now.to_f)
+ end
- describe '#migrate_async' do
- it 'calls BackgroundMigrationWorker.perform_async' do
- expect(BackgroundMigrationWorker).to receive(:perform_async).with("Class", "hello", "world")
+ it 'retrieve jobs in batches' do
+ jobs = double('jobs')
+ expect(Gitlab::Database::BackgroundMigrationJob).to receive(:pending) { jobs }
+ allow(jobs).to receive(:where).with(class_name: job_class_name) { jobs }
+ expect(jobs).to receive(:each_batch).with(of: 1)
- model.migrate_async("Class", "hello", "world")
- end
+ subject
+ end
+ end
- it 'pushes a context with the current class name as caller_id' do
- expect(Gitlab::ApplicationContext).to receive(:with_context).with(caller_id: model.class.to_s)
+ context 'with initial_delay option' do
+ let_it_be(:initial_delay) { 3.minutes }
- model.migrate_async('Class', 'hello', 'world')
- end
- end
+ subject { model.requeue_background_migration_jobs_by_range_at_intervals(job_class_name, 10.minutes, initial_delay: initial_delay) }
- describe '#migrate_in' do
- it 'calls BackgroundMigrationWorker.perform_in' do
- expect(BackgroundMigrationWorker).to receive(:perform_in).with(10.minutes, 'Class', 'Hello', 'World')
+ it 'returns the expected duration' do
+ expect(subject).to eq(23.minutes)
+ end
- model.migrate_in(10.minutes, 'Class', 'Hello', 'World')
- end
+ it 'queues pending jobs' do
+ subject
+
+ expect(worker_class.jobs[0]['args']).to eq([job_class_name, [1, 2]])
+ expect(worker_class.jobs[0]['at']).to eq(3.minutes.from_now.to_f)
+ expect(worker_class.jobs[1]['args']).to eq([job_class_name, [3, 4]])
+ expect(worker_class.jobs[1]['at']).to eq(13.minutes.from_now.to_f)
+ end
- it 'pushes a context with the current class name as caller_id' do
- expect(Gitlab::ApplicationContext).to receive(:with_context).with(caller_id: model.class.to_s)
+ context 'when nothing is queued' do
+ subject { model.requeue_background_migration_jobs_by_range_at_intervals('FakeJob', 10.minutes) }
- model.migrate_in(10.minutes, 'Class', 'Hello', 'World')
+ it 'returns expected duration of zero when nothing gets queued' do
+ expect(subject).to eq(0)
+ end
+ end
+ end
end
- end
- describe '#bulk_migrate_async' do
- it 'calls BackgroundMigrationWorker.bulk_perform_async' do
- expect(BackgroundMigrationWorker).to receive(:bulk_perform_async).with([%w(Class hello world)])
+ describe '#finalized_background_migration' do
+ let(:coordinator) { Gitlab::BackgroundMigration::JobCoordinator.new(worker_class) }
- model.bulk_migrate_async([%w(Class hello world)])
- end
+ let!(:tracked_pending_job) { create(:background_migration_job, class_name: job_class_name, status: :pending, arguments: [1]) }
+ let!(:tracked_successful_job) { create(:background_migration_job, class_name: job_class_name, status: :succeeded, arguments: [2]) }
+ let!(:job_class_name) { 'TestJob' }
- it 'pushes a context with the current class name as caller_id' do
- expect(Gitlab::ApplicationContext).to receive(:with_context).with(caller_id: model.class.to_s)
+ let!(:job_class) do
+ Class.new do
+ def perform(*arguments)
+ Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded('TestJob', arguments)
+ end
+ end
+ end
- model.bulk_migrate_async([%w(Class hello world)])
- end
- end
+ before do
+ allow(Gitlab::BackgroundMigration).to receive(:coordinator_for_database)
+ .with('main').and_return(coordinator)
- describe '#bulk_migrate_in' do
- it 'calls BackgroundMigrationWorker.bulk_perform_in_' do
- expect(BackgroundMigrationWorker).to receive(:bulk_perform_in).with(10.minutes, [%w(Class hello world)])
+ expect(coordinator).to receive(:migration_class_for)
+ .with(job_class_name).at_least(:once) { job_class }
- model.bulk_migrate_in(10.minutes, [%w(Class hello world)])
- end
+ Sidekiq::Testing.disable! do
+ worker_class.perform_async(job_class_name, [1, 2])
+ worker_class.perform_async(job_class_name, [3, 4])
+ worker_class.perform_in(10, job_class_name, [5, 6])
+ worker_class.perform_in(20, job_class_name, [7, 8])
+ end
+ end
- it 'pushes a context with the current class name as caller_id' do
- expect(Gitlab::ApplicationContext).to receive(:with_context).with(caller_id: model.class.to_s)
+ it_behaves_like 'finalized tracked background migration', worker_class do
+ before do
+ model.finalize_background_migration(job_class_name)
+ end
+ end
- model.bulk_migrate_in(10.minutes, [%w(Class hello world)])
- end
- end
+ context 'when removing all tracked job records' do
+ let!(:job_class) do
+ Class.new do
+ def perform(*arguments)
+ # Force pending jobs to remain pending
+ end
+ end
+ end
- describe '#delete_queued_jobs' do
- let(:job1) { double }
- let(:job2) { double }
+ before do
+ model.finalize_background_migration(job_class_name, delete_tracking_jobs: %w[pending succeeded])
+ end
- it 'deletes all queued jobs for the given background migration' do
- expect(Gitlab::BackgroundMigration).to receive(:steal).with('BackgroundMigrationClassName') do |&block|
- expect(block.call(job1)).to be(false)
- expect(block.call(job2)).to be(false)
+ it_behaves_like 'finalized tracked background migration', worker_class
+ it_behaves_like 'removed tracked jobs', 'pending'
+ it_behaves_like 'removed tracked jobs', 'succeeded'
end
- expect(job1).to receive(:delete)
- expect(job2).to receive(:delete)
+ context 'when retaining all tracked job records' do
+ before do
+ model.finalize_background_migration(job_class_name, delete_tracking_jobs: false)
+ end
- model.delete_queued_jobs('BackgroundMigrationClassName')
- end
- end
+ it_behaves_like 'finalized background migration', worker_class
+ include_examples 'retained tracked jobs', 'succeeded'
+ end
- describe '#finalized_background_migration' do
- let(:job_coordinator) { Gitlab::BackgroundMigration::JobCoordinator.new(BackgroundMigrationWorker) }
+ context 'during retry race condition' do
+ let!(:job_class) do
+ Class.new do
+ class << self
+ attr_accessor :worker_class
- let!(:job_class_name) { 'TestJob' }
- let!(:job_class) { Class.new }
- let!(:job_perform_method) do
- ->(*arguments) do
- Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
- # Value is 'TestJob' defined by :job_class_name in the let! above.
- # Scoping prohibits us from directly referencing job_class_name.
- RSpec.current_example.example_group_instance.job_class_name,
- arguments
- )
- end
- end
+ def queue_items_added
+ @queue_items_added ||= []
+ end
+ end
- let!(:tracked_pending_job) { create(:background_migration_job, class_name: job_class_name, status: :pending, arguments: [1]) }
- let!(:tracked_successful_job) { create(:background_migration_job, class_name: job_class_name, status: :succeeded, arguments: [2]) }
+ def worker_class
+ self.class.worker_class
+ end
- before do
- job_class.define_method(:perform, job_perform_method)
+ def queue_items_added
+ self.class.queue_items_added
+ end
- allow(Gitlab::BackgroundMigration).to receive(:coordinator_for_database)
- .with('main').and_return(job_coordinator)
+ def perform(*arguments)
+ Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded('TestJob', arguments)
- expect(job_coordinator).to receive(:migration_class_for)
- .with(job_class_name).at_least(:once) { job_class }
+ # Mock another process pushing queue jobs.
+ if self.class.queue_items_added.count < 10
+ Sidekiq::Testing.disable! do
+ queue_items_added << worker_class.perform_async('TestJob', [Time.current])
+ queue_items_added << worker_class.perform_in(10, 'TestJob', [Time.current])
+ end
+ end
+ end
+ end
+ end
- Sidekiq::Testing.disable! do
- BackgroundMigrationWorker.perform_async(job_class_name, [1, 2])
- BackgroundMigrationWorker.perform_async(job_class_name, [3, 4])
- BackgroundMigrationWorker.perform_in(10, job_class_name, [5, 6])
- BackgroundMigrationWorker.perform_in(20, job_class_name, [7, 8])
- end
- end
+ it_behaves_like 'finalized tracked background migration', worker_class do
+ before do
+ # deliberately set the worker class on our test job since it won't be pulled from the surrounding scope
+ job_class.worker_class = worker_class
- it_behaves_like 'finalized tracked background migration' do
- before do
- model.finalize_background_migration(job_class_name)
+ model.finalize_background_migration(job_class_name, delete_tracking_jobs: ['succeeded'])
+ end
+ end
end
end
- context 'when removing all tracked job records' do
- # Force pending jobs to remain pending.
- let!(:job_perform_method) { ->(*arguments) { } }
+ describe '#migrate_in' do
+ it 'calls perform_in for the correct worker' do
+ expect(worker_class).to receive(:perform_in).with(10.minutes, 'Class', 'Hello', 'World')
- before do
- model.finalize_background_migration(job_class_name, delete_tracking_jobs: %w[pending succeeded])
+ model.migrate_in(10.minutes, 'Class', 'Hello', 'World')
end
- it_behaves_like 'finalized tracked background migration'
- it_behaves_like 'removed tracked jobs', 'pending'
- it_behaves_like 'removed tracked jobs', 'succeeded'
- end
+ it 'pushes a context with the current class name as caller_id' do
+ expect(Gitlab::ApplicationContext).to receive(:with_context).with(caller_id: model.class.to_s)
- context 'when retaining all tracked job records' do
- before do
- model.finalize_background_migration(job_class_name, delete_tracking_jobs: false)
+ model.migrate_in(10.minutes, 'Class', 'Hello', 'World')
end
- it_behaves_like 'finalized background migration'
- include_examples 'retained tracked jobs', 'succeeded'
- end
+ context 'when a specific coordinator is given' do
+ let(:coordinator) { Gitlab::BackgroundMigration::JobCoordinator.for_tracking_database('main') }
- context 'during retry race condition' do
- let(:queue_items_added) { [] }
- let!(:job_perform_method) do
- ->(*arguments) do
- Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
- RSpec.current_example.example_group_instance.job_class_name,
- arguments
- )
-
- # Mock another process pushing queue jobs.
- queue_items_added = RSpec.current_example.example_group_instance.queue_items_added
- if queue_items_added.count < 10
- Sidekiq::Testing.disable! do
- job_class_name = RSpec.current_example.example_group_instance.job_class_name
- queue_items_added << BackgroundMigrationWorker.perform_async(job_class_name, [Time.current])
- queue_items_added << BackgroundMigrationWorker.perform_in(10, job_class_name, [Time.current])
- end
- end
+ it 'uses that coordinator' do
+ expect(coordinator).to receive(:perform_in).with(10.minutes, 'Class', 'Hello', 'World').and_call_original
+ expect(worker_class).to receive(:perform_in).with(10.minutes, 'Class', 'Hello', 'World')
+
+ model.migrate_in(10.minutes, 'Class', 'Hello', 'World', coordinator: coordinator)
end
end
+ end
- it_behaves_like 'finalized tracked background migration' do
- before do
- model.finalize_background_migration(job_class_name, delete_tracking_jobs: ['succeeded'])
+ describe '#delete_queued_jobs' do
+ let(:job1) { double }
+ let(:job2) { double }
+
+ it 'deletes all queued jobs for the given background migration' do
+ expect_next_instance_of(Gitlab::BackgroundMigration::JobCoordinator) do |coordinator|
+ expect(coordinator).to receive(:steal).with('BackgroundMigrationClassName') do |&block|
+ expect(block.call(job1)).to be(false)
+ expect(block.call(job2)).to be(false)
+ end
end
+
+ expect(job1).to receive(:delete)
+ expect(job2).to receive(:delete)
+
+ model.delete_queued_jobs('BackgroundMigrationClassName')
end
end
end
+ context 'when the migration is running against the main database' do
+ it_behaves_like 'helpers that enqueue background migrations', BackgroundMigrationWorker, 'main'
+ end
+
describe '#delete_job_tracking' do
let!(:job_class_name) { 'TestJob' }
diff --git a/spec/lib/gitlab/database/migrations/runner_spec.rb b/spec/lib/gitlab/database/migrations/runner_spec.rb
index 4616bd6941e..7dc965c84fa 100644
--- a/spec/lib/gitlab/database/migrations/runner_spec.rb
+++ b/spec/lib/gitlab/database/migrations/runner_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe Gitlab::Database::Migrations::Runner do
allow(ActiveRecord::Migrator).to receive(:new) do |dir, _all_migrations, _schema_migration_class, version_to_migrate|
migrator = double(ActiveRecord::Migrator)
expect(migrator).to receive(:run) do
- migration_runs << OpenStruct.new(dir: dir, version_to_migrate: version_to_migrate)
+ migration_runs << double('migrator', dir: dir, version_to_migrate: version_to_migrate)
end
migrator
end
diff --git a/spec/lib/gitlab/database/no_cross_db_foreign_keys_spec.rb b/spec/lib/gitlab/database/no_cross_db_foreign_keys_spec.rb
new file mode 100644
index 00000000000..e5a8143fcc3
--- /dev/null
+++ b/spec/lib/gitlab/database/no_cross_db_foreign_keys_spec.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'cross-database foreign keys' do
+ # TODO: We are trying to empty out this list in
+ # https://gitlab.com/groups/gitlab-org/-/epics/7249 . Once we are done we can
+ # keep this test and assert that there are no cross-db foreign keys. We
+ # should not be adding anything to this list but should instead only add new
+ # loose foreign keys
+ # https://docs.gitlab.com/ee/development/database/loose_foreign_keys.html .
+ let(:allowed_cross_database_foreign_keys) do
+ %w(
+ ci_build_report_results.project_id
+ ci_builds.project_id
+ ci_builds_metadata.project_id
+ ci_daily_build_group_report_results.group_id
+ ci_daily_build_group_report_results.project_id
+ ci_freeze_periods.project_id
+ ci_job_artifacts.project_id
+ ci_job_token_project_scope_links.added_by_id
+ ci_job_token_project_scope_links.source_project_id
+ ci_job_token_project_scope_links.target_project_id
+ ci_pending_builds.namespace_id
+ ci_pending_builds.project_id
+ ci_pipeline_schedules.owner_id
+ ci_pipeline_schedules.project_id
+ ci_pipelines.merge_request_id
+ ci_pipelines.project_id
+ ci_project_monthly_usages.project_id
+ ci_refs.project_id
+ ci_resource_groups.project_id
+ ci_runner_namespaces.namespace_id
+ ci_runner_projects.project_id
+ ci_running_builds.project_id
+ ci_sources_pipelines.project_id
+ ci_sources_pipelines.source_project_id
+ ci_sources_projects.source_project_id
+ ci_stages.project_id
+ ci_subscriptions_projects.downstream_project_id
+ ci_subscriptions_projects.upstream_project_id
+ ci_triggers.owner_id
+ ci_triggers.project_id
+ ci_unit_tests.project_id
+ ci_variables.project_id
+ dast_profiles_pipelines.ci_pipeline_id
+ dast_scanner_profiles_builds.ci_build_id
+ dast_site_profiles_builds.ci_build_id
+ dast_site_profiles_pipelines.ci_pipeline_id
+ external_pull_requests.project_id
+ merge_requests.head_pipeline_id
+ merge_trains.pipeline_id
+ requirements_management_test_reports.build_id
+ security_scans.build_id
+ vulnerability_feedback.pipeline_id
+ vulnerability_occurrence_pipelines.pipeline_id
+ vulnerability_statistics.latest_pipeline_id
+ ).freeze
+ end
+
+ def foreign_keys_for(table_name)
+ ApplicationRecord.connection.foreign_keys(table_name)
+ end
+
+ def is_cross_db?(fk_record)
+ Gitlab::Database::GitlabSchema.table_schemas([fk_record.from_table, fk_record.to_table]).many?
+ end
+
+ it 'onlies have allowed list of cross-database foreign keys', :aggregate_failures do
+ all_tables = ApplicationRecord.connection.data_sources
+
+ all_tables.each do |table|
+ foreign_keys_for(table).each do |fk|
+ if is_cross_db?(fk)
+ column = "#{fk.from_table}.#{fk.column}"
+ expect(allowed_cross_database_foreign_keys).to include(column), "Found extra cross-database foreign key #{column} referencing #{fk.to_table} with constraint name #{fk.name}. When a foreign key references another database you must use a Loose Foreign Key instead https://docs.gitlab.com/ee/development/database/loose_foreign_keys.html ."
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/database/partitioning/partition_manager_spec.rb b/spec/lib/gitlab/database/partitioning/partition_manager_spec.rb
index 5e107109fc9..64dcdb9628a 100644
--- a/spec/lib/gitlab/database/partitioning/partition_manager_spec.rb
+++ b/spec/lib/gitlab/database/partitioning/partition_manager_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe Gitlab::Database::Partitioning::PartitionManager do
let(:model) { double(partitioning_strategy: partitioning_strategy, table_name: table, connection: connection) }
let(:partitioning_strategy) { double(missing_partitions: partitions, extra_partitions: [], after_adding_partitions: nil) }
let(:connection) { ActiveRecord::Base.connection }
- let(:table) { "some_table" }
+ let(:table) { "issues" }
before do
allow(connection).to receive(:table_exists?).and_call_original
@@ -36,6 +36,7 @@ RSpec.describe Gitlab::Database::Partitioning::PartitionManager do
end
it 'creates the partition' do
+ expect(connection).to receive(:execute).with("LOCK TABLE \"#{table}\" IN ACCESS EXCLUSIVE MODE")
expect(connection).to receive(:execute).with(partitions.first.to_sql)
expect(connection).to receive(:execute).with(partitions.second.to_sql)
diff --git a/spec/lib/gitlab/database/partitioning/sliding_list_strategy_spec.rb b/spec/lib/gitlab/database/partitioning/sliding_list_strategy_spec.rb
index 636a09e5710..1cec0463055 100644
--- a/spec/lib/gitlab/database/partitioning/sliding_list_strategy_spec.rb
+++ b/spec/lib/gitlab/database/partitioning/sliding_list_strategy_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Database::Partitioning::SlidingListStrategy do
let(:connection) { ActiveRecord::Base.connection }
let(:table_name) { :_test_partitioned_test }
- let(:model) { double('model', table_name: table_name, ignored_columns: %w[partition]) }
+ let(:model) { double('model', table_name: table_name, ignored_columns: %w[partition], connection: connection) }
let(:next_partition_if) { double('next_partition_if') }
let(:detach_partition_if) { double('detach_partition_if') }
@@ -94,7 +94,8 @@ RSpec.describe Gitlab::Database::Partitioning::SlidingListStrategy do
let(:detach_partition_if) { ->(p) { p != 5 } }
it 'is the leading set of partitions before that value' do
- expect(strategy.extra_partitions.map(&:value)).to contain_exactly(1, 2, 3, 4)
+ # should not contain partition 2 since it's the default value for the partition column
+ expect(strategy.extra_partitions.map(&:value)).to contain_exactly(1, 3, 4)
end
end
@@ -102,7 +103,7 @@ RSpec.describe Gitlab::Database::Partitioning::SlidingListStrategy do
let(:detach_partition_if) { proc { true } }
it 'is all but the most recent partition', :aggregate_failures do
- expect(strategy.extra_partitions.map(&:value)).to contain_exactly(1, 2, 3, 4, 5, 6, 7, 8, 9)
+ expect(strategy.extra_partitions.map(&:value)).to contain_exactly(1, 3, 4, 5, 6, 7, 8, 9)
expect(strategy.current_partitions.map(&:value).max).to eq(10)
end
diff --git a/spec/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table_spec.rb b/spec/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table_spec.rb
index c43b51e10a0..3072c413246 100644
--- a/spec/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table_spec.rb
+++ b/spec/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table_spec.rb
@@ -3,14 +3,15 @@
require 'spec_helper'
RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::BackfillPartitionedTable, '#perform' do
- subject { described_class.new }
+ subject(:backfill_job) { described_class.new(connection: connection) }
+ let(:connection) { ActiveRecord::Base.connection }
let(:source_table) { '_test_partitioning_backfills' }
let(:destination_table) { "#{source_table}_part" }
let(:unique_key) { 'id' }
before do
- allow(subject).to receive(:transaction_open?).and_return(false)
+ allow(backfill_job).to receive(:transaction_open?).and_return(false)
end
context 'when the destination table exists' do
@@ -50,10 +51,9 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::BackfillPartition
stub_const("#{described_class}::SUB_BATCH_SIZE", 2)
stub_const("#{described_class}::PAUSE_SECONDS", pause_seconds)
- allow(subject).to receive(:sleep)
+ allow(backfill_job).to receive(:sleep)
end
- let(:connection) { ActiveRecord::Base.connection }
let(:source_model) { Class.new(ActiveRecord::Base) }
let(:destination_model) { Class.new(ActiveRecord::Base) }
let(:timestamp) { Time.utc(2020, 1, 2).round }
@@ -66,7 +66,7 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::BackfillPartition
it 'copies data into the destination table idempotently' do
expect(destination_model.count).to eq(0)
- subject.perform(source1.id, source3.id, source_table, destination_table, unique_key)
+ backfill_job.perform(source1.id, source3.id, source_table, destination_table, unique_key)
expect(destination_model.count).to eq(3)
@@ -76,7 +76,7 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::BackfillPartition
expect(destination_record.attributes).to eq(source_record.attributes)
end
- subject.perform(source1.id, source3.id, source_table, destination_table, unique_key)
+ backfill_job.perform(source1.id, source3.id, source_table, destination_table, unique_key)
expect(destination_model.count).to eq(3)
end
@@ -87,13 +87,13 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::BackfillPartition
expect(bulk_copy).to receive(:copy_between).with(source3.id, source3.id)
end
- subject.perform(source1.id, source3.id, source_table, destination_table, unique_key)
+ backfill_job.perform(source1.id, source3.id, source_table, destination_table, unique_key)
end
it 'pauses after copying each sub-batch' do
- expect(subject).to receive(:sleep).with(pause_seconds).twice
+ expect(backfill_job).to receive(:sleep).with(pause_seconds).twice
- subject.perform(source1.id, source3.id, source_table, destination_table, unique_key)
+ backfill_job.perform(source1.id, source3.id, source_table, destination_table, unique_key)
end
it 'marks each job record as succeeded after processing' do
@@ -103,7 +103,7 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::BackfillPartition
expect(::Gitlab::Database::BackgroundMigrationJob).to receive(:mark_all_as_succeeded).and_call_original
expect do
- subject.perform(source1.id, source3.id, source_table, destination_table, unique_key)
+ backfill_job.perform(source1.id, source3.id, source_table, destination_table, unique_key)
end.to change { ::Gitlab::Database::BackgroundMigrationJob.succeeded.count }.from(0).to(1)
end
@@ -111,24 +111,24 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::BackfillPartition
create(:background_migration_job, class_name: "::#{described_class.name}",
arguments: [source1.id, source3.id, source_table, destination_table, unique_key])
- jobs_updated = subject.perform(source1.id, source3.id, source_table, destination_table, unique_key)
+ jobs_updated = backfill_job.perform(source1.id, source3.id, source_table, destination_table, unique_key)
expect(jobs_updated).to eq(1)
end
context 'when the job is run within an explicit transaction block' do
- let(:mock_connection) { double('connection') }
+ subject(:backfill_job) { described_class.new(connection: mock_connection) }
- before do
- allow(subject).to receive(:connection).and_return(mock_connection)
- allow(subject).to receive(:transaction_open?).and_return(true)
- end
+ let(:mock_connection) { double('connection') }
it 'raises an error before copying data' do
+ expect(backfill_job).to receive(:transaction_open?).and_call_original
+
+ expect(mock_connection).to receive(:transaction_open?).and_return(true)
expect(mock_connection).not_to receive(:execute)
expect do
- subject.perform(1, 100, source_table, destination_table, unique_key)
+ backfill_job.perform(1, 100, source_table, destination_table, unique_key)
end.to raise_error(/Aborting job to backfill partitioned #{source_table}/)
expect(destination_model.count).to eq(0)
@@ -137,24 +137,25 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::BackfillPartition
end
context 'when the destination table does not exist' do
+ subject(:backfill_job) { described_class.new(connection: mock_connection) }
+
let(:mock_connection) { double('connection') }
let(:mock_logger) { double('logger') }
before do
- allow(subject).to receive(:connection).and_return(mock_connection)
- allow(subject).to receive(:logger).and_return(mock_logger)
-
- expect(mock_connection).to receive(:table_exists?).with(destination_table).and_return(false)
+ allow(backfill_job).to receive(:logger).and_return(mock_logger)
allow(mock_logger).to receive(:warn)
end
it 'exits without attempting to copy data' do
+ expect(mock_connection).to receive(:table_exists?).with(destination_table).and_return(false)
expect(mock_connection).not_to receive(:execute)
subject.perform(1, 100, source_table, destination_table, unique_key)
end
it 'logs a warning message that the job was skipped' do
+ expect(mock_connection).to receive(:table_exists?).with(destination_table).and_return(false)
expect(mock_logger).to receive(:warn).with(/#{destination_table} does not exist/)
subject.perform(1, 100, source_table, destination_table, unique_key)
diff --git a/spec/lib/gitlab/database/reflection_spec.rb b/spec/lib/gitlab/database/reflection_spec.rb
index 7c3d797817d..efc5bd1c1e1 100644
--- a/spec/lib/gitlab/database/reflection_spec.rb
+++ b/spec/lib/gitlab/database/reflection_spec.rb
@@ -259,6 +259,66 @@ RSpec.describe Gitlab::Database::Reflection do
end
end
+ describe '#flavor', :delete do
+ let(:result) { [double] }
+ let(:connection) { database.model.connection }
+
+ def stub_statements(statements)
+ statements = Array.wrap(statements)
+ execute = connection.method(:execute)
+
+ allow(connection).to receive(:execute) do |arg|
+ if statements.include?(arg)
+ result
+ else
+ execute.call(arg)
+ end
+ end
+ end
+
+ it 're-raises exceptions not matching expected messages' do
+ expect(database.model.connection)
+ .to receive(:execute)
+ .and_raise(ActiveRecord::StatementInvalid, 'Something else')
+
+ expect { database.flavor }.to raise_error ActiveRecord::StatementInvalid, /Something else/
+ end
+
+ it 'recognizes Amazon Aurora PostgreSQL' do
+ stub_statements(['SHOW rds.extensions', 'SELECT AURORA_VERSION()'])
+
+ expect(database.flavor).to eq('Amazon Aurora PostgreSQL')
+ end
+
+ it 'recognizes PostgreSQL on Amazon RDS' do
+ stub_statements('SHOW rds.extensions')
+
+ expect(database.flavor).to eq('PostgreSQL on Amazon RDS')
+ end
+
+ it 'recognizes CloudSQL for PostgreSQL' do
+ stub_statements('SHOW cloudsql.iam_authentication')
+
+ expect(database.flavor).to eq('Cloud SQL for PostgreSQL')
+ end
+
+ it 'recognizes Azure Database for PostgreSQL - Flexible Server' do
+ stub_statements(["SELECT datname FROM pg_database WHERE datname = 'azure_maintenance'", 'SHOW azure.extensions'])
+
+ expect(database.flavor).to eq('Azure Database for PostgreSQL - Flexible Server')
+ end
+
+ it 'recognizes Azure Database for PostgreSQL - Single Server' do
+ stub_statements("SELECT datname FROM pg_database WHERE datname = 'azure_maintenance'")
+
+ expect(database.flavor).to eq('Azure Database for PostgreSQL - Single Server')
+ end
+
+ it 'returns nil if can not recognize the flavor' do
+ expect(database.flavor).to be_nil
+ end
+ end
+
describe '#config' do
it 'returns a HashWithIndifferentAccess' do
expect(database.config)
diff --git a/spec/lib/gitlab/database/reindexing/coordinator_spec.rb b/spec/lib/gitlab/database/reindexing/coordinator_spec.rb
index 0afbe46b7f1..bb91617714a 100644
--- a/spec/lib/gitlab/database/reindexing/coordinator_spec.rb
+++ b/spec/lib/gitlab/database/reindexing/coordinator_spec.rb
@@ -6,30 +6,34 @@ RSpec.describe Gitlab::Database::Reindexing::Coordinator do
include Database::DatabaseHelpers
include ExclusiveLeaseHelpers
- describe '.perform' do
- subject { described_class.new(index, notifier).perform }
-
- let(:index) { create(:postgres_index) }
- let(:notifier) { instance_double(Gitlab::Database::Reindexing::GrafanaNotifier, notify_start: nil, notify_end: nil) }
- let(:reindexer) { instance_double(Gitlab::Database::Reindexing::ReindexConcurrently, perform: nil) }
- let(:action) { create(:reindex_action, index: index) }
+ let(:notifier) { instance_double(Gitlab::Database::Reindexing::GrafanaNotifier, notify_start: nil, notify_end: nil) }
+ let(:index) { create(:postgres_index) }
+ let(:connection) { index.connection }
- let!(:lease) { stub_exclusive_lease(lease_key, uuid, timeout: lease_timeout) }
- let(:lease_key) { "gitlab/database/reindexing/coordinator/#{Gitlab::Database::PRIMARY_DATABASE_NAME}" }
- let(:lease_timeout) { 1.day }
- let(:uuid) { 'uuid' }
+ let!(:lease) { stub_exclusive_lease(lease_key, uuid, timeout: lease_timeout) }
+ let(:lease_key) { "gitlab/database/reindexing/coordinator/#{Gitlab::Database::PRIMARY_DATABASE_NAME}" }
+ let(:lease_timeout) { 1.day }
+ let(:uuid) { 'uuid' }
- around do |example|
- model = Gitlab::Database.database_base_models[Gitlab::Database::PRIMARY_DATABASE_NAME]
+ around do |example|
+ model = Gitlab::Database.database_base_models[Gitlab::Database::PRIMARY_DATABASE_NAME]
- Gitlab::Database::SharedModel.using_connection(model.connection) do
- example.run
- end
+ Gitlab::Database::SharedModel.using_connection(model.connection) do
+ example.run
end
+ end
- before do
- swapout_view_for_table(:postgres_indexes)
+ before do
+ swapout_view_for_table(:postgres_indexes)
+ end
+ describe '#perform' do
+ subject { described_class.new(index, notifier).perform }
+
+ let(:reindexer) { instance_double(Gitlab::Database::Reindexing::ReindexConcurrently, perform: nil) }
+ let(:action) { create(:reindex_action, index: index) }
+
+ before do
allow(Gitlab::Database::Reindexing::ReindexConcurrently).to receive(:new).with(index).and_return(reindexer)
allow(Gitlab::Database::Reindexing::ReindexAction).to receive(:create_for).with(index).and_return(action)
end
@@ -87,4 +91,40 @@ RSpec.describe Gitlab::Database::Reindexing::Coordinator do
end
end
end
+
+ describe '#drop' do
+ let(:connection) { index.connection }
+
+ subject(:drop) { described_class.new(index, notifier).drop }
+
+ context 'when exclusive lease is granted' do
+ it 'drops the index with lock retries' do
+ expect(lease).to receive(:try_obtain).ordered.and_return(uuid)
+
+ expect_query("SET lock_timeout TO '60000ms'")
+ expect_query("DROP INDEX CONCURRENTLY IF EXISTS \"public\".\"#{index.name}\"")
+ expect_query("RESET idle_in_transaction_session_timeout; RESET lock_timeout")
+
+ expect(Gitlab::ExclusiveLease).to receive(:cancel).ordered.with(lease_key, uuid)
+
+ drop
+ end
+
+ def expect_query(sql)
+ expect(connection).to receive(:execute).ordered.with(sql).and_wrap_original do |method, sql|
+ method.call(sql.sub(/CONCURRENTLY/, ''))
+ end
+ end
+ end
+
+ context 'when exclusive lease is not granted' do
+ it 'does not drop the index' do
+ expect(lease).to receive(:try_obtain).ordered.and_return(false)
+ expect(Gitlab::Database::WithLockRetriesOutsideTransaction).not_to receive(:new)
+ expect(connection).not_to receive(:execute)
+
+ drop
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/email/failure_handler_spec.rb b/spec/lib/gitlab/email/failure_handler_spec.rb
new file mode 100644
index 00000000000..a912996e8f2
--- /dev/null
+++ b/spec/lib/gitlab/email/failure_handler_spec.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Email::FailureHandler do
+ let(:raw_message) { fixture_file('emails/valid_reply.eml') }
+ let(:receiver) { Gitlab::Email::Receiver.new(raw_message) }
+
+ context 'email processing errors' do
+ where(:error, :message, :can_retry) do
+ [
+ [Gitlab::Email::UnknownIncomingEmail, "We couldn't figure out what the email is for", false],
+ [Gitlab::Email::SentNotificationNotFoundError, "We couldn't figure out what the email is in reply to", false],
+ [Gitlab::Email::ProjectNotFound, "We couldn't find the project", false],
+ [Gitlab::Email::EmptyEmailError, "It appears that the email is blank", true],
+ [Gitlab::Email::UserNotFoundError, "We couldn't figure out what user corresponds to the email", false],
+ [Gitlab::Email::UserBlockedError, "Your account has been blocked", false],
+ [Gitlab::Email::UserNotAuthorizedError, "You are not allowed to perform this action", false],
+ [Gitlab::Email::NoteableNotFoundError, "The thread you are replying to no longer exists", false],
+ [Gitlab::Email::InvalidAttachment, "Could not deal with that", false],
+ [Gitlab::Email::InvalidRecordError, "The note could not be created for the following reasons", true],
+ [Gitlab::Email::EmailTooLarge, "it is too large", false]
+ ]
+ end
+
+ with_them do
+ it "sends out a rejection email for #{params[:error]}" do
+ perform_enqueued_jobs do
+ described_class.handle(receiver, error.new(message))
+ end
+
+ email = ActionMailer::Base.deliveries.last
+ expect(email).not_to be_nil
+ expect(email.to).to match_array(["jake@adventuretime.ooo"])
+ expect(email.subject).to include("Rejected")
+ expect(email.body.parts.last.to_s).to include(message)
+ end
+
+ it 'strips out the body before passing to EmailRejectionMailer' do
+ mail = Mail.new(raw_message)
+ mail.body = nil
+
+ expect(EmailRejectionMailer).to receive(:rejection).with(match(message), mail.encoded, can_retry).and_call_original
+
+ described_class.handle(receiver, error.new(message))
+ end
+ end
+ end
+
+ context 'non-processing errors' do
+ where(:error) do
+ [
+ [Gitlab::Email::AutoGeneratedEmailError.new("")],
+ [ActiveRecord::StatementTimeout.new("StatementTimeout")],
+ [RateLimitedService::RateLimitedError.new(key: :issues_create, rate_limiter: nil)]
+ ]
+ end
+
+ with_them do
+ it "does not send a rejection email for #{params[:error]}" do
+ perform_enqueued_jobs do
+ described_class.handle(receiver, error)
+ end
+
+ expect(ActionMailer::Base.deliveries).to be_empty
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/error_tracking/processor/sidekiq_processor_spec.rb b/spec/lib/gitlab/error_tracking/processor/sidekiq_processor_spec.rb
index af5f11c9362..3febc10831a 100644
--- a/spec/lib/gitlab/error_tracking/processor/sidekiq_processor_spec.rb
+++ b/spec/lib/gitlab/error_tracking/processor/sidekiq_processor_spec.rb
@@ -178,5 +178,14 @@ RSpec.describe Gitlab::ErrorTracking::Processor::SidekiqProcessor do
expect(result_hash.dig(:extra, :sidekiq)).to be_nil
end
end
+
+ context 'when there is Sidekiq data but no job' do
+ let(:value) { { other: 'foo' } }
+ let(:wrapped_value) { { extra: { sidekiq: value } } }
+
+ it 'does nothing' do
+ expect(result_hash.dig(:extra, :sidekiq)).to eq(value)
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/event_store/event_spec.rb b/spec/lib/gitlab/event_store/event_spec.rb
new file mode 100644
index 00000000000..97f6870a5ec
--- /dev/null
+++ b/spec/lib/gitlab/event_store/event_spec.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::EventStore::Event do
+ let(:event_class) { stub_const('TestEvent', Class.new(described_class)) }
+ let(:event) { event_class.new(data: data) }
+ let(:data) { { project_id: 123, project_path: 'org/the-project' } }
+
+ context 'when schema is not defined' do
+ it 'raises an error on initialization' do
+ expect { event }.to raise_error(NotImplementedError)
+ end
+ end
+
+ context 'when schema is defined' do
+ before do
+ event_class.class_eval do
+ def schema
+ {
+ 'required' => ['project_id'],
+ 'type' => 'object',
+ 'properties' => {
+ 'project_id' => { 'type' => 'integer' },
+ 'project_path' => { 'type' => 'string' }
+ }
+ }
+ end
+ end
+ end
+
+ describe 'schema validation' do
+ context 'when data matches the schema' do
+ it 'initializes the event correctly' do
+ expect(event.data).to eq(data)
+ end
+ end
+
+ context 'when required properties are present as well as unknown properties' do
+ let(:data) { { project_id: 123, unknown_key: 'unknown_value' } }
+
+ it 'initializes the event correctly' do
+ expect(event.data).to eq(data)
+ end
+ end
+
+ context 'when some properties are missing' do
+ let(:data) { { project_path: 'org/the-project' } }
+
+ it 'expects all properties to be present' do
+ expect { event }.to raise_error(Gitlab::EventStore::InvalidEvent, /does not match the defined schema/)
+ end
+ end
+
+ context 'when data is not a Hash' do
+ let(:data) { 123 }
+
+ it 'raises an error' do
+ expect { event }.to raise_error(Gitlab::EventStore::InvalidEvent, 'Event data must be a Hash')
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/event_store/store_spec.rb b/spec/lib/gitlab/event_store/store_spec.rb
new file mode 100644
index 00000000000..711e1d5b4d5
--- /dev/null
+++ b/spec/lib/gitlab/event_store/store_spec.rb
@@ -0,0 +1,262 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::EventStore::Store do
+ let(:event_klass) { stub_const('TestEvent', Class.new(Gitlab::EventStore::Event)) }
+ let(:event) { event_klass.new(data: data) }
+ let(:another_event_klass) { stub_const('TestAnotherEvent', Class.new(Gitlab::EventStore::Event)) }
+
+ let(:worker) do
+ stub_const('EventSubscriber', Class.new).tap do |klass|
+ klass.class_eval do
+ include ApplicationWorker
+ include Gitlab::EventStore::Subscriber
+
+ def handle_event(event)
+ event.data
+ end
+ end
+ end
+ end
+
+ let(:another_worker) do
+ stub_const('AnotherEventSubscriber', Class.new).tap do |klass|
+ klass.class_eval do
+ include ApplicationWorker
+ include Gitlab::EventStore::Subscriber
+ end
+ end
+ end
+
+ let(:unrelated_worker) do
+ stub_const('UnrelatedEventSubscriber', Class.new).tap do |klass|
+ klass.class_eval do
+ include ApplicationWorker
+ include Gitlab::EventStore::Subscriber
+ end
+ end
+ end
+
+ before do
+ event_klass.class_eval do
+ def schema
+ {
+ 'required' => %w[name id],
+ 'type' => 'object',
+ 'properties' => {
+ 'name' => { 'type' => 'string' },
+ 'id' => { 'type' => 'integer' }
+ }
+ }
+ end
+ end
+ end
+
+ describe '#subscribe' do
+ it 'subscribes a worker to an event' do
+ store = described_class.new do |s|
+ s.subscribe worker, to: event_klass
+ end
+
+ subscriptions = store.subscriptions[event_klass]
+ expect(subscriptions.map(&:worker)).to contain_exactly(worker)
+ end
+
+ it 'subscribes multiple workers to an event' do
+ store = described_class.new do |s|
+ s.subscribe worker, to: event_klass
+ s.subscribe another_worker, to: event_klass
+ end
+
+ subscriptions = store.subscriptions[event_klass]
+ expect(subscriptions.map(&:worker)).to contain_exactly(worker, another_worker)
+ end
+
+ it 'subscribes a worker to multiple events is separate calls' do
+ store = described_class.new do |s|
+ s.subscribe worker, to: event_klass
+ s.subscribe worker, to: another_event_klass
+ end
+
+ subscriptions = store.subscriptions[event_klass]
+ expect(subscriptions.map(&:worker)).to contain_exactly(worker)
+
+ subscriptions = store.subscriptions[another_event_klass]
+ expect(subscriptions.map(&:worker)).to contain_exactly(worker)
+ end
+
+ it 'subscribes a worker to multiple events in a single call' do
+ store = described_class.new do |s|
+ s.subscribe worker, to: [event_klass, another_event_klass]
+ end
+
+ subscriptions = store.subscriptions[event_klass]
+ expect(subscriptions.map(&:worker)).to contain_exactly(worker)
+
+ subscriptions = store.subscriptions[another_event_klass]
+ expect(subscriptions.map(&:worker)).to contain_exactly(worker)
+ end
+
+ it 'subscribes a worker to an event with condition' do
+ store = described_class.new do |s|
+ s.subscribe worker, to: event_klass, if: ->(event) { event.data[:name] == 'Alice' }
+ end
+
+ subscriptions = store.subscriptions[event_klass]
+
+ expect(subscriptions.size).to eq(1)
+
+ subscription = subscriptions.first
+ expect(subscription).to be_an_instance_of(Gitlab::EventStore::Subscription)
+ expect(subscription.worker).to eq(worker)
+ expect(subscription.condition.call(double(data: { name: 'Bob' }))).to eq(false)
+ expect(subscription.condition.call(double(data: { name: 'Alice' }))).to eq(true)
+ end
+
+ it 'refuses the subscription if the target is not an Event object' do
+ expect do
+ described_class.new do |s|
+ s.subscribe worker, to: Integer
+ end
+ end.to raise_error(
+ Gitlab::EventStore::Error,
+ /Event being subscribed to is not a subclass of Gitlab::EventStore::Event/)
+ end
+
+ it 'refuses the subscription if the subscriber is not a worker' do
+ expect do
+ described_class.new do |s|
+ s.subscribe double, to: event_klass
+ end
+ end.to raise_error(
+ Gitlab::EventStore::Error,
+ /Subscriber is not an ApplicationWorker/)
+ end
+ end
+
+ describe '#publish' do
+ let(:data) { { name: 'Bob', id: 123 } }
+
+ context 'when event has a subscribed worker' do
+ let(:store) do
+ described_class.new do |store|
+ store.subscribe worker, to: event_klass
+ store.subscribe another_worker, to: another_event_klass
+ end
+ end
+
+ it 'dispatches the event to the subscribed worker' do
+ expect(worker).to receive(:perform_async).with('TestEvent', data)
+ expect(another_worker).not_to receive(:perform_async)
+
+ store.publish(event)
+ end
+
+ context 'when other workers subscribe to the same event' do
+ let(:store) do
+ described_class.new do |store|
+ store.subscribe worker, to: event_klass
+ store.subscribe another_worker, to: event_klass
+ store.subscribe unrelated_worker, to: another_event_klass
+ end
+ end
+
+ it 'dispatches the event to each subscribed worker' do
+ expect(worker).to receive(:perform_async).with('TestEvent', data)
+ expect(another_worker).to receive(:perform_async).with('TestEvent', data)
+ expect(unrelated_worker).not_to receive(:perform_async)
+
+ store.publish(event)
+ end
+ end
+
+ context 'when an error is raised' do
+ before do
+ allow(worker).to receive(:perform_async).and_raise(NoMethodError, 'the error message')
+ end
+
+ it 'is rescued and tracked' do
+ expect(Gitlab::ErrorTracking)
+ .to receive(:track_and_raise_for_dev_exception)
+ .with(kind_of(NoMethodError), event_class: event.class.name, event_data: event.data)
+ .and_call_original
+
+ expect { store.publish(event) }.to raise_error(NoMethodError, 'the error message')
+ end
+ end
+
+ it 'raises and tracks an error when event is published inside a database transaction' do
+ expect(Gitlab::ErrorTracking)
+ .to receive(:track_and_raise_for_dev_exception)
+ .at_least(:once)
+ .and_call_original
+
+ expect do
+ ApplicationRecord.transaction do
+ store.publish(event)
+ end
+ end.to raise_error(Sidekiq::Worker::EnqueueFromTransactionError)
+ end
+
+ it 'refuses publishing if the target is not an Event object' do
+ expect { store.publish(double(:event)) }
+ .to raise_error(
+ Gitlab::EventStore::Error,
+ /Event being published is not an instance of Gitlab::EventStore::Event/)
+ end
+ end
+
+ context 'when event has subscribed workers with condition' do
+ let(:store) do
+ described_class.new do |s|
+ s.subscribe worker, to: event_klass, if: -> (event) { event.data[:name] == 'Bob' }
+ s.subscribe another_worker, to: event_klass, if: -> (event) { event.data[:name] == 'Alice' }
+ end
+ end
+
+ let(:event) { event_klass.new(data: data) }
+
+ it 'dispatches the event to the workers satisfying the condition' do
+ expect(worker).to receive(:perform_async).with('TestEvent', data)
+ expect(another_worker).not_to receive(:perform_async)
+
+ store.publish(event)
+ end
+ end
+ end
+
+ describe 'subscriber' do
+ let(:data) { { name: 'Bob', id: 123 } }
+ let(:event_name) { event.class.name }
+ let(:worker_instance) { worker.new }
+
+ subject { worker_instance.perform(event_name, data) }
+
+ it 'handles the event' do
+ expect(worker_instance).to receive(:handle_event).with(instance_of(event.class))
+
+ expect_any_instance_of(event.class) do |event|
+ expect(event).to receive(:data).and_return(data)
+ end
+
+ subject
+ end
+
+ context 'when the event name does not exist' do
+ let(:event_name) { 'UnknownClass' }
+
+ it 'raises an error' do
+ expect { subject }.to raise_error(Gitlab::EventStore::InvalidEvent)
+ end
+ end
+
+ context 'when the worker does not define handle_event method' do
+ let(:worker_instance) { another_worker.new }
+
+ it 'raises an error' do
+ expect { subject }.to raise_error(NotImplementedError)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/exceptions_app_spec.rb b/spec/lib/gitlab/exceptions_app_spec.rb
new file mode 100644
index 00000000000..6b726a044a8
--- /dev/null
+++ b/spec/lib/gitlab/exceptions_app_spec.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::ExceptionsApp, type: :request do
+ describe '.call' do
+ let(:exceptions_app) { described_class.new(Rails.public_path) }
+ let(:app) { ActionDispatch::ShowExceptions.new(error_raiser, exceptions_app) }
+
+ before do
+ @app = app
+ end
+
+ context 'for a 500 error' do
+ let(:error_raiser) { proc { raise 'an unhandled error' } }
+
+ context 'for an HTML request' do
+ it 'fills in the request ID' do
+ get '/', env: { 'action_dispatch.request_id' => 'foo' }
+
+ expect(response).to have_gitlab_http_status(:internal_server_error)
+ expect(response).to have_header('X-Gitlab-Custom-Error')
+ expect(response.body).to include('Request ID: <code>foo</code>')
+ end
+
+ it 'HTML-escapes the request ID' do
+ get '/', env: { 'action_dispatch.request_id' => '<b>foo</b>' }
+
+ expect(response).to have_gitlab_http_status(:internal_server_error)
+ expect(response).to have_header('X-Gitlab-Custom-Error')
+ expect(response.body).to include('Request ID: <code>&lt;b&gt;foo&lt;/b&gt;</code>')
+ end
+
+ it 'returns an empty 500 when the 500.html page cannot be found' do
+ allow(File).to receive(:exist?).and_return(false)
+
+ get '/', env: { 'action_dispatch.request_id' => 'foo' }
+
+ expect(response).to have_gitlab_http_status(:internal_server_error)
+ expect(response).not_to have_header('X-Gitlab-Custom-Error')
+ expect(response.body).to be_empty
+ end
+ end
+
+ context 'for a JSON request' do
+ it 'does not include the request ID' do
+ get '/', env: { 'action_dispatch.request_id' => 'foo' }, as: :json
+
+ expect(response).to have_gitlab_http_status(:internal_server_error)
+ expect(response).not_to have_header('X-Gitlab-Custom-Error')
+ expect(response.body).not_to include('foo')
+ end
+ end
+ end
+
+ context 'for a 404 error' do
+ let(:error_raiser) { proc { raise AbstractController::ActionNotFound } }
+
+ it 'returns a 404 response that does not include the request ID' do
+ get '/', env: { 'action_dispatch.request_id' => 'foo' }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(response).not_to have_header('X-Gitlab-Custom-Error')
+ expect(response.body).not_to include('foo')
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/gfm/reference_rewriter_spec.rb b/spec/lib/gitlab/gfm/reference_rewriter_spec.rb
index f4875aa0ebc..7d4a3655be6 100644
--- a/spec/lib/gitlab/gfm/reference_rewriter_spec.rb
+++ b/spec/lib/gitlab/gfm/reference_rewriter_spec.rb
@@ -92,7 +92,7 @@ RSpec.describe Gitlab::Gfm::ReferenceRewriter do
let!(:group_label) { create(:group_label, id: 321, name: 'group label', group: old_group) }
before do
- old_project.update(namespace: old_group)
+ old_project.update!(namespace: old_group)
end
context 'label referenced by id' do
diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb
index bf2e3c7f5f8..4bf7994f4dd 100644
--- a/spec/lib/gitlab/git_access_spec.rb
+++ b/spec/lib/gitlab/git_access_spec.rb
@@ -96,7 +96,7 @@ RSpec.describe Gitlab::GitAccess do
context 'when the DeployKey has access to the project' do
before do
- deploy_key.deploy_keys_projects.create(project: project, can_push: true)
+ deploy_key.deploy_keys_projects.create!(project: project, can_push: true)
end
it 'allows push and pull access' do
@@ -820,7 +820,7 @@ RSpec.describe Gitlab::GitAccess do
project.add_role(user, role)
end
- protected_branch.save
+ protected_branch.save!
aggregate_failures do
matrix.each do |action, allowed|
@@ -1090,7 +1090,7 @@ RSpec.describe Gitlab::GitAccess do
context 'when deploy_key can push' do
context 'when project is authorized' do
before do
- key.deploy_keys_projects.create(project: project, can_push: true)
+ key.deploy_keys_projects.create!(project: project, can_push: true)
end
it { expect { push_access_check }.not_to raise_error }
@@ -1120,7 +1120,7 @@ RSpec.describe Gitlab::GitAccess do
context 'when deploy_key cannot push' do
context 'when project is authorized' do
before do
- key.deploy_keys_projects.create(project: project, can_push: false)
+ key.deploy_keys_projects.create!(project: project, can_push: false)
end
it { expect { push_access_check }.to raise_forbidden(described_class::ERROR_MESSAGES[:deploy_key_upload]) }
diff --git a/spec/lib/gitlab/gpg/commit_spec.rb b/spec/lib/gitlab/gpg/commit_spec.rb
index 20d5972bd88..9c399e78d80 100644
--- a/spec/lib/gitlab/gpg/commit_spec.rb
+++ b/spec/lib/gitlab/gpg/commit_spec.rb
@@ -233,30 +233,6 @@ RSpec.describe Gitlab::Gpg::Commit do
verification_status: 'multiple_signatures'
)
end
-
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(multiple_gpg_signatures: false)
- end
-
- it 'returns an valid signature' do
- verified_signature = double('verified-signature', fingerprint: GpgHelpers::User1.fingerprint, valid?: true)
- allow(GPGME::Crypto).to receive(:new).and_return(crypto)
- allow(crypto).to receive(:verify).and_yield(verified_signature).and_yield(verified_signature)
-
- signature = described_class.new(commit).signature
-
- expect(signature).to have_attributes(
- commit_sha: commit_sha,
- project: project,
- gpg_key: gpg_key,
- gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid,
- gpg_key_user_name: GpgHelpers::User1.names.first,
- gpg_key_user_email: GpgHelpers::User1.emails.first,
- verification_status: 'verified'
- )
- end
- end
end
context 'commit signed with a subkey' do
diff --git a/spec/lib/gitlab/http_spec.rb b/spec/lib/gitlab/http_spec.rb
index d0aae2ac475..7d459f2d88a 100644
--- a/spec/lib/gitlab/http_spec.rb
+++ b/spec/lib/gitlab/http_spec.rb
@@ -29,14 +29,42 @@ RSpec.describe Gitlab::HTTP do
context 'when reading the response is too slow' do
before do
+ # Override Net::HTTP to add a delay between sending each response chunk
+ mocked_http = Class.new(Net::HTTP) do
+ def request(*)
+ super do |response|
+ response.instance_eval do
+ def read_body(*)
+ @body.each do |fragment|
+ sleep 0.002.seconds
+
+ yield fragment if block_given?
+ end
+ end
+ end
+
+ yield response if block_given?
+
+ response
+ end
+ end
+ end
+
+ @original_net_http = Net.send(:remove_const, :HTTP)
+ Net.send(:const_set, :HTTP, mocked_http)
+
stub_const("#{described_class}::DEFAULT_READ_TOTAL_TIMEOUT", 0.001.seconds)
WebMock.stub_request(:post, /.*/).to_return do |request|
- sleep 0.002.seconds
- { body: 'I\'m slow', status: 200 }
+ { body: %w(a b), status: 200 }
end
end
+ after do
+ Net.send(:remove_const, :HTTP)
+ Net.send(:const_set, :HTTP, @original_net_http)
+ end
+
let(:options) { {} }
subject(:request_slow_responder) { described_class.post('http://example.org', **options) }
@@ -51,7 +79,7 @@ RSpec.describe Gitlab::HTTP do
end
it 'still calls the block' do
- expect { |b| described_class.post('http://example.org', **options, &b) }.to yield_with_args
+ expect { |b| described_class.post('http://example.org', **options, &b) }.to yield_successive_args('a', 'b')
end
end
diff --git a/spec/lib/gitlab/import/set_async_jid_spec.rb b/spec/lib/gitlab/import/set_async_jid_spec.rb
index 016f7cac61a..6931a7a953d 100644
--- a/spec/lib/gitlab/import/set_async_jid_spec.rb
+++ b/spec/lib/gitlab/import/set_async_jid_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe Gitlab::Import::SetAsyncJid do
it 'sets the JID in Redis' do
expect(Gitlab::SidekiqStatus)
.to receive(:set)
- .with("async-import/project-import-state/#{project.id}", Gitlab::Import::StuckImportJob::IMPORT_JOBS_EXPIRATION, value: 2)
+ .with("async-import/project-import-state/#{project.id}", Gitlab::Import::StuckImportJob::IMPORT_JOBS_EXPIRATION)
.and_call_original
described_class.set_jid(project.import_state)
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 7ed80cbcf66..f4a112d35aa 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -58,6 +58,7 @@ issues:
- test_reports
- requirement
- incident_management_issuable_escalation_status
+- incident_management_timeline_events
- pending_escalations
- customer_relations_contacts
- issue_customer_relations_contacts
@@ -135,6 +136,7 @@ project_members:
- source
- project
- member_task
+- member_namespace
merge_requests:
- status_check_responses
- subscriptions
@@ -280,6 +282,7 @@ ci_pipelines:
- dast_site_profiles_pipeline
- package_build_infos
- package_file_build_infos
+- build_trace_chunks
ci_refs:
- project
- ci_pipelines
@@ -601,6 +604,7 @@ project:
- bulk_import_exports
- ci_project_mirror
- sync_events
+- secure_files
award_emoji:
- awardable
- user
diff --git a/spec/lib/gitlab/import_export/avatar_saver_spec.rb b/spec/lib/gitlab/import_export/avatar_saver_spec.rb
index 334d930c47c..d897ce76da0 100644
--- a/spec/lib/gitlab/import_export/avatar_saver_spec.rb
+++ b/spec/lib/gitlab/import_export/avatar_saver_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe Gitlab::ImportExport::AvatarSaver do
end
it 'saves a project avatar' do
- described_class.new(project: project_with_avatar, shared: shared).save
+ described_class.new(project: project_with_avatar, shared: shared).save # rubocop:disable Rails/SaveBang
expect(File).to exist(Dir["#{shared.export_path}/avatar/**/dk.png"].first)
end
diff --git a/spec/lib/gitlab/import_export/base/relation_factory_spec.rb b/spec/lib/gitlab/import_export/base/relation_factory_spec.rb
index bd8873fe20e..b8999f608b1 100644
--- a/spec/lib/gitlab/import_export/base/relation_factory_spec.rb
+++ b/spec/lib/gitlab/import_export/base/relation_factory_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe Gitlab::ImportExport::Base::RelationFactory do
let(:excluded_keys) { [] }
subject do
- described_class.create(relation_sym: relation_sym,
+ described_class.create(relation_sym: relation_sym, # rubocop:disable Rails/SaveBang
relation_hash: relation_hash,
relation_index: 1,
object_builder: Gitlab::ImportExport::Project::ObjectBuilder,
diff --git a/spec/lib/gitlab/import_export/design_repo_restorer_spec.rb b/spec/lib/gitlab/import_export/design_repo_restorer_spec.rb
index 6680f4e7a03..346f653acd4 100644
--- a/spec/lib/gitlab/import_export/design_repo_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/design_repo_restorer_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe Gitlab::ImportExport::DesignRepoRestorer do
allow(instance).to receive(:storage_path).and_return(export_path)
end
- bundler.save
+ bundler.save # rubocop:disable Rails/SaveBang
end
after do
diff --git a/spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb b/spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb
index d5f31f235f5..adb613c3abc 100644
--- a/spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb
+++ b/spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb
@@ -258,7 +258,7 @@ RSpec.describe Gitlab::ImportExport::FastHashSerializer do
create(:resource_label_event, label: group_label, merge_request: merge_request)
create(:event, :created, target: milestone, project: project, author: user)
- create(:service, project: project, type: 'CustomIssueTrackerService', category: 'issue_tracker', properties: { one: 'value' })
+ create(:integration, project: project, type: 'CustomIssueTrackerService', category: 'issue_tracker', properties: { one: 'value' })
create(:project_custom_attribute, project: project)
create(:project_custom_attribute, project: project)
diff --git a/spec/lib/gitlab/import_export/group/relation_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/group/relation_tree_restorer_spec.rb
index ce6607f6a26..2f1e2dd2db4 100644
--- a/spec/lib/gitlab/import_export/group/relation_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/group/relation_tree_restorer_spec.rb
@@ -48,41 +48,16 @@ RSpec.describe Gitlab::ImportExport::Group::RelationTreeRestorer do
subject { relation_tree_restorer.restore }
- shared_examples 'logging of relations creation' do
- context 'when log_import_export_relation_creation feature flag is enabled' do
- before do
- stub_feature_flags(log_import_export_relation_creation: group)
- end
-
- it 'logs top-level relation creation' do
- expect(shared.logger)
- .to receive(:info)
- .with(hash_including(message: '[Project/Group Import] Created new object relation'))
- .at_least(:once)
-
- subject
- end
- end
-
- context 'when log_import_export_relation_creation feature flag is disabled' do
- before do
- stub_feature_flags(log_import_export_relation_creation: false)
- end
-
- it 'does not log top-level relation creation' do
- expect(shared.logger)
- .to receive(:info)
- .with(hash_including(message: '[Project/Group Import] Created new object relation'))
- .never
-
- subject
- end
- end
- end
-
it 'restores group tree' do
expect(subject).to eq(true)
end
- include_examples 'logging of relations creation'
+ it 'logs top-level relation creation' do
+ expect(shared.logger)
+ .to receive(:info)
+ .with(hash_including(message: '[Project/Group Import] Created new object relation'))
+ .at_least(:once)
+
+ subject
+ 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 80ba50976af..ea8b10675af 100644
--- a/spec/lib/gitlab/import_export/project/relation_factory_spec.rb
+++ b/spec/lib/gitlab/import_export/project/relation_factory_spec.rb
@@ -88,7 +88,7 @@ RSpec.describe Gitlab::ImportExport::Project::RelationFactory, :use_clean_rails_
end
context 'original service exists' do
- let(:service_id) { create(:service, project: project).id }
+ let(:service_id) { create(:integration, project: project).id }
it 'does not have the original service_id' do
expect(created_object.service_id).not_to eq(service_id)
diff --git a/spec/lib/gitlab/import_export/project/relation_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project/relation_tree_restorer_spec.rb
index 577f1e46db6..b7b652005e9 100644
--- a/spec/lib/gitlab/import_export/project/relation_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project/relation_tree_restorer_spec.rb
@@ -54,38 +54,6 @@ RSpec.describe Gitlab::ImportExport::Project::RelationTreeRestorer do
end
end
- shared_examples 'logging of relations creation' do
- context 'when log_import_export_relation_creation feature flag is enabled' do
- before do
- stub_feature_flags(log_import_export_relation_creation: group)
- end
-
- it 'logs top-level relation creation' do
- expect(shared.logger)
- .to receive(:info)
- .with(hash_including(message: '[Project/Group Import] Created new object relation'))
- .at_least(:once)
-
- subject
- end
- end
-
- context 'when log_import_export_relation_creation feature flag is disabled' do
- before do
- stub_feature_flags(log_import_export_relation_creation: false)
- end
-
- it 'does not log top-level relation creation' do
- expect(shared.logger)
- .to receive(:info)
- .with(hash_including(message: '[Project/Group Import] Created new object relation'))
- .never
-
- subject
- end
- end
- end
-
context 'with legacy reader' do
let(:path) { 'spec/fixtures/lib/gitlab/import_export/complex/project.json' }
let(:relation_reader) do
@@ -106,7 +74,14 @@ RSpec.describe Gitlab::ImportExport::Project::RelationTreeRestorer do
create(:project, :builds_enabled, :issues_disabled, name: 'project', path: 'project', group: group)
end
- include_examples 'logging of relations creation'
+ it 'logs top-level relation creation' do
+ expect(shared.logger)
+ .to receive(:info)
+ .with(hash_including(message: '[Project/Group Import] Created new object relation'))
+ .at_least(:once)
+
+ subject
+ 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 6ffe2187466..f019883a91e 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -692,6 +692,7 @@ Badge:
- type
ProjectCiCdSetting:
- group_runners_enabled
+- runner_token_expiration_interval
ProjectSetting:
- allow_merge_on_skipped_pipeline
- has_confluence
diff --git a/spec/lib/gitlab/import_export/uploads_saver_spec.rb b/spec/lib/gitlab/import_export/uploads_saver_spec.rb
index 8e9be209f89..bfb18c58806 100644
--- a/spec/lib/gitlab/import_export/uploads_saver_spec.rb
+++ b/spec/lib/gitlab/import_export/uploads_saver_spec.rb
@@ -32,7 +32,7 @@ RSpec.describe Gitlab::ImportExport::UploadsSaver do
end
it 'copies the uploads to the export path' do
- saver.save
+ saver.save # rubocop:disable Rails/SaveBang
uploads = Dir.glob(File.join(shared.export_path, 'uploads/**/*')).map { |file| File.basename(file) }
@@ -54,7 +54,7 @@ RSpec.describe Gitlab::ImportExport::UploadsSaver do
end
it 'copies the uploads to the export path' do
- saver.save
+ saver.save # rubocop:disable Rails/SaveBang
uploads = Dir.glob(File.join(shared.export_path, 'uploads/**/*')).map { |file| File.basename(file) }
diff --git a/spec/lib/gitlab/integrations/sti_type_spec.rb b/spec/lib/gitlab/integrations/sti_type_spec.rb
index 70b93d6a4b5..1205b74dc9d 100644
--- a/spec/lib/gitlab/integrations/sti_type_spec.rb
+++ b/spec/lib/gitlab/integrations/sti_type_spec.rb
@@ -46,11 +46,11 @@ RSpec.describe Gitlab::Integrations::StiType do
SQL
end
- let_it_be(:service) { create(:service) }
+ let_it_be(:integration) { create(:integration) }
it 'forms SQL UPDATE statements correctly' do
sql_statements = types.map do |type|
- record = ActiveRecord::QueryRecorder.new { service.update_column(:type, type) }
+ record = ActiveRecord::QueryRecorder.new { integration.update_column(:type, type) }
record.log.first
end
@@ -65,8 +65,6 @@ RSpec.describe Gitlab::Integrations::StiType do
SQL
end
- let(:service) { create(:service) }
-
it 'forms SQL DELETE statements correctly' do
sql_statements = types.map do |type|
record = ActiveRecord::QueryRecorder.new { Integration.delete_by(type: type) }
@@ -81,7 +79,7 @@ RSpec.describe Gitlab::Integrations::StiType do
describe '#deserialize' do
specify 'it deserializes type correctly', :aggregate_failures do
types.each do |type|
- service = create(:service, type: type)
+ service = create(:integration, type: type)
expect(service.type).to eq('AsanaService')
end
@@ -90,7 +88,7 @@ RSpec.describe Gitlab::Integrations::StiType do
describe '#cast' do
it 'casts type as model correctly', :aggregate_failures do
- create(:service, type: 'AsanaService')
+ create(:integration, type: 'AsanaService')
types.each do |type|
expect(Integration.find_by(type: type)).to be_kind_of(Integrations::Asana)
@@ -100,7 +98,7 @@ RSpec.describe Gitlab::Integrations::StiType do
describe '#changed?' do
it 'detects changes correctly', :aggregate_failures do
- service = create(:service, type: 'AsanaService')
+ service = create(:integration, type: 'AsanaService')
types.each do |type|
service.type = type
diff --git a/spec/lib/gitlab/jwt_authenticatable_spec.rb b/spec/lib/gitlab/jwt_authenticatable_spec.rb
index 36bb46cb250..92d5feceb75 100644
--- a/spec/lib/gitlab/jwt_authenticatable_spec.rb
+++ b/spec/lib/gitlab/jwt_authenticatable_spec.rb
@@ -14,17 +14,12 @@ RSpec.describe Gitlab::JwtAuthenticatable do
end
before do
- begin
- File.delete(test_class.secret_path)
- rescue Errno::ENOENT
- end
+ FileUtils.rm_f(test_class.secret_path)
test_class.write_secret
end
- describe '.secret' do
- subject(:secret) { test_class.secret }
-
+ shared_examples 'reading secret from the secret path' do
it 'returns 32 bytes' do
expect(secret).to be_a(String)
expect(secret.length).to eq(32)
@@ -32,62 +27,170 @@ RSpec.describe Gitlab::JwtAuthenticatable do
end
it 'accepts a trailing newline' do
- File.open(test_class.secret_path, 'a') { |f| f.write "\n" }
+ File.open(secret_path, 'a') { |f| f.write "\n" }
expect(secret.length).to eq(32)
end
it 'raises an exception if the secret file cannot be read' do
- File.delete(test_class.secret_path)
+ File.delete(secret_path)
expect { secret }.to raise_exception(Errno::ENOENT)
end
it 'raises an exception if the secret file contains the wrong number of bytes' do
- File.truncate(test_class.secret_path, 0)
+ File.truncate(secret_path, 0)
expect { secret }.to raise_exception(RuntimeError)
end
end
+ describe '.secret' do
+ it_behaves_like 'reading secret from the secret path' do
+ subject(:secret) { test_class.secret }
+
+ let(:secret_path) { test_class.secret_path }
+ end
+ end
+
+ describe '.read_secret' do
+ it_behaves_like 'reading secret from the secret path' do
+ subject(:secret) { test_class.read_secret(secret_path) }
+
+ let(:secret_path) { test_class.secret_path }
+ end
+ end
+
describe '.write_secret' do
- it 'uses mode 0600' do
- expect(File.stat(test_class.secret_path).mode & 0777).to eq(0600)
+ context 'without an input' do
+ it 'uses mode 0600' do
+ expect(File.stat(test_class.secret_path).mode & 0777).to eq(0600)
+ end
+
+ it 'writes base64 data' do
+ bytes = Base64.strict_decode64(File.read(test_class.secret_path))
+
+ expect(bytes).not_to be_empty
+ end
end
- it 'writes base64 data' do
- bytes = Base64.strict_decode64(File.read(test_class.secret_path))
+ context 'with an input' do
+ let(:another_path) do
+ Rails.root.join('tmp', 'tests', '.jwt_another_shared_secret')
+ end
- expect(bytes).not_to be_empty
+ after do
+ File.delete(another_path)
+ rescue Errno::ENOENT
+ end
+
+ it 'uses mode 0600' do
+ test_class.write_secret(another_path)
+ expect(File.stat(another_path).mode & 0777).to eq(0600)
+ end
+
+ it 'writes base64 data' do
+ test_class.write_secret(another_path)
+ bytes = Base64.strict_decode64(File.read(another_path))
+
+ expect(bytes).not_to be_empty
+ end
end
end
- describe '.decode_jwt_for_issuer' do
- let(:payload) { { 'iss' => 'test_issuer' } }
+ describe '.decode_jwt' do |decode|
+ let(:payload) { {} }
+
+ context 'use included class secret' do
+ it 'accepts a correct header' do
+ encoded_message = JWT.encode(payload, test_class.secret, 'HS256')
+
+ expect { test_class.decode_jwt(encoded_message) }.not_to raise_error
+ end
+
+ it 'raises an error when the JWT is not signed' do
+ encoded_message = JWT.encode(payload, nil, 'none')
+
+ expect { test_class.decode_jwt(encoded_message) }.to raise_error(JWT::DecodeError)
+ end
- it 'accepts a correct header' do
- encoded_message = JWT.encode(payload, test_class.secret, 'HS256')
+ it 'raises an error when the header is signed with the wrong secret' do
+ encoded_message = JWT.encode(payload, 'wrongsecret', 'HS256')
- expect { test_class.decode_jwt_for_issuer('test_issuer', encoded_message) }.not_to raise_error
+ expect { test_class.decode_jwt(encoded_message) }.to raise_error(JWT::DecodeError)
+ end
end
- it 'raises an error when the JWT is not signed' do
- encoded_message = JWT.encode(payload, nil, 'none')
+ context 'use an input secret' do
+ let(:another_secret) { 'another secret' }
+
+ it 'accepts a correct header' do
+ encoded_message = JWT.encode(payload, another_secret, 'HS256')
+
+ expect { test_class.decode_jwt(encoded_message, another_secret) }.not_to raise_error
+ end
- expect { test_class.decode_jwt_for_issuer('test_issuer', encoded_message) }.to raise_error(JWT::DecodeError)
+ it 'raises an error when the JWT is not signed' do
+ encoded_message = JWT.encode(payload, nil, 'none')
+
+ expect { test_class.decode_jwt(encoded_message, another_secret) }.to raise_error(JWT::DecodeError)
+ end
+
+ it 'raises an error when the header is signed with the wrong secret' do
+ encoded_message = JWT.encode(payload, 'wrongsecret', 'HS256')
+
+ expect { test_class.decode_jwt(encoded_message, another_secret) }.to raise_error(JWT::DecodeError)
+ end
end
- it 'raises an error when the header is signed with the wrong secret' do
- encoded_message = JWT.encode(payload, 'wrongsecret', 'HS256')
+ context 'issuer option' do
+ let(:payload) { { 'iss' => 'test_issuer' } }
+
+ it 'returns decoded payload if issuer is correct' do
+ encoded_message = JWT.encode(payload, test_class.secret, 'HS256')
+ payload = test_class.decode_jwt(encoded_message, issuer: 'test_issuer')
- expect { test_class.decode_jwt_for_issuer('test_issuer', encoded_message) }.to raise_error(JWT::DecodeError)
+ expect(payload[0]).to match a_hash_including('iss' => 'test_issuer')
+ end
+
+ it 'raises an error when the issuer is incorrect' do
+ payload['iss'] = 'somebody else'
+ encoded_message = JWT.encode(payload, test_class.secret, 'HS256')
+
+ expect { test_class.decode_jwt(encoded_message, issuer: 'test_issuer') }.to raise_error(JWT::DecodeError)
+ end
end
- it 'raises an error when the issuer is incorrect' do
- payload['iss'] = 'somebody else'
- encoded_message = JWT.encode(payload, test_class.secret, 'HS256')
+ context 'iat_after option' do
+ it 'returns decoded payload if iat is valid' do
+ freeze_time do
+ encoded_message = JWT.encode(payload.merge(iat: (Time.current - 10.seconds).to_i), test_class.secret, 'HS256')
+ payload = test_class.decode_jwt(encoded_message, iat_after: Time.current - 20.seconds)
+
+ expect(payload[0]).to match a_hash_including('iat' => be_a(Integer))
+ end
+ end
+
+ it 'raises an error if iat is invalid' do
+ encoded_message = JWT.encode(payload.merge(iat: 'wrong'), test_class.secret, 'HS256')
- expect { test_class.decode_jwt_for_issuer('test_issuer', encoded_message) }.to raise_error(JWT::DecodeError)
+ expect { test_class.decode_jwt(encoded_message, iat_after: true) }.to raise_error(JWT::DecodeError)
+ end
+
+ it 'raises an error if iat is absent' do
+ encoded_message = JWT.encode(payload, test_class.secret, 'HS256')
+
+ expect { test_class.decode_jwt(encoded_message, iat_after: true) }.to raise_error(JWT::DecodeError)
+ end
+
+ it 'raises an error if iat is too far in the past' do
+ freeze_time do
+ encoded_message = JWT.encode(payload.merge(iat: (Time.current - 30.seconds).to_i), test_class.secret, 'HS256')
+ expect do
+ test_class.decode_jwt(encoded_message, iat_after: Time.current - 20.seconds)
+ end.to raise_error(JWT::ExpiredSignature, 'Token has expired')
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/lets_encrypt/client_spec.rb b/spec/lib/gitlab/lets_encrypt/client_spec.rb
index f1284318687..1baf8749532 100644
--- a/spec/lib/gitlab/lets_encrypt/client_spec.rb
+++ b/spec/lib/gitlab/lets_encrypt/client_spec.rb
@@ -42,7 +42,7 @@ RSpec.describe ::Gitlab::LetsEncrypt::Client do
context 'when private key is saved in settings' do
let!(:saved_private_key) do
key = OpenSSL::PKey::RSA.new(4096).to_pem
- Gitlab::CurrentSettings.current_application_settings.update(lets_encrypt_private_key: key)
+ Gitlab::CurrentSettings.current_application_settings.update!(lets_encrypt_private_key: key)
key
end
diff --git a/spec/lib/gitlab/lfs/client_spec.rb b/spec/lib/gitlab/lfs/client_spec.rb
index 0f9637e8ca4..db450c79dfa 100644
--- a/spec/lib/gitlab/lfs/client_spec.rb
+++ b/spec/lib/gitlab/lfs/client_spec.rb
@@ -114,6 +114,52 @@ RSpec.describe Gitlab::Lfs::Client do
end
end
+ context 'server returns 200 OK with a chunked transfer request' do
+ before do
+ upload_action['header']['Transfer-Encoding'] = 'gzip, chunked'
+ end
+
+ it "makes an HTTP PUT with expected parameters" do
+ stub_upload(object: object, headers: upload_action['header'], chunked_transfer: true).to_return(status: 200)
+
+ lfs_client.upload!(object, upload_action, authenticated: true)
+ end
+ end
+
+ context 'server returns 200 OK with a username and password in the URL' do
+ let(:base_url) { "https://someuser:testpass@example.com" }
+
+ it "makes an HTTP PUT with expected parameters" do
+ stub_upload(
+ object: object,
+ headers: basic_auth_headers.merge(upload_action['header']),
+ url: "https://example.com/some/file"
+ ).to_return(status: 200)
+
+ lfs_client.upload!(object, upload_action, authenticated: true)
+ end
+ end
+
+ context 'no credentials in client' do
+ subject(:lfs_client) { described_class.new(base_url, credentials: {}) }
+
+ context 'server returns 200 OK with credentials in URL' do
+ let(:creds) { 'someuser:testpass' }
+ let(:base_url) { "https://#{creds}@example.com" }
+ let(:auth_headers) { { 'Authorization' => "Basic #{Base64.strict_encode64(creds)}" } }
+
+ it "makes an HTTP PUT with expected parameters" do
+ stub_upload(
+ object: object,
+ headers: auth_headers.merge(upload_action['header']),
+ url: "https://example.com/some/file"
+ ).to_return(status: 200)
+
+ lfs_client.upload!(object, upload_action, authenticated: true)
+ end
+ end
+ end
+
context 'server returns 200 OK to an unauthenticated request' do
it "makes an HTTP PUT with expected parameters" do
stub = stub_upload(
@@ -159,7 +205,7 @@ RSpec.describe Gitlab::Lfs::Client do
it 'raises an error' do
stub_upload(object: object, headers: upload_action['header']).to_return(status: 400)
- expect { lfs_client.upload!(object, upload_action, authenticated: true) }.to raise_error(/Failed/)
+ expect { lfs_client.upload!(object, upload_action, authenticated: true) }.to raise_error(/Failed to upload object: HTTP status 400/)
end
end
@@ -167,20 +213,25 @@ RSpec.describe Gitlab::Lfs::Client do
it 'raises an error' do
stub_upload(object: object, headers: upload_action['header']).to_return(status: 500)
- expect { lfs_client.upload!(object, upload_action, authenticated: true) }.to raise_error(/Failed/)
+ expect { lfs_client.upload!(object, upload_action, authenticated: true) }.to raise_error(/Failed to upload object: HTTP status 500/)
end
end
- def stub_upload(object:, headers:)
+ def stub_upload(object:, headers:, url: upload_action['href'], chunked_transfer: false)
headers = {
'Content-Type' => 'application/octet-stream',
- 'Content-Length' => object.size.to_s,
'User-Agent' => git_lfs_user_agent
}.merge(headers)
- stub_request(:put, upload_action['href']).with(
+ if chunked_transfer
+ headers['Transfer-Encoding'] = 'gzip, chunked'
+ else
+ headers['Content-Length'] = object.size.to_s
+ end
+
+ stub_request(:put, url).with(
body: object.file.read,
- headers: headers.merge('Content-Length' => object.size.to_s)
+ headers: headers
)
end
end
@@ -196,11 +247,25 @@ RSpec.describe Gitlab::Lfs::Client do
end
end
+ context 'server returns 200 OK with a username and password in the URL' do
+ let(:base_url) { "https://someuser:testpass@example.com" }
+
+ it "makes an HTTP PUT with expected parameters" do
+ stub_verify(
+ object: object,
+ headers: basic_auth_headers.merge(verify_action['header']),
+ url: "https://example.com/some/file/verify"
+ ).to_return(status: 200)
+
+ lfs_client.verify!(object, verify_action, authenticated: true)
+ end
+ end
+
context 'server returns 200 OK to an unauthenticated request' do
it "makes an HTTP POST with expected parameters" do
stub = stub_verify(
object: object,
- headers: basic_auth_headers.merge(upload_action['header'])
+ headers: basic_auth_headers.merge(verify_action['header'])
).to_return(status: 200)
lfs_client.verify!(object, verify_action, authenticated: false)
@@ -226,7 +291,7 @@ RSpec.describe Gitlab::Lfs::Client do
it 'raises an error' do
stub_verify(object: object, headers: verify_action['header']).to_return(status: 400)
- expect { lfs_client.verify!(object, verify_action, authenticated: true) }.to raise_error(/Failed/)
+ expect { lfs_client.verify!(object, verify_action, authenticated: true) }.to raise_error(/Failed to verify object: HTTP status 400/)
end
end
@@ -234,18 +299,18 @@ RSpec.describe Gitlab::Lfs::Client do
it 'raises an error' do
stub_verify(object: object, headers: verify_action['header']).to_return(status: 500)
- expect { lfs_client.verify!(object, verify_action, authenticated: true) }.to raise_error(/Failed/)
+ expect { lfs_client.verify!(object, verify_action, authenticated: true) }.to raise_error(/Failed to verify object: HTTP status 500/)
end
end
- def stub_verify(object:, headers:)
+ def stub_verify(object:, headers:, url: verify_action['href'])
headers = {
'Accept' => git_lfs_content_type,
'Content-Type' => git_lfs_content_type,
'User-Agent' => git_lfs_user_agent
}.merge(headers)
- stub_request(:post, verify_action['href']).with(
+ stub_request(:post, url).with(
body: object.to_json(only: [:oid, :size]),
headers: headers
)
diff --git a/spec/lib/gitlab/logger_spec.rb b/spec/lib/gitlab/logger_spec.rb
new file mode 100644
index 00000000000..ed22af8355f
--- /dev/null
+++ b/spec/lib/gitlab/logger_spec.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Logger do
+ describe '.build' do
+ before do
+ allow(described_class).to receive(:file_name_noext).and_return('log')
+ end
+
+ subject { described_class.build }
+
+ it 'builds logger using Gitlab::Logger.log_level' do
+ expect(described_class).to receive(:log_level).and_return(:warn)
+
+ expect(subject.level).to eq(described_class::WARN)
+ end
+
+ it 'raises ArgumentError if invalid log level' do
+ allow(described_class).to receive(:log_level).and_return(:invalid)
+
+ expect { subject.level }.to raise_error(ArgumentError, 'invalid log level: invalid')
+ end
+
+ using RSpec::Parameterized::TableSyntax
+
+ where(:env_value, :resulting_level) do
+ 0 | described_class::DEBUG
+ :debug | described_class::DEBUG
+ 'debug' | described_class::DEBUG
+ 'DEBUG' | described_class::DEBUG
+ 'DeBuG' | described_class::DEBUG
+ 1 | described_class::INFO
+ :info | described_class::INFO
+ 'info' | described_class::INFO
+ 'INFO' | described_class::INFO
+ 'InFo' | described_class::INFO
+ 2 | described_class::WARN
+ :warn | described_class::WARN
+ 'warn' | described_class::WARN
+ 'WARN' | described_class::WARN
+ 'WaRn' | described_class::WARN
+ 3 | described_class::ERROR
+ :error | described_class::ERROR
+ 'error' | described_class::ERROR
+ 'ERROR' | described_class::ERROR
+ 'ErRoR' | described_class::ERROR
+ 4 | described_class::FATAL
+ :fatal | described_class::FATAL
+ 'fatal' | described_class::FATAL
+ 'FATAL' | described_class::FATAL
+ 'FaTaL' | described_class::FATAL
+ 5 | described_class::UNKNOWN
+ :unknown | described_class::UNKNOWN
+ 'unknown' | described_class::UNKNOWN
+ 'UNKNOWN' | described_class::UNKNOWN
+ 'UnKnOwN' | described_class::UNKNOWN
+ end
+
+ with_them do
+ it 'builds logger if valid log level' do
+ stub_env('GITLAB_LOG_LEVEL', env_value)
+
+ expect(subject.level).to eq(resulting_level)
+ end
+ end
+ end
+
+ describe '.log_level' do
+ context 'if GITLAB_LOG_LEVEL is set' do
+ before do
+ stub_env('GITLAB_LOG_LEVEL', described_class::ERROR)
+ end
+
+ it 'returns value of GITLAB_LOG_LEVEL' do
+ expect(described_class.log_level).to eq(described_class::ERROR)
+ end
+
+ it 'ignores fallback' do
+ expect(described_class.log_level(fallback: described_class::FATAL)).to eq(described_class::ERROR)
+ end
+ end
+
+ context 'if GITLAB_LOG_LEVEL is not set' do
+ it 'returns default fallback DEBUG' do
+ expect(described_class.log_level).to eq(described_class::DEBUG)
+ end
+
+ it 'returns passed fallback' do
+ expect(described_class.log_level(fallback: described_class::FATAL)).to eq(described_class::FATAL)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/mail_room/authenticator_spec.rb b/spec/lib/gitlab/mail_room/authenticator_spec.rb
new file mode 100644
index 00000000000..44120902661
--- /dev/null
+++ b/spec/lib/gitlab/mail_room/authenticator_spec.rb
@@ -0,0 +1,188 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::MailRoom::Authenticator do
+ let(:yml_config) do
+ {
+ enabled: true,
+ address: 'address@example.com'
+ }
+ end
+
+ let(:incoming_email_secret_path) { '/path/to/incoming_email_secret' }
+ let(:incoming_email_config) { yml_config.merge(secret_file: incoming_email_secret_path) }
+
+ let(:service_desk_email_secret_path) { '/path/to/service_desk_email_secret' }
+ let(:service_desk_email_config) { yml_config.merge(secret_file: service_desk_email_secret_path) }
+
+ let(:configs) do
+ {
+ incoming_email: incoming_email_config,
+ service_desk_email: service_desk_email_config
+ }
+ end
+
+ before do
+ allow(Gitlab::MailRoom).to receive(:enabled_configs).and_return(configs)
+
+ described_class.clear_memoization(:jwt_secret_incoming_email)
+ described_class.clear_memoization(:jwt_secret_service_desk_email)
+ end
+
+ after do
+ described_class.clear_memoization(:jwt_secret_incoming_email)
+ described_class.clear_memoization(:jwt_secret_service_desk_email)
+ end
+
+ around do |example|
+ freeze_time do
+ example.run
+ end
+ end
+
+ 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 } }
+
+ before do
+ allow(described_class).to receive(:secret).with(:incoming_email).and_return(incoming_email_secret)
+ allow(described_class).to receive(:secret).with(:service_desk_email).and_return(service_desk_email_secret)
+ end
+
+ 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 }
+
+ expect(described_class.verify_api_request(headers, 'incoming_email')[0]).to match a_hash_including(
+ "iss" => "gitlab-mailroom",
+ "iat" => be_a(Integer)
+ )
+
+ encoded_token = JWT.encode(payload, service_desk_email_secret, 'HS256')
+ headers = { described_class::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",
+ "iat" => be_a(Integer)
+ )
+ end
+ end
+
+ 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 }
+
+ expect(described_class.verify_api_request(headers, 'incoming_email')).to eq(false)
+ end
+ end
+
+ 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 }
+
+ expect(described_class.verify_api_request(headers, 'service_desk_email')).to eq(false)
+ end
+ end
+
+ context 'verify a valid token but wrong issuer' do
+ let(:payload) { { iss: 'invalid_issuer' } }
+
+ it 'returns false' do
+ encoded_token = JWT.encode(payload, incoming_email_secret, 'HS256')
+ headers = { described_class::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 } }
+
+ it 'returns false' do
+ encoded_token = JWT.encode(payload, incoming_email_secret, 'HS256')
+ headers = { described_class::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 wrong header field' do
+ it 'returns false' do
+ encoded_token = JWT.encode(payload, incoming_email_secret, 'HS256')
+ headers = { 'a-wrong-header' => encoded_token }
+
+ expect(described_class.verify_api_request(headers, 'incoming_email')).to eq(false)
+ end
+ end
+
+ context 'verify headers for a disabled mailbox type' do
+ let(:configs) { { service_desk_email: service_desk_email_config } }
+
+ it 'returns false' do
+ encoded_token = JWT.encode(payload, incoming_email_secret, 'HS256')
+ headers = { described_class::INTERNAL_API_REQUEST_HEADER => encoded_token }
+
+ expect(described_class.verify_api_request(headers, 'incoming_email')).to eq(false)
+ end
+ end
+
+ context 'verify headers for a non-existing mailbox type' do
+ it 'returns false' do
+ headers = { described_class::INTERNAL_API_REQUEST_HEADER => 'something' }
+
+ expect(described_class.verify_api_request(headers, 'invalid_mailbox_type')).to eq(false)
+ end
+ end
+ end
+
+ describe '#secret' do
+ let(:incoming_email_secret) { SecureRandom.hex(16) }
+ let(:service_desk_email_secret) { SecureRandom.hex(16) }
+
+ context 'the secret is valid' do
+ before do
+ allow(described_class).to receive(:read_secret).with(incoming_email_secret_path).and_return(incoming_email_secret).once
+ allow(described_class).to receive(:read_secret).with(service_desk_email_secret_path).and_return(service_desk_email_secret).once
+ end
+
+ it 'returns the memorized secret from a file' do
+ expect(described_class.secret(:incoming_email)).to eql(incoming_email_secret)
+ # The second call does not trigger secret read again
+ expect(described_class.secret(:incoming_email)).to eql(incoming_email_secret)
+ expect(described_class).to have_received(:read_secret).with(incoming_email_secret_path).once
+
+ expect(described_class.secret(:service_desk_email)).to eql(service_desk_email_secret)
+ # The second call does not trigger secret read again
+ expect(described_class.secret(:service_desk_email)).to eql(service_desk_email_secret)
+ expect(described_class).to have_received(:read_secret).with(service_desk_email_secret_path).once
+ end
+ end
+
+ context 'the secret file is not configured' do
+ let(:incoming_email_config) { yml_config }
+
+ it 'raises a SecretConfigurationError exception' do
+ expect do
+ described_class.secret(:incoming_email)
+ end.to raise_error(described_class::SecretConfigurationError, "incoming_email's secret_file configuration is missing")
+ end
+ end
+
+ context 'the secret file not found' do
+ before do
+ allow(described_class).to receive(:read_secret).with(incoming_email_secret_path).and_raise(Errno::ENOENT)
+ end
+
+ it 'raises a SecretConfigurationError exception' do
+ expect do
+ described_class.secret(:incoming_email)
+ end.to raise_error(described_class::SecretConfigurationError, "Fail to read incoming_email's secret: No such file or directory")
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/mail_room/mail_room_spec.rb b/spec/lib/gitlab/mail_room/mail_room_spec.rb
index 0bd1a27c65e..a4fcf71a012 100644
--- a/spec/lib/gitlab/mail_room/mail_room_spec.rb
+++ b/spec/lib/gitlab/mail_room/mail_room_spec.rb
@@ -30,6 +30,7 @@ RSpec.describe Gitlab::MailRoom do
end
before do
+ allow(described_class).to receive(:load_yaml).and_return(configs)
described_class.instance_variable_set(:@enabled_configs, nil)
end
@@ -38,10 +39,6 @@ RSpec.describe Gitlab::MailRoom do
end
describe '#enabled_configs' do
- before do
- allow(described_class).to receive(:load_yaml).and_return(configs)
- end
-
context 'when both email and address is set' do
it 'returns email configs' do
expect(described_class.enabled_configs.size).to eq(2)
@@ -79,7 +76,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.first[:port]).to eq(Gitlab::MailRoom::DEFAULT_CONFIG[:port])
+ expect(described_class.enabled_configs.each_value.first[:port]).to eq(Gitlab::MailRoom::DEFAULT_CONFIG[:port])
end
end
@@ -88,7 +85,7 @@ 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.first[:worker]).to eq('EmailReceiverWorker')
+ expect(described_class.enabled_configs.each_value.first[:worker]).to eq('EmailReceiverWorker')
end
end
@@ -100,11 +97,12 @@ RSpec.describe Gitlab::MailRoom do
end
it 'sets redis config' do
- config = described_class.enabled_configs.first
-
- expect(config[:redis_url]).to eq('localhost')
- expect(config[:redis_db]).to eq(99)
- expect(config[:sentinels]).to eq('yes, them')
+ config = described_class.enabled_configs.each_value.first
+ expect(config).to include(
+ redis_url: 'localhost',
+ redis_db: 99,
+ sentinels: 'yes, them'
+ )
end
end
@@ -113,7 +111,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.first[:log_path])
+ new_path = Pathname.new(described_class.enabled_configs.each_value.first[:log_path])
expect(new_path.absolute?).to be_truthy
end
end
@@ -122,9 +120,48 @@ RSpec.describe Gitlab::MailRoom do
let(:custom_config) { { log_path: '/dev/null' } }
it 'leaves the path as-is' do
- expect(described_class.enabled_configs.first[:log_path]).to eq '/dev/null'
+ expect(described_class.enabled_configs.each_value.first[:log_path]).to eq '/dev/null'
end
end
end
end
+
+ describe '#enabled_mailbox_types' do
+ context 'when all mailbox types are enabled' do
+ it 'returns the mailbox types' do
+ expect(described_class.enabled_mailbox_types).to match(%w[incoming_email service_desk_email])
+ end
+ end
+
+ context 'when an mailbox_types is disabled' do
+ let(:incoming_email_config) { yml_config.merge(enabled: false) }
+
+ it 'returns the mailbox types' do
+ expect(described_class.enabled_mailbox_types).to match(%w[service_desk_email])
+ end
+ end
+
+ context 'when email is disabled' do
+ let(:custom_config) { { enabled: false } }
+
+ it 'returns an empty array' do
+ expect(described_class.enabled_mailbox_types).to match_array([])
+ end
+ end
+ end
+
+ describe '#worker_for' do
+ context 'matched mailbox types' do
+ it 'returns the constantized worker class' do
+ expect(described_class.worker_for('incoming_email')).to eql(EmailReceiverWorker)
+ expect(described_class.worker_for('service_desk_email')).to eql(ServiceDeskEmailReceiverWorker)
+ end
+ end
+
+ context 'non-existing mailbox_type' do
+ it 'returns nil' do
+ expect(described_class.worker_for('another_mailbox_type')).to be(nil)
+ 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 65c76aac10c..2407b497249 100644
--- a/spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb
+++ b/spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb
@@ -15,7 +15,8 @@ RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do
)
end
- let(:user) { project.creator }
+ let(:current_user) { create(:user, name: 'John Doe', email: 'john.doe@example.com') }
+ let(:author) { project.creator }
let(:source_branch) { 'feature' }
let(:merge_request_description) { "Merge Request Description\nNext line" }
let(:merge_request_title) { 'Bugfix' }
@@ -27,13 +28,13 @@ RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do
target_project: project,
target_branch: 'master',
source_branch: source_branch,
- author: user,
+ author: author,
description: merge_request_description,
title: merge_request_title
)
end
- subject { described_class.new(merge_request: merge_request) }
+ subject { described_class.new(merge_request: merge_request, current_user: current_user) }
shared_examples_for 'commit message with template' do |message_template_name|
it 'returns nil when template is not set in target project' do
@@ -56,6 +57,19 @@ RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do
end
end
+ context 'when project has commit template with only the title' do
+ let(:merge_request) do
+ double(:merge_request, title: 'Fixes', target_project: project, to_reference: '!123', metrics: nil, merge_user: nil)
+ end
+
+ let(message_template_name) { '%{title}' }
+
+ it 'evaluates only necessary variables' do
+ expect(result_message).to eq 'Fixes'
+ expect(merge_request).not_to have_received(:to_reference)
+ end
+ end
+
context 'when project has commit template with closed issues' do
let(message_template_name) { <<~MSG.rstrip }
Merge branch '%{source_branch}' into '%{target_branch}'
@@ -274,17 +288,319 @@ RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do
end
end
end
+
+ context 'when project has merge commit template with approvers' do
+ let(:user1) { create(:user) }
+ let(:user2) { create(:user) }
+ let(message_template_name) { <<~MSG.rstrip }
+ Merge branch '%{source_branch}' into '%{target_branch}'
+
+ %{approved_by}
+ MSG
+
+ context 'and mr has no approval' do
+ before do
+ merge_request.approved_by_users = []
+ end
+
+ it 'removes variable and blank line' do
+ expect(result_message).to eq <<~MSG.rstrip
+ Merge branch 'feature' into 'master'
+ MSG
+ end
+
+ context 'when there is blank line after approved_by' do
+ let(message_template_name) { <<~MSG.rstrip }
+ Merge branch '%{source_branch}' into '%{target_branch}'
+
+ %{approved_by}
+
+ Type: merge
+ MSG
+
+ it 'removes blank line before it' do
+ expect(result_message).to eq <<~MSG.rstrip
+ Merge branch 'feature' into 'master'
+
+ Type: merge
+ MSG
+ end
+ end
+
+ context 'when there is no blank line after approved_by' do
+ let(message_template_name) { <<~MSG.rstrip }
+ Merge branch '%{source_branch}' into '%{target_branch}'
+
+ %{approved_by}
+ Type: merge
+ MSG
+
+ it 'does not remove blank line before it' do
+ expect(result_message).to eq <<~MSG.rstrip
+ Merge branch 'feature' into 'master'
+
+ Type: merge
+ MSG
+ end
+ end
+ end
+
+ context 'and mr has one approval' do
+ before do
+ merge_request.approved_by_users = [user1]
+ end
+
+ it 'returns user name and email' do
+ expect(result_message).to eq <<~MSG.rstrip
+ Merge branch 'feature' into 'master'
+
+ Approved-by: #{user1.name} <#{user1.email}>
+ MSG
+ end
+ end
+
+ context 'and mr has multiple approvals' do
+ before do
+ merge_request.approved_by_users = [user1, user2]
+ end
+
+ it 'returns users names and emails' do
+ expect(result_message).to eq <<~MSG.rstrip
+ Merge branch 'feature' into 'master'
+
+ Approved-by: #{user1.name} <#{user1.email}>
+ Approved-by: #{user2.name} <#{user2.email}>
+ MSG
+ end
+ end
+ end
+
+ context 'when project has merge commit template with url' do
+ let(message_template_name) do
+ "Merge Request URL is '%{url}'"
+ end
+
+ context "and merge request has url" do
+ it "returns mr url" do
+ expect(result_message).to eq <<~MSG.rstrip
+ Merge Request URL is '#{Gitlab::UrlBuilder.build(merge_request)}'
+ MSG
+ end
+ end
+ end
+
+ context 'when project has merge commit template with merged_by' do
+ let(message_template_name) do
+ "Merge Request merged by '%{merged_by}'"
+ end
+
+ context "and current_user is passed" do
+ it "returns user name and email" do
+ expect(result_message).to eq <<~MSG.rstrip
+ Merge Request merged by '#{current_user.name} <#{current_user.email}>'
+ MSG
+ end
+ end
+ end
+
+ context 'user' do
+ subject { described_class.new(merge_request: merge_request, current_user: nil) }
+
+ let(:user1) { create(:user) }
+ let(:user2) { create(:user) }
+ let(message_template_name) do
+ "Merge Request merged by '%{merged_by}'"
+ end
+
+ context 'comes from metrics' do
+ before do
+ merge_request.metrics.merged_by = user1
+ end
+
+ it "returns user name and email" do
+ expect(result_message).to eq <<~MSG.rstrip
+ Merge Request merged by '#{user1.name} <#{user1.email}>'
+ MSG
+ end
+ end
+
+ context 'comes from merge_user' do
+ before do
+ merge_request.merge_user = user2
+ end
+
+ it "returns user name and email" do
+ expect(result_message).to eq <<~MSG.rstrip
+ Merge Request merged by '#{user2.name} <#{user2.email}>'
+ MSG
+ end
+ end
+ end
+
+ context 'when project has commit template with the same variable used twice' do
+ let(message_template_name) { '%{title} %{title}' }
+
+ it 'uses custom template' do
+ expect(result_message).to eq 'Bugfix Bugfix'
+ end
+ end
+
+ context 'when project has commit template without any variable' do
+ let(message_template_name) { 'static text' }
+
+ it 'uses custom template' do
+ expect(result_message).to eq 'static text'
+ end
+ end
+
+ context 'when project has template with all variables' do
+ let(message_template_name) { <<~MSG.rstrip }
+ source_branch:%{source_branch}
+ target_branch:%{target_branch}
+ title:%{title}
+ issues:%{issues}
+ description:%{description}
+ first_commit:%{first_commit}
+ first_multiline_commit:%{first_multiline_commit}
+ url:%{url}
+ approved_by:%{approved_by}
+ merged_by:%{merged_by}
+ co_authored_by:%{co_authored_by}
+ MSG
+
+ it 'uses custom template' do
+ expect(result_message).to eq <<~MSG.rstrip
+ source_branch:feature
+ target_branch:master
+ title:Bugfix
+ issues:
+ description:Merge Request Description
+ Next line
+ first_commit:Feature added
+
+ Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
+ first_multiline_commit:Feature added
+
+ Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
+ url:#{Gitlab::UrlBuilder.build(merge_request)}
+ 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>
+ MSG
+ end
+ end
+
+ context 'when project has merge commit template with co_authored_by' do
+ let(:source_branch) { 'signed-commits' }
+ let(message_template_name) { <<~MSG.rstrip }
+ %{title}
+
+ %{co_authored_by}
+ MSG
+
+ it 'uses custom template' do
+ expect(result_message).to eq <<~MSG.rstrip
+ Bugfix
+
+ Co-authored-by: Nannie Bernhard <nannie.bernhard@example.com>
+ Co-authored-by: Winnie Hellmann <winnie@gitlab.com>
+ MSG
+ end
+
+ context 'when author and merging user is one of the commit authors' do
+ let(:author) { create(:user, email: 'nannie.bernhard@example.com') }
+
+ before do
+ merge_request.merge_user = author
+ end
+
+ it 'skips his mail in coauthors' do
+ expect(result_message).to eq <<~MSG.rstrip
+ Bugfix
+
+ Co-authored-by: Winnie Hellmann <winnie@gitlab.com>
+ MSG
+ end
+ end
+
+ context 'when author and merging user is the only author of commits' do
+ let(:author) { create(:user, email: 'dmitriy.zaporozhets@gmail.com') }
+ let(:source_branch) { 'feature' }
+
+ before do
+ merge_request.merge_user = author
+ end
+
+ it 'skips coauthors and empty lines before it' do
+ expect(result_message).to eq <<~MSG.rstrip
+ Bugfix
+ MSG
+ end
+ end
+ end
end
describe '#merge_message' do
let(:result_message) { subject.merge_message }
it_behaves_like 'commit message with template', :merge_commit_template
+
+ context 'when project has merge commit template with co_authored_by' do
+ let(:source_branch) { 'signed-commits' }
+ let(:merge_commit_template) { <<~MSG.rstrip }
+ %{title}
+
+ %{co_authored_by}
+ MSG
+
+ context 'when author and merging user are one of the commit authors' do
+ let(:author) { create(:user, email: 'nannie.bernhard@example.com') }
+ let(:merge_user) { create(:user, email: 'winnie@gitlab.com') }
+
+ before do
+ merge_request.merge_user = merge_user
+ end
+
+ it 'skips merging user, but does not skip merge request author' do
+ expect(result_message).to eq <<~MSG.rstrip
+ Bugfix
+
+ Co-authored-by: Nannie Bernhard <nannie.bernhard@example.com>
+ MSG
+ end
+ end
+ end
end
describe '#squash_message' do
let(:result_message) { subject.squash_message }
it_behaves_like 'commit message with template', :squash_commit_template
+
+ context 'when project has merge commit template with co_authored_by' do
+ let(:source_branch) { 'signed-commits' }
+ let(:squash_commit_template) { <<~MSG.rstrip }
+ %{title}
+
+ %{co_authored_by}
+ MSG
+
+ context 'when author and merging user are one of the commit authors' do
+ let(:author) { create(:user, email: 'nannie.bernhard@example.com') }
+ let(:merge_user) { create(:user, email: 'winnie@gitlab.com') }
+
+ before do
+ merge_request.merge_user = merge_user
+ end
+
+ it 'skips merge request author, but does not skip merging user' do
+ expect(result_message).to eq <<~MSG.rstrip
+ Bugfix
+
+ Co-authored-by: Winnie Hellmann <winnie@gitlab.com>
+ MSG
+ end
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/metrics/exporter/base_exporter_spec.rb b/spec/lib/gitlab/metrics/exporter/base_exporter_spec.rb
index 9cd1ef4094e..c7afc02f0af 100644
--- a/spec/lib/gitlab/metrics/exporter/base_exporter_spec.rb
+++ b/spec/lib/gitlab/metrics/exporter/base_exporter_spec.rb
@@ -4,13 +4,8 @@ require 'spec_helper'
RSpec.describe Gitlab::Metrics::Exporter::BaseExporter do
let(:settings) { double('settings') }
- let(:exporter) { described_class.new(settings) }
- let(:log_filename) { File.join(Rails.root, 'log', 'sidekiq_exporter.log') }
-
- before do
- allow_any_instance_of(described_class).to receive(:log_filename).and_return(log_filename)
- allow_any_instance_of(described_class).to receive(:settings).and_return(settings)
- end
+ let(:log_enabled) { false }
+ let(:exporter) { described_class.new(settings, log_enabled: log_enabled, log_file: 'test_exporter.log') }
describe 'when exporter is enabled' do
before do
@@ -61,6 +56,38 @@ RSpec.describe Gitlab::Metrics::Exporter::BaseExporter do
exporter.start.join
end
+
+ context 'logging enabled' do
+ let(:log_enabled) { true }
+ let(:logger) { instance_double(WEBrick::Log) }
+
+ before do
+ allow(logger).to receive(:time_format=)
+ allow(logger).to receive(:info)
+ end
+
+ it 'configures a WEBrick logger with the given file' do
+ expect(WEBrick::Log).to receive(:new).with(end_with('test_exporter.log')).and_return(logger)
+
+ exporter
+ end
+
+ it 'logs any errors during startup' do
+ expect(::WEBrick::Log).to receive(:new).and_return(logger)
+ expect(::WEBrick::HTTPServer).to receive(:new).and_raise 'fail'
+ expect(logger).to receive(:error)
+
+ exporter.start
+ end
+ end
+
+ context 'logging disabled' do
+ it 'configures a WEBrick logger with the null device' do
+ expect(WEBrick::Log).to receive(:new).with(File::NULL).and_call_original
+
+ exporter
+ end
+ end
end
describe 'when thread is not alive' do
@@ -111,6 +138,18 @@ RSpec.describe Gitlab::Metrics::Exporter::BaseExporter do
describe 'request handling' do
using RSpec::Parameterized::TableSyntax
+ let(:fake_collector) do
+ Class.new do
+ def initialize(app, ...)
+ @app = app
+ end
+
+ def call(env)
+ @app.call(env)
+ end
+ end
+ end
+
where(:method_class, :path, :http_status) do
Net::HTTP::Get | '/metrics' | 200
Net::HTTP::Get | '/liveness' | 200
@@ -123,6 +162,8 @@ RSpec.describe Gitlab::Metrics::Exporter::BaseExporter do
allow(settings).to receive(:port).and_return(0)
allow(settings).to receive(:address).and_return('127.0.0.1')
+ stub_const('Gitlab::Metrics::Exporter::MetricsMiddleware', fake_collector)
+
# We want to wrap original method
# and run handling of requests
# in separate thread
@@ -134,8 +175,6 @@ RSpec.describe Gitlab::Metrics::Exporter::BaseExporter do
# is raised as we close listeners
end
end
-
- exporter.start.join
end
after do
@@ -146,12 +185,25 @@ RSpec.describe Gitlab::Metrics::Exporter::BaseExporter do
let(:config) { exporter.server.config }
let(:request) { method_class.new(path) }
- it 'responds with proper http_status' do
+ subject(:response) do
http = Net::HTTP.new(config[:BindAddress], config[:Port])
- response = http.request(request)
+ http.request(request)
+ end
+
+ it 'responds with proper http_status' do
+ exporter.start.join
expect(response.code).to eq(http_status.to_s)
end
+
+ it 'collects request metrics' do
+ expect_next_instance_of(fake_collector) do |instance|
+ expect(instance).to receive(:call).and_call_original
+ end
+
+ exporter.start.join
+ response
+ end
end
end
diff --git a/spec/lib/gitlab/metrics/exporter/gc_request_middleware_spec.rb b/spec/lib/gitlab/metrics/exporter/gc_request_middleware_spec.rb
new file mode 100644
index 00000000000..0c70a5de701
--- /dev/null
+++ b/spec/lib/gitlab/metrics/exporter/gc_request_middleware_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+
+RSpec.describe Gitlab::Metrics::Exporter::GcRequestMiddleware do
+ let(:app) { double(:app) }
+ let(:env) { {} }
+
+ subject(:middleware) { described_class.new(app) }
+
+ describe '#call' do
+ it 'runs a major GC after the next middleware is called' do
+ expect(app).to receive(:call).with(env).ordered.and_return([200, {}, []])
+ expect(GC).to receive(:start).ordered
+
+ response = middleware.call(env)
+
+ expect(response).to eq([200, {}, []])
+ end
+ end
+end
diff --git a/spec/lib/gitlab/metrics/exporter/health_checks_middleware_spec.rb b/spec/lib/gitlab/metrics/exporter/health_checks_middleware_spec.rb
new file mode 100644
index 00000000000..9ee46a45e7a
--- /dev/null
+++ b/spec/lib/gitlab/metrics/exporter/health_checks_middleware_spec.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+
+RSpec.describe Gitlab::Metrics::Exporter::HealthChecksMiddleware do
+ let(:app) { double(:app) }
+ let(:env) { { 'PATH_INFO' => path } }
+
+ let(:readiness_probe) { double(:readiness_probe) }
+ let(:liveness_probe) { double(:liveness_probe) }
+ let(:probe_result) { Gitlab::HealthChecks::Probes::Status.new(200, { status: 'ok' }) }
+
+ subject(:middleware) { described_class.new(app, readiness_probe, liveness_probe) }
+
+ describe '#call' do
+ context 'handling /readiness requests' do
+ let(:path) { '/readiness' }
+
+ it 'handles the request' do
+ expect(readiness_probe).to receive(:execute).and_return(probe_result)
+
+ response = middleware.call(env)
+
+ expect(response).to eq([200, { 'Content-Type' => 'application/json; charset=utf-8' }, ['{"status":"ok"}']])
+ end
+ end
+
+ context 'handling /liveness requests' do
+ let(:path) { '/liveness' }
+
+ it 'handles the request' do
+ expect(liveness_probe).to receive(:execute).and_return(probe_result)
+
+ response = middleware.call(env)
+
+ expect(response).to eq([200, { 'Content-Type' => 'application/json; charset=utf-8' }, ['{"status":"ok"}']])
+ end
+ end
+
+ context 'handling other requests' do
+ let(:path) { '/other_path' }
+
+ it 'forwards them to the next middleware' do
+ expect(app).to receive(:call).with(env).and_return([201, {}, []])
+
+ response = middleware.call(env)
+
+ expect(response).to eq([201, {}, []])
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/metrics/exporter/metrics_middleware_spec.rb b/spec/lib/gitlab/metrics/exporter/metrics_middleware_spec.rb
new file mode 100644
index 00000000000..ac5721f5974
--- /dev/null
+++ b/spec/lib/gitlab/metrics/exporter/metrics_middleware_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Metrics::Exporter::MetricsMiddleware do
+ let(:app) { double(:app) }
+ let(:pid) { 'fake_exporter' }
+ let(:env) { { 'PATH_INFO' => '/path', 'REQUEST_METHOD' => 'GET' } }
+
+ subject(:middleware) { described_class.new(app, pid) }
+
+ def metric(name, method, path, status)
+ metric = ::Prometheus::Client.registry.get(name)
+ return unless metric
+
+ values = metric.values.transform_keys { |k| k.slice(:method, :path, :pid, :code) }
+ values[{ method: method, path: path, pid: pid, code: status.to_s }]&.get
+ end
+
+ before do
+ expect(app).to receive(:call).with(env).and_return([200, {}, []])
+ end
+
+ describe '#call', :prometheus do
+ it 'records a total requests metric' do
+ response = middleware.call(env)
+
+ expect(response).to eq([200, {}, []])
+ expect(metric(:exporter_http_requests_total, 'get', '/path', 200)).to eq(1.0)
+ end
+
+ it 'records a request duration histogram' do
+ response = middleware.call(env)
+
+ expect(response).to eq([200, {}, []])
+ expect(metric(:exporter_http_request_duration_seconds, 'get', '/path', 200)).to be_a(Hash)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/metrics/exporter/sidekiq_exporter_spec.rb b/spec/lib/gitlab/metrics/exporter/sidekiq_exporter_spec.rb
deleted file mode 100644
index 75bc3ba9626..00000000000
--- a/spec/lib/gitlab/metrics/exporter/sidekiq_exporter_spec.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::Metrics::Exporter::SidekiqExporter do
- let(:exporter) { described_class.new(Settings.monitoring.sidekiq_exporter) }
-
- after do
- exporter.stop
- end
-
- context 'with valid config' do
- before do
- stub_config(
- monitoring: {
- sidekiq_exporter: {
- enabled: true,
- log_enabled: false,
- port: 0,
- address: '127.0.0.1'
- }
- }
- )
- end
-
- it 'does start thread' do
- expect(exporter.start).not_to be_nil
- end
-
- it 'does not enable logging by default' do
- expect(exporter.log_filename).to eq(File::NULL)
- end
- end
-
- context 'with logging enabled' do
- before do
- stub_config(
- monitoring: {
- sidekiq_exporter: {
- enabled: true,
- log_enabled: true,
- port: 0,
- address: '127.0.0.1'
- }
- }
- )
- end
-
- it 'returns a valid log filename' do
- expect(exporter.log_filename).to end_with('sidekiq_exporter.log')
- end
- end
-end
diff --git a/spec/lib/gitlab/metrics/exporter/web_exporter_spec.rb b/spec/lib/gitlab/metrics/exporter/web_exporter_spec.rb
index 9deaecbf41b..0531bccf4b4 100644
--- a/spec/lib/gitlab/metrics/exporter/web_exporter_spec.rb
+++ b/spec/lib/gitlab/metrics/exporter/web_exporter_spec.rb
@@ -24,14 +24,14 @@ RSpec.describe Gitlab::Metrics::Exporter::WebExporter do
exporter.stop
end
- context 'when running server' do
+ context 'when running server', :prometheus do
it 'readiness probe returns succesful status' do
expect(readiness_probe.http_status).to eq(200)
expect(readiness_probe.json).to include(status: 'ok')
expect(readiness_probe.json).to include('web_exporter' => [{ 'status': 'ok' }])
end
- it 'initializes request metrics', :prometheus do
+ it 'initializes request metrics' do
expect(Gitlab::Metrics::RailsSlis).to receive(:initialize_request_slis_if_needed!).and_call_original
http = Net::HTTP.new(exporter.server.config[:BindAddress], exporter.server.config[:Port])
@@ -42,7 +42,7 @@ RSpec.describe Gitlab::Metrics::Exporter::WebExporter do
end
describe '#mark_as_not_running!' do
- it 'readiness probe returns a failure status' do
+ it 'readiness probe returns a failure status', :prometheus do
exporter.mark_as_not_running!
expect(readiness_probe.http_status).to eq(503)
diff --git a/spec/lib/gitlab/metrics/samplers/action_cable_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/action_cable_sampler_spec.rb
index d834b796179..e1e4877cd50 100644
--- a/spec/lib/gitlab/metrics/samplers/action_cable_sampler_spec.rb
+++ b/spec/lib/gitlab/metrics/samplers/action_cable_sampler_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Metrics::Samplers::ActionCableSampler do
let(:action_cable) { instance_double(ActionCable::Server::Base) }
- subject { described_class.new(action_cable: action_cable) }
+ subject { described_class.new(action_cable: action_cable, logger: double) }
it_behaves_like 'metrics sampler', 'ACTION_CABLE_SAMPLER'
diff --git a/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb
index e8f8947c9e8..c88d8c17eac 100644
--- a/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb
+++ b/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb
@@ -62,7 +62,7 @@ RSpec.describe Gitlab::Metrics::Samplers::DatabaseSampler do
end
context 'when replica hosts are configured' do
- let(:main_load_balancer) { ActiveRecord::Base.load_balancer } # rubocop:disable Database/MultipleDatabases
+ let(:main_load_balancer) { ApplicationRecord.load_balancer }
let(:main_replica_host) { main_load_balancer.host }
let(:ci_load_balancer) { double(:load_balancer, host_list: ci_host_list, configuration: configuration) }
@@ -117,7 +117,7 @@ RSpec.describe Gitlab::Metrics::Samplers::DatabaseSampler do
end
context 'when the base model has replica connections' do
- let(:main_load_balancer) { ActiveRecord::Base.load_balancer } # rubocop:disable Database/MultipleDatabases
+ let(:main_load_balancer) { ApplicationRecord.load_balancer }
let(:main_replica_host) { main_load_balancer.host }
let(:ci_load_balancer) { double(:load_balancer, host_list: ci_host_list, configuration: configuration) }
diff --git a/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
index 6f1e0480197..a4877208bcf 100644
--- a/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
+++ b/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
@@ -84,7 +84,7 @@ RSpec.describe Gitlab::Metrics::Samplers::RubySampler do
end
describe '#sample_gc' do
- let!(:sampler) { described_class.new(5) }
+ let!(:sampler) { described_class.new }
let(:gc_reports) { [{ GC_TIME: 0.1 }, { GC_TIME: 0.2 }, { GC_TIME: 0.3 }] }
diff --git a/spec/lib/gitlab/middleware/go_spec.rb b/spec/lib/gitlab/middleware/go_spec.rb
index 1ef548ab29b..bc1d53b2ccb 100644
--- a/spec/lib/gitlab/middleware/go_spec.rb
+++ b/spec/lib/gitlab/middleware/go_spec.rb
@@ -100,7 +100,7 @@ RSpec.describe Gitlab::Middleware::Go do
context 'without access to the project', :sidekiq_inline do
before do
- project.team.find_member(current_user).destroy
+ project.team.find_member(current_user).destroy!
end
it_behaves_like 'unauthorized'
diff --git a/spec/lib/gitlab/middleware/webhook_recursion_detection_spec.rb b/spec/lib/gitlab/middleware/webhook_recursion_detection_spec.rb
new file mode 100644
index 00000000000..c8dbc990f8c
--- /dev/null
+++ b/spec/lib/gitlab/middleware/webhook_recursion_detection_spec.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require 'action_dispatch'
+require 'rack'
+require 'request_store'
+
+RSpec.describe Gitlab::Middleware::WebhookRecursionDetection do
+ let(:app) { double(:app) }
+ let(:middleware) { described_class.new(app) }
+ let(:env) { Rack::MockRequest.env_for("/").merge(headers) }
+
+ around do |example|
+ Gitlab::WithRequestStore.with_request_store { example.run }
+ end
+
+ describe '#call' do
+ subject(:call) { described_class.new(app).call(env) }
+
+ context 'when the recursion detection header is present' do
+ let(:new_uuid) { SecureRandom.uuid }
+ let(:headers) { { 'HTTP_X_GITLAB_EVENT_UUID' => new_uuid } }
+
+ it 'sets the request UUID from the header' do
+ expect(app).to receive(:call)
+ expect { call }.to change { Gitlab::WebHooks::RecursionDetection::UUID.instance.request_uuid }.to(new_uuid)
+ end
+ end
+
+ context 'when recursion headers are not present' do
+ let(:headers) { {} }
+
+ it 'works without errors' do
+ expect(app).to receive(:call)
+
+ call
+
+ expect(Gitlab::WebHooks::RecursionDetection::UUID.instance.request_uuid).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_column_data_spec.rb b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_column_data_spec.rb
new file mode 100644
index 00000000000..b4869f49081
--- /dev/null
+++ b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_column_data_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::OrderByColumnData do
+ let(:arel_table) { Issue.arel_table }
+
+ let(:column) do
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: :id,
+ column_expression: arel_table[:id],
+ order_expression: arel_table[:id].desc
+ )
+ end
+
+ subject(:column_data) { described_class.new(column, 'column_alias', arel_table) }
+
+ describe '#arel_column' do
+ it 'delegates to column_expression' do
+ expect(column_data.arel_column).to eq(column.column_expression)
+ end
+ end
+
+ describe '#column_for_projection' do
+ it 'returns the expression with AS using the original column name' do
+ expect(column_data.column_for_projection.to_sql).to eq('"issues"."id" AS id')
+ end
+ end
+
+ describe '#projection' do
+ it 'returns the expression with AS using the specified column lias' do
+ expect(column_data.projection.to_sql).to eq('"issues"."id" AS column_alias')
+ end
+ end
+end
diff --git a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb
index 00beacd4b35..58db22e5a9c 100644
--- a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb
+++ b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb
@@ -33,14 +33,14 @@ RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder
]
end
- shared_examples 'correct ordering examples' do
- let(:iterator) do
- Gitlab::Pagination::Keyset::Iterator.new(
- scope: scope.limit(batch_size),
- in_operator_optimization_options: in_operator_optimization_options
- )
- end
+ let(:iterator) do
+ Gitlab::Pagination::Keyset::Iterator.new(
+ scope: scope.limit(batch_size),
+ in_operator_optimization_options: in_operator_optimization_options
+ )
+ end
+ shared_examples 'correct ordering examples' do |opts = {}|
let(:all_records) do
all_records = []
iterator.each_batch(of: batch_size) do |records|
@@ -49,8 +49,10 @@ RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder
all_records
end
- it 'returns records in correct order' do
- expect(all_records).to eq(expected_order)
+ unless opts[:skip_finder_query_test]
+ it 'returns records in correct order' do
+ expect(all_records).to eq(expected_order)
+ end
end
context 'when not passing the finder query' do
@@ -248,4 +250,57 @@ RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder
expect { described_class.new(**options).execute }.to raise_error(/The order on the scope does not support keyset pagination/)
end
+
+ context 'when ordering by SQL expression' do
+ let(:order) do
+ # ORDER BY (id * 10), id
+ Gitlab::Pagination::Keyset::Order.build([
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'id_multiplied_by_ten',
+ order_expression: Arel.sql('(id * 10)').asc,
+ sql_type: 'integer'
+ ),
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: :id,
+ order_expression: Issue.arel_table[:id].asc
+ )
+ ])
+ end
+
+ let(:scope) { Issue.reorder(order) }
+ let(:expected_order) { issues.sort_by(&:id) }
+
+ let(:in_operator_optimization_options) do
+ {
+ array_scope: Project.where(namespace_id: top_level_group.self_and_descendants.select(:id)).select(:id),
+ array_mapping_scope: -> (id_expression) { Issue.where(Issue.arel_table[:project_id].eq(id_expression)) }
+ }
+ end
+
+ context 'when iterating records one by one' do
+ let(:batch_size) { 1 }
+
+ it_behaves_like 'correct ordering examples', skip_finder_query_test: true
+ end
+
+ context 'when iterating records with LIMIT 3' do
+ let(:batch_size) { 3 }
+
+ it_behaves_like 'correct ordering examples', skip_finder_query_test: true
+ end
+
+ context 'when passing finder query' do
+ let(:batch_size) { 3 }
+
+ it 'raises error, loading complete rows are not supported with SQL expressions' do
+ in_operator_optimization_options[:finder_query] = -> (_, _) { Issue.select(:id, '(id * 10)').where(id: -1) }
+
+ expect(in_operator_optimization_options[:finder_query]).not_to receive(:call)
+
+ expect do
+ iterator.each_batch(of: batch_size) { |records| records.to_a }
+ end.to raise_error /The "RecordLoaderStrategy" does not support/
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/order_values_loader_strategy_spec.rb b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/order_values_loader_strategy_spec.rb
index fe95d5406dd..ab1037b318b 100644
--- a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/order_values_loader_strategy_spec.rb
+++ b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/order_values_loader_strategy_spec.rb
@@ -31,4 +31,41 @@ RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::Strategies::O
])
end
end
+
+ context 'when an SQL expression is given' do
+ context 'when the sql_type attribute is missing' do
+ let(:order) do
+ Gitlab::Pagination::Keyset::Order.build([
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'id_times_ten',
+ order_expression: Arel.sql('id * 10').asc
+ )
+ ])
+ end
+
+ let(:keyset_scope) { Project.order(order) }
+
+ it 'raises error' do
+ expect { strategy.initializer_columns }.to raise_error(Gitlab::Pagination::Keyset::SqlTypeMissingError)
+ end
+ end
+
+ context 'when the sql_type_attribute is present' do
+ let(:order) do
+ Gitlab::Pagination::Keyset::Order.build([
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'id_times_ten',
+ order_expression: Arel.sql('id * 10').asc,
+ sql_type: 'integer'
+ )
+ ])
+ end
+
+ let(:keyset_scope) { Project.order(order) }
+
+ it 'returns the initializer columns' do
+ expect(strategy.initializer_columns).to eq(['NULL::integer AS id_times_ten'])
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/redis/multi_store_spec.rb b/spec/lib/gitlab/redis/multi_store_spec.rb
deleted file mode 100644
index 76731bb916c..00000000000
--- a/spec/lib/gitlab/redis/multi_store_spec.rb
+++ /dev/null
@@ -1,676 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::Redis::MultiStore do
- using RSpec::Parameterized::TableSyntax
-
- let_it_be(:redis_store_class) do
- Class.new(Gitlab::Redis::Wrapper) do
- def config_file_name
- config_file_name = "spec/fixtures/config/redis_new_format_host.yml"
- Rails.root.join(config_file_name).to_s
- end
-
- def self.name
- 'Sessions'
- end
- end
- end
-
- let_it_be(:primary_db) { 1 }
- let_it_be(:secondary_db) { 2 }
- let_it_be(:primary_store) { create_redis_store(redis_store_class.params, db: primary_db, serializer: nil) }
- let_it_be(:secondary_store) { create_redis_store(redis_store_class.params, db: secondary_db, serializer: nil) }
- let_it_be(:instance_name) { 'TestStore' }
- let_it_be(:multi_store) { described_class.new(primary_store, secondary_store, instance_name)}
-
- subject { multi_store.send(name, *args) }
-
- before do
- skip_feature_flags_yaml_validation
- skip_default_enabled_yaml_check
- end
-
- after(:all) do
- primary_store.flushdb
- secondary_store.flushdb
- end
-
- context 'when primary_store is nil' do
- let(:multi_store) { described_class.new(nil, secondary_store, instance_name)}
-
- it 'fails with exception' do
- expect { multi_store }.to raise_error(ArgumentError, /primary_store is required/)
- end
- end
-
- context 'when secondary_store is nil' do
- let(:multi_store) { described_class.new(primary_store, nil, instance_name)}
-
- it 'fails with exception' do
- expect { multi_store }.to raise_error(ArgumentError, /secondary_store is required/)
- end
- end
-
- context 'when instance_name is nil' do
- let(:instance_name) { nil }
- let(:multi_store) { described_class.new(primary_store, secondary_store, instance_name)}
-
- it 'fails with exception' do
- expect { multi_store }.to raise_error(ArgumentError, /instance_name is required/)
- end
- end
-
- context 'when primary_store is not a ::Redis instance' do
- before do
- allow(primary_store).to receive(:is_a?).with(::Redis).and_return(false)
- end
-
- it 'fails with exception' do
- expect { described_class.new(primary_store, secondary_store, instance_name) }.to raise_error(ArgumentError, /invalid primary_store/)
- end
- end
-
- context 'when secondary_store is not a ::Redis instance' do
- before do
- allow(secondary_store).to receive(:is_a?).with(::Redis).and_return(false)
- end
-
- it 'fails with exception' do
- expect { described_class.new(primary_store, secondary_store, instance_name) }.to raise_error(ArgumentError, /invalid secondary_store/)
- end
- end
-
- context 'with READ redis commands' do
- let_it_be(:key1) { "redis:{1}:key_a" }
- let_it_be(:key2) { "redis:{1}:key_b" }
- let_it_be(:value1) { "redis_value1"}
- let_it_be(:value2) { "redis_value2"}
- let_it_be(:skey) { "redis:set:key" }
- let_it_be(:keys) { [key1, key2] }
- let_it_be(:values) { [value1, value2] }
- let_it_be(:svalues) { [value2, value1] }
-
- where(:case_name, :name, :args, :value, :block) do
- 'execute :get command' | :get | ref(:key1) | ref(:value1) | nil
- 'execute :mget command' | :mget | ref(:keys) | ref(:values) | nil
- 'execute :mget with block' | :mget | ref(:keys) | ref(:values) | ->(value) { value }
- 'execute :smembers command' | :smembers | ref(:skey) | ref(:svalues) | nil
- 'execute :scard command' | :scard | ref(:skey) | 2 | nil
- end
-
- before(:all) do
- primary_store.multi do |multi|
- multi.set(key1, value1)
- multi.set(key2, value2)
- multi.sadd(skey, value1)
- multi.sadd(skey, value2)
- end
-
- secondary_store.multi do |multi|
- multi.set(key1, value1)
- multi.set(key2, value2)
- multi.sadd(skey, value1)
- multi.sadd(skey, value2)
- end
- end
-
- RSpec.shared_examples_for 'reads correct value' do
- it 'returns the correct value' do
- if value.is_a?(Array)
- # :smembers does not guarantee the order it will return the values (unsorted set)
- is_expected.to match_array(value)
- else
- is_expected.to eq(value)
- end
- end
- end
-
- RSpec.shared_examples_for 'fallback read from the secondary store' do
- let(:counter) { Gitlab::Metrics::NullMetric.instance }
-
- before do
- allow(Gitlab::Metrics).to receive(:counter).and_return(counter)
- end
-
- it 'fallback and execute on secondary instance' do
- expect(secondary_store).to receive(name).with(*args).and_call_original
-
- subject
- end
-
- it 'logs the ReadFromPrimaryError' do
- expect(Gitlab::ErrorTracking).to receive(:log_exception).with(an_instance_of(Gitlab::Redis::MultiStore::ReadFromPrimaryError),
- hash_including(command_name: name, extra: hash_including(instance_name: instance_name)))
-
- subject
- end
-
- it 'increment read fallback count metrics' do
- expect(counter).to receive(:increment).with(command: name, instance_name: instance_name)
-
- subject
- end
-
- include_examples 'reads correct value'
-
- context 'when fallback read from the secondary instance raises an exception' do
- before do
- allow(secondary_store).to receive(name).with(*args).and_raise(StandardError)
- end
-
- it 'fails with exception' do
- expect { subject }.to raise_error(StandardError)
- end
- end
- end
-
- RSpec.shared_examples_for 'secondary store' do
- it 'execute on the secondary instance' do
- expect(secondary_store).to receive(name).with(*args).and_call_original
-
- subject
- end
-
- include_examples 'reads correct value'
-
- it 'does not execute on the primary store' do
- expect(primary_store).not_to receive(name)
-
- subject
- end
- end
-
- with_them do
- describe "#{name}" do
- before do
- allow(primary_store).to receive(name).and_call_original
- allow(secondary_store).to receive(name).and_call_original
- end
-
- context 'with feature flag :use_primary_and_secondary_stores_for_test_store' do
- before do
- stub_feature_flags(use_primary_and_secondary_stores_for_test_store: true)
- end
-
- context 'when reading from the primary is successful' do
- it 'returns the correct value' do
- expect(primary_store).to receive(name).with(*args).and_call_original
-
- subject
- end
-
- it 'does not execute on the secondary store' do
- expect(secondary_store).not_to receive(name)
-
- subject
- end
-
- include_examples 'reads correct value'
- end
-
- context 'when reading from primary instance is raising an exception' do
- before do
- allow(primary_store).to receive(name).with(*args).and_raise(StandardError)
- allow(Gitlab::ErrorTracking).to receive(:log_exception)
- end
-
- it 'logs the exception' do
- expect(Gitlab::ErrorTracking).to receive(:log_exception).with(an_instance_of(StandardError),
- hash_including(extra: hash_including(:multi_store_error_message, instance_name: instance_name),
- command_name: name))
-
- subject
- end
-
- include_examples 'fallback read from the secondary store'
- end
-
- context 'when reading from primary instance return no value' do
- before do
- allow(primary_store).to receive(name).and_return(nil)
- end
-
- include_examples 'fallback read from the secondary store'
- end
-
- context 'when the command is executed within pipelined block' do
- subject do
- multi_store.pipelined do
- multi_store.send(name, *args)
- end
- end
-
- it 'is executed only 1 time on primary instance' do
- expect(primary_store).to receive(name).with(*args).once
-
- subject
- end
- end
-
- if params[:block]
- subject do
- multi_store.send(name, *args, &block)
- end
-
- context 'when block is provided' do
- it 'yields to the block' do
- expect(primary_store).to receive(name).and_yield(value)
-
- subject
- end
-
- include_examples 'reads correct value'
- end
- end
- end
-
- context 'with feature flag :use_primary_and_secondary_stores_for_test_store' do
- before do
- stub_feature_flags(use_primary_and_secondary_stores_for_test_store: false)
- end
-
- context 'with feature flag :use_primary_store_as_default_for_test_store is disabled' do
- before do
- stub_feature_flags(use_primary_store_as_default_for_test_store: false)
- end
-
- it_behaves_like 'secondary store'
- end
-
- context 'with feature flag :use_primary_store_as_default_for_test_store is enabled' do
- before do
- stub_feature_flags(use_primary_store_as_default_for_test_store: true)
- end
-
- it 'execute on the primary instance' do
- expect(primary_store).to receive(name).with(*args).and_call_original
-
- subject
- end
-
- include_examples 'reads correct value'
-
- it 'does not execute on the secondary store' do
- expect(secondary_store).not_to receive(name)
-
- subject
- end
- end
- end
-
- context 'with both primary and secondary store using same redis instance' do
- let(:primary_store) { create_redis_store(redis_store_class.params, db: primary_db, serializer: nil) }
- let(:secondary_store) { create_redis_store(redis_store_class.params, db: primary_db, serializer: nil) }
- let(:multi_store) { described_class.new(primary_store, secondary_store, instance_name)}
-
- it_behaves_like 'secondary store'
- end
- end
- end
- end
-
- context 'with WRITE redis commands' do
- let_it_be(:key1) { "redis:{1}:key_a" }
- let_it_be(:key2) { "redis:{1}:key_b" }
- let_it_be(:value1) { "redis_value1"}
- let_it_be(:value2) { "redis_value2"}
- let_it_be(:key1_value1) { [key1, value1] }
- let_it_be(:key1_value2) { [key1, value2] }
- let_it_be(:ttl) { 10 }
- let_it_be(:key1_ttl_value1) { [key1, ttl, value1] }
- let_it_be(:skey) { "redis:set:key" }
- let_it_be(:svalues1) { [value2, value1] }
- let_it_be(:svalues2) { [value1] }
- let_it_be(:skey_value1) { [skey, value1] }
- let_it_be(:skey_value2) { [skey, value2] }
-
- where(:case_name, :name, :args, :expected_value, :verification_name, :verification_args) do
- 'execute :set command' | :set | ref(:key1_value1) | ref(:value1) | :get | ref(:key1)
- 'execute :setnx command' | :setnx | ref(:key1_value2) | ref(:value1) | :get | ref(:key2)
- 'execute :setex command' | :setex | ref(:key1_ttl_value1) | ref(:ttl) | :ttl | ref(:key1)
- 'execute :sadd command' | :sadd | ref(:skey_value2) | ref(:svalues1) | :smembers | ref(:skey)
- 'execute :srem command' | :srem | ref(:skey_value1) | [] | :smembers | ref(:skey)
- 'execute :del command' | :del | ref(:key2) | nil | :get | ref(:key2)
- 'execute :flushdb command' | :flushdb | nil | 0 | :dbsize | nil
- end
-
- before do
- primary_store.flushdb
- secondary_store.flushdb
-
- primary_store.multi do |multi|
- multi.set(key2, value1)
- multi.sadd(skey, value1)
- end
-
- secondary_store.multi do |multi|
- multi.set(key2, value1)
- multi.sadd(skey, value1)
- end
- end
-
- RSpec.shared_examples_for 'verify that store contains values' do |store|
- it "#{store} redis store contains correct values", :aggregate_errors do
- subject
-
- redis_store = multi_store.send(store)
-
- if expected_value.is_a?(Array)
- # :smembers does not guarantee the order it will return the values
- expect(redis_store.send(verification_name, *verification_args)).to match_array(expected_value)
- else
- expect(redis_store.send(verification_name, *verification_args)).to eq(expected_value)
- end
- end
- end
-
- with_them do
- describe "#{name}" do
- let(:expected_args) {args || no_args }
-
- before do
- allow(primary_store).to receive(name).and_call_original
- allow(secondary_store).to receive(name).and_call_original
- end
-
- context 'with feature flag :use_primary_and_secondary_stores_for_test_store' do
- before do
- stub_feature_flags(use_primary_and_secondary_stores_for_test_store: true)
- end
-
- context 'when executing on primary instance is successful' do
- it 'executes on both primary and secondary redis store', :aggregate_errors do
- expect(primary_store).to receive(name).with(*expected_args).and_call_original
- expect(secondary_store).to receive(name).with(*expected_args).and_call_original
-
- subject
- end
-
- include_examples 'verify that store contains values', :primary_store
- include_examples 'verify that store contains values', :secondary_store
- end
-
- context 'when executing on the primary instance is raising an exception' do
- before do
- allow(primary_store).to receive(name).with(*expected_args).and_raise(StandardError)
- allow(Gitlab::ErrorTracking).to receive(:log_exception)
- end
-
- it 'logs the exception and execute on secondary instance', :aggregate_errors do
- expect(Gitlab::ErrorTracking).to receive(:log_exception).with(an_instance_of(StandardError),
- hash_including(extra: hash_including(:multi_store_error_message), command_name: name))
- expect(secondary_store).to receive(name).with(*expected_args).and_call_original
-
- subject
- end
-
- include_examples 'verify that store contains values', :secondary_store
- end
-
- context 'when the command is executed within pipelined block' do
- subject do
- multi_store.pipelined do
- multi_store.send(name, *args)
- end
- end
-
- it 'is executed only 1 time on each instance', :aggregate_errors do
- expect(primary_store).to receive(name).with(*expected_args).once
- expect(secondary_store).to receive(name).with(*expected_args).once
-
- subject
- end
-
- include_examples 'verify that store contains values', :primary_store
- include_examples 'verify that store contains values', :secondary_store
- end
- end
-
- context 'with feature flag :use_primary_and_secondary_stores_for_test_store is disabled' do
- before do
- stub_feature_flags(use_primary_and_secondary_stores_for_test_store: false)
- end
-
- context 'with feature flag :use_primary_store_as_default_for_test_store is disabled' do
- before do
- stub_feature_flags(use_primary_store_as_default_for_test_store: false)
- end
-
- it 'executes only on the secondary redis store', :aggregate_errors do
- expect(secondary_store).to receive(name).with(*expected_args)
- expect(primary_store).not_to receive(name).with(*expected_args)
-
- subject
- end
-
- include_examples 'verify that store contains values', :secondary_store
- end
-
- context 'with feature flag :use_primary_store_as_default_for_test_store is enabled' do
- before do
- stub_feature_flags(use_primary_store_as_default_for_test_store: true)
- end
-
- it 'executes only on the primary_redis redis store', :aggregate_errors do
- expect(primary_store).to receive(name).with(*expected_args)
- expect(secondary_store).not_to receive(name).with(*expected_args)
-
- subject
- end
-
- include_examples 'verify that store contains values', :primary_store
- end
- end
- end
- end
- end
-
- context 'with unsupported command' do
- let(:counter) { Gitlab::Metrics::NullMetric.instance }
-
- before do
- primary_store.flushdb
- secondary_store.flushdb
- allow(Gitlab::Metrics).to receive(:counter).and_return(counter)
- end
-
- let_it_be(:key) { "redis:counter" }
-
- subject { multi_store.incr(key) }
-
- it 'executes method missing' do
- expect(multi_store).to receive(:method_missing)
-
- subject
- end
-
- context 'when command is not in SKIP_LOG_METHOD_MISSING_FOR_COMMANDS' do
- it 'logs MethodMissingError' do
- expect(Gitlab::ErrorTracking).to receive(:log_exception).with(an_instance_of(Gitlab::Redis::MultiStore::MethodMissingError),
- hash_including(command_name: :incr, extra: hash_including(instance_name: instance_name)))
-
- subject
- end
-
- it 'increments method missing counter' do
- expect(counter).to receive(:increment).with(command: :incr, instance_name: instance_name)
-
- subject
- end
- end
-
- context 'when command is in SKIP_LOG_METHOD_MISSING_FOR_COMMANDS' do
- subject { multi_store.info }
-
- it 'does not log MethodMissingError' do
- expect(Gitlab::ErrorTracking).not_to receive(:log_exception)
-
- subject
- end
-
- it 'does not increment method missing counter' do
- expect(counter).not_to receive(:increment)
-
- subject
- end
- end
-
- context 'with feature flag :use_primary_store_as_default_for_test_store is enabled' do
- before do
- stub_feature_flags(use_primary_store_as_default_for_test_store: true)
- end
-
- it 'fallback and executes only on the secondary store', :aggregate_errors do
- expect(primary_store).to receive(:incr).with(key).and_call_original
- expect(secondary_store).not_to receive(:incr)
-
- subject
- end
-
- it 'correct value is stored on the secondary store', :aggregate_errors do
- subject
-
- expect(secondary_store.get(key)).to be_nil
- expect(primary_store.get(key)).to eq('1')
- end
- end
-
- context 'with feature flag :use_primary_store_as_default_for_test_store is disabled' do
- before do
- stub_feature_flags(use_primary_store_as_default_for_test_store: false)
- end
-
- it 'fallback and executes only on the secondary store', :aggregate_errors do
- expect(secondary_store).to receive(:incr).with(key).and_call_original
- expect(primary_store).not_to receive(:incr)
-
- subject
- end
-
- it 'correct value is stored on the secondary store', :aggregate_errors do
- subject
-
- expect(primary_store.get(key)).to be_nil
- expect(secondary_store.get(key)).to eq('1')
- end
- end
-
- context 'when the command is executed within pipelined block' do
- subject do
- multi_store.pipelined do
- multi_store.incr(key)
- end
- end
-
- it 'is executed only 1 time on each instance', :aggregate_errors do
- expect(primary_store).to receive(:incr).with(key).once
- expect(secondary_store).to receive(:incr).with(key).once
-
- subject
- end
-
- it "both redis stores are containing correct values", :aggregate_errors do
- subject
-
- expect(primary_store.get(key)).to eq('1')
- expect(secondary_store.get(key)).to eq('1')
- end
- end
- end
-
- describe '#to_s' do
- subject { multi_store.to_s }
-
- context 'with feature flag :use_primary_and_secondary_stores_for_test_store is enabled' do
- before do
- stub_feature_flags(use_primary_and_secondary_stores_for_test_store: true)
- end
-
- it 'returns same value as primary_store' do
- is_expected.to eq(primary_store.to_s)
- end
- end
-
- context 'with feature flag :use_primary_and_secondary_stores_for_test_store is disabled' do
- before do
- stub_feature_flags(use_primary_and_secondary_stores_for_test_store: false)
- end
-
- context 'with feature flag :use_primary_store_as_default_for_test_store is enabled' do
- before do
- stub_feature_flags(use_primary_store_as_default_for_test_store: true)
- end
-
- it 'returns same value as primary_store' do
- is_expected.to eq(primary_store.to_s)
- end
- end
-
- context 'with feature flag :use_primary_store_as_default_for_test_store is disabled' do
- before do
- stub_feature_flags(use_primary_store_as_default_for_test_store: false)
- end
-
- it 'returns same value as primary_store' do
- is_expected.to eq(secondary_store.to_s)
- end
- end
- end
- end
-
- describe '#is_a?' do
- it 'returns true for ::Redis::Store' do
- expect(multi_store.is_a?(::Redis::Store)).to be true
- end
- end
-
- describe '#use_primary_and_secondary_stores?' do
- context 'with feature flag :use_primary_and_secondary_stores_for_test_store is enabled' do
- before do
- stub_feature_flags(use_primary_and_secondary_stores_for_test_store: true)
- end
-
- it 'multi store is disabled' do
- expect(multi_store.use_primary_and_secondary_stores?).to be true
- end
- end
-
- context 'with feature flag :use_primary_and_secondary_stores_for_test_store is disabled' do
- before do
- stub_feature_flags(use_primary_and_secondary_stores_for_test_store: false)
- end
-
- it 'multi store is disabled' do
- expect(multi_store.use_primary_and_secondary_stores?).to be false
- end
- end
- end
-
- describe '#use_primary_store_as_default?' do
- context 'with feature flag :use_primary_store_as_default_for_test_store is enabled' do
- before do
- stub_feature_flags(use_primary_store_as_default_for_test_store: true)
- end
-
- it 'multi store is disabled' do
- expect(multi_store.use_primary_store_as_default?).to be true
- end
- end
-
- context 'with feature flag :use_primary_store_as_default_for_test_store is disabled' do
- before do
- stub_feature_flags(use_primary_store_as_default_for_test_store: false)
- end
-
- it 'multi store is disabled' do
- expect(multi_store.use_primary_store_as_default?).to be false
- end
- end
- end
-
- def create_redis_store(options, extras = {})
- ::Redis::Store.new(options.merge(extras))
- end
-end
diff --git a/spec/lib/gitlab/redis/sessions_spec.rb b/spec/lib/gitlab/redis/sessions_spec.rb
index 6ecbbf3294d..b02864cb73d 100644
--- a/spec/lib/gitlab/redis/sessions_spec.rb
+++ b/spec/lib/gitlab/redis/sessions_spec.rb
@@ -6,31 +6,16 @@ RSpec.describe Gitlab::Redis::Sessions do
it_behaves_like "redis_new_instance_shared_examples", 'sessions', Gitlab::Redis::SharedState
describe 'redis instance used in connection pool' do
- before do
+ around do |example|
clear_pool
- end
-
- after do
+ example.run
+ ensure
clear_pool
end
- context 'when redis.sessions configuration is not provided' do
- it 'uses ::Redis instance' do
- expect(described_class).to receive(:config_fallback?).and_return(true)
-
- described_class.pool.with do |redis_instance|
- expect(redis_instance).to be_instance_of(::Redis)
- end
- end
- end
-
- context 'when redis.sessions configuration is provided' do
- it 'instantiates an instance of MultiStore' do
- expect(described_class).to receive(:config_fallback?).and_return(false)
-
- described_class.pool.with do |redis_instance|
- expect(redis_instance).to be_instance_of(::Gitlab::Redis::MultiStore)
- end
+ it 'uses ::Redis instance' do
+ described_class.pool.with do |redis_instance|
+ expect(redis_instance).to be_instance_of(::Redis)
end
end
@@ -44,49 +29,9 @@ RSpec.describe Gitlab::Redis::Sessions do
describe '#store' do
subject(:store) { described_class.store(namespace: described_class::SESSION_NAMESPACE) }
- context 'when redis.sessions configuration is NOT provided' do
- it 'instantiates ::Redis instance' do
- expect(described_class).to receive(:config_fallback?).and_return(true)
- expect(store).to be_instance_of(::Redis::Store)
- end
- end
-
- context 'when redis.sessions configuration is provided' do
- let(:config_new_format_host) { "spec/fixtures/config/redis_new_format_host.yml" }
- let(:config_new_format_socket) { "spec/fixtures/config/redis_new_format_socket.yml" }
-
- before do
- redis_clear_raw_config!(Gitlab::Redis::Sessions)
- redis_clear_raw_config!(Gitlab::Redis::SharedState)
- allow(described_class).to receive(:config_fallback?).and_return(false)
- end
-
- after do
- redis_clear_raw_config!(Gitlab::Redis::Sessions)
- redis_clear_raw_config!(Gitlab::Redis::SharedState)
- end
-
- # Check that Gitlab::Redis::Sessions is configured as MultiStore with proper attrs.
- it 'instantiates an instance of MultiStore', :aggregate_failures do
- expect(described_class).to receive(:config_file_name).and_return(config_new_format_host)
- expect(::Gitlab::Redis::SharedState).to receive(:config_file_name).and_return(config_new_format_socket)
-
- expect(store).to be_instance_of(::Gitlab::Redis::MultiStore)
-
- expect(store.primary_store.to_s).to eq("Redis Client connected to test-host:6379 against DB 99 with namespace session:gitlab")
- expect(store.secondary_store.to_s).to eq("Redis Client connected to /path/to/redis.sock against DB 0 with namespace session:gitlab")
-
- expect(store.instance_name).to eq('Sessions')
- end
-
- context 'when MultiStore correctly configured' do
- before do
- allow(described_class).to receive(:config_file_name).and_return(config_new_format_host)
- allow(::Gitlab::Redis::SharedState).to receive(:config_file_name).and_return(config_new_format_socket)
- end
-
- it_behaves_like 'multi store feature flags', :use_primary_and_secondary_stores_for_sessions, :use_primary_store_as_default_for_sessions
- end
+ # Check that Gitlab::Redis::Sessions is configured as RedisStore.
+ it 'instantiates an instance of Redis::Store' do
+ expect(store).to be_instance_of(::Redis::Store)
end
end
end
diff --git a/spec/lib/gitlab/regex_spec.rb b/spec/lib/gitlab/regex_spec.rb
index 83f85cc73d0..8d67350f0f3 100644
--- a/spec/lib/gitlab/regex_spec.rb
+++ b/spec/lib/gitlab/regex_spec.rb
@@ -433,6 +433,7 @@ RSpec.describe Gitlab::Regex do
describe '.nuget_version_regex' do
subject { described_class.nuget_version_regex }
+ it { is_expected.to match('1.2') }
it { is_expected.to match('1.2.3') }
it { is_expected.to match('1.2.3.4') }
it { is_expected.to match('1.2.3.4-stable.1') }
@@ -440,7 +441,6 @@ RSpec.describe Gitlab::Regex do
it { is_expected.to match('1.2.3-alpha.3') }
it { is_expected.to match('1.0.7+r3456') }
it { is_expected.not_to match('1') }
- it { is_expected.not_to match('1.2') }
it { is_expected.not_to match('1./2.3') }
it { is_expected.not_to match('../../../../../1.2.3') }
it { is_expected.not_to match('%2e%2e%2f1.2.3') }
diff --git a/spec/lib/gitlab/search/params_spec.rb b/spec/lib/gitlab/search/params_spec.rb
index 6d15337b872..13770e550ec 100644
--- a/spec/lib/gitlab/search/params_spec.rb
+++ b/spec/lib/gitlab/search/params_spec.rb
@@ -133,4 +133,12 @@ RSpec.describe Gitlab::Search::Params do
end
end
end
+
+ describe '#email_lookup?' do
+ it 'is true if at least 1 word in search is an email' do
+ expect(described_class.new({ search: 'email@example.com' })).to be_email_lookup
+ expect(described_class.new({ search: 'foo email@example.com bar' })).to be_email_lookup
+ expect(described_class.new({ search: 'foo bar' })).not_to be_email_lookup
+ end
+ end
end
diff --git a/spec/lib/gitlab/shard_health_cache_spec.rb b/spec/lib/gitlab/shard_health_cache_spec.rb
index 5c47ac7e9a0..0c25cc7dab5 100644
--- a/spec/lib/gitlab/shard_health_cache_spec.rb
+++ b/spec/lib/gitlab/shard_health_cache_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Gitlab::ShardHealthCache, :clean_gitlab_redis_cache do
let(:shards) { %w(foo bar) }
before do
- described_class.update(shards)
+ described_class.update(shards) # rubocop:disable Rails/SaveBang
end
describe '.clear' do
@@ -24,7 +24,7 @@ RSpec.describe Gitlab::ShardHealthCache, :clean_gitlab_redis_cache do
it 'replaces the existing set' do
new_set = %w(test me more)
- described_class.update(new_set)
+ described_class.update(new_set) # rubocop:disable Rails/SaveBang
expect(described_class.cached_healthy_shards).to match_array(new_set)
end
@@ -36,7 +36,7 @@ RSpec.describe Gitlab::ShardHealthCache, :clean_gitlab_redis_cache do
end
it 'returns 0 if no shards are available' do
- described_class.update([])
+ described_class.update([]) # rubocop:disable Rails/SaveBang
expect(described_class.healthy_shard_count).to eq(0)
end
diff --git a/spec/lib/gitlab/sherlock/collection_spec.rb b/spec/lib/gitlab/sherlock/collection_spec.rb
deleted file mode 100644
index fcf8e6638f8..00000000000
--- a/spec/lib/gitlab/sherlock/collection_spec.rb
+++ /dev/null
@@ -1,84 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::Sherlock::Collection do
- let(:collection) { described_class.new }
-
- let(:transaction) do
- Gitlab::Sherlock::Transaction.new('POST', '/cat_pictures')
- end
-
- describe '#add' do
- it 'adds a new transaction' do
- collection.add(transaction)
-
- expect(collection).not_to be_empty
- end
-
- it 'is aliased as <<' do
- collection << transaction
-
- expect(collection).not_to be_empty
- end
- end
-
- describe '#each' do
- it 'iterates over every transaction' do
- collection.add(transaction)
-
- expect { |b| collection.each(&b) }.to yield_with_args(transaction)
- end
- end
-
- describe '#clear' do
- it 'removes all transactions' do
- collection.add(transaction)
-
- collection.clear
-
- expect(collection).to be_empty
- end
- end
-
- describe '#empty?' do
- it 'returns true for an empty collection' do
- expect(collection).to be_empty
- end
-
- it 'returns false for a collection with a transaction' do
- collection.add(transaction)
-
- expect(collection).not_to be_empty
- end
- end
-
- describe '#find_transaction' do
- it 'returns the transaction for the given ID' do
- collection.add(transaction)
-
- expect(collection.find_transaction(transaction.id)).to eq(transaction)
- end
-
- it 'returns nil when no transaction could be found' do
- collection.add(transaction)
-
- expect(collection.find_transaction('cats')).to be_nil
- end
- end
-
- describe '#newest_first' do
- it 'returns transactions sorted from new to old' do
- trans1 = Gitlab::Sherlock::Transaction.new('POST', '/cat_pictures')
- trans2 = Gitlab::Sherlock::Transaction.new('POST', '/more_cat_pictures')
-
- allow(trans1).to receive(:finished_at).and_return(Time.utc(2015, 1, 1))
- allow(trans2).to receive(:finished_at).and_return(Time.utc(2015, 1, 2))
-
- collection.add(trans1)
- collection.add(trans2)
-
- expect(collection.newest_first).to eq([trans2, trans1])
- end
- end
-end
diff --git a/spec/lib/gitlab/sherlock/file_sample_spec.rb b/spec/lib/gitlab/sherlock/file_sample_spec.rb
deleted file mode 100644
index 8a1aa51e2d4..00000000000
--- a/spec/lib/gitlab/sherlock/file_sample_spec.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::Sherlock::FileSample do
- let(:sample) { described_class.new(__FILE__, [], 150.4, 2) }
-
- describe '#id' do
- it 'returns the ID' do
- expect(sample.id).to be_an_instance_of(String)
- end
- end
-
- describe '#file' do
- it 'returns the file path' do
- expect(sample.file).to eq(__FILE__)
- end
- end
-
- describe '#line_samples' do
- it 'returns the line samples' do
- expect(sample.line_samples).to eq([])
- end
- end
-
- describe '#events' do
- it 'returns the total number of events' do
- expect(sample.events).to eq(2)
- end
- end
-
- describe '#duration' do
- it 'returns the total execution time' do
- expect(sample.duration).to eq(150.4)
- end
- end
-
- describe '#relative_path' do
- it 'returns the relative path' do
- expect(sample.relative_path)
- .to eq('spec/lib/gitlab/sherlock/file_sample_spec.rb')
- end
- end
-
- describe '#to_param' do
- it 'returns the sample ID' do
- expect(sample.to_param).to eq(sample.id)
- end
- end
-
- describe '#source' do
- it 'returns the contents of the file' do
- expect(sample.source).to eq(File.read(__FILE__))
- end
- end
-end
diff --git a/spec/lib/gitlab/sherlock/line_profiler_spec.rb b/spec/lib/gitlab/sherlock/line_profiler_spec.rb
deleted file mode 100644
index 2220a2cafc8..00000000000
--- a/spec/lib/gitlab/sherlock/line_profiler_spec.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::Sherlock::LineProfiler do
- let(:profiler) { described_class.new }
-
- describe '#profile' do
- it 'runs the profiler when using MRI' do
- allow(profiler).to receive(:mri?).and_return(true)
- allow(profiler).to receive(:profile_mri)
-
- profiler.profile { 'cats' }
- end
-
- it 'raises NotImplementedError when profiling an unsupported platform' do
- allow(profiler).to receive(:mri?).and_return(false)
-
- expect { profiler.profile { 'cats' } }.to raise_error(NotImplementedError)
- end
- end
-
- describe '#profile_mri' do
- it 'returns an Array containing the return value and profiling samples' do
- allow(profiler).to receive(:lineprof)
- .and_yield
- .and_return({ __FILE__ => [[0, 0, 0, 0]] })
-
- retval, samples = profiler.profile_mri { 42 }
-
- expect(retval).to eq(42)
- expect(samples).to eq([])
- end
- end
-
- describe '#aggregate_rblineprof' do
- let(:raw_samples) do
- { __FILE__ => [[30000, 30000, 5, 0], [15000, 15000, 4, 0]] }
- end
-
- it 'returns an Array of FileSample objects' do
- samples = profiler.aggregate_rblineprof(raw_samples)
-
- expect(samples).to be_an_instance_of(Array)
- expect(samples[0]).to be_an_instance_of(Gitlab::Sherlock::FileSample)
- end
-
- describe 'the first FileSample object' do
- let(:file_sample) do
- profiler.aggregate_rblineprof(raw_samples)[0]
- end
-
- it 'uses the correct file path' do
- expect(file_sample.file).to eq(__FILE__)
- end
-
- it 'contains a list of line samples' do
- line_sample = file_sample.line_samples[0]
-
- expect(line_sample).to be_an_instance_of(Gitlab::Sherlock::LineSample)
-
- expect(line_sample.duration).to eq(15.0)
- expect(line_sample.events).to eq(4)
- end
-
- it 'contains the total file execution time' do
- expect(file_sample.duration).to eq(30.0)
- end
-
- it 'contains the total amount of file events' do
- expect(file_sample.events).to eq(5)
- end
- end
- end
-end
diff --git a/spec/lib/gitlab/sherlock/line_sample_spec.rb b/spec/lib/gitlab/sherlock/line_sample_spec.rb
deleted file mode 100644
index db031377787..00000000000
--- a/spec/lib/gitlab/sherlock/line_sample_spec.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::Sherlock::LineSample do
- let(:sample) { described_class.new(150.0, 4) }
-
- describe '#duration' do
- it 'returns the duration' do
- expect(sample.duration).to eq(150.0)
- end
- end
-
- describe '#events' do
- it 'returns the amount of events' do
- expect(sample.events).to eq(4)
- end
- end
-
- describe '#percentage_of' do
- it 'returns the percentage of 1500.0' do
- expect(sample.percentage_of(1500.0)).to be_within(0.1).of(10.0)
- end
- end
-
- describe '#majority_of' do
- it 'returns true if the sample takes up the majority of the given duration' do
- expect(sample.majority_of?(500.0)).to eq(true)
- end
-
- it "returns false if the sample doesn't take up the majority of the given duration" do
- expect(sample.majority_of?(1500.0)).to eq(false)
- end
- end
-end
diff --git a/spec/lib/gitlab/sherlock/location_spec.rb b/spec/lib/gitlab/sherlock/location_spec.rb
deleted file mode 100644
index 4a8b5dffba2..00000000000
--- a/spec/lib/gitlab/sherlock/location_spec.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::Sherlock::Location do
- let(:location) { described_class.new(__FILE__, 1) }
-
- describe 'from_ruby_location' do
- it 'creates a Location from a Thread::Backtrace::Location' do
- input = caller_locations[0]
- output = described_class.from_ruby_location(input)
-
- expect(output).to be_an_instance_of(described_class)
- expect(output.path).to eq(input.path)
- expect(output.line).to eq(input.lineno)
- end
- end
-
- describe '#path' do
- it 'returns the file path' do
- expect(location.path).to eq(__FILE__)
- end
- end
-
- describe '#line' do
- it 'returns the line number' do
- expect(location.line).to eq(1)
- end
- end
-
- describe '#application?' do
- it 'returns true for an application frame' do
- expect(location.application?).to eq(true)
- end
-
- it 'returns false for a non application frame' do
- loc = described_class.new('/tmp/cats.rb', 1)
-
- expect(loc.application?).to eq(false)
- end
- end
-end
diff --git a/spec/lib/gitlab/sherlock/middleware_spec.rb b/spec/lib/gitlab/sherlock/middleware_spec.rb
deleted file mode 100644
index 645bde6681d..00000000000
--- a/spec/lib/gitlab/sherlock/middleware_spec.rb
+++ /dev/null
@@ -1,81 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::Sherlock::Middleware do
- let(:app) { double(:app) }
- let(:middleware) { described_class.new(app) }
-
- describe '#call' do
- describe 'when instrumentation is enabled' do
- it 'instruments a request' do
- allow(middleware).to receive(:instrument?).and_return(true)
- allow(middleware).to receive(:call_with_instrumentation)
-
- middleware.call({})
- end
- end
-
- describe 'when instrumentation is disabled' do
- it "doesn't instrument a request" do
- allow(middleware).to receive(:instrument).and_return(false)
- allow(app).to receive(:call)
-
- middleware.call({})
- end
- end
- end
-
- describe '#call_with_instrumentation' do
- it 'instruments a request' do
- trans = double(:transaction)
- retval = 'cats are amazing'
- env = {}
-
- allow(app).to receive(:call).with(env).and_return(retval)
- allow(middleware).to receive(:transaction_from_env).and_return(trans)
- allow(trans).to receive(:run).and_yield.and_return(retval)
- allow(Gitlab::Sherlock.collection).to receive(:add).with(trans)
-
- middleware.call_with_instrumentation(env)
- end
- end
-
- describe '#instrument?' do
- it 'returns false for a text/css request' do
- env = { 'HTTP_ACCEPT' => 'text/css', 'REQUEST_URI' => '/' }
-
- expect(middleware.instrument?(env)).to eq(false)
- end
-
- it 'returns false for a request to a Sherlock route' do
- env = {
- 'HTTP_ACCEPT' => 'text/html',
- 'REQUEST_URI' => '/sherlock/transactions'
- }
-
- expect(middleware.instrument?(env)).to eq(false)
- end
-
- it 'returns true for a request that should be instrumented' do
- env = {
- 'HTTP_ACCEPT' => 'text/html',
- 'REQUEST_URI' => '/cats'
- }
-
- expect(middleware.instrument?(env)).to eq(true)
- end
- end
-
- describe '#transaction_from_env' do
- it 'returns a Transaction' do
- env = {
- 'HTTP_ACCEPT' => 'text/html',
- 'REQUEST_URI' => '/cats'
- }
-
- expect(middleware.transaction_from_env(env))
- .to be_an_instance_of(Gitlab::Sherlock::Transaction)
- end
- end
-end
diff --git a/spec/lib/gitlab/sherlock/query_spec.rb b/spec/lib/gitlab/sherlock/query_spec.rb
deleted file mode 100644
index b8dfd082c37..00000000000
--- a/spec/lib/gitlab/sherlock/query_spec.rb
+++ /dev/null
@@ -1,115 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::Sherlock::Query do
- let(:started_at) { Time.utc(2015, 1, 1) }
- let(:finished_at) { started_at + 5 }
-
- let(:query) do
- described_class.new('SELECT COUNT(*) FROM users', started_at, finished_at)
- end
-
- describe 'new_with_bindings' do
- it 'returns a Query' do
- sql = 'SELECT COUNT(*) FROM users WHERE id = $1'
- bindings = [[double(:column), 10]]
-
- query = described_class
- .new_with_bindings(sql, bindings, started_at, finished_at)
-
- expect(query.query).to eq('SELECT COUNT(*) FROM users WHERE id = 10;')
- end
- end
-
- describe '#id' do
- it 'returns a String' do
- expect(query.id).to be_an_instance_of(String)
- end
- end
-
- describe '#query' do
- it 'returns the query with a trailing semi-colon' do
- expect(query.query).to eq('SELECT COUNT(*) FROM users;')
- end
- end
-
- describe '#started_at' do
- it 'returns the start time' do
- expect(query.started_at).to eq(started_at)
- end
- end
-
- describe '#finished_at' do
- it 'returns the completion time' do
- expect(query.finished_at).to eq(finished_at)
- end
- end
-
- describe '#backtrace' do
- it 'returns the backtrace' do
- expect(query.backtrace).to be_an_instance_of(Array)
- end
- end
-
- describe '#duration' do
- it 'returns the duration in milliseconds' do
- expect(query.duration).to be_within(0.1).of(5000.0)
- end
- end
-
- describe '#to_param' do
- it 'returns the query ID' do
- expect(query.to_param).to eq(query.id)
- end
- end
-
- describe '#formatted_query' do
- it 'returns a formatted version of the query' do
- expect(query.formatted_query).to eq(<<-EOF.strip)
-SELECT COUNT(*)
-FROM users;
- EOF
- end
- end
-
- describe '#last_application_frame' do
- it 'returns the last application frame' do
- frame = query.last_application_frame
-
- expect(frame).to be_an_instance_of(Gitlab::Sherlock::Location)
- expect(frame.path).to eq(__FILE__)
- end
- end
-
- describe '#application_backtrace' do
- it 'returns an Array of application frames' do
- frames = query.application_backtrace
-
- expect(frames).to be_an_instance_of(Array)
- expect(frames).not_to be_empty
-
- frames.each do |frame|
- expect(frame.path).to start_with(Rails.root.to_s)
- end
- end
- end
-
- describe '#explain' do
- it 'returns the query plan as a String' do
- lines = [
- ['Aggregate (cost=123 rows=1)'],
- [' -> Index Only Scan using index_cats_are_amazing']
- ]
-
- result = double(:result, values: lines)
-
- allow(query).to receive(:raw_explain).and_return(result)
-
- expect(query.explain).to eq(<<-EOF.strip)
-Aggregate (cost=123 rows=1)
- -> Index Only Scan using index_cats_are_amazing
- EOF
- end
- end
-end
diff --git a/spec/lib/gitlab/sherlock/transaction_spec.rb b/spec/lib/gitlab/sherlock/transaction_spec.rb
deleted file mode 100644
index 535b0ad4d8a..00000000000
--- a/spec/lib/gitlab/sherlock/transaction_spec.rb
+++ /dev/null
@@ -1,238 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::Sherlock::Transaction do
- let(:transaction) { described_class.new('POST', '/cat_pictures') }
-
- describe '#id' do
- it 'returns the transaction ID' do
- expect(transaction.id).to be_an_instance_of(String)
- end
- end
-
- describe '#type' do
- it 'returns the type' do
- expect(transaction.type).to eq('POST')
- end
- end
-
- describe '#path' do
- it 'returns the path' do
- expect(transaction.path).to eq('/cat_pictures')
- end
- end
-
- describe '#queries' do
- it 'returns an Array of queries' do
- expect(transaction.queries).to be_an_instance_of(Array)
- end
- end
-
- describe '#file_samples' do
- it 'returns an Array of file samples' do
- expect(transaction.file_samples).to be_an_instance_of(Array)
- end
- end
-
- describe '#started_at' do
- it 'returns the start time' do
- allow(transaction).to receive(:profile_lines).and_yield
-
- transaction.run { 'cats are amazing' }
-
- expect(transaction.started_at).to be_an_instance_of(Time)
- end
- end
-
- describe '#finished_at' do
- it 'returns the completion time' do
- allow(transaction).to receive(:profile_lines).and_yield
-
- transaction.run { 'cats are amazing' }
-
- expect(transaction.finished_at).to be_an_instance_of(Time)
- end
- end
-
- describe '#view_counts' do
- it 'returns a Hash' do
- expect(transaction.view_counts).to be_an_instance_of(Hash)
- end
-
- it 'sets the default value of a key to 0' do
- expect(transaction.view_counts['cats.rb']).to be_zero
- end
- end
-
- describe '#run' do
- it 'runs the transaction' do
- allow(transaction).to receive(:profile_lines).and_yield
-
- retval = transaction.run { 'cats are amazing' }
-
- expect(retval).to eq('cats are amazing')
- end
- end
-
- describe '#duration' do
- it 'returns the duration in seconds' do
- start_time = Time.now
-
- allow(transaction).to receive(:started_at).and_return(start_time)
- allow(transaction).to receive(:finished_at).and_return(start_time + 5)
-
- expect(transaction.duration).to be_within(0.1).of(5.0)
- end
- end
-
- describe '#query_duration' do
- it 'returns the total query duration in seconds' do
- time = Time.now
- query1 = Gitlab::Sherlock::Query.new('SELECT 1', time, time + 5)
- query2 = Gitlab::Sherlock::Query.new('SELECT 2', time, time + 2)
-
- transaction.queries << query1
- transaction.queries << query2
-
- expect(transaction.query_duration).to be_within(0.1).of(7.0)
- end
- end
-
- describe '#to_param' do
- it 'returns the transaction ID' do
- expect(transaction.to_param).to eq(transaction.id)
- end
- end
-
- describe '#sorted_queries' do
- it 'returns the queries in descending order' do
- start_time = Time.now
-
- query1 = Gitlab::Sherlock::Query.new('SELECT 1', start_time, start_time)
-
- query2 = Gitlab::Sherlock::Query
- .new('SELECT 2', start_time, start_time + 5)
-
- transaction.queries << query1
- transaction.queries << query2
-
- expect(transaction.sorted_queries).to eq([query2, query1])
- end
- end
-
- describe '#sorted_file_samples' do
- it 'returns the file samples in descending order' do
- sample1 = Gitlab::Sherlock::FileSample.new(__FILE__, [], 10.0, 1)
- sample2 = Gitlab::Sherlock::FileSample.new(__FILE__, [], 15.0, 1)
-
- transaction.file_samples << sample1
- transaction.file_samples << sample2
-
- expect(transaction.sorted_file_samples).to eq([sample2, sample1])
- end
- end
-
- describe '#find_query' do
- it 'returns a Query when found' do
- query = Gitlab::Sherlock::Query.new('SELECT 1', Time.now, Time.now)
-
- transaction.queries << query
-
- expect(transaction.find_query(query.id)).to eq(query)
- end
-
- it 'returns nil when no query could be found' do
- expect(transaction.find_query('cats')).to be_nil
- end
- end
-
- describe '#find_file_sample' do
- it 'returns a FileSample when found' do
- sample = Gitlab::Sherlock::FileSample.new(__FILE__, [], 10.0, 1)
-
- transaction.file_samples << sample
-
- expect(transaction.find_file_sample(sample.id)).to eq(sample)
- end
-
- it 'returns nil when no file sample could be found' do
- expect(transaction.find_file_sample('cats')).to be_nil
- end
- end
-
- describe '#profile_lines' do
- describe 'when line profiling is enabled' do
- it 'yields the block using the line profiler' do
- allow(Gitlab::Sherlock).to receive(:enable_line_profiler?)
- .and_return(true)
-
- allow_next_instance_of(Gitlab::Sherlock::LineProfiler) do |instance|
- allow(instance).to receive(:profile).and_return('cats are amazing', [])
- end
-
- retval = transaction.profile_lines { 'cats are amazing' }
-
- expect(retval).to eq('cats are amazing')
- end
- end
-
- describe 'when line profiling is disabled' do
- it 'yields the block' do
- allow(Gitlab::Sherlock).to receive(:enable_line_profiler?)
- .and_return(false)
-
- retval = transaction.profile_lines { 'cats are amazing' }
-
- expect(retval).to eq('cats are amazing')
- end
- end
- end
-
- describe '#subscribe_to_active_record' do
- let(:subscription) { transaction.subscribe_to_active_record }
- let(:time) { Time.now }
- let(:query_data) { { sql: 'SELECT 1', binds: [] } }
-
- after do
- ActiveSupport::Notifications.unsubscribe(subscription)
- end
-
- it 'tracks executed queries' do
- expect(transaction).to receive(:track_query)
- .with('SELECT 1', [], time, time)
-
- subscription.publish('test', time, time, nil, query_data)
- end
-
- it 'only tracks queries triggered from the transaction thread' do
- expect(transaction).not_to receive(:track_query)
-
- Thread.new { subscription.publish('test', time, time, nil, query_data) }
- .join
- end
- end
-
- describe '#subscribe_to_action_view' do
- let(:subscription) { transaction.subscribe_to_action_view }
- let(:time) { Time.now }
- let(:view_data) { { identifier: 'foo.rb' } }
-
- after do
- ActiveSupport::Notifications.unsubscribe(subscription)
- end
-
- it 'tracks rendered views' do
- expect(transaction).to receive(:track_view).with('foo.rb')
-
- subscription.publish('test', time, time, nil, view_data)
- end
-
- it 'only tracks views rendered from the transaction thread' do
- expect(transaction).not_to receive(:track_view)
-
- Thread.new { subscription.publish('test', time, time, nil, view_data) }
- .join
- end
- end
-end
diff --git a/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb b/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb
index 2f2499753b9..9affc3d5146 100644
--- a/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb
+++ b/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb
@@ -2,11 +2,11 @@
require 'fast_spec_helper'
-RSpec.describe Gitlab::SidekiqStatus::ClientMiddleware do
+RSpec.describe Gitlab::SidekiqStatus::ClientMiddleware, :clean_gitlab_redis_queues do
describe '#call' do
context 'when the job has status_expiration set' do
- it 'tracks the job in Redis with a value of 2' do
- expect(Gitlab::SidekiqStatus).to receive(:set).with('123', 1.hour.to_i, value: 2)
+ it 'tracks the job in Redis' do
+ expect(Gitlab::SidekiqStatus).to receive(:set).with('123', 1.hour.to_i)
described_class.new
.call('Foo', { 'jid' => '123', 'status_expiration' => 1.hour.to_i }, double(:queue), double(:pool)) { nil }
@@ -14,8 +14,8 @@ RSpec.describe Gitlab::SidekiqStatus::ClientMiddleware do
end
context 'when the job does not have status_expiration set' do
- it 'tracks the job in Redis with a value of 1' do
- expect(Gitlab::SidekiqStatus).to receive(:set).with('123', Gitlab::SidekiqStatus::DEFAULT_EXPIRATION, value: 1)
+ it 'does not track the job in Redis' do
+ expect(Gitlab::SidekiqStatus).to receive(:set).with('123', nil)
described_class.new
.call('Foo', { 'jid' => '123' }, double(:queue), double(:pool)) { nil }
diff --git a/spec/lib/gitlab/sidekiq_status_spec.rb b/spec/lib/gitlab/sidekiq_status_spec.rb
index 1e7b52471b0..c94deb8e008 100644
--- a/spec/lib/gitlab/sidekiq_status_spec.rb
+++ b/spec/lib/gitlab/sidekiq_status_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe Gitlab::SidekiqStatus, :clean_gitlab_redis_queues, :clean_gitlab_
Sidekiq.redis do |redis|
expect(redis.exists(key)).to eq(true)
expect(redis.ttl(key) > 0).to eq(true)
- expect(redis.get(key)).to eq(described_class::DEFAULT_VALUE.to_s)
+ expect(redis.get(key)).to eq('1')
end
end
@@ -24,19 +24,17 @@ RSpec.describe Gitlab::SidekiqStatus, :clean_gitlab_redis_queues, :clean_gitlab_
Sidekiq.redis do |redis|
expect(redis.exists(key)).to eq(true)
expect(redis.ttl(key) > described_class::DEFAULT_EXPIRATION).to eq(true)
- expect(redis.get(key)).to eq(described_class::DEFAULT_VALUE.to_s)
+ expect(redis.get(key)).to eq('1')
end
end
- it 'allows overriding the default value' do
- described_class.set('123', value: 2)
+ it 'does not store anything with a nil expiry' do
+ described_class.set('123', nil)
key = described_class.key_for('123')
Sidekiq.redis do |redis|
- expect(redis.exists(key)).to eq(true)
- expect(redis.ttl(key) > 0).to eq(true)
- expect(redis.get(key)).to eq('2')
+ expect(redis.exists(key)).to eq(false)
end
end
end
@@ -138,33 +136,5 @@ RSpec.describe Gitlab::SidekiqStatus, :clean_gitlab_redis_queues, :clean_gitlab_
it 'handles an empty array' do
expect(described_class.job_status([])).to eq([])
end
-
- context 'when log_implicit_sidekiq_status_calls is enabled' do
- it 'logs keys that contained the default value' do
- described_class.set('123', value: 2)
- described_class.set('456')
- described_class.set('012')
-
- expect(Sidekiq.logger).to receive(:info).with(message: described_class::DEFAULT_VALUE_MESSAGE,
- keys: [described_class.key_for('456'), described_class.key_for('012')])
-
- expect(described_class.job_status(%w(123 456 789 012))).to eq([true, true, false, true])
- end
- end
-
- context 'when log_implicit_sidekiq_status_calls is disabled' do
- before do
- stub_feature_flags(log_implicit_sidekiq_status_calls: false)
- end
-
- it 'does not perform any logging' do
- described_class.set('123', value: 2)
- described_class.set('456')
-
- expect(Sidekiq.logger).not_to receive(:info)
-
- expect(described_class.job_status(%w(123 456 789))).to eq([true, true, false])
- end
- end
end
end
diff --git a/spec/lib/gitlab/sourcegraph_spec.rb b/spec/lib/gitlab/sourcegraph_spec.rb
index 6bebd1ca3e6..e2c1e959cbf 100644
--- a/spec/lib/gitlab/sourcegraph_spec.rb
+++ b/spec/lib/gitlab/sourcegraph_spec.rb
@@ -37,6 +37,12 @@ RSpec.describe Gitlab::Sourcegraph do
it { is_expected.to be_truthy }
end
+
+ context 'when feature is disabled' do
+ let(:feature_scope) { false }
+
+ it { is_expected.to be_falsey }
+ end
end
describe '.feature_enabled?' do
diff --git a/spec/lib/gitlab/ssh_public_key_spec.rb b/spec/lib/gitlab/ssh_public_key_spec.rb
index e1a588a4b7d..38486b313cb 100644
--- a/spec/lib/gitlab/ssh_public_key_spec.rb
+++ b/spec/lib/gitlab/ssh_public_key_spec.rb
@@ -21,6 +21,14 @@ RSpec.describe Gitlab::SSHPublicKey, lib: true do
end
end
+ describe '.supported_types' do
+ it 'returns array with the names of supported technologies' do
+ expect(described_class.supported_types).to eq(
+ [:rsa, :dsa, :ecdsa, :ed25519]
+ )
+ end
+ end
+
describe '.supported_sizes(name)' do
where(:name, :sizes) do
[
@@ -31,14 +39,43 @@ RSpec.describe Gitlab::SSHPublicKey, lib: true do
]
end
- subject { described_class.supported_sizes(name) }
-
with_them do
it { expect(described_class.supported_sizes(name)).to eq(sizes) }
it { expect(described_class.supported_sizes(name.to_s)).to eq(sizes) }
end
end
+ describe '.supported_algorithms' do
+ it 'returns all supported algorithms' do
+ expect(described_class.supported_algorithms).to eq(
+ %w(
+ ssh-rsa
+ ssh-dss
+ ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521
+ ssh-ed25519
+ )
+ )
+ end
+ end
+
+ describe '.supported_algorithms_for_name' do
+ where(:name, :algorithms) do
+ [
+ [:rsa, %w(ssh-rsa)],
+ [:dsa, %w(ssh-dss)],
+ [:ecdsa, %w(ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521)],
+ [:ed25519, %w(ssh-ed25519)]
+ ]
+ end
+
+ with_them do
+ it "returns all supported algorithms for #{params[:name]}" do
+ expect(described_class.supported_algorithms_for_name(name)).to eq(algorithms)
+ expect(described_class.supported_algorithms_for_name(name.to_s)).to eq(algorithms)
+ end
+ end
+ end
+
describe '.sanitize(key_content)' do
let(:content) { build(:key).key }
diff --git a/spec/lib/gitlab/themes_spec.rb b/spec/lib/gitlab/themes_spec.rb
index 6d03cf496b8..c9dc23d7c14 100644
--- a/spec/lib/gitlab/themes_spec.rb
+++ b/spec/lib/gitlab/themes_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe Gitlab::Themes, lib: true do
it 'prevents an infinite loop when configuration default is invalid' do
default = described_class::APPLICATION_DEFAULT
- themes = described_class::THEMES
+ themes = described_class.available_themes
config = double(default_theme: 0).as_null_object
allow(Gitlab).to receive(:config).and_return(config)
diff --git a/spec/lib/gitlab/tracking/standard_context_spec.rb b/spec/lib/gitlab/tracking/standard_context_spec.rb
index 7d678db5ec8..c88b0af30f6 100644
--- a/spec/lib/gitlab/tracking/standard_context_spec.rb
+++ b/spec/lib/gitlab/tracking/standard_context_spec.rb
@@ -58,6 +58,10 @@ RSpec.describe Gitlab::Tracking::StandardContext do
expect(snowplow_context.to_json.dig(:data, :source)).to eq(described_class::GITLAB_RAILS_SOURCE)
end
+ it 'contains context_generated_at timestamp', :freeze_time do
+ expect(snowplow_context.to_json.dig(:data, :context_generated_at)).to eq(Time.current)
+ end
+
context 'plan' do
context 'when namespace is not available' do
it 'is nil' do
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 0a32bdb95d3..4d84423cde4 100644
--- a/spec/lib/gitlab/usage/metrics/instrumentations/database_metric_spec.rb
+++ b/spec/lib/gitlab/usage/metrics/instrumentations/database_metric_spec.rb
@@ -19,7 +19,7 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
let_it_be(:issues) { Issue.all }
before do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false)
+ allow(Issue.connection).to receive(:transaction_open?).and_return(false)
end
it 'calculates a correct result' do
@@ -82,7 +82,7 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
end.new(time_frame: 'all')
end
- it 'calculates a correct result' do
+ it 'calculates a correct result', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/349762' do
expect(subject.value).to be_within(Gitlab::Database::PostgresHll::BatchDistinctCounter::ERROR_RATE).percent_of(3)
end
diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/generic_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/generic_metric_spec.rb
index c8cb1bb4373..cc4df696b37 100644
--- a/spec/lib/gitlab/usage/metrics/instrumentations/generic_metric_spec.rb
+++ b/spec/lib/gitlab/usage/metrics/instrumentations/generic_metric_spec.rb
@@ -17,9 +17,25 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::GenericMetric do
end
context 'when raising an exception' do
- it 'return the custom fallback' do
+ before do
+ allow(Gitlab::ErrorTracking).to receive(:should_raise_for_dev?).and_return(should_raise_for_dev)
expect(ApplicationRecord.database).to receive(:version).and_raise('Error')
- expect(subject.value).to eq(custom_fallback)
+ end
+
+ context 'with should_raise_for_dev? false' do
+ let(:should_raise_for_dev) { false }
+
+ it 'return the custom fallback' do
+ expect(subject.value).to eq(custom_fallback)
+ end
+ end
+
+ context 'with should_raise_for_dev? true' do
+ let(:should_raise_for_dev) { true }
+
+ it 'raises an error' do
+ expect { subject.value }.to raise_error('Error')
+ end
end
end
end
@@ -38,9 +54,25 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::GenericMetric do
end
context 'when raising an exception' do
- it 'return the default fallback' do
+ before do
+ allow(Gitlab::ErrorTracking).to receive(:should_raise_for_dev?).and_return(should_raise_for_dev)
expect(ApplicationRecord.database).to receive(:version).and_raise('Error')
- expect(subject.value).to eq(described_class::FALLBACK)
+ end
+
+ context 'with should_raise_for_dev? false' do
+ let(:should_raise_for_dev) { false }
+
+ it 'return the default fallback' do
+ expect(subject.value).to eq(described_class::FALLBACK)
+ end
+ end
+
+ context 'with should_raise_for_dev? true' do
+ let(:should_raise_for_dev) { true }
+
+ it 'raises an error' do
+ expect { subject.value }.to raise_error('Error')
+ end
end
end
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 0ec805714e3..f7ff68af8a2 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
@@ -48,7 +48,8 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
'epic_boards_usage',
'secure',
'importer',
- 'network_policies'
+ 'network_policies',
+ 'geo'
)
end
end
diff --git a/spec/lib/gitlab/usage_data_counters/package_event_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/package_event_counter_spec.rb
index 6f201b43390..1ac344d9250 100644
--- a/spec/lib/gitlab/usage_data_counters/package_event_counter_spec.rb
+++ b/spec/lib/gitlab/usage_data_counters/package_event_counter_spec.rb
@@ -13,10 +13,6 @@ RSpec.describe Gitlab::UsageDataCounters::PackageEventCounter, :clean_gitlab_red
end
end
- it 'includes the right events' do
- expect(described_class::KNOWN_EVENTS.size).to eq 63
- end
-
described_class::KNOWN_EVENTS.each do |event|
it_behaves_like 'usage counter with totals', event
end
@@ -24,8 +20,8 @@ RSpec.describe Gitlab::UsageDataCounters::PackageEventCounter, :clean_gitlab_red
describe '.fetch_supported_event' do
subject { described_class.fetch_supported_event(event_name) }
- let(:event_name) { 'package_events_i_package_composer_push_package' }
+ let(:event_name) { 'package_events_i_package_conan_push_package' }
- it { is_expected.to eq 'i_package_composer_push_package' }
+ it { is_expected.to eq 'i_package_conan_push_package' }
end
end
diff --git a/spec/lib/gitlab/usage_data_queries_spec.rb b/spec/lib/gitlab/usage_data_queries_spec.rb
index 64eff76a9f2..a8cf87d9364 100644
--- a/spec/lib/gitlab/usage_data_queries_spec.rb
+++ b/spec/lib/gitlab/usage_data_queries_spec.rb
@@ -3,10 +3,6 @@
require 'spec_helper'
RSpec.describe Gitlab::UsageDataQueries do
- before do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false)
- end
-
describe '#add_metric' do
let(:metric) { 'CountBoardsMetric' }
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 015ecd1671e..427e8e67090 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -9,6 +9,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
stub_usage_data_connections
stub_object_store_settings
clear_memoized_values(described_class::CE_MEMOIZED_VALUES)
+ stub_database_flavor_check('Cloud SQL for PostgreSQL')
end
describe '.uncached_data' do
@@ -160,7 +161,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
another_project = create(:project, :repository, creator: another_user)
create(:remote_mirror, project: another_project, enabled: false)
create(:snippet, author: user)
- create(:suggestion, note: create(:note, project: project))
end
expect(described_class.usage_activity_by_stage_create({})).to include(
@@ -170,8 +170,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
projects_with_disable_overriding_approvers_per_merge_request: 2,
projects_without_disable_overriding_approvers_per_merge_request: 6,
remote_mirrors: 2,
- snippets: 2,
- suggestions: 2
+ snippets: 2
)
expect(described_class.usage_activity_by_stage_create(described_class.monthly_time_range_db_params)).to include(
deploy_keys: 1,
@@ -180,8 +179,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
projects_with_disable_overriding_approvers_per_merge_request: 1,
projects_without_disable_overriding_approvers_per_merge_request: 3,
remote_mirrors: 1,
- snippets: 1,
- suggestions: 1
+ snippets: 1
)
end
end
@@ -278,8 +276,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
expect(described_class.usage_activity_by_stage_manage({})).to include(
{
bulk_imports: {
- gitlab_v1: 2,
- gitlab: Gitlab::UsageData::DEPRECATED_VALUE
+ gitlab_v1: 2
},
project_imports: {
bitbucket: 2,
@@ -302,32 +299,13 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
group_imports: {
group_import: 2,
gitlab_migration: 2
- },
- projects_imported: {
- total: Gitlab::UsageData::DEPRECATED_VALUE,
- gitlab_project: Gitlab::UsageData::DEPRECATED_VALUE,
- gitlab: Gitlab::UsageData::DEPRECATED_VALUE,
- github: Gitlab::UsageData::DEPRECATED_VALUE,
- bitbucket: Gitlab::UsageData::DEPRECATED_VALUE,
- bitbucket_server: Gitlab::UsageData::DEPRECATED_VALUE,
- gitea: Gitlab::UsageData::DEPRECATED_VALUE,
- git: Gitlab::UsageData::DEPRECATED_VALUE,
- manifest: Gitlab::UsageData::DEPRECATED_VALUE
- },
- issues_imported: {
- jira: Gitlab::UsageData::DEPRECATED_VALUE,
- fogbugz: Gitlab::UsageData::DEPRECATED_VALUE,
- phabricator: Gitlab::UsageData::DEPRECATED_VALUE,
- csv: Gitlab::UsageData::DEPRECATED_VALUE
- },
- groups_imported: Gitlab::UsageData::DEPRECATED_VALUE
+ }
}
)
expect(described_class.usage_activity_by_stage_manage(described_class.monthly_time_range_db_params)).to include(
{
bulk_imports: {
- gitlab_v1: 1,
- gitlab: Gitlab::UsageData::DEPRECATED_VALUE
+ gitlab_v1: 1
},
project_imports: {
bitbucket: 1,
@@ -350,25 +328,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
group_imports: {
group_import: 1,
gitlab_migration: 1
- },
- projects_imported: {
- total: Gitlab::UsageData::DEPRECATED_VALUE,
- gitlab_project: Gitlab::UsageData::DEPRECATED_VALUE,
- gitlab: Gitlab::UsageData::DEPRECATED_VALUE,
- github: Gitlab::UsageData::DEPRECATED_VALUE,
- bitbucket: Gitlab::UsageData::DEPRECATED_VALUE,
- bitbucket_server: Gitlab::UsageData::DEPRECATED_VALUE,
- gitea: Gitlab::UsageData::DEPRECATED_VALUE,
- git: Gitlab::UsageData::DEPRECATED_VALUE,
- manifest: Gitlab::UsageData::DEPRECATED_VALUE
- },
- issues_imported: {
- jira: Gitlab::UsageData::DEPRECATED_VALUE,
- fogbugz: Gitlab::UsageData::DEPRECATED_VALUE,
- phabricator: Gitlab::UsageData::DEPRECATED_VALUE,
- csv: Gitlab::UsageData::DEPRECATED_VALUE
- },
- groups_imported: Gitlab::UsageData::DEPRECATED_VALUE
+ }
}
)
end
@@ -920,6 +880,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
expect(subject[:database][:adapter]).to eq(ApplicationRecord.database.adapter_name)
expect(subject[:database][:version]).to eq(ApplicationRecord.database.version)
expect(subject[:database][:pg_system_id]).to eq(ApplicationRecord.database.system_id)
+ expect(subject[:database][:flavor]).to eq('Cloud SQL for PostgreSQL')
expect(subject[:mail][:smtp_server]).to eq(ActionMailer::Base.smtp_settings[:address])
expect(subject[:gitaly][:version]).to be_present
expect(subject[:gitaly][:servers]).to be >= 1
@@ -964,10 +925,25 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
end
context 'when retrieve component setting meets exception' do
- it 'returns -1 for component enable status' do
+ before do
+ allow(Gitlab::ErrorTracking).to receive(:should_raise_for_dev?).and_return(should_raise_for_dev)
allow(Settings).to receive(:[]).with(component).and_raise(StandardError)
+ end
+
+ context 'with should_raise_for_dev? false' do
+ let(:should_raise_for_dev) { false }
+
+ it 'returns -1 for component enable status' do
+ expect(subject).to eq({ enabled: -1 })
+ end
+ end
+
+ context 'with should_raise_for_dev? true' do
+ let(:should_raise_for_dev) { true }
- expect(subject).to eq({ enabled: -1 })
+ it 'raises an error' do
+ expect { subject.value }.to raise_error(StandardError)
+ end
end
end
end
@@ -1328,6 +1304,8 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
let(:categories) { ::Gitlab::UsageDataCounters::HLLRedisCounter.categories }
+ let(:ignored_metrics) { ["i_package_composer_deploy_token_weekly"] }
+
it 'has all known_events' do
expect(subject).to have_key(:redis_hll_counters)
@@ -1337,6 +1315,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
keys = ::Gitlab::UsageDataCounters::HLLRedisCounter.events_for_category(category)
metrics = keys.map { |key| "#{key}_weekly" } + keys.map { |key| "#{key}_monthly" }
+ metrics -= ignored_metrics
if ::Gitlab::UsageDataCounters::HLLRedisCounter::CATEGORIES_FOR_TOTALS.include?(category)
metrics.append("#{category}_total_unique_counts_weekly", "#{category}_total_unique_counts_monthly")
diff --git a/spec/lib/gitlab/utils/usage_data_spec.rb b/spec/lib/gitlab/utils/usage_data_spec.rb
index 325ace6fbbf..b44c6565538 100644
--- a/spec/lib/gitlab/utils/usage_data_spec.rb
+++ b/spec/lib/gitlab/utils/usage_data_spec.rb
@@ -5,11 +5,13 @@ require 'spec_helper'
RSpec.describe Gitlab::Utils::UsageData do
include Database::DatabaseHelpers
- shared_examples 'failing hardening method' do
+ shared_examples 'failing hardening method' do |raised_exception|
+ let(:exception) { raised_exception || ActiveRecord::StatementInvalid }
+
before do
allow(Gitlab::ErrorTracking).to receive(:should_raise_for_dev?).and_return(should_raise_for_dev)
stub_const("Gitlab::Utils::UsageData::FALLBACK", fallback)
- allow(failing_class).to receive(failing_method).and_raise(ActiveRecord::StatementInvalid)
+ allow(failing_class).to receive(failing_method).and_raise(exception) unless failing_class.nil?
end
context 'with should_raise_for_dev? false' do
@@ -24,7 +26,7 @@ RSpec.describe Gitlab::Utils::UsageData do
let(:should_raise_for_dev) { true }
it 'raises an error' do
- expect { subject }.to raise_error(ActiveRecord::StatementInvalid)
+ expect { subject }.to raise_error(exception)
end
end
end
@@ -366,8 +368,13 @@ RSpec.describe Gitlab::Utils::UsageData do
expect(described_class.add).to eq(0)
end
- it 'returns the fallback value when adding fails' do
- expect(described_class.add(nil, 3)).to eq(-1)
+ context 'when adding fails' do
+ subject { described_class.add(nil, 3) }
+
+ let(:fallback) { -1 }
+ let(:failing_class) { nil }
+
+ it_behaves_like 'failing hardening method', StandardError
end
it 'returns the fallback value one of the arguments is negative' do
@@ -376,8 +383,13 @@ RSpec.describe Gitlab::Utils::UsageData do
end
describe '#alt_usage_data' do
- it 'returns the fallback when it gets an error' do
- expect(described_class.alt_usage_data { raise StandardError } ).to eq(-1)
+ context 'when method fails' do
+ subject { described_class.alt_usage_data { raise StandardError } }
+
+ let(:fallback) { -1 }
+ let(:failing_class) { nil }
+
+ it_behaves_like 'failing hardening method', StandardError
end
it 'returns the evaluated block when give' do
@@ -391,14 +403,22 @@ RSpec.describe Gitlab::Utils::UsageData do
describe '#redis_usage_data' do
context 'with block given' do
- it 'returns the fallback when it gets an error' do
- expect(described_class.redis_usage_data { raise ::Redis::CommandError } ).to eq(-1)
+ context 'when method fails' do
+ subject { described_class.redis_usage_data { raise ::Redis::CommandError } }
+
+ let(:fallback) { -1 }
+ let(:failing_class) { nil }
+
+ it_behaves_like 'failing hardening method', ::Redis::CommandError
end
- it 'returns the fallback when Redis HLL raises any error' do
- stub_const("Gitlab::Utils::UsageData::FALLBACK", 15)
+ context 'when Redis HLL raises any error' do
+ subject { described_class.redis_usage_data { raise Gitlab::UsageDataCounters::HLLRedisCounter::CategoryMismatch } }
+
+ let(:fallback) { 15 }
+ let(:failing_class) { nil }
- expect(described_class.redis_usage_data { raise Gitlab::UsageDataCounters::HLLRedisCounter::CategoryMismatch } ).to eq(15)
+ it_behaves_like 'failing hardening method', Gitlab::UsageDataCounters::HLLRedisCounter::CategoryMismatch
end
it 'returns the evaluated block when given' do
@@ -407,9 +427,14 @@ RSpec.describe Gitlab::Utils::UsageData do
end
context 'with counter given' do
- it 'returns the falback values for all counter keys when it gets an error' do
- allow(::Gitlab::UsageDataCounters::WikiPageCounter).to receive(:totals).and_raise(::Redis::CommandError)
- expect(described_class.redis_usage_data(::Gitlab::UsageDataCounters::WikiPageCounter)).to eql(::Gitlab::UsageDataCounters::WikiPageCounter.fallback_totals)
+ context 'when gets an error' do
+ subject { described_class.redis_usage_data(::Gitlab::UsageDataCounters::WikiPageCounter) }
+
+ let(:fallback) { ::Gitlab::UsageDataCounters::WikiPageCounter.fallback_totals }
+ let(:failing_class) { ::Gitlab::UsageDataCounters::WikiPageCounter }
+ let(:failing_method) { :totals }
+
+ it_behaves_like 'failing hardening method', ::Redis::CommandError
end
it 'returns the totals when couter is given' do
diff --git a/spec/lib/gitlab/web_hooks/recursion_detection_spec.rb b/spec/lib/gitlab/web_hooks/recursion_detection_spec.rb
new file mode 100644
index 00000000000..45170864967
--- /dev/null
+++ b/spec/lib/gitlab/web_hooks/recursion_detection_spec.rb
@@ -0,0 +1,221 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::WebHooks::RecursionDetection, :clean_gitlab_redis_shared_state, :request_store do
+ let_it_be(:web_hook) { create(:project_hook) }
+
+ let!(:uuid_class) { described_class::UUID }
+
+ describe '.set_from_headers' do
+ let(:old_uuid) { SecureRandom.uuid }
+ let(:rack_headers) { Rack::MockRequest.env_for("/").merge(headers) }
+
+ subject(:set_from_headers) { described_class.set_from_headers(rack_headers) }
+
+ # Note, having a previous `request_uuid` value set before `.set_from_headers` is
+ # called is contrived and should not normally happen. However, testing with this scenario
+ # allows us to assert the ideal outcome if it ever were to happen.
+ before do
+ uuid_class.instance.request_uuid = old_uuid
+ end
+
+ context 'when the detection header is present' do
+ let(:new_uuid) { SecureRandom.uuid }
+
+ let(:headers) do
+ { uuid_class::HEADER => new_uuid }
+ end
+
+ it 'sets the request UUID value from the headers' do
+ set_from_headers
+
+ expect(uuid_class.instance.request_uuid).to eq(new_uuid)
+ end
+ end
+
+ context 'when detection header is not present' do
+ let(:headers) { {} }
+
+ it 'does not set the request UUID' do
+ set_from_headers
+
+ expect(uuid_class.instance.request_uuid).to eq(old_uuid)
+ end
+ end
+ end
+
+ describe '.set_request_uuid' do
+ it 'sets the request UUID value' do
+ new_uuid = SecureRandom.uuid
+
+ described_class.set_request_uuid(new_uuid)
+
+ expect(uuid_class.instance.request_uuid).to eq(new_uuid)
+ end
+ end
+
+ describe '.register!' do
+ let_it_be(:second_web_hook) { create(:project_hook) }
+ let_it_be(:third_web_hook) { create(:project_hook) }
+
+ def cache_key(hook)
+ described_class.send(:cache_key_for_hook, hook)
+ end
+
+ it 'stores IDs in the same cache when a request UUID is set, until the request UUID changes', :aggregate_failures do
+ # Register web_hook and second_web_hook against the same request UUID.
+ uuid_class.instance.request_uuid = SecureRandom.uuid
+ described_class.register!(web_hook)
+ described_class.register!(second_web_hook)
+ first_cache_key = cache_key(web_hook)
+ second_cache_key = cache_key(second_web_hook)
+
+ # Register third_web_hook against a new request UUID.
+ uuid_class.instance.request_uuid = SecureRandom.uuid
+ described_class.register!(third_web_hook)
+ third_cache_key = cache_key(third_web_hook)
+
+ expect(first_cache_key).to eq(second_cache_key)
+ expect(second_cache_key).not_to eq(third_cache_key)
+
+ ::Gitlab::Redis::SharedState.with do |redis|
+ members = redis.smembers(first_cache_key).map(&:to_i)
+ expect(members).to contain_exactly(web_hook.id, second_web_hook.id)
+
+ members = redis.smembers(third_cache_key).map(&:to_i)
+ expect(members).to contain_exactly(third_web_hook.id)
+ end
+ end
+
+ it 'stores IDs in unique caches when no request UUID is present', :aggregate_failures do
+ described_class.register!(web_hook)
+ described_class.register!(second_web_hook)
+ described_class.register!(third_web_hook)
+
+ first_cache_key = cache_key(web_hook)
+ second_cache_key = cache_key(second_web_hook)
+ third_cache_key = cache_key(third_web_hook)
+
+ expect([first_cache_key, second_cache_key, third_cache_key].compact.length).to eq(3)
+
+ ::Gitlab::Redis::SharedState.with do |redis|
+ members = redis.smembers(first_cache_key).map(&:to_i)
+ expect(members).to contain_exactly(web_hook.id)
+
+ members = redis.smembers(second_cache_key).map(&:to_i)
+ expect(members).to contain_exactly(second_web_hook.id)
+
+ members = redis.smembers(third_cache_key).map(&:to_i)
+ expect(members).to contain_exactly(third_web_hook.id)
+ end
+ end
+
+ it 'touches the storage ttl each time it is called', :aggregate_failures do
+ freeze_time do
+ described_class.register!(web_hook)
+
+ ::Gitlab::Redis::SharedState.with do |redis|
+ expect(redis.ttl(cache_key(web_hook))).to eq(described_class::TOUCH_CACHE_TTL.to_i)
+ end
+ end
+
+ travel_to(1.minute.from_now) do
+ described_class.register!(second_web_hook)
+
+ ::Gitlab::Redis::SharedState.with do |redis|
+ expect(redis.ttl(cache_key(web_hook))).to eq(described_class::TOUCH_CACHE_TTL.to_i)
+ end
+ end
+ end
+ end
+
+ describe 'block?' do
+ let_it_be(:registered_web_hooks) { create_list(:project_hook, 2) }
+
+ subject(:block?) { described_class.block?(web_hook) }
+
+ before do
+ # Register some previous webhooks.
+ uuid_class.instance.request_uuid = SecureRandom.uuid
+
+ registered_web_hooks.each do |web_hook|
+ described_class.register!(web_hook)
+ end
+ end
+
+ it 'returns false if webhook should not be blocked' do
+ is_expected.to eq(false)
+ end
+
+ context 'when the webhook has previously fired' do
+ before do
+ described_class.register!(web_hook)
+ end
+
+ it 'returns true' do
+ is_expected.to eq(true)
+ end
+
+ context 'when the request UUID changes again' do
+ before do
+ uuid_class.instance.request_uuid = SecureRandom.uuid
+ end
+
+ it 'returns false' do
+ is_expected.to eq(false)
+ end
+ end
+ end
+
+ context 'when the count limit has been reached' do
+ let_it_be(:registered_web_hooks) { create_list(:project_hook, 2) }
+
+ before do
+ registered_web_hooks.each do |web_hook|
+ described_class.register!(web_hook)
+ end
+
+ stub_const("#{described_class.name}::COUNT_LIMIT", registered_web_hooks.size)
+ end
+
+ it 'returns true' do
+ is_expected.to eq(true)
+ end
+
+ context 'when the request UUID changes again' do
+ before do
+ uuid_class.instance.request_uuid = SecureRandom.uuid
+ end
+
+ it 'returns false' do
+ is_expected.to eq(false)
+ end
+ end
+ end
+ end
+
+ describe '.header' do
+ subject(:header) { described_class.header(web_hook) }
+
+ it 'returns a header with the UUID value' do
+ uuid = SecureRandom.uuid
+ allow(uuid_class.instance).to receive(:uuid_for_hook).and_return(uuid)
+
+ is_expected.to eq({ uuid_class::HEADER => uuid })
+ end
+ end
+
+ describe '.to_log' do
+ subject(:to_log) { described_class.to_log(web_hook) }
+
+ it 'returns the UUID value and all registered webhook IDs in a Hash' do
+ uuid = SecureRandom.uuid
+ allow(uuid_class.instance).to receive(:uuid_for_hook).and_return(uuid)
+ registered_web_hooks = create_list(:project_hook, 2)
+ registered_web_hooks.each { described_class.register!(_1) }
+
+ is_expected.to eq({ uuid: uuid, ids: registered_web_hooks.map(&:id) })
+ end
+ end
+end
diff --git a/spec/lib/gitlab_edition_spec.rb b/spec/lib/gitlab_edition_spec.rb
new file mode 100644
index 00000000000..2f1316819ec
--- /dev/null
+++ b/spec/lib/gitlab_edition_spec.rb
@@ -0,0 +1,160 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabEdition do
+ before do
+ # Make sure the ENV is clean
+ stub_env('FOSS_ONLY', nil)
+ stub_env('EE_ONLY', nil)
+
+ described_class.instance_variable_set(:@is_ee, nil)
+ described_class.instance_variable_set(:@is_jh, nil)
+ end
+
+ after do
+ described_class.instance_variable_set(:@is_ee, nil)
+ described_class.instance_variable_set(:@is_jh, nil)
+ end
+
+ describe '.root' do
+ it 'returns the root path of the app' do
+ expect(described_class.root).to eq(Pathname.new(File.expand_path('../..', __dir__)))
+ end
+ end
+
+ describe 'extensions' do
+ context 'when .jh? is true' do
+ before do
+ allow(described_class).to receive(:jh?).and_return(true)
+ end
+
+ it 'returns %w[ee jh]' do
+ expect(described_class.extensions).to match_array(%w[ee jh])
+ end
+ end
+
+ context 'when .ee? is true' do
+ before do
+ allow(described_class).to receive(:jh?).and_return(false)
+ allow(described_class).to receive(:ee?).and_return(true)
+ end
+
+ it 'returns %w[ee]' do
+ expect(described_class.extensions).to match_array(%w[ee])
+ end
+ end
+
+ context 'when neither .jh? and .ee? are true' do
+ before do
+ allow(described_class).to receive(:jh?).and_return(false)
+ allow(described_class).to receive(:ee?).and_return(false)
+ end
+
+ it 'returns the exyensions according to the current edition' do
+ expect(described_class.extensions).to be_empty
+ end
+ end
+ end
+
+ describe '.ee? and .jh?' do
+ def stub_path(*paths, **arguments)
+ root = Pathname.new('dummy')
+ pathname = double(:path, **arguments)
+
+ allow(described_class)
+ .to receive(:root)
+ .and_return(root)
+
+ allow(root).to receive(:join)
+
+ paths.each do |path|
+ allow(root)
+ .to receive(:join)
+ .with(path)
+ .and_return(pathname)
+ end
+ end
+
+ describe '.ee?' do
+ context 'for EE' do
+ before do
+ stub_path('ee/app/models/license.rb', exist?: true)
+ end
+
+ context 'when using FOSS_ONLY=1' do
+ before do
+ stub_env('FOSS_ONLY', '1')
+ end
+
+ it 'returns not to be EE' do
+ expect(described_class).not_to be_ee
+ end
+ end
+
+ context 'when using FOSS_ONLY=0' do
+ before do
+ stub_env('FOSS_ONLY', '0')
+ end
+
+ it 'returns to be EE' do
+ expect(described_class).to be_ee
+ end
+ end
+
+ context 'when using default FOSS_ONLY' do
+ it 'returns to be EE' do
+ expect(described_class).to be_ee
+ end
+ end
+ end
+
+ context 'for CE' do
+ before do
+ stub_path('ee/app/models/license.rb', exist?: false)
+ end
+
+ it 'returns not to be EE' do
+ expect(described_class).not_to be_ee
+ end
+ end
+ end
+
+ describe '.jh?' do
+ context 'for JH' do
+ before do
+ stub_path(
+ 'ee/app/models/license.rb',
+ 'jh',
+ exist?: true)
+ end
+
+ context 'when using default FOSS_ONLY and EE_ONLY' do
+ it 'returns to be JH' do
+ expect(described_class).to be_jh
+ end
+ end
+
+ context 'when using FOSS_ONLY=1' do
+ before do
+ stub_env('FOSS_ONLY', '1')
+ end
+
+ it 'returns not to be JH' do
+ expect(described_class).not_to be_jh
+ end
+ end
+
+ context 'when using EE_ONLY=1' do
+ before do
+ stub_env('EE_ONLY', '1')
+ end
+
+ it 'returns not to be JH' do
+ expect(described_class).not_to be_jh
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab_spec.rb b/spec/lib/gitlab_spec.rb
index 869eaf26772..49ba4debe31 100644
--- a/spec/lib/gitlab_spec.rb
+++ b/spec/lib/gitlab_spec.rb
@@ -3,9 +3,19 @@
require 'spec_helper'
RSpec.describe Gitlab do
- describe '.root' do
- it 'returns the root path of the app' do
- expect(described_class.root).to eq(Pathname.new(File.expand_path('../..', __dir__)))
+ %w[root extensions ee? jh?].each do |method_name|
+ it "delegates #{method_name} to GitlabEdition" do
+ expect(GitlabEdition).to receive(method_name)
+
+ described_class.public_send(method_name)
+ end
+ end
+
+ %w[ee jh].each do |method_name|
+ it "delegates #{method_name} to GitlabEdition" do
+ expect(GitlabEdition).to receive(method_name)
+
+ described_class.public_send(method_name) {}
end
end
@@ -248,121 +258,6 @@ RSpec.describe Gitlab do
end
end
- describe 'ee? and jh?' do
- before do
- # Make sure the ENV is clean
- stub_env('FOSS_ONLY', nil)
- stub_env('EE_ONLY', nil)
-
- described_class.instance_variable_set(:@is_ee, nil)
- described_class.instance_variable_set(:@is_jh, nil)
- end
-
- after do
- described_class.instance_variable_set(:@is_ee, nil)
- described_class.instance_variable_set(:@is_jh, nil)
- end
-
- def stub_path(*paths, **arguments)
- root = Pathname.new('dummy')
- pathname = double(:path, **arguments)
-
- allow(described_class)
- .to receive(:root)
- .and_return(root)
-
- allow(root).to receive(:join)
-
- paths.each do |path|
- allow(root)
- .to receive(:join)
- .with(path)
- .and_return(pathname)
- end
- end
-
- describe '.ee?' do
- context 'for EE' do
- before do
- stub_path('ee/app/models/license.rb', exist?: true)
- end
-
- context 'when using FOSS_ONLY=1' do
- before do
- stub_env('FOSS_ONLY', '1')
- end
-
- it 'returns not to be EE' do
- expect(described_class).not_to be_ee
- end
- end
-
- context 'when using FOSS_ONLY=0' do
- before do
- stub_env('FOSS_ONLY', '0')
- end
-
- it 'returns to be EE' do
- expect(described_class).to be_ee
- end
- end
-
- context 'when using default FOSS_ONLY' do
- it 'returns to be EE' do
- expect(described_class).to be_ee
- end
- end
- end
-
- context 'for CE' do
- before do
- stub_path('ee/app/models/license.rb', exist?: false)
- end
-
- it 'returns not to be EE' do
- expect(described_class).not_to be_ee
- end
- end
- end
-
- describe '.jh?' do
- context 'for JH' do
- before do
- stub_path(
- 'ee/app/models/license.rb',
- 'jh',
- exist?: true)
- end
-
- context 'when using default FOSS_ONLY and EE_ONLY' do
- it 'returns to be JH' do
- expect(described_class).to be_jh
- end
- end
-
- context 'when using FOSS_ONLY=1' do
- before do
- stub_env('FOSS_ONLY', '1')
- end
-
- it 'returns not to be JH' do
- expect(described_class).not_to be_jh
- end
- end
-
- context 'when using EE_ONLY=1' do
- before do
- stub_env('EE_ONLY', '1')
- end
-
- it 'returns not to be JH' do
- expect(described_class).not_to be_jh
- end
- end
- end
- end
- end
-
describe '.http_proxy_env?' do
it 'returns true when lower case https' do
stub_env('https_proxy', 'https://my.proxy')
diff --git a/spec/lib/sidebars/groups/menus/settings_menu_spec.rb b/spec/lib/sidebars/groups/menus/settings_menu_spec.rb
index 314c4cdc602..252da8ea699 100644
--- a/spec/lib/sidebars/groups/menus/settings_menu_spec.rb
+++ b/spec/lib/sidebars/groups/menus/settings_menu_spec.rb
@@ -56,6 +56,12 @@ RSpec.describe Sidebars::Groups::Menus::SettingsMenu do
it_behaves_like 'access rights checks'
end
+ describe 'Access Tokens' do
+ let(:item_id) { :access_tokens }
+
+ it_behaves_like 'access rights checks'
+ end
+
describe 'Repository menu' do
let(:item_id) { :repository }
diff --git a/spec/lib/sidebars/projects/panel_spec.rb b/spec/lib/sidebars/projects/panel_spec.rb
index 2e79ced7039..7e69a2dfe52 100644
--- a/spec/lib/sidebars/projects/panel_spec.rb
+++ b/spec/lib/sidebars/projects/panel_spec.rb
@@ -3,7 +3,8 @@
require 'spec_helper'
RSpec.describe Sidebars::Projects::Panel do
- let(:project) { build(:project) }
+ let_it_be(:project) { create(:project) }
+
let(:context) { Sidebars::Projects::Context.new(current_user: nil, container: project) }
subject { described_class.new(context) }
diff --git a/spec/lib/version_check_spec.rb b/spec/lib/version_check_spec.rb
index d7a772a3f7e..736a8f9595e 100644
--- a/spec/lib/version_check_spec.rb
+++ b/spec/lib/version_check_spec.rb
@@ -3,12 +3,6 @@
require 'spec_helper'
RSpec.describe VersionCheck do
- describe '.image_url' do
- it 'returns the correct URL' do
- expect(described_class.image_url).to match(%r{\A#{Regexp.escape(described_class.host)}/check\.svg\?gitlab_info=\w+})
- end
- end
-
describe '.url' do
it 'returns the correct URL' do
expect(described_class.url).to match(%r{\A#{Regexp.escape(described_class.host)}/check\.json\?gitlab_info=\w+})
diff --git a/spec/mailers/emails/profile_spec.rb b/spec/mailers/emails/profile_spec.rb
index 365ca892bb1..af77989dbbc 100644
--- a/spec/mailers/emails/profile_spec.rb
+++ b/spec/mailers/emails/profile_spec.rb
@@ -49,7 +49,7 @@ RSpec.describe Emails::Profile do
describe 'for users that signed up, the email' do
let(:example_site_path) { root_path }
- let(:new_user) { create(:user, email: new_user_address, password: "securePassword") }
+ let(:new_user) { create(:user, email: new_user_address, password: Gitlab::Password.test_default) }
subject { Notify.new_user_email(new_user.id) }
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index 44cb18008d2..0fbdc09a206 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -213,7 +213,7 @@ RSpec.describe Notify do
subject { described_class.issue_due_email(recipient.id, issue.id) }
before do
- issue.update(due_date: Date.tomorrow)
+ issue.update!(due_date: Date.tomorrow)
end
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
@@ -1229,7 +1229,7 @@ RSpec.describe Notify do
end
context 'when a comment on an existing discussion' do
- let(:first_note) { create(model) }
+ let(:first_note) { create(model) } # rubocop:disable Rails/SaveBang
let(:note) { create(model, author: note_author, noteable: nil, in_reply_to: first_note) }
it 'contains an introduction' do
@@ -1505,7 +1505,7 @@ RSpec.describe Notify do
context 'member is not created by a user' do
before do
- group_member.update(created_by: nil)
+ group_member.update!(created_by: nil)
end
it_behaves_like 'no email is sent'
@@ -1513,7 +1513,7 @@ RSpec.describe Notify do
context 'member is a known user' do
before do
- group_member.update(user: create(:user))
+ group_member.update!(user: create(:user))
end
it_behaves_like 'no email is sent'
@@ -1737,7 +1737,7 @@ RSpec.describe Notify do
stub_config_setting(email_subject_suffix: 'A Nice Suffix')
perform_enqueued_jobs do
user.email = "new-email@mail.com"
- user.save
+ user.save!
end
end
diff --git a/spec/metrics_server/metrics_server_spec.rb b/spec/metrics_server/metrics_server_spec.rb
index 4e3c6900875..fc18df9b5cd 100644
--- a/spec/metrics_server/metrics_server_spec.rb
+++ b/spec/metrics_server/metrics_server_spec.rb
@@ -8,18 +8,32 @@ 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 }
+
+ # Prometheus::Client is a singleton, i.e. shared global state, so
+ # we need to reset it after testing.
+ let!(:old_multiprocess_files_dir) { prometheus_config.multiprocess_files_dir }
+
before do
# We do not want this to have knock-on effects on the test process.
allow(Gitlab::ProcessManagement).to receive(:modify_signals)
end
+ after do
+ Gitlab::Metrics.reset_registry!
+ prometheus_config.multiprocess_files_dir = old_multiprocess_files_dir
+
+ FileUtils.rm_rf(metrics_dir, secure: true)
+ end
+
describe '.spawn' do
context 'when in parent process' do
it 'forks into a new process and detaches it' do
expect(Process).to receive(:fork).and_return(99)
expect(Process).to receive(:detach).with(99)
- described_class.spawn('sidekiq', metrics_dir: 'path/to/metrics')
+ described_class.spawn('sidekiq', metrics_dir: metrics_dir)
end
end
@@ -35,13 +49,13 @@ RSpec.describe MetricsServer do # rubocop:disable RSpec/FilePath
expect(server).to receive(:start)
end
- described_class.spawn('sidekiq', metrics_dir: 'path/to/metrics')
+ described_class.spawn('sidekiq', metrics_dir: metrics_dir)
end
it 'resets signal handlers from parent process' do
expect(Gitlab::ProcessManagement).to receive(:modify_signals).with(%i[A B], 'DEFAULT')
- described_class.spawn('sidekiq', metrics_dir: 'path/to/metrics', trapped_signals: %i[A B])
+ described_class.spawn('sidekiq', metrics_dir: metrics_dir, trapped_signals: %i[A B])
end
end
end
@@ -49,29 +63,27 @@ RSpec.describe MetricsServer do # rubocop:disable RSpec/FilePath
describe '#start' do
let(:exporter_class) { Class.new(Gitlab::Metrics::Exporter::BaseExporter) }
let(:exporter_double) { double('fake_exporter', start: true) }
- let(:prometheus_config) { ::Prometheus::Client.configuration }
- let(:metrics_dir) { Dir.mktmpdir }
let(:settings) { { "fake_exporter" => { "enabled" => true } } }
- let!(:old_metrics_dir) { prometheus_config.multiprocess_files_dir }
+ let(:ruby_sampler_double) { double(Gitlab::Metrics::Samplers::RubySampler) }
subject(:metrics_server) { described_class.new('fake', metrics_dir, true)}
before do
stub_const('Gitlab::Metrics::Exporter::FakeExporter', exporter_class)
- expect(exporter_class).to receive(:instance).with(settings['fake_exporter'], synchronous: true).and_return(exporter_double)
+ expect(exporter_class).to receive(:instance).with(
+ settings['fake_exporter'], gc_requests: true, synchronous: true
+ ).and_return(exporter_double)
expect(Settings).to receive(:monitoring).and_return(settings)
- end
- after do
- Gitlab::Metrics.reset_registry!
- FileUtils.rm_rf(metrics_dir, secure: true)
- prometheus_config.multiprocess_files_dir = old_metrics_dir
+ allow(Gitlab::Metrics::Samplers::RubySampler).to receive(:initialize_instance).and_return(ruby_sampler_double)
+ allow(ruby_sampler_double).to receive(:start)
end
it 'configures ::Prometheus::Client' do
metrics_server.start
expect(prometheus_config.multiprocess_files_dir).to eq metrics_dir
+ expect(::Prometheus::Client.configuration.pid_provider.call).to eq 'fake_exporter'
end
it 'ensures that metrics directory exists in correct mode (0700)' do
@@ -105,5 +117,11 @@ RSpec.describe MetricsServer do # rubocop:disable RSpec/FilePath
metrics_server.start
end
+
+ it 'starts a RubySampler instance' do
+ expect(ruby_sampler_double).to receive(:start)
+
+ subject.start
+ end
end
end
diff --git a/spec/migrations/20210112143418_remove_duplicate_services2_spec.rb b/spec/migrations/20210112143418_remove_duplicate_services2_spec.rb
deleted file mode 100644
index b8dc4d7c8ae..00000000000
--- a/spec/migrations/20210112143418_remove_duplicate_services2_spec.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe RemoveDuplicateServices2 do
- let_it_be(:namespaces) { table(:namespaces) }
- let_it_be(:projects) { table(:projects) }
- let_it_be(:services) { table(:services) }
-
- describe '#up' do
- before do
- stub_const("#{described_class}::BATCH_SIZE", 2)
-
- namespaces.create!(id: 1, name: 'group', path: 'group')
-
- projects.create!(id: 1, namespace_id: 1) # duplicate services
- projects.create!(id: 2, namespace_id: 1) # normal services
- projects.create!(id: 3, namespace_id: 1) # no services
- projects.create!(id: 4, namespace_id: 1) # duplicate services
- projects.create!(id: 5, namespace_id: 1) # duplicate services
-
- services.create!(id: 1, project_id: 1, type: 'JiraService')
- services.create!(id: 2, project_id: 1, type: 'JiraService')
- services.create!(id: 3, project_id: 2, type: 'JiraService')
- services.create!(id: 4, project_id: 4, type: 'AsanaService')
- services.create!(id: 5, project_id: 4, type: 'AsanaService')
- services.create!(id: 6, project_id: 4, type: 'JiraService')
- services.create!(id: 7, project_id: 4, type: 'JiraService')
- services.create!(id: 8, project_id: 4, type: 'SlackService')
- services.create!(id: 9, project_id: 4, type: 'SlackService')
- services.create!(id: 10, project_id: 5, type: 'JiraService')
- services.create!(id: 11, project_id: 5, type: 'JiraService')
-
- # Services without a project_id should be ignored
- services.create!(id: 12, type: 'JiraService')
- services.create!(id: 13, type: 'JiraService')
- end
-
- it 'schedules background jobs for all projects with duplicate services' do
- Sidekiq::Testing.fake! do
- freeze_time do
- migrate!
-
- expect(BackgroundMigrationWorker.jobs.size).to eq(2)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, 1, 4)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, 5)
- end
- end
- end
- end
-end
diff --git a/spec/migrations/20210119122354_alter_vsa_issue_first_mentioned_in_commit_value_spec.rb b/spec/migrations/20210119122354_alter_vsa_issue_first_mentioned_in_commit_value_spec.rb
deleted file mode 100644
index e07b5a48909..00000000000
--- a/spec/migrations/20210119122354_alter_vsa_issue_first_mentioned_in_commit_value_spec.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe AlterVsaIssueFirstMentionedInCommitValue, schema: 20210114033715 do
- let(:group_stages) { table(:analytics_cycle_analytics_group_stages) }
- let(:value_streams) { table(:analytics_cycle_analytics_group_value_streams) }
- let(:namespaces) { table(:namespaces) }
-
- let(:namespace) { namespaces.create!(id: 1, name: 'group', path: 'group') }
- let(:value_stream) { value_streams.create!(name: 'test', group_id: namespace.id) }
-
- let!(:stage_1) { group_stages.create!(group_value_stream_id: value_stream.id, group_id: namespace.id, name: 'stage 1', start_event_identifier: described_class::ISSUE_FIRST_MENTIONED_IN_COMMIT_EE, end_event_identifier: 1) }
- let!(:stage_2) { group_stages.create!(group_value_stream_id: value_stream.id, group_id: namespace.id, name: 'stage 2', start_event_identifier: 2, end_event_identifier: described_class::ISSUE_FIRST_MENTIONED_IN_COMMIT_EE) }
- let!(:stage_3) { group_stages.create!(group_value_stream_id: value_stream.id, group_id: namespace.id, name: 'stage 3', start_event_identifier: described_class::ISSUE_FIRST_MENTIONED_IN_COMMIT_FOSS, end_event_identifier: 3) }
-
- describe '#up' do
- it 'changes the EE specific identifier values to the FOSS version' do
- migrate!
-
- expect(stage_1.reload.start_event_identifier).to eq(described_class::ISSUE_FIRST_MENTIONED_IN_COMMIT_FOSS)
- expect(stage_2.reload.end_event_identifier).to eq(described_class::ISSUE_FIRST_MENTIONED_IN_COMMIT_FOSS)
- end
-
- it 'does not change irrelevant records' do
- expect { migrate! }.not_to change { stage_3.reload }
- end
- end
-end
diff --git a/spec/migrations/20210205174154_remove_bad_dependency_proxy_manifests_spec.rb b/spec/migrations/20210205174154_remove_bad_dependency_proxy_manifests_spec.rb
deleted file mode 100644
index 97438062458..00000000000
--- a/spec/migrations/20210205174154_remove_bad_dependency_proxy_manifests_spec.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe RemoveBadDependencyProxyManifests, schema: 20210128140157 do
- let_it_be(:namespaces) { table(:namespaces) }
- let_it_be(:dependency_proxy_manifests) { table(:dependency_proxy_manifests) }
- let_it_be(:group) { namespaces.create!(type: 'Group', name: 'test', path: 'test') }
-
- let_it_be(:dependency_proxy_manifest_with_content_type) do
- dependency_proxy_manifests.create!(group_id: group.id, file: 'foo', file_name: 'foo', digest: 'asdf1234', content_type: 'content-type' )
- end
-
- let_it_be(:dependency_proxy_manifest_without_content_type) do
- dependency_proxy_manifests.create!(group_id: group.id, file: 'bar', file_name: 'bar', digest: 'fdsa6789')
- end
-
- it 'removes the dependency_proxy_manifests with a content_type', :aggregate_failures do
- expect(dependency_proxy_manifest_with_content_type).to be_present
- expect(dependency_proxy_manifest_without_content_type).to be_present
-
- expect { migrate! }.to change { dependency_proxy_manifests.count }.from(2).to(1)
-
- expect(dependency_proxy_manifests.where.not(content_type: nil)).to be_empty
- expect(dependency_proxy_manifest_without_content_type.reload).to be_present
- end
-end
diff --git a/spec/migrations/20210210093901_backfill_updated_at_after_repository_storage_move_spec.rb b/spec/migrations/20210210093901_backfill_updated_at_after_repository_storage_move_spec.rb
deleted file mode 100644
index 4a31d36e2bc..00000000000
--- a/spec/migrations/20210210093901_backfill_updated_at_after_repository_storage_move_spec.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe BackfillUpdatedAtAfterRepositoryStorageMove, :sidekiq do
- let_it_be(:projects) { table(:projects) }
- let_it_be(:project_repository_storage_moves) { table(:project_repository_storage_moves) }
- let_it_be(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
-
- describe '#up' do
- it 'schedules background jobs for all distinct projects in batches' do
- stub_const("#{described_class}::BATCH_SIZE", 3)
-
- project_1 = projects.create!(id: 1, namespace_id: namespace.id)
- project_2 = projects.create!(id: 2, namespace_id: namespace.id)
- project_3 = projects.create!(id: 3, namespace_id: namespace.id)
- project_4 = projects.create!(id: 4, namespace_id: namespace.id)
- project_5 = projects.create!(id: 5, namespace_id: namespace.id)
- project_6 = projects.create!(id: 6, namespace_id: namespace.id)
- project_7 = projects.create!(id: 7, namespace_id: namespace.id)
- projects.create!(id: 8, namespace_id: namespace.id)
-
- project_repository_storage_moves.create!(id: 1, project_id: project_1.id, source_storage_name: 'default', destination_storage_name: 'default')
- project_repository_storage_moves.create!(id: 2, project_id: project_1.id, source_storage_name: 'default', destination_storage_name: 'default')
- project_repository_storage_moves.create!(id: 3, project_id: project_2.id, source_storage_name: 'default', destination_storage_name: 'default')
- project_repository_storage_moves.create!(id: 4, project_id: project_3.id, source_storage_name: 'default', destination_storage_name: 'default')
- project_repository_storage_moves.create!(id: 5, project_id: project_3.id, source_storage_name: 'default', destination_storage_name: 'default')
- project_repository_storage_moves.create!(id: 6, project_id: project_4.id, source_storage_name: 'default', destination_storage_name: 'default')
- project_repository_storage_moves.create!(id: 7, project_id: project_4.id, source_storage_name: 'default', destination_storage_name: 'default')
- project_repository_storage_moves.create!(id: 8, project_id: project_5.id, source_storage_name: 'default', destination_storage_name: 'default')
- project_repository_storage_moves.create!(id: 9, project_id: project_6.id, source_storage_name: 'default', destination_storage_name: 'default')
- project_repository_storage_moves.create!(id: 10, project_id: project_7.id, source_storage_name: 'default', destination_storage_name: 'default')
-
- Sidekiq::Testing.fake! do
- freeze_time do
- migrate!
-
- expect(BackgroundMigrationWorker.jobs.size).to eq(3)
- expect(described_class::MIGRATION_CLASS).to be_scheduled_delayed_migration(2.minutes, 1, 2, 3)
- expect(described_class::MIGRATION_CLASS).to be_scheduled_delayed_migration(4.minutes, 4, 5, 6)
- expect(described_class::MIGRATION_CLASS).to be_scheduled_delayed_migration(6.minutes, 7)
- end
- end
- end
- end
-end
diff --git a/spec/migrations/20210218040814_add_environment_scope_to_group_variables_spec.rb b/spec/migrations/20210218040814_add_environment_scope_to_group_variables_spec.rb
deleted file mode 100644
index 039ce53cac4..00000000000
--- a/spec/migrations/20210218040814_add_environment_scope_to_group_variables_spec.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe AddEnvironmentScopeToGroupVariables do
- let(:migration) { described_class.new }
- let(:ci_group_variables) { table(:ci_group_variables) }
- let(:group) { table(:namespaces).create!(name: 'group', path: 'group') }
-
- def create_variable!(group, key:, environment_scope: '*')
- table(:ci_group_variables).create!(
- group_id: group.id,
- key: key,
- environment_scope: environment_scope
- )
- end
-
- describe '#down' do
- context 'group has variables with duplicate keys' do
- it 'deletes all but the first record' do
- migration.up
-
- remaining_variable = create_variable!(group, key: 'key')
- create_variable!(group, key: 'key', environment_scope: 'staging')
- create_variable!(group, key: 'key', environment_scope: 'production')
-
- migration.down
-
- expect(ci_group_variables.pluck(:id)).to eq [remaining_variable.id]
- end
- end
-
- context 'group does not have variables with duplicate keys' do
- it 'does not delete any records' do
- migration.up
-
- create_variable!(group, key: 'key')
- create_variable!(group, key: 'staging')
- create_variable!(group, key: 'production')
-
- expect { migration.down }.not_to change { ci_group_variables.count }
- end
- end
- end
-end
diff --git a/spec/migrations/20210226141517_dedup_issue_metrics_spec.rb b/spec/migrations/20210226141517_dedup_issue_metrics_spec.rb
deleted file mode 100644
index 1b57bf0431f..00000000000
--- a/spec/migrations/20210226141517_dedup_issue_metrics_spec.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe DedupIssueMetrics, :migration, schema: 20210205104425 do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:issues) { table(:issues) }
- let(:metrics) { table(:issue_metrics) }
- let(:issue_params) { { title: 'title', project_id: project.id } }
-
- let!(:namespace) { namespaces.create!(name: 'foo', path: 'foo') }
- let!(:project) { projects.create!(namespace_id: namespace.id) }
- let!(:issue_1) { issues.create!(issue_params) }
- let!(:issue_2) { issues.create!(issue_params) }
- let!(:issue_3) { issues.create!(issue_params) }
-
- let!(:duplicated_metrics_1) { metrics.create!(issue_id: issue_1.id, first_mentioned_in_commit_at: 1.day.ago, first_added_to_board_at: 5.days.ago, updated_at: 2.months.ago) }
- let!(:duplicated_metrics_2) { metrics.create!(issue_id: issue_1.id, first_mentioned_in_commit_at: Time.now, first_associated_with_milestone_at: Time.now, updated_at: 1.month.ago) }
-
- let!(:duplicated_metrics_3) { metrics.create!(issue_id: issue_3.id, first_mentioned_in_commit_at: 1.day.ago, updated_at: 2.months.ago) }
- let!(:duplicated_metrics_4) { metrics.create!(issue_id: issue_3.id, first_added_to_board_at: 1.day.ago, updated_at: 1.month.ago) }
-
- let!(:non_duplicated_metrics) { metrics.create!(issue_id: issue_2.id, first_added_to_board_at: 2.days.ago) }
-
- it 'deduplicates issue_metrics table' do
- expect { migrate! }.to change { metrics.count }.from(5).to(3)
- end
-
- it 'merges `duplicated_metrics_1` with `duplicated_metrics_2`' do
- migrate!
-
- expect(metrics.where(id: duplicated_metrics_1.id)).not_to exist
-
- merged_metrics = metrics.find_by(id: duplicated_metrics_2.id)
-
- expect(merged_metrics).to be_present
- expect(merged_metrics.first_mentioned_in_commit_at).to be_like_time(duplicated_metrics_2.first_mentioned_in_commit_at)
- expect(merged_metrics.first_added_to_board_at).to be_like_time(duplicated_metrics_1.first_added_to_board_at)
- end
-
- it 'merges `duplicated_metrics_3` with `duplicated_metrics_4`' do
- migrate!
-
- expect(metrics.where(id: duplicated_metrics_3.id)).not_to exist
-
- merged_metrics = metrics.find_by(id: duplicated_metrics_4.id)
-
- expect(merged_metrics).to be_present
- expect(merged_metrics.first_mentioned_in_commit_at).to be_like_time(duplicated_metrics_3.first_mentioned_in_commit_at)
- expect(merged_metrics.first_added_to_board_at).to be_like_time(duplicated_metrics_4.first_added_to_board_at)
- end
-
- it 'does not change non duplicated records' do
- expect { migrate! }.not_to change { non_duplicated_metrics.reload.attributes }
- end
-
- it 'does nothing when there are no metrics' do
- metrics.delete_all
-
- migrate!
-
- expect(metrics.count).to eq(0)
- end
-end
diff --git a/spec/migrations/20210918202855_reschedule_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb b/spec/migrations/20210918202855_reschedule_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb
deleted file mode 100644
index 5a2531bb63f..00000000000
--- a/spec/migrations/20210918202855_reschedule_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20210918202855_reschedule_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid.rb')
-
-RSpec.describe ReschedulePendingJobsForRecalculateVulnerabilitiesOccurrencesUuid, :migration do
- let_it_be(:background_migration_jobs) { table(:background_migration_jobs) }
-
- context 'when RecalculateVulnerabilitiesOccurrencesUuid jobs are pending' do
- before do
- background_migration_jobs.create!(
- class_name: 'RecalculateVulnerabilitiesOccurrencesUuid',
- arguments: [1, 2, 3],
- status: Gitlab::Database::BackgroundMigrationJob.statuses['pending']
- )
- background_migration_jobs.create!(
- class_name: 'RecalculateVulnerabilitiesOccurrencesUuid',
- arguments: [4, 5, 6],
- status: Gitlab::Database::BackgroundMigrationJob.statuses['succeeded']
- )
- end
-
- it 'queues pending jobs' do
- migrate!
-
- expect(BackgroundMigrationWorker.jobs.length).to eq(1)
- expect(BackgroundMigrationWorker.jobs[0]['args']).to eq(['RecalculateVulnerabilitiesOccurrencesUuid', [1, 2, 3]])
- expect(BackgroundMigrationWorker.jobs[0]['at']).to be_nil
- end
- end
-end
diff --git a/spec/migrations/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb b/spec/migrations/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb
new file mode 100644
index 00000000000..491aad1b30b
--- /dev/null
+++ b/spec/migrations/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+require 'spec_helper'
+require_migration!
+
+def create_background_migration_jobs(ids, status, created_at)
+ proper_status = case status
+ when :pending
+ Gitlab::Database::BackgroundMigrationJob.statuses['pending']
+ when :succeeded
+ Gitlab::Database::BackgroundMigrationJob.statuses['succeeded']
+ else
+ raise ArgumentError
+ end
+
+ background_migration_jobs.create!(
+ class_name: 'RecalculateVulnerabilitiesOccurrencesUuid',
+ arguments: Array(ids),
+ status: proper_status,
+ created_at: created_at
+ )
+end
+
+RSpec.describe RemoveJobsForRecalculateVulnerabilitiesOccurrencesUuid, :migration do
+ let_it_be(:background_migration_jobs) { table(:background_migration_jobs) }
+
+ context 'when RecalculateVulnerabilitiesOccurrencesUuid jobs are present' do
+ before do
+ create_background_migration_jobs([1, 2, 3], :succeeded, DateTime.new(2021, 5, 5, 0, 2))
+ create_background_migration_jobs([4, 5, 6], :pending, DateTime.new(2021, 5, 5, 0, 4))
+
+ create_background_migration_jobs([1, 2, 3], :succeeded, DateTime.new(2021, 8, 18, 0, 0))
+ create_background_migration_jobs([4, 5, 6], :pending, DateTime.new(2021, 8, 18, 0, 2))
+ create_background_migration_jobs([7, 8, 9], :pending, DateTime.new(2021, 8, 18, 0, 4))
+ end
+
+ it 'removes all jobs' do
+ expect(background_migration_jobs.count).to eq(5)
+
+ migrate!
+
+ expect(background_migration_jobs.count).to eq(0)
+ end
+ end
+end
diff --git a/spec/migrations/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4_spec.rb b/spec/migrations/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4_spec.rb
new file mode 100644
index 00000000000..71ffcafaae1
--- /dev/null
+++ b/spec/migrations/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4_spec.rb
@@ -0,0 +1,148 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleRecalculateUuidOnVulnerabilitiesOccurrences4 do
+ let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
+ let(:users) { table(:users) }
+ let(:user) { create_user! }
+ let(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) }
+ let(:scanners) { table(:vulnerability_scanners) }
+ let(:scanner) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
+ let(:different_scanner) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') }
+ let(:vulnerabilities) { table(:vulnerabilities) }
+ let(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
+ let(:vulnerability_finding_signatures) { table(:vulnerability_finding_signatures) }
+ let(:vulnerability_identifiers) { table(:vulnerability_identifiers) }
+ let(:vulnerability_identifier) do
+ vulnerability_identifiers.create!(
+ project_id: project.id,
+ external_type: 'uuid-v5',
+ external_id: 'uuid-v5',
+ fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
+ name: 'Identifier for UUIDv5')
+ end
+
+ let(:different_vulnerability_identifier) do
+ vulnerability_identifiers.create!(
+ project_id: project.id,
+ external_type: 'uuid-v4',
+ external_id: 'uuid-v4',
+ fingerprint: '772da93d34a1ba010bcb5efa9fb6f8e01bafcc89',
+ name: 'Identifier for UUIDv4')
+ end
+
+ let!(:uuidv4_finding) do
+ create_finding!(
+ vulnerability_id: vulnerability_for_uuidv4.id,
+ project_id: project.id,
+ scanner_id: different_scanner.id,
+ primary_identifier_id: different_vulnerability_identifier.id,
+ location_fingerprint: Gitlab::Database::ShaAttribute.serialize('fa18f432f1d56675f4098d318739c3cd5b14eb3e'),
+ uuid: 'b3cc2518-5446-4dea-871c-89d5e999c1ac'
+ )
+ end
+
+ let(:vulnerability_for_uuidv4) do
+ create_vulnerability!(
+ project_id: project.id,
+ author_id: user.id
+ )
+ end
+
+ let!(:uuidv5_finding) do
+ create_finding!(
+ vulnerability_id: vulnerability_for_uuidv5.id,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ primary_identifier_id: vulnerability_identifier.id,
+ location_fingerprint: Gitlab::Database::ShaAttribute.serialize('838574be0210968bf6b9f569df9c2576242cbf0a'),
+ uuid: '77211ed6-7dff-5f6b-8c9a-da89ad0a9b60'
+ )
+ end
+
+ let(:vulnerability_for_uuidv5) do
+ create_vulnerability!(
+ project_id: project.id,
+ author_id: user.id
+ )
+ end
+
+ let(:vulnerability_for_finding_with_signature) do
+ create_vulnerability!(
+ project_id: project.id,
+ author_id: user.id
+ )
+ end
+
+ let!(:finding_with_signature) do
+ create_finding!(
+ vulnerability_id: vulnerability_for_finding_with_signature.id,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ primary_identifier_id: vulnerability_identifier.id,
+ report_type: 0, # "sast"
+ location_fingerprint: Gitlab::Database::ShaAttribute.serialize('123609eafffffa2207a9ca2425ba4337h34fga1b'),
+ uuid: '252aa474-d689-5d2b-ab42-7bbb5a100c02'
+ )
+ end
+
+ before do
+ stub_const("#{described_class}::BATCH_SIZE", 1)
+ end
+
+ around do |example|
+ freeze_time { Sidekiq::Testing.fake! { example.run } }
+ end
+
+ it 'schedules background migrations', :aggregate_failures do
+ migrate!
+
+ expect(BackgroundMigrationWorker.jobs.size).to eq(3)
+ expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, uuidv4_finding.id, uuidv4_finding.id)
+ expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, uuidv5_finding.id, uuidv5_finding.id)
+ expect(described_class::MIGRATION).to be_scheduled_delayed_migration(6.minutes, finding_with_signature.id, finding_with_signature.id)
+ end
+
+ private
+
+ def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
+ vulnerabilities.create!(
+ project_id: project_id,
+ author_id: author_id,
+ title: title,
+ severity: severity,
+ confidence: confidence,
+ report_type: report_type
+ )
+ end
+
+ def create_finding!(
+ vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:, location_fingerprint:, uuid:, report_type: 0)
+ vulnerabilities_findings.create!(
+ vulnerability_id: vulnerability_id,
+ project_id: project_id,
+ name: 'test',
+ severity: 7,
+ confidence: 7,
+ report_type: report_type,
+ project_fingerprint: '123qweasdzxc',
+ scanner_id: scanner_id,
+ primary_identifier_id: primary_identifier_id,
+ location_fingerprint: location_fingerprint,
+ metadata_version: 'test',
+ raw_metadata: 'test',
+ uuid: uuid
+ )
+ end
+
+ def create_user!(name: "Example User", email: "user@example.com", user_type: nil)
+ users.create!(
+ name: name,
+ email: email,
+ username: name,
+ projects_limit: 0
+ )
+ end
+end
diff --git a/spec/migrations/20211210140629_encrypt_static_object_token_spec.rb b/spec/migrations/20211210140629_encrypt_static_object_token_spec.rb
new file mode 100644
index 00000000000..289cf9a93ed
--- /dev/null
+++ b/spec/migrations/20211210140629_encrypt_static_object_token_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe EncryptStaticObjectToken, :migration do
+ let_it_be(:background_migration_jobs) { table(:background_migration_jobs) }
+ let_it_be(:users) { table(:users) }
+
+ let!(:user_without_tokens) { create_user!(name: 'notoken') }
+ let!(:user_with_plaintext_token_1) { create_user!(name: 'plaintext_1', token: 'token') }
+ let!(:user_with_plaintext_token_2) { create_user!(name: 'plaintext_2', token: 'TOKEN') }
+ let!(:user_with_encrypted_token) { create_user!(name: 'encrypted', encrypted_token: 'encrypted') }
+ let!(:user_with_both_tokens) { create_user!(name: 'both', token: 'token2', encrypted_token: 'encrypted2') }
+
+ before do
+ stub_const("#{described_class}::BATCH_SIZE", 1)
+ end
+
+ around do |example|
+ freeze_time { Sidekiq::Testing.fake! { example.run } }
+ end
+
+ it 'schedules background migrations' do
+ migrate!
+
+ expect(background_migration_jobs.count).to eq(2)
+ expect(background_migration_jobs.first.arguments).to match_array([user_with_plaintext_token_1.id, user_with_plaintext_token_1.id])
+ expect(background_migration_jobs.second.arguments).to match_array([user_with_plaintext_token_2.id, user_with_plaintext_token_2.id])
+
+ expect(BackgroundMigrationWorker.jobs.size).to eq(2)
+ expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, user_with_plaintext_token_1.id, user_with_plaintext_token_1.id)
+ expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, user_with_plaintext_token_2.id, user_with_plaintext_token_2.id)
+ end
+
+ private
+
+ def create_user!(name:, token: nil, encrypted_token: nil)
+ email = "#{name}@example.com"
+
+ table(:users).create!(
+ name: name,
+ email: email,
+ username: name,
+ projects_limit: 0,
+ static_object_token: token,
+ static_object_token_encrypted: encrypted_token
+ )
+ end
+end
diff --git a/spec/migrations/20211214012507_backfill_incident_issue_escalation_statuses_spec.rb b/spec/migrations/20211214012507_backfill_incident_issue_escalation_statuses_spec.rb
new file mode 100644
index 00000000000..a17fee6bab2
--- /dev/null
+++ b/spec/migrations/20211214012507_backfill_incident_issue_escalation_statuses_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe BackfillIncidentIssueEscalationStatuses do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:issues) { table(:issues) }
+ let(:namespace) { namespaces.create!(name: 'foo', path: 'foo') }
+ let(:project) { projects.create!(namespace_id: namespace.id) }
+
+ before do
+ stub_const("#{described_class.name}::BATCH_SIZE", 1)
+ end
+
+ it 'schedules jobs for incident issues' do
+ issue_1 = issues.create!(project_id: project.id) # non-incident issue
+ incident_1 = issues.create!(project_id: project.id, issue_type: 1)
+ incident_2 = issues.create!(project_id: project.id, issue_type: 1)
+
+ Sidekiq::Testing.fake! do
+ freeze_time do
+ migrate!
+
+ expect(described_class::MIGRATION).to be_scheduled_delayed_migration(
+ 2.minutes, issue_1.id, issue_1.id)
+ expect(described_class::MIGRATION).to be_scheduled_delayed_migration(
+ 4.minutes, incident_1.id, incident_1.id)
+ expect(described_class::MIGRATION).to be_scheduled_delayed_migration(
+ 6.minutes, incident_2.id, incident_2.id)
+ expect(BackgroundMigrationWorker.jobs.size).to eq(3)
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20211217174331_mark_recalculate_finding_signatures_as_completed_spec.rb b/spec/migrations/20211217174331_mark_recalculate_finding_signatures_as_completed_spec.rb
new file mode 100644
index 00000000000..c5058f30d82
--- /dev/null
+++ b/spec/migrations/20211217174331_mark_recalculate_finding_signatures_as_completed_spec.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+require 'spec_helper'
+require_migration!
+
+def create_background_migration_jobs(ids, status, created_at)
+ proper_status = case status
+ when :pending
+ Gitlab::Database::BackgroundMigrationJob.statuses['pending']
+ when :succeeded
+ Gitlab::Database::BackgroundMigrationJob.statuses['succeeded']
+ else
+ raise ArgumentError
+ end
+
+ background_migration_jobs.create!(
+ class_name: 'RecalculateVulnerabilitiesOccurrencesUuid',
+ arguments: Array(ids),
+ status: proper_status,
+ created_at: created_at
+ )
+end
+
+RSpec.describe MarkRecalculateFindingSignaturesAsCompleted, :migration do
+ let_it_be(:background_migration_jobs) { table(:background_migration_jobs) }
+
+ context 'when RecalculateVulnerabilitiesOccurrencesUuid jobs are present' do
+ before do
+ create_background_migration_jobs([1, 2, 3], :succeeded, DateTime.new(2021, 5, 5, 0, 2))
+ create_background_migration_jobs([4, 5, 6], :pending, DateTime.new(2021, 5, 5, 0, 4))
+
+ create_background_migration_jobs([1, 2, 3], :succeeded, DateTime.new(2021, 8, 18, 0, 0))
+ create_background_migration_jobs([4, 5, 6], :pending, DateTime.new(2021, 8, 18, 0, 2))
+ create_background_migration_jobs([7, 8, 9], :pending, DateTime.new(2021, 8, 18, 0, 4))
+ end
+
+ describe 'gitlab.com' do
+ before do
+ allow(::Gitlab).to receive(:com?).and_return(true)
+ end
+
+ it 'marks all jobs as succeeded' do
+ expect(background_migration_jobs.where(status: 1).count).to eq(2)
+
+ migrate!
+
+ expect(background_migration_jobs.where(status: 1).count).to eq(5)
+ end
+ end
+
+ describe 'self managed' do
+ before do
+ allow(::Gitlab).to receive(:com?).and_return(false)
+ end
+
+ it 'does not change job status' do
+ expect(background_migration_jobs.where(status: 1).count).to eq(2)
+
+ migrate!
+
+ expect(background_migration_jobs.where(status: 1).count).to eq(2)
+ end
+ end
+ end
+end
diff --git a/spec/migrations/add_has_external_issue_tracker_trigger_spec.rb b/spec/migrations/add_has_external_issue_tracker_trigger_spec.rb
deleted file mode 100644
index 72983c7cfbf..00000000000
--- a/spec/migrations/add_has_external_issue_tracker_trigger_spec.rb
+++ /dev/null
@@ -1,164 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe AddHasExternalIssueTrackerTrigger do
- let(:migration) { described_class.new }
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:services) { table(:services) }
-
- before do
- @namespace = namespaces.create!(name: 'foo', path: 'foo')
- @project = projects.create!(namespace_id: @namespace.id)
- end
-
- describe '#up' do
- before do
- migrate!
- end
-
- describe 'INSERT trigger' do
- it 'sets `has_external_issue_tracker` to true when active `issue_tracker` is inserted' do
- expect do
- services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
- end.to change { @project.reload.has_external_issue_tracker }.to(true)
- end
-
- it 'does not set `has_external_issue_tracker` to true when service is for a different project' do
- different_project = projects.create!(namespace_id: @namespace.id)
-
- expect do
- services.create!(category: 'issue_tracker', active: true, project_id: different_project.id)
- end.not_to change { @project.reload.has_external_issue_tracker }
- end
-
- it 'does not set `has_external_issue_tracker` to true when inactive `issue_tracker` is inserted' do
- expect do
- services.create!(category: 'issue_tracker', active: false, project_id: @project.id)
- end.not_to change { @project.reload.has_external_issue_tracker }
- end
-
- it 'does not set `has_external_issue_tracker` to true when a non-`issue tracker` active service is inserted' do
- expect do
- services.create!(category: 'my_type', active: true, project_id: @project.id)
- end.not_to change { @project.reload.has_external_issue_tracker }
- end
- end
-
- describe 'UPDATE trigger' do
- it 'sets `has_external_issue_tracker` to true when `issue_tracker` is made active' do
- service = services.create!(category: 'issue_tracker', active: false, project_id: @project.id)
-
- expect do
- service.update!(active: true)
- end.to change { @project.reload.has_external_issue_tracker }.to(true)
- end
-
- it 'sets `has_external_issue_tracker` to false when `issue_tracker` is made inactive' do
- service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
-
- expect do
- service.update!(active: false)
- end.to change { @project.reload.has_external_issue_tracker }.to(false)
- end
-
- it 'sets `has_external_issue_tracker` to false when `issue_tracker` is made inactive, and an inactive `issue_tracker` exists' do
- services.create!(category: 'issue_tracker', active: false, project_id: @project.id)
- service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
-
- expect do
- service.update!(active: false)
- end.to change { @project.reload.has_external_issue_tracker }.to(false)
- end
-
- it 'does not change `has_external_issue_tracker` when `issue_tracker` is made inactive, if an active `issue_tracker` exists' do
- services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
- service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
-
- expect do
- service.update!(active: false)
- end.not_to change { @project.reload.has_external_issue_tracker }
- end
-
- it 'does not change `has_external_issue_tracker` when service is for a different project' do
- different_project = projects.create!(namespace_id: @namespace.id)
- service = services.create!(category: 'issue_tracker', active: false, project_id: different_project.id)
-
- expect do
- service.update!(active: true)
- end.not_to change { @project.reload.has_external_issue_tracker }
- end
- end
-
- describe 'DELETE trigger' do
- it 'sets `has_external_issue_tracker` to false when `issue_tracker` is deleted' do
- service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
-
- expect do
- service.delete
- end.to change { @project.reload.has_external_issue_tracker }.to(false)
- end
-
- it 'sets `has_external_issue_tracker` to false when `issue_tracker` is deleted, if an inactive `issue_tracker` still exists' do
- services.create!(category: 'issue_tracker', active: false, project_id: @project.id)
- service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
-
- expect do
- service.delete
- end.to change { @project.reload.has_external_issue_tracker }.to(false)
- end
-
- it 'does not change `has_external_issue_tracker` when `issue_tracker` is deleted, if an active `issue_tracker` still exists' do
- services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
- service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
-
- expect do
- service.delete
- end.not_to change { @project.reload.has_external_issue_tracker }
- end
-
- it 'does not change `has_external_issue_tracker` when service is for a different project' do
- different_project = projects.create!(namespace_id: @namespace.id)
- service = services.create!(category: 'issue_tracker', active: true, project_id: different_project.id)
-
- expect do
- service.delete
- end.not_to change { @project.reload.has_external_issue_tracker }
- end
- end
- end
-
- describe '#down' do
- before do
- migration.up
- migration.down
- end
-
- it 'drops the INSERT trigger' do
- expect do
- services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
- end.not_to change { @project.reload.has_external_issue_tracker }
- end
-
- it 'drops the UPDATE trigger' do
- service = services.create!(category: 'issue_tracker', active: false, project_id: @project.id)
- @project.update!(has_external_issue_tracker: false)
-
- expect do
- service.update!(active: true)
- end.not_to change { @project.reload.has_external_issue_tracker }
- end
-
- it 'drops the DELETE trigger' do
- service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
- @project.update!(has_external_issue_tracker: true)
-
- expect do
- service.delete
- end.not_to change { @project.reload.has_external_issue_tracker }
- end
- end
-end
diff --git a/spec/migrations/add_has_external_wiki_trigger_spec.rb b/spec/migrations/add_has_external_wiki_trigger_spec.rb
deleted file mode 100644
index 10c6888c87e..00000000000
--- a/spec/migrations/add_has_external_wiki_trigger_spec.rb
+++ /dev/null
@@ -1,128 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe AddHasExternalWikiTrigger do
- let(:migration) { described_class.new }
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:services) { table(:services) }
-
- before do
- @namespace = namespaces.create!(name: 'foo', path: 'foo')
- @project = projects.create!(namespace_id: @namespace.id)
- end
-
- describe '#up' do
- before do
- migrate!
- end
-
- describe 'INSERT trigger' do
- it 'sets `has_external_wiki` to true when active `ExternalWikiService` is inserted' do
- expect do
- services.create!(type: 'ExternalWikiService', active: true, project_id: @project.id)
- end.to change { @project.reload.has_external_wiki }.to(true)
- end
-
- it 'does not set `has_external_wiki` to true when service is for a different project' do
- different_project = projects.create!(namespace_id: @namespace.id)
-
- expect do
- services.create!(type: 'ExternalWikiService', active: true, project_id: different_project.id)
- end.not_to change { @project.reload.has_external_wiki }
- end
-
- it 'does not set `has_external_wiki` to true when inactive `ExternalWikiService` is inserted' do
- expect do
- services.create!(type: 'ExternalWikiService', active: false, project_id: @project.id)
- end.not_to change { @project.reload.has_external_wiki }
- end
-
- it 'does not set `has_external_wiki` to true when active other service is inserted' do
- expect do
- services.create!(type: 'MyService', active: true, project_id: @project.id)
- end.not_to change { @project.reload.has_external_wiki }
- end
- end
-
- describe 'UPDATE trigger' do
- it 'sets `has_external_wiki` to true when `ExternalWikiService` is made active' do
- service = services.create!(type: 'ExternalWikiService', active: false, project_id: @project.id)
-
- expect do
- service.update!(active: true)
- end.to change { @project.reload.has_external_wiki }.to(true)
- end
-
- it 'sets `has_external_wiki` to false when `ExternalWikiService` is made inactive' do
- service = services.create!(type: 'ExternalWikiService', active: true, project_id: @project.id)
-
- expect do
- service.update!(active: false)
- end.to change { @project.reload.has_external_wiki }.to(false)
- end
-
- it 'does not change `has_external_wiki` when service is for a different project' do
- different_project = projects.create!(namespace_id: @namespace.id)
- service = services.create!(type: 'ExternalWikiService', active: false, project_id: different_project.id)
-
- expect do
- service.update!(active: true)
- end.not_to change { @project.reload.has_external_wiki }
- end
- end
-
- describe 'DELETE trigger' do
- it 'sets `has_external_wiki` to false when `ExternalWikiService` is deleted' do
- service = services.create!(type: 'ExternalWikiService', active: true, project_id: @project.id)
-
- expect do
- service.delete
- end.to change { @project.reload.has_external_wiki }.to(false)
- end
-
- it 'does not change `has_external_wiki` when service is for a different project' do
- different_project = projects.create!(namespace_id: @namespace.id)
- service = services.create!(type: 'ExternalWikiService', active: true, project_id: different_project.id)
-
- expect do
- service.delete
- end.not_to change { @project.reload.has_external_wiki }
- end
- end
- end
-
- describe '#down' do
- before do
- migration.up
- migration.down
- end
-
- it 'drops the INSERT trigger' do
- expect do
- services.create!(type: 'ExternalWikiService', active: true, project_id: @project.id)
- end.not_to change { @project.reload.has_external_wiki }
- end
-
- it 'drops the UPDATE trigger' do
- service = services.create!(type: 'ExternalWikiService', active: false, project_id: @project.id)
- @project.update!(has_external_wiki: false)
-
- expect do
- service.update!(active: true)
- end.not_to change { @project.reload.has_external_wiki }
- end
-
- it 'drops the DELETE trigger' do
- service = services.create!(type: 'ExternalWikiService', active: true, project_id: @project.id)
- @project.update!(has_external_wiki: true)
-
- expect do
- service.delete
- end.not_to change { @project.reload.has_external_wiki }
- end
- end
-end
diff --git a/spec/migrations/add_new_post_eoa_plans_spec.rb b/spec/migrations/add_new_post_eoa_plans_spec.rb
deleted file mode 100644
index 02360d5a12d..00000000000
--- a/spec/migrations/add_new_post_eoa_plans_spec.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe AddNewPostEoaPlans do
- let(:plans) { table(:plans) }
-
- subject(:migration) { described_class.new }
-
- describe '#up' do
- it 'creates the two new records' do
- expect { migration.up }.to change { plans.count }.by(2)
-
- new_plans = plans.last(2)
- expect(new_plans.map(&:name)).to contain_exactly('premium', 'ultimate')
- end
- end
-
- describe '#down' do
- it 'removes these two new records' do
- plans.create!(name: 'premium', title: 'Premium (Formerly Silver)')
- plans.create!(name: 'ultimate', title: 'Ultimate (Formerly Gold)')
-
- expect { migration.down }.to change { plans.count }.by(-2)
-
- expect(plans.find_by(name: 'premium')).to be_nil
- expect(plans.find_by(name: 'ultimate')).to be_nil
- end
- end
-end
diff --git a/spec/migrations/cleanup_after_add_primary_email_to_emails_if_user_confirmed_spec.rb b/spec/migrations/cleanup_after_add_primary_email_to_emails_if_user_confirmed_spec.rb
new file mode 100644
index 00000000000..abff7c6aba1
--- /dev/null
+++ b/spec/migrations/cleanup_after_add_primary_email_to_emails_if_user_confirmed_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe CleanupAfterAddPrimaryEmailToEmailsIfUserConfirmed, :sidekiq do
+ let(:migration) { described_class.new }
+ let(:users) { table(:users) }
+ let(:emails) { table(:emails) }
+
+ let!(:user_1) { users.create!(name: 'confirmed-user-1', email: 'confirmed-1@example.com', confirmed_at: 3.days.ago, projects_limit: 100) }
+ let!(:user_2) { users.create!(name: 'confirmed-user-2', email: 'confirmed-2@example.com', confirmed_at: 1.day.ago, projects_limit: 100) }
+ let!(:user_3) { users.create!(name: 'confirmed-user-3', email: 'confirmed-3@example.com', confirmed_at: 1.day.ago, projects_limit: 100) }
+ let!(:user_4) { users.create!(name: 'unconfirmed-user', email: 'unconfirmed@example.com', confirmed_at: nil, projects_limit: 100) }
+
+ let!(:email_1) { emails.create!(email: 'confirmed-1@example.com', user_id: user_1.id, confirmed_at: 1.day.ago) }
+ let!(:email_2) { emails.create!(email: 'other_2@example.com', user_id: user_2.id, confirmed_at: 1.day.ago) }
+
+ before do
+ stub_const("#{described_class.name}::BATCH_SIZE", 2)
+ end
+
+ it 'consume any pending background migration job' do
+ expect_next_instance_of(Gitlab::BackgroundMigration::JobCoordinator) do |coordinator|
+ expect(coordinator).to receive(:steal).with('AddPrimaryEmailToEmailsIfUserConfirmed').twice
+ end
+
+ migration.up
+ end
+
+ it 'adds the primary email to emails for leftover confirmed users that do not have their primary email in the emails table', :aggregate_failures do
+ original_email_1_confirmed_at = email_1.reload.confirmed_at
+
+ expect { migration.up }.to change { emails.count }.by(2)
+
+ expect(emails.find_by(user_id: user_2.id, email: 'confirmed-2@example.com').confirmed_at).to eq(user_2.reload.confirmed_at)
+ expect(emails.find_by(user_id: user_3.id, email: 'confirmed-3@example.com').confirmed_at).to eq(user_3.reload.confirmed_at)
+ expect(email_1.reload.confirmed_at).to eq(original_email_1_confirmed_at)
+
+ expect(emails.exists?(user_id: user_4.id)).to be(false)
+ end
+
+ it 'continues in case of errors with one email' do
+ allow(Email).to receive(:create) { raise 'boom!' }
+
+ expect { migration.up }.not_to raise_error
+ end
+end
diff --git a/spec/migrations/cleanup_projects_with_bad_has_external_issue_tracker_data_spec.rb b/spec/migrations/cleanup_projects_with_bad_has_external_issue_tracker_data_spec.rb
deleted file mode 100644
index 8aedd1f9607..00000000000
--- a/spec/migrations/cleanup_projects_with_bad_has_external_issue_tracker_data_spec.rb
+++ /dev/null
@@ -1,94 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe CleanupProjectsWithBadHasExternalIssueTrackerData, :migration do
- let(:namespace) { table(:namespaces).create!(name: 'foo', path: 'bar') }
- let(:projects) { table(:projects) }
- let(:services) { table(:services) }
-
- def create_projects!(num)
- Array.new(num) do
- projects.create!(namespace_id: namespace.id)
- end
- end
-
- def create_active_external_issue_tracker_integrations!(*projects)
- projects.each do |project|
- services.create!(category: 'issue_tracker', project_id: project.id, active: true)
- end
- end
-
- def create_disabled_external_issue_tracker_integrations!(*projects)
- projects.each do |project|
- services.create!(category: 'issue_tracker', project_id: project.id, active: false)
- end
- end
-
- def create_active_other_integrations!(*projects)
- projects.each do |project|
- services.create!(category: 'not_an_issue_tracker', project_id: project.id, active: true)
- end
- end
-
- it 'sets `projects.has_external_issue_tracker` correctly' do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false)
-
- project_with_an_external_issue_tracker_1,
- project_with_an_external_issue_tracker_2,
- project_with_only_a_disabled_external_issue_tracker_1,
- project_with_only_a_disabled_external_issue_tracker_2,
- project_without_any_external_issue_trackers_1,
- project_without_any_external_issue_trackers_2 = create_projects!(6)
-
- create_active_external_issue_tracker_integrations!(
- project_with_an_external_issue_tracker_1,
- project_with_an_external_issue_tracker_2
- )
-
- create_disabled_external_issue_tracker_integrations!(
- project_with_an_external_issue_tracker_1,
- project_with_an_external_issue_tracker_2,
- project_with_only_a_disabled_external_issue_tracker_1,
- project_with_only_a_disabled_external_issue_tracker_2
- )
-
- create_active_other_integrations!(
- project_with_an_external_issue_tracker_1,
- project_with_an_external_issue_tracker_2,
- project_without_any_external_issue_trackers_1,
- project_without_any_external_issue_trackers_2
- )
-
- # PG triggers on the services table added in
- # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51852 will have set
- # the `has_external_issue_tracker` columns to correct data when the services
- # records were created above.
- #
- # We set the `has_external_issue_tracker` columns for projects to incorrect
- # data manually below to emulate projects in a state before the PG
- # triggers were added.
- project_with_an_external_issue_tracker_2.update!(has_external_issue_tracker: false)
- project_with_only_a_disabled_external_issue_tracker_2.update!(has_external_issue_tracker: true)
- project_without_any_external_issue_trackers_2.update!(has_external_issue_tracker: true)
-
- migrate!
-
- expected_true = [
- project_with_an_external_issue_tracker_1,
- project_with_an_external_issue_tracker_2
- ].each(&:reload).map(&:has_external_issue_tracker)
-
- expected_not_true = [
- project_without_any_external_issue_trackers_1,
- project_without_any_external_issue_trackers_2,
- project_with_only_a_disabled_external_issue_tracker_1,
- project_with_only_a_disabled_external_issue_tracker_2
- ].each(&:reload).map(&:has_external_issue_tracker)
-
- expect(expected_true).to all(eq(true))
- expect(expected_not_true).to all(be_falsey)
- end
-end
diff --git a/spec/migrations/cleanup_projects_with_bad_has_external_wiki_data_spec.rb b/spec/migrations/cleanup_projects_with_bad_has_external_wiki_data_spec.rb
deleted file mode 100644
index ee1f718849f..00000000000
--- a/spec/migrations/cleanup_projects_with_bad_has_external_wiki_data_spec.rb
+++ /dev/null
@@ -1,89 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe CleanupProjectsWithBadHasExternalWikiData, :migration do
- let(:namespace) { table(:namespaces).create!(name: 'foo', path: 'bar') }
- let(:projects) { table(:projects) }
- let(:services) { table(:services) }
-
- def create_projects!(num)
- Array.new(num) do
- projects.create!(namespace_id: namespace.id)
- end
- end
-
- def create_active_external_wiki_integrations!(*projects)
- projects.each do |project|
- services.create!(type: 'ExternalWikiService', project_id: project.id, active: true)
- end
- end
-
- def create_disabled_external_wiki_integrations!(*projects)
- projects.each do |project|
- services.create!(type: 'ExternalWikiService', project_id: project.id, active: false)
- end
- end
-
- def create_active_other_integrations!(*projects)
- projects.each do |project|
- services.create!(type: 'NotAnExternalWikiService', project_id: project.id, active: true)
- end
- end
-
- it 'sets `projects.has_external_wiki` correctly' do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false)
-
- project_with_external_wiki_1,
- project_with_external_wiki_2,
- project_with_disabled_external_wiki_1,
- project_with_disabled_external_wiki_2,
- project_without_external_wiki_1,
- project_without_external_wiki_2 = create_projects!(6)
-
- create_active_external_wiki_integrations!(
- project_with_external_wiki_1,
- project_with_external_wiki_2
- )
-
- create_disabled_external_wiki_integrations!(
- project_with_disabled_external_wiki_1,
- project_with_disabled_external_wiki_2
- )
-
- create_active_other_integrations!(
- project_without_external_wiki_1,
- project_without_external_wiki_2
- )
-
- # PG triggers on the services table added in a previous migration
- # will have set the `has_external_wiki` columns to correct data when
- # the services records were created above.
- #
- # We set the `has_external_wiki` columns for projects to incorrect
- # data manually below to emulate projects in a state before the PG
- # triggers were added.
- project_with_external_wiki_2.update!(has_external_wiki: false)
- project_with_disabled_external_wiki_2.update!(has_external_wiki: true)
- project_without_external_wiki_2.update!(has_external_wiki: true)
-
- migrate!
-
- expected_true = [
- project_with_external_wiki_1,
- project_with_external_wiki_2
- ].each(&:reload).map(&:has_external_wiki)
-
- expected_not_true = [
- project_without_external_wiki_1,
- project_without_external_wiki_2,
- project_with_disabled_external_wiki_1,
- project_with_disabled_external_wiki_2
- ].each(&:reload).map(&:has_external_wiki)
-
- expect(expected_true).to all(eq(true))
- expect(expected_not_true).to all(be_falsey)
- end
-end
diff --git a/spec/migrations/drop_alerts_service_data_spec.rb b/spec/migrations/drop_alerts_service_data_spec.rb
deleted file mode 100644
index 06382132952..00000000000
--- a/spec/migrations/drop_alerts_service_data_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe DropAlertsServiceData do
- let_it_be(:alerts_service_data) { table(:alerts_service_data) }
-
- it 'correctly migrates up and down' do
- reversible_migration do |migration|
- migration.before -> {
- expect(alerts_service_data.create!(service_id: 1)).to be_a alerts_service_data
- }
-
- migration.after -> {
- expect { alerts_service_data.create!(service_id: 1) }
- .to raise_error(ActiveRecord::StatementInvalid, /UndefinedTable/)
- }
- end
- end
-end
diff --git a/spec/migrations/migrate_delayed_project_removal_from_namespaces_to_namespace_settings_spec.rb b/spec/migrations/migrate_delayed_project_removal_from_namespaces_to_namespace_settings_spec.rb
deleted file mode 100644
index 0f45cc842ef..00000000000
--- a/spec/migrations/migrate_delayed_project_removal_from_namespaces_to_namespace_settings_spec.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe MigrateDelayedProjectRemovalFromNamespacesToNamespaceSettings, :migration do
- let(:namespaces) { table(:namespaces) }
- let(:namespace_settings) { table(:namespace_settings) }
-
- let!(:namespace_wo_settings) { namespaces.create!(name: generate(:name), path: generate(:name), delayed_project_removal: true) }
- let!(:namespace_wo_settings_delay_false) { namespaces.create!(name: generate(:name), path: generate(:name), delayed_project_removal: false) }
- let!(:namespace_w_settings_delay_true) { namespaces.create!(name: generate(:name), path: generate(:name), delayed_project_removal: true) }
- let!(:namespace_w_settings_delay_false) { namespaces.create!(name: generate(:name), path: generate(:name), delayed_project_removal: false) }
-
- let!(:namespace_settings_delay_true) { namespace_settings.create!(namespace_id: namespace_w_settings_delay_true.id, delayed_project_removal: false, created_at: DateTime.now, updated_at: DateTime.now) }
- let!(:namespace_settings_delay_false) { namespace_settings.create!(namespace_id: namespace_w_settings_delay_false.id, delayed_project_removal: false, created_at: DateTime.now, updated_at: DateTime.now) }
-
- it 'migrates delayed_project_removal to namespace_settings' do
- disable_migrations_output { migrate! }
-
- expect(namespace_settings.count).to eq(3)
-
- expect(namespace_settings.find_by(namespace_id: namespace_wo_settings.id).delayed_project_removal).to eq(true)
- expect(namespace_settings.find_by(namespace_id: namespace_wo_settings_delay_false.id)).to be_nil
-
- expect(namespace_settings_delay_true.reload.delayed_project_removal).to eq(true)
- expect(namespace_settings_delay_false.reload.delayed_project_removal).to eq(false)
- end
-end
diff --git a/spec/migrations/remove_alerts_service_records_again_spec.rb b/spec/migrations/remove_alerts_service_records_again_spec.rb
deleted file mode 100644
index 94d3e957b6a..00000000000
--- a/spec/migrations/remove_alerts_service_records_again_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe RemoveAlertsServiceRecordsAgain do
- let(:services) { table(:services) }
-
- before do
- 5.times { services.create!(type: 'AlertsService') }
- services.create!(type: 'SomeOtherType')
- end
-
- it 'removes services records of type AlertsService and corresponding data', :aggregate_failures do
- expect(services.count).to eq(6)
-
- migrate!
-
- expect(services.count).to eq(1)
- expect(services.first.type).to eq('SomeOtherType')
- expect(services.where(type: 'AlertsService')).to be_empty
- end
-end
diff --git a/spec/migrations/remove_alerts_service_records_spec.rb b/spec/migrations/remove_alerts_service_records_spec.rb
deleted file mode 100644
index 83f440f8e17..00000000000
--- a/spec/migrations/remove_alerts_service_records_spec.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe RemoveAlertsServiceRecords do
- let(:services) { table(:services) }
- let(:alerts_service_data) { table(:alerts_service_data) }
-
- before do
- 5.times do
- service = services.create!(type: 'AlertsService')
- alerts_service_data.create!(service_id: service.id)
- end
-
- services.create!(type: 'SomeOtherType')
- end
-
- it 'removes services records of type AlertsService and corresponding data', :aggregate_failures do
- expect(services.count).to eq(6)
- expect(alerts_service_data.count).to eq(5)
-
- migrate!
-
- expect(services.count).to eq(1)
- expect(services.first.type).to eq('SomeOtherType')
- expect(services.where(type: 'AlertsService')).to be_empty
- expect(alerts_service_data.all).to be_empty
- end
-end
diff --git a/spec/migrations/reschedule_artifact_expiry_backfill_spec.rb b/spec/migrations/reschedule_artifact_expiry_backfill_spec.rb
deleted file mode 100644
index c06ce3d5bea..00000000000
--- a/spec/migrations/reschedule_artifact_expiry_backfill_spec.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe RescheduleArtifactExpiryBackfill, :migration do
- let(:migration_class) { Gitlab::BackgroundMigration::BackfillArtifactExpiryDate }
- let(:migration_name) { migration_class.to_s.demodulize }
-
- before do
- table(:namespaces).create!(id: 123, name: 'test_namespace', path: 'test_namespace')
- table(:projects).create!(id: 123, name: 'sample_project', path: 'sample_project', namespace_id: 123)
- end
-
- it 'correctly schedules background migrations' do
- first_artifact = create_artifact(job_id: 0, expire_at: nil, created_at: Date.new(2020, 06, 21))
- second_artifact = create_artifact(job_id: 1, expire_at: nil, created_at: Date.new(2020, 06, 21))
- create_artifact(job_id: 2, expire_at: Date.yesterday, created_at: Date.new(2020, 06, 21))
- create_artifact(job_id: 3, expire_at: nil, created_at: Date.new(2020, 06, 23))
-
- Sidekiq::Testing.fake! do
- freeze_time do
- migrate!
-
- expect(BackgroundMigrationWorker.jobs.size).to eq(1)
- expect(migration_name).to be_scheduled_migration_with_multiple_args(first_artifact.id, second_artifact.id)
- end
- end
- end
-
- private
-
- def create_artifact(params)
- table(:ci_builds).create!(id: params[:job_id], project_id: 123)
- table(:ci_job_artifacts).create!(project_id: 123, file_type: 1, **params)
- end
-end
diff --git a/spec/migrations/schedule_migrate_pages_to_zip_storage_spec.rb b/spec/migrations/schedule_migrate_pages_to_zip_storage_spec.rb
index 29e4cf05c2b..52bbd5b4f6e 100644
--- a/spec/migrations/schedule_migrate_pages_to_zip_storage_spec.rb
+++ b/spec/migrations/schedule_migrate_pages_to_zip_storage_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require_migration!
-RSpec.describe ScheduleMigratePagesToZipStorage, :sidekiq_might_not_need_inline, schema: 20201231133921 do
+RSpec.describe ScheduleMigratePagesToZipStorage, :sidekiq_might_not_need_inline, schema: 20210301200959 do
let(:migration_class) { described_class::MIGRATION }
let(:migration_name) { migration_class.to_s.demodulize }
diff --git a/spec/migrations/schedule_populate_finding_uuid_for_vulnerability_feedback_spec.rb b/spec/migrations/schedule_populate_finding_uuid_for_vulnerability_feedback_spec.rb
deleted file mode 100644
index d8bdefd5546..00000000000
--- a/spec/migrations/schedule_populate_finding_uuid_for_vulnerability_feedback_spec.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe SchedulePopulateFindingUuidForVulnerabilityFeedback do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:users) { table(:users) }
- let(:vulnerability_feedback) { table(:vulnerability_feedback) }
-
- let(:namespace) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') }
- let(:project) { projects.create!(namespace_id: namespace.id, name: 'foo') }
- let(:user) { users.create!(username: 'john.doe', projects_limit: 1) }
-
- let(:common_feedback_params) { { feedback_type: 0, category: 0, project_id: project.id, author_id: user.id } }
- let!(:feedback_1) { vulnerability_feedback.create!(**common_feedback_params, project_fingerprint: 'foo') }
- let!(:feedback_2) { vulnerability_feedback.create!(**common_feedback_params, project_fingerprint: 'bar') }
- let!(:feedback_3) { vulnerability_feedback.create!(**common_feedback_params, project_fingerprint: 'zoo', finding_uuid: SecureRandom.uuid) }
-
- around do |example|
- freeze_time { Sidekiq::Testing.fake! { example.run } }
- end
-
- before do
- stub_const("#{described_class.name}::BATCH_SIZE", 1)
- end
-
- it 'schedules the background jobs', :aggregate_failures do
- migrate!
-
- expect(BackgroundMigrationWorker.jobs.size).to be(3)
- expect(described_class::MIGRATION_CLASS).to be_scheduled_delayed_migration(2.minutes, feedback_1.id, feedback_1.id)
- expect(described_class::MIGRATION_CLASS).to be_scheduled_delayed_migration(4.minutes, feedback_2.id, feedback_2.id)
- expect(described_class::MIGRATION_CLASS).to be_scheduled_delayed_migration(6.minutes, feedback_3.id, feedback_3.id)
- end
-end
diff --git a/spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences2_spec.rb b/spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences2_spec.rb
deleted file mode 100644
index e7d1813e428..00000000000
--- a/spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences2_spec.rb
+++ /dev/null
@@ -1,127 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe ScheduleRecalculateUuidOnVulnerabilitiesOccurrences2 do
- let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
- let(:users) { table(:users) }
- let(:user) { create_user! }
- let(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) }
- let(:scanners) { table(:vulnerability_scanners) }
- let(:scanner) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
- let(:different_scanner) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') }
- let(:vulnerabilities) { table(:vulnerabilities) }
- let(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
- let(:vulnerability_identifiers) { table(:vulnerability_identifiers) }
- let(:vulnerability_identifier) do
- vulnerability_identifiers.create!(
- project_id: project.id,
- external_type: 'uuid-v5',
- external_id: 'uuid-v5',
- fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
- name: 'Identifier for UUIDv5')
- end
-
- let(:different_vulnerability_identifier) do
- vulnerability_identifiers.create!(
- project_id: project.id,
- external_type: 'uuid-v4',
- external_id: 'uuid-v4',
- fingerprint: '772da93d34a1ba010bcb5efa9fb6f8e01bafcc89',
- name: 'Identifier for UUIDv4')
- end
-
- let(:vulnerability_for_uuidv4) do
- create_vulnerability!(
- project_id: project.id,
- author_id: user.id
- )
- end
-
- let(:vulnerability_for_uuidv5) do
- create_vulnerability!(
- project_id: project.id,
- author_id: user.id
- )
- end
-
- let!(:finding1) do
- create_finding!(
- vulnerability_id: vulnerability_for_uuidv4.id,
- project_id: project.id,
- scanner_id: different_scanner.id,
- primary_identifier_id: different_vulnerability_identifier.id,
- location_fingerprint: 'fa18f432f1d56675f4098d318739c3cd5b14eb3e',
- uuid: 'b3cc2518-5446-4dea-871c-89d5e999c1ac'
- )
- end
-
- let!(:finding2) do
- create_finding!(
- vulnerability_id: vulnerability_for_uuidv5.id,
- project_id: project.id,
- scanner_id: scanner.id,
- primary_identifier_id: vulnerability_identifier.id,
- location_fingerprint: '838574be0210968bf6b9f569df9c2576242cbf0a',
- uuid: '77211ed6-7dff-5f6b-8c9a-da89ad0a9b60'
- )
- end
-
- before do
- stub_const("#{described_class}::BATCH_SIZE", 1)
- end
-
- around do |example|
- freeze_time { Sidekiq::Testing.fake! { example.run } }
- end
-
- it 'schedules background migrations', :aggregate_failures do
- migrate!
-
- expect(BackgroundMigrationWorker.jobs.size).to eq(2)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, finding1.id, finding1.id)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, finding2.id, finding2.id)
- end
-
- private
-
- def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
- vulnerabilities.create!(
- project_id: project_id,
- author_id: author_id,
- title: title,
- severity: severity,
- confidence: confidence,
- report_type: report_type
- )
- end
-
- def create_finding!(
- vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:, location_fingerprint:, uuid:)
- vulnerabilities_findings.create!(
- vulnerability_id: vulnerability_id,
- project_id: project_id,
- name: 'test',
- severity: 7,
- confidence: 7,
- report_type: 0,
- project_fingerprint: '123qweasdzxc',
- scanner_id: scanner_id,
- primary_identifier_id: primary_identifier_id,
- location_fingerprint: location_fingerprint,
- metadata_version: 'test',
- raw_metadata: 'test',
- uuid: uuid
- )
- end
-
- def create_user!(name: "Example User", email: "user@example.com", user_type: nil)
- users.create!(
- name: name,
- email: email,
- username: name,
- projects_limit: 0
- )
- end
-end
diff --git a/spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences3_spec.rb b/spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences3_spec.rb
deleted file mode 100644
index 77f298b5ecb..00000000000
--- a/spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences3_spec.rb
+++ /dev/null
@@ -1,127 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe ScheduleRecalculateUuidOnVulnerabilitiesOccurrences3 do
- let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
- let(:users) { table(:users) }
- let(:user) { create_user! }
- let(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) }
- let(:scanners) { table(:vulnerability_scanners) }
- let(:scanner) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
- let(:different_scanner) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') }
- let(:vulnerabilities) { table(:vulnerabilities) }
- let(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
- let(:vulnerability_identifiers) { table(:vulnerability_identifiers) }
- let(:vulnerability_identifier) do
- vulnerability_identifiers.create!(
- project_id: project.id,
- external_type: 'uuid-v5',
- external_id: 'uuid-v5',
- fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
- name: 'Identifier for UUIDv5')
- end
-
- let(:different_vulnerability_identifier) do
- vulnerability_identifiers.create!(
- project_id: project.id,
- external_type: 'uuid-v4',
- external_id: 'uuid-v4',
- fingerprint: '772da93d34a1ba010bcb5efa9fb6f8e01bafcc89',
- name: 'Identifier for UUIDv4')
- end
-
- let(:vulnerability_for_uuidv4) do
- create_vulnerability!(
- project_id: project.id,
- author_id: user.id
- )
- end
-
- let(:vulnerability_for_uuidv5) do
- create_vulnerability!(
- project_id: project.id,
- author_id: user.id
- )
- end
-
- let!(:finding1) do
- create_finding!(
- vulnerability_id: vulnerability_for_uuidv4.id,
- project_id: project.id,
- scanner_id: different_scanner.id,
- primary_identifier_id: different_vulnerability_identifier.id,
- location_fingerprint: 'fa18f432f1d56675f4098d318739c3cd5b14eb3e',
- uuid: 'b3cc2518-5446-4dea-871c-89d5e999c1ac'
- )
- end
-
- let!(:finding2) do
- create_finding!(
- vulnerability_id: vulnerability_for_uuidv5.id,
- project_id: project.id,
- scanner_id: scanner.id,
- primary_identifier_id: vulnerability_identifier.id,
- location_fingerprint: '838574be0210968bf6b9f569df9c2576242cbf0a',
- uuid: '77211ed6-7dff-5f6b-8c9a-da89ad0a9b60'
- )
- end
-
- before do
- stub_const("#{described_class}::BATCH_SIZE", 1)
- end
-
- around do |example|
- freeze_time { Sidekiq::Testing.fake! { example.run } }
- end
-
- it 'schedules background migrations', :aggregate_failures do
- migrate!
-
- expect(BackgroundMigrationWorker.jobs.size).to eq(2)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, finding1.id, finding1.id)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, finding2.id, finding2.id)
- end
-
- private
-
- def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
- vulnerabilities.create!(
- project_id: project_id,
- author_id: author_id,
- title: title,
- severity: severity,
- confidence: confidence,
- report_type: report_type
- )
- end
-
- def create_finding!(
- vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:, location_fingerprint:, uuid:)
- vulnerabilities_findings.create!(
- vulnerability_id: vulnerability_id,
- project_id: project_id,
- name: 'test',
- severity: 7,
- confidence: 7,
- report_type: 0,
- project_fingerprint: '123qweasdzxc',
- scanner_id: scanner_id,
- primary_identifier_id: primary_identifier_id,
- location_fingerprint: location_fingerprint,
- metadata_version: 'test',
- raw_metadata: 'test',
- uuid: uuid
- )
- end
-
- def create_user!(name: "Example User", email: "user@example.com", user_type: nil)
- users.create!(
- name: name,
- email: email,
- username: name,
- projects_limit: 0
- )
- end
-end
diff --git a/spec/migrations/update_application_settings_protected_paths_spec.rb b/spec/migrations/update_application_settings_protected_paths_spec.rb
new file mode 100644
index 00000000000..21879995f1b
--- /dev/null
+++ b/spec/migrations/update_application_settings_protected_paths_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe UpdateApplicationSettingsProtectedPaths, :aggregate_failures do
+ subject(:migration) { described_class.new }
+
+ let_it_be(:application_settings) { table(:application_settings) }
+ let_it_be(:oauth_paths) { %w[/oauth/authorize /oauth/token] }
+ let_it_be(:custom_paths) { %w[/foo /bar] }
+
+ let(:default_paths) { application_settings.column_defaults.fetch('protected_paths') }
+
+ before do
+ application_settings.create!(protected_paths: custom_paths)
+ application_settings.create!(protected_paths: custom_paths + oauth_paths)
+ application_settings.create!(protected_paths: custom_paths + oauth_paths.take(1))
+ end
+
+ describe '#up' do
+ before do
+ migrate!
+ application_settings.reset_column_information
+ end
+
+ it 'removes the OAuth paths from the default value and persisted records' do
+ expect(default_paths).not_to include(*oauth_paths)
+ expect(default_paths).to eq(described_class::NEW_DEFAULT_PROTECTED_PATHS)
+ expect(application_settings.all).to all(have_attributes(protected_paths: custom_paths))
+ end
+ end
+
+ describe '#down' do
+ before do
+ migrate!
+ schema_migrate_down!
+ end
+
+ it 'adds the OAuth paths to the default value and persisted records' do
+ expect(default_paths).to include(*oauth_paths)
+ expect(default_paths).to eq(described_class::OLD_DEFAULT_PROTECTED_PATHS)
+ expect(application_settings.all).to all(have_attributes(protected_paths: custom_paths + oauth_paths))
+ end
+ end
+end
diff --git a/spec/migrations/update_invalid_member_states_spec.rb b/spec/migrations/update_invalid_member_states_spec.rb
new file mode 100644
index 00000000000..802634230a9
--- /dev/null
+++ b/spec/migrations/update_invalid_member_states_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe UpdateInvalidMemberStates do
+ let(:members) { table(:members) }
+ let(:groups) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:users) { table(:users) }
+
+ before do
+ user = users.create!(first_name: 'Test', last_name: 'User', email: 'test@user.com', projects_limit: 1)
+ group = groups.create!(name: 'gitlab', path: 'gitlab-org')
+ project = projects.create!(namespace_id: group.id)
+
+ members.create!(state: 2, source_id: group.id, source_type: 'Group', type: 'GroupMember', user_id: user.id, access_level: 50, notification_level: 0)
+ members.create!(state: 2, source_id: project.id, source_type: 'Project', type: 'ProjectMember', user_id: user.id, access_level: 50, notification_level: 0)
+ members.create!(state: 1, source_id: group.id, source_type: 'Group', type: 'GroupMember', user_id: user.id, access_level: 50, notification_level: 0)
+ members.create!(state: 0, source_id: group.id, source_type: 'Group', type: 'GroupMember', user_id: user.id, access_level: 50, notification_level: 0)
+ end
+
+ it 'updates matching member record states' do
+ expect { migrate! }
+ .to change { members.where(state: 0).count }.from(1).to(3)
+ .and change { members.where(state: 2).count }.from(2).to(0)
+ .and change { members.where(state: 1).count }.by(0)
+ end
+end
diff --git a/spec/models/alert_management/alert_spec.rb b/spec/models/alert_management/alert_spec.rb
index 35398e29062..40bdfd4bc92 100644
--- a/spec/models/alert_management/alert_spec.rb
+++ b/spec/models/alert_management/alert_spec.rb
@@ -211,12 +211,6 @@ RSpec.describe AlertManagement::Alert do
end
end
- describe '.open' do
- subject { described_class.open }
-
- it { is_expected.to contain_exactly(acknowledged_alert, triggered_alert) }
- end
-
describe '.not_resolved' do
subject { described_class.not_resolved }
@@ -324,33 +318,6 @@ RSpec.describe AlertManagement::Alert do
end
end
- describe '.open_status?' do
- using RSpec::Parameterized::TableSyntax
-
- where(:status, :is_open_status) do
- :triggered | true
- :acknowledged | true
- :resolved | false
- :ignored | false
- nil | false
- end
-
- with_them do
- it 'returns true when the status is open status' do
- expect(described_class.open_status?(status)).to eq(is_open_status)
- end
- end
- end
-
- describe '#open?' do
- it 'returns true when the status is open status' do
- expect(triggered_alert.open?).to be true
- expect(acknowledged_alert.open?).to be true
- expect(resolved_alert.open?).to be false
- expect(ignored_alert.open?).to be false
- end
- end
-
describe '#to_reference' do
it { expect(triggered_alert.to_reference).to eq("^alert##{triggered_alert.iid}") }
end
diff --git a/spec/models/application_record_spec.rb b/spec/models/application_record_spec.rb
index f0212da3041..9c9a048999c 100644
--- a/spec/models/application_record_spec.rb
+++ b/spec/models/application_record_spec.rb
@@ -147,22 +147,20 @@ RSpec.describe ApplicationRecord do
end
end
- # rubocop:disable Database/MultipleDatabases
it 'increments a counter when a transaction is created in ActiveRecord' do
expect(described_class.connection.transaction_open?).to be false
expect(::Gitlab::Database::Metrics)
.to receive(:subtransactions_increment)
- .with('ActiveRecord::Base')
+ .with('ApplicationRecord')
.once
- ActiveRecord::Base.transaction do
- ActiveRecord::Base.transaction(requires_new: true) do
- expect(ActiveRecord::Base.connection.transaction_open?).to be true
+ ApplicationRecord.transaction do
+ ApplicationRecord.transaction(requires_new: true) do
+ expect(ApplicationRecord.connection.transaction_open?).to be true
end
end
end
- # rubocop:enable Database/MultipleDatabases
end
describe '.with_fast_read_statement_timeout' do
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb
index 67314084c4f..0ece212d692 100644
--- a/spec/models/application_setting_spec.rb
+++ b/spec/models/application_setting_spec.rb
@@ -77,9 +77,24 @@ RSpec.describe ApplicationSetting do
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 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) }
+ it { is_expected.to validate_numericality_of(:container_registry_import_start_max_retries).only_integer.is_greater_than_or_equal_to(0) }
+ it { is_expected.to validate_numericality_of(:container_registry_import_max_step_duration).only_integer.is_greater_than_or_equal_to(0) }
+ it { is_expected.not_to allow_value(nil).for(:container_registry_import_max_tags_count) }
+ it { is_expected.not_to allow_value(nil).for(:container_registry_import_max_retries) }
+ it { is_expected.not_to allow_value(nil).for(:container_registry_import_start_max_retries) }
+ it { is_expected.not_to allow_value(nil).for(:container_registry_import_max_step_duration) }
+
+ it { is_expected.to validate_presence_of(:container_registry_import_target_plan) }
+ it { is_expected.to validate_presence_of(:container_registry_import_created_before) }
+
it { is_expected.to validate_numericality_of(:dependency_proxy_ttl_group_policy_worker_capacity).only_integer.is_greater_than_or_equal_to(0) }
it { is_expected.not_to allow_value(nil).for(:dependency_proxy_ttl_group_policy_worker_capacity) }
+ it { is_expected.to validate_numericality_of(:packages_cleanup_package_file_worker_capacity).only_integer.is_greater_than_or_equal_to(0) }
+ it { is_expected.not_to allow_value(nil).for(:packages_cleanup_package_file_worker_capacity) }
+
it { is_expected.to validate_numericality_of(:snippet_size_limit).only_integer.is_greater_than(0) }
it { is_expected.to validate_numericality_of(:wiki_page_max_content_bytes).only_integer.is_greater_than_or_equal_to(1024) }
it { is_expected.to validate_presence_of(:max_artifacts_size) }
@@ -126,11 +141,13 @@ 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") }
- it { is_expected.to allow_value(400).for(:notes_create_limit) }
- it { is_expected.not_to allow_value('two').for(:notes_create_limit) }
- it { is_expected.not_to allow_value(nil).for(:notes_create_limit) }
- it { is_expected.not_to allow_value(5.5).for(:notes_create_limit) }
- it { is_expected.not_to allow_value(-2).for(:notes_create_limit) }
+ %i[notes_create_limit user_email_lookup_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) }
+ it { is_expected.not_to allow_value(5.5).for(setting) }
+ it { is_expected.not_to allow_value(-2).for(setting) }
+ end
def many_usernames(num = 100)
Array.new(num) { |i| "username#{i}" }
@@ -489,7 +506,7 @@ RSpec.describe ApplicationSetting do
context 'key restrictions' do
it 'supports all key types' do
- expect(described_class::SUPPORTED_KEY_TYPES).to contain_exactly(:rsa, :dsa, :ecdsa, :ed25519)
+ expect(described_class::SUPPORTED_KEY_TYPES).to eq(Gitlab::SSHPublicKey.supported_types)
end
it 'does not allow all key types to be disabled' do
@@ -1242,7 +1259,7 @@ RSpec.describe ApplicationSetting do
end
end
- describe '#static_objects_external_storage_auth_token=' do
+ describe '#static_objects_external_storage_auth_token=', :aggregate_failures do
subject { setting.static_objects_external_storage_auth_token = token }
let(:token) { 'Test' }
@@ -1266,5 +1283,20 @@ RSpec.describe ApplicationSetting do
expect(setting.static_objects_external_storage_auth_token).to be_nil
end
end
+
+ context 'with plaintext token only' do
+ let(:token) { '' }
+
+ it 'ignores the plaintext token' do
+ subject
+
+ ApplicationSetting.update_all(static_objects_external_storage_auth_token: 'Test')
+
+ setting.reload
+ expect(setting[:static_objects_external_storage_auth_token]).to be_nil
+ expect(setting[:static_objects_external_storage_auth_token_encrypted]).to be_nil
+ expect(setting.static_objects_external_storage_auth_token).to be_nil
+ end
+ end
end
end
diff --git a/spec/models/bulk_imports/file_transfer/project_config_spec.rb b/spec/models/bulk_imports/file_transfer/project_config_spec.rb
index 02151da583e..61caff647d6 100644
--- a/spec/models/bulk_imports/file_transfer/project_config_spec.rb
+++ b/spec/models/bulk_imports/file_transfer/project_config_spec.rb
@@ -91,4 +91,10 @@ RSpec.describe BulkImports::FileTransfer::ProjectConfig do
end
end
end
+
+ describe '#file_relations' do
+ it 'returns project file relations' do
+ expect(subject.file_relations).to contain_exactly('uploads', 'lfs_objects')
+ end
+ end
end
diff --git a/spec/models/ci/build_report_result_spec.rb b/spec/models/ci/build_report_result_spec.rb
index e78f602feef..3f53c6c1c0e 100644
--- a/spec/models/ci/build_report_result_spec.rb
+++ b/spec/models/ci/build_report_result_spec.rb
@@ -5,6 +5,11 @@ require 'spec_helper'
RSpec.describe Ci::BuildReportResult do
let(:build_report_result) { build(:ci_build_report_result, :with_junit_success) }
+ it_behaves_like 'cleanup by a loose foreign key' do
+ let!(:parent) { create(:project) }
+ let!(:model) { create(:ci_build_report_result, project: parent) }
+ end
+
describe 'associations' do
it { is_expected.to belong_to(:build) }
it { is_expected.to belong_to(:project) }
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index b9a12339e61..b8c5af5a911 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -565,6 +565,26 @@ RSpec.describe Ci::Build do
expect(build.reload.runtime_metadata).not_to be_present
end
end
+
+ context 'when a failure reason is provided' do
+ context 'when a failure reason is a symbol' do
+ it 'correctly sets a failure reason' do
+ build.drop!(:script_failure)
+
+ expect(build.failure_reason).to eq 'script_failure'
+ end
+ end
+
+ context 'when a failure reason is an object' do
+ it 'correctly sets a failure reason' do
+ reason = ::Gitlab::Ci::Build::Status::Reason.new(build, :script_failure)
+
+ build.drop!(reason)
+
+ expect(build.failure_reason).to eq 'script_failure'
+ end
+ end
+ end
end
describe '#schedulable?' do
@@ -2002,6 +2022,16 @@ RSpec.describe Ci::Build do
it { is_expected.not_to be_retryable }
end
+
+ context 'when build is waiting for deployment approval' do
+ subject { build_stubbed(:ci_build, :manual, environment: 'production') }
+
+ before do
+ create(:deployment, :blocked, deployable: subject)
+ end
+
+ it { is_expected.not_to be_retryable }
+ end
end
end
@@ -2064,6 +2094,31 @@ RSpec.describe Ci::Build do
end
describe 'build auto retry feature' do
+ context 'with deployment job' do
+ let(:build) do
+ create(:ci_build, :deploy_to_production, :with_deployment,
+ user: user, pipeline: pipeline, project: project)
+ end
+
+ before do
+ project.add_developer(user)
+ allow(build).to receive(:auto_retry_allowed?) { true }
+ end
+
+ it 'creates a deployment when a build is dropped' do
+ expect { build.drop!(:script_failure) }.to change { Deployment.count }.by(1)
+
+ retried_deployment = Deployment.last
+ expect(build.deployment.environment).to eq(retried_deployment.environment)
+ expect(build.deployment.ref).to eq(retried_deployment.ref)
+ expect(build.deployment.sha).to eq(retried_deployment.sha)
+ expect(build.deployment.tag).to eq(retried_deployment.tag)
+ expect(build.deployment.user).to eq(retried_deployment.user)
+ expect(build.deployment).to be_failed
+ expect(retried_deployment).to be_created
+ end
+ end
+
describe '#retries_count' do
subject { create(:ci_build, name: 'test', pipeline: pipeline) }
@@ -2152,6 +2207,28 @@ RSpec.describe Ci::Build do
end
end
+ describe '#auto_retry_expected?' do
+ subject { create(:ci_build, :failed) }
+
+ context 'when build is failed and auto retry is configured' do
+ before do
+ allow(subject)
+ .to receive(:auto_retry_allowed?)
+ .and_return(true)
+ end
+
+ it 'expects auto-retry to happen' do
+ expect(subject.auto_retry_expected?).to be true
+ end
+ end
+
+ context 'when build failed by auto retry is not configured' do
+ it 'does not expect auto-retry to happen' do
+ expect(subject.auto_retry_expected?).to be false
+ end
+ end
+ end
+
describe '#artifacts_file_for_type' do
let(:build) { create(:ci_build, :artifacts) }
let(:file_type) { :archive }
@@ -2443,6 +2520,16 @@ RSpec.describe Ci::Build do
it { is_expected.not_to be_playable }
end
+
+ context 'when build is waiting for deployment approval' do
+ subject { build_stubbed(:ci_build, :manual, environment: 'production') }
+
+ before do
+ create(:deployment, :blocked, deployable: subject)
+ end
+
+ it { is_expected.not_to be_playable }
+ end
end
describe 'project settings' do
@@ -2653,6 +2740,8 @@ RSpec.describe Ci::Build do
{ key: 'CI_DEPENDENCY_PROXY_USER', value: 'gitlab-ci-token', public: true, masked: false },
{ key: 'CI_DEPENDENCY_PROXY_PASSWORD', value: 'my-token', public: false, masked: true },
{ key: 'CI_JOB_JWT', value: 'ci.job.jwt', public: false, masked: true },
+ { key: 'CI_JOB_JWT_V1', value: 'ci.job.jwt', public: false, masked: true },
+ { key: 'CI_JOB_JWT_V2', value: 'ci.job.jwtv2', public: false, masked: true },
{ key: 'CI_JOB_NAME', value: 'test', public: true, masked: false },
{ key: 'CI_JOB_STAGE', value: 'test', public: true, masked: false },
{ key: 'CI_NODE_TOTAL', value: '1', public: true, masked: false },
@@ -2720,6 +2809,7 @@ RSpec.describe Ci::Build do
before do
allow(Gitlab::Ci::Jwt).to receive(:for_build).and_return('ci.job.jwt')
+ allow(Gitlab::Ci::JwtV2).to receive(:for_build).and_return('ci.job.jwtv2')
build.set_token('my-token')
build.yaml_variables = []
end
@@ -2771,6 +2861,8 @@ RSpec.describe Ci::Build do
let(:build_yaml_var) { { key: 'yaml', value: 'value', public: true, masked: false } }
let(:dependency_proxy_var) { { key: 'dependency_proxy', value: 'value', public: true, masked: false } }
let(:job_jwt_var) { { key: 'CI_JOB_JWT', value: 'ci.job.jwt', public: false, masked: true } }
+ let(:job_jwt_var_v1) { { key: 'CI_JOB_JWT_V1', value: 'ci.job.jwt', public: false, masked: true } }
+ let(:job_jwt_var_v2) { { key: 'CI_JOB_JWT_V2', value: 'ci.job.jwtv2', public: false, masked: true } }
let(:job_dependency_var) { { key: 'job_dependency', value: 'value', public: true, masked: false } }
before do
@@ -2784,7 +2876,7 @@ RSpec.describe Ci::Build do
allow(build).to receive(:dependency_variables) { [job_dependency_var] }
allow(build).to receive(:dependency_proxy_variables) { [dependency_proxy_var] }
- allow(build.project)
+ allow(build.pipeline.project)
.to receive(:predefined_variables) { [project_pre_var] }
project.variables.create!(key: 'secret', value: 'value')
@@ -3084,7 +3176,7 @@ RSpec.describe Ci::Build do
context 'when the branch is protected' do
before do
- allow(build.project).to receive(:protected_for?).with(ref).and_return(true)
+ allow(build.pipeline.project).to receive(:protected_for?).with(ref).and_return(true)
end
it { is_expected.to include(protected_variable) }
@@ -3092,7 +3184,7 @@ RSpec.describe Ci::Build do
context 'when the tag is protected' do
before do
- allow(build.project).to receive(:protected_for?).with(ref).and_return(true)
+ allow(build.pipeline.project).to receive(:protected_for?).with(ref).and_return(true)
end
it { is_expected.to include(protected_variable) }
@@ -3131,7 +3223,7 @@ RSpec.describe Ci::Build do
context 'when the branch is protected' do
before do
- allow(build.project).to receive(:protected_for?).with(ref).and_return(true)
+ allow(build.pipeline.project).to receive(:protected_for?).with(ref).and_return(true)
end
it { is_expected.to include(protected_variable) }
@@ -3139,7 +3231,7 @@ RSpec.describe Ci::Build do
context 'when the tag is protected' do
before do
- allow(build.project).to receive(:protected_for?).with(ref).and_return(true)
+ allow(build.pipeline.project).to receive(:protected_for?).with(ref).and_return(true)
end
it { is_expected.to include(protected_variable) }
@@ -3526,6 +3618,20 @@ RSpec.describe Ci::Build do
build.scoped_variables
end
+
+ context 'when variables builder is used' do
+ it 'returns the same variables' do
+ build.user = create(:user)
+
+ allow(build.pipeline).to receive(:use_variables_builder_definitions?).and_return(false)
+ legacy_variables = build.scoped_variables.to_hash
+
+ allow(build.pipeline).to receive(:use_variables_builder_definitions?).and_return(true)
+ new_variables = build.scoped_variables.to_hash
+
+ expect(new_variables).to eq(legacy_variables)
+ end
+ end
end
describe '#simple_variables_without_dependencies' do
@@ -3538,7 +3644,8 @@ RSpec.describe Ci::Build do
shared_examples "secret CI variables" do
context 'when ref is branch' do
- let(:build) { create(:ci_build, ref: 'master', tag: false, project: project) }
+ let(:pipeline) { create(:ci_pipeline, project: project) }
+ let(:build) { create(:ci_build, ref: 'master', tag: false, pipeline: pipeline, project: project) }
context 'when ref is protected' do
before do
@@ -3554,7 +3661,8 @@ RSpec.describe Ci::Build do
end
context 'when ref is tag' do
- let(:build) { create(:ci_build, ref: 'v1.1.0', tag: true, project: project) }
+ let(:pipeline) { create(:ci_pipeline, project: project) }
+ let(:build) { create(:ci_build, ref: 'v1.1.0', tag: true, pipeline: pipeline, project: project) }
context 'when ref is protected' do
before do
@@ -3652,8 +3760,6 @@ RSpec.describe Ci::Build do
.and_return(project_variables)
end
- it { is_expected.to eq(project_variables) }
-
context 'environment is nil' do
let(:environment) { nil }
@@ -3661,6 +3767,35 @@ RSpec.describe Ci::Build do
end
end
+ describe '#user_variables' do
+ subject { build.user_variables.to_hash }
+
+ context 'with user' do
+ let(:expected_variables) do
+ {
+ 'GITLAB_USER_EMAIL' => user.email,
+ 'GITLAB_USER_ID' => user.id.to_s,
+ 'GITLAB_USER_LOGIN' => user.username,
+ 'GITLAB_USER_NAME' => user.name
+ }
+ end
+
+ before do
+ build.user = user
+ end
+
+ it { is_expected.to eq(expected_variables) }
+ end
+
+ context 'without user' do
+ before do
+ expect(build).to receive(:user).and_return(nil)
+ end
+
+ it { is_expected.to be_empty }
+ end
+ end
+
describe '#any_unmet_prerequisites?' do
let(:build) { create(:ci_build, :created) }
@@ -3762,6 +3897,18 @@ RSpec.describe Ci::Build do
end
end
+ describe 'when the build is waiting for deployment approval' do
+ let(:build) { create(:ci_build, :manual, environment: 'production') }
+
+ before do
+ create(:deployment, :blocked, deployable: build)
+ end
+
+ it 'does not allow the build to be enqueued' do
+ expect { build.enqueue! }.to raise_error(StateMachines::InvalidTransition)
+ end
+ end
+
describe 'state transition: any => [:pending]' do
let(:build) { create(:ci_build, :created) }
@@ -5174,25 +5321,32 @@ RSpec.describe Ci::Build do
.to change { build.reload.failed? }
end
- it 'is executed inside a transaction' do
- expect(build).to receive(:drop!)
- .with(:unknown_failure)
- .and_raise(ActiveRecord::Rollback)
-
- expect(build).to receive(:conditionally_allow_failure!)
- .with(1)
- .and_call_original
-
- expect { drop_with_exit_code }
- .not_to change { build.reload.allow_failure }
- end
-
context 'when exit_code is nil' do
let(:exit_code) {}
it_behaves_like 'drops the build without changing allow_failure'
end
end
+
+ context 'when build is configured to be retried' do
+ let(:options) { { retry: 3 } }
+
+ context 'when there is an MR attached to the pipeline and a failed job todo for that MR' do
+ let!(:merge_request) { create(:merge_request, source_project: project, author: user, head_pipeline: pipeline) }
+ let!(:todo) { create(:todo, :build_failed, user: user, project: project, author: user, target: merge_request) }
+
+ before do
+ build.update!(user: user)
+ project.add_developer(user)
+ end
+
+ it 'resolves the todo for the old failed build' do
+ expect do
+ drop_with_exit_code
+ end.to change { todo.reload.state }.from('pending').to('done')
+ end
+ end
+ end
end
describe '#exit_codes_defined?' do
@@ -5377,7 +5531,8 @@ RSpec.describe Ci::Build do
describe '#doom!' do
subject { build.doom! }
- let_it_be(:build) { create(:ci_build, :queued) }
+ let(:traits) { [] }
+ let(:build) { create(:ci_build, *traits, pipeline: pipeline) }
it 'updates status and failure_reason', :aggregate_failures do
subject
@@ -5386,10 +5541,33 @@ RSpec.describe Ci::Build do
expect(build.failure_reason).to eq("data_integrity_failure")
end
- it 'drops associated pending build' do
+ it 'logs a message' do
+ expect(Gitlab::AppLogger)
+ .to receive(:info)
+ .with(a_hash_including(message: 'Build doomed', class: build.class.name, build_id: build.id))
+ .and_call_original
+
subject
+ end
+
+ context 'with queued builds' do
+ let(:traits) { [:queued] }
+
+ it 'drops associated pending build' do
+ subject
- expect(build.reload.queuing_entry).not_to be_present
+ expect(build.reload.queuing_entry).not_to be_present
+ end
+ end
+
+ context 'with running builds' do
+ let(:traits) { [:picked] }
+
+ it 'drops associated runtime metadata' do
+ subject
+
+ expect(build.reload.runtime_metadata).not_to be_present
+ end
end
end
diff --git a/spec/models/ci/build_trace_chunk_spec.rb b/spec/models/ci/build_trace_chunk_spec.rb
index b6e128c317c..31c7c7a44bc 100644
--- a/spec/models/ci/build_trace_chunk_spec.rb
+++ b/spec/models/ci/build_trace_chunk_spec.rb
@@ -49,9 +49,8 @@ RSpec.describe Ci::BuildTraceChunk, :clean_gitlab_redis_shared_state, :clean_git
end
context 'FastDestroyAll' do
- let(:parent) { create(:project) }
- let(:pipeline) { create(:ci_pipeline, project: parent) }
- let!(:build) { create(:ci_build, :running, :trace_live, pipeline: pipeline, project: parent) }
+ let(:pipeline) { create(:ci_pipeline) }
+ let!(:build) { create(:ci_build, :running, :trace_live, pipeline: pipeline) }
let(:subjects) { build.trace_chunks }
describe 'Forbid #destroy and #destroy_all' do
@@ -84,7 +83,7 @@ RSpec.describe Ci::BuildTraceChunk, :clean_gitlab_redis_shared_state, :clean_git
expect(external_data_counter).to be > 0
expect(subjects.count).to be > 0
- expect { parent.destroy! }.not_to raise_error
+ expect { pipeline.destroy! }.not_to raise_error
expect(subjects.count).to eq(0)
expect(external_data_counter).to eq(0)
@@ -830,7 +829,7 @@ RSpec.describe Ci::BuildTraceChunk, :clean_gitlab_redis_shared_state, :clean_git
expect(described_class.count).to eq(3)
- subject
+ expect(subject).to be_truthy
expect(described_class.count).to eq(0)
@@ -852,7 +851,7 @@ RSpec.describe Ci::BuildTraceChunk, :clean_gitlab_redis_shared_state, :clean_git
context 'when project is destroyed' do
let(:subject) do
- project.destroy!
+ Projects::DestroyService.new(project, project.owner).execute
end
it_behaves_like 'deletes all build_trace_chunk and data in redis'
diff --git a/spec/models/ci/daily_build_group_report_result_spec.rb b/spec/models/ci/daily_build_group_report_result_spec.rb
index acc87c61036..43ba4c32477 100644
--- a/spec/models/ci/daily_build_group_report_result_spec.rb
+++ b/spec/models/ci/daily_build_group_report_result_spec.rb
@@ -164,4 +164,16 @@ RSpec.describe Ci::DailyBuildGroupReportResult do
end
end
end
+
+ it_behaves_like 'cleanup by a loose foreign key' do
+ let!(:model) { create(:ci_daily_build_group_report_result) }
+
+ let!(:parent) { model.group }
+ end
+
+ it_behaves_like 'cleanup by a loose foreign key' do
+ let!(:model) { create(:ci_daily_build_group_report_result) }
+
+ let!(:parent) { model.project }
+ end
end
diff --git a/spec/models/ci/freeze_period_spec.rb b/spec/models/ci/freeze_period_spec.rb
index f7f840c6696..b9bf1657e28 100644
--- a/spec/models/ci/freeze_period_spec.rb
+++ b/spec/models/ci/freeze_period_spec.rb
@@ -5,6 +5,11 @@ require 'spec_helper'
RSpec.describe Ci::FreezePeriod, type: :model do
subject { build(:ci_freeze_period) }
+ it_behaves_like 'cleanup by a loose foreign key' do
+ let!(:parent) { create(:project) }
+ let!(:model) { create(:ci_freeze_period, project: parent) }
+ end
+
let(:invalid_cron) { '0 0 0 * *' }
it { is_expected.to belong_to(:project) }
diff --git a/spec/models/ci/group_variable_spec.rb b/spec/models/ci/group_variable_spec.rb
index f0eec549da7..4cb3b9eef0c 100644
--- a/spec/models/ci/group_variable_spec.rb
+++ b/spec/models/ci/group_variable_spec.rb
@@ -42,4 +42,10 @@ RSpec.describe Ci::GroupVariable do
end
end
end
+
+ it_behaves_like 'cleanup by a loose foreign key' do
+ let!(:model) { create(:ci_group_variable) }
+
+ let!(:parent) { model.group }
+ end
end
diff --git a/spec/models/ci/job_artifact_spec.rb b/spec/models/ci/job_artifact_spec.rb
index 38061e0975f..2e8c41b410a 100644
--- a/spec/models/ci/job_artifact_spec.rb
+++ b/spec/models/ci/job_artifact_spec.rb
@@ -143,6 +143,17 @@ RSpec.describe Ci::JobArtifact do
end
end
+ describe '.erasable_file_types' do
+ subject { described_class.erasable_file_types }
+
+ it 'returns a list of erasable file types' do
+ all_types = described_class.file_types.keys
+ erasable_types = all_types - described_class::NON_ERASABLE_FILE_TYPES
+
+ expect(subject).to contain_exactly(*erasable_types)
+ end
+ end
+
describe '.erasable' do
subject { described_class.erasable }
@@ -534,20 +545,8 @@ RSpec.describe Ci::JobArtifact do
context 'when the artifact is a trace' do
let(:file_type) { :trace }
- context 'when ci_store_trace_outside_transaction is enabled' do
- it 'returns true' do
- expect(artifact.store_after_commit?).to be_truthy
- end
- end
-
- context 'when ci_store_trace_outside_transaction is disabled' do
- before do
- stub_feature_flags(ci_store_trace_outside_transaction: false)
- end
-
- it 'returns false' do
- expect(artifact.store_after_commit?).to be_falsey
- end
+ it 'returns true' do
+ expect(artifact.store_after_commit?).to be_truthy
end
end
diff --git a/spec/models/ci/job_token/project_scope_link_spec.rb b/spec/models/ci/job_token/project_scope_link_spec.rb
index dd6a75dfd89..8d7bb44bd16 100644
--- a/spec/models/ci/job_token/project_scope_link_spec.rb
+++ b/spec/models/ci/job_token/project_scope_link_spec.rb
@@ -9,6 +9,11 @@ RSpec.describe Ci::JobToken::ProjectScopeLink do
let_it_be(:project) { create(:project) }
+ it_behaves_like 'cleanup by a loose foreign key' do
+ let!(:parent) { create(:user) }
+ let!(:model) { create(:ci_job_token_project_scope_link, added_by: parent) }
+ end
+
describe 'unique index' do
let!(:link) { create(:ci_job_token_project_scope_link) }
diff --git a/spec/models/ci/namespace_mirror_spec.rb b/spec/models/ci/namespace_mirror_spec.rb
index b4c71f51377..a9d916115fc 100644
--- a/spec/models/ci/namespace_mirror_spec.rb
+++ b/spec/models/ci/namespace_mirror_spec.rb
@@ -8,50 +8,91 @@ RSpec.describe Ci::NamespaceMirror do
let!(:group3) { create(:group, parent: group2) }
let!(:group4) { create(:group, parent: group3) }
- describe '.sync!' do
- let!(:event) { namespace.sync_events.create! }
+ before do
+ # refreshing ci mirrors according to the parent tree above
+ Namespaces::SyncEvent.find_each { |event| Ci::NamespaceMirror.sync!(event) }
+
+ # checking initial situation. we need to reload to reflect the changes of event sync
+ expect(group1.reload.ci_namespace_mirror).to have_attributes(traversal_ids: [group1.id])
+ expect(group2.reload.ci_namespace_mirror).to have_attributes(traversal_ids: [group1.id, group2.id])
+ expect(group3.reload.ci_namespace_mirror).to have_attributes(traversal_ids: [group1.id, group2.id, group3.id])
+ expect(group4.reload.ci_namespace_mirror).to have_attributes(traversal_ids: [group1.id, group2.id, group3.id, group4.id])
+ end
+
+ context 'scopes' do
+ describe '.contains_namespace' do
+ let_it_be(:another_group) { create(:group) }
+
+ subject(:result) { described_class.contains_namespace(group2.id) }
+
+ it 'returns groups having group2.id in traversal_ids' do
+ expect(result.pluck(:namespace_id)).to contain_exactly(group2.id, group3.id, group4.id)
+ end
+ end
+
+ describe '.contains_any_of_namespaces' do
+ let!(:other_group1) { create(:group) }
+ let!(:other_group2) { create(:group, parent: other_group1) }
+ let!(:other_group3) { create(:group, parent: other_group2) }
+
+ subject(:result) { described_class.contains_any_of_namespaces([group2.id, other_group2.id]) }
+
+ it 'returns groups having group2.id in traversal_ids' do
+ expect(result.pluck(:namespace_id)).to contain_exactly(
+ group2.id, group3.id, group4.id, other_group2.id, other_group3.id
+ )
+ end
+ end
+
+ describe '.by_namespace_id' do
+ subject(:result) { described_class.by_namespace_id(group2.id) }
+
+ it 'returns namesapce mirrors of namespace id' do
+ expect(result).to contain_exactly(group2.ci_namespace_mirror)
+ end
+ end
+ end
- subject(:sync) { described_class.sync!(event.reload) }
+ describe '.sync!' do
+ subject(:sync) { described_class.sync!(Namespaces::SyncEvent.last) }
- context 'when namespace hierarchy does not exist in the first place' do
+ context 'when namespace mirror does not exist in the first place' do
let(:namespace) { group3 }
- it 'creates the hierarchy' do
- expect { sync }.to change { described_class.count }.from(0).to(1)
+ before do
+ namespace.ci_namespace_mirror.destroy!
+ namespace.sync_events.create!
+ end
+
+ it 'creates the mirror' do
+ expect { sync }.to change { described_class.count }.from(3).to(4)
- expect(namespace.ci_namespace_mirror).to have_attributes(traversal_ids: [group1.id, group2.id, group3.id])
+ expect(namespace.reload.ci_namespace_mirror).to have_attributes(traversal_ids: [group1.id, group2.id, group3.id])
end
end
- context 'when namespace hierarchy does already exist' do
+ context 'when namespace mirror does already exist' do
let(:namespace) { group3 }
before do
- described_class.create!(namespace: namespace, traversal_ids: [namespace.id])
+ namespace.sync_events.create!
end
- it 'updates the hierarchy' do
+ it 'updates the mirror' do
expect { sync }.not_to change { described_class.count }
- expect(namespace.ci_namespace_mirror).to have_attributes(traversal_ids: [group1.id, group2.id, group3.id])
+ expect(namespace.reload.ci_namespace_mirror).to have_attributes(traversal_ids: [group1.id, group2.id, group3.id])
end
end
- # I did not extract this context to a `shared_context` because the behavior will change
- # after implementing the TODO in `Ci::NamespaceMirror.sync!`
- context 'changing the middle namespace' do
+ shared_context 'changing the middle namespace' do
let(:namespace) { group2 }
before do
- described_class.create!(namespace_id: group1.id, traversal_ids: [group1.id])
- described_class.create!(namespace_id: group2.id, traversal_ids: [group1.id, group2.id])
- described_class.create!(namespace_id: group3.id, traversal_ids: [group1.id, group2.id, group3.id])
- described_class.create!(namespace_id: group4.id, traversal_ids: [group1.id, group2.id, group3.id, group4.id])
-
- group2.update!(parent: nil)
+ group2.update!(parent: nil) # creates a sync event
end
- it 'updates hierarchies for the base but wait for events for the children' do
+ it 'updates traversal_ids for the base and descendants' do
expect { sync }.not_to change { described_class.count }
expect(group1.reload.ci_namespace_mirror).to have_attributes(traversal_ids: [group1.id])
@@ -61,6 +102,8 @@ RSpec.describe Ci::NamespaceMirror do
end
end
+ it_behaves_like 'changing the middle namespace'
+
context 'when the FFs sync_traversal_ids, use_traversal_ids and use_traversal_ids_for_ancestors are disabled' do
before do
stub_feature_flags(sync_traversal_ids: false,
@@ -68,27 +111,7 @@ RSpec.describe Ci::NamespaceMirror do
use_traversal_ids_for_ancestors: false)
end
- context 'changing the middle namespace' do
- let(:namespace) { group2 }
-
- before do
- described_class.create!(namespace_id: group1.id, traversal_ids: [group1.id])
- described_class.create!(namespace_id: group2.id, traversal_ids: [group1.id, group2.id])
- described_class.create!(namespace_id: group3.id, traversal_ids: [group1.id, group2.id, group3.id])
- described_class.create!(namespace_id: group4.id, traversal_ids: [group1.id, group2.id, group3.id, group4.id])
-
- group2.update!(parent: nil)
- end
-
- it 'updates hierarchies for the base and descendants' do
- expect { sync }.not_to change { described_class.count }
-
- expect(group1.reload.ci_namespace_mirror).to have_attributes(traversal_ids: [group1.id])
- expect(group2.reload.ci_namespace_mirror).to have_attributes(traversal_ids: [group2.id])
- expect(group3.reload.ci_namespace_mirror).to have_attributes(traversal_ids: [group2.id, group3.id])
- expect(group4.reload.ci_namespace_mirror).to have_attributes(traversal_ids: [group2.id, group3.id, group4.id])
- end
- end
+ it_behaves_like 'changing the middle namespace'
end
end
end
diff --git a/spec/models/ci/pending_build_spec.rb b/spec/models/ci/pending_build_spec.rb
index abf0fb443bb..5692444339f 100644
--- a/spec/models/ci/pending_build_spec.rb
+++ b/spec/models/ci/pending_build_spec.rb
@@ -223,4 +223,14 @@ RSpec.describe Ci::PendingBuild do
end
end
end
+
+ it_behaves_like 'cleanup by a loose foreign key' do
+ let!(:parent) { create(:namespace) }
+ let!(:model) { create(:ci_pending_build, namespace: parent) }
+ end
+
+ it_behaves_like 'cleanup by a loose foreign key' do
+ let!(:parent) { create(:project) }
+ let!(:model) { create(:ci_pending_build, project: parent) }
+ end
end
diff --git a/spec/models/ci/pipeline_artifact_spec.rb b/spec/models/ci/pipeline_artifact_spec.rb
index f65483d2290..801505f0231 100644
--- a/spec/models/ci/pipeline_artifact_spec.rb
+++ b/spec/models/ci/pipeline_artifact_spec.rb
@@ -215,4 +215,11 @@ RSpec.describe Ci::PipelineArtifact, type: :model do
end
end
end
+
+ context 'loose foreign key on ci_pipeline_artifacts.project_id' do
+ it_behaves_like 'cleanup by a loose foreign key' do
+ let!(:parent) { create(:project) }
+ let!(:model) { create(:ci_pipeline_artifact, project: parent) }
+ end
+ end
end
diff --git a/spec/models/ci/pipeline_schedule_spec.rb b/spec/models/ci/pipeline_schedule_spec.rb
index fee74f8f674..0f1cb721e95 100644
--- a/spec/models/ci/pipeline_schedule_spec.rb
+++ b/spec/models/ci/pipeline_schedule_spec.rb
@@ -23,6 +23,11 @@ RSpec.describe Ci::PipelineSchedule do
subject { build(:ci_pipeline_schedule, project: project) }
end
+ it_behaves_like 'cleanup by a loose foreign key' do
+ let!(:parent) { create(:user) }
+ let!(:model) { create(:ci_pipeline_schedule, owner: parent) }
+ end
+
describe 'validations' do
it 'does not allow invalid cron patterns' do
pipeline_schedule = build(:ci_pipeline_schedule, cron: '0 0 0 * *')
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index fd9970699d7..90f56c1e0a4 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -31,6 +31,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
it { is_expected.to have_many(:statuses_order_id_desc) }
it { is_expected.to have_many(:bridges) }
it { is_expected.to have_many(:job_artifacts).through(:builds) }
+ it { is_expected.to have_many(:build_trace_chunks).through(:builds) }
it { is_expected.to have_many(:auto_canceled_pipelines) }
it { is_expected.to have_many(:auto_canceled_jobs) }
it { is_expected.to have_many(:sourced_pipelines) }
@@ -1516,30 +1517,12 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
end
describe 'pipeline caching' do
- context 'when expire_job_and_pipeline_cache_synchronously is enabled' do
- before do
- stub_feature_flags(expire_job_and_pipeline_cache_synchronously: true)
- end
-
- it 'executes Ci::ExpirePipelineCacheService' do
- expect_next_instance_of(Ci::ExpirePipelineCacheService) do |service|
- expect(service).to receive(:execute).with(pipeline)
- end
-
- pipeline.cancel
+ it 'executes Ci::ExpirePipelineCacheService' do
+ expect_next_instance_of(Ci::ExpirePipelineCacheService) do |service|
+ expect(service).to receive(:execute).with(pipeline)
end
- end
-
- context 'when expire_job_and_pipeline_cache_synchronously is disabled' do
- before do
- stub_feature_flags(expire_job_and_pipeline_cache_synchronously: false)
- end
-
- it 'performs ExpirePipelinesCacheWorker' do
- expect(ExpirePipelineCacheWorker).to receive(:perform_async).with(pipeline.id)
- pipeline.cancel
- end
+ pipeline.cancel
end
end
@@ -4677,4 +4660,23 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
let!(:model) { create(:ci_pipeline, user: create(:user)) }
let!(:parent) { model.user }
end
+
+ describe 'tags count' do
+ let_it_be_with_refind(:pipeline) do
+ create(:ci_empty_pipeline, project: project)
+ end
+
+ it { expect(pipeline.tags_count).to eq(0) }
+ it { expect(pipeline.distinct_tags_count).to eq(0) }
+
+ context 'with builds' do
+ before do
+ create(:ci_build, pipeline: pipeline, tag_list: %w[a b])
+ create(:ci_build, pipeline: pipeline, tag_list: %w[b c])
+ end
+
+ it { expect(pipeline.tags_count).to eq(4) }
+ it { expect(pipeline.distinct_tags_count).to eq(3) }
+ end
+ end
end
diff --git a/spec/models/ci/project_mirror_spec.rb b/spec/models/ci/project_mirror_spec.rb
index 199285b036c..5ef520b4230 100644
--- a/spec/models/ci/project_mirror_spec.rb
+++ b/spec/models/ci/project_mirror_spec.rb
@@ -8,12 +8,36 @@ RSpec.describe Ci::ProjectMirror do
let!(:project) { create(:project, namespace: group2) }
+ context 'scopes' do
+ let_it_be(:another_project) { create(:project, namespace: group1) }
+
+ describe '.by_project_id' do
+ subject(:result) { described_class.by_project_id(project.id) }
+
+ it 'returns project mirrors of project' do
+ expect(result.pluck(:project_id)).to contain_exactly(project.id)
+ end
+ end
+
+ describe '.by_namespace_id' do
+ subject(:result) { described_class.by_namespace_id(group2.id) }
+
+ it 'returns project mirrors of namespace id' do
+ expect(result).to contain_exactly(project.ci_project_mirror)
+ end
+ end
+ end
+
describe '.sync!' do
let!(:event) { Projects::SyncEvent.create!(project: project) }
- subject(:sync) { described_class.sync!(event.reload) }
+ subject(:sync) { described_class.sync!(event) }
+
+ context 'when project mirror does not exist in the first place' do
+ before do
+ project.ci_project_mirror.destroy!
+ end
- context 'when project hierarchy does not exist in the first place' do
it 'creates a ci_projects record' do
expect { sync }.to change { described_class.count }.from(0).to(1)
@@ -21,11 +45,7 @@ RSpec.describe Ci::ProjectMirror do
end
end
- context 'when project hierarchy does already exist' do
- before do
- described_class.create!(project_id: project.id, namespace_id: group1.id)
- end
-
+ context 'when project mirror does already exist' do
it 'updates the related ci_projects record' do
expect { sync }.not_to change { described_class.count }
diff --git a/spec/models/ci/resource_group_spec.rb b/spec/models/ci/resource_group_spec.rb
index aae16157fbf..76e74f3193c 100644
--- a/spec/models/ci/resource_group_spec.rb
+++ b/spec/models/ci/resource_group_spec.rb
@@ -3,6 +3,11 @@
require 'spec_helper'
RSpec.describe Ci::ResourceGroup do
+ it_behaves_like 'cleanup by a loose foreign key' do
+ let!(:parent) { create(:project) }
+ let!(:model) { create(:ci_resource_group, project: parent) }
+ end
+
describe 'validation' do
it 'valids when key includes allowed character' do
resource_group = build(:ci_resource_group, key: 'test')
diff --git a/spec/models/ci/runner_namespace_spec.rb b/spec/models/ci/runner_namespace_spec.rb
index 41d805adb9f..2d1fe11147c 100644
--- a/spec/models/ci/runner_namespace_spec.rb
+++ b/spec/models/ci/runner_namespace_spec.rb
@@ -6,4 +6,10 @@ RSpec.describe Ci::RunnerNamespace do
it_behaves_like 'includes Limitable concern' do
subject { build(:ci_runner_namespace, group: create(:group, :nested), runner: create(:ci_runner, :group)) }
end
+
+ it_behaves_like 'cleanup by a loose foreign key' do
+ let!(:model) { create(:ci_runner_namespace) }
+
+ let!(:parent) { model.namespace }
+ end
end
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index 5142f70fa2c..6830a8daa3b 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -48,7 +48,7 @@ RSpec.describe Ci::Runner do
let(:runner) { create(:ci_runner, :group, groups: [group]) }
it 'disallows assigning group if already assigned to a group' do
- runner.runner_namespaces << build(:ci_runner_namespace)
+ runner.runner_namespaces << create(:ci_runner_namespace)
expect(runner).not_to be_valid
expect(runner.errors.full_messages).to include('Runner needs to be assigned to exactly one group')
@@ -203,28 +203,56 @@ RSpec.describe Ci::Runner do
end
end
- describe '.belonging_to_parent_group_of_project' do
- let(:project) { create(:project, group: group) }
- let(:group) { create(:group) }
- let(:runner) { create(:ci_runner, :group, groups: [group]) }
- let!(:unrelated_group) { create(:group) }
- let!(:unrelated_project) { create(:project, group: unrelated_group) }
- let!(:unrelated_runner) { create(:ci_runner, :group, groups: [unrelated_group]) }
+ shared_examples '.belonging_to_parent_group_of_project' do
+ let!(:group1) { create(:group) }
+ let!(:project1) { create(:project, group: group1) }
+ let!(:runner1) { create(:ci_runner, :group, groups: [group1]) }
+
+ let!(:group2) { create(:group) }
+ let!(:project2) { create(:project, group: group2) }
+ let!(:runner2) { create(:ci_runner, :group, groups: [group2]) }
+
+ let(:project_id) { project1.id }
+
+ subject(:result) { described_class.belonging_to_parent_group_of_project(project_id) }
it 'returns the specific group runner' do
- expect(described_class.belonging_to_parent_group_of_project(project.id)).to contain_exactly(runner)
+ expect(result).to contain_exactly(runner1)
end
- context 'with a parent group with a runner' do
- let(:runner) { create(:ci_runner, :group, groups: [parent_group]) }
- let(:project) { create(:project, group: group) }
- let(:group) { create(:group, parent: parent_group) }
- let(:parent_group) { create(:group) }
+ context 'with a parent group with a runner', :sidekiq_inline do
+ before do
+ group1.update!(parent: group2)
+ end
- it 'returns the group runner from the parent group' do
- expect(described_class.belonging_to_parent_group_of_project(project.id)).to contain_exactly(runner)
+ it 'returns the group runner from the group and the parent group' do
+ expect(result).to contain_exactly(runner1, runner2)
end
end
+
+ context 'with multiple project ids' do
+ let(:project_id) { [project1.id, project2.id] }
+
+ it 'raises ArgumentError' do
+ expect { result }.to raise_error(ArgumentError)
+ end
+ end
+ end
+
+ context 'when use_traversal_ids* are enabled' do
+ it_behaves_like '.belonging_to_parent_group_of_project'
+ end
+
+ context 'when use_traversal_ids* are disabled' do
+ before do
+ stub_feature_flags(
+ use_traversal_ids: false,
+ use_traversal_ids_for_ancestors: false,
+ use_traversal_ids_for_ancestor_scopes: false
+ )
+ end
+
+ it_behaves_like '.belonging_to_parent_group_of_project'
end
describe '.owned_or_instance_wide' do
@@ -1358,7 +1386,7 @@ RSpec.describe Ci::Runner do
it { is_expected.to eq(contacted_at_stored) }
end
- describe '.belonging_to_group' do
+ describe '.legacy_belonging_to_group' do
shared_examples 'returns group runners' do
it 'returns the specific group runner' do
group = create(:group)
@@ -1366,7 +1394,7 @@ RSpec.describe Ci::Runner do
unrelated_group = create(:group)
create(:ci_runner, :group, groups: [unrelated_group])
- expect(described_class.belonging_to_group(group.id)).to contain_exactly(runner)
+ expect(described_class.legacy_belonging_to_group(group.id)).to contain_exactly(runner)
end
context 'runner belonging to parent group' do
@@ -1376,13 +1404,13 @@ RSpec.describe Ci::Runner do
context 'when include_parent option is passed' do
it 'returns the group runner from the parent group' do
- expect(described_class.belonging_to_group(group.id, include_ancestors: true)).to contain_exactly(parent_runner)
+ expect(described_class.legacy_belonging_to_group(group.id, include_ancestors: true)).to contain_exactly(parent_runner)
end
end
context 'when include_parent option is not passed' do
it 'does not return the group runner from the parent group' do
- expect(described_class.belonging_to_group(group.id)).to be_empty
+ expect(described_class.legacy_belonging_to_group(group.id)).to be_empty
end
end
end
@@ -1398,4 +1426,48 @@ RSpec.describe Ci::Runner do
it_behaves_like 'returns group runners'
end
end
+
+ describe '.belonging_to_group' do
+ it 'returns the specific group runner' do
+ group = create(:group)
+ runner = create(:ci_runner, :group, groups: [group])
+ unrelated_group = create(:group)
+ create(:ci_runner, :group, groups: [unrelated_group])
+
+ expect(described_class.belonging_to_group(group.id)).to contain_exactly(runner)
+ end
+ end
+
+ describe '.belonging_to_group_and_ancestors' do
+ let_it_be(:parent_group) { create(:group) }
+ let_it_be(:parent_runner) { create(:ci_runner, :group, groups: [parent_group]) }
+ let_it_be(:group) { create(:group, parent: parent_group) }
+
+ it 'returns the group runner from the parent group' do
+ expect(described_class.belonging_to_group_and_ancestors(group.id)).to contain_exactly(parent_runner)
+ end
+ end
+
+ describe '.belonging_to_group_or_project_descendants' do
+ it 'returns the specific group runners' do
+ group1 = create(:group)
+ group2 = create(:group, parent: group1)
+ group3 = create(:group)
+
+ project1 = create(:project, namespace: group1)
+ project2 = create(:project, namespace: group2)
+ project3 = create(:project, namespace: group3)
+
+ runner1 = create(:ci_runner, :group, groups: [group1])
+ runner2 = create(:ci_runner, :group, groups: [group2])
+ _runner3 = create(:ci_runner, :group, groups: [group3])
+ runner4 = create(:ci_runner, :project, projects: [project1])
+ runner5 = create(:ci_runner, :project, projects: [project2])
+ _runner6 = create(:ci_runner, :project, projects: [project3])
+
+ expect(described_class.belonging_to_group_or_project_descendants(group1.id)).to contain_exactly(
+ runner1, runner2, runner4, runner5
+ )
+ end
+ end
end
diff --git a/spec/models/ci/running_build_spec.rb b/spec/models/ci/running_build_spec.rb
index 629861e35b8..d2f74494308 100644
--- a/spec/models/ci/running_build_spec.rb
+++ b/spec/models/ci/running_build_spec.rb
@@ -49,4 +49,9 @@ RSpec.describe Ci::RunningBuild do
end
end
end
+
+ it_behaves_like 'cleanup by a loose foreign key' do
+ let!(:parent) { create(:project) }
+ let!(:model) { create(:ci_running_build, project: parent) }
+ end
end
diff --git a/spec/models/ci/secure_file_spec.rb b/spec/models/ci/secure_file_spec.rb
new file mode 100644
index 00000000000..ae57b63e7a4
--- /dev/null
+++ b/spec/models/ci/secure_file_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::SecureFile do
+ let(:sample_file) { fixture_file('ci_secure_files/upload-keystore.jks') }
+
+ subject { create(:ci_secure_file) }
+
+ before do
+ stub_ci_secure_file_object_storage
+ end
+
+ it { is_expected.to be_a FileStoreMounter }
+
+ it { is_expected.to belong_to(:project).required }
+
+ it_behaves_like 'having unique enum values'
+
+ describe 'validations' do
+ it { is_expected.to validate_presence_of(:checksum) }
+ it { is_expected.to validate_presence_of(:file_store) }
+ it { is_expected.to validate_presence_of(:name) }
+ it { is_expected.to validate_presence_of(:permissions) }
+ it { is_expected.to validate_presence_of(:project_id) }
+ end
+
+ describe '#permissions' do
+ it 'defaults to read_only file permssions' do
+ expect(subject.permissions).to eq('read_only')
+ end
+ end
+
+ describe '#checksum' do
+ it 'computes SHA256 checksum on the file before encrypted' do
+ subject.file = CarrierWaveStringFile.new(sample_file)
+ subject.save!
+ expect(subject.checksum).to eq(Digest::SHA256.hexdigest(sample_file))
+ end
+ end
+
+ describe '#checksum_algorithm' do
+ it 'returns the configured checksum_algorithm' do
+ expect(subject.checksum_algorithm).to eq('sha256')
+ end
+ end
+
+ describe '#file' do
+ it 'returns the saved file' do
+ subject.file = CarrierWaveStringFile.new(sample_file)
+ subject.save!
+ expect(Base64.encode64(subject.file.read)).to eq(Base64.encode64(sample_file))
+ end
+ end
+end
diff --git a/spec/models/ci/unit_test_spec.rb b/spec/models/ci/unit_test_spec.rb
index 2207a362be3..556cf93c266 100644
--- a/spec/models/ci/unit_test_spec.rb
+++ b/spec/models/ci/unit_test_spec.rb
@@ -3,6 +3,11 @@
require 'spec_helper'
RSpec.describe Ci::UnitTest do
+ it_behaves_like 'cleanup by a loose foreign key' do
+ let!(:parent) { create(:project) }
+ let!(:model) { create(:ci_unit_test, project: parent) }
+ end
+
describe 'relationships' do
it { is_expected.to belong_to(:project) }
it { is_expected.to have_many(:unit_test_failures) }
diff --git a/spec/models/clusters/agent_spec.rb b/spec/models/clusters/agent_spec.rb
index 3b521086c14..f279e779de5 100644
--- a/spec/models/clusters/agent_spec.rb
+++ b/spec/models/clusters/agent_spec.rb
@@ -76,12 +76,12 @@ RSpec.describe Clusters::Agent do
end
end
- describe '#active?' do
+ describe '#connected?' do
let_it_be(:agent) { create(:cluster_agent) }
let!(:token) { create(:cluster_agent_token, agent: agent, last_used_at: last_used_at) }
- subject { agent.active? }
+ subject { agent.connected? }
context 'agent has never connected' do
let(:last_used_at) { nil }
@@ -99,6 +99,14 @@ RSpec.describe Clusters::Agent do
let(:last_used_at) { 2.minutes.ago }
it { is_expected.to be_truthy }
+
+ context 'agent token has been revoked' do
+ before do
+ token.revoked!
+ end
+
+ it { is_expected.to be_falsey }
+ end
end
context 'agent has multiple tokens' do
@@ -108,4 +116,19 @@ RSpec.describe Clusters::Agent do
it { is_expected.to be_truthy }
end
end
+
+ describe '#activity_event_deletion_cutoff' do
+ let_it_be(:agent) { create(:cluster_agent) }
+ let_it_be(:event1) { create(:agent_activity_event, agent: agent, recorded_at: 1.hour.ago) }
+ let_it_be(:event2) { create(:agent_activity_event, agent: agent, recorded_at: 2.hours.ago) }
+ let_it_be(:event3) { create(:agent_activity_event, agent: agent, recorded_at: 3.hours.ago) }
+
+ subject { agent.activity_event_deletion_cutoff }
+
+ before do
+ stub_const("#{described_class}::ACTIVITY_EVENT_LIMIT", 2)
+ end
+
+ it { is_expected.to be_like_time(event2.recorded_at) }
+ end
end
diff --git a/spec/models/clusters/agent_token_spec.rb b/spec/models/clusters/agent_token_spec.rb
index ad9f948224f..efa2a3eb09b 100644
--- a/spec/models/clusters/agent_token_spec.rb
+++ b/spec/models/clusters/agent_token_spec.rb
@@ -9,17 +9,29 @@ RSpec.describe Clusters::AgentToken do
it { is_expected.to validate_length_of(:name).is_at_most(255) }
it { is_expected.to validate_presence_of(:name) }
+ it_behaves_like 'having unique enum values'
+
describe 'scopes' do
describe '.order_last_used_at_desc' do
- let_it_be(:token_1) { create(:cluster_agent_token, last_used_at: 7.days.ago) }
- let_it_be(:token_2) { create(:cluster_agent_token, last_used_at: nil) }
- let_it_be(:token_3) { create(:cluster_agent_token, last_used_at: 2.days.ago) }
+ let_it_be(:agent) { create(:cluster_agent) }
+ let_it_be(:token_1) { create(:cluster_agent_token, agent: agent, last_used_at: 7.days.ago) }
+ let_it_be(:token_2) { create(:cluster_agent_token, agent: agent, last_used_at: nil) }
+ let_it_be(:token_3) { create(:cluster_agent_token, agent: agent, last_used_at: 2.days.ago) }
it 'sorts by last_used_at descending, with null values at last' do
expect(described_class.order_last_used_at_desc)
.to eq([token_3, token_1, token_2])
end
end
+
+ describe '.with_status' do
+ let!(:active_token) { create(:cluster_agent_token) }
+ let!(:revoked_token) { create(:cluster_agent_token, :revoked) }
+
+ subject { described_class.with_status(:active) }
+
+ it { is_expected.to contain_exactly(active_token) }
+ end
end
describe '#token' do
@@ -37,83 +49,4 @@ RSpec.describe Clusters::AgentToken do
expect(agent_token.token.length).to be >= 50
end
end
-
- describe '#track_usage', :clean_gitlab_redis_cache do
- let_it_be(:agent) { create(:cluster_agent) }
-
- let(:agent_token) { create(:cluster_agent_token, agent: agent) }
-
- subject { agent_token.track_usage }
-
- context 'when last_used_at was updated recently' do
- before do
- agent_token.update!(last_used_at: 10.minutes.ago)
- end
-
- it 'updates cache but not database' do
- expect { subject }.not_to change { agent_token.reload.read_attribute(:last_used_at) }
-
- expect_redis_update
- end
- end
-
- context 'when last_used_at was not updated recently' do
- it 'updates cache and database' do
- does_db_update
- expect_redis_update
- end
-
- context 'with invalid token' do
- before do
- agent_token.description = SecureRandom.hex(2000)
- end
-
- it 'still updates caches and database' do
- expect(agent_token).to be_invalid
-
- does_db_update
- expect_redis_update
- end
- end
-
- context 'agent is inactive' do
- before do
- allow(agent).to receive(:active?).and_return(false)
- end
-
- it 'creates an activity event' do
- expect { subject }.to change { agent.activity_events.count }
-
- event = agent.activity_events.last
- expect(event).to have_attributes(
- kind: 'agent_connected',
- level: 'info',
- recorded_at: agent_token.reload.read_attribute(:last_used_at),
- agent_token: agent_token
- )
- end
- end
-
- context 'agent is active' do
- before do
- allow(agent).to receive(:active?).and_return(true)
- end
-
- it 'does not create an activity event' do
- expect { subject }.not_to change { agent.activity_events.count }
- end
- end
- end
-
- def expect_redis_update
- Gitlab::Redis::Cache.with do |redis|
- redis_key = "cache:#{described_class.name}:#{agent_token.id}:attributes"
- expect(redis.get(redis_key)).to be_present
- end
- end
-
- def does_db_update
- expect { subject }.to change { agent_token.reload.read_attribute(:last_used_at) }
- end
- end
end
diff --git a/spec/models/clusters/agents/activity_event_spec.rb b/spec/models/clusters/agents/activity_event_spec.rb
index 18b9c82fa6a..2e3833898fd 100644
--- a/spec/models/clusters/agents/activity_event_spec.rb
+++ b/spec/models/clusters/agents/activity_event_spec.rb
@@ -16,11 +16,10 @@ RSpec.describe Clusters::Agents::ActivityEvent do
let_it_be(:agent) { create(:cluster_agent) }
describe '.in_timeline_order' do
- let(:recorded_at) { 1.hour.ago }
-
- let!(:event1) { create(:agent_activity_event, agent: agent, recorded_at: recorded_at) }
- let!(:event2) { create(:agent_activity_event, agent: agent, recorded_at: Time.current) }
- let!(:event3) { create(:agent_activity_event, agent: agent, recorded_at: recorded_at) }
+ let_it_be(:recorded_at) { 1.hour.ago }
+ let_it_be(:event1) { create(:agent_activity_event, agent: agent, recorded_at: recorded_at) }
+ let_it_be(:event2) { create(:agent_activity_event, agent: agent, recorded_at: Time.current) }
+ let_it_be(:event3) { create(:agent_activity_event, agent: agent, recorded_at: recorded_at) }
subject { described_class.in_timeline_order }
@@ -28,5 +27,19 @@ RSpec.describe Clusters::Agents::ActivityEvent do
is_expected.to eq([event2, event3, event1])
end
end
+
+ describe '.recorded_before' do
+ let_it_be(:event1) { create(:agent_activity_event, agent: agent, recorded_at: 1.hour.ago) }
+ let_it_be(:event2) { create(:agent_activity_event, agent: agent, recorded_at: 2.hours.ago) }
+ let_it_be(:event3) { create(:agent_activity_event, agent: agent, recorded_at: 3.hours.ago) }
+
+ let(:cutoff) { event2.recorded_at }
+
+ subject { described_class.recorded_before(cutoff) }
+
+ it 'returns only events recorded before the cutoff' do
+ is_expected.to contain_exactly(event3)
+ end
+ end
end
end
diff --git a/spec/models/clusters/applications/runner_spec.rb b/spec/models/clusters/applications/runner_spec.rb
index 434d7ad4a90..8f02161843b 100644
--- a/spec/models/clusters/applications/runner_spec.rb
+++ b/spec/models/clusters/applications/runner_spec.rb
@@ -101,19 +101,6 @@ RSpec.describe Clusters::Applications::Runner do
end
end
- describe '#prepare_uninstall' do
- it 'pauses associated runner' do
- active_runner = create(:ci_runner, contacted_at: 1.second.ago)
-
- expect(active_runner.active).to be_truthy
-
- application_runner = create(:clusters_applications_runner, :scheduled, runner: active_runner)
- application_runner.prepare_uninstall
-
- expect(active_runner.active).to be_falsey
- end
- end
-
describe '#make_uninstalling!' do
subject { create(:clusters_applications_runner, :scheduled, runner: ci_runner) }
diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb
index 665a2a936af..d5e74d36b58 100644
--- a/spec/models/commit_status_spec.rb
+++ b/spec/models/commit_status_spec.rb
@@ -46,28 +46,10 @@ RSpec.describe CommitStatus do
describe 'status state machine' do
let!(:commit_status) { create(:commit_status, :running, project: project) }
- context 'when expire_job_and_pipeline_cache_synchronously is enabled' do
- before do
- stub_feature_flags(expire_job_and_pipeline_cache_synchronously: true)
- end
-
- it 'invalidates the cache after a transition' do
- expect(commit_status).to receive(:expire_etag_cache!)
+ it 'invalidates the cache after a transition' do
+ expect(commit_status).to receive(:expire_etag_cache!)
- commit_status.success!
- end
- end
-
- context 'when expire_job_and_pipeline_cache_synchronously is disabled' do
- before do
- stub_feature_flags(expire_job_and_pipeline_cache_synchronously: false)
- end
-
- it 'invalidates the cache after a transition' do
- expect(ExpireJobCacheWorker).to receive(:perform_async).with(commit_status.id)
-
- commit_status.success!
- end
+ commit_status.success!
end
describe 'transitioning to running' do
@@ -773,6 +755,26 @@ RSpec.describe CommitStatus do
expect { commit_status.drop! }.to change { commit_status.status }.from('manual').to('failed')
end
end
+
+ context 'when a failure reason is provided' do
+ context 'when a failure reason is a symbol' do
+ it 'correctly sets a failure reason' do
+ commit_status.drop!(:script_failure)
+
+ expect(commit_status).to be_script_failure
+ end
+ end
+
+ context 'when a failure reason is an object' do
+ it 'correctly sets a failure reason' do
+ reason = ::Gitlab::Ci::Build::Status::Reason.new(commit_status, :script_failure)
+
+ commit_status.drop!(reason)
+
+ expect(commit_status).to be_script_failure
+ end
+ end
+ end
end
describe 'ensure stage assignment' do
@@ -961,18 +963,17 @@ RSpec.describe CommitStatus do
describe '.bulk_insert_tags!' do
let(:statuses) { double('statuses') }
- let(:tag_list_by_build) { double('tag list') }
let(:inserter) { double('inserter') }
it 'delegates to bulk insert class' do
expect(Gitlab::Ci::Tags::BulkInsert)
.to receive(:new)
- .with(statuses, tag_list_by_build)
+ .with(statuses)
.and_return(inserter)
expect(inserter).to receive(:insert!)
- described_class.bulk_insert_tags!(statuses, tag_list_by_build)
+ described_class.bulk_insert_tags!(statuses)
end
end
diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb
index 2a3f639a8ac..e9c3d1dc646 100644
--- a/spec/models/concerns/issuable_spec.rb
+++ b/spec/models/concerns/issuable_spec.rb
@@ -922,6 +922,22 @@ RSpec.describe Issuable do
end
end
+ describe '#supports_escalation?' do
+ where(:issuable_type, :supports_escalation) do
+ :issue | false
+ :incident | true
+ :merge_request | false
+ end
+
+ with_them do
+ let(:issuable) { build_stubbed(issuable_type) }
+
+ subject { issuable.supports_escalation? }
+
+ it { is_expected.to eq(supports_escalation) }
+ end
+ end
+
describe '#incident?' do
where(:issuable_type, :incident) do
:issue | false
diff --git a/spec/models/concerns/participable_spec.rb b/spec/models/concerns/participable_spec.rb
index 50cf7377b99..99a3a0fb79a 100644
--- a/spec/models/concerns/participable_spec.rb
+++ b/spec/models/concerns/participable_spec.rb
@@ -138,7 +138,7 @@ RSpec.describe Participable do
allow(instance).to receive_message_chain(:model_name, :element) { 'class' }
expect(instance).to receive(:foo).and_return(user2)
expect(instance).to receive(:bar).and_return(user3)
- expect(instance).to receive(:project).thrice.and_return(project)
+ expect(instance).to receive(:project).twice.and_return(project)
participants = instance.visible_participants(user1)
@@ -159,31 +159,10 @@ RSpec.describe Participable do
allow(instance).to receive_message_chain(:model_name, :element) { 'class' }
allow(instance).to receive(:bar).and_return(user2)
- expect(instance).to receive(:project).thrice.and_return(project)
+ expect(instance).to receive(:project).twice.and_return(project)
expect(instance.visible_participants(user1)).to be_empty
end
-
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(verify_participants_access: false)
- end
-
- it 'returns unavailable participants' do
- model.participant(:bar)
-
- instance = model.new
- user1 = build(:user)
- user2 = build(:user)
- project = build(:project, :public)
-
- allow(instance).to receive_message_chain(:model_name, :element) { 'class' }
- allow(instance).to receive(:bar).and_return(user2)
- expect(instance).to receive(:project).thrice.and_return(project)
-
- expect(instance.visible_participants(user1)).to match_array([user2])
- end
- end
end
end
diff --git a/spec/models/concerns/routable_spec.rb b/spec/models/concerns/routable_spec.rb
index 2330147b376..cf66ba83e87 100644
--- a/spec/models/concerns/routable_spec.rb
+++ b/spec/models/concerns/routable_spec.rb
@@ -141,6 +141,11 @@ RSpec.describe Group, 'Routable', :with_clean_rails_cache do
end
end
+ it 'creates route with namespace referencing group' do
+ expect(group.route).not_to be_nil
+ expect(group.route.namespace).to eq(group)
+ end
+
describe '.where_full_path_in' do
context 'without any paths' do
it 'returns an empty relation' do
@@ -208,30 +213,20 @@ RSpec.describe Project, 'Routable', :with_clean_rails_cache do
it_behaves_like 'routable resource with parent' do
let_it_be(:record) { project }
end
+
+ it 'creates route with namespace referencing project namespace' do
+ expect(project.route).not_to be_nil
+ expect(project.route.namespace).to eq(project.project_namespace)
+ end
end
RSpec.describe Namespaces::ProjectNamespace, 'Routable', :with_clean_rails_cache do
let_it_be(:group) { create(:group) }
- let_it_be(:project_namespace) do
- # For now we create only project namespace w/o project, otherwise same path
- # would be used for project and project namespace.
- # This can be removed when route is created automatically for project namespaces.
- # https://gitlab.com/gitlab-org/gitlab/-/issues/346448
- create(:project_namespace, project: nil, parent: group,
- visibility_level: Gitlab::VisibilityLevel::PUBLIC,
- path: 'foo', name: 'foo').tap do |project_namespace|
- Route.create!(source: project_namespace, path: project_namespace.full_path,
- name: project_namespace.full_name)
- end
- end
-
- # we have couple of places where we use generic Namespace, in that case
- # we don't want to include ProjectNamespace routes yet
- it 'ignores project namespace when searching for generic namespace' do
- redirect_route = create(:redirect_route, source: project_namespace)
- expect(Namespace.find_by_full_path(project_namespace.full_path)).to be_nil
- expect(Namespace.find_by_full_path(redirect_route.path, follow_redirects: true)).to be_nil
+ it 'skips route creation for the resource' do
+ expect do
+ described_class.create!(project: nil, parent: group, visibility_level: Gitlab::VisibilityLevel::PUBLIC, path: 'foo', name: 'foo')
+ end.not_to change { Route.count }
end
end
diff --git a/spec/models/concerns/triggerable_hooks_spec.rb b/spec/models/concerns/triggerable_hooks_spec.rb
index 10a6c1aa821..90c88c888ff 100644
--- a/spec/models/concerns/triggerable_hooks_spec.rb
+++ b/spec/models/concerns/triggerable_hooks_spec.rb
@@ -46,7 +46,7 @@ RSpec.describe TriggerableHooks do
describe '.select_active' do
it 'returns hooks that match the active filter' do
TestableHook.create!(url: 'http://example1.com', push_events: true)
- TestableHook.create!(url: 'http://example2.com', push_events: true)
+ TestableHook.create!(url: 'http://example.org', push_events: true)
filter1 = double(:filter1)
filter2 = double(:filter2)
allow(ActiveHookFilter).to receive(:new).twice.and_return(filter1, filter2)
diff --git a/spec/models/container_repository_spec.rb b/spec/models/container_repository_spec.rb
index 51fdbfebd3a..8f7c13d7ae6 100644
--- a/spec/models/container_repository_spec.rb
+++ b/spec/models/container_repository_spec.rb
@@ -25,12 +25,20 @@ RSpec.describe ContainerRepository do
headers: { 'Content-Type' => 'application/json' })
end
+ it_behaves_like 'having unique enum values'
+
describe 'associations' do
it 'belongs to the project' do
expect(repository).to belong_to(:project)
end
end
+ describe 'validations' do
+ it { is_expected.to validate_presence_of(:migration_retries_count) }
+ it { is_expected.to validate_numericality_of(:migration_retries_count).is_greater_than_or_equal_to(0) }
+ it { is_expected.to validate_presence_of(:migration_state) }
+ end
+
describe '#tag' do
it 'has a test tag' do
expect(repository.tag('test')).not_to be_nil
diff --git a/spec/models/customer_relations/contact_spec.rb b/spec/models/customer_relations/contact_spec.rb
index 7e26d324ac2..1225f9d089b 100644
--- a/spec/models/customer_relations/contact_spec.rb
+++ b/spec/models/customer_relations/contact_spec.rb
@@ -26,6 +26,38 @@ RSpec.describe CustomerRelations::Contact, type: :model do
it_behaves_like 'an object with RFC3696 compliant email-formatted attributes', :email
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
+ 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) }
+
+ it { is_expected.to be_invalid }
+ end
+ end
+
describe '#before_validation' do
it 'strips leading and trailing whitespace' do
contact = described_class.new(first_name: ' First ', last_name: ' Last ', phone: ' 123456 ')
@@ -43,20 +75,27 @@ RSpec.describe CustomerRelations::Contact, type: :model do
let_it_be(:other_contacts) { create_list(:contact, 2) }
it 'returns ids of contacts from group' do
- contact_ids = described_class.find_ids_by_emails(group.id, group_contacts.pluck(:email))
+ contact_ids = described_class.find_ids_by_emails(group, group_contacts.pluck(:email))
+
+ 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.id, other_contacts.pluck(:email))
+ contact_ids = described_class.find_ids_by_emails(group, other_contacts.pluck(:email))
expect(contact_ids).to be_empty
end
it 'raises ArgumentError when called with too many emails' do
too_many_emails = described_class::MAX_PLUCK + 1
- expect { described_class.find_ids_by_emails(group.id, Array(0..too_many_emails)) }.to raise_error(ArgumentError)
+ expect { described_class.find_ids_by_emails(group, Array(0..too_many_emails)) }.to raise_error(ArgumentError)
end
end
end
diff --git a/spec/models/customer_relations/issue_contact_spec.rb b/spec/models/customer_relations/issue_contact_spec.rb
index 474455a9884..c6373fddbfb 100644
--- a/spec/models/customer_relations/issue_contact_spec.rb
+++ b/spec/models/customer_relations/issue_contact_spec.rb
@@ -5,7 +5,8 @@ require 'spec_helper'
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(:project) { create(:project, group: group) }
+ let_it_be(:subgroup) { create(:group, parent: group) }
+ let_it_be(:project) { create(:project, group: subgroup) }
let_it_be(:issue) { create(:issue, project: project) }
subject { issue_contact }
@@ -33,17 +34,29 @@ RSpec.describe CustomerRelations::IssueContact do
end
it 'builds using the same group', :aggregate_failures do
- expect(for_issue.contact.group).to eq(group)
+ expect(for_issue.contact.group).to eq(subgroup)
expect(for_contact.issue.project.group).to eq(group)
end
end
describe 'validation' do
- let(:built) { build(:issue_customer_relations_contact, issue: create(:issue), contact: create(:contact)) }
+ it 'fails when the contact group does not belong to the issue group or ancestors' do
+ built = build(:issue_customer_relations_contact, issue: create(:issue), contact: create(:contact))
- it 'fails when the contact group does not match the issue group' do
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))
+
+ 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))
+
+ expect(built).to be_valid
+ end
end
describe '#self.find_contact_ids_by_emails' do
diff --git a/spec/models/dependency_proxy/blob_spec.rb b/spec/models/dependency_proxy/blob_spec.rb
index 3c54d3126a8..10d06406ad7 100644
--- a/spec/models/dependency_proxy/blob_spec.rb
+++ b/spec/models/dependency_proxy/blob_spec.rb
@@ -3,6 +3,7 @@ require 'spec_helper'
RSpec.describe DependencyProxy::Blob, type: :model do
it_behaves_like 'ttl_expirable'
+ it_behaves_like 'destructible', factory: :dependency_proxy_blob
describe 'relationships' do
it { is_expected.to belong_to(:group) }
diff --git a/spec/models/dependency_proxy/manifest_spec.rb b/spec/models/dependency_proxy/manifest_spec.rb
index 59415096989..ab7881b1d39 100644
--- a/spec/models/dependency_proxy/manifest_spec.rb
+++ b/spec/models/dependency_proxy/manifest_spec.rb
@@ -3,6 +3,7 @@ require 'spec_helper'
RSpec.describe DependencyProxy::Manifest, type: :model do
it_behaves_like 'ttl_expirable'
+ it_behaves_like 'destructible', factory: :dependency_proxy_manifest
describe 'relationships' do
it { is_expected.to belong_to(:group) }
diff --git a/spec/models/email_spec.rb b/spec/models/email_spec.rb
index 59299a507e4..b76063bfa1a 100644
--- a/spec/models/email_spec.rb
+++ b/spec/models/email_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe Email do
end
describe 'validations' do
- it_behaves_like 'an object with RFC3696 compliant email-formatted attributes', :email do
+ it_behaves_like 'an object with email-formatted attributes', :email do
subject { build(:email) }
end
@@ -71,4 +71,84 @@ RSpec.describe Email do
end
end
end
+
+ describe '#confirm' do
+ let(:expired_confirmation_sent_at) { Date.today - described_class.confirm_within - 7.days }
+ let(:extant_confirmation_sent_at) { Date.today }
+
+ let(:email) do
+ create(:email, email: 'test@gitlab.com').tap do |email|
+ email.update!(confirmation_sent_at: confirmation_sent_at)
+ end
+ end
+
+ shared_examples_for 'unconfirmed email' do
+ it 'returns unconfirmed' do
+ expect(email.confirmed?).to be_falsey
+ end
+ end
+
+ context 'when the confirmation period has expired' do
+ let(:confirmation_sent_at) { expired_confirmation_sent_at }
+
+ it_behaves_like 'unconfirmed email'
+
+ it 'does not confirm the email' do
+ email.confirm
+
+ expect(email.confirmed?).to be_falsey
+ end
+ end
+
+ context 'when the confirmation period has not expired' do
+ let(:confirmation_sent_at) { extant_confirmation_sent_at }
+
+ it_behaves_like 'unconfirmed email'
+
+ it 'confirms the email' do
+ email.confirm
+
+ expect(email.confirmed?).to be_truthy
+ 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 }
+
+ let(:email) do
+ create(:email, email: 'test@gitlab.com').tap do |email|
+ email.update!(confirmation_sent_at: confirmation_sent_at)
+ end
+ end
+
+ shared_examples_for 'unconfirmed email' do
+ it 'returns unconfirmed' do
+ expect(email.confirmed?).to be_falsey
+ end
+ end
+
+ shared_examples_for 'confirms the email on force_confirm' do
+ it 'confirms an email' do
+ email.force_confirm
+
+ expect(email.reload.confirmed?).to be_truthy
+ end
+ end
+
+ context 'when the confirmation period has expired' do
+ let(:confirmation_sent_at) { expired_confirmation_sent_at }
+
+ it_behaves_like 'unconfirmed email'
+ it_behaves_like 'confirms the email on force_confirm'
+ end
+
+ context 'when the confirmation period has not expired' do
+ let(:confirmation_sent_at) { extant_confirmation_sent_at }
+
+ it_behaves_like 'unconfirmed email'
+ it_behaves_like 'confirms the email on force_confirm'
+ end
+ end
end
diff --git a/spec/models/experiment_spec.rb b/spec/models/experiment_spec.rb
index ea5d2b27028..de6ce3ba053 100644
--- a/spec/models/experiment_spec.rb
+++ b/spec/models/experiment_spec.rb
@@ -235,6 +235,54 @@ RSpec.describe Experiment do
end
end
+ describe '#record_conversion_event_for_subject' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:experiment) { create(:experiment) }
+ let_it_be(:context) { { a: 42 } }
+
+ subject(:record_conversion) { experiment.record_conversion_event_for_subject(user, context) }
+
+ context 'when no existing experiment_subject record exists for the given user' do
+ it 'does not update or create an experiment_subject record' do
+ expect { record_conversion }.not_to change { ExperimentSubject.all.to_a }
+ end
+ end
+
+ context 'when an existing experiment_subject exists for the given user' do
+ context 'but it has already been converted' do
+ let(:experiment_subject) { create(:experiment_subject, experiment: experiment, user: user, converted_at: 2.days.ago) }
+
+ it 'does not update the converted_at value' do
+ expect { record_conversion }.not_to change { experiment_subject.converted_at }
+ end
+ end
+
+ context 'and it has not yet been converted' do
+ let(:experiment_subject) { create(:experiment_subject, experiment: experiment, user: user) }
+
+ it 'updates the converted_at value' do
+ expect { record_conversion }.to change { experiment_subject.reload.converted_at }
+ end
+ end
+
+ context 'with no existing context' do
+ let(:experiment_subject) { create(:experiment_subject, experiment: experiment, user: user) }
+
+ it 'updates the context' do
+ expect { record_conversion }.to change { experiment_subject.reload.context }.to('a' => 42)
+ end
+ end
+
+ context 'with an existing context' do
+ let(:experiment_subject) { create(:experiment_subject, experiment: experiment, user: user, converted_at: 2.days.ago, context: { b: 1 } ) }
+
+ it 'merges the context' do
+ expect { record_conversion }.to change { experiment_subject.reload.context }.to('a' => 42, 'b' => 1)
+ end
+ end
+ end
+ end
+
describe '#record_subject_and_variant!' do
let_it_be(:subject_to_record) { create(:group) }
let_it_be(:variant) { :control }
diff --git a/spec/models/group/crm_settings_spec.rb b/spec/models/group/crm_settings_spec.rb
new file mode 100644
index 00000000000..35fcdca6389
--- /dev/null
+++ b/spec/models/group/crm_settings_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Group::CrmSettings do
+ describe 'associations' do
+ it { is_expected.to belong_to(:group) }
+ end
+
+ describe 'validations' do
+ subject { build(:crm_settings) }
+
+ it { is_expected.to validate_presence_of(:group) }
+ end
+end
diff --git a/spec/models/group_group_link_spec.rb b/spec/models/group_group_link_spec.rb
index 03cc9d7e64c..034a5c1dfc6 100644
--- a/spec/models/group_group_link_spec.rb
+++ b/spec/models/group_group_link_spec.rb
@@ -29,32 +29,6 @@ RSpec.describe GroupGroupLink do
])
end
end
-
- describe '.public_or_visible_to_user' do
- let!(:user_with_access) { create :user }
- let!(:user_without_access) { create :user }
- let!(:shared_with_group) { create :group, :private }
- let!(:shared_group) { create :group }
- let!(:private_group_group_link) { create(:group_group_link, shared_group: shared_group, shared_with_group: shared_with_group) }
-
- before do
- shared_group.add_owner(user_with_access)
- shared_group.add_owner(user_without_access)
- shared_with_group.add_developer(user_with_access)
- end
-
- context 'when user can access shared group' do
- it 'returns the private group' do
- expect(described_class.public_or_visible_to_user(shared_group, user_with_access)).to include(private_group_group_link)
- end
- end
-
- context 'when user does not have access to shared group' do
- it 'does not return private group' do
- expect(described_class.public_or_visible_to_user(shared_group, user_without_access)).not_to include(private_group_group_link)
- end
- end
- end
end
describe 'validation' do
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index fed4ee3f3a4..05ee2166245 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe Group do
include ReloadHelpers
+ include StubGitlabCalls
let!(:group) { create(:group) }
@@ -39,6 +40,7 @@ RSpec.describe Group do
it { is_expected.to have_many(:bulk_import_exports).class_name('BulkImports::Export') }
it { is_expected.to have_many(:contacts).class_name('CustomerRelations::Contact') }
it { is_expected.to have_many(:organizations).class_name('CustomerRelations::Organization') }
+ it { is_expected.to have_one(:crm_settings) }
describe '#members & #requesters' do
let(:requester) { create(:user) }
@@ -63,6 +65,7 @@ RSpec.describe Group do
describe 'validations' do
it { is_expected.to validate_presence_of :name }
+ it { is_expected.not_to allow_value('colon:in:path').for(:path) } # This is to validate that a specially crafted name cannot bypass a pattern match. See !72555
it { is_expected.to allow_value('group test_4').for(:name) }
it { is_expected.not_to allow_value('test/../foo').for(:name) }
it { is_expected.not_to allow_value('<script>alert("Attack!")</script>').for(:name) }
@@ -502,6 +505,10 @@ RSpec.describe Group do
it { expect(group.descendants.to_sql).not_to include 'traversal_ids @>' }
end
+ describe '#self_and_hierarchy' do
+ it { expect(group.self_and_hierarchy.to_sql).not_to include 'traversal_ids @>' }
+ end
+
describe '#ancestors' do
it { expect(group.ancestors.to_sql).not_to include 'traversal_ids <@' }
end
@@ -526,6 +533,10 @@ RSpec.describe Group do
it { expect(group.descendants.to_sql).to include 'traversal_ids @>' }
end
+ describe '#self_and_hierarchy' do
+ it { expect(group.self_and_hierarchy.to_sql).to include 'traversal_ids @>' }
+ end
+
describe '#ancestors' do
it { expect(group.ancestors.to_sql).to include "\"namespaces\".\"id\" = #{group.parent_id}" }
@@ -670,6 +681,26 @@ RSpec.describe Group do
expect(result).to match_array([internal_group])
end
end
+
+ describe 'by_ids_or_paths' do
+ let(:group_path) { 'group_path' }
+ let!(:group) { create(:group, path: group_path) }
+ let(:group_id) { group.id }
+
+ it 'returns matching records based on paths' do
+ expect(described_class.by_ids_or_paths(nil, [group_path])).to match_array([group])
+ end
+
+ it 'returns matching records based on ids' do
+ expect(described_class.by_ids_or_paths([group_id], nil)).to match_array([group])
+ end
+
+ it 'returns matching records based on both paths and ids' do
+ new_group = create(:group)
+
+ expect(described_class.by_ids_or_paths([new_group.id], [group_path])).to match_array([group, new_group])
+ end
+ end
end
describe '#to_reference' do
@@ -2056,6 +2087,23 @@ RSpec.describe Group do
end
end
+ describe '#bots' do
+ subject { group.bots }
+
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project_bot) { create(:user, :project_bot) }
+ let_it_be(:user) { create(:user) }
+
+ before_all do
+ [project_bot, user].each do |member|
+ group.add_maintainer(member)
+ end
+ end
+
+ it { is_expected.to contain_exactly(project_bot) }
+ it { is_expected.not_to include(user) }
+ end
+
describe '#related_group_ids' do
let(:nested_group) { create(:group, parent: group) }
let(:shared_with_group) { create(:group, parent: group) }
@@ -2492,7 +2540,7 @@ RSpec.describe Group do
end
end
- describe '#default_owner' do
+ describe '#first_owner' do
let(:group) { build(:group) }
context 'the group has owners' do
@@ -2502,7 +2550,7 @@ RSpec.describe Group do
end
it 'is the first owner' do
- expect(group.default_owner)
+ expect(group.first_owner)
.to eq(group.owners.first)
.and be_a(User)
end
@@ -2517,8 +2565,8 @@ RSpec.describe Group do
end
it 'is the first owner of the parent' do
- expect(group.default_owner)
- .to eq(parent.default_owner)
+ expect(group.first_owner)
+ .to eq(parent.first_owner)
.and be_a(User)
end
end
@@ -2529,7 +2577,7 @@ RSpec.describe Group do
end
it 'is the group.owner' do
- expect(group.default_owner)
+ expect(group.first_owner)
.to eq(group.owner)
.and be_a(User)
end
@@ -2775,4 +2823,330 @@ RSpec.describe Group do
end
end
end
+
+ describe '#dependency_proxy_setting' do
+ subject(:setting) { group.dependency_proxy_setting }
+
+ it 'builds a new policy if one does not exist', :aggregate_failures do
+ expect(setting.enabled).to eq(true)
+ expect(setting).not_to be_persisted
+ end
+
+ context 'with existing policy' do
+ before do
+ group.dependency_proxy_setting.update!(enabled: false)
+ end
+
+ it 'returns the policy if it already exists', :aggregate_failures do
+ expect(setting.enabled).to eq(false)
+ expect(setting).to be_persisted
+ end
+ end
+ end
+
+ describe '#crm_enabled?' do
+ it 'returns false where no crm_settings exist' do
+ expect(group.crm_enabled?).to be_falsey
+ end
+
+ it 'returns false where crm_settings.state is disabled' do
+ create(:crm_settings, enabled: false, group: group)
+
+ expect(group.crm_enabled?).to be_falsey
+ end
+
+ it 'returns true where crm_settings.state is enabled' do
+ create(:crm_settings, enabled: true, group: group)
+
+ expect(group.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) }
+ let(:group_id) { group.id }
+
+ it 'returns ids matching records based on paths' do
+ expect(described_class.get_ids_by_ids_or_paths(nil, [group_path])).to match_array([group_id])
+ end
+
+ it 'returns ids matching records based on ids' do
+ expect(described_class.get_ids_by_ids_or_paths([group_id], nil)).to match_array([group_id])
+ end
+
+ it 'returns ids matching records based on both paths and ids' do
+ new_group_id = create(:group).id
+
+ expect(described_class.get_ids_by_ids_or_paths([new_group_id], [group_path])).to match_array([group_id, new_group_id])
+ end
+ end
+
+ describe '#shared_with_group_links_visible_to_user' do
+ let_it_be(:admin) { create :admin }
+ let_it_be(:normal_user) { create :user }
+ let_it_be(:user_with_access) { create :user }
+ let_it_be(:user_with_parent_access) { create :user }
+ let_it_be(:user_without_access) { create :user }
+ let_it_be(:shared_group) { create :group }
+ let_it_be(:parent_group) { create :group, :private }
+ let_it_be(:shared_with_private_group) { create :group, :private, parent: parent_group }
+ let_it_be(:shared_with_internal_group) { create :group, :internal }
+ let_it_be(:shared_with_public_group) { create :group, :public }
+ let_it_be(:private_group_group_link) { create(:group_group_link, shared_group: shared_group, shared_with_group: shared_with_private_group) }
+ let_it_be(:internal_group_group_link) { create(:group_group_link, shared_group: shared_group, shared_with_group: shared_with_internal_group) }
+ let_it_be(:public_group_group_link) { create(:group_group_link, shared_group: shared_group, shared_with_group: shared_with_public_group) }
+
+ before do
+ shared_with_private_group.add_developer(user_with_access)
+ parent_group.add_developer(user_with_parent_access)
+ end
+
+ context 'when user is admin', :enable_admin_mode do
+ it 'returns all existing shared group links' do
+ expect(shared_group.shared_with_group_links_visible_to_user(admin)).to contain_exactly(private_group_group_link, internal_group_group_link, public_group_group_link)
+ end
+ end
+
+ context 'when user is nil' do
+ it 'returns only link of public shared group' do
+ expect(shared_group.shared_with_group_links_visible_to_user(nil)).to contain_exactly(public_group_group_link)
+ end
+ end
+
+ context 'when user has no access to private shared group' do
+ it 'returns links of internal and public shared groups' do
+ expect(shared_group.shared_with_group_links_visible_to_user(normal_user)).to contain_exactly(internal_group_group_link, public_group_group_link)
+ end
+ end
+
+ context 'when user is member of private shared group' do
+ it 'returns links of private, internal and public shared groups' do
+ expect(shared_group.shared_with_group_links_visible_to_user(user_with_access)).to contain_exactly(private_group_group_link, internal_group_group_link, public_group_group_link)
+ end
+ end
+
+ context 'when user is inherited member of private shared group' do
+ it 'returns links of private, internal and public shared groups' do
+ expect(shared_group.shared_with_group_links_visible_to_user(user_with_parent_access)).to contain_exactly(private_group_group_link, internal_group_group_link, public_group_group_link)
+ end
+ end
+ end
+
+ describe '#enforced_runner_token_expiration_interval and #effective_runner_token_expiration_interval' do
+ shared_examples 'no enforced expiration interval' do
+ it { expect(subject.enforced_runner_token_expiration_interval).to be_nil }
+ end
+
+ shared_examples 'enforced expiration interval' do |enforced_interval:|
+ it { expect(subject.enforced_runner_token_expiration_interval).to eq(enforced_interval) }
+ end
+
+ shared_examples 'no effective expiration interval' do
+ it { expect(subject.effective_runner_token_expiration_interval).to be_nil }
+ end
+
+ shared_examples 'effective expiration interval' do |effective_interval:|
+ it { expect(subject.effective_runner_token_expiration_interval).to eq(effective_interval) }
+ end
+
+ context 'when there is no interval in group settings' do
+ let_it_be(:group) { create(:group) }
+
+ subject { group }
+
+ it_behaves_like 'no enforced expiration interval'
+ it_behaves_like 'no effective expiration interval'
+ end
+
+ context 'when there is a group interval' do
+ let(:group_settings) { create(:namespace_settings, runner_token_expiration_interval: 3.days.to_i) }
+
+ subject { create(:group, namespace_settings: group_settings) }
+
+ it_behaves_like 'no enforced expiration interval'
+ it_behaves_like 'effective expiration interval', effective_interval: 3.days
+ end
+
+ # runner_token_expiration_interval should not affect the expiration interval, only
+ # group_runner_token_expiration_interval should.
+ context 'when there is a site-wide enforced shared interval' do
+ before do
+ stub_application_setting(runner_token_expiration_interval: 5.days.to_i)
+ end
+
+ let_it_be(:group) { create(:group) }
+
+ subject { group }
+
+ it_behaves_like 'no enforced expiration interval'
+ it_behaves_like 'no effective expiration interval'
+ end
+
+ context 'when there is a site-wide enforced group interval' do
+ before do
+ stub_application_setting(group_runner_token_expiration_interval: 5.days.to_i)
+ end
+
+ let_it_be(:group) { create(:group) }
+
+ subject { group }
+
+ it_behaves_like 'enforced expiration interval', enforced_interval: 5.days
+ it_behaves_like 'effective expiration interval', effective_interval: 5.days
+ end
+
+ # project_runner_token_expiration_interval should not affect the expiration interval, only
+ # group_runner_token_expiration_interval should.
+ context 'when there is a site-wide enforced project interval' do
+ before do
+ stub_application_setting(project_runner_token_expiration_interval: 5.days.to_i)
+ end
+
+ let_it_be(:group) { create(:group) }
+
+ subject { group }
+
+ it_behaves_like 'no enforced expiration interval'
+ it_behaves_like 'no effective expiration interval'
+ end
+
+ # runner_token_expiration_interval should not affect the expiration interval, only
+ # subgroup_runner_token_expiration_interval should.
+ context 'when there is a grandparent group enforced group interval' do
+ let_it_be(:grandparent_group_settings) { create(:namespace_settings, runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:grandparent_group) { create(:group, namespace_settings: grandparent_group_settings) }
+ let_it_be(:parent_group) { create(:group, parent: grandparent_group) }
+ let_it_be(:subgroup) { create(:group, parent: parent_group) }
+
+ subject { subgroup }
+
+ it_behaves_like 'no enforced expiration interval'
+ it_behaves_like 'no effective expiration interval'
+ end
+
+ context 'when there is a grandparent group enforced subgroup interval' do
+ let_it_be(:grandparent_group_settings) { create(:namespace_settings, subgroup_runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:grandparent_group) { create(:group, namespace_settings: grandparent_group_settings) }
+ let_it_be(:parent_group) { create(:group, parent: grandparent_group) }
+ let_it_be(:subgroup) { create(:group, parent: parent_group) }
+
+ subject { subgroup }
+
+ it_behaves_like 'enforced expiration interval', enforced_interval: 4.days
+ it_behaves_like 'effective expiration interval', effective_interval: 4.days
+ end
+
+ # project_runner_token_expiration_interval should not affect the expiration interval, only
+ # subgroup_runner_token_expiration_interval should.
+ context 'when there is a grandparent group enforced project interval' do
+ let_it_be(:grandparent_group_settings) { create(:namespace_settings, project_runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:grandparent_group) { create(:group, namespace_settings: grandparent_group_settings) }
+ let_it_be(:parent_group) { create(:group, parent: grandparent_group) }
+ let_it_be(:subgroup) { create(:group, parent: parent_group) }
+
+ subject { subgroup }
+
+ it_behaves_like 'no enforced expiration interval'
+ it_behaves_like 'no effective expiration interval'
+ end
+
+ context 'when there is a parent group enforced interval overridden by group interval' do
+ let_it_be(:parent_group_settings) { create(:namespace_settings, subgroup_runner_token_expiration_interval: 5.days.to_i) }
+ let_it_be(:parent_group) { create(:group, namespace_settings: parent_group_settings) }
+ let_it_be(:group_settings) { create(:namespace_settings, runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:subgroup_with_settings) { create(:group, parent: parent_group, namespace_settings: group_settings) }
+
+ subject { subgroup_with_settings }
+
+ it_behaves_like 'enforced expiration interval', enforced_interval: 5.days
+ it_behaves_like 'effective expiration interval', effective_interval: 4.days
+
+ it 'has human-readable expiration intervals' do
+ expect(subject.enforced_runner_token_expiration_interval_human_readable).to eq('5d')
+ expect(subject.effective_runner_token_expiration_interval_human_readable).to eq('4d')
+ end
+ end
+
+ context 'when site-wide enforced interval overrides group interval' do
+ before do
+ stub_application_setting(group_runner_token_expiration_interval: 3.days.to_i)
+ end
+
+ let_it_be(:group_settings) { create(:namespace_settings, runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:group_with_settings) { create(:group, namespace_settings: group_settings) }
+
+ subject { group_with_settings }
+
+ it_behaves_like 'enforced expiration interval', enforced_interval: 3.days
+ it_behaves_like 'effective expiration interval', effective_interval: 3.days
+ end
+
+ context 'when group interval overrides site-wide enforced interval' do
+ before do
+ stub_application_setting(group_runner_token_expiration_interval: 5.days.to_i)
+ end
+
+ let_it_be(:group_settings) { create(:namespace_settings, runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:group_with_settings) { create(:group, namespace_settings: group_settings) }
+
+ subject { group_with_settings }
+
+ it_behaves_like 'enforced expiration interval', enforced_interval: 5.days
+ it_behaves_like 'effective expiration interval', effective_interval: 4.days
+ end
+
+ context 'when site-wide enforced interval overrides parent group enforced interval' do
+ before do
+ stub_application_setting(group_runner_token_expiration_interval: 3.days.to_i)
+ end
+
+ let_it_be(:parent_group_settings) { create(:namespace_settings, subgroup_runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:parent_group) { create(:group, namespace_settings: parent_group_settings) }
+ let_it_be(:subgroup) { create(:group, parent: parent_group) }
+
+ subject { subgroup }
+
+ it_behaves_like 'enforced expiration interval', enforced_interval: 3.days
+ it_behaves_like 'effective expiration interval', effective_interval: 3.days
+ end
+
+ context 'when parent group enforced interval overrides site-wide enforced interval' do
+ before do
+ stub_application_setting(group_runner_token_expiration_interval: 5.days.to_i)
+ end
+
+ let_it_be(:parent_group_settings) { create(:namespace_settings, subgroup_runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:parent_group) { create(:group, namespace_settings: parent_group_settings) }
+ let_it_be(:subgroup) { create(:group, parent: parent_group) }
+
+ subject { subgroup }
+
+ it_behaves_like 'enforced expiration interval', enforced_interval: 4.days
+ it_behaves_like 'effective expiration interval', effective_interval: 4.days
+ end
+
+ # Unrelated groups should not affect the expiration interval.
+ context 'when there is an enforced group interval in an unrelated group' do
+ let_it_be(:unrelated_group_settings) { create(:namespace_settings, subgroup_runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:unrelated_group) { create(:group, namespace_settings: unrelated_group_settings) }
+ let_it_be(:group) { create(:group) }
+
+ subject { group }
+
+ it_behaves_like 'no enforced expiration interval'
+ it_behaves_like 'no effective expiration interval'
+ end
+
+ # Subgroups should not affect the parent group expiration interval.
+ context 'when there is an enforced group interval in a subgroup' do
+ let_it_be(:subgroup_settings) { create(:namespace_settings, subgroup_runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:subgroup) { create(:group, parent: group, namespace_settings: subgroup_settings) }
+ let_it_be(:group) { create(:group) }
+
+ subject { group }
+
+ it_behaves_like 'no enforced expiration interval'
+ it_behaves_like 'no effective expiration interval'
+ end
+ end
end
diff --git a/spec/models/hooks/project_hook_spec.rb b/spec/models/hooks/project_hook_spec.rb
index f0ee9a613d8..ec2eca96755 100644
--- a/spec/models/hooks/project_hook_spec.rb
+++ b/spec/models/hooks/project_hook_spec.rb
@@ -40,6 +40,15 @@ RSpec.describe ProjectHook do
end
end
+ describe '#parent' do
+ it 'returns the associated project' do
+ project = build(:project)
+ hook = build(:project_hook, project: project)
+
+ expect(hook.parent).to eq(project)
+ end
+ end
+
describe '#application_context' do
let_it_be(:hook) { build(:project_hook) }
diff --git a/spec/models/hooks/service_hook_spec.rb b/spec/models/hooks/service_hook_spec.rb
index 4ce2e729d89..85f433f5f81 100644
--- a/spec/models/hooks/service_hook_spec.rb
+++ b/spec/models/hooks/service_hook_spec.rb
@@ -31,6 +31,36 @@ RSpec.describe ServiceHook do
end
end
+ describe '#parent' do
+ let(:hook) { build(:service_hook, integration: integration) }
+
+ context 'with a project-level integration' do
+ let(:project) { build(:project) }
+ let(:integration) { build(:integration, project: project) }
+
+ it 'returns the associated project' do
+ expect(hook.parent).to eq(project)
+ end
+ end
+
+ context 'with a group-level integration' do
+ let(:group) { build(:group) }
+ let(:integration) { build(:integration, :group, group: group) }
+
+ it 'returns the associated group' do
+ expect(hook.parent).to eq(group)
+ end
+ end
+
+ context 'with an instance-level integration' do
+ let(:integration) { build(:integration, :instance) }
+
+ it 'returns nil' do
+ expect(hook.parent).to be_nil
+ end
+ end
+ end
+
describe '#application_context' do
let(:hook) { build(:service_hook) }
diff --git a/spec/models/hooks/system_hook_spec.rb b/spec/models/hooks/system_hook_spec.rb
index 17cb5da977a..89bfb742f5d 100644
--- a/spec/models/hooks/system_hook_spec.rb
+++ b/spec/models/hooks/system_hook_spec.rb
@@ -37,7 +37,7 @@ RSpec.describe SystemHook do
let(:project) { create(:project, namespace: user.namespace) }
let(:group) { create(:group) }
let(:params) do
- { name: 'John Doe', username: 'jduser', email: 'jg@example.com', password: 'mydummypass' }
+ { name: 'John Doe', username: 'jduser', email: 'jg@example.com', password: Gitlab::Password.test_default }
end
before do
diff --git a/spec/models/instance_configuration_spec.rb b/spec/models/instance_configuration_spec.rb
index 698d74abf03..a47bc6a5b6d 100644
--- a/spec/models/instance_configuration_spec.rb
+++ b/spec/models/instance_configuration_spec.rb
@@ -205,7 +205,8 @@ RSpec.describe InstanceConfiguration do
group_export_limit: 1018,
group_download_export_limit: 1019,
group_import_limit: 1020,
- raw_blob_request_limit: 1021
+ raw_blob_request_limit: 1021,
+ user_email_lookup_limit: 1022
)
end
@@ -228,6 +229,7 @@ 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 })
end
end
end
diff --git a/spec/models/integration_spec.rb b/spec/models/integration_spec.rb
index de47fb3839a..7bc670302f1 100644
--- a/spec/models/integration_spec.rb
+++ b/spec/models/integration_spec.rb
@@ -33,28 +33,28 @@ RSpec.describe Integration do
end
with_them do
- it 'validates the service' do
- expect(build(:service, project_id: project_id, group_id: group_id, instance: instance).valid?).to eq(valid)
+ it 'validates the integration' do
+ expect(build(:integration, project_id: project_id, group_id: group_id, instance: instance).valid?).to eq(valid)
end
end
- context 'with existing services' do
+ context 'with existing integrations' do
before_all do
- create(:service, :instance)
- create(:service, project: project)
- create(:service, group: group, project: nil)
+ create(:integration, :instance)
+ create(:integration, project: project)
+ create(:integration, group: group, project: nil)
end
- it 'allows only one instance service per type' do
- expect(build(:service, :instance)).to be_invalid
+ it 'allows only one instance integration per type' do
+ expect(build(:integration, :instance)).to be_invalid
end
- it 'allows only one project service per type' do
- expect(build(:service, project: project)).to be_invalid
+ it 'allows only one project integration per type' do
+ expect(build(:integration, project: project)).to be_invalid
end
- it 'allows only one group service per type' do
- expect(build(:service, group: group, project: nil)).to be_invalid
+ it 'allows only one group integration per type' do
+ expect(build(:integration, group: group, project: nil)).to be_invalid
end
end
end
@@ -79,93 +79,85 @@ RSpec.describe Integration do
end
describe '.by_type' do
- let!(:service1) { create(:jira_integration) }
- let!(:service2) { create(:jira_integration) }
- let!(:service3) { create(:redmine_integration) }
+ let!(:integration1) { create(:jira_integration) }
+ let!(:integration2) { create(:jira_integration) }
+ let!(:integration3) { create(:redmine_integration) }
subject { described_class.by_type(type) }
context 'when type is "JiraService"' do
let(:type) { 'JiraService' }
- it { is_expected.to match_array([service1, service2]) }
+ it { is_expected.to match_array([integration1, integration2]) }
end
context 'when type is "RedmineService"' do
let(:type) { 'RedmineService' }
- it { is_expected.to match_array([service3]) }
+ it { is_expected.to match_array([integration3]) }
end
end
describe '.for_group' do
- let!(:service1) { create(:jira_integration, project_id: nil, group_id: group.id) }
- let!(:service2) { create(:jira_integration) }
+ let!(:integration1) { create(:jira_integration, project_id: nil, group_id: group.id) }
+ let!(:integration2) { create(:jira_integration) }
- it 'returns the right group service' do
- expect(described_class.for_group(group)).to match_array([service1])
+ it 'returns the right group integration' do
+ expect(described_class.for_group(group)).to match_array([integration1])
end
end
- describe '.confidential_note_hooks' do
- it 'includes services where confidential_note_events is true' do
- create(:service, active: true, confidential_note_events: true)
+ shared_examples 'hook scope' do |hook_type|
+ describe ".#{hook_type}_hooks" do
+ it "includes services where #{hook_type}_events is true" do
+ create(:integration, active: true, "#{hook_type}_events": true)
- expect(described_class.confidential_note_hooks.count).to eq 1
- end
+ expect(described_class.send("#{hook_type}_hooks").count).to eq 1
+ end
- it 'excludes services where confidential_note_events is false' do
- create(:service, active: true, confidential_note_events: false)
+ it "excludes services where #{hook_type}_events is false" do
+ create(:integration, active: true, "#{hook_type}_events": false)
- expect(described_class.confidential_note_hooks.count).to eq 0
+ expect(described_class.send("#{hook_type}_hooks").count).to eq 0
+ end
end
end
- describe '.alert_hooks' do
- it 'includes services where alert_events is true' do
- create(:service, active: true, alert_events: true)
-
- expect(described_class.alert_hooks.count).to eq 1
- end
-
- it 'excludes services where alert_events is false' do
- create(:service, active: true, alert_events: false)
-
- expect(described_class.alert_hooks.count).to eq 0
- end
- end
+ include_examples 'hook scope', 'confidential_note'
+ include_examples 'hook scope', 'alert'
+ include_examples 'hook scope', 'archive_trace'
end
describe '#operating?' do
- it 'is false when the service is not active' do
- expect(build(:service).operating?).to eq(false)
+ it 'is false when the integration is not active' do
+ expect(build(:integration).operating?).to eq(false)
end
- it 'is false when the service is not persisted' do
- expect(build(:service, active: true).operating?).to eq(false)
+ it 'is false when the integration is not persisted' do
+ expect(build(:integration, active: true).operating?).to eq(false)
end
- it 'is true when the service is active and persisted' do
- expect(create(:service, active: true).operating?).to eq(true)
+ it 'is true when the integration is active and persisted' do
+ expect(create(:integration, active: true).operating?).to eq(true)
end
end
describe '#testable?' do
context 'when integration is project-level' do
- subject { build(:service, project: project) }
+ subject { build(:integration, project: project) }
it { is_expected.to be_testable }
end
context 'when integration is not project-level' do
- subject { build(:service, project: nil) }
+ subject { build(:integration, project: nil) }
it { is_expected.not_to be_testable }
end
end
describe '#test' do
- let(:integration) { build(:service, project: project) }
+ let(:integration) { build(:integration, project: project) }
let(:data) { 'test' }
it 'calls #execute' do
@@ -186,32 +178,32 @@ RSpec.describe Integration do
end
describe '#project_level?' do
- it 'is true when service has a project' do
- expect(build(:service, project: project)).to be_project_level
+ it 'is true when integration has a project' do
+ expect(build(:integration, project: project)).to be_project_level
end
- it 'is false when service has no project' do
- expect(build(:service, project: nil)).not_to be_project_level
+ it 'is false when integration has no project' do
+ expect(build(:integration, project: nil)).not_to be_project_level
end
end
describe '#group_level?' do
- it 'is true when service has a group' do
- expect(build(:service, group: group)).to be_group_level
+ it 'is true when integration has a group' do
+ expect(build(:integration, group: group)).to be_group_level
end
- it 'is false when service has no group' do
- expect(build(:service, group: nil)).not_to be_group_level
+ it 'is false when integration has no group' do
+ expect(build(:integration, group: nil)).not_to be_group_level
end
end
describe '#instance_level?' do
- it 'is true when service has instance-level integration' do
- expect(build(:service, :instance)).to be_instance_level
+ it 'is true when integration has instance-level integration' do
+ expect(build(:integration, :instance)).to be_instance_level
end
- it 'is false when service does not have instance-level integration' do
- expect(build(:service, instance: false)).not_to be_instance_level
+ it 'is false when integration does not have instance-level integration' do
+ expect(build(:integration, instance: false)).not_to be_instance_level
end
end
@@ -231,19 +223,19 @@ RSpec.describe Integration do
end
describe '.find_or_initialize_all_non_project_specific' do
- shared_examples 'service instances' do
- it 'returns the available service instances' do
+ shared_examples 'integration instances' do
+ it 'returns the available integration instances' do
expect(Integration.find_or_initialize_all_non_project_specific(Integration.for_instance).map(&:to_param))
.to match_array(Integration.available_integration_names(include_project_specific: false))
end
- it 'does not create service instances' do
+ it 'does not create integration instances' do
expect { Integration.find_or_initialize_all_non_project_specific(Integration.for_instance) }
.not_to change(Integration, :count)
end
end
- it_behaves_like 'service instances'
+ it_behaves_like 'integration instances'
context 'with all existing instances' do
before do
@@ -252,15 +244,15 @@ RSpec.describe Integration do
)
end
- it_behaves_like 'service instances'
+ it_behaves_like 'integration instances'
- context 'with a previous existing service (MockCiService) and a new service (Asana)' do
+ context 'with a previous existing integration (MockCiService) and a new integration (Asana)' do
before do
Integration.insert({ type: 'MockCiService', instance: true })
Integration.delete_by(type: 'AsanaService', instance: true)
end
- it_behaves_like 'service instances'
+ it_behaves_like 'integration instances'
end
end
@@ -269,7 +261,7 @@ RSpec.describe Integration do
create(:jira_integration, :instance)
end
- it_behaves_like 'service instances'
+ it_behaves_like 'integration instances'
end
end
@@ -320,31 +312,31 @@ RSpec.describe Integration do
}
end
- shared_examples 'service creation from an integration' do
- it 'creates a correct service for a project integration' do
- service = described_class.build_from_integration(integration, project_id: project.id)
+ shared_examples 'integration creation from an integration' do
+ it 'creates a correct integration for a project integration' do
+ new_integration = described_class.build_from_integration(integration, project_id: project.id)
- expect(service).to be_active
- expect(service.url).to eq(url)
- expect(service.api_url).to eq(api_url)
- expect(service.username).to eq(username)
- expect(service.password).to eq(password)
- expect(service.instance).to eq(false)
- expect(service.project).to eq(project)
- expect(service.group).to eq(nil)
+ expect(new_integration).to be_active
+ expect(new_integration.url).to eq(url)
+ expect(new_integration.api_url).to eq(api_url)
+ expect(new_integration.username).to eq(username)
+ expect(new_integration.password).to eq(password)
+ expect(new_integration.instance).to eq(false)
+ expect(new_integration.project).to eq(project)
+ expect(new_integration.group).to eq(nil)
end
- it 'creates a correct service for a group integration' do
- service = described_class.build_from_integration(integration, group_id: group.id)
-
- expect(service).to be_active
- expect(service.url).to eq(url)
- expect(service.api_url).to eq(api_url)
- expect(service.username).to eq(username)
- expect(service.password).to eq(password)
- expect(service.instance).to eq(false)
- expect(service.project).to eq(nil)
- expect(service.group).to eq(group)
+ it 'creates a correct integration for a group integration' do
+ new_integration = described_class.build_from_integration(integration, group_id: group.id)
+
+ expect(new_integration).to be_active
+ expect(new_integration.url).to eq(url)
+ expect(new_integration.api_url).to eq(api_url)
+ expect(new_integration.username).to eq(username)
+ expect(new_integration.password).to eq(password)
+ expect(new_integration.instance).to eq(false)
+ expect(new_integration.project).to eq(nil)
+ expect(new_integration.group).to eq(group)
end
end
@@ -355,7 +347,7 @@ RSpec.describe Integration do
create(:jira_integration, :without_properties_callback, properties: properties.merge(additional: 'something'))
end
- it_behaves_like 'service creation from an integration'
+ it_behaves_like 'integration creation from an integration'
end
context 'when data are stored in separated fields' do
@@ -363,7 +355,7 @@ RSpec.describe Integration do
create(:jira_integration, data_params.merge(properties: {}))
end
- it_behaves_like 'service creation from an integration'
+ it_behaves_like 'integration creation from an integration'
end
context 'when data are stored in both properties and separated fields' do
@@ -374,7 +366,7 @@ RSpec.describe Integration do
end
end
- it_behaves_like 'service creation from an integration'
+ it_behaves_like 'integration creation from an integration'
end
end
end
@@ -565,17 +557,17 @@ RSpec.describe Integration do
end
describe '.integration_name_to_model' do
- it 'returns the model for the given service name' do
+ it 'returns the model for the given integration name' do
expect(described_class.integration_name_to_model('asana')).to eq(Integrations::Asana)
end
- it 'raises an error if service name is invalid' 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/)
end
end
describe "{property}_changed?" do
- let(:service) do
+ let(:integration) do
Integrations::Bamboo.create!(
project: project,
properties: {
@@ -587,35 +579,35 @@ RSpec.describe Integration do
end
it "returns false when the property has not been assigned a new value" do
- service.username = "key_changed"
- expect(service.bamboo_url_changed?).to be_falsy
+ integration.username = "key_changed"
+ expect(integration.bamboo_url_changed?).to be_falsy
end
it "returns true when the property has been assigned a different value" do
- service.bamboo_url = "http://example.com"
- expect(service.bamboo_url_changed?).to be_truthy
+ integration.bamboo_url = "http://example.com"
+ expect(integration.bamboo_url_changed?).to be_truthy
end
it "returns true when the property has been assigned a different value twice" do
- service.bamboo_url = "http://example.com"
- service.bamboo_url = "http://example.com"
- expect(service.bamboo_url_changed?).to be_truthy
+ integration.bamboo_url = "http://example.com"
+ integration.bamboo_url = "http://example.com"
+ expect(integration.bamboo_url_changed?).to be_truthy
end
it "returns false when the property has been re-assigned the same value" do
- service.bamboo_url = 'http://gitlab.com'
- expect(service.bamboo_url_changed?).to be_falsy
+ integration.bamboo_url = 'http://gitlab.com'
+ expect(integration.bamboo_url_changed?).to be_falsy
end
it "returns false when the property has been assigned a new value then saved" do
- service.bamboo_url = 'http://example.com'
- service.save!
- expect(service.bamboo_url_changed?).to be_falsy
+ integration.bamboo_url = 'http://example.com'
+ integration.save!
+ expect(integration.bamboo_url_changed?).to be_falsy
end
end
describe "{property}_touched?" do
- let(:service) do
+ let(:integration) do
Integrations::Bamboo.create!(
project: project,
properties: {
@@ -627,35 +619,35 @@ RSpec.describe Integration do
end
it "returns false when the property has not been assigned a new value" do
- service.username = "key_changed"
- expect(service.bamboo_url_touched?).to be_falsy
+ integration.username = "key_changed"
+ expect(integration.bamboo_url_touched?).to be_falsy
end
it "returns true when the property has been assigned a different value" do
- service.bamboo_url = "http://example.com"
- expect(service.bamboo_url_touched?).to be_truthy
+ integration.bamboo_url = "http://example.com"
+ expect(integration.bamboo_url_touched?).to be_truthy
end
it "returns true when the property has been assigned a different value twice" do
- service.bamboo_url = "http://example.com"
- service.bamboo_url = "http://example.com"
- expect(service.bamboo_url_touched?).to be_truthy
+ integration.bamboo_url = "http://example.com"
+ integration.bamboo_url = "http://example.com"
+ expect(integration.bamboo_url_touched?).to be_truthy
end
it "returns true when the property has been re-assigned the same value" do
- service.bamboo_url = 'http://gitlab.com'
- expect(service.bamboo_url_touched?).to be_truthy
+ integration.bamboo_url = 'http://gitlab.com'
+ expect(integration.bamboo_url_touched?).to be_truthy
end
it "returns false when the property has been assigned a new value then saved" do
- service.bamboo_url = 'http://example.com'
- service.save!
- expect(service.bamboo_url_changed?).to be_falsy
+ integration.bamboo_url = 'http://example.com'
+ integration.save!
+ expect(integration.bamboo_url_changed?).to be_falsy
end
end
describe "{property}_was" do
- let(:service) do
+ let(:integration) do
Integrations::Bamboo.create!(
project: project,
properties: {
@@ -667,35 +659,35 @@ RSpec.describe Integration do
end
it "returns nil when the property has not been assigned a new value" do
- service.username = "key_changed"
- expect(service.bamboo_url_was).to be_nil
+ integration.username = "key_changed"
+ expect(integration.bamboo_url_was).to be_nil
end
it "returns the previous value when the property has been assigned a different value" do
- service.bamboo_url = "http://example.com"
- expect(service.bamboo_url_was).to eq('http://gitlab.com')
+ integration.bamboo_url = "http://example.com"
+ expect(integration.bamboo_url_was).to eq('http://gitlab.com')
end
it "returns initial value when the property has been re-assigned the same value" do
- service.bamboo_url = 'http://gitlab.com'
- expect(service.bamboo_url_was).to eq('http://gitlab.com')
+ integration.bamboo_url = 'http://gitlab.com'
+ expect(integration.bamboo_url_was).to eq('http://gitlab.com')
end
it "returns initial value when the property has been assigned multiple values" do
- service.bamboo_url = "http://example.com"
- service.bamboo_url = "http://example2.com"
- expect(service.bamboo_url_was).to eq('http://gitlab.com')
+ integration.bamboo_url = "http://example.com"
+ integration.bamboo_url = "http://example.org"
+ expect(integration.bamboo_url_was).to eq('http://gitlab.com')
end
it "returns nil when the property has been assigned a new value then saved" do
- service.bamboo_url = 'http://example.com'
- service.save!
- expect(service.bamboo_url_was).to be_nil
+ integration.bamboo_url = 'http://example.com'
+ integration.save!
+ expect(integration.bamboo_url_was).to be_nil
end
end
- describe 'initialize service with no properties' do
- let(:service) do
+ describe 'initialize integration with no properties' do
+ let(:integration) do
Integrations::Bugzilla.create!(
project: project,
project_url: 'http://gitlab.example.com'
@@ -703,16 +695,16 @@ RSpec.describe Integration do
end
it 'does not raise error' do
- expect { service }.not_to raise_error
+ expect { integration }.not_to raise_error
end
it 'sets data correctly' do
- expect(service.data_fields.project_url).to eq('http://gitlab.example.com')
+ expect(integration.data_fields.project_url).to eq('http://gitlab.example.com')
end
end
describe '#api_field_names' do
- let(:fake_service) do
+ let(:fake_integration) do
Class.new(Integration) do
def fields
[
@@ -728,8 +720,8 @@ RSpec.describe Integration do
end
end
- let(:service) do
- fake_service.new(properties: [
+ let(:integration) do
+ fake_integration.new(properties: [
{ token: 'token-value' },
{ api_token: 'api_token-value' },
{ key: 'key-value' },
@@ -741,16 +733,16 @@ RSpec.describe Integration do
end
it 'filters out sensitive fields' do
- expect(service.api_field_names).to eq(['safe_field'])
+ expect(integration.api_field_names).to eq(['safe_field'])
end
end
context 'logging' do
- let(:service) { build(:service, project: project) }
+ let(:integration) { build(:integration, project: project) }
let(:test_message) { "test message" }
let(:arguments) do
{
- service_class: service.class.name,
+ service_class: integration.class.name,
project_path: project.full_path,
project_id: project.id,
message: test_message,
@@ -761,20 +753,20 @@ RSpec.describe Integration do
it 'logs info messages using json logger' do
expect(Gitlab::JsonLogger).to receive(:info).with(arguments)
- service.log_info(test_message, additional_argument: 'some argument')
+ integration.log_info(test_message, additional_argument: 'some argument')
end
it 'logs error messages using json logger' do
expect(Gitlab::JsonLogger).to receive(:error).with(arguments)
- service.log_error(test_message, additional_argument: 'some argument')
+ integration.log_error(test_message, additional_argument: 'some argument')
end
context 'when project is nil' do
let(:project) { nil }
let(:arguments) do
{
- service_class: service.class.name,
+ service_class: integration.class.name,
project_path: nil,
project_id: nil,
message: test_message,
@@ -785,7 +777,7 @@ RSpec.describe Integration do
it 'logs info messages using json logger' do
expect(Gitlab::JsonLogger).to receive(:info).with(arguments)
- service.log_info(test_message, additional_argument: 'some argument')
+ integration.log_info(test_message, additional_argument: 'some argument')
end
end
end
diff --git a/spec/models/integrations/asana_spec.rb b/spec/models/integrations/asana_spec.rb
index f7e7eb1b0ae..b6602964182 100644
--- a/spec/models/integrations/asana_spec.rb
+++ b/spec/models/integrations/asana_spec.rb
@@ -14,27 +14,29 @@ RSpec.describe Integrations::Asana do
end
describe 'Execute' do
- let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+
let(:gid) { "123456789ABCD" }
+ let(:asana_task) { double(::Asana::Resources::Task) }
+ let(:asana_integration) { described_class.new }
- def create_data_for_commits(*messages)
+ let(:data) do
{
object_kind: 'push',
ref: 'master',
user_name: user.name,
- commits: messages.map do |m|
+ commits: [
{
- message: m,
+ message: message,
url: 'https://gitlab.com/'
}
- end
+ ]
}
end
before do
- @asana = described_class.new
- allow(@asana).to receive_messages(
+ allow(asana_integration).to receive_messages(
project: project,
project_id: project.id,
api_key: 'verySecret',
@@ -42,67 +44,79 @@ RSpec.describe Integrations::Asana do
)
end
- it 'calls Asana integration to create a story' do
- data = create_data_for_commits("Message from commit. related to ##{gid}")
- expected_message = "#{data[:user_name]} pushed to branch #{data[:ref]} of #{project.full_name} ( #{data[:commits][0][:url]} ): #{data[:commits][0][:message]}"
+ subject(:execute_integration) { asana_integration.execute(data) }
+
+ context 'when creating a story' do
+ let(:message) { "Message from commit. related to ##{gid}" }
+ let(:expected_message) do
+ "#{user.name} pushed to branch master of #{project.full_name} ( https://gitlab.com/ ): #{message}"
+ end
- d1 = double('Asana::Resources::Task')
- expect(d1).to receive(:add_comment).with(text: expected_message)
- expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, gid).once.and_return(d1)
+ it 'calls Asana integration to create a story' do
+ expect(asana_task).to receive(:add_comment).with(text: expected_message)
+ expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, gid).once.and_return(asana_task)
- @asana.execute(data)
+ execute_integration
+ end
end
- it 'calls Asana integration to create a story and close a task' do
- data = create_data_for_commits('fix #456789')
- d1 = double('Asana::Resources::Task')
- expect(d1).to receive(:add_comment)
- expect(d1).to receive(:update).with(completed: true)
- expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '456789').once.and_return(d1)
+ context 'when creating a story and closing a task' do
+ let(:message) { 'fix #456789' }
- @asana.execute(data)
+ it 'calls Asana integration to create a story and close a task' do
+ expect(asana_task).to receive(:add_comment)
+ expect(asana_task).to receive(:update).with(completed: true)
+ expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '456789').once.and_return(asana_task)
+
+ execute_integration
+ end
end
- it 'is able to close via url' do
- data = create_data_for_commits('closes https://app.asana.com/19292/956299/42')
- d1 = double('Asana::Resources::Task')
- expect(d1).to receive(:add_comment)
- expect(d1).to receive(:update).with(completed: true)
- expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '42').once.and_return(d1)
+ context 'when closing via url' do
+ let(:message) { 'closes https://app.asana.com/19292/956299/42' }
- @asana.execute(data)
+ it 'calls Asana integration to close via url' do
+ expect(asana_task).to receive(:add_comment)
+ expect(asana_task).to receive(:update).with(completed: true)
+ expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '42').once.and_return(asana_task)
+
+ execute_integration
+ end
end
- it 'allows multiple matches per line' do
- message = <<-EOF
- minor bigfix, refactoring, fixed #123 and Closes #456 work on #789
- ref https://app.asana.com/19292/956299/42 and closing https://app.asana.com/19292/956299/12
- EOF
- data = create_data_for_commits(message)
- d1 = double('Asana::Resources::Task')
- expect(d1).to receive(:add_comment)
- expect(d1).to receive(:update).with(completed: true)
- expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '123').once.and_return(d1)
-
- d2 = double('Asana::Resources::Task')
- expect(d2).to receive(:add_comment)
- expect(d2).to receive(:update).with(completed: true)
- expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '456').once.and_return(d2)
-
- d3 = double('Asana::Resources::Task')
- expect(d3).to receive(:add_comment)
- expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '789').once.and_return(d3)
-
- d4 = double('Asana::Resources::Task')
- expect(d4).to receive(:add_comment)
- expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '42').once.and_return(d4)
-
- d5 = double('Asana::Resources::Task')
- expect(d5).to receive(:add_comment)
- expect(d5).to receive(:update).with(completed: true)
- expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '12').once.and_return(d5)
-
- @asana.execute(data)
+ context 'with multiple matches per line' do
+ let(:message) do
+ <<-EOF
+ minor bigfix, refactoring, fixed #123 and Closes #456 work on #789
+ ref https://app.asana.com/19292/956299/42 and closing https://app.asana.com/19292/956299/12
+ EOF
+ end
+
+ it 'allows multiple matches per line' do
+ expect(asana_task).to receive(:add_comment)
+ expect(asana_task).to receive(:update).with(completed: true)
+ expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '123').once.and_return(asana_task)
+
+ asana_task_2 = double(Asana::Resources::Task)
+ expect(asana_task_2).to receive(:add_comment)
+ expect(asana_task_2).to receive(:update).with(completed: true)
+ expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '456').once.and_return(asana_task_2)
+
+ asana_task_3 = double(Asana::Resources::Task)
+ expect(asana_task_3).to receive(:add_comment)
+ expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '789').once.and_return(asana_task_3)
+
+ asana_task_4 = double(Asana::Resources::Task)
+ expect(asana_task_4).to receive(:add_comment)
+ expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '42').once.and_return(asana_task_4)
+
+ asana_task_5 = double(Asana::Resources::Task)
+ expect(asana_task_5).to receive(:add_comment)
+ expect(asana_task_5).to receive(:update).with(completed: true)
+ expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '12').once.and_return(asana_task_5)
+
+ execute_integration
+ end
end
end
end
diff --git a/spec/models/integrations/datadog_spec.rb b/spec/models/integrations/datadog_spec.rb
index 9c3ff7aa35b..9856c53a390 100644
--- a/spec/models/integrations/datadog_spec.rb
+++ b/spec/models/integrations/datadog_spec.rb
@@ -38,6 +38,11 @@ RSpec.describe Integrations::Datadog do
let(:pipeline_data) { Gitlab::DataBuilder::Pipeline.build(pipeline) }
let(:build_data) { Gitlab::DataBuilder::Build.build(build) }
+ let(:archive_trace_data) do
+ create(:ci_job_artifact, :trace, job: build)
+
+ Gitlab::DataBuilder::ArchiveTrace.build(build)
+ end
it_behaves_like Integrations::HasWebHook do
let(:integration) { instance }
@@ -100,6 +105,13 @@ RSpec.describe Integrations::Datadog do
end
end
+ describe '#help' do
+ subject { instance.help }
+
+ it { is_expected.to be_a(String) }
+ it { is_expected.not_to be_empty }
+ end
+
describe '#hook_url' do
subject { instance.hook_url }
@@ -161,13 +173,16 @@ RSpec.describe Integrations::Datadog do
end
before do
+ stub_feature_flags(datadog_integration_logs_collection: enable_logs_collection)
stub_request(:post, expected_hook_url)
saved_instance.execute(data)
end
+ let(:enable_logs_collection) { true }
+
context 'with pipeline data' do
let(:data) { pipeline_data }
- let(:expected_headers) { { WebHookService::GITLAB_EVENT_HEADER => 'Pipeline Hook' } }
+ let(:expected_headers) { { ::Gitlab::WebHooks::GITLAB_EVENT_HEADER => 'Pipeline Hook' } }
let(:expected_body) { data.with_retried_builds.to_json }
it { expect(a_request(:post, expected_hook_url).with(headers: expected_headers, body: expected_body)).to have_been_made }
@@ -175,10 +190,24 @@ RSpec.describe Integrations::Datadog do
context 'with job data' do
let(:data) { build_data }
- let(:expected_headers) { { WebHookService::GITLAB_EVENT_HEADER => 'Job Hook' } }
+ let(:expected_headers) { { ::Gitlab::WebHooks::GITLAB_EVENT_HEADER => 'Job Hook' } }
+ let(:expected_body) { data.to_json }
+
+ it { expect(a_request(:post, expected_hook_url).with(headers: expected_headers, body: expected_body)).to have_been_made }
+ end
+
+ context 'with archive trace data' do
+ let(:data) { archive_trace_data }
+ let(:expected_headers) { { ::Gitlab::WebHooks::GITLAB_EVENT_HEADER => 'Archive Trace Hook' } }
let(:expected_body) { data.to_json }
it { expect(a_request(:post, expected_hook_url).with(headers: expected_headers, body: expected_body)).to have_been_made }
+
+ context 'but feature flag disabled' do
+ let(:enable_logs_collection) { false }
+
+ it { expect(a_request(:post, expected_hook_url)).not_to have_been_made }
+ end
end
end
end
diff --git a/spec/models/integrations/jira_spec.rb b/spec/models/integrations/jira_spec.rb
index 9163a7ef845..e80fa6e3b70 100644
--- a/spec/models/integrations/jira_spec.rb
+++ b/spec/models/integrations/jira_spec.rb
@@ -937,18 +937,6 @@ RSpec.describe Integrations::Jira do
end
end
- context 'with jira_use_first_ref_by_oid feature flag disabled' do
- before do
- stub_feature_flags(jira_use_first_ref_by_oid: false)
- end
-
- it 'creates a comment and remote link on Jira' do
- expect(subject).to eq(success_message)
- expect(WebMock).to have_requested(:post, comment_url).with(body: comment_body).once
- expect(WebMock).to have_requested(:post, remote_link_url).once
- end
- end
-
it 'tracks usage' do
expect(Gitlab::UsageDataCounters::HLLRedisCounter)
.to receive(:track_event)
diff --git a/spec/models/internal_id_spec.rb b/spec/models/internal_id_spec.rb
index 51b27151ba2..f0007e1203c 100644
--- a/spec/models/internal_id_spec.rb
+++ b/spec/models/internal_id_spec.rb
@@ -87,7 +87,7 @@ RSpec.describe InternalId do
context 'when executed outside of transaction' do
it 'increments counter with in_transaction: "false"' do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?) { false } # rubocop: disable Database/MultipleDatabases
+ allow(ApplicationRecord.connection).to receive(:transaction_open?) { false }
expect(InternalId.internal_id_transactions_total).to receive(:increment)
.with(operation: :generate, usage: 'issues', in_transaction: 'false').and_call_original
@@ -146,7 +146,7 @@ RSpec.describe InternalId do
let(:value) { 2 }
it 'increments counter with in_transaction: "false"' do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?) { false } # rubocop: disable Database/MultipleDatabases
+ allow(ApplicationRecord.connection).to receive(:transaction_open?) { false }
expect(InternalId.internal_id_transactions_total).to receive(:increment)
.with(operation: :reset, usage: 'issues', in_transaction: 'false').and_call_original
@@ -217,7 +217,7 @@ RSpec.describe InternalId do
context 'when executed outside of transaction' do
it 'increments counter with in_transaction: "false"' do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?) { false } # rubocop: disable Database/MultipleDatabases
+ allow(ApplicationRecord.connection).to receive(:transaction_open?) { false }
expect(InternalId.internal_id_transactions_total).to receive(:increment)
.with(operation: :track_greatest, usage: 'issues', in_transaction: 'false').and_call_original
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index 4cbfa7c7758..c105f6c3439 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe Issue do
it { is_expected.to belong_to(:iteration) }
it { is_expected.to belong_to(:project) }
it { is_expected.to have_one(:namespace).through(:project) }
- it { is_expected.to belong_to(:work_item_type).class_name('WorkItem::Type') }
+ it { is_expected.to belong_to(:work_item_type).class_name('WorkItems::Type') }
it { is_expected.to belong_to(:moved_to).class_name('Issue') }
it { is_expected.to have_one(:moved_from).class_name('Issue') }
it { is_expected.to belong_to(:duplicated_to).class_name('Issue') }
@@ -238,6 +238,17 @@ RSpec.describe Issue do
end
end
+ # TODO: Remove when NOT NULL constraint is added to the relationship
+ describe '#work_item_type' do
+ let(:issue) { create(:issue, :incident, project: reusable_project, work_item_type: nil) }
+
+ it 'returns a default type if the legacy issue does not have a work item type associated yet' do
+ expect(issue.work_item_type_id).to be_nil
+ expect(issue.issue_type).to eq('incident')
+ expect(issue.work_item_type).to eq(WorkItems::Type.default_by_type(:incident))
+ end
+ end
+
describe '#sort' do
let(:project) { reusable_project }
@@ -1317,28 +1328,10 @@ RSpec.describe Issue do
let_it_be(:issue1) { create(:issue, project: project, relative_position: nil) }
let_it_be(:issue2) { create(:issue, project: project, relative_position: nil) }
- context 'when optimized_issue_neighbor_queries is enabled' do
- before do
- stub_feature_flags(optimized_issue_neighbor_queries: true)
- end
-
- it_behaves_like "a class that supports relative positioning" do
- let_it_be(:project) { reusable_project }
- let(:factory) { :issue }
- let(:default_params) { { project: project } }
- end
- end
-
- context 'when optimized_issue_neighbor_queries is disabled' do
- before do
- stub_feature_flags(optimized_issue_neighbor_queries: false)
- end
-
- it_behaves_like "a class that supports relative positioning" do
- let_it_be(:project) { reusable_project }
- let(:factory) { :issue }
- let(:default_params) { { project: project } }
- end
+ it_behaves_like "a class that supports relative positioning" do
+ let_it_be(:project) { reusable_project }
+ let(:factory) { :issue }
+ let(:default_params) { { project: project } }
end
it 'is not blocked for repositioning by default' do
@@ -1580,4 +1573,13 @@ RSpec.describe Issue do
expect(participant.issue.email_participants_emails_downcase).to match([participant.email.downcase])
end
end
+
+ describe '#escalation_status' do
+ it 'returns the incident_management_issuable_escalation_status association' do
+ escalation_status = create(:incident_management_issuable_escalation_status)
+ issue = escalation_status.issue
+
+ expect(issue.escalation_status).to eq(escalation_status)
+ end
+ end
end
diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb
index d41a1604211..19459561edf 100644
--- a/spec/models/key_spec.rb
+++ b/spec/models/key_spec.rb
@@ -21,6 +21,28 @@ RSpec.describe Key, :mailer do
it { is_expected.to allow_value(attributes_for(:ecdsa_key_256)[:key]).for(:key) }
it { is_expected.to allow_value(attributes_for(:ed25519_key_256)[:key]).for(:key) }
it { is_expected.not_to allow_value('foo-bar').for(:key) }
+
+ context 'key format' do
+ let(:key) { build(:key) }
+
+ it 'does not allow the key that begins with an algorithm name that is unsupported' do
+ key.key = 'unsupported-ssh-rsa key'
+
+ key.valid?
+
+ expect(key.errors.of_kind?(:key, :invalid)).to eq(true)
+ end
+
+ Gitlab::SSHPublicKey.supported_algorithms.each do |supported_algorithm|
+ it "allows the key that begins with supported algorithm name '#{supported_algorithm}'" do
+ key.key = "#{supported_algorithm} key"
+
+ key.valid?
+
+ expect(key.errors.of_kind?(:key, :invalid)).to eq(false)
+ end
+ end
+ end
end
describe "Methods" do
diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb
index 7ce32de6edc..1957c58ec81 100644
--- a/spec/models/member_spec.rb
+++ b/spec/models/member_spec.rb
@@ -9,6 +9,7 @@ RSpec.describe Member do
describe 'Associations' do
it { is_expected.to belong_to(:user) }
+ it { is_expected.to belong_to(:member_namespace) }
it { is_expected.to have_one(:member_task) }
end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index e1db1b3cf3e..4005a2ec6da 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -1648,10 +1648,7 @@ RSpec.describe MergeRequest, factory_default: :keep do
it 'uses template from target project' do
request = build(:merge_request, title: 'Fix everything')
- request.compare_commits = [
- double(safe_message: 'Commit message', gitaly_commit?: true, merge_commit?: false, description?: false)
- ]
- subject.target_project.merge_commit_template = '%{title}'
+ request.target_project.merge_commit_template = '%{title}'
expect(request.default_merge_commit_message)
.to eq('Fix everything')
@@ -3495,84 +3492,6 @@ RSpec.describe MergeRequest, factory_default: :keep do
end
end
- describe "#environments_for" do
- let(:project) { create(:project, :repository) }
- let(:user) { project.creator }
- let(:merge_request) { create(:merge_request, source_project: project) }
- let(:source_branch) { merge_request.source_branch }
- let(:target_branch) { merge_request.target_branch }
- let(:source_oid) { project.commit(source_branch).id }
- let(:target_oid) { project.commit(target_branch).id }
-
- before do
- merge_request.source_project.add_maintainer(user)
- merge_request.target_project.add_maintainer(user)
- end
-
- context 'with multiple environments' do
- let(:environments) { create_list(:environment, 3, project: project) }
-
- before do
- create(:deployment, :success, environment: environments.first, ref: source_branch, sha: source_oid)
- create(:deployment, :success, environment: environments.second, ref: target_branch, sha: target_oid)
- end
-
- it 'selects deployed environments' do
- expect(merge_request.environments_for(user)).to contain_exactly(environments.first)
- end
-
- it 'selects latest deployed environment' do
- latest_environment = create(:environment, project: project)
- create(:deployment, :success, environment: latest_environment, ref: source_branch, sha: source_oid)
-
- expect(merge_request.environments_for(user)).to eq([environments.first, latest_environment])
- expect(merge_request.environments_for(user, latest: true)).to contain_exactly(latest_environment)
- end
- end
-
- context 'with environments on source project' do
- let(:source_project) { fork_project(project, nil, repository: true) }
-
- let(:merge_request) do
- create(:merge_request,
- source_project: source_project, source_branch: 'feature',
- target_project: project)
- end
-
- let(:source_environment) { create(:environment, project: source_project) }
-
- before do
- create(:deployment, :success, environment: source_environment, ref: 'feature', sha: merge_request.diff_head_sha)
- end
-
- it 'selects deployed environments', :sidekiq_might_not_need_inline do
- expect(merge_request.environments_for(user)).to contain_exactly(source_environment)
- end
-
- context 'with environments on target project' do
- let(:target_environment) { create(:environment, project: project) }
-
- before do
- create(:deployment, :success, environment: target_environment, tag: true, sha: merge_request.diff_head_sha)
- end
-
- it 'selects deployed environments', :sidekiq_might_not_need_inline do
- expect(merge_request.environments_for(user)).to contain_exactly(source_environment, target_environment)
- end
- end
- end
-
- context 'without a diff_head_commit' do
- before do
- expect(merge_request).to receive(:diff_head_commit).and_return(nil)
- end
-
- it 'returns an empty array' do
- expect(merge_request.environments_for(user)).to be_empty
- end
- end
- end
-
describe "#environments" do
subject { merge_request.environments }
diff --git a/spec/models/namespace_setting_spec.rb b/spec/models/namespace_setting_spec.rb
index 429727c2360..c9f8a1bcdc2 100644
--- a/spec/models/namespace_setting_spec.rb
+++ b/spec/models/namespace_setting_spec.rb
@@ -126,57 +126,4 @@ RSpec.describe NamespaceSetting, type: :model do
end
end
end
-
- describe 'hooks related to group user cap update' do
- let(:settings) { create(:namespace_settings, new_user_signups_cap: user_cap) }
- let(:group) { create(:group, namespace_settings: settings) }
-
- before do
- allow(group).to receive(:root?).and_return(true)
- end
-
- context 'when updating a group with a user cap' do
- let(:user_cap) { nil }
-
- it 'also sets share_with_group_lock and prevent_sharing_groups_outside_hierarchy to true' do
- expect(group.new_user_signups_cap).to be_nil
- expect(group.share_with_group_lock).to be_falsey
- expect(settings.prevent_sharing_groups_outside_hierarchy).to be_falsey
-
- settings.update!(new_user_signups_cap: 10)
- group.reload
-
- expect(group.new_user_signups_cap).to eq(10)
- expect(group.share_with_group_lock).to be_truthy
- expect(settings.reload.prevent_sharing_groups_outside_hierarchy).to be_truthy
- end
-
- it 'has share_with_group_lock and prevent_sharing_groups_outside_hierarchy returning true for descendent groups' do
- descendent = create(:group, parent: group)
- desc_settings = descendent.namespace_settings
-
- expect(descendent.share_with_group_lock).to be_falsey
- expect(desc_settings.prevent_sharing_groups_outside_hierarchy).to be_falsey
-
- settings.update!(new_user_signups_cap: 10)
-
- expect(descendent.reload.share_with_group_lock).to be_truthy
- expect(desc_settings.reload.prevent_sharing_groups_outside_hierarchy).to be_truthy
- end
- end
-
- context 'when removing a user cap from namespace settings' do
- let(:user_cap) { 10 }
-
- it 'leaves share_with_group_lock and prevent_sharing_groups_outside_hierarchy set to true to the related group' do
- expect(group.share_with_group_lock).to be_truthy
- expect(settings.prevent_sharing_groups_outside_hierarchy).to be_truthy
-
- settings.update!(new_user_signups_cap: nil)
-
- expect(group.reload.share_with_group_lock).to be_truthy
- expect(settings.reload.prevent_sharing_groups_outside_hierarchy).to be_truthy
- end
- end
- end
end
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 54327fc70d9..5da0f7a134c 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -28,6 +28,8 @@ RSpec.describe Namespace do
it { is_expected.to have_one :onboarding_progress }
it { is_expected.to have_one :admin_note }
it { is_expected.to have_many :pending_builds }
+ it { is_expected.to have_one :namespace_route }
+ it { is_expected.to have_many :namespace_members }
describe '#children' do
let_it_be(:group) { create(:group) }
@@ -1263,6 +1265,32 @@ RSpec.describe Namespace do
end
end
+ describe '#use_traversal_ids_for_self_and_hierarchy?' do
+ let_it_be(:namespace, reload: true) { create(:namespace) }
+
+ subject { namespace.use_traversal_ids_for_self_and_hierarchy? }
+
+ it { is_expected.to eq true }
+
+ it_behaves_like 'disabled feature flag when traversal_ids is blank'
+
+ context 'when use_traversal_ids_for_self_and_hierarchy feature flag is false' do
+ before do
+ stub_feature_flags(use_traversal_ids_for_self_and_hierarchy: false)
+ end
+
+ it { is_expected.to eq false }
+ end
+
+ context 'when use_traversal_ids? feature flag is false' do
+ before do
+ stub_feature_flags(use_traversal_ids: false)
+ end
+
+ it { is_expected.to eq false }
+ end
+ end
+
describe '#users_with_descendants' do
let(:user_a) { create(:user) }
let(:user_b) { create(:user) }
diff --git a/spec/models/namespaces/project_namespace_spec.rb b/spec/models/namespaces/project_namespace_spec.rb
index 4416c49f1bf..47cf866c143 100644
--- a/spec/models/namespaces/project_namespace_spec.rb
+++ b/spec/models/namespaces/project_namespace_spec.rb
@@ -17,11 +17,11 @@ RSpec.describe Namespaces::ProjectNamespace, type: :model do
let_it_be(:project) { create(:project) }
let_it_be(:project_namespace) { project.project_namespace }
- it 'also deletes the associated project' do
+ it 'keeps the associated project' do
project_namespace.delete
expect { project_namespace.reload }.to raise_error(ActiveRecord::RecordNotFound)
- expect { project.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ expect(project.reload.project_namespace).to be_nil
end
end
end
diff --git a/spec/models/onboarding_progress_spec.rb b/spec/models/onboarding_progress_spec.rb
index deac8d29196..80a39404d10 100644
--- a/spec/models/onboarding_progress_spec.rb
+++ b/spec/models/onboarding_progress_spec.rb
@@ -131,29 +131,86 @@ RSpec.describe OnboardingProgress do
end
describe '.register' do
- subject(:register_action) { described_class.register(namespace, action) }
+ context 'for a single action' do
+ subject(:register_action) { described_class.register(namespace, action) }
- context 'when the namespace was onboarded' do
- before do
- described_class.onboard(namespace)
- end
+ context 'when the namespace was onboarded' do
+ before do
+ described_class.onboard(namespace)
+ end
- it 'registers the action for the namespace' do
- expect { register_action }.to change { described_class.completed?(namespace, action) }.from(false).to(true)
- end
+ it 'registers the action for the namespace' do
+ expect { register_action }.to change { described_class.completed?(namespace, action) }.from(false).to(true)
+ end
- context 'when the action does not exist' do
- let(:action) { :foo }
+ it 'does not override timestamp', :aggregate_failures do
+ expect(described_class.find_by_namespace_id(namespace.id).subscription_created_at).to be_nil
+ register_action
+ expect(described_class.find_by_namespace_id(namespace.id).subscription_created_at).not_to be_nil
+ expect { described_class.register(namespace, action) }.not_to change { described_class.find_by_namespace_id(namespace.id).subscription_created_at }
+ end
+
+ context 'when the action does not exist' do
+ let(:action) { :foo }
+ it 'does not register the action for the namespace' do
+ expect { register_action }.not_to change { described_class.completed?(namespace, action) }.from(nil)
+ end
+ end
+ end
+
+ context 'when the namespace was not onboarded' do
it 'does not register the action for the namespace' do
- expect { register_action }.not_to change { described_class.completed?(namespace, action) }.from(nil)
+ expect { register_action }.not_to change { described_class.completed?(namespace, action) }.from(false)
end
end
end
- context 'when the namespace was not onboarded' do
- it 'does not register the action for the namespace' do
- expect { register_action }.not_to change { described_class.completed?(namespace, action) }.from(false)
+ context 'for multiple actions' do
+ let(:action1) { :security_scan_enabled }
+ let(:action2) { :secure_dependency_scanning_run }
+ let(:actions) { [action1, action2] }
+
+ subject(:register_action) { described_class.register(namespace, actions) }
+
+ context 'when the namespace was onboarded' do
+ before do
+ described_class.onboard(namespace)
+ end
+
+ it 'registers the actions for the namespace' do
+ expect { register_action }.to change {
+ [described_class.completed?(namespace, action1), described_class.completed?(namespace, action2)]
+ }.from([false, false]).to([true, true])
+ end
+
+ it 'does not override timestamp', :aggregate_failures do
+ described_class.register(namespace, [action1])
+ expect(described_class.find_by_namespace_id(namespace.id).security_scan_enabled_at).not_to be_nil
+ expect(described_class.find_by_namespace_id(namespace.id).secure_dependency_scanning_run_at).to be_nil
+
+ expect { described_class.register(namespace, [action1, action2]) }.not_to change {
+ described_class.find_by_namespace_id(namespace.id).security_scan_enabled_at
+ }
+ expect(described_class.find_by_namespace_id(namespace.id).secure_dependency_scanning_run_at).not_to be_nil
+ end
+
+ context 'when one of the actions does not exist' do
+ let(:action2) { :foo }
+
+ it 'does not register any action for the namespace' do
+ expect { register_action }.not_to change {
+ [described_class.completed?(namespace, action1), described_class.completed?(namespace, action2)]
+ }.from([false, nil])
+ end
+ end
+ end
+
+ context 'when the namespace was not onboarded' do
+ it 'does not register the action for the namespace' do
+ expect { register_action }.not_to change { described_class.completed?(namespace, action1) }.from(false)
+ expect { described_class.register(namespace, action) }.not_to change { described_class.completed?(namespace, action2) }.from(false)
+ end
end
end
end
diff --git a/spec/models/packages/package_file_spec.rb b/spec/models/packages/package_file_spec.rb
index 8617793f41d..a86caa074f1 100644
--- a/spec/models/packages/package_file_spec.rb
+++ b/spec/models/packages/package_file_spec.rb
@@ -10,6 +10,9 @@ RSpec.describe Packages::PackageFile, type: :model do
let_it_be(:package_file3) { create(:package_file, :xml, file_name: 'formatted.zip') }
let_it_be(:debian_package) { create(:debian_package, project: project) }
+ it_behaves_like 'having unique enum values'
+ it_behaves_like 'destructible', factory: :package_file
+
describe 'relationships' do
it { is_expected.to belong_to(:package) }
it { is_expected.to have_one(:conan_file_metadatum) }
@@ -138,6 +141,24 @@ RSpec.describe Packages::PackageFile, type: :model do
it 'returns the matching file only for Helm packages' do
expect(described_class.for_helm_with_channel(project, channel)).to contain_exactly(helm_file2)
end
+
+ context 'with package files pending destruction' do
+ let_it_be(:package_file_pending_destruction) { create(:helm_package_file, :pending_destruction, package: helm_package2, channel: channel) }
+
+ it 'does not return them' do
+ expect(described_class.for_helm_with_channel(project, channel)).to contain_exactly(helm_file2)
+ end
+
+ context 'with packages_installable_package_files disabled' do
+ before do
+ stub_feature_flags(packages_installable_package_files: false)
+ end
+
+ it 'returns them' do
+ expect(described_class.for_helm_with_channel(project, channel)).to contain_exactly(helm_file2, package_file_pending_destruction)
+ end
+ end
+ end
end
describe '.most_recent!' do
@@ -154,15 +175,17 @@ RSpec.describe Packages::PackageFile, type: :model do
let_it_be(:package_file3_2) { create(:package_file, :npm, package: package3) }
let_it_be(:package_file3_3) { create(:package_file, :npm, package: package3) }
+ let_it_be(:package_file3_4) { create(:package_file, :npm, :pending_destruction, package: package3) }
let_it_be(:package_file4_2) { create(:package_file, :npm, package: package2) }
let_it_be(:package_file4_3) { create(:package_file, :npm, package: package2) }
let_it_be(:package_file4_4) { create(:package_file, :npm, package: package2) }
+ let_it_be(:package_file4_4) { create(:package_file, :npm, :pending_destruction, package: package2) }
- let(:most_recent_package_file1) { package1.package_files.recent.first }
- let(:most_recent_package_file2) { package2.package_files.recent.first }
- let(:most_recent_package_file3) { package3.package_files.recent.first }
- let(:most_recent_package_file4) { package4.package_files.recent.first }
+ let(:most_recent_package_file1) { package1.installable_package_files.recent.first }
+ let(:most_recent_package_file2) { package2.installable_package_files.recent.first }
+ let(:most_recent_package_file3) { package3.installable_package_files.recent.first }
+ let(:most_recent_package_file4) { package4.installable_package_files.recent.first }
subject { described_class.most_recent_for(packages) }
@@ -202,6 +225,24 @@ RSpec.describe Packages::PackageFile, type: :model do
it 'returns the most recent package for the selected channel' do
expect(subject).to contain_exactly(helm_package_file2)
end
+
+ context 'with package files pending destruction' do
+ let_it_be(:package_file_pending_destruction) { create(:helm_package_file, :pending_destruction, package: helm_package, channel: 'alpha') }
+
+ it 'does not return them' do
+ expect(subject).to contain_exactly(helm_package_file2)
+ end
+
+ context 'with packages_installable_package_files disabled' do
+ before do
+ stub_feature_flags(packages_installable_package_files: false)
+ end
+
+ it 'returns them' do
+ expect(subject).to contain_exactly(package_file_pending_destruction)
+ end
+ end
+ end
end
end
@@ -314,4 +355,25 @@ RSpec.describe Packages::PackageFile, type: :model do
end
end
end
+
+ context 'status scopes' do
+ let_it_be(:package) { create(:package) }
+ let_it_be(:default_package_file) { create(:package_file, package: package) }
+ let_it_be(:pending_destruction_package_file) { create(:package_file, :pending_destruction, package: package) }
+
+ describe '.installable' do
+ subject { package.installable_package_files }
+
+ it 'does not include non-displayable packages', :aggregate_failures do
+ is_expected.to include(default_package_file)
+ is_expected.not_to include(pending_destruction_package_file)
+ end
+ end
+
+ describe '.with_status' do
+ subject { described_class.with_status(:pending_destruction) }
+
+ it { is_expected.to contain_exactly(pending_destruction_package_file) }
+ end
+ end
end
diff --git a/spec/models/packages/package_spec.rb b/spec/models/packages/package_spec.rb
index 44ba6e0e2fd..122340f7bec 100644
--- a/spec/models/packages/package_spec.rb
+++ b/spec/models/packages/package_spec.rb
@@ -413,9 +413,17 @@ RSpec.describe Packages::Package, type: :model do
it_behaves_like 'validating version to be SemVer compliant for', :terraform_module_package
context 'nuget package' do
- it_behaves_like 'validating version to be SemVer compliant for', :nuget_package
+ subject { build_stubbed(:nuget_package) }
+ it { is_expected.to allow_value('1.2').for(:version) }
+ it { is_expected.to allow_value('1.2.3').for(:version) }
it { is_expected.to allow_value('1.2.3.4').for(:version) }
+ it { is_expected.to allow_value('1.2.3-beta').for(:version) }
+ it { is_expected.to allow_value('1.2.3-alpha.3').for(:version) }
+ it { is_expected.not_to allow_value('1').for(:version) }
+ it { is_expected.not_to allow_value('1./2.3').for(:version) }
+ it { is_expected.not_to allow_value('../../../../../1.2.3').for(:version) }
+ it { is_expected.not_to allow_value('%2e%2e%2f1.2.3').for(:version) }
end
end
@@ -839,6 +847,7 @@ RSpec.describe Packages::Package, type: :model do
end
context 'status scopes' do
+ let_it_be(:default_package) { create(:maven_package, :default) }
let_it_be(:hidden_package) { create(:maven_package, :hidden) }
let_it_be(:processing_package) { create(:maven_package, :processing) }
let_it_be(:error_package) { create(:maven_package, :error) }
@@ -856,11 +865,15 @@ RSpec.describe Packages::Package, type: :model do
describe '.installable' do
subject { described_class.installable }
- it 'does not include non-displayable packages', :aggregate_failures do
+ it 'does not include non-installable packages', :aggregate_failures do
is_expected.not_to include(error_package)
- is_expected.not_to include(hidden_package)
is_expected.not_to include(processing_package)
end
+
+ it 'includes installable packages', :aggregate_failures do
+ is_expected.to include(default_package)
+ is_expected.to include(hidden_package)
+ end
end
describe '.with_status' do
diff --git a/spec/models/pages_domain_spec.rb b/spec/models/pages_domain_spec.rb
index 8a5b1e73194..0735bf25690 100644
--- a/spec/models/pages_domain_spec.rb
+++ b/spec/models/pages_domain_spec.rb
@@ -336,129 +336,6 @@ RSpec.describe PagesDomain do
end
end
- describe '#update_daemon' do
- let_it_be(:project) { create(:project).tap(&:mark_pages_as_deployed) }
-
- context 'when usage is serverless' do
- it 'does not call the UpdatePagesConfigurationService' do
- expect(PagesUpdateConfigurationWorker).not_to receive(:perform_async)
-
- create(:pages_domain, usage: :serverless)
- end
- end
-
- it 'runs when the domain is created' do
- domain = build(:pages_domain)
-
- expect(domain).to receive(:update_daemon)
-
- domain.save!
- end
-
- it 'runs when the domain is destroyed' do
- domain = create(:pages_domain)
-
- expect(domain).to receive(:update_daemon)
-
- domain.destroy!
- end
-
- it "schedules a PagesUpdateConfigurationWorker" do
- expect(PagesUpdateConfigurationWorker).to receive(:perform_async).with(project.id)
-
- create(:pages_domain, project: project)
- end
-
- context "when the pages aren't deployed" do
- let_it_be(:project) { create(:project).tap(&:mark_pages_as_not_deployed) }
-
- it "does not schedule a PagesUpdateConfigurationWorker" do
- expect(PagesUpdateConfigurationWorker).not_to receive(:perform_async).with(project.id)
-
- create(:pages_domain, project: project)
- end
- end
-
- context 'configuration updates when attributes change' do
- let_it_be(:project1) { create(:project) }
- let_it_be(:project2) { create(:project) }
- let_it_be(:domain) { create(:pages_domain) }
-
- where(:attribute, :old_value, :new_value, :update_expected) do
- now = Time.current
- future = now + 1.day
-
- :project | nil | :project1 | true
- :project | :project1 | :project1 | false
- :project | :project1 | :project2 | true
- :project | :project1 | nil | true
-
- # domain can't be set to nil
- :domain | 'a.com' | 'a.com' | false
- :domain | 'a.com' | 'b.com' | true
-
- # verification_code can't be set to nil
- :verification_code | 'foo' | 'foo' | false
- :verification_code | 'foo' | 'bar' | false
-
- :verified_at | nil | now | false
- :verified_at | now | now | false
- :verified_at | now | future | false
- :verified_at | now | nil | false
-
- :enabled_until | nil | now | true
- :enabled_until | now | now | false
- :enabled_until | now | future | false
- :enabled_until | now | nil | true
- end
-
- with_them do
- it 'runs if a relevant attribute has changed' do
- a = old_value.is_a?(Symbol) ? send(old_value) : old_value
- b = new_value.is_a?(Symbol) ? send(new_value) : new_value
-
- domain.update!(attribute => a)
-
- if update_expected
- expect(domain).to receive(:update_daemon)
- else
- expect(domain).not_to receive(:update_daemon)
- end
-
- domain.update!(attribute => b)
- end
- end
-
- context 'TLS configuration' do
- let_it_be(:domain_without_tls) { create(:pages_domain, :without_certificate, :without_key) }
- let_it_be(:domain) { create(:pages_domain) }
-
- let(:cert1) { domain.certificate }
- let(:cert2) { cert1 + ' ' }
- let(:key1) { domain.key }
- let(:key2) { key1 + ' ' }
-
- it 'updates when added' do
- expect(domain_without_tls).to receive(:update_daemon)
-
- domain_without_tls.update!(key: key1, certificate: cert1)
- end
-
- it 'updates when changed' do
- expect(domain).to receive(:update_daemon)
-
- domain.update!(key: key2, certificate: cert2)
- end
-
- it 'updates when removed' do
- expect(domain).to receive(:update_daemon)
-
- domain.update!(key: nil, certificate: nil)
- end
- end
- end
- end
-
describe '#user_provided_key' do
subject { domain.user_provided_key }
diff --git a/spec/models/preloaders/environments/deployment_preloader_spec.rb b/spec/models/preloaders/environments/deployment_preloader_spec.rb
new file mode 100644
index 00000000000..c1812d45628
--- /dev/null
+++ b/spec/models/preloaders/environments/deployment_preloader_spec.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Preloaders::Environments::DeploymentPreloader do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project, reload: true) { create(:project, :repository) }
+
+ let_it_be(:pipeline) { create(:ci_pipeline, user: user, project: project, sha: project.commit.sha) }
+ let_it_be(:ci_build_a) { create(:ci_build, user: user, project: project, pipeline: pipeline) }
+ let_it_be(:ci_build_b) { create(:ci_build, user: user, project: project, pipeline: pipeline) }
+ let_it_be(:ci_build_c) { create(:ci_build, user: user, project: project, pipeline: pipeline) }
+
+ let_it_be(:environment_a) { create(:environment, project: project, state: :available) }
+ let_it_be(:environment_b) { create(:environment, project: project, state: :available) }
+
+ before do
+ create(:deployment, :success, project: project, environment: environment_a, deployable: ci_build_a)
+ create(:deployment, :success, project: project, environment: environment_a, deployable: ci_build_b)
+ create(:deployment, :success, project: project, environment: environment_b, deployable: ci_build_c)
+ end
+
+ def preload_association(association_name)
+ described_class.new(project.environments)
+ .execute_with_union(association_name, deployment_associations)
+ end
+
+ def deployment_associations
+ {
+ user: [],
+ deployable: {
+ pipeline: {
+ manual_actions: []
+ }
+ }
+ }
+ end
+
+ it 'does not trigger N+1 queries' do
+ control = ActiveRecord::QueryRecorder.new { preload_association(:last_deployment) }
+
+ ci_build_d = create(:ci_build, user: user, project: project, pipeline: pipeline)
+ create(:deployment, :success, project: project, environment: environment_b, deployable: ci_build_d)
+
+ expect { preload_association(:last_deployment) }.not_to exceed_query_limit(control)
+ end
+
+ it 'batch loads the dependent associations' do
+ preload_association(:last_deployment)
+
+ expect do
+ project.environments.first.last_deployment.deployable.pipeline.manual_actions
+ end.not_to exceed_query_limit(0)
+ end
+
+ # Example query scoped with IN clause for `last_deployment` association preload:
+ # SELECT DISTINCT ON (environment_id) deployments.* FROM "deployments" WHERE "deployments"."status" IN (1, 2, 3, 4, 6) AND "deployments"."environment_id" IN (35, 34, 33) ORDER BY environment_id, deployments.id DESC
+ it 'avoids scoping with IN clause during preload' do
+ control = ActiveRecord::QueryRecorder.new { preload_association(:last_deployment) }
+
+ default_preload_query = control.occurrences_by_line_method.first[1][:occurrences].any? { |i| i.include?('"deployments"."environment_id" IN') }
+
+ expect(default_preload_query).to be(false)
+ end
+end
diff --git a/spec/models/project_pages_metadatum_spec.rb b/spec/models/project_pages_metadatum_spec.rb
index 31a533e0363..af2f9b94871 100644
--- a/spec/models/project_pages_metadatum_spec.rb
+++ b/spec/models/project_pages_metadatum_spec.rb
@@ -18,4 +18,15 @@ 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 4e38bf7d3e3..2fe50f8c48a 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -7,6 +7,7 @@ RSpec.describe Project, factory_default: :keep do
include GitHelpers
include ExternalAuthorizationServiceHelpers
include ReloadHelpers
+ include StubGitlabCalls
using RSpec::Parameterized::TableSyntax
let_it_be(:namespace) { create_default(:namespace).freeze }
@@ -379,6 +380,7 @@ RSpec.describe Project, factory_default: :keep do
it { is_expected.to validate_presence_of(:name) }
it { is_expected.to validate_uniqueness_of(:name).scoped_to(:namespace_id) }
it { is_expected.to validate_length_of(:name).is_at_most(255) }
+ it { is_expected.not_to allow_value('colon:in:path').for(:path) } # This is to validate that a specially crafted name cannot bypass a pattern match. See !72555
it { is_expected.to validate_presence_of(:path) }
it { is_expected.to validate_length_of(:path).is_at_most(255) }
it { is_expected.to validate_length_of(:description).is_at_most(2000) }
@@ -1298,7 +1300,7 @@ RSpec.describe Project, factory_default: :keep do
end
end
- describe '#default_owner' do
+ describe '#first_owner' do
let_it_be(:owner) { create(:user) }
let_it_be(:namespace) { create(:namespace, owner: owner) }
@@ -1306,7 +1308,7 @@ RSpec.describe Project, factory_default: :keep do
let(:project) { build(:project, namespace: namespace) }
it 'is the namespace owner' do
- expect(project.default_owner).to eq(owner)
+ expect(project.first_owner).to eq(owner)
end
end
@@ -1315,9 +1317,9 @@ RSpec.describe Project, factory_default: :keep do
let(:project) { build(:project, group: group, namespace: namespace) }
it 'is the group owner' do
- allow(group).to receive(:default_owner).and_return(Object.new)
+ allow(group).to receive(:first_owner).and_return(Object.new)
- expect(project.default_owner).to eq(group.default_owner)
+ expect(project.first_owner).to eq(group.first_owner)
end
end
end
@@ -1358,51 +1360,51 @@ RSpec.describe Project, factory_default: :keep do
project.reload.has_external_issue_tracker
end
- it 'is false when external issue tracker service is not active' do
- create(:service, project: project, category: 'issue_tracker', active: false)
+ it 'is false when external issue tracker integration is not active' do
+ create(:integration, project: project, category: 'issue_tracker', active: false)
is_expected.to eq(false)
end
- it 'is false when other service is active' do
- create(:service, project: project, category: 'not_issue_tracker', active: true)
+ it 'is false when other integration is active' do
+ create(:integration, project: project, category: 'not_issue_tracker', active: true)
is_expected.to eq(false)
end
- context 'when there is an active external issue tracker service' do
- let!(:service) do
- create(:service, project: project, type: 'JiraService', category: 'issue_tracker', active: true)
+ 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)
end
specify { is_expected.to eq(true) }
- it 'becomes false when external issue tracker service is destroyed' do
+ it 'becomes false when external issue tracker integration is destroyed' do
expect do
- Integration.find(service.id).delete
+ Integration.find(integration.id).delete
end.to change { subject }.to(false)
end
- it 'becomes false when external issue tracker service becomes inactive' do
+ it 'becomes false when external issue tracker integration becomes inactive' do
expect do
- service.update_column(:active, false)
+ integration.update_column(:active, false)
end.to change { subject }.to(false)
end
- context 'when there are two active external issue tracker services' do
- let_it_be(:second_service) do
- create(:service, project: project, type: 'CustomIssueTracker', category: 'issue_tracker', active: true)
+ 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)
end
- it 'does not become false when external issue tracker service is destroyed' do
+ it 'does not become false when external issue tracker integration is destroyed' do
expect do
- Integration.find(service.id).delete
+ Integration.find(integration.id).delete
end.not_to change { subject }
end
- it 'does not become false when external issue tracker service becomes inactive' do
+ it 'does not become false when external issue tracker integration becomes inactive' do
expect do
- service.update_column(:active, false)
+ integration.update_column(:active, false)
end.not_to change { subject }
end
end
@@ -1454,13 +1456,13 @@ RSpec.describe Project, factory_default: :keep do
specify { expect(has_external_wiki).to eq(true) }
- it 'becomes false if the external wiki service is destroyed' do
+ it 'becomes false if the external wiki integration is destroyed' do
expect do
Integration.find(integration.id).delete
end.to change { has_external_wiki }.to(false)
end
- it 'becomes false if the external wiki service becomes inactive' do
+ it 'becomes false if the external wiki integration becomes inactive' do
expect do
integration.update_column(:active, false)
end.to change { has_external_wiki }.to(false)
@@ -4580,11 +4582,25 @@ RSpec.describe Project, factory_default: :keep do
include ProjectHelpers
let_it_be(:group) { create(:group) }
+ let_it_be_with_reload(:project) { create(:project, namespace: group) }
- let!(:project) { create(:project, project_level, namespace: group ) }
let(:user) { create_user_from_membership(project, membership) }
- context 'reporter level access' do
+ subject { described_class.filter_by_feature_visibility(feature, user) }
+
+ shared_examples 'filter respects visibility' do
+ it 'respects visibility' do
+ enable_admin_mode!(user) if admin_mode
+ project.update!(visibility_level: Gitlab::VisibilityLevel.level_value(project_level.to_s))
+ update_feature_access_level(project, feature_access_level)
+
+ expected_objects = expected_count == 1 ? [project] : []
+
+ expect(subject).to eq(expected_objects)
+ end
+ end
+
+ context 'with reporter level access' do
let(:feature) { MergeRequest }
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
@@ -4592,20 +4608,11 @@ RSpec.describe Project, factory_default: :keep do
end
with_them do
- it "respects visibility" do
- enable_admin_mode!(user) if admin_mode
- update_feature_access_level(project, feature_access_level)
-
- expected_objects = expected_count == 1 ? [project] : []
-
- expect(
- described_class.filter_by_feature_visibility(feature, user)
- ).to eq(expected_objects)
- end
+ it_behaves_like 'filter respects visibility'
end
end
- context 'issues' do
+ context 'with feature issues' do
let(:feature) { Issue }
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
@@ -4613,20 +4620,11 @@ RSpec.describe Project, factory_default: :keep do
end
with_them do
- it "respects visibility" do
- enable_admin_mode!(user) if admin_mode
- update_feature_access_level(project, feature_access_level)
-
- expected_objects = expected_count == 1 ? [project] : []
-
- expect(
- described_class.filter_by_feature_visibility(feature, user)
- ).to eq(expected_objects)
- end
+ it_behaves_like 'filter respects visibility'
end
end
- context 'wiki' do
+ context 'with feature wiki' do
let(:feature) { :wiki }
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
@@ -4634,20 +4632,11 @@ RSpec.describe Project, factory_default: :keep do
end
with_them do
- it "respects visibility" do
- enable_admin_mode!(user) if admin_mode
- update_feature_access_level(project, feature_access_level)
-
- expected_objects = expected_count == 1 ? [project] : []
-
- expect(
- described_class.filter_by_feature_visibility(feature, user)
- ).to eq(expected_objects)
- end
+ it_behaves_like 'filter respects visibility'
end
end
- context 'code' do
+ context 'with feature code' do
let(:feature) { :repository }
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
@@ -4655,16 +4644,7 @@ RSpec.describe Project, factory_default: :keep do
end
with_them do
- it "respects visibility" do
- enable_admin_mode!(user) if admin_mode
- update_feature_access_level(project, feature_access_level)
-
- expected_objects = expected_count == 1 ? [project] : []
-
- expect(
- described_class.filter_by_feature_visibility(feature, user)
- ).to eq(expected_objects)
- end
+ it_behaves_like 'filter respects visibility'
end
end
end
@@ -6835,7 +6815,7 @@ RSpec.describe Project, factory_default: :keep do
describe 'with integrations and chat names' do
subject { create(:project) }
- let(:integration) { create(:service, project: subject) }
+ let(:integration) { create(:integration, project: subject) }
before do
create_list(:chat_name, 5, integration: integration)
@@ -7476,6 +7456,258 @@ RSpec.describe Project, factory_default: :keep do
end
end
+ describe '#enforced_runner_token_expiration_interval and #effective_runner_token_expiration_interval' do
+ shared_examples 'no enforced expiration interval' do
+ it { expect(subject.enforced_runner_token_expiration_interval).to be_nil }
+ end
+
+ shared_examples 'enforced expiration interval' do |enforced_interval:|
+ it { expect(subject.enforced_runner_token_expiration_interval).to eq(enforced_interval) }
+ end
+
+ shared_examples 'no effective expiration interval' do
+ it { expect(subject.effective_runner_token_expiration_interval).to be_nil }
+ end
+
+ shared_examples 'effective expiration interval' do |effective_interval:|
+ it { expect(subject.effective_runner_token_expiration_interval).to eq(effective_interval) }
+ end
+
+ context 'when there is no interval' do
+ let_it_be(:project) { create(:project) }
+
+ subject { project }
+
+ it_behaves_like 'no enforced expiration interval'
+ it_behaves_like 'no effective expiration interval'
+ end
+
+ context 'when there is a project interval' do
+ let_it_be(:project) { create(:project, runner_token_expiration_interval: 3.days.to_i) }
+
+ subject { project }
+
+ it_behaves_like 'no enforced expiration interval'
+ it_behaves_like 'effective expiration interval', effective_interval: 3.days
+ end
+
+ # runner_token_expiration_interval should not affect the expiration interval, only
+ # project_runner_token_expiration_interval should.
+ context 'when there is a site-wide enforced shared interval' do
+ before do
+ stub_application_setting(runner_token_expiration_interval: 5.days.to_i)
+ end
+
+ let_it_be(:project) { create(:project) }
+
+ subject { project }
+
+ it_behaves_like 'no enforced expiration interval'
+ it_behaves_like 'no effective expiration interval'
+ end
+
+ # group_runner_token_expiration_interval should not affect the expiration interval, only
+ # project_runner_token_expiration_interval should.
+ context 'when there is a site-wide enforced group interval' do
+ before do
+ stub_application_setting(group_runner_token_expiration_interval: 5.days.to_i)
+ end
+
+ let_it_be(:project) { create(:project) }
+
+ subject { project }
+
+ it_behaves_like 'no enforced expiration interval'
+ it_behaves_like 'no effective expiration interval'
+ end
+
+ context 'when there is a site-wide enforced project interval' do
+ before do
+ stub_application_setting(project_runner_token_expiration_interval: 5.days.to_i)
+ end
+
+ let_it_be(:project) { create(:project) }
+
+ subject { project }
+
+ it_behaves_like 'enforced expiration interval', enforced_interval: 5.days
+ it_behaves_like 'effective expiration interval', effective_interval: 5.days
+ end
+
+ # runner_token_expiration_interval should not affect the expiration interval, only
+ # project_runner_token_expiration_interval should.
+ context 'when there is a group-enforced group interval' do
+ let_it_be(:group_settings) { create(:namespace_settings, runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:group) { create(:group, namespace_settings: group_settings) }
+ let_it_be(:project) { create(:project, group: group) }
+
+ subject { project }
+
+ it_behaves_like 'no enforced expiration interval'
+ it_behaves_like 'no effective expiration interval'
+ end
+
+ # subgroup_runner_token_expiration_interval should not affect the expiration interval, only
+ # project_runner_token_expiration_interval should.
+ context 'when there is a group-enforced subgroup interval' do
+ let_it_be(:group_settings) { create(:namespace_settings, subgroup_runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:group) { create(:group, namespace_settings: group_settings) }
+ let_it_be(:project) { create(:project, group: group) }
+
+ subject { project }
+
+ it_behaves_like 'no enforced expiration interval'
+ it_behaves_like 'no effective expiration interval'
+ end
+
+ context 'when there is an owner group-enforced project interval' do
+ let_it_be(:group_settings) { create(:namespace_settings, project_runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:group) { create(:group, namespace_settings: group_settings) }
+ let_it_be(:project) { create(:project, group: group) }
+
+ subject { project }
+
+ it_behaves_like 'enforced expiration interval', enforced_interval: 4.days
+ it_behaves_like 'effective expiration interval', effective_interval: 4.days
+ end
+
+ context 'when there is a grandparent group-enforced interval' do
+ let_it_be(:grandparent_group_settings) { create(:namespace_settings, project_runner_token_expiration_interval: 3.days.to_i) }
+ let_it_be(:grandparent_group) { create(:group, namespace_settings: grandparent_group_settings) }
+ let_it_be(:parent_group_settings) { create(:namespace_settings) }
+ let_it_be(:parent_group) { create(:group, parent: grandparent_group, namespace_settings: parent_group_settings) }
+ let_it_be(:group_settings) { create(:namespace_settings, project_runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:group) { create(:group, parent: parent_group, namespace_settings: group_settings) }
+ let_it_be(:project) { create(:project, group: group) }
+
+ subject { project }
+
+ it_behaves_like 'enforced expiration interval', enforced_interval: 3.days
+ it_behaves_like 'effective expiration interval', effective_interval: 3.days
+ end
+
+ context 'when there is a parent group-enforced interval overridden by group-enforced interval' do
+ let_it_be(:parent_group_settings) { create(:namespace_settings, project_runner_token_expiration_interval: 5.days.to_i) }
+ let_it_be(:parent_group) { create(:group, namespace_settings: parent_group_settings) }
+ let_it_be(:group_settings) { create(:namespace_settings, project_runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:group) { create(:group, parent: parent_group, namespace_settings: group_settings) }
+ let_it_be(:project) { create(:project, group: group) }
+
+ subject { project }
+
+ it_behaves_like 'enforced expiration interval', enforced_interval: 4.days
+ it_behaves_like 'effective expiration interval', effective_interval: 4.days
+ end
+
+ context 'when site-wide enforced interval overrides project interval' do
+ before do
+ stub_application_setting(project_runner_token_expiration_interval: 3.days.to_i)
+ end
+
+ let_it_be(:project) { create(:project, runner_token_expiration_interval: 4.days.to_i) }
+
+ subject { project }
+
+ it_behaves_like 'enforced expiration interval', enforced_interval: 3.days
+ it_behaves_like 'effective expiration interval', effective_interval: 3.days
+ end
+
+ context 'when project interval overrides site-wide enforced interval' do
+ before do
+ stub_application_setting(project_runner_token_expiration_interval: 5.days.to_i)
+ end
+
+ let_it_be(:project) { create(:project, runner_token_expiration_interval: 4.days.to_i) }
+
+ subject { project }
+
+ it_behaves_like 'enforced expiration interval', enforced_interval: 5.days
+ it_behaves_like 'effective expiration interval', effective_interval: 4.days
+
+ it 'has human-readable expiration intervals' do
+ expect(subject.enforced_runner_token_expiration_interval_human_readable).to eq('5d')
+ expect(subject.effective_runner_token_expiration_interval_human_readable).to eq('4d')
+ end
+ end
+
+ context 'when site-wide enforced interval overrides group-enforced interval' do
+ before do
+ stub_application_setting(project_runner_token_expiration_interval: 3.days.to_i)
+ end
+
+ let_it_be(:group_settings) { create(:namespace_settings, project_runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:group) { create(:group, namespace_settings: group_settings) }
+ let_it_be(:project) { create(:project, group: group) }
+
+ subject { project }
+
+ it_behaves_like 'enforced expiration interval', enforced_interval: 3.days
+ it_behaves_like 'effective expiration interval', effective_interval: 3.days
+ end
+
+ context 'when group-enforced interval overrides site-wide enforced interval' do
+ before do
+ stub_application_setting(project_runner_token_expiration_interval: 5.days.to_i)
+ end
+
+ let_it_be(:group_settings) { create(:namespace_settings, project_runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:group) { create(:group, namespace_settings: group_settings) }
+ let_it_be(:project) { create(:project, group: group) }
+
+ subject { project }
+
+ it_behaves_like 'enforced expiration interval', enforced_interval: 4.days
+ it_behaves_like 'effective expiration interval', effective_interval: 4.days
+ end
+
+ context 'when group-enforced interval overrides project interval' do
+ let_it_be(:group_settings) { create(:namespace_settings, project_runner_token_expiration_interval: 3.days.to_i) }
+ let_it_be(:group) { create(:group, namespace_settings: group_settings) }
+ let_it_be(:project) { create(:project, group: group, runner_token_expiration_interval: 4.days.to_i) }
+
+ subject { project }
+
+ it_behaves_like 'enforced expiration interval', enforced_interval: 3.days
+ it_behaves_like 'effective expiration interval', effective_interval: 3.days
+ end
+
+ context 'when project interval overrides group-enforced interval' do
+ let_it_be(:group_settings) { create(:namespace_settings, project_runner_token_expiration_interval: 5.days.to_i) }
+ let_it_be(:group) { create(:group, namespace_settings: group_settings) }
+ let_it_be(:project) { create(:project, group: group, runner_token_expiration_interval: 4.days.to_i) }
+
+ subject { project }
+
+ it_behaves_like 'enforced expiration interval', enforced_interval: 5.days
+ it_behaves_like 'effective expiration interval', effective_interval: 4.days
+ end
+
+ # Unrelated groups should not affect the expiration interval.
+ context 'when there is an enforced project interval in an unrelated group' do
+ let_it_be(:unrelated_group_settings) { create(:namespace_settings, project_runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:unrelated_group) { create(:group, namespace_settings: unrelated_group_settings) }
+ let_it_be(:project) { create(:project) }
+
+ subject { project }
+
+ it_behaves_like 'no enforced expiration interval'
+ it_behaves_like 'no effective expiration interval'
+ end
+
+ # Subgroups should not affect the parent group expiration interval.
+ context 'when there is an enforced project interval in a subgroup' do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:subgroup_settings) { create(:namespace_settings, project_runner_token_expiration_interval: 4.days.to_i) }
+ let_it_be(:subgroup) { create(:group, parent: group, namespace_settings: subgroup_settings) }
+ let_it_be(:project) { create(:project, group: group) }
+
+ subject { project }
+
+ it_behaves_like 'no enforced expiration interval'
+ it_behaves_like 'no effective expiration interval'
+ end
+ end
+
it_behaves_like 'it has loose foreign keys' do
let(:factory_name) { :project }
end
@@ -7551,6 +7783,46 @@ RSpec.describe Project, factory_default: :keep do
end
end
+ describe '#context_commits_enabled?' do
+ let_it_be(:project) { create(:project) }
+
+ 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
+
+ it { is_expected.to be_falsey }
+ end
+
+ context 'when context_commits feature flag is enabled on this project' do
+ before do
+ stub_feature_flags(context_commits: project)
+ end
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when context_commits feature flag is enabled on another project' do
+ let(:another_project) { create(:project) }
+
+ before do
+ stub_feature_flags(context_commits: another_project)
+ end
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
private
def finish_job(export_job)
diff --git a/spec/models/protectable_dropdown_spec.rb b/spec/models/protectable_dropdown_spec.rb
index ab3f455fe63..a256f9e0ab1 100644
--- a/spec/models/protectable_dropdown_spec.rb
+++ b/spec/models/protectable_dropdown_spec.rb
@@ -3,8 +3,9 @@
require 'spec_helper'
RSpec.describe ProtectableDropdown do
+ subject(:dropdown) { described_class.new(project, ref_type) }
+
let(:project) { create(:project, :repository) }
- let(:subject) { described_class.new(project, :branches) }
describe 'initialize' do
it 'raises ArgumentError for invalid ref type' do
@@ -13,34 +14,75 @@ RSpec.describe ProtectableDropdown do
end
end
- describe '#protectable_ref_names' do
+ shared_examples 'protectable_ref_names' do
context 'when project repository is not empty' do
- before do
- create(:protected_branch, project: project, name: 'master')
- end
-
- it { expect(subject.protectable_ref_names).to include('feature') }
- it { expect(subject.protectable_ref_names).not_to include('master') }
+ it 'includes elements matching a protected ref wildcard' do
+ is_expected.to include(matching_ref)
- it "includes branches matching a protected branch wildcard" do
- expect(subject.protectable_ref_names).to include('feature')
+ factory = ref_type == :branches ? :protected_branch : :protected_tag
- create(:protected_branch, name: 'feat*', project: project)
+ create(factory, name: "#{matching_ref[0]}*", project: project)
- subject = described_class.new(project.reload, :branches)
+ subject = described_class.new(project.reload, ref_type)
- expect(subject.protectable_ref_names).to include('feature')
+ expect(subject.protectable_ref_names).to include(matching_ref)
end
end
context 'when project repository is empty' do
let(:project) { create(:project) }
- it "returns empty list" do
- subject = described_class.new(project, :branches)
+ it 'returns empty list' do
+ is_expected.to be_empty
+ end
+ end
+ end
+
+ describe '#protectable_ref_names' do
+ subject { dropdown.protectable_ref_names }
+
+ context 'for branches' do
+ let(:ref_type) { :branches }
+ let(:matching_ref) { 'feature' }
- expect(subject.protectable_ref_names).to be_empty
+ before do
+ create(:protected_branch, project: project, name: 'master')
end
+
+ it { is_expected.to include(matching_ref) }
+ it { is_expected.not_to include('master') }
+
+ it_behaves_like 'protectable_ref_names'
+ end
+
+ context 'for tags' do
+ let(:ref_type) { :tags }
+ let(:matching_ref) { 'v1.0.0' }
+
+ before do
+ create(:protected_tag, project: project, name: 'v1.1.0')
+ end
+
+ it { is_expected.to include(matching_ref) }
+ it { is_expected.not_to include('v1.1.0') }
+
+ it_behaves_like 'protectable_ref_names'
+ end
+ end
+
+ describe '#hash' do
+ subject { dropdown.hash }
+
+ context 'for branches' do
+ let(:ref_type) { :branches }
+
+ it { is_expected.to include(id: 'feature', text: 'feature', title: 'feature') }
+ end
+
+ context 'for tags' do
+ let(:ref_type) { :tags }
+
+ it { is_expected.to include(id: 'v1.0.0', text: 'v1.0.0', title: 'v1.0.0') }
end
end
end
diff --git a/spec/models/ref_matcher_spec.rb b/spec/models/ref_matcher_spec.rb
new file mode 100644
index 00000000000..47a6a8b986c
--- /dev/null
+++ b/spec/models/ref_matcher_spec.rb
@@ -0,0 +1,83 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe RefMatcher do
+ subject(:ref_matcher) { described_class.new(ref_pattern) }
+
+ let(:ref_pattern) { 'v1.0' }
+
+ shared_examples 'matching_refs' do
+ context 'when there is no match' do
+ let(:ref_pattern) { 'unknown' }
+
+ it { is_expected.to match_array([]) }
+ end
+
+ context 'when ref pattern is a wildcard' do
+ let(:ref_pattern) { 'v*' }
+
+ it { is_expected.to match_array(refs) }
+ end
+ end
+
+ describe '#matching' do
+ subject { ref_matcher.matching(refs) }
+
+ context 'when refs are strings' do
+ let(:refs) { ['v1.0', 'v1.1'] }
+
+ it { is_expected.to match_array([ref_pattern]) }
+
+ it_behaves_like 'matching_refs'
+ end
+
+ context 'when refs are ref objects' do
+ let(:matching_ref) { double('tag', name: 'v1.0') }
+ let(:not_matching_ref) { double('tag', name: 'v1.1') }
+ let(:refs) { [matching_ref, not_matching_ref] }
+
+ it { is_expected.to match_array([matching_ref]) }
+
+ it_behaves_like 'matching_refs'
+ end
+ end
+
+ describe '#matches?' do
+ subject { ref_matcher.matches?(ref_name) }
+
+ let(:ref_name) { 'v1.0' }
+
+ it { is_expected.to be_truthy }
+
+ context 'when ref_name is empty' do
+ let(:ref_name) { '' }
+
+ it { is_expected.to be_falsey }
+ end
+
+ context 'when ref pattern matches wildcard' do
+ let(:ref_pattern) { 'v*' }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when ref pattern does not match wildcard' do
+ let(:ref_pattern) { 'v2.*' }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
+ describe '#wildcard?' do
+ subject { ref_matcher.wildcard? }
+
+ it { is_expected.to be_falsey }
+
+ context 'when pattern is a wildcard' do
+ let(:ref_pattern) { 'v*' }
+
+ it { is_expected.to be_truthy }
+ end
+ end
+end
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 96cbdb468aa..e592a4964f5 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -2398,17 +2398,6 @@ RSpec.describe Repository do
it 'returns nil when tag does not exists' do
expect(repository.find_tag('does-not-exist')).to be_nil
end
-
- context 'when find_tag_via_gitaly is disabled' do
- it 'fetches all tags' do
- stub_feature_flags(find_tag_via_gitaly: false)
-
- expect(Gitlab::GitalyClient)
- .to receive(:call).with(anything, :ref_service, :find_all_tags, anything, anything).and_call_original
-
- expect(repository.find_tag('v1.1.0').name).to eq('v1.1.0')
- end
- end
end
describe '#avatar' do
diff --git a/spec/models/route_spec.rb b/spec/models/route_spec.rb
index b2fa9c24535..0489a4fb995 100644
--- a/spec/models/route_spec.rb
+++ b/spec/models/route_spec.rb
@@ -8,6 +8,7 @@ RSpec.describe Route do
describe 'relationships' do
it { is_expected.to belong_to(:source) }
+ it { is_expected.to belong_to(:namespace) }
end
describe 'validations' do
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index f8cea619233..ac2474ac393 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -83,6 +83,9 @@ RSpec.describe User do
it { is_expected.to delegate_method(:registration_objective).to(:user_detail).allow_nil }
it { is_expected.to delegate_method(:registration_objective=).to(:user_detail).with_arguments(:args).allow_nil }
+
+ it { is_expected.to delegate_method(:requires_credit_card_verification).to(:user_detail).allow_nil }
+ it { is_expected.to delegate_method(:requires_credit_card_verification=).to(:user_detail).with_arguments(:args).allow_nil }
end
describe 'associations' do
@@ -436,7 +439,7 @@ RSpec.describe User do
subject { build(:user) }
end
- it_behaves_like 'an object with RFC3696 compliant email-formatted attributes', :public_email, :notification_email do
+ it_behaves_like 'an object with email-formatted attributes', :public_email, :notification_email do
subject { create(:user).tap { |user| user.emails << build(:email, email: email_value, confirmed_at: Time.current) } }
end
@@ -542,6 +545,13 @@ RSpec.describe User do
expect(user).to be_invalid
expect(user.errors.messages[:email].first).to eq(expected_error)
end
+
+ it 'does not allow user to update email to a non-allowlisted domain' 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.')
+ end
end
context 'when a signup domain is allowed and subdomains are not allowed' do
@@ -608,6 +618,13 @@ RSpec.describe User do
user = build(:user, email: 'info@example.com', created_by_id: 1)
expect(user).to be_valid
end
+
+ it 'does not allow user to update email to a denied domain' 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.')
+ end
end
context 'when a signup domain is denied but a wildcard subdomain is allowed' do
@@ -679,6 +696,13 @@ RSpec.describe User do
expect(user.errors.messages[:email].first).to eq(expected_error)
end
+ it 'does not allow user to update email to a restricted domain' 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.')
+ end
+
it 'does accept a valid email address' do
user = build(:user, email: 'info@test.com')
@@ -1398,7 +1422,7 @@ RSpec.describe User do
end
describe '#update_tracked_fields!', :clean_gitlab_redis_shared_state do
- let(:request) { OpenStruct.new(remote_ip: "127.0.0.1") }
+ let(:request) { double('request', remote_ip: "127.0.0.1") }
let(:user) { create(:user) }
it 'writes trackable attributes' do
@@ -1481,27 +1505,176 @@ RSpec.describe User do
end
describe '#confirm' do
+ let(:expired_confirmation_sent_at) { Date.today - described_class.confirm_within - 7.days }
+ let(:extant_confirmation_sent_at) { Date.today }
+
before do
allow_any_instance_of(ApplicationSetting).to receive(:send_user_confirmation_email).and_return(true)
end
- let(:user) { create(:user, :unconfirmed, unconfirmed_email: 'test@gitlab.com') }
+ let(:user) do
+ create(:user, :unconfirmed, unconfirmed_email: 'test@gitlab.com').tap do |user|
+ user.update!(confirmation_sent_at: confirmation_sent_at)
+ end
+ end
- it 'returns unconfirmed' do
- expect(user.confirmed?).to be_falsey
+ shared_examples_for 'unconfirmed user' do
+ it 'returns unconfirmed' do
+ expect(user.confirmed?).to be_falsey
+ end
end
- it 'confirms a user' do
- user.confirm
- expect(user.confirmed?).to be_truthy
+ context 'when the confirmation period has expired' do
+ let(:confirmation_sent_at) { expired_confirmation_sent_at }
+
+ it_behaves_like 'unconfirmed user'
+
+ it 'does not confirm the user' do
+ user.confirm
+
+ expect(user.confirmed?).to be_falsey
+ end
+
+ it 'does not add the confirmed primary email to emails' do
+ user.confirm
+
+ expect(user.emails.confirmed.map(&:email)).not_to include(user.email)
+ end
end
- it 'adds the confirmed primary email to emails' do
- expect(user.emails.confirmed.map(&:email)).not_to include(user.email)
+ context 'when the confirmation period has not expired' do
+ let(:confirmation_sent_at) { extant_confirmation_sent_at }
- user.confirm
+ it_behaves_like 'unconfirmed user'
- expect(user.emails.confirmed.map(&:email)).to include(user.email)
+ it 'confirms a user' do
+ user.confirm
+ expect(user.confirmed?).to be_truthy
+ end
+
+ it 'adds the confirmed primary email to emails' do
+ expect(user.emails.confirmed.map(&:email)).not_to include(user.email)
+
+ user.confirm
+
+ expect(user.emails.confirmed.map(&:email)).to include(user.email)
+ end
+
+ context 'when the primary email is already included in user.emails' do
+ let(:expired_confirmation_sent_at_for_email) { Date.today - Email.confirm_within - 7.days }
+ let(:extant_confirmation_sent_at_for_email) { Date.today }
+
+ let!(:email) do
+ create(:email, email: user.unconfirmed_email, user: user).tap do |email|
+ email.update!(confirmation_sent_at: confirmation_sent_at_for_email)
+ end
+ end
+
+ context 'when the confirmation period of the email record has expired' do
+ let(:confirmation_sent_at_for_email) { expired_confirmation_sent_at_for_email }
+
+ it 'does not confirm the email record' do
+ user.confirm
+
+ expect(email.reload.confirmed?).to be_falsey
+ end
+ end
+
+ context 'when the confirmation period of the email record has not expired' do
+ let(:confirmation_sent_at_for_email) { extant_confirmation_sent_at_for_email }
+
+ it 'confirms the email record' do
+ user.confirm
+
+ expect(email.reload.confirmed?).to be_truthy
+ end
+ end
+ 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 }
+
+ let(:user) do
+ create(:user, :unconfirmed, unconfirmed_email: 'test@gitlab.com').tap do |user|
+ user.update!(confirmation_sent_at: confirmation_sent_at)
+ end
+ end
+
+ shared_examples_for 'unconfirmed user' do
+ it 'returns unconfirmed' do
+ expect(user.confirmed?).to be_falsey
+ end
+ end
+
+ shared_examples_for 'confirms the user on force_confirm' do
+ it 'confirms a user' do
+ user.force_confirm
+ expect(user.confirmed?).to be_truthy
+ end
+ end
+
+ shared_examples_for 'adds the confirmed primary email to emails' do
+ it 'adds the confirmed primary email to emails' do
+ expect(user.emails.confirmed.map(&:email)).not_to include(user.email)
+
+ user.force_confirm
+
+ expect(user.emails.confirmed.map(&:email)).to include(user.email)
+ end
+ end
+
+ shared_examples_for 'confirms the email record if the primary email was already present in user.emails' do
+ context 'when the primary email is already included in user.emails' do
+ let(:expired_confirmation_sent_at_for_email) { Date.today - Email.confirm_within - 7.days }
+ let(:extant_confirmation_sent_at_for_email) { Date.today }
+
+ let!(:email) do
+ create(:email, email: user.unconfirmed_email, user: user).tap do |email|
+ email.update!(confirmation_sent_at: confirmation_sent_at_for_email)
+ end
+ end
+
+ shared_examples_for 'confirms the email record' do
+ it 'confirms the email record' do
+ user.force_confirm
+
+ expect(email.reload.confirmed?).to be_truthy
+ end
+ end
+
+ context 'when the confirmation period of the email record has expired' do
+ let(:confirmation_sent_at_for_email) { expired_confirmation_sent_at_for_email }
+
+ it_behaves_like 'confirms the email record'
+ end
+
+ context 'when the confirmation period of the email record has not expired' do
+ let(:confirmation_sent_at_for_email) { extant_confirmation_sent_at_for_email }
+
+ it_behaves_like 'confirms the email record'
+ end
+ end
+ end
+
+ context 'when the confirmation period has expired' do
+ let(:confirmation_sent_at) { expired_confirmation_sent_at }
+
+ it_behaves_like 'unconfirmed user'
+ it_behaves_like 'confirms the user on force_confirm'
+ it_behaves_like 'adds the confirmed primary email to emails'
+ it_behaves_like 'confirms the email record if the primary email was already present in user.emails'
+ end
+
+ context 'when the confirmation period has not expired' do
+ let(:confirmation_sent_at) { extant_confirmation_sent_at }
+
+ it_behaves_like 'unconfirmed user'
+ it_behaves_like 'confirms the user on force_confirm'
+ it_behaves_like 'adds the confirmed primary email to emails'
+ it_behaves_like 'confirms the email record if the primary email was already present in user.emails'
end
end
@@ -1523,9 +1696,9 @@ RSpec.describe User do
describe '#generate_password' do
it 'does not generate password by default' do
- user = create(:user, password: 'abcdefghe')
+ user = create(:user, password: Gitlab::Password.test_default)
- expect(user.password).to eq('abcdefghe')
+ expect(user.password).to eq(Gitlab::Password.test_default)
end
end
@@ -1624,6 +1797,29 @@ RSpec.describe User do
expect(static_object_token).not_to be_blank
expect(user.reload.static_object_token).to eq static_object_token
end
+
+ it 'generates an encrypted version of the token' do
+ user = create(:user, static_object_token: nil)
+
+ expect(user[:static_object_token]).to be_nil
+ expect(user[:static_object_token_encrypted]).to be_nil
+
+ user.static_object_token
+
+ expect(user[:static_object_token]).to be_nil
+ expect(user[:static_object_token_encrypted]).to be_present
+ end
+
+ it 'prefers an encoded version of the token' do
+ user = create(:user, static_object_token: nil)
+
+ token = user.static_object_token
+
+ user.update_column(:static_object_token, 'Test')
+
+ expect(user.static_object_token).not_to eq('Test')
+ expect(user.static_object_token).to eq(token)
+ end
end
describe 'enabled_static_object_token' do
@@ -1862,7 +2058,7 @@ RSpec.describe User do
it { expect(user.authorized_groups).to eq([group]) }
it { expect(user.owned_groups).to eq([group]) }
it { expect(user.namespaces).to contain_exactly(user.namespace, group) }
- it { expect(user.manageable_namespaces).to contain_exactly(user.namespace, group) }
+ it { expect(user.forkable_namespaces).to contain_exactly(user.namespace, group) }
context 'with owned groups only' do
before do
@@ -1876,9 +2072,12 @@ RSpec.describe User do
context 'with child groups' do
let!(:subgroup) { create(:group, parent: group) }
- describe '#manageable_namespaces' do
- it 'includes all the namespaces the user can manage' do
- expect(user.manageable_namespaces).to contain_exactly(user.namespace, group, subgroup)
+ describe '#forkable_namespaces' do
+ it 'includes all the namespaces the user can fork into' do
+ developer_group = create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS)
+ developer_group.add_developer(user)
+
+ expect(user.forkable_namespaces).to contain_exactly(user.namespace, group, subgroup, developer_group)
end
end
@@ -2592,6 +2791,12 @@ RSpec.describe User do
end
end
+ describe '.user_search_minimum_char_limit' do
+ it 'returns true' do
+ expect(described_class.user_search_minimum_char_limit).to be(true)
+ end
+ end
+
describe '.find_by_ssh_key_id' do
let_it_be(:user) { create(:user) }
let_it_be(:key) { create(:key, user: user) }
@@ -3768,7 +3973,7 @@ RSpec.describe User do
end
end
- describe '#ci_owned_runners' do
+ shared_context '#ci_owned_runners' do
let(:user) { create(:user) }
shared_examples :nested_groups_owner do
@@ -4075,6 +4280,16 @@ RSpec.describe User do
end
end
+ it_behaves_like '#ci_owned_runners'
+
+ context 'when FF ci_owned_runners_cross_joins_fix is disabled' do
+ before do
+ stub_feature_flags(ci_owned_runners_cross_joins_fix: false)
+ end
+
+ it_behaves_like '#ci_owned_runners'
+ end
+
describe '#projects_with_reporter_access_limited_to' do
let(:project1) { create(:project) }
let(:project2) { create(:project) }
@@ -5606,6 +5821,48 @@ RSpec.describe User do
end
end
+ describe '#can_log_in_with_non_expired_password?' do
+ let(:user) { build(:user) }
+
+ subject { user.can_log_in_with_non_expired_password? }
+
+ context 'when user can log in' do
+ it 'returns true' do
+ is_expected.to be_truthy
+ end
+
+ context 'when user with expired password' do
+ before do
+ user.password_expires_at = 2.minutes.ago
+ end
+
+ it 'returns false' do
+ is_expected.to be_falsey
+ end
+
+ context 'when password expiration is not applicable' do
+ context 'when ldap user' do
+ let(:user) { build(:omniauth_user, provider: 'ldap') }
+
+ it 'returns true' do
+ is_expected.to be_truthy
+ end
+ end
+ end
+ end
+ end
+
+ context 'when user cannot log in' do
+ context 'when user is blocked' do
+ let(:user) { build(:user, :blocked) }
+
+ it 'returns false' do
+ is_expected.to be_falsey
+ end
+ end
+ end
+ end
+
describe '#read_only_attribute?' do
context 'when synced attributes metadata is present' do
it 'delegates to synced_attributes_metadata' do
@@ -6303,13 +6560,43 @@ RSpec.describe User do
specify { is_expected.to contain_exactly(developer_group2) }
end
- describe '.get_ids_by_username' do
+ describe '.get_ids_by_ids_or_usernames' do
let(:user_name) { 'user_name' }
let!(:user) { create(:user, username: user_name) }
let(:user_id) { user.id }
it 'returns the id of each record matching username' do
- expect(described_class.get_ids_by_username([user_name])).to match_array([user_id])
+ expect(described_class.get_ids_by_ids_or_usernames(nil, [user_name])).to match_array([user_id])
+ end
+
+ it 'returns the id of each record matching user id' do
+ expect(described_class.get_ids_by_ids_or_usernames([user_id], nil)).to match_array([user_id])
+ end
+
+ it 'return the id for all records matching either user id or user name' do
+ new_user_id = create(:user).id
+
+ expect(described_class.get_ids_by_ids_or_usernames([new_user_id], [user_name])).to match_array([user_id, new_user_id])
+ end
+ end
+
+ describe '.by_ids_or_usernames' do
+ let(:user_name) { 'user_name' }
+ let!(:user) { create(:user, username: user_name) }
+ let(:user_id) { user.id }
+
+ it 'returns matching records based on username' do
+ expect(described_class.by_ids_or_usernames(nil, [user_name])).to match_array([user])
+ end
+
+ it 'returns matching records based on id' do
+ expect(described_class.by_ids_or_usernames([user_id], nil)).to match_array([user])
+ end
+
+ it 'returns matching records based on both username and id' do
+ new_user = create(:user)
+
+ expect(described_class.by_ids_or_usernames([new_user.id], [user_name])).to match_array([user, new_user])
end
end
diff --git a/spec/models/users_statistics_spec.rb b/spec/models/users_statistics_spec.rb
index 8553d0bfdb0..add9bd18755 100644
--- a/spec/models/users_statistics_spec.rb
+++ b/spec/models/users_statistics_spec.rb
@@ -43,7 +43,7 @@ RSpec.describe UsersStatistics do
create_list(:user, 2, :bot)
create_list(:user, 1, :blocked)
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false)
+ allow(described_class.connection).to receive(:transaction_open?).and_return(false)
end
context 'when successful' do
diff --git a/spec/models/work_item/type_spec.rb b/spec/models/work_item/type_spec.rb
deleted file mode 100644
index cc18558975b..00000000000
--- a/spec/models/work_item/type_spec.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe WorkItem::Type do
- describe 'modules' do
- it { is_expected.to include_module(CacheMarkdownField) }
- end
-
- describe 'associations' do
- it { is_expected.to have_many(:work_items).with_foreign_key('work_item_type_id') }
- it { is_expected.to belong_to(:namespace) }
- end
-
- describe '#destroy' do
- let!(:work_item) { create :issue }
-
- context 'when there are no work items of that type' do
- it 'deletes type but not unrelated issues' do
- type = create(:work_item_type)
-
- expect(WorkItem::Type.count).to eq(6)
-
- expect { type.destroy! }.not_to change(Issue, :count)
- expect(WorkItem::Type.count).to eq(5)
- end
- end
-
- it 'does not delete type when there are related issues' do
- type = create(:work_item_type, work_items: [work_item])
-
- expect { type.destroy! }.to raise_error(ActiveRecord::InvalidForeignKey)
- expect(Issue.count).to eq(1)
- end
- end
-
- describe 'validation' do
- describe 'name uniqueness' do
- subject { create(:work_item_type) }
-
- it { is_expected.to validate_uniqueness_of(:name).case_insensitive.scoped_to([:namespace_id]) }
- end
-
- it { is_expected.not_to allow_value('s' * 256).for(:icon_name) }
- end
-
- describe '#name' do
- it 'strips name' do
- work_item_type = described_class.new(name: ' label😸 ')
- work_item_type.valid?
-
- expect(work_item_type.name).to eq('label😸')
- end
- end
-end
diff --git a/spec/models/work_items/type_spec.rb b/spec/models/work_items/type_spec.rb
new file mode 100644
index 00000000000..6e9f3210e65
--- /dev/null
+++ b/spec/models/work_items/type_spec.rb
@@ -0,0 +1,87 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe WorkItems::Type do
+ describe 'modules' do
+ it { is_expected.to include_module(CacheMarkdownField) }
+ end
+
+ describe 'associations' do
+ it { is_expected.to have_many(:work_items).with_foreign_key('work_item_type_id') }
+ it { is_expected.to belong_to(:namespace) }
+ end
+
+ describe 'scopes' do
+ describe 'order_by_name_asc' do
+ subject { described_class.order_by_name_asc.pluck(:name) }
+
+ before do
+ # Deletes all so we have control on the entire list of names
+ described_class.delete_all
+ create(:work_item_type, name: 'Ztype')
+ create(:work_item_type, name: 'atype')
+ create(:work_item_type, name: 'gtype')
+ end
+
+ it { is_expected.to match(%w[atype gtype Ztype]) }
+ end
+ end
+
+ describe '#destroy' do
+ let!(:work_item) { create :issue }
+
+ context 'when there are no work items of that type' do
+ it 'deletes type but not unrelated issues' do
+ type = create(:work_item_type)
+
+ expect(WorkItems::Type.count).to eq(6)
+
+ expect { type.destroy! }.not_to change(Issue, :count)
+ expect(WorkItems::Type.count).to eq(5)
+ end
+ end
+
+ it 'does not delete type when there are related issues' do
+ type = create(:work_item_type, work_items: [work_item])
+
+ expect { type.destroy! }.to raise_error(ActiveRecord::InvalidForeignKey)
+ expect(Issue.count).to eq(1)
+ end
+ end
+
+ describe 'validation' do
+ describe 'name uniqueness' do
+ subject { create(:work_item_type) }
+
+ it { is_expected.to validate_uniqueness_of(:name).case_insensitive.scoped_to([:namespace_id]) }
+ end
+
+ it { is_expected.not_to allow_value('s' * 256).for(:icon_name) }
+ end
+
+ describe 'default?' do
+ subject { build(:work_item_type, namespace: namespace).default? }
+
+ context 'when namespace is nil' do
+ let(:namespace) { nil }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when namespace is present' do
+ let(:namespace) { build(:namespace) }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
+ describe '#name' do
+ it 'strips name' do
+ work_item_type = described_class.new(name: ' label😸 ')
+ work_item_type.valid?
+
+ expect(work_item_type.name).to eq('label😸')
+ end
+ end
+end
diff --git a/spec/policies/blob_policy_spec.rb b/spec/policies/blob_policy_spec.rb
index daabcd844af..2b0465f3615 100644
--- a/spec/policies/blob_policy_spec.rb
+++ b/spec/policies/blob_policy_spec.rb
@@ -5,9 +5,9 @@ require 'spec_helper'
RSpec.describe BlobPolicy do
include_context 'ProjectPolicyTable context'
include ProjectHelpers
- using RSpec::Parameterized::TableSyntax
- let(:project) { create(:project, :repository, project_level) }
+ let_it_be_with_reload(:project) { create(:project, :repository) }
+
let(:user) { create_user_from_membership(project, membership) }
let(:blob) { project.repository.blob_at(SeedRepo::FirstCommit::ID, 'README.md') }
@@ -18,8 +18,9 @@ RSpec.describe BlobPolicy do
end
with_them do
- it "grants permission" do
+ it 'grants permission' do
enable_admin_mode!(user) if admin_mode
+ project.update!(visibility_level: Gitlab::VisibilityLevel.level_value(project_level.to_s))
update_feature_access_level(project, feature_access_level)
if expected_count == 1
diff --git a/spec/policies/group_member_policy_spec.rb b/spec/policies/group_member_policy_spec.rb
index d283b0ffda5..50774313aae 100644
--- a/spec/policies/group_member_policy_spec.rb
+++ b/spec/policies/group_member_policy_spec.rb
@@ -83,6 +83,23 @@ RSpec.describe GroupMemberPolicy do
specify { expect_allowed(:read_group) }
end
+ context 'with bot user' do
+ let(:current_user) { create(:user, :project_bot) }
+
+ before do
+ group.add_owner(current_user)
+ end
+
+ specify { expect_allowed(:read_group, :destroy_project_bot_member) }
+ end
+
+ context 'with anonymous bot user' do
+ let(:current_user) { create(:user, :project_bot) }
+ let(:membership) { guest.members.first }
+
+ specify { expect_disallowed(:read_group, :destroy_project_bot_member) }
+ end
+
context 'with one owner' do
let(:current_user) { owner }
@@ -106,6 +123,7 @@ RSpec.describe GroupMemberPolicy do
end
specify { expect_allowed(*member_related_permissions) }
+ specify { expect_disallowed(:destroy_project_bot_member) }
end
context 'with the group parent' do
diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb
index 7822ee2b92e..2607e285a80 100644
--- a/spec/policies/group_policy_spec.rb
+++ b/spec/policies/group_policy_spec.rb
@@ -6,15 +6,11 @@ RSpec.describe GroupPolicy do
include_context 'GroupPolicy context'
context 'public group with no user' do
- let(:group) { create(:group, :public) }
+ let(:group) { create(:group, :public, :crm_enabled) }
let(:current_user) { nil }
it do
- expect_allowed(:read_group)
- expect_allowed(:read_crm_organization)
- expect_allowed(:read_crm_contact)
- expect_allowed(:read_counts)
- expect_allowed(*read_group_permissions)
+ expect_allowed(*public_permissions)
expect_disallowed(:upload_file)
expect_disallowed(*reporter_permissions)
expect_disallowed(*developer_permissions)
@@ -24,34 +20,49 @@ RSpec.describe GroupPolicy do
end
end
- context 'with no user and public project' do
- let(:project) { create(:project, :public) }
+ context 'public group with user who is not a member' do
+ let(:group) { create(:group, :public, :crm_enabled) }
+ let(:current_user) { create(:user) }
+
+ it do
+ expect_allowed(*public_permissions)
+ expect_disallowed(:upload_file)
+ expect_disallowed(*reporter_permissions)
+ expect_disallowed(*developer_permissions)
+ expect_disallowed(*maintainer_permissions)
+ expect_disallowed(*owner_permissions)
+ expect_disallowed(:read_namespace)
+ end
+ end
+
+ context 'private group that has been invited to a public project and with no user' do
+ let(:project) { create(:project, :public, group: create(:group, :crm_enabled)) }
let(:current_user) { nil }
before do
create(:project_group_link, project: project, group: group)
end
- it { expect_disallowed(:read_group) }
- it { expect_disallowed(:read_crm_organization) }
- it { expect_disallowed(:read_crm_contact) }
- it { expect_disallowed(:read_counts) }
- it { expect_disallowed(*read_group_permissions) }
+ it do
+ expect_disallowed(*public_permissions)
+ expect_disallowed(*reporter_permissions)
+ expect_disallowed(*owner_permissions)
+ end
end
- context 'with foreign user and public project' do
- let(:project) { create(:project, :public) }
+ context 'private group that has been invited to a public project and with a foreign user' do
+ let(:project) { create(:project, :public, group: create(:group, :crm_enabled)) }
let(:current_user) { create(:user) }
before do
create(:project_group_link, project: project, group: group)
end
- it { expect_disallowed(:read_group) }
- it { expect_disallowed(:read_crm_organization) }
- it { expect_disallowed(:read_crm_contact) }
- it { expect_disallowed(:read_counts) }
- it { expect_disallowed(*read_group_permissions) }
+ it do
+ expect_disallowed(*public_permissions)
+ expect_disallowed(*reporter_permissions)
+ expect_disallowed(*owner_permissions)
+ end
end
context 'has projects' do
@@ -62,13 +73,13 @@ RSpec.describe GroupPolicy do
project.add_developer(current_user)
end
- it { expect_allowed(*read_group_permissions) }
+ it { expect_allowed(*(public_permissions - [:read_counts])) }
context 'in subgroups' do
- let(:subgroup) { create(:group, :private, parent: group) }
+ let(:subgroup) { create(:group, :private, :crm_enabled, parent: group) }
let(:project) { create(:project, namespace: subgroup) }
- it { expect_allowed(*read_group_permissions) }
+ it { expect_allowed(*(public_permissions - [:read_counts])) }
end
end
@@ -81,7 +92,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { deploy_token }
it do
- expect_disallowed(*read_group_permissions)
+ expect_disallowed(*public_permissions)
expect_disallowed(*guest_permissions)
expect_disallowed(*reporter_permissions)
expect_disallowed(*developer_permissions)
@@ -94,7 +105,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { guest }
it do
- expect_allowed(*read_group_permissions)
+ expect_allowed(*public_permissions)
expect_allowed(*guest_permissions)
expect_disallowed(*reporter_permissions)
expect_disallowed(*developer_permissions)
@@ -111,7 +122,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { reporter }
it do
- expect_allowed(*read_group_permissions)
+ expect_allowed(*public_permissions)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
expect_disallowed(*developer_permissions)
@@ -128,7 +139,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { developer }
it do
- expect_allowed(*read_group_permissions)
+ expect_allowed(*public_permissions)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
expect_allowed(*developer_permissions)
@@ -156,7 +167,7 @@ RSpec.describe GroupPolicy do
updated_owner_permissions =
owner_permissions - create_subgroup_permission
- expect_allowed(*read_group_permissions)
+ expect_allowed(*public_permissions)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
expect_allowed(*developer_permissions)
@@ -167,7 +178,7 @@ RSpec.describe GroupPolicy do
context 'with subgroup_creation_level set to owner' do
it 'allows every maintainer permission' do
- expect_allowed(*read_group_permissions)
+ expect_allowed(*public_permissions)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
expect_allowed(*developer_permissions)
@@ -185,7 +196,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { owner }
it do
- expect_allowed(*read_group_permissions)
+ expect_allowed(*public_permissions)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
expect_allowed(*developer_permissions)
@@ -202,7 +213,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { admin }
specify do
- expect_disallowed(*read_group_permissions)
+ expect_disallowed(*public_permissions)
expect_disallowed(*guest_permissions)
expect_disallowed(*reporter_permissions)
expect_disallowed(*developer_permissions)
@@ -212,7 +223,7 @@ RSpec.describe GroupPolicy do
context 'with admin mode', :enable_admin_mode do
specify do
- expect_allowed(*read_group_permissions)
+ expect_allowed(*public_permissions)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
expect_allowed(*developer_permissions)
@@ -233,7 +244,7 @@ RSpec.describe GroupPolicy do
describe 'private nested group use the highest access level from the group and inherited permissions' do
let_it_be(:nested_group) do
- create(:group, :private, :owner_subgroup_creation_only, parent: group)
+ create(:group, :private, :owner_subgroup_creation_only, :crm_enabled, parent: group)
end
before_all do
@@ -254,8 +265,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { nil }
it do
- expect_disallowed(:read_counts)
- expect_disallowed(*read_group_permissions)
+ expect_disallowed(*public_permissions)
expect_disallowed(*guest_permissions)
expect_disallowed(*reporter_permissions)
expect_disallowed(*developer_permissions)
@@ -268,8 +278,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { guest }
it do
- expect_allowed(:read_counts)
- expect_allowed(*read_group_permissions)
+ expect_allowed(*public_permissions)
expect_allowed(*guest_permissions)
expect_disallowed(*reporter_permissions)
expect_disallowed(*developer_permissions)
@@ -282,8 +291,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { reporter }
it do
- expect_allowed(:read_counts)
- expect_allowed(*read_group_permissions)
+ expect_allowed(*public_permissions)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
expect_disallowed(*developer_permissions)
@@ -296,8 +304,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { developer }
it do
- expect_allowed(:read_counts)
- expect_allowed(*read_group_permissions)
+ expect_allowed(*public_permissions)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
expect_allowed(*developer_permissions)
@@ -310,8 +317,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { maintainer }
it do
- expect_allowed(:read_counts)
- expect_allowed(*read_group_permissions)
+ expect_allowed(*public_permissions)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
expect_allowed(*developer_permissions)
@@ -324,8 +330,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { owner }
it do
- expect_allowed(:read_counts)
- expect_allowed(*read_group_permissions)
+ expect_allowed(*public_permissions)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
expect_allowed(*developer_permissions)
@@ -340,7 +345,7 @@ RSpec.describe GroupPolicy do
let(:current_user) { owner }
context 'when the group share_with_group_lock is enabled' do
- let(:group) { create(:group, share_with_group_lock: true, parent: parent) }
+ let(:group) { create(:group, :crm_enabled, share_with_group_lock: true, parent: parent) }
before do
group.add_owner(owner)
@@ -348,10 +353,10 @@ RSpec.describe GroupPolicy do
context 'when the parent group share_with_group_lock is enabled' do
context 'when the group has a grandparent' do
- let(:parent) { create(:group, share_with_group_lock: true, parent: grandparent) }
+ let(:parent) { create(:group, :crm_enabled, share_with_group_lock: true, parent: grandparent) }
context 'when the grandparent share_with_group_lock is enabled' do
- let(:grandparent) { create(:group, share_with_group_lock: true) }
+ let(:grandparent) { create(:group, :crm_enabled, share_with_group_lock: true) }
context 'when the current_user owns the parent' do
before do
@@ -377,7 +382,7 @@ RSpec.describe GroupPolicy do
end
context 'when the grandparent share_with_group_lock is disabled' do
- let(:grandparent) { create(:group) }
+ let(:grandparent) { create(:group, :crm_enabled) }
context 'when the current_user owns the parent' do
before do
@@ -394,7 +399,7 @@ RSpec.describe GroupPolicy do
end
context 'when the group does not have a grandparent' do
- let(:parent) { create(:group, share_with_group_lock: true) }
+ let(:parent) { create(:group, :crm_enabled, share_with_group_lock: true) }
context 'when the current_user owns the parent' do
before do
@@ -411,7 +416,7 @@ RSpec.describe GroupPolicy do
end
context 'when the parent group share_with_group_lock is disabled' do
- let(:parent) { create(:group) }
+ let(:parent) { create(:group, :crm_enabled) }
it { expect_allowed(:change_share_with_group_lock) }
end
@@ -696,7 +701,7 @@ RSpec.describe GroupPolicy do
end
it_behaves_like 'clusterable policies' do
- let(:clusterable) { create(:group) }
+ let(:clusterable) { create(:group, :crm_enabled) }
let(:cluster) do
create(:cluster,
:provided_by_gcp,
@@ -706,7 +711,7 @@ RSpec.describe GroupPolicy do
end
describe 'update_max_artifacts_size' do
- let(:group) { create(:group, :public) }
+ let(:group) { create(:group, :public, :crm_enabled) }
context 'when no user' do
let(:current_user) { nil }
@@ -736,7 +741,7 @@ RSpec.describe GroupPolicy do
end
describe 'design activity' do
- let_it_be(:group) { create(:group, :public) }
+ let_it_be(:group) { create(:group, :public, :crm_enabled) }
let(:current_user) { nil }
@@ -904,7 +909,6 @@ RSpec.describe GroupPolicy do
context 'feature enabled' do
before do
stub_config(dependency_proxy: { enabled: true })
- group.create_dependency_proxy_setting!(enabled: true)
end
context 'reporter' do
@@ -933,8 +937,6 @@ RSpec.describe GroupPolicy do
it { is_expected.to be_allowed(:read_package) }
it { is_expected.to be_allowed(:read_group) }
- it { is_expected.to be_allowed(:read_crm_organization) }
- it { is_expected.to be_allowed(:read_crm_contact) }
it { is_expected.to be_disallowed(:create_package) }
end
@@ -944,8 +946,6 @@ RSpec.describe GroupPolicy do
it { is_expected.to be_allowed(:create_package) }
it { is_expected.to be_allowed(:read_package) }
it { is_expected.to be_allowed(:read_group) }
- it { is_expected.to be_allowed(:read_crm_organization) }
- it { is_expected.to be_allowed(:read_crm_contact) }
it { is_expected.to be_disallowed(:destroy_package) }
end
@@ -954,7 +954,6 @@ RSpec.describe GroupPolicy do
before do
stub_config(dependency_proxy: { enabled: true })
- group.create_dependency_proxy_setting!(enabled: true)
end
it { is_expected.to be_allowed(:read_dependency_proxy) }
@@ -965,7 +964,7 @@ RSpec.describe GroupPolicy do
it_behaves_like 'Self-managed Core resource access tokens'
context 'support bot' do
- let_it_be(:group) { create(:group, :private) }
+ let_it_be(:group) { create(:group, :private, :crm_enabled) }
let_it_be(:current_user) { User.support_bot }
before do
@@ -975,7 +974,7 @@ RSpec.describe GroupPolicy do
it { expect_disallowed(:read_label) }
context 'when group hierarchy has a project with service desk enabled' do
- let_it_be(:subgroup) { create(:group, :private, parent: group)}
+ let_it_be(:subgroup) { create(:group, :private, :crm_enabled, parent: group) }
let_it_be(:project) { create(:project, group: subgroup, service_desk_enabled: true) }
it { expect_allowed(:read_label) }
@@ -983,6 +982,49 @@ RSpec.describe GroupPolicy do
end
end
+ context "project bots" do
+ let(:project_bot) { create(:user, :project_bot) }
+ let(:user) { create(:user) }
+
+ context "project_bot_access" do
+ context "when regular user and part of the group" do
+ let(:current_user) { user }
+
+ before do
+ group.add_developer(user)
+ end
+
+ it { is_expected.not_to be_allowed(:project_bot_access) }
+ end
+
+ context "when project bot and not part of the project" do
+ let(:current_user) { project_bot }
+
+ it { is_expected.not_to be_allowed(:project_bot_access) }
+ end
+
+ context "when project bot and part of the project" do
+ let(:current_user) { project_bot }
+
+ before do
+ group.add_developer(project_bot)
+ end
+
+ it { is_expected.to be_allowed(:project_bot_access) }
+ end
+ end
+
+ context 'with resource access tokens' do
+ let(:current_user) { project_bot }
+
+ before do
+ group.add_maintainer(project_bot)
+ end
+
+ it { is_expected.not_to be_allowed(:create_resource_access_tokens) }
+ end
+ end
+
describe 'update_runners_registration_token' do
context 'admin' do
let(:current_user) { admin }
@@ -1083,9 +1125,7 @@ RSpec.describe GroupPolicy do
context 'with maintainer' do
let(:current_user) { maintainer }
- it { is_expected.to be_allowed(:register_group_runners) }
-
- it_behaves_like 'expected outcome based on runner registration control'
+ it { is_expected.to be_disallowed(:register_group_runners) }
end
context 'with reporter' do
@@ -1113,7 +1153,7 @@ RSpec.describe GroupPolicy do
end
end
- context 'with customer_relations feature flag disabled' do
+ context 'with customer relations feature flag disabled' do
let(:current_user) { owner }
before do
@@ -1125,4 +1165,18 @@ RSpec.describe GroupPolicy do
it { is_expected.to be_disallowed(:admin_crm_contact) }
it { is_expected.to be_disallowed(:admin_crm_organization) }
end
+
+ context 'when crm_enabled is false' do
+ let(:current_user) { owner }
+
+ before_all do
+ group.crm_settings.enabled = false
+ group.crm_settings.save!
+ end
+
+ it { is_expected.to be_disallowed(:read_crm_contact) }
+ it { is_expected.to be_disallowed(:read_crm_organization) }
+ it { is_expected.to be_disallowed(:admin_crm_contact) }
+ it { is_expected.to be_disallowed(:admin_crm_organization) }
+ end
end
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index 2953c198af6..38e4e18c894 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -61,7 +61,7 @@ RSpec.describe ProjectPolicy do
end
it 'does not include the issues permissions' do
- expect_disallowed :read_issue, :read_issue_iid, :create_issue, :update_issue, :admin_issue, :create_incident
+ expect_disallowed :read_issue, :read_issue_iid, :create_issue, :update_issue, :admin_issue, :create_incident, :create_work_item, :create_task
end
it 'disables boards and lists permissions' do
@@ -73,7 +73,7 @@ RSpec.describe ProjectPolicy do
it 'does not include the issues permissions' do
create(:jira_integration, project: project)
- expect_disallowed :read_issue, :read_issue_iid, :create_issue, :update_issue, :admin_issue, :create_incident
+ expect_disallowed :read_issue, :read_issue_iid, :create_issue, :update_issue, :admin_issue, :create_incident, :create_work_item, :create_task
end
end
end
diff --git a/spec/presenters/blob_presenter_spec.rb b/spec/presenters/blob_presenter_spec.rb
index 8c0347b3c8d..3bf592ed2b9 100644
--- a/spec/presenters/blob_presenter_spec.rb
+++ b/spec/presenters/blob_presenter_spec.rb
@@ -53,6 +53,10 @@ RSpec.describe BlobPresenter do
end
end
+ describe '#archived?' do
+ it { expect(presenter.archived?).to eq(project.archived) }
+ end
+
describe '#pipeline_editor_path' do
context 'when blob is .gitlab-ci.yml' do
before do
@@ -67,6 +71,22 @@ RSpec.describe BlobPresenter do
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
+
+ describe '#blame_path' do
+ it { expect(presenter.blame_path).to eq("/#{project.full_path}/-/blame/HEAD/files/ruby/regex.rb") }
+ end
+
+ describe '#history_path' do
+ it { expect(presenter.history_path).to eq("/#{project.full_path}/-/commits/HEAD/files/ruby/regex.rb") }
+ end
+
+ describe '#permalink_path' do
+ it { expect(presenter.permalink_path).to eq("/#{project.full_path}/-/blob/#{project.repository.commit.sha}/files/ruby/regex.rb") }
+ end
+
describe '#code_owners' do
it { expect(presenter.code_owners).to match_array([]) }
end
diff --git a/spec/presenters/label_presenter_spec.rb b/spec/presenters/label_presenter_spec.rb
index bab0d9a1065..b4d36eaf340 100644
--- a/spec/presenters/label_presenter_spec.rb
+++ b/spec/presenters/label_presenter_spec.rb
@@ -10,6 +10,7 @@ RSpec.describe LabelPresenter do
let(:label) { build_stubbed(:label, project: project).present(issuable_subject: project) }
let(:group_label) { build_stubbed(:group_label, group: group).present(issuable_subject: project) }
+ let(:admin_label) { build_stubbed(:admin_label).present(issuable_subject: nil) }
describe '#edit_path' do
context 'with group label' do
@@ -23,6 +24,12 @@ RSpec.describe LabelPresenter do
it { is_expected.to eq(edit_project_label_path(project, label)) }
end
+
+ context 'with an admin label' do
+ subject { admin_label.edit_path }
+
+ it { is_expected.to eq(edit_admin_label_path(admin_label)) }
+ end
end
describe '#destroy_path' do
@@ -37,6 +44,12 @@ RSpec.describe LabelPresenter do
it { is_expected.to eq(project_label_path(project, label)) }
end
+
+ context 'with an admin label' do
+ subject { admin_label.destroy_path }
+
+ it { is_expected.to eq(admin_label_path(admin_label)) }
+ end
end
describe '#filter_path' do
@@ -91,6 +104,12 @@ RSpec.describe LabelPresenter do
it { is_expected.to eq(label.project.name) }
end
+
+ context 'with an admin label' do
+ subject { admin_label.subject_name }
+
+ it { is_expected.to be_nil }
+ end
end
describe '#subject_full_name' do
@@ -105,5 +124,11 @@ RSpec.describe LabelPresenter do
it { is_expected.to eq(label.project.full_name) }
end
+
+ context 'with an admin label' do
+ subject { admin_label.subject_full_name }
+
+ it { is_expected.to be_nil }
+ end
end
end
diff --git a/spec/presenters/packages/conan/package_presenter_spec.rb b/spec/presenters/packages/conan/package_presenter_spec.rb
index 6d82c5ef547..27ecf32b6f2 100644
--- a/spec/presenters/packages/conan/package_presenter_spec.rb
+++ b/spec/presenters/packages/conan/package_presenter_spec.rb
@@ -9,6 +9,7 @@ RSpec.describe ::Packages::Conan::PackagePresenter do
let_it_be(:conan_package_reference) { '123456789'}
let(:params) { { package_scope: :instance } }
+ let(:presenter) { described_class.new(package, user, project, params) }
shared_examples 'no existing package' do
context 'when package does not exist' do
@@ -21,7 +22,7 @@ RSpec.describe ::Packages::Conan::PackagePresenter do
shared_examples 'conan_file_metadatum is not found' do
context 'when no conan_file_metadatum exists' do
before do
- package.package_files.each do |file|
+ package.installable_package_files.each do |file|
file.conan_file_metadatum.delete
file.reload
end
@@ -32,7 +33,7 @@ RSpec.describe ::Packages::Conan::PackagePresenter do
end
describe '#recipe_urls' do
- subject { described_class.new(package, user, project, params).recipe_urls }
+ subject { presenter.recipe_urls }
it_behaves_like 'no existing package'
it_behaves_like 'conan_file_metadatum is not found'
@@ -71,7 +72,9 @@ RSpec.describe ::Packages::Conan::PackagePresenter do
end
describe '#recipe_snapshot' do
- subject { described_class.new(package, user, project).recipe_snapshot }
+ let(:params) { {} }
+
+ subject { presenter.recipe_snapshot }
it_behaves_like 'no existing package'
it_behaves_like 'conan_file_metadatum is not found'
@@ -180,12 +183,9 @@ RSpec.describe ::Packages::Conan::PackagePresenter do
describe '#package_snapshot' do
let(:reference) { conan_package_reference }
+ let(:params) { { conan_package_reference: reference } }
- subject do
- described_class.new(
- package, user, project, conan_package_reference: reference
- ).package_snapshot
- end
+ subject { presenter.package_snapshot }
it_behaves_like 'no existing package'
it_behaves_like 'conan_file_metadatum is not found'
@@ -208,4 +208,22 @@ RSpec.describe ::Packages::Conan::PackagePresenter do
end
end
end
+
+ # TODO when cleaning up packages_installable_package_files, consider removing this context and
+ # add a dummy package file pending destruction on L8
+ context 'with package files pending destruction' do
+ let_it_be(:package_file_pending_destruction) { create(:package_file, :pending_destruction, package: package) }
+
+ subject { presenter.send(:package_files).to_a }
+
+ it { is_expected.not_to include(package_file_pending_destruction) }
+
+ context 'with packages_installable_package_files disabled' do
+ before do
+ stub_feature_flags(packages_installable_package_files: false)
+ end
+
+ it { is_expected.to include(package_file_pending_destruction) }
+ end
+ end
end
diff --git a/spec/presenters/packages/detail/package_presenter_spec.rb b/spec/presenters/packages/detail/package_presenter_spec.rb
index 3009f2bd56d..4e2645b27ff 100644
--- a/spec/presenters/packages/detail/package_presenter_spec.rb
+++ b/spec/presenters/packages/detail/package_presenter_spec.rb
@@ -6,12 +6,12 @@ RSpec.describe ::Packages::Detail::PackagePresenter do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, creator: user) }
let_it_be(:package) { create(:npm_package, :with_build, project: project) }
- let(:presenter) { described_class.new(package) }
-
let_it_be(:user_info) { { name: user.name, avatar_url: user.avatar_url } }
+ let(:presenter) { described_class.new(package) }
+
let!(:expected_package_files) do
- package.package_files.map do |file|
+ package.installable_package_files.map do |file|
{
created_at: file.created_at,
download_path: file.download_path,
@@ -154,5 +154,21 @@ RSpec.describe ::Packages::Detail::PackagePresenter do
expect(presenter.detail_view).to eq expected_package_details
end
end
+
+ context 'with package files pending destruction' do
+ let_it_be(:package_file_pending_destruction) { create(:package_file, :pending_destruction, package: package) }
+
+ subject { presenter.detail_view[:package_files].map { |e| e[:id] } }
+
+ it { is_expected.not_to include(package_file_pending_destruction.id) }
+
+ context 'with packages_installable_package_files disabled' do
+ before do
+ stub_feature_flags(packages_installable_package_files: false)
+ end
+
+ it { is_expected.to include(package_file_pending_destruction.id) }
+ end
+ end
end
end
diff --git a/spec/presenters/packages/npm/package_presenter_spec.rb b/spec/presenters/packages/npm/package_presenter_spec.rb
index 3b6dfcd20b8..2308f928c92 100644
--- a/spec/presenters/packages/npm/package_presenter_spec.rb
+++ b/spec/presenters/packages/npm/package_presenter_spec.rb
@@ -95,6 +95,27 @@ RSpec.describe ::Packages::Npm::PackagePresenter do
end
end
end
+
+ context 'with package files pending destruction' do
+ let_it_be(:package_file_pending_destruction) { create(:package_file, :pending_destruction, package: package2, file_sha1: 'pending_destruction_sha1') }
+
+ let(:shasums) { subject.values.map { |v| v.dig(:dist, :shasum) } }
+
+ it 'does not return them' do
+ expect(shasums).not_to include(package_file_pending_destruction.file_sha1)
+ end
+
+ context 'with packages_installable_package_files disabled' do
+ before do
+ stub_feature_flags(packages_installable_package_files: false)
+ package2.package_files.id_not_in(package_file_pending_destruction.id).delete_all
+ end
+
+ it 'returns them' do
+ expect(shasums).to include(package_file_pending_destruction.file_sha1)
+ end
+ end
+ end
end
describe '#dist_tags' do
diff --git a/spec/presenters/packages/nuget/package_metadata_presenter_spec.rb b/spec/presenters/packages/nuget/package_metadata_presenter_spec.rb
index 8bb0694f39c..6e99b6bafec 100644
--- a/spec/presenters/packages/nuget/package_metadata_presenter_spec.rb
+++ b/spec/presenters/packages/nuget/package_metadata_presenter_spec.rb
@@ -24,6 +24,20 @@ RSpec.describe Packages::Nuget::PackageMetadataPresenter do
subject { presenter.archive_url }
it { is_expected.to end_with(expected_suffix) }
+
+ context 'with package files pending destruction' do
+ let_it_be(:package_file_pending_destruction) { create(:package_file, :pending_destruction, package: package, file_name: 'pending_destruction.nupkg') }
+
+ it { is_expected.not_to include('pending_destruction.nupkg') }
+
+ context 'with packages_installable_package_files disabled' do
+ before do
+ stub_feature_flags(packages_installable_package_files: false)
+ end
+
+ it { is_expected.to include('pending_destruction.nupkg') }
+ end
+ end
end
describe '#catalog_entry' do
diff --git a/spec/presenters/packages/nuget/search_results_presenter_spec.rb b/spec/presenters/packages/nuget/search_results_presenter_spec.rb
index 39ec7251dfd..745914c6c43 100644
--- a/spec/presenters/packages/nuget/search_results_presenter_spec.rb
+++ b/spec/presenters/packages/nuget/search_results_presenter_spec.rb
@@ -9,9 +9,9 @@ RSpec.describe Packages::Nuget::SearchResultsPresenter do
let_it_be(:tag2) { create(:packages_tag, package: package_a, name: 'tag2') }
let_it_be(:packages_b) { create_list(:nuget_package, 5, project: project, name: 'DummyPackageB') }
let_it_be(:packages_c) { create_list(:nuget_package, 5, project: project, name: 'DummyPackageC') }
- let_it_be(:search_results) { OpenStruct.new(total_count: 3, results: [package_a, packages_b, packages_c].flatten) }
- let_it_be(:presenter) { described_class.new(search_results) }
+ let(:search_results) { double('search_results', total_count: 3, results: [package_a, packages_b, packages_c].flatten) }
+ let(:presenter) { described_class.new(search_results) }
let(:total_count) { presenter.total_count }
let(:data) { presenter.data }
diff --git a/spec/presenters/packages/pypi/package_presenter_spec.rb b/spec/presenters/packages/pypi/package_presenter_spec.rb
index 25aa5c31034..8a23c0ec3cb 100644
--- a/spec/presenters/packages/pypi/package_presenter_spec.rb
+++ b/spec/presenters/packages/pypi/package_presenter_spec.rb
@@ -52,5 +52,21 @@ RSpec.describe ::Packages::Pypi::PackagePresenter do
it_behaves_like 'pypi package presenter'
end
+
+ context 'with package files pending destruction' do
+ let_it_be(:package_file_pending_destruction) { create(:package_file, :pending_destruction, package: package1, file_name: "package_file_pending_destruction") }
+
+ let(:project_or_group) { project }
+
+ it { is_expected.not_to include(package_file_pending_destruction.file_name)}
+
+ context 'with packages_installable_package_files disabled' do
+ before do
+ stub_feature_flags(packages_installable_package_files: false)
+ end
+
+ it { is_expected.to include(package_file_pending_destruction.file_name)}
+ end
+ end
end
end
diff --git a/spec/presenters/project_presenter_spec.rb b/spec/presenters/project_presenter_spec.rb
index 27b777dec5f..e4a08bd56c8 100644
--- a/spec/presenters/project_presenter_spec.rb
+++ b/spec/presenters/project_presenter_spec.rb
@@ -554,7 +554,7 @@ RSpec.describe ProjectPresenter do
expect(presenter.kubernetes_cluster_anchor_data).to have_attributes(
is_link: false,
label: a_string_including('Add Kubernetes cluster'),
- link: presenter.new_project_cluster_path(project)
+ link: presenter.project_clusters_path(project)
)
end
end
diff --git a/spec/presenters/projects/security/configuration_presenter_spec.rb b/spec/presenters/projects/security/configuration_presenter_spec.rb
index 836753d0483..f9150179ae5 100644
--- a/spec/presenters/projects/security/configuration_presenter_spec.rb
+++ b/spec/presenters/projects/security/configuration_presenter_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe Projects::Security::ConfigurationPresenter do
before do
stub_licensed_features(licensed_scan_types.to_h { |type| [type, true] })
- stub_feature_flags(corpus_management: false)
+ stub_feature_flags(corpus_management_ui: false)
end
describe '#to_html_data_attribute' do
diff --git a/spec/presenters/service_hook_presenter_spec.rb b/spec/presenters/service_hook_presenter_spec.rb
index 7d7b71f324a..25ded17fb34 100644
--- a/spec/presenters/service_hook_presenter_spec.rb
+++ b/spec/presenters/service_hook_presenter_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe ServiceHookPresenter do
subject { service_hook.present.logs_details_path(web_hook_log) }
let(:expected_path) do
- "/#{project.namespace.path}/#{project.name}/-/services/#{integration.to_param}/hook_logs/#{web_hook_log.id}"
+ "/#{project.namespace.path}/#{project.name}/-/integrations/#{integration.to_param}/hook_logs/#{web_hook_log.id}"
end
it { is_expected.to eq(expected_path) }
@@ -22,7 +22,7 @@ RSpec.describe ServiceHookPresenter do
subject { service_hook.present.logs_retry_path(web_hook_log) }
let(:expected_path) do
- "/#{project.namespace.path}/#{project.name}/-/services/#{integration.to_param}/hook_logs/#{web_hook_log.id}/retry"
+ "/#{project.namespace.path}/#{project.name}/-/integrations/#{integration.to_param}/hook_logs/#{web_hook_log.id}/retry"
end
it { is_expected.to eq(expected_path) }
diff --git a/spec/presenters/web_hook_log_presenter_spec.rb b/spec/presenters/web_hook_log_presenter_spec.rb
index aa9d1d8f545..5827f3378de 100644
--- a/spec/presenters/web_hook_log_presenter_spec.rb
+++ b/spec/presenters/web_hook_log_presenter_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe WebHookLogPresenter do
let(:web_hook) { create(:service_hook, integration: integration) }
let(:integration) { create(:drone_ci_integration, project: project) }
- it { is_expected.to eq(project_service_hook_log_path(project, integration, web_hook_log)) }
+ it { is_expected.to eq(project_integration_hook_log_path(project, integration, web_hook_log)) }
end
end
@@ -41,7 +41,7 @@ RSpec.describe WebHookLogPresenter do
let(:web_hook) { create(:service_hook, integration: integration) }
let(:integration) { create(:drone_ci_integration, project: project) }
- it { is_expected.to eq(retry_project_service_hook_log_path(project, integration, web_hook_log)) }
+ it { is_expected.to eq(retry_project_integration_hook_log_path(project, integration, web_hook_log)) }
end
end
end
diff --git a/spec/rake_helper.rb b/spec/rake_helper.rb
index ca5b4d8337c..0386fef5134 100644
--- a/spec/rake_helper.rb
+++ b/spec/rake_helper.rb
@@ -11,7 +11,7 @@ RSpec.configure do |config|
Rake::Task.define_task :environment
end
- config.after(:all) do
+ config.after(:all, type: :task) do
delete_from_all_tables!(except: deletion_except_tables)
end
end
diff --git a/spec/requests/api/ci/job_artifacts_spec.rb b/spec/requests/api/ci/job_artifacts_spec.rb
index 585fab33708..0db6acbc7b8 100644
--- a/spec/requests/api/ci/job_artifacts_spec.rb
+++ b/spec/requests/api/ci/job_artifacts_spec.rb
@@ -81,6 +81,71 @@ RSpec.describe API::Ci::JobArtifacts do
end
end
+ describe 'DELETE /projects/:id/artifacts' do
+ context 'when feature flag is disabled' do
+ before do
+ stub_feature_flags(bulk_expire_project_artifacts: false)
+ end
+
+ it 'returns 404' do
+ delete api("/projects/#{project.id}/artifacts", api_user)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'when user is anonymous' do
+ let(:api_user) { nil }
+
+ it 'does not execute Ci::JobArtifacts::DeleteProjectArtifactsService' do
+ expect(Ci::JobArtifacts::DeleteProjectArtifactsService)
+ .not_to receive(:new)
+
+ delete api("/projects/#{project.id}/artifacts", api_user)
+ end
+
+ it 'returns status 401 (unauthorized)' do
+ delete api("/projects/#{project.id}/artifacts", api_user)
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
+
+ context 'with developer' do
+ it 'does not execute Ci::JobArtifacts::DeleteProjectArtifactsService' do
+ expect(Ci::JobArtifacts::DeleteProjectArtifactsService)
+ .not_to receive(:new)
+
+ delete api("/projects/#{project.id}/artifacts", api_user)
+ end
+
+ it 'returns status 403 (forbidden)' do
+ delete api("/projects/#{project.id}/artifacts", api_user)
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+ end
+
+ context 'with authorized user' do
+ let(:maintainer) { create(:project_member, :maintainer, project: project).user }
+ let!(:api_user) { maintainer }
+
+ it 'executes Ci::JobArtifacts::DeleteProjectArtifactsService' do
+ expect_next_instance_of(Ci::JobArtifacts::DeleteProjectArtifactsService, project: project) do |service|
+ expect(service).to receive(:execute).and_call_original
+ end
+
+ delete api("/projects/#{project.id}/artifacts", api_user)
+ end
+
+ it 'returns status 202 (accepted)' do
+ delete api("/projects/#{project.id}/artifacts", api_user)
+
+ expect(response).to have_gitlab_http_status(:accepted)
+ end
+ end
+ end
+
describe 'GET /projects/:id/jobs/:job_id/artifacts/:artifact_path' do
context 'when job has artifacts' do
let(:job) { create(:ci_build, :artifacts, pipeline: pipeline) }
diff --git a/spec/requests/api/ci/runner/runners_post_spec.rb b/spec/requests/api/ci/runner/runners_post_spec.rb
index a51d8b458f8..530b601add9 100644
--- a/spec/requests/api/ci/runner/runners_post_spec.rb
+++ b/spec/requests/api/ci/runner/runners_post_spec.rb
@@ -3,21 +3,6 @@
require 'spec_helper'
RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
- include StubGitlabCalls
- include RedisHelpers
- include WorkhorseHelpers
-
- let(:registration_token) { 'abcdefg123456' }
-
- before do
- stub_feature_flags(ci_enable_live_trace: true)
- stub_feature_flags(runner_registration_control: false)
- stub_gitlab_calls
- stub_application_setting(runners_registration_token: registration_token)
- stub_application_setting(valid_runner_registrars: ApplicationSetting::VALID_RUNNER_REGISTRAR_TYPES)
- allow_any_instance_of(::Ci::Runner).to receive(:cache_attributes)
- end
-
describe '/api/v4/runners' do
describe 'POST /api/v4/runners' do
context 'when no token is provided' do
@@ -30,380 +15,108 @@ 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(service).to receive(:execute).and_return(nil)
+ end
+
post api('/runners'), params: { token: 'invalid' }
expect(response).to have_gitlab_http_status(:forbidden)
end
end
- context 'when valid token is provided' do
+ context 'when valid parameters are provided' do
def request
- post api('/runners'), params: { token: token }
- end
-
- context 'with a registration token' do
- let(:token) { registration_token }
-
- it 'creates runner with default values' do
- request
-
- runner = ::Ci::Runner.first
-
- expect(response).to have_gitlab_http_status(:created)
- expect(json_response['id']).to eq(runner.id)
- expect(json_response['token']).to eq(runner.token)
- expect(runner.run_untagged).to be true
- expect(runner.active).to be true
- expect(runner.token).not_to eq(registration_token)
- expect(runner).to be_instance_type
- end
-
- it_behaves_like 'storing arguments in the application context for the API' do
- subject { request }
-
- let(:expected_params) { { client_id: "runner/#{::Ci::Runner.first.id}" } }
- end
-
- it_behaves_like 'not executing any extra queries for the application context' do
- let(:subject_proc) { proc { request } }
- end
- end
-
- context 'when project token is used' do
- let(:project) { create(:project) }
- let(:token) { project.runners_token }
-
- it 'creates project runner' do
- request
-
- expect(response).to have_gitlab_http_status(:created)
- expect(project.runners.size).to eq(1)
- runner = ::Ci::Runner.first
- expect(runner.token).not_to eq(registration_token)
- expect(runner.token).not_to eq(project.runners_token)
- expect(runner).to be_project_type
- end
-
- it_behaves_like 'storing arguments in the application context for the API' do
- subject { request }
-
- let(:expected_params) { { project: project.full_path, client_id: "runner/#{::Ci::Runner.first.id}" } }
- end
-
- it_behaves_like 'not executing any extra queries for the application context' do
- let(:subject_proc) { proc { request } }
- 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
- request
-
- expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response['message']).to include('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
- request
-
- expect(response).to have_gitlab_http_status(:created)
- expect(json_response['message']).to be_nil
- 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
- request
-
- expect(response).to have_gitlab_http_status(:forbidden)
- end
- end
-
- context 'when feature flag is disabled' do
- it 'registers the runner' do
- request
-
- expect(response).to have_gitlab_http_status(:created)
- expect(::Ci::Runner.first.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
- request
-
- expect(response).to have_gitlab_http_status(:created)
- expect(group.runners.reload.size).to eq(1)
- runner = ::Ci::Runner.first
- expect(runner.token).not_to eq(registration_token)
- expect(runner.token).not_to eq(group.runners_token)
- expect(runner).to be_group_type
- end
-
- it_behaves_like 'storing arguments in the application context for the API' do
- subject { request }
-
- let(:expected_params) { { root_namespace: group.full_path_components.first, client_id: "runner/#{::Ci::Runner.first.id}" } }
- end
-
- it_behaves_like 'not executing any extra queries for the application context' do
- let(:subject_proc) { proc { request } }
- 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
- request
-
- expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response['message']).to include('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
- request
-
- expect(response).to have_gitlab_http_status(:created)
- expect(json_response['message']).to be_nil
- 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 403 error' do
- request
-
- expect(response).to have_gitlab_http_status(:forbidden)
- end
- end
-
- context 'when feature flag is disabled' do
- it 'registers the runner' do
- request
-
- expect(response).to have_gitlab_http_status(:created)
- expect(::Ci::Runner.first.active).to be true
- end
- end
- end
- end
- end
-
- context 'when runner description is provided' do
- it 'creates runner' do
- post api('/runners'), params: {
- token: registration_token,
- description: 'server.hostname'
- }
-
- expect(response).to have_gitlab_http_status(:created)
- expect(::Ci::Runner.first.description).to eq('server.hostname')
- end
- end
-
- context 'when runner tags are provided' do
- it 'creates runner' do
post api('/runners'), params: {
- token: registration_token,
- tag_list: 'tag1, tag2'
- }
-
- expect(response).to have_gitlab_http_status(:created)
- expect(::Ci::Runner.first.tag_list.sort).to eq(%w(tag1 tag2))
- end
- end
-
- context 'when option for running untagged jobs is provided' do
- context 'when tags are provided' do
- it 'creates runner' do
- post api('/runners'), params: {
- token: registration_token,
- run_untagged: false,
- tag_list: ['tag']
- }
-
- expect(response).to have_gitlab_http_status(:created)
- expect(::Ci::Runner.first.run_untagged).to be false
- expect(::Ci::Runner.first.tag_list.sort).to eq(['tag'])
- end
- end
-
- context 'when tags are not provided' do
- it 'returns 400 error' do
- post api('/runners'), params: {
- token: registration_token,
- run_untagged: false
- }
-
- expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response['message']).to include(
- 'tags_list' => ['can not be empty when runner is not allowed to pick untagged jobs'])
+ token: 'valid token',
+ description: 'server.hostname',
+ maintainer_note: 'Some maintainer notes',
+ run_untagged: false,
+ tag_list: 'tag1, tag2',
+ locked: true,
+ active: true,
+ access_level: 'ref_protected',
+ maximum_timeout: 9000
+ }
+ end
+
+ let_it_be(:new_runner) { create(:ci_runner) }
+
+ before do
+ allow_next_instance_of(::Ci::RegisterRunnerService) do |service|
+ expected_params = {
+ description: 'server.hostname',
+ maintainer_note: 'Some maintainer notes',
+ run_untagged: false,
+ tag_list: %w(tag1 tag2),
+ locked: true,
+ active: true,
+ access_level: 'ref_protected',
+ maximum_timeout: 9000
+ }.stringify_keys
+
+ allow(service).to receive(:execute)
+ .once
+ .with('valid token', a_hash_including(expected_params))
+ .and_return(new_runner)
end
end
- end
- context 'when option for locking Runner is provided' do
it 'creates runner' do
- post api('/runners'), params: {
- token: registration_token,
- locked: true
- }
+ request
expect(response).to have_gitlab_http_status(:created)
- expect(::Ci::Runner.first.locked).to be true
+ expect(json_response['id']).to eq(new_runner.id)
+ expect(json_response['token']).to eq(new_runner.token)
end
- end
- context 'when option for activating a Runner is provided' do
- context 'when active is set to true' do
- it 'creates runner' do
- post api('/runners'), params: {
- token: registration_token,
- active: true
- }
+ it_behaves_like 'storing arguments in the application context for the API' do
+ subject { request }
- expect(response).to have_gitlab_http_status(:created)
- expect(::Ci::Runner.first.active).to be true
- end
+ let(:expected_params) { { client_id: "runner/#{new_runner.id}" } }
end
- context 'when active is set to false' do
- it 'creates runner' do
- post api('/runners'), params: {
- token: registration_token,
- active: false
- }
-
- expect(response).to have_gitlab_http_status(:created)
- expect(::Ci::Runner.first.active).to be false
- end
+ it_behaves_like 'not executing any extra queries for the application context' do
+ let(:subject_proc) { proc { request } }
end
end
- context 'when access_level is provided for Runner' do
- context 'when access_level is set to ref_protected' do
- it 'creates runner' do
- post api('/runners'), params: {
- token: registration_token,
- access_level: 'ref_protected'
- }
-
- expect(response).to have_gitlab_http_status(:created)
- expect(::Ci::Runner.first.ref_protected?).to be true
- end
- end
+ context 'calling actual register service' do
+ include StubGitlabCalls
- context 'when access_level is set to not_protected' do
- it 'creates runner' do
- post api('/runners'), params: {
- token: registration_token,
- access_level: 'not_protected'
- }
+ let(:registration_token) { 'abcdefg123456' }
- expect(response).to have_gitlab_http_status(:created)
- expect(::Ci::Runner.first.ref_protected?).to be false
- end
+ before do
+ stub_gitlab_calls
+ stub_application_setting(runners_registration_token: registration_token)
+ allow_any_instance_of(::Ci::Runner).to receive(:cache_attributes)
end
- end
-
- context 'when maximum job timeout is specified' do
- it 'creates runner' do
- post api('/runners'), params: {
- token: registration_token,
- maximum_timeout: 9000
- }
- expect(response).to have_gitlab_http_status(:created)
- expect(::Ci::Runner.first.maximum_timeout).to eq(9000)
- end
+ %w(name version revision platform architecture).each do |param|
+ context "when info parameter '#{param}' info is present" do
+ let(:value) { "#{param}_value" }
- context 'when maximum job timeout is empty' do
- it 'creates runner' do
- post api('/runners'), params: {
- token: registration_token,
- maximum_timeout: ''
- }
+ it "updates provided Runner's parameter" do
+ post api('/runners'), params: {
+ token: registration_token,
+ info: { param => value }
+ }
- expect(response).to have_gitlab_http_status(:created)
- expect(::Ci::Runner.first.maximum_timeout).to be_nil
+ expect(response).to have_gitlab_http_status(:created)
+ expect(::Ci::Runner.last.read_attribute(param.to_sym)).to eq(value)
+ end
end
end
- end
- %w(name version revision platform architecture).each do |param|
- context "when info parameter '#{param}' info is present" do
- let(:value) { "#{param}_value" }
+ it "sets the runner's ip_address" do
+ post api('/runners'),
+ params: { token: registration_token },
+ headers: { 'X-Forwarded-For' => '123.111.123.111' }
- it "updates provided Runner's parameter" do
- post api('/runners'), params: {
- token: registration_token,
- info: { param => value }
- }
-
- expect(response).to have_gitlab_http_status(:created)
- expect(::Ci::Runner.first.read_attribute(param.to_sym)).to eq(value)
- end
+ expect(response).to have_gitlab_http_status(:created)
+ expect(::Ci::Runner.last.ip_address).to eq('123.111.123.111')
end
end
-
- it "sets the runner's ip_address" do
- post api('/runners'),
- params: { token: registration_token },
- headers: { 'X-Forwarded-For' => '123.111.123.111' }
-
- expect(response).to have_gitlab_http_status(:created)
- expect(::Ci::Runner.first.ip_address).to eq('123.111.123.111')
- end
end
end
end
diff --git a/spec/requests/api/ci/runners_spec.rb b/spec/requests/api/ci/runners_spec.rb
index 6ca380a3cb9..305c0bd9df0 100644
--- a/spec/requests/api/ci/runners_spec.rb
+++ b/spec/requests/api/ci/runners_spec.rb
@@ -980,7 +980,7 @@ RSpec.describe API::Ci::Runners do
end
end
- describe 'GET /groups/:id/runners' do
+ shared_context 'GET /groups/:id/runners' do
context 'authorized user with maintainer privileges' do
it 'returns all runners' do
get api("/groups/#{group.id}/runners", user)
@@ -1048,6 +1048,16 @@ RSpec.describe API::Ci::Runners do
end
end
+ it_behaves_like 'GET /groups/:id/runners'
+
+ context 'when the FF ci_find_runners_by_ci_mirrors is disabled' do
+ before do
+ stub_feature_flags(ci_find_runners_by_ci_mirrors: false)
+ end
+
+ it_behaves_like 'GET /groups/:id/runners'
+ end
+
describe 'POST /projects/:id/runners' do
context 'authorized user' do
let_it_be(:project_runner2) { create(:ci_runner, :project, projects: [project2]) }
diff --git a/spec/requests/api/ci/triggers_spec.rb b/spec/requests/api/ci/triggers_spec.rb
index d270a16d28d..a036a55f5f3 100644
--- a/spec/requests/api/ci/triggers_spec.rb
+++ b/spec/requests/api/ci/triggers_spec.rb
@@ -162,7 +162,7 @@ RSpec.describe API::Ci::Triggers do
expect do
post api("/projects/#{project.id}/ref/master/trigger/pipeline?token=#{trigger_token}"),
params: { ref: 'refs/heads/other-branch' },
- headers: { WebHookService::GITLAB_EVENT_HEADER => 'Pipeline Hook' }
+ headers: { ::Gitlab::WebHooks::GITLAB_EVENT_HEADER => 'Pipeline Hook' }
end.not_to change(Ci::Pipeline, :count)
expect(response).to have_gitlab_http_status(:forbidden)
diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb
index 1e587480fd9..2bc642f8b14 100644
--- a/spec/requests/api/commits_spec.rb
+++ b/spec/requests/api/commits_spec.rb
@@ -1056,9 +1056,7 @@ RSpec.describe API::Commits do
shared_examples_for 'ref with pipeline' do
let!(:pipeline) do
- project
- .ci_pipelines
- .create!(source: :push, ref: 'master', sha: commit.sha, protected: false)
+ create(:ci_empty_pipeline, project: project, status: :created, source: :push, ref: 'master', sha: commit.sha, protected: false)
end
it 'includes status as "created" and a last_pipeline object' do
@@ -1090,9 +1088,7 @@ RSpec.describe API::Commits do
shared_examples_for 'ref with unaccessible pipeline' do
let!(:pipeline) do
- project
- .ci_pipelines
- .create!(source: :push, ref: 'master', sha: commit.sha, protected: false)
+ create(:ci_empty_pipeline, project: project, status: :created, source: :push, ref: 'master', sha: commit.sha, protected: false)
end
it 'does not include last_pipeline' do
diff --git a/spec/requests/api/generic_packages_spec.rb b/spec/requests/api/generic_packages_spec.rb
index 2d85d7b9583..1836233594d 100644
--- a/spec/requests/api/generic_packages_spec.rb
+++ b/spec/requests/api/generic_packages_spec.rb
@@ -574,6 +574,27 @@ RSpec.describe API::GenericPackages do
end
end
+ context 'with package status' do
+ where(:package_status, :expected_status) do
+ :default | :success
+ :hidden | :success
+ :error | :not_found
+ end
+
+ with_them do
+ before do
+ project.add_developer(user)
+ package.update!(status: package_status)
+ end
+
+ it "responds with #{params[:expected_status]}" do
+ download_file(personal_access_token_header)
+
+ expect(response).to have_gitlab_http_status(expected_status)
+ end
+ end
+ end
+
context 'event tracking' do
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, user: user } }
diff --git a/spec/requests/api/graphql/ci/config_spec.rb b/spec/requests/api/graphql/ci/config_spec.rb
index 8ede6e1538c..755585f8e0e 100644
--- a/spec/requests/api/graphql/ci/config_spec.rb
+++ b/spec/requests/api/graphql/ci/config_spec.rb
@@ -20,6 +20,7 @@ RSpec.describe 'Query.ciConfig' do
ciConfig(projectPath: "#{project.full_path}", content: "#{content}", dryRun: false) {
status
errors
+ warnings
stages {
nodes {
name
@@ -73,6 +74,7 @@ RSpec.describe 'Query.ciConfig' do
expect(graphql_data['ciConfig']).to eq(
"status" => "VALID",
"errors" => [],
+ "warnings" => [],
"stages" =>
{
"nodes" =>
@@ -220,6 +222,21 @@ RSpec.describe 'Query.ciConfig' do
)
end
+ context 'when using deprecated keywords' do
+ let_it_be(:content) do
+ YAML.dump(
+ rspec: { script: 'ls' },
+ types: ['test']
+ )
+ end
+
+ it 'returns a warning' do
+ post_graphql_query
+
+ expect(graphql_data['ciConfig']['warnings']).to include('root `types` is deprecated in 9.0 and will be removed in 15.0.')
+ end
+ end
+
context 'when the config file includes other files' do
let_it_be(:content) do
YAML.dump(
@@ -250,6 +267,7 @@ RSpec.describe 'Query.ciConfig' do
expect(graphql_data['ciConfig']).to eq(
"status" => "VALID",
"errors" => [],
+ "warnings" => [],
"stages" =>
{
"nodes" =>
diff --git a/spec/requests/api/graphql/ci/jobs_spec.rb b/spec/requests/api/graphql/ci/jobs_spec.rb
index 3a1df3525ef..b191b585d06 100644
--- a/spec/requests/api/graphql/ci/jobs_spec.rb
+++ b/spec/requests/api/graphql/ci/jobs_spec.rb
@@ -44,6 +44,10 @@ RSpec.describe 'Query.project.pipeline' do
name
jobs {
nodes {
+ downstreamPipeline {
+ id
+ path
+ }
name
needs {
nodes { #{all_graphql_fields_for('CiBuildNeed')} }
@@ -131,6 +135,8 @@ RSpec.describe 'Query.project.pipeline' do
end
it 'does not generate N+1 queries', :request_store, :use_sql_query_cache do
+ create(:ci_bridge, name: 'bridge-1', pipeline: pipeline, downstream_pipeline: create(:ci_pipeline))
+
post_graphql(query, current_user: user)
control = ActiveRecord::QueryRecorder.new(skip_cached: false) do
@@ -139,6 +145,8 @@ RSpec.describe 'Query.project.pipeline' do
create(:ci_build, name: 'test-a', pipeline: pipeline)
create(:ci_build, name: 'test-b', pipeline: pipeline)
+ create(:ci_bridge, name: 'bridge-2', pipeline: pipeline, downstream_pipeline: create(:ci_pipeline))
+ create(:ci_bridge, name: 'bridge-3', pipeline: pipeline, downstream_pipeline: create(:ci_pipeline))
expect do
post_graphql(query, current_user: user)
diff --git a/spec/requests/api/graphql/ci/pipelines_spec.rb b/spec/requests/api/graphql/ci/pipelines_spec.rb
index 95ddd0250e7..5ae68be46a2 100644
--- a/spec/requests/api/graphql/ci/pipelines_spec.rb
+++ b/spec/requests/api/graphql/ci/pipelines_spec.rb
@@ -12,6 +12,38 @@ RSpec.describe 'Query.project(fullPath).pipelines' do
travel_to(Time.current) { example.run }
end
+ describe 'sha' do
+ let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
+
+ let(:pipelines_graphql_data) { graphql_data.dig(*%w[project pipelines nodes]).first }
+
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ pipelines {
+ nodes {
+ fullSha: sha
+ shortSha: sha(format: SHORT)
+ alsoFull: sha(format: LONG)
+ }
+ }
+ }
+ }
+ )
+ end
+
+ it 'returns all formats of the SHA' do
+ post_graphql(query, current_user: user)
+
+ expect(pipelines_graphql_data).to include(
+ 'fullSha' => eq(pipeline.sha),
+ 'alsoFull' => eq(pipeline.sha),
+ 'shortSha' => eq(pipeline.short_sha)
+ )
+ end
+ end
+
describe 'duration fields' do
let_it_be(:pipeline) do
create(:ci_pipeline, project: project)
@@ -251,6 +283,50 @@ RSpec.describe 'Query.project(fullPath).pipelines' do
end
end
+ describe 'warningMessages' do
+ let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
+ let_it_be(:warning_message) { create(:ci_pipeline_message, pipeline: pipeline, content: 'warning') }
+
+ let(:pipelines_graphql_data) { graphql_data.dig(*%w[project pipelines nodes]).first }
+
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ pipelines {
+ nodes {
+ warningMessages {
+ content
+ }
+ }
+ }
+ }
+ }
+ )
+ end
+
+ it 'returns pipeline warnings' do
+ post_graphql(query, current_user: user)
+
+ expect(pipelines_graphql_data['warningMessages']).to contain_exactly(
+ a_hash_including('content' => 'warning')
+ )
+ end
+
+ it 'avoids N+1 queries' do
+ control_count = ActiveRecord::QueryRecorder.new do
+ post_graphql(query, current_user: user)
+ end
+
+ pipeline_2 = create(:ci_pipeline, project: project)
+ create(:ci_pipeline_message, pipeline: pipeline_2, content: 'warning')
+
+ expect do
+ post_graphql(query, current_user: user)
+ end.not_to exceed_query_limit(control_count)
+ end
+ end
+
describe '.jobs(securityReportTypes)' do
let_it_be(:query) do
%(
@@ -420,4 +496,36 @@ RSpec.describe 'Query.project(fullPath).pipelines' do
end
end
end
+
+ describe 'ref_path' do
+ let_it_be(:merge_request) { create(:merge_request, source_project: project) }
+ let_it_be(:pipeline_1) { create(:ci_pipeline, project: project, user: user, merge_request: merge_request) }
+ let_it_be(:pipeline_2) { create(:ci_pipeline, project: project, user: user, merge_request: merge_request) }
+
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ pipelines {
+ nodes {
+ refPath
+ }
+ }
+ }
+ }
+ )
+ end
+
+ it 'avoids N+1 queries' do
+ control_count = ActiveRecord::QueryRecorder.new do
+ post_graphql(query, current_user: user)
+ end
+
+ create(:ci_pipeline, project: project, user: user, merge_request: merge_request)
+
+ expect do
+ post_graphql(query, current_user: user)
+ end.not_to exceed_query_limit(control_count)
+ end
+ end
end
diff --git a/spec/requests/api/graphql/ci/runner_spec.rb b/spec/requests/api/graphql/ci/runner_spec.rb
index 98d3a3b1c51..8c919b48849 100644
--- a/spec/requests/api/graphql/ci/runner_spec.rb
+++ b/spec/requests/api/graphql/ci/runner_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe 'Query.runner(id)' do
let_it_be(:active_instance_runner) do
create(:ci_runner, :instance, description: 'Runner 1', contacted_at: 2.hours.ago,
active: true, version: 'adfe156', revision: 'a', locked: true, ip_address: '127.0.0.1', maximum_timeout: 600,
- access_level: 0, tag_list: %w[tag1 tag2], run_untagged: true)
+ access_level: 0, tag_list: %w[tag1 tag2], run_untagged: true, executor_type: :custom)
end
let_it_be(:inactive_instance_runner) do
@@ -22,7 +22,7 @@ RSpec.describe 'Query.runner(id)' do
let_it_be(:active_group_runner) do
create(:ci_runner, :group, groups: [group], description: 'Group runner 1', contacted_at: 2.hours.ago,
active: true, version: 'adfe156', revision: 'a', locked: true, ip_address: '127.0.0.1', maximum_timeout: 600,
- access_level: 0, tag_list: %w[tag1 tag2], run_untagged: true)
+ access_level: 0, tag_list: %w[tag1 tag2], run_untagged: true, executor_type: :shell)
end
def get_runner(id)
@@ -57,6 +57,7 @@ RSpec.describe 'Query.runner(id)' do
expect(runner_data).to match a_hash_including(
'id' => "gid://gitlab/Ci::Runner/#{runner.id}",
'description' => runner.description,
+ 'createdAt' => runner.created_at&.iso8601,
'contactedAt' => runner.contacted_at&.iso8601,
'version' => runner.version,
'shortSha' => runner.short_sha,
@@ -69,6 +70,7 @@ RSpec.describe 'Query.runner(id)' do
'runUntagged' => runner.run_untagged,
'ipAddress' => runner.ip_address,
'runnerType' => runner.instance_type? ? 'INSTANCE_TYPE' : 'PROJECT_TYPE',
+ 'executorName' => runner.executor_type&.dasherize,
'jobCount' => 0,
'projectCount' => nil,
'adminUrl' => "http://localhost/admin/runners/#{runner.id}",
diff --git a/spec/requests/api/graphql/group/group_members_spec.rb b/spec/requests/api/graphql/group/group_members_spec.rb
index 31cb0393d7f..06afb5b9a49 100644
--- a/spec/requests/api/graphql/group/group_members_spec.rb
+++ b/spec/requests/api/graphql/group/group_members_spec.rb
@@ -56,12 +56,16 @@ RSpec.describe 'getting group members information' do
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) }
+ let_it_be(:invited_group) { create(:group, :public) }
let_it_be(:child_user) { create(:user) }
let_it_be(:grandchild_user) { create(:user) }
+ let_it_be(:invited_user) { create(:user) }
+ let_it_be(:group_link) { create(:group_group_link, shared_group: child_group, shared_with_group: invited_group) }
before_all do
child_group.add_guest(child_user)
grandchild_group.add_guest(grandchild_user)
+ invited_group.add_guest(invited_user)
end
it 'returns direct members' do
@@ -71,6 +75,13 @@ RSpec.describe 'getting group members information' do
expect_array_response(child_user)
end
+ it 'returns invited members plus inherited members' do
+ fetch_members(group: child_group, args: { relations: [:DIRECT, :INHERITED, :SHARED_FROM_GROUPS] })
+
+ expect(graphql_errors).to be_nil
+ expect_array_response(invited_user, user_1, user_2, child_user)
+ end
+
it 'returns direct and inherited members' do
fetch_members(group: child_group, args: { relations: [:DIRECT, :INHERITED] })
diff --git a/spec/requests/api/graphql/group/work_item_types_spec.rb b/spec/requests/api/graphql/group/work_item_types_spec.rb
new file mode 100644
index 00000000000..0667e09d1e9
--- /dev/null
+++ b/spec/requests/api/graphql/group/work_item_types_spec.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'getting a list of work item types for a group' do
+ include GraphqlHelpers
+
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:group) { create(:group, :private) }
+
+ before_all do
+ group.add_developer(developer)
+ end
+
+ let(:current_user) { developer }
+
+ let(:fields) do
+ <<~GRAPHQL
+ workItemTypes{
+ nodes { id name iconName }
+ }
+ GRAPHQL
+ end
+
+ let(:query) do
+ graphql_query_for(
+ 'group',
+ { 'fullPath' => group.full_path },
+ fields
+ )
+ end
+
+ context 'when user has access to the group' do
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+
+ it_behaves_like 'a working graphql query'
+
+ it 'returns all default work item types' do
+ expect(graphql_data.dig('group', 'workItemTypes', 'nodes')).to match_array(
+ WorkItems::Type.default.map do |type|
+ hash_including('id' => type.to_global_id.to_s, 'name' => type.name, 'iconName' => type.icon_name)
+ end
+ )
+ end
+ end
+
+ context "when user doesn't have acces to the group" do
+ let(:current_user) { create(:user) }
+
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+
+ it 'does not return the group' do
+ expect(graphql_data).to eq('group' => nil)
+ end
+ end
+
+ context 'when the work_items feature flag is disabled' do
+ before do
+ stub_feature_flags(work_items: false)
+ 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'"))
+ 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 2da69509ad6..79d687a2bdb 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
@@ -6,13 +6,18 @@ RSpec.describe 'Setting issues crm contacts' do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
- let_it_be(:group) { create(:group) }
- let_it_be(:project) { create(:project, group: group) }
- let_it_be(:contacts) { create_list(:contact, 4, group: group) }
+ 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(:issue) { create(:issue, project: project) }
let(:operation_mode) { Types::MutationOperationModeEnum.default_mode }
- let(:contact_ids) { [global_id_of(contacts[1]), global_id_of(contacts[2])] }
+ let(:contacts) { subgroup_contacts }
+ let(:initial_contacts) { contacts[0..1] }
+ let(:mutation_contacts) { contacts[1..2] }
+ let(:contact_ids) { contact_global_ids(mutation_contacts) }
let(:does_not_exist_or_no_permission) { "The resource that you are attempting to access does not exist or you don't have permission to perform this action" }
let(:mutation) do
@@ -42,9 +47,47 @@ RSpec.describe 'Setting issues crm contacts' do
graphql_mutation_response(:issue_set_crm_contacts)
end
+ def contact_global_ids(contacts)
+ contacts.map { |contact| global_id_of(contact) }
+ end
+
before do
- create(:issue_customer_relations_contact, issue: issue, contact: contacts[0])
- create(:issue_customer_relations_contact, issue: issue, contact: contacts[1])
+ initial_contacts.each { |contact| create(:issue_customer_relations_contact, issue: issue, contact: contact) }
+ end
+
+ shared_examples 'successful mutation' do
+ context 'replace' do
+ it 'updates the issue with correct contacts' do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(graphql_data_at(:issue_set_crm_contacts, :issue, :customer_relations_contacts, :nodes, :id))
+ .to match_array(contact_global_ids(mutation_contacts))
+ end
+ end
+
+ context 'append' do
+ let(:mutation_contacts) { [contacts[3]] }
+ let(:operation_mode) { Types::MutationOperationModeEnum.enum[:append] }
+
+ it 'updates the issue with correct contacts' do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(graphql_data_at(:issue_set_crm_contacts, :issue, :customer_relations_contacts, :nodes, :id))
+ .to match_array(contact_global_ids(initial_contacts + mutation_contacts))
+ end
+ end
+
+ context 'remove' do
+ let(:mutation_contacts) { [contacts[0]] }
+ let(:operation_mode) { Types::MutationOperationModeEnum.enum[:remove] }
+
+ it 'updates the issue with correct contacts' do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(graphql_data_at(:issue_set_crm_contacts, :issue, :customer_relations_contacts, :nodes, :id))
+ .to match_array(contact_global_ids(initial_contacts - mutation_contacts))
+ end
+ end
end
context 'when the user has no permission' do
@@ -73,37 +116,14 @@ RSpec.describe 'Setting issues crm contacts' do
end
end
- context 'replace' do
- it 'updates the issue with correct contacts' do
- post_graphql_mutation(mutation, current_user: user)
-
- expect(graphql_data_at(:issue_set_crm_contacts, :issue, :customer_relations_contacts, :nodes, :id))
- .to match_array([global_id_of(contacts[1]), global_id_of(contacts[2])])
- end
- end
+ context 'with issue group contacts' do
+ let(:contacts) { subgroup_contacts }
- context 'append' do
- let(:contact_ids) { [global_id_of(contacts[3])] }
- let(:operation_mode) { Types::MutationOperationModeEnum.enum[:append] }
-
- it 'updates the issue with correct contacts' do
- post_graphql_mutation(mutation, current_user: user)
-
- expect(graphql_data_at(:issue_set_crm_contacts, :issue, :customer_relations_contacts, :nodes, :id))
- .to match_array([global_id_of(contacts[0]), global_id_of(contacts[1]), global_id_of(contacts[3])])
- end
+ it_behaves_like 'successful mutation'
end
- context 'remove' do
- let(:contact_ids) { [global_id_of(contacts[0])] }
- let(:operation_mode) { Types::MutationOperationModeEnum.enum[:remove] }
-
- it 'updates the issue with correct contacts' do
- post_graphql_mutation(mutation, current_user: user)
-
- expect(graphql_data_at(:issue_set_crm_contacts, :issue, :customer_relations_contacts, :nodes, :id))
- .to match_array([global_id_of(contacts[1])])
- end
+ context 'with issue ancestor group contacts' do
+ it_behaves_like 'successful mutation'
end
context 'when the contact does not exist' do
@@ -118,7 +138,7 @@ RSpec.describe 'Setting issues crm contacts' do
end
context 'when the contact belongs to a different group' do
- let(:group2) { create(:group) }
+ let(:group2) { create(:group, :crm_enabled) }
let(:contact) { create(:contact, group: group2) }
let(:contact_ids) { [global_id_of(contact)] }
@@ -158,4 +178,17 @@ RSpec.describe 'Setting issues crm contacts' do
end
end
end
+
+ context 'when crm_enabled is false' do
+ let(:issue) { create(:issue) }
+ let(:initial_contacts) { [] }
+
+ it 'raises expected error' do
+ issue.project.add_reporter(user)
+
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(graphql_errors).to include(a_hash_including('message' => 'Feature disabled'))
+ end
+ end
end
diff --git a/spec/requests/api/graphql/mutations/issues/set_escalation_status_spec.rb b/spec/requests/api/graphql/mutations/issues/set_escalation_status_spec.rb
new file mode 100644
index 00000000000..0166871502b
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/issues/set_escalation_status_spec.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Setting the escalation status of an incident' do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project) }
+ let_it_be(:issue) { create(:incident, project: project) }
+ let_it_be(:escalation_status) { create(:incident_management_issuable_escalation_status, issue: issue) }
+ let_it_be(:user) { create(:user) }
+
+ let(:status) { 'ACKNOWLEDGED' }
+ let(:input) { { project_path: project.full_path, iid: issue.iid.to_s, status: status } }
+
+ let(:current_user) { user }
+ let(:mutation) do
+ graphql_mutation(:issue_set_escalation_status, input) do
+ <<~QL
+ clientMutationId
+ errors
+ issue {
+ iid
+ escalationStatus
+ }
+ QL
+ end
+ end
+
+ let(:mutation_response) { graphql_mutation_response(:issue_set_escalation_status) }
+
+ before_all do
+ project.add_developer(user)
+ end
+
+ context 'when user does not have permission to edit the escalation status' do
+ let(:current_user) { create(:user) }
+
+ before_all do
+ project.add_reporter(user)
+ end
+
+ it_behaves_like 'a mutation that returns a top-level access error'
+ end
+
+ context 'with non-incident issue is provided' do
+ let_it_be(:issue) { create(:issue, project: project) }
+
+ it_behaves_like 'a mutation that returns top-level errors', errors: ['Feature unavailable for provided issue']
+ end
+
+ context 'with feature disabled' do
+ before do
+ stub_feature_flags(incident_escalations: false)
+ end
+
+ it_behaves_like 'a mutation that returns top-level errors', errors: ['Feature unavailable for provided issue']
+ end
+
+ it 'sets given escalation_policy to the escalation status for the issue' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response['errors']).to be_empty
+ expect(mutation_response['issue']['escalationStatus']).to eq(status)
+ expect(escalation_status.reload.status_name).to eq(:acknowledged)
+ end
+
+ context 'when status argument is not given' do
+ let(:input) { {} }
+
+ it_behaves_like 'a mutation that returns top-level errors' do
+ let(:match_errors) { contain_exactly(include('status (Expected value to not be null)')) }
+ end
+ end
+
+ context 'when status argument is invalid' do
+ let(:status) { 'INVALID' }
+
+ it_behaves_like 'an invalid argument to the mutation', argument_name: :status
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/work_items/create_spec.rb b/spec/requests/api/graphql/mutations/work_items/create_spec.rb
new file mode 100644
index 00000000000..e7a0c7753fb
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/work_items/create_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Create a work item' do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project) }
+ let_it_be(:developer) { create(:user).tap { |user| project.add_developer(user) } }
+
+ let(:input) do
+ {
+ 'title' => 'new title',
+ 'description' => 'new description',
+ 'workItemTypeId' => WorkItems::Type.default_by_type(:task).to_global_id.to_s
+ }
+ end
+
+ let(:mutation) { graphql_mutation(:workItemCreate, input.merge('projectPath' => project.full_path)) }
+
+ let(:mutation_response) { graphql_mutation_response(:work_item_create) }
+
+ context 'the user is not allowed to create 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
+
+ expect(response).to have_gitlab_http_status(:success)
+ 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(
+ input.except('workItemTypeId').merge(
+ 'id' => created_work_item.to_global_id.to_s,
+ 'workItemType' => hash_including('name' => 'Task')
+ )
+ )
+ end
+
+ it_behaves_like 'has spam protection' do
+ let(:mutation_class) { ::Mutations::WorkItems::Create }
+ end
+
+ context 'when the work_items feature flag is disabled' do
+ before do
+ stub_feature_flags(work_items: false)
+ end
+
+ it_behaves_like 'a mutation that returns top-level errors',
+ errors: ["Field 'workItemCreate' doesn't exist on type 'Mutation'", "Variable $workItemCreateInput is declared by anonymous mutation but not used"]
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/packages/package_spec.rb b/spec/requests/api/graphql/packages/package_spec.rb
index a9019a7611a..2ff3bc7cc47 100644
--- a/spec/requests/api/graphql/packages/package_spec.rb
+++ b/spec/requests/api/graphql/packages/package_spec.rb
@@ -4,7 +4,9 @@ require 'spec_helper'
RSpec.describe 'package details' do
include GraphqlHelpers
- let_it_be_with_reload(:project) { create(:project) }
+ let_it_be_with_reload(:group) { create(:group) }
+ let_it_be_with_reload(:project) { create(:project, group: group) }
+ let_it_be(:user) { create(:user) }
let_it_be(:composer_package) { create(:composer_package, project: project) }
let_it_be(:composer_json) { { name: 'name', type: 'type', license: 'license', version: 1 } }
let_it_be(:composer_metadatum) do
@@ -17,7 +19,6 @@ RSpec.describe 'package details' do
let(:excluded) { %w[metadata apiFuzzingCiConfiguration pipeline packageFiles] }
let(:metadata) { query_graphql_fragment('ComposerMetadata') }
let(:package_files) {all_graphql_fields_for('PackageFile')}
- let(:user) { project.owner }
let(:package_global_id) { global_id_of(composer_package) }
let(:package_details) { graphql_data_at(:package) }
@@ -37,145 +38,198 @@ RSpec.describe 'package details' do
subject { post_graphql(query, current_user: user) }
- it_behaves_like 'a working graphql query' do
+ context 'with unauthorized user' do
before do
- subject
+ project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
end
- it 'matches the JSON schema' do
- expect(package_details).to match_schema('graphql/packages/package_details')
+ it 'returns no packages' do
+ subject
+
+ expect(graphql_data_at(:package)).to be_nil
end
end
- context 'there are other versions of this package' do
- let(:depth) { 3 }
- let(:excluded) { %w[metadata project tags pipelines] } # to limit the query complexity
-
- let_it_be(:siblings) { create_list(:composer_package, 2, project: project, name: composer_package.name) }
+ context 'with authorized user' do
+ before do
+ project.add_developer(user)
+ end
- it 'includes the sibling versions' do
- subject
+ it_behaves_like 'a working graphql query' do
+ before do
+ subject
+ end
- expect(graphql_data_at(:package, :versions, :nodes)).to match_array(
- siblings.map { |p| a_hash_including('id' => global_id_of(p)) }
- )
+ it 'matches the JSON schema' do
+ expect(package_details).to match_schema('graphql/packages/package_details')
+ end
end
- context 'going deeper' do
- let(:depth) { 6 }
+ context 'there are other versions of this package' do
+ let(:depth) { 3 }
+ let(:excluded) { %w[metadata project tags pipelines] } # to limit the query complexity
- it 'does not create a cycle of versions' do
+ let_it_be(:siblings) { create_list(:composer_package, 2, project: project, name: composer_package.name) }
+
+ it 'includes the sibling versions' do
subject
- expect(graphql_data_at(:package, :versions, :nodes, :version)).to be_present
- expect(graphql_data_at(:package, :versions, :nodes, :versions, :nodes)).to eq [nil, nil]
+ expect(graphql_data_at(:package, :versions, :nodes)).to match_array(
+ siblings.map { |p| a_hash_including('id' => global_id_of(p)) }
+ )
end
- end
- end
- context 'with a batched query' do
- let_it_be(:conan_package) { create(:conan_package, project: project) }
+ context 'going deeper' do
+ let(:depth) { 6 }
- let(:batch_query) do
- <<~QUERY
- {
- a: package(id: "#{global_id_of(composer_package)}") { name }
- b: package(id: "#{global_id_of(conan_package)}") { name }
- }
- QUERY
+ it 'does not create a cycle of versions' do
+ subject
+
+ expect(graphql_data_at(:package, :versions, :nodes, :version)).to be_present
+ expect(graphql_data_at(:package, :versions, :nodes, :versions, :nodes)).to match_array [nil, nil]
+ end
+ end
end
- let(:a_packages_names) { graphql_data_at(:a, :packages, :nodes, :name) }
+ context 'with package files pending destruction' do
+ let_it_be(:package_file) { create(:package_file, package: composer_package) }
+ let_it_be(:package_file_pending_destruction) { create(:package_file, :pending_destruction, package: composer_package) }
- it 'returns an error for the second package and data for the first' do
- post_graphql(batch_query, current_user: user)
+ let(:package_file_ids) { graphql_data_at(:package, :package_files, :nodes).map { |node| node["id"] } }
- expect(graphql_data_at(:a, :name)).to eq(composer_package.name)
+ it 'does not return them' do
+ subject
- expect_graphql_errors_to_include [/Package details can be requested only for one package at a time/]
- expect(graphql_data_at(:b)).to be(nil)
- end
- end
+ expect(package_file_ids).to contain_exactly(package_file.to_global_id.to_s)
+ end
- context 'with unauthorized user' do
- let_it_be(:user) { create(:user) }
+ context 'with packages_installable_package_files disabled' do
+ before do
+ stub_feature_flags(packages_installable_package_files: false)
+ end
- before do
- project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
+ it 'returns them' do
+ subject
+
+ expect(package_file_ids).to contain_exactly(package_file_pending_destruction.to_global_id.to_s, package_file.to_global_id.to_s)
+ end
+ end
end
- it 'returns no packages' do
- subject
+ context 'with a batched query' do
+ let_it_be(:conan_package) { create(:conan_package, project: project) }
- expect(graphql_data_at(:package)).to be_nil
- end
- end
+ let(:batch_query) do
+ <<~QUERY
+ {
+ a: package(id: "#{global_id_of(composer_package)}") { name }
+ b: package(id: "#{global_id_of(conan_package)}") { name }
+ }
+ QUERY
+ end
- context 'pipelines field', :aggregate_failures do
- let(:pipelines) { create_list(:ci_pipeline, 6, project: project) }
- let(:pipeline_gids) { pipelines.sort_by(&:id).map(&:to_gid).map(&:to_s).reverse }
+ let(:a_packages_names) { graphql_data_at(:a, :packages, :nodes, :name) }
- before do
- composer_package.pipelines = pipelines
- composer_package.save!
- end
+ it 'returns an error for the second package and data for the first' do
+ post_graphql(batch_query, current_user: user)
- def run_query(args)
- pipelines_nodes = <<~QUERY
- nodes {
- id
- }
- pageInfo {
- startCursor
- endCursor
- }
- QUERY
+ expect(graphql_data_at(:a, :name)).to eq(composer_package.name)
- query = graphql_query_for(:package, { id: package_global_id }, query_graphql_field("pipelines", args, pipelines_nodes))
- post_graphql(query, current_user: user)
+ expect_graphql_errors_to_include [/Package details can be requested only for one package at a time/]
+ expect(graphql_data_at(:b)).to be(nil)
+ end
end
- it 'loads the second page with pagination first correctly' do
- run_query(first: 2)
- pipeline_ids = graphql_data.dig('package', 'pipelines', 'nodes').pluck('id')
+ context 'pipelines field', :aggregate_failures do
+ let(:pipelines) { create_list(:ci_pipeline, 6, project: project) }
+ let(:pipeline_gids) { pipelines.sort_by(&:id).map(&:to_gid).map(&:to_s).reverse }
- expect(pipeline_ids).to eq(pipeline_gids[0..1])
+ before do
+ composer_package.pipelines = pipelines
+ composer_package.save!
+ end
- cursor = graphql_data.dig('package', 'pipelines', 'pageInfo', 'endCursor')
+ def run_query(args)
+ pipelines_nodes = <<~QUERY
+ nodes {
+ id
+ }
+ pageInfo {
+ startCursor
+ endCursor
+ }
+ QUERY
+
+ query = graphql_query_for(:package, { id: package_global_id }, query_graphql_field("pipelines", args, pipelines_nodes))
+ post_graphql(query, current_user: user)
+ end
- run_query(first: 2, after: cursor)
+ it 'loads the second page with pagination first correctly' do
+ run_query(first: 2)
+ pipeline_ids = graphql_data.dig('package', 'pipelines', 'nodes').pluck('id')
- pipeline_ids = graphql_data.dig('package', 'pipelines', 'nodes').pluck('id')
+ expect(pipeline_ids).to eq(pipeline_gids[0..1])
- expect(pipeline_ids).to eq(pipeline_gids[2..3])
- end
+ cursor = graphql_data.dig('package', 'pipelines', 'pageInfo', 'endCursor')
- it 'loads the second page with pagination last correctly' do
- run_query(last: 2)
- pipeline_ids = graphql_data.dig('package', 'pipelines', 'nodes').pluck('id')
+ run_query(first: 2, after: cursor)
- expect(pipeline_ids).to eq(pipeline_gids[4..5])
+ pipeline_ids = graphql_data.dig('package', 'pipelines', 'nodes').pluck('id')
- cursor = graphql_data.dig('package', 'pipelines', 'pageInfo', 'startCursor')
+ expect(pipeline_ids).to eq(pipeline_gids[2..3])
+ end
- run_query(last: 2, before: cursor)
+ it 'loads the second page with pagination last correctly' do
+ run_query(last: 2)
+ pipeline_ids = graphql_data.dig('package', 'pipelines', 'nodes').pluck('id')
- pipeline_ids = graphql_data.dig('package', 'pipelines', 'nodes').pluck('id')
+ expect(pipeline_ids).to eq(pipeline_gids[4..5])
- expect(pipeline_ids).to eq(pipeline_gids[2..3])
- end
+ cursor = graphql_data.dig('package', 'pipelines', 'pageInfo', 'startCursor')
+
+ run_query(last: 2, before: cursor)
+
+ pipeline_ids = graphql_data.dig('package', 'pipelines', 'nodes').pluck('id')
- context 'with unauthorized user' do
- let_it_be(:user) { create(:user) }
+ expect(pipeline_ids).to eq(pipeline_gids[2..3])
+ end
+ end
+ context 'package managers paths' do
before do
- project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
+ subject
end
- it 'returns no packages' do
- run_query(first: 2)
+ it 'returns npm_url correctly' do
+ expect(graphql_data_at(:package, :npm_url)).to eq("http://localhost/api/v4/projects/#{project.id}/packages/npm")
+ end
+
+ it 'returns maven_url correctly' do
+ expect(graphql_data_at(:package, :maven_url)).to eq("http://localhost/api/v4/projects/#{project.id}/packages/maven")
+ end
+
+ it 'returns conan_url correctly' do
+ expect(graphql_data_at(:package, :conan_url)).to eq("http://localhost/api/v4/projects/#{project.id}/packages/conan")
+ end
+
+ it 'returns nuget_url correctly' do
+ expect(graphql_data_at(:package, :nuget_url)).to eq("http://localhost/api/v4/projects/#{project.id}/packages/nuget/index.json")
+ end
+
+ it 'returns pypi_url correctly' do
+ expect(graphql_data_at(:package, :pypi_url)).to eq("http://__token__:<your_personal_token>@localhost/api/v4/projects/#{project.id}/packages/pypi/simple")
+ end
+
+ it 'returns pypi_setup_url correctly' do
+ expect(graphql_data_at(:package, :pypi_setup_url)).to eq("http://localhost/api/v4/projects/#{project.id}/packages/pypi")
+ end
+
+ it 'returns composer_url correctly' do
+ expect(graphql_data_at(:package, :composer_url)).to eq("http://localhost/api/v4/group/#{group.id}/-/packages/composer/packages.json")
+ end
- expect(graphql_data_at(:package)).to be_nil
+ it 'returns composer_config_repository_url correctly' do
+ expect(graphql_data_at(:package, :composer_config_repository_url)).to eq("localhost/#{group.id}")
end
end
end
diff --git a/spec/requests/api/graphql/project/issues_spec.rb b/spec/requests/api/graphql/project/issues_spec.rb
index b3e91afb5b3..f358ec3e53f 100644
--- a/spec/requests/api/graphql/project/issues_spec.rb
+++ b/spec/requests/api/graphql/project/issues_spec.rb
@@ -539,6 +539,43 @@ RSpec.describe 'getting an issue list for a project' do
end
end
+ context 'when fetching escalation status' do
+ let_it_be(:escalation_status) { create(:incident_management_issuable_escalation_status, issue: issue_a) }
+
+ let(:statuses) { issue_data.to_h { |issue| [issue['iid'], issue['escalationStatus']] } }
+ let(:fields) do
+ <<~QUERY
+ edges {
+ node {
+ id
+ escalationStatus
+ }
+ }
+ QUERY
+ end
+
+ before do
+ issue_a.update!(issue_type: Issue.issue_types[:incident])
+ end
+
+ it 'returns the escalation status values' do
+ post_graphql(query, current_user: current_user)
+
+ statuses = issues_data.map { |issue| issue.dig('node', 'escalationStatus') }
+
+ expect(statuses).to contain_exactly(escalation_status.status_name.upcase.to_s, nil)
+ end
+
+ it 'avoids N+1 queries', :aggregate_failures do
+ base_count = ActiveRecord::QueryRecorder.new { run_with_clean_state(query, context: { current_user: current_user }) }
+
+ new_incident = create(:incident, project: project)
+ create(:incident_management_issuable_escalation_status, issue: new_incident)
+
+ expect { run_with_clean_state(query, context: { current_user: current_user }) }.not_to exceed_query_limit(base_count)
+ end
+ end
+
describe 'N+1 query checks' do
let(:extra_iid_for_second_query) { issue_b.iid.to_s }
let(:search_params) { { iids: [issue_a.iid.to_s] } }
diff --git a/spec/requests/api/graphql/project/work_item_types_spec.rb b/spec/requests/api/graphql/project/work_item_types_spec.rb
new file mode 100644
index 00000000000..2caaedda2a1
--- /dev/null
+++ b/spec/requests/api/graphql/project/work_item_types_spec.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'getting a list of work item types for a project' do
+ include GraphqlHelpers
+
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:project) { create(:project) }
+
+ before_all do
+ project.add_developer(developer)
+ end
+
+ let(:current_user) { developer }
+
+ let(:fields) do
+ <<~GRAPHQL
+ workItemTypes{
+ nodes { id name iconName }
+ }
+ GRAPHQL
+ end
+
+ let(:query) do
+ graphql_query_for(
+ 'project',
+ { 'fullPath' => project.full_path },
+ fields
+ )
+ end
+
+ context 'when user has access to the project' do
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+
+ it_behaves_like 'a working graphql query'
+
+ it 'returns all default work item types' do
+ expect(graphql_data.dig('project', 'workItemTypes', 'nodes')).to match_array(
+ WorkItems::Type.default.map do |type|
+ hash_including('id' => type.to_global_id.to_s, 'name' => type.name, 'iconName' => type.icon_name)
+ end
+ )
+ end
+ end
+
+ context "when user doesn't have access to the project" do
+ let(:current_user) { create(:user) }
+
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+
+ it 'does not return the project' do
+ expect(graphql_data).to eq('project' => nil)
+ end
+ end
+
+ context 'when the work_items feature flag is disabled' do
+ before do
+ stub_feature_flags(work_items: false)
+ 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'"))
+ end
+ end
+end
diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb
index d226bb07c73..88c004345fc 100644
--- a/spec/requests/api/groups_spec.rb
+++ b/spec/requests/api/groups_spec.rb
@@ -801,6 +801,54 @@ RSpec.describe API::Groups do
expect(json_response['shared_projects'].count).to eq(limit)
end
end
+
+ context 'when a group is shared', :aggregate_failures do
+ let_it_be(:shared_group) { create(:group) }
+ let_it_be(:group2_sub) { create(:group, :private, parent: group2) }
+ let_it_be(:group_link_1) { create(:group_group_link, shared_group: shared_group, shared_with_group: group1) }
+ let_it_be(:group_link_2) { create(:group_group_link, shared_group: shared_group, shared_with_group: group2_sub) }
+
+ subject(:shared_with_groups) { json_response['shared_with_groups'].map { _1['group_id']} }
+
+ context 'when authenticated as admin' do
+ it 'returns all groups that share the group' do
+ get api("/groups/#{shared_group.id}", admin)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(shared_with_groups).to contain_exactly(group_link_1.shared_with_group_id, group_link_2.shared_with_group_id)
+ end
+ end
+
+ context 'when unauthenticated' do
+ it 'returns only public groups that share the group' do
+ get api("/groups/#{shared_group.id}")
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(shared_with_groups).to contain_exactly(group_link_1.shared_with_group_id)
+ end
+ end
+
+ context 'when authenticated as a member of a parent group that has shared the group' do
+ it 'returns private group if direct member' do
+ group2_sub.add_guest(user3)
+
+ get api("/groups/#{shared_group.id}", user3)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(shared_with_groups).to contain_exactly(group_link_1.shared_with_group_id, group_link_2.shared_with_group_id)
+ end
+
+ it 'returns private group if inherited member' do
+ inherited_guest_member = create(:user)
+ group2.add_guest(inherited_guest_member)
+
+ get api("/groups/#{shared_group.id}", inherited_guest_member)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(shared_with_groups).to contain_exactly(group_link_1.shared_with_group_id, group_link_2.shared_with_group_id)
+ end
+ end
+ end
end
describe 'PUT /groups/:id' do
diff --git a/spec/requests/api/integrations_spec.rb b/spec/requests/api/integrations_spec.rb
index 649647804c0..033c80a5696 100644
--- a/spec/requests/api/integrations_spec.rb
+++ b/spec/requests/api/integrations_spec.rb
@@ -55,8 +55,10 @@ RSpec.describe API::Integrations do
current_integration = project.integrations.first
events = current_integration.event_names.empty? ? ["foo"].freeze : current_integration.event_names
query_strings = []
- events.each do |event|
- query_strings << "#{event}=#{!current_integration[event]}"
+ events.map(&:to_sym).each do |event|
+ event_value = !current_integration[event]
+ query_strings << "#{event}=#{event_value}"
+ integration_attrs[event] = event_value if integration_attrs[event].present?
end
query_strings = query_strings.join('&')
diff --git a/spec/requests/api/internal/base_spec.rb b/spec/requests/api/internal/base_spec.rb
index 0a71eb43f81..9aa8aaafc68 100644
--- a/spec/requests/api/internal/base_spec.rb
+++ b/spec/requests/api/internal/base_spec.rb
@@ -372,7 +372,38 @@ RSpec.describe API::Internal::Base do
end
end
- describe "POST /internal/allowed", :clean_gitlab_redis_shared_state do
+ describe "POST /internal/allowed", :clean_gitlab_redis_shared_state, :clean_gitlab_redis_rate_limiting do
+ shared_examples 'rate limited request' do
+ let(:action) { 'git-upload-pack' }
+ let(:actor) { key }
+
+ it 'is throttled by rate limiter' do
+ allow(::Gitlab::ApplicationRateLimiter).to receive(:threshold).and_return(1)
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).with(:gitlab_shell_operation, scope: [action, project.full_path, actor]).twice.and_call_original
+
+ request
+
+ expect(response).to have_gitlab_http_status(:ok)
+
+ request
+
+ expect(response).to have_gitlab_http_status(:too_many_requests)
+ expect(json_response['message']['error']).to eq('This endpoint has been requested too many times. Try again later.')
+ end
+
+ context 'when rate_limit_gitlab_shell feature flag is disabled' do
+ before do
+ stub_feature_flags(rate_limit_gitlab_shell: false)
+ end
+
+ it 'is not throttled by rate limiter' do
+ expect(::Gitlab::ApplicationRateLimiter).not_to receive(:throttled?)
+
+ subject
+ end
+ end
+ end
+
context "access granted" do
let(:env) { {} }
@@ -530,6 +561,32 @@ RSpec.describe API::Internal::Base do
expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-mep-mep' => 'true')
expect(user.reload.last_activity_on).to eql(Date.today)
end
+
+ it_behaves_like 'rate limited request' do
+ def request
+ pull(key, project)
+ end
+ end
+
+ context 'when user_id is passed' do
+ it_behaves_like 'rate limited request' do
+ let(:actor) { user }
+
+ def request
+ post(
+ api("/internal/allowed"),
+ params: {
+ user_id: user.id,
+ project: full_path_for(project),
+ gl_repository: gl_repository_for(project),
+ action: 'git-upload-pack',
+ secret_token: secret_token,
+ protocol: 'ssh'
+ }
+ )
+ end
+ end
+ end
end
context "with a feature flag enabled for a project" do
@@ -576,6 +633,14 @@ RSpec.describe API::Internal::Base do
expect(json_response["gitaly"]["token"]).to eq(Gitlab::GitalyClient.token(project.repository_storage))
expect(user.reload.last_activity_on).to be_nil
end
+
+ it_behaves_like 'rate limited request' do
+ let(:action) { 'git-receive-pack' }
+
+ def request
+ push(key, project)
+ end
+ end
end
context 'when receive_max_input_size has been updated' do
@@ -838,6 +903,14 @@ RSpec.describe API::Internal::Base do
expect(json_response["gitaly"]["address"]).to eq(Gitlab::GitalyClient.address(project.repository_storage))
expect(json_response["gitaly"]["token"]).to eq(Gitlab::GitalyClient.token(project.repository_storage))
end
+
+ it_behaves_like 'rate limited request' do
+ let(:action) { 'git-upload-archive' }
+
+ def request
+ archive(key, project)
+ end
+ end
end
context "not added to project" do
diff --git a/spec/requests/api/internal/kubernetes_spec.rb b/spec/requests/api/internal/kubernetes_spec.rb
index 245e4e6ba15..59d185fe6c8 100644
--- a/spec/requests/api/internal/kubernetes_spec.rb
+++ b/spec/requests/api/internal/kubernetes_spec.rb
@@ -53,7 +53,9 @@ RSpec.describe API::Internal::Kubernetes do
shared_examples 'agent token tracking' do
it 'tracks token usage' do
- expect { response }.to change { agent_token.reload.read_attribute(:last_used_at) }
+ expect do
+ send_request(headers: { 'Authorization' => "Bearer #{agent_token.token}" })
+ end.to change { agent_token.reload.read_attribute(:last_used_at) }
end
end
@@ -149,7 +151,7 @@ RSpec.describe API::Internal::Kubernetes do
let(:agent) { agent_token.agent }
let(:project) { agent.project }
- shared_examples 'agent token tracking'
+ include_examples 'agent token tracking'
it 'returns expected data', :aggregate_failures do
send_request(headers: { 'Authorization' => "Bearer #{agent_token.token}" })
diff --git a/spec/requests/api/internal/mail_room_spec.rb b/spec/requests/api/internal/mail_room_spec.rb
new file mode 100644
index 00000000000..f3ca3708c0c
--- /dev/null
+++ b/spec/requests/api/internal/mail_room_spec.rb
@@ -0,0 +1,194 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Internal::MailRoom do
+ let(:base_configs) do
+ {
+ enabled: true,
+ address: 'address@example.com',
+ port: 143,
+ ssl: false,
+ start_tls: false,
+ mailbox: 'inbox',
+ idle_timeout: 60,
+ log_path: Rails.root.join('log', 'mail_room_json.log').to_s,
+ expunge_deleted: false
+ }
+ end
+
+ let(:enabled_configs) do
+ {
+ incoming_email: base_configs.merge(
+ secure_file: Rails.root.join('tmp', 'tests', '.incoming_email_secret').to_s
+ ),
+ service_desk_email: base_configs.merge(
+ secure_file: Rails.root.join('tmp', 'tests', '.service_desk_email').to_s
+ )
+ }
+ end
+
+ let(:auth_payload) { { 'iss' => Gitlab::MailRoom::Authenticator::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' }
+
+ let(:email_content) { fixture_file("emails/commands_in_reply.eml") }
+
+ before do
+ allow(Gitlab::MailRoom::Authenticator).to receive(:secret).with(:incoming_email).and_return(incoming_email_secret)
+ allow(Gitlab::MailRoom::Authenticator).to receive(:secret).with(:service_desk_email).and_return(service_desk_email_secret)
+ allow(Gitlab::MailRoom).to receive(:enabled_configs).and_return(enabled_configs)
+ end
+
+ around do |example|
+ freeze_time do
+ example.run
+ end
+ end
+
+ describe "POST /internal/mail_room/*mailbox_type" 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 }
+ end
+
+ it 'schedules a EmailReceiverWorker job with raw email content' do
+ Sidekiq::Testing.fake! do
+ expect do
+ post api("/internal/mail_room/incoming_email"), headers: auth_headers, params: email_content
+ end.to change { EmailReceiverWorker.jobs.size }.by(1)
+ end
+
+ expect(response).to have_gitlab_http_status(:ok)
+
+ job = EmailReceiverWorker.jobs.last
+ expect(job).to match a_hash_including('args' => [email_content])
+ end
+ end
+
+ 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 }
+ end
+
+ it 'schedules a ServiceDeskEmailReceiverWorker job with raw email content' do
+ Sidekiq::Testing.fake! do
+ expect do
+ post api("/internal/mail_room/service_desk_email"), headers: auth_headers, params: email_content
+ end.to change { ServiceDeskEmailReceiverWorker.jobs.size }.by(1)
+ end
+
+ expect(response).to have_gitlab_http_status(:ok)
+
+ job = ServiceDeskEmailReceiverWorker.jobs.last
+ expect(job).to match a_hash_including('args' => [email_content])
+ end
+ end
+
+ 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 }
+ end
+
+ before do
+ allow(EmailReceiverWorker).to receive(:perform_async).and_raise(
+ Gitlab::SidekiqMiddleware::SizeLimiter::ExceedLimitError.new(EmailReceiverWorker, email_content.bytesize, email_content.bytesize - 1)
+ )
+ end
+
+ it 'responds with 400 bad request and replies with a failure message' do
+ perform_enqueued_jobs do
+ Sidekiq::Testing.fake! do
+ expect do
+ post api("/internal/mail_room/incoming_email"), headers: auth_headers, params: email_content
+ end.not_to change { EmailReceiverWorker.jobs.size }
+ end
+ end
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(Gitlab::Json.parse(response.body)).to match a_hash_including(
+ "success" => false,
+ "message" => "We couldn't process your email because it is too large. Please create your issue or comment through the web interface."
+ )
+
+ email = ActionMailer::Base.deliveries.last
+ expect(email).not_to be_nil
+ expect(email.to).to match_array(["jake@adventuretime.ooo"])
+ expect(email.subject).to include("Rejected")
+ expect(email.body.parts.last.to_s).to include("We couldn't process your email")
+ end
+ end
+
+ context 'not authenticated' do
+ it 'responds with 401 Unauthorized' do
+ post api("/internal/mail_room/incoming_email")
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
+
+ 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 }
+ end
+
+ it 'responds with 401 Unauthorized' do
+ post api("/internal/mail_room/incoming_email"), headers: auth_headers
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
+
+ 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 }
+ end
+
+ it 'responds with 401 Unauthorized' do
+ post api("/internal/mail_room/incoming_email"), headers: auth_headers
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
+
+ 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 }
+ end
+
+ it 'responds with 401 Unauthorized' do
+ post api("/internal/mail_room/invalid_mailbox_type"), headers: auth_headers
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
+
+ context 'not enabled mailbox type' do
+ let(:enabled_configs) do
+ {
+ incoming_email: base_configs.merge(
+ secure_file: Rails.root.join('tmp', 'tests', '.incoming_email_secret').to_s
+ )
+ }
+ end
+
+ let(:auth_headers) do
+ jwt_token = JWT.encode(auth_payload, service_desk_email_secret, 'HS256')
+ { Gitlab::MailRoom::Authenticator::INTERNAL_API_REQUEST_HEADER => jwt_token }
+ end
+
+ it 'responds with 401 Unauthorized' do
+ post api("/internal/mail_room/service_desk_email"), headers: auth_headers
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/lint_spec.rb b/spec/requests/api/lint_spec.rb
index 0e83b964121..7c1e731a99a 100644
--- a/spec/requests/api/lint_spec.rb
+++ b/spec/requests/api/lint_spec.rb
@@ -121,8 +121,8 @@ RSpec.describe API::Lint do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an Hash
expect(json_response['status']).to eq('valid')
- expect(json_response['warnings']).to eq([])
- expect(json_response['errors']).to eq([])
+ expect(json_response['warnings']).to match_array([])
+ expect(json_response['errors']).to match_array([])
end
it 'outputs expanded yaml content' do
@@ -149,7 +149,20 @@ RSpec.describe API::Lint do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['status']).to eq('valid')
expect(json_response['warnings']).not_to be_empty
- expect(json_response['errors']).to eq([])
+ expect(json_response['errors']).to match_array([])
+ end
+ end
+
+ context 'with valid .gitlab-ci.yaml using deprecated keywords' do
+ let(:yaml_content) { { job: { script: 'ls' }, types: ['test'] }.to_yaml }
+
+ it 'passes validation but returns warnings' do
+ post api('/ci/lint', api_user), params: { content: yaml_content }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['status']).to eq('valid')
+ expect(json_response['warnings']).not_to be_empty
+ expect(json_response['errors']).to match_array([])
end
end
diff --git a/spec/requests/api/maven_packages_spec.rb b/spec/requests/api/maven_packages_spec.rb
index 5a682ee8532..bc325aad823 100644
--- a/spec/requests/api/maven_packages_spec.rb
+++ b/spec/requests/api/maven_packages_spec.rb
@@ -425,7 +425,7 @@ RSpec.describe API::MavenPackages do
context 'internal project' do
before do
- group.group_member(user).destroy!
+ group.member(user).destroy!
project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
end
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 7c147419354..a751f785913 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -1269,6 +1269,7 @@ RSpec.describe API::MergeRequests do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user)
expect(json_response).to include('merged_by',
+ 'merge_user',
'merged_at',
'closed_by',
'closed_at',
@@ -1279,9 +1280,10 @@ RSpec.describe API::MergeRequests do
end
it 'returns correct values' do
- get api("/projects/#{project.id}/merge_requests/#{merge_request.reload.iid}", user)
+ get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user)
expect(json_response['merged_by']['id']).to eq(merge_request.metrics.merged_by_id)
+ expect(json_response['merge_user']['id']).to eq(merge_request.metrics.merged_by_id)
expect(Time.parse(json_response['merged_at'])).to be_like_time(merge_request.metrics.merged_at)
expect(json_response['closed_by']['id']).to eq(merge_request.metrics.latest_closed_by_id)
expect(Time.parse(json_response['closed_at'])).to be_like_time(merge_request.metrics.latest_closed_at)
@@ -1292,6 +1294,32 @@ RSpec.describe API::MergeRequests do
end
end
+ context 'merge_user' do
+ context 'when MR is set to MWPS' do
+ let(:merge_request) { create(:merge_request, :merge_when_pipeline_succeeds, source_project: project, target_project: project) }
+
+ it 'returns user who set MWPS' do
+ get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['merge_user']['id']).to eq(user.id)
+ end
+
+ context 'when MR is already merged' do
+ before do
+ merge_request.metrics.update!(merged_by: user2)
+ end
+
+ it 'returns user who actually merged' do
+ get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['merge_user']['id']).to eq(user2.id)
+ end
+ end
+ end
+ end
+
context 'head_pipeline' do
let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request, :simple, author: user, source_project: project, source_branch: 'markdown', title: "Test") }
@@ -3278,9 +3306,10 @@ RSpec.describe API::MergeRequests do
context 'when skip_ci parameter is set' do
it 'enqueues a rebase of the merge request with skip_ci flag set' do
- allow(RebaseWorker).to receive(:with_status).and_return(RebaseWorker)
+ with_status = RebaseWorker.with_status
- expect(RebaseWorker).to receive(:perform_async).with(merge_request.id, user.id, true).and_call_original
+ expect(RebaseWorker).to receive(:with_status).and_return(with_status)
+ expect(with_status).to receive(:perform_async).with(merge_request.id, user.id, true).and_call_original
Sidekiq::Testing.fake! do
expect do
diff --git a/spec/requests/api/package_files_spec.rb b/spec/requests/api/package_files_spec.rb
index eb1f04d193e..7a6b1599154 100644
--- a/spec/requests/api/package_files_spec.rb
+++ b/spec/requests/api/package_files_spec.rb
@@ -76,6 +76,30 @@ RSpec.describe API::PackageFiles do
end
end
end
+
+ context 'with package files pending destruction' do
+ let!(:package_file_pending_destruction) { create(:package_file, :pending_destruction, package: package) }
+
+ let(:package_file_ids) { json_response.map { |e| e['id'] } }
+
+ it 'does not return them' do
+ get api(url, user)
+
+ expect(package_file_ids).not_to include(package_file_pending_destruction.id)
+ end
+
+ context 'with packages_installable_package_files disabled' do
+ before do
+ stub_feature_flags(packages_installable_package_files: false)
+ end
+
+ it 'returns them' do
+ get api(url, user)
+
+ expect(package_file_ids).to include(package_file_pending_destruction.id)
+ end
+ end
+ end
end
end
@@ -149,6 +173,32 @@ RSpec.describe API::PackageFiles do
expect(response).to have_gitlab_http_status(:not_found)
end
end
+
+ context 'with package file pending destruction' do
+ let!(:package_file_id) { create(:package_file, :pending_destruction, package: package).id }
+
+ before do
+ project.add_maintainer(user)
+ end
+
+ it 'can not be accessed', :aggregate_failures do
+ expect { api_request }.not_to change { package.package_files.count }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
+ context 'with packages_installable_package_files disabled' do
+ before do
+ stub_feature_flags(packages_installable_package_files: false)
+ end
+
+ it 'can be accessed', :aggregate_failures do
+ expect { api_request }.to change { package.package_files.count }.by(-1)
+
+ expect(response).to have_gitlab_http_status(:no_content)
+ end
+ end
+ end
end
end
end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 8406ded85d8..bf41a808219 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -3704,6 +3704,46 @@ RSpec.describe API::Projects do
expect { subject }.to change { project.reload.keep_latest_artifact }.to(true)
end
end
+
+ context 'attribute mr_default_target_self' do
+ let_it_be(:source_project) { create(:project, :public) }
+
+ let(:forked_project) { fork_project(source_project, user) }
+
+ it 'is by default set to false' do
+ expect(source_project.mr_default_target_self).to be false
+ expect(forked_project.mr_default_target_self).to be false
+ end
+
+ describe 'for a non-forked project' do
+ before_all do
+ source_project.add_maintainer(user)
+ end
+
+ it 'is not exposed' do
+ get api("/projects/#{source_project.id}", user)
+
+ expect(json_response).not_to include('mr_default_target_self')
+ end
+
+ it 'is not possible to update' do
+ put api("/projects/#{source_project.id}", user), params: { mr_default_target_self: true }
+
+ source_project.reload
+ expect(source_project.mr_default_target_self).to be false
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+ end
+
+ describe 'for a forked project' do
+ it 'updates to true' do
+ put api("/projects/#{forked_project.id}", user), params: { mr_default_target_self: true }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['mr_default_target_self']).to eq(true)
+ end
+ end
+ end
end
describe 'POST /projects/:id/archive' do
@@ -4213,7 +4253,13 @@ RSpec.describe API::Projects do
end
it 'accepts custom parameters for the target project' do
- post api("/projects/#{project.id}/fork", user2), params: { name: 'My Random Project', description: 'A description', visibility: 'private' }
+ post api("/projects/#{project.id}/fork", user2),
+ params: {
+ name: 'My Random Project',
+ description: 'A description',
+ visibility: 'private',
+ mr_default_target_self: true
+ }
expect(response).to have_gitlab_http_status(:created)
expect(json_response['name']).to eq('My Random Project')
@@ -4224,6 +4270,7 @@ RSpec.describe API::Projects do
expect(json_response['description']).to eq('A description')
expect(json_response['visibility']).to eq('private')
expect(json_response['import_status']).to eq('scheduled')
+ expect(json_response['mr_default_target_self']).to eq(true)
expect(json_response).to include("import_error")
end
diff --git a/spec/requests/api/resource_access_tokens_spec.rb b/spec/requests/api/resource_access_tokens_spec.rb
index 23061ab4bf0..7e3e682767f 100644
--- a/spec/requests/api/resource_access_tokens_spec.rb
+++ b/spec/requests/api/resource_access_tokens_spec.rb
@@ -3,25 +3,27 @@
require "spec_helper"
RSpec.describe API::ResourceAccessTokens do
- context "when the resource is a project" do
- let_it_be(:project) { create(:project) }
- let_it_be(:other_project) { create(:project) }
- let_it_be(:user) { create(:user) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:user_non_priviledged) { create(:user) }
- describe "GET projects/:id/access_tokens" do
- subject(:get_tokens) { get api("/projects/#{project_id}/access_tokens", user) }
+ shared_examples 'resource access token API' do |source_type|
+ context "GET #{source_type}s/:id/access_tokens" do
+ subject(:get_tokens) { get api("/#{source_type}s/#{resource_id}/access_tokens", user) }
- context "when the user has maintainer permissions" do
+ context "when the user has valid permissions" do
let_it_be(:project_bot) { create(:user, :project_bot) }
let_it_be(:access_tokens) { create_list(:personal_access_token, 3, user: project_bot) }
- let_it_be(:project_id) { project.id }
+ let_it_be(:resource_id) { resource.id }
before do
- project.add_maintainer(user)
- project.add_maintainer(project_bot)
+ if source_type == 'project'
+ resource.add_maintainer(project_bot)
+ else
+ resource.add_owner(project_bot)
+ end
end
- it "gets a list of access tokens for the specified project" do
+ it "gets a list of access tokens for the specified #{source_type}" do
get_tokens
token_ids = json_response.map { |token| token['id'] }
@@ -38,16 +40,22 @@ RSpec.describe API::ResourceAccessTokens do
expect(api_get_token["name"]).to eq(token.name)
expect(api_get_token["scopes"]).to eq(token.scopes)
- expect(api_get_token["access_level"]).to eq(project.team.max_member_access(token.user.id))
+
+ if source_type == 'project'
+ expect(api_get_token["access_level"]).to eq(resource.team.max_member_access(token.user.id))
+ else
+ expect(api_get_token["access_level"]).to eq(resource.max_member_access_for_user(token.user))
+ end
+
expect(api_get_token["expires_at"]).to eq(token.expires_at.to_date.iso8601)
expect(api_get_token).not_to have_key('token')
end
- context "when using a project access token to GET other project access tokens" do
+ context "when using a #{source_type} access token to GET other #{source_type} access tokens" do
let_it_be(:token) { access_tokens.first }
- it "gets a list of access tokens for the specified project" do
- get api("/projects/#{project_id}/access_tokens", personal_access_token: token)
+ it "gets a list of access tokens for the specified #{source_type}" do
+ get api("/#{source_type}s/#{resource_id}/access_tokens", personal_access_token: token)
token_ids = json_response.map { |token| token['id'] }
@@ -56,16 +64,15 @@ RSpec.describe API::ResourceAccessTokens do
end
end
- context "when tokens belong to a different project" do
+ context "when tokens belong to a different #{source_type}" do
let_it_be(:bot) { create(:user, :project_bot) }
let_it_be(:token) { create(:personal_access_token, user: bot) }
before do
- other_project.add_maintainer(bot)
- other_project.add_maintainer(user)
+ other_resource.add_maintainer(bot)
end
- it "does not return tokens from a different project" do
+ it "does not return tokens from a different #{source_type}" do
get_tokens
token_ids = json_response.map { |token| token['id'] }
@@ -74,12 +81,8 @@ RSpec.describe API::ResourceAccessTokens do
end
end
- context "when the project has no access tokens" do
- let(:project_id) { other_project.id }
-
- before do
- other_project.add_maintainer(user)
- end
+ context "when the #{source_type} has no access tokens" do
+ let(:resource_id) { other_resource.id }
it 'returns an empty array' do
get_tokens
@@ -89,8 +92,8 @@ RSpec.describe API::ResourceAccessTokens do
end
end
- context "when trying to get the tokens of a different project" do
- let_it_be(:project_id) { other_project.id }
+ context "when trying to get the tokens of a different #{source_type}" do
+ let_it_be(:resource_id) { unknown_resource.id }
it "returns 404" do
get_tokens
@@ -99,8 +102,8 @@ RSpec.describe API::ResourceAccessTokens do
end
end
- context "when the project does not exist" do
- let(:project_id) { non_existing_record_id }
+ context "when the #{source_type} does not exist" do
+ let(:resource_id) { non_existing_record_id }
it "returns 404" do
get_tokens
@@ -111,13 +114,13 @@ RSpec.describe API::ResourceAccessTokens do
end
context "when the user does not have valid permissions" do
+ let_it_be(:user) { user_non_priviledged }
let_it_be(:project_bot) { create(:user, :project_bot) }
let_it_be(:access_tokens) { create_list(:personal_access_token, 3, user: project_bot) }
- let_it_be(:project_id) { project.id }
+ let_it_be(:resource_id) { resource.id }
before do
- project.add_developer(user)
- project.add_maintainer(project_bot)
+ resource.add_maintainer(project_bot)
end
it "returns 401" do
@@ -128,40 +131,36 @@ RSpec.describe API::ResourceAccessTokens do
end
end
- describe "DELETE projects/:id/access_tokens/:token_id", :sidekiq_inline do
- subject(:delete_token) { delete api("/projects/#{project_id}/access_tokens/#{token_id}", user) }
+ context "DELETE #{source_type}s/:id/access_tokens/:token_id", :sidekiq_inline do
+ subject(:delete_token) { delete api("/#{source_type}s/#{resource_id}/access_tokens/#{token_id}", user) }
let_it_be(:project_bot) { create(:user, :project_bot) }
let_it_be(:token) { create(:personal_access_token, user: project_bot) }
- let_it_be(:project_id) { project.id }
+ let_it_be(:resource_id) { resource.id }
let_it_be(:token_id) { token.id }
before do
- project.add_maintainer(project_bot)
+ resource.add_maintainer(project_bot)
end
- context "when the user has maintainer permissions" do
- before do
- project.add_maintainer(user)
- end
-
- it "deletes the project access token from the project" do
+ context "when the user has valid permissions" do
+ it "deletes the #{source_type} access token from the #{source_type}" do
delete_token
expect(response).to have_gitlab_http_status(:no_content)
expect(User.exists?(project_bot.id)).to be_falsy
end
- context "when using project access token to DELETE other project access token" do
+ context "when using #{source_type} access token to DELETE other #{source_type} access token" do
let_it_be(:other_project_bot) { create(:user, :project_bot) }
let_it_be(:other_token) { create(:personal_access_token, user: other_project_bot) }
let_it_be(:token_id) { other_token.id }
before do
- project.add_maintainer(other_project_bot)
+ resource.add_maintainer(other_project_bot)
end
- it "deletes the project access token from the project" do
+ it "deletes the #{source_type} access token from the #{source_type}" do
delete_token
expect(response).to have_gitlab_http_status(:no_content)
@@ -169,37 +168,31 @@ RSpec.describe API::ResourceAccessTokens do
end
end
- context "when attempting to delete a non-existent project access token" do
+ context "when attempting to delete a non-existent #{source_type} access token" do
let_it_be(:token_id) { non_existing_record_id }
it "does not delete the token, and returns 404" do
delete_token
expect(response).to have_gitlab_http_status(:not_found)
- expect(response.body).to include("Could not find project access token with token_id: #{token_id}")
+ expect(response.body).to include("Could not find #{source_type} access token with token_id: #{token_id}")
end
end
- context "when attempting to delete a token that does not belong to the specified project" do
- let_it_be(:project_id) { other_project.id }
-
- before do
- other_project.add_maintainer(user)
- end
+ context "when attempting to delete a token that does not belong to the specified #{source_type}" do
+ let_it_be(:resource_id) { other_resource.id }
it "does not delete the token, and returns 404" do
delete_token
expect(response).to have_gitlab_http_status(:not_found)
- expect(response.body).to include("Could not find project access token with token_id: #{token_id}")
+ expect(response.body).to include("Could not find #{source_type} access token with token_id: #{token_id}")
end
end
end
context "when the user does not have valid permissions" do
- before do
- project.add_developer(user)
- end
+ let_it_be(:user) { user_non_priviledged }
it "does not delete the token, and returns 400", :aggregate_failures do
delete_token
@@ -211,23 +204,19 @@ RSpec.describe API::ResourceAccessTokens do
end
end
- describe "POST projects/:id/access_tokens" do
+ context "POST #{source_type}s/:id/access_tokens" do
let(:params) { { name: "test", scopes: ["api"], expires_at: expires_at, access_level: access_level } }
let(:expires_at) { 1.month.from_now }
let(:access_level) { 20 }
- subject(:create_token) { post api("/projects/#{project_id}/access_tokens", user), params: params }
+ subject(:create_token) { post api("/#{source_type}s/#{resource_id}/access_tokens", user), params: params }
- context "when the user has maintainer permissions" do
- let_it_be(:project_id) { project.id }
-
- before do
- project.add_maintainer(user)
- end
+ context "when the user has valid permissions" do
+ let_it_be(:resource_id) { resource.id }
context "with valid params" do
context "with full params" do
- it "creates a project access token with the params", :aggregate_failures do
+ it "creates a #{source_type} access token with the params", :aggregate_failures do
create_token
expect(response).to have_gitlab_http_status(:created)
@@ -242,7 +231,7 @@ RSpec.describe API::ResourceAccessTokens do
context "when 'expires_at' is not set" do
let(:expires_at) { nil }
- it "creates a project access token with the params", :aggregate_failures do
+ it "creates a #{source_type} access token with the params", :aggregate_failures do
create_token
expect(response).to have_gitlab_http_status(:created)
@@ -255,7 +244,7 @@ RSpec.describe API::ResourceAccessTokens do
context "when 'access_level' is not set" do
let(:access_level) { nil }
- it 'creates a project access token with the default access level', :aggregate_failures do
+ it "creates a #{source_type} access token with the default access level", :aggregate_failures do
create_token
expect(response).to have_gitlab_http_status(:created)
@@ -272,7 +261,7 @@ RSpec.describe API::ResourceAccessTokens do
context "when missing the 'name' param" do
let_it_be(:params) { { scopes: ["api"], expires_at: 5.days.from_now } }
- it "does not create a project access token without 'name'" do
+ it "does not create a #{source_type} access token without 'name'" do
create_token
expect(response).to have_gitlab_http_status(:bad_request)
@@ -283,7 +272,7 @@ RSpec.describe API::ResourceAccessTokens do
context "when missing the 'scopes' param" do
let_it_be(:params) { { name: "test", expires_at: 5.days.from_now } }
- it "does not create a project access token without 'scopes'" do
+ it "does not create a #{source_type} access token without 'scopes'" do
create_token
expect(response).to have_gitlab_http_status(:bad_request)
@@ -292,50 +281,80 @@ RSpec.describe API::ResourceAccessTokens do
end
end
- context "when trying to create a token in a different project" do
- let_it_be(:project_id) { other_project.id }
+ context "when trying to create a token in a different #{source_type}" do
+ let_it_be(:resource_id) { unknown_resource.id }
- it "does not create the token, and returns the project not found error" do
+ it "does not create the token, and returns the #{source_type} not found error" do
create_token
expect(response).to have_gitlab_http_status(:not_found)
- expect(response.body).to include("Project Not Found")
+ expect(response.body).to include("#{source_type.capitalize} Not Found")
end
end
end
context "when the user does not have valid permissions" do
- let_it_be(:project_id) { project.id }
+ let_it_be(:resource_id) { resource.id }
- context "when the user is a developer" do
- before do
- project.add_developer(user)
- end
+ context "when the user role is too low" do
+ let_it_be(:user) { user_non_priviledged }
it "does not create the token, and returns the permission error" do
create_token
expect(response).to have_gitlab_http_status(:bad_request)
- expect(response.body).to include("User does not have permission to create project access token")
+ expect(response.body).to include("User does not have permission to create #{source_type} access token")
end
end
- context "when a project access token tries to create another project access token" do
+ context "when a #{source_type} access token tries to create another #{source_type} access token" do
let_it_be(:project_bot) { create(:user, :project_bot) }
let_it_be(:user) { project_bot }
before do
- project.add_maintainer(user)
+ if source_type == 'project'
+ resource.add_maintainer(project_bot)
+ else
+ resource.add_owner(project_bot)
+ end
end
- it "does not allow a project access token to create another project access token" do
+ it "does not allow a #{source_type} access token to create another #{source_type} access token" do
create_token
expect(response).to have_gitlab_http_status(:bad_request)
- expect(response.body).to include("User does not have permission to create project access token")
+ expect(response.body).to include("User does not have permission to create #{source_type} access token")
end
end
end
end
end
+
+ context 'when the resource is a project' do
+ let_it_be(:resource) { create(:project) }
+ let_it_be(:other_resource) { create(:project) }
+ let_it_be(:unknown_resource) { create(:project) }
+
+ before_all do
+ resource.add_maintainer(user)
+ other_resource.add_maintainer(user)
+ resource.add_developer(user_non_priviledged)
+ end
+
+ it_behaves_like 'resource access token API', 'project'
+ end
+
+ context 'when the resource is a group' do
+ let_it_be(:resource) { create(:group) }
+ let_it_be(:other_resource) { create(:group) }
+ let_it_be(:unknown_resource) { create(:project) }
+
+ before_all do
+ resource.add_owner(user)
+ other_resource.add_owner(user)
+ resource.add_maintainer(user_non_priviledged)
+ end
+
+ it_behaves_like 'resource access token API', 'group'
+ end
end
diff --git a/spec/requests/api/rubygem_packages_spec.rb b/spec/requests/api/rubygem_packages_spec.rb
index 9b104520b52..0e63a7269e7 100644
--- a/spec/requests/api/rubygem_packages_spec.rb
+++ b/spec/requests/api/rubygem_packages_spec.rb
@@ -173,6 +173,34 @@ RSpec.describe API::RubygemPackages do
it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member]
end
end
+
+ context 'with package files pending destruction' do
+ let_it_be(:package_file_pending_destruction) { create(:package_file, :pending_destruction, :xml, package: package, file_name: file_name) }
+
+ before do
+ project.update_column(:visibility_level, Gitlab::VisibilityLevel::PUBLIC)
+ end
+
+ it 'does not return them' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.body).not_to eq(package_file_pending_destruction.file.file.read)
+ end
+
+ context 'with packages_installable_package_files disabled' do
+ before do
+ stub_feature_flags(packages_installable_package_files: false)
+ end
+
+ it 'returns them' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.body).to eq(package_file_pending_destruction.file.file.read)
+ end
+ end
+ end
end
describe 'POST /api/v4/projects/:project_id/packages/rubygems/api/v1/gems/authorize' do
diff --git a/spec/requests/api/search_spec.rb b/spec/requests/api/search_spec.rb
index b75fe11b06d..24cd95781c3 100644
--- a/spec/requests/api/search_spec.rb
+++ b/spec/requests/api/search_spec.rb
@@ -346,6 +346,14 @@ RSpec.describe API::Search do
end
end
end
+
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :user_email_lookup do
+ let(:current_user) { user }
+
+ def request
+ get api(endpoint, current_user), params: { scope: 'users', search: 'foo@bar.com' }
+ end
+ end
end
describe "GET /groups/:id/search" do
@@ -513,6 +521,14 @@ 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
+ let(:current_user) { user }
+
+ def request
+ get api(endpoint, current_user), params: { scope: 'users', search: 'foo@bar.com' }
+ end
+ end
end
end
@@ -786,6 +802,14 @@ RSpec.describe API::Search do
end
end
end
+
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :user_email_lookup do
+ let(:current_user) { user }
+
+ def request
+ get api(endpoint, current_user), params: { scope: 'users', search: 'foo@bar.com' }
+ end
+ end
end
end
end
diff --git a/spec/requests/api/terraform/modules/v1/packages_spec.rb b/spec/requests/api/terraform/modules/v1/packages_spec.rb
index b17bc11a451..c0f04ba09be 100644
--- a/spec/requests/api/terraform/modules/v1/packages_spec.rb
+++ b/spec/requests/api/terraform/modules/v1/packages_spec.rb
@@ -154,6 +154,7 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
end
describe 'GET /api/v4/packages/terraform/modules/v1/:module_namespace/:module_name/:module_system/:module_version/file' do
+ let(:url) { api("/packages/terraform/modules/v1/#{group.path}/#{package.name}/#{package.version}/file?token=#{token}") }
let(:tokens) do
{
personal_access_token: ::Gitlab::JWTToken.new.tap { |jwt| jwt['token'] = personal_access_token.id }.encoded,
@@ -202,7 +203,6 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
with_them do
let(:token) { valid_token ? tokens[token_type] : 'invalid-token123' }
- let(:url) { api("/packages/terraform/modules/v1/#{group.path}/#{package.name}/#{package.version}/file?token=#{token}") }
let(:snowplow_gitlab_standard_context) { { project: project, user: user, namespace: project.namespace } }
before do
@@ -212,6 +212,41 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member]
end
end
+
+ context 'with package file pending destruction' do
+ let_it_be(:package) { create(:package, package_type: :terraform_module, project: project, name: "module-555/pending-destruction", version: '1.0.0') }
+ let_it_be(:package_file_pending_destruction) { create(:package_file, :pending_destruction, :xml, package: package) }
+ let_it_be(:package_file) { create(:package_file, :terraform_module, package: package) }
+
+ let(:token) { tokens[:personal_access_token] }
+ let(:headers) { { 'Authorization' => "Bearer #{token}" } }
+
+ before do
+ project.add_maintainer(user)
+ end
+
+ it 'does not return them' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.body).not_to eq(package_file_pending_destruction.file.file.read)
+ expect(response.body).to eq(package_file.file.file.read)
+ end
+
+ context 'with packages_installable_package_files disabled' do
+ before do
+ stub_feature_flags(packages_installable_package_files: false)
+ end
+
+ it 'returns them' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.body).to eq(package_file_pending_destruction.file.file.read)
+ expect(response.body).not_to eq(package_file.file.file.read)
+ end
+ end
+ end
end
describe 'PUT /api/v4/projects/:project_id/packages/terraform/modules/:module_name/:module_system/:module_version/file/authorize' do
diff --git a/spec/requests/api/usage_data_non_sql_metrics_spec.rb b/spec/requests/api/usage_data_non_sql_metrics_spec.rb
index 225af57a267..0b73d0f96a4 100644
--- a/spec/requests/api/usage_data_non_sql_metrics_spec.rb
+++ b/spec/requests/api/usage_data_non_sql_metrics_spec.rb
@@ -18,6 +18,7 @@ RSpec.describe API::UsageDataNonSqlMetrics do
context 'with authentication' do
before do
stub_feature_flags(usage_data_non_sql_metrics: true)
+ stub_database_flavor_check
end
it 'returns non sql metrics if user is admin' do
diff --git a/spec/requests/api/usage_data_queries_spec.rb b/spec/requests/api/usage_data_queries_spec.rb
index 0ba4a37bc9b..69a8d865a59 100644
--- a/spec/requests/api/usage_data_queries_spec.rb
+++ b/spec/requests/api/usage_data_queries_spec.rb
@@ -10,6 +10,7 @@ RSpec.describe API::UsageDataQueries do
before do
stub_usage_data_connections
+ stub_database_flavor_check
end
describe 'GET /usage_data/usage_data_queries' do
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index b93df2f3bae..98875d7e8d2 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -498,6 +498,10 @@ RSpec.describe API::Users do
describe "GET /users/:id" do
let_it_be(:user2, reload: true) { create(:user, username: 'another_user') }
+ before do
+ allow(Gitlab::ApplicationRateLimiter).to receive(:throttled?).with(:users_get_by_id, scope: user).and_return(false)
+ end
+
it "returns a user by id" do
get api("/users/#{user.id}", user)
@@ -593,6 +597,55 @@ RSpec.describe API::Users do
expect(json_response).not_to have_key('sign_in_count')
end
+ context 'when the rate limit is not exceeded' do
+ it 'returns a success status' do
+ expect(Gitlab::ApplicationRateLimiter)
+ .to receive(:throttled?).with(:users_get_by_id, scope: user)
+ .and_return(false)
+
+ get api("/users/#{user.id}", user)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'when the rate limit is exceeded' do
+ context 'when feature flag is enabled' do
+ it 'returns "too many requests" status' do
+ expect(Gitlab::ApplicationRateLimiter)
+ .to receive(:throttled?).with(:users_get_by_id, scope: user)
+ .and_return(true)
+
+ get api("/users/#{user.id}", user)
+
+ expect(response).to have_gitlab_http_status(:too_many_requests)
+ end
+
+ it 'still allows admin users' do
+ expect(Gitlab::ApplicationRateLimiter)
+ .not_to receive(:throttled?)
+
+ get api("/users/#{user.id}", admin)
+
+ 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
let(:job_title) { 'Fullstack Engineer' }
@@ -974,7 +1027,7 @@ RSpec.describe API::Users do
post api('/users', admin),
params: {
email: 'invalid email',
- password: 'password',
+ password: Gitlab::Password.test_default,
name: 'test'
}
expect(response).to have_gitlab_http_status(:bad_request)
@@ -1040,7 +1093,7 @@ RSpec.describe API::Users do
post api('/users', admin),
params: {
email: 'test@example.com',
- password: 'password',
+ password: Gitlab::Password.test_default,
username: 'test',
name: 'foo'
}
@@ -1052,7 +1105,7 @@ RSpec.describe API::Users do
params: {
name: 'foo',
email: 'test@example.com',
- password: 'password',
+ password: Gitlab::Password.test_default,
username: 'foo'
}
end.to change { User.count }.by(0)
@@ -1066,7 +1119,7 @@ RSpec.describe API::Users do
params: {
name: 'foo',
email: 'foo@example.com',
- password: 'password',
+ password: Gitlab::Password.test_default,
username: 'test'
}
end.to change { User.count }.by(0)
@@ -1080,7 +1133,7 @@ RSpec.describe API::Users do
params: {
name: 'foo',
email: 'foo@example.com',
- password: 'password',
+ password: Gitlab::Password.test_default,
username: 'TEST'
}
end.to change { User.count }.by(0)
@@ -1425,8 +1478,8 @@ RSpec.describe API::Users do
context "with existing user" do
before do
- post api("/users", admin), params: { email: 'test@example.com', password: 'password', username: 'test', name: 'test' }
- post api("/users", admin), params: { email: 'foo@bar.com', password: 'password', username: 'john', name: 'john' }
+ post api("/users", admin), params: { email: 'test@example.com', password: Gitlab::Password.test_default, username: 'test', name: 'test' }
+ post api("/users", admin), params: { email: 'foo@bar.com', password: Gitlab::Password.test_default, username: 'john', name: 'john' }
@user = User.all.last
end
diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb
index d2528600477..623cf24b9cb 100644
--- a/spec/requests/git_http_spec.rb
+++ b/spec/requests/git_http_spec.rb
@@ -319,7 +319,7 @@ RSpec.describe 'Git HTTP requests' do
context 'when user is using credentials with special characters' do
context 'with password with special characters' do
before do
- user.update!(password: 'RKszEwéC5kFnû∆f243fycGu§Gh9ftDj!U')
+ user.update!(password: Gitlab::Password.test_default)
end
it 'allows clones' do
@@ -1670,7 +1670,7 @@ RSpec.describe 'Git HTTP requests' do
context 'when user is using credentials with special characters' do
context 'with password with special characters' do
before do
- user.update!(password: 'RKszEwéC5kFnû∆f243fycGu§Gh9ftDj!U')
+ user.update!(password: Gitlab::Password.test_default)
end
it 'allows clones' do
diff --git a/spec/requests/groups/crm/contacts_controller_spec.rb b/spec/requests/groups/crm/contacts_controller_spec.rb
index a4b2a28e77a..5d126c6ead5 100644
--- a/spec/requests/groups/crm/contacts_controller_spec.rb
+++ b/spec/requests/groups/crm/contacts_controller_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe Groups::Crm::ContactsController do
shared_examples 'ok response with index template if authorized' do
context 'private group' do
- let(:group) { create(:group, :private) }
+ let(:group) { create(:group, :private, :crm_enabled) }
context 'with authorized user' do
before do
@@ -32,11 +32,17 @@ RSpec.describe Groups::Crm::ContactsController do
sign_in(user)
end
- context 'when feature flag is enabled' do
+ context 'when crm_enabled is true' do
it_behaves_like 'ok response with index template'
end
- context 'when feature flag is not enabled' do
+ context 'when crm_enabled is false' do
+ let(:group) { create(:group, :private) }
+
+ it_behaves_like 'response with 404 status'
+ end
+
+ context 'when feature flag is disabled' do
before do
stub_feature_flags(customer_relations: false)
end
@@ -64,10 +70,10 @@ RSpec.describe Groups::Crm::ContactsController do
end
context 'public group' do
- let(:group) { create(:group, :public) }
+ let(:group) { create(:group, :public, :crm_enabled) }
context 'with anonymous user' do
- it_behaves_like 'ok response with index template'
+ it_behaves_like 'response with 404 status'
end
end
end
diff --git a/spec/requests/groups/crm/organizations_controller_spec.rb b/spec/requests/groups/crm/organizations_controller_spec.rb
index 7595950350d..f38300c3c5b 100644
--- a/spec/requests/groups/crm/organizations_controller_spec.rb
+++ b/spec/requests/groups/crm/organizations_controller_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe Groups::Crm::OrganizationsController do
shared_examples 'ok response with index template if authorized' do
context 'private group' do
- let(:group) { create(:group, :private) }
+ let(:group) { create(:group, :private, :crm_enabled) }
context 'with authorized user' do
before do
@@ -32,11 +32,17 @@ RSpec.describe Groups::Crm::OrganizationsController do
sign_in(user)
end
- context 'when feature flag is enabled' do
+ context 'when crm_enabled is true' do
it_behaves_like 'ok response with index template'
end
- context 'when feature flag is not enabled' do
+ context 'when crm_enabled is false' do
+ let(:group) { create(:group, :private) }
+
+ it_behaves_like 'response with 404 status'
+ end
+
+ context 'when feature flag is disabled' do
before do
stub_feature_flags(customer_relations: false)
end
@@ -64,10 +70,10 @@ RSpec.describe Groups::Crm::OrganizationsController do
end
context 'public group' do
- let(:group) { create(:group, :public) }
+ let(:group) { create(:group, :public, :crm_enabled) }
context 'with anonymous user' do
- it_behaves_like 'ok response with index template'
+ it_behaves_like 'response with 404 status'
end
end
end
diff --git a/spec/requests/groups/settings/access_tokens_controller_spec.rb b/spec/requests/groups/settings/access_tokens_controller_spec.rb
new file mode 100644
index 00000000000..eabdef3c41e
--- /dev/null
+++ b/spec/requests/groups/settings/access_tokens_controller_spec.rb
@@ -0,0 +1,90 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Groups::Settings::AccessTokensController do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:resource) { create(:group) }
+ let_it_be(:bot_user) { create(:user, :project_bot) }
+
+ before_all do
+ resource.add_owner(user)
+ resource.add_maintainer(bot_user)
+ end
+
+ before do
+ sign_in(user)
+ end
+
+ shared_examples 'feature unavailable' do
+ context 'user is not a owner' do
+ before do
+ resource.add_maintainer(user)
+ end
+
+ it { expect(subject).to have_gitlab_http_status(:not_found) }
+ end
+ end
+
+ describe 'GET /:namespace/-/settings/access_tokens' do
+ subject do
+ get group_settings_access_tokens_path(resource)
+ response
+ end
+
+ it_behaves_like 'feature unavailable'
+ it_behaves_like 'GET resource access tokens available'
+ end
+
+ describe 'POST /:namespace/-/settings/access_tokens' do
+ let(:access_token_params) { { name: 'Nerd bot', scopes: ["api"], expires_at: Date.today + 1.month } }
+
+ subject do
+ post group_settings_access_tokens_path(resource), params: { resource_access_token: access_token_params }
+ response
+ end
+
+ it_behaves_like 'feature unavailable'
+ it_behaves_like 'POST resource access tokens available'
+
+ context 'when group access token creation is disabled' do
+ before do
+ resource.namespace_settings.update_column(:resource_access_token_creation_allowed, false)
+ end
+
+ it { expect(subject).to have_gitlab_http_status(:not_found) }
+
+ it 'does not create the token' do
+ expect { subject }.not_to change { PersonalAccessToken.count }
+ end
+
+ it 'does not add the project bot as a member' do
+ expect { subject }.not_to change { Member.count }
+ end
+
+ it 'does not create the project bot user' do
+ expect { subject }.not_to change { User.count }
+ end
+ end
+
+ context 'with custom access level' do
+ let(:access_token_params) { { name: 'Nerd bot', scopes: ["api"], expires_at: Date.today + 1.month, access_level: 20 } }
+
+ subject { post group_settings_access_tokens_path(resource), params: { resource_access_token: access_token_params } }
+
+ it_behaves_like 'POST resource access tokens available'
+ end
+ end
+
+ describe 'PUT /:namespace/-/settings/access_tokens/:id', :sidekiq_inline do
+ let(:resource_access_token) { create(:personal_access_token, user: bot_user) }
+
+ subject do
+ put revoke_group_settings_access_token_path(resource, resource_access_token)
+ response
+ end
+
+ it_behaves_like 'feature unavailable'
+ it_behaves_like 'PUT resource access tokens available'
+ end
+end
diff --git a/spec/requests/projects/google_cloud/deployments_controller_spec.rb b/spec/requests/projects/google_cloud/deployments_controller_spec.rb
new file mode 100644
index 00000000000..a5eccc43147
--- /dev/null
+++ b/spec/requests/projects/google_cloud/deployments_controller_spec.rb
@@ -0,0 +1,103 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::GoogleCloud::DeploymentsController do
+ let_it_be(:project) { create(:project, :public) }
+
+ let_it_be(:user_guest) { create(:user) }
+ let_it_be(:user_developer) { create(:user) }
+ let_it_be(:user_maintainer) { create(:user) }
+ let_it_be(:user_creator) { project.creator }
+
+ let_it_be(:unauthorized_members) { [user_guest, user_developer] }
+ let_it_be(:authorized_members) { [user_maintainer, user_creator] }
+
+ let_it_be(:urls_list) { %W[#{project_google_cloud_deployments_cloud_run_path(project)} #{project_google_cloud_deployments_cloud_storage_path(project)}] }
+
+ before do
+ project.add_guest(user_guest)
+ project.add_developer(user_developer)
+ project.add_maintainer(user_maintainer)
+ end
+
+ describe "Routes must be restricted behind Google OAuth2" 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)
+ end
+ end
+ end
+
+ context 'when unauthorized members make requests' do
+ it 'returns not found on GET request' do
+ urls_list.each do |url|
+ unauthorized_members.each do |unauthorized_member|
+ sign_in(unauthorized_member)
+
+ get url
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+ end
+
+ context 'when authorized members make requests' do
+ it 'redirects on GET request' do
+ urls_list.each do |url|
+ authorized_members.each do |authorized_member|
+ sign_in(authorized_member)
+
+ get url
+
+ expect(response).to redirect_to(assigns(:authorize_url))
+ end
+ end
+ end
+ end
+ end
+
+ describe 'Authorized GET project/-/google_cloud/deployments/cloud_run' do
+ let_it_be(:url) { "#{project_google_cloud_deployments_cloud_run_path(project)}" }
+
+ before do
+ allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |client|
+ allow(client).to receive(:validate_token).and_return(true)
+ end
+ end
+
+ it 'renders placeholder' do
+ authorized_members.each do |authorized_member|
+ sign_in(authorized_member)
+
+ get url
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
+
+ describe 'Authorized GET project/-/google_cloud/deployments/cloud_storage' do
+ let_it_be(:url) { "#{project_google_cloud_deployments_cloud_storage_path(project)}" }
+
+ before do
+ allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |client|
+ allow(client).to receive(:validate_token).and_return(true)
+ end
+ end
+
+ it 'renders placeholder' do
+ authorized_members.each do |authorized_member|
+ sign_in(authorized_member)
+
+ get url
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
+end
diff --git a/spec/requests/projects/merge_requests/context_commit_diffs_spec.rb b/spec/requests/projects/merge_requests/context_commit_diffs_spec.rb
index 434e6f19ff5..7be863aae75 100644
--- a/spec/requests/projects/merge_requests/context_commit_diffs_spec.rb
+++ b/spec/requests/projects/merge_requests/context_commit_diffs_spec.rb
@@ -31,7 +31,6 @@ RSpec.describe 'Merge Requests Context Commit Diffs' do
def collection_arguments(pagination_data = {})
{
- environment: nil,
merge_request: merge_request,
commit: nil,
diff_view: :inline,
diff --git a/spec/requests/projects/merge_requests/diffs_spec.rb b/spec/requests/projects/merge_requests/diffs_spec.rb
index ad50c39c65d..e17be1ff984 100644
--- a/spec/requests/projects/merge_requests/diffs_spec.rb
+++ b/spec/requests/projects/merge_requests/diffs_spec.rb
@@ -29,7 +29,6 @@ RSpec.describe 'Merge Requests Diffs' do
def collection_arguments(pagination_data = {})
{
- environment: nil,
merge_request: merge_request,
commit: nil,
diff_view: :inline,
@@ -110,21 +109,6 @@ RSpec.describe 'Merge Requests Diffs' do
end
end
- context 'with a new environment' do
- let(:environment) do
- create(:environment, :available, project: project)
- end
-
- let!(:deployment) do
- create(:deployment, :success, environment: environment, ref: merge_request.source_branch)
- end
-
- it_behaves_like 'serializes diffs with expected arguments' do
- let(:collection) { Gitlab::Diff::FileCollection::MergeRequestDiffBatch }
- let(:expected_options) { collection_arguments(total_pages: 20).merge(environment: environment) }
- end
- end
-
context 'with disabled display_merge_conflicts_in_diff feature' do
before do
stub_feature_flags(display_merge_conflicts_in_diff: false)
diff --git a/spec/requests/projects/merge_requests_discussions_spec.rb b/spec/requests/projects/merge_requests_discussions_spec.rb
index 4921a43ab8b..6cf7bfb1795 100644
--- a/spec/requests/projects/merge_requests_discussions_spec.rb
+++ b/spec/requests/projects/merge_requests_discussions_spec.rb
@@ -244,7 +244,7 @@ RSpec.describe 'merge requests discussions' do
context 'when current_user role changes' do
before do
- Members::UpdateService.new(owner, access_level: Gitlab::Access::GUEST).execute(project.project_member(user))
+ Members::UpdateService.new(owner, access_level: Gitlab::Access::GUEST).execute(project.member(user))
end
it_behaves_like 'cache miss' do
diff --git a/spec/requests/projects/settings/access_tokens_controller_spec.rb b/spec/requests/projects/settings/access_tokens_controller_spec.rb
new file mode 100644
index 00000000000..780d1b8caef
--- /dev/null
+++ b/spec/requests/projects/settings/access_tokens_controller_spec.rb
@@ -0,0 +1,91 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::Settings::AccessTokensController do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:resource) { create(:project, group: group) }
+ let_it_be(:bot_user) { create(:user, :project_bot) }
+
+ before_all do
+ resource.add_maintainer(user)
+ resource.add_maintainer(bot_user)
+ end
+
+ before do
+ sign_in(user)
+ end
+
+ shared_examples 'feature unavailable' do
+ context 'user is not a maintainer' do
+ before do
+ resource.add_developer(user)
+ end
+
+ it { expect(subject).to have_gitlab_http_status(:not_found) }
+ end
+ end
+
+ describe 'GET /:namespace/:project/-/settings/access_tokens' do
+ subject do
+ get project_settings_access_tokens_path(resource)
+ response
+ end
+
+ it_behaves_like 'feature unavailable'
+ it_behaves_like 'GET resource access tokens available'
+ end
+
+ describe 'POST /:namespace/:project/-/settings/access_tokens' do
+ let(:access_token_params) { { name: 'Nerd bot', scopes: ["api"], expires_at: Date.today + 1.month } }
+
+ subject do
+ post project_settings_access_tokens_path(resource), params: { resource_access_token: access_token_params }
+ response
+ end
+
+ it_behaves_like 'feature unavailable'
+ it_behaves_like 'POST resource access tokens available'
+
+ context 'when project access token creation is disabled' do
+ before do
+ group.namespace_settings.update_column(:resource_access_token_creation_allowed, false)
+ end
+
+ it { expect(subject).to have_gitlab_http_status(:not_found) }
+
+ it 'does not create the token' do
+ expect { subject }.not_to change { PersonalAccessToken.count }
+ end
+
+ it 'does not add the project bot as a member' do
+ expect { subject }.not_to change { Member.count }
+ end
+
+ it 'does not create the project bot user' do
+ expect { subject }.not_to change { User.count }
+ end
+ end
+
+ context 'with custom access level' do
+ let(:access_token_params) { { name: 'Nerd bot', scopes: ["api"], expires_at: Date.today + 1.month, access_level: 20 } }
+
+ subject { post project_settings_access_tokens_path(resource), params: { resource_access_token: access_token_params } }
+
+ it_behaves_like 'POST resource access tokens available'
+ end
+ end
+
+ describe 'PUT /:namespace/:project/-/settings/access_tokens/:id', :sidekiq_inline do
+ let(:resource_access_token) { create(:personal_access_token, user: bot_user) }
+
+ subject do
+ put revoke_project_settings_access_token_path(resource, resource_access_token)
+ response
+ end
+
+ it_behaves_like 'feature unavailable'
+ it_behaves_like 'PUT resource access tokens available'
+ end
+end
diff --git a/spec/requests/rack_attack_global_spec.rb b/spec/requests/rack_attack_global_spec.rb
index 244ec111a0c..793438808a5 100644
--- a/spec/requests/rack_attack_global_spec.rb
+++ b/spec/requests/rack_attack_global_spec.rb
@@ -499,9 +499,7 @@ RSpec.describe 'Rack Attack global throttles', :use_clean_rails_memory_store_cac
before do
group.add_owner(user)
- group.create_dependency_proxy_setting!(enabled: true)
other_group.add_owner(other_user)
- other_group.create_dependency_proxy_setting!(enabled: true)
allow(Gitlab.config.dependency_proxy)
.to receive(:enabled).and_return(true)
@@ -533,16 +531,10 @@ RSpec.describe 'Rack Attack global throttles', :use_clean_rails_memory_store_cac
context 'getting a blob' do
let_it_be(:blob) { create(:dependency_proxy_blob) }
+ let_it_be(:other_blob) { create(:dependency_proxy_blob) }
- let(:path) { "/v2/#{group.path}/dependency_proxy/containers/alpine/blobs/sha256:a0d0a0d46f8b52473982a3c466318f479767577551a53ffc9074c9fa7035982e" }
- let(:other_path) { "/v2/#{other_group.path}/dependency_proxy/containers/alpine/blobs/sha256:a0d0a0d46f8b52473982a3c466318f479767577551a53ffc9074c9fa7035982e" }
- let(:blob_response) { { status: :success, blob: blob, from_cache: false } }
-
- before do
- allow_next_instance_of(DependencyProxy::FindOrCreateBlobService) do |instance|
- allow(instance).to receive(:execute).and_return(blob_response)
- end
- end
+ let(:path) { "/v2/#{blob.group.path}/dependency_proxy/containers/alpine/blobs/sha256:a0d0a0d46f8b52473982a3c466318f479767577551a53ffc9074c9fa7035982e" }
+ let(:other_path) { "/v2/#{other_blob.group.path}/dependency_proxy/containers/alpine/blobs/sha256:a0d0a0d46f8b52473982a3c466318f479767577551a53ffc9074c9fa7035982e" }
it_behaves_like 'rate-limited token-authenticated requests'
end
diff --git a/spec/requests/recursive_webhook_detection_spec.rb b/spec/requests/recursive_webhook_detection_spec.rb
new file mode 100644
index 00000000000..a3014bf1d73
--- /dev/null
+++ b/spec/requests/recursive_webhook_detection_spec.rb
@@ -0,0 +1,182 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Recursive webhook detection', :sidekiq_inline, :clean_gitlab_redis_shared_state, :request_store do
+ include StubRequests
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :repository, namespace: user.namespace, creator: user) }
+ let_it_be(:merge_request) { create(:merge_request, source_project: project) }
+ let_it_be(:project_hook) { create(:project_hook, project: project, merge_requests_events: true) }
+ let_it_be(:system_hook) { create(:system_hook, merge_requests_events: true) }
+
+ # Trigger a change to the merge request to fire the webhooks.
+ def trigger_web_hooks
+ params = { merge_request: { description: FFaker::Lorem.sentence } }
+ put project_merge_request_path(project, merge_request), params: params, headers: headers
+ end
+
+ def stub_requests
+ stub_full_request(project_hook.url, method: :post, ip_address: '8.8.8.8')
+ stub_full_request(system_hook.url, method: :post, ip_address: '8.8.8.9')
+ end
+
+ before do
+ login_as(user)
+ end
+
+ context 'when the request headers include the recursive webhook detection header' do
+ let(:uuid) { SecureRandom.uuid }
+ let(:headers) { { Gitlab::WebHooks::RecursionDetection::UUID::HEADER => uuid } }
+
+ it 'executes all webhooks, logs no errors, and the webhook requests contain the same UUID header', :aggregate_failures do
+ stub_requests
+
+ expect(Gitlab::AuthLogger).not_to receive(:error)
+
+ trigger_web_hooks
+
+ expect(WebMock).to have_requested(:post, stubbed_hostname(project_hook.url))
+ .with { |req| req.headers['X-Gitlab-Event-Uuid'] == uuid }
+ .once
+ expect(WebMock).to have_requested(:post, stubbed_hostname(system_hook.url))
+ .with { |req| req.headers['X-Gitlab-Event-Uuid'] == uuid }
+ .once
+ end
+
+ context 'when one of the webhooks is recursive' do
+ before do
+ # Recreate the necessary state for the previous request to be
+ # considered made from the webhook.
+ Gitlab::WebHooks::RecursionDetection.set_request_uuid(uuid)
+ Gitlab::WebHooks::RecursionDetection.register!(project_hook)
+ Gitlab::WebHooks::RecursionDetection.set_request_uuid(nil)
+ end
+
+ it 'executes all webhooks and logs an error for the recursive hook', :aggregate_failures do
+ stub_requests
+
+ expect(Gitlab::AuthLogger).to receive(:error).with(
+ include(
+ message: 'Webhook recursion detected and will be blocked in future',
+ hook_id: project_hook.id,
+ recursion_detection: {
+ uuid: uuid,
+ ids: [project_hook.id]
+ }
+ )
+ ).twice # Twice: once in `#async_execute`, and again in `#execute`.
+
+ trigger_web_hooks
+
+ expect(WebMock).to have_requested(:post, stubbed_hostname(project_hook.url)).once
+ expect(WebMock).to have_requested(:post, stubbed_hostname(system_hook.url)).once
+ end
+ end
+
+ context 'when the count limit has been reached' do
+ let_it_be(:previous_hooks) { create_list(:project_hook, 3) }
+
+ before do
+ stub_const('Gitlab::WebHooks::RecursionDetection::COUNT_LIMIT', 2)
+ # Recreate the necessary state for a number of previous webhooks to
+ # have been triggered previously.
+ Gitlab::WebHooks::RecursionDetection.set_request_uuid(uuid)
+ previous_hooks.each { Gitlab::WebHooks::RecursionDetection.register!(_1) }
+ Gitlab::WebHooks::RecursionDetection.set_request_uuid(nil)
+ end
+
+ it 'executes and logs errors for all hooks', :aggregate_failures do
+ stub_requests
+ previous_hook_ids = previous_hooks.map(&:id)
+
+ expect(Gitlab::AuthLogger).to receive(:error).with(
+ include(
+ message: 'Webhook recursion detected and will be blocked in future',
+ hook_id: project_hook.id,
+ recursion_detection: {
+ uuid: uuid,
+ ids: include(*previous_hook_ids)
+ }
+ )
+ ).twice
+ expect(Gitlab::AuthLogger).to receive(:error).with(
+ include(
+ message: 'Webhook recursion detected and will be blocked in future',
+ hook_id: system_hook.id,
+ recursion_detection: {
+ uuid: uuid,
+ ids: include(*previous_hook_ids)
+ }
+ )
+ ).twice
+
+ trigger_web_hooks
+
+ expect(WebMock).to have_requested(:post, stubbed_hostname(project_hook.url)).once
+ expect(WebMock).to have_requested(:post, stubbed_hostname(system_hook.url)).once
+ end
+ end
+ end
+
+ context 'when the recursive webhook detection header is absent' do
+ let(:headers) { {} }
+
+ let(:uuid_header_spy) do
+ Class.new do
+ attr_reader :values
+
+ def initialize
+ @values = []
+ end
+
+ def to_proc
+ proc do |method, *args|
+ method.call(*args).tap do |headers|
+ @values << headers[Gitlab::WebHooks::RecursionDetection::UUID::HEADER]
+ end
+ end
+ end
+ end.new
+ end
+
+ before do
+ allow(Gitlab::WebHooks::RecursionDetection).to receive(:header).at_least(:once).and_wrap_original(&uuid_header_spy)
+ end
+
+ it 'executes all webhooks, logs no errors, and the webhook requests contain different UUID headers', :aggregate_failures do
+ stub_requests
+
+ expect(Gitlab::AuthLogger).not_to receive(:error)
+
+ trigger_web_hooks
+
+ uuid_headers = uuid_header_spy.values
+
+ expect(uuid_headers).to all(be_present)
+ expect(uuid_headers.uniq.length).to eq(2)
+ expect(WebMock).to have_requested(:post, stubbed_hostname(project_hook.url))
+ .with { |req| uuid_headers.include?(req.headers['X-Gitlab-Event-Uuid']) }
+ .once
+ expect(WebMock).to have_requested(:post, stubbed_hostname(system_hook.url))
+ .with { |req| uuid_headers.include?(req.headers['X-Gitlab-Event-Uuid']) }
+ .once
+ end
+
+ it 'uses new UUID values between requests' do
+ stub_requests
+
+ trigger_web_hooks
+ trigger_web_hooks
+
+ uuid_headers = uuid_header_spy.values
+
+ expect(uuid_headers).to all(be_present)
+ expect(uuid_headers.length).to eq(4)
+ expect(uuid_headers.uniq.length).to eq(4)
+ expect(WebMock).to have_requested(:post, stubbed_hostname(project_hook.url)).twice
+ expect(WebMock).to have_requested(:post, stubbed_hostname(system_hook.url)).twice
+ end
+ end
+end
diff --git a/spec/requests/sandbox_controller_spec.rb b/spec/requests/sandbox_controller_spec.rb
new file mode 100644
index 00000000000..4fc26580123
--- /dev/null
+++ b/spec/requests/sandbox_controller_spec.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe SandboxController do
+ describe 'GET #mermaid' do
+ it 'renders page without template' do
+ get sandbox_mermaid_path
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to render_template(layout: nil)
+ end
+ end
+end
diff --git a/spec/requests/users_controller_spec.rb b/spec/requests/users_controller_spec.rb
index eefc24f7824..dacc11eece7 100644
--- a/spec/requests/users_controller_spec.rb
+++ b/spec/requests/users_controller_spec.rb
@@ -636,6 +636,8 @@ RSpec.describe UsersController do
describe 'GET #exists' do
before do
sign_in(user)
+
+ allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(false)
end
context 'when user exists' do
@@ -677,6 +679,17 @@ RSpec.describe UsersController do
end
end
end
+
+ context 'when the rate limit has been reached' do
+ it 'returns status 429 Too Many Requests', :aggregate_failures do
+ ip = '1.2.3.4'
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).with(:username_exists, scope: ip).and_return(true)
+
+ get user_exists_url(user.username), env: { 'REMOTE_ADDR': ip }
+
+ expect(response).to have_gitlab_http_status(:too_many_requests)
+ end
+ end
end
describe '#ensure_canonical_path' do
diff --git a/spec/routing/routing_spec.rb b/spec/routing/routing_spec.rb
index e7ea5b79897..79edfdd2b3f 100644
--- a/spec/routing/routing_spec.rb
+++ b/spec/routing/routing_spec.rb
@@ -364,6 +364,12 @@ RSpec.describe AutocompleteController, 'routing' do
end
end
+RSpec.describe SandboxController, 'routing' do
+ it 'to #mermaid' do
+ expect(get("/-/sandbox/mermaid")).to route_to('sandbox#mermaid')
+ end
+end
+
RSpec.describe Snippets::BlobsController, "routing" do
it "to #raw" do
expect(get('/-/snippets/1/raw/master/lib/version.rb'))
diff --git a/spec/rubocop/code_reuse_helpers_spec.rb b/spec/rubocop/code_reuse_helpers_spec.rb
index 3220cff1681..d437ada85ee 100644
--- a/spec/rubocop/code_reuse_helpers_spec.rb
+++ b/spec/rubocop/code_reuse_helpers_spec.rb
@@ -315,76 +315,11 @@ RSpec.describe RuboCop::CodeReuseHelpers do
end
end
- describe '#ee?' do
- before do
- stub_env('FOSS_ONLY', nil)
- allow(File).to receive(:exist?).with(ee_file_path) { true }
- end
-
- it 'returns true when ee/app/models/license.rb exists' do
- expect(cop.ee?).to eq(true)
- end
- end
-
- describe '#jh?' do
- context 'when jh directory exists and EE_ONLY is not set' do
- before do
- stub_env('EE_ONLY', nil)
-
- allow(Dir).to receive(:exist?).with(File.expand_path('../../jh', __dir__)) { true }
- end
-
- context 'when ee/app/models/license.rb exists' do
- before do
- allow(File).to receive(:exist?).with(ee_file_path) { true }
- end
-
- context 'when FOSS_ONLY is not set' do
- before do
- stub_env('FOSS_ONLY', nil)
- end
-
- it 'returns true' do
- expect(cop.jh?).to eq(true)
- end
- end
-
- context 'when FOSS_ONLY is set to 1' do
- before do
- stub_env('FOSS_ONLY', '1')
- end
+ %w[ee? jh?].each do |method_name|
+ it "delegates #{method_name} to GitlabEdition" do
+ expect(GitlabEdition).to receive(method_name)
- it 'returns false' do
- expect(cop.jh?).to eq(false)
- end
- end
- end
-
- context 'when ee/app/models/license.rb not exist' do
- before do
- allow(File).to receive(:exist?).with(ee_file_path) { false }
- end
-
- context 'when FOSS_ONLY is not set' do
- before do
- stub_env('FOSS_ONLY', nil)
- end
-
- it 'returns true' do
- expect(cop.jh?).to eq(false)
- end
- end
-
- context 'when FOSS_ONLY is set to 1' do
- before do
- stub_env('FOSS_ONLY', '1')
- end
-
- it 'returns false' do
- expect(cop.jh?).to eq(false)
- end
- end
- end
+ cop.public_send(method_name)
end
end
end
diff --git a/spec/rubocop/cop/database/establish_connection_spec.rb b/spec/rubocop/cop/database/establish_connection_spec.rb
new file mode 100644
index 00000000000..a3c27d33cb0
--- /dev/null
+++ b/spec/rubocop/cop/database/establish_connection_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_relative '../../../../rubocop/cop/database/establish_connection'
+
+RSpec.describe RuboCop::Cop::Database::EstablishConnection do
+ subject(:cop) { described_class.new }
+
+ it 'flags the use of ActiveRecord::Base.establish_connection' do
+ expect_offense(<<~CODE)
+ ActiveRecord::Base.establish_connection
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't establish new database [...]
+ CODE
+ end
+
+ it 'flags the use of ActiveRecord::Base.establish_connection with arguments' do
+ expect_offense(<<~CODE)
+ ActiveRecord::Base.establish_connection(:foo)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't establish new database [...]
+ CODE
+ end
+
+ it 'flags the use of SomeModel.establish_connection' do
+ expect_offense(<<~CODE)
+ SomeModel.establish_connection
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't establish new database [...]
+ CODE
+ end
+end
diff --git a/spec/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction_spec.rb b/spec/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction_spec.rb
new file mode 100644
index 00000000000..aa63259288d
--- /dev/null
+++ b/spec/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction_spec.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require_relative '../../../../rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction'
+
+RSpec.describe RuboCop::Cop::Migration::PreventGlobalEnableLockRetriesWithDisableDdlTransaction do
+ subject(:cop) { described_class.new }
+
+ context 'when in migration' do
+ before do
+ allow(cop).to receive(:in_migration?).and_return(true)
+ end
+
+ it 'registers an offense when `enable_lock_retries` and `disable_ddl_transaction` is used together' do
+ code = <<~RUBY
+ class SomeMigration < ActiveRecord::Migration[6.0]
+ enable_lock_retries!
+ disable_ddl_transaction!
+ end
+ RUBY
+
+ expect_offense(<<~RUBY, node: code, msg: described_class::MSG)
+ class SomeMigration < ActiveRecord::Migration[6.0]
+ enable_lock_retries!
+ disable_ddl_transaction!
+ ^^^^^^^^^^^^^^^^^^^^^^^^ %{msg}
+ end
+ RUBY
+ end
+
+ it 'registers no offense when `enable_lock_retries!` is used' do
+ expect_no_offenses(<<~RUBY)
+ class SomeMigration < ActiveRecord::Migration[6.0]
+ enable_lock_retries!
+ end
+ RUBY
+ end
+
+ it 'registers no offense when `disable_ddl_transaction!` is used' do
+ expect_no_offenses(<<~RUBY)
+ class SomeMigration < ActiveRecord::Migration[6.0]
+ disable_ddl_transaction!
+ end
+ RUBY
+ end
+ end
+
+ context 'when outside of migration' do
+ it 'registers no offense' do
+ expect_no_offenses(<<~RUBY)
+ class SomeMigration
+ enable_lock_retries!
+ disable_ddl_transaction!
+ end
+ RUBY
+ end
+ end
+end
diff --git a/spec/rubocop/cop/migration/schedule_async_spec.rb b/spec/rubocop/cop/migration/schedule_async_spec.rb
index b89acb6db41..5f848dd9b66 100644
--- a/spec/rubocop/cop/migration/schedule_async_spec.rb
+++ b/spec/rubocop/cop/migration/schedule_async_spec.rb
@@ -43,24 +43,18 @@ RSpec.describe RuboCop::Cop::Migration::ScheduleAsync do
end
context 'BackgroundMigrationWorker.perform_async' do
- it 'adds an offense when calling `BackgroundMigrationWorker.peform_async` and corrects', :aggregate_failures do
+ it 'adds an offense when calling `BackgroundMigrationWorker.peform_async`' do
expect_offense(<<~RUBY)
def up
BackgroundMigrationWorker.perform_async(ClazzName, "Bar", "Baz")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't call [...]
end
RUBY
-
- expect_correction(<<~RUBY)
- def up
- migrate_async(ClazzName, "Bar", "Baz")
- end
- RUBY
end
end
context 'BackgroundMigrationWorker.perform_in' do
- it 'adds an offense and corrects', :aggregate_failures do
+ it 'adds an offense' do
expect_offense(<<~RUBY)
def up
BackgroundMigrationWorker
@@ -68,17 +62,11 @@ RSpec.describe RuboCop::Cop::Migration::ScheduleAsync do
.perform_in(delay, ClazzName, "Bar", "Baz")
end
RUBY
-
- expect_correction(<<~RUBY)
- def up
- migrate_in(delay, ClazzName, "Bar", "Baz")
- end
- RUBY
end
end
context 'BackgroundMigrationWorker.bulk_perform_async' do
- it 'adds an offense and corrects', :aggregate_failures do
+ it 'adds an offense' do
expect_offense(<<~RUBY)
def up
BackgroundMigrationWorker
@@ -86,17 +74,11 @@ RSpec.describe RuboCop::Cop::Migration::ScheduleAsync do
.bulk_perform_async(jobs)
end
RUBY
-
- expect_correction(<<~RUBY)
- def up
- bulk_migrate_async(jobs)
- end
- RUBY
end
end
context 'BackgroundMigrationWorker.bulk_perform_in' do
- it 'adds an offense and corrects', :aggregate_failures do
+ it 'adds an offense' do
expect_offense(<<~RUBY)
def up
BackgroundMigrationWorker
@@ -104,12 +86,6 @@ RSpec.describe RuboCop::Cop::Migration::ScheduleAsync do
.bulk_perform_in(5.minutes, jobs)
end
RUBY
-
- expect_correction(<<~RUBY)
- def up
- bulk_migrate_in(5.minutes, jobs)
- end
- RUBY
end
end
end
diff --git a/spec/scripts/setup/find_jh_branch_spec.rb b/spec/scripts/setup/find_jh_branch_spec.rb
new file mode 100644
index 00000000000..dfc3601ffa9
--- /dev/null
+++ b/spec/scripts/setup/find_jh_branch_spec.rb
@@ -0,0 +1,97 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+
+# NOTE: Under the context of fast_spec_helper, when we `require 'gitlab'`
+# we do not load the Gitlab client, but our own Gitlab module.
+# Keep this in mind and just stub anything which might touch it!
+require_relative '../../../scripts/setup/find-jh-branch'
+
+RSpec.describe FindJhBranch do
+ subject { described_class.new }
+
+ describe '#run' do
+ context 'when it is not a merge request' do
+ before do
+ expect(subject).to receive(:merge_request?).and_return(false)
+ end
+
+ it 'returns JH_DEFAULT_BRANCH' do
+ expect(subject.run).to eq(described_class::JH_DEFAULT_BRANCH)
+ end
+ end
+
+ context 'when it is a merge request' do
+ let(:branch_name) { 'branch-name' }
+ let(:jh_branch_name) { 'branch-name-jh' }
+ let(:default_branch) { 'main' }
+ let(:merge_request) { double(target_branch: target_branch) }
+ let(:target_branch) { default_branch }
+
+ before do
+ expect(subject).to receive(:merge_request?).and_return(true)
+
+ expect(subject)
+ .to receive(:branch_exist?)
+ .with(described_class::JH_PROJECT_PATH, jh_branch_name)
+ .and_return(jh_branch_exist)
+
+ allow(subject).to receive(:ref_name).and_return(branch_name)
+ allow(subject).to receive(:default_branch).and_return(default_branch)
+ allow(subject).to receive(:merge_request).and_return(merge_request)
+ end
+
+ context 'when there is a corresponding JH branch' do
+ let(:jh_branch_exist) { true }
+
+ it 'returns the corresponding JH branch name' do
+ expect(subject.run).to eq(jh_branch_name)
+ end
+ end
+
+ context 'when there is no corresponding JH branch' do
+ let(:jh_branch_exist) { false }
+
+ it 'returns the default JH branch' do
+ expect(subject.run).to eq(described_class::JH_DEFAULT_BRANCH)
+ end
+
+ context 'when it is targeting a default branch' do
+ let(:target_branch) { '14-6-stable-ee' }
+ let(:jh_stable_branch_name) { '14-6-stable-jh' }
+
+ before do
+ expect(subject)
+ .to receive(:branch_exist?)
+ .with(described_class::JH_PROJECT_PATH, jh_stable_branch_name)
+ .and_return(jh_stable_branch_exist)
+ end
+
+ context 'when there is a corresponding JH stable branch' do
+ let(:jh_stable_branch_exist) { true }
+
+ it 'returns the corresponding JH stable branch' do
+ expect(subject.run).to eq(jh_stable_branch_name)
+ end
+ end
+
+ context 'when there is no corresponding JH stable branch' do
+ let(:jh_stable_branch_exist) { false }
+
+ it "raises #{described_class::BranchNotFound}" do
+ expect { subject.run }.to raise_error(described_class::BranchNotFound)
+ end
+ end
+ end
+
+ context 'when it is not targeting the default branch' do
+ let(:target_branch) { default_branch.swapcase }
+
+ it 'returns the default JH branch' do
+ expect(subject.run).to eq(described_class::JH_DEFAULT_BRANCH)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/serializers/analytics_build_entity_spec.rb b/spec/serializers/analytics_build_entity_spec.rb
index 09804681f5d..b5678d91248 100644
--- a/spec/serializers/analytics_build_entity_spec.rb
+++ b/spec/serializers/analytics_build_entity_spec.rb
@@ -27,6 +27,14 @@ RSpec.describe AnalyticsBuildEntity do
expect(subject).to include(:author)
end
+ it 'contains the project path' do
+ expect(subject).to include(:project_path)
+ end
+
+ it 'contains the namespace full path' do
+ expect(subject).to include(:namespace_full_path)
+ end
+
it 'does not contain sensitive information' do
expect(subject).not_to include(/token/)
expect(subject).not_to include(/variables/)
diff --git a/spec/serializers/analytics_issue_entity_spec.rb b/spec/serializers/analytics_issue_entity_spec.rb
index 447c5e7d02a..bc5cab638cd 100644
--- a/spec/serializers/analytics_issue_entity_spec.rb
+++ b/spec/serializers/analytics_issue_entity_spec.rb
@@ -32,6 +32,14 @@ RSpec.describe AnalyticsIssueEntity do
expect(subject).to include(:author)
end
+ it 'contains the project path' do
+ expect(subject).to include(:project_path)
+ end
+
+ it 'contains the namespace full path' do
+ expect(subject).to include(:namespace_full_path)
+ end
+
it 'does not contain sensitive information' do
expect(subject).not_to include(/token/)
expect(subject).not_to include(/variables/)
diff --git a/spec/serializers/environment_serializer_spec.rb b/spec/serializers/environment_serializer_spec.rb
index 985e18f27a0..80b6f00d8c9 100644
--- a/spec/serializers/environment_serializer_spec.rb
+++ b/spec/serializers/environment_serializer_spec.rb
@@ -185,6 +185,42 @@ RSpec.describe EnvironmentSerializer do
end
end
+ context 'batching loading' do
+ let(:resource) { Environment.all }
+
+ before do
+ create(:environment, name: 'staging/review-1')
+ create_environment_with_associations(project)
+ end
+
+ it 'uses the custom preloader service' do
+ expect_next_instance_of(Preloaders::Environments::DeploymentPreloader) do |preloader|
+ expect(preloader).to receive(:execute_with_union).with(:last_deployment, hash_including(:deployable)).and_call_original
+ end
+
+ expect_next_instance_of(Preloaders::Environments::DeploymentPreloader) do |preloader|
+ expect(preloader).to receive(:execute_with_union).with(:upcoming_deployment, hash_including(:deployable)).and_call_original
+ end
+
+ json
+ end
+
+ # Including for test coverage pipeline failure, remove along with feature flag.
+ context 'when custom preload feature is disabled' do
+ before do
+ Feature.disable(:custom_preloader_for_deployments)
+ end
+
+ it 'avoids N+1 database queries' do
+ control_count = ActiveRecord::QueryRecorder.new { json }.count
+
+ create_environment_with_associations(project)
+
+ expect { json }.not_to exceed_query_limit(control_count)
+ end
+ end
+ end
+
def create_environment_with_associations(project)
create(:environment, project: project).tap do |environment|
create(:deployment, :success, environment: environment, project: project)
diff --git a/spec/serializers/group_child_entity_spec.rb b/spec/serializers/group_child_entity_spec.rb
index e4844c25067..59340181075 100644
--- a/spec/serializers/group_child_entity_spec.rb
+++ b/spec/serializers/group_child_entity_spec.rb
@@ -62,6 +62,10 @@ RSpec.describe GroupChildEntity do
expect(json[:edit_path]).to eq(edit_project_path(object))
end
+ it 'includes the last activity at' do
+ expect(json[:last_activity_at]).to be_present
+ end
+
it_behaves_like 'group child json'
end
diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb
index 587d167520f..f5398013a70 100644
--- a/spec/serializers/pipeline_serializer_spec.rb
+++ b/spec/serializers/pipeline_serializer_spec.rb
@@ -202,7 +202,7 @@ RSpec.describe PipelineSerializer do
# Existing numbers are high and require performance optimization
# Ongoing issue:
# https://gitlab.com/gitlab-org/gitlab/-/issues/225156
- expected_queries = Gitlab.ee? ? 74 : 70
+ expected_queries = Gitlab.ee? ? 78 : 74
expect(recorded.count).to be_within(2).of(expected_queries)
expect(recorded.cached_count).to eq(0)
diff --git a/spec/services/alert_management/alerts/update_service_spec.rb b/spec/services/alert_management/alerts/update_service_spec.rb
index 4b47efca9ed..35697ac79a0 100644
--- a/spec/services/alert_management/alerts/update_service_spec.rb
+++ b/spec/services/alert_management/alerts/update_service_spec.rb
@@ -235,6 +235,59 @@ RSpec.describe AlertManagement::Alerts::UpdateService do
it_behaves_like 'adds a system note'
end
+
+ context 'with an associated issue' do
+ let_it_be(:issue, reload: true) { create(:issue, project: project) }
+
+ before do
+ alert.update!(issue: issue)
+ end
+
+ shared_examples 'does not sync with the incident status' do
+ specify do
+ expect(::Issues::UpdateService).not_to receive(:new)
+ expect { response }.to change { alert.acknowledged? }.to(true)
+ end
+ end
+
+ it_behaves_like 'does not sync with the incident status'
+
+ context 'when the issue is an incident' do
+ before do
+ issue.update!(issue_type: Issue.issue_types[:incident])
+ end
+
+ it_behaves_like 'does not sync with the incident status'
+
+ context 'when the incident has an escalation status' do
+ let_it_be(:escalation_status, reload: true) { create(:incident_management_issuable_escalation_status, issue: issue) }
+
+ it 'updates the incident escalation status with the new alert status' do
+ expect(::Issues::UpdateService).to receive(:new).once.and_call_original
+ expect(described_class).to receive(:new).once.and_call_original
+
+ expect { response }.to change { escalation_status.reload.acknowledged? }.to(true)
+ .and change { alert.reload.acknowledged? }.to(true)
+ end
+
+ context 'when the statuses match' do
+ before do
+ escalation_status.update!(status_event: :acknowledge)
+ end
+
+ it_behaves_like 'does not sync with the incident status'
+ end
+
+ context 'when feature flag is disabled' do
+ before do
+ stub_feature_flags(incident_escalations: false)
+ end
+
+ it_behaves_like 'does not sync with the incident status'
+ end
+ end
+ end
+ end
end
end
end
diff --git a/spec/services/audit_event_service_spec.rb b/spec/services/audit_event_service_spec.rb
index ce7b43972da..0379fd3f05c 100644
--- a/spec/services/audit_event_service_spec.rb
+++ b/spec/services/audit_event_service_spec.rb
@@ -60,17 +60,18 @@ RSpec.describe AuditEventService do
ip_address: user.current_sign_in_ip,
result: AuthenticationEvent.results[:success],
provider: 'standard'
- )
+ ).and_call_original
audit_service.for_authentication.security_event
end
it 'tracks exceptions when the event cannot be created' do
- allow(user).to receive_messages(current_sign_in_ip: 'invalid IP')
+ allow_next_instance_of(AuditEvent) do |event|
+ allow(event).to receive(:valid?).and_return(false)
+ end
expect(Gitlab::ErrorTracking).to(
- receive(:track_exception)
- .with(ActiveRecord::RecordInvalid, audit_event_type: 'AuthenticationEvent').and_call_original
+ receive(:track_and_raise_for_dev_exception)
)
audit_service.for_authentication.security_event
@@ -93,7 +94,7 @@ RSpec.describe AuditEventService do
end
specify do
- expect(AuthenticationEvent).to receive(:new).with(hash_including(ip_address: output))
+ expect(AuthenticationEvent).to receive(:new).with(hash_including(ip_address: output)).and_call_original
audit_service.for_authentication.security_event
end
diff --git a/spec/services/auth/container_registry_authentication_service_spec.rb b/spec/services/auth/container_registry_authentication_service_spec.rb
index 46cc027fcb3..83f77780b80 100644
--- a/spec/services/auth/container_registry_authentication_service_spec.rb
+++ b/spec/services/auth/container_registry_authentication_service_spec.rb
@@ -92,6 +92,35 @@ RSpec.describe Auth::ContainerRegistryAuthenticationService do
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
@@ -116,4 +145,28 @@ RSpec.describe Auth::ContainerRegistryAuthenticationService do
it_behaves_like 'an unmodified token'
end
end
+
+ context 'CDN redirection' do
+ include_context 'container registry auth service context'
+
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:current_params) { { scopes: ["repository:#{project.full_path}:pull"] } }
+
+ before do
+ project.add_developer(current_user)
+ end
+
+ it_behaves_like 'a valid token'
+ it { expect(payload['access']).to include(include('cdn_redirect' => true)) }
+
+ context 'when the feature flag is disabled' do
+ before do
+ stub_feature_flags(container_registry_cdn_redirect: false)
+ end
+
+ it_behaves_like 'a valid token'
+ it { expect(payload['access']).not_to include(have_key('cdn_redirect')) }
+ end
+ end
end
diff --git a/spec/services/branches/delete_merged_service_spec.rb b/spec/services/branches/delete_merged_service_spec.rb
index 2cf0f53c8c3..46611670fe1 100644
--- a/spec/services/branches/delete_merged_service_spec.rb
+++ b/spec/services/branches/delete_merged_service_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Branches::DeleteMergedService do
include ProjectForksHelper
- subject(:service) { described_class.new(project, project.owner) }
+ subject(:service) { described_class.new(project, project.first_owner) }
let(:project) { create(:project, :repository) }
diff --git a/spec/services/bulk_imports/archive_extraction_service_spec.rb b/spec/services/bulk_imports/archive_extraction_service_spec.rb
index aa823d88010..da9df31cde9 100644
--- a/spec/services/bulk_imports/archive_extraction_service_spec.rb
+++ b/spec/services/bulk_imports/archive_extraction_service_spec.rb
@@ -34,9 +34,9 @@ RSpec.describe BulkImports::ArchiveExtractionService do
context 'when dir is not in tmpdir' do
it 'raises an error' do
- ['/etc', '/usr', '/', '/home', '', '/some/other/path', Rails.root].each do |path|
+ ['/etc', '/usr', '/', '/home', '/some/other/path', Rails.root.to_s].each do |path|
expect { described_class.new(tmpdir: path, filename: 'filename').execute }
- .to raise_error(BulkImports::Error, 'Invalid target directory')
+ .to raise_error(StandardError, "path #{path} is not allowed")
end
end
end
@@ -52,7 +52,7 @@ RSpec.describe BulkImports::ArchiveExtractionService do
context 'when filepath is being traversed' do
it 'raises an error' do
- expect { described_class.new(tmpdir: File.join(tmpdir, '../../../'), filename: 'name').execute }
+ expect { described_class.new(tmpdir: File.join(Dir.mktmpdir, 'test', '..'), filename: 'name').execute }
.to raise_error(Gitlab::Utils::PathTraversalAttackError, 'Invalid path')
end
end
diff --git a/spec/services/bulk_imports/file_decompression_service_spec.rb b/spec/services/bulk_imports/file_decompression_service_spec.rb
index 4e8f78c8243..1d6aa79a37f 100644
--- a/spec/services/bulk_imports/file_decompression_service_spec.rb
+++ b/spec/services/bulk_imports/file_decompression_service_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe BulkImports::FileDecompressionService do
FileUtils.remove_entry(tmpdir)
end
- subject { described_class.new(dir: tmpdir, filename: gz_filename) }
+ subject { described_class.new(tmpdir: tmpdir, filename: gz_filename) }
describe '#execute' do
it 'decompresses specified file' do
@@ -55,10 +55,18 @@ RSpec.describe BulkImports::FileDecompressionService do
end
context 'when dir is not in tmpdir' do
- subject { described_class.new(dir: '/etc', filename: 'filename') }
+ subject { described_class.new(tmpdir: '/etc', filename: 'filename') }
it 'raises an error' do
- expect { subject.execute }.to raise_error(described_class::ServiceError, 'Invalid target directory')
+ expect { subject.execute }.to raise_error(StandardError, 'path /etc is not allowed')
+ end
+ end
+
+ context 'when path is being traversed' do
+ subject { described_class.new(tmpdir: File.join(Dir.mktmpdir, 'test', '..'), filename: 'filename') }
+
+ it 'raises an error' do
+ expect { subject.execute }.to raise_error(Gitlab::Utils::PathTraversalAttackError, 'Invalid path')
end
end
@@ -69,7 +77,7 @@ RSpec.describe BulkImports::FileDecompressionService do
FileUtils.ln_s(File.join(tmpdir, gz_filename), symlink)
end
- subject { described_class.new(dir: tmpdir, filename: 'symlink.gz') }
+ subject { described_class.new(tmpdir: tmpdir, filename: 'symlink.gz') }
it 'raises an error and removes the file' do
expect { subject.execute }.to raise_error(described_class::ServiceError, 'Invalid file')
@@ -87,7 +95,7 @@ RSpec.describe BulkImports::FileDecompressionService do
subject.instance_variable_set(:@decompressed_filepath, symlink)
end
- subject { described_class.new(dir: tmpdir, filename: gz_filename) }
+ subject { described_class.new(tmpdir: tmpdir, filename: gz_filename) }
it 'raises an error and removes the file' do
expect { subject.execute }.to raise_error(described_class::ServiceError, 'Invalid file')
diff --git a/spec/services/bulk_imports/file_download_service_spec.rb b/spec/services/bulk_imports/file_download_service_spec.rb
index a24af9ae64d..bd664d6e996 100644
--- a/spec/services/bulk_imports/file_download_service_spec.rb
+++ b/spec/services/bulk_imports/file_download_service_spec.rb
@@ -33,7 +33,7 @@ RSpec.describe BulkImports::FileDownloadService do
described_class.new(
configuration: config,
relative_url: '/test',
- dir: tmpdir,
+ tmpdir: tmpdir,
filename: filename,
file_size_limit: file_size_limit,
allowed_content_types: allowed_content_types
@@ -72,7 +72,7 @@ RSpec.describe BulkImports::FileDownloadService do
service = described_class.new(
configuration: double,
relative_url: '/test',
- dir: tmpdir,
+ tmpdir: tmpdir,
filename: filename,
file_size_limit: file_size_limit,
allowed_content_types: allowed_content_types
@@ -157,7 +157,7 @@ RSpec.describe BulkImports::FileDownloadService do
described_class.new(
configuration: config,
relative_url: '/test',
- dir: tmpdir,
+ tmpdir: tmpdir,
filename: 'symlink',
file_size_limit: file_size_limit,
allowed_content_types: allowed_content_types
@@ -179,7 +179,7 @@ RSpec.describe BulkImports::FileDownloadService do
described_class.new(
configuration: config,
relative_url: '/test',
- dir: '/etc',
+ tmpdir: '/etc',
filename: filename,
file_size_limit: file_size_limit,
allowed_content_types: allowed_content_types
@@ -188,8 +188,28 @@ RSpec.describe BulkImports::FileDownloadService do
it 'raises an error' do
expect { subject.execute }.to raise_error(
- described_class::ServiceError,
- 'Invalid target directory'
+ StandardError,
+ 'path /etc is not allowed'
+ )
+ end
+ end
+
+ context 'when dir path is being traversed' do
+ subject do
+ described_class.new(
+ configuration: config,
+ relative_url: '/test',
+ tmpdir: File.join(Dir.mktmpdir('bulk_imports'), 'test', '..'),
+ filename: filename,
+ file_size_limit: file_size_limit,
+ allowed_content_types: allowed_content_types
+ )
+ end
+
+ it 'raises an error' do
+ expect { subject.execute }.to raise_error(
+ Gitlab::Utils::PathTraversalAttackError,
+ 'Invalid path'
)
end
end
diff --git a/spec/services/bulk_imports/file_export_service_spec.rb b/spec/services/bulk_imports/file_export_service_spec.rb
index 0d129c75384..94efceff6c6 100644
--- a/spec/services/bulk_imports/file_export_service_spec.rb
+++ b/spec/services/bulk_imports/file_export_service_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe BulkImports::FileExportService do
let_it_be(:project) { create(:project) }
let_it_be(:export_path) { Dir.mktmpdir }
- let_it_be(:relation) { 'uploads' }
+ let_it_be(:relation) { BulkImports::FileTransfer::BaseConfig::UPLOADS_RELATION }
subject(:service) { described_class.new(project, export_path, relation) }
@@ -20,6 +20,20 @@ RSpec.describe BulkImports::FileExportService do
subject.execute
end
+ context 'when relation is lfs objects' do
+ let_it_be(:relation) { BulkImports::FileTransfer::ProjectConfig::LFS_OBJECTS_RELATION }
+
+ it 'executes lfs objects export service' do
+ expect_next_instance_of(BulkImports::LfsObjectsExportService) do |service|
+ expect(service).to receive(:execute)
+ end
+
+ expect(subject).to receive(:tar_cf).with(archive: File.join(export_path, 'lfs_objects.tar'), dir: export_path)
+
+ subject.execute
+ end
+ end
+
context 'when unsupported relation is passed' do
it 'raises an error' do
service = described_class.new(project, export_path, 'unsupported')
diff --git a/spec/services/bulk_imports/lfs_objects_export_service_spec.rb b/spec/services/bulk_imports/lfs_objects_export_service_spec.rb
new file mode 100644
index 00000000000..5ae54ed309b
--- /dev/null
+++ b/spec/services/bulk_imports/lfs_objects_export_service_spec.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe BulkImports::LfsObjectsExportService do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:lfs_json_filename) { "#{BulkImports::FileTransfer::ProjectConfig::LFS_OBJECTS_RELATION}.json" }
+ let_it_be(:remote_url) { 'http://my-object-storage.local' }
+
+ let(:export_path) { Dir.mktmpdir }
+ let(:lfs_object) { create(:lfs_object, :with_file) }
+
+ subject(:service) { described_class.new(project, export_path) }
+
+ before do
+ stub_lfs_object_storage
+
+ %w(wiki design).each do |repository_type|
+ create(
+ :lfs_objects_project,
+ project: project,
+ repository_type: repository_type,
+ lfs_object: lfs_object
+ )
+ end
+
+ project.lfs_objects << lfs_object
+ end
+
+ after do
+ FileUtils.remove_entry(export_path) if Dir.exist?(export_path)
+ end
+
+ describe '#execute' do
+ it 'exports lfs objects and their repository types' do
+ filepath = File.join(export_path, lfs_json_filename)
+
+ service.execute
+
+ expect(File).to exist(File.join(export_path, lfs_object.oid))
+ expect(File).to exist(filepath)
+
+ lfs_json = Gitlab::Json.parse(File.read(filepath))
+
+ expect(lfs_json).to eq(
+ {
+ lfs_object.oid => [
+ LfsObjectsProject.repository_types['wiki'],
+ LfsObjectsProject.repository_types['design'],
+ nil
+ ]
+ }
+ )
+ end
+
+ context 'when lfs object is remotely stored' do
+ let(:lfs_object) { create(:lfs_object, :object_storage) }
+
+ it 'downloads lfs object from object storage' do
+ expect_next_instance_of(LfsObjectUploader) do |instance|
+ expect(instance).to receive(:url).and_return(remote_url)
+ end
+
+ expect(subject).to receive(:download).with(remote_url, File.join(export_path, lfs_object.oid))
+
+ service.execute
+ end
+ end
+ end
+end
diff --git a/spec/services/chat_names/authorize_user_service_spec.rb b/spec/services/chat_names/authorize_user_service_spec.rb
index b0bb741564d..53d90c7f100 100644
--- a/spec/services/chat_names/authorize_user_service_spec.rb
+++ b/spec/services/chat_names/authorize_user_service_spec.rb
@@ -4,10 +4,10 @@ require 'spec_helper'
RSpec.describe ChatNames::AuthorizeUserService do
describe '#execute' do
- subject { described_class.new(service, params) }
-
+ let(:integration) { create(:integration) }
let(:result) { subject.execute }
- let(:service) { create(:service) }
+
+ subject { described_class.new(integration, params) }
context 'when all parameters are valid' do
let(:params) { { team_id: 'T0001', team_domain: 'myteam', user_id: 'U0001', user_name: 'user' } }
diff --git a/spec/services/chat_names/find_user_service_spec.rb b/spec/services/chat_names/find_user_service_spec.rb
index 9bbad09cd0d..4b0a1204558 100644
--- a/spec/services/chat_names/find_user_service_spec.rb
+++ b/spec/services/chat_names/find_user_service_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe ChatNames::FindUserService, :clean_gitlab_redis_shared_state do
describe '#execute' do
- let(:integration) { create(:service) }
+ let(:integration) { create(:integration) }
subject { described_class.new(integration, params).execute }
diff --git a/spec/services/ci/after_requeue_job_service_spec.rb b/spec/services/ci/after_requeue_job_service_spec.rb
index 2465bac7d10..d2acf3ad2f1 100644
--- a/spec/services/ci/after_requeue_job_service_spec.rb
+++ b/spec/services/ci/after_requeue_job_service_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Ci::AfterRequeueJobService do
let_it_be(:project) { create(:project) }
- let_it_be(:user) { project.owner }
+ let_it_be(:user) { project.first_owner }
let(:pipeline) { create(:ci_pipeline, project: project) }
diff --git a/spec/services/ci/archive_trace_service_spec.rb b/spec/services/ci/archive_trace_service_spec.rb
index b08ba6fd5e5..bf2e5302d2e 100644
--- a/spec/services/ci/archive_trace_service_spec.rb
+++ b/spec/services/ci/archive_trace_service_spec.rb
@@ -15,6 +15,25 @@ RSpec.describe Ci::ArchiveTraceService, '#execute' do
expect(job.trace_metadata.trace_artifact).to eq(job.job_artifacts_trace)
end
+ context 'integration hooks' do
+ it do
+ stub_feature_flags(datadog_integration_logs_collection: [job.project])
+
+ expect(job.project).to receive(:execute_integrations) do |data, hook_type|
+ expect(data).to eq Gitlab::DataBuilder::ArchiveTrace.build(job)
+ expect(hook_type).to eq :archive_trace_hooks
+ end
+ expect { subject }.not_to raise_error
+ end
+
+ it 'with feature flag disabled' do
+ stub_feature_flags(datadog_integration_logs_collection: false)
+
+ expect(job.project).not_to receive(:execute_integrations)
+ expect { subject }.not_to raise_error
+ end
+ end
+
context 'when trace is already archived' do
let!(:job) { create(:ci_build, :success, :trace_artifact) }
diff --git a/spec/services/ci/create_downstream_pipeline_service_spec.rb b/spec/services/ci/create_downstream_pipeline_service_spec.rb
index 2237fd76d07..d61abf6a6ee 100644
--- a/spec/services/ci/create_downstream_pipeline_service_spec.rb
+++ b/spec/services/ci/create_downstream_pipeline_service_spec.rb
@@ -604,7 +604,7 @@ RSpec.describe Ci::CreateDownstreamPipelineService, '#execute' do
context 'when configured with bridge job rules' do
before do
stub_ci_pipeline_yaml_file(config)
- downstream_project.add_maintainer(upstream_project.owner)
+ downstream_project.add_maintainer(upstream_project.first_owner)
end
let(:config) do
@@ -622,13 +622,13 @@ RSpec.describe Ci::CreateDownstreamPipelineService, '#execute' do
end
let(:primary_pipeline) do
- Ci::CreatePipelineService.new(upstream_project, upstream_project.owner, { ref: 'master' })
+ Ci::CreatePipelineService.new(upstream_project, upstream_project.first_owner, { ref: 'master' })
.execute(:push, save_on_errors: false)
.payload
end
let(:bridge) { primary_pipeline.processables.find_by(name: 'bridge-job') }
- let(:service) { described_class.new(upstream_project, upstream_project.owner) }
+ let(:service) { described_class.new(upstream_project, upstream_project.first_owner) }
context 'that include the bridge job' do
it 'creates the downstream pipeline' do
diff --git a/spec/services/ci/create_pipeline_service/cache_spec.rb b/spec/services/ci/create_pipeline_service/cache_spec.rb
index f5f162e4578..ca85a8cce64 100644
--- a/spec/services/ci/create_pipeline_service/cache_spec.rb
+++ b/spec/services/ci/create_pipeline_service/cache_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
context 'cache' do
let(:project) { create(:project, :custom_repo, files: files) }
- let(:user) { project.owner }
+ let(:user) { project.first_owner }
let(:ref) { 'refs/heads/master' }
let(:source) { :push }
let(:service) { described_class.new(project, user, { ref: ref }) }
diff --git a/spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb b/spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb
index c69c91593ae..e62a94b6df8 100644
--- a/spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb
+++ b/spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
describe 'creation errors and warnings' do
let_it_be(:project) { create(:project, :repository) }
- let_it_be(:user) { project.owner }
+ let_it_be(:user) { project.first_owner }
let(:ref) { 'refs/heads/master' }
let(:source) { :push }
diff --git a/spec/services/ci/create_pipeline_service/custom_config_content_spec.rb b/spec/services/ci/create_pipeline_service/custom_config_content_spec.rb
index f150a4f8b51..a0cbf14d936 100644
--- a/spec/services/ci/create_pipeline_service/custom_config_content_spec.rb
+++ b/spec/services/ci/create_pipeline_service/custom_config_content_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
let_it_be(:project) { create(:project, :repository) }
- let_it_be(:user) { project.owner }
+ let_it_be(:user) { project.first_owner }
let(:ref) { 'refs/heads/master' }
let(:service) { described_class.new(project, user, { ref: ref }) }
diff --git a/spec/services/ci/create_pipeline_service/custom_yaml_tags_spec.rb b/spec/services/ci/create_pipeline_service/custom_yaml_tags_spec.rb
index 026111d59f1..716a929830e 100644
--- a/spec/services/ci/create_pipeline_service/custom_yaml_tags_spec.rb
+++ b/spec/services/ci/create_pipeline_service/custom_yaml_tags_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
describe '!reference tags' do
let_it_be(:project) { create(:project, :repository) }
- let_it_be(:user) { project.owner }
+ let_it_be(:user) { project.first_owner }
let(:ref) { 'refs/heads/master' }
let(:source) { :push }
diff --git a/spec/services/ci/create_pipeline_service/dry_run_spec.rb b/spec/services/ci/create_pipeline_service/dry_run_spec.rb
index ae43c63b516..9a7e97fb12b 100644
--- a/spec/services/ci/create_pipeline_service/dry_run_spec.rb
+++ b/spec/services/ci/create_pipeline_service/dry_run_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
let_it_be(:project) { create(:project, :repository) }
- let_it_be(:user) { project.owner }
+ let_it_be(:user) { project.first_owner }
let(:ref) { 'refs/heads/master' }
let(:service) { described_class.new(project, user, { ref: ref }) }
diff --git a/spec/services/ci/create_pipeline_service/include_spec.rb b/spec/services/ci/create_pipeline_service/include_spec.rb
index aa01977272a..3116801d50c 100644
--- a/spec/services/ci/create_pipeline_service/include_spec.rb
+++ b/spec/services/ci/create_pipeline_service/include_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
context 'include:' do
let_it_be(:project) { create(:project, :repository) }
- let_it_be(:user) { project.owner }
+ let_it_be(:user) { project.first_owner }
let(:ref) { 'refs/heads/master' }
let(:variables_attributes) { [{ key: 'MYVAR', secret_value: 'hello' }] }
diff --git a/spec/services/ci/create_pipeline_service/logger_spec.rb b/spec/services/ci/create_pipeline_service/logger_spec.rb
index dfe0859015d..53e5f0dd7f2 100644
--- a/spec/services/ci/create_pipeline_service/logger_spec.rb
+++ b/spec/services/ci/create_pipeline_service/logger_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
context 'pipeline logger' do
let_it_be(:project) { create(:project, :repository) }
- let_it_be(:user) { project.owner }
+ let_it_be(:user) { project.first_owner }
let(:ref) { 'refs/heads/master' }
let(:service) { described_class.new(project, user, { ref: ref }) }
@@ -35,7 +35,10 @@ RSpec.describe Ci::CreatePipelineService do
'pipeline_creation_service_duration_s' => a_kind_of(Numeric),
'pipeline_creation_duration_s' => counters,
'pipeline_size_count' => counters,
- 'pipeline_step_gitlab_ci_pipeline_chain_seed_duration_s' => counters
+ 'pipeline_step_gitlab_ci_pipeline_chain_seed_duration_s' => counters,
+ 'pipeline_seed_build_inclusion_duration_s' => counters,
+ 'pipeline_builds_tags_count' => a_kind_of(Numeric),
+ 'pipeline_builds_distinct_tags_count' => a_kind_of(Numeric)
}
end
@@ -81,7 +84,6 @@ RSpec.describe Ci::CreatePipelineService do
{
'pipeline_creation_caller' => 'Ci::CreatePipelineService',
'pipeline_source' => 'push',
- 'pipeline_id' => nil,
'pipeline_persisted' => false,
'project_id' => project.id,
'pipeline_creation_service_duration_s' => a_kind_of(Numeric),
diff --git a/spec/services/ci/create_pipeline_service/merge_requests_spec.rb b/spec/services/ci/create_pipeline_service/merge_requests_spec.rb
index a1f85faa69f..de19ef363fb 100644
--- a/spec/services/ci/create_pipeline_service/merge_requests_spec.rb
+++ b/spec/services/ci/create_pipeline_service/merge_requests_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
context 'merge requests handling' do
let_it_be(:project) { create(:project, :repository) }
- let_it_be(:user) { project.owner }
+ let_it_be(:user) { project.first_owner }
let(:ref) { 'refs/heads/feature' }
let(:source) { :push }
diff --git a/spec/services/ci/create_pipeline_service/needs_spec.rb b/spec/services/ci/create_pipeline_service/needs_spec.rb
index 9070d86f7f6..abd17ccdd6a 100644
--- a/spec/services/ci/create_pipeline_service/needs_spec.rb
+++ b/spec/services/ci/create_pipeline_service/needs_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
context 'needs' do
let_it_be(:project) { create(:project, :repository) }
- let_it_be(:user) { project.owner }
+ let_it_be(:user) { project.first_owner }
let(:ref) { 'refs/heads/master' }
let(:source) { :push }
diff --git a/spec/services/ci/create_pipeline_service/parallel_spec.rb b/spec/services/ci/create_pipeline_service/parallel_spec.rb
index 6b455bf4874..ae28b74fef5 100644
--- a/spec/services/ci/create_pipeline_service/parallel_spec.rb
+++ b/spec/services/ci/create_pipeline_service/parallel_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
let_it_be(:project) { create(:project, :repository) }
- let_it_be(:user) { project.owner }
+ let_it_be(:user) { project.first_owner }
let(:service) { described_class.new(project, user, { ref: 'master' }) }
let(:pipeline) { service.execute(:push).payload }
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 761504ffb58..c28bc9d8c13 100644
--- a/spec/services/ci/create_pipeline_service/parameter_content_spec.rb
+++ b/spec/services/ci/create_pipeline_service/parameter_content_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
let_it_be(:project) { create(:project, :repository) }
- let_it_be(:user) { project.owner }
+ let_it_be(:user) { project.first_owner }
let(:service) { described_class.new(project, user, { ref: 'refs/heads/master' }) }
let(:content) do
diff --git a/spec/services/ci/create_pipeline_service/pre_post_stages_spec.rb b/spec/services/ci/create_pipeline_service/pre_post_stages_spec.rb
index 5e34eeb99db..c6e69862422 100644
--- a/spec/services/ci/create_pipeline_service/pre_post_stages_spec.rb
+++ b/spec/services/ci/create_pipeline_service/pre_post_stages_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
describe '.pre/.post stages' do
let_it_be(:project) { create(:project, :repository) }
- let_it_be(:user) { project.owner }
+ let_it_be(:user) { project.first_owner }
let(:source) { :push }
let(:service) { described_class.new(project, user, { ref: ref }) }
diff --git a/spec/services/ci/create_pipeline_service/rules_spec.rb b/spec/services/ci/create_pipeline_service/rules_spec.rb
index d0915f099de..d0ce1c5aba8 100644
--- a/spec/services/ci/create_pipeline_service/rules_spec.rb
+++ b/spec/services/ci/create_pipeline_service/rules_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
let(:project) { create(:project, :repository) }
- let(:user) { project.owner }
+ let(:user) { project.first_owner }
let(:ref) { 'refs/heads/master' }
let(:source) { :push }
let(:service) { described_class.new(project, user, { ref: ref }) }
diff --git a/spec/services/ci/create_pipeline_service/tags_spec.rb b/spec/services/ci/create_pipeline_service/tags_spec.rb
index cbbeb870c5f..61c2415fa33 100644
--- a/spec/services/ci/create_pipeline_service/tags_spec.rb
+++ b/spec/services/ci/create_pipeline_service/tags_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
describe 'tags:' do
let_it_be(:project) { create(:project, :repository) }
- let_it_be(:user) { project.owner }
+ let_it_be(:user) { project.first_owner }
let(:ref) { 'refs/heads/master' }
let(:service) { described_class.new(project, user, { ref: ref }) }
diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb
index ef879d536c3..a7026f5062e 100644
--- a/spec/services/ci/create_pipeline_service_spec.rb
+++ b/spec/services/ci/create_pipeline_service_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Ci::CreatePipelineService do
include ProjectForksHelper
let_it_be_with_refind(:project) { create(:project, :repository) }
- let_it_be_with_reload(:user) { project.owner }
+ let_it_be_with_reload(:user) { project.first_owner }
let(:ref_name) { 'refs/heads/master' }
@@ -146,140 +146,22 @@ RSpec.describe Ci::CreatePipelineService do
end
context 'when merge requests already exist for this source branch' do
- let(:merge_request_1) do
+ let!(:merge_request_1) do
create(:merge_request, source_branch: 'feature', target_branch: "master", source_project: project)
end
- let(:merge_request_2) do
+ let!(:merge_request_2) do
create(:merge_request, source_branch: 'feature', target_branch: "v1.1.0", source_project: project)
end
- context 'when related merge request is already merged' do
- let!(:merged_merge_request) do
- create(:merge_request, source_branch: 'master', target_branch: "branch_2", source_project: project, state: 'merged')
- end
-
- it 'does not schedule update head pipeline job' do
- expect(UpdateHeadPipelineForMergeRequestWorker).not_to receive(:perform_async).with(merged_merge_request.id)
-
- execute_service
- end
- end
-
context 'when the head pipeline sha equals merge request sha' do
it 'updates head pipeline of each merge request', :sidekiq_might_not_need_inline do
- merge_request_1
- merge_request_2
-
head_pipeline = execute_service(ref: 'feature', after: nil).payload
expect(merge_request_1.reload.head_pipeline).to eq(head_pipeline)
expect(merge_request_2.reload.head_pipeline).to eq(head_pipeline)
end
end
-
- context 'when the head pipeline sha does not equal merge request sha' do
- it 'does not update the head piepeline of MRs' do
- merge_request_1
- merge_request_2
-
- allow_any_instance_of(Ci::Pipeline).to receive(:latest?).and_return(true)
-
- expect { execute_service(after: 'ae73cb07c9eeaf35924a10f713b364d32b2dd34f') }.not_to raise_error
-
- last_pipeline = Ci::Pipeline.last
-
- expect(merge_request_1.reload.head_pipeline).not_to eq(last_pipeline)
- expect(merge_request_2.reload.head_pipeline).not_to eq(last_pipeline)
- end
- end
-
- context 'when there is no pipeline for source branch' do
- it "does not update merge request head pipeline" do
- merge_request = create(:merge_request, source_branch: 'feature',
- target_branch: "branch_1",
- source_project: project)
-
- head_pipeline = execute_service.payload
-
- expect(merge_request.reload.head_pipeline).not_to eq(head_pipeline)
- end
- end
-
- context 'when merge request target project is different from source project' do
- let!(:project) { fork_project(target_project, nil, repository: true) }
- let!(:target_project) { create(:project, :repository) }
- let!(:user) { create(:user) }
-
- before do
- project.add_developer(user)
- end
-
- it 'updates head pipeline for merge request', :sidekiq_might_not_need_inline do
- merge_request = create(:merge_request, source_branch: 'feature',
- target_branch: "master",
- source_project: project,
- target_project: target_project)
-
- head_pipeline = execute_service(ref: 'feature', after: nil).payload
-
- expect(merge_request.reload.head_pipeline).to eq(head_pipeline)
- end
- end
-
- context 'when the pipeline is not the latest for the branch' do
- it 'does not update merge request head pipeline' do
- merge_request = create(:merge_request, source_branch: 'master',
- target_branch: "branch_1",
- source_project: project)
-
- allow_any_instance_of(MergeRequest)
- .to receive(:find_actual_head_pipeline) { }
-
- execute_service
-
- expect(merge_request.reload.head_pipeline).to be_nil
- end
- end
-
- context 'when pipeline has errors' do
- before do
- stub_ci_pipeline_yaml_file('some invalid syntax')
- end
-
- it 'updates merge request head pipeline reference', :sidekiq_might_not_need_inline do
- merge_request = create(:merge_request, source_branch: 'master',
- target_branch: 'feature',
- source_project: project)
-
- head_pipeline = execute_service.payload
-
- expect(head_pipeline).to be_persisted
- expect(head_pipeline.yaml_errors).to be_present
- expect(head_pipeline.messages).to be_present
- expect(merge_request.reload.head_pipeline).to eq head_pipeline
- end
- end
-
- context 'when pipeline has been skipped' do
- before do
- allow_any_instance_of(Ci::Pipeline)
- .to receive(:git_commit_message)
- .and_return('some commit [ci skip]')
- end
-
- it 'updates merge request head pipeline', :sidekiq_might_not_need_inline do
- merge_request = create(:merge_request, source_branch: 'master',
- target_branch: 'feature',
- source_project: project)
-
- head_pipeline = execute_service.payload
-
- expect(head_pipeline).to be_skipped
- expect(head_pipeline).to be_persisted
- expect(merge_request.reload.head_pipeline).to eq head_pipeline
- end
- end
end
context 'auto-cancel enabled' do
@@ -1655,7 +1537,7 @@ RSpec.describe Ci::CreatePipelineService do
expect(pipeline.target_sha).to be_nil
end
- it 'schedules update for the head pipeline of the merge request' do
+ it 'schedules update for the head pipeline of the merge request', :sidekiq_inline do
expect(UpdateHeadPipelineForMergeRequestWorker)
.to receive(:perform_async).with(merge_request.id)
diff --git a/spec/services/ci/destroy_pipeline_service_spec.rb b/spec/services/ci/destroy_pipeline_service_spec.rb
index 6c1c02b2875..045051c7152 100644
--- a/spec/services/ci/destroy_pipeline_service_spec.rb
+++ b/spec/services/ci/destroy_pipeline_service_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe ::Ci::DestroyPipelineService do
subject { described_class.new(project, user).execute(pipeline) }
context 'user is owner' do
- let(:user) { project.owner }
+ let(:user) { project.first_owner }
it 'destroys the pipeline' do
subject
@@ -66,6 +66,28 @@ RSpec.describe ::Ci::DestroyPipelineService do
expect { subject }.to change { Ci::DeletedObject.count }
end
end
+
+ context 'when job has trace chunks' do
+ let(:connection_params) { Gitlab.config.artifacts.object_store.connection.symbolize_keys }
+ let(:connection) { ::Fog::Storage.new(connection_params) }
+
+ before do
+ stub_object_storage(connection_params: connection_params, remote_directory: 'artifacts')
+ stub_artifacts_object_storage
+ end
+
+ let!(:trace_chunk) { create(:ci_build_trace_chunk, :fog_with_data, build: build) }
+
+ it 'destroys associated trace chunks' do
+ subject
+
+ expect { trace_chunk.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+
+ it 'removes data from object store' do
+ expect { subject }.to change { Ci::BuildTraceChunks::Fog.new.data(trace_chunk) }
+ end
+ end
end
context 'when pipeline is in cancelable state' do
diff --git a/spec/services/ci/job_artifacts/delete_project_artifacts_service_spec.rb b/spec/services/ci/job_artifacts/delete_project_artifacts_service_spec.rb
new file mode 100644
index 00000000000..74fa42962f3
--- /dev/null
+++ b/spec/services/ci/job_artifacts/delete_project_artifacts_service_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::JobArtifacts::DeleteProjectArtifactsService do
+ let_it_be(:project) { create(:project) }
+
+ subject { described_class.new(project: project) }
+
+ describe '#execute' do
+ it 'enqueues a Ci::ExpireProjectBuildArtifactsWorker' do
+ expect(Ci::JobArtifacts::ExpireProjectBuildArtifactsWorker).to receive(:perform_async).with(project.id).and_call_original
+
+ subject.execute
+ end
+ end
+end
diff --git a/spec/services/ci/job_artifacts/destroy_all_expired_service_spec.rb b/spec/services/ci/job_artifacts/destroy_all_expired_service_spec.rb
index e71f1a4266a..e95a449d615 100644
--- a/spec/services/ci/job_artifacts/destroy_all_expired_service_spec.rb
+++ b/spec/services/ci/job_artifacts/destroy_all_expired_service_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe Ci::JobArtifacts::DestroyAllExpiredService, :clean_gitlab_redis_s
context 'with preloaded relationships' do
before do
- stub_const("#{described_class}::LOOP_LIMIT", 1)
+ stub_const("#{described_class}::LARGE_LOOP_LIMIT", 1)
end
context 'with ci_destroy_unlocked_job_artifacts feature flag disabled' do
@@ -53,46 +53,6 @@ RSpec.describe Ci::JobArtifacts::DestroyAllExpiredService, :clean_gitlab_redis_s
log = ActiveRecord::QueryRecorder.new { subject }
expect(log.count).to be_within(1).of(8)
end
-
- context 'with several locked-unknown artifact records' do
- before do
- stub_const("#{described_class}::LOOP_LIMIT", 10)
- stub_const("#{described_class}::BATCH_SIZE", 2)
- end
-
- let!(:lockable_artifact_records) do
- [
- create(:ci_job_artifact, :metadata, :expired, locked: ::Ci::JobArtifact.lockeds[:unknown], job: locked_job),
- create(:ci_job_artifact, :junit, :expired, locked: ::Ci::JobArtifact.lockeds[:unknown], job: locked_job),
- create(:ci_job_artifact, :sast, :expired, locked: ::Ci::JobArtifact.lockeds[:unknown], job: locked_job),
- create(:ci_job_artifact, :cobertura, :expired, locked: ::Ci::JobArtifact.lockeds[:unknown], job: locked_job),
- create(:ci_job_artifact, :trace, :expired, locked: ::Ci::JobArtifact.lockeds[:unknown], job: locked_job)
- ]
- end
-
- let!(:unlockable_artifact_records) do
- [
- create(:ci_job_artifact, :metadata, :expired, locked: ::Ci::JobArtifact.lockeds[:unknown], job: job),
- create(:ci_job_artifact, :junit, :expired, locked: ::Ci::JobArtifact.lockeds[:unknown], job: job),
- create(:ci_job_artifact, :sast, :expired, locked: ::Ci::JobArtifact.lockeds[:unknown], job: job),
- create(:ci_job_artifact, :cobertura, :expired, locked: ::Ci::JobArtifact.lockeds[:unknown], job: job),
- create(:ci_job_artifact, :trace, :expired, locked: ::Ci::JobArtifact.lockeds[:unknown], job: job),
- artifact
- ]
- end
-
- it 'updates the locked status of job artifacts from artifacts-locked pipelines' do
- subject
-
- expect(lockable_artifact_records).to be_all(&:persisted?)
- expect(lockable_artifact_records).to be_all { |artifact| artifact.reload.artifact_artifacts_locked? }
- end
-
- it 'unlocks and then destroys job artifacts from artifacts-unlocked pipelines' do
- expect { subject }.to change { Ci::JobArtifact.count }.by(-6)
- expect(Ci::JobArtifact.where(id: unlockable_artifact_records.map(&:id))).to be_empty
- end
- end
end
end
@@ -159,7 +119,7 @@ RSpec.describe Ci::JobArtifacts::DestroyAllExpiredService, :clean_gitlab_redis_s
let!(:artifact) { create(:ci_job_artifact, :expired, job: job, locked: job.pipeline.locked) }
before do
- stub_const("#{described_class}::LOOP_LIMIT", 10)
+ stub_const("#{described_class}::LARGE_LOOP_LIMIT", 10)
end
context 'when the import fails' do
@@ -229,7 +189,8 @@ RSpec.describe Ci::JobArtifacts::DestroyAllExpiredService, :clean_gitlab_redis_s
context 'when loop reached loop limit' do
before do
- stub_const("#{described_class}::LOOP_LIMIT", 1)
+ stub_feature_flags(ci_artifact_fast_removal_large_loop_limit: false)
+ stub_const("#{described_class}::SMALL_LOOP_LIMIT", 1)
end
it 'destroys one artifact' do
diff --git a/spec/services/ci/job_artifacts/expire_project_build_artifacts_service_spec.rb b/spec/services/ci/job_artifacts/expire_project_build_artifacts_service_spec.rb
new file mode 100644
index 00000000000..fb9dd6b876b
--- /dev/null
+++ b/spec/services/ci/job_artifacts/expire_project_build_artifacts_service_spec.rb
@@ -0,0 +1,157 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::JobArtifacts::ExpireProjectBuildArtifactsService do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:pipeline, reload: true) { create(:ci_pipeline, :unlocked, project: project) }
+
+ let(:expiry_time) { Time.current }
+
+ RSpec::Matchers.define :have_locked_status do |expected_status|
+ match do |job_artifacts|
+ predicate = "#{expected_status}?".to_sym
+ job_artifacts.all? { |artifact| artifact.__send__(predicate) }
+ end
+ end
+
+ RSpec::Matchers.define :expire_at do |expected_expiry|
+ match do |job_artifacts|
+ job_artifacts.all? { |artifact| artifact.expire_at.to_i == expected_expiry.to_i }
+ end
+ end
+
+ RSpec::Matchers.define :have_no_expiry do
+ match do |job_artifacts|
+ job_artifacts.all? { |artifact| artifact.expire_at.nil? }
+ end
+ end
+
+ describe '#execute' do
+ subject(:execute) { described_class.new(project.id, expiry_time).execute }
+
+ context 'with job containing erasable artifacts' do
+ let_it_be(:job, reload: true) { create(:ci_build, :erasable, pipeline: pipeline) }
+
+ it 'unlocks erasable job artifacts' do
+ execute
+
+ expect(job.job_artifacts).to have_locked_status(:artifact_unlocked)
+ end
+
+ it 'expires erasable job artifacts' do
+ execute
+
+ expect(job.job_artifacts).to expire_at(expiry_time)
+ end
+ end
+
+ context 'with job containing trace artifacts' do
+ let_it_be(:job, reload: true) { create(:ci_build, :trace_artifact, pipeline: pipeline) }
+
+ it 'does not unlock trace artifacts' do
+ execute
+
+ expect(job.job_artifacts).to have_locked_status(:artifact_unknown)
+ end
+
+ it 'does not expire trace artifacts' do
+ execute
+
+ expect(job.job_artifacts).to have_no_expiry
+ end
+ end
+
+ context 'with job from artifact locked pipeline' do
+ let_it_be(:job, reload: true) { create(:ci_build, pipeline: pipeline) }
+ let_it_be(:locked_artifact, reload: true) { create(:ci_job_artifact, :locked, job: job) }
+
+ before do
+ pipeline.artifacts_locked!
+ end
+
+ it 'does not unlock locked artifacts' do
+ execute
+
+ expect(job.job_artifacts).to have_locked_status(:artifact_artifacts_locked)
+ end
+
+ it 'does not expire locked artifacts' do
+ execute
+
+ expect(job.job_artifacts).to have_no_expiry
+ end
+ end
+
+ context 'with job containing both erasable and trace artifacts' do
+ let_it_be(:job, reload: true) { create(:ci_build, pipeline: pipeline) }
+ let_it_be(:erasable_artifact, reload: true) { create(:ci_job_artifact, :archive, job: job) }
+ let_it_be(:trace_artifact, reload: true) { create(:ci_job_artifact, :trace, job: job) }
+
+ it 'unlocks erasable artifacts' do
+ execute
+
+ expect(erasable_artifact.artifact_unlocked?).to be_truthy
+ end
+
+ it 'expires erasable artifacts' do
+ execute
+
+ expect(erasable_artifact.expire_at.to_i).to eq(expiry_time.to_i)
+ end
+
+ it 'does not unlock trace artifacts' do
+ execute
+
+ expect(trace_artifact.artifact_unlocked?).to be_falsey
+ end
+
+ it 'does not expire trace artifacts' do
+ execute
+
+ expect(trace_artifact.expire_at).to be_nil
+ end
+ end
+
+ context 'with multiple pipelines' do
+ let_it_be(:job, reload: true) { create(:ci_build, :erasable, pipeline: pipeline) }
+
+ let_it_be(:pipeline2, reload: true) { create(:ci_pipeline, :unlocked, project: project) }
+ let_it_be(:job2, reload: true) { create(:ci_build, :erasable, pipeline: pipeline) }
+
+ it 'unlocks artifacts across pipelines' do
+ execute
+
+ expect(job.job_artifacts).to have_locked_status(:artifact_unlocked)
+ expect(job2.job_artifacts).to have_locked_status(:artifact_unlocked)
+ end
+
+ it 'expires artifacts across pipelines' do
+ execute
+
+ expect(job.job_artifacts).to expire_at(expiry_time)
+ expect(job2.job_artifacts).to expire_at(expiry_time)
+ end
+ end
+
+ context 'with artifacts belonging to another project' do
+ let_it_be(:job, reload: true) { create(:ci_build, :erasable, pipeline: pipeline) }
+
+ let_it_be(:another_project, reload: true) { create(:project) }
+ let_it_be(:another_pipeline, reload: true) { create(:ci_pipeline, project: another_project) }
+ let_it_be(:another_job, reload: true) { create(:ci_build, :erasable, pipeline: another_pipeline) }
+
+ it 'does not unlock erasable artifacts in other projects' do
+ execute
+
+ expect(another_job.job_artifacts).to have_locked_status(:artifact_unknown)
+ end
+
+ it 'does not expire erasable artifacts in other projects' do
+ execute
+
+ expect(another_job.job_artifacts).to have_no_expiry
+ end
+ end
+ end
+end
diff --git a/spec/services/ci/pipeline_processing/atomic_processing_service_spec.rb b/spec/services/ci/pipeline_processing/atomic_processing_service_spec.rb
index 31e1b0a896d..26bc6f747e1 100644
--- a/spec/services/ci/pipeline_processing/atomic_processing_service_spec.rb
+++ b/spec/services/ci/pipeline_processing/atomic_processing_service_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Ci::PipelineProcessing::AtomicProcessingService do
describe 'Pipeline Processing Service Tests With Yaml' do
let_it_be(:project) { create(:project, :repository) }
- let_it_be(:user) { project.owner }
+ let_it_be(:user) { project.first_owner }
where(:test_file_path) do
Dir.glob(Rails.root.join('spec/services/ci/pipeline_processing/test_cases/*.yml'))
@@ -65,7 +65,7 @@ RSpec.describe Ci::PipelineProcessing::AtomicProcessingService do
describe 'Pipeline Processing Service' do
let(:project) { create(:project, :repository) }
- let(:user) { project.owner }
+ let(:user) { project.first_owner }
let(:pipeline) do
create(:ci_empty_pipeline, ref: 'master', project: project)
diff --git a/spec/services/ci/pipelines/add_job_service_spec.rb b/spec/services/ci/pipelines/add_job_service_spec.rb
index 709a840c644..560724a1c6a 100644
--- a/spec/services/ci/pipelines/add_job_service_spec.rb
+++ b/spec/services/ci/pipelines/add_job_service_spec.rb
@@ -31,7 +31,7 @@ RSpec.describe Ci::Pipelines::AddJobService do
execute
end.to change { job.slice(:pipeline, :project, :ref) }.to(
pipeline: pipeline, project: pipeline.project, ref: pipeline.ref
- )
+ ).and change { job.metadata.project }.to(pipeline.project)
end
it 'returns a service response with the job as payload' do
diff --git a/spec/services/ci/play_build_service_spec.rb b/spec/services/ci/play_build_service_spec.rb
index 34f77260334..85ef8b60af4 100644
--- a/spec/services/ci/play_build_service_spec.rb
+++ b/spec/services/ci/play_build_service_spec.rb
@@ -122,7 +122,7 @@ RSpec.describe Ci::PlayBuildService, '#execute' do
end
context 'when build is not a playable manual action' do
- let(:build) { create(:ci_build, when: :manual, pipeline: pipeline) }
+ let(:build) { create(:ci_build, :success, pipeline: pipeline) }
let!(:branch) { create(:protected_branch, :developers_can_merge, name: build.ref, project: project) }
it 'duplicates the build' do
@@ -138,6 +138,18 @@ RSpec.describe Ci::PlayBuildService, '#execute' do
expect(build.user).not_to eq user
expect(duplicate.user).to eq user
end
+
+ context 'and is not retryable' do
+ let(:build) { create(:ci_build, :deployment_rejected, pipeline: pipeline) }
+
+ it 'does not duplicate the build' do
+ expect { service.execute(build) }.not_to change { Ci::Build.count }
+ end
+
+ it 'does not enqueue the build' do
+ expect { service.execute(build) }.not_to change { build.status }
+ end
+ end
end
context 'when build is not action' do
diff --git a/spec/services/ci/process_sync_events_service_spec.rb b/spec/services/ci/process_sync_events_service_spec.rb
index 00b670ff54f..8b7717fe4bf 100644
--- a/spec/services/ci/process_sync_events_service_spec.rb
+++ b/spec/services/ci/process_sync_events_service_spec.rb
@@ -28,10 +28,10 @@ RSpec.describe Ci::ProcessSyncEventsService do
it 'consumes events' do
expect { execute }.to change(Projects::SyncEvent, :count).from(2).to(0)
- expect(project1.ci_project_mirror).to have_attributes(
+ expect(project1.reload.ci_project_mirror).to have_attributes(
namespace_id: parent_group_1.id
)
- expect(project2.ci_project_mirror).to have_attributes(
+ expect(project2.reload.ci_project_mirror).to have_attributes(
namespace_id: parent_group_2.id
)
end
@@ -71,6 +71,24 @@ RSpec.describe Ci::ProcessSyncEventsService do
expect { execute }.not_to change(Projects::SyncEvent, :count)
end
end
+
+ it 'does not delete non-executed events' do
+ new_project = create(:project)
+ sync_event_class.delete_all
+
+ project1.update!(group: parent_group_2)
+ new_project.update!(group: parent_group_1)
+ project2.update!(group: parent_group_1)
+
+ new_project_sync_event = new_project.sync_events.last
+
+ allow(sync_event_class).to receive(:preload_synced_relation).and_return(
+ sync_event_class.where.not(id: new_project_sync_event)
+ )
+
+ expect { execute }.to change(Projects::SyncEvent, :count).from(3).to(1)
+ expect(new_project_sync_event.reload).to be_persisted
+ end
end
context 'for Namespaces::SyncEvent' do
@@ -88,10 +106,10 @@ RSpec.describe Ci::ProcessSyncEventsService do
it 'consumes events' do
expect { execute }.to change(Namespaces::SyncEvent, :count).from(2).to(0)
- expect(group.ci_namespace_mirror).to have_attributes(
+ expect(group.reload.ci_namespace_mirror).to have_attributes(
traversal_ids: [parent_group_1.id, parent_group_2.id, group.id]
)
- expect(parent_group_2.ci_namespace_mirror).to have_attributes(
+ expect(parent_group_2.reload.ci_namespace_mirror).to have_attributes(
traversal_ids: [parent_group_1.id, parent_group_2.id]
)
end
diff --git a/spec/services/ci/register_job_service_spec.rb b/spec/services/ci/register_job_service_spec.rb
index 866015aa523..251159864f5 100644
--- a/spec/services/ci/register_job_service_spec.rb
+++ b/spec/services/ci/register_job_service_spec.rb
@@ -827,11 +827,17 @@ module Ci
end
context 'when project already has running jobs' do
- let!(:build2) { create(:ci_build, :running, pipeline: pipeline, runner: shared_runner) }
- let!(:build3) { create(:ci_build, :running, pipeline: pipeline, runner: shared_runner) }
+ let(:build2) { create(:ci_build, :running, pipeline: pipeline, runner: shared_runner) }
+ let(:build3) { create(:ci_build, :running, pipeline: pipeline, runner: shared_runner) }
+
+ before do
+ ::Ci::RunningBuild.upsert_shared_runner_build!(build2)
+ ::Ci::RunningBuild.upsert_shared_runner_build!(build3)
+ end
it 'counts job queuing time histogram with expected labels' do
allow(attempt_counter).to receive(:increment)
+
expect(job_queue_duration_seconds).to receive(:observe)
.with({ shared_runner: expected_shared_runner,
jobs_running_for_project: expected_jobs_running_for_project_third_job,
@@ -845,6 +851,14 @@ module Ci
shared_examples 'metrics collector' do
it_behaves_like 'attempt counter collector'
it_behaves_like 'jobs queueing time histogram collector'
+
+ context 'when using denormalized data is disabled' do
+ before do
+ stub_feature_flags(ci_pending_builds_maintain_denormalized_data: false)
+ end
+
+ it_behaves_like 'jobs queueing time histogram collector'
+ end
end
context 'when shared runner is used' do
@@ -875,6 +889,16 @@ module Ci
it_behaves_like 'metrics collector'
end
+ context 'when max running jobs bucket size is exceeded' do
+ before do
+ stub_const('Gitlab::Ci::Queue::Metrics::JOBS_RUNNING_FOR_PROJECT_MAX_BUCKET', 1)
+ end
+
+ let(:expected_jobs_running_for_project_third_job) { '1+' }
+
+ it_behaves_like 'metrics collector'
+ end
+
context 'when pending job with queued_at=nil is used' do
before do
pending_job.update!(queued_at: nil)
diff --git a/spec/services/ci/register_runner_service_spec.rb b/spec/services/ci/register_runner_service_spec.rb
new file mode 100644
index 00000000000..e813a1d8b31
--- /dev/null
+++ b/spec/services/ci/register_runner_service_spec.rb
@@ -0,0 +1,226 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Ci::RegisterRunnerService do
+ let(:registration_token) { 'abcdefg123456' }
+
+ 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
+
+ describe '#execute' do
+ let(:token) { }
+ let(:args) { {} }
+
+ 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
+ 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
+end
diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb
index 5d56084faa8..4e8e41ca6e6 100644
--- a/spec/services/ci/retry_build_service_spec.rb
+++ b/spec/services/ci/retry_build_service_spec.rb
@@ -188,13 +188,6 @@ RSpec.describe Ci::RetryBuildService do
expect(new_build).to be_pending
end
- it 'resolves todos for old build that failed' do
- expect(::MergeRequests::AddTodoWhenBuildFailsService)
- .to receive_message_chain(:new, :close)
-
- service.execute(build)
- end
-
context 'when there are subsequent processables that are skipped' do
let!(:subsequent_build) do
create(:ci_build, :skipped, stage_idx: 2,
@@ -272,6 +265,17 @@ RSpec.describe Ci::RetryBuildService do
expect(bridge.reload).to be_pending
end
end
+
+ context 'when there is a failed job todo for the MR' do
+ let!(:merge_request) { create(:merge_request, source_project: project, author: user, head_pipeline: pipeline) }
+ let!(:todo) { create(:todo, :build_failed, user: user, project: project, author: user, target: merge_request) }
+
+ it 'resolves the todo for the old failed build' do
+ expect do
+ service.execute(build)
+ end.to change { todo.reload.state }.from('pending').to('done')
+ end
+ end
end
context 'when user does not have ability to execute build' do
@@ -367,6 +371,14 @@ RSpec.describe Ci::RetryBuildService do
it_behaves_like 'when build with dynamic environment is retried'
context 'when create_deployment_in_separate_transaction feature flag is disabled' do
+ let(:new_build) do
+ travel_to(1.second.from_now) do
+ ::Gitlab::Database::QueryAnalyzers::PreventCrossDatabaseModification.allow_cross_database_modification_within_transaction(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/345668') do
+ service.clone!(build)
+ end
+ end
+ end
+
before do
stub_feature_flags(create_deployment_in_separate_transaction: false)
end
diff --git a/spec/services/clusters/agent_tokens/track_usage_service_spec.rb b/spec/services/clusters/agent_tokens/track_usage_service_spec.rb
new file mode 100644
index 00000000000..3350b15a5ce
--- /dev/null
+++ b/spec/services/clusters/agent_tokens/track_usage_service_spec.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Clusters::AgentTokens::TrackUsageService do
+ let_it_be(:agent) { create(:cluster_agent) }
+
+ describe '#execute', :clean_gitlab_redis_cache do
+ let(:agent_token) { create(:cluster_agent_token, agent: agent) }
+
+ subject { described_class.new(agent_token).execute }
+
+ context 'when last_used_at was updated recently' do
+ before do
+ agent_token.update!(last_used_at: 10.minutes.ago)
+ end
+
+ it 'updates cache but not database' do
+ expect { subject }.not_to change { agent_token.reload.read_attribute(:last_used_at) }
+
+ expect_redis_update
+ end
+ end
+
+ context 'when last_used_at was not updated recently' do
+ it 'updates cache and database' do
+ does_db_update
+ expect_redis_update
+ end
+
+ context 'with invalid token' do
+ before do
+ agent_token.description = SecureRandom.hex(2000)
+ end
+
+ it 'still updates caches and database' do
+ expect(agent_token).to be_invalid
+
+ does_db_update
+ expect_redis_update
+ end
+ end
+
+ context 'agent is not connected' do
+ before do
+ allow(agent).to receive(:connected?).and_return(false)
+ end
+
+ it 'creates an activity event' do
+ expect { subject }.to change { agent.activity_events.count }
+
+ event = agent.activity_events.last
+ expect(event).to have_attributes(
+ kind: 'agent_connected',
+ level: 'info',
+ recorded_at: agent_token.reload.read_attribute(:last_used_at),
+ agent_token: agent_token
+ )
+ end
+ end
+
+ context 'agent is connected' do
+ before do
+ allow(agent).to receive(:connected?).and_return(true)
+ end
+
+ it 'does not create an activity event' do
+ expect { subject }.not_to change { agent.activity_events.count }
+ end
+ end
+ end
+
+ def expect_redis_update
+ Gitlab::Redis::Cache.with do |redis|
+ redis_key = "cache:#{agent_token.class}:#{agent_token.id}:attributes"
+ expect(redis.get(redis_key)).to be_present
+ end
+ end
+
+ def does_db_update
+ expect { subject }.to change { agent_token.reload.read_attribute(:last_used_at) }
+ end
+ end
+end
diff --git a/spec/services/clusters/agents/create_activity_event_service_spec.rb b/spec/services/clusters/agents/create_activity_event_service_spec.rb
new file mode 100644
index 00000000000..7a8f0e16d60
--- /dev/null
+++ b/spec/services/clusters/agents/create_activity_event_service_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Clusters::Agents::CreateActivityEventService do
+ let_it_be(:agent) { create(:cluster_agent) }
+ let_it_be(:token) { create(:cluster_agent_token, agent: agent) }
+ let_it_be(:user) { create(:user) }
+
+ describe '#execute' do
+ let(:params) do
+ {
+ kind: :token_created,
+ level: :info,
+ recorded_at: token.created_at,
+ user: user,
+ agent_token: token
+ }
+ end
+
+ subject { described_class.new(agent, **params).execute }
+
+ it 'creates an activity event record' do
+ expect { subject }.to change(agent.activity_events, :count).from(0).to(1)
+
+ event = agent.activity_events.last
+
+ expect(event).to have_attributes(
+ kind: 'token_created',
+ level: 'info',
+ recorded_at: token.reload.created_at,
+ user: user,
+ agent_token_id: token.id
+ )
+ end
+
+ it 'schedules the cleanup worker' do
+ expect(Clusters::Agents::DeleteExpiredEventsWorker).to receive(:perform_at)
+ .with(1.hour.from_now.change(min: agent.id % 60), agent.id)
+
+ subject
+ end
+ end
+end
diff --git a/spec/services/clusters/agents/delete_expired_events_service_spec.rb b/spec/services/clusters/agents/delete_expired_events_service_spec.rb
new file mode 100644
index 00000000000..3dc166f54eb
--- /dev/null
+++ b/spec/services/clusters/agents/delete_expired_events_service_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Clusters::Agents::DeleteExpiredEventsService do
+ let_it_be(:agent) { create(:cluster_agent) }
+
+ describe '#execute' do
+ let_it_be(:event1) { create(:agent_activity_event, agent: agent, recorded_at: 1.hour.ago) }
+ let_it_be(:event2) { create(:agent_activity_event, agent: agent, recorded_at: 2.hours.ago) }
+ let_it_be(:event3) { create(:agent_activity_event, agent: agent, recorded_at: 3.hours.ago) }
+ let_it_be(:event4) { create(:agent_activity_event, agent: agent, recorded_at: 4.hours.ago) }
+ let_it_be(:event5) { create(:agent_activity_event, agent: agent, recorded_at: 5.hours.ago) }
+
+ let(:deletion_cutoff) { 1.day.ago }
+
+ subject { described_class.new(agent).execute }
+
+ before do
+ allow(agent).to receive(:activity_event_deletion_cutoff).and_return(deletion_cutoff)
+ end
+
+ it 'does not delete events if the limit has not been reached' do
+ expect { subject }.not_to change(agent.activity_events, :count)
+ end
+
+ context 'there are more events than the limit' do
+ let(:deletion_cutoff) { event3.recorded_at }
+
+ it 'removes events to remain at the limit, keeping the most recent' do
+ expect { subject }.to change(agent.activity_events, :count).from(5).to(3)
+ expect(agent.activity_events).to contain_exactly(event1, event2, event3)
+ end
+ end
+ end
+end
diff --git a/spec/services/clusters/integrations/create_service_spec.rb b/spec/services/clusters/integrations/create_service_spec.rb
index 14653236ab1..6dac97ebf8f 100644
--- a/spec/services/clusters/integrations/create_service_spec.rb
+++ b/spec/services/clusters/integrations/create_service_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Clusters::Integrations::CreateService, '#execute' do
let_it_be_with_reload(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
let(:service) do
- described_class.new(container: project, cluster: cluster, current_user: project.owner, params: params)
+ described_class.new(container: project, cluster: cluster, current_user: project.first_owner, params: params)
end
shared_examples_for 'a cluster integration' do |application_type|
diff --git a/spec/services/customer_relations/contacts/create_service_spec.rb b/spec/services/customer_relations/contacts/create_service_spec.rb
index 71eb447055e..567e1c91e78 100644
--- a/spec/services/customer_relations/contacts/create_service_spec.rb
+++ b/spec/services/customer_relations/contacts/create_service_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe CustomerRelations::Contacts::CreateService do
subject(:response) { described_class.new(group: group, current_user: user, params: params).execute }
context 'when user does not have permission' do
- let_it_be(:group) { create(:group) }
+ let_it_be(:group) { create(:group, :crm_enabled) }
before_all do
group.add_reporter(user)
@@ -25,7 +25,7 @@ RSpec.describe CustomerRelations::Contacts::CreateService do
end
context 'when user has permission' do
- let_it_be(:group) { create(:group) }
+ let_it_be(:group) { create(:group, :crm_enabled) }
before_all do
group.add_developer(user)
diff --git a/spec/services/customer_relations/contacts/update_service_spec.rb b/spec/services/customer_relations/contacts/update_service_spec.rb
index 7c5fbabb600..253bbc23226 100644
--- a/spec/services/customer_relations/contacts/update_service_spec.rb
+++ b/spec/services/customer_relations/contacts/update_service_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe CustomerRelations::Contacts::UpdateService do
describe '#execute' do
context 'when the user has no permission' do
- let_it_be(:group) { create(:group) }
+ let_it_be(:group) { create(:group, :crm_enabled) }
let(:params) { { first_name: 'Gary' } }
@@ -24,7 +24,7 @@ RSpec.describe CustomerRelations::Contacts::UpdateService do
end
context 'when user has permission' do
- let_it_be(:group) { create(:group) }
+ let_it_be(:group) { create(:group, :crm_enabled) }
before_all do
group.add_developer(user)
diff --git a/spec/services/customer_relations/organizations/create_service_spec.rb b/spec/services/customer_relations/organizations/create_service_spec.rb
index d8985d8d90b..18eefdd716e 100644
--- a/spec/services/customer_relations/organizations/create_service_spec.rb
+++ b/spec/services/customer_relations/organizations/create_service_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe CustomerRelations::Organizations::CreateService do
describe '#execute' do
let_it_be(:user) { create(:user) }
- let(:group) { create(:group) }
+ let(:group) { create(:group, :crm_enabled) }
let(:params) { attributes_for(:organization, group: group) }
subject(:response) { described_class.new(group: group, current_user: user, params: params).execute }
diff --git a/spec/services/customer_relations/organizations/update_service_spec.rb b/spec/services/customer_relations/organizations/update_service_spec.rb
index bc40cb3e8e7..8461c98ef0e 100644
--- a/spec/services/customer_relations/organizations/update_service_spec.rb
+++ b/spec/services/customer_relations/organizations/update_service_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe CustomerRelations::Organizations::UpdateService do
describe '#execute' do
context 'when the user has no permission' do
- let_it_be(:group) { create(:group) }
+ let_it_be(:group) { create(:group, :crm_enabled) }
let(:params) { { name: 'GitLab' } }
@@ -24,7 +24,7 @@ RSpec.describe CustomerRelations::Organizations::UpdateService do
end
context 'when user has permission' do
- let_it_be(:group) { create(:group) }
+ let_it_be(:group) { create(:group, :crm_enabled) }
before_all do
group.add_developer(user)
diff --git a/spec/services/dependency_proxy/download_blob_service_spec.rb b/spec/services/dependency_proxy/download_blob_service_spec.rb
deleted file mode 100644
index 2f293b8a46b..00000000000
--- a/spec/services/dependency_proxy/download_blob_service_spec.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-# frozen_string_literal: true
-require 'spec_helper'
-
-RSpec.describe DependencyProxy::DownloadBlobService do
- include DependencyProxyHelpers
-
- let(:image) { 'alpine' }
- let(:token) { Digest::SHA256.hexdigest('123') }
- let(:blob_sha) { Digest::SHA256.hexdigest('ruby:2.7.0') }
-
- subject(:download_blob) { described_class.new(image, blob_sha, token).execute }
-
- context 'remote request is successful' do
- before do
- stub_blob_download(image, blob_sha)
- end
-
- it { expect(subject[:status]).to eq(:success) }
- it { expect(subject[:file]).to be_a(Tempfile) }
- it { expect(subject[:file].size).to eq(6) }
-
- it 'streams the download' do
- expected_options = { headers: anything, stream_body: true }
-
- expect(Gitlab::HTTP).to receive(:perform_request).with(Net::HTTP::Get, anything, expected_options)
-
- download_blob
- end
-
- it 'skips read_total_timeout', :aggregate_failures do
- stub_const('GitLab::HTTP::DEFAULT_READ_TOTAL_TIMEOUT', 0)
-
- expect(Gitlab::Metrics::System).not_to receive(:monotonic_time)
- expect(download_blob).to include(status: :success)
- end
- end
-
- context 'remote request is not found' do
- before do
- stub_blob_download(image, blob_sha, 404)
- end
-
- it { expect(subject[:status]).to eq(:error) }
- it { expect(subject[:http_status]).to eq(404) }
- it { expect(subject[:message]).to eq('Non-success response code on downloading blob fragment') }
- end
-
- context 'net timeout exception' do
- before do
- blob_url = DependencyProxy::Registry.blob_url(image, blob_sha)
-
- stub_full_request(blob_url).to_timeout
- end
-
- it { expect(subject[:status]).to eq(:error) }
- it { expect(subject[:http_status]).to eq(599) }
- it { expect(subject[:message]).to eq('execution expired') }
- end
-end
diff --git a/spec/services/dependency_proxy/find_cached_manifest_service_spec.rb b/spec/services/dependency_proxy/find_cached_manifest_service_spec.rb
index 29bdf1f11c3..607d67d8efe 100644
--- a/spec/services/dependency_proxy/find_cached_manifest_service_spec.rb
+++ b/spec/services/dependency_proxy/find_cached_manifest_service_spec.rb
@@ -91,9 +91,9 @@ RSpec.describe DependencyProxy::FindCachedManifestService do
it_behaves_like 'returning no manifest'
end
- context 'when the cached manifest is expired' do
+ context 'when the cached manifest is pending destruction' do
before do
- dependency_proxy_manifest.update_column(:status, DependencyProxy::Manifest.statuses[:expired])
+ dependency_proxy_manifest.update_column(:status, DependencyProxy::Manifest.statuses[:pending_destruction])
stub_manifest_head(image, tag, headers: headers)
stub_manifest_download(image, tag, headers: headers)
end
diff --git a/spec/services/dependency_proxy/find_or_create_blob_service_spec.rb b/spec/services/dependency_proxy/find_or_create_blob_service_spec.rb
deleted file mode 100644
index 5f7afdf699a..00000000000
--- a/spec/services/dependency_proxy/find_or_create_blob_service_spec.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-# frozen_string_literal: true
-require 'spec_helper'
-
-RSpec.describe DependencyProxy::FindOrCreateBlobService do
- include DependencyProxyHelpers
-
- let_it_be_with_reload(:blob) { create(:dependency_proxy_blob) }
-
- let(:group) { blob.group }
- let(:image) { 'alpine' }
- let(:tag) { '3.9' }
- let(:token) { Digest::SHA256.hexdigest('123') }
- let(:blob_sha) { '40bd001563085fc35165329ea1ff5c5ecbdbbeef' }
-
- subject { described_class.new(group, image, token, blob_sha).execute }
-
- before do
- stub_registry_auth(image, token)
- end
-
- shared_examples 'downloads the remote blob' do
- it 'downloads blob from remote registry if there is no cached one' do
- expect(subject[:status]).to eq(:success)
- expect(subject[:blob]).to be_a(DependencyProxy::Blob)
- expect(subject[:blob]).to be_persisted
- expect(subject[:from_cache]).to eq false
- end
- end
-
- context 'no cache' do
- before do
- stub_blob_download(image, blob_sha)
- end
-
- it_behaves_like 'downloads the remote blob'
- end
-
- context 'cached blob' do
- let(:blob_sha) { blob.file_name.sub('.gz', '') }
-
- it 'uses cached blob instead of downloading one' do
- expect { subject }.to change { blob.reload.read_at }
-
- expect(subject[:status]).to eq(:success)
- expect(subject[:blob]).to be_a(DependencyProxy::Blob)
- expect(subject[:blob]).to eq(blob)
- expect(subject[:from_cache]).to eq true
- end
-
- context 'when the cached blob is expired' do
- before do
- blob.update_column(:status, DependencyProxy::Blob.statuses[:expired])
- stub_blob_download(image, blob_sha)
- end
-
- it_behaves_like 'downloads the remote blob'
- end
- end
-
- context 'no such blob exists remotely' do
- before do
- stub_blob_download(image, blob_sha, 404)
- end
-
- it 'returns error message and http status' do
- expect(subject[:status]).to eq(:error)
- expect(subject[:message]).to eq('Failed to download the blob')
- expect(subject[:http_status]).to eq(404)
- end
- end
-end
diff --git a/spec/services/deployments/archive_in_project_service_spec.rb b/spec/services/deployments/archive_in_project_service_spec.rb
index d4039ee7b4a..a316c210d64 100644
--- a/spec/services/deployments/archive_in_project_service_spec.rb
+++ b/spec/services/deployments/archive_in_project_service_spec.rb
@@ -50,17 +50,6 @@ RSpec.describe Deployments::ArchiveInProjectService do
end
end
- context 'when deployments_archive feature flag is disabled' do
- before do
- stub_feature_flags(deployments_archive: false)
- end
-
- it 'does not do anything' do
- expect(subject[:status]).to eq(:error)
- expect(subject[:message]).to eq('Feature flag is not enabled')
- end
- end
-
def deployment_refs_exist?
deployment_refs.map { |path| project.repository.ref_exists?(path) }
end
diff --git a/spec/services/deployments/create_for_build_service_spec.rb b/spec/services/deployments/create_for_build_service_spec.rb
new file mode 100644
index 00000000000..6fc7c9e56a6
--- /dev/null
+++ b/spec/services/deployments/create_for_build_service_spec.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Deployments::CreateForBuildService do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:user) { create(:user) }
+
+ let(:service) { described_class.new }
+
+ describe '#execute' do
+ subject { service.execute(build) }
+
+ context 'with a deployment job' do
+ let!(:build) { create(:ci_build, :start_review_app, project: project) }
+ let!(:environment) { create(:environment, project: project, name: build.expanded_environment_name) }
+
+ it 'creates a deployment record' do
+ expect { subject }.to change { Deployment.count }.by(1)
+
+ build.reset
+ expect(build.deployment.project).to eq(build.project)
+ expect(build.deployment.ref).to eq(build.ref)
+ expect(build.deployment.sha).to eq(build.sha)
+ expect(build.deployment.deployable).to eq(build)
+ expect(build.deployment.deployable_type).to eq('CommitStatus')
+ expect(build.deployment.environment).to eq(build.persisted_environment)
+ end
+
+ context 'when creation failure occures' do
+ before do
+ allow(build).to receive(:create_deployment!) { raise ActiveRecord::RecordInvalid }
+ end
+
+ it 'trackes the exception' do
+ expect { subject }.to raise_error(described_class::DeploymentCreationError)
+
+ expect(Deployment.count).to eq(0)
+ end
+ end
+
+ context 'when the corresponding environment does not exist' do
+ let!(:environment) { }
+
+ it 'does not create a deployment record' do
+ expect { subject }.not_to change { Deployment.count }
+
+ expect(build.deployment).to be_nil
+ end
+ end
+ end
+
+ context 'with a teardown job' do
+ let!(:build) { create(:ci_build, :stop_review_app, project: project) }
+ let!(:environment) { create(:environment, name: build.expanded_environment_name) }
+
+ it 'does not create a deployment record' do
+ expect { subject }.not_to change { Deployment.count }
+
+ expect(build.deployment).to be_nil
+ end
+ end
+
+ context 'with a normal job' do
+ let!(:build) { create(:ci_build, project: project) }
+
+ it 'does not create a deployment record' do
+ expect { subject }.not_to change { Deployment.count }
+
+ expect(build.deployment).to be_nil
+ end
+ end
+
+ context 'with a bridge' do
+ let!(:build) { create(:ci_bridge, project: project) }
+
+ it 'does not create a deployment record' do
+ expect { subject }.not_to change { Deployment.count }
+ end
+ end
+ end
+end
diff --git a/spec/services/discussions/update_diff_position_service_spec.rb b/spec/services/discussions/update_diff_position_service_spec.rb
index 85020e95c83..e7a3505bbd4 100644
--- a/spec/services/discussions/update_diff_position_service_spec.rb
+++ b/spec/services/discussions/update_diff_position_service_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Discussions::UpdateDiffPositionService do
let(:project) { create(:project, :repository) }
- let(:current_user) { project.owner }
+ let(:current_user) { project.first_owner }
let(:create_commit) { project.commit("913c66a37b4a45b9769037c55c2d238bd0942d2e") }
let(:modify_commit) { project.commit("874797c3a73b60d2187ed6e2fcabd289ff75171e") }
let(:edit_commit) { project.commit("570e7b2abdd848b95f2f578043fc23bd6f6fd24d") }
diff --git a/spec/services/error_tracking/collect_error_service_spec.rb b/spec/services/error_tracking/collect_error_service_spec.rb
index 52d095148c8..2b16612dac3 100644
--- a/spec/services/error_tracking/collect_error_service_spec.rb
+++ b/spec/services/error_tracking/collect_error_service_spec.rb
@@ -4,8 +4,9 @@ require 'spec_helper'
RSpec.describe ErrorTracking::CollectErrorService do
let_it_be(:project) { create(:project) }
- let_it_be(:parsed_event_file) { 'error_tracking/parsed_event.json' }
- let_it_be(:parsed_event) { Gitlab::Json.parse(fixture_file(parsed_event_file)) }
+
+ let(:parsed_event_file) { 'error_tracking/parsed_event.json' }
+ let(:parsed_event) { parse_valid_event(parsed_event_file) }
subject { described_class.new(project, nil, event: parsed_event) }
@@ -43,7 +44,7 @@ RSpec.describe ErrorTracking::CollectErrorService do
end
context 'python sdk event' do
- let(:parsed_event) { Gitlab::Json.parse(fixture_file('error_tracking/python_event.json')) }
+ let(:parsed_event_file) { 'error_tracking/python_event.json' }
it 'creates a valid event' do
expect { subject.execute }.to change { ErrorTracking::ErrorEvent.count }.by(1)
@@ -75,7 +76,7 @@ RSpec.describe ErrorTracking::CollectErrorService do
end
context 'go payload' do
- let(:parsed_event) { Gitlab::Json.parse(fixture_file('error_tracking/go_parsed_event.json')) }
+ let(:parsed_event_file) { 'error_tracking/go_parsed_event.json' }
it 'has correct values set' do
subject.execute
@@ -92,6 +93,38 @@ RSpec.describe ErrorTracking::CollectErrorService do
expect(event.environment).to eq 'Accumulate'
expect(event.payload).to eq parsed_event
end
+
+ context 'with two exceptions' do
+ let(:parsed_event_file) { 'error_tracking/go_two_exception_event.json' }
+
+ it 'reports using second exception', :aggregate_failures do
+ subject.execute
+
+ event = ErrorTracking::ErrorEvent.last
+ error = event.error
+
+ expect(error.name).to eq '*url.Error'
+ expect(error.description).to eq(%(Get \"foobar\": unsupported protocol scheme \"\"))
+ expect(error.platform).to eq 'go'
+ expect(error.actor).to eq('main(main)')
+
+ expect(event.description).to eq(%(Get \"foobar\": unsupported protocol scheme \"\"))
+ expect(event.payload).to eq parsed_event
+ end
+ end
end
end
+
+ private
+
+ def parse_valid_event(parsed_event_file)
+ parsed_event = Gitlab::Json.parse(fixture_file(parsed_event_file))
+
+ validator = ErrorTracking::Collector::PayloadValidator.new
+ # This a precondition for all specs to verify that
+ # submitted JSON payload is valid.
+ expect(validator).to be_valid(parsed_event)
+
+ parsed_event
+ end
end
diff --git a/spec/services/events/destroy_service_spec.rb b/spec/services/events/destroy_service_spec.rb
index 8dcbb83eb1d..8b07852c040 100644
--- a/spec/services/events/destroy_service_spec.rb
+++ b/spec/services/events/destroy_service_spec.rb
@@ -30,16 +30,28 @@ RSpec.describe Events::DestroyService do
expect(unrelated_event.reload).to be_present
end
+ context 'batch delete' do
+ before do
+ stub_const("#{described_class}::BATCH_SIZE", 2)
+ end
+
+ it 'splits delete queries into batches' do
+ expect(project).to receive(:events).twice.and_call_original
+
+ subject.execute
+ end
+ end
+
context 'when an error is raised while deleting the records' do
before do
- allow(project).to receive_message_chain(:events, :all, :delete_all).and_raise(ActiveRecord::ActiveRecordError)
+ allow(project).to receive_message_chain(:events, :limit, :delete_all).and_raise(ActiveRecord::ActiveRecordError, 'custom error')
end
it 'returns error' do
response = subject.execute
expect(response).to be_error
- expect(response.message).to eq 'Failed to remove events.'
+ expect(response.message).to eq 'custom error'
end
it 'does not delete events' do
diff --git a/spec/services/feature_flags/hook_service_spec.rb b/spec/services/feature_flags/hook_service_spec.rb
index 02cdbbd86ac..19c935e43f3 100644
--- a/spec/services/feature_flags/hook_service_spec.rb
+++ b/spec/services/feature_flags/hook_service_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe FeatureFlags::HookService do
let_it_be(:namespace) { create(:namespace) }
let_it_be(:project) { create(:project, :repository, namespace: namespace) }
let_it_be(:feature_flag) { create(:operations_feature_flag, project: project) }
- let_it_be(:user) { namespace.owner }
+ let_it_be(:user) { namespace.first_owner }
let!(:hook) { create(:project_hook, project: project) }
let(:hook_data) { double }
diff --git a/spec/services/git/process_ref_changes_service_spec.rb b/spec/services/git/process_ref_changes_service_spec.rb
index f52df9b0073..05c1f898cab 100644
--- a/spec/services/git/process_ref_changes_service_spec.rb
+++ b/spec/services/git/process_ref_changes_service_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Git::ProcessRefChangesService do
let(:project) { create(:project, :repository) }
- let(:user) { project.owner }
+ let(:user) { project.first_owner }
let(:params) { { changes: git_changes } }
subject { described_class.new(project, user, params) }
@@ -34,7 +34,7 @@ RSpec.describe Git::ProcessRefChangesService do
it "calls #{push_service_class}" do
expect(push_service_class)
.to receive(:new)
- .with(project, project.owner, hash_including(execute_project_hooks: true, create_push_event: true))
+ .with(project, project.first_owner, hash_including(execute_project_hooks: true, create_push_event: true))
.exactly(changes.count).times
.and_return(service)
@@ -58,7 +58,7 @@ RSpec.describe Git::ProcessRefChangesService do
it "calls #{push_service_class} with execute_project_hooks set to false" do
expect(push_service_class)
.to receive(:new)
- .with(project, project.owner, hash_including(execute_project_hooks: false))
+ .with(project, project.first_owner, hash_including(execute_project_hooks: false))
.exactly(changes.count).times
.and_return(service)
@@ -86,7 +86,7 @@ RSpec.describe Git::ProcessRefChangesService do
it "calls #{push_service_class} with create_push_event set to false" do
expect(push_service_class)
.to receive(:new)
- .with(project, project.owner, hash_including(create_push_event: false))
+ .with(project, project.first_owner, hash_including(create_push_event: false))
.exactly(changes.count).times
.and_return(service)
@@ -170,7 +170,7 @@ RSpec.describe Git::ProcessRefChangesService do
allow(push_service_class)
.to receive(:new)
- .with(project, project.owner, hash_including(execute_project_hooks: true, create_push_event: true))
+ .with(project, project.first_owner, hash_including(execute_project_hooks: true, create_push_event: true))
.exactly(changes.count).times
.and_return(service)
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
new file mode 100644
index 00000000000..190e1a8098c
--- /dev/null
+++ b/spec/services/google_cloud/create_service_accounts_service_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+# Mock Types
+MockGoogleOAuth2Credentials = Struct.new(:app_id, :app_secret)
+MockServiceAccount = Struct.new(:project_id, :unique_id)
+
+RSpec.describe GoogleCloud::CreateServiceAccountsService do
+ describe '#execute' do
+ before do
+ allow(Gitlab::Auth::OAuth::Provider).to receive(:config_for)
+ .with('google_oauth2')
+ .and_return(MockGoogleOAuth2Credentials.new('mock-app-id', 'mock-app-secret'))
+
+ allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |client|
+ allow(client).to receive(:create_service_account)
+ .and_return(MockServiceAccount.new('mock-project-id', 'mock-unique-id'))
+ allow(client).to receive(:create_service_account_key)
+ .and_return('mock-key')
+ end
+ end
+
+ it 'creates unprotected vars', :aggregate_failures do
+ 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(false)
+ expect(project.variables.second.protected).to eq(false)
+ expect(project.variables.third.protected).to eq(false)
+ 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 505c623c02a..17c1f61a96e 100644
--- a/spec/services/google_cloud/service_accounts_service_spec.rb
+++ b/spec/services/google_cloud/service_accounts_service_spec.rb
@@ -60,8 +60,8 @@ RSpec.describe GoogleCloud::ServiceAccountsService do
let_it_be(:project) { create(:project) }
it 'saves GCP creds as project CI vars' do
- service.add_for_project('env_1', 'gcp_prj_id_1', 'srv_acc_1', 'srv_acc_key_1')
- service.add_for_project('env_2', 'gcp_prj_id_2', 'srv_acc_2', 'srv_acc_key_2')
+ service.add_for_project('env_1', 'gcp_prj_id_1', 'srv_acc_1', 'srv_acc_key_1', true)
+ service.add_for_project('env_2', 'gcp_prj_id_2', 'srv_acc_2', 'srv_acc_key_2', false)
list = service.find_for_project
@@ -81,7 +81,7 @@ RSpec.describe GoogleCloud::ServiceAccountsService do
end
it 'replaces previously stored CI vars with new CI vars' do
- service.add_for_project('env_1', 'new_project', 'srv_acc_1', 'srv_acc_key_1')
+ service.add_for_project('env_1', 'new_project', 'srv_acc_1', 'srv_acc_key_1', false)
list = service.find_for_project
@@ -101,9 +101,16 @@ RSpec.describe GoogleCloud::ServiceAccountsService do
end
end
- it 'underlying project CI vars must be protected' do
- expect(project.variables.first.protected).to eq(true)
- expect(project.variables.second.protected).to eq(true)
+ it 'underlying project CI vars must be protected as per value' do
+ service.add_for_project('env_1', 'gcp_prj_id_1', 'srv_acc_1', 'srv_acc_key_1', true)
+ service.add_for_project('env_2', 'gcp_prj_id_2', 'srv_acc_2', 'srv_acc_key_2', false)
+
+ expect(project.variables[0].protected).to eq(true)
+ expect(project.variables[1].protected).to eq(true)
+ expect(project.variables[2].protected).to eq(true)
+ expect(project.variables[3].protected).to eq(false)
+ expect(project.variables[4].protected).to eq(false)
+ expect(project.variables[5].protected).to eq(false)
end
end
end
diff --git a/spec/services/groups/update_service_spec.rb b/spec/services/groups/update_service_spec.rb
index e1bd3732820..46c5e2a9818 100644
--- a/spec/services/groups/update_service_spec.rb
+++ b/spec/services/groups/update_service_spec.rb
@@ -163,6 +163,70 @@ RSpec.describe Groups::UpdateService do
expect(updated_group.parent_id).to be_nil
end
end
+
+ context 'crm_enabled param' do
+ context 'when no existing crm_settings' do
+ it 'when param not present, leave crm disabled' do
+ params = {}
+
+ described_class.new(public_group, user, params).execute
+ updated_group = public_group.reload
+
+ expect(updated_group.crm_enabled?).to be_falsey
+ end
+
+ it 'when param set true, enables crm' do
+ params = { crm_enabled: true }
+
+ described_class.new(public_group, user, params).execute
+ updated_group = public_group.reload
+
+ expect(updated_group.crm_enabled?).to be_truthy
+ end
+ end
+
+ context 'with existing crm_settings' do
+ it 'when param set true, enables crm' do
+ params = { crm_enabled: true }
+ create(:crm_settings, group: public_group)
+
+ described_class.new(public_group, user, params).execute
+
+ updated_group = public_group.reload
+ expect(updated_group.crm_enabled?).to be_truthy
+ end
+
+ it 'when param set false, disables crm' do
+ params = { crm_enabled: false }
+ create(:crm_settings, group: public_group, enabled: true)
+
+ described_class.new(public_group, user, params).execute
+
+ updated_group = public_group.reload
+ expect(updated_group.crm_enabled?).to be_falsy
+ end
+
+ it 'when param not present, crm remains disabled' do
+ params = {}
+ create(:crm_settings, group: public_group)
+
+ described_class.new(public_group, user, params).execute
+
+ updated_group = public_group.reload
+ expect(updated_group.crm_enabled?).to be_falsy
+ end
+
+ it 'when param not present, crm remains enabled' do
+ params = {}
+ create(:crm_settings, group: public_group, enabled: true)
+
+ described_class.new(public_group, user, params).execute
+
+ updated_group = public_group.reload
+ expect(updated_group.crm_enabled?).to be_truthy
+ end
+ end
+ end
end
context "unauthorized visibility_level validation" do
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
index 3c461c91ff0..92c46cf7052 100644
--- 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
@@ -18,24 +18,29 @@ RSpec.describe ::Import::GitlabProjects::CreateProjectFromRemoteFileService do
subject { described_class.new(user, params) }
- it 'creates a project and returns a successful response' do
- stub_headers_for(remote_url, {
- 'content-type' => 'application/gzip',
- 'content-length' => '10'
- })
-
- response = nil
- expect { response = subject.execute }
- .to change(Project, :count).by(1)
+ 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'
+ })
- 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)
+ 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)
@@ -79,7 +84,7 @@ RSpec.describe ::Import::GitlabProjects::CreateProjectFromRemoteFileService do
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)")
+ .to eq("Remote file content type 'application/js' not allowed. (Allowed content types: application/gzip, application/x-tar)")
end
end
@@ -130,6 +135,20 @@ RSpec.describe ::Import::GitlabProjects::CreateProjectFromRemoteFileService do
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) { {} }
diff --git a/spec/services/import/validate_remote_git_endpoint_service_spec.rb b/spec/services/import/validate_remote_git_endpoint_service_spec.rb
index fbd8a3cb323..9dc862b6ca3 100644
--- a/spec/services/import/validate_remote_git_endpoint_service_spec.rb
+++ b/spec/services/import/validate_remote_git_endpoint_service_spec.rb
@@ -24,6 +24,17 @@ RSpec.describe Import::ValidateRemoteGitEndpointService do
expect(Gitlab::HTTP).to have_received(:get).with(endpoint_url, basic_auth: nil, stream_body: true, follow_redirects: false)
end
+ context 'when uri is using git:// protocol' do
+ subject { described_class.new(url: 'git://demo.host/repo')}
+
+ it 'returns success' do
+ result = subject.execute
+
+ expect(result).to be_a(ServiceResponse)
+ expect(result.success?).to be(true)
+ end
+ end
+
context 'when receiving HTTP response' do
subject { described_class.new(url: base_url) }
diff --git a/spec/services/incident_management/incidents/create_service_spec.rb b/spec/services/incident_management/incidents/create_service_spec.rb
index 0f32a4b5425..47ce9d01f66 100644
--- a/spec/services/incident_management/incidents/create_service_spec.rb
+++ b/spec/services/incident_management/incidents/create_service_spec.rb
@@ -39,7 +39,7 @@ RSpec.describe IncidentManagement::Incidents::CreateService do
let(:issue) { new_issue }
- include_examples 'has incident label'
+ include_examples 'does not have incident label'
end
context 'with default severity' do
@@ -71,8 +71,8 @@ RSpec.describe IncidentManagement::Incidents::CreateService do
end
context 'when incident label does not exists' do
- it 'creates incident label' do
- expect { create_incident }.to change { project.labels.where(title: label_title).count }.by(1)
+ it 'does not create incident label' do
+ expect { create_incident }.to not_change { project.labels.where(title: label_title).count }
end
end
diff --git a/spec/services/incident_management/issuable_escalation_statuses/after_update_service_spec.rb b/spec/services/incident_management/issuable_escalation_statuses/after_update_service_spec.rb
new file mode 100644
index 00000000000..e9db6ba8d28
--- /dev/null
+++ b/spec/services/incident_management/issuable_escalation_statuses/after_update_service_spec.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe IncidentManagement::IssuableEscalationStatuses::AfterUpdateService do
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:escalation_status, reload: true) { create(:incident_management_issuable_escalation_status, :triggered) }
+ let_it_be(:issue, reload: true) { escalation_status.issue }
+ let_it_be(:project) { issue.project }
+ let_it_be(:alert) { create(:alert_management_alert, issue: issue, project: project) }
+
+ let(:status_event) { :acknowledge }
+ let(:update_params) { { incident_management_issuable_escalation_status_attributes: { status_event: status_event } } }
+ let(:service) { IncidentManagement::IssuableEscalationStatuses::AfterUpdateService.new(issue, current_user) }
+
+ subject(:result) do
+ issue.update!(update_params)
+ service.execute
+ end
+
+ before do
+ issue.project.add_developer(current_user)
+ end
+
+ shared_examples 'does not attempt to update the alert' do
+ specify do
+ expect(::AlertManagement::Alerts::UpdateService).not_to receive(:new)
+
+ expect(result).to be_success
+ end
+ end
+
+ context 'with status attributes' do
+ it 'updates the alert with the new alert status' do
+ expect(::AlertManagement::Alerts::UpdateService).to receive(:new).once.and_call_original
+ expect(described_class).to receive(:new).once.and_call_original
+
+ expect { result }.to change { escalation_status.reload.acknowledged? }.to(true)
+ .and change { alert.reload.acknowledged? }.to(true)
+ end
+
+ context 'when incident is not associated with an alert' do
+ before do
+ alert.destroy!
+ end
+
+ it_behaves_like 'does not attempt to update the alert'
+ end
+
+ context 'when new status matches the current status' do
+ let(:status_event) { :trigger }
+
+ it_behaves_like 'does not attempt to update the alert'
+ end
+ end
+end
diff --git a/spec/services/incident_management/issuable_escalation_statuses/prepare_update_service_spec.rb b/spec/services/incident_management/issuable_escalation_statuses/prepare_update_service_spec.rb
new file mode 100644
index 00000000000..bfed5319028
--- /dev/null
+++ b/spec/services/incident_management/issuable_escalation_statuses/prepare_update_service_spec.rb
@@ -0,0 +1,108 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe IncidentManagement::IssuableEscalationStatuses::PrepareUpdateService do
+ let_it_be(:escalation_status) { create(:incident_management_issuable_escalation_status, :triggered) }
+ let_it_be(:user_with_permissions) { create(:user) }
+
+ let(:current_user) { user_with_permissions }
+ let(:issue) { escalation_status.issue }
+ let(:status) { :acknowledged }
+ let(:params) { { status: status } }
+ let(:service) { IncidentManagement::IssuableEscalationStatuses::PrepareUpdateService.new(issue, current_user, params) }
+
+ subject(:result) { service.execute }
+
+ before do
+ issue.project.add_developer(user_with_permissions)
+ end
+
+ shared_examples 'successful response' do |payload|
+ it 'returns valid parameters which can be used to update the issue' do
+ expect(result).to be_success
+ expect(result.payload).to eq(escalation_status: payload)
+ end
+ end
+
+ shared_examples 'error response' do |message|
+ specify do
+ expect(result).to be_error
+ expect(result.message).to eq(message)
+ end
+ end
+
+ shared_examples 'availability error response' do
+ include_examples 'error response', 'Escalation status updates are not available for this issue, user, or project.'
+ end
+
+ shared_examples 'invalid params error response' do
+ include_examples 'error response', 'Invalid value was provided for a parameter.'
+ end
+
+ it_behaves_like 'successful response', { status_event: :acknowledge }
+
+ context 'when feature flag is disabled' do
+ before do
+ stub_feature_flags(incident_escalations: false)
+ end
+
+ it_behaves_like 'availability error response'
+ end
+
+ context 'when user is anonymous' do
+ let(:current_user) { nil }
+
+ it_behaves_like 'availability error response'
+ end
+
+ context 'when user does not have permissions' do
+ let(:current_user) { create(:user) }
+
+ it_behaves_like 'availability error response'
+ end
+
+ context 'when called with an unsupported issue type' do
+ let(:issue) { create(:issue) }
+
+ it_behaves_like 'availability error response'
+ end
+
+ context 'when an IssuableEscalationStatus record for the issue does not exist' do
+ let(:issue) { create(:incident) }
+
+ it_behaves_like 'availability error response'
+ end
+
+ context 'when called without params' do
+ let(:params) { nil }
+
+ it_behaves_like 'successful response', {}
+ end
+
+ context 'when called with unsupported params' do
+ let(:params) { { escalations_started_at: Time.current } }
+
+ it_behaves_like 'successful response', {}
+ end
+
+ context 'with status param' do
+ context 'when status matches the current status' do
+ let(:params) { { status: :triggered } }
+
+ it_behaves_like 'successful response', {}
+ end
+
+ context 'when status is unsupported' do
+ let(:params) { { status: :mitigated } }
+
+ it_behaves_like 'invalid params error response'
+ end
+
+ context 'when status is a String' do
+ let(:params) { { status: 'acknowledged' } }
+
+ it_behaves_like 'successful response', { status_event: :acknowledge }
+ end
+ end
+end
diff --git a/spec/services/integrations/test/project_service_spec.rb b/spec/services/integrations/test/project_service_spec.rb
index 32f9f632d7a..74833686283 100644
--- a/spec/services/integrations/test/project_service_spec.rb
+++ b/spec/services/integrations/test/project_service_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe Integrations::Test::ProjectService do
let_it_be(:project) { create(:project) }
let(:integration) { create(:integrations_slack, project: project) }
- let(:user) { project.owner }
+ let(:user) { project.first_owner }
let(:event) { nil }
let(:sample_data) { { data: 'sample' } }
let(:success_result) { { success: true, result: {} } }
diff --git a/spec/services/issues/build_service_spec.rb b/spec/services/issues/build_service_spec.rb
index cf75efb5c57..304e4bb3ebb 100644
--- a/spec/services/issues/build_service_spec.rb
+++ b/spec/services/issues/build_service_spec.rb
@@ -172,9 +172,9 @@ RSpec.describe Issues::BuildService do
end
describe 'setting issue type' do
- context 'with a corresponding WorkItem::Type' do
- let_it_be(:type_issue_id) { WorkItem::Type.default_issue_type.id }
- let_it_be(:type_incident_id) { WorkItem::Type.default_by_type(:incident).id }
+ context 'with a corresponding WorkItems::Type' do
+ let_it_be(:type_issue_id) { WorkItems::Type.default_issue_type.id }
+ let_it_be(:type_incident_id) { WorkItems::Type.default_by_type(:incident).id }
where(:issue_type, :current_user, :work_item_type_id, :resulting_issue_type) do
nil | ref(:guest) | ref(:type_issue_id) | 'issue'
diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb
index 8496bd31e00..b2dcfb5c6d3 100644
--- a/spec/services/issues/create_service_spec.rb
+++ b/spec/services/issues/create_service_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Issues::CreateService do
include AfterNextHelpers
- let_it_be(:group) { create(:group) }
+ let_it_be(:group) { create(:group, :crm_enabled) }
let_it_be_with_reload(:project) { create(:project, group: group) }
let_it_be(:user) { create(:user) }
@@ -61,6 +61,7 @@ RSpec.describe Issues::CreateService do
expect(Issuable::CommonSystemNotesService).to receive_message_chain(:new, :execute)
expect(issue).to be_persisted
+ expect(issue).to be_a(::Issue)
expect(issue.title).to eq('Awesome issue')
expect(issue.assignees).to eq([assignee])
expect(issue.labels).to match_array(labels)
@@ -69,6 +70,18 @@ RSpec.describe Issues::CreateService do
expect(issue.work_item_type.base_type).to eq('issue')
end
+ context 'when a build_service is provided' do
+ let(:issue) { described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params, build_service: build_service).execute }
+
+ let(:issue_from_builder) { WorkItem.new(project: project, title: 'Issue from builder') }
+ let(:build_service) { double(:build_service, execute: issue_from_builder) }
+
+ it 'uses the provided service to build the issue' do
+ expect(issue).to be_persisted
+ expect(issue).to be_a(WorkItem)
+ end
+ end
+
context 'when skip_system_notes is true' do
let(:issue) { described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params).execute(skip_system_notes: true) }
@@ -101,11 +114,11 @@ RSpec.describe Issues::CreateService do
end
it_behaves_like 'incident issue'
- it_behaves_like 'has incident label'
+ it_behaves_like 'does not have incident label'
- it 'does create an incident label' do
+ it 'does not create an incident label' do
expect { subject }
- .to change { Label.where(incident_label_attributes).count }.by(1)
+ .to not_change { Label.where(incident_label_attributes).count }
end
it 'calls IncidentManagement::Incidents::CreateEscalationStatusService' do
diff --git a/spec/services/issues/move_service_spec.rb b/spec/services/issues/move_service_spec.rb
index 36af38aef18..ef501f47f0d 100644
--- a/spec/services/issues/move_service_spec.rb
+++ b/spec/services/issues/move_service_spec.rb
@@ -259,6 +259,16 @@ RSpec.describe Issues::MoveService do
it_behaves_like 'copy or reset relative position'
end
+
+ context 'issue with escalation status' do
+ it 'keeps the escalation status' do
+ escalation_status = create(:incident_management_issuable_escalation_status, issue: old_issue)
+
+ move_service.execute(old_issue, new_project)
+
+ expect(escalation_status.reload.issue).to eq(old_issue)
+ end
+ end
end
describe 'move permissions' do
diff --git a/spec/services/issues/set_crm_contacts_service_spec.rb b/spec/services/issues/set_crm_contacts_service_spec.rb
index 628f70efad6..2418f317551 100644
--- a/spec/services/issues/set_crm_contacts_service_spec.rb
+++ b/spec/services/issues/set_crm_contacts_service_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Issues::SetCrmContactsService do
let_it_be(:user) { create(:user) }
- 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(:contacts) { create_list(:contact, 4, group: group) }
diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb
index 4739b7e0f28..11ed47b84d9 100644
--- a/spec/services/issues/update_service_spec.rb
+++ b/spec/services/issues/update_service_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Issues::UpdateService, :mailer do
let_it_be(:user2) { create(:user) }
let_it_be(:user3) { create(:user) }
let_it_be(:guest) { create(:user) }
- let_it_be(:group) { create(:group, :public) }
+ let_it_be(:group) { create(:group, :public, :crm_enabled) }
let_it_be(:project, reload: true) { create(:project, :repository, group: group) }
let_it_be(:label) { create(:label, project: project) }
let_it_be(:label2) { create(:label, project: project) }
@@ -22,10 +22,10 @@ RSpec.describe Issues::UpdateService, :mailer do
end
before_all do
- project.add_maintainer(user)
- project.add_developer(user2)
- project.add_developer(user3)
- project.add_guest(guest)
+ group.add_maintainer(user)
+ group.add_developer(user2)
+ group.add_developer(user3)
+ group.add_guest(guest)
end
describe 'execute' do
@@ -191,11 +191,6 @@ RSpec.describe Issues::UpdateService, :mailer do
end
end
- it 'adds a `incident` label if one does not exist' do
- expect { update_issue(issue_type: 'incident') }.to change(issue.labels, :count).by(1)
- expect(issue.labels.pluck(:title)).to eq(['incident'])
- end
-
it 'creates system note about issue type' do
update_issue(issue_type: 'incident')
@@ -204,6 +199,13 @@ RSpec.describe Issues::UpdateService, :mailer do
expect(note).not_to eq(nil)
end
+ it 'creates an escalation status' do
+ expect { update_issue(issue_type: 'incident') }
+ .to change { issue.reload.incident_management_issuable_escalation_status }
+ .from(nil)
+ .to(a_kind_of(IncidentManagement::IssuableEscalationStatus))
+ end
+
context 'for an issue with multiple labels' do
let(:issue) { create(:incident, project: project, labels: [label_1]) }
@@ -215,18 +217,6 @@ RSpec.describe Issues::UpdateService, :mailer do
expect(issue.labels).to eq([label_1])
end
end
-
- context 'filtering the incident label' do
- let(:params) { { add_label_ids: [] } }
-
- before do
- update_issue(issue_type: 'incident')
- end
-
- it 'creates and add a incident label id to add_label_ids' do
- expect(issue.label_ids).to contain_exactly(label_1.id)
- end
- end
end
context 'from incident to issue' do
@@ -241,10 +231,8 @@ RSpec.describe Issues::UpdateService, :mailer do
context 'for an incident with multiple labels' do
let(:issue) { create(:incident, project: project, labels: [label_1, label_2]) }
- it 'removes an `incident` label if one exists on the incident' do
- expect { update_issue(issue_type: 'issue') }.to change(issue, :label_ids)
- .from(containing_exactly(label_1.id, label_2.id))
- .to([label_2.id])
+ it 'does not remove an `incident` label if one exists on the incident' do
+ expect { update_issue(issue_type: 'issue') }.to not_change(issue, :label_ids)
end
end
@@ -252,10 +240,8 @@ RSpec.describe Issues::UpdateService, :mailer do
let(:issue) { create(:incident, project: project, labels: [label_1, label_2]) }
let(:params) { { label_ids: [label_1.id, label_2.id], remove_label_ids: [] } }
- it 'adds an incident label id to remove_label_ids for it to be removed' do
- expect { update_issue(issue_type: 'issue') }.to change(issue, :label_ids)
- .from(containing_exactly(label_1.id, label_2.id))
- .to([label_2.id])
+ it 'does not add an incident label id to remove_label_ids for it to be removed' do
+ expect { update_issue(issue_type: 'issue') }.to not_change(issue, :label_ids)
end
end
end
@@ -1157,6 +1143,83 @@ RSpec.describe Issues::UpdateService, :mailer do
end
end
+ context 'updating escalation status' do
+ let(:opts) { { escalation_status: { status: 'acknowledged' } } }
+ let(:escalation_update_class) { ::IncidentManagement::IssuableEscalationStatuses::AfterUpdateService }
+
+ shared_examples 'updates the escalation status record' do |expected_status|
+ let(:service_double) { instance_double(escalation_update_class) }
+
+ it 'has correct value' do
+ expect(escalation_update_class).to receive(:new).with(issue, user).and_return(service_double)
+ expect(service_double).to receive(:execute)
+
+ update_issue(opts)
+
+ expect(issue.escalation_status.status_name).to eq(expected_status)
+ end
+ end
+
+ shared_examples 'does not change the status record' do
+ it 'retains the original value' do
+ expected_status = issue.escalation_status&.status_name
+
+ update_issue(opts)
+
+ expect(issue.escalation_status&.status_name).to eq(expected_status)
+ end
+
+ it 'does not trigger side-effects' do
+ expect(escalation_update_class).not_to receive(:new)
+
+ update_issue(opts)
+ end
+ end
+
+ context 'when issue is an incident' do
+ let(:issue) { create(:incident, project: project) }
+
+ context 'with an escalation status record' do
+ before do
+ create(:incident_management_issuable_escalation_status, issue: issue)
+ end
+
+ it_behaves_like 'updates the escalation status record', :acknowledged
+
+ context 'with associated alert' do
+ let!(:alert) { create(:alert_management_alert, issue: issue, project: project) }
+
+ it 'syncs the update back to the alert' do
+ update_issue(opts)
+
+ expect(issue.escalation_status.status_name).to eq(:acknowledged)
+ expect(alert.reload.status_name).to eq(:acknowledged)
+ end
+ end
+
+ context 'with unsupported status value' do
+ let(:opts) { { escalation_status: { status: 'unsupported-status' } } }
+
+ it_behaves_like 'does not change the status record'
+ end
+
+ context 'with status value defined but unchanged' do
+ let(:opts) { { escalation_status: { status: issue.escalation_status.status_name } } }
+
+ it_behaves_like 'does not change the status record'
+ end
+ end
+
+ context 'without an escalation status record' do
+ it_behaves_like 'does not change the status record'
+ end
+ end
+
+ context 'when issue type is not incident' do
+ it_behaves_like 'does not change the status record'
+ end
+ end
+
context 'duplicate issue' do
let(:canonical_issue) { create(:issue, project: project) }
diff --git a/spec/services/labels/transfer_service_spec.rb b/spec/services/labels/transfer_service_spec.rb
index 05190accb33..e67ab6025a5 100644
--- a/spec/services/labels/transfer_service_spec.rb
+++ b/spec/services/labels/transfer_service_spec.rb
@@ -109,15 +109,5 @@ RSpec.describe Labels::TransferService do
end
end
- context 'with use_optimized_group_labels_query FF on' do
- it_behaves_like 'transfer labels'
- end
-
- context 'with use_optimized_group_labels_query FF off' do
- before do
- stub_feature_flags(use_optimized_group_labels_query: false)
- end
-
- it_behaves_like 'transfer labels'
- end
+ it_behaves_like 'transfer labels'
end
diff --git a/spec/services/members/destroy_service_spec.rb b/spec/services/members/destroy_service_spec.rb
index b9f382d3cd8..1a1283b1078 100644
--- a/spec/services/members/destroy_service_spec.rb
+++ b/spec/services/members/destroy_service_spec.rb
@@ -424,7 +424,7 @@ RSpec.describe Members::DestroyService do
end
context 'deletion of invitations created by deleted project member' do
- let(:user) { project.owner }
+ let(:user) { project.first_owner }
let(:member_user) { create(:user) }
let(:project) { create(:project) }
diff --git a/spec/services/members/invite_service_spec.rb b/spec/services/members/invite_service_spec.rb
index 7b9ae19f038..8ceb9979f33 100644
--- a/spec/services/members/invite_service_spec.rb
+++ b/spec/services/members/invite_service_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_shared_state, :sidekiq_inline do
let_it_be(:project, reload: true) { create(:project) }
- let_it_be(:user) { project.owner }
+ let_it_be(:user) { project.first_owner }
let_it_be(:project_user) { create(:user) }
let_it_be(:namespace) { project.namespace }
diff --git a/spec/services/merge_requests/base_service_spec.rb b/spec/services/merge_requests/base_service_spec.rb
index 7911392ef19..6eeba3029ae 100644
--- a/spec/services/merge_requests/base_service_spec.rb
+++ b/spec/services/merge_requests/base_service_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe MergeRequests::BaseService do
}
end
- subject { MergeRequests::CreateService.new(project: project, current_user: project.owner, params: params) }
+ subject { MergeRequests::CreateService.new(project: project, current_user: project.first_owner, params: params) }
describe '#execute_hooks' do
shared_examples 'enqueues Jira sync worker' do
diff --git a/spec/services/merge_requests/squash_service_spec.rb b/spec/services/merge_requests/squash_service_spec.rb
index 4b21812503e..e5bea0e7b14 100644
--- a/spec/services/merge_requests/squash_service_spec.rb
+++ b/spec/services/merge_requests/squash_service_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe MergeRequests::SquashService do
include GitHelpers
let(:service) { described_class.new(project: project, current_user: user, params: { merge_request: merge_request }) }
- let(:user) { project.owner }
+ let(:user) { project.first_owner }
let(:project) { create(:project, :repository) }
let(:repository) { project.repository.raw }
let(:log_error) { "Failed to squash merge request #{merge_request.to_reference(full: true)}:" }
diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb
index 6ec2b158d30..2925dad7f6b 100644
--- a/spec/services/merge_requests/update_service_spec.rb
+++ b/spec/services/merge_requests/update_service_spec.rb
@@ -1132,7 +1132,7 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
context 'updating `force_remove_source_branch`' do
let(:target_project) { create(:project, :repository, :public) }
let(:source_project) { fork_project(target_project, nil, repository: true) }
- let(:user) { target_project.owner }
+ let(:user) { target_project.first_owner }
let(:merge_request) do
create(:merge_request,
source_project: source_project,
diff --git a/spec/services/notes/create_service_spec.rb b/spec/services/notes/create_service_spec.rb
index 793e9ed9848..1fb50b07b3b 100644
--- a/spec/services/notes/create_service_spec.rb
+++ b/spec/services/notes/create_service_spec.rb
@@ -402,7 +402,7 @@ RSpec.describe Notes::CreateService do
let_it_be(:design) { create(:design, :with_file) }
let_it_be(:project) { design.project }
- let_it_be(:user) { project.owner }
+ let_it_be(:user) { project.first_owner }
let_it_be(:params) do
{
type: 'DiffNote',
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index 24775ce06a4..9cbc16f0c95 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -2885,7 +2885,7 @@ RSpec.describe NotificationService, :mailer do
let(:member) { create(:user) }
before do
- project.add_developer(member, current_user: project.owner)
+ project.add_developer(member, current_user: project.first_owner)
end
it do
@@ -3287,7 +3287,7 @@ RSpec.describe NotificationService, :mailer do
let_it_be(:domain, reload: true) { create(:pages_domain, project: project) }
let_it_be(:u_blocked) { create(:user, :blocked) }
let_it_be(:u_silence) { create_user_with_notification(:disabled, 'silent', project) }
- let_it_be(:u_owner) { project.owner }
+ let_it_be(:u_owner) { project.first_owner }
let_it_be(:u_maintainer1) { create(:user) }
let_it_be(:u_maintainer2) { create(:user) }
let_it_be(:u_developer) { create(:user) }
@@ -3395,7 +3395,7 @@ RSpec.describe NotificationService, :mailer do
let(:remote_mirror) { create(:remote_mirror, project: project) }
let(:u_blocked) { create(:user, :blocked) }
let(:u_silence) { create_user_with_notification(:disabled, 'silent-maintainer', project) }
- let(:u_owner) { project.owner }
+ let(:u_owner) { project.first_owner }
let(:u_maintainer1) { create(:user) }
let(:u_maintainer2) { create(:user) }
let(:u_developer) { create(:user) }
@@ -3489,7 +3489,7 @@ RSpec.describe NotificationService, :mailer do
it 'sends the email to owners and masters' do
expect(Notify).to receive(:prometheus_alert_fired_email).with(project, master, alert).and_call_original
- expect(Notify).to receive(:prometheus_alert_fired_email).with(project, project.owner, alert).and_call_original
+ expect(Notify).to receive(:prometheus_alert_fired_email).with(project, project.first_owner, alert).and_call_original
expect(Notify).not_to receive(:prometheus_alert_fired_email).with(project, developer, alert)
subject.prometheus_alerts_fired(project, [alert])
diff --git a/spec/services/packages/create_event_service_spec.rb b/spec/services/packages/create_event_service_spec.rb
index 122f1e88ad0..58fa68b11fe 100644
--- a/spec/services/packages/create_event_service_spec.rb
+++ b/spec/services/packages/create_event_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Packages::CreateEventService do
- let(:scope) { 'container' }
+ let(:scope) { 'generic' }
let(:event_name) { 'push_package' }
let(:params) do
@@ -75,24 +75,24 @@ RSpec.describe Packages::CreateEventService do
context 'with a user' do
let(:user) { create(:user) }
- it_behaves_like 'db package event creation', 'user', 'container'
- it_behaves_like 'redis package unique event creation', 'user', 'container'
- it_behaves_like 'redis package count event creation', 'user', 'container'
+ it_behaves_like 'db package event creation', 'user', 'generic'
+ it_behaves_like 'redis package unique event creation', 'user', 'generic'
+ it_behaves_like 'redis package count event creation', 'user', 'generic'
end
context 'with a deploy token' do
let(:user) { create(:deploy_token) }
- it_behaves_like 'db package event creation', 'deploy_token', 'container'
- it_behaves_like 'redis package unique event creation', 'deploy_token', 'container'
- it_behaves_like 'redis package count event creation', 'deploy_token', 'container'
+ it_behaves_like 'db package event creation', 'deploy_token', 'generic'
+ it_behaves_like 'redis package unique event creation', 'deploy_token', 'generic'
+ it_behaves_like 'redis package count event creation', 'deploy_token', 'generic'
end
context 'with no user' do
let(:user) { nil }
- it_behaves_like 'db package event creation', 'guest', 'container'
- it_behaves_like 'redis package count event creation', 'guest', 'container'
+ it_behaves_like 'db package event creation', 'guest', 'generic'
+ it_behaves_like 'redis package count event creation', 'guest', 'generic'
end
context 'with a package as scope' do
diff --git a/spec/services/packages/maven/metadata/sync_service_spec.rb b/spec/services/packages/maven/metadata/sync_service_spec.rb
index 30ddb48207a..a736ed281f0 100644
--- a/spec/services/packages/maven/metadata/sync_service_spec.rb
+++ b/spec/services/packages/maven/metadata/sync_service_spec.rb
@@ -265,4 +265,22 @@ RSpec.describe ::Packages::Maven::Metadata::SyncService do
end
end
end
+
+ # TODO When cleaning up packages_installable_package_files, consider adding a
+ # dummy package file pending for destruction on L10/11 and remove this context
+ context 'with package files pending destruction' do
+ let_it_be(:package_file_pending_destruction) { create(:package_file, :pending_destruction, package: versionless_package_for_versions, file_name: Packages::Maven::Metadata.filename) }
+
+ subject { service.send(:metadata_package_file_for, versionless_package_for_versions) }
+
+ it { is_expected.not_to eq(package_file_pending_destruction) }
+
+ context 'with packages_installable_package_files disabled' do
+ before do
+ stub_feature_flags(packages_installable_package_files: false)
+ end
+
+ it { is_expected.to eq(package_file_pending_destruction) }
+ end
+ end
end
diff --git a/spec/services/packages/terraform_module/create_package_service_spec.rb b/spec/services/packages/terraform_module/create_package_service_spec.rb
index f911bb5b82c..e172aa726fd 100644
--- a/spec/services/packages/terraform_module/create_package_service_spec.rb
+++ b/spec/services/packages/terraform_module/create_package_service_spec.rb
@@ -37,7 +37,7 @@ RSpec.describe Packages::TerraformModule::CreatePackageService do
let!(:existing_package) { create(:terraform_module_package, project: project2, name: 'foo/bar', version: '1.0.0') }
it { expect(subject[:http_status]).to eq 403 }
- it { expect(subject[:message]).to be 'Package already exists.' }
+ it { expect(subject[:message]).to be 'Access Denied' }
end
context 'version already exists' do
diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb
index 2aa9be5066f..d5fbf96ce74 100644
--- a/spec/services/projects/create_service_spec.rb
+++ b/spec/services/projects/create_service_spec.rb
@@ -119,7 +119,7 @@ RSpec.describe Projects::CreateService, '#execute' do
project = create_project(user, opts)
expect(project).to be_valid
- expect(project.owner).to eq(user)
+ expect(project.first_owner).to eq(user)
expect(project.team.maintainers).to include(user)
expect(project.namespace).to eq(user.namespace)
expect(project.project_namespace).to be_in_sync_with_project(project)
@@ -154,6 +154,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.namespace).to eq(user.namespace)
expect(project.project_namespace).to be_in_sync_with_project(project)
diff --git a/spec/services/projects/destroy_service_spec.rb b/spec/services/projects/destroy_service_spec.rb
index b22f276ee1f..9475f562d71 100644
--- a/spec/services/projects/destroy_service_spec.rb
+++ b/spec/services/projects/destroy_service_spec.rb
@@ -64,7 +64,7 @@ RSpec.describe Projects::DestroyService, :aggregate_failures do
create(:ci_pipeline_artifact, pipeline: pipeline)
create_list(:ci_build_trace_chunk, 3, build: builds[0])
- expect { destroy_project(project, project.owner, {}) }.not_to exceed_query_limit(recorder)
+ expect { destroy_project(project, project.first_owner, {}) }.not_to exceed_query_limit(recorder)
end
it_behaves_like 'deleting the project'
@@ -78,6 +78,11 @@ RSpec.describe Projects::DestroyService, :aggregate_failures do
end.not_to raise_error
end
+ it 'reports the error' do
+ expect(Gitlab::ErrorTracking).to receive(:track_exception).and_call_original
+ destroy_project(project, user, {})
+ end
+
it 'unmarks the project as "pending deletion"' do
destroy_project(project, user, {})
diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb
index 3f58fa46806..ce30a20edf4 100644
--- a/spec/services/projects/fork_service_spec.rb
+++ b/spec/services/projects/fork_service_spec.rb
@@ -61,7 +61,7 @@ RSpec.describe Projects::ForkService do
it { expect(to_project).to be_persisted }
it { expect(to_project.errors).to be_empty }
- it { expect(to_project.owner).to eq(@to_user) }
+ it { expect(to_project.first_owner).to eq(@to_user) }
it { expect(to_project.namespace).to eq(@to_user.namespace) }
it { expect(to_project.star_count).to be_zero }
it { expect(to_project.description).to eq(@from_project.description) }
@@ -274,7 +274,7 @@ RSpec.describe Projects::ForkService do
expect(to_project).to be_persisted
expect(to_project.errors).to be_empty
- expect(to_project.owner).to eq(@group)
+ expect(to_project.first_owner).to eq(@group_owner)
expect(to_project.namespace).to eq(@group)
expect(to_project.name).to eq(@project.name)
expect(to_project.path).to eq(@project.path)
diff --git a/spec/services/projects/prometheus/alerts/notify_service_spec.rb b/spec/services/projects/prometheus/alerts/notify_service_spec.rb
index 3bd96ad19bc..0d0bb317df2 100644
--- a/spec/services/projects/prometheus/alerts/notify_service_spec.rb
+++ b/spec/services/projects/prometheus/alerts/notify_service_spec.rb
@@ -224,6 +224,78 @@ RSpec.describe Projects::Prometheus::Alerts::NotifyService do
end
end
end
+
+ context 'when payload exceeds max amount of processable alerts' do
+ # We are defining 2 alerts in payload_raw above
+ let(:max_alerts) { 1 }
+
+ before do
+ stub_const("#{described_class}::PROCESS_MAX_ALERTS", max_alerts)
+
+ create(:prometheus_integration, project: project)
+ create(:project_alerting_setting, project: project, token: token)
+
+ allow(Gitlab::AppLogger).to receive(:warn)
+ end
+
+ shared_examples 'process truncated alerts' do
+ it 'returns 200 but skips processing and logs a warning', :aggregate_failures do
+ expect(subject).to be_success
+ expect(subject.payload[:alerts].size).to eq(max_alerts)
+ expect(Gitlab::AppLogger)
+ .to have_received(:warn)
+ .with(
+ message: 'Prometheus payload exceeded maximum amount of alerts. Truncating alerts.',
+ project_id: project.id,
+ alerts: {
+ total: 2,
+ max: max_alerts
+ })
+ end
+ end
+
+ shared_examples 'process all alerts' do
+ it 'returns 200 and process alerts without warnings', :aggregate_failures do
+ expect(subject).to be_success
+ expect(subject.payload[:alerts].size).to eq(2)
+ expect(Gitlab::AppLogger).not_to have_received(:warn)
+ end
+ end
+
+ context 'with feature flag globally enabled' do
+ before do
+ stub_feature_flags(prometheus_notify_max_alerts: true)
+ end
+
+ include_examples 'process truncated alerts'
+ end
+
+ context 'with feature flag enabled on project' do
+ before do
+ stub_feature_flags(prometheus_notify_max_alerts: project)
+ end
+
+ include_examples 'process truncated alerts'
+ end
+
+ context 'with feature flag enabled on unrelated project' do
+ let(:another_project) { create(:project) }
+
+ before do
+ stub_feature_flags(prometheus_notify_max_alerts: another_project)
+ end
+
+ include_examples 'process all alerts'
+ end
+
+ context 'with feature flag disabled' do
+ before do
+ stub_feature_flags(prometheus_notify_max_alerts: false)
+ end
+
+ include_examples 'process all alerts'
+ end
+ end
end
context 'with invalid payload' do
diff --git a/spec/services/projects/repository_languages_service_spec.rb b/spec/services/projects/repository_languages_service_spec.rb
index cb61a7a1a3e..50d5fba6b84 100644
--- a/spec/services/projects/repository_languages_service_spec.rb
+++ b/spec/services/projects/repository_languages_service_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Projects::RepositoryLanguagesService do
- let(:service) { described_class.new(project, project.owner) }
+ let(:service) { described_class.new(project, project.first_owner) }
context 'when detected_repository_languages flag is set' do
let(:project) { create(:project) }
diff --git a/spec/services/projects/update_pages_configuration_service_spec.rb b/spec/services/projects/update_pages_configuration_service_spec.rb
deleted file mode 100644
index 58939ef4ada..00000000000
--- a/spec/services/projects/update_pages_configuration_service_spec.rb
+++ /dev/null
@@ -1,76 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Projects::UpdatePagesConfigurationService do
- let(:service) { described_class.new(project) }
-
- describe "#execute" do
- subject { service.execute }
-
- context 'when pages are deployed' do
- let_it_be(:project) do
- create(:project).tap(&:mark_pages_as_deployed)
- end
-
- let(:file) { Tempfile.new('pages-test') }
-
- before do
- allow(service).to receive(:pages_config_file).and_return(file.path)
- end
-
- after do
- file.close
- file.unlink
- end
-
- context 'when configuration changes' do
- it 'updates the config and reloads the daemon' do
- expect(service).to receive(:update_file).with(file.path, an_instance_of(String))
- .and_call_original
- allow(service).to receive(:update_file).with(File.join(::Settings.pages.path, '.update'),
- an_instance_of(String)).and_call_original
-
- expect(subject).to include(status: :success)
- end
-
- it "doesn't update configuration files if updates on legacy storage are disabled" do
- allow(Settings.pages.local_store).to receive(:enabled).and_return(false)
-
- expect(service).not_to receive(:update_file)
-
- expect(subject).to include(status: :success)
- end
- end
-
- context 'when configuration does not change' do
- before do
- # we set the configuration
- service.execute
- end
-
- it 'does not update anything' do
- expect(service).not_to receive(:update_file)
-
- expect(subject).to include(status: :success)
- end
- end
- end
-
- context 'when pages are not deployed' do
- let_it_be(:project) do
- create(:project).tap(&:mark_pages_as_not_deployed)
- end
-
- it 'returns successfully' do
- expect(subject).to eq(status: :success)
- end
-
- it 'does not update the config' do
- expect(service).not_to receive(:update_file)
-
- subject
- end
- end
- end
-end
diff --git a/spec/services/projects/update_remote_mirror_service_spec.rb b/spec/services/projects/update_remote_mirror_service_spec.rb
index f4a6d1b19e7..547641867bc 100644
--- a/spec/services/projects/update_remote_mirror_service_spec.rb
+++ b/spec/services/projects/update_remote_mirror_service_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe Projects::UpdateRemoteMirrorService do
subject(:execute!) { service.execute(remote_mirror, retries) }
before do
- project.repository.add_branch(project.owner, 'existing-branch', 'master')
+ project.repository.add_branch(project.first_owner, 'existing-branch', 'master')
allow(remote_mirror)
.to receive(:update_repository)
@@ -131,32 +131,82 @@ RSpec.describe Projects::UpdateRemoteMirrorService do
expect_next_instance_of(Lfs::PushService) do |service|
expect(service).to receive(:execute)
end
+ expect(Gitlab::AppJsonLogger).not_to receive(:info)
execute!
+
+ expect(remote_mirror.update_status).to eq('finished')
+ expect(remote_mirror.last_error).to be_nil
end
- it 'does nothing to an SSH repository' do
- remote_mirror.update!(url: 'ssh://example.com')
+ context 'when LFS objects fail to push' do
+ before do
+ expect_next_instance_of(Lfs::PushService) do |service|
+ expect(service).to receive(:execute).and_return({ status: :error, message: 'unauthorized' })
+ end
+ end
+
+ context 'when remote_mirror_fail_on_lfs feature flag enabled' do
+ it 'fails update' do
+ expect(Gitlab::AppJsonLogger).to receive(:info).with(
+ hash_including(message: "Error synching remote mirror")).and_call_original
- expect_any_instance_of(Lfs::PushService).not_to receive(:execute)
+ execute!
- execute!
- end
+ expect(remote_mirror.update_status).to eq('failed')
+ expect(remote_mirror.last_error).to eq("Error synchronizing LFS files:\n\nunauthorized\n\n")
+ end
+ end
- it 'does nothing if LFS is disabled' do
- expect(project).to receive(:lfs_enabled?) { false }
+ context 'when remote_mirror_fail_on_lfs feature flag is disabled' do
+ before do
+ stub_feature_flags(remote_mirror_fail_on_lfs: false)
+ end
- expect_any_instance_of(Lfs::PushService).not_to receive(:execute)
+ it 'does not fail update' do
+ expect(Gitlab::AppJsonLogger).to receive(:info).with(
+ hash_including(message: "Error synching remote mirror")).and_call_original
- execute!
+ execute!
+
+ expect(remote_mirror.update_status).to eq('finished')
+ expect(remote_mirror.last_error).to be_nil
+ end
+ end
end
- it 'does nothing if non-password auth is specified' do
- remote_mirror.update!(auth_method: 'ssh_public_key')
+ context 'with SSH repository' do
+ let(:ssh_mirror) { create(:remote_mirror, project: project, enabled: true) }
+
+ before do
+ allow(ssh_mirror)
+ .to receive(:update_repository)
+ .and_return(double(divergent_refs: []))
+ end
+
+ it 'does nothing to an SSH repository' do
+ ssh_mirror.update!(url: 'ssh://example.com')
- expect_any_instance_of(Lfs::PushService).not_to receive(:execute)
+ expect_any_instance_of(Lfs::PushService).not_to receive(:execute)
- execute!
+ service.execute(ssh_mirror, retries)
+ end
+
+ it 'does nothing if LFS is disabled' do
+ expect(project).to receive(:lfs_enabled?) { false }
+
+ expect_any_instance_of(Lfs::PushService).not_to receive(:execute)
+
+ service.execute(ssh_mirror, retries)
+ end
+
+ it 'does nothing if non-password auth is specified' do
+ ssh_mirror.update!(auth_method: 'ssh_public_key')
+
+ expect_any_instance_of(Lfs::PushService).not_to receive(:execute)
+
+ service.execute(ssh_mirror, retries)
+ end
end
end
end
diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb
index 4923ef169e8..7b5bf1db030 100644
--- a/spec/services/projects/update_service_spec.rb
+++ b/spec/services/projects/update_service_spec.rb
@@ -149,7 +149,7 @@ RSpec.describe Projects::UpdateService do
describe 'when updating project that has forks' do
let(:project) { create(:project, :internal) }
- let(:user) { project.owner }
+ let(:user) { project.first_owner }
let(:forked_project) { fork_project(project) }
context 'and unlink forks feature flag is off' do
@@ -379,52 +379,6 @@ RSpec.describe Projects::UpdateService do
end
end
- shared_examples 'updating pages configuration' do
- it 'schedules the `PagesUpdateConfigurationWorker` when pages are deployed' do
- project.mark_pages_as_deployed
-
- expect(PagesUpdateConfigurationWorker).to receive(:perform_async).with(project.id)
-
- subject
- end
-
- it "does not schedule a job when pages aren't deployed" do
- project.mark_pages_as_not_deployed
-
- expect(PagesUpdateConfigurationWorker).not_to receive(:perform_async).with(project.id)
-
- subject
- end
- end
-
- context 'when updating #pages_https_only', :https_pages_enabled do
- subject(:call_service) do
- update_project(project, admin, pages_https_only: false)
- end
-
- it 'updates the attribute' do
- expect { call_service }
- .to change { project.pages_https_only? }
- .to(false)
- end
-
- it_behaves_like 'updating pages configuration'
- end
-
- context 'when updating #pages_access_level' do
- subject(:call_service) do
- update_project(project, admin, project_feature_attributes: { pages_access_level: ProjectFeature::ENABLED })
- end
-
- it 'updates the attribute' do
- expect { call_service }
- .to change { project.project_feature.pages_access_level }
- .to(ProjectFeature::ENABLED)
- end
-
- it_behaves_like 'updating pages configuration'
- end
-
context 'when updating #emails_disabled' do
it 'updates the attribute for the project owner' do
expect { update_project(project, user, emails_disabled: true) }
diff --git a/spec/services/protected_branches/create_service_spec.rb b/spec/services/protected_branches/create_service_spec.rb
index 756c775be9b..0bea3edf203 100644
--- a/spec/services/protected_branches/create_service_spec.rb
+++ b/spec/services/protected_branches/create_service_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe ProtectedBranches::CreateService do
let(:project) { create(:project) }
- let(:user) { project.owner }
+ let(:user) { project.first_owner }
let(:params) do
{
name: name,
diff --git a/spec/services/protected_branches/destroy_service_spec.rb b/spec/services/protected_branches/destroy_service_spec.rb
index 47a048e7033..4e55c72f312 100644
--- a/spec/services/protected_branches/destroy_service_spec.rb
+++ b/spec/services/protected_branches/destroy_service_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe ProtectedBranches::DestroyService do
let(:protected_branch) { create(:protected_branch) }
let(:project) { protected_branch.project }
- let(:user) { project.owner }
+ let(:user) { project.first_owner }
describe '#execute' do
subject(:service) { described_class.new(project, user) }
diff --git a/spec/services/protected_branches/update_service_spec.rb b/spec/services/protected_branches/update_service_spec.rb
index b5cf1a54aff..3d9b77dcfc0 100644
--- a/spec/services/protected_branches/update_service_spec.rb
+++ b/spec/services/protected_branches/update_service_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe ProtectedBranches::UpdateService do
let(:protected_branch) { create(:protected_branch) }
let(:project) { protected_branch.project }
- let(:user) { project.owner }
+ let(:user) { project.first_owner }
let(:params) { { name: new_name } }
describe '#execute' do
diff --git a/spec/services/protected_tags/create_service_spec.rb b/spec/services/protected_tags/create_service_spec.rb
index 3d06cc9fb6c..31059d17f10 100644
--- a/spec/services/protected_tags/create_service_spec.rb
+++ b/spec/services/protected_tags/create_service_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe ProtectedTags::CreateService do
let(:project) { create(:project) }
- let(:user) { project.owner }
+ let(:user) { project.first_owner }
let(:params) do
{
name: name,
diff --git a/spec/services/protected_tags/destroy_service_spec.rb b/spec/services/protected_tags/destroy_service_spec.rb
index fbd1452a8d1..658a4f5557e 100644
--- a/spec/services/protected_tags/destroy_service_spec.rb
+++ b/spec/services/protected_tags/destroy_service_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe ProtectedTags::DestroyService do
let(:protected_tag) { create(:protected_tag) }
let(:project) { protected_tag.project }
- let(:user) { project.owner }
+ let(:user) { project.first_owner }
describe '#execute' do
subject(:service) { described_class.new(project, user) }
diff --git a/spec/services/protected_tags/update_service_spec.rb b/spec/services/protected_tags/update_service_spec.rb
index 22005bb9b89..8d301dcd825 100644
--- a/spec/services/protected_tags/update_service_spec.rb
+++ b/spec/services/protected_tags/update_service_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe ProtectedTags::UpdateService do
let(:protected_tag) { create(:protected_tag) }
let(:project) { protected_tag.project }
- let(:user) { project.owner }
+ let(:user) { project.first_owner }
let(:params) { { name: new_name } }
describe '#execute' do
diff --git a/spec/services/quick_actions/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb
index 77d263f4b70..e56e54db6f4 100644
--- a/spec/services/quick_actions/interpret_service_spec.rb
+++ b/spec/services/quick_actions/interpret_service_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe QuickActions::InterpretService do
- let_it_be(:group) { create(:group) }
+ let_it_be(:group) { create(:group, :crm_enabled) }
let_it_be(:public_project) { create(:project, :public, group: group) }
let_it_be(:repository_project) { create(:project, :repository) }
let_it_be(:project) { public_project }
diff --git a/spec/services/resource_access_tokens/create_service_spec.rb b/spec/services/resource_access_tokens/create_service_spec.rb
index 42520ea26b2..5a88929334b 100644
--- a/spec/services/resource_access_tokens/create_service_spec.rb
+++ b/spec/services/resource_access_tokens/create_service_spec.rb
@@ -7,10 +7,14 @@ RSpec.describe ResourceAccessTokens::CreateService do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :private) }
+ let_it_be(:group) { create(:group, :private) }
let_it_be(:params) { {} }
+ before do
+ stub_config_setting(host: 'example.com')
+ end
+
describe '#execute' do
- # Created shared_examples as it will easy to include specs for group bots in https://gitlab.com/gitlab-org/gitlab/-/issues/214046
shared_examples 'token creation fails' do
let(:resource) { create(:project)}
@@ -31,7 +35,7 @@ RSpec.describe ResourceAccessTokens::CreateService do
access_token = response.payload[:access_token]
- expect(access_token.user.reload.user_type).to eq("#{resource_type}_bot")
+ expect(access_token.user.reload.user_type).to eq("project_bot")
expect(access_token.user.created_by_id).to eq(user.id)
end
@@ -88,6 +92,15 @@ RSpec.describe ResourceAccessTokens::CreateService do
end
end
+ context 'bot email' do
+ it 'check email domain' do
+ response = subject
+ access_token = response.payload[:access_token]
+
+ expect(access_token.user.email).to end_with("@noreply.#{Gitlab.config.gitlab.host}")
+ end
+ end
+
context 'access level' do
context 'when user does not specify an access level' do
it 'adds the bot user as a maintainer in the resource' do
@@ -112,10 +125,8 @@ RSpec.describe ResourceAccessTokens::CreateService do
end
context 'when user is external' do
- let(:user) { create(:user, :external) }
-
before do
- project.add_maintainer(user)
+ user.update!(external: true)
end
it 'creates resource bot user with external status' do
@@ -162,7 +173,7 @@ RSpec.describe ResourceAccessTokens::CreateService do
access_token = response.payload[:access_token]
project_bot = access_token.user
- expect(project.members.find_by(user_id: project_bot.id).expires_at).to eq(nil)
+ expect(resource.members.find_by(user_id: project_bot.id).expires_at).to eq(nil)
end
end
end
@@ -183,7 +194,7 @@ RSpec.describe ResourceAccessTokens::CreateService do
access_token = response.payload[:access_token]
project_bot = access_token.user
- expect(project.members.find_by(user_id: project_bot.id).expires_at).to eq(params[:expires_at])
+ expect(resource.members.find_by(user_id: project_bot.id).expires_at).to eq(params[:expires_at])
end
end
end
@@ -234,24 +245,41 @@ RSpec.describe ResourceAccessTokens::CreateService do
end
end
+ shared_examples 'when user does not have permission to create a resource bot' do
+ it_behaves_like 'token creation fails'
+
+ it 'returns the permission error message' do
+ response = subject
+
+ expect(response.error?).to be true
+ expect(response.errors).to include("User does not have permission to create #{resource_type} access token")
+ end
+ end
+
context 'when resource is a project' do
let_it_be(:resource_type) { 'project' }
let_it_be(:resource) { project }
- context 'when user does not have permission to create a resource bot' do
- it_behaves_like 'token creation fails'
-
- it 'returns the permission error message' do
- response = subject
+ it_behaves_like 'when user does not have permission to create a resource bot'
- expect(response.error?).to be true
- expect(response.errors).to include("User does not have permission to create #{resource_type} access token")
+ context 'user with valid permission' do
+ before_all do
+ resource.add_maintainer(user)
end
+
+ it_behaves_like 'allows creation of bot with valid params'
end
+ end
+
+ context 'when resource is a project' do
+ let_it_be(:resource_type) { 'group' }
+ let_it_be(:resource) { group }
+
+ it_behaves_like 'when user does not have permission to create a resource bot'
context 'user with valid permission' do
before_all do
- resource.add_maintainer(user)
+ resource.add_owner(user)
end
it_behaves_like 'allows creation of bot with valid params'
diff --git a/spec/services/resource_access_tokens/revoke_service_spec.rb b/spec/services/resource_access_tokens/revoke_service_spec.rb
index 4f4e2ab0c99..3d724a79fef 100644
--- a/spec/services/resource_access_tokens/revoke_service_spec.rb
+++ b/spec/services/resource_access_tokens/revoke_service_spec.rb
@@ -6,11 +6,12 @@ RSpec.describe ResourceAccessTokens::RevokeService do
subject { described_class.new(user, resource, access_token).execute }
let_it_be(:user) { create(:user) }
+ let_it_be(:user_non_priviledged) { create(:user) }
+ let_it_be(:resource_bot) { create(:user, :project_bot) }
let(:access_token) { create(:personal_access_token, user: resource_bot) }
describe '#execute', :sidekiq_inline do
- # Created shared_examples as it will easy to include specs for group bots in https://gitlab.com/gitlab-org/gitlab/-/issues/214046
shared_examples 'revokes access token' do
it { expect(subject.success?).to be true }
@@ -79,71 +80,80 @@ RSpec.describe ResourceAccessTokens::RevokeService do
end
end
- context 'when resource is a project' do
- let_it_be(:resource) { create(:project, :private) }
+ shared_examples 'revoke fails' do |resource_type|
+ let_it_be(:other_user) { create(:user) }
- let(:resource_bot) { create(:user, :project_bot) }
+ context "when access token does not belong to this #{resource_type}" do
+ it 'does not find the bot' do
+ other_access_token = create(:personal_access_token, user: other_user)
- before do
- resource.add_maintainer(user)
- resource.add_maintainer(resource_bot)
- end
+ response = described_class.new(user, resource, other_access_token).execute
- it_behaves_like 'revokes access token'
+ expect(response.success?).to be false
+ expect(response.message).to eq("Failed to find bot user")
+ expect(access_token.reload.revoked?).to be false
+ end
+ end
- context 'revoke fails' do
- let_it_be(:other_user) { create(:user) }
+ context 'when user does not have permission to destroy bot' do
+ context "when non-#{resource_type} member tries to delete project bot" do
+ it 'does not allow other user to delete bot' do
+ response = described_class.new(other_user, resource, access_token).execute
- context 'when access token does not belong to this project' do
- it 'does not find the bot' do
- other_access_token = create(:personal_access_token, user: other_user)
+ expect(response.success?).to be false
+ expect(response.message).to eq("#{other_user.name} cannot delete #{access_token.user.name}")
+ expect(access_token.reload.revoked?).to be false
+ end
+ end
- response = described_class.new(user, resource, other_access_token).execute
+ context "when non-priviledged #{resource_type} member tries to delete project bot" do
+ it 'does not allow developer to delete bot' do
+ response = described_class.new(user_non_priviledged, resource, access_token).execute
expect(response.success?).to be false
- expect(response.message).to eq("Failed to find bot user")
+ expect(response.message).to eq("#{user_non_priviledged.name} cannot delete #{access_token.user.name}")
expect(access_token.reload.revoked?).to be false
end
end
+ end
- context 'when user does not have permission to destroy bot' do
- context 'when non-project member tries to delete project bot' do
- it 'does not allow other user to delete bot' do
- response = described_class.new(other_user, resource, access_token).execute
-
- expect(response.success?).to be false
- expect(response.message).to eq("#{other_user.name} cannot delete #{access_token.user.name}")
- expect(access_token.reload.revoked?).to be false
- end
+ context 'when deletion of bot user fails' do
+ before do
+ allow_next_instance_of(::ResourceAccessTokens::RevokeService) do |service|
+ allow(service).to receive(:execute).and_return(false)
end
+ end
+
+ it_behaves_like 'rollback revoke steps'
+ end
+ end
- context 'when non-maintainer project member tries to delete project bot' do
- let(:developer) { create(:user) }
+ context 'when resource is a project' do
+ let_it_be(:resource) { create(:project, :private) }
- before do
- resource.add_developer(developer)
- end
+ before do
+ resource.add_maintainer(user)
+ resource.add_developer(user_non_priviledged)
+ resource.add_maintainer(resource_bot)
+ end
- it 'does not allow developer to delete bot' do
- response = described_class.new(developer, resource, access_token).execute
+ it_behaves_like 'revokes access token'
- expect(response.success?).to be false
- expect(response.message).to eq("#{developer.name} cannot delete #{access_token.user.name}")
- expect(access_token.reload.revoked?).to be false
- end
- end
- end
+ it_behaves_like 'revoke fails', 'project'
+ end
- context 'when deletion of bot user fails' do
- before do
- allow_next_instance_of(::ResourceAccessTokens::RevokeService) do |service|
- allow(service).to receive(:execute).and_return(false)
- end
- end
+ context 'when resource is a group' do
+ let_it_be(:resource) { create(:group, :private) }
- it_behaves_like 'rollback revoke steps'
- end
+ before do
+ resource.add_owner(user)
+ resource.add_maintainer(user_non_priviledged)
+ resource.add_maintainer(resource_bot)
end
+
+ it_behaves_like 'revokes access token'
+
+ it_behaves_like 'revoke fails', 'group'
end
end
end
diff --git a/spec/services/service_ping/submit_service_ping_service_spec.rb b/spec/services/service_ping/submit_service_ping_service_spec.rb
index ca387690e83..2971c9a9309 100644
--- a/spec/services/service_ping/submit_service_ping_service_spec.rb
+++ b/spec/services/service_ping/submit_service_ping_service_spec.rb
@@ -110,6 +110,7 @@ RSpec.describe ServicePing::SubmitService do
context 'when product_intelligence_enabled is true' do
before do
stub_usage_data_connections
+ stub_database_flavor_check
allow(ServicePing::ServicePingSettings).to receive(:product_intelligence_enabled?).and_return(true)
end
@@ -126,6 +127,7 @@ RSpec.describe ServicePing::SubmitService do
context 'when usage ping is enabled' do
before do
stub_usage_data_connections
+ stub_database_flavor_check
stub_application_setting(usage_ping_enabled: true)
end
diff --git a/spec/services/test_hooks/system_service_spec.rb b/spec/services/test_hooks/system_service_spec.rb
index a13ae471b4b..48c8c24212a 100644
--- a/spec/services/test_hooks/system_service_spec.rb
+++ b/spec/services/test_hooks/system_service_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe TestHooks::SystemService do
let_it_be(:project) { create(:project, :repository) }
let(:hook) { create(:system_hook) }
- let(:service) { described_class.new(hook, project.owner, trigger) }
+ let(:service) { described_class.new(hook, project.first_owner, trigger) }
let(:success_result) { { status: :success, http_status: 200, message: 'ok' } }
before do
diff --git a/spec/services/users/create_service_spec.rb b/spec/services/users/create_service_spec.rb
index 74340bac055..ab9da82e91c 100644
--- a/spec/services/users/create_service_spec.rb
+++ b/spec/services/users/create_service_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe Users::CreateService do
context 'when required parameters are provided' do
let(:params) do
- { name: 'John Doe', username: 'jduser', email: email, password: 'mydummypass' }
+ { name: 'John Doe', username: 'jduser', email: email, password: Gitlab::Password.test_default }
end
it 'returns a persisted user' do
@@ -82,13 +82,13 @@ RSpec.describe Users::CreateService do
context 'when force_random_password parameter is true' do
let(:params) do
- { name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: 'mydummypass', force_random_password: true }
+ { name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: Gitlab::Password.test_default, force_random_password: true }
end
it 'generates random password' do
user = service.execute
- expect(user.password).not_to eq 'mydummypass'
+ expect(user.password).not_to eq Gitlab::Password.test_default
expect(user.password).to be_present
end
end
@@ -99,7 +99,7 @@ RSpec.describe Users::CreateService do
name: 'John Doe',
username: 'jduser',
email: 'jd@example.com',
- password: 'mydummypass',
+ password: Gitlab::Password.test_default,
password_automatically_set: true
}
end
@@ -121,7 +121,7 @@ RSpec.describe Users::CreateService do
context 'when skip_confirmation parameter is true' do
let(:params) do
- { name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: 'mydummypass', skip_confirmation: true }
+ { name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: Gitlab::Password.test_default, skip_confirmation: true }
end
it 'confirms the user' do
@@ -131,7 +131,7 @@ RSpec.describe Users::CreateService do
context 'when reset_password parameter is true' do
let(:params) do
- { name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: 'mydummypass', reset_password: true }
+ { name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: Gitlab::Password.test_default, reset_password: true }
end
it 'resets password even if a password parameter is given' do
@@ -152,7 +152,7 @@ RSpec.describe Users::CreateService do
context 'with nil user' do
let(:params) do
- { name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: 'mydummypass', skip_confirmation: true }
+ { name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: Gitlab::Password.test_default, skip_confirmation: true }
end
let(:service) { described_class.new(nil, params) }
diff --git a/spec/services/users/refresh_authorized_projects_service_spec.rb b/spec/services/users/refresh_authorized_projects_service_spec.rb
index aa4df93a241..a31902c7f16 100644
--- a/spec/services/users/refresh_authorized_projects_service_spec.rb
+++ b/spec/services/users/refresh_authorized_projects_service_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe Users::RefreshAuthorizedProjectsService do
# triggered twice.
let!(:project) { create(:project) }
- let(:user) { project.namespace.owner }
+ let(:user) { project.namespace.first_owner }
let(:service) { described_class.new(user) }
describe '#execute', :clean_gitlab_redis_shared_state do
diff --git a/spec/services/users/upsert_credit_card_validation_service_spec.rb b/spec/services/users/upsert_credit_card_validation_service_spec.rb
index 952d482f1bd..ac7e619612f 100644
--- a/spec/services/users/upsert_credit_card_validation_service_spec.rb
+++ b/spec/services/users/upsert_credit_card_validation_service_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Users::UpsertCreditCardValidationService do
- let_it_be(:user) { create(:user) }
+ let_it_be(:user) { create(:user, requires_credit_card_verification: true) }
let(:user_id) { user.id }
let(:credit_card_validated_time) { Time.utc(2020, 1, 1) }
@@ -21,7 +21,7 @@ RSpec.describe Users::UpsertCreditCardValidationService do
end
describe '#execute' do
- subject(:service) { described_class.new(params) }
+ subject(:service) { described_class.new(params, user) }
context 'successfully set credit card validation record for the user' do
context 'when user does not have credit card validation record' do
@@ -42,6 +42,10 @@ RSpec.describe Users::UpsertCreditCardValidationService do
expiration_date: Date.new(expiration_year, 1, 31)
)
end
+
+ it 'sets the requires_credit_card_verification attribute on the user to false' do
+ expect { service.execute }.to change { user.reload.requires_credit_card_verification }.to(false)
+ end
end
context 'when user has credit card validation record' do
diff --git a/spec/services/verify_pages_domain_service_spec.rb b/spec/services/verify_pages_domain_service_spec.rb
index 2a3b3814065..42f7ebc85f9 100644
--- a/spec/services/verify_pages_domain_service_spec.rb
+++ b/spec/services/verify_pages_domain_service_spec.rb
@@ -269,56 +269,6 @@ RSpec.describe VerifyPagesDomainService do
end
end
- context 'pages configuration updates' do
- context 'enabling a disabled domain' do
- let(:domain) { create(:pages_domain, :disabled) }
-
- it 'schedules an update' do
- stub_resolver(domain.domain => domain.verification_code)
-
- expect(domain).to receive(:update_daemon)
-
- service.execute
- end
- end
-
- context 'verifying an enabled domain' do
- let(:domain) { create(:pages_domain) }
-
- it 'schedules an update' do
- stub_resolver(domain.domain => domain.verification_code)
-
- expect(domain).not_to receive(:update_daemon)
-
- service.execute
- end
- end
-
- context 'disabling an expired domain' do
- let(:domain) { create(:pages_domain, :expired) }
-
- it 'schedules an update' do
- stub_resolver
-
- expect(domain).to receive(:update_daemon)
-
- service.execute
- end
- end
-
- context 'failing to verify a disabled domain' do
- let(:domain) { create(:pages_domain, :disabled) }
-
- it 'does not schedule an update' do
- stub_resolver
-
- expect(domain).not_to receive(:update_daemon)
-
- service.execute
- end
- end
- end
-
context 'no verification code' do
let(:domain) { create(:pages_domain) }
diff --git a/spec/services/web_hook_service_spec.rb b/spec/services/web_hook_service_spec.rb
index 2aebd2adab9..7d933ea9c5c 100644
--- a/spec/services/web_hook_service_spec.rb
+++ b/spec/services/web_hook_service_spec.rb
@@ -2,20 +2,12 @@
require 'spec_helper'
-RSpec.describe WebHookService do
+RSpec.describe WebHookService, :request_store, :clean_gitlab_redis_shared_state do
include StubRequests
let_it_be(:project) { create(:project) }
let_it_be_with_reload(:project_hook) { create(:project_hook, project: project) }
- let(:headers) do
- {
- 'Content-Type' => 'application/json',
- 'User-Agent' => "GitLab/#{Gitlab::VERSION}",
- 'X-Gitlab-Event' => 'Push Hook'
- }
- end
-
let(:data) do
{ before: 'oldrev', after: 'newrev', ref: 'ref' }
end
@@ -61,6 +53,21 @@ RSpec.describe WebHookService do
end
describe '#execute' do
+ let!(:uuid) { SecureRandom.uuid }
+ let(:headers) do
+ {
+ 'Content-Type' => 'application/json',
+ 'User-Agent' => "GitLab/#{Gitlab::VERSION}",
+ 'X-Gitlab-Event' => 'Push Hook',
+ 'X-Gitlab-Event-UUID' => uuid
+ }
+ end
+
+ before do
+ # Set a stable value for the `X-Gitlab-Event-UUID` header.
+ Gitlab::WebHooks::RecursionDetection.set_request_uuid(uuid)
+ end
+
context 'when token is defined' do
let_it_be(:project_hook) { create(:project_hook, :token) }
@@ -127,11 +134,74 @@ RSpec.describe WebHookService do
expect(service_instance.execute).to eq({ status: :error, message: 'Hook disabled' })
end
+ it 'executes and registers the hook with the recursion detection', :aggregate_failures do
+ stub_full_request(project_hook.url, method: :post)
+ cache_key = Gitlab::WebHooks::RecursionDetection.send(:cache_key_for_hook, project_hook)
+
+ ::Gitlab::Redis::SharedState.with do |redis|
+ expect { service_instance.execute }.to change {
+ redis.sismember(cache_key, project_hook.id)
+ }.to(true)
+ end
+
+ expect(WebMock).to have_requested(:post, stubbed_hostname(project_hook.url))
+ .with(headers: headers)
+ .once
+ end
+
+ it 'executes and logs if a recursive web hook is detected', :aggregate_failures do
+ stub_full_request(project_hook.url, method: :post)
+ Gitlab::WebHooks::RecursionDetection.register!(project_hook)
+
+ expect(Gitlab::AuthLogger).to receive(:error).with(
+ include(
+ message: 'Webhook recursion detected and will be blocked in future',
+ hook_id: project_hook.id,
+ hook_type: 'ProjectHook',
+ hook_name: 'push_hooks',
+ recursion_detection: Gitlab::WebHooks::RecursionDetection.to_log(project_hook),
+ 'correlation_id' => kind_of(String)
+ )
+ )
+
+ service_instance.execute
+
+ expect(WebMock).to have_requested(:post, stubbed_hostname(project_hook.url))
+ .with(headers: headers)
+ .once
+ end
+
+ it 'executes and logs if the recursion count limit would be exceeded', :aggregate_failures do
+ stub_full_request(project_hook.url, method: :post)
+ stub_const("#{Gitlab::WebHooks::RecursionDetection.name}::COUNT_LIMIT", 3)
+ previous_hooks = create_list(:project_hook, 3)
+ previous_hooks.each { Gitlab::WebHooks::RecursionDetection.register!(_1) }
+
+ expect(Gitlab::AuthLogger).to receive(:error).with(
+ include(
+ message: 'Webhook recursion detected and will be blocked in future',
+ hook_id: project_hook.id,
+ hook_type: 'ProjectHook',
+ hook_name: 'push_hooks',
+ recursion_detection: Gitlab::WebHooks::RecursionDetection.to_log(project_hook),
+ 'correlation_id' => kind_of(String)
+ )
+ )
+
+ service_instance.execute
+
+ expect(WebMock).to have_requested(:post, stubbed_hostname(project_hook.url))
+ .with(headers: headers)
+ .once
+ end
+
it 'handles exceptions' do
exceptions = Gitlab::HTTP::HTTP_ERRORS + [
Gitlab::Json::LimitedEncoder::LimitExceeded, URI::InvalidURIError
]
+ allow(Gitlab::WebHooks::RecursionDetection).to receive(:block?).and_return(false)
+
exceptions.each do |exception_class|
exception = exception_class.new('Exception message')
project_hook.enable!
@@ -420,6 +490,57 @@ RSpec.describe WebHookService do
end
end
+ context 'recursion detection' do
+ before do
+ # Set a request UUID so `RecursionDetection.block?` will query redis.
+ Gitlab::WebHooks::RecursionDetection.set_request_uuid(SecureRandom.uuid)
+ end
+
+ it 'queues a worker and logs an error if the call chain limit would be exceeded' do
+ stub_const("#{Gitlab::WebHooks::RecursionDetection.name}::COUNT_LIMIT", 3)
+ previous_hooks = create_list(:project_hook, 3)
+ previous_hooks.each { Gitlab::WebHooks::RecursionDetection.register!(_1) }
+
+ expect(WebHookWorker).to receive(:perform_async)
+ expect(Gitlab::AuthLogger).to receive(:error).with(
+ include(
+ message: 'Webhook recursion detected and will be blocked in future',
+ hook_id: project_hook.id,
+ hook_type: 'ProjectHook',
+ hook_name: 'push_hooks',
+ recursion_detection: Gitlab::WebHooks::RecursionDetection.to_log(project_hook),
+ 'correlation_id' => kind_of(String),
+ 'meta.project' => project.full_path,
+ 'meta.related_class' => 'ProjectHook',
+ 'meta.root_namespace' => project.root_namespace.full_path
+ )
+ )
+
+ service_instance.async_execute
+ end
+
+ it 'queues a worker and logs an error if a recursive call chain is detected' do
+ Gitlab::WebHooks::RecursionDetection.register!(project_hook)
+
+ expect(WebHookWorker).to receive(:perform_async)
+ expect(Gitlab::AuthLogger).to receive(:error).with(
+ include(
+ message: 'Webhook recursion detected and will be blocked in future',
+ hook_id: project_hook.id,
+ hook_type: 'ProjectHook',
+ hook_name: 'push_hooks',
+ recursion_detection: Gitlab::WebHooks::RecursionDetection.to_log(project_hook),
+ 'correlation_id' => kind_of(String),
+ 'meta.project' => project.full_path,
+ 'meta.related_class' => 'ProjectHook',
+ 'meta.root_namespace' => project.root_namespace.full_path
+ )
+ )
+
+ service_instance.async_execute
+ end
+ end
+
context 'when hook has custom context attributes' do
it 'includes the attributes in the worker context' do
expect(WebHookWorker).to receive(:perform_async) do
diff --git a/spec/services/work_items/build_service_spec.rb b/spec/services/work_items/build_service_spec.rb
new file mode 100644
index 00000000000..6b2e2d8819e
--- /dev/null
+++ b/spec/services/work_items/build_service_spec.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe WorkItems::BuildService do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:guest) { create(:user) }
+
+ let(:user) { guest }
+
+ before_all do
+ project.add_guest(guest)
+ end
+
+ describe '#execute' do
+ subject { described_class.new(project: project, current_user: user, params: {}).execute }
+
+ it { is_expected.to be_a(::WorkItem) }
+ end
+end
diff --git a/spec/services/work_items/create_service_spec.rb b/spec/services/work_items/create_service_spec.rb
new file mode 100644
index 00000000000..2c054ae59a0
--- /dev/null
+++ b/spec/services/work_items/create_service_spec.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe WorkItems::CreateService do
+ include AfterNextHelpers
+
+ let_it_be(:group) { create(:group) }
+ let_it_be_with_reload(:project) { create(:project, group: group) }
+ let_it_be(:user) { create(:user) }
+
+ let(:spam_params) { double }
+
+ describe '#execute' do
+ let(:work_item) { described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params).execute }
+
+ before do
+ stub_spam_services
+ end
+
+ context 'when params are valid' do
+ before_all do
+ project.add_guest(user)
+ end
+
+ let(:opts) do
+ {
+ title: 'Awesome work_item',
+ description: 'please fix'
+ }
+ end
+
+ it 'created instance is a WorkItem' do
+ expect(Issuable::CommonSystemNotesService).to receive_message_chain(:new, :execute)
+
+ expect(work_item).to be_persisted
+ expect(work_item).to be_a(::WorkItem)
+ expect(work_item.title).to eq('Awesome work_item')
+ expect(work_item.description).to eq('please fix')
+ expect(work_item.work_item_type.base_type).to eq('issue')
+ end
+ end
+
+ context 'checking spam' do
+ let(:params) do
+ {
+ title: 'Spam work_item'
+ }
+ end
+
+ subject do
+ described_class.new(project: project, current_user: user, params: params, spam_params: spam_params)
+ end
+
+ it 'executes SpamActionService' do
+ expect_next_instance_of(
+ Spam::SpamActionService,
+ {
+ spammable: kind_of(WorkItem),
+ spam_params: spam_params,
+ user: an_instance_of(User),
+ action: :create
+ }
+ ) do |instance|
+ expect(instance).to receive(:execute)
+ end
+
+ subject.execute
+ end
+ end
+ end
+end
diff --git a/spec/simplecov_env.rb b/spec/simplecov_env.rb
index a5efc8348a4..da4a0e8da80 100644
--- a/spec/simplecov_env.rb
+++ b/spec/simplecov_env.rb
@@ -53,7 +53,6 @@ module SimpleCovEnv
track_files '{app,config/initializers,config/initializers_before_autoloader,db/post_migrate,haml_lint,lib,rubocop,tooling}/**/*.rb'
add_filter '/vendor/ruby/'
- add_filter '/app/controllers/sherlock/' # Profiling tool used only in development
add_filter '/bin/'
add_filter 'db/fixtures/development/' # Matches EE files as well
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index c497f8245fe..6d5036365e1 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -290,15 +290,9 @@ RSpec.configure do |config|
stub_feature_flags(diffs_virtual_scrolling: false)
- # The following `vue_issues_list`/`vue_issuables_list` stubs can be removed
+ # The following `vue_issues_list` stub can be removed
# once the Vue issues page has feature parity with the current Haml page
stub_feature_flags(vue_issues_list: false)
- stub_feature_flags(vue_issuables_list: false)
-
- # Disable `refactor_blob_viewer` as we refactor
- # the blob viewer. See the follwing epic for more:
- # https://gitlab.com/groups/gitlab-org/-/epics/5531
- stub_feature_flags(refactor_blob_viewer: false)
# Disable `main_branch_over_master` as we migrate
# from `master` to `main` accross our codebase.
@@ -459,10 +453,23 @@ RSpec.configure do |config|
end
end
+ # Ensures that any Javascript script that tries to make the external VersionCheck API call skips it and returns a response
+ config.before(:each, :js) do
+ allow_any_instance_of(VersionCheck).to receive(:response).and_return({ "severity" => "success" })
+ end
+
config.after(:each, :silence_stdout) do
$stdout = STDOUT
end
+ config.around(:each, stubbing_settings_source: true) do |example|
+ original_instance = ::Settings.instance_variable_get(:@instance)
+
+ example.run
+
+ ::Settings.instance_variable_set(:@instance, original_instance)
+ end
+
config.disable_monkey_patching!
end
diff --git a/spec/support/database/cross-database-modification-allowlist.yml b/spec/support/database/cross-database-modification-allowlist.yml
index d6e74349069..fe51488c706 100644
--- a/spec/support/database/cross-database-modification-allowlist.yml
+++ b/spec/support/database/cross-database-modification-allowlist.yml
@@ -1,31 +1 @@
-- "./ee/spec/mailers/notify_spec.rb"
-- "./ee/spec/models/group_member_spec.rb"
-- "./ee/spec/replicators/geo/terraform_state_version_replicator_spec.rb"
-- "./ee/spec/services/ci/retry_build_service_spec.rb"
-- "./spec/controllers/abuse_reports_controller_spec.rb"
-- "./spec/controllers/omniauth_callbacks_controller_spec.rb"
-- "./spec/controllers/projects/issues_controller_spec.rb"
-- "./spec/features/issues/issue_detail_spec.rb"
-- "./spec/features/projects/pipelines/pipeline_spec.rb"
-- "./spec/features/signed_commits_spec.rb"
-- "./spec/helpers/issuables_helper_spec.rb"
-- "./spec/lib/gitlab/auth_spec.rb"
-- "./spec/lib/gitlab/ci/pipeline/chain/create_spec.rb"
-- "./spec/lib/gitlab/email/handler/create_issue_handler_spec.rb"
-- "./spec/lib/gitlab/email/handler/create_merge_request_handler_spec.rb"
-- "./spec/lib/gitlab/email/handler/create_note_handler_spec.rb"
-- "./spec/lib/gitlab/email/handler/create_note_on_issuable_handler_spec.rb"
-- "./spec/models/ci/build_trace_chunk_spec.rb"
-- "./spec/models/ci/job_artifact_spec.rb"
-- "./spec/models/ci/runner_spec.rb"
-- "./spec/models/clusters/applications/runner_spec.rb"
-- "./spec/models/design_management/version_spec.rb"
-- "./spec/models/hooks/system_hook_spec.rb"
-- "./spec/models/members/project_member_spec.rb"
-- "./spec/models/user_spec.rb"
-- "./spec/models/user_status_spec.rb"
-- "./spec/requests/api/commits_spec.rb"
-- "./spec/services/ci/retry_build_service_spec.rb"
-- "./spec/services/projects/overwrite_project_service_spec.rb"
-- "./spec/workers/merge_requests/create_pipeline_worker_spec.rb"
-- "./spec/workers/repository_cleanup_worker_spec.rb"
+[]
diff --git a/spec/support/db_cleaner.rb b/spec/support/db_cleaner.rb
index 316d645f99f..fb70f82ef87 100644
--- a/spec/support/db_cleaner.rb
+++ b/spec/support/db_cleaner.rb
@@ -67,7 +67,7 @@ module DbCleaner
# Migrate each database individually
with_reestablished_active_record_base do
all_connection_classes.each do |connection_class|
- ActiveRecord::Base.establish_connection(connection_class.connection_db_config)
+ ActiveRecord::Base.establish_connection(connection_class.connection_db_config) # rubocop: disable Database/EstablishConnection
ActiveRecord::Tasks::DatabaseTasks.migrate
end
diff --git a/spec/support/flaky_tests.rb b/spec/support/flaky_tests.rb
index 0c211af695d..5ce55c47aab 100644
--- a/spec/support/flaky_tests.rb
+++ b/spec/support/flaky_tests.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
return unless ENV['CI']
-return unless ENV['SKIP_FLAKY_TESTS_AUTOMATICALLY'] == "true"
+return if ENV['SKIP_FLAKY_TESTS_AUTOMATICALLY'] == "false"
return if ENV['CI_MERGE_REQUEST_LABELS'].to_s.include?('pipeline:run-flaky-tests')
require_relative '../../tooling/rspec_flaky/report'
diff --git a/spec/support/gitlab_stubs/gitlab_ci.yml b/spec/support/gitlab_stubs/gitlab_ci.yml
index f3755e52b2c..52ae36229a6 100644
--- a/spec/support/gitlab_stubs/gitlab_ci.yml
+++ b/spec/support/gitlab_stubs/gitlab_ci.yml
@@ -9,7 +9,7 @@ before_script:
variables:
DB_NAME: postgres
-types:
+stages:
- test
- deploy
- notify
@@ -36,7 +36,7 @@ staging:
KEY1: value1
KEY2: value2
script: "cap deploy stating"
- type: deploy
+ stage: deploy
tags:
- ruby
- mysql
@@ -46,7 +46,7 @@ staging:
production:
variables:
DB_NAME: mysql
- type: deploy
+ stage: deploy
script:
- cap deploy production
- cap notify
@@ -58,7 +58,7 @@ production:
- /^deploy-.*$/
dockerhub:
- type: notify
+ stage: notify
script: "curl http://dockerhub/URL"
tags:
- ruby
diff --git a/spec/support/helpers/cycle_analytics_helpers.rb b/spec/support/helpers/cycle_analytics_helpers.rb
index 722d484609c..70b794f7d82 100644
--- a/spec/support/helpers/cycle_analytics_helpers.rb
+++ b/spec/support/helpers/cycle_analytics_helpers.rb
@@ -59,7 +59,7 @@ module CycleAnalyticsHelpers
def save_value_stream(custom_value_stream_name)
fill_in 'create-value-stream-name', with: custom_value_stream_name
- page.find_button(s_('CreateValueStreamForm|Create Value Stream')).click
+ page.find_button(s_('CreateValueStreamForm|Create value stream')).click
wait_for_requests
end
diff --git a/spec/support/helpers/gitaly_setup.rb b/spec/support/helpers/gitaly_setup.rb
index 923051a2e04..905c439f4d9 100644
--- a/spec/support/helpers/gitaly_setup.rb
+++ b/spec/support/helpers/gitaly_setup.rb
@@ -9,8 +9,13 @@
require 'securerandom'
require 'socket'
require 'logger'
+require 'bundler'
module GitalySetup
+ extend self
+
+ REPOS_STORAGE = 'default'
+
LOGGER = begin
default_name = ENV['CI'] ? 'DEBUG' : 'WARN'
level_name = ENV['GITLAB_TESTING_LOG_LEVEL']&.upcase
@@ -52,11 +57,13 @@ module GitalySetup
def env
{
- 'HOME' => expand_path('tmp/tests'),
'GEM_PATH' => Gem.path.join(':'),
- 'BUNDLE_APP_CONFIG' => File.join(gemfile_dir, '.bundle'),
'BUNDLE_INSTALL_FLAGS' => nil,
+ 'BUNDLE_IGNORE_CONFIG' => '1',
+ 'BUNDLE_PATH' => bundle_path,
'BUNDLE_GEMFILE' => gemfile,
+ 'BUNDLE_JOBS' => '4',
+ 'BUNDLE_RETRY' => '3',
'RUBYOPT' => nil,
# Git hooks can't run during tests as the internal API is not running.
@@ -65,17 +72,20 @@ module GitalySetup
}
end
- # rubocop:disable GitlabSecurity/SystemCommandInjection
- def set_bundler_config
- system('bundle config set --local jobs 4', chdir: gemfile_dir)
- system('bundle config set --local retry 3', chdir: gemfile_dir)
+ def bundle_path
+ # Allow the user to override BUNDLE_PATH if they need to
+ return ENV['GITALY_TEST_BUNDLE_PATH'] if ENV['GITALY_TEST_BUNDLE_PATH']
if ENV['CI']
- bundle_path = expand_path('vendor/gitaly-ruby')
- system('bundle', 'config', 'set', '--local', 'path', bundle_path, chdir: gemfile_dir)
+ expand_path('vendor/gitaly-ruby')
+ else
+ explicit_path = Bundler.configured_bundle_path.explicit_path
+
+ return unless explicit_path
+
+ expand_path(explicit_path)
end
end
- # rubocop:enable GitlabSecurity/SystemCommandInjection
def config_path(service)
case service
@@ -88,6 +98,10 @@ module GitalySetup
end
end
+ def repos_path(storage = REPOS_STORAGE)
+ Gitlab.config.repositories.storages[REPOS_STORAGE].legacy_disk_path
+ end
+
def service_binary(service)
case service
when :gitaly, :gitaly2
@@ -97,16 +111,20 @@ module GitalySetup
end
end
+ def run_command(cmd, env: {})
+ system(env, *cmd, exception: true, chdir: tmp_tests_gitaly_dir)
+ end
+
def install_gitaly_gems
- system(env, "make #{tmp_tests_gitaly_dir}/.ruby-bundle", chdir: tmp_tests_gitaly_dir) # rubocop:disable GitlabSecurity/SystemCommandInjection
+ run_command(%W[make #{tmp_tests_gitaly_dir}/.ruby-bundle], env: env)
end
def build_gitaly
- system(env.merge({ 'GIT_VERSION' => nil }), 'make all git', chdir: tmp_tests_gitaly_dir) # rubocop:disable GitlabSecurity/SystemCommandInjection
+ run_command(%w[make all git], env: env.merge('GIT_VERSION' => nil))
end
- def start_gitaly
- start(:gitaly)
+ def start_gitaly(toml = nil)
+ start(:gitaly, toml)
end
def start_gitaly2
@@ -117,14 +135,20 @@ module GitalySetup
start(:praefect)
end
- def start(service)
+ def start(service, toml = nil)
+ toml ||= config_path(service)
args = ["#{tmp_tests_gitaly_bin_dir}/#{service_binary(service)}"]
args.push("-config") if service == :praefect
- args.push(config_path(service))
+ args.push(toml)
+
+ # Ensure user configuration does not affect Git
+ # Context: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58776#note_547613780
+ env = self.env.merge('HOME' => nil, 'XDG_CONFIG_HOME' => nil)
+
pid = spawn(env, *args, [:out, :err] => "log/#{service}-test.log")
begin
- try_connect!(service)
+ try_connect!(service, toml)
rescue StandardError
Process.kill('TERM', pid)
raise
@@ -161,29 +185,37 @@ module GitalySetup
abort 'bundle check failed' unless system(env, 'bundle', 'check', out: out, chdir: gemfile_dir)
end
- def read_socket_path(service)
+ def connect_proc(toml)
# This code needs to work in an environment where we cannot use bundler,
# so we cannot easily use the toml-rb gem. This ad-hoc parser should be
# good enough.
- config_text = IO.read(config_path(service))
+ config_text = IO.read(toml)
config_text.lines.each do |line|
- match_data = line.match(/^\s*socket_path\s*=\s*"([^"]*)"$/)
+ match_data = line.match(/^\s*(socket_path|listen_addr)\s*=\s*"([^"]*)"$/)
- return match_data[1] if match_data
+ next unless match_data
+
+ case match_data[1]
+ when 'socket_path'
+ return -> { UNIXSocket.new(match_data[2]) }
+ when 'listen_addr'
+ addr, port = match_data[2].split(':')
+ return -> { TCPSocket.new(addr, port.to_i) }
+ end
end
- raise "failed to find socket_path in #{config_path(service)}"
+ raise "failed to find socket_path or listen_addr in #{toml}"
end
- def try_connect!(service)
+ def try_connect!(service, toml)
LOGGER.debug "Trying to connect to #{service}: "
timeout = 20
delay = 0.1
- socket = read_socket_path(service)
+ connect = connect_proc(toml)
Integer(timeout / delay).times do
- UNIXSocket.new(socket)
+ connect.call
LOGGER.debug " OK\n"
return
@@ -194,6 +226,128 @@ module GitalySetup
LOGGER.warn " FAILED to connect to #{service}\n"
- raise "could not connect to #{socket}"
+ raise "could not connect to #{service}"
+ end
+
+ def gitaly_socket_path
+ Gitlab::GitalyClient.address(REPOS_STORAGE).delete_prefix('unix:')
+ end
+
+ def gitaly_dir
+ socket_path = gitaly_socket_path
+ socket_path = File.expand_path(gitaly_socket_path) if expand_path_for_socket?
+
+ File.dirname(socket_path)
+ end
+
+ # Linux fails with "bind: invalid argument" if a UNIX socket path exceeds 108 characters:
+ # https://github.com/golang/go/issues/6895. We use absolute paths in CI to ensure
+ # that changes in the current working directory don't affect GRPC reconnections.
+ def expand_path_for_socket?
+ !!ENV['CI']
+ end
+
+ def setup_gitaly
+ unless ENV['CI']
+ # In CI Gitaly is built in the setup-test-env job and saved in the
+ # artifacts. So when tests are started, there's no need to build Gitaly.
+ build_gitaly
+ end
+
+ Gitlab::SetupHelper::Gitaly.create_configuration(
+ gitaly_dir,
+ { 'default' => repos_path },
+ force: true,
+ options: {
+ prometheus_listen_addr: 'localhost:9236'
+ }
+ )
+ Gitlab::SetupHelper::Gitaly.create_configuration(
+ gitaly_dir,
+ { 'default' => repos_path },
+ force: true,
+ options: {
+ internal_socket_dir: File.join(gitaly_dir, "internal_gitaly2"),
+ gitaly_socket: "gitaly2.socket",
+ config_filename: "gitaly2.config.toml"
+ }
+ )
+ Gitlab::SetupHelper::Praefect.create_configuration(gitaly_dir, { 'praefect' => repos_path }, force: true)
+ end
+
+ def socket_path(service)
+ File.join(tmp_tests_gitaly_dir, "#{service}.socket")
+ end
+
+ def praefect_socket_path
+ "unix:" + socket_path(:praefect)
+ end
+
+ def stop(pid)
+ Process.kill('KILL', pid)
+ rescue Errno::ESRCH
+ # The process can already be gone if the test run was INTerrupted.
+ end
+
+ def spawn_gitaly(toml = nil)
+ check_gitaly_config!
+
+ pids = []
+
+ if toml
+ pids << start_gitaly(toml)
+ else
+ pids << start_gitaly
+ pids << start_gitaly2
+ pids << start_praefect
+ end
+
+ Kernel.at_exit do
+ # In CI, this function is called by scripts/gitaly-test-spawn, triggered
+ # in a before_script. Gitaly needs to remain running until the container
+ # is stopped.
+ next if ENV['CI']
+ # In Workhorse tests (locally or in CI), this function is called by
+ # scripts/gitaly-test-spawn during `make test`. Gitaly needs to remain
+ # running until `make test` cleans it up.
+ next if ENV['GITALY_PID_FILE']
+
+ pids.each { |pid| stop(pid) }
+ end
+ rescue StandardError
+ raise gitaly_failure_message
+ end
+
+ def gitaly_failure_message
+ message = "gitaly spawn failed\n\n"
+
+ message += "- The `gitaly` binary does not exist: #{gitaly_binary}\n" unless File.exist?(gitaly_binary)
+ message += "- The `praefect` binary does not exist: #{praefect_binary}\n" unless File.exist?(praefect_binary)
+ message += "- The `git` binary does not exist: #{git_binary}\n" unless File.exist?(git_binary)
+
+ message += "\nCheck log/gitaly-test.log for errors.\n"
+
+ unless ci?
+ message += "\nIf binaries are missing, try running `make -C tmp/tests/gitaly build git.`\n"
+ message += "\nOtherwise, try running `rm -rf #{tmp_tests_gitaly_dir}`."
+ end
+
+ message
+ end
+
+ def git_binary
+ File.join(tmp_tests_gitaly_dir, "_build", "deps", "git", "install", "bin", "git")
+ end
+
+ def gitaly_binary
+ File.join(tmp_tests_gitaly_dir, "_build", "bin", "gitaly")
+ end
+
+ def praefect_binary
+ File.join(tmp_tests_gitaly_dir, "_build", "bin", "praefect")
+ end
+
+ def git_binary_exists?
+ File.exist?(git_binary)
end
end
diff --git a/spec/support/helpers/login_helpers.rb b/spec/support/helpers/login_helpers.rb
index d9157fa7485..4e0e8dd96ee 100644
--- a/spec/support/helpers/login_helpers.rb
+++ b/spec/support/helpers/login_helpers.rb
@@ -95,7 +95,7 @@ module LoginHelpers
visit new_user_session_path
fill_in "user_login", with: user.email
- fill_in "user_password", with: "12345678"
+ fill_in "user_password", with: Gitlab::Password.test_default
check 'user_remember_me' if remember
click_button "Sign in"
diff --git a/spec/support/helpers/stub_gitlab_calls.rb b/spec/support/helpers/stub_gitlab_calls.rb
index ae031f58bd4..c3459f7bc81 100644
--- a/spec/support/helpers/stub_gitlab_calls.rb
+++ b/spec/support/helpers/stub_gitlab_calls.rb
@@ -92,12 +92,7 @@ module StubGitlabCalls
end
def stub_commonmark_sourcepos_disabled
- render_options =
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- Banzai::Filter::MarkdownEngines::CommonMark::RENDER_OPTIONS_C
- else
- Banzai::Filter::MarkdownEngines::CommonMark::RENDER_OPTIONS_RUBY
- end
+ render_options = Banzai::Filter::MarkdownEngines::CommonMark::RENDER_OPTIONS
allow_any_instance_of(Banzai::Filter::MarkdownEngines::CommonMark)
.to receive(:render_options)
diff --git a/spec/support/helpers/stub_object_storage.rb b/spec/support/helpers/stub_object_storage.rb
index 5e86b08aa45..d49a14f7f5b 100644
--- a/spec/support/helpers/stub_object_storage.rb
+++ b/spec/support/helpers/stub_object_storage.rb
@@ -91,6 +91,12 @@ module StubObjectStorage
**params)
end
+ def stub_ci_secure_file_object_storage(**params)
+ stub_object_storage_uploader(config: Gitlab.config.ci_secure_files.object_store,
+ uploader: Ci::SecureFileUploader,
+ **params)
+ end
+
def stub_terraform_state_object_storage(**params)
stub_object_storage_uploader(config: Gitlab.config.terraform_state.object_store,
uploader: Terraform::StateUploader,
diff --git a/spec/support/helpers/test_env.rb b/spec/support/helpers/test_env.rb
index d36bc4e3cb4..5c3ca92c4d0 100644
--- a/spec/support/helpers/test_env.rb
+++ b/spec/support/helpers/test_env.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require 'parallel'
+require_relative 'gitaly_setup'
module TestEnv
extend self
@@ -93,7 +94,6 @@ module TestEnv
}.freeze
TMP_TEST_PATH = Rails.root.join('tmp', 'tests').freeze
- REPOS_STORAGE = 'default'
SECOND_STORAGE_PATH = Rails.root.join('tmp', 'tests', 'second_storage')
SETUP_METHODS = %i[setup_gitaly setup_gitlab_shell setup_workhorse setup_factory_repo setup_forked_repo].freeze
@@ -128,7 +128,7 @@ module TestEnv
# Can be overriden
def post_init
- start_gitaly(gitaly_dir)
+ start_gitaly
end
# Clean /tmp/tests
@@ -142,12 +142,15 @@ module TestEnv
end
FileUtils.mkdir_p(
- Gitlab::GitalyClient::StorageSettings.allow_disk_access { TestEnv.repos_path }
+ Gitlab::GitalyClient::StorageSettings.allow_disk_access { GitalySetup.repos_path }
)
FileUtils.mkdir_p(SECOND_STORAGE_PATH)
FileUtils.mkdir_p(backup_path)
FileUtils.mkdir_p(pages_path)
FileUtils.mkdir_p(artifacts_path)
+ FileUtils.mkdir_p(lfs_path)
+ FileUtils.mkdir_p(terraform_state_path)
+ FileUtils.mkdir_p(packages_path)
end
def setup_gitlab_shell
@@ -156,111 +159,28 @@ module TestEnv
def setup_gitaly
component_timed_setup('Gitaly',
- install_dir: gitaly_dir,
+ install_dir: GitalySetup.gitaly_dir,
version: Gitlab::GitalyClient.expected_server_version,
- task: "gitlab:gitaly:test_install",
- task_args: [gitaly_dir, repos_path, gitaly_url].compact) do
- Gitlab::SetupHelper::Gitaly.create_configuration(
- gitaly_dir,
- { 'default' => repos_path },
- force: true,
- options: {
- prometheus_listen_addr: 'localhost:9236'
- }
- )
- Gitlab::SetupHelper::Gitaly.create_configuration(
- gitaly_dir,
- { 'default' => repos_path },
- force: true,
- options: {
- internal_socket_dir: File.join(gitaly_dir, "internal_gitaly2"),
- gitaly_socket: "gitaly2.socket",
- config_filename: "gitaly2.config.toml"
- }
- )
- Gitlab::SetupHelper::Praefect.create_configuration(gitaly_dir, { 'praefect' => repos_path }, force: true)
- end
- end
-
- def gitaly_socket_path
- Gitlab::GitalyClient.address('default').sub(/\Aunix:/, '')
- end
-
- def gitaly_dir
- socket_path = gitaly_socket_path
- socket_path = File.expand_path(gitaly_socket_path) if expand_path?
-
- File.dirname(socket_path)
- end
-
- # Linux fails with "bind: invalid argument" if a UNIX socket path exceeds 108 characters:
- # https://github.com/golang/go/issues/6895. We use absolute paths in CI to ensure
- # that changes in the current working directory don't affect GRPC reconnections.
- def expand_path?
- !!ENV['CI']
+ task: "gitlab:gitaly:clone",
+ fresh_install: ENV.key?('FORCE_GITALY_INSTALL'),
+ task_args: [GitalySetup.gitaly_dir, GitalySetup.repos_path, gitaly_url].compact) do
+ GitalySetup.setup_gitaly
+ end
end
- def start_gitaly(gitaly_dir)
+ def start_gitaly
if ci?
# Gitaly has been spawned outside this process already
return
end
- spawn_script = Rails.root.join('scripts/gitaly-test-spawn').to_s
- Bundler.with_original_env do
- unless system(spawn_script)
- message = 'gitaly spawn failed'
- message += " (try `rm -rf #{gitaly_dir}` ?)" unless ci?
- raise message
- end
- end
-
- gitaly_pid = Integer(File.read(TMP_TEST_PATH.join('gitaly.pid')))
- gitaly2_pid = Integer(File.read(TMP_TEST_PATH.join('gitaly2.pid')))
- praefect_pid = Integer(File.read(TMP_TEST_PATH.join('praefect.pid')))
-
- Kernel.at_exit do
- pids = [gitaly_pid, gitaly2_pid, praefect_pid]
- pids.each { |pid| stop(pid) }
- end
-
- wait('gitaly')
- wait('praefect')
- end
-
- def stop(pid)
- Process.kill('KILL', pid)
- rescue Errno::ESRCH
- # The process can already be gone if the test run was INTerrupted.
+ GitalySetup.spawn_gitaly
end
def gitaly_url
ENV.fetch('GITALY_REPO_URL', nil)
end
- def socket_path(service)
- TMP_TEST_PATH.join('gitaly', "#{service}.socket").to_s
- end
-
- def praefect_socket_path
- "unix:" + socket_path(:praefect)
- end
-
- def wait(service)
- sleep_time = 10
- sleep_interval = 0.1
- socket = socket_path(service)
-
- Integer(sleep_time / sleep_interval).times do
- Socket.unix(socket)
- return
- rescue StandardError
- sleep sleep_interval
- end
-
- raise "could not connect to #{service} at #{socket.inspect} after #{sleep_time} seconds"
- end
-
# Feature specs are run through Workhorse
def setup_workhorse
# Always rebuild the config file
@@ -376,8 +296,7 @@ module TestEnv
def rm_storage_dir(storage, dir)
Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- repos_path = Gitlab.config.repositories.storages[storage].legacy_disk_path
- target_repo_refs_path = File.join(repos_path, dir)
+ target_repo_refs_path = File.join(GitalySetup.repos_path(storage), dir)
FileUtils.remove_dir(target_repo_refs_path)
end
rescue Errno::ENOENT
@@ -385,8 +304,7 @@ module TestEnv
def storage_dir_exists?(storage, dir)
Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- repos_path = Gitlab.config.repositories.storages[storage].legacy_disk_path
- File.exist?(File.join(repos_path, dir))
+ File.exist?(File.join(GitalySetup.repos_path(storage), dir))
end
end
@@ -399,7 +317,7 @@ module TestEnv
end
def repos_path
- @repos_path ||= Gitlab.config.repositories.storages[REPOS_STORAGE].legacy_disk_path
+ @repos_path ||= GitalySetup.repos_path
end
def backup_path
@@ -414,6 +332,18 @@ module TestEnv
Gitlab.config.artifacts.storage_path
end
+ def lfs_path
+ Gitlab.config.lfs.storage_path
+ end
+
+ def terraform_state_path
+ Gitlab.config.terraform_state.storage_path
+ end
+
+ def packages_path
+ Gitlab.config.packages.storage_path
+ end
+
# When no cached assets exist, manually hit the root path to create them
#
# Otherwise they'd be created by the first test, often timing out and
@@ -512,7 +442,7 @@ module TestEnv
end
end
- def component_timed_setup(component, install_dir:, version:, task:, task_args: [])
+ def component_timed_setup(component, install_dir:, version:, task:, fresh_install: true, task_args: [])
start = Time.now
ensure_component_dir_name_is_correct!(component, install_dir)
@@ -522,7 +452,7 @@ module TestEnv
if component_needs_update?(install_dir, version)
# Cleanup the component entirely to ensure we start fresh
- FileUtils.rm_rf(install_dir)
+ FileUtils.rm_rf(install_dir) if fresh_install
if ENV['SKIP_RAILS_ENV_IN_RAKE']
# When we run `scripts/setup-test-env`, we take care of loading the necessary dependencies
diff --git a/spec/support/helpers/usage_data_helpers.rb b/spec/support/helpers/usage_data_helpers.rb
index 5865bafd382..776ea37ffdc 100644
--- a/spec/support/helpers/usage_data_helpers.rb
+++ b/spec/support/helpers/usage_data_helpers.rb
@@ -183,6 +183,10 @@ module UsageDataHelpers
)
end
+ def stub_database_flavor_check(flavor = nil)
+ allow(ApplicationRecord.database).to receive(:flavor).and_return(flavor)
+ end
+
def clear_memoized_values(values)
values.each { |v| described_class.clear_memoization(v) }
end
diff --git a/spec/support/import_export/export_file_helper.rb b/spec/support/import_export/export_file_helper.rb
index f862a9bc1a4..3134e5c32a3 100644
--- a/spec/support/import_export/export_file_helper.rb
+++ b/spec/support/import_export/export_file_helper.rb
@@ -44,7 +44,7 @@ module ExportFileHelper
create(:ci_trigger, project: project)
key = create(:deploy_key)
key.projects << project
- create(:service, project: project)
+ create(:integration, project: project)
create(:project_hook, project: project, token: 'token')
create(:protected_branch, project: project)
diff --git a/spec/support/praefect.rb b/spec/support/praefect.rb
index 3218275c2aa..451b47cc83c 100644
--- a/spec/support/praefect.rb
+++ b/spec/support/praefect.rb
@@ -1,11 +1,11 @@
# frozen_string_literal: true
-require_relative 'helpers/test_env'
+require_relative 'helpers/gitaly_setup'
RSpec.configure do |config|
config.before(:each, :praefect) do
allow(Gitlab.config.repositories.storages['default']).to receive(:[]).and_call_original
allow(Gitlab.config.repositories.storages['default']).to receive(:[]).with('gitaly_address')
- .and_return(TestEnv.praefect_socket_path)
+ .and_return(GitalySetup.praefect_socket_path)
end
end
diff --git a/spec/support/shared_contexts/navbar_structure_context.rb b/spec/support/shared_contexts/navbar_structure_context.rb
index 085f1f13c2c..27967850389 100644
--- a/spec/support/shared_contexts/navbar_structure_context.rb
+++ b/spec/support/shared_contexts/navbar_structure_context.rb
@@ -142,6 +142,7 @@ RSpec.shared_context 'group navbar structure' do
nav_sub_items: [
_('General'),
_('Integrations'),
+ _('Access Tokens'),
_('Projects'),
_('Repository'),
_('CI/CD'),
diff --git a/spec/support/shared_contexts/policies/group_policy_shared_context.rb b/spec/support/shared_contexts/policies/group_policy_shared_context.rb
index ad6462dc367..0dfd76de79c 100644
--- a/spec/support/shared_contexts/policies/group_policy_shared_context.rb
+++ b/spec/support/shared_contexts/policies/group_policy_shared_context.rb
@@ -8,7 +8,14 @@ RSpec.shared_context 'GroupPolicy context' do
let_it_be(:owner) { create(:user) }
let_it_be(:admin) { create(:admin) }
let_it_be(:non_group_member) { create(:user) }
- let_it_be(:group, refind: true) { create(:group, :private, :owner_subgroup_creation_only) }
+ let_it_be(:group, refind: true) { create(:group, :private, :owner_subgroup_creation_only, :crm_enabled) }
+
+ let(:public_permissions) do
+ %i[
+ read_group read_counts
+ read_label read_issue_board_list read_milestone read_issue_board
+ ]
+ end
let(:guest_permissions) do
%i[
@@ -18,8 +25,6 @@ RSpec.shared_context 'GroupPolicy context' do
]
end
- let(:read_group_permissions) { %i[read_label read_issue_board_list read_milestone read_issue_board] }
-
let(:reporter_permissions) do
%i[
admin_label
@@ -28,6 +33,8 @@ RSpec.shared_context 'GroupPolicy context' do
read_metrics_dashboard_annotation
read_prometheus
read_package_settings
+ read_crm_contact
+ read_crm_organization
]
end
@@ -48,22 +55,24 @@ RSpec.shared_context 'GroupPolicy context' do
destroy_package
create_projects
read_cluster create_cluster update_cluster admin_cluster add_cluster
- admin_group_runners
]
end
let(:owner_permissions) do
- [
- :owner_access,
- :admin_group,
- :admin_namespace,
- :admin_group_member,
- :change_visibility_level,
- :set_note_created_at,
- :create_subgroup,
- :read_statistics,
- :update_default_branch_protection
- ].compact
+ %i[
+ owner_access
+ admin_group
+ admin_namespace
+ admin_group_member
+ change_visibility_level
+ set_note_created_at
+ create_subgroup
+ read_statistics
+ update_default_branch_protection
+ read_group_runners
+ admin_group_runners
+ register_group_runners
+ ]
end
let(:admin_permissions) { %i[read_confidential_issues] }
diff --git a/spec/support/shared_contexts/policies/project_policy_shared_context.rb b/spec/support/shared_contexts/policies/project_policy_shared_context.rb
index 8a90f887381..c39252cef13 100644
--- a/spec/support/shared_contexts/policies/project_policy_shared_context.rb
+++ b/spec/support/shared_contexts/policies/project_policy_shared_context.rb
@@ -50,7 +50,7 @@ RSpec.shared_context 'ProjectPolicy context' do
resolve_note update_build update_commit_status update_container_image
update_deployment update_environment update_merge_request
update_metrics_dashboard_annotation update_pipeline update_release destroy_release
- read_resource_group update_resource_group
+ read_resource_group update_resource_group update_escalation_status
]
end
diff --git a/spec/support/shared_examples/controllers/access_tokens_controller_shared_examples.rb b/spec/support/shared_examples/controllers/access_tokens_controller_shared_examples.rb
deleted file mode 100644
index 017e55309f7..00000000000
--- a/spec/support/shared_examples/controllers/access_tokens_controller_shared_examples.rb
+++ /dev/null
@@ -1,124 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.shared_examples 'project access tokens available #index' do
- let_it_be(:active_project_access_token) { create(:personal_access_token, user: bot_user) }
- let_it_be(:inactive_project_access_token) { create(:personal_access_token, :revoked, user: bot_user) }
-
- it 'retrieves active project access tokens' do
- subject
-
- expect(assigns(:active_project_access_tokens)).to contain_exactly(active_project_access_token)
- end
-
- it 'retrieves inactive project access tokens' do
- subject
-
- expect(assigns(:inactive_project_access_tokens)).to contain_exactly(inactive_project_access_token)
- end
-
- it 'lists all available scopes' do
- subject
-
- expect(assigns(:scopes)).to eq(Gitlab::Auth.resource_bot_scopes)
- end
-
- it 'retrieves newly created personal access token value' do
- token_value = 'random-value'
- allow(PersonalAccessToken).to receive(:redis_getdel).with("#{user.id}:#{project.id}").and_return(token_value)
-
- subject
-
- expect(assigns(:new_project_access_token)).to eq(token_value)
- end
-end
-
-RSpec.shared_examples 'project access tokens available #create' do
- def created_token
- PersonalAccessToken.order(:created_at).last
- end
-
- it 'returns success message' do
- subject
-
- expect(controller).to set_flash[:notice].to match('Your new project access token has been created.')
- end
-
- it 'creates project access token' do
- access_level = access_token_params[:access_level] || Gitlab::Access::MAINTAINER
- subject
-
- expect(created_token.name).to eq(access_token_params[:name])
- expect(created_token.scopes).to eq(access_token_params[:scopes])
- expect(created_token.expires_at).to eq(access_token_params[:expires_at])
- expect(project.project_member(created_token.user).access_level).to eq(access_level)
- end
-
- it 'creates project bot user' do
- subject
-
- expect(created_token.user).to be_project_bot
- end
-
- it 'stores newly created token redis store' do
- expect(PersonalAccessToken).to receive(:redis_store!)
-
- subject
- end
-
- it { expect { subject }.to change { User.count }.by(1) }
- it { expect { subject }.to change { PersonalAccessToken.count }.by(1) }
-
- context 'when unsuccessful' do
- before do
- allow_next_instance_of(ResourceAccessTokens::CreateService) do |service|
- allow(service).to receive(:execute).and_return ServiceResponse.error(message: 'Failed!')
- end
- end
-
- it 'does not create the token' do
- expect { subject }.not_to change { PersonalAccessToken.count }
- end
-
- it 'does not add the project bot as a member' do
- expect { subject }.not_to change { Member.count }
- end
-
- it 'does not create the project bot user' do
- expect { subject }.not_to change { User.count }
- end
-
- it 'shows a failure alert' do
- subject
-
- expect(controller).to set_flash[:alert].to match("Failed to create new project access token: Failed!")
- end
- end
-end
-
-RSpec.shared_examples 'project access tokens available #revoke' do
- it 'calls delete user worker' do
- expect(DeleteUserWorker).to receive(:perform_async).with(user.id, bot_user.id, skip_authorization: true)
-
- subject
- end
-
- it 'removes membership of bot user' do
- subject
-
- expect(project.reload.bots).not_to include(bot_user)
- end
-
- it 'converts issuables of the bot user to ghost user' do
- issue = create(:issue, author: bot_user)
-
- subject
-
- expect(issue.reload.author.ghost?).to be true
- end
-
- it 'deletes project bot user' do
- subject
-
- expect(User.exists?(bot_user.id)).to be_falsy
- end
-end
diff --git a/spec/support/shared_examples/controllers/create_notes_rate_limit_shared_examples.rb b/spec/support/shared_examples/controllers/create_notes_rate_limit_shared_examples.rb
index 8affe4ac8f5..08d0be8c7ac 100644
--- a/spec/support/shared_examples/controllers/create_notes_rate_limit_shared_examples.rb
+++ b/spec/support/shared_examples/controllers/create_notes_rate_limit_shared_examples.rb
@@ -3,44 +3,19 @@
# Requires a context containing:
# - user
# - params
-# - request_full_path
-RSpec.shared_examples 'request exceeding rate limit' do
- context 'with rate limiter', :freeze_time, :clean_gitlab_redis_rate_limiting do
- before do
- stub_application_setting(notes_create_limit: 2)
- 2.times { post :create, params: params }
- end
+RSpec.shared_examples 'create notes request exceeding rate limit' do
+ include_examples 'rate limited endpoint', rate_limit_key: :notes_create
- it 'prevents from creating more notes' do
- expect { post :create, params: params }
- .to change { Note.count }.by(0)
+ it 'allows user in allow-list to create notes, even if the case is different', :freeze_time, :clean_gitlab_redis_rate_limiting do
+ allow(Gitlab::ApplicationRateLimiter).to receive(:threshold).with(:notes_create).and_return(1)
- expect(response).to have_gitlab_http_status(:too_many_requests)
- expect(response.body).to eq(_('This endpoint has been requested too many times. Try again later.'))
- end
+ current_user.update_attribute(:username, current_user.username.titleize)
+ stub_application_setting(notes_create_limit_allowlist: [current_user.username.downcase])
- it 'logs the event in auth.log' do
- attributes = {
- message: 'Application_Rate_Limiter_Request',
- env: :notes_create_request_limit,
- remote_ip: '0.0.0.0',
- request_method: 'POST',
- path: request_full_path,
- user_id: user.id,
- username: user.username
- }
+ request
+ request
- expect(Gitlab::AuthLogger).to receive(:error).with(attributes).once
- post :create, params: params
- end
-
- it 'allows user in allow-list to create notes, even if the case is different' do
- user.update_attribute(:username, user.username.titleize)
- stub_application_setting(notes_create_limit_allowlist: ["#{user.username.downcase}"])
-
- post :create, params: params
- expect(response).to have_gitlab_http_status(:found)
- end
+ expect(response).to have_gitlab_http_status(:found)
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
new file mode 100644
index 00000000000..bb2a4159071
--- /dev/null
+++ b/spec/support/shared_examples/controllers/rate_limited_endpoint_shared_examples.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+#
+# Requires a context containing:
+# - request (use method definition to avoid memoizing!)
+# - current_user
+# - error_message # optional
+
+RSpec.shared_examples 'rate limited endpoint' do |rate_limit_key:|
+ context 'when rate limiter enabled', :freeze_time, :clean_gitlab_redis_rate_limiting do
+ let(:expected_logger_attributes) do
+ {
+ message: 'Application_Rate_Limiter_Request',
+ 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
+ }
+ end
+
+ let(:error_message) { _('This endpoint has been requested too many times. Try again later.') }
+
+ before do
+ allow(Gitlab::ApplicationRateLimiter).to receive(:threshold).with(rate_limit_key).and_return(1)
+ end
+
+ it 'logs request and declines it when endpoint called more than the threshold' do |example|
+ expect(Gitlab::AuthLogger).to receive(:error).with(expected_logger_attributes).once
+
+ request
+ request
+
+ expect(response).to have_gitlab_http_status(:too_many_requests)
+
+ if example.metadata[:type] == :controller
+ expect(response.body).to eq(error_message)
+ else # it is API spec
+ expect(response.body).to eq({ message: { error: error_message } }.to_json)
+ end
+ end
+ end
+
+ context 'when rate limiter is disabled' do
+ before do
+ allow(Gitlab::ApplicationRateLimiter).to receive(:threshold).with(rate_limit_key).and_return(0)
+ end
+
+ it 'does not log request and does not block the request' do
+ expect(Gitlab::AuthLogger).not_to receive(:error)
+
+ request
+
+ expect(response).not_to have_gitlab_http_status(:too_many_requests)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/features/access_tokens_shared_examples.rb b/spec/support/shared_examples/features/access_tokens_shared_examples.rb
new file mode 100644
index 00000000000..ae246a87bb6
--- /dev/null
+++ b/spec/support/shared_examples/features/access_tokens_shared_examples.rb
@@ -0,0 +1,165 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'resource access tokens missing access rights' do
+ it 'does not show access token page' do
+ visit resource_settings_access_tokens_path
+
+ expect(page).to have_content("Page Not Found")
+ end
+end
+
+RSpec.shared_examples 'resource access tokens creation' do |resource_type|
+ def active_resource_access_tokens
+ find('.table.active-tokens')
+ end
+
+ def created_resource_access_token
+ find('#created-personal-access-token').value
+ end
+
+ it 'allows creation of an access token', :aggregate_failures do
+ name = 'My access token'
+
+ visit resource_settings_access_tokens_path
+ fill_in 'Token name', with: name
+
+ # Set date to 1st of next month
+ find_field('Expiration date').click
+ find('.pika-next').click
+ click_on '1'
+
+ # Scopes
+ check 'api'
+ check 'read_api'
+
+ click_on "Create #{resource_type} access token"
+
+ expect(active_resource_access_tokens).to have_text(name)
+ expect(active_resource_access_tokens).to have_text('in')
+ expect(active_resource_access_tokens).to have_text('api')
+ expect(active_resource_access_tokens).to have_text('read_api')
+ expect(active_resource_access_tokens).to have_text('Maintainer')
+ expect(created_resource_access_token).not_to be_empty
+ end
+end
+
+RSpec.shared_examples 'resource access tokens creation disallowed' do |error_message|
+ before do
+ group.namespace_settings.update_column(:resource_access_token_creation_allowed, false)
+ end
+
+ it 'does not show access token creation form' do
+ visit resource_settings_access_tokens_path
+
+ expect(page).not_to have_selector('#new_resource_access_token')
+ end
+
+ it 'shows access token creation disabled text' do
+ visit resource_settings_access_tokens_path
+
+ expect(page).to have_text(error_message)
+ end
+
+ context 'group settings link' do
+ context 'when user is not a group owner' do
+ before do
+ group.add_developer(user)
+ end
+
+ it 'does not show group settings link' do
+ visit resource_settings_access_tokens_path
+
+ expect(page).not_to have_link('group settings', href: edit_group_path(group))
+ end
+ end
+
+ context 'with nested groups' do
+ let(:parent_group) { create(:group) }
+ let(:group) { create(:group, parent: parent_group) }
+
+ context 'when user is not a top level group owner' do
+ before do
+ group.add_owner(user)
+ end
+
+ it 'does not show group settings link' do
+ visit resource_settings_access_tokens_path
+
+ expect(page).not_to have_link('group settings', href: edit_group_path(group))
+ end
+ end
+ end
+
+ context 'when user is a group owner' do
+ before do
+ group.add_owner(user)
+ end
+
+ it 'shows group settings link' do
+ visit resource_settings_access_tokens_path
+
+ expect(page).to have_link('group settings', href: edit_group_path(group))
+ end
+ end
+ end
+end
+
+RSpec.shared_examples 'active resource access tokens' do
+ def active_resource_access_tokens
+ find('.table.active-tokens')
+ end
+
+ it 'shows active access tokens' do
+ visit resource_settings_access_tokens_path
+
+ expect(active_resource_access_tokens).to have_text(resource_access_token.name)
+ end
+
+ context 'when User#time_display_relative is false' do
+ before do
+ user.update!(time_display_relative: false)
+ end
+
+ it 'shows absolute times for expires_at' do
+ visit resource_settings_access_tokens_path
+
+ expect(active_resource_access_tokens).to have_text(PersonalAccessToken.last.expires_at.strftime('%b %-d'))
+ end
+ end
+end
+
+RSpec.shared_examples 'inactive resource access tokens' do |no_active_tokens_text|
+ def no_resource_access_tokens_message
+ find('.settings-message')
+ end
+
+ it 'allows revocation of an active token' do
+ visit resource_settings_access_tokens_path
+ accept_confirm { click_on 'Revoke' }
+
+ expect(page).to have_selector('.settings-message')
+ expect(no_resource_access_tokens_message).to have_text(no_active_tokens_text)
+ end
+
+ it 'removes expired tokens from active section' do
+ resource_access_token.update!(expires_at: 5.days.ago)
+ visit resource_settings_access_tokens_path
+
+ expect(page).to have_selector('.settings-message')
+ expect(no_resource_access_tokens_message).to have_text(no_active_tokens_text)
+ end
+
+ context 'when resource access token creation is not allowed' do
+ before do
+ group.namespace_settings.update_column(:resource_access_token_creation_allowed, false)
+ end
+
+ it 'allows revocation of an active token' do
+ visit resource_settings_access_tokens_path
+ accept_confirm { click_on 'Revoke' }
+
+ expect(page).to have_selector('.settings-message')
+ expect(no_resource_access_tokens_message).to have_text(no_active_tokens_text)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/features/packages_shared_examples.rb b/spec/support/shared_examples/features/packages_shared_examples.rb
index d14b4638ca5..ded30f32314 100644
--- a/spec/support/shared_examples/features/packages_shared_examples.rb
+++ b/spec/support/shared_examples/features/packages_shared_examples.rb
@@ -19,14 +19,12 @@ RSpec.shared_examples 'packages list' do |check_project_name: false|
end
RSpec.shared_examples 'package details link' do |property|
- let(:package) { packages.first }
-
it 'navigates to the correct url' do
page.within(packages_table_selector) do
click_link package.name
end
- expect(page).to have_current_path(project_package_path(package.project, package))
+ expect(page).to have_current_path(package_details_path)
expect(page).to have_css('.packages-app h2[data-testid="title"]', text: package.name)
diff --git a/spec/support/shared_examples/features/sidebar/sidebar_labels_shared_examples.rb b/spec/support/shared_examples/features/sidebar/sidebar_labels_shared_examples.rb
new file mode 100644
index 00000000000..a9dac7a391f
--- /dev/null
+++ b/spec/support/shared_examples/features/sidebar/sidebar_labels_shared_examples.rb
@@ -0,0 +1,127 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'labels sidebar widget' do
+ context 'editing labels' do
+ let_it_be(:development) { create(:group_label, group: group, name: 'Development') }
+ let_it_be(:stretch) { create(:label, project: project, name: 'Stretch') }
+ let_it_be(:xss_label) { create(:label, project: project, title: '&lt;script&gt;alert("xss");&lt;&#x2F;script&gt;') }
+
+ let(:labels_widget) { find('[data-testid="sidebar-labels"]') }
+
+ before do
+ page.within(labels_widget) do
+ click_on 'Edit'
+ end
+
+ wait_for_all_requests
+ end
+
+ it 'shows labels list in the dropdown' do
+ expect(labels_widget.find('.gl-new-dropdown-contents')).to have_selector('li.gl-new-dropdown-item', count: 4)
+ end
+
+ it 'adds a label' do
+ within(labels_widget) do
+ adds_label(stretch)
+
+ page.within('[data-testid="value-wrapper"]') do
+ expect(page).to have_content(stretch.name)
+ end
+ end
+ end
+
+ it 'removes a label' do
+ within(labels_widget) do
+ adds_label(stretch)
+ page.within('[data-testid="value-wrapper"]') do
+ expect(page).to have_content(stretch.name)
+ end
+
+ click_on 'Remove label'
+
+ wait_for_requests
+
+ page.within('[data-testid="value-wrapper"]') do
+ expect(page).not_to have_content(stretch.name)
+ end
+ end
+ end
+
+ it 'adds first label by pressing enter when search' do
+ within(labels_widget) do
+ page.within('[data-testid="value-wrapper"]') do
+ expect(page).not_to have_content(development.name)
+ end
+
+ fill_in 'Search', with: 'Devel'
+ sleep 1
+ expect(page.all(:css, '[data-testid="dropdown-content"] .gl-new-dropdown-item').length).to eq(1)
+
+ find_field('Search').native.send_keys(:enter)
+ click_button 'Close'
+ wait_for_requests
+
+ page.within('[data-testid="value-wrapper"]') do
+ expect(page).to have_content(development.name)
+ end
+ end
+ end
+
+ it 'escapes XSS when viewing issuable labels' do
+ page.within(labels_widget) do
+ expect(page).to have_content '<script>alert("xss");</script>'
+ end
+ end
+
+ it 'shows option to create a label' do
+ page.within(labels_widget) do
+ expect(page).to have_content 'Create'
+ end
+ end
+
+ context 'creating a label', :js do
+ before do
+ page.within(labels_widget) do
+ page.find('[data-testid="create-label-button"]').click
+ end
+ end
+
+ it 'shows dropdown switches to "create label" section' do
+ page.within(labels_widget) do
+ expect(page.find('[data-testid="dropdown-header"]')).to have_content 'Create'
+ end
+ end
+
+ it 'creates new label' do
+ page.within(labels_widget) do
+ fill_in 'Name new label', with: 'wontfix'
+ page.find('.suggest-colors a', match: :first).click
+ page.find('button', text: 'Create').click
+ wait_for_requests
+
+ expect(page).to have_content 'wontfix'
+ end
+ end
+
+ it 'shows error message if label title is taken' do
+ page.within(labels_widget) do
+ fill_in 'Name new label', with: development.title
+ page.find('.suggest-colors a', match: :first).click
+ page.find('button', text: 'Create').click
+ wait_for_requests
+
+ page.within('.dropdown-input') do
+ expect(page.find('.gl-alert')).to have_content 'Title'
+ end
+ end
+ end
+ end
+ end
+
+ def adds_label(label)
+ click_button label.name
+ click_button 'Close'
+
+ wait_for_requests
+ end
+end
diff --git a/spec/support/shared_examples/features/sidebar_shared_examples.rb b/spec/support/shared_examples/features/sidebar_shared_examples.rb
index 615f568420e..11d216ff4b6 100644
--- a/spec/support/shared_examples/features/sidebar_shared_examples.rb
+++ b/spec/support/shared_examples/features/sidebar_shared_examples.rb
@@ -50,6 +50,10 @@ RSpec.shared_examples 'issue boards sidebar' do
it_behaves_like 'date sidebar widget'
end
+ context 'editing issue labels', :js do
+ it_behaves_like 'labels sidebar widget'
+ end
+
context 'in notifications subscription' do
it 'displays notifications toggle', :aggregate_failures do
page.within('[data-testid="sidebar-notifications"]') do
diff --git a/spec/support/shared_examples/finders/snippet_visibility_shared_examples.rb b/spec/support/shared_examples/finders/snippet_visibility_shared_examples.rb
index a2c34cdd4a1..601a53ed913 100644
--- a/spec/support/shared_examples/finders/snippet_visibility_shared_examples.rb
+++ b/spec/support/shared_examples/finders/snippet_visibility_shared_examples.rb
@@ -233,7 +233,7 @@ RSpec.shared_examples 'snippet visibility' do
project.update!(visibility_level: Gitlab::VisibilityLevel.level_value(project_visibility.to_s), snippets_access_level: feature_visibility)
if user_type == :external
- member = project.project_member(external)
+ member = project.member(external)
if project.private?
project.add_developer(external) unless member
diff --git a/spec/support/shared_examples/graphql/mutation_shared_examples.rb b/spec/support/shared_examples/graphql/mutation_shared_examples.rb
index 51d52cbb901..dc590e23ace 100644
--- a/spec/support/shared_examples/graphql/mutation_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/mutation_shared_examples.rb
@@ -8,7 +8,7 @@
# There must be a method or let called `mutation` defined that executes
# the mutation.
RSpec.shared_examples 'a mutation that returns top-level errors' do |errors: []|
- let(:match_errors) { eq(errors) }
+ let(:match_errors) { match_array(errors) }
it do
post_graphql_mutation(mutation, current_user: current_user)
diff --git a/spec/support/shared_examples/graphql/mutations/issues/permission_check_shared_examples.rb b/spec/support/shared_examples/graphql/mutations/issues/permission_check_shared_examples.rb
index 34c58f524cd..05fee45427a 100644
--- a/spec/support/shared_examples/graphql/mutations/issues/permission_check_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/mutations/issues/permission_check_shared_examples.rb
@@ -1,12 +1,34 @@
# frozen_string_literal: true
RSpec.shared_examples 'permission level for issue mutation is correctly verified' do |raises_for_all_errors = false|
- before do
- issue.assignees = []
- issue.author = user
+ let_it_be(:other_user_author) { create(:user) }
+
+ def issue_attributes(issue)
+ issue.attributes.except(
+ # Description and title can be updated by authors and assignees of the issues
+ 'description',
+ 'title',
+ # Those fields are calculated or expected to be modified during the mutations
+ 'author_id',
+ 'updated_at',
+ 'updated_by_id',
+ 'last_edited_at',
+ 'last_edited_by_id',
+ 'lock_version',
+ # There were spec failures due to nano-second comparisons
+ # this property isn't changed by any mutation so we don't have to verify it
+ 'created_at'
+ )
end
- shared_examples_for 'when the user does not have access to the resource' do |raise_for_assigned|
+ let(:expected) { issue_attributes(issue) }
+
+ shared_examples_for 'when the user does not have access to the resource' do |raise_for_assigned_and_author|
+ before do
+ issue.assignees = []
+ issue.update!(author: other_user_author)
+ end
+
it 'raises an error' do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
@@ -17,21 +39,25 @@ RSpec.shared_examples 'permission level for issue mutation is correctly verified
end
it 'does not modify issue' do
- if raises_for_all_errors || raise_for_assigned
+ if raises_for_all_errors || raise_for_assigned_and_author
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
else
- expect(subject[:issue]).to eq issue
+ expect(issue_attributes(subject[:issue])).to eq expected
end
end
end
context 'even if author of the issue' do
before do
- issue.author = user
+ issue.update!(author: user)
end
- it 'raises an error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ it 'does not modify issue' do
+ if raises_for_all_errors || raise_for_assigned_and_author
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ else
+ expect(issue_attributes(subject[:issue])).to eq expected
+ end
end
end
end
diff --git a/spec/support/shared_examples/graphql/mutations/merge_requests/permission_check_shared_examples.rb b/spec/support/shared_examples/graphql/mutations/merge_requests/permission_check_shared_examples.rb
index 1ddbad1cea7..b0ac742079a 100644
--- a/spec/support/shared_examples/graphql/mutations/merge_requests/permission_check_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/mutations/merge_requests/permission_check_shared_examples.rb
@@ -1,13 +1,39 @@
# frozen_string_literal: true
RSpec.shared_examples 'permission level for merge request mutation is correctly verified' do
- before do
- merge_request.assignees = []
- merge_request.reviewers = []
- merge_request.author = nil
+ let(:other_user_author) { create(:user) }
+
+ def mr_attributes(mr)
+ mr.attributes.except(
+ # Authors and assignees can edit title, description, target branch and draft status
+ 'title',
+ 'description',
+ 'target_branch',
+ 'draft',
+ # Those fields are calculated or expected to be modified during the mutations
+ 'author_id',
+ 'latest_merge_request_diff_id',
+ 'last_edited_at',
+ 'last_edited_by_id',
+ 'lock_version',
+ 'updated_at',
+ 'updated_by_id',
+ 'merge_status',
+ # There were spec failures due to nano-second comparisons
+ # this property isn't changed by any mutation so we don't have to verify it
+ 'created_at'
+ )
end
- shared_examples_for 'when the user does not have access to the resource' do |raise_for_assigned|
+ let(:expected) { mr_attributes(merge_request) }
+
+ shared_examples_for 'when the user does not have access to the resource' do |raise_for_assigned_and_author|
+ before do
+ merge_request.assignees = []
+ merge_request.reviewers = []
+ merge_request.update!(author: other_user_author)
+ end
+
it 'raises an error' do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
@@ -18,12 +44,12 @@ RSpec.shared_examples 'permission level for merge request mutation is correctly
end
it 'does not modify merge request' do
- if raise_for_assigned
+ if raise_for_assigned_and_author
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
else
# In some cases we simply do nothing instead of raising
# https://gitlab.com/gitlab-org/gitlab/-/issues/196241
- expect(subject[:merge_request]).to eq merge_request
+ expect(mr_attributes(subject[:merge_request])).to eq expected
end
end
end
@@ -40,11 +66,17 @@ RSpec.shared_examples 'permission level for merge request mutation is correctly
context 'even if author of the merge request' do
before do
- merge_request.author = user
+ merge_request.update!(author: user)
end
it 'raises an error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ if raise_for_assigned_and_author
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ else
+ # In some cases we simply do nothing instead of raising
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/196241
+ expect(mr_attributes(subject[:merge_request])).to eq expected
+ end
end
end
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 7888ade56eb..213f084be17 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
@@ -22,19 +22,19 @@ RSpec.shared_examples 'marks background migration job records' do
end
end
-RSpec.shared_examples 'finalized background migration' do
+RSpec.shared_examples 'finalized background migration' do |worker_class|
it 'processed the scheduled sidekiq queue' do
queued = Sidekiq::ScheduledSet
.new
.select do |scheduled|
- scheduled.klass == 'BackgroundMigrationWorker' &&
+ scheduled.klass == worker_class.name &&
scheduled.args.first == job_class_name
end
expect(queued.size).to eq(0)
end
it 'processed the async sidekiq queue' do
- queued = Sidekiq::Queue.new('BackgroundMigrationWorker')
+ queued = Sidekiq::Queue.new(worker_class.name)
.select { |scheduled| scheduled.klass == job_class_name }
expect(queued.size).to eq(0)
end
@@ -42,8 +42,8 @@ RSpec.shared_examples 'finalized background migration' do
include_examples 'removed tracked jobs', 'pending'
end
-RSpec.shared_examples 'finalized tracked background migration' do
- include_examples 'finalized background migration'
+RSpec.shared_examples 'finalized tracked background migration' do |worker_class|
+ include_examples 'finalized background migration', worker_class
include_examples 'removed tracked jobs', 'succeeded'
end
diff --git a/spec/support/shared_examples/lib/gitlab/redis/multi_store_feature_flags_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/redis/multi_store_feature_flags_shared_examples.rb
deleted file mode 100644
index 046c70bf779..00000000000
--- a/spec/support/shared_examples/lib/gitlab/redis/multi_store_feature_flags_shared_examples.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.shared_examples 'multi store feature flags' do |use_primary_and_secondary_stores, use_primary_store_as_default|
- context "with feature flag :#{use_primary_and_secondary_stores} is enabled" do
- before do
- stub_feature_flags(use_primary_and_secondary_stores => true)
- end
-
- it 'multi store is enabled' do
- expect(subject.use_primary_and_secondary_stores?).to be true
- end
- end
-
- context "with feature flag :#{use_primary_and_secondary_stores} is disabled" do
- before do
- stub_feature_flags(use_primary_and_secondary_stores => false)
- end
-
- it 'multi store is disabled' do
- expect(subject.use_primary_and_secondary_stores?).to be false
- end
- end
-
- context "with feature flag :#{use_primary_store_as_default} is enabled" do
- before do
- stub_feature_flags(use_primary_store_as_default => true)
- end
-
- it 'primary store is enabled' do
- expect(subject.use_primary_store_as_default?).to be true
- end
- end
-
- context "with feature flag :#{use_primary_store_as_default} is disabled" do
- before do
- stub_feature_flags(use_primary_store_as_default => false)
- end
-
- it 'primary store is disabled' do
- expect(subject.use_primary_store_as_default?).to be false
- end
- end
-end
diff --git a/spec/support/shared_examples/lib/gitlab/unique_ip_check_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/unique_ip_check_shared_examples.rb
index e42a927b5ba..c735b98aa23 100644
--- a/spec/support/shared_examples/lib/gitlab/unique_ip_check_shared_examples.rb
+++ b/spec/support/shared_examples/lib/gitlab/unique_ip_check_shared_examples.rb
@@ -7,13 +7,13 @@ RSpec.shared_examples 'user login operation with unique ip limit' do
end
it 'allows user authenticating from the same ip' do
- expect { operation_from_ip('ip') }.not_to raise_error
- expect { operation_from_ip('ip') }.not_to raise_error
+ expect { operation_from_ip('111.221.4.3') }.not_to raise_error
+ expect { operation_from_ip('111.221.4.3') }.not_to raise_error
end
it 'blocks user authenticating from two distinct ips' do
- expect { operation_from_ip('ip') }.not_to raise_error
- expect { operation_from_ip('ip2') }.to raise_error(Gitlab::Auth::TooManyIps)
+ expect { operation_from_ip('111.221.4.3') }.not_to raise_error
+ expect { operation_from_ip('1.2.2.3') }.to raise_error(Gitlab::Auth::TooManyIps)
end
end
end
@@ -25,13 +25,13 @@ RSpec.shared_examples 'user login request with unique ip limit' do |success_stat
end
it 'allows user authenticating from the same ip' do
- expect(request_from_ip('ip')).to have_gitlab_http_status(success_status)
- expect(request_from_ip('ip')).to have_gitlab_http_status(success_status)
+ expect(request_from_ip('111.221.4.3')).to have_gitlab_http_status(success_status)
+ expect(request_from_ip('111.221.4.3')).to have_gitlab_http_status(success_status)
end
it 'blocks user authenticating from two distinct ips' do
- expect(request_from_ip('ip')).to have_gitlab_http_status(success_status)
- expect(request_from_ip('ip2')).to have_gitlab_http_status(:forbidden)
+ expect(request_from_ip('111.221.4.3')).to have_gitlab_http_status(success_status)
+ expect(request_from_ip('1.2.2.3')).to have_gitlab_http_status(:forbidden)
end
end
end
diff --git a/spec/support/shared_examples/loose_foreign_keys/have_loose_foreign_key.rb b/spec/support/shared_examples/loose_foreign_keys/have_loose_foreign_key.rb
index 8f3a93de509..42eec74e64f 100644
--- a/spec/support/shared_examples/loose_foreign_keys/have_loose_foreign_key.rb
+++ b/spec/support/shared_examples/loose_foreign_keys/have_loose_foreign_key.rb
@@ -55,10 +55,16 @@ RSpec.shared_examples 'cleanup by a loose foreign key' do
end
def find_model
- model.class.find_by(id: model.id)
+ query = model.class
+ # handle composite primary keys
+ connection = model.class.connection
+ connection.primary_keys(model.class.table_name).each do |primary_key|
+ query = query.where(primary_key => model.public_send(primary_key))
+ end
+ query.first
end
- it 'deletes the model' do
+ it 'cleans up (delete or nullify) the model' do
parent.delete
expect(find_model).to be_present
diff --git a/spec/support/shared_examples/metrics/sampler_shared_examples.rb b/spec/support/shared_examples/metrics/sampler_shared_examples.rb
index ebf199c3a8d..cec540cd120 100644
--- a/spec/support/shared_examples/metrics/sampler_shared_examples.rb
+++ b/spec/support/shared_examples/metrics/sampler_shared_examples.rb
@@ -2,26 +2,98 @@
RSpec.shared_examples 'metrics sampler' do |env_prefix|
context 'when sampling interval is passed explicitly' do
- subject { described_class.new(42) }
+ subject(:sampler) { described_class.new(interval: 42, logger: double) }
- specify { expect(subject.interval).to eq(42) }
+ specify { expect(sampler.interval).to eq(42) }
end
context 'when sampling interval is passed through the environment' do
- subject { described_class.new }
+ subject(:sampler) { described_class.new(logger: double) }
before do
stub_env("#{env_prefix}_INTERVAL_SECONDS", '42')
end
- specify { expect(subject.interval).to eq(42) }
+ specify { expect(sampler.interval).to eq(42) }
end
context 'when no sampling interval is passed anywhere' do
- subject { described_class.new }
+ subject(:sampler) { described_class.new(logger: double) }
it 'uses the hardcoded default' do
- expect(subject.interval).to eq(described_class::DEFAULT_SAMPLING_INTERVAL_SECONDS)
+ expect(sampler.interval).to eq(described_class::DEFAULT_SAMPLING_INTERVAL_SECONDS)
+ end
+ end
+
+ describe '#start' do
+ include WaitHelpers
+
+ subject(:sampler) { described_class.new(interval: 0.1) }
+
+ it 'calls the sample method on the sampler thread' do
+ sampling_threads = []
+ expect(sampler).to receive(:sample).at_least(:once) { sampling_threads << Thread.current }
+
+ sampler.start
+
+ wait_for('sampler has sampled', max_wait_time: 3) { sampling_threads.any? }
+ expect(sampling_threads.first.name).to eq(sampler.thread_name)
+
+ sampler.stop
+ end
+
+ context 'with warmup set to true' do
+ subject(:sampler) { described_class.new(interval: 0.1, warmup: true) }
+
+ it 'calls the sample method first on the caller thread' do
+ sampling_threads = []
+ current_thread = Thread.current
+ # Instead of sampling, we're keeping track of which thread the sampling happened on.
+ # We want the first sample to be on the spec thread, which would mean a blocking sample
+ # before the actual sampler thread starts.
+ expect(sampler).to receive(:sample).at_least(:once) { sampling_threads << Thread.current }
+
+ sampler.start
+
+ wait_for('sampler has sampled', max_wait_time: 3) { sampling_threads.size == 2 }
+
+ expect(sampling_threads.first).to be(current_thread)
+ expect(sampling_threads.last.name).to eq(sampler.thread_name)
+
+ sampler.stop
+ end
+ end
+ end
+
+ describe '#safe_sample' do
+ let(:logger) { Logger.new(File::NULL) }
+
+ subject(:sampler) { described_class.new(logger: logger) }
+
+ it 'calls #sample once' do
+ expect(sampler).to receive(:sample)
+
+ sampler.safe_sample
+ end
+
+ context 'when sampling fails with error' do
+ before do
+ expect(sampler).to receive(:sample).and_raise "something failed"
+ end
+
+ it 'recovers from errors' do
+ expect { sampler.safe_sample }.not_to raise_error
+ end
+
+ context 'with logger' do
+ let(:logger) { double('logger') }
+
+ it 'logs errors' do
+ expect(logger).to receive(:warn).with(an_instance_of(String))
+
+ expect { sampler.safe_sample }.not_to raise_error
+ end
+ end
end
end
end
diff --git a/spec/support/shared_examples/models/application_setting_shared_examples.rb b/spec/support/shared_examples/models/application_setting_shared_examples.rb
index 60a02d85a1e..38f5c7be393 100644
--- a/spec/support/shared_examples/models/application_setting_shared_examples.rb
+++ b/spec/support/shared_examples/models/application_setting_shared_examples.rb
@@ -94,7 +94,7 @@ RSpec.shared_examples 'application settings examples' do
'1:2:3:4:5::7:8',
'[1:2:3:4:5::7:8]',
'[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443',
- 'www.example2.com:8080',
+ 'www.example.org:8080',
'example.com:8080'
]
@@ -114,7 +114,7 @@ RSpec.shared_examples 'application settings examples' do
an_object_having_attributes(domain: 'example.com'),
an_object_having_attributes(domain: 'subdomain.example.com'),
an_object_having_attributes(domain: 'www.example.com'),
- an_object_having_attributes(domain: 'www.example2.com', port: 8080),
+ an_object_having_attributes(domain: 'www.example.org', port: 8080),
an_object_having_attributes(domain: 'example.com', port: 8080)
]
diff --git a/spec/support/shared_examples/models/concerns/incident_management/escalatable_shared_examples.rb b/spec/support/shared_examples/models/concerns/incident_management/escalatable_shared_examples.rb
index 7b33a95bfa1..8ee76efc896 100644
--- a/spec/support/shared_examples/models/concerns/incident_management/escalatable_shared_examples.rb
+++ b/spec/support/shared_examples/models/concerns/incident_management/escalatable_shared_examples.rb
@@ -95,6 +95,12 @@ RSpec.shared_examples 'a model including Escalatable' do
it { is_expected.to eq([ignored_escalatable, resolved_escalatable, acknowledged_escalatable, triggered_escalatable]) }
end
end
+
+ describe '.open' do
+ subject { all_escalatables.open }
+
+ it { is_expected.to contain_exactly(acknowledged_escalatable, triggered_escalatable) }
+ end
end
describe '.status_value' do
@@ -133,6 +139,24 @@ RSpec.shared_examples 'a model including Escalatable' do
end
end
+ describe '.open_status?' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:status, :is_open_status) do
+ :triggered | true
+ :acknowledged | true
+ :resolved | false
+ :ignored | false
+ nil | false
+ end
+
+ with_them do
+ it 'returns true when the status is open status' do
+ expect(described_class.open_status?(status)).to eq(is_open_status)
+ end
+ end
+ end
+
describe '#trigger' do
subject { escalatable.trigger }
@@ -237,6 +261,15 @@ RSpec.shared_examples 'a model including Escalatable' do
end
end
+ describe '#open?' do
+ it 'returns true when the status is open status' do
+ expect(triggered_escalatable.open?).to be true
+ expect(acknowledged_escalatable.open?).to be true
+ expect(resolved_escalatable.open?).to be false
+ expect(ignored_escalatable.open?).to be false
+ end
+ end
+
private
def factory_from_class(klass)
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 ad15f82be5e..2a976fb7421 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
@@ -1,9 +1,9 @@
# frozen_string_literal: true
-RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
+RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name|
include StubRequests
- let(:chat_service) { described_class.new }
+ let(:chat_integration) { described_class.new }
let(:webhook_url) { 'https://example.gitlab.com' }
def execute_with_options(options)
@@ -17,7 +17,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
end
describe 'Validations' do
- context 'when service is active' do
+ context 'when integration is active' do
before do
subject.active = true
end
@@ -26,7 +26,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
it_behaves_like 'issue tracker integration URL attribute', :webhook
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
before do
subject.active = false
end
@@ -35,9 +35,9 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
end
end
- shared_examples "triggered #{service_name} service" do |event_type: nil, branches_to_be_notified: nil|
+ shared_examples "triggered #{integration_name} integration" do |event_type: nil, branches_to_be_notified: nil|
before do
- chat_service.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified
+ chat_integration.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified
end
let!(:stubbed_resolved_hostname) do
@@ -45,14 +45,14 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
end
it "notifies about #{event_type} events" do
- chat_service.execute(data)
+ chat_integration.execute(data)
expect(WebMock).to have_requested(:post, stubbed_resolved_hostname)
end
end
- shared_examples "untriggered #{service_name} service" do |event_type: nil, branches_to_be_notified: nil|
+ shared_examples "untriggered #{integration_name} integration" do |event_type: nil, branches_to_be_notified: nil|
before do
- chat_service.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified
+ chat_integration.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified
end
let!(:stubbed_resolved_hostname) do
@@ -60,7 +60,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
end
it "notifies about #{event_type} events" do
- chat_service.execute(data)
+ chat_integration.execute(data)
expect(WebMock).not_to have_requested(:post, stubbed_resolved_hostname)
end
end
@@ -69,50 +69,50 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
let_it_be(:project) { create(:project, :repository, :wiki_repo) }
let_it_be(:user) { create(:user) }
- let(:chat_service) { described_class.new( { project: project, webhook: webhook_url, branches_to_be_notified: 'all' }.merge(chat_service_params)) }
- let(:chat_service_params) { {} }
+ let(:chat_integration) { described_class.new( { project: project, webhook: webhook_url, branches_to_be_notified: 'all' }.merge(chat_integration_params)) }
+ let(:chat_integration_params) { {} }
let(:data) { Gitlab::DataBuilder::Push.build_sample(project, user) }
let!(:stubbed_resolved_hostname) do
stub_full_request(webhook_url, method: :post).request_pattern.uri_pattern.to_s
end
- subject(:execute_service) { chat_service.execute(data) }
+ subject(:execute_integration) { chat_integration.execute(data) }
- shared_examples 'calls the service API with the event message' do |event_message|
+ shared_examples 'calls the integration API with the event message' do |event_message|
specify do
expect_next_instance_of(::Slack::Messenger) do |messenger|
expect(messenger).to receive(:ping).with(event_message, anything).and_call_original
end
- execute_service
+ execute_integration
expect(WebMock).to have_requested(:post, stubbed_resolved_hostname).once
end
end
context 'with username for slack configured' do
- let(:chat_service_params) { { username: 'slack_username' } }
+ let(:chat_integration_params) { { username: 'slack_username' } }
it 'uses the username as an option' do
expect(::Slack::Messenger).to execute_with_options(username: 'slack_username')
- execute_service
+ execute_integration
end
end
context 'push events' do
let(:data) { Gitlab::DataBuilder::Push.build_sample(project, user) }
- it_behaves_like 'calls the service API with the event message', /pushed to branch/
+ it_behaves_like 'calls the integration API with the event message', /pushed to branch/
context 'with event channel' do
- let(:chat_service_params) { { push_channel: 'random' } }
+ let(:chat_integration_params) { { push_channel: 'random' } }
it 'uses the right channel for push event' do
expect(::Slack::Messenger).to execute_with_options(channel: ['random'])
- execute_service
+ execute_integration
end
end
end
@@ -123,7 +123,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
let(:ref) { 'refs/tags/v1.1.0' }
let(:data) { Git::TagHooksService.new(project, user, change: { oldrev: oldrev, newrev: newrev, ref: ref }).send(:push_data) }
- it_behaves_like 'calls the service API with the event message', /pushed new tag/
+ it_behaves_like 'calls the integration API with the event message', /pushed new tag/
end
context 'issue events' do
@@ -131,15 +131,15 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
let(:data) { issue.to_hook_data(user) }
- it_behaves_like 'calls the service API with the event message', /Issue (.*?) opened by/
+ it_behaves_like 'calls the integration API with the event message', /Issue (.*?) opened by/
context 'whith event channel' do
- let(:chat_service_params) { { issue_channel: 'random' } }
+ let(:chat_integration_params) { { issue_channel: 'random' } }
it 'uses the right channel for issue event' do
expect(::Slack::Messenger).to execute_with_options(channel: ['random'])
- execute_service
+ execute_integration
end
context 'for confidential issues' do
@@ -150,16 +150,16 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
it 'falls back to issue channel' do
expect(::Slack::Messenger).to execute_with_options(channel: ['random'])
- execute_service
+ execute_integration
end
context 'and confidential_issue_channel is defined' do
- let(:chat_service_params) { { issue_channel: 'random', confidential_issue_channel: 'confidential' } }
+ let(:chat_integration_params) { { issue_channel: 'random', confidential_issue_channel: 'confidential' } }
it 'uses the confidential issue channel when it is defined' do
expect(::Slack::Messenger).to execute_with_options(channel: ['confidential'])
- execute_service
+ execute_integration
end
end
end
@@ -171,15 +171,15 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
let(:data) { merge_request.to_hook_data(user) }
- it_behaves_like 'calls the service API with the event message', /opened merge request/
+ it_behaves_like 'calls the integration API with the event message', /opened merge request/
context 'with event channel' do
- let(:chat_service_params) { { merge_request_channel: 'random' } }
+ let(:chat_integration_params) { { merge_request_channel: 'random' } }
it 'uses the right channel for merge request event' do
expect(::Slack::Messenger).to execute_with_options(channel: ['random'])
- execute_service
+ execute_integration
end
end
end
@@ -189,15 +189,15 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
let(:data) { Gitlab::DataBuilder::WikiPage.build(wiki_page, user, 'create') }
- it_behaves_like 'calls the service API with the event message', %r{ created (.*?)wikis/(.*?)|wiki page> in}
+ it_behaves_like 'calls the integration API with the event message', %r{ created (.*?)wikis/(.*?)|wiki page> in}
context 'with event channel' do
- let(:chat_service_params) { { wiki_page_channel: 'random' } }
+ let(:chat_integration_params) { { wiki_page_channel: 'random' } }
it 'uses the right channel for wiki event' do
expect(::Slack::Messenger).to execute_with_options(channel: ['random'])
- execute_service
+ execute_integration
end
end
end
@@ -207,7 +207,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
let(:data) { Gitlab::DataBuilder::Deployment.build(deployment, Time.current) }
- it_behaves_like 'calls the service API with the event message', /Deploy to (.*?) created/
+ it_behaves_like 'calls the integration API with the event message', /Deploy to (.*?) created/
end
context 'note event' do
@@ -215,15 +215,15 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
let(:data) { Gitlab::DataBuilder::Note.build(issue_note, user) }
- it_behaves_like 'calls the service API with the event message', /commented on issue/
+ it_behaves_like 'calls the integration API with the event message', /commented on issue/
context 'with event channel' do
- let(:chat_service_params) { { note_channel: 'random' } }
+ let(:chat_integration_params) { { note_channel: 'random' } }
it 'uses the right channel' do
expect(::Slack::Messenger).to execute_with_options(channel: ['random'])
- execute_service
+ execute_integration
end
context 'for confidential notes' do
@@ -234,16 +234,16 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
it 'falls back to note channel' do
expect(::Slack::Messenger).to execute_with_options(channel: ['random'])
- execute_service
+ execute_integration
end
context 'and confidential_note_channel is defined' do
- let(:chat_service_params) { { note_channel: 'random', confidential_note_channel: 'confidential' } }
+ let(:chat_integration_params) { { note_channel: 'random', confidential_note_channel: 'confidential' } }
it 'uses confidential channel' do
expect(::Slack::Messenger).to execute_with_options(channel: ['confidential'])
- execute_service
+ execute_integration
end
end
end
@@ -256,7 +256,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
let(:project) { create(:project, :repository, creator: user) }
before do
- allow(chat_service).to receive_messages(
+ allow(chat_integration).to receive_messages(
project: project,
service_hook: true,
webhook: webhook_url
@@ -283,23 +283,23 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
)
end
- it_behaves_like "triggered #{service_name} service", event_type: "push"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "push"
end
context 'notification enabled only for default branch' do
- it_behaves_like "triggered #{service_name} service", event_type: "push", branches_to_be_notified: "default"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "push", branches_to_be_notified: "default"
end
context 'notification enabled only for protected branches' do
- it_behaves_like "untriggered #{service_name} service", event_type: "push", branches_to_be_notified: "protected"
+ it_behaves_like "untriggered #{integration_name} integration", event_type: "push", branches_to_be_notified: "protected"
end
context 'notification enabled only for default and protected branches' do
- it_behaves_like "triggered #{service_name} service", event_type: "push", branches_to_be_notified: "default_and_protected"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "push", branches_to_be_notified: "default_and_protected"
end
context 'notification enabled for all branches' do
- it_behaves_like "triggered #{service_name} service", event_type: "push", branches_to_be_notified: "all"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "push", branches_to_be_notified: "all"
end
end
@@ -325,23 +325,23 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
)
end
- it_behaves_like "triggered #{service_name} service", event_type: "push"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "push"
end
context 'notification enabled only for default branch' do
- it_behaves_like "untriggered #{service_name} service", event_type: "push", branches_to_be_notified: "default"
+ it_behaves_like "untriggered #{integration_name} integration", event_type: "push", branches_to_be_notified: "default"
end
context 'notification enabled only for protected branches' do
- it_behaves_like "triggered #{service_name} service", event_type: "push", branches_to_be_notified: "protected"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "push", branches_to_be_notified: "protected"
end
context 'notification enabled only for default and protected branches' do
- it_behaves_like "triggered #{service_name} service", event_type: "push", branches_to_be_notified: "default_and_protected"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "push", branches_to_be_notified: "default_and_protected"
end
context 'notification enabled for all branches' do
- it_behaves_like "triggered #{service_name} service", event_type: "push", branches_to_be_notified: "all"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "push", branches_to_be_notified: "all"
end
end
@@ -367,23 +367,23 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
)
end
- it_behaves_like "triggered #{service_name} service", event_type: "push"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "push"
end
context 'notification enabled only for default branch' do
- it_behaves_like "untriggered #{service_name} service", event_type: "push", branches_to_be_notified: "default"
+ it_behaves_like "untriggered #{integration_name} integration", event_type: "push", branches_to_be_notified: "default"
end
context 'notification enabled only for protected branches' do
- it_behaves_like "triggered #{service_name} service", event_type: "push", branches_to_be_notified: "protected"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "push", branches_to_be_notified: "protected"
end
context 'notification enabled only for default and protected branches' do
- it_behaves_like "triggered #{service_name} service", event_type: "push", branches_to_be_notified: "default_and_protected"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "push", branches_to_be_notified: "default_and_protected"
end
context 'notification enabled for all branches' do
- it_behaves_like "triggered #{service_name} service", event_type: "push", branches_to_be_notified: "all"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "push", branches_to_be_notified: "all"
end
end
@@ -405,23 +405,23 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
)
end
- it_behaves_like "triggered #{service_name} service", event_type: "push"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "push"
end
context 'notification enabled only for default branch' do
- it_behaves_like "untriggered #{service_name} service", event_type: "push", branches_to_be_notified: "default"
+ it_behaves_like "untriggered #{integration_name} integration", event_type: "push", branches_to_be_notified: "default"
end
context 'notification enabled only for protected branches' do
- it_behaves_like "untriggered #{service_name} service", event_type: "push", branches_to_be_notified: "protected"
+ it_behaves_like "untriggered #{integration_name} integration", event_type: "push", branches_to_be_notified: "protected"
end
context 'notification enabled only for default and protected branches' do
- it_behaves_like "untriggered #{service_name} service", event_type: "push", branches_to_be_notified: "default_and_protected"
+ it_behaves_like "untriggered #{integration_name} integration", event_type: "push", branches_to_be_notified: "default_and_protected"
end
context 'notification enabled for all branches' do
- it_behaves_like "triggered #{service_name} service", event_type: "push", branches_to_be_notified: "all"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "push", branches_to_be_notified: "all"
end
end
end
@@ -431,7 +431,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
let(:project) { create(:project, :repository, creator: user) }
before do
- allow(chat_service).to receive_messages(
+ allow(chat_integration).to receive_messages(
project: project,
service_hook: true,
webhook: webhook_url
@@ -452,7 +452,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
Gitlab::DataBuilder::Note.build(commit_note, user)
end
- it_behaves_like "triggered #{service_name} service", event_type: "commit comment"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "commit comment"
end
context 'when merge request comment event executed' do
@@ -465,7 +465,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
Gitlab::DataBuilder::Note.build(merge_request_note, user)
end
- it_behaves_like "triggered #{service_name} service", event_type: "merge request comment"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "merge request comment"
end
context 'when issue comment event executed' do
@@ -478,7 +478,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
Gitlab::DataBuilder::Note.build(issue_note, user)
end
- it_behaves_like "triggered #{service_name} service", event_type: "issue comment"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "issue comment"
end
context 'when snippet comment event executed' do
@@ -491,7 +491,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
Gitlab::DataBuilder::Note.build(snippet_note, user)
end
- it_behaves_like "triggered #{service_name} service", event_type: "snippet comment"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "snippet comment"
end
end
@@ -505,7 +505,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
end
before do
- allow(chat_service).to receive_messages(
+ allow(chat_integration).to receive_messages(
project: project,
service_hook: true,
webhook: webhook_url
@@ -519,15 +519,15 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) }
context 'with default to notify_only_broken_pipelines' do
- it_behaves_like "untriggered #{service_name} service", event_type: "pipeline"
+ it_behaves_like "untriggered #{integration_name} integration", event_type: "pipeline"
end
context 'with setting notify_only_broken_pipelines to false' do
before do
- chat_service.notify_only_broken_pipelines = false
+ chat_integration.notify_only_broken_pipelines = false
end
- it_behaves_like "triggered #{service_name} service", event_type: "pipeline"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "pipeline"
end
end
@@ -542,19 +542,19 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) }
context 'notification enabled only for default branch' do
- it_behaves_like "triggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "default"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "default"
end
context 'notification enabled only for protected branches' do
- it_behaves_like "untriggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "protected"
+ it_behaves_like "untriggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "protected"
end
context 'notification enabled only for default and protected branches' do
- it_behaves_like "triggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "default_and_protected"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "default_and_protected"
end
context 'notification enabled for all branches' do
- it_behaves_like "triggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "all"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "all"
end
end
@@ -572,19 +572,19 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) }
context 'notification enabled only for default branch' do
- it_behaves_like "untriggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "default"
+ it_behaves_like "untriggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "default"
end
context 'notification enabled only for protected branches' do
- it_behaves_like "triggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "protected"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "protected"
end
context 'notification enabled only for default and protected branches' do
- it_behaves_like "triggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "default_and_protected"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "default_and_protected"
end
context 'notification enabled for all branches' do
- it_behaves_like "triggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "all"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "all"
end
end
@@ -602,19 +602,19 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) }
context 'notification enabled only for default branch' do
- it_behaves_like "untriggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "default"
+ it_behaves_like "untriggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "default"
end
context 'notification enabled only for protected branches' do
- it_behaves_like "triggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "protected"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "protected"
end
context 'notification enabled only for default and protected branches' do
- it_behaves_like "triggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "default_and_protected"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "default_and_protected"
end
context 'notification enabled for all branches' do
- it_behaves_like "triggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "all"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "all"
end
end
@@ -628,19 +628,78 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name|
let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) }
context 'notification enabled only for default branch' do
- it_behaves_like "untriggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "default"
+ it_behaves_like "untriggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "default"
end
context 'notification enabled only for protected branches' do
- it_behaves_like "untriggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "protected"
+ it_behaves_like "untriggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "protected"
end
context 'notification enabled only for default and protected branches' do
- it_behaves_like "untriggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "default_and_protected"
+ it_behaves_like "untriggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "default_and_protected"
end
context 'notification enabled for all branches' do
- it_behaves_like "triggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "all"
+ it_behaves_like "triggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "all"
+ end
+ end
+ end
+ end
+
+ describe 'Deployment events' do
+ let_it_be(:user) { create(:user) }
+ let_it_be_with_reload(:project) { create(:project, :repository, creator: user) }
+
+ let(:deployment) do
+ create(:deployment, :success, project: project, sha: project.commit.sha, ref: project.default_branch)
+ end
+
+ let(:data) { Gitlab::DataBuilder::Deployment.build(deployment, Time.now) }
+
+ before do
+ allow(chat_integration).to receive_messages(
+ project: project,
+ service_hook: true,
+ webhook: webhook_url
+ )
+
+ stub_full_request(webhook_url, method: :post)
+ end
+
+ it_behaves_like "triggered #{integration_name} integration", event_type: "deployment"
+
+ context 'on a protected branch' do
+ before do
+ create(:protected_branch, :create_branch_on_repository, project: project, name: 'a-protected-branch')
+ end
+
+ let(:deployment) do
+ create(:deployment, :success, project: project, sha: project.commit.sha, ref: 'a-protected-branch')
+ end
+
+ context 'notification enabled only for default branch' do
+ it_behaves_like "untriggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "default"
+ end
+
+ context 'notification enabled only for protected branches' do
+ it_behaves_like "triggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "protected"
+ end
+
+ context 'notification enabled only for default and protected branches' do
+ it_behaves_like "triggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "default_and_protected"
+ end
+
+ 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
diff --git a/spec/support/shared_examples/models/concerns/packages/destructible_shared_examples.rb b/spec/support/shared_examples/models/concerns/packages/destructible_shared_examples.rb
new file mode 100644
index 00000000000..f974b46f881
--- /dev/null
+++ b/spec/support/shared_examples/models/concerns/packages/destructible_shared_examples.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'destructible' do |factory:|
+ let_it_be(:item1) { create(factory, created_at: 1.month.ago, updated_at: 1.day.ago) }
+ let_it_be(:item2) { create(factory, created_at: 1.year.ago, updated_at: 1.year.ago) }
+ let_it_be(:item3) { create(factory, :pending_destruction, created_at: 2.years.ago, updated_at: 1.month.ago) }
+ let_it_be(:item4) { create(factory, :pending_destruction, created_at: 3.years.ago, updated_at: 2.weeks.ago) }
+
+ describe '.next_pending_destruction' do
+ it 'returns the oldest item pending destruction based on updated_at' do
+ expect(described_class.next_pending_destruction(order_by: :updated_at)).to eq(item3)
+ end
+
+ it 'returns the oldest item pending destruction based on created_at' do
+ expect(described_class.next_pending_destruction(order_by: :created_at)).to eq(item4)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/models/concerns/ttl_expirable_shared_examples.rb b/spec/support/shared_examples/models/concerns/ttl_expirable_shared_examples.rb
index 2d08de297a3..174b8609337 100644
--- a/spec/support/shared_examples/models/concerns/ttl_expirable_shared_examples.rb
+++ b/spec/support/shared_examples/models/concerns/ttl_expirable_shared_examples.rb
@@ -29,7 +29,7 @@ RSpec.shared_examples 'ttl_expirable' do
describe '.active' do
# rubocop:disable Rails/SaveBang
let_it_be(:item1) { create(class_symbol) }
- let_it_be(:item2) { create(class_symbol, :expired) }
+ let_it_be(:item2) { create(class_symbol, :pending_destruction) }
let_it_be(:item3) { create(class_symbol, status: :error) }
# rubocop:enable Rails/SaveBang
@@ -38,17 +38,6 @@ RSpec.shared_examples 'ttl_expirable' do
end
end
- describe '.lock_next_by' do
- let_it_be(:item1) { create(class_symbol, created_at: 1.month.ago, updated_at: 1.day.ago) }
- let_it_be(:item2) { create(class_symbol, created_at: 1.year.ago, updated_at: 1.year.ago) }
- let_it_be(:item3) { create(class_symbol, created_at: 2.years.ago, updated_at: 1.month.ago) }
-
- it 'returns the first item sorted by the argument' do
- expect(described_class.lock_next_by(:updated_at)).to contain_exactly(item2)
- expect(described_class.lock_next_by(:created_at)).to contain_exactly(item3)
- end
- end
-
describe '#read', :freeze_time do
let_it_be(:old_read_at) { 1.day.ago }
let_it_be(:item1) { create(class_symbol, read_at: old_read_at) }
diff --git a/spec/support/shared_examples/models/member_shared_examples.rb b/spec/support/shared_examples/models/member_shared_examples.rb
index d5d137922eb..5b4b8c8fcc1 100644
--- a/spec/support/shared_examples/models/member_shared_examples.rb
+++ b/spec/support/shared_examples/models/member_shared_examples.rb
@@ -3,7 +3,7 @@
RSpec.shared_examples 'inherited access level as a member of entity' do
let(:parent_entity) { create(:group) }
let(:user) { create(:user) }
- let(:member) { entity.is_a?(Group) ? entity.group_member(user) : entity.project_member(user) }
+ let(:member) { entity.member(user) }
context 'with root parent_entity developer member' do
before do
@@ -49,7 +49,7 @@ RSpec.shared_examples 'inherited access level as a member of entity' do
entity.add_maintainer(non_member_user)
- non_member = entity.is_a?(Group) ? entity.group_member(non_member_user) : entity.project_member(non_member_user)
+ non_member = entity.member(non_member_user)
expect { non_member.update!(access_level: Gitlab::Access::GUEST) }
.to change { non_member.reload.access_level }
diff --git a/spec/support/shared_examples/models/packages/debian/distribution_shared_examples.rb b/spec/support/shared_examples/models/packages/debian/distribution_shared_examples.rb
index 750d3dd11e3..3f8c3b8960b 100644
--- a/spec/support/shared_examples/models/packages/debian/distribution_shared_examples.rb
+++ b/spec/support/shared_examples/models/packages/debian/distribution_shared_examples.rb
@@ -198,7 +198,6 @@ RSpec.shared_examples 'Debian Distribution' do |factory, container, can_freeze|
describe 'relationships' do
it { is_expected.to have_many(:publications).class_name('Packages::Debian::Publication').inverse_of(:distribution).with_foreign_key(:distribution_id) }
it { is_expected.to have_many(:packages).class_name('Packages::Package').through(:publications) }
- it { is_expected.to have_many(:package_files).class_name('Packages::PackageFile').through(:packages) }
end
end
else
@@ -229,6 +228,26 @@ RSpec.shared_examples 'Debian Distribution' do |factory, container, can_freeze|
it 'returns only files from public packages with same codename' do
expect(subject.to_a).to contain_exactly(*public_package_with_same_codename.package_files)
end
+
+ context 'with pending destruction package files' do
+ let_it_be(:package_file_pending_destruction) { create(:package_file, :pending_destruction, package: public_package_with_same_codename) }
+
+ it 'does not return them' do
+ expect(subject.to_a).not_to include(package_file_pending_destruction)
+ end
+
+ context 'with packages_installable_package_files disabled' do
+ before do
+ stub_feature_flags(packages_installable_package_files: false)
+ end
+
+ it 'returns them' do
+ subject
+
+ expect(subject.to_a).to include(package_file_pending_destruction)
+ end
+ end
+ end
end
end
end
diff --git a/spec/support/shared_examples/models/update_project_statistics_shared_examples.rb b/spec/support/shared_examples/models/update_project_statistics_shared_examples.rb
index 2e01de2ea84..06326ffac97 100644
--- a/spec/support/shared_examples/models/update_project_statistics_shared_examples.rb
+++ b/spec/support/shared_examples/models/update_project_statistics_shared_examples.rb
@@ -115,16 +115,14 @@ RSpec.shared_examples 'UpdateProjectStatistics' do |with_counter_attribute|
expect(ProjectStatistics)
.not_to receive(:increment_statistic)
- project.update!(pending_delete: true)
- project.destroy!
+ expect(Projects::DestroyService.new(project, project.owner).execute).to eq(true)
end
it 'does not schedule a namespace statistics worker' do
expect(Namespaces::ScheduleAggregationWorker)
.not_to receive(:perform_async)
- project.update!(pending_delete: true)
- project.destroy!
+ expect(Projects::DestroyService.new(project, project.owner).execute).to eq(true)
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 3d52ed30c62..b43b7946e69 100644
--- a/spec/support/shared_examples/namespaces/traversal_scope_examples.rb
+++ b/spec/support/shared_examples/namespaces/traversal_scope_examples.rb
@@ -124,6 +124,18 @@ RSpec.shared_examples 'namespace traversal scopes' do
it { expect(subject[0, 2]).to contain_exactly(group_1, group_2) }
it { expect(subject[2, 2]).to contain_exactly(nested_group_1, nested_group_2) }
end
+
+ 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 }
+
+ it { is_expected.to contain_exactly(group_2, nested_group_2, deep_nested_group_2) }
+ end
+
+ context 'with upto' do
+ subject { described_class.where(id: deep_nested_group_1).self_and_ancestors(upto: nested_group_1.id) }
+
+ it { is_expected.to contain_exactly(deep_nested_group_1) }
+ end
end
describe '.self_and_ancestors' do
@@ -168,6 +180,19 @@ RSpec.shared_examples 'namespace traversal scopes' do
it { is_expected.to contain_exactly(group_1.id, group_2.id) }
end
+
+ context 'with offset and limit' do
+ subject do
+ described_class
+ .where(id: [deep_nested_group_1, deep_nested_group_2])
+ .limit(1)
+ .offset(1)
+ .self_and_ancestor_ids
+ .pluck(:id)
+ end
+
+ it { is_expected.to contain_exactly(group_2.id, nested_group_2.id, deep_nested_group_2.id) }
+ end
end
describe '.self_and_ancestor_ids' do
diff --git a/spec/support/shared_examples/requests/access_tokens_controller_shared_examples.rb b/spec/support/shared_examples/requests/access_tokens_controller_shared_examples.rb
new file mode 100644
index 00000000000..6cd871d354c
--- /dev/null
+++ b/spec/support/shared_examples/requests/access_tokens_controller_shared_examples.rb
@@ -0,0 +1,138 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'GET resource access tokens available' do
+ let_it_be(:active_resource_access_token) { create(:personal_access_token, user: bot_user) }
+ let_it_be(:inactive_resource_access_token) { create(:personal_access_token, :revoked, user: bot_user) }
+
+ it 'retrieves active resource access tokens' do
+ subject
+
+ expect(assigns(:active_resource_access_tokens)).to contain_exactly(active_resource_access_token)
+ end
+
+ it 'retrieves inactive resource access tokens' do
+ subject
+
+ expect(assigns(:inactive_resource_access_tokens)).to contain_exactly(inactive_resource_access_token)
+ end
+
+ it 'lists all available scopes' do
+ subject
+
+ expect(assigns(:scopes)).to eq(Gitlab::Auth.resource_bot_scopes)
+ end
+
+ it 'retrieves newly created personal access token value' do
+ token_value = 'random-value'
+ allow(PersonalAccessToken).to receive(:redis_getdel).with("#{user.id}:#{resource.id}").and_return(token_value)
+
+ subject
+
+ expect(assigns(:new_resource_access_token)).to eq(token_value)
+ end
+end
+
+RSpec.shared_examples 'POST resource access tokens available' do
+ def created_token
+ PersonalAccessToken.order(:created_at).last
+ end
+
+ it 'returns success message' do
+ subject
+
+ expect(flash[:notice]).to match('Your new access token has been created.')
+ end
+
+ it 'creates resource access token' do
+ access_level = access_token_params[:access_level] || Gitlab::Access::MAINTAINER
+ subject
+
+ expect(created_token.name).to eq(access_token_params[:name])
+ expect(created_token.scopes).to eq(access_token_params[:scopes])
+ expect(created_token.expires_at).to eq(access_token_params[:expires_at])
+ expect(resource.member(created_token.user).access_level).to eq(access_level)
+ end
+
+ it 'creates project bot user' do
+ subject
+
+ expect(created_token.user).to be_project_bot
+ end
+
+ it 'stores newly created token redis store' do
+ expect(PersonalAccessToken).to receive(:redis_store!)
+
+ subject
+ end
+
+ it { expect { subject }.to change { User.count }.by(1) }
+ it { expect { subject }.to change { PersonalAccessToken.count }.by(1) }
+
+ context 'when unsuccessful' do
+ before do
+ allow_next_instance_of(ResourceAccessTokens::CreateService) do |service|
+ allow(service).to receive(:execute).and_return ServiceResponse.error(message: 'Failed!')
+ end
+ end
+
+ it 'does not create the token' do
+ expect { subject }.not_to change { PersonalAccessToken.count }
+ end
+
+ it 'does not add the project bot as a member' do
+ expect { subject }.not_to change { Member.count }
+ end
+
+ it 'does not create the project bot user' do
+ expect { subject }.not_to change { User.count }
+ end
+
+ it 'shows a failure alert' do
+ subject
+
+ expect(flash[:alert]).to match("Failed to create new access token: Failed!")
+ end
+ end
+end
+
+RSpec.shared_examples 'PUT resource access tokens available' do
+ it 'calls delete user worker' do
+ expect(DeleteUserWorker).to receive(:perform_async).with(user.id, bot_user.id, skip_authorization: true)
+
+ subject
+ end
+
+ it 'removes membership of bot user' do
+ subject
+
+ expect(resource.reload.bots).not_to include(bot_user)
+ end
+
+ it 'converts issuables of the bot user to ghost user' do
+ issue = create(:issue, author: bot_user)
+
+ subject
+
+ expect(issue.reload.author.ghost?).to be true
+ end
+
+ it 'deletes project bot user' do
+ subject
+
+ expect(User.exists?(bot_user.id)).to be_falsy
+ end
+
+ context 'when unsuccessful' do
+ before do
+ allow_next_instance_of(ResourceAccessTokens::RevokeService) do |service|
+ allow(service).to receive(:execute).and_return ServiceResponse.error(message: 'Failed!')
+ end
+ end
+
+ it 'shows a failure alert' do
+ subject
+
+ expect(flash[:alert]).to include("Could not revoke access token")
+ end
+ end
+end
diff --git a/spec/support/shared_examples/requests/api/debian_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/debian_packages_shared_examples.rb
index 2fd5e6a5f91..9f96cb2a164 100644
--- a/spec/support/shared_examples/requests/api/debian_packages_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/debian_packages_shared_examples.rb
@@ -40,7 +40,6 @@ RSpec.shared_examples 'Debian packages upload request' do |status, body = nil|
expect(response.body).to match(body)
end
end
- it_behaves_like 'a package tracking event', described_class.name, 'push_package'
else
it "returns #{status}#{and_body}", :aggregate_failures do
subject
diff --git a/spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb b/spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb
index d576a5874fd..9385706d991 100644
--- a/spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb
@@ -38,4 +38,28 @@ RSpec.shared_examples 'a package with files' do
'fileSha256' => first_file.file_sha256
)
end
+
+ context 'with package files pending destruction' do
+ let_it_be(:package_file_pending_destruction) { create(:package_file, :pending_destruction, package: package) }
+
+ let(:response_package_file_ids) { package_files_response.map { |pf| pf['id'] } }
+
+ it 'does not return them' do
+ expect(package.reload.package_files).to include(package_file_pending_destruction)
+
+ expect(response_package_file_ids).not_to include(package_file_pending_destruction.to_global_id.to_s)
+ end
+
+ context 'with packages_installable_package_files disabled' do
+ before(:context) do
+ stub_feature_flags(packages_installable_package_files: false)
+ end
+
+ it 'returns them' do
+ expect(package.reload.package_files).to include(package_file_pending_destruction)
+
+ expect(response_package_file_ids).to include(package_file_pending_destruction.to_global_id.to_s)
+ end
+ end
+ end
end
diff --git a/spec/support/shared_examples/requests/api/nuget_endpoints_shared_examples.rb b/spec/support/shared_examples/requests/api/nuget_endpoints_shared_examples.rb
index db70bc75c63..290bf58fb6b 100644
--- a/spec/support/shared_examples/requests/api/nuget_endpoints_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/nuget_endpoints_shared_examples.rb
@@ -221,6 +221,7 @@ RSpec.shared_examples 'handling nuget search requests' do |anonymous_requests_ex
let_it_be(:packages_c) { create_list(:nuget_package, 5, name: 'Dummy.PackageC', project: project) }
let_it_be(:package_d) { create(:nuget_package, name: 'Dummy.PackageD', version: '5.0.5-alpha', project: project) }
let_it_be(:package_e) { create(:nuget_package, name: 'Foo.BarE', project: project) }
+
let(:search_term) { 'uMmy' }
let(:take) { 26 }
let(:skip) { 0 }
diff --git a/spec/support/shared_examples/services/alert_management_shared_examples.rb b/spec/support/shared_examples/services/alert_management_shared_examples.rb
index 827ae42f970..23aee912d2d 100644
--- a/spec/support/shared_examples/services/alert_management_shared_examples.rb
+++ b/spec/support/shared_examples/services/alert_management_shared_examples.rb
@@ -64,12 +64,16 @@ RSpec.shared_examples 'processes never-before-seen recovery alert' do
end
RSpec.shared_examples 'processes one firing and one resolved prometheus alerts' do
- it 'creates AlertManagement::Alert' do
+ it 'creates alerts and returns them in the payload', :aggregate_failures do
expect(Gitlab::AppLogger).not_to receive(:warn)
expect { subject }
.to change(AlertManagement::Alert, :count).by(2)
.and change(Note, :count).by(4)
+
+ expect(subject).to be_success
+ expect(subject.payload[:alerts]).to all(be_a_kind_of(AlertManagement::Alert))
+ expect(subject.payload[:alerts].size).to eq(2)
end
it_behaves_like 'processes incident issues'
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 f6e25ee6647..87bf134eeb8 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
@@ -71,6 +71,7 @@ end
RSpec.shared_examples 'an accessible' do
before do
stub_feature_flags(container_registry_migration_phase1: false)
+ stub_feature_flags(container_registry_cdn_redirect: false)
end
let(:access) do
@@ -163,6 +164,7 @@ RSpec.shared_examples 'a container registry auth service' do
before do
stub_feature_flags(container_registry_migration_phase1: false)
+ stub_feature_flags(container_registry_cdn_redirect: false)
end
describe '#full_access_token' do
diff --git a/spec/support/shared_examples/services/incident_shared_examples.rb b/spec/support/shared_examples/services/incident_shared_examples.rb
index 0277cce975a..36b0acf5a51 100644
--- a/spec/support/shared_examples/services/incident_shared_examples.rb
+++ b/spec/support/shared_examples/services/incident_shared_examples.rb
@@ -17,16 +17,6 @@ RSpec.shared_examples 'incident issue' do
end
end
-RSpec.shared_examples 'has incident label' do
- let(:label_properties) { attributes_for(:label, :incident) }
-
- it 'has exactly one incident label' do
- expect(issue.labels).to be_one do |label|
- label.slice(*label_properties.keys).symbolize_keys == label_properties
- end
- end
-end
-
# This shared_example requires the following variables:
# - issue (required)
#
@@ -45,6 +35,12 @@ RSpec.shared_examples 'not an incident issue' do
expect(issue.work_item_type.base_type).not_to eq('incident')
end
+ it_behaves_like 'does not have incident label'
+end
+
+RSpec.shared_examples 'does not have incident label' do
+ let(:label_properties) { attributes_for(:label, :incident) }
+
it 'has not an incident label' do
expect(issue.labels).not_to include(have_attributes(label_properties))
end
diff --git a/spec/support/shared_examples/services/service_ping/service_ping_payload_with_all_expected_metrics_shared_examples.rb b/spec/support/shared_examples/services/service_ping/service_ping_payload_with_all_expected_metrics_shared_examples.rb
index 535e7291b7e..856810a4de1 100644
--- a/spec/support/shared_examples/services/service_ping/service_ping_payload_with_all_expected_metrics_shared_examples.rb
+++ b/spec/support/shared_examples/services/service_ping/service_ping_payload_with_all_expected_metrics_shared_examples.rb
@@ -2,6 +2,8 @@
RSpec.shared_examples 'service ping payload with all expected metrics' do
specify do
+ allow(ApplicationRecord.database).to receive(:flavor).and_return(nil)
+
aggregate_failures do
expected_metrics.each do |metric|
is_expected.to have_usage_metric metric['key_path']
diff --git a/spec/support/shared_examples/services/service_ping/service_ping_payload_without_restricted_metrics_shared_examples.rb b/spec/support/shared_examples/services/service_ping/service_ping_payload_without_restricted_metrics_shared_examples.rb
index 9f18174cbc7..e05239a9a36 100644
--- a/spec/support/shared_examples/services/service_ping/service_ping_payload_without_restricted_metrics_shared_examples.rb
+++ b/spec/support/shared_examples/services/service_ping/service_ping_payload_without_restricted_metrics_shared_examples.rb
@@ -2,6 +2,8 @@
RSpec.shared_examples 'service ping payload without restricted metrics' do
specify do
+ allow(ApplicationRecord.database).to receive(:flavor).and_return(nil)
+
aggregate_failures do
restricted_metrics.each do |metric|
is_expected.not_to have_usage_metric metric['key_path']
diff --git a/spec/support/shared_examples/work_item_base_types_importer.rb b/spec/support/shared_examples/work_item_base_types_importer.rb
index 7d652be8d05..68e37171ea2 100644
--- a/spec/support/shared_examples/work_item_base_types_importer.rb
+++ b/spec/support/shared_examples/work_item_base_types_importer.rb
@@ -3,8 +3,8 @@
RSpec.shared_examples 'work item base types importer' do
it 'creates all base work item types' do
# Fixtures need to run on a pristine DB, but the test suite preloads the base types before(:suite)
- WorkItem::Type.delete_all
+ WorkItems::Type.delete_all
- expect { subject }.to change(WorkItem::Type, :count).from(0).to(WorkItem::Type::BASE_TYPES.count)
+ expect { subject }.to change(WorkItems::Type, :count).from(0).to(WorkItems::Type::BASE_TYPES.count)
end
end
diff --git a/spec/support/shared_examples/workers/concerns/dependency_proxy/cleanup_worker_shared_examples.rb b/spec/support/shared_examples/workers/concerns/dependency_proxy/cleanup_worker_shared_examples.rb
index c9014ad549c..26444437826 100644
--- a/spec/support/shared_examples/workers/concerns/dependency_proxy/cleanup_worker_shared_examples.rb
+++ b/spec/support/shared_examples/workers/concerns/dependency_proxy/cleanup_worker_shared_examples.rb
@@ -13,12 +13,12 @@ RSpec.shared_examples 'dependency_proxy_cleanup_worker' do
end
context 'with work to do' do
- let_it_be(:artifact1) { create(factory_type, :expired, group: group) }
- let_it_be(:artifact2) { create(factory_type, :expired, group: group, updated_at: 6.months.ago, created_at: 2.years.ago) }
- let_it_be_with_reload(:artifact3) { create(factory_type, :expired, group: group, updated_at: 1.year.ago, created_at: 1.year.ago) }
+ let_it_be(:artifact1) { create(factory_type, :pending_destruction, group: group) }
+ let_it_be(:artifact2) { create(factory_type, :pending_destruction, group: group, updated_at: 6.months.ago, created_at: 2.years.ago) }
+ let_it_be_with_reload(:artifact3) { create(factory_type, :pending_destruction, group: group, updated_at: 1.year.ago, created_at: 1.year.ago) }
let_it_be(:artifact4) { create(factory_type, group: group, updated_at: 2.years.ago, created_at: 2.years.ago) }
- it 'deletes the oldest expired artifact based on updated_at', :aggregate_failures do
+ it 'deletes the oldest artifact pending destruction based on updated_at', :aggregate_failures do
expect(worker).to receive(:log_extra_metadata_on_done).with("#{factory_type}_id".to_sym, artifact3.id)
expect(worker).to receive(:log_extra_metadata_on_done).with(:group_id, group.id)
@@ -40,10 +40,8 @@ RSpec.shared_examples 'dependency_proxy_cleanup_worker' do
end
describe '#remaining_work_count' do
- let_it_be(:expired_artifacts) do
- (1..3).map do |_|
- create(factory_type, :expired, group: group)
- end
+ before(:context) do
+ create_list(factory_type, 3, :pending_destruction, group: group)
end
subject { worker.remaining_work_count }
diff --git a/spec/support/system_exit_detected.rb b/spec/support/system_exit_detected.rb
new file mode 100644
index 00000000000..86c6af3ba8c
--- /dev/null
+++ b/spec/support/system_exit_detected.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+SystemExitDetected = Class.new(RuntimeError)
+
+RSpec.configure do |config|
+ config.around do |example|
+ example.run
+ rescue SystemExit
+ # In any cases, we cannot raise SystemExit in the tests,
+ # because it'll skip any following tests from running.
+ # Convert it to something that won't skip everything.
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/350060
+ raise SystemExitDetected, "SystemExit should be rescued in the tests!"
+ end
+end
diff --git a/spec/support_specs/database/multiple_databases_spec.rb b/spec/support_specs/database/multiple_databases_spec.rb
index a8692e315fe..b4cfa253813 100644
--- a/spec/support_specs/database/multiple_databases_spec.rb
+++ b/spec/support_specs/database/multiple_databases_spec.rb
@@ -7,13 +7,13 @@ RSpec.describe 'Database::MultipleDatabases' do
context 'when doing establish_connection' do
context 'on ActiveRecord::Base' do
it 'raises exception' do
- expect { ActiveRecord::Base.establish_connection(:main) }.to raise_error /Cannot re-establish/
+ expect { ActiveRecord::Base.establish_connection(:main) }.to raise_error /Cannot re-establish/ # rubocop: disable Database/EstablishConnection
end
context 'when using with_reestablished_active_record_base' do
it 'does not raise exception' do
with_reestablished_active_record_base do
- expect { ActiveRecord::Base.establish_connection(:main) }.not_to raise_error
+ expect { ActiveRecord::Base.establish_connection(:main) }.not_to raise_error # rubocop: disable Database/EstablishConnection
end
end
end
@@ -25,13 +25,13 @@ RSpec.describe 'Database::MultipleDatabases' do
end
it 'raises exception' do
- expect { Ci::ApplicationRecord.establish_connection(:ci) }.to raise_error /Cannot re-establish/
+ expect { Ci::ApplicationRecord.establish_connection(:ci) }.to raise_error /Cannot re-establish/ # rubocop: disable Database/EstablishConnection
end
context 'when using with_reestablished_active_record_base' do
it 'does not raise exception' do
with_reestablished_active_record_base do
- expect { Ci::ApplicationRecord.establish_connection(:main) }.not_to raise_error
+ expect { Ci::ApplicationRecord.establish_connection(:main) }.not_to raise_error # rubocop: disable Database/EstablishConnection
end
end
end
@@ -42,7 +42,7 @@ RSpec.describe 'Database::MultipleDatabases' do
context 'when reconnect is true' do
it 'does not raise exception' do
with_reestablished_active_record_base(reconnect: true) do
- expect { ActiveRecord::Base.connection.execute("SELECT 1") }.not_to raise_error # rubocop:disable Database/MultipleDatabases
+ expect { ApplicationRecord.connection.execute("SELECT 1") }.not_to raise_error
end
end
end
@@ -50,7 +50,7 @@ RSpec.describe 'Database::MultipleDatabases' do
context 'when reconnect is false' do
it 'does raise exception' do
with_reestablished_active_record_base(reconnect: false) do
- expect { ActiveRecord::Base.connection.execute("SELECT 1") }.to raise_error(ActiveRecord::ConnectionNotEstablished) # rubocop:disable Database/MultipleDatabases
+ expect { ApplicationRecord.connection.execute("SELECT 1") }.to raise_error(ActiveRecord::ConnectionNotEstablished)
end
end
end
diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb
index 99deaa8d154..c5e73aa3b45 100644
--- a/spec/tasks/gitlab/backup_rake_spec.rb
+++ b/spec/tasks/gitlab/backup_rake_spec.rb
@@ -4,6 +4,7 @@ require 'rake_helper'
RSpec.describe 'gitlab:app namespace rake task', :delete do
let(:enable_registry) { true }
+ let(:backup_types) { %w{db repo uploads builds artifacts pages lfs terraform_state registry packages} }
def tars_glob
Dir.glob(File.join(Gitlab.config.backup.path, '*_gitlab_backup.tar'))
@@ -14,7 +15,7 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
end
def backup_files
- %w(backup_information.yml artifacts.tar.gz builds.tar.gz lfs.tar.gz pages.tar.gz)
+ %w(backup_information.yml artifacts.tar.gz builds.tar.gz lfs.tar.gz terraform_state.tar.gz pages.tar.gz packages.tar.gz)
end
def backup_directories
@@ -47,7 +48,7 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
end
def reenable_backup_sub_tasks
- %w{db repo uploads builds artifacts pages lfs registry}.each do |subtask|
+ backup_types.each do |subtask|
Rake::Task["gitlab:backup:#{subtask}:create"].reenable
end
end
@@ -71,14 +72,9 @@ 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(Rake::Task['gitlab:backup:db:restore']).to receive(:invoke)
- expect(Rake::Task['gitlab:backup:repo:restore']).to receive(:invoke)
- expect(Rake::Task['gitlab:backup:builds:restore']).to receive(:invoke)
- expect(Rake::Task['gitlab:backup:uploads:restore']).to receive(:invoke)
- expect(Rake::Task['gitlab:backup:artifacts:restore']).to receive(:invoke)
- expect(Rake::Task['gitlab:backup:pages:restore']).to receive(:invoke)
- expect(Rake::Task['gitlab:backup:lfs:restore']).to receive(:invoke)
- expect(Rake::Task['gitlab:backup:registry:restore']).to receive(:invoke)
+ backup_types.each do |subtask|
+ expect(Rake::Task["gitlab:backup:#{subtask}:restore"]).to receive(:invoke)
+ end
expect(Rake::Task['gitlab:shell:setup']).to receive(:invoke)
end
@@ -95,7 +91,7 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
context 'when the restore directory is not empty' do
before do
# We only need a backup of the repositories for this test
- stub_env('SKIP', 'db,uploads,builds,artifacts,lfs,registry')
+ stub_env('SKIP', 'db,uploads,builds,artifacts,lfs,terraform_state,registry')
create(:project, :repository)
end
@@ -139,11 +135,10 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
expect(Rake::Task['gitlab:backup:artifacts:restore']).to receive(:invoke)
expect(Rake::Task['gitlab:backup:pages:restore']).to receive(:invoke)
expect(Rake::Task['gitlab:backup:lfs:restore']).to receive(:invoke)
+ expect(Rake::Task['gitlab:backup:terraform_state:restore']).to receive(:invoke)
expect(Rake::Task['gitlab:backup:registry:restore']).to receive(:invoke)
+ expect(Rake::Task['gitlab:backup:packages:restore']).to receive(:invoke)
expect(Rake::Task['gitlab:shell:setup']).to receive(:invoke)
-
- # We only need a backup of the repositories for this test
- stub_env('SKIP', 'db,uploads,builds,artifacts,lfs,registry')
end
it 'restores the data' do
@@ -202,10 +197,8 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
end
context 'specific backup tasks' do
- let(:task_list) { %w(db repo uploads builds artifacts pages lfs registry) }
-
it 'prints a progress message to stdout' do
- task_list.each do |task|
+ backup_types.each do |task|
expect { run_rake_task("gitlab:backup:#{task}:create") }.to output(/Dumping /).to_stdout_from_any_process
end
end
@@ -219,16 +212,49 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping artifacts ... ")
expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping pages ... ")
expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping lfs objects ... ")
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping terraform states ... ")
expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping container registry images ... ")
- expect(Gitlab::BackupLogger).to receive(:info).with(message: "done").exactly(7).times
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping packages ... ")
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: "done").exactly(9).times
- task_list.each do |task|
+ backup_types.each do |task|
run_rake_task("gitlab:backup:#{task}:create")
end
end
end
end
+ describe 'backup create fails' do
+ using RSpec::Parameterized::TableSyntax
+
+ file_backup_error = Backup::FileBackupError.new('/tmp', '/tmp/backup/uploads')
+ config = ActiveRecord::Base.configurations.find_db_config(Rails.env).configuration_hash
+ db_file_name = File.join(Gitlab.config.backup.path, 'db', 'database.sql.gz')
+ db_backup_error = Backup::DatabaseBackupError.new(config, db_file_name)
+
+ where(:backup_class, :rake_task, :error) do
+ Backup::Database | 'gitlab:backup:db:create' | db_backup_error
+ Backup::Builds | 'gitlab:backup:builds:create' | file_backup_error
+ Backup::Uploads | 'gitlab:backup:uploads:create' | file_backup_error
+ Backup::Artifacts | 'gitlab:backup:artifacts:create' | file_backup_error
+ Backup::Pages | 'gitlab:backup:pages:create' | file_backup_error
+ Backup::Lfs | 'gitlab:backup:lfs:create' | file_backup_error
+ Backup::Registry | 'gitlab:backup:registry:create' | file_backup_error
+ end
+
+ with_them do
+ before do
+ expect_next_instance_of(backup_class) do |instance|
+ expect(instance).to receive(:dump).and_raise(error)
+ end
+ end
+
+ it "raises an error with message" do
+ expect { run_rake_task(rake_task) }.to output(Regexp.new(error.message)).to_stdout_from_any_process
+ end
+ end
+ end
+
context 'tar creation' do
context 'archive file permissions' do
it 'sets correct permissions on the tar file' do
@@ -255,9 +281,11 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
expect { run_rake_task('gitlab:backup:create') }.to output.to_stdout_from_any_process
tar_contents, exit_status = Gitlab::Popen.popen(
- %W{tar -tvf #{backup_tar} db uploads.tar.gz repositories builds.tar.gz artifacts.tar.gz pages.tar.gz lfs.tar.gz registry.tar.gz}
+ %W{tar -tvf #{backup_tar} db uploads.tar.gz repositories builds.tar.gz artifacts.tar.gz pages.tar.gz lfs.tar.gz terraform_state.tar.gz registry.tar.gz packages.tar.gz}
)
+ puts "CONTENT: #{tar_contents}"
+
expect(exit_status).to eq(0)
expect(tar_contents).to match('db')
expect(tar_contents).to match('uploads.tar.gz')
@@ -266,7 +294,9 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
expect(tar_contents).to match('artifacts.tar.gz')
expect(tar_contents).to match('pages.tar.gz')
expect(tar_contents).to match('lfs.tar.gz')
+ expect(tar_contents).to match('terraform_state.tar.gz')
expect(tar_contents).to match('registry.tar.gz')
+ expect(tar_contents).to match('packages.tar.gz')
expect(tar_contents).not_to match(%r{^.{4,9}[rwx].* (database.sql.gz|uploads.tar.gz|repositories|builds.tar.gz|pages.tar.gz|artifacts.tar.gz|registry.tar.gz)/$})
end
@@ -274,7 +304,7 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
expect { run_rake_task('gitlab:backup:create') }.to output.to_stdout_from_any_process
temp_dirs = Dir.glob(
- File.join(Gitlab.config.backup.path, '{db,repositories,uploads,builds,artifacts,pages,lfs,registry}')
+ File.join(Gitlab.config.backup.path, '{db,repositories,uploads,builds,artifacts,pages,lfs,terraform_state,registry,packages}')
)
expect(temp_dirs).to be_empty
@@ -304,7 +334,7 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
before do
# We only need a backup of the repositories for this test
- stub_env('SKIP', 'db,uploads,builds,artifacts,lfs,registry')
+ stub_env('SKIP', 'db,uploads,builds,artifacts,lfs,terraform_state,registry')
stub_storage_settings( second_storage_name => {
'gitaly_address' => Gitlab.config.repositories.storages.default.gitaly_address,
'path' => TestEnv::SECOND_STORAGE_PATH
@@ -378,7 +408,7 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
context 'concurrency settings' do
before do
# We only need a backup of the repositories for this test
- stub_env('SKIP', 'db,uploads,builds,artifacts,lfs,registry')
+ stub_env('SKIP', 'db,uploads,builds,artifacts,lfs,terraform_state,registry')
create(:project, :repository)
end
@@ -407,7 +437,7 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
.with(max_concurrency: 5, max_storage_concurrency: 2)
.and_call_original
end
- expect(::Backup::GitalyBackup).to receive(:new).with(anything, parallel: 5, parallel_storage: 2).and_call_original
+ expect(::Backup::GitalyBackup).to receive(:new).with(anything, max_parallelism: 5, storage_parallelism: 2).and_call_original
expect { run_rake_task('gitlab:backup:create') }.to output.to_stdout_from_any_process
end
@@ -425,31 +455,34 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
end
# backup_create task
- describe "Skipping items" do
+ describe "Skipping items in a backup" do
before do
- stub_env('SKIP', 'repositories,uploads')
+ stub_env('SKIP', 'an-unknown-type,repositories,uploads,anotherunknowntype')
create(:project, :repository)
end
- it "does not contain skipped item" do
+ it "does not contain repositories and uploads" do
expect { run_rake_task('gitlab:backup:create') }.to output.to_stdout_from_any_process
tar_contents, _exit_status = Gitlab::Popen.popen(
- %W{tar -tvf #{backup_tar} db uploads.tar.gz repositories builds.tar.gz artifacts.tar.gz pages.tar.gz lfs.tar.gz registry.tar.gz}
+ %W{tar -tvf #{backup_tar} db uploads.tar.gz repositories builds.tar.gz artifacts.tar.gz pages.tar.gz lfs.tar.gz terraform_state.tar.gz registry.tar.gz packages.tar.gz}
)
expect(tar_contents).to match('db/')
- expect(tar_contents).to match('uploads.tar.gz')
+ expect(tar_contents).to match('uploads.tar.gz: Not found in archive')
expect(tar_contents).to match('builds.tar.gz')
expect(tar_contents).to match('artifacts.tar.gz')
expect(tar_contents).to match('lfs.tar.gz')
+ expect(tar_contents).to match('terraform_state.tar.gz')
expect(tar_contents).to match('pages.tar.gz')
expect(tar_contents).to match('registry.tar.gz')
+ expect(tar_contents).to match('packages.tar.gz')
expect(tar_contents).not_to match('repositories/')
+ expect(tar_contents).to match('repositories: Not found in archive')
end
- it 'does not invoke repositories restore' do
+ it 'does not invoke restore of repositories and uploads' do
expect { run_rake_task('gitlab:backup:create') }.to output.to_stdout_from_any_process
allow(Rake::Task['gitlab:shell:setup'])
@@ -463,7 +496,9 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
expect(Rake::Task['gitlab:backup:artifacts:restore']).to receive :invoke
expect(Rake::Task['gitlab:backup:pages:restore']).to receive :invoke
expect(Rake::Task['gitlab:backup:lfs:restore']).to receive :invoke
+ expect(Rake::Task['gitlab:backup:terraform_state:restore']).to receive :invoke
expect(Rake::Task['gitlab:backup:registry:restore']).to receive :invoke
+ expect(Rake::Task['gitlab:backup:packages:restore']).to receive :invoke
expect(Rake::Task['gitlab:shell:setup']).to receive :invoke
expect { run_rake_task('gitlab:backup:restore') }.to output.to_stdout_from_any_process
end
@@ -488,8 +523,10 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
'builds.tar.gz',
'artifacts.tar.gz',
'lfs.tar.gz',
+ 'terraform_state.tar.gz',
'pages.tar.gz',
'registry.tar.gz',
+ 'packages.tar.gz',
'repositories'
)
end
@@ -501,14 +538,9 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
.to receive(:invoke).and_return(true)
expect(Rake::Task['gitlab:db:drop_tables']).to receive :invoke
- expect(Rake::Task['gitlab:backup:db:restore']).to receive :invoke
- expect(Rake::Task['gitlab:backup:repo:restore']).to receive :invoke
- expect(Rake::Task['gitlab:backup:uploads:restore']).to receive :invoke
- expect(Rake::Task['gitlab:backup:builds:restore']).to receive :invoke
- expect(Rake::Task['gitlab:backup:artifacts:restore']).to receive :invoke
- expect(Rake::Task['gitlab:backup:pages:restore']).to receive :invoke
- expect(Rake::Task['gitlab:backup:lfs:restore']).to receive :invoke
- expect(Rake::Task['gitlab:backup:registry:restore']).to receive :invoke
+ backup_types.each do |subtask|
+ expect(Rake::Task["gitlab:backup:#{subtask}:restore"]).to receive :invoke
+ end
expect(Rake::Task['gitlab:shell:setup']).to receive :invoke
expect { run_rake_task("gitlab:backup:restore") }.to output.to_stdout_from_any_process
end
diff --git a/spec/tasks/gitlab/db_rake_spec.rb b/spec/tasks/gitlab/db_rake_spec.rb
index 830d0dded2e..92c896b1ab0 100644
--- a/spec/tasks/gitlab/db_rake_spec.rb
+++ b/spec/tasks/gitlab/db_rake_spec.rb
@@ -214,7 +214,7 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout do
expect(Gitlab::Database::Reindexing).to receive(:enabled?).and_return(false)
expect(Gitlab::Database::Reindexing).not_to receive(:invoke)
- run_rake_task('gitlab:db:reindex')
+ expect { run_rake_task('gitlab:db:reindex') }.to raise_error(SystemExit)
end
end
end
@@ -233,7 +233,7 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout do
expect(Gitlab::Database::Reindexing).to receive(:enabled?).and_return(false)
expect(Gitlab::Database::Reindexing).not_to receive(:invoke).with(database_name)
- run_rake_task("gitlab:db:reindex:#{database_name}")
+ expect { run_rake_task("gitlab:db:reindex:#{database_name}") }.to raise_error(SystemExit)
end
end
end
diff --git a/spec/tasks/gitlab/password_rake_spec.rb b/spec/tasks/gitlab/password_rake_spec.rb
index 65bba836024..ec18d713351 100644
--- a/spec/tasks/gitlab/password_rake_spec.rb
+++ b/spec/tasks/gitlab/password_rake_spec.rb
@@ -3,7 +3,7 @@
require 'rake_helper'
RSpec.describe 'gitlab:password rake tasks', :silence_stdout do
- let_it_be(:user_1) { create(:user, username: 'foobar', password: 'initial_password') }
+ let_it_be(:user_1) { create(:user, username: 'foobar', password: Gitlab::Password.test_default) }
def stub_username(username)
allow(Gitlab::TaskHelpers).to receive(:prompt).with('Enter username: ').and_return(username)
@@ -19,14 +19,14 @@ RSpec.describe 'gitlab:password rake tasks', :silence_stdout do
Rake.application.rake_require 'tasks/gitlab/password'
stub_username('foobar')
- stub_password('secretpassword')
+ stub_password(Gitlab::Password.test_default)
end
describe ':reset' do
context 'when all inputs are correct' do
it 'updates the password properly' do
run_rake_task('gitlab:password:reset', user_1.username)
- expect(user_1.reload.valid_password?('secretpassword')).to eq(true)
+ expect(user_1.reload.valid_password?(Gitlab::Password.test_default)).to eq(true)
end
end
@@ -55,7 +55,7 @@ RSpec.describe 'gitlab:password rake tasks', :silence_stdout do
context 'when passwords do not match' do
before do
- stub_password('randompassword', 'differentpassword')
+ stub_password(Gitlab::Password.test_default, "different" + Gitlab::Password.test_default)
end
it 'aborts with an error' do
diff --git a/spec/tasks/gitlab/usage_data_rake_spec.rb b/spec/tasks/gitlab/usage_data_rake_spec.rb
index acaf9b5729b..442b884b313 100644
--- a/spec/tasks/gitlab/usage_data_rake_spec.rb
+++ b/spec/tasks/gitlab/usage_data_rake_spec.rb
@@ -9,6 +9,7 @@ RSpec.describe 'gitlab:usage data take tasks', :silence_stdout do
Rake.application.rake_require 'tasks/gitlab/usage_data'
# stub prometheus external http calls https://gitlab.com/gitlab-org/gitlab/-/issues/245277
stub_prometheus_queries
+ stub_database_flavor_check
end
describe 'dump_sql_in_yaml' do
diff --git a/spec/tooling/danger/datateam_spec.rb b/spec/tooling/danger/datateam_spec.rb
new file mode 100644
index 00000000000..3bcef3ac886
--- /dev/null
+++ b/spec/tooling/danger/datateam_spec.rb
@@ -0,0 +1,113 @@
+# frozen_string_literal: true
+
+require 'rspec-parameterized'
+require 'gitlab-dangerfiles'
+require 'gitlab/dangerfiles/spec_helper'
+require 'pry'
+require_relative '../../../tooling/danger/datateam'
+
+RSpec.describe Tooling::Danger::Datateam do
+ include_context "with dangerfile"
+
+ let(:fake_danger) { DangerSpecHelper.fake_danger.include(described_class) }
+ let(:datateam) { fake_danger.new(helper: fake_helper) }
+
+ describe 'data team danger' do
+ using RSpec::Parameterized::TableSyntax
+
+ where do
+ {
+ 'with structure.sql changes and no Data Warehouse::Impact Check label' => {
+ modified_files: %w(db/structure.sql app/models/user.rb),
+ changed_lines: ['+group_id bigint NOT NULL'],
+ mr_labels: [],
+ impacted: true,
+ impacted_files: %w(db/structure.sql)
+ },
+ 'with structure.sql changes and Data Warehouse::Impact Check label' => {
+ modified_files: %w(db/structure.sql),
+ changed_lines: ['+group_id bigint NOT NULL)'],
+ mr_labels: ['Data Warehouse::Impact Check'],
+ impacted: false,
+ impacted_files: %w(db/structure.sql)
+ },
+ 'with user model changes' => {
+ modified_files: %w(app/models/users.rb),
+ changed_lines: ['+has_one :namespace'],
+ mr_labels: [],
+ impacted: false,
+ impacted_files: []
+ },
+ 'with perfomance indicator changes and no Data Warehouse::Impact Check label' => {
+ modified_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml app/models/user.rb),
+ changed_lines: ['+-gmau'],
+ mr_labels: [],
+ impacted: true,
+ impacted_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml)
+ },
+ 'with perfomance indicator changes and Data Warehouse::Impact Check label' => {
+ modified_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml),
+ changed_lines: ['+-gmau'],
+ mr_labels: ['Data Warehouse::Impact Check'],
+ impacted: false,
+ impacted_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml)
+ },
+ 'with metric file changes and no performance indicator changes' => {
+ modified_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml),
+ changed_lines: ['-product_stage: growth'],
+ mr_labels: [],
+ impacted: false,
+ impacted_files: []
+ },
+ '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'],
+ 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'],
+ 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'],
+ 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'],
+ impacted: false,
+ impacted_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml)
+ }
+ }
+ end
+
+ with_them do
+ before do
+ allow(fake_helper).to receive(:modified_files).and_return(modified_files)
+ allow(fake_helper).to receive(:changed_lines).and_return(changed_lines)
+ allow(fake_helper).to receive(:mr_labels).and_return(mr_labels)
+ allow(fake_helper).to receive(:markdown_list).with(impacted_files).and_return(impacted_files.map { |item| "* `#{item}`" }.join("\n"))
+ end
+
+ it :aggregate_failures do
+ expect(datateam.impacted?).to be(impacted)
+ expect(datateam.build_message).to match_expected_message
+ end
+ end
+ end
+
+ def match_expected_message
+ return be_nil unless impacted
+
+ start_with(described_class::CHANGED_SCHEMA_MESSAGE).and(include(*impacted_files))
+ end
+end
diff --git a/spec/tooling/danger/project_helper_spec.rb b/spec/tooling/danger/project_helper_spec.rb
index f13083bdf0a..52aa90beb2b 100644
--- a/spec/tooling/danger/project_helper_spec.rb
+++ b/spec/tooling/danger/project_helper_spec.rb
@@ -269,7 +269,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')
+ 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')
end
end
diff --git a/spec/tooling/docs/deprecation_handling_spec.rb b/spec/tooling/docs/deprecation_handling_spec.rb
new file mode 100644
index 00000000000..e389fe882b2
--- /dev/null
+++ b/spec/tooling/docs/deprecation_handling_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require_relative '../../fast_spec_helper'
+require_relative '../../../tooling/docs/deprecation_handling'
+require_relative '../../support/helpers/next_instance_of'
+
+RSpec.describe Docs::DeprecationHandling do
+ include ::NextInstanceOf
+
+ let(:type) { 'deprecation' }
+
+ subject { described_class.new(type).render }
+
+ before do
+ allow(Rake::FileList).to receive(:new).and_return(
+ ['14-10-c.yml', '14-2-b.yml', '14-2-a.yml']
+ )
+ # Create dummy YAML data based on file name
+ allow(YAML).to receive(:load_file) do |file_name|
+ {
+ 'name' => file_name[/[a-z]*\.yml/],
+ 'announcement_milestone' => file_name[/\d+-\d+/].tr('-', '.')
+ }
+ end
+ end
+
+ it 'sorts entries and milestones' do
+ allow_next_instance_of(ERB) do |template|
+ expect(template).to receive(:result_with_hash) do |arguments|
+ milestones = arguments[:milestones]
+ entries = arguments[:entries]
+
+ expect(milestones).to eq(['14.2', '14.10'])
+ expect(entries.map { |e| e['name'] }).to eq(['a.yml', 'b.yml', 'c.yml'])
+ end
+ end
+
+ subject
+ end
+end
diff --git a/spec/uploaders/ci/secure_file_uploader_spec.rb b/spec/uploaders/ci/secure_file_uploader_spec.rb
new file mode 100644
index 00000000000..3be4f742a24
--- /dev/null
+++ b/spec/uploaders/ci/secure_file_uploader_spec.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::SecureFileUploader do
+ subject { ci_secure_file.file }
+
+ let(:project) { create(:project) }
+ let(:ci_secure_file) { create(:ci_secure_file) }
+ let(:sample_file) { fixture_file('ci_secure_files/upload-keystore.jks') }
+
+ before do
+ stub_ci_secure_file_object_storage
+ end
+
+ describe '#key' do
+ it 'creates a digest with a secret key and the project id' do
+ expect(OpenSSL::HMAC)
+ .to receive(:digest)
+ .with('SHA256', Gitlab::Application.secrets.db_key_base, ci_secure_file.project_id.to_s)
+ .and_return('digest')
+
+ expect(subject.key).to eq('digest')
+ end
+ end
+
+ describe '.checksum' do
+ it 'returns a SHA256 checksum for the unencrypted file' do
+ expect(subject.checksum).to eq(Digest::SHA256.hexdigest(sample_file))
+ end
+ end
+
+ describe 'encryption' do
+ it 'encrypts the stored file' do
+ expect(Base64.encode64(subject.file.read)).not_to eq(Base64.encode64(sample_file))
+ end
+
+ it 'decrypts the file when reading' do
+ expect(Base64.encode64(subject.read)).to eq(Base64.encode64(sample_file))
+ end
+ end
+
+ describe '.direct_upload_enabled?' do
+ it 'returns false' do
+ expect(described_class.direct_upload_enabled?).to eq(false)
+ end
+ end
+
+ describe '.background_upload_enabled?' do
+ it 'returns false' do
+ expect(described_class.background_upload_enabled?).to eq(false)
+ end
+ end
+
+ describe '.default_store' do
+ context 'when object storage is enabled' do
+ it 'returns REMOTE' do
+ expect(described_class.default_store).to eq(ObjectStorage::Store::REMOTE)
+ end
+ end
+
+ context 'when object storage is disabled' do
+ before do
+ stub_ci_secure_file_object_storage(enabled: false)
+ end
+
+ it 'returns LOCAL' do
+ expect(described_class.default_store).to eq(ObjectStorage::Store::LOCAL)
+ end
+ end
+ end
+end
diff --git a/spec/views/admin/dashboard/index.html.haml_spec.rb b/spec/views/admin/dashboard/index.html.haml_spec.rb
index 9fa95613d1c..9db2bd3741a 100644
--- a/spec/views/admin/dashboard/index.html.haml_spec.rb
+++ b/spec/views/admin/dashboard/index.html.haml_spec.rb
@@ -53,11 +53,14 @@ RSpec.describe 'admin/dashboard/index.html.haml' do
expect(rendered).not_to have_content "Users over License"
end
- it 'links to the GitLab Changelog' do
- stub_application_setting(version_check_enabled: true)
-
- render
+ describe 'when show_version_check? is true' do
+ before do
+ allow(view).to receive(:show_version_check?).and_return(true)
+ render
+ end
- expect(rendered).to have_link(href: 'https://gitlab.com/gitlab-org/gitlab/-/blob/master/CHANGELOG.md')
+ it 'renders the version check badge' do
+ expect(rendered).to have_selector('.js-gitlab-version-check')
+ end
end
end
diff --git a/spec/views/groups/edit.html.haml_spec.rb b/spec/views/groups/edit.html.haml_spec.rb
index 43e11d31611..eaa909a5da0 100644
--- a/spec/views/groups/edit.html.haml_spec.rb
+++ b/spec/views/groups/edit.html.haml_spec.rb
@@ -115,4 +115,52 @@ RSpec.describe 'groups/edit.html.haml' do
end
end
end
+
+ context 'ip_restriction' do
+ let(:group) { create(:group) }
+ let(:user) { create(:user) }
+
+ before do
+ group.add_owner(user)
+
+ assign(:group, group)
+ allow(view).to receive(:current_user) { user }
+ end
+
+ context 'prompt user about registration features' do
+ before do
+ if Gitlab.ee?
+ allow(License).to receive(:current).and_return(nil)
+ end
+ end
+
+ context 'with service ping disabled' do
+ before do
+ stub_application_setting(usage_ping_enabled: false)
+ end
+
+ it 'renders a placeholder input with registration features message' do
+ render
+
+ expect(rendered).to have_field(:group_disabled_ip_restriction_ranges, disabled: true)
+ expect(rendered).to have_content(s_("RegistrationFeatures|Want to %{feature_title} for free?") % { feature_title: s_('RegistrationFeatures|use this feature') })
+ expect(rendered).to have_link(s_('RegistrationFeatures|Registration Features Program'))
+ end
+ end
+
+ context 'with service ping enabled' do
+ before do
+ stub_application_setting(usage_ping_enabled: true)
+ end
+
+ it 'does not render a placeholder input with registration features message' do
+ render
+
+ expect(rendered).not_to have_field(:group_disabled_ip_restriction_ranges, disabled: true)
+ expect(rendered).not_to have_content(s_("RegistrationFeatures|Want to %{feature_title} for free?") % { feature_title: s_('RegistrationFeatures|use this feature') })
+ expect(rendered).not_to have_link(s_('RegistrationFeatures|Registration Features Program'))
+ end
+ end
+ end
+ end
end
diff --git a/spec/views/help/index.html.haml_spec.rb b/spec/views/help/index.html.haml_spec.rb
index 600e431b7ef..1d26afcc567 100644
--- a/spec/views/help/index.html.haml_spec.rb
+++ b/spec/views/help/index.html.haml_spec.rb
@@ -76,7 +76,6 @@ RSpec.describe 'help/index' do
def stub_helpers
allow(view).to receive(:markdown).and_return('')
- allow(view).to receive(:version_status_badge).and_return('')
allow(view).to receive(:current_application_settings).and_return(Gitlab::CurrentSettings.current_application_settings)
end
end
diff --git a/spec/views/layouts/header/_gitlab_version.html.haml_spec.rb b/spec/views/layouts/header/_gitlab_version.html.haml_spec.rb
new file mode 100644
index 00000000000..0e24810f835
--- /dev/null
+++ b/spec/views/layouts/header/_gitlab_version.html.haml_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'layouts/header/_gitlab_version' do
+ describe 'when show_version_check? is true' do
+ before do
+ allow(view).to receive(:show_version_check?).and_return(true)
+ render
+ end
+
+ it 'renders the version check badge' do
+ expect(rendered).to have_selector('.js-gitlab-version-check')
+ end
+ end
+end
diff --git a/spec/views/profiles/keys/_form.html.haml_spec.rb b/spec/views/profiles/keys/_form.html.haml_spec.rb
index d5a605958dc..624d7492aea 100644
--- a/spec/views/profiles/keys/_form.html.haml_spec.rb
+++ b/spec/views/profiles/keys/_form.html.haml_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'profiles/keys/_form.html.haml' do
+ include SshKeysHelper
+
let_it_be(:key) { Key.new }
let(:page) { Capybara::Node::Simple.new(rendered) }
@@ -23,8 +25,8 @@ RSpec.describe 'profiles/keys/_form.html.haml' do
end
it 'has the key field', :aggregate_failures do
- expect(rendered).to have_field('Key', type: 'textarea', placeholder: 'Typically starts with "ssh-ed25519 …" or "ssh-rsa …"')
- expect(rendered).to have_text("Paste your public SSH key, which is usually contained in the file '~/.ssh/id_ed25519.pub' or '~/.ssh/id_rsa.pub' and begins with 'ssh-ed25519' or 'ssh-rsa'. Do not paste your private SSH key, as that can compromise your identity.")
+ expect(rendered).to have_field('Key', type: 'textarea')
+ expect(rendered).to have_text(s_('Profiles|Begins with %{ssh_key_algorithms}.') % { ssh_key_algorithms: ssh_key_allowed_algorithms })
end
it 'has the title field', :aggregate_failures do
diff --git a/spec/views/projects/commits/_commit.html.haml_spec.rb b/spec/views/projects/commits/_commit.html.haml_spec.rb
index ed93240abc1..5c66fbe7dd7 100644
--- a/spec/views/projects/commits/_commit.html.haml_spec.rb
+++ b/spec/views/projects/commits/_commit.html.haml_spec.rb
@@ -19,7 +19,7 @@ RSpec.describe 'projects/commits/_commit.html.haml' do
allow(commit).to receive(:different_committer?).and_return(true)
allow(commit).to receive(:committer).and_return(committer)
- render partial: template, locals: {
+ render partial: template, formats: :html, locals: {
project: project,
ref: ref,
commit: commit
diff --git a/spec/views/projects/edit.html.haml_spec.rb b/spec/views/projects/edit.html.haml_spec.rb
index 8c96f286c79..11f542767f4 100644
--- a/spec/views/projects/edit.html.haml_spec.rb
+++ b/spec/views/projects/edit.html.haml_spec.rb
@@ -29,19 +29,6 @@ RSpec.describe 'projects/edit' do
end
context 'merge suggestions settings' do
- it 'displays all possible variables' do
- render
-
- expect(rendered).to have_content('%{branch_name}')
- expect(rendered).to have_content('%{files_count}')
- expect(rendered).to have_content('%{file_paths}')
- expect(rendered).to have_content('%{project_name}')
- expect(rendered).to have_content('%{project_path}')
- expect(rendered).to have_content('%{user_full_name}')
- expect(rendered).to have_content('%{username}')
- expect(rendered).to have_content('%{suggestions_count}')
- end
-
it 'displays a placeholder if none is set' do
render
@@ -58,17 +45,6 @@ RSpec.describe 'projects/edit' do
end
context 'merge commit template' do
- it 'displays all possible variables' do
- render
-
- expect(rendered).to have_content('%{source_branch}')
- expect(rendered).to have_content('%{target_branch}')
- expect(rendered).to have_content('%{title}')
- expect(rendered).to have_content('%{issues}')
- expect(rendered).to have_content('%{description}')
- expect(rendered).to have_content('%{reference}')
- end
-
it 'displays a placeholder if none is set' do
render
diff --git a/spec/views/projects/merge_requests/show.html.haml_spec.rb b/spec/views/projects/merge_requests/show.html.haml_spec.rb
index 6b6bc1f0b14..6ffd0936003 100644
--- a/spec/views/projects/merge_requests/show.html.haml_spec.rb
+++ b/spec/views/projects/merge_requests/show.html.haml_spec.rb
@@ -45,32 +45,4 @@ RSpec.describe 'projects/merge_requests/show.html.haml', :aggregate_failures do
end
end
end
-
- describe 'gitpod modal' do
- let(:gitpod_modal_selector) { '#modal-enable-gitpod' }
- let(:user) { create(:user) }
- let(:user_gitpod_enabled) { create(:user).tap { |x| x.update!(gitpod_enabled: true) } }
-
- where(:site_enabled, :current_user, :should_show) do
- false | ref(:user) | false
- true | ref(:user) | true
- true | nil | true
- true | ref(:user_gitpod_enabled) | false
- end
-
- with_them do
- it 'handles rendering gitpod user enable modal' do
- allow(Gitlab::CurrentSettings).to receive(:gitpod_enabled).and_return(site_enabled)
- allow(view).to receive(:current_user).and_return(current_user)
-
- render
-
- if should_show
- expect(rendered).to have_css(gitpod_modal_selector)
- else
- expect(rendered).to have_no_css(gitpod_modal_selector)
- end
- end
- end
- end
end
diff --git a/spec/views/projects/services/_form.haml_spec.rb b/spec/views/projects/services/_form.haml_spec.rb
index 177f703ba6c..f212fd78b1a 100644
--- a/spec/views/projects/services/_form.haml_spec.rb
+++ b/spec/views/projects/services/_form.haml_spec.rb
@@ -20,13 +20,33 @@ RSpec.describe 'projects/services/_form' do
)
end
- context 'commit_events and merge_request_events' do
- it 'display merge_request_events and commit_events descriptions' do
- allow(Integrations::Redmine).to receive(:supported_events).and_return(%w(commit merge_request))
-
+ context 'integrations form' do
+ it 'does not render form element' do
render
- expect(rendered).to have_css("input[name='redirect_to'][value='/services']", count: 1, visible: false)
+ expect(rendered).not_to have_selector('[data-testid="integration-form"]')
+ end
+
+ context 'when vue_integration_form feature flag is disabled' do
+ before do
+ stub_feature_flags(vue_integration_form: false)
+ end
+
+ it 'renders form element' do
+ render
+
+ expect(rendered).to have_selector('[data-testid="integration-form"]')
+ end
+
+ context 'commit_events and merge_request_events' do
+ it 'display merge_request_events and commit_events descriptions' do
+ allow(Integrations::Redmine).to receive(:supported_events).and_return(%w(commit merge_request))
+
+ render
+
+ expect(rendered).to have_css("input[name='redirect_to'][value='/services']", count: 1, visible: false)
+ end
+ end
end
end
end
diff --git a/spec/views/shared/access_tokens/_table.html.haml_spec.rb b/spec/views/shared/access_tokens/_table.html.haml_spec.rb
index 0a23768b4f1..fca2fc3183c 100644
--- a/spec/views/shared/access_tokens/_table.html.haml_spec.rb
+++ b/spec/views/shared/access_tokens/_table.html.haml_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe 'shared/access_tokens/_table.html.haml' do
let_it_be(:user) { create(:user) }
let_it_be(:tokens) { [create(:personal_access_token, user: user)] }
- let_it_be(:project) { false }
+ let_it_be(:resource) { false }
before do
stub_licensed_features(enforce_personal_access_token_expiration: true)
@@ -20,8 +20,8 @@ RSpec.describe 'shared/access_tokens/_table.html.haml' do
allow(view).to receive(:personal_access_token_expiration_enforced?).and_return(token_expiry_enforced?)
allow(view).to receive(:show_profile_token_expiry_notification?).and_return(true)
- if project
- project.add_maintainer(user)
+ if resource
+ resource.add_maintainer(user)
end
# Forcibly removing scopes from one token as it's not possible to do with the current modal on creation
@@ -34,7 +34,7 @@ RSpec.describe 'shared/access_tokens/_table.html.haml' do
type: type,
type_plural: type_plural,
active_tokens: tokens,
- project: project,
+ resource: resource,
impersonation: impersonation,
revoke_route_helper: ->(token) { 'path/' }
}
@@ -80,8 +80,8 @@ RSpec.describe 'shared/access_tokens/_table.html.haml' do
end
end
- context 'if project' do
- let_it_be(:project) { create(:project) }
+ context 'if resource is project' do
+ let_it_be(:resource) { create(:project) }
it 'shows the project content', :aggregate_failures do
expect(rendered).to have_selector 'th', text: 'Role'
@@ -92,6 +92,18 @@ RSpec.describe 'shared/access_tokens/_table.html.haml' do
end
end
+ context 'if resource is group' do
+ let_it_be(:resource) { create(:group) }
+
+ it 'shows the group content', :aggregate_failures do
+ expect(rendered).to have_selector 'th', text: 'Role'
+ expect(rendered).to have_selector 'td', text: 'Maintainer'
+
+ expect(rendered).not_to have_content 'Personal access tokens are not revoked upon expiration.'
+ expect(rendered).not_to have_content 'To see all the user\'s personal access tokens you must impersonate them first.'
+ end
+ end
+
context 'without tokens' do
let_it_be(:tokens) { [] }
diff --git a/spec/views/shared/nav/_sidebar.html.haml_spec.rb b/spec/views/shared/nav/_sidebar.html.haml_spec.rb
index 2eeebdff7a8..0eb945f5624 100644
--- a/spec/views/shared/nav/_sidebar.html.haml_spec.rb
+++ b/spec/views/shared/nav/_sidebar.html.haml_spec.rb
@@ -3,7 +3,8 @@
require 'spec_helper'
RSpec.describe 'shared/nav/_sidebar.html.haml' do
- let(:project) { build(:project, id: non_existing_record_id) }
+ let_it_be(:project) { create(:project) }
+
let(:context) { Sidebars::Projects::Context.new(current_user: nil, container: project) }
let(:sidebar) { Sidebars::Projects::Panel.new(context) }
diff --git a/spec/views/shared/wikis/_sidebar.html.haml_spec.rb b/spec/views/shared/wikis/_sidebar.html.haml_spec.rb
index 70991369506..bf050d601e3 100644
--- a/spec/views/shared/wikis/_sidebar.html.haml_spec.rb
+++ b/spec/views/shared/wikis/_sidebar.html.haml_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
RSpec.describe 'shared/wikis/_sidebar.html.haml' do
let_it_be(:project) { create(:project) }
- let_it_be(:wiki) { Wiki.for_container(project, project.default_owner) }
+ let_it_be(:wiki) { Wiki.for_container(project, project.first_owner) }
before do
assign(:wiki, wiki)
diff --git a/spec/workers/ci/build_finished_worker_spec.rb b/spec/workers/ci/build_finished_worker_spec.rb
index 9096b0d2ba9..839723ac2fc 100644
--- a/spec/workers/ci/build_finished_worker_spec.rb
+++ b/spec/workers/ci/build_finished_worker_spec.rb
@@ -50,6 +50,21 @@ RSpec.describe Ci::BuildFinishedWorker do
subject
end
+
+ context 'when a build can be auto-retried' do
+ before do
+ allow(build)
+ .to receive(:auto_retry_allowed?)
+ .and_return(true)
+ end
+
+ it 'does not add a todo' do
+ expect(::Ci::MergeRequests::AddTodoWhenBuildFailsWorker)
+ .not_to receive(:perform_async)
+
+ subject
+ end
+ end
end
context 'when build has a chat' do
diff --git a/spec/workers/ci/job_artifacts/expire_project_build_artifacts_worker_spec.rb b/spec/workers/ci/job_artifacts/expire_project_build_artifacts_worker_spec.rb
new file mode 100644
index 00000000000..0460738f3f2
--- /dev/null
+++ b/spec/workers/ci/job_artifacts/expire_project_build_artifacts_worker_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::JobArtifacts::ExpireProjectBuildArtifactsWorker do
+ let(:worker) { described_class.new }
+ let(:current_time) { Time.current }
+
+ let_it_be(:project) { create(:project) }
+
+ around do |example|
+ freeze_time { example.run }
+ end
+
+ describe '#perform' do
+ it 'executes ExpireProjectArtifactsService service with the project' do
+ expect_next_instance_of(Ci::JobArtifacts::ExpireProjectBuildArtifactsService, project.id, current_time) do |instance|
+ expect(instance).to receive(:execute).and_call_original
+ end
+
+ worker.perform(project.id)
+ end
+
+ context 'when project does not exist' do
+ it 'does nothing' do
+ expect(Ci::JobArtifacts::ExpireProjectBuildArtifactsService).not_to receive(:new)
+
+ worker.perform(non_existing_record_id)
+ end
+ end
+ end
+end
diff --git a/spec/workers/clusters/agents/delete_expired_events_worker_spec.rb b/spec/workers/clusters/agents/delete_expired_events_worker_spec.rb
new file mode 100644
index 00000000000..1a5ca744091
--- /dev/null
+++ b/spec/workers/clusters/agents/delete_expired_events_worker_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Clusters::Agents::DeleteExpiredEventsWorker do
+ let(:agent) { create(:cluster_agent) }
+
+ describe '#perform' do
+ let(:agent_id) { agent.id }
+ let(:deletion_service) { double(execute: true) }
+
+ subject { described_class.new.perform(agent_id) }
+
+ it 'calls the deletion service' do
+ expect(deletion_service).to receive(:execute).once
+ expect(Clusters::Agents::DeleteExpiredEventsService).to receive(:new)
+ .with(agent).and_return(deletion_service)
+
+ subject
+ end
+
+ context 'agent no longer exists' do
+ let(:agent_id) { -1 }
+
+ it 'completes without raising an error' do
+ expect { subject }.not_to raise_error
+ end
+ end
+ end
+end
diff --git a/spec/workers/concerns/application_worker_spec.rb b/spec/workers/concerns/application_worker_spec.rb
index 7608b5f49a1..85731de2a45 100644
--- a/spec/workers/concerns/application_worker_spec.rb
+++ b/spec/workers/concerns/application_worker_spec.rb
@@ -287,12 +287,6 @@ RSpec.describe ApplicationWorker do
end
context 'different kinds of push_bulk' do
- shared_context 'disable the `sidekiq_push_bulk_in_batches` feature flag' do
- before do
- stub_feature_flags(sidekiq_push_bulk_in_batches: false)
- end
- end
-
shared_context 'set safe limit beyond the number of jobs to be enqueued' do
before do
stub_const("#{described_class}::SAFE_PUSH_BULK_LIMIT", args.count + 1)
@@ -408,27 +402,6 @@ RSpec.describe ApplicationWorker do
it_behaves_like 'returns job_id of all enqueued jobs'
it_behaves_like 'does not schedule the jobs for any specific time'
end
-
- context 'when the feature flag `sidekiq_push_bulk_in_batches` is disabled' do
- include_context 'disable the `sidekiq_push_bulk_in_batches` feature flag'
-
- context 'when the number of jobs to be enqueued does not exceed the safe limit' do
- include_context 'set safe limit beyond the number of jobs to be enqueued'
-
- it_behaves_like 'enqueues jobs in one go'
- it_behaves_like 'logs bulk insertions'
- it_behaves_like 'returns job_id of all enqueued jobs'
- it_behaves_like 'does not schedule the jobs for any specific time'
- end
-
- context 'when the number of jobs to be enqueued exceeds safe limit' do
- include_context 'set safe limit below the number of jobs to be enqueued'
-
- it_behaves_like 'enqueues jobs in one go'
- it_behaves_like 'returns job_id of all enqueued jobs'
- it_behaves_like 'does not schedule the jobs for any specific time'
- end
- end
end
end
@@ -476,26 +449,6 @@ RSpec.describe ApplicationWorker do
it_behaves_like 'returns job_id of all enqueued jobs'
it_behaves_like 'schedules all the jobs at a specific time'
end
-
- context 'when the feature flag `sidekiq_push_bulk_in_batches` is disabled' do
- include_context 'disable the `sidekiq_push_bulk_in_batches` feature flag'
-
- context 'when the number of jobs to be enqueued does not exceed the safe limit' do
- include_context 'set safe limit beyond the number of jobs to be enqueued'
-
- it_behaves_like 'enqueues jobs in one go'
- it_behaves_like 'returns job_id of all enqueued jobs'
- it_behaves_like 'schedules all the jobs at a specific time'
- end
-
- context 'when the number of jobs to be enqueued exceeds safe limit' do
- include_context 'set safe limit below the number of jobs to be enqueued'
-
- it_behaves_like 'enqueues jobs in one go'
- it_behaves_like 'returns job_id of all enqueued jobs'
- it_behaves_like 'schedules all the jobs at a specific time'
- end
- end
end
end
@@ -575,26 +528,6 @@ RSpec.describe ApplicationWorker do
it_behaves_like 'returns job_id of all enqueued jobs'
it_behaves_like 'schedules all the jobs at a specific time, per batch'
end
-
- context 'when the feature flag `sidekiq_push_bulk_in_batches` is disabled' do
- include_context 'disable the `sidekiq_push_bulk_in_batches` feature flag'
-
- context 'when the number of jobs to be enqueued does not exceed the safe limit' do
- include_context 'set safe limit beyond the number of jobs to be enqueued'
-
- it_behaves_like 'enqueues jobs in one go'
- it_behaves_like 'returns job_id of all enqueued jobs'
- it_behaves_like 'schedules all the jobs at a specific time, per batch'
- end
-
- context 'when the number of jobs to be enqueued exceeds safe limit' do
- include_context 'set safe limit below the number of jobs to be enqueued'
-
- it_behaves_like 'enqueues jobs in one go'
- it_behaves_like 'returns job_id of all enqueued jobs'
- it_behaves_like 'schedules all the jobs at a specific time, per batch'
- end
- end
end
end
end
diff --git a/spec/workers/concerns/cluster_agent_queue_spec.rb b/spec/workers/concerns/cluster_agent_queue_spec.rb
new file mode 100644
index 00000000000..b5189cbd8c8
--- /dev/null
+++ b/spec/workers/concerns/cluster_agent_queue_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ClusterAgentQueue do
+ let(:worker) do
+ Class.new do
+ def self.name
+ 'ExampleWorker'
+ end
+
+ include ApplicationWorker
+ include ClusterAgentQueue
+ end
+ end
+
+ it { expect(worker.queue).to eq('cluster_agent:example') }
+ it { expect(worker.get_feature_category).to eq(:kubernetes_management) }
+end
diff --git a/spec/workers/concerns/packages/cleanup_artifact_worker_spec.rb b/spec/workers/concerns/packages/cleanup_artifact_worker_spec.rb
new file mode 100644
index 00000000000..95962d4810e
--- /dev/null
+++ b/spec/workers/concerns/packages/cleanup_artifact_worker_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Packages::CleanupArtifactWorker do
+ let_it_be(:worker_class) do
+ Class.new do
+ def self.name
+ 'Gitlab::Foo::Bar::DummyWorker'
+ end
+
+ include ApplicationWorker
+ include ::Packages::CleanupArtifactWorker
+ end
+ end
+
+ let(:worker) { worker_class.new }
+
+ describe '#model' do
+ subject { worker.send(:model) }
+
+ it { expect { subject }.to raise_error(NotImplementedError) }
+ end
+
+ describe '#log_metadata' do
+ subject { worker.send(:log_metadata) }
+
+ it { expect { subject }.to raise_error(NotImplementedError) }
+ end
+
+ describe '#log_cleanup_item' do
+ subject { worker.send(:log_cleanup_item) }
+
+ it { expect { subject }.to raise_error(NotImplementedError) }
+ end
+end
diff --git a/spec/workers/dependency_proxy/cleanup_dependency_proxy_worker_spec.rb b/spec/workers/dependency_proxy/cleanup_dependency_proxy_worker_spec.rb
index ed0bdefbdb8..1100f9a7fae 100644
--- a/spec/workers/dependency_proxy/cleanup_dependency_proxy_worker_spec.rb
+++ b/spec/workers/dependency_proxy/cleanup_dependency_proxy_worker_spec.rb
@@ -9,8 +9,8 @@ RSpec.describe DependencyProxy::CleanupDependencyProxyWorker do
context 'when there are records to be deleted' do
it_behaves_like 'an idempotent worker' do
it 'queues the cleanup jobs', :aggregate_failures do
- create(:dependency_proxy_blob, :expired)
- create(:dependency_proxy_manifest, :expired)
+ create(:dependency_proxy_blob, :pending_destruction)
+ create(:dependency_proxy_manifest, :pending_destruction)
expect(DependencyProxy::CleanupBlobWorker).to receive(:perform_with_capacity).twice
expect(DependencyProxy::CleanupManifestWorker).to receive(:perform_with_capacity).twice
diff --git a/spec/workers/dependency_proxy/image_ttl_group_policy_worker_spec.rb b/spec/workers/dependency_proxy/image_ttl_group_policy_worker_spec.rb
index b035a2ec0b7..6a2fdfbe8f5 100644
--- a/spec/workers/dependency_proxy/image_ttl_group_policy_worker_spec.rb
+++ b/spec/workers/dependency_proxy/image_ttl_group_policy_worker_spec.rb
@@ -17,19 +17,19 @@ RSpec.describe DependencyProxy::ImageTtlGroupPolicyWorker do
let_it_be_with_reload(:new_blob) { create(:dependency_proxy_blob, group: group) }
let_it_be_with_reload(:new_manifest) { create(:dependency_proxy_manifest, group: group) }
- it 'updates the old images to expired' do
+ it 'updates the old images to pending_destruction' do
expect { subject }
- .to change { old_blob.reload.status }.from('default').to('expired')
- .and change { old_manifest.reload.status }.from('default').to('expired')
+ .to change { old_blob.reload.status }.from('default').to('pending_destruction')
+ .and change { old_manifest.reload.status }.from('default').to('pending_destruction')
.and not_change { new_blob.reload.status }
.and not_change { new_manifest.reload.status }
end
end
context 'counts logging' do
- let_it_be(:expired_blob) { create(:dependency_proxy_blob, :expired, group: group) }
- let_it_be(:expired_blob2) { create(:dependency_proxy_blob, :expired, group: group) }
- let_it_be(:expired_manifest) { create(:dependency_proxy_manifest, :expired, group: group) }
+ let_it_be(:expired_blob) { create(:dependency_proxy_blob, :pending_destruction, group: group) }
+ let_it_be(:expired_blob2) { create(:dependency_proxy_blob, :pending_destruction, group: group) }
+ let_it_be(:expired_manifest) { create(:dependency_proxy_manifest, :pending_destruction, group: group) }
let_it_be(:processing_blob) { create(:dependency_proxy_blob, status: :processing, group: group) }
let_it_be(:processing_manifest) { create(:dependency_proxy_manifest, status: :processing, group: group) }
let_it_be(:error_blob) { create(:dependency_proxy_blob, status: :error, group: group) }
diff --git a/spec/workers/deployments/hooks_worker_spec.rb b/spec/workers/deployments/hooks_worker_spec.rb
index b4a91cff2ac..50ead66cfbf 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(:service, type: 'SlackService', project: project, deployment_events: true, active: true)
+ service = create(:integration, type: 'SlackService', project: project, deployment_events: true, active: 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(:service, type: 'SlackService', project: project, deployment_events: true, active: false)
+ create(:integration, type: 'SlackService', project: project, deployment_events: true, active: false)
expect(ProjectServiceWorker).not_to receive(:perform_async)
diff --git a/spec/workers/email_receiver_worker_spec.rb b/spec/workers/email_receiver_worker_spec.rb
index 83720ee132b..dba535654a1 100644
--- a/spec/workers/email_receiver_worker_spec.rb
+++ b/spec/workers/email_receiver_worker_spec.rb
@@ -21,87 +21,45 @@ RSpec.describe EmailReceiverWorker, :mailer do
context "when an error occurs" do
before do
allow_any_instance_of(Gitlab::Email::Receiver).to receive(:execute).and_raise(error)
- expect(Sidekiq.logger).to receive(:error).with(hash_including('exception.class' => error.class.name)).and_call_original
end
- context 'when the error is Gitlab::Email::EmptyEmailError' do
+ context 'when error is a processing error' do
let(:error) { Gitlab::Email::EmptyEmailError.new }
- it 'sends out a rejection email' do
- perform_enqueued_jobs do
- described_class.new.perform(raw_message)
+ it 'triggers email failure handler' do
+ expect(Gitlab::Email::FailureHandler).to receive(:handle) do |receiver, received_error|
+ expect(receiver).to be_a(Gitlab::Email::Receiver)
+ expect(receiver.mail.encoded).to eql(Mail::Message.new(raw_message).encoded)
+ expect(received_error).to be(error)
end
- email = ActionMailer::Base.deliveries.last
- expect(email).not_to be_nil
- expect(email.to).to eq(["jake@adventuretime.ooo"])
- expect(email.subject).to include("Rejected")
- end
-
- it 'strips out the body before passing to EmailRejectionMailer' do
- mail = Mail.new(raw_message)
- mail.body = nil
-
- expect(EmailRejectionMailer).to receive(:rejection).with(anything, mail.encoded, anything).and_call_original
-
described_class.new.perform(raw_message)
end
- end
-
- context 'when the error is Gitlab::Email::AutoGeneratedEmailError' do
- let(:error) { Gitlab::Email::AutoGeneratedEmailError.new }
-
- it 'does not send out any rejection email' do
- perform_enqueued_jobs do
- described_class.new.perform(raw_message)
- end
-
- should_not_email_anyone
- end
- end
- context 'when the error is Gitlab::Email::InvalidAttachment' do
- let(:error) { Gitlab::Email::InvalidAttachment.new("Could not deal with that") }
+ it 'logs the error' do
+ expect(Sidekiq.logger).to receive(:error).with(hash_including('exception.class' => error.class.name)).and_call_original
- it 'reports the error to the sender' do
- perform_enqueued_jobs do
- described_class.new.perform(raw_message)
- end
-
- email = ActionMailer::Base.deliveries.last
- expect(email).not_to be_nil
- expect(email.to).to eq(["jake@adventuretime.ooo"])
- expect(email.body.parts.last.to_s).to include("Could not deal with that")
+ described_class.new.perform(raw_message)
end
end
- context 'when the error is ActiveRecord::StatementTimeout' do
+ context 'when error is not a processing error' do
let(:error) { ActiveRecord::StatementTimeout.new("Statement timeout") }
- it 'does not report the error to the sender' do
- expect(Gitlab::ErrorTracking).to receive(:track_exception).with(error).and_call_original
-
- perform_enqueued_jobs do
- described_class.new.perform(raw_message)
+ it 'triggers email failure handler' do
+ expect(Gitlab::Email::FailureHandler).to receive(:handle) do |receiver, received_error|
+ expect(receiver).to be_a(Gitlab::Email::Receiver)
+ expect(receiver.mail.encoded).to eql(Mail::Message.new(raw_message).encoded)
+ expect(received_error).to be(error)
end
- email = ActionMailer::Base.deliveries.last
- expect(email).to be_nil
+ described_class.new.perform(raw_message)
end
- end
-
- context 'when the error is RateLimitedService::RateLimitedError' do
- let(:error) { RateLimitedService::RateLimitedError.new(key: :issues_create, rate_limiter: Gitlab::ApplicationRateLimiter) }
- it 'does not report the error to the sender' do
+ it 'reports the error' do
expect(Gitlab::ErrorTracking).to receive(:track_exception).with(error).and_call_original
- perform_enqueued_jobs do
- described_class.new.perform(raw_message)
- end
-
- email = ActionMailer::Base.deliveries.last
- expect(email).to be_nil
+ described_class.new.perform(raw_message)
end
end
end
diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb
index 00b6d2635a5..bb4e2981070 100644
--- a/spec/workers/every_sidekiq_worker_spec.rb
+++ b/spec/workers/every_sidekiq_worker_spec.rb
@@ -361,6 +361,7 @@ RSpec.describe 'Every Sidekiq worker' do
'ObjectPool::ScheduleJoinWorker' => 3,
'ObjectStorage::BackgroundMoveWorker' => 5,
'ObjectStorage::MigrateUploadsWorker' => 3,
+ 'Packages::CleanupPackageFileWorker' => 0,
'Packages::Composer::CacheUpdateWorker' => false,
'Packages::Go::SyncPackagesWorker' => 3,
'Packages::Maven::Metadata::SyncWorker' => 3,
@@ -369,7 +370,7 @@ RSpec.describe 'Every Sidekiq worker' do
'PagesDomainSslRenewalWorker' => 3,
'PagesDomainVerificationWorker' => 3,
'PagesTransferWorker' => 3,
- 'PagesUpdateConfigurationWorker' => 3,
+ 'PagesUpdateConfigurationWorker' => 1,
'PagesWorker' => 3,
'PersonalAccessTokens::Groups::PolicyWorker' => 3,
'PersonalAccessTokens::Instance::PolicyWorker' => 3,
diff --git a/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb b/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb
index 3c628d036ff..497f95cf34d 100644
--- a/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb
+++ b/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe LooseForeignKeys::CleanupWorker do
include MigrationsHelpers
+ using RSpec::Parameterized::TableSyntax
def create_table_structure
migration = ActiveRecord::Migration.new.extend(Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers)
@@ -149,4 +150,31 @@ RSpec.describe LooseForeignKeys::CleanupWorker do
expect { described_class.new.perform }.not_to change { LooseForeignKeys::DeletedRecord.status_processed.count }
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
+ end
+
+ with_them do
+ before do
+ allow(Gitlab::Database).to receive(:database_base_models).and_return(configured_base_models)
+ end
+
+ it 'uses the correct connection' do
+ LooseForeignKeys::DeletedRecord.count.times do
+ expect_next_found_instance_of(LooseForeignKeys::DeletedRecord) do |instance|
+ expect(instance.class.connection).to eq(expected_connection)
+ end
+ end
+
+ travel_to DateTime.new(2019, 1, 1, 10, current_minute) do
+ described_class.new.perform
+ end
+ end
+ end
+ end
end
diff --git a/spec/workers/merge_requests/update_head_pipeline_worker_spec.rb b/spec/workers/merge_requests/update_head_pipeline_worker_spec.rb
new file mode 100644
index 00000000000..f3ea14ad539
--- /dev/null
+++ b/spec/workers/merge_requests/update_head_pipeline_worker_spec.rb
@@ -0,0 +1,138 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe MergeRequests::UpdateHeadPipelineWorker do
+ include ProjectForksHelper
+
+ let_it_be(:project) { create(:project, :repository) }
+
+ let(:ref) { 'master' }
+ let(:pipeline) { create(:ci_pipeline, project: project, ref: ref) }
+ let(:event) { Ci::PipelineCreatedEvent.new(data: { pipeline_id: pipeline.id }) }
+
+ subject { consume_event(event) }
+
+ def consume_event(event)
+ described_class.new.perform(event.class.name, event.data)
+ end
+
+ context 'when merge requests already exist for this source branch', :sidekiq_inline do
+ let(:merge_request_1) do
+ create(:merge_request, source_branch: 'feature', target_branch: "master", source_project: project)
+ end
+
+ let(:merge_request_2) do
+ create(:merge_request, source_branch: 'feature', target_branch: "v1.1.0", source_project: project)
+ end
+
+ context 'when related merge request is already merged' do
+ let!(:merged_merge_request) do
+ create(:merge_request, source_branch: 'master', target_branch: "branch_2", source_project: project, state: 'merged')
+ end
+
+ it 'does not schedule update head pipeline job' do
+ expect(UpdateHeadPipelineForMergeRequestWorker).not_to receive(:perform_async).with(merged_merge_request.id)
+
+ subject
+ end
+ end
+
+ context 'when the head pipeline sha equals merge request sha' do
+ let(:ref) { 'feature' }
+
+ before do
+ pipeline.update!(sha: project.repository.commit(ref).id)
+ end
+
+ it 'updates head pipeline of each merge request' do
+ merge_request_1
+ merge_request_2
+
+ subject
+
+ expect(merge_request_1.reload.head_pipeline).to eq(pipeline)
+ expect(merge_request_2.reload.head_pipeline).to eq(pipeline)
+ end
+ end
+
+ context 'when the head pipeline sha does not equal merge request sha' do
+ let(:ref) { 'feature' }
+
+ it 'does not update the head piepeline of MRs' do
+ merge_request_1
+ merge_request_2
+
+ subject
+
+ expect(merge_request_1.reload.head_pipeline).not_to eq(pipeline)
+ expect(merge_request_2.reload.head_pipeline).not_to eq(pipeline)
+ end
+ end
+
+ context 'when there is no pipeline for source branch' do
+ it "does not update merge request head pipeline" do
+ merge_request = create(:merge_request, source_branch: 'feature',
+ target_branch: "branch_1",
+ source_project: project)
+
+ subject
+
+ expect(merge_request.reload.head_pipeline).not_to eq(pipeline)
+ end
+ end
+
+ context 'when merge request target project is different from source project' do
+ let(:project) { fork_project(target_project, nil, repository: true) }
+ let(:target_project) { create(:project, :repository) }
+ let(:user) { create(:user) }
+ let(:ref) { 'feature' }
+
+ before do
+ project.add_developer(user)
+ pipeline.update!(sha: project.repository.commit(ref).id)
+ end
+
+ it 'updates head pipeline for merge request' do
+ merge_request = create(:merge_request, source_branch: 'feature',
+ target_branch: "master",
+ source_project: project,
+ target_project: target_project)
+
+ subject
+
+ expect(merge_request.reload.head_pipeline).to eq(pipeline)
+ end
+ end
+
+ context 'when the pipeline is not the latest for the branch' do
+ it 'does not update merge request head pipeline' do
+ merge_request = create(:merge_request, source_branch: 'master',
+ target_branch: "branch_1",
+ source_project: project)
+
+ create(:ci_pipeline, project: pipeline.project, ref: pipeline.ref)
+
+ subject
+
+ expect(merge_request.reload.head_pipeline).to be_nil
+ end
+ end
+
+ context 'when pipeline has errors' do
+ before do
+ pipeline.update!(yaml_errors: 'some errors', status: :failed)
+ end
+
+ it 'updates merge request head pipeline reference' do
+ merge_request = create(:merge_request, source_branch: 'master',
+ target_branch: 'feature',
+ source_project: project)
+
+ subject
+
+ expect(merge_request.reload.head_pipeline).to eq(pipeline)
+ end
+ end
+ end
+end
diff --git a/spec/workers/metrics/dashboard/sync_dashboards_worker_spec.rb b/spec/workers/metrics/dashboard/sync_dashboards_worker_spec.rb
index 19b79835825..f151780ffd7 100644
--- a/spec/workers/metrics/dashboard/sync_dashboards_worker_spec.rb
+++ b/spec/workers/metrics/dashboard/sync_dashboards_worker_spec.rb
@@ -10,16 +10,34 @@ RSpec.describe Metrics::Dashboard::SyncDashboardsWorker do
let(:dashboard_path) { '.gitlab/dashboards/test.yml' }
describe ".perform" do
- it 'imports metrics' do
- expect { worker.perform(project.id) }.to change(PrometheusMetric, :count).by(3)
+ context 'with valid dashboard hash' do
+ it 'imports metrics' do
+ expect { worker.perform(project.id) }.to change(PrometheusMetric, :count).by(3)
+ end
+
+ it 'is idempotent' do
+ 2.times do
+ worker.perform(project.id)
+ end
+
+ expect(PrometheusMetric.count).to eq(3)
+ end
end
- it 'is idempotent' do
- 2.times do
- worker.perform(project.id)
+ context 'with invalid dashboard hash' do
+ before do
+ allow_next_instance_of(Gitlab::Metrics::Dashboard::Importer) do |instance|
+ allow(instance).to receive(:dashboard_hash).and_return({})
+ end
end
- expect(PrometheusMetric.count).to eq(3)
+ it 'does not import metrics' do
+ expect { worker.perform(project.id) }.not_to change(PrometheusMetric, :count)
+ end
+
+ it 'does not raise an error' do
+ expect { worker.perform(project.id) }.not_to raise_error
+ end
end
end
end
diff --git a/spec/workers/packages/cleanup_package_file_worker_spec.rb b/spec/workers/packages/cleanup_package_file_worker_spec.rb
new file mode 100644
index 00000000000..b423c4d3f06
--- /dev/null
+++ b/spec/workers/packages/cleanup_package_file_worker_spec.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Packages::CleanupPackageFileWorker do
+ let_it_be(:package) { create(:package) }
+
+ let(:worker) { described_class.new }
+
+ describe '#perform_work' do
+ subject { worker.perform_work }
+
+ context 'with no work to do' do
+ it { is_expected.to be_nil }
+ end
+
+ context 'with work to do' do
+ let_it_be(:package_file1) { create(:package_file, package: package) }
+ let_it_be(:package_file2) { create(:package_file, :pending_destruction, package: package) }
+ let_it_be(:package_file3) { create(:package_file, :pending_destruction, package: package, updated_at: 1.year.ago, created_at: 1.year.ago) }
+
+ it 'deletes the oldest package file pending destruction based on id', :aggregate_failures do
+ expect(worker).to receive(:log_extra_metadata_on_done).twice
+
+ expect { subject }.to change { Packages::PackageFile.count }.by(-1)
+ end
+ end
+
+ context 'with an error during the destroy' do
+ let_it_be(:package_file) { create(:package_file, :pending_destruction) }
+
+ before do
+ expect(worker).to receive(:log_metadata).and_raise('Error!')
+ end
+
+ it 'handles the error' do
+ expect { subject }.to change { Packages::PackageFile.error.count }.from(0).to(1)
+ expect(package_file.reload).to be_error
+ end
+ end
+ end
+
+ describe '#max_running_jobs' do
+ let(:capacity) { 5 }
+
+ subject { worker.max_running_jobs }
+
+ before do
+ stub_application_setting(packages_cleanup_package_file_worker_capacity: capacity)
+ end
+
+ it { is_expected.to eq(capacity) }
+ end
+
+ describe '#remaining_work_count' do
+ before(:context) do
+ create_list(:package_file, 3, :pending_destruction, package: package)
+ end
+
+ subject { worker.remaining_work_count }
+
+ it { is_expected.to eq(3) }
+ end
+end
diff --git a/spec/workers/packages/cleanup_package_registry_worker_spec.rb b/spec/workers/packages/cleanup_package_registry_worker_spec.rb
new file mode 100644
index 00000000000..e43864975f6
--- /dev/null
+++ b/spec/workers/packages/cleanup_package_registry_worker_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Packages::CleanupPackageRegistryWorker do
+ describe '#perform' do
+ let_it_be_with_reload(:package_files) { create_list(:package_file, 2, :pending_destruction) }
+
+ let(:worker) { described_class.new }
+
+ subject(:perform) { worker.perform }
+
+ context 'with package files pending destruction' do
+ it_behaves_like 'an idempotent worker'
+
+ it 'queues the cleanup job' do
+ expect(Packages::CleanupPackageFileWorker).to receive(:perform_with_capacity)
+
+ perform
+ end
+ end
+
+ context 'with no package files pending destruction' do
+ before do
+ ::Packages::PackageFile.update_all(status: :default)
+ end
+
+ it_behaves_like 'an idempotent worker'
+
+ it 'does not queue the cleanup job' do
+ expect(Packages::CleanupPackageFileWorker).not_to receive(:perform_with_capacity)
+
+ perform
+ end
+ end
+
+ describe 'counts logging' do
+ let_it_be(:processing_package_file) { create(:package_file, status: :processing) }
+
+ it 'logs all the counts', :aggregate_failures do
+ expect(worker).to receive(:log_extra_metadata_on_done).with(:pending_destruction_package_files_count, 2)
+ expect(worker).to receive(:log_extra_metadata_on_done).with(:processing_package_files_count, 1)
+ expect(worker).to receive(:log_extra_metadata_on_done).with(:error_package_files_count, 0)
+
+ perform
+ end
+
+ context 'with load balancing enabled', :db_load_balancing do
+ it 'reads the count from the replica' do
+ expect(Gitlab::Database::LoadBalancing::Session.current).to receive(:use_replicas_for_read_queries).and_call_original
+
+ perform
+ end
+ end
+ end
+ end
+end
diff --git a/spec/workers/pages_update_configuration_worker_spec.rb b/spec/workers/pages_update_configuration_worker_spec.rb
index 7cceeaa52d6..af71f6b3cca 100644
--- a/spec/workers/pages_update_configuration_worker_spec.rb
+++ b/spec/workers/pages_update_configuration_worker_spec.rb
@@ -5,59 +5,8 @@ RSpec.describe PagesUpdateConfigurationWorker do
let_it_be(:project) { create(:project) }
describe "#perform" do
- it "does not break if the project doesn't exist" do
+ it "does not break" do
expect { subject.perform(-1) }.not_to raise_error
end
-
- it "calls the correct service" do
- expect_next_instance_of(Projects::UpdatePagesConfigurationService, project) do |service|
- expect(service).to receive(:execute).and_return({})
- end
-
- subject.perform(project.id)
- end
-
- it_behaves_like "an idempotent worker" do
- let(:job_args) { [project.id] }
- let(:pages_dir) { Dir.mktmpdir }
- let(:config_path) { File.join(pages_dir, "config.json") }
-
- before do
- allow(Project).to receive(:find_by_id).with(project.id).and_return(project)
- allow(project).to receive(:pages_path).and_return(pages_dir)
-
- # Make sure _some_ config exists
- FileUtils.touch(config_path)
- end
-
- after do
- FileUtils.remove_entry(pages_dir)
- end
-
- it "only updates the config file once" do
- described_class.new.perform(project.id)
-
- expect(File.mtime(config_path)).not_to be_nil
- expect { subject }.not_to change { File.mtime(config_path) }
- end
- end
- end
-
- describe '#perform_async' do
- it "calls the correct service", :sidekiq_inline do
- expect_next_instance_of(Projects::UpdatePagesConfigurationService, project) do |service|
- expect(service).to receive(:execute).and_return(status: :success)
- end
-
- described_class.perform_async(project.id)
- end
-
- it "doesn't schedule a worker if updates on legacy storage are disabled", :sidekiq_inline do
- allow(Settings.pages.local_store).to receive(:enabled).and_return(false)
-
- expect(Projects::UpdatePagesConfigurationService).not_to receive(:new)
-
- described_class.perform_async(project.id)
- end
end
end
diff --git a/spec/workers/pages_worker_spec.rb b/spec/workers/pages_worker_spec.rb
new file mode 100644
index 00000000000..5ddfd5b43b9
--- /dev/null
+++ b/spec/workers/pages_worker_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe PagesWorker, :sidekiq_inline do
+ let(:project) { create(:project) }
+ let(:ci_build) { create(:ci_build, project: project)}
+
+ it 'calls UpdatePagesService' do
+ expect_next_instance_of(Projects::UpdatePagesService, project, ci_build) do |service|
+ expect(service).to receive(:execute)
+ end
+
+ described_class.perform_async(:deploy, ci_build.id)
+ end
+end
diff --git a/spec/workers/purge_dependency_proxy_cache_worker_spec.rb b/spec/workers/purge_dependency_proxy_cache_worker_spec.rb
index b928104fb58..3de59670f8d 100644
--- a/spec/workers/purge_dependency_proxy_cache_worker_spec.rb
+++ b/spec/workers/purge_dependency_proxy_cache_worker_spec.rb
@@ -25,11 +25,11 @@ RSpec.describe PurgeDependencyProxyCacheWorker do
include_examples 'an idempotent worker' do
let(:job_args) { [user.id, group_id] }
- it 'expires the blobs and returns ok', :aggregate_failures do
+ it 'marks the blobs as pending_destruction and returns ok', :aggregate_failures do
subject
- expect(blob).to be_expired
- expect(manifest).to be_expired
+ expect(blob).to be_pending_destruction
+ expect(manifest).to be_pending_destruction
end
end
end
diff --git a/spec/workers/web_hook_worker_spec.rb b/spec/workers/web_hook_worker_spec.rb
index 0f40177eb7d..bbb8844a447 100644
--- a/spec/workers/web_hook_worker_spec.rb
+++ b/spec/workers/web_hook_worker_spec.rb
@@ -19,6 +19,15 @@ RSpec.describe WebHookWorker do
expect { subject.perform(non_existing_record_id, data, hook_name) }.not_to raise_error
end
+ it 'retrieves recursion detection data, reinstates it, and cleans it from payload', :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/tooling/bin/find_changes b/tooling/bin/find_changes
index c6b8bafbd85..8ad5011459b 100755
--- a/tooling/bin/find_changes
+++ b/tooling/bin/find_changes
@@ -48,7 +48,7 @@ class FindChanges # rubocop:disable Gitlab/NamespacedClass
mr_changes = Gitlab.merge_request_changes(mr_project_path, mr_iid)
- mr_changes.changes.map { |change| change['new_path'] }
+ mr_changes.changes.map { |change| change['new_path'] unless change['deleted_file'] }.compact
end
end
diff --git a/tooling/danger/datateam.rb b/tooling/danger/datateam.rb
new file mode 100644
index 00000000000..b3779aa13bb
--- /dev/null
+++ b/tooling/danger/datateam.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module Tooling
+ module Danger
+ module Datateam
+ CHANGED_SCHEMA_MESSAGE = <<~MSG
+ Notification to the Data Team about changes to files with possible impact on Data Warehouse, add label `Data Warehouse::Impact Check`.
+
+ /label ~"Data Warehouse::Impact Check"
+
+ The following files require a review:
+
+ MSG
+
+ DATA_WAREHOUSE_SCOPE = 'Data Warehouse::'
+ FILE_PATH_REGEX = %r{((ee|jh)/)?config/metrics(/.+\.yml)}.freeze
+ PERFORMANCE_INDICATOR_REGEX = %r{gmau|smau|paid_gmau|umau}.freeze
+ DATABASE_REGEX = %r{\Adb/structure\.sql}.freeze
+ STRUCTURE_SQL_FILE = %w(db/structure.sql).freeze
+
+ def build_message
+ return unless impacted?
+
+ CHANGED_SCHEMA_MESSAGE + helper.markdown_list(data_warehouse_impact_files)
+ end
+
+ def impacted?
+ !labelled_as_datawarehouse? && data_warehouse_impact_files.any?
+ end
+
+ private
+
+ def data_warehouse_impact_files
+ @impacted_files ||= (performance_indicator_changed_files + database_changed_files)
+ end
+
+ def labelled_as_datawarehouse?
+ helper.mr_labels.any? { |label| label.start_with?(DATA_WAREHOUSE_SCOPE) }
+ end
+
+ def performance_indicator_changed_files
+ metrics_definitions_files = helper.modified_files.grep(FILE_PATH_REGEX)
+
+ metrics_definitions_files.select do |file|
+ helper.changed_lines(file).any? { |change| change =~ PERFORMANCE_INDICATOR_REGEX }
+ end.compact
+ end
+
+ def database_changes?
+ !helper.modified_files.grep(DATABASE_REGEX).empty?
+ end
+
+ def database_changed_files
+ helper.modified_files & STRUCTURE_SQL_FILE
+ end
+ end
+ end
+end
diff --git a/tooling/danger/project_helper.rb b/tooling/danger/project_helper.rb
index b49df50c5f0..f49b8bf7f2a 100644
--- a/tooling/danger/project_helper.rb
+++ b/tooling/danger/project_helper.rb
@@ -17,6 +17,7 @@ module Tooling
product_intelligence
utility_css
vue_shared_documentation
+ datateam
].freeze
CI_ONLY_RULES ||= %w[
diff --git a/tooling/deprecations/docs.rb b/tooling/deprecations/docs.rb
deleted file mode 100644
index 0f649024b60..00000000000
--- a/tooling/deprecations/docs.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-# frozen_string_literal: true
-require 'erb'
-
-module Deprecations
- module Docs
- module_function
-
- def path
- Rails.root.join("doc/update/deprecations.md")
- end
-
- def render
- deprecations_yaml_glob = Rails.root.join("data/deprecations/**/*.yml")
-
- source_files = Rake::FileList.new(deprecations_yaml_glob) do |fl|
- fl.exclude(/example\.yml$/)
- end
-
- deprecations = source_files.flat_map do |file|
- YAML.load_file(file)
- end
-
- deps = VersionSorter.sort(deprecations) { |d| d["removal_milestone"] }
-
- deprecations = deps.sort_by { |d| d["name"] }
-
- milestones = deps.map { |d| d["removal_milestone"] }.uniq
-
- template = Rails.root.join("data/deprecations/templates/_deprecation_template.md.erb")
-
- load_template(template)
- .result_with_hash(deprecations: deprecations, milestones: milestones)
- end
-
- def load_template(filename)
- ERB.new(File.read(filename), trim_mode: '-')
- end
- end
-end
diff --git a/tooling/docs/deprecation_handling.rb b/tooling/docs/deprecation_handling.rb
new file mode 100644
index 00000000000..7dfd3e1101d
--- /dev/null
+++ b/tooling/docs/deprecation_handling.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+require 'erb'
+
+module Docs
+ class DeprecationHandling
+ def initialize(type)
+ @type = type
+ @yaml_glob_path = Rails.root.join("data/#{type.pluralize}/**/*.yml")
+ @template_path = Rails.root.join("data/#{type.pluralize}/templates/_#{type}_template.md.erb")
+ @milestone_key_name = if type == "deprecation"
+ "announcement_milestone"
+ else
+ "removal_milestone"
+ end
+ end
+
+ def render
+ source_file_paths = Rake::FileList.new(yaml_glob_path) do |fl|
+ fl.exclude(/example\.yml$/)
+ end
+
+ entries = source_file_paths.flat_map do |file|
+ YAML.load_file(file)
+ end
+ entries = entries.sort_by { |d| d["name"] }
+
+ milestones = entries.map { |entry| entry[milestone_key_name] }.uniq
+ milestones = VersionSorter.sort(milestones)
+
+ load_template(template_path)
+ .result_with_hash(entries: entries, milestones: milestones)
+ end
+
+ private
+
+ def load_template(filename)
+ ERB.new(File.read(filename), trim_mode: '-')
+ end
+
+ attr_reader :type, :yaml_glob_path, :milestone_key_name, :template_path
+ end
+end
diff --git a/workhorse/.gitignore b/workhorse/.gitignore
index 7d339fef482..97a27630a9c 100644
--- a/workhorse/.gitignore
+++ b/workhorse/.gitignore
@@ -9,3 +9,4 @@ testdata/alt-public
/_build
coverage.html
/*.toml
+/gitaly.pid
diff --git a/workhorse/Makefile b/workhorse/Makefile
index 3cf592b0cff..031fe581d28 100644
--- a/workhorse/Makefile
+++ b/workhorse/Makefile
@@ -65,7 +65,12 @@ install: $(EXE_ALL)
.PHONY: test
test: prepare-tests
$(call message,$@)
- go test -tags "$(BUILD_TAGS)" ./... ;\
+ @if [ -z "$${GITALY_ADDRESS+x}" ] ; then \
+ echo "To run gitaly integration tests set GITALY_ADDRESS=tcp://127.0.0.1:8075" ; \
+ else \
+ $(MAKE) run-gitaly ; \
+ fi
+ @go test -tags "$(BUILD_TAGS)" ./... ;\
status="$$?" ;\
if [ -f "$(GITALY_PID_FILE)" ] ; then \
echo "Clean up Gitaly server for workhorse integration test" ;\
@@ -93,27 +98,24 @@ clean-build:
rm -rf $(TARGET_DIR)
.PHONY: prepare-tests
-prepare-tests: run-gitaly
prepare-tests: testdata/data/group/test.git $(EXE_ALL)
prepare-tests: testdata/scratch
.PHONY: run-gitaly
-run-gitaly: gitaly.pid
+run-gitaly: $(GITALY_PID_FILE)
$(GITALY_PID_FILE): gitaly.toml
- @{ \
- if [ -z "$${GITALY_ADDRESS+x}" ] ; then \
- echo "To run gitaly integration tests set GITALY_ADDRESS=tcp://127.0.0.1:8075" ; \
- else \
- cd .. ; \
- GITALY_TESTING_NO_GIT_HOOKS=1 GITALY_PID_FILE=workhorse/$(GITALY_PID_FILE) $(GITALY) workhorse/gitaly.toml ; \
- fi \
- } &
+ $(call message, "Starting gitaly")
+ cd ..; GITALY_TESTING_NO_GIT_HOOKS=1 GITALY_PID_FILE=workhorse/$(GITALY_PID_FILE) scripts/gitaly-test-spawn workhorse/gitaly.toml
gitaly.toml: ../tmp/tests/gitaly/config.toml
sed -e 's/^socket_path.*$$/listen_addr = "0.0.0.0:8075"/;s/^\[auth\]$$//;s/^token.*$$//;s/^internal_socket_dir.*$$//' \
$< > $@
+../tmp/tests/gitaly/config.toml:
+ $(call message, "Building a complete test environment")
+ cd .. ; ./scripts/setup-test-env
+
testdata/data/group/test.git:
$(call message,$@)
git clone --quiet --bare https://gitlab.com/gitlab-org/gitlab-test.git $@
diff --git a/workhorse/internal/proxy/proxy.go b/workhorse/internal/proxy/proxy.go
index 40be0fa96f6..be161c833a9 100644
--- a/workhorse/internal/proxy/proxy.go
+++ b/workhorse/internal/proxy/proxy.go
@@ -18,10 +18,17 @@ type Proxy struct {
Version string
reverseProxy *httputil.ReverseProxy
AllowResponseBuffering bool
+ customHeaders map[string]string
}
-func NewProxy(myURL *url.URL, version string, roundTripper http.RoundTripper) *Proxy {
- p := Proxy{Version: version, AllowResponseBuffering: true}
+func WithCustomHeaders(customHeaders map[string]string) func(*Proxy) {
+ return func(proxy *Proxy) {
+ proxy.customHeaders = customHeaders
+ }
+}
+
+func NewProxy(myURL *url.URL, version string, roundTripper http.RoundTripper, options ...func(*Proxy)) *Proxy {
+ p := Proxy{Version: version, AllowResponseBuffering: true, customHeaders: make(map[string]string)}
if myURL == nil {
myURL = defaultTarget
@@ -31,6 +38,11 @@ func NewProxy(myURL *url.URL, version string, roundTripper http.RoundTripper) *P
u.Path = ""
p.reverseProxy = httputil.NewSingleHostReverseProxy(&u)
p.reverseProxy.Transport = roundTripper
+
+ for _, option := range options {
+ option(&p)
+ }
+
return &p
}
@@ -43,6 +55,10 @@ func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
req.Header.Set("Gitlab-Workhorse", p.Version)
req.Header.Set("Gitlab-Workhorse-Proxy-Start", fmt.Sprintf("%d", time.Now().UnixNano()))
+ for k, v := range p.customHeaders {
+ req.Header.Set(k, v)
+ }
+
if p.AllowResponseBuffering {
helper.AllowResponseBuffering(w)
}
diff --git a/workhorse/internal/upstream/upstream.go b/workhorse/internal/upstream/upstream.go
index 065cae53e2b..c0678b1cb3e 100644
--- a/workhorse/internal/upstream/upstream.go
+++ b/workhorse/internal/upstream/upstream.go
@@ -37,6 +37,7 @@ var (
upload.RewrittenFieldsHeader,
}
geoProxyApiPollingInterval = 10 * time.Second
+ geoProxyWorkhorseHeaders = map[string]string{"Gitlab-Workhorse-Geo-Proxy": "1"}
)
type upstream struct {
@@ -237,7 +238,12 @@ func (u *upstream) updateGeoProxyFields(geoProxyURL *url.URL) {
}
geoProxyRoundTripper := roundtripper.NewBackendRoundTripper(u.geoProxyBackend, "", u.ProxyHeadersTimeout, u.DevelopmentMode)
- geoProxyUpstream := proxypkg.NewProxy(u.geoProxyBackend, u.Version, geoProxyRoundTripper)
+ geoProxyUpstream := proxypkg.NewProxy(
+ u.geoProxyBackend,
+ u.Version,
+ geoProxyRoundTripper,
+ proxypkg.WithCustomHeaders(geoProxyWorkhorseHeaders),
+ )
u.geoProxyCableRoute = u.wsRoute(`^/-/cable\z`, geoProxyUpstream)
u.geoProxyRoute = u.route("", "", geoProxyUpstream, withGeoProxy())
}
diff --git a/workhorse/internal/upstream/upstream_test.go b/workhorse/internal/upstream/upstream_test.go
index 2031fa84ce2..80e59202b69 100644
--- a/workhorse/internal/upstream/upstream_test.go
+++ b/workhorse/internal/upstream/upstream_test.go
@@ -209,6 +209,23 @@ func TestGeoProxyFeatureEnablingAndDisabling(t *testing.T) {
runTestCases(t, ws, testCasesProxied)
}
+func TestGeoProxySetsCustomHeader(t *testing.T) {
+ remoteServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ require.Equal(t, "1", r.Header.Get("Gitlab-Workhorse-Geo-Proxy"), "custom proxy header")
+ w.WriteHeader(http.StatusOK)
+ }))
+ defer remoteServer.Close()
+
+ geoProxyEndpointResponseBody := fmt.Sprintf(`{"geo_proxy_url":"%v"}`, remoteServer.URL)
+ railsServer, deferredClose := startRailsServer("Local Rails server", &geoProxyEndpointResponseBody)
+ defer deferredClose()
+
+ ws, wsDeferredClose, _ := startWorkhorseServer(railsServer.URL, true)
+ defer wsDeferredClose()
+
+ http.Get(ws.URL)
+}
+
func runTestCases(t *testing.T, ws *httptest.Server, testCases []testCase) {
t.Helper()
for _, tc := range testCases {
diff --git a/workhorse/proxy_test.go b/workhorse/proxy_test.go
index 48d7db428fd..754deea0032 100644
--- a/workhorse/proxy_test.go
+++ b/workhorse/proxy_test.go
@@ -22,12 +22,12 @@ import (
const testVersion = "123"
-func newProxy(url string, rt http.RoundTripper) *proxy.Proxy {
+func newProxy(url string, rt http.RoundTripper, opts ...func(*proxy.Proxy)) *proxy.Proxy {
parsedURL := helper.URLMustParse(url)
if rt == nil {
rt = roundtripper.NewTestBackendRoundTripper(parsedURL)
}
- return proxy.NewProxy(parsedURL, testVersion, rt)
+ return proxy.NewProxy(parsedURL, testVersion, rt, opts...)
}
func TestProxyRequest(t *testing.T) {
@@ -64,6 +64,24 @@ func TestProxyRequest(t *testing.T) {
require.Equal(t, "test", w.Header().Get("Custom-Response-Header"), "custom response header")
}
+func TestProxyWithCustomHeaders(t *testing.T) {
+ ts := testhelper.TestServerWithHandler(regexp.MustCompile(`/url/path\z`), func(w http.ResponseWriter, r *http.Request) {
+ require.Equal(t, "value", r.Header.Get("Custom-Header"), "custom proxy header")
+ require.Equal(t, testVersion, r.Header.Get("Gitlab-Workhorse"), "version header")
+
+ _, err := w.Write([]byte(`ok`))
+ require.NoError(t, err, "write ok response")
+ })
+
+ httpRequest, err := http.NewRequest("POST", ts.URL+"/url/path", nil)
+ require.NoError(t, err)
+
+ w := httptest.NewRecorder()
+ testProxy := newProxy(ts.URL, nil, proxy.WithCustomHeaders(map[string]string{"Custom-Header": "value"}))
+ testProxy.ServeHTTP(w, httpRequest)
+ testhelper.RequireResponseBody(t, w, "ok")
+}
+
func TestProxyError(t *testing.T) {
httpRequest, err := http.NewRequest("POST", "/url/path", bytes.NewBufferString("REQUEST"))
require.NoError(t, err)
diff --git a/yarn.lock b/yarn.lock
index c0ac7988cfc..0917c1690b6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9,12 +9,12 @@
dependencies:
"@babel/highlight" "^7.10.4"
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.14.5":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb"
- integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==
+"@babel/code-frame@7.16.0", "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.14.5":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431"
+ integrity sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==
dependencies:
- "@babel/highlight" "^7.14.5"
+ "@babel/highlight" "^7.16.0"
"@babel/compat-data@^7.10.1", "@babel/compat-data@^7.15.0":
version "7.15.0"
@@ -226,7 +226,7 @@
dependencies:
"@babel/types" "^7.15.4"
-"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9", "@babel/helper-validator-identifier@^7.15.7":
+"@babel/helper-validator-identifier@^7.14.9", "@babel/helper-validator-identifier@^7.15.7":
version "7.15.7"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389"
integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==
@@ -255,19 +255,19 @@
"@babel/traverse" "^7.15.4"
"@babel/types" "^7.15.4"
-"@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9"
- integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==
+"@babel/highlight@^7.10.4", "@babel/highlight@^7.16.0":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a"
+ integrity sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==
dependencies:
- "@babel/helper-validator-identifier" "^7.14.5"
+ "@babel/helper-validator-identifier" "^7.15.7"
chalk "^2.0.0"
js-tokens "^4.0.0"
-"@babel/parser@7.15.7", "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.15.0", "@babel/parser@^7.15.4":
- version "7.15.7"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.7.tgz#0c3ed4a2eb07b165dfa85b3cc45c727334c4edae"
- integrity sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g==
+"@babel/parser@7.15.8", "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.15.0", "@babel/parser@^7.15.4":
+ version "7.15.8"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.8.tgz#7bacdcbe71bdc3ff936d510c15dcea7cf0b99016"
+ integrity sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==
"@babel/plugin-proposal-async-generator-functions@^7.10.1":
version "7.10.1"
@@ -914,20 +914,20 @@
stylelint-declaration-strict-value "1.7.7"
stylelint-scss "3.18.0"
-"@gitlab/svgs@2.0.0":
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-2.0.0.tgz#06af5e91c36498ccf7e3e30e432eefcb3b1276c2"
- integrity sha512-kBq7RZ0N+h41b4JbPOmwzx1X++fD+tz8HhaBmHTkOmRFY/7Ygvt2A8GodUUtpFK/NxRxy8O+knZvLNdfMLAIoQ==
+"@gitlab/svgs@2.2.0":
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-2.2.0.tgz#95cf58d6ae634d535145159f08f5cff6241d4013"
+ integrity sha512-mCwR3KfNPsxRoojtTjMIZwdd4FFlBh5DlR9AeodP+7+k8rILdWGYxTZbJMPNXoPbZx16R94nG8c5bR7toD4QBw==
"@gitlab/tributejs@1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@gitlab/tributejs/-/tributejs-1.0.0.tgz#672befa222aeffc83e7d799b0500a7a4418e59b8"
integrity sha512-nmKw1+hB6MHvlmPz63yPwVs1qQkycHwsKgxpEbzmky16Y6mL4EJMk3w1b8QlOAF/AIAzjCERPhe/R4MJiohbZw==
-"@gitlab/ui@32.50.0":
- version "32.50.0"
- resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-32.50.0.tgz#ac50617a8b84f78949e177f495ade276f8560679"
- integrity sha512-7wPEgbOn7M9hqzq5LZND5b8/OEajoFCjwaXzO42FBNJ+pb80JBsTg1Mu8dyXMGQP/SPcxO58BdQLUSjE0WER4w==
+"@gitlab/ui@32.68.0":
+ version "32.68.0"
+ resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-32.68.0.tgz#f7c4ebd2f9b3635db16589b289fdda149ca1cbcc"
+ integrity sha512-rTd0+bNBjPvL1ZMfGEHNoBSZwumu6DMQLBwtPhUaj288nAB4K2xibdhFmsm1yqhnW04VNLyBs9FqKdXRQqFttA==
dependencies:
"@babel/standalone" "^7.0.0"
bootstrap-vue "2.20.1"
@@ -947,164 +947,162 @@
resolved "https://registry.yarnpkg.com/@gitlab/visual-review-tools/-/visual-review-tools-1.6.1.tgz#0d8f3ff9f51b05f7c80b9a107727703d48997e4e"
integrity sha512-vY8K1igwZFoEOmU0h4E7XTLlilsQ4ylPr27O01UsSe6ZTKi6oEMREsRAEpNIUgRlxUARCsf+Opp4pgSFzFkFcw==
-"@graphql-eslint/eslint-plugin@2.3.0":
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/@graphql-eslint/eslint-plugin/-/eslint-plugin-2.3.0.tgz#4e500466fa56b64680c67d7639f1bdf11d890f8a"
- integrity sha512-YYTBKhadvdTO6myWFm3O8A8dP/ca5NsyB2FKYoHGUIToEl25xAMuj2yzvhIjIBwA/yhlLRPe9+EIQ+8f0kjBDg==
- dependencies:
- "@graphql-tools/code-file-loader" "^7.0.2"
- "@graphql-tools/graphql-tag-pluck" "^7.0.2"
- "@graphql-tools/import" "^6.3.1"
- "@graphql-tools/utils" "^8.0.2"
- graphql-config "^4.0.1"
+"@graphql-eslint/eslint-plugin@3.0.0":
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/@graphql-eslint/eslint-plugin/-/eslint-plugin-3.0.0.tgz#d0f7d6e4f6f772312500abbf6c94c59d5cb52c12"
+ integrity sha512-EfkMABrCbWhhArEGg4w2r/z8sEPp1fL0Ar3xFWBX9c11t5+T5XqGAGVxUi5vuEx9PrSqhYisPrxTibqNoxuEzQ==
+ dependencies:
+ "@babel/code-frame" "7.16.0"
+ "@graphql-tools/code-file-loader" "7.2.2"
+ "@graphql-tools/graphql-tag-pluck" "7.1.3"
+ "@graphql-tools/import" "6.6.1"
+ "@graphql-tools/utils" "8.5.3"
+ graphql-config "4.1.0"
graphql-depth-limit "1.1.0"
- lodash.lowercase "^4.3.0"
+ lodash.lowercase "4.3.0"
-"@graphql-tools/batch-execute@^8.3.0":
- version "8.3.0"
- resolved "https://registry.yarnpkg.com/@graphql-tools/batch-execute/-/batch-execute-8.3.0.tgz#a8fabc5f5d6e9fa5b34bbc9cdc2f1809ee164f3f"
- integrity sha512-rv7lCH4T8hapJ9o1/aOhr64oEZhYaNRt8lzuEC3BlhzJc/szSt+/ry6mBNDjca6tjxJpMc82XLWAx9ppBLnyVA==
+"@graphql-tools/batch-execute@^8.3.1":
+ version "8.3.1"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/batch-execute/-/batch-execute-8.3.1.tgz#0b74c54db5ac1c5b9a273baefc034c2343ebbb74"
+ integrity sha512-63kHY8ZdoO5FoeDXYHnAak1R3ysMViMPwWC2XUblFckuVLMUPmB2ONje8rjr2CvzWBHAW8c1Zsex+U3xhKtGIA==
dependencies:
- "@graphql-tools/utils" "^8.5.0"
+ "@graphql-tools/utils" "^8.5.1"
dataloader "2.0.0"
tslib "~2.3.0"
value-or-promise "1.0.11"
-"@graphql-tools/code-file-loader@^7.0.2":
- version "7.2.1"
- resolved "https://registry.yarnpkg.com/@graphql-tools/code-file-loader/-/code-file-loader-7.2.1.tgz#09c5981cb42579f921f2506164f54892bade85cd"
- integrity sha512-n9qoGZzJ+zfcUsrWz0uC2tevBcIUgT0adgoaj4OG67i1xfsJ2dJYXurbYpD38G4QKfOZ0DTYJ0oWKYWPkc54Qw==
+"@graphql-tools/code-file-loader@7.2.2":
+ version "7.2.2"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/code-file-loader/-/code-file-loader-7.2.2.tgz#79f8ce5723ee87ecb4d490d1497ac7e616340358"
+ integrity sha512-AADyxqipGWLBl4N59CGPgv3i35UF1fQpJvbC5a6TXmcppnghD2olDLewOh1pIQrwxGAAh1S75XVIi28PTKYZhg==
dependencies:
- "@graphql-tools/graphql-tag-pluck" "^7.1.0"
- "@graphql-tools/utils" "^8.3.0"
+ "@graphql-tools/graphql-tag-pluck" "^7.1.3"
+ "@graphql-tools/utils" "^8.5.1"
globby "^11.0.3"
tslib "~2.3.0"
unixify "^1.0.0"
-"@graphql-tools/delegate@^8.4.0":
- version "8.4.0"
- resolved "https://registry.yarnpkg.com/@graphql-tools/delegate/-/delegate-8.4.0.tgz#630c7e30b8b0f4039bc453082d6f77501488a9b6"
- integrity sha512-FtMN1+q6aNahg0AGCEndUpfdOZ6O7OnIsLTauMPEG/vrwoIlMb8tn+qBRlGrWWxyUPKBSD31T74EWM3Tq/bBaQ==
+"@graphql-tools/delegate@^8.4.1", "@graphql-tools/delegate@^8.4.2":
+ version "8.4.2"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/delegate/-/delegate-8.4.2.tgz#a61d45719855720304e3656800342cfa17d82558"
+ integrity sha512-CjggOhiL4WtyG2I3kux+1/p8lQxSFHBj0gwa0NxnQ6Vsnpw7Ig5VP1ovPnitFuBv2k4QdC37Nj2xv2n7DRn8fw==
dependencies:
- "@graphql-tools/batch-execute" "^8.3.0"
- "@graphql-tools/schema" "^8.3.0"
- "@graphql-tools/utils" "^8.5.0"
+ "@graphql-tools/batch-execute" "^8.3.1"
+ "@graphql-tools/schema" "^8.3.1"
+ "@graphql-tools/utils" "^8.5.3"
dataloader "2.0.0"
tslib "~2.3.0"
value-or-promise "1.0.11"
-"@graphql-tools/graphql-file-loader@^7.0.1":
- version "7.3.1"
- resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-file-loader/-/graphql-file-loader-7.3.1.tgz#12c3650197acda0a031fa4d47d371d44908eac88"
- integrity sha512-LgbnUjhMuHUGmPouhql8q437B2/pO4S04RWGRywkY75+FPrFiSsxyk13qB/lTaUMtrhPz0h8SUAh/09mF/1gpw==
+"@graphql-tools/graphql-file-loader@^7.3.2":
+ version "7.3.3"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-file-loader/-/graphql-file-loader-7.3.3.tgz#7cee2f84f08dc13fa756820b510248b857583d36"
+ integrity sha512-6kUJZiNpYKVhum9E5wfl5PyLLupEDYdH7c8l6oMrk6c7EPEVs6iSUyB7yQoWrtJccJLULBW2CRQ5IHp5JYK0mA==
dependencies:
- "@graphql-tools/import" "^6.5.4"
- "@graphql-tools/utils" "^8.3.0"
+ "@graphql-tools/import" "^6.5.7"
+ "@graphql-tools/utils" "^8.5.1"
globby "^11.0.3"
tslib "~2.3.0"
unixify "^1.0.0"
-"@graphql-tools/graphql-tag-pluck@^7.0.2", "@graphql-tools/graphql-tag-pluck@^7.1.0":
- version "7.1.2"
- resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-7.1.2.tgz#1f4ae8a98df3529da1dc5654469900d4c08cc3a1"
- integrity sha512-YVvzG6UaWJQgbU+VvjFY5rZQQDvkyNX+rEbqYpJOt1muhP67dAwAGyWMyDcyEi4QAsEpSvaxfy/Km6lR/NHwWA==
+"@graphql-tools/graphql-tag-pluck@7.1.3", "@graphql-tools/graphql-tag-pluck@^7.1.3":
+ version "7.1.3"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-7.1.3.tgz#2c638aac84f279f95bf3da50b71f2b4b82641539"
+ integrity sha512-zxVYLiAnNxFg6bnDZdNpLJNfjf6GHYLQsVHDcbYyQcWJzIaeWPylX/Q1gyvw8MFO4ICYExNPqgBA/is2kZBlHw==
dependencies:
- "@babel/parser" "7.15.7"
+ "@babel/parser" "7.15.8"
"@babel/traverse" "7.15.4"
"@babel/types" "7.15.6"
- "@graphql-tools/utils" "^8.2.5"
+ "@graphql-tools/utils" "^8.5.1"
tslib "~2.3.0"
-"@graphql-tools/import@^6.3.1", "@graphql-tools/import@^6.5.4":
- version "6.5.6"
- resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-6.5.6.tgz#9ea073d7fb4fdd177ecc2df4c553b61db9d55fcb"
- integrity sha512-SxCpNhN3sIZM4wsMjQWXKkff/CBn7+WHoZ9OjZkdV5nxGbnzRKh5SZAAsvAFuj6Kst5Y9mlAaiwy+QufZZ1F1w==
+"@graphql-tools/import@6.6.1", "@graphql-tools/import@^6.5.7":
+ version "6.6.1"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-6.6.1.tgz#2a7e1ceda10103ffeb8652a48ddc47150b035485"
+ integrity sha512-i9WA6k+erJMci822o9w9DoX+uncVBK60LGGYW8mdbhX0l7wEubUpA000thJ1aarCusYh0u+ZT9qX0HyVPXu25Q==
dependencies:
- "@graphql-tools/utils" "8.5.0"
+ "@graphql-tools/utils" "8.5.3"
resolve-from "5.0.0"
tslib "~2.3.0"
-"@graphql-tools/json-file-loader@^7.0.1":
- version "7.3.1"
- resolved "https://registry.yarnpkg.com/@graphql-tools/json-file-loader/-/json-file-loader-7.3.1.tgz#5252a65380c70343e8c761c1fea3f59c65d22114"
- integrity sha512-A2Pa4C8KoZkiqTk2/YxU6uIlRpIcPSUBBSL6cXh0877XZeCgs2cmmFMvZOnYJni0X6Bw38gkCAjaYJXpBzNFPQ==
+"@graphql-tools/json-file-loader@^7.3.2":
+ version "7.3.3"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/json-file-loader/-/json-file-loader-7.3.3.tgz#45cfde77b9dc4ab6c21575305ae537d2814d237f"
+ integrity sha512-CN2Qk9rt+Gepa3rb3X/mpxYA5MIYLwZBPj2Njw6lbZ6AaxG+O1ArDCL5ACoiWiBimn1FCOM778uhRM9znd0b3Q==
dependencies:
- "@graphql-tools/utils" "^8.3.0"
+ "@graphql-tools/utils" "^8.5.1"
globby "^11.0.3"
tslib "~2.3.0"
unixify "^1.0.0"
-"@graphql-tools/load@^7.1.0":
- version "7.4.0"
- resolved "https://registry.yarnpkg.com/@graphql-tools/load/-/load-7.4.0.tgz#259e2b0b5efe1b7d1834ca462ff22785a42e5c7e"
- integrity sha512-f1RpBa/TIHIRxzcmL+pRj+021P8lx1Tu0gQ/6tzEHMlvh8AhPchXlOiASWBWDVo0J7+fSL+KQrlVORQ7VVMT0w==
+"@graphql-tools/load@^7.4.1":
+ version "7.4.1"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/load/-/load-7.4.1.tgz#aa572fcef11d6028097b6ef39c13fa9d62e5a441"
+ integrity sha512-UvBodW5hRHpgBUBVz5K5VIhJDOTFIbRRAGD6sQ2l9J5FDKBEs3u/6JjZDzbdL96br94D5cEd2Tk6auaHpTn7mQ==
dependencies:
- "@graphql-tools/schema" "8.3.0"
- "@graphql-tools/utils" "^8.4.0"
+ "@graphql-tools/schema" "8.3.1"
+ "@graphql-tools/utils" "^8.5.1"
p-limit "3.1.0"
tslib "~2.3.0"
-"@graphql-tools/merge@^6.2.16 || ^7.0.0 || ^8.0.0", "@graphql-tools/merge@^8.2.0":
- version "8.2.0"
- resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.2.0.tgz#8f6638eeecf19f59fef28598024308e0452dd0a2"
- integrity sha512-nfMLYF7zczjnIbChZtqbvozRfuRweMD1Fe9HHd4RXd3Tcsj6E17srW0QJfxUoIIWh4pitj+XwZAwhj1PWBDU7g==
+"@graphql-tools/merge@^8.2.1":
+ version "8.2.1"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.2.1.tgz#bf83aa06a0cfc6a839e52a58057a84498d0d51ff"
+ integrity sha512-Q240kcUszhXiAYudjuJgNuLgy9CryDP3wp83NOZQezfA6h3ByYKU7xI6DiKrdjyVaGpYN3ppUmdj0uf5GaXzMA==
dependencies:
- "@graphql-tools/utils" "^8.4.0"
+ "@graphql-tools/utils" "^8.5.1"
tslib "~2.3.0"
-"@graphql-tools/schema@8.3.0", "@graphql-tools/schema@^8.3.0":
- version "8.3.0"
- resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-8.3.0.tgz#ddf4297859c6d7ac1ebbbd91460260ed424115db"
- integrity sha512-OJD4Q1Xa3sffRiHzy0sskZz9ZWeqaujINfoim4CTk5Y9es1LS+WnKi25wVhmL2SGzzmKuAv7oDn+dpQAlM+Gfw==
+"@graphql-tools/schema@8.3.1", "@graphql-tools/schema@^8.3.1":
+ version "8.3.1"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-8.3.1.tgz#1ee9da494d2da457643b3c93502b94c3c4b68c74"
+ integrity sha512-3R0AJFe715p4GwF067G5i0KCr/XIdvSfDLvTLEiTDQ8V/hwbOHEKHKWlEBHGRQwkG5lwFQlW1aOn7VnlPERnWQ==
dependencies:
- "@graphql-tools/merge" "^8.2.0"
- "@graphql-tools/utils" "^8.4.0"
+ "@graphql-tools/merge" "^8.2.1"
+ "@graphql-tools/utils" "^8.5.1"
tslib "~2.3.0"
value-or-promise "1.0.11"
-"@graphql-tools/url-loader@^7.0.3":
- version "7.4.1"
- resolved "https://registry.yarnpkg.com/@graphql-tools/url-loader/-/url-loader-7.4.1.tgz#2cdae0d27271aa7f8d88788698f6490dd88de4cf"
- integrity sha512-RrgXxiabfCH0gTvn86o6wOKXCqhb5EFoZlbK2TzWECA4i3mJehrxZ+FSIDrbcFcpgrE94SNj9a/xXK4VcgJNKg==
+"@graphql-tools/url-loader@^7.4.2":
+ version "7.5.2"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/url-loader/-/url-loader-7.5.2.tgz#fb3737fd1269ab61b195b63052179b6049d90ce1"
+ integrity sha512-EilHqbhUY/qg55SSEdklDhPXgSz9+9a63SX3mcD8J2qwZHJD/wOLcyKs8m6BXfuGwUiuB0j3fmDSEVmva2onBg==
dependencies:
- "@graphql-tools/delegate" "^8.4.0"
- "@graphql-tools/utils" "^8.5.0"
- "@graphql-tools/wrap" "^8.3.0"
- "@n1ru4l/graphql-live-query" "0.8.1"
+ "@graphql-tools/delegate" "^8.4.1"
+ "@graphql-tools/utils" "^8.5.1"
+ "@graphql-tools/wrap" "^8.3.1"
+ "@n1ru4l/graphql-live-query" "0.9.0"
"@types/websocket" "1.0.4"
"@types/ws" "^8.0.0"
- abort-controller "3.0.0"
- cross-fetch "3.1.4"
+ cross-undici-fetch "^0.0.20"
dset "^3.1.0"
extract-files "11.0.0"
- form-data "4.0.0"
graphql-sse "^1.0.1"
graphql-ws "^5.4.1"
- is-promise "4.0.0"
isomorphic-ws "4.0.1"
meros "1.1.4"
- subscriptions-transport-ws "^0.10.0"
+ subscriptions-transport-ws "^0.11.0"
sync-fetch "0.3.1"
tslib "~2.3.0"
valid-url "1.0.9"
value-or-promise "1.0.11"
ws "8.2.3"
-"@graphql-tools/utils@8.5.0", "@graphql-tools/utils@^8.0.1", "@graphql-tools/utils@^8.0.2", "@graphql-tools/utils@^8.2.5", "@graphql-tools/utils@^8.3.0", "@graphql-tools/utils@^8.4.0", "@graphql-tools/utils@^8.5.0":
- version "8.5.0"
- resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.5.0.tgz#439487ac756d9458a33091e5e0435ddf8e794f3e"
- integrity sha512-jMwLm6YdN+Vbqntg5GHqDvGLpLa/xPSpRs/c40d0rBuel77wo7AaQ8jHeBSpp9y+7kp7HrGSWff1u7yJ7F8ppw==
+"@graphql-tools/utils@8.5.3", "@graphql-tools/utils@^8.5.1", "@graphql-tools/utils@^8.5.3":
+ version "8.5.3"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.5.3.tgz#404062e62cae9453501197039687749c4885356e"
+ integrity sha512-HDNGWFVa8QQkoQB0H1lftvaO1X5xUaUDk1zr1qDe0xN1NL0E/CrQdJ5UKLqOvH4hkqVUPxQsyOoAZFkaH6rLHg==
dependencies:
tslib "~2.3.0"
-"@graphql-tools/wrap@^8.3.0":
- version "8.3.0"
- resolved "https://registry.yarnpkg.com/@graphql-tools/wrap/-/wrap-8.3.0.tgz#ae40302965176614adde80fd1e3ea93b87d3219d"
- integrity sha512-DB9Rc/GHAAPizarlCAeo7KzZLN0VaMB+9XG6Pm8IfoNNYHq1I6czlzskHGd+U5nkXUhkuHFlV2QnersxhyJkHA==
+"@graphql-tools/wrap@^8.3.1":
+ version "8.3.2"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/wrap/-/wrap-8.3.2.tgz#d3bcecb7529d071e4ecc4dfc75b9566e3da79d4f"
+ integrity sha512-7DcOBFB+Dd84x9dxSm7qS4iJONMyfLnCJb8A19vGPffpu4SMJ3sFcgwibKFu5l6mMUiigKgXna2RRgWI+02bKQ==
dependencies:
- "@graphql-tools/delegate" "^8.4.0"
- "@graphql-tools/schema" "^8.3.0"
- "@graphql-tools/utils" "^8.5.0"
+ "@graphql-tools/delegate" "^8.4.2"
+ "@graphql-tools/schema" "^8.3.1"
+ "@graphql-tools/utils" "^8.5.3"
tslib "~2.3.0"
value-or-promise "1.0.11"
@@ -1319,10 +1317,10 @@
resolved "https://registry.yarnpkg.com/@miragejs/pretender-node-polyfill/-/pretender-node-polyfill-0.1.2.tgz#d26b6b7483fb70cd62189d05c95d2f67153e43f2"
integrity sha512-M/BexG/p05C5lFfMunxo/QcgIJnMT2vDVCd00wNqK2ImZONIlEETZwWJu1QtLxtmYlSHlCFl3JNzp0tLe7OJ5g==
-"@n1ru4l/graphql-live-query@0.8.1":
- version "0.8.1"
- resolved "https://registry.yarnpkg.com/@n1ru4l/graphql-live-query/-/graphql-live-query-0.8.1.tgz#2d6ca6157dafdc5d122a1aeb623b43e939c4b238"
- integrity sha512-x5SLY+L9/5s07OJprISXx4csNBPF74UZeTI01ZPSaxOtRz2Gljk652kSPf6OjMLtx5uATr35O0M3G0LYhHBLtg==
+"@n1ru4l/graphql-live-query@0.9.0":
+ version "0.9.0"
+ resolved "https://registry.yarnpkg.com/@n1ru4l/graphql-live-query/-/graphql-live-query-0.9.0.tgz#defaebdd31f625bee49e6745934f36312532b2bc"
+ integrity sha512-BTpWy1e+FxN82RnLz4x1+JcEewVdfmUhV1C6/XYD5AjS7PQp9QFF7K8bCD6gzPTr2l+prvqOyVueQhFJxB1vfg==
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
@@ -1492,73 +1490,73 @@
dom-accessibility-api "^0.5.1"
pretty-format "^26.4.2"
-"@tiptap/core@^2.0.0-beta.143":
- version "2.0.0-beta.143"
- resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.143.tgz#e1eb470351867eb13a8f2169958f2231138a6dc1"
- integrity sha512-3AoKMZmuc+Lh/ZsM7dj+mSQvRMFANgLVAT0Fza9DaEMREnbpS6nDZlpcbb0HnoExbd7ZLobuwDGxEIZG5uo3Lw==
+"@tiptap/core@^2.0.0-beta.160":
+ version "2.0.0-beta.160"
+ resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.160.tgz#98f0625dc12a3498c6bbe2ae4aed4667b62a2a11"
+ integrity sha512-oKtx4vn4ew+mCH3kiBeD4UdPa5IVLLBCuSgGNnqdoIuRv397uh5SwOz7TiL5A+vTa6yke0xLSKxZ+QNR2qfVXg==
dependencies:
"@types/prosemirror-commands" "^1.0.4"
"@types/prosemirror-keymap" "^1.0.4"
"@types/prosemirror-model" "^1.13.2"
"@types/prosemirror-schema-list" "^1.0.3"
"@types/prosemirror-state" "^1.2.8"
- "@types/prosemirror-transform" "^1.1.4"
- "@types/prosemirror-view" "^1.19.1"
+ "@types/prosemirror-transform" "^1.1.5"
+ "@types/prosemirror-view" "^1.19.2"
prosemirror-commands "^1.1.12"
prosemirror-keymap "^1.1.5"
- prosemirror-model "^1.15.0"
+ prosemirror-model "^1.16.1"
prosemirror-schema-list "^1.1.6"
prosemirror-state "^1.3.4"
prosemirror-transform "^1.3.3"
- prosemirror-view "^1.23.1"
+ prosemirror-view "^1.23.5"
-"@tiptap/extension-blockquote@^2.0.0-beta.25":
- version "2.0.0-beta.25"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.0.0-beta.25.tgz#f133381163b92b34d9dc6e0d78a52cf56098eb40"
- integrity sha512-994bQQhyOmPGCNTnzHY5UwZceBh42Xcr6MEB3XnnYk5kgfNnOlrnHHt3l8mJeSnC78Bs1cRSs1BKmDF8WufauQ==
+"@tiptap/extension-blockquote@^2.0.0-beta.26":
+ version "2.0.0-beta.26"
+ 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.24":
- version "2.0.0-beta.24"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.0.0-beta.24.tgz#a8d1076922580db528cc6988fde08f731dcfe733"
- integrity sha512-2VTCtY2JI0wpDwWT0a2fMFkjbgxDpwD3wvtY3/ndh5pyNX0JQCXtJarFzfZZurWvLNQ8QPRRel73182RBYUOHQ==
+"@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-bubble-menu@^2.0.0-beta.50":
- version "2.0.0-beta.50"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.0.0-beta.50.tgz#96c09e71d84473c018fa63dc072fa3732c2b3e88"
- integrity sha512-UYnIaUTbI1K759z3A44dahp/NyHKjSaRvIptMnAv7q312l5n+czGwBcjZo41YUxjLPhnwGk1Siny1V+b5+4yBA==
+"@tiptap/extension-bubble-menu@^2.0.0-beta.54":
+ version "2.0.0-beta.54"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.0.0-beta.54.tgz#90ac838cb7899317207037abb74ed2f68528bd22"
+ integrity sha512-jSvNy+ZVHIzEvf8BY/pLpir7CB4lWL4RNUWLT6YMmGCzdzYJK3RZ6Qp0Yoo7UMTjA5JDGn3Ax1lDj4qcsoXwzA==
dependencies:
prosemirror-state "^1.3.4"
- prosemirror-view "^1.23.1"
+ prosemirror-view "^1.23.5"
tippy.js "^6.3.7"
-"@tiptap/extension-bullet-list@^2.0.0-beta.23":
- version "2.0.0-beta.23"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.0.0-beta.23.tgz#64698c98039ad301c94a9041bbd117e82957be21"
- integrity sha512-ReoUiz9f1IX87RX+GRE+fCaLEzNNwmiP4kli3QH8/qrLK3qxvZYr9N31fUeOHecCctUofPSbQB79B39zSo9Ouw==
+"@tiptap/extension-bullet-list@^2.0.0-beta.26":
+ version "2.0.0-beta.26"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.0.0-beta.26.tgz#b42126d2d984c04041b14037e8d3ec1bcf16e7ec"
+ integrity sha512-1n5HV8gY1tLjPk4x48nva6SZlFHoPlRfF6pqSu9JcJxPO7FUSPxUokuz4swYNe0LRrtykfyNz44dUcxKVhoFow==
-"@tiptap/extension-code-block-lowlight@2.0.0-beta.57":
- version "2.0.0-beta.57"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.0.0-beta.57.tgz#afaa3a59da8d688f4f402d31ad6e5bea6ff87390"
- integrity sha512-HbUkhJkTiDusLX+qqaJsqCiTKpWR6LPWScKP/Sk7744EnjMmyiqbmNwyqSx538Z8GIS89TKj1vERLUAAAOGCIQ==
+"@tiptap/extension-code-block-lowlight@2.0.0-beta.63":
+ version "2.0.0-beta.63"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.0.0-beta.63.tgz#5d99e7693c2181d15f6599b4a20aa386efdc9c00"
+ integrity sha512-Eam+j5YO7ulytOL+NMIhoEPZsAQag9hL19q17ctgl1k1yPwdLuUtU0lkIr0P+qxSzWXUGWX6q/nXM92Vb4hVPA==
dependencies:
- "@tiptap/extension-code-block" "^2.0.0-beta.29"
+ "@tiptap/extension-code-block" "^2.0.0-beta.33"
"@types/lowlight" "^0.0.3"
lowlight "^1.20.0"
- prosemirror-model "^1.15.0"
+ prosemirror-model "^1.16.1"
prosemirror-state "^1.3.4"
- prosemirror-view "^1.23.1"
+ prosemirror-view "^1.23.5"
-"@tiptap/extension-code-block@^2.0.0-beta.29":
- version "2.0.0-beta.29"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.0.0-beta.29.tgz#ad7f537bc1f12decf027d66c7328f36a8b07795c"
- integrity sha512-IoBJxqZ4F7dApRL3NisvMCBJmzpV0LmfJlFQacgm64Li15dP/QyDuvXpku03gT3y9e4f9Gv/KTKwJizXEVABhw==
+"@tiptap/extension-code-block@^2.0.0-beta.33":
+ version "2.0.0-beta.33"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.0.0-beta.33.tgz#963b06ec88f97f79e1c90b3b830eff826a4bad88"
+ integrity sha512-zKiGxbbnZJrKXr0DtBd0B7yXvY3wRk5Y5BsJqe0ZsyXR8lCEY4+DcOPpr6dja2gpgQIB9+vtqZvgBfnnUXXTcw==
dependencies:
prosemirror-state "^1.3.4"
-"@tiptap/extension-code@^2.0.0-beta.25":
- version "2.0.0-beta.25"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.0.0-beta.25.tgz#055dc8dc6d19d3f0439f57dd8ba6433e2f2fd733"
- integrity sha512-kXBR4Zp79lpUEfqJtBGv9tO1mj9jFQLMj0iVhj8e8ZporNKei5JfDOY83kwFcKAE60i7tiRDtV3OizpAKMeqDg==
+"@tiptap/extension-code@^2.0.0-beta.26":
+ version "2.0.0-beta.26"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.0.0-beta.26.tgz#bbfa600a252ee2cded6947b56b6c4c33d998e53a"
+ integrity sha512-QcFWdEFfbJ1n5UFFBD17QPPAJ3J5p/b7XV484u0shCzywO7aNPV32QeHy1z0eMoyZtCbOWf6hg/a7Ugv8IwpHw==
"@tiptap/extension-document@^2.0.0-beta.15":
version "2.0.0-beta.15"
@@ -1573,32 +1571,32 @@
"@types/prosemirror-dropcursor" "^1.0.3"
prosemirror-dropcursor "^1.4.0"
-"@tiptap/extension-floating-menu@^2.0.0-beta.45":
- version "2.0.0-beta.45"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.0.0-beta.45.tgz#0ccba4bc376171ff4cb0ad9b6e032bfa69488010"
- integrity sha512-UjAXhdrcVInCydCoRq+9IOEHQC2lR6BSNACFiTzgzObY7aFaNmMus/9MZ/WZKSN3Rw8Mk4lr8PXFP/3zuNqbYA==
+"@tiptap/extension-floating-menu@^2.0.0-beta.49":
+ version "2.0.0-beta.49"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.0.0-beta.49.tgz#36682849f50e217137775d7f738af952a0434113"
+ integrity sha512-VY0d+fJmz8FP1CxqB9u09xCZe/9Wtwff+SxY+LGpflVf0JjS+CWcaVIDNF8zHG13SMobQ5xH6RRnSuTzlS2bRA==
dependencies:
prosemirror-state "^1.3.4"
- prosemirror-view "^1.23.1"
+ prosemirror-view "^1.23.5"
tippy.js "^6.3.7"
-"@tiptap/extension-gapcursor@^2.0.0-beta.33":
- version "2.0.0-beta.33"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.0.0-beta.33.tgz#99414204e61655d4df61efc27823732176719532"
- integrity sha512-Yu6BJ1bseyXIgLlcw/2R/2wWe1mIQilMwW7hhfDJPLbFwLJrMINtA9hxd2qY7mtW19/CveT5HOihQS6QEk59iw==
+"@tiptap/extension-gapcursor@^2.0.0-beta.34":
+ version "2.0.0-beta.34"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.0.0-beta.34.tgz#0e4971affb1621934422dd5fc4bf2dd7a84f70f7"
+ integrity sha512-Vm8vMWWQ2kJcUOLfB5CEo5pYgyudI7JeeiZvX9ScPmUmgKVYhEpt3EAICY9pUYJ41aAVH35gZLXkUtsz2f9GHw==
dependencies:
"@types/prosemirror-gapcursor" "^1.0.4"
- prosemirror-gapcursor "^1.2.0"
+ prosemirror-gapcursor "^1.2.1"
"@tiptap/extension-hard-break@^2.0.0-beta.30":
version "2.0.0-beta.30"
resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.0.0-beta.30.tgz#165494f1194a7bad08907e6d64d349dd15851b72"
integrity sha512-X9xj/S+CikrbIE7ccUFVwit5QHEbflnKVxod+4zPwr1cxogFbE9AyLZE2MpYdx3z9LcnTYYi9leBqFrP4T/Olw==
-"@tiptap/extension-heading@^2.0.0-beta.23":
- version "2.0.0-beta.23"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.0.0-beta.23.tgz#8aafadc58a8d536b7f7885e4ff0f64d30908a868"
- integrity sha512-/WLymJjY+MMvee79rWHSKDBGVRw4dbBUMrFLqKLjQQBS1xS8+UW2TYzRrAH6HAH4Tc6WO39ZDbd9K9kc9wqPnA==
+"@tiptap/extension-heading@^2.0.0-beta.24":
+ version "2.0.0-beta.24"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.0.0-beta.24.tgz#52ba163c8d16985739387682d5e5b28ddf242661"
+ integrity sha512-5a3vgdO7Cf2+z7sulCGs/1j23gBcKiZe3pA1FrC5h6blwLu86hA1xnMAVBVNilP9b6c9f3lN9yxMzEWsp6ZEkA==
"@tiptap/extension-history@^2.0.0-beta.21":
version "2.0.0-beta.21"
@@ -1620,48 +1618,49 @@
resolved "https://registry.yarnpkg.com/@tiptap/extension-image/-/extension-image-2.0.0-beta.24.tgz#1010676f79925cbe11a44b6d8eee1251910fbc1d"
integrity sha512-7oiX/Ovj9WN4xTBqWbQWd4H3SUO2eNzOiKHebVo3eqWG8NxzOGfuU0iRCENtEa7vTiRrFgyeBotneMALDpDnTQ==
-"@tiptap/extension-italic@^2.0.0-beta.24":
- version "2.0.0-beta.24"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.0.0-beta.24.tgz#0a08d06dbd8dbf10f18ed17f019aa42d7ac9dbe0"
- integrity sha512-pMAWFaLFb0Z0SC5pjoTKzC6m4CQOdUYeVlHvTS/550Z9lf8cqMawQ8H6Yk6brIuANyh7iUi4/zpq4H4rAdUCuw==
+"@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-link@^2.0.0-beta.28":
- version "2.0.0-beta.28"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.0.0-beta.28.tgz#4385f36b6bb31fab34a86fb7c686ca05a37ed572"
- integrity sha512-dZNaEjoDhgjmts44KqgtOYObCdDYZq/yFhsZ8QfqEgNHJMvBNTDaPXwBDW9i3BTkkyLTmwR/qwWxqDrfDdKh2A==
+"@tiptap/extension-link@^2.0.0-beta.34":
+ version "2.0.0-beta.34"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.0.0-beta.34.tgz#9f07b9db6a3b62192b0162afdab5480fcd93e731"
+ integrity sha512-v9qqPWyKfJ9BbV2eWR4a+za1cepZywV/2Rng+1gTivzLpfBgy6Q50vgUyMe7KTZpNZw5MuZO4sBwlvangmj6Vg==
dependencies:
- linkifyjs "^3.0.3"
+ linkifyjs "^3.0.5"
+ prosemirror-model "^1.16.1"
prosemirror-state "^1.3.4"
-"@tiptap/extension-list-item@^2.0.0-beta.19":
- version "2.0.0-beta.19"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.0.0-beta.19.tgz#657f2c5624a30f3effff723f4fadb0851a61dab8"
- integrity sha512-z/5NrRKwwJc2ZkgoGxRQmA/VENxQugZoxKhUu2qoUdg5cJRcW+ERoKTiY1/AR+4M2k1izNWQMIz3nQNWMx1kQA==
+"@tiptap/extension-list-item@^2.0.0-beta.20":
+ version "2.0.0-beta.20"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.0.0-beta.20.tgz#7169528b226dee4590e013bdf6e5fc6d83729b0f"
+ integrity sha512-5IPEspJt38t9ROj4xLUesOVEYlTT/R9Skd9meHRxJQZX1qrzBICs5PC/WRIsnexrvTBhdxpYgCYjpvpsJBlKuQ==
-"@tiptap/extension-ordered-list@^2.0.0-beta.24":
- version "2.0.0-beta.24"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.0.0-beta.24.tgz#69c56e2cfbf582b338d5dbc94c5eda4593775cb5"
- integrity sha512-pXgwV+vuBAHMBGnUPa8fjxHapGCitfBJ1k8o3XvhotO7243Y7KOfYT7kg6XrY6dmTwCX2WLkIc912PP/E60y3A==
+"@tiptap/extension-ordered-list@^2.0.0-beta.27":
+ version "2.0.0-beta.27"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.0.0-beta.27.tgz#ed48a53a9b012d578613b68375db31e8664bfdc9"
+ integrity sha512-apFDeignxdZb3cA3p1HJu0zw1JgJdBYUBz1r7f99qdNybYuk3I/1MPUvlOuOgvIrBB/wydoyVDP+v9F7QN3tfQ==
-"@tiptap/extension-paragraph@^2.0.0-beta.22":
- version "2.0.0-beta.22"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.0.0-beta.22.tgz#7740fb6393296ec58e98332b2855ebdc3fd05226"
- integrity sha512-BY6GWHlMvGiXLgPHcfZRUHKzMi1jKw3i1JrpMEQ8JLwYD3koI/6UOB/qphwUJkCkIPQXNkZw4/aSBxL9uChRDg==
+"@tiptap/extension-paragraph@^2.0.0-beta.23":
+ version "2.0.0-beta.23"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.0.0-beta.23.tgz#2ab77308519494994d7a9e5a4acd14042f45f28c"
+ integrity sha512-VWAxyzecErYWk97Kv/Gkghh97zAQTcaVOisEnYYArZAlyYDaYM48qVssAC/vnRRynP2eQxb1EkppbAxE+bMHAA==
-"@tiptap/extension-strike@^2.0.0-beta.26":
- version "2.0.0-beta.26"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.0.0-beta.26.tgz#19eda1a61706ac9690ecbc794c711deb4e1efc3e"
- integrity sha512-BA+oqqYOZzRLiMYlHX6BJXlIGaNIR9LObgkHEXAj/JPK7do4wDOcuVaw+dlWS+tzvTebLbC9GYAALfNqVBlTwA==
+"@tiptap/extension-strike@^2.0.0-beta.27":
+ version "2.0.0-beta.27"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.0.0-beta.27.tgz#c5187bf3c28837f95a5c0c0617d0dd31c318353d"
+ integrity sha512-2dmCgtesuDdivM/54Q+Y6Tc3JbGz1SkHP6c62piuqBiYLWg3xa16zChZOhfN8szbbQlBgLT6XRTDt3c2Ux+Dug==
-"@tiptap/extension-subscript@^2.0.0-beta.9":
- version "2.0.0-beta.9"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-subscript/-/extension-subscript-2.0.0-beta.9.tgz#4d86e904ec081384696562a5f550e81a1ddf2c76"
- integrity sha512-wrmcDbXeilBW9HjJi34KpUioBCYD5zyaRu1hnIymVRwmfLNrwGpNyo/8VZTfNDdvliyMYHiRVFI4Mott6OzmgA==
+"@tiptap/extension-subscript@^2.0.0-beta.10":
+ version "2.0.0-beta.10"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-subscript/-/extension-subscript-2.0.0-beta.10.tgz#177e9501f805d3cdcb359411b80b54dc7d77373e"
+ integrity sha512-er8/1lp0Rb+SKwEioW0w4oVf3EkdQZ0WS/5kPBG4W0DncfUMT+bw5de76S3kRL9PLZ9UShAL7wuXtuiSi5QsMw==
-"@tiptap/extension-superscript@^2.0.0-beta.9":
- version "2.0.0-beta.9"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-superscript/-/extension-superscript-2.0.0-beta.9.tgz#be43b0e85f6440ed200831309060c3f0691811f2"
- integrity sha512-BxXvCDGtIiuPmY9JbgIEjNbrFzXN3SBj178CfmDcu/FrQimwcqmsfLP3JOu1ZbUwQJuNwubx026vHXPzHlLXDA==
+"@tiptap/extension-superscript@^2.0.0-beta.10":
+ version "2.0.0-beta.10"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-superscript/-/extension-superscript-2.0.0-beta.10.tgz#f91c19c2d30aabe3f8c21e87f8e5e8b2e6a55893"
+ integrity sha512-TUUBS8XsD2MorGORYVlhGDH7wcc9diSbHscD4Dnz8pKWVR0JPUd/od4h5qSffDzAOKxtphTiX9LOFWk6zVooKg==
"@tiptap/extension-table-cell@^2.0.0-beta.20":
version "2.0.0-beta.20"
@@ -1678,37 +1677,37 @@
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-row/-/extension-table-row-2.0.0-beta.19.tgz#b45e82f29dfcc7405440ba237b069dbb93d1a94a"
integrity sha512-ldEVDpIUX7ZqbViTy4c/RfyNGRv++O/r3A/Ivuon1PykaDDTbPlp5JM89FunAD39cLAbo2HKtweqdmzCMlZsqA==
-"@tiptap/extension-table@^2.0.0-beta.43":
- version "2.0.0-beta.43"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.0.0-beta.43.tgz#12fc8513f05dd49cba5f1a0d9dd14df9efc2050a"
- integrity sha512-PALo2WCf/4RpICfJzBvbTaEOf6rpwmQK78jC3tR8kE9Sz6xOSydZmmbl4vovklXCHy3euaW9LCuyiiX+fjJDxw==
+"@tiptap/extension-table@^2.0.0-beta.46":
+ version "2.0.0-beta.46"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.0.0-beta.46.tgz#cce4d64fe58479031eb975626cc42e3ca9ae26bd"
+ integrity sha512-JP0eYb2gS9RW1xzB1yCAgcSX4eg1MvhnYNLOxL6VCKvoHf33RW7zQEGx11W/Lrc3lh5qaMjkWcCdQYq5d8qJOA==
dependencies:
prosemirror-tables "^1.1.1"
- prosemirror-view "^1.23.1"
+ prosemirror-view "^1.23.5"
-"@tiptap/extension-task-item@^2.0.0-beta.29":
- version "2.0.0-beta.29"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-task-item/-/extension-task-item-2.0.0-beta.29.tgz#789bd2012fd9e89623c29a347da02c9cd6e34906"
- integrity sha512-6pkY2NoLMJQxfaJsK8XY5Lv/fx0LVJBJ/J15RE8glUEzkDipNhHTBnHWcfzsa4Qzi6UcSy7NJKtT8ixiyqkRmw==
+"@tiptap/extension-task-item@^2.0.0-beta.30":
+ version "2.0.0-beta.30"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-task-item/-/extension-task-item-2.0.0-beta.30.tgz#54c97d2dd84e0ff40689e02f7361dbd903a40161"
+ integrity sha512-56hS7vP/Hgv5R6otEPInTnd8z5n6UCBFm4sbMPA8d7yWWJDskkfuMp9YDEu2zgHZtTghPyGkw3wO6yxouGWlkg==
-"@tiptap/extension-task-list@^2.0.0-beta.23":
- version "2.0.0-beta.23"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-task-list/-/extension-task-list-2.0.0-beta.23.tgz#ca29039de53f7315e5612bfd1fb4ca6d471b9a2f"
- integrity sha512-NjAQhtWDtkDpeKtJPItNeLi1fLLVACBFMq2yRCtKBXDGYg2X5w9CYPqXzh8gAIM2qs11wIgS60UtvF2No7Crxg==
+"@tiptap/extension-task-list@^2.0.0-beta.26":
+ version "2.0.0-beta.26"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-task-list/-/extension-task-list-2.0.0-beta.26.tgz#75a20795429c40c3b12544483ea63014487d71c7"
+ integrity sha512-7zPpz9eOUCnFyWNDFYPCUJ39gjID+mCI5BuXyXrjJjDfm8wxg/xTgg9+KC6xakczos7DypnhzlRKSs4EFczeUg==
"@tiptap/extension-text@^2.0.0-beta.15":
version "2.0.0-beta.15"
resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.0.0-beta.15.tgz#f08cff1b78f1c6996464dfba1fef8ec1e107617f"
integrity sha512-S3j2+HyV2gsXZP8Wg/HA+YVXQsZ3nrXgBM9HmGAxB0ESOO50l7LWfip0f3qcw1oRlh5H3iLPkA6/f7clD2/TFA==
-"@tiptap/vue-2@^2.0.0-beta.69":
- version "2.0.0-beta.69"
- resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.0.0-beta.69.tgz#65ed98e966c28c9614d4c5a6218e99397a2e0a26"
- integrity sha512-Adm+YvhaihW3mpFIBgPH/3qlxG3hY7/g52gM3Kg0f//SNg/bDqK+AMLroZB5Je06ihCqBaRb1hrSD0/gTVMJ1g==
+"@tiptap/vue-2@^2.0.0-beta.74":
+ version "2.0.0-beta.74"
+ resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.0.0-beta.74.tgz#da9e56113018525d0cb55812a2452d57b9710d26"
+ integrity sha512-OY6RhR2DSvP4iIxtoWeg2qmQ1uYP4kJkdMT5ePQBFqVzs6l5+FpSjETskS8EwZVgM/IrLTMp5lHfKboP/YacOA==
dependencies:
- "@tiptap/extension-bubble-menu" "^2.0.0-beta.50"
- "@tiptap/extension-floating-menu" "^2.0.0-beta.45"
- prosemirror-view "^1.23.1"
+ "@tiptap/extension-bubble-menu" "^2.0.0-beta.54"
+ "@tiptap/extension-floating-menu" "^2.0.0-beta.49"
+ prosemirror-view "^1.23.5"
"@toast-ui/editor@^2.5.2":
version "2.5.2"
@@ -1944,17 +1943,17 @@
"@types/prosemirror-transform" "*"
"@types/prosemirror-view" "*"
-"@types/prosemirror-transform@*", "@types/prosemirror-transform@^1.1.4":
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/@types/prosemirror-transform/-/prosemirror-transform-1.1.4.tgz#c3565e81b2ef3ce3254e6927d6f63eb8d7bb20d0"
- integrity sha512-HP1PauvkqSgDquZut8HaLOTUDQ6jja/LAy4OA7tTS1XG7wqRnX3gLUyEj0mD6vFd4y8BPkNddNdOh/BeGHlUjg==
+"@types/prosemirror-transform@*", "@types/prosemirror-transform@^1.1.5":
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/@types/prosemirror-transform/-/prosemirror-transform-1.1.5.tgz#e6949398c64a5d3ca53e6081352751aa9e9ce76e"
+ integrity sha512-Wr2HXaEF4JPklWpC17RTxE6PxyU54Taqk5FMhK1ojgcN93J+GpkYW8s0mD3rl7KfTmlhVwZPCHE9o0cYf2Go5A==
dependencies:
"@types/prosemirror-model" "*"
-"@types/prosemirror-view@*", "@types/prosemirror-view@^1.19.1":
- version "1.19.1"
- resolved "https://registry.yarnpkg.com/@types/prosemirror-view/-/prosemirror-view-1.19.1.tgz#f12309ef07dfb701d20c2e4d0292d42ba34a081b"
- integrity sha512-fyQ4NVxAdfISWrE2qT8cpZdosXoH/1JuVYMBs9CdaXPbvi/8R2L2tkkcMRM314piKrO8nfYH5OBZKzP2Ax3jtA==
+"@types/prosemirror-view@*", "@types/prosemirror-view@^1.19.2":
+ version "1.19.2"
+ resolved "https://registry.yarnpkg.com/@types/prosemirror-view/-/prosemirror-view-1.19.2.tgz#1bab4daf0f1f14313fe0d3f6b57f0a3b4ef6c50d"
+ integrity sha512-pmh2DuMJzva4D7SxspRKIzkV6FK2o52uAqGjq2dPYcQFPwu4+5RcS1TMjFVCh1R+Ia1Rx8wsCNIId/5+6DB0Bg==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
@@ -2046,10 +2045,10 @@
source-map "~0.6.1"
vue-template-es2015-compiler "^1.9.0"
-"@vue/test-utils@1.2.0":
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.2.0.tgz#3bc8c17ed549157275f0aec6b95da40887f7297f"
- integrity sha512-poBTLqeJYNq1TXVhtVfnY8vELUVOFdJY8KZZoUuaAkIqPTWsxonU1M8nMWpZT+xEMrM+49+YcuEqtMHVD9Q9gw==
+"@vue/test-utils@1.3.0":
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.3.0.tgz#d563decdcd9c68a7bca151d4179a2bfd6d5c3e15"
+ integrity sha512-Xk2Xiyj2k5dFb8eYUKkcN9PzqZSppTlx7LaQWBbdA8tqh3jHr/KHX2/YLhNFc/xwDrgeLybqd+4ZCPJSGPIqeA==
dependencies:
dom-event-types "^1.0.0"
lodash "^4.17.15"
@@ -2240,7 +2239,7 @@ abbrev@1:
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
-abort-controller@3.0.0:
+abort-controller@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==
@@ -2289,9 +2288,9 @@ acorn@^7.1.1, acorn@^7.4.0:
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
acorn@^8.0.4:
- version "8.1.0"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.1.0.tgz#52311fd7037ae119cbb134309e901aa46295b3fe"
- integrity sha512-LWCF/Wn0nfHOmJ9rzQApGnxnvgfROzGilS8936rqN/lfcYkY9MYZzdMqN+2NJ4SlTc+m5HiSa+kNfDtI64dwUA==
+ version "8.6.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895"
+ integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==
agent-base@4, agent-base@^4.3.0:
version "4.3.0"
@@ -2396,6 +2395,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
dependencies:
color-convert "^2.0.1"
+ansi-styles@^5.0.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b"
+ integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
+
anymatch@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
@@ -3435,19 +3439,10 @@ cli-boxes@^2.2.0:
resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.0.tgz#538ecae8f9c6ca508e3c3c95b453fe93cb4c168d"
integrity sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==
-clipboard@^1.7.1:
- version "1.7.1"
- resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-1.7.1.tgz#360d6d6946e99a7a1fef395e42ba92b5e9b5a16b"
- integrity sha1-Ng1taUbpmnof7zleQrqStem1oWs=
- dependencies:
- good-listener "^1.2.2"
- select "^1.1.2"
- tiny-emitter "^2.0.0"
-
-clipboard@^2.0.0:
- version "2.0.6"
- resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.6.tgz#52921296eec0fdf77ead1749421b21c968647376"
- integrity sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==
+clipboard@^2.0.0, clipboard@^2.0.8:
+ version "2.0.8"
+ resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.8.tgz#ffc6c103dd2967a83005f3f61976aa4655a4cdba"
+ integrity sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==
dependencies:
good-listener "^1.2.2"
select "^1.1.2"
@@ -3790,10 +3785,10 @@ core-js-pure@^3.0.0:
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813"
integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==
-core-js@^3.20.0:
- version "3.20.0"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.20.0.tgz#1c5ac07986b8d15473ab192e45a2e115a4a95b79"
- integrity sha512-KjbKU7UEfg4YPpskMtMXPhUKn7m/1OdTHTVjy09ScR2LVaoUXe8Jh0UdvN2EKUR6iKTJph52SJP95mAB0MnVLQ==
+core-js@^3.20.2:
+ version "3.20.2"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.20.2.tgz#46468d8601eafc8b266bd2dd6bf9dee622779581"
+ integrity sha512-nuqhq11DcOAbFBV4zCbKeGbKQsUDRqTX0oqx7AttUBuqe3h20ixsE039QHelbL6P4h+9kytVqyEtyZ6gsiwEYw==
core-js@~2.3.0:
version "2.3.0"
@@ -3875,13 +3870,6 @@ cropper@^2.3.0:
dependencies:
jquery ">= 1.9.1"
-cross-fetch@3.1.4:
- version "3.1.4"
- resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39"
- integrity sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==
- dependencies:
- node-fetch "2.6.1"
-
cross-spawn@^6.0.0, cross-spawn@^6.0.5:
version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
@@ -3902,6 +3890,16 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2:
shebang-command "^2.0.0"
which "^2.0.1"
+cross-undici-fetch@^0.0.20:
+ version "0.0.20"
+ resolved "https://registry.yarnpkg.com/cross-undici-fetch/-/cross-undici-fetch-0.0.20.tgz#6b7c5ac82a3601edd439f37275ac0319d77a120a"
+ integrity sha512-5d3WBC4VRHpFndECK9bx4TngXrw0OUXdhX561Ty1ZoqMASz9uf55BblhTC1CO6GhMWnvk9SOqYEXQliq6D2P4A==
+ dependencies:
+ abort-controller "^3.0.0"
+ form-data "^4.0.0"
+ node-fetch "^2.6.5"
+ undici "^4.9.3"
+
crypt@~0.0.1:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
@@ -4785,6 +4783,11 @@ diff-sequences@^26.5.0:
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.5.0.tgz#ef766cf09d43ed40406611f11c6d8d9dd8b2fefd"
integrity sha512-ZXx86srb/iYy6jG71k++wBN9P9J05UNQ5hQHQd9MtMPvcqXPx/vKU69jfHV637D00Q2gSgPk2D+jSx3l1lDW/Q==
+diff-sequences@^27.4.0:
+ version "27.4.0"
+ resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.4.0.tgz#d783920ad8d06ec718a060d00196dfef25b132a5"
+ integrity sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==
+
diff@^3.4.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
@@ -4919,12 +4922,7 @@ domhandler@^4.0.0, domhandler@^4.2.0:
dependencies:
domelementtype "^2.2.0"
-dompurify@2.3.3:
- version "2.3.3"
- resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.3.tgz#c1af3eb88be47324432964d8abc75cf4b98d634c"
- integrity sha512-dqnqRkPMAjOZE0FogZ+ceJNM2dZ3V/yNOuFB7+39qpO93hHhfRpHw3heYQC7DPK9FqbQTfBKUJhiSfz4MvXYwg==
-
-dompurify@^2.3.4:
+dompurify@2.3.4, dompurify@^2.3.4:
version "2.3.4"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.4.tgz#1cf5cf0105ccb4debdf6db162525bd41e6ddacc6"
integrity sha512-6BVcgOAVFXjI0JTjEvZy901Rghm+7fDQOrNIcxB4+gdhj6Kwp6T9VBhBY/AbagKHJocRkDYGd6wvI+p4/10xtQ==
@@ -5901,7 +5899,7 @@ forever-agent@~0.6.1:
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
-form-data@4.0.0:
+form-data@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
@@ -6224,18 +6222,18 @@ graphlib@^2.1.8:
dependencies:
lodash "^4.17.15"
-graphql-config@^4.0.1:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-4.0.2.tgz#4c3c2eaafe4ffe090da55c48ce6f835c3fee133f"
- integrity sha512-O8De/OscAaD4Kwe70Ik3BKg2DQRKh8J5Bq5HsMKWb9OtzVU+t/zoPD8wh7sNNxFNG8sLjT4cCP/9UorQpHTdeQ==
+graphql-config@4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-4.1.0.tgz#a3b28d3fb537952ebeb69c75e4430605a10695e3"
+ integrity sha512-Myqay6pmdcmX3KqoH+bMbeKZ1cTODpHS2CxF1ZzNnfTE+YUpGTcp01bOw6LpzamRb0T/WTYtGFbZeXGo9Hab2Q==
dependencies:
"@endemolshinegroup/cosmiconfig-typescript-loader" "3.0.2"
- "@graphql-tools/graphql-file-loader" "^7.0.1"
- "@graphql-tools/json-file-loader" "^7.0.1"
- "@graphql-tools/load" "^7.1.0"
- "@graphql-tools/merge" "^6.2.16 || ^7.0.0 || ^8.0.0"
- "@graphql-tools/url-loader" "^7.0.3"
- "@graphql-tools/utils" "^8.0.1"
+ "@graphql-tools/graphql-file-loader" "^7.3.2"
+ "@graphql-tools/json-file-loader" "^7.3.2"
+ "@graphql-tools/load" "^7.4.1"
+ "@graphql-tools/merge" "^8.2.1"
+ "@graphql-tools/url-loader" "^7.4.2"
+ "@graphql-tools/utils" "^8.5.1"
cosmiconfig "7.0.1"
cosmiconfig-toml-loader "1.0.0"
minimatch "3.0.4"
@@ -6263,10 +6261,10 @@ graphql-ws@^5.4.1:
resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-5.5.3.tgz#1495c1c1ad7dcd3cf76a46db629810a55d3b2d18"
integrity sha512-Okp3gE3vq9OoeqsYVbmzKvPcvlinKNXrfVajH7D3ul1UdCg2+K2zVYbWKmqxehkAZ+GKVfngK5fzyXSsfpe+pA==
-graphql@^15.4.0:
- version "15.4.0"
- resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.4.0.tgz#e459dea1150da5a106486ba7276518b5295a4347"
- integrity sha512-EB3zgGchcabbsU9cFe1j+yxdzKQKAbGUWRb13DsrsMN1yyfmmIq+2+L5MqVWcDCE4V89R5AyUOi7sMOGxdsYtA==
+graphql@^15.7.2:
+ version "15.7.2"
+ resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.7.2.tgz#85ab0eeb83722977151b3feb4d631b5f2ab287ef"
+ integrity sha512-AnnKk7hFQFmU/2I9YSQf3xw44ctnSFCfp3zE0N6W174gqe9fWG/2rKaKxROK7CcI3XtERpjEKFqts8o319Kf7A==
growly@^1.3.0:
version "1.3.0"
@@ -7026,11 +7024,6 @@ is-potential-custom-element-name@^1.0.0:
resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397"
integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c=
-is-promise@4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-4.0.0.tgz#42ff9f84206c1991d26debf520dd5c01042dd2f3"
- integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==
-
is-regex@^1.1.1, is-regex@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
@@ -7265,6 +7258,16 @@ jest-diff@^26.5.2:
jest-get-type "^26.3.0"
pretty-format "^26.5.2"
+jest-diff@^27.4.6:
+ version "27.4.6"
+ resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.4.6.tgz#93815774d2012a2cbb6cf23f84d48c7a2618f98d"
+ integrity sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w==
+ dependencies:
+ chalk "^4.0.0"
+ diff-sequences "^27.4.0"
+ jest-get-type "^27.4.0"
+ pretty-format "^27.4.6"
+
jest-docblock@^26.0.0:
version "26.0.0"
resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-26.0.0.tgz#3e2fa20899fc928cb13bd0ff68bd3711a36889b5"
@@ -7313,6 +7316,11 @@ jest-get-type@^26.3.0:
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0"
integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==
+jest-get-type@^27.4.0:
+ version "27.4.0"
+ resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.4.0.tgz#7503d2663fffa431638337b3998d39c5e928e9b5"
+ integrity sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==
+
jest-haste-map@^26.5.2:
version "26.5.2"
resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.5.2.tgz#a15008abfc502c18aa56e4919ed8c96304ceb23d"
@@ -7936,10 +7944,10 @@ linkify-it@^3.0.1:
dependencies:
uc.micro "^1.0.1"
-linkifyjs@^3.0.3:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-3.0.3.tgz#51ea2160b4c60c2c87c27757a1e9eacd422c6076"
- integrity sha512-ba5opS5wRHSbDC8VaiDdN14nPGm6LqyRsIPQZGG4qXV4scFdrPneT/uoZOaq9QAPBf6W9I9D/6tNSzWH//815Q==
+linkifyjs@^3.0.5:
+ version "3.0.5"
+ resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-3.0.5.tgz#99e51a3a0c0e232fcb63ebb89eea3ff923378f34"
+ integrity sha512-1Y9XQH65eQKA9p2xtk+zxvnTeQBG7rdAXSkUG97DmuI/Xhji9uaUzaWxRj6rf9YC0v8KKHkxav7tnLX82Sz5Fg==
load-json-file@^2.0.0:
version "2.0.0"
@@ -8082,7 +8090,7 @@ lodash.kebabcase@4.1.1:
resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36"
integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY=
-lodash.lowercase@^4.3.0:
+lodash.lowercase@4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.lowercase/-/lodash.lowercase-4.3.0.tgz#46515aced4acb0b7093133333af068e4c3b14e9d"
integrity sha1-RlFaztSssLcJMTMzOvBo5MOxTp0=
@@ -8456,16 +8464,16 @@ merge2@^1.3.0:
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
-mermaid@^8.13.4:
- version "8.13.4"
- resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-8.13.4.tgz#924cb85f39380285e0a99f245c66cfa61014a2e1"
- integrity sha512-zdWtsXabVy1PEAE25Jkm4zbTDlQe8rqNlTMq2B3j+D+NxDskJEY5OsgalarvNLsw+b5xFa1a8D1xcm/PijrDow==
+mermaid@^8.13.8:
+ version "8.13.8"
+ resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-8.13.8.tgz#fc137e2a59df34a3e053712033833ffbbc8d84a9"
+ integrity sha512-Z5v31rvo8P7BPTiGicdJl9BbzyUe9s5sXILK8sM1g7ijkagpfFjPtXZVsq5P1WlN8m/fUp2PPNXVF9SqeTM91w==
dependencies:
"@braintree/sanitize-url" "^3.1.0"
d3 "^7.0.0"
dagre "^0.8.5"
dagre-d3 "^0.6.4"
- dompurify "2.3.3"
+ dompurify "2.3.4"
graphlib "^2.1.8"
khroma "^1.4.1"
moment-mini "^2.24.0"
@@ -8829,10 +8837,12 @@ node-ensure@^0.0.0:
resolved "https://registry.yarnpkg.com/node-ensure/-/node-ensure-0.0.0.tgz#ecae764150de99861ec5c810fd5d096b183932a7"
integrity sha1-7K52QVDemYYexcgQ/V0Jaxg5Mqc=
-node-fetch@2.6.1, node-fetch@^2.6.1:
- version "2.6.1"
- resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
- integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
+node-fetch@^2.6.1, node-fetch@^2.6.5:
+ version "2.6.6"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89"
+ integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==
+ dependencies:
+ whatwg-url "^5.0.0"
node-forge@^0.10.0:
version "0.10.0"
@@ -9726,6 +9736,15 @@ pretty-format@^26.4.2, pretty-format@^26.5.2:
ansi-styles "^4.0.0"
react-is "^16.12.0"
+pretty-format@^27.4.6:
+ version "27.4.6"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.4.6.tgz#1b784d2f53c68db31797b2348fa39b49e31846b7"
+ integrity sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g==
+ dependencies:
+ ansi-regex "^5.0.1"
+ ansi-styles "^5.0.0"
+ react-is "^17.0.1"
+
pretty@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pretty/-/pretty-2.0.0.tgz#adbc7960b7bbfe289a557dc5f737619a220d06a5"
@@ -9805,10 +9824,10 @@ 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.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.2.0.tgz#28fb60bf3d9baf1f920907d2c3e613137204e8f3"
- integrity sha512-yCLy5+0rVqLir/KcHFathQj4Rf8aRHi80FmEfKtM0JmyzvwdomslLzDZ/pX4oFhFKDgjl/WBBBFNqDyNifWg7g==
+prosemirror-gapcursor@^1.1.5, 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==
dependencies:
prosemirror-keymap "^1.0.0"
prosemirror-model "^1.0.0"
@@ -9840,7 +9859,7 @@ 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:
+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==
@@ -9848,10 +9867,10 @@ prosemirror-markdown@^1.6.0:
markdown-it "^10.0.0"
prosemirror-model "^1.0.0"
-prosemirror-model@^1.0.0, prosemirror-model@^1.13.1, prosemirror-model@^1.14.3, prosemirror-model@^1.15.0, prosemirror-model@^1.2.0, prosemirror-model@^1.8.1:
- version "1.15.0"
- resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.15.0.tgz#23bc09098daa7c309dba90a76a1b989ce6f61405"
- integrity sha512-hQJv7SnIhlAy9ga3lhPPgaufhvCbQB9tHwscJ9E1H1pPHmN8w5V/lURueoYv9Kc3/bpNWoyHa8r3g//m7N0ChQ==
+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:
+ version "1.16.1"
+ resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.16.1.tgz#fb388270bc9609b66298d6a7e15d0cc1d6c61253"
+ integrity sha512-r1/w0HDU40TtkXp0DyKBnFPYwd8FSlUSJmGCGFv4DeynfeSlyQF2FD0RQbVEMOe6P3PpUSXM6LZBV7W/YNZ4mA==
dependencies:
orderedmap "^1.1.0"
@@ -9905,12 +9924,12 @@ prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transfor
dependencies:
prosemirror-model "^1.0.0"
-prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.16.5, prosemirror-view@^1.23.1, prosemirror-view@^1.23.3:
- version "1.23.3"
- resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.23.3.tgz#9ba85fefaf45e813c46562b694fc5f6f9a5cba9c"
- integrity sha512-89icyMdXXwxmTxYj0TIuG5M/d0iKeu79tr+PVtC/4qtCOoHrPSPrblJcFOuOWcxGlA/Ei8PqJB4g5HkKR8jWvQ==
+prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.16.5, prosemirror-view@^1.23.5:
+ version "1.23.5"
+ resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.23.5.tgz#0f4af48fa9d30aa0b945816e2b8e6cb1c82ac674"
+ integrity sha512-GlcCtoFdW17KNOKjOl7OZTU3btENgVfzN/i0RBvy1SEKAZfo88PdvcFrWTraNZHH+y/uhYR3PAdMiDK9DlN5UA==
dependencies:
- prosemirror-model "^1.14.3"
+ prosemirror-model "^1.16.0"
prosemirror-state "^1.0.0"
prosemirror-transform "^1.1.0"
@@ -10113,6 +10132,11 @@ react-is@^16.12.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
+react-is@^17.0.1:
+ version "17.0.2"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
+ integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
+
read-pkg-up@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be"
@@ -10232,9 +10256,9 @@ regex-not@^1.0.0, regex-not@^1.0.2:
safe-regex "^1.1.0"
regexpp@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2"
- integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
+ integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
regexpu-core@^4.7.0:
version "4.7.0"
@@ -11136,7 +11160,7 @@ string-width@^3.0.0, string-width@^3.1.0:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^5.1.0"
-string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0:
+string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -11322,10 +11346,10 @@ stylis@^4.0.10:
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.10.tgz#446512d1097197ab3f02fb3c258358c3f7a14240"
integrity sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg==
-subscriptions-transport-ws@^0.10.0:
- version "0.10.0"
- resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.10.0.tgz#91fce775b31935e4ca995895a40942268877d23f"
- integrity sha512-k28LhLn3abJ1mowFW+LP4QGggE0e3hrk55zXbMHyAeZkCUYtC0owepiwqMD3zX8DglQVaxnhE760pESrNSEzpg==
+subscriptions-transport-ws@^0.11.0:
+ version "0.11.0"
+ resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.11.0.tgz#baf88f050cba51d52afe781de5e81b3c31f89883"
+ integrity sha512-8D4C6DIH5tGiAIpp5I0wD/xRlNiZAPGHygzCe7VzyzUoxHtawzjNAY9SUTXU05/EY2NMY9/9GF0ycizkXr1CWQ==
dependencies:
backo2 "^1.0.2"
eventemitter3 "^3.1.0"
@@ -11398,16 +11422,15 @@ sync-fetch@0.3.1:
node-fetch "^2.6.1"
table@^6.0.7, table@^6.0.9:
- version "6.7.1"
- resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2"
- integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==
+ version "6.7.3"
+ resolved "https://registry.yarnpkg.com/table/-/table-6.7.3.tgz#255388439715a738391bd2ee4cbca89a4d05a9b7"
+ integrity sha512-5DkIxeA7XERBqMwJq0aHZOdMadBx4e6eDoFRuyT5VR82J0Ycg2DwM6GfA/EQAhJ+toRTaS1lIdSQCqgrmhPnlw==
dependencies:
ajv "^8.0.1"
- lodash.clonedeep "^4.5.0"
lodash.truncate "^4.4.2"
slice-ansi "^4.0.0"
- string-width "^4.2.0"
- strip-ansi "^6.0.0"
+ string-width "^4.2.3"
+ strip-ansi "^6.0.1"
taffydb@2.6.2:
version "2.6.2"
@@ -11712,6 +11735,11 @@ tr46@^2.0.2:
dependencies:
punycode "^2.1.1"
+tr46@~0.0.3:
+ version "0.0.3"
+ resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
+ integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
+
trim-newlines@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.0.tgz#79726304a6a898aa8373427298d54c2ee8b1cb30"
@@ -11883,6 +11911,11 @@ underscore@~1.8.3:
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022"
integrity sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=
+undici@^4.9.3:
+ version "4.10.2"
+ resolved "https://registry.yarnpkg.com/undici/-/undici-4.10.2.tgz#27e360f2d4202ef98dfc1c8e13dcd329660a6d7c"
+ integrity sha512-QoQH4PpV3dqJwr4h1HazggbB4f5CBknvYANjI9hxXCml+AAzLoh4HBkce0Jc0wW/pmVbrus8Gfeo8QounE+/9g==
+
unicode-canonical-property-names-ecmascript@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818"
@@ -12438,6 +12471,11 @@ web-vitals@^0.2.4:
resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-0.2.4.tgz#ec3df43c834a207fd7cdefd732b2987896e08511"
integrity sha512-6BjspCO9VriYy12z356nL6JBS0GYeEcA457YyRzD+dD6XYCQ75NKhcOHUMHentOE7OcVCIXXDvOm0jKFfQG2Gg==
+webidl-conversions@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
+ integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
+
webidl-conversions@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff"
@@ -12606,6 +12644,14 @@ whatwg-mimetype@^2.3.0:
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
+whatwg-url@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
+ integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0=
+ dependencies:
+ tr46 "~0.0.3"
+ webidl-conversions "^3.0.0"
+
whatwg-url@^8.0.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.1.0.tgz#c628acdcf45b82274ce7281ee31dd3c839791771"